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.

Problems with OMAP3530 and DSPLink

Other Parts Discussed in Thread: OMAP3530

Hi, everyone.

I'm doing a work with BeagleBoard which use its DSP, the way of communication is DSPLINK, but I'm having many problems.
I'm trying run the G.729 codec in the DSP, my application is based in demo sample readwrite that come with DSPLINK.

The main fuction in GPP side is it:

NORMAL_API
DSP_STATUS
TP_Execute (IN Uint32  dspAddress,
              IN Uint32  bufferSize,
              IN Uint32  numIterations,
              IN Uint8   processorId,
              IN Char8 * bufferPCM,
              IN Uint32  sizeBufferPCM,
              IN Char8 * bufferG729,
              IN Uint32  sizeBufferG729
            )
{

    DSP_STATUS      status   = DSP_SOK ;
    Uint16 *        bufIn    = NULL ;
    Uint16 *        bufOut   = NULL ;
    Uint8 *         ptr8     = NULL ;
    Uint8 *         ptr8_1   = NULL ;
    Uint16 *        ptr16    = NULL ;
    Uint16 *        ptr16_1  = NULL ;
    Uint32          dspAddr1 = dspAddress ;
    Uint32          dspAddr2 = (dspAddress + bufferSize) ;
    //Uint32          dspAddr2 = (dspAddress + bufferSize) ;
    SampleMessage * msg ;
    Uint32          i, j ;
    
    status = TP_AllocateBuffer (bufferSize, (Pvoid *) &bufIn) ;
    
    if (DSP_FAILED (status)) {
        TP_1Print ("BufferIn Allocation Failed. Status: [0x%x]\n", status) ;
    }
    status = TP_AllocateBuffer (bufferSize, (Pvoid *) &bufOut) ;
    if (DSP_FAILED (status)) {
        TP_1Print ("BufferOut Allocation Failed. Status: [0x%x]\n", status) ;
    }


        memcpy(bufIn, bufferPCM, bufferSize);

    /*  Write the data buffer to the DSP side */
       if (DSP_SUCCEEDED (status))
    {
           status = PROC_write (processorId, dspAddr2, bufferSize , bufIn) ;
        if (DSP_FAILED (status))
        {
            TP_1Print ("1 - PROC_write Failed. /Statu : [0x%x]\n", status) ;
        }
    }

        /*  Prime the data buffer for the sample application
         *  - Initialize the buffer to '1's. This value is multiplied
         *    by the DSP with the iteration number
         */
        memcpy(bufOut, bufferG729, bufferSize);
 
    /*  Write the data buffer to the DSP side */
    if (DSP_SUCCEEDED (status)) {
        status = PROC_write (processorId, dspAddr1, bufferSize, bufOut) ;
        if (DSP_FAILED (status)) {
            TP_1Print ("2 - PROC_write Failed. Status: [0x%x]\n", status) ;
        }
    }
    
    /*  Inform the DSP side that the data buffer has been written */
    if (DSP_SUCCEEDED (status)) {
        status = MSGQ_alloc (POOL_makePoolId(processorId, SAMPLE_POOL_ID), APP_MSG_SIZE, (MSGQ_Msg *) &msg) ;
        if (DSP_SUCCEEDED (status))
        {
           msg->gppWriteAddr  = dspAddr1;
           msg->dspWriteAddr  = dspAddr2;
           msg->size          = bufferSize;
           msg->scalingFactor = i;

/*#if (definied (OMAP) && defined (PCPY_LINK)) || defined (WORD_SWAP)
            msg->gppWriteAddr  = WORDSWAP_LONG ((dspAddr1  / DSP_MAUSIZE)) ;
            msg->dspWriteAddr  = WORDSWAP_LONG ((dspAddr2  / DSP_MAUSIZE)) ;
            msg->size          = WORDSWAP_LONG ((bufferSize/ DSP_MAUSIZE)) ;
            msg->scalingFactor = WORDSWAP_LONG (i) ;
#else // * if defined (OMAP) && defined (PCPY_LINK)) || defined (WORD_SWAP) * /
            msg->gppWriteAddr  = (dspAddr1   / DSP_MAUSIZE) ;
            msg->dspWriteAddr  = (dspAddr2   / DSP_MAUSIZE) ;
            msg->size          = (bufferSize / DSP_MAUSIZE) ;
            msg->scalingFactor = 2 ; // usa este fator de escala
#endif // * if (defined (OMAP) && defined (PCPY_LINK)) || defined (WORD_SWAP) * /
*/
                /* Send the message */
            status = MSGQ_put (SampleDspMsgq, (MSGQ_Msg) msg) ;
            if (DSP_FAILED (status)) {
                TP_1Print ("MSGQ_put failed. Status: [0x%x]\n", status) ;
               }
        }
        else {
            TP_1Print ("MSGQ_alloc failed. Status: [0x%x]\n", status) ;
        }
    }


        /*  Wait for a message from the DSP confirming it has written data  */
    if (DSP_SUCCEEDED (status)) {
        status = MSGQ_get (SampleGppMsgq, WAIT_FOREVER, (MSGQ_Msg *) &msg) ;
        if (DSP_SUCCEEDED (status)) {
            status = MSGQ_free ((MSGQ_Msg) msg) ;
            if (DSP_FAILED (status)) {
                TP_1Print ("MSGQ_free failed. Status: [0x%x]\n", status) ;
            }
        }
        else {
            TP_1Print ("MSGQ_get failed. Status: [0x%x]\n", status) ;
        }
    }
 
        /*  Read from the DSP memory region */
    if (DSP_SUCCEEDED (status)) {
        status = PROC_read (processorId, dspAddr2, bufferSize, bufIn) ;
        if (DSP_FAILED (status)) {
            TP_1Print ("PROC_read Failed. Status: [0x%x]\n", status) ;
        }
    }else{
            TP_1Print ("3 - PROC_write Failed. Status: [0x%x]\n", status) ;
    }
    /*  Read from the DSP memory region */
    if (DSP_SUCCEEDED (status)) {
        status = PROC_read (processorId, dspAddr1, bufferSize, bufOut) ;
         if (DSP_FAILED (status)) {
             TP_1Print ("PROC_read Failed. Status: [0x%x]\n", status) ;
        }
    }else{
           TP_1Print ("3 - PROC_write Failed. Status: [0x%x]\n", status) ;
    }

 
    memcpy(bufferG729, bufOut, sizeBufferG729);
    memcpy(bufferPCM, bufIn, sizeBufferPCM);
    
    
    if (bufIn != NULL) {
        TP_FreeBuffer ((Pvoid *) &bufIn) ;
    }
    
    if (bufOut != NULL) {
        TP_FreeBuffer ((Pvoid *) &bufOut) ;
    }
      
    TP_0Print ("Leaving TP_Execute 3 \n") ;

    return status ;
}

---------//---------//-------------//--------//-------

the main code of DSP side is it:

Int TSKTP_execute(TSKTP_TransferInfo * info)
{
    Int             status    = SYS_OK;
    Uint16 *        readBuf ;
    Uint16          serial[40] ;
    Uint16          temp[40];
    Uint16 *        writeBuf;
    Uint16 *        new_speech;
    Uint32          scalingFactor ;
    Uint32          size ;
    Uint32          j;
    Uint16        i;    
    SampleMessage * msg;    

      /* Execute the loop for configured number of transfers
     * A value of 0 in numTransfers implies infinite iterations
     */

    status = MSGQ_get (info->dspMsgqQueue, (MSGQ_Msg *) &msg, SYS_FOREVER) ;
    if (status == SYS_OK)
    {
           writeBuf      = (Uint16 *) msg->gppWriteAddr ;     
           readBuf           = (Uint16 *) msg->dspWriteAddr ;
        
        size          = msg->size ;
        scalingFactor = msg->scalingFactor ;

        new_speech = &readBuf[160];

        HAL_cacheInv ((Ptr) readBuf, size) ;

        Init_Pre_Process();
        Init_Coder_ld8a(readBuf);
        Set_zero(writeBuf, PRM_SIZE);

        // * Loop for each "L_FRAME" speech data. * /

       Pre_Process(new_speech, L_FRAME);
        Coder_ld8a(temp); //Codigo Principal
        
        for(j =0 ; j < 11; j++)
            writeBuf[j] = temp[j];
           
        //prm2bits_ld8k( temp, serial);

        HAL_cacheWbInv ((Ptr)(msg->gppWriteAddr), size) ;

        /* Now send a message to the GPP */
        status = MSGQ_put (info->gppMsgqQueue, (MSGQ_Msg) msg) ;
        if (status != SYS_OK) {
            SET_FAILURE_REASON(status);
        }
    }
    
    return status ;
}

I pass to DSP the below memory address, how do the MMU translate it to physical memory?  
strDspAddress    = "2280587264"; //transforme to MB - 2280587264/1024/1024 = 2174.9375 MB - what is wrong?

But always I get this erro:

DSP MMU Error Fault!  MMU_IRQSTATUS = [0x1]. Virtual DSP addr reference that generated the interrupt = [0xfffffff8].   

The code of GPP is inside of a "for" (I want to compact a file of voice, and this code is executed with 80 samples of voice), and this problem is got after some interations. I have read some troubleshooting but don't solve my problem.  
 
I don't change nothin in memory map, I use the same of readwrite example (and the readwrite example works)
and if I want change the memory map in the file CFG_OMAP3530_SHMEM.c I need rebuild the dsplink module?

I'm in this problem have a month and I don't know what's I can do.

Sorry for my bad english
thanks

Willian Henrique

  • Ok, from what I did understand, I need increase the DSP space memory. Alright ?

    To change the memory map I need update the file dsplink-omap3530-base.tci and CFG_OMAP3530_SHMEM.c (in anexe). I'm sure?
    When I change this files I need rebuild the module dsplink, or only the application of DSP and GPP side?

    dsplink-omap3530-base.tci renamed to dsplink-omap3530-base.txt because the TI site don't allow files with .tci extension

    5807.CFG_OMAP3530_SHMEM.c6470.dsplink-omap3530-base .txt

  • Willian,

    Are you using the latest release: DSPLink 1.65.02.09 ? Here is the download link in case you need to upgrade:

    http://software-dl.ti.com/dsps/dsps_public_sw/sdo_sb/targetcontent/

    Here is a link on changing the DSPLink memory map.

    http://processors.wiki.ti.com/index.php/Changing_DSPLink_Memory_Map

    In the platform guide, section 6.2, there is also some information on memory map and MMU faults. For the BeagleBoard, you would look in dsplink/doc/PlatformGuide_OMAP3530.pdf.

    When you edit dsplink/config/all/CFG_OMAP3530_SHMEM.c, you need to rebuild the DSPLink module. Be sure to copy the new driver (dsplinkk.ko) to your target file system and install it with the insmod command. In most cases, you do not need to rebuild the ARM executable.

    When you edit dsplink/dsp/inc/DspBios/5.XX/OMAP3530/dsplink-omap3530-base.tci, you will need to rebuild the DSP executable.

    Sometimes, when you edit these files, there are sections which must be the same in both (unfortunately, they are duplicated). For example, RESETCTRLADDR and RESET_VECTOR must agree. If you move this, you would edit both files and rebuild on both side. Some of the other sections must also agree but are not easy to change, for example POOL.

    Looking at your program flow above, it seems that using the message sample would be a better fit instead of using the readwrite sample.

    dsplink/dsp/src/samples/message
    dsplink/gpp/src/samples/message

    The PROC_read() and PROC_write() functions are designed for small data access, mostly configuration type of operations. They are not designed for large data transfers. In addition, you will need to manage the cache in your program in order to see coherent memory.

    With MSGQ, you can create a message with a large payload. Use the payload for your data. The transport is zero-copy (unlike using PROC_read/PROC_write). This means that when you write the payload into the message on the ARM side, it is actually going into memory which is visible to both the ARM and the DSP. So, when sending the message (MSGQ_put()), only the message address is transferred to the DSP, not the entire payload. Once the DSP receives the message, it can access all the data. Also, the cache management is performed for you by DSPLink. Be sure to honor the message ownership rules. You cannot access a message once you send it, only after you receive it. This has to do with proper cache management.

    I'm sorry, but I don't have time today to inspect your attached files. If you are still stuck, let us know and I will get back to it when I can.

    ~Ramsey