ddk_dmac.c

来自「mx27 f14v2 源代码。包括ADS板上诸多驱动的源码。」· C语言 代码 · 共 1,172 行 · 第 1/3 页

C
1,172
字号
// Function:  DDKDmacIsChannelIntr
//
// This function returns true if the channel has interrupted.
//
// Parameters:
//      chan
//          [in] - channel returned by DDKDmacRequestChan function.
//
// Returns:
//      Returns TRUE if channel interrupt pending, otherwise returns FALSE.
//
//------------------------------------------------------------------------------
BOOL DDKDmacIsChannelIntr(UINT8 chan)
{
    UINT32 mask = CHAN_MASK(chan);
    return ((g_pDMAC->DISR & mask) == mask);
}

//------------------------------------------------------------------------------
//
// Function:  DDKDmacClearChannelIntr
//
// This function returns true if the channel has interrupted.
//
// Parameters:
//      chan
//          [in] - channel returned by DDKDmacRequestChan function.
//
// Returns:
//      None
//
//------------------------------------------------------------------------------
void DDKDmacClearChannelIntr(UINT8 chan)
{
    UINT32 mask;
    
    DEBUGMSG(ZONE_FUNCTION, (TEXT("+DDKDmacClearChannelIntr\r\n")));

    mask = CHAN_MASK(chan);
    g_pDMAC->DSESR = mask;
    g_pDMAC->DBOSR = mask;
    g_pDMAC->DRTOSR = mask;
    g_pDMAC->DBTOSR = mask;
    g_pDMAC->DISR = mask;

    DEBUGMSG(ZONE_FUNCTION, (TEXT("-DDKDmacClearChannelIntr\r\n")));
}

//------------------------------------------------------------------------------
//
// Function:  DDKDmacEnableChannelIntr
//
// This function enables interrupts for the desired channel.
//
// Parameters:
//      chan
//          [in] - channel returned by DDKDmacRequestChan function.
//
// Returns:
//      None
//
//------------------------------------------------------------------------------
void DDKDmacEnableChannelIntr(UINT8 chan)
{
    UINT32 mask;
    
    DEBUGMSG(ZONE_FUNCTION, (TEXT("+DDKDmacEnableChannelIntr\r\n")));

    mask = CHAN_MASK(chan);
    // Clear any pending interrupt status
    g_pDMAC->DSESR = mask;
    g_pDMAC->DBOSR = mask;
    g_pDMAC->DRTOSR = mask;
    g_pDMAC->DBTOSR = mask;
    g_pDMAC->DISR = mask;
    // Enable channel interrupt
    g_pDMAC->DIMR &= ~mask;

    DEBUGMSG(ZONE_FUNCTION, (TEXT("-DDKDmacEnableChannelIntr: DIMR=0x%x\r\n"), g_pDMAC->DIMR));
}

//------------------------------------------------------------------------------
//
// Function:  DDKDmacDisableChannelIntr
//
// This function disables interrupts for the desired channel.
//
// Parameters:
//      chan
//          [in] - channel returned by DDKDmacRequestChan function.
//
// Returns:
//      None
//
//------------------------------------------------------------------------------
void DDKDmacDisableChannelIntr(UINT8 chan)
{
    UINT32 mask;
    
    DEBUGMSG(ZONE_FUNCTION, (TEXT("+DDKDmacDisableChannelIntr\r\n")));

    mask = CHAN_MASK(chan);
    // Disable channel interrupt
    g_pDMAC->DIMR |= mask;
    // Clear any pending interrupt status
    g_pDMAC->DSESR = mask;
    g_pDMAC->DBOSR = mask;
    g_pDMAC->DRTOSR = mask;
    g_pDMAC->DBTOSR = mask;
    g_pDMAC->DISR = mask;

    DEBUGMSG(ZONE_FUNCTION, (TEXT("-DDKDmacDisableChannelIntr: DIMR=0x%x\r\n"), g_pDMAC->DIMR));
}

//-----------------------------------------------------------------------------
//
// Function:  DmacAlloc
//
// This function allocates the data structures required for interaction
// with the DMAC hardware.
//
// Parameters:
//      None.
//
// Returns:
//      Returns TRUE if successful, otherwise returns FALSE.
//
//-----------------------------------------------------------------------------
BOOL DmacAlloc(void)
{
    BOOL rc = FALSE;
    PHYSICAL_ADDRESS phyAddr;

    DEBUGMSG(ZONE_INIT, (_T("DmacAlloc+\r\n")));

    if (g_hFileMap == NULL)
    {
        g_hFileMap = CreateFileMapping(INVALID_HANDLE_VALUE, NULL,
            PAGE_READWRITE, 0, sizeof(DMAC_DLL_SHARED), _T("DMAC_DLL_SHARED"));

        if (g_hFileMap == NULL)
        {
            DEBUGMSG(ZONE_ERROR, (_T("DmacAlloc: CreateFileMapping failed!\r\n")));
            goto cleanUp;
        }
    }

    if (g_pDllShared == NULL)
    {
        g_pDllShared = (DMAC_DLL_SHARED *)MapViewOfFile(g_hFileMap,
            FILE_MAP_ALL_ACCESS, 0, 0, 0);

        if (g_pDllShared == NULL)
        {
            DEBUGMSG(ZONE_ERROR, (_T("DmacAlloc: MapViewOfFile failed!\r\n")));
            goto cleanUp;
        }
    }

    if (g_pDMAC == NULL)
    {
        phyAddr.QuadPart = CSP_BASE_REG_PA_DMAC;

        // Map peripheral physical address to virtual address
        g_pDMAC = (CSP_DMAC_REGS *)MmMapIoSpace(phyAddr, sizeof(CSP_DMAC_REGS), FALSE);

        // Check if virtual mapping failed
        if (g_pDMAC == NULL)
        {
            DEBUGMSG(ZONE_ERROR, (_T("DmacAlloc:  MmMapIoSpace failed!\r\n")));
            goto cleanUp;
        }
    }

    rc = TRUE;

cleanUp:
    // If initialization failed, be sure to clean up
    if (!rc) DmacDealloc();
    DEBUGMSG(ZONE_INIT, (_T("DmacAlloc- (rc = %d)\r\n"), rc));
    return rc;
}


//-----------------------------------------------------------------------------
//
// Function:  DmacDealloc
//
// This function deallocates the data structures required for interaction
// with the DMAC hardware.  Note that data structures for individual channels
// are freed in DmacDeinit.
//
// Parameters:
//      None.
//
// Returns:
//      Returns TRUE.
//
//-----------------------------------------------------------------------------
BOOL DmacDealloc(void)
{
    DEBUGMSG(ZONE_INIT, (_T("DmacDealloc+\r\n")));

    // Unmap peripheral registers
    if (g_pDMAC)
    {
        MmUnmapIoSpace(g_pDMAC, sizeof(CSP_DMAC_REGS));
        g_pDMAC = NULL;
    }

    // Unmap view of shared DLL memory
    if (g_pDllShared)
    {
        UnmapViewOfFile(g_pDllShared);
        g_pDllShared = NULL;
    }

    // Close handle to shared DLL memory
    if (g_hFileMap)
    {
        CloseHandle(g_hFileMap);
        g_hFileMap = NULL;
    }

    DEBUGMSG(ZONE_INIT, (_T("DmacDealloc- (rc = %d)\r\n"), TRUE));

    return TRUE;
}

//------------------------------------------------------------------------------
//
// Function:  DmacTranslateCfg
//
// This function is used to translate the input channel configuration into 
// DMAC register values.
//
// Parameters:
//      pChannelCfg
//          [in] - channel configuration.
//
//      pChannelData
//          [out] - DMAC channel register values
//
// Returns:
//      Returns TRUE if successful, otherwise returns FALSE.
//
//------------------------------------------------------------------------------
static BOOL DmacTranslateCfg(DMAC_CHANNEL_CFG *pChannelCfg, DMAC_CHANNEL_DATA *pChannelData)
{
    BOOL rc = FALSE;
    
    DEBUGMSG(ZONE_FUNCTION, (_T("DmacTranslateCfg+\r\n")));
    
    // Translate configuration for CCR
    switch(pChannelCfg->RepeatType)
    {
        case DMAC_REPEAT_DISABLED:
            pChannelData->CCR = CSP_BITFVAL(DMAC_CCR_ACRPT, DMAC_CCR_ACRPT_DISABLE) |
                                CSP_BITFVAL(DMAC_CCR_RPT, DMAC_CCR_RPT_DISABLE);
            break;

        case DMAC_REPEAT_ONCE:
            pChannelData->CCR = CSP_BITFVAL(DMAC_CCR_ACRPT, DMAC_CCR_ACRPT_AUTOCLEAR_RPT) |
                                CSP_BITFVAL(DMAC_CCR_RPT, DMAC_CCR_RPT_ENABLE);
            break;

        case DMAC_REPEAT_FOREVER:
            pChannelData->CCR =  CSP_BITFVAL(DMAC_CCR_ACRPT, DMAC_CCR_ACRPT_DISABLE) |
                                 CSP_BITFVAL(DMAC_CCR_RPT, DMAC_CCR_RPT_ENABLE);
            break;
            
        default:
            DEBUGMSG(ZONE_ERROR, (_T("DmacTranslateCfg: Invalid repeat type\r\n")));
            goto cleanUp;
    }
    
    if((pChannelCfg->DstMode >= DMAC_TRANSFER_MODE_LINEAR_MEMORY) && (pChannelCfg->DstMode <= DMAC_TRANSFER_MODE_EOBE)  &&
       (pChannelCfg->SrcMode >= DMAC_TRANSFER_MODE_LINEAR_MEMORY) && (pChannelCfg->SrcMode <= DMAC_TRANSFER_MODE_EOBE) &&
       (pChannelCfg->DstSize >= DMAC_TRANSFER_SIZE_32BIT) && (pChannelCfg->DstSize <= DMAC_TRANSFER_SIZE_16BIT) &&
       (pChannelCfg->SrcSize >= DMAC_TRANSFER_SIZE_32BIT) && (pChannelCfg->SrcSize <= DMAC_TRANSFER_SIZE_16BIT) )
            pChannelData->CCR |= CSP_BITFVAL(DMAC_CCR_DMOD, pChannelCfg->DstMode) |
                                 CSP_BITFVAL(DMAC_CCR_SMOD, pChannelCfg->SrcMode) |
                                 CSP_BITFVAL(DMAC_CCR_DSIZ, pChannelCfg->DstSize) |
                                 CSP_BITFVAL(DMAC_CCR_SSIZ, pChannelCfg->SrcSize) ;
    else
    {
        DEBUGMSG(ZONE_ERROR, (_T("DmacTranslateCfg: Invalid dest/src configuration\r\n")));
        goto cleanUp;
    }
    
    if (pChannelCfg->MemDirIncrease)
        pChannelData->CCR |= CSP_BITFVAL(DMAC_CCR_MDIR, DMAC_CCR_MDIR_INCREMENT);
    else
        pChannelData->CCR |= CSP_BITFVAL(DMAC_CCR_MDIR, DMAC_CCR_MDIR_DECREMENT);

    
    // BUCR & RTOR share the same address. Which register is written depends on 
    // whether ext request enable (REN) is set in CCR.
    
    if (pChannelCfg->ExtReqEnable)
    {
        pChannelData->CCR |= CSP_BITFVAL(DMAC_CCR_REN, DMAC_CCR_REN_ENABLE) |
                             CSP_BITFVAL(DMAC_CCR_FRC, DMAC_CCR_FRC_NOEFFECT);

        pChannelData->RSSR = CSP_BITFVAL(DMAC_RSSR_RSS, pChannelCfg->ReqSrc);

        // Set source clock of request time out counter is HCLK
        if (pChannelCfg->ReqTimeout)
            pChannelData->RTOR_BUCR = CSP_BITFVAL(DMAC_RTOR_EN, DMAC_RTOR_EN_ENABLE) |
                             CSP_BITFVAL(DMAC_RTOR_CLK, DMAC_RTOR_CLK_HCLK) |
                             CSP_BITFVAL(DMAC_RTOR_PSC, 0) |
                             CSP_BITFVAL(DMAC_RTOR_CNT, pChannelCfg->ReqTOCounter);
        else
            pChannelData->RTOR_BUCR = 0;
    }
    else
    {
        pChannelData->CCR |= CSP_BITFVAL(DMAC_CCR_REN, DMAC_CCR_REN_DISABLE) |
                             CSP_BITFVAL(DMAC_CCR_FRC, DMAC_CCR_FRC_FORCE_DMA_CYCLE);

        pChannelData->RSSR = 0; // default

        pChannelData->RTOR_BUCR = CSP_BITFVAL(DMAC_BUCR_BU_CNT, pChannelCfg->BusClkCounter);
    }

    // Translate other registers data
    pChannelData->SAR = pChannelCfg->SrcAddr;
    pChannelData->DAR = pChannelCfg->DstAddr;
    pChannelData->CNTR = pChannelCfg->DataSize;
    pChannelData->BLR = CSP_BITFVAL(DMAC_BLR_BL, pChannelCfg->BurstLength);

    rc = TRUE;

cleanUp:
    DEBUGMSG(ZONE_FUNCTION, (_T("DmacTranslateCfg- (rc = %d)\r\n"), rc));
    return rc;
}

//-----------------------------------------------------------------------------
//
// Function:  DmacShowRegister
//
// This function prints out the values in the DMAC registers.
//
// Parameters:
//      None.
//
// Returns:
//      None.
//
//-----------------------------------------------------------------------------
static void DmacShowRegister(UINT32 channelMask)
{   
    UINT32 mask;
    UINT8 i;

    DEBUGMSG(1, (TEXT("DMAC General Registers:\r\n")));
    DEBUGMSG(1, (TEXT("DCR(0x%08x)\r\n"), g_pDMAC->DCR));
    DEBUGMSG(1, (TEXT("DISR(0x%08x)\r\n"), g_pDMAC->DISR));
    DEBUGMSG(1, (TEXT("DIMR(0x%08x)\r\n"), g_pDMAC->DIMR));
    DEBUGMSG(1, (TEXT("DRTOSR(0x%08x)\r\n"), g_pDMAC->DRTOSR));
    DEBUGMSG(1, (TEXT("DBOSR(0x%08x)\r\n"), g_pDMAC->DBOSR));
    DEBUGMSG(1, (TEXT("DBTOCR(0x%08x)\r\n"), g_pDMAC->DBTOCR));
    DEBUGMSG(1, (TEXT("2D memory registers:\r\n")));
    DEBUGMSG(1, (TEXT("WSRA(0x%08x)\r\n"), g_pDMAC->WSRA));
    DEBUGMSG(1, (TEXT("XSRA(0x%08x)\r\n"), g_pDMAC->XSRA));
    DEBUGMSG(1, (TEXT("YSRA(0x%08x)\r\n"), g_pDMAC->YSRA));
    DEBUGMSG(1, (TEXT("WSRB(0x%08x)\r\n"), g_pDMAC->WSRB));
    DEBUGMSG(1, (TEXT("XSRB(0x%08x)\r\n"), g_pDMAC->XSRB));
    DEBUGMSG(1, (TEXT("YSRB(0x%08x)\r\n"), g_pDMAC->YSRB));

    for(i = 0, mask = 1; i <= DMAC_NUM_CHANNELS; i++, mask <<= 1)
    {
        if(mask & channelMask)
        {
            DEBUGMSG(1, (TEXT("Channel %d:\r\n"), i));
            DEBUGMSG(1, (TEXT("SAR(0x%08x)\r\n"), g_pDMAC->CHANNEL[i].SAR));
            DEBUGMSG(1, (TEXT("DAR(0x%08x)\r\n"), g_pDMAC->CHANNEL[i].DAR));
            DEBUGMSG(1, (TEXT("CNTR(0x%08x)\r\n"), g_pDMAC->CHANNEL[i].CNTR));
            DEBUGMSG(1, (TEXT("CCR(0x%08x)\r\n"), g_pDMAC->CHANNEL[i].CCR));
            DEBUGMSG(1, (TEXT("RSSR(0x%08x)\r\n"), g_pDMAC->CHANNEL[i].RSSR));
            DEBUGMSG(1, (TEXT("BLR(0x%08x)\r\n"), g_pDMAC->CHANNEL[i].BLR));
            DEBUGMSG(1, (TEXT("RTOR_BUCR(0x%08x)\r\n"), g_pDMAC->CHANNEL[i].RTOR_BUCR));
            DEBUGMSG(1, (TEXT("CCNR(0x%08x)\r\n"), g_pDMAC->CHANNEL[i].CCNR));
        }
    }
}


⌨️ 快捷键说明

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