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.

How to enable the Mcbsp LoopjobBuffers

I want to enable the MCBSP loopjob buffers but I don't know how to verify whether they are enabled. The main problem is that I am using mcbsp in SIO_ISSUE_RECLAIM mode with 4 tx and rx buffers. My Input/read buffers seem to work ok but after I issue all 4 tx buffers I am only able to reclaim one or two of the buffers.

I check whether any of the buffers are ready with a call to SIO_ready(McbspOutHandle) before I go ahead to do a reclaim. After the first two or so successful reclaims a call to SIO_reclaim returns -9 and thereafter all calls to SIO_ready return false. I suppose if I am able to get the loopjob buffers configured correctly that it will help. I have also realized that sometimes this seems to happen after I get XEMPTY status in the SPCR.

I am using Mcbsp in slave mode with external clk and frame sync signals. These signals are always present so I should be able to transmit data. I suppose that if the tx loop job is running correctly and I am not transmitting all zeros from my loopjob buffer, I should be able to see the data on the scope but I don't and that is why I can't tell whether my loop job buffers are working correctly. How can I tell that the loopjob buffers are configured and are being used?

To enable loop job I recompiled the mcbsp library with Mcbsp_LOOPJOB_ENABLED defined. I have tried both 1.passing my own buffer/length or 2.leaving the internal loopjob buffer field in the Mcbsp_ChanParams as NULL and the length 0 but both ways didn't help. What is all that I need to do to enable the loopjob buffers?

I am using psp driver 01_30_01.

Any help is appreciated.

  • Hi Cecil,

    A quick suggestion here..

    Please recompile the mcbsp library with Mcbsp_LOOPJOB_ENABLE defined

    In the mcbsp.pjt file you need to add the following option as mentioned below:

    "Compiler" Settings: "Debug"]

    Options=-g -mo -pdr -fr"$(Proj_dir)\Debug" -i"$(Proj_dir)\..\..\..\..\..\..\" -i"%EDMA3LLD_BIOS5_INSTALLDIR%\packages" -d"CHIP_C6748" -d"BIOS_PWRM_ENABLE"  -d"Mcbsp_LOOPJOB_ENABLE" -mv6740

    If you are able to access the mcbsp driver file(mcbsp.c), place breakpoints in the following sections of the driver file,

    #ifdef Mcbsp_LOOPJOB_ENABLE

    #endif

    for example line 535 or line 630 etc,. of Mcbsp.c file. If you hit the breakpoint then the Loopjob is enabled. Otherwise(with Mcbsp_LOOPJOB_ENABLED), you will not be able to apply the breakpoint itself!!.

    Please try this and let us know the results.

     

    Thanks & regards,

    Ragahvendra

  • Hi Raghavendra,

    Thanks for the suggestion. I was able to set a breakpoint in one of the #ifdef Mcbsp_LOOPJOB_ENABLE sections and hit the breakpoint. That means the loopjob is enabled and also I see that whatever buffer I pass in via the Mcbsp_ChanParams gets loaded into DXR which is good. However I don't see that the loopjob is transmitting anything on the oscilloscope. I am expecting to see my loopjob buffer being transmitted on the scope because I run in free emulation mode (Mcbsp_EmuMode_FREE) and always have a clock and frame sync signal from the master.

    The problem I have now is that it seems the read is broken because I issue all my four input buffers when I initialize Mcbsp by calling SIO_issue but when I go to check if any buffer is ready to be reclaimed by calling SIO_ready before I do a reclaim, it always returns false. How can I check whether Mcbsp is sending EDMA events when it receives data? The master sends data in bursts and always has a CLK and FSR running. The DRR register always remains empty and I don't get a RSYNCERR or RFULL condition.

    I have the Mcbsp TX and RX FIFOs enabled too.

    My number of channels is set to 14 but I transmit on channels 1 through 14 and receive on channels 1 and 6. This configuration works for good reception when I don't have loopjob enabled but like I mentioned in my earlier post it fails after a while and never recovers. That is why I want to enable loopjob.

    Can you advise what sizes I should use for my Tx and Rx loopjob buffers?

    I am doing only single phase TX and RX and here are my multi-channel settings.

    Mcbsp_McrSetup Mcbsp0MultiChanCtrl =

    {

    Mcbsp_McmMode_ALL_CHAN_DISABLED_UNMASKED,

    Mcbsp_PartitionMode_CHAN_0_15,

    Mcbsp_PartitionMode_CHAN_0_15,

    Mcbsp_PartitionMode_8

    }

     

    An extra addition;

    I recompiled the mcbsp library without loopjob enabled and now SIO_ready calls return true with or without the use of the FIFOs. So question is what could it be about the loobjob that affects the McbspInHandle? Could it be that the loopjob is the only thing that runs and so we actually never receive anything into our buffers to make reclaim possible?

  • Hi Cecil,

     

    Cecil Schandorf said:
    However I don't see that the loopjob is transmitting anything on the oscilloscope.

    The loop job buffers are maintained in the driver, and are initialized to zero!. Probably this is why you are not able to observe anything on the oscilloscope. If you need to observe data, then you will have to provide the loopjob buffers from the application itself. 

    Cecil Schandorf said:
    I initialize Mcbsp by calling SIO_issue but when I go to check if any buffer is ready to be reclaimed by calling SIO_ready before I do a reclaim, it always returns false. How can I check whether Mcbsp is sending EDMA events when it receives data?

    Only when there are NO requests from the application, the loobjob comes into picture. Otherwise(if there are any requests from the application) the loopjob is not running!!. So, if you are sending requests, the SIO_ready() should return 'true' if not sooner but after some time atleast. When a request is submitted, the EDMA completes the transfer, and the callback(Mcbsp_localEdmaCallback) is called, which in turn would call the application callback(line 1847 of Mcbsp.c file) notifying the stream layer. Now, to know whether Mcbsp is sending EDMA events, you can simply place a breakpoint in Mcbsp_localEdmaCallback(...) function of Mcbsp_edma.c file and check if this breakpoint is hit. If so, then the transfer is complete which also justifies an event being generated.

    Cecil Schandorf said:
    Can you advise what sizes I should use for my Tx and Rx loopjob buffers?

    This depends on your requirement. Basically, depends on the gap between two consecutive requests.

    Can you please brief us your application scenario?. Are you using McBSP in master/ slave configuration or doing a loopback?. NOTE: The PSP userguide specifies that the the sample on the slave side is loaded and executed first, next the sample application on the master side is loaded and executed!.

     

    Thanks & regards,

    Raghavendra

  • Hi Raghavendra,

    I placed a breakpoint in the Mcbsp_localEdmaCallback function and realized that it only gets hit twice the first time when I issue my two tx buffers. After that I fail to get EDMA events and that is probably why calls to SIO_ready return false. Increasing my number of tx buffers to four just means I get to send an extra two packets before I stop receiving edma events.

    I am using Mcbsp in a TDM master/slave configuration not in a loopback. The master supplies the clk and fsr signals. My tx and rx buffers are aligned to 128 bytes with sizes of 256 and 512 respectively. My tx and rx loopjob buffer lengths correspond to these values also. Here is my config. I have 14 channels enabled for tx and 2 channels enabled for rx. Here is my config:

    Mcbsp_DataConfig Mcbsp0TXChanConfig =

    {

    Mcbsp_Phase_SINGLE,

    Mcbsp_WordLength_32,

     

    Mcbsp_WordLength_32, /* Dont care */

    14,

     

    0, /* Dont care */

     

    Mcbsp_FrmSync_IGNORE,

    Mcbsp_DataDelay_1_BIT,

    Mcbsp_Compand_OFF_MSB_FIRST,

    Mcbsp_BitReversal_DISABLE,

    Mcbsp_IntMode_ON_SYNCERR,

     

    Mcbsp_RxJust_RxJUST_LZF, /* Dont care for TX */

    Mcbsp_DxEna_ON

    };

    Mcbsp_DataConfig Mcbsp0RXChanConfig =

    {

    Mcbsp_Phase_SINGLE,

    Mcbsp_WordLength_32,

     

    Mcbsp_WordLength_32, /* Dont care */

    2,

     

    0,//2, /* Dont care */

    Mcbsp_FrmSync_DETECT,

    Mcbsp_DataDelay_1_BIT,

    Mcbsp_Compand_OFF_MSB_FIRST,

    Mcbsp_BitReversal_DISABLE,

    Mcbsp_IntMode_ON_SYNCERR,

     

    Mcbsp_RxJust_RxJUST_LZF, /* Dont care for TX */

    Mcbsp_DxEna_ON

    };

     

    /**< clock setup for the RX or the TX section */

    Mcbsp_ClkSetup Mcbsp0TXClkConfig =

    {

    Mcbsp_FsClkMode_EXTERNAL,

     

    96000, /* 96KHz ????? */

    Mcbsp_TxRxClkMode_EXTERNAL,

    Mcbsp_FsPol_ACTIVE_HIGH,

    Mcbsp_ClkPol_RISING_EDGE

    };

    Mcbsp_ClkSetup Mcbsp0RXClkConfig =

    {

    Mcbsp_FsClkMode_EXTERNAL,

     

    96000, /* 96KHz ????? */

    Mcbsp_TxRxClkMode_EXTERNAL,

    Mcbsp_FsPol_ACTIVE_HIGH,

    Mcbsp_ClkPol_FALLING_EDGE

    };

    ///< Multi channel setup

    Mcbsp_McrSetup Mcbsp0TXMultiChanCtrl =

    {

    Mcbsp_McmMode_ALL_CHAN_DISABLED_UNMASKED,

    Mcbsp_PartitionMode_CHAN_0_15,

     

    Mcbsp_PartitionMode_CHAN_16_31,

    Mcbsp_PartitionMode_8

    };

    Mcbsp_McrSetup Mcbsp0RXMultiChanCtrl =

    {

    Mcbsp_McmMode_ALL_CHAN_DISABLED_UNMASKED,

    Mcbsp_PartitionMode_CHAN_0_15,

     

    Mcbsp_PartitionMode_CHAN_16_31,

    Mcbsp_PartitionMode_8

    };

    Mcbsp_ChanParams Mcbsp0TXChanparam =

    {

     

    Mcbsp_WordLength_32, /* wordlength configured */

     

    &TxLoopJobBuffer, /* loop job buffer internal */

     

    256, /* user loopjob length */

     

    NULL, /* global error callback */

     

    NULL, /* edma Handle */

     

    0, /* EDMA event queue */

     

    8, /* hwi number */

     

    Mcbsp_BufferFormat_MULTISLOT_NON_INTERLEAVED,

     

    TRUE, /* FIFO mode enabled */

     

    &Mcbsp0TXChanConfig, /* channel configuration */

     

    &Mcbsp0TXClkConfig, /* clock configuration */

     

    &Mcbsp0TXMultiChanCtrl, /* multi channel control */

     

    0x00007FFE, //Channel enable mask for X/RCERE0

     

    0x00000000, //Channel enable mask for X/RCERE1 40-47

     

    0x00000000, //Channel enable mask for X/RCERE2

     

    0x00000000 //Channel enable mask for X/RCERE3

    };

    Mcbsp_ChanParams Mcbsp0RXChanparam =

    {

     

    Mcbsp_WordLength_32, /* wordlength configured */

     

    &RxLoopJobBuffer, /* loop job buffer internal */

     

    512, /* user loopjob length */

     

    NULL, /* global error callback */

     

    NULL, /* edma Handle */

     

    0, /* EDMA event queue */

     

    8, /* hwi number */

     

    Mcbsp_BufferFormat_MULTISLOT_NON_INTERLEAVED,

     

    TRUE, /* FIFO mode enabled */

     

    &Mcbsp0RXChanConfig, /* channel configuration */

     

    &Mcbsp0RXClkConfig, /* clock configuration */

     

    &Mcbsp0RXMultiChanCtrl, /* multi channel control */

     

    0x00000021, //Channel enable mask for X/RCERE0

     

    0x00000000, //Channel enable mask for X/RCERE1 40-47

     

    0x00000000, //Channel enable mask for X/RCERE2

     

    0x00000000 //Channel enable mask for X/RCERE3

    };

    Hope this helps you understand my application scenario better.

  • Hi Cecil,

    Sorry for the delayed response. Firstly, have you tried executing the sample application provide by the psp_01_30_01)?. The sample application uses "NUM_BUFS" set to 1u. Change this to 4u and try this with and without loopjob enable. Try for both the cases and let us know the results..

    Coming to the issue, So you are issuing four buffers for read, of that only for first two requests, the Mcbsp_localEdmaCallback(...) is getting hit correct? And, there are two Mcbsp_localEdmaCallback(..) functions, one inside the #ifdef Mcbsp_LOOPJOB_ENABLE and the other in the #else part. Hope you have placed the breakpoint in the #else part of the code!. You can also place a breakpoint at line 1030 EDMA3_DRV_clearErrorBits(..) to check if there are any EDMA errors occuring?. Hitting this breakpoint itself signifies EDMA error. Check this and let us know..

    Looking into the previous posts, you have mentioned that "the The DRR register always remains empty". If so, there will not be any events getting generated. Because, whenever the RBR contents are copied to DRR, the RRDY bit of SPCR is set. RRDY directly drives the McBSP receive event to the EDMA controller!. Can you please check this?..

    Since you are not getting callback for the other two requests, the SIO layer keeps returning false for SIO_ready(). Need to ensure there is data coming in the receiver FIFO and the the submitted requests are completed appropriately.

     

    Thanks & regards,

    Raghavendra

  • Hi Raghavendra,

    I implemented a change I read in another mcbsp post and now it seems to have improved somewhat but I still get a SIO_reclaim error after transmitting two or three packets. The change I made was to disable and re-enable the mcbsp fifos before the EDMA3_DRV_enableTransfer call in  mcbspMdCreateChan. Now calls to SIO_ready return true but after a short while SIO_reclaim returns -9 (SYS_ETIMEOUT). How can SIO_ready return true that a buffer is ready but SIO_reclaim return a timeout error? Could it be that the buffer being ready has nothing to do with whether it timed out or not?

    In what units is the SIO_Attrs timeout member variable? I am assuming it is system ticks and I don't have it set to SYS_FOREVER.

    Now what I want to check is whether I am making the SIO_reclaim call from within a SWI. The BIOS API guide says that calls to SIO_reclaim within a SWI thread return an error if no buffer is ready but that is exactly why I check to ensure that a buffer is ready by calling SIO_ready before I do a reclaim. Any hint as to why this error is being returned?

    Is there anything that can happen between the time when SIO_ready returns true that a buffer is ready and when I do a reclaim to make this error happen?

    Thanks

  • Hi Cecil,

    Cecil Schandorf said:
    Now calls to SIO_ready return true but after a short while SIO_reclaim returns -9 (SYS_ETIMEOUT)

    It returns -9 or 9?. If it returns -9 then it is error code "IOM_ENOTIMPL" returned from the bios layer. So, you are not getting a timeout here.

    And, timeout value is in ticks.

     

    Thansk & regards,

    Raghavendra

  • Well there are only two places in Mcbsp_localSubmitIoct which is in Mcbsp_ioctl.c that IOM_ENOTIMPL is returned and when I put a breakpoint at these points they don't get hit even though I get the -9 error.

    I read in the BIOS5x_API_Guide that the SIO_reclaim function returns -1*SYS_ETIMEOUT (SYS_ETIMEOUT = -9 in sys.h) if the timeout expires before a buffer is available to be returned. Again my question is why does SIO_ready return true that a buffer is ready to be reclaimed but a call to SIO_reclaim return this timeout error? I am making the reclaim call from within a SWI but that is why I check with SIO_ready first.

    Please refer to the previous post for more information. I want to know why the discrepancy between ready and reclaim.

    Thanks.

  • Cecil --

    This seems like same issue as this other post which I just answered.  If you use SIO_reclaim() from an SWI, you need to make sure you are using SIO in callback mode.

    http://e2e.ti.com/support/embedded/f/355/p/116290/422338.aspx#422338

    Are you guys working together on this issue?

    Regards,
    -Karl-

  • Hi Karl,

    Thanks for the suggestions and yes, we're working on the same issue. I haven't had time to implement the suggestions yet but I found a workaround by increasing the number of buffers I issue. This way I can issue for example 10 packets and then come back after a few milliseconds to reclaim and re-issue them. During this time between issue and reclaim the loopjobs run and everything seems to work fine so far.

    I think your suggestion is a more robust solution and so when I have time I will implement that and let you know whether it fixes the problem.

    Thanks

  • Hi Karl,

    So I finally got round to implementing the SIO in callback mode a few weeks ago and it definitely improved things a lot. I hardly have any errors now when I go to reclaim a buffer so I guess I will mark your solution as a fix.

    Thanks