void dmacHw_initiateTransfer(dmacHw_HANDLE_t handle, dmacHw_CONFIG_t *pConfig, void *pDescriptor ) { dmacHw_DESC_RING_t *pRing; dmacHw_DESC_t *pProg; dmacHw_CBLK_t *pCblk; pCblk = dmacHw_HANDLE_TO_CBLK(handle); pRing = dmacHw_GET_DESC_RING(pDescriptor); if (CHANNEL_BUSY(pCblk->module, pCblk->channel)) { return; } if (pCblk->varDataStarted) { if (pCblk->descUpdated) { pCblk->descUpdated = 0; pProg = (dmacHw_DESC_t *) ((uint32_t) dmacHw_REG_LLP(pCblk->module, pCblk->channel) + pRing->virt2PhyOffset); if (!(pProg->ctl.hi & dmacHw_REG_CTL_DONE)) { dmacHw_SET_SAR(pCblk->module, pCblk->channel, pProg->sar); dmacHw_SET_DAR(pCblk->module, pCblk->channel, pProg->dar); dmacHw_REG_CTL_LO(pCblk->module, pCblk->channel) = pProg->ctl.lo; dmacHw_REG_CTL_HI(pCblk->module, pCblk->channel) = pProg->ctl.hi; } else if (pProg == (dmacHw_DESC_t *) pRing->pEnd->llp) { return; } else { dmacHw_ASSERT(0); } } else { return; } } else { if (pConfig->transferMode == dmacHw_TRANSFER_MODE_PERIODIC) { pProg = pRing->pHead; dmacHw_NEXT_DESC(pRing, pHead); } else { if (pRing->pEnd == NULL) { return; } pProg = pRing->pProg; if (pConfig->transferMode == dmacHw_TRANSFER_MODE_CONTINUOUS) { dmacHw_ASSERT((dmacHw_DESC_t *) pRing->pEnd-> llp == pRing->pProg); dmacHw_ASSERT((dmacHw_DESC_t *) pRing->pProg == pRing->pHead); do { pRing->pProg->ctl.lo |= (dmacHw_REG_CTL_LLP_DST_EN | dmacHw_REG_CTL_LLP_SRC_EN); pRing->pProg = (dmacHw_DESC_t *) pRing->pProg->llp; } while (pRing->pProg != pRing->pHead); } else { while (pRing->pProg != pRing->pEnd) { pRing->pProg->ctl.lo |= (dmacHw_REG_CTL_LLP_DST_EN | dmacHw_REG_CTL_LLP_SRC_EN); pRing->pProg = (dmacHw_DESC_t *) pRing->pProg->llp; } } } dmacHw_SET_SAR(pCblk->module, pCblk->channel, pProg->sar); dmacHw_SET_DAR(pCblk->module, pCblk->channel, pProg->dar); dmacHw_SET_LLP(pCblk->module, pCblk->channel, (uint32_t) pProg - pRing->virt2PhyOffset); dmacHw_REG_CTL_LO(pCblk->module, pCblk->channel) = pProg->ctl.lo; dmacHw_REG_CTL_HI(pCblk->module, pCblk->channel) = pProg->ctl.hi; if (pRing->pEnd) { pRing->pProg = (dmacHw_DESC_t *) pRing->pEnd->llp; } pRing->pEnd = (dmacHw_DESC_t *) NULL; } dmacHw_DMA_START(pCblk->module, pCblk->channel); }
static void DisplayRegisterContents(int module, /* [ IN ] DMA Controller unit (0-1) */ int channel, /* [ IN ] DMA Channel (0-7) / -1(all) */ int (*fpPrint) (const char *, ...) /* [ IN ] Callback to the print function */ ) { int chan; (*fpPrint) ("Displaying register content \n\n"); (*fpPrint) ("Module %d: Interrupt raw transfer 0x%X\n", module, (uint32_t) (dmacHw_REG_INT_RAW_TRAN(module))); (*fpPrint) ("Module %d: Interrupt raw block 0x%X\n", module, (uint32_t) (dmacHw_REG_INT_RAW_BLOCK(module))); (*fpPrint) ("Module %d: Interrupt raw src transfer 0x%X\n", module, (uint32_t) (dmacHw_REG_INT_RAW_STRAN(module))); (*fpPrint) ("Module %d: Interrupt raw dst transfer 0x%X\n", module, (uint32_t) (dmacHw_REG_INT_RAW_DTRAN(module))); (*fpPrint) ("Module %d: Interrupt raw error 0x%X\n", module, (uint32_t) (dmacHw_REG_INT_RAW_ERROR(module))); (*fpPrint) ("--------------------------------------------------\n"); (*fpPrint) ("Module %d: Interrupt stat transfer 0x%X\n", module, (uint32_t) (dmacHw_REG_INT_STAT_TRAN(module))); (*fpPrint) ("Module %d: Interrupt stat block 0x%X\n", module, (uint32_t) (dmacHw_REG_INT_STAT_BLOCK(module))); (*fpPrint) ("Module %d: Interrupt stat src transfer 0x%X\n", module, (uint32_t) (dmacHw_REG_INT_STAT_STRAN(module))); (*fpPrint) ("Module %d: Interrupt stat dst transfer 0x%X\n", module, (uint32_t) (dmacHw_REG_INT_STAT_DTRAN(module))); (*fpPrint) ("Module %d: Interrupt stat error 0x%X\n", module, (uint32_t) (dmacHw_REG_INT_STAT_ERROR(module))); (*fpPrint) ("--------------------------------------------------\n"); (*fpPrint) ("Module %d: Interrupt mask transfer 0x%X\n", module, (uint32_t) (dmacHw_REG_INT_MASK_TRAN(module))); (*fpPrint) ("Module %d: Interrupt mask block 0x%X\n", module, (uint32_t) (dmacHw_REG_INT_MASK_BLOCK(module))); (*fpPrint) ("Module %d: Interrupt mask src transfer 0x%X\n", module, (uint32_t) (dmacHw_REG_INT_MASK_STRAN(module))); (*fpPrint) ("Module %d: Interrupt mask dst transfer 0x%X\n", module, (uint32_t) (dmacHw_REG_INT_MASK_DTRAN(module))); (*fpPrint) ("Module %d: Interrupt mask error 0x%X\n", module, (uint32_t) (dmacHw_REG_INT_MASK_ERROR(module))); (*fpPrint) ("--------------------------------------------------\n"); (*fpPrint) ("Module %d: Interrupt clear transfer 0x%X\n", module, (uint32_t) (dmacHw_REG_INT_CLEAR_TRAN(module))); (*fpPrint) ("Module %d: Interrupt clear block 0x%X\n", module, (uint32_t) (dmacHw_REG_INT_CLEAR_BLOCK(module))); (*fpPrint) ("Module %d: Interrupt clear src transfer 0x%X\n", module, (uint32_t) (dmacHw_REG_INT_CLEAR_STRAN(module))); (*fpPrint) ("Module %d: Interrupt clear dst transfer 0x%X\n", module, (uint32_t) (dmacHw_REG_INT_CLEAR_DTRAN(module))); (*fpPrint) ("Module %d: Interrupt clear error 0x%X\n", module, (uint32_t) (dmacHw_REG_INT_CLEAR_ERROR(module))); (*fpPrint) ("--------------------------------------------------\n"); (*fpPrint) ("Module %d: SW source req 0x%X\n", module, (uint32_t) (dmacHw_REG_SW_HS_SRC_REQ(module))); (*fpPrint) ("Module %d: SW dest req 0x%X\n", module, (uint32_t) (dmacHw_REG_SW_HS_DST_REQ(module))); (*fpPrint) ("Module %d: SW source signal 0x%X\n", module, (uint32_t) (dmacHw_REG_SW_HS_SRC_SGL_REQ(module))); (*fpPrint) ("Module %d: SW dest signal 0x%X\n", module, (uint32_t) (dmacHw_REG_SW_HS_DST_SGL_REQ(module))); (*fpPrint) ("Module %d: SW source last 0x%X\n", module, (uint32_t) (dmacHw_REG_SW_HS_SRC_LST_REQ(module))); (*fpPrint) ("Module %d: SW dest last 0x%X\n", module, (uint32_t) (dmacHw_REG_SW_HS_DST_LST_REQ(module))); (*fpPrint) ("--------------------------------------------------\n"); (*fpPrint) ("Module %d: misc config 0x%X\n", module, (uint32_t) (dmacHw_REG_MISC_CFG(module))); (*fpPrint) ("Module %d: misc channel enable 0x%X\n", module, (uint32_t) (dmacHw_REG_MISC_CH_ENABLE(module))); (*fpPrint) ("Module %d: misc ID 0x%X\n", module, (uint32_t) (dmacHw_REG_MISC_ID(module))); (*fpPrint) ("Module %d: misc test 0x%X\n", module, (uint32_t) (dmacHw_REG_MISC_TEST(module))); if (channel == -1) { for (chan = 0; chan < 8; chan++) { (*fpPrint) ("--------------------------------------------------\n"); (*fpPrint) ("Module %d: Channel %d Source 0x%X\n", module, chan, (uint32_t) (dmacHw_REG_SAR(module, chan))); (*fpPrint) ("Module %d: Channel %d Destination 0x%X\n", module, chan, (uint32_t) (dmacHw_REG_DAR(module, chan))); (*fpPrint) ("Module %d: Channel %d LLP 0x%X\n", module, chan, (uint32_t) (dmacHw_REG_LLP(module, chan))); (*fpPrint) ("Module %d: Channel %d Control (LO) 0x%X\n", module, chan, (uint32_t) (dmacHw_REG_CTL_LO(module, chan))); (*fpPrint) ("Module %d: Channel %d Control (HI) 0x%X\n", module, chan, (uint32_t) (dmacHw_REG_CTL_HI(module, chan))); (*fpPrint) ("Module %d: Channel %d Source Stats 0x%X\n", module, chan, (uint32_t) (dmacHw_REG_SSTAT(module, chan))); (*fpPrint) ("Module %d: Channel %d Dest Stats 0x%X\n", module, chan, (uint32_t) (dmacHw_REG_DSTAT(module, chan))); (*fpPrint) ("Module %d: Channel %d Source Stats Addr 0x%X\n", module, chan, (uint32_t) (dmacHw_REG_SSTATAR(module, chan))); (*fpPrint) ("Module %d: Channel %d Dest Stats Addr 0x%X\n", module, chan, (uint32_t) (dmacHw_REG_DSTATAR(module, chan))); (*fpPrint) ("Module %d: Channel %d Config (LO) 0x%X\n", module, chan, (uint32_t) (dmacHw_REG_CFG_LO(module, chan))); (*fpPrint) ("Module %d: Channel %d Config (HI) 0x%X\n", module, chan, (uint32_t) (dmacHw_REG_CFG_HI(module, chan))); } } else { chan = channel; (*fpPrint) ("--------------------------------------------------\n"); (*fpPrint) ("Module %d: Channel %d Source 0x%X\n", module, chan, (uint32_t) (dmacHw_REG_SAR(module, chan))); (*fpPrint) ("Module %d: Channel %d Destination 0x%X\n", module, chan, (uint32_t) (dmacHw_REG_DAR(module, chan))); (*fpPrint) ("Module %d: Channel %d LLP 0x%X\n", module, chan, (uint32_t) (dmacHw_REG_LLP(module, chan))); (*fpPrint) ("Module %d: Channel %d Control (LO) 0x%X\n", module, chan, (uint32_t) (dmacHw_REG_CTL_LO(module, chan))); (*fpPrint) ("Module %d: Channel %d Control (HI) 0x%X\n", module, chan, (uint32_t) (dmacHw_REG_CTL_HI(module, chan))); (*fpPrint) ("Module %d: Channel %d Source Stats 0x%X\n", module, chan, (uint32_t) (dmacHw_REG_SSTAT(module, chan))); (*fpPrint) ("Module %d: Channel %d Dest Stats 0x%X\n", module, chan, (uint32_t) (dmacHw_REG_DSTAT(module, chan))); (*fpPrint) ("Module %d: Channel %d Source Stats Addr 0x%X\n", module, chan, (uint32_t) (dmacHw_REG_SSTATAR(module, chan))); (*fpPrint) ("Module %d: Channel %d Dest Stats Addr 0x%X\n", module, chan, (uint32_t) (dmacHw_REG_DSTATAR(module, chan))); (*fpPrint) ("Module %d: Channel %d Config (LO) 0x%X\n", module, chan, (uint32_t) (dmacHw_REG_CFG_LO(module, chan))); (*fpPrint) ("Module %d: Channel %d Config (HI) 0x%X\n", module, chan, (uint32_t) (dmacHw_REG_CFG_HI(module, chan))); } }
void dmacHw_initiateTransfer(dmacHw_HANDLE_t handle, /* [ IN ] DMA Channel handle */ dmacHw_CONFIG_t *pConfig, /* [ IN ] Configuration settings */ void *pDescriptor /* [ IN ] Descriptor buffer */ ) { dmacHw_DESC_RING_t *pRing; dmacHw_DESC_t *pProg; dmacHw_CBLK_t *pCblk; pCblk = dmacHw_HANDLE_TO_CBLK(handle); pRing = dmacHw_GET_DESC_RING(pDescriptor); if (CHANNEL_BUSY(pCblk->module, pCblk->channel)) { /* Not safe yet to program the channel */ return; } if (pCblk->varDataStarted) { if (pCblk->descUpdated) { pCblk->descUpdated = 0; pProg = (dmacHw_DESC_t *) ((uint32_t) dmacHw_REG_LLP(pCblk->module, pCblk->channel) + pRing->virt2PhyOffset); /* Load descriptor if not loaded */ if (!(pProg->ctl.hi & dmacHw_REG_CTL_DONE)) { dmacHw_SET_SAR(pCblk->module, pCblk->channel, pProg->sar); dmacHw_SET_DAR(pCblk->module, pCblk->channel, pProg->dar); dmacHw_REG_CTL_LO(pCblk->module, pCblk->channel) = pProg->ctl.lo; dmacHw_REG_CTL_HI(pCblk->module, pCblk->channel) = pProg->ctl.hi; } else if (pProg == (dmacHw_DESC_t *) pRing->pEnd->llp) { /* Return as end descriptor is processed */ return; } else { dmacHw_ASSERT(0); } } else { return; } } else { if (pConfig->transferMode == dmacHw_TRANSFER_MODE_PERIODIC) { /* Do not make a single chain, rather process one descriptor at a time */ pProg = pRing->pHead; /* Point to the next descriptor for next iteration */ dmacHw_NEXT_DESC(pRing, pHead); } else { /* Return if no more pending descriptor */ if (pRing->pEnd == NULL) { return; } pProg = pRing->pProg; if (pConfig->transferMode == dmacHw_TRANSFER_MODE_CONTINUOUS) { /* Make sure a complete ring can be formed */ dmacHw_ASSERT((dmacHw_DESC_t *) pRing->pEnd-> llp == pRing->pProg); /* Make sure pProg pointing to the pHead */ dmacHw_ASSERT((dmacHw_DESC_t *) pRing->pProg == pRing->pHead); /* Make a complete ring */ do { pRing->pProg->ctl.lo |= (dmacHw_REG_CTL_LLP_DST_EN | dmacHw_REG_CTL_LLP_SRC_EN); pRing->pProg = (dmacHw_DESC_t *) pRing->pProg->llp; } while (pRing->pProg != pRing->pHead); } else { /* Make a single long chain */ while (pRing->pProg != pRing->pEnd) { pRing->pProg->ctl.lo |= (dmacHw_REG_CTL_LLP_DST_EN | dmacHw_REG_CTL_LLP_SRC_EN); pRing->pProg = (dmacHw_DESC_t *) pRing->pProg->llp; } } } /* Program the channel registers */ dmacHw_SET_SAR(pCblk->module, pCblk->channel, pProg->sar); dmacHw_SET_DAR(pCblk->module, pCblk->channel, pProg->dar); dmacHw_SET_LLP(pCblk->module, pCblk->channel, (uint32_t) pProg - pRing->virt2PhyOffset); dmacHw_REG_CTL_LO(pCblk->module, pCblk->channel) = pProg->ctl.lo; dmacHw_REG_CTL_HI(pCblk->module, pCblk->channel) = pProg->ctl.hi; if (pRing->pEnd) { /* Remember the descriptor to use next */ pRing->pProg = (dmacHw_DESC_t *) pRing->pEnd->llp; } /* Indicate no more pending descriptor */ pRing->pEnd = (dmacHw_DESC_t *) NULL; } /* Start DMA operation */ dmacHw_DMA_START(pCblk->module, pCblk->channel); }