• Join
  • Sign In with my.TI Login
Texas Instruments
  • Products
  • Applications
  • Tools & Software
  • Support & Community
  • Sample & Buy
  • About TI
Sample & Purchase Cart Sample & Purchase Cart
  • Search
  • Advanced
TI E2E™ Community
  • Support Forums
  • Blogs
  • Groups
  • Videos
  • 简体中文
  • More ...
TI Home » TI E2E Community » Support Forums » Digital Signal Processors (DSP) » C5000 Ultra Low Power DSP » C5000 Ultra Low Power DSP Forum » DMA not working when booting from SPI EEPROM, works when running from debugger
Share
C5000 Ultra Low Power DSP
  • Forum
  • Announcements
Options
  • Subscribe via RSS
Top 6 Wiki Links
  • C5000 Main Wiki
  • C5000 Software
  • C5515 Boot-Image Programmer
  • CSL (including CSL 3.00)
  • C5000 Connected Audio Framework
  • Porting C5000 Teaching ROM to C5535 eZdsp
  • DMA not working when booting from SPI EEPROM, works when running from debugger

    DMA not working when booting from SPI EEPROM, works when running from debugger

    This question is answered
    Richard von Lehe58975
    Posted by Richard von Lehe58975
    on Oct 22 2010 10:46 AM
    Prodigy200 points

    Hi all,

    I'm looking for some advice or any technique I can use to debug this problem:

    We have a 5505 pulling data from codec into RAM across I2S0 using channels 0 and 1.  The testing of this took place primarily when debugging the target with an XDS100 emulator connected to the board (i.e. running from RAM).  When the code is written into EEPROM and the built-in bootloader loads the code, the image runs but DMA does not behave in the same way - we never get our DMA interrupt.  In my reading of the documentation it states that SPI transfers do not (can not) use the DMA controller, so it's not the bootloader somehow leaving the DMA in a bad state.  In any case, we are re-initializing the DMA subsystem with the appropriate CSL_DMA calls (DMA_init).

    Thanks in advance,

    Rich

    Report Abuse
    • Reply
    You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    All Replies
    • Richard von Lehe58975
      Posted by Richard von Lehe58975
      on Oct 25 2010 10:06 AM
      Prodigy200 points

      Some more update if anyone is still thinking about this problem:

       

      ·         It doesn’t appear that the problems we’ve seen have anything to do with the actual copying of the image

      o   I am able to reproduce the problem in the debugger.  The steps to do this are:

      §  Load the program (or if you’d like, use what’s already in eeprom by just connecting to the target)

      §  Reset the CPU (do not use ‘restart’)

      §  Hit F8 or RUN when you see that the CPU reset puts the program counter in the bootloader area (0xFF6ADC)

      §  The code will run, completely executing the DMA initialization routines (I tested with GPIO).  But no DMA interrupts will occur.

      §  Now HALT and RUN and dma interrupts appear as does audio moments later.

      o   The key to this is that the problem occurs when there is no interruption of the CPU between the bootloader and the application image running.    For some reason halting anywhere (be it ‘main’ or anywhere after) and continuing allows DMA to suddenly kick in.

      ·         It doesn’t appear that the problems have to do with registers being set improperly by the bootloader and/or not reset properly by the application.  I did some register dumps when paused right before the dma starts working and after it starts working and noticed nothing in particular – mostly differences in timer counts, the dma destination address (makes sense, since it auto-increments), real-time clock counts, etc.  The key here is that there were no differences in DMA registers or PLL/clock registers.

       

      With all that said, I just noticed that where I break affects whether or not the audio gets detected.  I have no idea if this means anything, but if I break at the entry point of the application image (_c_int00), we never get a “StreamIsOn” to evaluate true, and therefore get no xmit or i2s line activity.  If I break at main (or later) and continue from there, we do.

      Report Abuse
      • Reply
      You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    • Brad Griffis
      Posted by Brad Griffis
      on Oct 25 2010 11:27 AM
      Guru57330 points

      Here are a few thoughts:

       

      • Are you configuring the DMA before configuring the I2S?  A common mistake I see a lot of people make is to configure the I2S first and so the first event ends up getting missed/dropped by the DMA controller and then the I2S never generates another because nothing ever serviced the first!
      • You mention that if you halt and then run it seems to fix things.  Do you have any watch windows or memory windows open when you halt?  Perhaps a memory read from the debugger (e.g. to I2SRX register) is kickstarting the transfers.
      • For viewing registers the memory window has a selection box where you can choose Program, Data, or I/O memory space.  Are you saying that even when you choose I/O memory space it still shows you values from Program space, or did you perhaps miss that box?

      ---------------------------------------------------------------------------------------------------------

      Please click the Verify Answer button on this post if it answers your question.
      --------------------------------------------------------------------------------------------------------- 

      Report Abuse
      • Reply
      You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    • Richard von Lehe58975
      Posted by Richard von Lehe58975
      on Oct 25 2010 11:59 AM
      Prodigy200 points

      I moved the DMA init above the i2s and codec init but still see the same issues.

      I also tried closing the memory window so that a read of the i2srx register when halting wouldn't kick off something unknowingly.  The issue was still there.

       

      I probably wasn't very clear when I was mentioning the memory window.  I was able to get the memory window to display everything just fine.  But I originally had tried to dump register contents using the register view.  Unfortunately, it took a little while to realize that the register view window does not provide accurate results for peripheral registers because it is looking in program memory space instead of i/o space.

       

      Report Abuse
      • Reply
      You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    • Brad Griffis
      Posted by Brad Griffis
      on Oct 25 2010 13:02 PM
      Guru57330 points

      Have you done any further looking into where you need to halt in order for things to work properly?  Have you tried putting a long spin loop in the code (as a substitute for halting)?  For example:

      volatile unsigned long dummy_loop;

      for (dummy_loop=0; dummy_loop<100000000; dummy_loop++);

      Don't forget to make the variable volatile or the compiler might get rid of it!

      Also, to be clear I don't expect the dummy_loop to be a final solution, just a means of trying to narrow down the issue, i.e. is it timing related, etc.

      ---------------------------------------------------------------------------------------------------------

      Please click the Verify Answer button on this post if it answers your question.
      --------------------------------------------------------------------------------------------------------- 

      Report Abuse
      • Reply
      You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    • Richard von Lehe58975
      Posted by Richard von Lehe58975
      on Oct 25 2010 15:01 PM
      Prodigy200 points

      Can I ask a basic question or two? 

      When I use the debugger and reset the CPU, the PC points to bootloader code in ROM.  If ROM executes, it's going to use what's in EEPROM every time, isn't it? How does the debugger determine when you want the bootloader to pull code from it's nonvolatile source and when it should execute what has just been loaded into RAM?

      I feel like I'm missing some information.

      Report Abuse
      • Reply
      You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    • Brad Griffis
      Posted by Brad Griffis
      on Oct 25 2010 15:05 PM
      Guru57330 points

      If you do a reset and execute from the boot ROM it will always do the exact same thing, i.e. run through the list of boot sources trying to find an image.

      if you do not want to execute the boot ROM code you can do a reset followed by a restart which will point the CPU to whatever has been designated the "entry point" to your program, generally _c_int00.

      ---------------------------------------------------------------------------------------------------------

      Please click the Verify Answer button on this post if it answers your question.
      --------------------------------------------------------------------------------------------------------- 

      Report Abuse
      • Reply
      You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    • Richard von Lehe58975
      Posted by Richard von Lehe58975
      on Oct 25 2010 15:53 PM
      Prodigy200 points

      I gave this a try right at the beginning of 'main'.  I noticed the delay on the scope (several seconds in my case), but the end result was the same.  That seems to indicate that it is still something the debugger is altering somehow when the system is halted and continued.

      Report Abuse
      • Reply
      You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    • Richard von Lehe58975
      Posted by Richard von Lehe58975
      on Oct 25 2010 19:07 PM
      Verified Answer
      Verified by Brad Griffis
      Prodigy200 points

      Solution:

       

      Add this to top of 'main':

       

      --------------------------------------------------------------

        *((volatile ioport unsigned *)(0x0001)) = 0x000E;   // Enable periph clocks in idle control register

        asm("\tnop_16");                   // flush the pipeline

        asm("\tnop_16");      

        asm("\tnop_16");      

        asm("\tnop_16");      

        asm("\tnop_16");      

        asm("\tnop_16");      

        asm("\tidle");                     // execute IDLE instr to apply changes

      --------------------------------------------------------------

      Report Abuse
      • Reply
      You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    • Brad Griffis
      Posted by Brad Griffis
      on Oct 25 2010 21:29 PM
      Guru57330 points

      Glad to hear you fixed it!  How did you figure that one out?  Brute force comparison of registers?  Did you ever figure out how connecting with CCS made a difference, i.e. did you miss  a gel file or something?

      In any case, I'm glad to hear you fixed it.  Also, thank you for reporting back your solution.

      Best regards,
      Brad

       

      ---------------------------------------------------------------------------------------------------------

      Please click the Verify Answer button on this post if it answers your question.
      --------------------------------------------------------------------------------------------------------- 

      Report Abuse
      • Reply
      You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    • Richard von Lehe58975
      Posted by Richard von Lehe58975
      on Oct 26 2010 10:03 AM
      Prodigy200 points

      Sorry, the fix was found in the user's guide for the DSP (sprufp0a.pdf) section 5.5, clock management.  It describes how to set the Idle control register.  I had read about the ICR a days or two ago, but didn't realize that the CSL didn't take care of that task when calling the _init routines of the various peripherals.  I don't know how feasible it would be to provide feedback in the return status when calling DMA_init that the DMA isn't getting a clock.  I sort of assumed when I got CSL_SOK back from all of those configuration routines that things were set up properly.

      Report Abuse
      • Reply
      You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    • D E Ungar
      Posted by D E Ungar
      on Oct 27 2010 10:18 AM
      Intellectual580 points

      I'm glad Richard got his application running.  I have been 3/4 successful – part of my application runs automatically upon power-up (via boot-loading from NOR Flash on the C5515 ezDSP); part requires a restart via the emulator, but then does run OK.

       

      Here's my situation:

       

      Source data is input from I2S via continuously running (auto-reload) ping-pong DMA, initiated at startup.  I2S Input DMA interrupts trigger bursts of processing.

       

      Accumulated processing results are output to the UART via sporadically initiated (not auto-reload) DMA, pending the interrupt that occurred when the preceding UART output DMA transfer completed.

       

      This all runs as soon as the board is powered up and the application is loaded from NOR Flash by the boot loader and started.

       

      Input data is also copied to another buffer and sent back to I2S via continuously running (auto-reload) ping-pong DMA.  Each copy operation is initiated by the I2S Input DMA interrupt, pending the interrupt that occurred when the preceding I2S Output DMA transfer completed.  Outward-bound DMA is initiated when both banks of the copy buffer have been filled from input buffer.  (The two initial copy operations do not pend on the I2S Output DMA interrupt.)

       

      I2S Output does not work at power-up.  (There is a brief burst of noise at the output.) After Target->Connect Target, with a GEL file doctored to take no action, followed by Target->Run, it still fails, because it merely resumes execution where it was suspended upon connection.

       

      If symbols have been loaded from the corresponding .out file and Target->Connect is followed by Target->Restart (again, with no GEL activity), returning the PC to the entry point for my application, Target->Run results in fully functional operation.

       

      Similarly, if Target->Connect is followed by Target->Reset->CPU Reset, returning the PC to the boot loader in ROM, Target->Run causes boot loader to reload the application from Flash and start fresh, again with full functionality.

       

      Since my initialization code resets all peripherals, I’m puzzled as to why having run the code once, without success, would somehow set the stage to run it successfully the next time.  Does power-up reset involve a race condition with power supplies that leaves the DMA controller or the peripherals in an odd state?

       

      I have included the ICR + NOP + idle operations Richard cites in my initialization C code, along with clock generator and peripheral initialization, modeled after InitSystem() in USB_Stick_Sample\src\main.c (similar to Peripheral_Reset() and ProgramPLL_100MHz() in usbstk5515.gel).  I have also incorporated a customized version of csl_init\c5515_init.asm *, modified by me to run before _c_int00 in same manner as reset_isr in USB_Stick_Sample\asm\vector.asm.  (This duplicates some of the initialization procedures that occur later in my C code.)

      Any clues?

      Dan

       

      *  See Hyun Kim’s posting in: C5515 CSL - Is the Idle Control (ICR) and Idle Status (ISTR) defined in LOWPOWER CSL

      http://e2e.ti.com/support/dsp/tms320c5000_power-efficient_dsps/f/109/p/59334/212336.aspx#212336

       

      C55X DMA I2S 5515 C5515 C55XX C5515 eZdsp ezDSPc5515 ezDSP5515
      Report Abuse
      • Reply
      You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    • Brad Griffis
      Posted by Brad Griffis
      on Oct 27 2010 11:55 AM
      Guru57330 points

      D E Ungar,

      Here's a strategy to help you track down the dependency:

      1. Put some kind of spin-loop in your code such that at power-on it waits for you to connect and change the (volatile) variable to make it exit the spin loop and move on.
      2. Try putting a breakpoint somewhere "way down the line" in your code. Run to that breakpoint.  Restart and run.  (Should work correctly.)
      3. Now do a power-up again and repeat the procedure, but this time put the breakpoint a lot sooner.  Does it still fail?
      4. You want to keep repeating the procedure until you can pin-point the exact code that is required to execute in order for things to work correctly on the restart.  I assume you must have something configured in the wrong order on power-up.

      Best regards,
      Brad

      ---------------------------------------------------------------------------------------------------------

      Please click the Verify Answer button on this post if it answers your question.
      --------------------------------------------------------------------------------------------------------- 

      Report Abuse
      • Reply
      You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    • D E Ungar
      Posted by D E Ungar
      on Oct 27 2010 12:23 PM
      Intellectual580 points

      An update:

      If I connect to target after power-up, when I hear no I2S audio out, and set breakpoints, I find that I am getting interrupts for I2S inbound and outbound DMA and my code is executing the copy to the outbound I2S buffer.  BUT, when the output is "silent," both the input and copy-buffer data differ from what I see when I hear proper audio via the I2S output.  I have not examined the UART output recently, since the wire I had tacked onto the PCB to pick up its output broke loose, but it appears that my problem is with the initialization of the codec or the I2S port configuration and, in the "silent" case I would surmise that I am also processing "silent" data and outputting its processed version through the UART.

      Since the data coming from the codec via I2S appears to be garabage, does anyone have any ideas why it would clean up upon re-executing my startup code via Target->Restart, Target->Run?

      Dan

       

      Report Abuse
      • Reply
      You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    • D E Ungar
      Posted by D E Ungar
      on Oct 27 2010 12:33 PM
      Intellectual580 points

      Brad,

      Thanks for the spin-loop trick.  I will give it a try in the near future.  In the meantime, my resources have been redirected, much as I'd like to keep poking at this.  (Since I have to re-flash about 100KB via the XDS100 everytime I try this, it's a slow process.)

      Dan

       

      Report Abuse
      • Reply
      You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    • D E Ungar
      Posted by D E Ungar
      on Oct 28 2010 10:59 AM
      Intellectual580 points

      OK, I'm getting clues, but still no joy.

       

      If I power up the 'C5515 ezDSP and allow my application to load from Flash and run, I get only a brief burst of noise out.

      • I then connect to target, load symbols, insert a breakpoint in my main DSP/BIOS task loop, run to it and record the PC.
      • I next put a breakpoint at the end of my aic3204 codec configuration routine, which I lifted wholesale from Spectrum Digital example project usbstk5515_BSL_RevA\usbstk5515_v1\tests\aic3204, force the PC to the start of the routine and run it.
      • Now I restore the PC to its previous value, disable the breakpoints and run.
      • Voila – I get good sound.

       

      I therefore thought that perhaps the hot DSP was configuring the codec (via I2C) during  main()  before it was ready, so I added an arbitrary USBSTK5515_waitusec( 100000 ) from the usbstk5515 BSL (~100 mS wait loop) before doing so, but to no avail.

      I then also re-executed the codec configuration routine in my main DSP/BIOS task, immediately before entering my primary processing loop, but still got no recognizable sound.

       

      Then, I noticed that in the Digital Spectrum sample code the codec is initialized before the I2S peripheral.  I tried a single codec initialization early in the program (during  main() ), followed by I2S configuration some operations later, but still no good. 
      Finally, I added the ~100 mS wait back in before codec initialization; still no good.

      I was still able to get each of these configurations to work by breaking in and re-running codec configuration via the emulator.

       

      Any thoughts?

      Report Abuse
      • Reply
      You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    12
    TI E2E™ Community
    • Support Forums
    • Blogs
    • Videos
    • Groups
    • Site Support & Feedback
    • Settings
    TI E2E™ Community Groups
    • TI University Program
    • Make the Switch
    • Microcontroller Projects
    • Motor Drive & Control
    Other Communities
    • Deyisupport
    • Designsomething.org
    • beagleboard.org
    • TI on Element 14
    • TI on TechXchangeSM
    Other Technical & Support Resources
    • WEBENCH® Design Center
    • Product Information Centers
    • Technical Documents
    • TI Design Network
    • TI Technical Articles
    • TI Training

    All content and materials on this site are provided "as is". TI and its respective suppliers and providers of content make no representations about the suitability of these materials for any purpose and disclaim all warranties and conditions with regard to these materials, including but not limited to all implied warranties and conditions of merchantability, fitness for a particular purpose, title and non-infringement of any third party intellectual property right. TI and its respective suppliers and providers of content make no representations about the suitability of these materials for any purpose and disclaim all warranties and conditions with respect to these materials. No license, either express or implied, by estoppel or otherwise, is granted by TI. Use of the information on this site may require a license from a third party, or a license from TI.

    Content on this site may contain or be subject to specific guidelines or limitations on use. All postings and use of the content on this site are subject to the Terms of Use of the site; third parties using this content agree to abide by any limitations or guidelines and to comply with the Terms of Use of this site. TI, its suppliers and providers of content reserve the right to make corrections, deletions, modifications, enhancements, improvements and other changes to the content and materials, its products, programs and services at any time or to move or discontinue any content, products, programs, or services without notice.

    Follow Us Texas Instruments on Facebook Texas Instruments on Twitter Texas Instruments on LinkedIn Texas Instruments on Google+
    TI Worldwide | Contact Us | my.TI Login | Site Map | Corporate Citizenship | mobile m.ti.com (Mobile Version)

    TI is a global semiconductor design and manufacturing company. Innovate with 100,000+ analog ICs and
    embedded processors, along with software, tools and the industry’s largest sales/support staff.

    © Copyright 1995-2013 Texas Instruments Incorporated. All rights reserved.
    Trademarks | Privacy Policy | Terms of Use