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_LOOPJOB_ENABLE transmit fails

Other Parts Discussed in Thread: OMAP-L138

I am using an omap-l138 with dsp/bios 5, pspdriver 01.30.01.

 

I am looking to use the Mcbsp_LOOPJOB_ENABLE compile flag on the Mcbsp driver.  I had it working fine without it enabled, working in a loopback configuration where I would receive audio data from a codec and then return that exact data to the codec.  When I enable loobjob mode, it never transmits anything and the SIO_reclaim calls return with -ETIMEDOUT.  SIO_issue returns 0.  Is there anything I need to do differently in order to enable LOOBJOB mode?

 

My config:

/**< settings to configure the TX or RX hardware sections                 */
Mcbsp_DataConfig mcbspChanConfig =
{
    Mcbsp_Phase_SINGLE,
    Mcbsp_WordLength_16,
    Mcbsp_WordLength_16,     /* Dont care                */
    AUDIO_NUMCHANNELS,
    AUDIO_NUMCHANNELS,        /* Dont care                */
    Mcbsp_FrmSync_DETECT,
    Mcbsp_DataDelay_0_BIT,
    Mcbsp_Compand_OFF_MSB_FIRST,
    Mcbsp_BitReversal_DISABLE,
    Mcbsp_IntMode_ON_SYNCERR,
    Mcbsp_RxJust_RZF,    /* Dont care for TX         */
    Mcbsp_DxEna_OFF
};


/**< clock setup for the RX or the TX section                             */
Mcbsp_ClkSetup mcbspClkConfig =
{
    Mcbsp_FsClkMode_INTERNAL,
    64000,
    Mcbsp_TxRxClkMode_INTERNAL,
    Mcbsp_FsPol_ACTIVE_HIGH,
    Mcbsp_ClkPol_RISING_EDGE,
    50 /* force 50 bit frame for even division */
};

/**< Multi channel setup                                                  */
Mcbsp_McrSetup mcbspMultiChanCtrl =
{
    Mcbsp_McmMode_ALL_CHAN_ENABLED_UNMASKED,
    Mcbsp_PartitionMode_CHAN_0_15,
    Mcbsp_PartitionMode_CHAN_16_31,
    Mcbsp_PartitionMode_2
};

Mcbsp_ChanParams mcbspChanparam =
{
    Mcbsp_WordLength_16,   /* wordlength configured    */
    NULL,                 /* loop job buffer internal */
    0,                    /* user loopjob length      */
    NULL,                 /* global error callback    */
    NULL,                 /* edma Handle              */
    1,                    /* EDMA event queue         */
    8,                    /* hwi number               */
    Mcbsp_BufferFormat_MULTISLOT_NON_INTERLEAVED,
    TRUE,                 /* FIFO mode enabled        */
    &mcbspChanConfig,     /* channel configuration    */
    &mcbspClkConfig,      /* clock configuration      */
    &mcbspMultiChanCtrl,  /* multi channel control    */
    0x00,
    0x00,
    0x00,
    0x00
};

  • Hi Mike,

    Whenever "Mcbsp_LOOPJOB_ENABLE" compiler flag is enabled, then the McBSP sends a known pattern of data when no iopacket is available with the driver and McBSP is not stopped.

    The loop job buffer to be programed for the this pupose can be done in two ways, one way is to provide the loop job buffer and its length in the application itself (refer Mcbsp_ChanParams structure) or allow the driver to use its own buffer with length 4 bytes and its own data.

    So in case of Loop job enabled, Whenever there is an SIO_issue() from the application, request is serviced by (edma) linking buffer to the already available loopjob buffer. Once the service is complete, then the callback will be invoked to inform the SIO layer. The SIO layer in turn returns to the application, when application calls the SIO_reclaim(), since the SIO_reclaim() is blocking call.

    So, in your case, the only reason that i can think of at this moment is, if there is no edma callback, then SIO_reclaim() can time out. This could happen in case of an error interrupt. This can be confirmed by having the call back function in the channel param (refer Mcbsp_ChanParams structure) and putting break point in the application when the call back function resides. Other way is to, have the break point at mcbspGblXmtIsr() [in Mcbsp.c file].

    Also, please verify that the edma call back is invoked or not (in transmit mode, after SIO_issue()) by having the break point at Mcbsp_localEdmaCallback() which is under Mcbsp_LOOPJOB_ENABLE flag.

    let  me know the result.

    Thanks and Regards,

    Sandeep K

  • Mcbsp_localEdmaCallback is continually hit at the beginning but the edmaStatus is EDMA3_RM_E_CC_DMA_EVT_MISS.  This is always on the output channel.  Then I stop getting them for the output channel and get successes on the input channel.

    Breakpoint mcbspGblXmtIsr was never hit.

  • I disabled the other McBSP, which was in slave mode, and that removed the EDMA3_RM_E_CC_DMA_EVT_MISS hits. No hits for the output channel now.

  • OK, it appears to be working if I disable the use of the McBSP FIFO.  Ideas as to why that is?

  • I have also seen a case now where it occasionally fails after a period of time.  By fails, I mean I get a timeout.  This scenario has an I2S bus with the DSP as the master receiving data, and then another I2S bus with the DSP as a slave.  The frame clocks should be roughly identical.  As buffers are received on one bus, they are repeated out the other bus and vice versa.  Neither bus should have stopped the frame/bit clocks, but at some point I get a timeout on transmitting on the I2S where the DSP is slave.  There was never a failure doing the SIO_issue call, just a timeout started happening on the SIO_reclaim.  Ideas?

  • Mike,

    There should not be any missed event whenever loopjob is enabled, since at any point of time, the loopjob buffer will be with the EDMA to transfer (in case of Tx). I do not know why the missed even is being generated with loop job enabled.

    At this moment i do not have the reason for your problem, which is why i am going to suggest some of the experiments, which might lead us to root cause of the problem.

    How many bytes are you receiving and transmitting? Please refer the user guide section 15.3.3.2, which explains the requirement with respect to Mcbsp_BufferFormat_MULTISLOT_NON_INTERLEAVED buffer format.

    If it is possible, try with other buffer format, since other format has different style of EDMA configuration.(refer Mcbsp_edma.c file)

    And also could you please test by providing the loop job buffer and its length from the application itself?

    Let me know the result.

    Thanks and Regads,

    Sandeep K 

     

  • The channel is I2S, with 2 channels of 16-bit words in each direction.  I tried another buffer format, with no change to the symptoms.

  • Testing again with FIFO enabled.  I tried using my own loop buffer, of varying sizes.  The transmit fifo always is empty and I don't even see my loop buffer being output.  The input channel works for the most part, but only for ~10 seconds before it too stops working.  The I2S bus is 2 channel, 16-bit words.  If my loop buffer is 2 bytes, then the input channel does not work.  Larger and it works for a bit.

  • Alright, I'm seeing a couple of problems occurring with the loopjob code here.

    1) cCnt is being set to zero for the loopjob edma because I am using Mcbsp_BufferFormat_MULTISLOT_NON_INTERLEAVED, and frmLen1=2 (aCnt=2, bCnt=2, cCnt=2/(2*2)=0).  So, the calculation of the loopjob size really only works for the other two buffer formats.  I can fix this for my needs, but it should be fixed generally.

    2) The write FIFO is not actually being written immediately.  WLVL is zero, unless I write a word to the FIFO (0x01F11000), which then causes the FIFO to fill up to 0x40.  So, for whatever reason, the edma transfer isn't being kicked off with FIFO enabled.

    I added code to mcbspMdCreateChan right before EDMA3_DRV_enableTransfer that disables and enables the FIFO, similar to what non-loopjob transfers do when the first packet is encountered.  This seems to fix it (at least in the initialization case, haven't tested starting/stopping the channel).

    I'll keep testing, and if everything looks good, mark this post as the solution.

  • Hi Mike,

    Not sure if you'll get this post, but thanks in any case! More than 3 years later it proved to be very helpfu...