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.

Problem with issue/reclaim on McBSP driver C6748

I am using the McBSP receiver as a master on the C6748.  I have started by using the example code that came with the driver.  The problem with the example is that it only issues one buffer, and then cannot keep up with streaming data.  If I change the number of buffers to 2, it doesn't run.  It should keep looping, but it hangs after going through the loop once.  This will run to completion if NUM_BUFS is set to 1.

The channel configuration parameters are like the example, except that the clocks and frame sync are generated internally.

Here's the code

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

#define NUM_BUFS              2
#define BUFALIGN              128           /* align buffers to 128 bytes     */
#define BUFSIZE               1024          /* 1K of data transceive          */
#define LOOP_COUNT            100

#define DEFAULT_BITPERSAMPLE  8             /* number of bits per slot        */
#define NUM_OF_CHANNELS       1             /* Number of slots to be used     */

/* ========================================================================== */
/*                          LOCAL VARIABLES                                   */
/* ========================================================================== */

/* Handles for the TX and RX channels                     */
static SIO_Handle mcbspInHandle  = NULL;

/* array to hold the pointer to the allocated buffers     */
Ptr bufIn[NUM_BUFS];

Uint32 pktCountIn = 0;

Void mcbspInputTask(Void)
{
    Ptr                rcv       = NULL;
    Uint32             count     = 0;
    Int32              nmadus1   = 0;
    Uint32             i         = 0;
    Bool               fail      = FALSE;
   
   
        // Init EDMA
    /* initialize the edma library                                            */
    if (IOM_COMPLETED != edma3init())
    {
        printf( "EDMA intialization failed");
       
        return;
    }
    else
    {
        printf( "EDMA intialized");

        /* update the edma handle to the channel parameters                   */
        mcbspChanparamIn.edmaHandle = hEdma[0];
    }   
   
   

    /* create the streams required for the transactions                       */
    mcbspCreateStreamsIn();

    /* prime the driver with packets                                          */
    mcbspDriverPrimeIn();


    /* reclaim each packet and resubmit for "LOOP_COUNT" number of iteration  */
    for (count = 0; count < LOOP_COUNT; count++)
    {
        /* Reclaim FULL buffer from the input stream to be reused             */
        nmadus1 = SIO_reclaim(mcbspInHandle,(Ptr *)&rcv,NULL);

        if (nmadus1 < 0)
        {
            printf("Error reclaiming empty buffer from the streams");
        }
        else
        {

            // Commented out this code so it would keep looping
            /* compare the received data                                      */
            //for (i = 0; i < BUFSIZE; i++)
            {
                //if (((Uint8 *)rcv)[i] != (i % 0x100))
                {
                    //printf("Iteration %d",count);
                    //printf("Data compare failed %x %x",
                    //    (i % 0x100),((Uint8 *)rcv)[i]);
                    //fail = TRUE;
                    //break;
                }
            }

//            if (TRUE == fail)
//            {
//                break;
//            }

            /* issue the received data to the output stream                   */
            if (IOM_COMPLETED != SIO_issue(mcbspInHandle, rcv, BUFSIZE, NULL))
            {
                printf("Error issuing buffer to the stream");
            }
            pktCountIn++;
        }
    }

    if (FALSE == fail)
    {
        printf("\r\nSample Application completed sucessfully...");
    }
    else
    {
        printf("\r\nSample Application failed...");
    }
   
 
}

/*
 * \brief   Function to submit the requests to the driver
 *
 * \param   None
 *
 * \return  None
 */
static Void mcbspDriverPrimeIn(Void)
{
    Uint32 count = 0;

    for (count = 0; count < NUM_BUFS; count++)
    {
        if (IOM_COMPLETED
            != SIO_issue(mcbspInHandle, (Ptr)(bufIn[count]), BUFSIZE, NULL))
        {
            SYS_abort("Issue to output stream failed\n");
        }
    }

    printf("Request submitted to Mcbsp Input driver.");
}


/*
 * \brief    Function to create the required streams for the reception of
 *           Mcbsp data.
 *
 * \params   None
 *
 * \return   None
 */
static Void mcbspCreateStreamsIn(Void)
{
    SIO_Attrs      sioAttrs  = SIO_ATTRS;
    Uint32         count     = 0;

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

    /* create the channel for the RX operation                                */
    mcbspInHandle = SIO_create("/dioMcbspIN", SIO_INPUT, BUFSIZE, &sioAttrs);

    if (NULL == mcbspInHandle)
    {
        printf("RX Stream creation Failed\n");
        SYS_abort("Stream Creation Failed\n");
    }

    /* create the buffers required for the RX operation                       */
    for (count = 0; count < (NUM_BUFS); count++)
    {
        bufIn[count] = (Ptr)MEM_calloc(0, BUFSIZE, BUFALIGN);

        if (NULL == bufIn[count])
        {
            printf("Memory allocaton failed\n");
            SYS_abort("MEM_calloc failed.\n");
        }
    }
}
:

 

 

  • Mary,

    I think you are using the BIOS PSP examples, could you please mention the BIOS PSP version which you are using?

    Thanks and Regards,

    Sandeep K

  • Hi Mary,

     

    Firstly, sorry for the late reply since I was setting up the setup to reproduce this issue. I did the following changes in my test application (mcbspSampleSlave_io.c)

     

    Mary Frantz said:

    /* reclaim each packet and resubmit for "LOOP_COUNT" number of iteration  */
        for (count = 0; count < LOOP_COUNT; count++)
        {
            /* Reclaim FULL buffer from the input stream to be reused             */
            nmadus1 = SIO_reclaim(mcbspInHandle,(Ptr *)&rcv,NULL);

            if (nmadus1 < 0)
            {
                printf("Error reclaiming empty buffer from the streams");
            }
            else
            {

                // Commented out this code so it would keep looping
                /* compare the received data                                      */
                //for (i = 0; i < BUFSIZE; i++)
                {
                    //if (((Uint8 *)rcv)[i] != (i % 0x100))
                    {
                        //printf("Iteration %d",count);
                        //printf("Data compare failed %x %x",
                        //    (i % 0x100),((Uint8 *)rcv)[i]);
                        //fail = TRUE;
                        //break;
                    }
                }

    //            if (TRUE == fail)
    //            {
    //                break;
    //            }

                /* issue the received data to the output stream                   */
                if (IOM_COMPLETED != SIO_issue(mcbspInHandle, rcv, BUFSIZE, NULL))
                {
                    printf("Error issuing buffer to the stream");
                }
                pktCountIn++;
            }

    The C6748_BIOSPSP_Userguide (section 15.16.1.4) says, the sample of the slave side is loaded and executed first. Next the sample application on the master side is loaded and executed.

    I did the above changes with NUM_BUFS set to 2u both in Master side application and slave side application, and it seems to be working fine for me(Without any blocking or hang). The application loops for "LOOP_COUNT" number of times and exits successfully with the following message on the slave side(receiving end):

    0   Mcbsp Sample Application

     

    1   EDMA intialised

    2   Request submitted to Mcbsp driver.

    3   Sample Application completed sucessfully...

    Note: The Master is configured as transmitter and slave as receiver. (In your case it is other way around!!)

    If the data comparison part is uncommented, then the comparison fails for the second iteration. Otherwise, there is no hang. So is this what you expected or you have any other specific requirement?.
    Thanks & regards,
    Raghavendra

  • My application also uses networking so it uses the NDK.  I found that if I delay the start of the McBSP task until after the network is done initializing, it works fine.  I'm guessing there is some interference in the eDMA while the network stack is running it's configuration which makes the reclaim hang.  Is there a way to know when the network stack is done with it's startup?  For now, the McBSP task is just calling TSK_sleep(5000) at the beginning.

     

    Thanks,

    Mary

  • Mary,

    I think you can do this by using a semaphore inside the Network startup callback function, which is specified within the call to NC_netstart().

    From the NDK user's guide (spru523_ug.pdf):

    "the network (and the network event
    scheduler) is invoked by calling the NETCTRL function NC_NetStart(). Besides the handle to the
    configuration, this function takes three additional callback pointer parameters; a pointer to a Start callback
    function, a Stop function, and a IP Address Event function.  The first two callback functions are called only once.  The Start callback is called when the system is initialized and ready to execute network applications (note there may not be a local IP network address
    installed yet).
    "

    For example, in the client.c file, in the function StackTest(), you can see this call:

        //
        // Boot the system using this configuration
        //
        // We keep booting until the function returns 0. This allows
        // us to have a "reboot" command.
        //
        do
        {
            rc = NC_NetStart( hCfg, NetworkOpen, NetworkClose, NetworkIPAddr );
        } while( rc > 0 );

     

    So, in this example "NetworkOpen" is the "start callback function."  So you could have your McBsp task pend on a semaphore.  Then inside the NetworkOpen() start function, you could post the semaphore.

    Please try that and see if it works for you.

    Thanks,

    Steve