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.

DSK6455 problems porting from CCS 3.1 to CCSv5

Other Parts Discussed in Thread: CCSTUDIO, SPRC234, TMS320C6455

RandyP, I ported the dks_app example for the Spectrum Digital C6455 evaluation board into CCS5.5.0 and was (finally) able to get the code to compile, link and run--almost. I can see the visual indication that the code is running from the 500ms blinking LED, but apparently the HWI interrupt handler is never invoked. This is my first exposure to the C6455 and how to debug the EDMA is not obvious. Do you know of some step(s) that are lost when moving from CCS3.1 (original IDE platform) to CCS5.5.0?

I was trying to trace the flow of execution through the source code, but the "thread" disappears in the thicket of macro substitutions and function calls. Examination of EDMA registers is very confusing given the enormous number of registers. I'm guessing that the handler and "chain" of interrupt conditions are not connected, but examination of the function HWI_dispatchPlug (~line 387 of dsk_app.c) goes nowhere. The code compiles, links, and runs, but the navigate tools within CCS5 says the function doesn't exist.

Any ideas?

David Ehrenberg

 

  • David,

    Since you tacked onto the end of a year-old thread about SYS/BIOS, and you were not addressing the original topic, the Moderators moved this to a new thread. You can change the subject line if you do not like what they chose.

    You are using DSP/BIOS which does not include debuggable object module or source, so you cannot step into the HWI_dispatchPlug function. But it does exist. You can type that label into the Disassembly Window to view the code. You can set breakpoints in there from the Disassembly Window also, if you want to confirm that it is being executed.

    Was the dsk_app written for the C6455 or for the C6416? Or updated for the C6455, using EDMA3 instead of EDMA? Because your LED is blinking, that is a good sign, but dsk_app is pretty old. I just wanted to make sure. Look for comments or a Readme that address this, or look for EDMA3 references in the source code.

    For newcomers to a processor, I recommend looking through the online training. You can go to the TI Wiki Pages and search for "c6455 workshop" (no quotes) to find the archived training class. It may not be based on the latest version of CCS but it will be a good start to understand the processor. You can search there for "ccs training" to find the online walk-through of CCSv5 features and capabilities. Later, when you want to move to SYS/BIOS, you can search for "SYS/BIOS workshop" for the latest archives on the TI Wiki Pages.

    For tracing back on interrupt activity, you will start with the Core Registers IFR and IER to see if your interrupt might be pending but disabled vs. enabled but not pending.

    Then you will look at the interrupt selectors that are used to map a peripheral or pin interrupt event to a particular C6455 interrupt. There are a lot of device interrupt signals, but only 12 available direct interrupt paths into the DSP. These have to be setup correctly.

    When you move to the EDMA3 registers, the module in the training class will help you understand how the interrupts are driven through the EDMA3 module. You will look for the IPR, IER, EMR, SER, and other registers, depending on what you are doing.

    After you have looked through the available resources online and within CCS, if you need more help then please offer more detail on "apparently the HWI interrupt handler is never invoked" and "navigate tools within CCS5".

    From the great work you have done so far with porting this code to CCSv5, I am sure you will do well at this.

    Regards,
    RandyP

  • This was also posted here.

  • Hi David,

    Found the same query at two places, so deleted the one existed at http://e2e.ti.com/support/dsp/tms320c6000_high_performance_dsps/f/112/t/305438.aspx.

    Please follow up the answers in this thread.

     

    Regards,

    Shankari

  • It was a miserable slog, but I got the dsk_app working--at least according to the LEDs. I have yet to test the audio channel, but my previous probing with a scope (on the pins of the AIC23) indicates that it's functioning.

    I found two problems with the code fromSpectrum Digital's software package: http://c6000.spectrumdigital.com/dsk6455/v2/

     1) The handle returned by CSL_edma3GetParamHandle() was zero. After digging through the code I realized the handle was simply the address of the 8-word block defining the DMA channel. I commented out that line and substituted a hardwired address. My code snippet below. Because the hParamBAsic1 = 0 the following call to CSL_edma3ParamSetup() would silently fail and the PaRAM block would not be written.

    I saw this failure in the Disassembly window having first filled the memory at 0x02a04000 with memset in main().
     memset((void*) 0x02a04000,0xFF,0x480); // for giggles, clear 24 PaRAM sets

    To prevent future silent failures, I now observe the status on every call with a printf() statement. This patch occurs in six places. The block addresses are 0x02a0[4860][4840][4820][4800][41A0][4180] for the channels numbers 67, 66, 65, 64, 13, and 12 (as used in the dsk_app example).


        /* Set up parameter block 67 as EDMA transmit ping reload */
       // The call to CSL_edma3GetParamHandle is broken, hardwiring address . . .
       // See .../csl_c6455_src/inc/cslr_edma3cc.h for < typedef struct{} >
       // hParamBasic1 = CSL_edma3GetParamHandle(hChannelXmt,67,NULL);       
     hParamBasic1 = (CSL_Edma3ccParamsetRegs*)(void*) 0x02a04860;
     status = CSL_edma3ParamSetup(hParamBasic1,&gParamSetupXmtPing);
     printf("67handle: %x status: %d, ",hParamBasic1,status);

    2) The Secondary Event Register (0x02a01038) was non-zero--preventing interrupt service. I added the lines
        /* Clear secondary event Reg (SER) via Secondary Event Clear Reg (SECR)*/
     *((Uint32*)0x02a01040) = 0xFFFFFFFF;

    to clear these bits in edmaInit() when initializing the board. This code is located just before the call to HWI_enable().

    With these changes, I can move forward. However, it's not clear to me why the call to CSL_edma3GetParamHandle(hChannelXmt,67,NULL) fails, but that is for another day. What should have taken me 20 minutes require three days of reading and experimenting . . .

    Randy, to answer your earlier question, the code I got from Spectrum Digital is new enough that the edma3 package was used in its construction.

    I'm tempted to cut/paste the entire dsk-app.c in this window (for the next poor, dumb, slob), but it's 621 lines and I worry about character count limits.

    I will revisit this thread after I test the audio from line-in to line-out.

    DE

  • David,

    It is obvious you had to do a lot of hard work here. I think there could a version problem between the dsk_app project and the CSL you are using.

    In the version of CSL that I have, 3.00.10.02 from 2006, CSL_edma3GetParamHandle should never return zero (NULL) unless there is an error. More relevant to your tests with dsk_app is the fact that  CSL_edma3GetParamHandle will always return NULL if the status argument is NULL. And status is NULL in the dsk_app example that I have.

    Are you using the same version of CSL that is delivered with the DSK6455, or have you updated it? There should be some library versions mentioned in the README or such for dsk_app. If not, you might want to contact Spectrum Digital to find out which version of CSL they tested the example with.

    I am curious what versions and dates you have on your files. And if you would, please paste the CSL_edma3GetParamHandle in this thread so I can compare it to mine.

    Regards,
    RandyP

  • Randy, in package 03.00.10.02, in file default_package\csl_c6455_src\src\edma\csl_edma3Param.c I found the following. This is from the SPR234 file I downloaded from TI's website (and probably matches want you're seeing).

    I couldn't locate a README file for dsk_app.c, but the comments at the top of the file mentions ccStudio_v3.2 and SPRU966.

    I also saw the if (status == NULL)statement and couldn't make sense of it (why the NULL argument in the call within dsk_app.c) and decide to bypass the entire function. Also, I'm not sure if this code is being compiied and linked in the example, or simply being called from the library. For example, I tried to get control of Hwi_dispatchPlug() by moving it into dsk_app.c, but was unable to clear the dangling references.

    My list of include statements required modification for functions C64_enableIER() and memset(). From my modified dsk_app.c:

    DE

    __---------------------------------------------------------------------------------

    #include "dsk6455.h"
    #include "dsk6455_led.h"
    #include "dsk6455_dip.h"
    #include "dsk6455_aic23.h"

    #include <stdio.h>
    #include <csl.h>
    #include <csl_edma3.h>
    #include <csl_intc.h>
    #include <soc.h>
    #include <hwi.h>

    // added by dge 20131122, to declare C64_enableIER() and memset()
    #include <C64.h>
    #include <string.h>

    // added by dge 20131127, to declare Hwi_dispatchPlug()
    // NO JOY, unable to clear dangling references.
    // #include <hwi_c64.h>
    // #include <fxn.h>

    #define BUFFSIZE 2048

    __-------------------------------------------------------------------------------------

    From the SPRC234 zipfile:

    /*=============================================================================

    */

    #pragma CODE_SECTION (CSL_edma3GetParamHandle, ".text:csl_section:edma3");

    CSL_Edma3ParamHandle

    CSL_edma3GetParamHandle (

      CSL_Edma3ChannelHandle hEdma,

      Int16 paramNum,

      CSL_Status *status

    )

    {

    CSL_Edma3ParamHandle handle = (CSL_Edma3ParamHandle)NULL;

    if (status == NULL) {

    /* Do nothing */

    }

    else if (hEdma == NULL) {

      *status = CSL_ESYS_BADHANDLE;

    }

    else if (paramNum < 0 || paramNum > 255) {

      *status = CSL_ESYS_INVPARAMS;

    }

    else {

      handle = (&hEdma->regs->PARAMSET[paramNum]);

      *status = CSL_SOK;

    }

    return (handle);

    }

  • Randy, I copied the file dsk_app.c to a safe place and added an FIR filter to the program. The interrupts fail to work. I started removing the changes and eventually got back to my program of 28nov. The interrupts are still not working. I REPLACED the dsk_app.c with the old version, the interrupts are STILL NOT WORKING.

    I tried cycling the power on the Spectrum Digital baord and recompiled/ reloaded the old program--the interrupts are not working.

    Any ideas?

    DE

  • Randy, I've been through the check list on page 175 of SPRU966C and all the register are being set correctly. The interrupt for the receiver ping-pong DMAs are operating successfully. However, the transmit side, set up in an identical fashion, never fires.

    I NEED SOME ANSWERS.

    DE

  • I restarted the board for a colleague this afternoon to solicited some sympathy for the difficulties I’m having—and the board operates as expected with both xmit and rcvr interrupts firing. Last night, only the rcvr interrupt was being asserted.

    I tried stopping and restarting the program (from within CCS5) and the tools works without needing to reload the program. [HOWEVER, if I reset the CPU (Run->Reset->CPU Reset) the program is “damaged” and requires re-loading.]

    I found an applique (stick-on) heatsink of about the same footprint as the TMX320C6455 DSP and stuck it to the top of the chip and have a small fan blowing air across the Spectrum Digital PWB. Hopefully, this will make the difference . . . The heatsink is noticeably warm to the touch.

    DE

     

    DE

  • David,

    Dangling references: No idea what particular references these are from the thread. But there are three different libraries that are being referenced and all will have their own method of separating which functions are grouped together, if any, meaning that including Hwi_dispatchPlug() from the BIOS library might also pull in C64_enableIER() but including CSL_edma3xyz() from the CSL library might not pull in that same library's CSL_edma3abc(). So sometimes you can put in source to replace something in a library and sometimes it might not work as expected. But Hwi_dispatchPlug is from BIOS and not CSL.

    CSL version mismatch: Since the source in CSL 03.00.10.02 clearly shows that CSL_edma3GetParamHandle should not have status==NULL, but your version of dsk_app calls just that way with status==NULL, that version of dsk_app could never have been tested to work correctly. You may want to contact the board vendor for support for that (getting an updated dsk_app).

    EDMA3 interrupts quit working until power cycled: Sometimes, power cycling requires closing CCS, turning off power to the DSK, and then even disconnecting the emulator cable from the board since some emulators can drive power to some EVMs and DSKs. On EDMA3 devices, I have found it difficult to guarantee that EMR and SER get cleared properly without a power cycle; a hard reset should work, but might not, and a CCS CPU Reset or System Reset should work, but might not. Within your code, the absolute safest thing to do is to clear SER in a loop writing to SECR until SER stays cleared and then write to EMCR to clear EMR (duplicate for SERH and EMRH). I think this should be in CSL_edma3Init() but it did not get in there. Instead of the loops, it can be faster to just write all 1's to SECR and SECRH four times and then write to EMCR and EMCRH (4 is probably overkill but it matches the worst possible case that I could figure out in 2006).

    The heatsink should be unnecessary, but it certainly cannot hurt.

    If there is something still unanswered, please repeat it.

    Regards,
    RandyP

  • Two prblems:

    a) I finally got to try the FIR filter, but found the ping-pong arrangement of the EDMA too slow. I'm trying to streamline the data throughput and work directly with the McBSP. However, writing the McBSP's registers is causing me grief. I would like to make the changes to the MCBSP's SPCR register to change the default setting on the XINTM and RINTM fields from 00b to 10b. The simple line:

    // MCBSP1->SPCR, XINTM and RINTM on frame sync, broken--line is ignored
     *((Uint32*)0x1900008) |=0x00200020;

    doesn't work, nor does placing the value in a local variable, ORing the bits and writing back the value to SPCR. However, I can change the value using the register window in CCS5. What am I missing here? From reading the literature, I don't think this is a user/supervisor mode issue. The SPCR is not listed among the protected registers. I even tried modifying the value within my ISR (per the explanation found in SPRU732, see below)--no joy.

    __----------------------------------------------------------

    8.4.2 Entering Supervisor Mode from User Mode

    The operating mode will change from User mode to Supervisor mode in the following cases:

    • While processing any interrupt

    • While processing an exception

    __----------------------------------------------------------

    Why can't I write this register?

    b) After masking off all (I think) unwanted interrupts, leaving only event 42, RINT1 from the McBSP, I still appear to be taking the interrupt from other sources. I looked at the Interrput Exception Status Register (INTXSTAT) and saw timer0 lower count interrupt, event 67, being missed. Event 67 is in a higher "consolidation group", and shouldn't effect the lower group of events 32->63--RINT1 and XINT1 are events 42 and 43. i disabled event 67 anyway, but found CCS5 to stop working. I re-enabled the interrupt.

    Looking at the Event Flag Register 1 (EVTFLAG1), I see only events 42 and 43 being set (as expected) and I mask off event 43 leaving on 42 to trigger the interrupt. However watching this register from within the ISR, I see the ISR being taken with none of the event flags being set. Are other "events" being mapped to CPU interrupt #4 and how can I check this?

    DE

  • Randy, I stripped out the dsk_app.c program to have the CPU respond directly to the interrupt from the McBSP connected to the CODEC. I removed many line in the edmainit() function leaving only what's shown below. I expected (hoped?) the calls to HWI_dispatchPlug(), HWI_eventMap(), and C64_enableIER() would set up the CPU interrupt registers to respond to the RINT1 signal from McBSP1. No joy, the interrupt is never taken. Any idea where I'm going wrong here?

    Are there FUNCTIONING examples of McBSP interrupt driven code to be found in the literature?

    DE

    // *************************************************************
    void edmaInit(){
        /* Disable global interrupts */
        HWI_disable();

     /* Install HWI handler */
     HWI_dispatchPlug(4, (Fxn) &McBSPHwi, 0, NULL);
        HWI_eventMap(4, 42); // Tested necessary--this enables RINT1
     C64_enableIER(0x10); // Tested necessary--CPU interrupt enable, #4 of 4->15

     // use McBSP RINT1 to drive interrupt behavior directly, bypassing EDMA.
     // see table 7-10 TMS320C6455 SPRS276 for entire interrupt map.
     // Events 32 through 63 combine on EVT1.

        // Clear CPU interrupt event 42: RINT1, 43: XINT1 (EVTCLR1)
     *((Uint32*)0x1800044) = 0x00000C00;

        // Enable CPU interrupt event 42 (EVTMASK1)
     *((Uint32*)0x1800084) =~0x00000400;  // zero to unmask

     // one to mask, timer0 lower count int (67)
     // *((Uint32*)0x18000C4) = 0x00000008;
     // HOWEVER, the timer interrupt appears necessary for debugger operation

     printf ("before HWI_enable, ");
     /* Re-enable global interrupts */
        HWI_enable();

     // printf ("end of edmaInit\n");  
    }
    // ******************************************************************

  • David,

    The below wiki article may help you for setting up interrupt
    http://processors.wiki.ti.com/index.php/Setting_up_interrupts_in_DSP_BIOS

  • I've answer one of the questions: McBSP1's SPCR register is located at 0x290_0008 for the the C6455, not at 180_0008 as seen on the C620+ and C670+ devices. I was reading the table 18 in SPRU580G without reading the header. The PDF does not provide register mapping for the C6455 device. That information is located in the TMS320C6455 datasheet, table 7-58.

  • David,

    In an earlier thread, I recommended going to our online training material. You can search the TI Wiki Pages for "c6455 workshop" (no quotes) and find some excellent guidance for going through the development process.

    It also includes the lab code and solutions. Some of the labs use the McBSP with interrupts, so you could get some benefit from there.

    Regards,
    RandyP

  • Randy, I dropped trying to get the interrupts to behave and simply polled the RRDY bit of McBSP1's SPCR register. When a fresh sample is taken, I run th FIR filter.

    The simple calculation say that when sampling at 48kHz and the processor is clocked at 1GHz, I should have 20.8 thousand machine cycles to complete the FIR filter computation.The application is a brute force echo cancellation and I would like to implement a 1500 tap filter. Dividing machine cycles by tap count give 13.9 machine cycles per tap. In 13 machine cycles I want to load multiplicand, load multiplier, multiply, add to accumulator, and test loop count. I can't even come close. I run out of time with a 300 tap filter--a factor of 5 slower than my goal.

    The assembly code for this machine is indecipherable and a colleague--a former TI employee--says don't even try to second guess the C compiler on this. I started with the Spectrum Digital board (with C6455 DSP) because we had one in the lab, but I'm dropping it in favor of using an Analog Devices DSP with a RISC architecture. If I need to be "one with the machine" and hand code the inner loop, I have some hope of understanding it, without making a career of this project.

    DE

  • David,

    Since this thread has been discussing EDMA3 and McBSP interrupts, we have not discussed code optimization. The workshop material I referenced earlier shows how to use the compiler most effectively to optimize code, and it may even use an FIR is its sample lab exercises (it has been a while since I looked at the class in detail).

    There are a lot of things that have not been discussed in the thread that would affect your operation. The simple things that make the code run faster are:

    1. Turn on optimization by using the Release build configuration instead of Debug. This can have a 10x effect on code performance.

    2. Turn on cache. By default, the L1 caches are "on" and the L2 caches are "off", which is adequate but using L2 cache can help. Also by default, all external memory is set to be uncacheable; this is changed by setting the MAR register bits to 1 for the relevant external memory addresses and can be done by CSL or by DSP/BIOS.

    3. For the FIR filter, use the DSPLIB function to get the best performance in the inner loop. No need to code it yourself or worry about using the keywords and pragmas to tell the compiler how to optimize the code.

    4. Use EDMA3 for data movement. This is the most work of all of these steps only because it has to be done by you in your code with insight into the system's operation.

    You definitely do not want to try to write C64x+ assembly code nor second guess the compiler. But reading the assembly code can tell you quickly if the compiler is optimizing well. You can search for the FIR function and see if there are a bunch of NOPs (bad) or an SPLOOP (good).

    Because the C64x+ is highly optimized for doing things like an FIR, you can get the performance down to just a few clock cycles per tap, conceivably less than 1 cycle per tap depending on all of the above numbered methods. The C64x+ has 8 RISC CPUs that operate in parallel. I would put it up against any of the Brand X or Y or Z DSPs, for each generation of DSPs.

    I am sorry for the trouble you have had with this design, and wish you well for the project's success. If there is anything else you would like to pursue on this, please let us know. TI wants to be part of your success.

    Regards,
    RandyP