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.

TMS570LS3137 PMU Initialization

Other Parts Discussed in Thread: HALCOGEN

Hello,

I want to start the PMU cycle counter as early as possible to measure power up time.  HALCoGen supplies the function _pmuInit_(), but doesn't place it in the startup code.  I currently have it at the start of main(), but would like to move it up in the execution path.  Do you have any recommendations on where to insert _pmuInit_() into a user code section in a HALCoGen file? 

(there is no mention of this in SPNA106D)

Thanks, Charlie Johnston

 

  • Hello Charlie,

    I've forwarded your question to our Halcogen team lead since he would be best suited for helping to identify the best placement of the user code in the Halcogen generated source. He should respond to you soon.

  • Hi Charlie,

    You can insert PMU function calls even at the very beginning ( user code (5) )..  But you need to make sure you are not performing STC ( CPU self test ). i.e, In HALCoGen - SAFETY INIT Tab "Enable CPU Self test" must be unchecked.

    Regards
    Prathap

  • Hi Prathap,

    I do have to run stcSelfCheck() and cpuSelfTest().  It looks like both of these will cause a reset.  Will the reset from both result in an unknown value for the ARM register PMCCNTR?

    Thanks, Charlie

  • That's correct. Since these test are used to do self check on the CPU, all the register values will be disturbed. Incase you are measuring the boot time with stcSelfCheck() and cpuSelfTest() I would recommend to use RTI Timer module or simple IO Pin toggle and measure outside.

  • Prathap said:

    You can insert PMU function calls even at the very beginning ( user code (5) )..  But you need to make sure you are not performing STC ( CPU self test ). i.e, In HALCoGen - SAFETY INIT Tab "Enable CPU Self test" must be unchecked.

    Hi Prathap,

    I finally got back to implementing this.  After taking out the CPU Self Test and the CCM Self Check, I added the following at User Code 5:

        // Initialize PMU Cycle and Event Counters
        _pmuInit_();
        // Start PMU Cycle and Event Counters
        _pmuStartCounters_(0x80000007U);  // Mask: Cycles ... Counter 2, 1, 0

    This worked fine on the HDK and some of our production boards, but at times the PMU Event Counter was not running.
    If I moved the code down to User Code 26 (just before systemInit is called), the PMU Event Counter is always running.

    Could there be a power-up timing issue with the ARM CPU?

    Thanks, Charlie Johnston
  • Hi Charlie

    Two things I want to mention

    1) errata_PBIST_4() function uses PMU so it clears the current PMU counter if enabled before.

    2) If you are using PMU before SystemInit, then u need to be careful in manipulating the cycle counts when converting it to TIme, becasue PLL will be on only during SystemInit ( mapClocks API). So any count before user code (13) in system.c counts with OSCIN and after that it uses PLL.

  • Hi Prathap,

    Thanks for responding so quickly.

    1) We're not using the errata_PBIST_4() function yet - the current errata (SPNZ195C) says running two PBISTs is sufficient.

    2) It's not an unexpected time conversion, it's that the cycle count is always zero. 

    Any other ideas?

    Thanks, Charlie Johnston

  • Hi Prathap,

    I moved the two PMU Init lines up to User Code 7, just after the registers and stack pointers are initialized.  This seems to work fine.  Could those two functions be required before trying to set up an ARM CPU coprocessor?  Initializing the registers includes 4 hidden branch and link registers, and the PMU init functions use the stack.

    I'm trying to figure out how soon I can reliably start the PMU, so understanding why it won't start at the code entry point will help determine the code order.

    Thanks, Charlie Johnston

  • Hi Charlie,

       _coreInitRegisters_(); --> Resets all CPU registers to Zero including SP, to Avoid CCM error.

       _coreInitStackPointer_(); --> Initialize SP for all CPU modes.

    _pmuInit_() --> Is assembly fucntion that uses R0 and SP for Push and POP. IF SP is not initialized this function might behave right.

    Hence It is necessary to have    _coreInitRegisters_(); and    _coreInitStackPointer_(); before using _pmuInit_().

    My suggestion would be to write a simpel asm codes before _coreInitRegisters_(); using user code (5). like below, It is basically PMUInit + Start counter like below ( Include "sys_pmu.h" to avoid compile error in sys_startup.c using user code(1)).

    /* USER CODE BEGIN (5) */

    // Enable Global Counter
    asm(" mrc p15, #0, r0, c9, c12, #0");
    asm(" orr r0, r0, #7");
    asm(" mcr p15, #0, r0, c9, c12, #0");

    _pmuStartCounters_(pmuCYCLE_COUNTER);

    /* USER CODE END */

  • Hi Prathap,

    Good idea, but I was hoping to find a cause for the PMU not starting.  We already know that moving the initialization around will make it work differently on different hardware platforms.  I can't just make it work for the few samples I have and hope it will work for all samples.

    Would this be a question for ARM to see if they have any limitations on the PMU relative to power on?

    Thanks, Charlie

  • Hi Prathap,

    Here's the code I added at User Code 5.  The PMU seems to be initialized and the event counter started correctly.

    Thanks, Charlie Johnston

        // set control register
        asm (" mrc p15, #0, r0, c9, c12, #0")    ; //Read Performance Monitor Control Register (PMCR)
        asm (" orr r0,  r0, #0x87U")             ; //Set X (Enable event export)
                                                   // Set D (Count every cycle)
                                                   // Set C (Reset cycle counter)
                                                   // Set P (Reset event counters)
                                                   // Set E (Enable all counters)
        asm (" mcr p15, #0, r0, c9, c12, #0")    ; //Write PMCR
    
        // clear counter overflow flags
        asm (" mov r0,  #0");
        asm (" sub r0,  r0,  #1")                ; //Set all r0 bits to 1
        asm (" mcr p15, #0, r0, c9, c12, #3")    ; //Clear P0, P1, P2 in Overflow Flag Status Register (PMOVSR)
                                                 ; //Flags are cleared by writing a 1.
    
    
        // start PMU Counters
        asm (" mov r0,  #0x80000007U")           ; //Enble Cycle, Events 2, 1, 0
        asm (" mcr p15, #0, r0, c9, c12, #1")    ; //Load r0 into Count Enable Set Register (PMCNTENSET)