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.

TMX320C6747 Lockups?

Other Parts Discussed in Thread: TMS320C6747, OMAPL138

I have some boards that have the TMX version of the TMS320C6747 DSPs that seem to be intermittently hanging and/or not booting after several months.  The code uses one of the MCASPs and EDMAs for passing audio streams.  Most boards will boot up and run fine for a while (anywhere from several minutes to several days) and some will eventually lockup.  The boards will even lockup under static input conditions (i.e. the board is running and no inputs are changing, no memory is being allocated, no new data is being processed) after a while.  I haven't checked all the boards yet but I noticed when I attach the debugger, when the board hangs, I believe it is within the SYS_EXITFXN function and it appears to be stuck on an endless NOP loop.  Also, in some cases the Heartbeat task is evidently not being called either because the LED is not blinking.  This task should always be running!  I also checked all the error registers associated with MCASP and did not see any errrors being asserted before or after locking up.

I realize the TMX devices are suspect, but I need some way to be certain that the problem is due to the TMX device and not our code.  I have had 3 boards that were failing with TMX devices replaced with TMS devices and at least for now, the problem is not showing up.  My concern is that we intially did not see any issues with the TMX devices, but now after several months we are starting to see failures and so how can I be sure the same will not occur with the TMS devices?

Also, on a couple of the boards that previously worked, but then all of the suddent would not boot, I tracked it down to a point in the code in which the MCASP was being switched from an internally generated clock to an external clock.  Apparently it could not detect the external clock properly and would hang there waiting for it.  If I forced it back to the internal clock, it ran fine.

  •  I was able to capture a case when the Abort function was being called.  It's difficult to tell from the screen capture below, but the Execution Graph Details indicates that an exception occurred.  I am not sure this same exception is happening for all cases, because it is not easy to recreate the failures, but I will try. 

  • Ok,

    I have 3 boards that are all throwing exceptions and appear to be corrupting a memory location.  What is strange is that the corruption is not random.  The corrupted memory location contains the same data as the following memory location.  On 2 of the boards, the same memory location has been corrupted to the same value.  Below is a capture of the Execution Graph log as well as a short memory dump showing the corrupted location.

    DATA

    ADDRESS

    BAD

    GOOD

    MATCH

    0xC00B0E34

    doswitch

    doswitch

    ---

    0xC00B0E34

    0x0001F8FA

    0x0001F8FA

    ---

    0xC00B0E38

    0x278C02F7

    0x3005FAFA

    NO

    0xC00B0E3C

    0x278C02F7

    0x278C02F7

    ---

    0xC00B0E40

    0x278016A2

    0x278016A2

    ---

    0xC00B0E44

    0x4CF704EF

    0x4CF704EF

    ---

    0xC00B0E48

    0x006803E2

    0x006803E2

    ---

    0xC00B0E4C

    0x000028F2

    0x000028F2

    ---

    0xC00B0E50

    0x0D0003A2

    0x0D0003A2

    ---

    0xC00B0E54

    0x0187302A

    0x0187302A

    ---

    0xC00B0E58

    0x01E005EA

    0x01E005EA

    ---

    0xC00B0E5C

    0xE0400004

    0xE0400004

    ---

    0xC00B0E60

    doret1, _HWI_lat3end2

    doret1, _HWI_lat3end2

    ---

    3334214   PRD: tick count = 414133 (0x000651b5)
    3334215   SWI: post  KNL_swi (TSK scheduler) (0x11835aa4)
    3334216   SWI: begin KNL_swi (TSK scheduler) (0x11835aa4)
    3334217   SWI: end   KNL_swi (TSK scheduler) (0x11835aa4) state = done
    3334218   CLK: current time = 414134 (0x000651b6)
    3334219   PRD: tick count = 414134 (0x000651b6)
    3334220   SWI: post  KNL_swi (TSK scheduler) (0x11835aa4)
    3334221   SWI: begin KNL_swi (TSK scheduler) (0x11835aa4)
    3334222   SWI: end   KNL_swi (TSK scheduler) (0x11835aa4) state = done
    3334223   SWI: begin KNL_swi (TSK scheduler) (0x11835aa4)
    3334224   TSK: blocked echoTask (0x1183567c) on <unknown handle> SEM
    3334225   TSK: running TSK_UART (0x1183573c)
    3334226   SWI: end   KNL_swi (TSK scheduler) (0x11835aa4) state = done
    3334227   CLK: current time = 414135 (0x000651b7)
    3334228   PRD: tick count = 414135 (0x000651b7)
    3334229   SWI: post  KNL_swi (TSK scheduler) (0x11835aa4)
    3334230   SWI: begin KNL_swi (TSK scheduler) (0x11835aa4)
    3334231   SWI: end   KNL_swi (TSK scheduler) (0x11835aa4) state = done
    3334232   CLK: current time = 414136 (0x000651b8)
    3334233   PRD: tick count = 414136 (0x000651b8)
    3334234   SWI: post  PRD_swi (0x11835ad0)
    3334235   SWI: post  KNL_swi (TSK scheduler) (0x11835aa4)
    3334236   SWI: begin PRD_swi (0x11835ad0)
    3334237   PRD: end
    3334238   SWI: end   PRD_swi (0x11835ad0) state = done
    3334239   SWI: begin KNL_swi (TSK scheduler) (0x11835aa4)
    3334240   SWI: end   KNL_swi (TSK scheduler) (0x11835aa4) state = done
    3334241   CLK: current time = 414137 (0x000651b9)
    3334242   PRD: tick count = 414137 (0x000651b9)
    3334243   SWI: post  KNL_swi (TSK scheduler) (0x11835aa4)
    3334244   SWI: begin KNL_swi (TSK scheduler) (0x11835aa4)
    3334245   SWI: end   KNL_swi (TSK scheduler) (0x11835aa4) state = done
    3334246   CLK: current time = 414138 (0x000651ba)
    3334247   PRD: tick count = 414138 (0x000651ba)
    3334248   SWI: post  KNL_swi (TSK scheduler) (0x11835aa4)
    3334249   SWI: begin KNL_swi (TSK scheduler) (0x11835aa4)
    3334250   SWI: end   KNL_swi (TSK scheduler) (0x11835aa4) state = done
    3334251   SEM: post <unknown handle> (0xc0043f5c) count = 0
    3334252   SWI: post  KNL_swi (TSK scheduler) (0x11835aa4)
    3334253   SEM: post <unknown handle> (0xc00440a4) count = 0
    3334254   SWI: post  KNL_swi (TSK scheduler) (0x11835aa4)
    3334255   SWI: begin KNL_swi (TSK scheduler) (0x11835aa4)
    3334256   TSK: ready echoTask (0x1183567c)
    3334257   TSK: running echoTask (0x1183567c)
    3334258   SWI: end   KNL_swi (TSK scheduler) (0x11835aa4) state = done
    3334259   CLK: current time = 414139 (0x000651bb)
    3334260   PRD: tick count = 414139 (0x000651bb)
    3334261   SWI: post  KNL_swi (TSK scheduler) (0x11835aa4)
    3334262   SWI: begin KNL_swi (TSK scheduler) (0x11835aa4)
    3334263   SWI: end   KNL_swi (TSK scheduler) (0x11835aa4) state = done
    3334264   CLK: current time = 414140 (0x000651bc)
    3334265   PRD: tick count = 414140 (0x000651bc)
    3334266   SWI: post  PRD_swi (0x11835ad0)
    3334267   SWI: post  KNL_swi (TSK scheduler) (0x11835aa4)
    3334268   SWI: begin PRD_swi (0x11835ad0)
    3334269   PRD: end
    3334270   SWI: end   PRD_swi (0x11835ad0) state = done
    3334271   SWI: begin KNL_swi (TSK scheduler) (0x11835aa4)
    3334272   SWI: end   KNL_swi (TSK scheduler) (0x11835aa4) state = done
    3334273   SWI: begin KNL_swi (TSK scheduler) (0x11835aa4)
    3334274   TSK: blocked echoTask (0x1183567c) on <unknown handle> SEM
    3334275   TSK: running TSK_UART (0x1183573c)
    3334276   SWI: end   KNL_swi (TSK scheduler) (0x11835aa4) state = done
    3334277   CLK: current time = 414141 (0x000651bd)
    3334278   PRD: tick count = 414141 (0x000651bd)
    3334279   SWI: post  KNL_swi (TSK scheduler) (0x11835aa4)
    3334280   SWI: begin KNL_swi (TSK scheduler) (0x11835aa4)
    3334281   SWI: end   KNL_swi (TSK scheduler) (0x11835aa4) state = done
    3334282   CLK: current time = 414142 (0x000651be)
    3334283   PRD: tick count = 414142 (0x000651be)
    3334284   SWI: post  KNL_swi (TSK scheduler) (0x11835aa4)
    3334285   SWI: begin KNL_swi (TSK scheduler) (0x11835aa4)
    3334286   SWI: end   KNL_swi (TSK scheduler) (0x11835aa4) state = done
    3334287   CLK: current time = 414143 (0x000651bf)
    3334288   PRD: tick count = 414143 (0x000651bf)
    3334289   SWI: post  KNL_swi (TSK scheduler) (0x11835aa4)
    3334290   SWI: begin KNL_swi (TSK scheduler) (0x11835aa4)
    3334291   SWI: end   KNL_swi (TSK scheduler) (0x11835aa4) state = done
    3334292   CLK: current time = 414144 (0x000651c0)
    3334293   PRD: tick count = 414144 (0x000651c0)
    3334294   SWI: post  PRD_swi (0x11835ad0)
    3334295   SWI: post  KNL_swi (TSK scheduler) (0x11835aa4)
    3334296   SWI: begin PRD_swi (0x11835ad0)
    3334297   PRD: end
    3334298   SWI: end   PRD_swi (0x11835ad0) state = done
    3334299   SWI: begin KNL_swi (TSK scheduler) (0x11835aa4)
    3334300   SWI: end   KNL_swi (TSK scheduler) (0x11835aa4) state = done
    3334301   SEM: post <unknown handle> (0xc0043f5c) count = 0
    3334302   SWI: post  KNL_swi (TSK scheduler) (0x11835aa4)
    3334303   SEM: post <unknown handle> (0xc00440a4) count = 0
    3334304   SWI: post  KNL_swi (TSK scheduler) (0x11835aa4)
    3334305   SWI: begin KNL_swi (TSK scheduler) (0x11835aa4)
    3334306   TSK: ready echoTask (0x1183567c)
    3334307   TSK: running echoTask (0x1183567c)
    3334308   SWI: end   KNL_swi (TSK scheduler) (0x11835aa4) state = done
    3334309   CLK: current time = 414145 (0x000651c1)
    3334310   PRD: tick count = 414145 (0x000651c1)
    3334311   SWI: post  KNL_swi (TSK scheduler) (0x11835aa4)
    3334312   SWI: begin KNL_swi (TSK scheduler) (0x11835aa4)
    3334313   SWI: end   KNL_swi (TSK scheduler) (0x11835aa4) state = done
    3334314   CLK: current time = 414146 (0x000651c2)
    3334315   PRD: tick count = 414146 (0x000651c2)
    3334316   SWI: post  KNL_swi (TSK scheduler) (0x11835aa4)
    3334317   SWI: begin KNL_swi (TSK scheduler) (0x11835aa4)
    3334318   SWI: end   KNL_swi (TSK scheduler) (0x11835aa4) state = done
    3334319   SWI: begin KNL_swi (TSK scheduler) (0x11835aa4)
    3334320   TSK: blocked echoTask (0x1183567c) on <unknown handle> SEM
    3334321   TSK: running TSK_UART (0x1183573c)
    3334322   SWI: end   KNL_swi (TSK scheduler) (0x11835aa4) state = done
    3334323   CLK: current time = 414147 (0x000651c3)
    3334324   PRD: tick count = 414147 (0x000651c3)
    3334325   SWI: post  KNL_swi (TSK scheduler) (0x11835aa4)
    3334326   SWI: begin KNL_swi (TSK scheduler) (0x11835aa4)
    3334327   SWI: end   KNL_swi (TSK scheduler) (0x11835aa4) state = done
    3334328   CLK: current time = 414148 (0x000651c4)
    3334329   PRD: tick count = 414148 (0x000651c4)
    3334330   SWI: post  PRD_swi (0x11835ad0)
    3334331   SWI: post  KNL_swi (TSK scheduler) (0x11835aa4)
    3334332   SWI: begin PRD_swi (0x11835ad0)
    3334333   PRD: end
    3334334   SWI: end   PRD_swi (0x11835ad0) state = done
    3334335   EXC_exceptionHandler: EFR=0x2
    3334336     NRP=0xc00b0e38
    3334337     mode=supervisor
    3334338   Internal exception: IERR=0x19
    3334339     Instruction fetch exception
    3334340     Opcode exception
    3334341     Resource conflict exception

     

     

  • Eric,

    Your symptoms sound like they would be consistent with an unstable view of the SDRAM contents.  If your code is getting corrupted in memory you would see unpredictable and seemingly random failures.

    Since you are seeing a difference in behavior between TMX and current production devices, I suspect that this could be related to Advisory 1.1.10 where EMIFB AC timings were somewhat misbalanced between signals.  This was fixed in Silicon Revision 2 and beyond.

    If you see failures with current production devices, it's also possible that some of the EMIFB SDTIMn register settings may need to be relaxed.  It is possible to program all of the SDTIMn values except for T_RAS_MAX to their maximum allowable values.

    -Tommy

  •  

    Tommy,

    Thanks for your reply.  We have not yet encountered failures on TMS320C6747BZKB3 devices (they haven't been fielded long), but most of the failures are on TMX320C6747BZKB3 devices which are Silicon Rev 2.  I have been told that there are no known differences between the TMX and TMS versions of the devices I listed above, but that the TMX versions were not thoroughly tested so there could have been some bad parts.

    I think it would be a bit odd to corrupt the exact same address with the exact same data on 2 different boards.  Also, as I mentioned above, the value of the changed data is exactly the same as the next value in memory which is the same value before the change took place.  I will attempt to slow down the SDRAM to see if it helps and let you know.

    best regards,

    Eric

  • Tommy,

    I tried slowing down the SDRAM clock speed and also adjusting the associated SDRAM timing registers, but I am still getting failures.  I also adjusted the memory configuration so that the BIOS code was running out of internal memory.  It still failed, but the Execution Log was a little different (I have pasted it below).  Could you please comment on the log.

    13488317   PRD: end
    13488318   SWI: end   PRD_swi (0x11835ad0) state = done
    13488319   SWI: begin KNL_swi (TSK scheduler) (0x11835aa4)
    13488320   SWI: end   KNL_swi (TSK scheduler) (0x11835aa4) state = done
    13488321   CLK: current time = 1675705 (0x001991b9)
    13488322   PRD: tick count = 1675705 (0x001991b9)
    13488323   SWI: post  KNL_swi (TSK scheduler) (0x11835aa4)
    13488324   SWI: begin KNL_swi (TSK scheduler) (0x11835aa4)
    13488325   SWI: end   KNL_swi (TSK scheduler) (0x11835aa4) state = done
    13488326   EXC_exceptionHandler: EFR=0x2
    13488327     NRP=0x0
    13488328     mode=supervisor
    13488329   Internal exception: IERR=0x1
    13488330     Instruction fetch exception
    13488331   SYS abort called with message 'Run-time exception detected, aborting ...'

  • Eric,

    I did not realize that your TMX devices were with the same revision.  I would agree with the assessment that there is no silicon difference between TMX and TMS devices of the same revision.

    When there is a timing sensitivity with the memory, it is not uncommon for the correct data to land in memory, but appear to be in the wrong location.  A software problem could also make the correct data land in the wrong address.

    Another good experiment to try is to run the SDRAM at a slower overall frequency.  If any of the timing or frequency experiments help the failures, that would point to a hardware/timing sensitivity.  If they do not help, it could be a software issue.

    -Tommy

  • Tommy,

    Does the TMS320C6747 have an ETB to support trace buffering?

  • Eric,

    I don't think that the C6747 has ETB.  Unfortunately I am not up to speed with BIOS so I cannot decipher a lot from the log.  I moved this thread to the BIOS forum so that the experts can look at the log.

    Since the failures continue when the software is moved to internal memory, I'm going to shift focus away from SDRAM.

    -Tommy

  • Thanks Tommy.

     

    BIOS Expert,

    Can you make any guesses as to what the root cause of my problem is based on the log files I listed above.  Also with regards to the partial memory dump I placed in the post on 17 Jan 2011 11:35 AM, it appears to me that the memory addresses were in the DVT event log area based on the map file, but I am a newbie when it comes to this.  It just seems strange to me that if seems to fail consistently at the same address and copy the data immediately below.  I tried using a newer BIOS version as well as the drivers from the latest PSP package, but I got the same results.

    I noticed that the DSP power supplies were noisy so I am now injecting clean power from a lab supply.  The board is still failing, but perhaps not as offten, but that's a little difficult to tell.

    Please offer any theories and/or debug suggestions ASAP.

  • Eric --

    The first asserts (with NRP=0xc00something) look like a bad pointer where someone is writing to code space.  The fact that it is not random might make it eas(ier) to find.   Some devices have emulation support to break on memory write.  I need to check to see if your device has this support.  If so, you can set a watchpoint to halt processor when that address is written to and find who's doing it.

    The 2nd assert (with NRP = 0) looks like you branched to 0.  There's no valid data at that address so the program counter fetched garbage and hence the illegal opcode.

    I would set a breakpoint at the NMI vector.  Look at ISTP (interrupt service table pointer) and put that address in dissassembly window.  Then put breakpoint on hwi1 (hwi0 is reset, hwi1 is NMI).  NMI handles NMI interrupts and exceptions.   When you get to NMI for 2nd failure, you should be able to look at 'B3' which should point back to the function that called the function that branched to 0.   If you look at the code right above B3, you can find what the function was that is doing the branch to 0.   You should also be able to look at the other registers in the register view to see if they provide any clues.

    Regards,
    -Karl-

  • Karl,

    Unfortunately the 2nd assert only happens very rarely.  I can get the first assert to happen very consistently now by heavly loading the DSP.  I didn't think this made a difference previously, but it does and I have gotten 3 boards to all fail with the same address being corrupted with the same data.

    The problem is that I can't seem to get the Watchpoint break to work on either read or write.  I read several documents about doing this and I think I am doing it correctly yet it never halts the DSP.  I did a test case where I set a watchpoint to halt on a read to an address that I know it reads numerous times, but it never halted (I can set a breakpoint there and it halts every time).  I looked at the datasheet for the TMS320C6747 and it does indicate that it has circuitry in the AET module to halt on reads or writes.  I tried this on both CCS3.3 and CCS4.2 even though I didn't think that would make a difference and it didn't.

    I really need to get this working as it would greatly help me debug our issue.  Is there any reason you can think of why it isn't working?  Can someone try to set a watchpoint on a board that has a TMS320C6747 and make sure it works?

  • Hi Eric --

    I verified that the watchpoint feature worked for me on OMAPL138 and OMAPL137.  OMAPL137 should have same DSP-subsystem and 6747.  Unfortunately, I don't have a raw 6747 board to try.

    I am using CCSv4.2.0.10016 and an external Spectrum Digital XDS510 USB emulator.   What emulator are you using?

    See attached screenshots for how to set up the watchpoint, to make sure you are doing the same thing.   On my setup, the target halts some 5-10 cycles after the write to 'myGlobalVar'.   I made simple change to the hello.c sample project to add global variable and write to this.  I see the halt occur at 3 points (1) write of '0' during C initialization, (2) write of 99, and (3) write of 11.


    Thanks,
    -Karl-

     

    7140.watchpoint.zip

  • Hey Karl,

    I was able to get the HW Watchpoint feature to work if I set it up to trigger on a write to a variable, but I haven't been able to get it to trigger on a read or write to code memory which is the issue I am trying to debug.

    Could you do me a favor and try setting a HW Watchpoint on a read of a code address instead of a data address?

    If you can't get that to work, perhaps the AET only allows for triggering on reads or writes to data memory.  If that is the case, is there anyway to trick the DSP into reconfiguring my code space as data space or maybe there is some register that needs to be configured to allow the AET to trigger on both code and data?

  • Karl,

    I can't get the HW Watchpoint to work for Program Addresses as I mentioned above, but I might get something to work using the Advanced Event Triggering features.  I am still working on trying to get it to work and will let you know results.

  • Hi Eric --

    I have to find someone with more knowledge about this emulation feature to comment.  

    In the meantime, here's what I see:

     

    (1)   I am able to set watchpoint on data memory write to any address (program or data) and the emulator is halting soon after (5 or 6 cycles) these data writes.

    (2)  I am able to set watchpoint on data memory read and emulator halts soon after (5 or 6 cycles) after the read.

    (3)  I am _not_ able to get watchpoint to halt on memory read by the program counter/program space. 

    My guess is that watchpoints don't trap on program counter access.

    Since you are not getting halt on the write to that address, I am starting to question our theory that this is a bad pointer write problem.   If CPU is doing that write to your program space, I would expect the watchpoint to catch it!   I wrote to my code space with watchpoint set up appropriately and the watchpoint caught the write.   Does your application have DMA in it?   I wonder if the DMA could somehow be doing this write?   Does the corrupted memory still have same exact value as the adjacent (correct) word in memory?  The fact that those adjacent words match makes the bad pointer/bad DMA write theory less compelling.  I wouldn't expect a bogus write to match that adjacent word in memory.  I'd expect it to be some random value.

    Regards,
    -Karl-

  • Karl,

    I'm not sure I understand your scenarios.  I think we are seeing the same thing, but your item 1) seems like you are saying that you can set a watchpoint to trigger on a write to program data space which I have not been able to do (still trying though).

    I guess if you find some with more knowledge I would like to know if it is possible to setup either the UBM or Advanced Event Trigger to cause the DSP to halt when anything is written into a specific address or range that is suppose to contain code and if so, how exactly is that accomplished step by step.

    With regards to the bad pointer write theory, I agree.  I beleive it is too much of a coincidence that the data corruption is always the same value as the data at the following address on 3 different boards!  I have also seen this corruption occur (at a different address) before any of our code executes (i.e. during the initialization phase, but the MCASP and DMA could still be running from the previous run).  Yes, we have quite of bit of DMA cycles occuring in order to grab the data coming in and going out on the MCASP.  I think there is something happeing due to the EDMA and/or MCASP configuration or possibly the Cache that is casuing this to happen.

     

     

  • Eric --

    For 1, I modified my program to have a pointer that I initialized to point within my code.  I then do a memory write.  It stops when I set watchpoint for write to that address.  I'm guessing that there's a difference between data accesses and program fetches.  The data accesses (read or write) are caught.   Program/code  fetches (read) are not.  I'm going to forward this forum link to the emulation team in hopes that someone can help with the AET and/or UBM.  I am not sure if it exists on your part or how to use it.

    -Karl-

  • Hi Karl,

    Yeah, I am still having a tough time getting it to work.  I had also created at pointer to the code address and then created an unsigned int to dereference the pointer.  In the watch window this seems fine, but when I used either the UBM or Event Triggering it still doesn't seem to work exactly correct (almost as if the variable is going out of scope).  When I try to assign a HW Watchpoint using the UBM, I get the following Error Message:

    "Not all symbols resolve to a valid location."

     

  • Eric,

    Do you know what is located at the corrupt memory location?  Just curious if it's something like software variable space, code instructions, or perhaps a buffer space used for McASP data.

    Would it be possible to remove concurrent activity in the system until a failing board starts to pass?  The hardware breakpoint would give us the best information, but if it's not working maybe we can brute force it.

    -Tommy

  • Tommy,

    Most of the time it appears to corrupt BIOS code and therefore causes an illegal op-code exception.  I really think the problem is how we ported TI's audioSample_io.c example code to our platform.  Our board has 5 codes with two inputs (L and R) and two outputs (L and R) for a total of 5 input serializers and 5 output serializers.  The codec is setup to run at 44.1kHz with the slot size set to 32-bits where the first 16-bits is the L channel and the last 16-bits is the R channel.  It would help me out greatly if someone could tell me how to reconfigure the MCASP to support this.  I have read various issues with regards to the MCASP and properly handling 16-bit samples.  Therefore, what I have tried to do is setup the MCASP for Burst mode operation to capture a single 32-bit slot on each serializer interleving the samples.  Our processing algorithm (RunMixer) expects short samples so I cast the xmt and rcv to pointers to shorts.

    Below, is my code, could someone please confirm that I have the MCASP setup properly for my system.

     

    /* ========================================================================== */
    /*                            INCLUDE FILES                                   */
    /* ========================================================================== */

    #include <stdio.h>
    #include <std.h>
    #include <sio.h>
    #include <iom.h>
    #include <mem.h>
    #include <ti/pspiom/psc/Psc.h>
    #include <ti/pspiom/platforms/evm6747/audio/Audio.h>
    #include <ti/pspiom/platforms/evm6747/Audio_evmInit.h>
    #include <ti/pspiom/platforms/codec/Aic31.h>
    #include <ti/pspiom/mcasp/Mcasp.h>
    #include <ti/sdo/edma3/drv/edma3_drv.h>
    #include "evmc6747_io.h"

    /* ========================================================================== */
    /*                          IMPORTED VARIABLES                                */
    /* ========================================================================== */

    Int edma3init();
    void     TargetConnect();
    extern EDMA3_DRV_Handle hEdma;

    /* ========================================================================== */
    /*                          MACRO DEFINITIONS                                 */
    /* ========================================================================== */


    /* mcasp1 module LPSC number      */
    #define PSC_MCASP1_LPSC  8

    /*
     * Buffers placed in external memory are aligned on a 128 bytes boundary.
     * In addition, the buffer should be of a size multiple of 128 bytes for
     * the cache work optimally on the C6x.
     */
     
     // Sample from codec is 32-bits with upper 16-bits for L channel and lower 16-bits for R channel
     // 5 input and 5 output serializers are used therefore I have defined BUFLEN to be 5*128
     #defineBUFLEN 640

    /** Number of serializers configured for record */
    #define RX_NUM_SERIALIZER       (5u)
    #define TX_NUM_SERIALIZER       (5u)


    #define BUFSIZE                 (BUFLEN * sizeof(Ptr))
    #define NUM_BUFS                4   // Num Bufs to be issued and reclaimed, might want to change to 2


    /* inStream and outStream are SIO handles created in main */
    static SIO_Handle inStream, outStream;

    /*
     * Mcasp device params. To be filled in userMcaspInit function which
     * is called before driver creation
     */
    Mcasp_Params audioMcaspParams;

    /*
     * Aic31 device params. To be filled in userAic31Init function which
     * is called before driver creation
     */
    Aic31_Params audioAic31Params;
    Aic31_Params audioAic31Params_1;

    /*
     * Audio device params. To be filled in userAudioInit function which
     * is called before driver creation
     */

    Audio_Params audioParams;

    /* Function prototype */
    static Void createStreams();
    static Void prime();

    void RunMixer(short * rcv_, short * xmt_);   // from Main.cpp
    void InitMixer();

    void Audio_echo_Task();
    void audioUserAic31Init();
    void audioUserAic31Init_1();
    void audioUserAudioInit();
    void audioUserMcaspInit();

    Ptr buf[NUM_BUFS * 2];


    Mcasp_HwSetupData mcaspRcvSetup = {
            /* .rmask    = */ 0xFFFFFFFF, /* All the data bits are to be used     */
            /* .rfmt     = */ 0x000080F0, /* EAH-CHANGED THIS DUE TO MCASP LIMITATIONS IN SUPPORT OF 16-BIT DATA SAMPLES
                                           * 0 bit delay from framsync
                                           * MSB first
                                           * No extra bit padding
                                           * Padding bit (ignore)
                                           * slot Size is 16
                                           * Reads from DMA port
                                           * Rotate right 16
                                           */
            /* .afsrctl  = */ 0x00000000, /* EAH-USING BURST MODE DUE TO MCASP LIMITATIONS IN SUPPORT OF 16-BIT SAMPLES
                            * Burst mode,
                                           * Frame sync is one bit
                                           * Rising edge is start of frame
                                           * externally generated frame sync
                                           */
            /* .rtdm     = */ 0x00000001, /* slot 1 is active (DSP)               */
            /* .rintctl  = */ 0x00000000,
            /* .rstat    = */ 0x000001FF, /* reset any existing status bits       */
            /* .revtctl  = */ 0x00000000, /* DMA request is enabled or disabled   */
            {
                 /* .aclkrctl  = */ 0x0000002B, /* \div = 12, clk = internal*/
                 /* .ahclkrctl = */ 0x00000000,
                 /* .rclkchk   = */ 0x00000000
            }
    } ;

    Mcasp_HwSetupData mcaspXmtSetup = {
            /* .xmask    = */ 0xFFFFFFFF, /* All the data bits are to be used     */
            /* .xfmt     = */ 0x000080F0, /* EAH-CHANGED THIS DUE TO MCASP LIMITATIONS IN SUPPORT OF 16-BIT DATA SAMPLES
                                           * 0 bit delay from framsync
                                           * MSB first
                                           * No extra bit padding
                                           * Padding bit (ignore)
                                           * slot Size is 32
                                           * Reads from DMA port
                                           * NO rotation
                                           */
            /* .afsxctl  = */ 0x00000000, /* EAH-USING BURST MODE DUE TO MCASP LIMITATIONS IN SUPPORT OF 16-BIT SAMPLES
                                           * Frame sync is one bit
                                           * Rising edge is start of frame
                                           * externally generated frame sync
                                           */
            /* .xtdm     = */ 0x00000001, /* slot 1 is active (DSP)               */
            /* .xintctl  = */ 0x00000000, /* sync error,overrun error,clK error   */
            /* .xstat    = */ 0x000001FF, /* reset any existing status bits       */
            /* .xevtctl  = */ 0x00000000, /* DMA request is enabled or disabled   */
            {
                 /* .aclkxctl  = */ 0x0000002B,  /* \div = 12, clk = internal*/
                 /* .ahclkxctl = */ 0x00000000,
                 /* .xclkchk   = */ 0x00000000
            },
    };

    // Mcasp channel parameters  for Tx serializers
    Mcasp_ChanParams  mcasp_chanparam0=
    {
            0x0005,                    // number of serialisers
            {Mcasp_SerializerNum_5, Mcasp_SerializerNum_6, Mcasp_SerializerNum_7, Mcasp_SerializerNum_8, Mcasp_SerializerNum_9, }, /* serialiser index           */
            (Mcasp_HwSetupData *)&mcaspXmtSetup,
            TRUE,
            Mcasp_OpMode_TDM,          // Mode (TDM/DIT)
            Mcasp_WordLength_32,
            NULL,
            0,
            NULL,
            NULL,
            1,                        // number of TDM channels
            Mcasp_BufferFormat_MULTISER_1SLOT_SER_INTERLEAVED,
            TRUE,
            TRUE
    };

    // Mcasp channel parameters  for Rx serializers
    Mcasp_ChanParams  mcasp_chanparam1=
    {
        0x0005,                      // number of serialisers     
        {Mcasp_SerializerNum_0, Mcasp_SerializerNum_1, Mcasp_SerializerNum_2, Mcasp_SerializerNum_3, Mcasp_SerializerNum_4, },      // serialiser index
        (Mcasp_HwSetupData *)&mcaspRcvSetup,             // word width             
        TRUE,                       // pointer to output buffer
        Mcasp_OpMode_TDM,             // output buf size        
        Mcasp_WordLength_32,
        NULL,
        0,
        NULL,
        NULL,
        1,
        Mcasp_BufferFormat_MULTISER_1SLOT_SER_INTERLEAVED,
        TRUE,
        TRUE
    };

    Audio_ChannelConfig audioChanParamsIN =
    {
       /*  channel 0 (RX)                                            */
        (Ptr)&mcasp_chanparam0,
        {   /* codec [0]                                              */
            {
                44100,  /* sampling rate for codec */
                // FIXME PORT 48000,  /* sampling rate for codec */
                   // FIXME PORT 30,  /* gain (%) for codec      */
                 101,  /* 101 to disablegain (%) for codec      */
                 0x00,  // bitclock
                 // FIXME PORT 0x00   // num slots
                 0x01   // num slots
            }
        }
    };

    Audio_ChannelConfig audioChanParamsOUT =
    {
        /*  channel 1 (TX)                                            */
        (Ptr)&mcasp_chanparam1,
        {
            /* codec [0]                           */
            {
                44100,  /* sampling rate           */
                // FIXME PORT 48000,  /* sampling rate           */
                   // FIXME PORT 70,  /* gain (%) for codec      */
                 101,  /* 101 to disable gain (%) for codec      */
                 0x00,  // bitclock
                 // FIXME PORT 0x00   // num slots
                 0x01   // num slots
            }
        }
    };


    /*
     * Aic31 init function called when creating the driver.
     */
    void audioUserAic31Init()
    {
        Aic31_init();
        audioAic31Params = Aic31_PARAMS;
        audioAic31Params.acCtrlBusName = "/i2c0";
        audioAic31Params.acSlotWidth = ICodec_SlotWidth_16;
        audioAic31Params.acOpMode = ICodec_OpMode_SLAVE;
        // audioAic31Params.acSerialDataType = ICodec_DataType_I2S;
        printf("done with audioUserAic31Init\n");
    }

    void audioUserAic31Init_1()
    {
        Aic31_init();
        audioAic31Params_1 = Aic31_PARAMS;
        audioAic31Params_1.acCtrlBusName = "/i2c1";
        audioAic31Params_1.acSlotWidth = ICodec_SlotWidth_16;
        audioAic31Params.acOpMode = ICodec_OpMode_SLAVE;
        // audioAic31Params.acSerialDataType = ICodec_DataType_I2S;
    }


    /*
     * Mcasp init function called when creating the driver.
     */
    void audioUserMcaspInit()
    {
        // be sure this function is called 1st
        TargetConnect();
        EVMC6747_IO_init();

        /* power on the Mcasp 1 instance in the PSC  */
        Psc_ModuleClkCtrl(Psc_DevId_1, PSC_MCASP1_LPSC, TRUE);

        Mcasp_init();
        audioMcaspParams = Mcasp_PARAMS;
        audioMcaspParams.hwiNumber = 8;
        printf("done with audioUserMcaspInit\n");
    }

    /*
     * Audio init function called when creating the driver.
     */
    void audioUserAudioInit()
    {
        Audio_init();
        audioParams = Audio_PARAMS;
        audioParams.adDevType = Audio_DeviceType_McASP;
        audioParams.adDevName = "/mcasp1";
        audioParams.acNumCodecs = 1;
        audioParams.acDevName[0] = "/aic310";
        printf("done with audioUserAudioInit\n");
    }

    /*
     * ======== createStreams ========
     */
    static Void createStreams()
    {
        SIO_Attrs sioAttrs;

        sioAttrs       = SIO_ATTRS;
        sioAttrs.nbufs = NUM_BUFS;
        sioAttrs.align = BUFALIGN;
        sioAttrs.model = SIO_ISSUERECLAIM;

        mcasp_chanparam0.edmaHandle = hEdma;
        mcasp_chanparam1.edmaHandle = hEdma;

        /* open the I/O streams */
        outStream = SIO_create("/dioAudioOUT", SIO_OUTPUT, BUFSIZE, &sioAttrs);

        if (outStream == NULL)
        {
            printf("Create output stream FAILED.");
            return;
        }
       
        inStream = SIO_create("/dioAudioIN", SIO_INPUT, BUFSIZE, &sioAttrs);

        if (inStream == NULL)
        {
            printf("Create input stream FAILED.");
            return;
        }   
    }

    /*
     * ======== prime ========
     */
    static Void prime()
    {
        Int32        count = 0;

        // Allocate buffers for the SIO buffer exchanges
        for(count = 0; count < (NUM_BUFS ); count ++)
        {
            buf[count] = (Ptr)MEM_calloc(0, BUFSIZE * RX_NUM_SERIALIZER, BUFALIGN);
            if(NULL == buf[count])
            {
                printf("MEM_calloc failed.");
            }
        }

        // Allocate buffers for the SIO buffer exchanges
        for(count = NUM_BUFS; count < (NUM_BUFS * 2); count ++)
        {
            buf[count] = (Ptr)MEM_calloc(0, BUFSIZE * TX_NUM_SERIALIZER, BUFALIGN);
            if(NULL == buf[count])
            {
                printf("MEM_calloc failed.");
            }
        }

        for(count = 0; count < NUM_BUFS; count ++)
        {
            /* Issue the first & second empty buffers to the input stream */
            SIO_issue(inStream, buf[count], BUFSIZE * RX_NUM_SERIALIZER,NULL);
        }

        for(count = NUM_BUFS; count < (NUM_BUFS * 2); count ++)
        {
            SIO_issue(outStream, buf[count], BUFSIZE * TX_NUM_SERIALIZER,NULL);
        }
    }

    /*
     * Initializes the input/output streams.  Called from main prior to tasks running
     */
    Void initStreams()
    {
        /* initialise the edma library                                            */
        edma3init();

        /* Call createStream function to create I/O streams                       */
        createStreams();

        /* Call prime function to do priming                                      */
        prime();
    }

    /*
     * ======== echo ========
     * This function copies from the input SIO to the output SIO. You could
     * easily replace the copy function with a signal processing algorithm.
     */
    Void Audio_echo_Task()
    {
        Int nmadus = 0;         // number of minimal addressable units
        Ptr rcv,xmt;

        initStreams();

        InitMixer();

        while (1)
        {
            nmadus = SIO_reclaim(inStream, (Ptr *)&rcv, NULL);

            // Reclaim full buffer from the input stream
            if (nmadus < 0)
            {
                printf("Error reclaiming full buffer from the input stream");
            }

            // Reclaim empty buffer from the output stream to be reused
            nmadus = SIO_reclaim(outStream, (Ptr *)&xmt, NULL);
            if (nmadus < 0)
            {
                printf("Error reclaiming empty buffer from the output stream");
            }

            // nmadus value updated from SIO_reclaim is always positive
            //memcpy(xmt,rcv,nmadus);
            RunMixer((short *)&rcv, (short *)&xmt);

            // Issue full buffer to the output stream
            if (SIO_issue(outStream, xmt, BUFSIZE * TX_NUM_SERIALIZER, NULL) != SYS_OK)
            {
                printf("Failed to issue empty buffer to stream\n");
            }

            /* Issue an empty buffer to the input stream */
            if (SIO_issue(inStream, rcv, BUFSIZE * RX_NUM_SERIALIZER, NULL) != SYS_OK)
            {
                printf("Failed to issue empty buffer to stream\n");
            }
        }
    }

  • Eric,

    Have you tried to run the same code on the EVM OMAP L-137 (It should work without any changes).  If it works there but not on your target hardware I would suspect your target hardware.  Look again at your power supplies.  Also write a program to test external memory. 

    Hope this helps,

    Fawad

  • Fawad,

    Thanks for the reply.  I have loaded it on to the EVM and it appears to be running as far as I can tell, but its a bit different because the EVM doesn't have all the codecs I need.  I guess I could try wiring them up, but as a said before, it seems to work on boards with the TMS version of the part already (at least it is much more difficult to get one of them to fail).

    I did modify the SDRAM test that comes with the PSP.  I modified it to add additional testing to write all 1's followed by all 0's as well as a unique value to every address.  It did not detect any failures when I ran it.  But it still could be a power integrity issue and only shows up when the DSP is heavly loaded.

     I am starting to think it may be something on the hardware side.  I got my code above working and commented out all our data processing so that the MCASP was just brining in data and sending it back out and eventually it would stop.  I verified that the input and output buffers were writing to the correct address range.  I had some flaky boards like this in the past and it turned out that the PCB mfg had widened the antipads under the uP (it was in a BGA  package) which removed the Gnd plane under the part.

  • Can someone point me to the document that defines the bits within the PINMUX registers for the TMS320C6747 (NOT THE OMAP BECAUSE SOME ARE DIFFERENT).  I've been looking and I can't find this document!

  • Look at the TMS320C6747 System Reference Guide (SPRUFK4) found in the Users Guides portion of the TMS320C6747 Product Folder.

  • There's also a pin multiplex tool: http://www.ti.com/lit/zip/sprab06a (and associated doc: http://www.ti.com/lit/pdf/sprab06a)