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.

Blinky LED example - stuck in _memoryInit_ loop



Dear TI experts,

I have similar issue as described in following forum thread (http://e2e.ti.com/support/microcontrollers/hercules/f/312/p/162759/728746.aspx#728746) with simple blinky example in IAR environment. Unfortunately the mentioned advices have not hepled -  the code of sys_memory.asm compiled and linked by IAR EWARM works incorrectly - processor stays in mloop.

IAR EWARM installation:

    IAR Assembler for ARM
      6.40.2.53884 (6.40.2.53884)

    IAR C/C++ Compiler for ARM
      6.40.2.23884 (6.40.2.23884)

    IAR ELF Linker for ARM
      6.40.2.53884 (6.40.2.53884)

target:
    TMS570LS3x HDK

code snippet:
;-------------------------------------------------------------------------------
; Initialize memory

    PUBLIC     _memoryInit_

_memoryInit_
        ldr   r12, regMinitGcr    ; MINITGCR register pointer
        mov   r4, #0xA
        str   r4, [r12]
        ldr   r4, ramInitMask     ; load RAM initialization mask
        str   r4, [r12, #4]
mloop
        ldr   r5, [r12, #12]
        tst   r5, #0x100
        beq   mloop
        mov   r4, #5
        str   r4, [r12]
        bx    lr

ramInitMask   dcd 0x657F       ; value copied from CCS project 

regMinitGcr   dcd 0xFFFFFF5C

A program built by TMS470 Code Generation Tools 4.9.1 is running properly, does not get stuck in _memoryInit_ function. By the way, the function _coreEnableRamEcc_() is not called.

IAR and TI compilers produce a different object code:

tst   r5, #0x100    

E3150F40  (IAR EWARM)      

E3150C01  (CCSv5)

Dump of SYS1 registers in IAR debugger:
    MINITGCR = 0xA       
    MSINENA = 0x657F
    MSTCGSTAT = 0x0 (0x100 expected)


Please do you have any idea what could be wrong?


Many thanks in advance,

Cheers
Jiri

  • Jiri,

    Would you please check the MINISTAT register (offset = 6Ch) to see if initialization is complete on any RAM module. Since you write 0x657F to MSINENA, you should see the same value in MINISTAT. Each bit represents a RAM module.

    You may also check the ESM registers to check if there is any error in your application before running memory initialization. You said that the same function works with TI compiler. Would you please check if there are any difference in the application compiled with TI compiler and IAR compiler?

    Thanks and regards,

    Zhaohong

  • Zhaohong,

    thanks for your quick response!

    The MINISTAT does not contain the expected value equal to the MSINEMA one. There is stored 0x7, so only 3 RAM modules are initialized properly.

    All registers related to ESM contain zero values except two regs:

    00 00 3f ff = ESMLTCR  @0xfffff530
    00 00 3f ff = ESMLTCPR @0xfffff534

    I have not compared all object files compiled by TI and IAR. Maybe we could suspect following piece of code..? Borders of segments FIQ_STACK, IRQ_STACK, etc. within IAR code are defined in linker file (*.icf) with the same address values as TI code includes.

    -------------------------------------------------------------------------------
    sys_core.asm

    ;+++++++++++++++++
    ; IAR
    ;+++++++++++++++++
    ;-------------------------------------------------------------------------------
    ; Initialize Stack Pointers

        public     _coreInitStackPointer_


    _coreInitStackPointer_

            cps   #17
            ldr   sp, =SFE(FIQ_STACK)
            
            cps   #18
            ldr   sp, =SFE(IRQ_STACK)
            
            cps   #23
            ldr   sp, =SFE(ABT_STACK)
            
        cps   #27
            ldr   sp, =SFE(UND_STACK)

            cps   #31
            ldr   sp, =SFE(CSTACK)

            cps   #19
            ldr   sp, =SFE(SVC_STACK)

            bx    lr

    ;+++++++++++++++++
    ; TI
    ;+++++++++++++++++
    ;-------------------------------------------------------------------------------
    ; Initialize Stack Pointers

        .def     _coreInitStackPointer_
        .asmfunc

    _coreInitStackPointer_

            msr   cpsr_c,   #0xD1         ; FIQ
            ldr   sp,       fiqSp
            msr   cpsr_c,   #0xD2
            ldr   sp,       irqSp
            msr   cpsr_c,   #0xD7
            ldr   sp,       abortSp
            msr   cpsr_c,   #0xDB
            ldr   sp,       undefSp
            msr   cpsr_c,   #0xDF
            ldr   sp,       userSp
            msr   cpsr_c,   #0xD3
            ldr   sp,       svcSp
            bx    lr

    userSp:   .word 0x08000000+0x00000200
    svcSp:    .word 0x08000000+0x00000200+0x00001200
    fiqSp:    .word 0x08000000+0x00000200+0x00001200+0x00000200
    irqSp:    .word 0x08000000+0x00000200+0x00001200+0x00000200+0x00000200
    abortSp:  .word 0x08000000+0x00000200+0x00001200+0x00000200+0x00000200+0x00000100
    undefSp:  .word 0x08000000+0x00000200+0x00001200+0x00000200+0x00000200+0x00000100+0x00000100
        .endasmfunc

  • Jiri,

    MINISTAT =0x7 means that only system RAMs are initialized and none of the peripheral RAM is initialized. Would you please check if the peripheral clock is enabled for the application? You need to set bit 8 of the CLKCNTL register at address 0xffffffd0 to enable peripheral clock.

    Thanks and regards,

    Zhaohong

  • Hello Zhaohong,

    yes, bit 8 is set as needed in the function systemInit() which is called just before _memoryInit_()

    /** - Enable Peripherals */
    systemREG1->PENA = 1U;

    This example has been originally made for RM48 (little endian) but the code supports both endianesses - CLKCNTL register definition at least.

    #ifdef __LITTLE_ENDIAN__
    unsigned : 8U; /* 0x00D0 */
    unsigned PENA : 1U; /* 0x00D0 */
    unsigned : 7U; /* 0x00D0 */
    unsigned VCLKR : 4U; /* 0x00D0 */
    unsigned : 4U; /* 0x00D0 */
    unsigned VCLK2R : 4U; /* 0x00D0 */
    unsigned : 4U; /* 0x00D0 */
    #else
    unsigned : 4U; /* 0x00D0 */
    unsigned VCLK2R : 4U; /* 0x00D0 */
    unsigned : 4U; /* 0x00D0 */
    unsigned VCLKR : 4U; /* 0x00D0 */
    unsigned : 7U; /* 0x00D0 */
    unsigned PENA : 1U; /* 0x00D0 */
    unsigned : 8U; /* 0x00D0 */
    #endif

    As was mentioned above:

    AR and TI compilers produce a different object code:

    tst   r5, #0x100    

    E3150F40  (IAR EWARM)      

    E3150C01  (CCSv5)

     OK, both TI and IAR codes for the value 0x100 are correct (surprisingly :-D) - according to ARM reference manual DDI0406C section A8.8.240 (page 742) + rotation (page 198).

  • Jiri,

    Would you please also check the PCR registers to see if the modules are enabled?

    Thanks and regards,

    Zhaohong

  • Jiri,

    I was just going to respond as Zhaohong did.

    When I clear my PSPWRDN registers, the sequence works correctly.

     

    Best regards,

    Forum Support

  • Zhaohong, Kevin,

    thanks for your ideas!

    Following code is included - so PSPWRDN regs are initialized correctly:

    /** - Power-up all peripharals */
    pcrREG->PSPWRDWNCLR0 = 0xFFFFFFFFU;
    pcrREG->PSPWRDWNCLR1 = 0xFFFFFFFFU;
    pcrREG->PSPWRDWNCLR2 = 0xFFFFFFFFU;
    pcrREG->PSPWRDWNCLR3 = 0xFFFFFFFFU;

  • Hello,

    I have a bit adjusted the value of MSIENA register (the variable ramInitMask in code). The loop does not get stuck if only main, DMA and VIM RAMs are initialized -  MSIENA = 0x0003. If inti of other RAM region is enabled, memory init fails.

    As mentioned above the function systemInit() which is called just before _memoryInit_() - systemInit() does contain the piece of code to power-up all peripherals.

  • Jiri,

    I was playing around with this on the bench yesterday. I poked values into registers and can clearly confirm the same findings you have -- that the MSISTAT is set to 0x7 but no further. When I cleared the Peripheral Powerdown bits (as your code snippet shows) and enabled the peripherals, my memory initialization ran through to completion. I did find that order mattered to this sequence.

     Since you say that all these items are done by your code, I wonder if there is some timing constraint; specifically, when I poke values into a register field, there is almost an infinte amount of time to complete the action before I poke the next value, but when you execute code, the time for completion is much smaller.  Can you set a breakpoint (which will create a large time delay) just before you write to MINITGCR?

    • Check the following registers (PSPWRDNCLR0:3 and CLKCNTL (for Peripheral enable)).
    • I expect that you will find all registers in their correct state.
    • Then either step or run forward.

    Do all memories initialize when the breakpoint is added?

    Best Regards,

    Kevin Lavery

  • Hello,

    if a function _memoryTest_() is called before _memoryInit_(), then the memory initialization works for all RAM blocks (e.g. MSIENA = 0x6573) in the device correctly.

    Silly mistake by me - I will have a look at the function _memoryTest_() why it is the must.

  • Hello Kevin,

    thanks for your attempts and recommendation!

    I have followed your procedure and got these results:

    (1) 

    _memoryTest_() NOT called / performed

     MSIENA = 0x0003

    -------

    code does not get stuck in the loop, runs properly

    PSPWRDNCLR0:3 = 0x00000000

    CLKCNTRL = 0x01010000 (PENA = 0x0 (!!!), VCLKR = 0x1, VCLK2R = 0x1)

    although there is following assignment in code:

    systemREG1->VCLKR = 15U;
    systemREG1->VCLK2R = 1U;
    systemREG1->VCLKR = 15U;

    When I go through this code step by step, this assignment is completely ignored - VCLKR remains at the init value of 0x1.

    (2) 

    _memoryTest_() IS called / performed before _memoryInit_() starts

     MSIENA = 0x657F

    -------

    code does not get stuck in the loop, runs properly

    PSPWRDNCLR0:3 = 0x00000000

    CLKCNTRL = 0x01010000 (PENA = 0x0 (!!!), VCLKR = 0x1, VCLK2R = 0x1) clock related code snippet identical with the one from (1)

    Best regards

    Jiri

  • Jiri,

    I think you understand the behavior. Does anything remain open on this topic.

    Best Regards,

    Kevin Lavery

  • Hello Kevin,

    honestly I do not :-/

    (1) I have not revealed why the function __memoryTest__() must be called before __memoryInit__()? OK, chosen RAM segments are check by selected test algorithm but I have not identified a code line in the function __memoryTest__() which allows following memory initialization to be performed.

    (2) As described above, this code snippet is executed before __memoryInit__()

    /** - Enable Peripherals */
    systemREG1->PENA = 1U;

    Regardless of this enabling the bit 8 of the register CLKCNTL remains at the value of 0 when reading out before write to MINITGCR (breakpoint placement as advised by Kevin).

    Thanks in advance,

    cheers, Jiri

  • I am also getting the same problem after doing everything described here.

    the PSPWRDWNCLRn being set to all ones

    PENA = 1u

    Is there a definitive description of how to initialise the memory with h/w as the TRM description doesn't seem complete enough ?

    Dav)D

  • Hello David,

    since the last post I have not been focused on this topic - sorry, I cannot advise you now. Hopefully other guys will support you - this forum thread has not been closed yet so we can expect a reply by TI expert ;-)

    I am also curious about a solution.

    Best regards,

    Jiri