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

📄 ddk_sdma.c

📁 freescale i.mx31 BSP CE5.0全部源码
💻 C
📖 第 1 页 / 共 4 页
字号:
//
//-----------------------------------------------------------------------------
BOOL SdmaDealloc(void)
{
    // Unmap host shared region
    if (g_pHostSharedUA)
    {
        MmUnmapIoSpace(g_pHostSharedUA, BSPSdmaGetSharedSize());
        g_pHostSharedUA = NULL;
        g_pHostSharedPA = NULL;
    }

    // Unmap peripheral registers
    if (g_pSDMA)
    {
        MmUnmapIoSpace(g_pSDMA, sizeof(CSP_SDMA_REGS));
        g_pSDMA = NULL;
    }

    if (g_hSdmaMutex)
    {
        CloseHandle(g_hSdmaMutex);
        g_hSdmaMutex = NULL;
    }

    if (g_hAcrMutex)
    {
        CloseHandle(g_hAcrMutex);
        g_hAcrMutex = NULL;
    }

    return TRUE;
}


//-----------------------------------------------------------------------------
//
// Function:  SdmaWritePM
//
// This function uses the channel 0 boot code to write code to the
// SDMA's internal memory.  This function can be used to load SDMA scripts
// from the host memory into the SDMA's RAM.
//
// Parameters:
//      srcAddrPA
//          [in] - Physical source address for data to be written into SDMA.
//
//      dstAddrPM
//          [in] - Physical destination address within SDMA program memory
//          into which the data will be written.
//
//      count
//          [in] - Number of data bytes to be written into the SDAM.
//
// Returns:
//      Returns TRUE.
//
//-----------------------------------------------------------------------------
static BOOL SdmaWritePM(UINT32 srcAddrPA, UINT32 dstAddrPM, UINT16 count)
{
    BOOL rc = FALSE;

    // Request lock
    SdmaLockCtrlChan();

    // Configure chan 0 buffer descriptor
    g_pHostSharedUA->chan0BufDesc.mode =
        CSP_BITFVAL(SDMA_MODE_COMMAND, SDMA_CMD_C0_SET_PM) |
        CSP_BITFVAL(SDMA_MODE_EXT, SDMA_MODE_EXT_USED) |
        CSP_BITFVAL(SDMA_MODE_ERROR, SDMA_MODE_ERROR_NOTFOUND) |
        CSP_BITFVAL(SDMA_MODE_INTR, SDMA_MODE_INTR_NOSEND) |
        CSP_BITFVAL(SDMA_MODE_CONT, SDMA_MODE_CONT_END) |
        CSP_BITFVAL(SDMA_MODE_WRAP, SDMA_MODE_WRAP_WRAP2FIRST) |
        CSP_BITFVAL(SDMA_MODE_DONE, SDMA_MODE_DONE_NOTREADY) |
        CSP_BITFVAL(SDMA_MODE_COUNT, count / 2);

    g_pHostSharedUA->chan0BufDesc.srcAddrPA = srcAddrPA;
    g_pHostSharedUA->chan0BufDesc.destAddrPA = dstAddrPM;

    // Start the channel 0 script
    if (!DDKSdmaStartChan(0))
    {
        ERRORMSG(1, (_T("Chan 0 cannot be started!\r\n")));
        goto cleanUp;
    }

    // Wait for script to complete
    while (SdmaGetChanStatus(0))
    {
        // Give up the CPU
        Sleep(0);
    }

    // Make sure chan 0 buffer descriptor was processed
    if (CSP_BITFEXT(g_pHostSharedUA->chan0BufDesc.mode, SDMA_MODE_DONE)
        == SDMA_MODE_DONE_NOTREADY)
    {
        ERRORMSG(1, (_T("Chan 0 buffer descriptor not processed!\r\n")));
        goto cleanUp;
    }

    // Make sure chan 0 buffer descriptor did not incur error
    if (CSP_BITFEXT(g_pHostSharedUA->chan0BufDesc.mode, SDMA_MODE_ERROR)
        == SDMA_MODE_ERROR_FOUND)
    {
        ERRORMSG(1, (_T("Chan 0 buffer descriptor incurred error!\r\n")));
        goto cleanUp;
    }

    rc = TRUE;

cleanUp:
    SdmaUnlockCtrlChan();
    return rc;
}


//-----------------------------------------------------------------------------
//
// Function:  SdmaWriteChanContext
//
// This function uses the channel 0 boot code to load a channel context into
// the SDMA's internal memory reserved for the context page area.
//
// Parameters:
//      chan
//          [in] - Virtual channel whose context will be loaded.
//
//      srcAddrPA
//          [in] - Physical source address for context to be written into SDMA.
//
// Returns:
//      Returns TRUE.
//
//-----------------------------------------------------------------------------
static BOOL SdmaWriteChanContext(UINT8 chan, UINT32 srcAddrPA)
{
    BOOL rc = FALSE;

    // Configure chan 0 buffer descriptor
    g_pHostSharedUA->chan0BufDesc.mode =
        CSP_BITFVAL(SDMA_MODE_COMMAND, CMD_SETCTX(chan)) |
        CSP_BITFVAL(SDMA_MODE_EXT, SDMA_MODE_EXT_UNUSED) |
        CSP_BITFVAL(SDMA_MODE_ERROR, SDMA_MODE_ERROR_NOTFOUND) |
        CSP_BITFVAL(SDMA_MODE_INTR, SDMA_MODE_INTR_NOSEND) |
        CSP_BITFVAL(SDMA_MODE_CONT, SDMA_MODE_CONT_END) |
        CSP_BITFVAL(SDMA_MODE_WRAP, SDMA_MODE_WRAP_WRAP2FIRST) |
        CSP_BITFVAL(SDMA_MODE_DONE, SDMA_MODE_DONE_NOTREADY) |
        CSP_BITFVAL(SDMA_MODE_COUNT, sizeof(SDMA_CHANNEL_CONTEXT) / 4);

    g_pHostSharedUA->chan0BufDesc.srcAddrPA = srcAddrPA;

    // Start the channel 0 script
    if (!DDKSdmaStartChan(0))
    {
        ERRORMSG(1, (_T("Chan 0 cannot be started!\r\n")));
        goto cleanUp;
    }

    // Wait for script to complete
    while (SdmaGetChanStatus(0))
    {
        // Give up the CPU
        Sleep(0);
    }

    // Make sure chan 0 buffer descriptor was processed
    if (CSP_BITFEXT(g_pHostSharedUA->chan0BufDesc.mode, SDMA_MODE_DONE)
        == SDMA_MODE_DONE_NOTREADY)
    {
        ERRORMSG(1, (_T("Chan 0 buffer descriptor not processed!\r\n")));
        goto cleanUp;
    }

    // Make sure chan 0 buffer descriptor did not incur error
    if (CSP_BITFEXT(g_pHostSharedUA->chan0BufDesc.mode, SDMA_MODE_ERROR)
        == SDMA_MODE_ERROR_FOUND)
    {
        ERRORMSG(1, (_T("Chan 0 buffer descriptor incurred error!\r\n")));
        goto cleanUp;
    }

    rc = TRUE;

cleanUp:
    return rc;
}


//-----------------------------------------------------------------------------
//
// Function:  SdmaSetChanOverride
//
// This function configures the override bits for a specified channel.
//
// Parameters:
//      chan
//          [in] - Channel for which override bits will be set.
//
//      bHostOvr
//          [in] - Specifies if the HO (Host Override) bit is set.
//
//      bEventOvr
//          [in] - Specifies if the EO (Event Override) bit is set.
//
//      bDspOvr
//          [in] - Specifies if the DO (DSP Override) bit is set.
//
// Returns:
//      None.
//
//-----------------------------------------------------------------------------
static void SdmaSetChanOverride(UINT8 chan, BOOL bHostOvr,
    BOOL bEventOvr, BOOL bDspOvr)
{
    UINT32 oldOvr, newOvr;
    
    // Use interlocked function to update override registers
    do
    {
        oldOvr = INREG32(&g_pSDMA->HOSTOVR);
        newOvr = (oldOvr & (~CHAN_MASK(chan))) | (bHostOvr << chan);
    } while (InterlockedTestExchange(&g_pSDMA->HOSTOVR, 
                        oldOvr, newOvr) != oldOvr);        
    do
    {
        oldOvr = INREG32(&g_pSDMA->EVTOVR);
        newOvr = (oldOvr & (~CHAN_MASK(chan))) | (bEventOvr << chan);
    } while (InterlockedTestExchange(&g_pSDMA->EVTOVR, 
                        oldOvr, newOvr) != oldOvr);        

    do
    {
        oldOvr = INREG32(&g_pSDMA->DSPOVR);
        newOvr = (oldOvr & (~CHAN_MASK(chan))) | (bDspOvr << chan);
    } while (InterlockedTestExchange(&g_pSDMA->DSPOVR, 
                        oldOvr, newOvr) != oldOvr);      

}


//-----------------------------------------------------------------------------
//
// Function:  SdmaSetChanPriority
//
// This function configures the priority for a specified channel.
//
// Parameters:
//      chan
//          [in] - Channel for which the priority will be set.
//
//      priority
//          [in] - Priority assigned to the channel.  Possible priority
//          values are 0-7 with 7 being the highest possible priority.
//          A channel assigned priority 0 will be prevented from running.
//
// Returns:
//      None.
//
//-----------------------------------------------------------------------------
static void SdmaSetChanPriority(UINT8 chan, UINT8 priority)
{
    OUTREG32(&g_pSDMA->CHNPRI[chan], priority);
}


//-----------------------------------------------------------------------------
//
// Function:  SdmaGetChanStatus
//
// This function reads the status the specified channel.
//
// Parameters:
//      chan
//          [in] - Virtual channel to for which status will be read.
//
// Returns:
//      Returns TRUE if the specified channel is enabled (HE bit set),
//      else returns FALSE (HE bit clear).
//
//-----------------------------------------------------------------------------
static BOOL SdmaGetChanStatus(UINT8 chan)
{
    return (INREG32(&g_pSDMA->STOP_STAT) & CHAN_MASK(chan)) ? TRUE : FALSE;
}


//-----------------------------------------------------------------------------
//
// Function:  SdmaFindUnusedChan
//
// This function searches the SDMA channel control blocks to find a virtual
// channel that is currently not in use and is available for a handling
// a peripheral-to-memory, memory-to-peripheral, or memory-to-memory
// trasfer.
//
// Parameters:
//      priority
//          [in] - Priority that will be assigned to unused channel to
//          claim it as used.
//
// Returns:
//      Returns virtual channel ID if an available virtual channel is found,
//      otherwise returns 0.
//
//-----------------------------------------------------------------------------
static UINT8 SdmaFindUnusedChan(UINT8 priority)
{
    UINT8 chan;

    // Walk the CCB to find available virtual channel (channel 0 is reserved)
    for (chan = 1; chan < SDMA_NUM_CHANNELS; chan++)
    {
        // Check channel status for availability
        if (INREG32(&g_pSDMA->CHNPRI[chan]) == SDMA_CHNPRI_CHNPRI_DISABLE)
        {
            // Use interlocked call to safely update CHNPRI register which
            // is a shared resource
            if (InterlockedTestExchange(&g_pSDMA->CHNPRI[chan], 
                SDMA_CHNPRI_CHNPRI_DISABLE, priority) 
                == SDMA_CHNPRI_CHNPRI_DISABLE)
            {
                break;
            }
        }
    }

    if (chan >= SDMA_NUM_CHANNELS)
    {
        ERRORMSG(1, (_T("No unused channel found!\r\n")));
        chan = 0;
    }

    return chan;

}


//-----------------------------------------------------------------------------
//
//  Function:  SdmaLockCtrlChan
//
//  This function locks the SDMA control channel (channel 0) to provide
//  safe access to the control channel shared resources.
//
// Parameters:
//      None.
//
// Returns:
//      None.
//
//-----------------------------------------------------------------------------
static void SdmaLockCtrlChan(void)
{
    WaitForSingleObject(g_hSdmaMutex, INFINITE);
    OUTREG32(&g_pSDMA->CHNPRI[0], SDMA_CHNPRI_CHNPRI_HIGHEST);
}


//-----------------------------------------------------------------------------
//
//  Function:  SdmaUnlockCtrlChan
//
//  This function unlocks the SDMA control channel (channel 0).
//
// Parameters:
//      None.
//
// Returns:
//      None.
//
//-----------------------------------------------------------------------------
static void SdmaUnlockCtrlChan(void)
{
    OUTREG32(&g_pSDMA->CHNPRI[0], SDMA_CHNPRI_CHNPRI_DISABLE); 
    ReleaseMutex(g_hSdmaMutex);
}


//-----------------------------------------------------------------------------
//
//  Function:  SdmaValidChan
//
//  This function determines if a channel is valid and configured properly
//  for allocation and configuration of buffer descriptors.
//
//  Parameters:
//      chan
//          [in] - Virtual channel to for which status will be read.
//
//  Returns:
//      Returns TRUE if the specified channel is valid, otherwise
//      returns FALSE.
//
//-----------------------------------------------------------------------------
static BOOL SdmaValidChan(UINT8 chan)
{
    BOOL rc = FALSE;
    
    // Validate channel parameter
    if (chan <= 0 || chan >= SDMA_NUM_CHANNELS)
    {
        ERRORMSG(1, (_T("Invalid channel!\r\n")));
        goto cleanUp;
    }

    // Check if channel has been previously opened
    if (INREG32(&g_pSDMA->CHNPRI[chan]) == SDMA_CHNPRI_CHNPRI_DISABLE)
    {
        ERRORMSG(1, (_T("Channel not opened!\r\n")));
        goto cleanUp;
    }

    rc = TRUE;
    
cleanUp:

    return rc;
}

⌨️ 快捷键说明

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