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.

McBSP multichannel transmit problem with bios_6_33_02_31 and biospsp_03_00_01_00



My environment is a custom board with C6746, bios_6_33_02_31, edma3_lld_02_11_04_01 and CCS 5.1. I have an 8kHz framesync rate and 16.384MHz clock rate.  I would like to create a loopback application for all 256 timeslots, but I have a problem with multichannel transmit.

I have based my code for transmitting a fixed pattern on the McBSP example enclosed with the BIOSPSP, modified to use external clock and framesync. Single channel 8 bit transmit works fine. Single channel 32-bit transmit also works fine. However, when I change the single-channel 32-bit to interleaved multi-channel 8-bit with 4 channels, I seem to get frequent underruns - at least I think that is what I get, I occasionally see a different pattern in the timeslots when connected to an oscilloscope. The larger buffer I use, the more rarely the underrun appears, but they are still there with 1024 samples per channel. I tried to set NUM_BUFS to 2 instead of 1, but then it seems that the EDMA does not run at all, the pattern is completely static. I removed the Task_sleep(100) between GIO_reclaim and GIO_issue in mcbspStartDemo, this was necessary to make the single-channel version run correctly. Also, I have trouble understanding why Mcbsp_IntMode_ON_SYNCERR is used, but using Mcbsp_IntMode_ON_FSYNC instead makes no difference.

Any advice in debugging this problem would be appreciated, the PSP and EDMA LLD are not easy to look into to find out what is happening.

  • It seems to be working now. I needed to use two buffers to make it work, and I needed to wait some time between (or before/after?) each GIO_issue when priming the TX channel. I would still like to know:

    1) Why is this wait necessary? And what is the minimum time I need to wait?  I am running my C6746 at 456MHz, could this have something to with it?

    2) Why does the example use only one buffer, and why does it use Mcbsp_IntMode_ON_SYNCERR? Both seem misleading to me.

  • Hi,

    First of all, which version of the PSP are you using?

    Are you using the EVM or the custom board?

    Ove Rikvold said:

    1) Why is this wait necessary? And what is the minimum time I need to wait?  I am running my C6746 at 456MHz, could this have something to with it?

    The delay at the master end has been introduced to have the sync between slave and the master. Because of this, master will send a packet and wait for sometime, by the time receiver would have received packet and verified it (this will take sometime to complete) and wait for the next packet. In your case, it looks like you are only using the master(Tx) and verifying the data at master (Tx) out. So, in this setup, no need to have the delay.

    If you are communicating between two EVMs, one of them as slave and other one as master, then it has to be '1' buffer and the wait delay is necessary. 

    You will bound to get the discontinuous data, if you introduce the wait in between reclaim and the issue OR if you are using the single buffer. Since once after completing the transaction, the mcbsp will shut the FSYNC off and reenabled during the next issue. 

    If you are only interested in the Tx, then prime 'n' number of packets to the mcbsp, inside the loop you can recalim the buffer and re-issue it.

     

    Ove Rikvold said:

    2) Why does the example use only one buffer, and why does it use Mcbsp_IntMode_ON_SYNCERR? Both seem misleading to me.

    As explained earlier, it is the limitation of the setup on which we are executing the sample app and not the limitation of the driver or the application. If you want to use the multiple buffers, you can modify the master (Tx) app and it will complete its execution.

    By using "Mcbsp_IntMode_ON_SYNCERR", we are configuring the McBSP to generate the interrupt only for error condition. For data transfer, we are depending on the EDMA completion interrupt (which will be serviced inside the EDMA callback function in the driver) 

    Thanks and Regards,

    Sandeep K

  • Thank you for the clarification. I am using biospsp_03_00_01_00. I am using my custom board.

    My only remaining question is this:

    In order to make my TX application with two buffers work properly, I added 1 second Task_sleep during initialisation between each GIO_issue call in mcbspDriverPrime. Without any wait the EDMA did not seem to start, the pattern on the TX pin was completely static.

    Why is this wait necessary? And what is the minimum time to wait?

    Regards,

    Ove

  • I think Task_sleep() was for 1 milli sec not 1 sec. Am i right?

    In order to make only Tx application to work, you do not need to have any delay in the application. The only requirement is the buffer duration, it has to be around 1msec.

    Example:

    For Sample frequency of 48KHz, 1 slot, 8bit slot size. The buffer size should be of 48 bytes to have 1 msec buffer duration. This may not be true if the buffer size is less than the FIFO size, because the EDMA will indicate the transfer completion before actually data transmitted out of the McBSP FIFO. So it is better to have the data size greater than the FIFO size and of duration more than 1 msec. 

    1 msec is sufficient time for the application to issue the next buffer.

    BTW, I guess you are using the external clock for Tx. From where are you deriving it, is it from the codec? Have you verified the frame sync signal, is it as per the expectaion?

    Thanks and Regards,

    Sandeep K

  • You are right, and I used Task_sleep(1000) to wait for 1 sec and be on the safe side.

    Thank you for the clarification. I now have a loopback application working with 256 8-bit timeslots (configured as 64 32-bit timeslots) in 1ms buffers. I have tested it successfully with a PRBS loopback sequence, so I am happy. I prime both RX and TX with two buffers each, as shown in your mcbsp_dlb sample.

    Clock and framesync are indeed supplied externally on my card.

    Is there a way to issue buffers to the driver (RX and TX) without actually starting the transfer, and then start the transfer at a defined point in time? For my old SW design with C6713/BIOS4/CCSv3 I would set up McBSP and EDMA registers using CSL, then issue CSL calls (EDMA_enableChannel/MCBSP_enableRcv/MCBSP_enableXmt) to 'start the show'.

    Regards,

    Ove

  • Ove Rikvold said:

    You are right, and I used Task_sleep(1000) to wait for 1 sec and be on the safe side.

    Thank you for the clarification. I now have a loopback application working with 256 8-bit timeslots (configured as 64 32-bit timeslots) in 1ms buffers. I have tested it successfully with a PRBS loopback sequence, so I am happy. I prime both RX and TX with two buffers each, as shown in your mcbsp_dlb sample.

    Nice to hear that the code is working.. :)

    Ove Rikvold said:

    Is there a way to issue buffers to the driver (RX and TX) without actually starting the transfer, and then start the transfer at a defined point in time? For my old SW design with C6713/BIOS4/CCSv3 I would set up McBSP and EDMA registers using CSL, then issue CSL calls (EDMA_enableChannel/MCBSP_enableRcv/MCBSP_enableXmt) to 'start the show'.

    No, actually this facility is not there. Whenever you issue the first buffer immediately the transfer will start. But later if you want you can stop (Mcbsp_IOCTL_STOP) the transfer and then you can restart (Mcbsp_IOCTL_START) the transfer as and when required.

    Thanks and Regards,

    Sandeep K