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

📄 s3c6410_dma_controller.c

📁 6410BSP3
💻 C
📖 第 1 页 / 共 3 页
字号:
    //-------------------
    case DMA_PCM1_TX:
        pCtxt->SrcAHBM = AHB_M1;            // Memory
        pCtxt->DstAHBM = AHB_M2;            // Peripheral
        pCtxt->SrcPeri = 0;                    // Memory (Don't Care)
        pCtxt->DstPeri = DMAC1_PCM1_TX;        // PCM1_TX
        pCtxt->FlowCtrl = MEM_TO_PERI;        // Memory -> Peripheral
        break;
    case DMA_PCM1_RX:
        pCtxt->SrcAHBM = AHB_M2;            // Peripheral
        pCtxt->DstAHBM = AHB_M1;            // Memory
        pCtxt->SrcPeri = DMAC1_PCM1_RX;        // PCM1_RX
        pCtxt->DstPeri = 0;                    // Memory (Don't Care)
        pCtxt->FlowCtrl = PERI_TO_MEM;        // Peripheral -> Memory
        break;
    case DMA_I2S1_TX:
        pCtxt->SrcAHBM = AHB_M1;            // Memory
        pCtxt->DstAHBM = AHB_M2;            // Peripheral
        pCtxt->SrcPeri = 0;                    // Memory (Don't Care)
        pCtxt->DstPeri = DMAC1_I2S1_TX;        // I2S1_TX
        pCtxt->FlowCtrl = MEM_TO_PERI;        // Memory -> Peripheral
        break;
    case DMA_I2S1_RX:
        pCtxt->SrcAHBM = AHB_M2;            // Peripheral
        pCtxt->DstAHBM = AHB_M1;            // Memory
        pCtxt->SrcPeri = DMAC1_I2S1_RX;        // I2S1_RX
        pCtxt->DstPeri = 0;                    // Memory (Don't Care)
        pCtxt->FlowCtrl = PERI_TO_MEM;        // Peripheral -> Memory
        break;
    case DMA_SPI1_TX:
        pCtxt->SrcAHBM = AHB_M1;            // Memory
        pCtxt->DstAHBM = AHB_M2;            // Peripheral
        pCtxt->SrcPeri = 0;                    // Memory (Don't Care)
        pCtxt->DstPeri = DMAC1_SPI1_TX;        // SPI1_TX
        pCtxt->FlowCtrl = MEM_TO_PERI;        // Memory -> Peripheral
        break;
    case DMA_SPI1_RX:
        pCtxt->SrcAHBM = AHB_M2;            // Peripheral
        pCtxt->DstAHBM = AHB_M1;            // Memory
        pCtxt->SrcPeri = DMAC1_SPI1_RX;        // SPI1_RX
        pCtxt->DstPeri = 0;                    // Memory (Don't Care)
        pCtxt->FlowCtrl = PERI_TO_MEM;        // Peripheral -> Memory
        break;
    case DMA_AC97_PCMOUT:
        pCtxt->SrcAHBM = AHB_M1;            // Memory
        pCtxt->DstAHBM = AHB_M2;            // Peripheral
        pCtxt->SrcPeri = 0;                    // Memory (Don't Care)
        pCtxt->DstPeri = DMAC1_AC97_PCMOUT;    // AC97_PCMOUT
        pCtxt->FlowCtrl = MEM_TO_PERI;        // Memory -> Peripheral
        break;
    case DMA_AC97_PCMIN:
        pCtxt->SrcAHBM = AHB_M2;            // Peripheral
        pCtxt->DstAHBM = AHB_M1;            // Memory
        pCtxt->SrcPeri = DMAC1_AC97_PCMIN;    // AC97_PCMIN
        pCtxt->DstPeri = 0;                    // Memory (Don't Care)
        pCtxt->FlowCtrl = PERI_TO_MEM;        // Peripheral -> Memory
        break;
    case DMA_AC97_MICIN:
        pCtxt->SrcAHBM = AHB_M2;            // Peripheral
        pCtxt->DstAHBM = AHB_M1;            // Memory
        pCtxt->SrcPeri = DMAC1_AC97_MICIN;    // AC97_MICIN
        pCtxt->DstPeri = 0;                    // Memory (Don't Care)
        pCtxt->FlowCtrl = PERI_TO_MEM;        // Peripheral -> Memory
        break;
    case DMA_PWM:
    case DMA_IRDA:
    case DMA_EXTERNAL:
    case DMA_SSS:
        DMA_ERR((_T("[DMA:ERR] DMA_initialize_channel() : Not Implemented\n\r")));
        error = DMA_ERROR_NOT_IMPLEMENTED;
        goto CleanUp;
        break;
    //------------------------
    // DMA Source in MEM to MEM
    //------------------------
    case DMA_MEM:
        pCtxt->SrcAHBM = AHB_M1;            // Memory
        pCtxt->DstAHBM = AHB_M1;            // Memory
        pCtxt->SrcPeri = 0;                    // Memory (Don't Care)
        pCtxt->DstPeri = 0;                    // Memory (Don't Care)
        pCtxt->FlowCtrl = MEM_TO_MEM;        // Memory -> Memory
        break;
    case DMA_FIMG:
        pCtxt->SrcAHBM = AHB_M1;            // Memory
        pCtxt->DstAHBM = AHB_M2;            // Memory
        pCtxt->SrcPeri = 0;                    // Memory (Don't Care)
        pCtxt->DstPeri = 0;                    // Memory (Don't Care)
        pCtxt->FlowCtrl = MEM_TO_MEM;        // Memory -> Memory
        break;        
    default:
        DMA_ERR((_T("[DMA:ERR] DMA_initialize_channel() : Unknown DMA Source [%d]\n\r"), pCtxt->DMASrc));
        error = DMA_ERROR_ILLEGAL_PARAMETER;
        goto CleanUp;
        break;
    }

#if    0
    if (pCtxt->Controller == DMAC0)        // channel in DMAC0
    {
        // Lock DMA Access
        DMA_lock();

        if (bSync)
        {
            // Synchronization Logic Enable (Default Value)
            g_pDMAC0Reg->DMACSync &= ~(1<<(pCtxt->DMASrc));
        }
        else
        {
            // Synchronization Logic Disable
            g_pDMAC0Reg->DMACSync |= (1<<(pCtxt->DMASrc));
        }

        // Unlock DMA Access
        DMA_unlock();
    }
    else if (pCtxt->Controller == DMAC1)    // channel in DMAC1
    {
        // Lock DMA Access
        DMA_lock();

        if (bSync)
        {
            // Synchronization Logic Enable (Default Value)
            g_pDMAC1Reg->DMACSync &= ~(1<<(pCtxt->DMASrc-16));
        }
        else
        {
            // Synchronization Logic Disable
            g_pDMAC1Reg->DMACSync |= (1<<(pCtxt->DMASrc-16));
        }

        // Unlock DMA Access
        DMA_unlock();
    }
#endif

    pDMACHReg = (S3C6410_DMA_CH_REG *)pCtxt->pCHReg;
    pDMACHReg->LLI = 0;        // Disable LLI

    pDMACHReg->Configuration = ALLOW_REQUEST | UNLOCK | FLOWCTRL(pCtxt->FlowCtrl)
                        | DEST_PERI(pCtxt->DstPeri) | SRC_PERI(pCtxt->SrcPeri);

CleanUp:

    DMA_MSG((_T("[DMA]--DMA_initialize_channel() : %d\n\r"), error));

    return error;
}

DMA_ERROR DMA_set_channel_source(DMA_CH_CONTEXT *pCtxt, unsigned int uiSrcAddr, TRANSFER_UNIT Unit, BURST_SIZE Burst, ADDRESS_UPDATE Update)
{
    volatile S3C6410_DMA_CH_REG *pDMACHReg;
    DMA_ERROR error = DMA_SUCCESS;

    DMA_MSG((_T("[DMA]++DMA_set_channel_source() : Ch%d in DMAC%d (0x%08x, %d, %d, %d)\n\r"), pCtxt->Channel, pCtxt->Controller, uiSrcAddr, Unit, Burst, Update));

    if (pCtxt->bValid == FALSE)
    {
        DMA_ERR((_T("[DMA:ERR] DMA_set_channel_source() : Invalid DMA_CH_CONTEXT\n\r")));
        error = DMA_ERROR_ILLEGAL_PARAMETER;
        goto CleanUp;
    }

    switch(Unit)
    {
    case BYTE_UNIT: case HWORD_UNIT: case WORD_UNIT:
        pCtxt->SrcUnit = Unit;
        break;
    default:
        DMA_ERR((_T("[DMA:ERR] DMA_set_channel_source() : Unknown Transfer Unit [%d]\n\r"), Unit));
        error = DMA_ERROR_ILLEGAL_PARAMETER;
        goto CleanUp;
        break;
    }

    switch(Burst)
    {
    case BURST_1:    case BURST_4:    case BURST_8:    case BURST_16:
    case BURST_32:    case BURST_64:    case BURST_128:    case BURST_256:
        pCtxt->SrcBurst = Burst;
        break;
    default:
        DMA_ERR((_T("[DMA:ERR] DMA_set_channel_source() : Unknown Burst Size [%d]\n\r"), Burst));
        error = DMA_ERROR_ILLEGAL_PARAMETER;
        goto CleanUp;
        break;
    }

    switch(Update)
    {
    case INCREASE: case FIXED:
        pCtxt->SrcUpdate = Update;
        break;
    default:
        DMA_ERR((_T("[DMA:ERR] DMA_set_channel_source() : Unknown Address Update [%d]\n\r"), Update));
        error = DMA_ERROR_ILLEGAL_PARAMETER;
        goto CleanUp;
        break;
    }

    pDMACHReg = (S3C6410_DMA_CH_REG *)pCtxt->pCHReg;

    pDMACHReg->SrcAddr = uiSrcAddr;
    pDMACHReg->Control0 = (pDMACHReg->Control0 & ~((1<<26)|(1<<24)|SRC_UNIT_MASK|SRC_BURST_MASK))
                        |(pCtxt->SrcUpdate<<26) |(pCtxt->SrcAHBM<<24)|(pCtxt->SrcUnit<<18)|(pCtxt->SrcBurst<<12);

CleanUp:

    DMA_MSG((_T("[DMA]--DMA_initialize_channel() : %d\n\r"), error));

    return error;
}

DMA_ERROR DMA_set_channel_destination(DMA_CH_CONTEXT *pCtxt, unsigned int uiDstAddr, TRANSFER_UNIT Unit, BURST_SIZE Burst, ADDRESS_UPDATE Update)
{
    volatile S3C6410_DMA_CH_REG *pDMACHReg;
    DMA_ERROR error = DMA_SUCCESS;

    DMA_MSG((_T("[DMA]++DMA_set_channel_destnation() : Ch%d in DMAC%d (0x%08x, %d, %d, %d)\n\r"), pCtxt->Channel, pCtxt->Controller, uiDstAddr, Unit, Burst, Update));

    if (pCtxt->bValid == FALSE)
    {
        DMA_ERR((_T("[DMA:ERR] DMA_set_channel_destnation() : Invalid DMA_CH_CONTEXT\n\r")));
        error = DMA_ERROR_ILLEGAL_PARAMETER;
        goto CleanUp;
    }

    switch(Unit)
    {
    case BYTE_UNIT: case HWORD_UNIT: case WORD_UNIT:
        pCtxt->DstUnit = Unit;
        break;
    default:
        DMA_ERR((_T("[DMA:ERR] DMA_set_channel_destnation() : Unknown Transfer Unit [%d]\n\r"), Unit));
        error = DMA_ERROR_ILLEGAL_PARAMETER;
        goto CleanUp;
        break;
    }

    switch(Burst)
    {
    case BURST_1:    case BURST_4:    case BURST_8:    case BURST_16:
    case BURST_32:    case BURST_64:    case BURST_128:    case BURST_256:
        pCtxt->DstBurst = Burst;
        break;
    default:
        DMA_ERR((_T("[DMA:ERR] DMA_set_channel_destnation() : Unknown Burst Size [%d]\n\r"), Burst));
        error = DMA_ERROR_ILLEGAL_PARAMETER;
        goto CleanUp;
        break;
    }

    switch(Update)
    {
    case INCREASE: case FIXED:
        pCtxt->DstUpdate = Update;
        break;
    default:
        DMA_ERR((_T("[DMA:ERR] DMA_set_channel_destnation() : Unknown Address Update [%d]\n\r"), Update));
        error = DMA_ERROR_ILLEGAL_PARAMETER;
        goto CleanUp;
        break;
    }

    pDMACHReg = (S3C6410_DMA_CH_REG *)pCtxt->pCHReg;

    pDMACHReg->DestAddr = uiDstAddr;
    pDMACHReg->Control0 = (pDMACHReg->Control0 & ~((1<<27)|(1<<25)|DEST_UNIT_MASK|DEST_BURST_MASK))
                        |(pCtxt->DstUpdate<<27) |(pCtxt->DstAHBM<<25)|(pCtxt->DstUnit<<21)|(pCtxt->DstBurst<<15);

CleanUp:

    DMA_MSG((_T("[DMA]--DMA_set_channel_destnation() : %d\n\r"), error));

    return error;
}

DMA_ERROR DMA_set_channel_transfer_size(DMA_CH_CONTEXT *pCtxt, unsigned int uiByteCount)
{
    volatile S3C6410_DMA_CH_REG *pDMACHReg;
    DMA_ERROR error = DMA_SUCCESS;

    DMA_MSG((_T("[DMA]++DMA_set_channel_transfer_size() : Ch%d in DMAC%d (ByteCount : %d)\n\r"), pCtxt->Channel, pCtxt->Controller, uiByteCount));

    if (pCtxt->bValid == FALSE)
    {
        DMA_ERR((_T("[DMA:ERR] DMA_set_channel_transfer_size() : Invalid DMA_CH_CONTEXT\n\r")));
        error = DMA_ERROR_ILLEGAL_PARAMETER;
        goto CleanUp;
    }

    pDMACHReg = (S3C6410_DMA_CH_REG *)pCtxt->pCHReg;

    switch(pCtxt->SrcUnit)
    {
    case BYTE_UNIT:
        pDMACHReg->Control1 = TRANSFERCOUNT(uiByteCount);
        break;
    case HWORD_UNIT:
        pDMACHReg->Control1 = TRANSFERCOUNT(uiByteCount/2);
        break;
    case WORD_UNIT:
        pDMACHReg->Control1 = TRANSFERCOUNT(uiByteCount/4);
        break;
    }

CleanUp:

    DMA_MSG((_T("[DMA]--DMA_initialize_channel() : %d\n\r"), error));

    return error;
}

DMA_ERROR DMA_initialize_LLI(DMA_CH_CONTEXT *pCtxt, int iLLICount)
{
    DMA_ERROR error = DMA_SUCCESS;

    DMA_MSG((_T("[DMA]++DMA_initialize_LLI() : Ch%d in DMAC%d (%d)\n\r"), pCtxt->Channel, pCtxt->Controller, iLLICount));

    if (pCtxt->bValid == FALSE)
    {
        DMA_ERR((_T("[DMA:ERR] DMA_initialize_LLI() : Invalid DMA_CH_CONTEXT\n\r")));
        error = DMA_ERROR_ILLEGAL_PARAMETER;
        goto CleanUp;
    }

    if (iLLICount == 0 || iLLICount > MAX_LLI_ENTRY)
    {
        DMA_ERR((_T("[DMA] DMA_initialize_LLI() : LLICount [%d] Out of Range \n\r"), pCtxt->LLICount));
        error = DMA_ERROR_ILLEGAL_PARAMETER;
        goto CleanUp;
    }

    pCtxt->LLICount = iLLICount;

    if (DMA_allocate_LLI_context(pCtxt) == FALSE)
    {
        DMA_ERR((_T("[DMA:ERR] DMA_initialize_LLI() : LLI Context Allocation Failed\n\r")));
        error = DMA_ERROR_NOT_INITIALIZED;
        goto CleanUp;
    }

CleanUp:

    DMA_MSG((_T("[DMA]--DMA_initialize_LLI() : %d\n\r"), error));

    return error;
}

DMA_ERROR DMA_set_initial_LLI(DMA_CH_CONTEXT *pCtxt, int iIntialLLIEntryNumber)
{
    volatile S3C6410_DMA_CH_REG *pDMACHReg;
    DMA_ERROR error = DMA_SUCCESS;

    DMA_MSG((_T("[DMA]++DMA_initialize_LLI() : Ch%d in DMAC%d (%d)\n\r"), pCtxt->Channel, pCtxt->Controller, iIntialLLIEntryNumber));

    if (pCtxt->bValid == FALSE)
    {
        DMA_ERR((_T("[DMA:ERR] DMA_initialize_LLI() : Invalid DMA_CH_CONTEXT\n\r")));
        error = DMA_ERROR_ILLEGAL_PARAMETER;
        goto CleanUp;
    }

    if (pCtxt->LLICount == 0)
    {
        DMA_ERR((_T("[DMA] DMA_initialize_LLI() : LLI Not Initialized\n\r")));
        error = DMA_ERROR_NOT_INITIALIZED;
        goto CleanUp;
    }

    if (iIntialLLIEntryNumber > pCtxt->LLICount-1)
    {
        DMA_ERR((_T("[DMA:ERR] DMA_initialize_LLI() : Initial Entry Number exceed  Maximum Entry Number (%d > %d)\n\r"), iIntialLLIEntryNumber, pCtxt->LLICount-1));
        error = DMA_ERROR_ILLEGAL_PARAMETER;
        goto CleanUp;
    }

    pDMACHReg = (S3C6410_DMA_CH_REG *)pCtxt->pCHReg;

    pDMACHReg->LLI = NEXT_LLI_ITEM(pCtxt->LLIPhyAddr+sizeof(DMA_LLI_ENTRY)*iIntialLLIEntryNumber) |pCtxt->LLIAHBM;

CleanUp:

    DMA_MSG((_T("[DMA]--DMA_initialize_LLI() : %d\n\r"), error));

    return error;
}

DMA_ERROR DMA_set_LLI_entry(DMA_CH_CONTEXT *pCtxt, int iEntryNumber, LLI_NEXT_ITEM NextItem, unsigned int uiSrcAddr, unsigned int uiDstAddr, unsigned int uiByteCount)
{
    DMA_LLI_ENTRY *pLLIEntry;
    DMA_ERROR error = DMA_SUCCESS;

    DMA_MSG((_T("[DMA]++DMA_initialize_LLI() : Ch%d in DMAC%d (%d, %d, 0x%08x, 0x%08x, %d)\n\r"), pCtxt->Channel, pCtxt->Controller, iEntryNumber, NextItem, uiSrcAddr, uiDstAddr, uiByteCount));

    if (pCtxt->bValid == FALSE)
    {
        DMA_ERR((_T("[DMA:ERR] DMA_initialize_LLI() : Invalid DMA_CH_CONTEXT\n\r")));
        error = DMA_ERROR_ILLEGAL_PARAMETER;
        goto CleanUp;
    }

    if (iEntryNumber > pCtxt->LLICount-1)
    {
        DMA_ERR((_T("[DMA:ERR] DMA_initialize_LLI() : LLI Entry exceed Maximum Entry Number (%d > %d)\n\r"), iEntryNumber, pCtxt->LLICount-1));
        error = DMA_ERROR_ILLEGAL_PARAMETER;
        goto CleanUp;

⌨️ 快捷键说明

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