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.

What exactly happens on "Connect", "Run" and "Halt" (in addition to the GEL commands)?

Other Parts Discussed in Thread: TMS320VC5505

 

Hi,

can anybody tell me what CCS4 or the JTAG does exactly in addition to the commands defined in the GEL file when "Connect", "Run" and "Halt" from the Target menu are selected?

My program seems to work from EEPROM properly only after a Connect-Run-Halt-Run sequence (no load, of course). The code basically executes from EEPROM on power-up without CCS4, but the DMA doesn't work, the interrupts are never triggered. After the sequence described it works completely. This is not due to the GEL commands, I commented them completely out and the behaviour stays the same. Any suggestions?

Regards,

Raphael

  •  

    The problem was caused by the hardware bootloader, who sets all parts of the DSP on idle during startup and un-idles only the ones he actually uses. In my case, MPORT was still on idle when booting from the EEPROM, which means that the DMA doesn't work. When the emulator connects over JTAG, the setting of the Idle Control Register ICR is ignored - therefore it worked after connecting the board to CCS4   (see TMS320VC5505 DSP System User's Guide, SPRUFP0A, section 5.5).

     

    The solution was un-idling the DMA (MPORT) manually in my reset_isr, which is my standard code entry point as defined in the linker options (function is declared in vectors.asm). See the code below:

     

    reset_isr:
            bit (ST1, #11) = #1                    ; Disable interrupts
            @IVPD_L = #(RST >> 8) || mmap()
            @IVPH_L = #(RST >> 8) || mmap()
            bit(ST3,#7) = #0                    ; Clear bus error interrupts

            @#IFR0_L = #0xFFFF   || mmap()      ; clear all pending interrupts
            @#IFR1_L = #0xFFFF   || mmap()
           

    ; ------------ THIS IS THE RELEVANT SECTION: ---------------------                               
            *port(#0x0001) = #0x000E            ; take all clock domains out of idle (especially MPORT)
            nop_16                                ; flush the pipeline
            nop_16
            nop_16
            nop_16
            nop_16
            nop_16
            idle                                ; execute IDLE instruction to apply changes
    ; ----------------------------------------------------------------------------------

          
            *port(#0x1C04) = 0x2                ; set reset counter (PSRCR)
            nop_16
            *port(#0x1C05) = 0x00FF                ; Reset all peripherals (PRCR)
            nop_16
            goto    _c_int00

     

    I hope this information saves someone else all the hours of work it took me to find that out....

    Regards

    Raphael

  • That's fantastic Raphael:

    I think that might be the issue I'm having.

    Does this isr run by default or did you have to add it?

     

    You mentioned it being in your linker setup.

    Thanks,

    Sam

     

     

  • Hi,

    this ISR doesn't run by default, you have to tell the linker that you want to use it as entry point instead of the default, _c_int00. You can either do that somewhere in the linker options (right-click on your CCS4 project, Preferences, C5500 Linker, Symbol Management: -entry_point, -e = reset_ISR) or write the -e command in your CMD file. I did the latter, please find the .CMD code below  (which is from a CSL example). Make sure that your new reset function, e.g. reset_ISR, is defined in your vectors.asm and jumps to the standard entry point _c_int00 after execution, see the code I posted before.

     

    -stack    0x2000                /* PRIMARY STACK SIZE    */
    -sysstack 0x1000                /* SECONDARY STACK SIZE  */
    -heap     0x2000                /* HEAP AREA SIZE        */ 

    /* Set entry point to Reset vector                                  */
    /* - Allows Reset ISR to force IVPD/IVPH to point to vector table.  */
    -e reset_isr

    MEMORY
    {
      PAGE 0:
        VEC(RWX)      : origin = 0000100h length = 000100h  /* was: origin = 0000100h length = 000100h */
        DATA(RWX)     : origin = 0000200h length = 007E00h     /* was: origin = 0000200h length = 007E00h */
        PROG(RX)      : origin = 0008000h length = 010000h     
    }

    SECTIONS
    {
      vectors (NOLOAD)                    /* not sure if this is necessary)        */   
      .vector    : > VEC ALIGN = 256      /* was: .intvec    : > VEC ALIGN = 256 */
      .text      : > PROG
      .data      : > DATA 
      .cinit     : > PROG
      .switch    : > PROG
      .stack     : > DATA
      .sysstack  : > DATA
      .bss       : > DATA
      .sysmem    : > DATA
      .const     : > PROG
      .cio         : > DATA
     
    }

     

    The IDLE commant could theoretically also be executed from somewhere in your C code, but I don't know the syntax for calling the assembler commands, therefore I chose the reset ISR option.

    Hope this helps,

    Raphael

  • Hi Raphael,

    I made a quick and dirty test of your code example above, only that I put it as the first lines in main(). It did not work. Does it have to be before the call to c_int00? I have not investigated the vector area and reset vector configuration but of course I would probably find it with some research.

    Please advice, I am a little bit tired on the trial-and-error to get the demo code working.

    Best regards,

    Lennart

  • Hi,

    what do you mean with "It didn't work", did it compile but there was no visible effect? How did you call the assembler code from your c-code in main()?

    I suggest you try to execute the lines from exactly the same location (the vectors.asm file), otherwise there might always be other things that go wrong.

    Good luck,

    Raphael

  • Raphael,

    I am very grateful for your post. I struggle for a while, but you solution corrected the issue I was having with the FFT HWA. I did the routine in C like:

          IDLE_ICR = 0x000E;
          asm(" nop_16");
          asm(" nop_16");
          asm(" nop_16");
          asm(" nop_16");
          asm(" nop_16");
          asm(" nop_16");
          asm(" idle");

     

    I guess there's probably a more concise way to to the asm code, but I am very relieved that this issue is finally resolved.

     

  • Thank you all contributors to this post, especially Raphael and Jonathan!!! 

    inserting Jonathan's C code snippet at the starting of my system and PLL register initialization resolved an issue that was holding me up for a few days now. My SD card write program that was using DMA to write to SD card was working while I ran in Debug mode through CCS but not after I loaded the bootimag to a SPI flash. I had overlooked the IdleConfig Register in my initializations and after reading this post saw the 'fine print' on ICR in the C5535 technical reference manual.

    Best

    Milind

    PS: I really wish TI had made their documentation more easy to read and search for information rather than fishing for information through over 500 pages of different documents and forms to resolve any single issue.