This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Enabled peripherals on reset, are there any?

Hello everyone,


Well I was trying to create Faults. This was to keen my analysis on Faults sources and debugging. I was successful but not at first and it's actually because of that failure to fail that I come here.

Well, I basically set Timer1 load value without enabling the peripheral clock. Well, this didn't generate any Fault! Or at least it didn't call the FaultISR. When I used Timer5 it faulted just fine.

So my questions is:

Is there peripherals (excluding cortex-m4 peripherals) already with clock enabled on reset, and if so where can I find this info?

  • Luis Afonso said:
    where can I find this info?

    Might clues exist win:

    a) your Start-Up file

    b) your compiler

    c) the "base program" (we know - it's never your "own creation" - instead (always) one pre-existing - might it be the culprit?)

    Review of the specific Peripheral Register content - PRIOR to the execution of any Start-Up file - may provide further insight

    And - for extra credit - I'll bet you that not all calls to Peripherals must wait for your (oft prescribed) 3 system clocks - after that peripheral is enabled...  (and why might that be?)

  • Hello cb1,

    Might I suggest that a previous code kept the clock enabled and the CPU reset never did reset the core!!!

    Regards
    Amit
  • Hi Amit,

    Only as you are proving (again) that you are way smarter than moi.

    Long ago - when LX4F first arrived - we found that (IAR's) start up file impacted some/many peripheral registers.

    The requirement for (some) delay - prior to an access to a just, " Enabled Peripheral" appears NOT to be "hard/fast" requirement. In fact many/most early (LMI) code examples rarely (if ever) showed such care/concern for such delay.

    Probably safer to use (safe trumps sorry) but Luis appears to seek, "When, where, why, how" - and that's bit beyond this reporter. (outside of the points I raised)
  • Hello everyone,

    So please bear with me for a bit, I might say something stupid.

    So I went and did some very small tests.

    The tests were done just with the GPIO for now. I was monitoring PRGPIO register.

    First test:

    1. unplug USB from board and plug back
    2. Upload main with clock set to 80Mhz and a while(1).
    3. Run code and then pause it

    So the code is inside the while(1) and all GPIO give unready status.



    Second test:

    First I uploaded this code:

    #define SYSCTL_RCGCBASE         0x400fe600
    #define base GPIO_PORTB_BASE
    #define peripheral SYSCTL_PERIPH_GPIOB
    
    int main(){
    	  //Set clock to 80Mhz, just like I normaly start a code
    	  SysCtlClockSet(SYSCTL_SYSDIV_2_5|SYSCTL_USE_PLL|SYSCTL_OSC_MAIN|SYSCTL_XTAL_16MHZ);
    
    	  //1st break point
    	  HWREGBITW(SYSCTL_RCGCBASE + ((SYSCTL_PERIPH_GPIOA & 0xff00) >> 8),
    			  SYSCTL_PERIPH_GPIOA & 0xff) = 1;
    
    	  //2nd break point
    	  HWREGBITW(SYSCTL_RCGCBASE + ((peripheral & 0xff00) >> 8),
    			  peripheral & 0xff) = 1;
    	  
    	  //GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3);
    	  //3rd break point
    	  HWREG(base + GPIO_O_DIR) |= GPIO_PIN_1;
    	  //4th break point
    	  HWREG(base + GPIO_O_AFSEL) &= ~(GPIO_PIN_1);
    
    
    	  while(1){
    		  /* more code here*/
    
    	  }
    }
    

    
    

    So I first enable GPIOA just as a control. I don't do anything else with it.
    Then I enable the GPIO of my choise (in here it was B) and proceed to write on some of the corresponding registers.

    1. Didn't unplug board,
    2. Upload code
    3. Check registers before running - all GPIO unready
    4. Add now break points to each direct register access to GPIO in the C code.
    5. Run code
      1. 1st break point - no change
      2. 2nd break point - GPIOA ready
        1. Checked assembly code, it's in the next instruction after STR so supposedly just 1 cycle occurred
      3. 3rd break point -GPIOB ready
      4. Code gets stuck on 3rd break point even after removing it - after resetting without break points the code reached while(1) 

    So it doesn't seem the GPIO need the delay at all!

    Now the question "which peripherals are on from the get go?": None besides the hibernation module.

    To add - I noticed with more testing that the peripherals keep their status of on after a reset - a power cycle is needed to completely reset them (or a peripheral reset of course). Edit: Like Amit referred.

    I was doing a lot of messing around with the board and that did include Timer0 so he was already enabled when I tried to cause a Fault with it.
    No test was made with other peripherals besides the GPIO so if any other needs the delay after enabling the clock is a mystery for me.



  • @Luis,

    You're silent as regards the (potential/likely) impact of Start-Up file. Appears that you had to run it - did you not? And - as stated (twice here) that start-up file indeed did alter (some) peripheral register contents - long before program reached "main()." Perhaps warrants (some) consideration...
  • Ah yes, sorry cb1.

    I did see the startup file and it doesn't seem do anything remotly relevant to the matter.
    Also since I checked, with a empty main after a power cycle, the ready registers to confirm them all 0 besides the hibernation module I ruled out that hypothesis.
  • @Luis,

    Paid IAR most definitely impacted our LX4F MCUs by running "start-up" file. (iirc - the actual code mechanisms were not easy to discover - but local TI FAE visited our facility - confirmed our findings. I believe that the PWM Registers were those (especially) impacted)

    Further point - you tested Port A - but is not that port the recipient of "special handling" (i.e. defaults into UART, I2C, SPI etc.) and not the "best/brightest" port for such a test? Suspect your targeting a most general port will yield more logically defensible results...

    Searching memory bit more - we noted a, "Lack of agreement" between LX4F's Peripheral Register Values - at Reset - w/in the MCU manual and that revealed under IAR.   It is possible that IAR (did something) even prior to the execution of the Start-Up file - and that TI FAE "tipped us" to the fact that we had to "break" prior to the start of "Start-Up" file.  This is 4-5 years past - but your post brought this back...

  • Hello cb1,

    The startup file if not modified other than the reset vector must not affect the peripheral settings.

    BTW: I was just complementing your post with something I have seen quite a lot of time.

    Regards
    Amit
  • Yes! Thinking! I got to sometimes actually think. (before acting) 

    Can I take a educated guess?

    It didn't make sense to me at all the need for a delay! The peripheral should be ready right away.
    Then it hit me. "Wait! Isn't there peripherals that don't get the clock from the system clock? There is! At least the ADC is one of them, let's check the clock tree!"
    Further to that I just went on a hunch and check 80Mhz/16Mhz. Why? Well in the source files, it's commented to wait 5 cycles on SysCtlPeripheralEnable. Well 80/16=5! It's the number of cycles it take for the ADC to be ready in relationship to the maximum CPU speed!

    Tried the "create a fault test" and it indeed it created a fault!

    Peripherals that start off with different clocks will have the same problem.


    Do I deserve a cookie?

  • For (long) service here - I can offer you (instead) a vendor supplied, "low-thread count" T-Shirt or a neat (yet leaky) coffee cup. All emblazoned w/famed logo. (not that my small group was not "thrilled" w/vendor's largesse...)
  • Leaky coffee cup = Cup for holding pencils
    I fail to see a problem, only wrong application :p
  • Hi , I actually was not aware that peripherals registers maintain the previous state after a reset and needed a power cycle to clear it previous to this discussion.

    About what I said about the different clock speeds on some peripherals - Do I deserve a cookie or am I completely wrong?
  • Hello Luis,

    Peripheral Registers do not maintain the value after a reset. Simple experiment, is to enable a peripheral, write a register (that is readable), reset the register using SysCtlPeripheralReset, re-enable it and read the register

    Regards
    Amit
  • Hi Amit,

    Thank you for the quick response.
    I was speaking of pressing the reset button.
    I saw that at least the peripherals clock enabled config is maintain in the sysctl. This when I press the reset button

    Are you saying that the registers in the peripheral itself are not maintain even when pressing the reset button, or they are just reset when using SysCtlPeripheralReset?
  • Hello Luis

    The Pad Reset will reset all registers. The issue is that the code starts executing so, by the time you connect and see via a debugger the values seem to be "not reset"

    Regards
    Amit
  • Hi Amit,

    Thank you very much. Found exactly what I was looking for.
    The problem was between debugs without any reset, I will have to remember to chose "System reset" on the debugger instead of "core reset"

    Thank you for bearing with me :D
  • Might you present here - in one final posting - the organized summary of your findings? Twenty or so "back-forth" fog your issue - one, neat well summarized presentation would best serve your readers. (and look nice @ "Luis-land" tutorial site...)
  • Hi cb1,

    Something like this? (ready to rain judgement on me)

    Original problem:

    "Accessing Timer0 registers without enabling the clock didn't cause a Fault"

    Answer:
    Previously loaded  code  that enabled Timer0. After that, without a power cycle or pressing the reset button the test "Fault inducing" code was loaded.
    Without a power cycle or a system reset the register keep their value from the previous executions.

    Solutions to avoid starting with non-default values:
    Solution 1 -Turn off and turn back on the power on the launchpad, a power cycle.
    Solution 2 - Press the reset button - this can cause problems while debugging.
    Solution 3- Improvement from solution 2 - While on debug do a "System Reset" (not core reset) before starting the code. If you alredy started the code restart the code after doing the system reset.


    2nd matter

    The discussion escalated to the "wait cycles after enabling a peripheral clock"
    It's advised in the datasheet that after enabling the peripheral clock there's the need to wait at least 3 clock cycles to access the peripheral registers. The source for SysCtlPeripheralEnable actually refers to a 5 cycle delay minimum.
    So I tried to check some peripherals - these were the GPIO, General Purpose Timers, SSI, I2C, UART and ADC. All this with the System Clock at 80Mhz:

    System clock setup: SysCtlClockSet(SYSCTL_SYSDIV_2_5|SYSCTL_USE_PLL|SYSCTL_OSC_MAIN|SYSCTL_XTAL_16MHZ);
    In the end of the main there is a while(1) to loop forever.

    Used functions for testing:

    For GPIO

    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
    GPIOPinTypeGPIOOutput(GPIO_PORTA_BASE, GPIO_PIN_1);

    For Timer

    SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0);
    TimerConfigure(TIMER0_BASE, TIMER_CFG_SPLIT_PAIR|TIMER_CFG_B_PWM);

    For SSI

    SysCtlPeripheralEnable(SYSCTL_PERIPH_SSI0);
    SSIConfigSetExpClk(SSI0_BASE, 80000000, SSI_FRF_MOTO_MODE_1,SSI_MODE_MASTER, 20000000, 16);

    For I2C

    SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C0);
    I2CMasterInitExpClk(I2C0_BASE,80000000,1);

    For UART

    SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
    UARTClockSourceGet(UART0_BASE);

    For ADC

    SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0);
    ADCSequenceConfigure(ADC0_BASE, 3, ADC_TRIGGER_PROCESSOR, 0);


    Now what the GPIO, Timer and I2C have in common is that they get their clock straight from the system clock, hence their clock speed is equal to the CPU.
    The SSI and the SSI are also fed the System clock to the control/status registers so they are also at the same speed as the CPU. You can see in the clock tree figure (Figure 5-5. Main Clock Tree)  that it's their baud-rate that can have separate clock configuration from the system clock.

    With all the above peripherals I had not a single Fault with the tests.

    Now the ADC. The ADC you can see in the clock tree that it can have a different clock path from the system clock. 2 options available: direct PIOSC or the 400MHz from the PLL divided by 25. And actually it's said in the ADC section that it requires the work at 16Mhz and that by default works from divided PLL.
    The ADC test did indeed cause a Fault.
    I can believe that this is the reason for the generic delay after peripheral enable. The maximum clock for the TM4C123 launchpad is 80Mhz, 80Mhz/16Mhz=5, reminds me of the 5 cycle wait referred in the source file.

    By assuming the above true and looking at the rest of the clock tree figure the next candidates for requiring the delay are the PWM module and the USB. Well then let's check their block diagrams:

    Analysis of PWM module diagram:

    Well it's pretty straightforward. We can see the system clock being fed to the control registers, while the PWM clock seen on the Clock Tree is actually just for the PWM generators.
    So we can rule out the need for the delay when enabling the PWM module


    Analysis of the USB diagram:

    I am not familiar at all with the USB so I can't conclude anything in the matter.

    My Verdict:

    Do all peripherals need a delay after enabling the clock?

    No. Just the ADC because the control registers work at a different clock speed from the System Clock which is normally slower. The delay should be at least CPUClockSpeed/16Mhz cycles.
    I can't say anything for the USB.
    Take note that some peripherals although not tested are assumed to work without the delay because all their control registers are feed with the System Clock.
    This is my findings which may be found to false later by further tests.

     

  • Luis Afonso said:
    Something like this? (ready to rain judgment on me)  

    That's (perhaps) a bit harsh - "drizzle" judgment seems far more appropriate.

    Amit's the real expert here - with his background and "insider knowledge" he's most qualified to read/review/comment.

    Alas - some "drizzle" does dot  our windshield - we note that Port "A" (notorious for "enjoying" special configurations) still remains w/in your gpio example...  Gaining any (meaningful) conclusions from a "special port/pin" is outside best-practice - is it not?   (VCs surely think so!)  

    Your summary here makes it far easier for Amit/interested others to read/review - thanks for that effort.

  • Luis Afonso said:
    Solution 3- Improvement from solution 2 - While on debug do a "System Reset" (not core reset) before starting the code. If you alredy started the code restart the code after doing the system reset.

    In the CCS project properties if you enable "Reset target during program load to Flash memory" checkbox in the On-chip Flash settings then a "System Reset" is generated automatically when starting a debug session. i.e. avoids the need to manually perform a "System Reset".

    See Tiva registers do not reset between debug sessions for more details.

  • Thank you Chester!

    A much better solution than remembering to do so every time a debug is done