⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mytasks.c

📁 基于DDK的DMA启动传输方式,DSP为主端方式
💻 C
📖 第 1 页 / 共 2 页
字号:
////  Output Parameters:
////      pExdD_io  - The Expected Data Buffer (pointer)
////      pRecvD_io - The Received Data Buffer (pointer)
////      pSendD_io - The Send     Data Buffer (pointer)
////
////  Return Value(s)  : none
////
//////////////////////////////////////////////////////////////////////////////

static void _ReleaseBuffers(Ptr *pExpD_io,
                            Ptr *pRecvD_io,
                            Ptr *pSendD_io )
{
    extern tMyBufInfo g_oBufInfo;


    LOG_printf(&trace, "Releasing the buffers ...");

    //---------------------------------------
    // Return/free the Expected Data buffer
    //---------------------------------------
    if (*pExpD_io != NULL)
    {
        BUF_free(g_oBufInfo.hBufPool, *pExpD_io);
    }

    //---------------------------------------
    // Return/free the Received Data buffer
    //---------------------------------------
    if (*pRecvD_io != NULL)
    {
        BUF_free(g_oBufInfo.hBufPool, *pRecvD_io);
    }

    //---------------------------------------
    // Return/free the (to) Send Data buffer
    //---------------------------------------
    if (*pSendD_io != NULL)
    {
        BUF_free(g_oBufInfo.hBufPool, *pSendD_io);
    }

}       // END _ReleaseBuffers()

//////////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////////
////
////  Name: _InitPciRequests
////
////  Purpose: This routine initializes 2 pci-request structures -- one for
////           reading and the other for writing.  These structures are
////           used to send read and write requests thru the DM642 device
////           driver and across the PCI bus.
////
////  Input Parameters:  none
////
////  Output Parameters:
////      pReadReq_o  - Structure used to request PCI  reads   to the DM642
////      pWriteReq_o - Structure used to request PCI writes from the DM642
////
////  Return Value(s)  : none
////
//////////////////////////////////////////////////////////////////////////////

static void _InitPciRequests( Ptr pReadReq_o,
                              Ptr pWriteReq_o )
{
    extern tMyPciXferInfo g_oXferInfo;

    C64XX_PCI_Request *pReadReq  = (C64XX_PCI_Request *)pReadReq_o;
    C64XX_PCI_Request *pWriteReq = (C64XX_PCI_Request *)pWriteReq_o;


    if (pReadReq != NULL)
	{
	    pReadReq->srcAddr  = (char *)g_oXferInfo.pPciAddr;
	    pReadReq->dstAddr  = (char *)g_oXferInfo.pDspRxAddr;
	    pReadReq->byteCnt  = g_oXferInfo.nCountB;
	    pReadReq->options  = 0;
	    pReadReq->options  = \
	            C64XX_PCI_SETXFERMODE(pReadReq->options, PCI_READ_NOPREF);
    }

    if (pWriteReq != NULL)
	{
	    pWriteReq->srcAddr  = (char *)g_oXferInfo.pDspTxAddr;
	    pWriteReq->dstAddr  = (char *)g_oXferInfo.pPciAddr;
	    pWriteReq->byteCnt  = g_oXferInfo.nCountB;
	    pWriteReq->options  = 0;
	    pWriteReq->options  = \
	            C64XX_PCI_SETXFERMODE(pWriteReq->options, PCI_WRITE);
    }

}       // END _InitPciRequests()

//////////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////////
////
////  Name: ProcessTask
////
////  Purpose: This routine implements the main body of the Target-side
////           application described in Exhibit #2.
////
////           The routine is a DSP/BIOS task (or Task Thread).
////           The routine WILL NOT RETURN.
////
////           The routine finishes the initialization process, and then
////           notifies the Host that it is ready by writing a local address
////           into DSPMA.  The routine then enters is main processing
////           loop.
////
////           In the main loop, which is infinite, the routine Pends on a
////           semaphore.  This semaphore is Posted in the DM642 device
////           driver's ISR when the Host raises HOSTSW.  The routine then
////           reads the data thru the DM642 PCI device driver, compares
////           received vs. expected, writes its own data out thru the
////           driver, notifies the Host via the PCI interrupt, and then
////           Pends on the above semaphore once again.
////
////           Any errors cause either a System Abort or a System Exit.
////
////  Input Parameters:
////      nIdArg - Task ID ##, passed in by DSP/BIOS.
////               NOT USED.
////
////  Output Parameters: none
////
////  Return Value(s)  : none
////
//////////////////////////////////////////////////////////////////////////////

Void ProcessTask(Arg nIdArg)
{
    extern tMyPciXferInfo g_oXferInfo;
    extern Ptr            g_pMyGio;

    Ptr pExpectedData;
    Ptr pRecvdData;
    Ptr pDataToSend;
    
    C64XX_PCI_Request oPciReadReq;
    C64XX_PCI_Request oPciWriteReq;

    Uint32 nIterCntE, nIterCntO;
    Uint32 nIterCnt;


    //------------------------------------
    // Tell the log that we got here ...
    //------------------------------------
    LOG_printf(&trace, "Entered ProcessTask!");

    //-------------------------------------------------------------------
    // Get our three buffers from the Buffer Pool, and initialize them
    //   as necessary.
    //-------------------------------------------------------------------

    if (_GrabBuffers(&pExpectedData, &pRecvdData, &pDataToSend) < 0)
    {
        LOG_printf(&trace, "ProcessTask(): ERROR grabbing buffers!");
        goto ExitTask;
    }

    _InitBuffers(pExpectedData, pRecvdData, pDataToSend);

    //------------------------------------------------------------------
    // Initialize the data-structs used to control our PCI transfers
    //   (via the GIO module)
    //------------------------------------------------------------------

    g_oXferInfo.pDspRxAddr = pRecvdData;
    g_oXferInfo.pDspTxAddr = pDataToSend;

    _InitPciRequests(&oPciReadReq, &oPciWriteReq);

    //------------------------------------------------------------------
    // This is the ACK back to the Host in response to it setting the
    //   PCIMA and PCIMC[CNT] registers.  The registers were checked
    //   in main().
    //------------------------------------------------------------------

    LOG_printf( &trace, "Setting DSPMA[ADDRMA] to ... %04x_%04x",
               (((LgUns)g_oXferInfo.pDspRxAddr) >> 16),
                ((LgUns)g_oXferInfo.pDspRxAddr & 0x0000FFFF));

    PCI_RSET(DSPMA, (((LgUns)g_oXferInfo.pDspRxAddr) & _PCI_DSPMA_ADDRMA_MASK));

    //************************************************************************

    ////////////////////////////////////////////
    //
    // The main processing LOOP.
    //
    ////////////////////////////////////////////

    for ( nIterCntE  = 0, nIterCntO  = 1, nIterCnt = 0;
          ;
          nIterCntE += 2, nIterCntO += 2, nIterCnt++ )
    {
        Uns nSize;
        int nStatus;

        //---------------------------------------------------------
        // Wait for the Host to signal that data is available ...
        //---------------------------------------------------------
        SEM_pend(&PciDmaDataAvail, SYS_FOREVER);

        //-----------------------------------------------------------
        // Put the iteration count(s) into the 1st 4 bytes of the
        //   appropriate buffers.
        // We expect to receive counts of 0,2,4,...
        // We will send counts of         1,3,5,...
        //-----------------------------------------------------------
        memcpy(pExpectedData, &nIterCntE, sizeof(nIterCntE));
        memcpy(pDataToSend,   &nIterCntO, sizeof(nIterCntO));

        //-------------------------------------------------------------
        // Read the available data (from the Host) into DSP memory
        //   (the pRecvData buffer)
        //-------------------------------------------------------------
        nSize   = 0;
        nStatus = GIO_read(g_pMyGio, &oPciReadReq, &nSize);
        if(nStatus < 0)
        {
            LOG_printf(&trace, "ProcessTask: ERROR -> GIO_read.  Status == %d; Size == %u",
                                nStatus, nSize);
        }

        //-----------------------------------------------------------
        // Compare what was received vs. what was expected ...
        // If a mismatch occurs, print an error message and bail.
        //-----------------------------------------------------------
        if ( _CompareBuffers(pRecvdData, pExpectedData, 4) < 0 )
        {
            LOG_printf(&trace, "ERROR: Data mismatch on iteration %u", nIterCnt);
            SYS_abort("ProcessTasks:Mismatch");
        }

        //-----------------------------------------------
        // Write data to the Host ...
        //-----------------------------------------------
        nSize   = 0;
        nStatus = GIO_write(g_pMyGio, &oPciWriteReq, &nSize);
        if(nStatus < 0)
        {
            LOG_printf(&trace, "ProcessTask: ERROR -> GIO_write.  Status == %d;%u",
                                nStatus, nSize);
        }

        //-------------------------------------------------------------
        // Trigger the DSP->to->Host interrupt.
        // Doing so tells the Host that it has data to read.
        //
        // Clearing the interrupt 1st forces it to 'fire', even if
        // an interrupt condition had already existed.
        //-------------------------------------------------------------
        GIO_control(g_pMyGio, C64XX_PCI_DSP_INT_REQ_CLEAR, NULL);
        GIO_control(g_pMyGio, C64XX_PCI_DSP_INT_REQ_SET,   NULL);

        //----------------------------------------------------------
        // "Print out" the iteration count every 10,000 iterations
        //----------------------------------------------------------
        if ((nIterCnt % 10000) == 0)
        {
            LOG_printf(&trace, "ProcessTask(): Iteration Count == 0x%04x_%04x",
                       (MdUns)(nIterCnt >> 16), (MdUns)nIterCnt);
        }
    }
    
    //************************************************************************
    
ExitTask:

    //------------------------------------------
    // Return the buffers to the Buffer Pool.
    //------------------------------------------
    _ReleaseBuffers(&pExpectedData, &pRecvdData, &pDataToSend);

    SYS_exit(0);

}       // END ProcessTask()


//############################################################################
//                             End of Functions
//############################################################################

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -