/** * \brief Try to allocate a DMA channel for on given controller. * \param pDmad Pointer to DMA driver instance. * \param bXdmac xDMA controller ID (0 ~ 1). * \param bSrcID Source peripheral ID, 0xFF for memory. * \param bDstID Destination peripheral ID, 0xFF for memory. * \return Channel number if allocation sucessful, return * DMAD_ALLOC_FAILED if allocation failed. */ static uint32_t XDMAD_AllocateXdmacChannel( sXdmad *pXdmad, uint8_t bXdmac, uint8_t bSrcID, uint8_t bDstID) { uint32_t i; /* Can't support peripheral to peripheral */ if ((( bSrcID != XDMAD_TRANSFER_MEMORY ) && ( bDstID != XDMAD_TRANSFER_MEMORY ))) { return XDMAD_ALLOC_FAILED; } /* dma transfer from peripheral to memory */ if ( bDstID == XDMAD_TRANSFER_MEMORY) { if( (!XDMAIF_IsValidatedPeripherOnDma(bXdmac, bSrcID)) ) { return XDMAD_ALLOC_FAILED; } } /* dma transfer from memory to peripheral */ if ( bSrcID == XDMAD_TRANSFER_MEMORY ) { if( (!XDMAIF_IsValidatedPeripherOnDma(bXdmac, bDstID)) ) { return XDMAD_ALLOC_FAILED; } } for (i = 0; i < pXdmad->numChannels; i ++) { if ( pXdmad->XdmaChannels[bXdmac][i].state == XDMAD_STATE_FREE ) { /* Allocate the channel */ pXdmad->XdmaChannels[bXdmac][i].state = XDMAD_STATE_ALLOCATED; /* Get general informations */ pXdmad->XdmaChannels[bXdmac][i].bSrcPeriphID = bSrcID; pXdmad->XdmaChannels[bXdmac][i].bDstPeriphID = bDstID; pXdmad->XdmaChannels[bXdmac][i].bSrcTxIfID = XDMAIF_Get_ChannelNumber(bXdmac, bSrcID, 0); pXdmad->XdmaChannels[bXdmac][i].bSrcRxIfID = XDMAIF_Get_ChannelNumber(bXdmac, bSrcID, 1); pXdmad->XdmaChannels[bXdmac][i].bDstTxIfID = XDMAIF_Get_ChannelNumber(bXdmac, bDstID, 0); pXdmad->XdmaChannels[bXdmac][i].bDstTxIfID = XDMAIF_Get_ChannelNumber(bXdmac, bDstID, 1); return ((bXdmac << 8)) | ((i) & 0xFF); } } return XDMAD_ALLOC_FAILED; }
/** * \brief Configure the USART tx DMA source with Linker List mode. * * \param UsartChannel Pointer to USART dma channel * \returns 0 if the dma multibuffer configuration successfully; otherwise returns * USARTD_ERROR_XXX. */ static uint8_t _configureTxLinkList(Usart *pUsartHw, void *pXdmad, UsartChannel *pUsartTx) { sXdmadCfg xdmadTxCfg; uint32_t xdmaCndc; uint32_t usartId; if ((unsigned int)pUsartHw == (unsigned int)USART0 ) usartId = ID_USART0; if ((unsigned int)pUsartHw == (unsigned int)USART1 ) usartId = ID_USART1; if ((unsigned int)pUsartHw == (unsigned int)USART2 ) usartId = ID_USART2; /* Setup TX Link List */ xdmadTxCfg.mbr_ubc = XDMA_UBC_NVIEW_NDV0 | XDMA_UBC_NDE_FETCH_DIS| XDMA_UBC_NSEN_UPDATED | pUsartTx->BuffSize; xdmadTxCfg.mbr_sa = (uint32_t)pUsartTx->pBuff; xdmadTxCfg.mbr_da = (uint32_t)&pUsartHw->US_THR; xdmadTxCfg.mbr_cfg = XDMAC_CC_TYPE_PER_TRAN | XDMAC_CC_MBSIZE_SINGLE | XDMAC_CC_DSYNC_MEM2PER | XDMAC_CC_CSIZE_CHK_1 | XDMAC_CC_DWIDTH_BYTE| XDMAC_CC_SIF_AHB_IF0 | XDMAC_CC_DIF_AHB_IF1 | XDMAC_CC_SAM_INCREMENTED_AM | XDMAC_CC_DAM_FIXED_AM | XDMAC_CC_PERID(XDMAIF_Get_ChannelNumber( usartId, XDMAD_TRANSFER_TX )); xdmadTxCfg.mbr_bc = 0; xdmadTxCfg.mbr_sus = 0; xdmadTxCfg.mbr_dus =0; xdmaCndc = 0; if (XDMAD_ConfigureTransfer( pXdmad, pUsartTx->ChNum, &xdmadTxCfg, xdmaCndc, 0)) return USARTD_ERROR; return 0; }
/** * \brief Start waiting USART data * Start DMA, the 1st DMA buffer is free USART buffer assigned. */ static void _UsartDmaRx() { sXdmad *pDmad = &dmad; sXdmadCfg xdmadUsartRxCfg; uint32_t xdmaUsartRxCndc, xdmaInt; xdmadUsartRxCfg.mbr_cfg = XDMAC_CC_TYPE_PER_TRAN | XDMAC_CC_MBSIZE_SINGLE | XDMAC_CC_DSYNC_PER2MEM | XDMAC_CC_CSIZE_CHK_1 | XDMAC_CC_DWIDTH_BYTE | XDMAC_CC_SIF_AHB_IF1 | XDMAC_CC_DIF_AHB_IF1 | XDMAC_CC_SAM_FIXED_AM | XDMAC_CC_DAM_INCREMENTED_AM | XDMAC_CC_PERID(XDMAIF_Get_ChannelNumber(ID_USART, XDMAD_TRANSFER_RX)); xdmadUsartRxCfg.mbr_sa = dmaRxLinkList.mbr_sa; xdmadUsartRxCfg.mbr_da = dmaRxLinkList.mbr_da; xdmadUsartRxCfg.mbr_ubc = DATAPACKETSIZE; xdmadUsartRxCfg.mbr_bc = 0; xdmaUsartRxCndc = 0; xdmaInt = XDMAC_CIE_BIE; XDMAD_ConfigureTransfer(pDmad, usartDmaRxChannel, &xdmadUsartRxCfg, xdmaUsartRxCndc, (uint32_t)&dmaRxLinkList, xdmaInt); XDMAD_StartTransfer(pDmad, usartDmaRxChannel); }
/** * \brief Send single buffer data through DMA */ static void _UsartDmaTx(uint32_t dwDestAddr, void *pBuffer, uint16_t wSize) { sXdmad *pDmad = &dmad; /* Setup transfer */ sXdmadCfg xdmadCfg; xdmadCfg.mbr_ubc = wSize; xdmadCfg.mbr_sa = (uint32_t) pBuffer; xdmadCfg.mbr_da = (uint32_t) dwDestAddr; xdmadCfg.mbr_cfg = XDMAC_CC_TYPE_PER_TRAN | XDMAC_CC_MEMSET_NORMAL_MODE | XDMAC_CC_DSYNC_MEM2PER | XDMAC_CC_CSIZE_CHK_1 | XDMAC_CC_DWIDTH_BYTE | XDMAC_CC_SIF_AHB_IF1 | XDMAC_CC_DIF_AHB_IF1 | XDMAC_CC_SAM_INCREMENTED_AM | XDMAC_CC_DAM_FIXED_AM | XDMAC_CC_PERID(XDMAIF_Get_ChannelNumber(ID_USART, XDMAD_TRANSFER_TX)); xdmadCfg.mbr_bc = 0; XDMAD_ConfigureTransfer(pDmad, usartDmaTxChannel, &xdmadCfg, 0, 0, ( XDMAC_CIE_BIE | XDMAC_CIE_DIE | XDMAC_CIE_FIE | XDMAC_CIE_RBIE | XDMAC_CIE_WBIE | XDMAC_CIE_ROIE)); SCB_CleanDCache_by_Addr((uint32_t *)pBuffer, wSize); XDMAD_StartTransfer(pDmad, usartDmaTxChannel); }
static uint8_t _Afe_configureLinkList(Afec *pAfeHw, void *pXdmad, AfeCmd *pCommand) { uint32_t xdmaCndc, xdmaInt; sXdmadCfg xdmadRxCfg; uint32_t afeId; if ((unsigned int)pAfeHw == (unsigned int)AFEC0) afeId = ID_AFEC0; if ((unsigned int)pAfeHw == (unsigned int)AFEC1) afeId = ID_AFEC1; /* Setup RX Link List */ xdmadRxCfg.mbr_ubc = XDMA_UBC_NVIEW_NDV0 | XDMA_UBC_NDE_FETCH_DIS | XDMA_UBC_NDEN_UPDATED | pCommand->RxSize; xdmadRxCfg.mbr_da = (uint32_t)pCommand->pRxBuff; xdmadRxCfg.mbr_sa = (uint32_t) & (pAfeHw->AFEC_LCDR); xdmadRxCfg.mbr_cfg = XDMAC_CC_TYPE_PER_TRAN | XDMAC_CC_MBSIZE_SINGLE | XDMAC_CC_DSYNC_PER2MEM | XDMAC_CC_CSIZE_CHK_1 | XDMAC_CC_DWIDTH_WORD | XDMAC_CC_SIF_AHB_IF1 | XDMAC_CC_DIF_AHB_IF1 | XDMAC_CC_SAM_FIXED_AM | XDMAC_CC_DAM_INCREMENTED_AM | XDMAC_CC_PERID( XDMAIF_Get_ChannelNumber(afeId, XDMAD_TRANSFER_RX)); xdmadRxCfg.mbr_bc = 0; xdmadRxCfg.mbr_sus = 0; xdmadRxCfg.mbr_dus = 0; xdmaInt = (XDMAC_CIE_BIE | XDMAC_CIE_DIE | XDMAC_CIE_FIE | XDMAC_CIE_RBIE | XDMAC_CIE_WBIE | XDMAC_CIE_ROIE); xdmaCndc = 0; if (XDMAD_ConfigureTransfer(pXdmad, afeDmaRxChannel, &xdmadRxCfg, xdmaCndc, 0, xdmaInt)) return AFE_ERROR; return AFE_OK; }
static uint8_t _Dac_configureLinkList(Dacc *pDacHw, void *pXdmad, DacCmd *pCommand) { uint32_t xdmaCndc; sXdmadCfg xdmadCfg; uint32_t *pBuffer; /* Setup TX Link List */ uint8_t i; pBuffer = (uint32_t *)pCommand->pTxBuff; for (i = 0; i < pCommand->TxSize; i++) { dmaWriteLinkList[i].mbr_ubc = XDMA_UBC_NVIEW_NDV1 | XDMA_UBC_NDE_FETCH_EN | XDMA_UBC_NSEN_UPDATED | XDMAC_CUBC_UBLEN(4); dmaWriteLinkList[i].mbr_sa = (uint32_t)pBuffer; dmaWriteLinkList[i].mbr_da = (uint32_t) & (pDacHw->DACC_CDR[pCommand->dacChannel]); if (i == (pCommand->TxSize - 1)) { if (pCommand->loopback) dmaWriteLinkList[i].mbr_nda = (uint32_t)&dmaWriteLinkList[0]; else dmaWriteLinkList[i].mbr_nda = 0; } else dmaWriteLinkList[i].mbr_nda = (uint32_t)&dmaWriteLinkList[i + 1]; pBuffer++; } xdmadCfg.mbr_cfg = XDMAC_CC_TYPE_PER_TRAN | XDMAC_CC_MBSIZE_SINGLE | XDMAC_CC_DSYNC_MEM2PER | XDMAC_CC_CSIZE_CHK_1 | XDMAC_CC_DWIDTH_WORD | XDMAC_CC_SIF_AHB_IF1 | XDMAC_CC_DIF_AHB_IF1 | XDMAC_CC_SAM_INCREMENTED_AM | XDMAC_CC_DAM_FIXED_AM | XDMAC_CC_PERID( XDMAIF_Get_ChannelNumber(ID_DACC, XDMAD_TRANSFER_TX)); xdmaCndc = XDMAC_CNDC_NDVIEW_NDV1 | XDMAC_CNDC_NDE_DSCR_FETCH_EN | XDMAC_CNDC_NDSUP_SRC_PARAMS_UPDATED | XDMAC_CNDC_NDDUP_DST_PARAMS_UPDATED; XDMAD_ConfigureTransfer(pXdmad, dacDmaTxChannel, &xdmadCfg, xdmaCndc, (uint32_t)&dmaWriteLinkList[0], XDMAC_CIE_LIE); return DAC_OK; }
/** * \brief Start USART waiting data. */ static void _DmaUsartRx(void) { uint32_t status; /* Read USART status */ status = USART->US_CSR; if ((status & US_CSR_RXRDY) == US_CSR_RXRDY) status = USART->US_RHR; /* clear the US_CSR_RXRDY*/ sXdmadCfg xdmadCfg; xdmadCfg.mbr_ubc = BUFFER_SIZE - 1; xdmadCfg.mbr_sa = (uint32_t)&USART->US_RHR; xdmadCfg.mbr_da = (uint32_t)pRecvBufferUSART; xdmadCfg.mbr_cfg = XDMAC_CC_TYPE_PER_TRAN | XDMAC_CC_MBSIZE_SINGLE | XDMAC_CC_DSYNC_PER2MEM | XDMAC_CC_CSIZE_CHK_1 | XDMAC_CC_DWIDTH_BYTE | XDMAC_CC_SIF_AHB_IF1 | XDMAC_CC_DIF_AHB_IF1 | XDMAC_CC_SAM_FIXED_AM | XDMAC_CC_DAM_INCREMENTED_AM | XDMAC_CC_PERID( XDMAIF_Get_ChannelNumber(ID_USART, XDMAD_TRANSFER_RX) ); xdmadCfg.mbr_bc = 0; xdmadCfg.mbr_ds = 0; xdmadCfg.mbr_sus = 0; xdmadCfg.mbr_dus = 0; XDMAD_ConfigureTransfer( &dmad, usartDmaRxChannel, &xdmadCfg, 0, 0, XDMAC_CIE_BIE | XDMAC_CIE_DIE | XDMAC_CIE_FIE | XDMAC_CIE_RBIE | XDMAC_CIE_WBIE | XDMAC_CIE_ROIE); XDMAD_StartTransfer(&dmad, usartDmaRxChannel); }
/** * \brief xDMA transfer PWM duty */ static void _PwmDmaTransfer(void) { sXdmadCfg xdmadCfg; uint32_t xdmaCndc; uint32_t i; for(i = 0; i < DUTY_BUFFER_LENGTH; i++){ dmaWriteLinkList[i].mbr_ubc = XDMA_UBC_NVIEW_NDV1 | XDMA_UBC_NDE_FETCH_EN | XDMA_UBC_NSEN_UPDATED | XDMAC_CUBC_UBLEN(1); dmaWriteLinkList[i].mbr_sa = (uint32_t)(&dwDutys[i]); dmaWriteLinkList[i].mbr_da = (uint32_t)(&(PWM0->PWM_DMAR)); if ( i == (DUTY_BUFFER_LENGTH - 1 )) { dmaWriteLinkList[i].mbr_nda = (uint32_t)&dmaWriteLinkList[0]; } else { dmaWriteLinkList[i].mbr_nda = (uint32_t)&dmaWriteLinkList[i+1]; } } xdmadCfg.mbr_cfg = XDMAC_CC_TYPE_PER_TRAN | XDMAC_CC_MBSIZE_SINGLE | XDMAC_CC_DSYNC_MEM2PER | XDMAC_CC_CSIZE_CHK_1 | XDMAC_CC_DWIDTH_HALFWORD | XDMAC_CC_SIF_AHB_IF0 | XDMAC_CC_DIF_AHB_IF1 | XDMAC_CC_SAM_FIXED_AM | XDMAC_CC_DAM_FIXED_AM | XDMAC_CC_PERID(XDMAIF_Get_ChannelNumber(ID_PWM0, XDMAD_TRANSFER_TX )); xdmaCndc = XDMAC_CNDC_NDVIEW_NDV1 | XDMAC_CNDC_NDE_DSCR_FETCH_EN | XDMAC_CNDC_NDSUP_SRC_PARAMS_UPDATED | XDMAC_CNDC_NDDUP_DST_PARAMS_UPDATED ; XDMAD_ConfigureTransfer( &dmad, pwmDmaTxChannel, &xdmadCfg, xdmaCndc, (uint32_t)&dmaWriteLinkList[0], XDMAC_CIE_LIE); SCB_CleanInvalidateDCache(); XDMAD_StartTransfer( &dmad, pwmDmaTxChannel); }
/** * \brief Start DMA sending/waiting data. */ static void _SscDma(volatile uint32_t *pReg, uint32_t dmaChannel, void *pBuffer, uint16_t wSize) { sXdmad *pDmad = &dmad; sXdmadCfg xdmadCfg; xdmadCfg.mbr_ubc = wSize; xdmadCfg.mbr_sa = (uint32_t) pBuffer; xdmadCfg.mbr_da = (uint32_t) pReg; xdmadCfg.mbr_cfg = XDMAC_CC_TYPE_PER_TRAN | XDMAC_CC_MBSIZE_SINGLE | XDMAC_CC_DSYNC_MEM2PER | XDMAC_CC_CSIZE_CHK_1 | XDMAC_CC_DWIDTH_HALFWORD | XDMAC_CC_SIF_AHB_IF1 | XDMAC_CC_DIF_AHB_IF1 | XDMAC_CC_SAM_INCREMENTED_AM | XDMAC_CC_DAM_FIXED_AM | XDMAC_CC_PERID(XDMAIF_Get_ChannelNumber( ID_SSC, XDMAD_TRANSFER_TX)); xdmadCfg.mbr_bc = 0; xdmadCfg.mbr_ds = 0; xdmadCfg.mbr_sus = 0; xdmadCfg.mbr_dus = 0; memory_sync(); XDMAD_ConfigureTransfer(pDmad, dmaChannel, &xdmadCfg, 0, 0, ( XDMAC_CIE_BIE | XDMAC_CIE_DIE | XDMAC_CIE_FIE | XDMAC_CIE_RBIE | XDMAC_CIE_WBIE | XDMAC_CIE_ROIE)); SCB_CleanDCache_by_Addr((uint32_t *)pBuffer, wSize); XDMAD_StartTransfer(pDmad, dmaChannel); SSC_EnableTransmitter(SSC); }
/** * \brief Start USART sending data. */ static void _DmaUsartTx(void) { sXdmadCfg xdmadCfg; xdmadCfg.mbr_ubc = BUFFER_SIZE; xdmadCfg.mbr_sa = (uint32_t)Buffer; xdmadCfg.mbr_da = (uint32_t)&USART->US_THR; xdmadCfg.mbr_cfg = XDMAC_CC_TYPE_PER_TRAN | XDMAC_CC_MBSIZE_SINGLE | XDMAC_CC_DSYNC_MEM2PER | XDMAC_CC_CSIZE_CHK_1 | XDMAC_CC_DWIDTH_BYTE | XDMAC_CC_SIF_AHB_IF1 | XDMAC_CC_DIF_AHB_IF1 | XDMAC_CC_SAM_INCREMENTED_AM | XDMAC_CC_DAM_FIXED_AM | XDMAC_CC_PERID( XDMAIF_Get_ChannelNumber(ID_USART, XDMAD_TRANSFER_TX) ); xdmadCfg.mbr_bc = 0; xdmadCfg.mbr_ds = 0; xdmadCfg.mbr_sus = 0; xdmadCfg.mbr_dus = 0; XDMAD_ConfigureTransfer( &dmad, usartDmaTxChannel, &xdmadCfg, 0, 0, XDMAC_CIE_BIE | XDMAC_CIE_DIE | XDMAC_CIE_FIE | XDMAC_CIE_RBIE | XDMAC_CIE_WBIE | XDMAC_CIE_ROIE); SCB_CleanDCache_by_Addr((uint32_t*)Buffer, BUFFER_SIZE); XDMAD_StartTransfer(&dmad, usartDmaTxChannel); }
/** * \brief Configure the DMA source and destination with Linker List mode. * * \param pCommand Pointer to command * \returns 0 if the dma multibuffer configuration successfully; otherwise returns * SPID_ERROR_XXX. */ static uint8_t _spid_configureLinkList(Spi *pSpiHw, void *pXdmad, SpidCmd *pCommand) { sXdmadCfg xdmadRxCfg,xdmadTxCfg; uint32_t xdmaCndc; uint32_t spiId; if ((unsigned int)pSpiHw == (unsigned int)SPI0 ) spiId = ID_SPI0; if ((unsigned int)pSpiHw == (unsigned int)SPI1 ) spiId = ID_SPI1; /* Setup TX */ xdmadTxCfg.mbr_sa = (uint32_t)pCommand->pTxBuff; xdmadTxCfg.mbr_da = (uint32_t)&pSpiHw->SPI_TDR; xdmadTxCfg.mbr_ubc = XDMA_UBC_NVIEW_NDV0 | XDMA_UBC_NDE_FETCH_DIS| XDMA_UBC_NSEN_UPDATED | pCommand->TxSize; xdmadTxCfg.mbr_cfg = XDMAC_CC_TYPE_PER_TRAN | XDMAC_CC_MBSIZE_SINGLE | XDMAC_CC_DSYNC_MEM2PER | XDMAC_CC_CSIZE_CHK_1 | XDMAC_CC_DWIDTH_BYTE| XDMAC_CC_SIF_AHB_IF0 | XDMAC_CC_DIF_AHB_IF1 | XDMAC_CC_SAM_INCREMENTED_AM | XDMAC_CC_DAM_FIXED_AM | XDMAC_CC_PERID(XDMAIF_Get_ChannelNumber( spiId, XDMAD_TRANSFER_TX )); xdmadTxCfg.mbr_bc = 0; xdmadTxCfg.mbr_sus = 0; xdmadTxCfg.mbr_dus =0; /* Setup RX Link List */ xdmadRxCfg.mbr_ubc = XDMA_UBC_NVIEW_NDV0 | XDMA_UBC_NDE_FETCH_DIS| XDMA_UBC_NDEN_UPDATED | pCommand->RxSize; xdmadRxCfg.mbr_da = (uint32_t)pCommand->pRxBuff; xdmadRxCfg.mbr_sa = (uint32_t)&pSpiHw->SPI_RDR; xdmadRxCfg.mbr_cfg = XDMAC_CC_TYPE_PER_TRAN | XDMAC_CC_MBSIZE_SINGLE | XDMAC_CC_DSYNC_PER2MEM | XDMAC_CC_CSIZE_CHK_1 | XDMAC_CC_DWIDTH_BYTE| XDMAC_CC_SIF_AHB_IF1 | XDMAC_CC_DIF_AHB_IF0 | XDMAC_CC_SAM_FIXED_AM | XDMAC_CC_DAM_INCREMENTED_AM | XDMAC_CC_PERID(XDMAIF_Get_ChannelNumber( spiId, XDMAD_TRANSFER_RX )); xdmadRxCfg.mbr_bc = 0; xdmadRxCfg.mbr_sus = 0; xdmadRxCfg.mbr_dus =0; xdmaCndc = 0; if (XDMAD_ConfigureTransfer( pXdmad, spiDmaRxChannel, &xdmadRxCfg, xdmaCndc, 0)) return SPID_ERROR; if (XDMAD_ConfigureTransfer( pXdmad, spiDmaTxChannel, &xdmadTxCfg, xdmaCndc, 0)) return SPID_ERROR; return 0; }
/** * \brief Configure the UART Tx DMA mode. * * \param pUartHw Pointer to UART instance * \param pXdmad Pointer to XDMA instance * \param pUsartTx Pointer to Usart Tx channel * \returns 0 if the dma multibuffer configuration successfully; otherwise returns * USARTD_ERROR_XXX. */ static uint8_t _configureUartTxDma(Uart *pUartHw, void *pXdmad, UartChannel *pUartTx) { sXdmadCfg xdmadTxCfg; uint32_t xdmaCndc, xdmaInt; uint32_t uartId, LLI_Size; uint8_t *pBuff = 0, i; if ((unsigned int)pUartHw == (unsigned int)UART0 ) uartId = ID_UART0; if ((unsigned int)pUartHw == (unsigned int)UART1 ) uartId = ID_UART1; if ((unsigned int)pUartHw == (unsigned int)UART2 ) uartId = ID_UART2; if ((unsigned int)pUartHw == (unsigned int)UART3 ) uartId = ID_UART3; if ((unsigned int)pUartHw == (unsigned int)UART4 ) uartId = ID_UART4; /* Setup TX */ if(pUartTx->dmaProgrammingMode < XDMAD_LLI) { xdmadTxCfg.mbr_ubc = XDMA_UBC_NVIEW_NDV0 | XDMA_UBC_NDE_FETCH_DIS| XDMA_UBC_NSEN_UPDATED | pUartTx->BuffSize; xdmadTxCfg.mbr_sa = (uint32_t)pUartTx->pBuff; xdmadTxCfg.mbr_da = (uint32_t)&pUartHw->UART_THR; xdmadTxCfg.mbr_cfg = XDMAC_CC_TYPE_PER_TRAN | XDMAC_CC_MBSIZE_SINGLE | XDMAC_CC_DSYNC_MEM2PER | XDMAC_CC_CSIZE_CHK_1 | XDMAC_CC_DWIDTH_BYTE| XDMAC_CC_SIF_AHB_IF0 | XDMAC_CC_DIF_AHB_IF1 | XDMAC_CC_SAM_INCREMENTED_AM | XDMAC_CC_DAM_FIXED_AM | XDMAC_CC_PERID(XDMAIF_Get_ChannelNumber( uartId, XDMAD_TRANSFER_TX )); xdmadTxCfg.mbr_bc = 0; xdmadTxCfg.mbr_sus = 0; xdmadTxCfg.mbr_dus =0; xdmaCndc = 0; xdmaInt = (XDMAC_CIE_BIE | XDMAC_CIE_DIE | XDMAC_CIE_FIE | XDMAC_CIE_RBIE | XDMAC_CIE_WBIE | XDMAC_CIE_ROIE); } if(pUartTx->dmaProgrammingMode == XDMAD_LLI) { LLI_Size = pUartTx->dmaLLI_Size; pBuff = pUartTx->pBuff; if(pLLIviewTx == NULL) { pLLIviewTx = malloc(sizeof(LinkedListDescriporView1)*LLI_Size); } xdmadTxCfg.mbr_cfg = XDMAC_CC_TYPE_PER_TRAN | XDMAC_CC_MBSIZE_SINGLE | XDMAC_CC_DSYNC_MEM2PER | XDMAC_CC_MEMSET_NORMAL_MODE | XDMAC_CC_CSIZE_CHK_1 | XDMAC_CC_DWIDTH_BYTE | XDMAC_CC_SIF_AHB_IF0 | XDMAC_CC_DIF_AHB_IF1 | XDMAC_CC_SAM_INCREMENTED_AM | XDMAC_CC_DAM_FIXED_AM | XDMAC_CC_PERID(XDMAIF_Get_ChannelNumber( uartId, XDMAD_TRANSFER_TX )); xdmadTxCfg.mbr_bc = 0; for (i = 0; i < LLI_Size; i++) { pLLIviewTx[i].mbr_ubc = XDMA_UBC_NVIEW_NDV1 | XDMA_UBC_NSEN_UPDATED | XDMA_UBC_NDEN_UNCHANGED | ((i== LLI_Size- 1)? ( (pUartTx->dmaRingBuffer)? XDMA_UBC_NDE_FETCH_EN : 0): XDMA_UBC_NDE_FETCH_EN) | pUartTx->BuffSize; pLLIviewTx[i].mbr_da = (uint32_t)&pUartHw->UART_THR; pLLIviewTx[i].mbr_sa = (uint32_t)pBuff; pLLIviewTx[i].mbr_nda = (i == ( LLI_Size - 1))? ( (pUartTx->dmaRingBuffer)? (uint32_t)&pLLIviewTx[ 0] : 0 ):(uint32_t)&pLLIviewTx[ i + 1 ]; pBuff += pUartTx->BuffSize; } xdmaCndc = XDMAC_CNDC_NDVIEW_NDV1 | XDMAC_CNDC_NDE_DSCR_FETCH_EN | XDMAC_CNDC_NDSUP_SRC_PARAMS_UPDATED| XDMAC_CNDC_NDDUP_DST_PARAMS_UPDATED ; xdmaInt = ((pUartTx->dmaRingBuffer)? XDMAC_CIE_BIE : XDMAC_CIE_LIE); } if (XDMAD_ConfigureTransfer( pXdmad, pUartTx->ChNum, &xdmadTxCfg, xdmaCndc, (uint32_t)&pLLIviewTx[0], xdmaInt)) return USARTD_ERROR; SCB_CleanInvalidateDCache(); return 0; }
/** * \brief Configure the UART Tx DMA mode. * * \param pUartHw Pointer to UART instance * \param pXdmad Pointer to XDMA instance * \param pUsartTx Pointer to Usart Tx channel * \returns 0 if the dma multibuffer configuration successfully; otherwise * returns USARTD_ERROR_XXX. */ static uint8_t _configureUartTxDma(UartDma *pUartd, UartChannel *pUartTx) { sXdmadCfg xdmadTxCfg; uint32_t xdmaCndc, xdmaInt, LLI_Size, i; uint8_t *pBuff = 0; Uart *pUartHwTx = pUartd->pUartHw; sXdmad* pXdmadTx = pUartd->pXdmad; /* Setup TX */ if(pUartTx->dmaProgrammingMode < XDMAD_LLI) { xdmadTxCfg.mbr_ubc = pUartTx->BuffSize; xdmadTxCfg.mbr_sa = (uint32_t)pUartTx->pBuff; xdmadTxCfg.mbr_da = (uint32_t)&pUartHwTx->UART_THR; xdmadTxCfg.mbr_cfg = XDMAC_CC_TYPE_PER_TRAN | XDMAC_CC_MBSIZE_SIXTEEN | XDMAC_CC_DSYNC_MEM2PER | XDMAC_CC_CSIZE_CHK_1 | XDMAC_CC_DWIDTH_BYTE| XDMAC_CC_SIF_AHB_IF0 | XDMAC_CC_DIF_AHB_IF1 | XDMAC_CC_SAM_INCREMENTED_AM | XDMAC_CC_DAM_FIXED_AM | XDMAC_CC_PERID(XDMAIF_Get_ChannelNumber( pUartd->uartId, XDMAD_TRANSFER_TX )); xdmadTxCfg.mbr_bc = 0; if(pUartTx->dmaProgrammingMode == XDMAD_MULTI) { xdmadTxCfg.mbr_bc = pUartTx->dmaBlockSize; } xdmadTxCfg.mbr_sus = 0; xdmadTxCfg.mbr_dus =0; xdmadTxCfg.mbr_ds= 0; xdmaCndc = 0; /* Enable End of Block; Read Bus error; Write Bus Error; Overflow Error interrupt */ xdmaInt = (XDMAC_CIE_BIE | XDMAC_CIE_RBIE | XDMAC_CIE_WBIE | XDMAC_CIE_ROIE); } else if(pUartTx->dmaProgrammingMode == XDMAD_LLI) { LLI_Size = pUartTx->dmaBlockSize; pBuff = pUartTx->pBuff; if(pUartTx->pLLIview != NULL) { free(pUartTx->pLLIview); pUartTx->pLLIview = NULL; } pUartTx->pLLIview = malloc(sizeof(LinkedListDescriporView1)*LLI_Size); if( pUartTx->pLLIview == NULL) { TRACE_ERROR(" Can not allocate memory to Tx LLI"); return USARTD_ERROR; } xdmadTxCfg.mbr_cfg = XDMAC_CC_TYPE_PER_TRAN | XDMAC_CC_MBSIZE_SIXTEEN | XDMAC_CC_DSYNC_MEM2PER | XDMAC_CC_MEMSET_NORMAL_MODE | XDMAC_CC_CSIZE_CHK_1 | XDMAC_CC_DWIDTH_BYTE | XDMAC_CC_SIF_AHB_IF0 | XDMAC_CC_DIF_AHB_IF1 | XDMAC_CC_SAM_INCREMENTED_AM | XDMAC_CC_DAM_FIXED_AM | XDMAC_CC_PERID(XDMAIF_Get_ChannelNumber( pUartd->uartId, XDMAD_TRANSFER_TX )); xdmadTxCfg.mbr_bc = 0; for (i = 0; i < LLI_Size; i++) { pUartTx->pLLIview[i].mbr_ubc = XDMA_UBC_NVIEW_NDV1 | XDMA_UBC_NSEN_UPDATED | XDMA_UBC_NDEN_UNCHANGED | ((i== LLI_Size- 1)? ( (pUartTx->dmaRingBuffer)? XDMA_UBC_NDE_FETCH_EN : 0): XDMA_UBC_NDE_FETCH_EN) | pUartTx->BuffSize; pUartTx->pLLIview[i].mbr_da = (uint32_t)&pUartHwTx->UART_THR; pUartTx->pLLIview[i].mbr_sa = (uint32_t)pBuff; pUartTx->pLLIview[i].mbr_nda = (i == ( LLI_Size - 1))? ( (pUartTx->dmaRingBuffer)? (uint32_t)pUartTx->pLLIview : 0 ): (uint32_t)&pUartTx->pLLIview[ i + 1 ]; pBuff += pUartTx->BuffSize; } xdmaCndc = XDMAC_CNDC_NDVIEW_NDV1 | XDMAC_CNDC_NDE_DSCR_FETCH_EN | XDMAC_CNDC_NDSUP_SRC_PARAMS_UPDATED| XDMAC_CNDC_NDDUP_DST_PARAMS_UPDATED ; xdmaInt = ((pUartTx->dmaRingBuffer)? XDMAC_CIE_BIE : XDMAC_CIE_LIE); } else { TRACE_ERROR("DmaProgState is incorrect \n\r"); return 1; } memory_barrier(); if (XDMAD_ConfigureTransfer( pXdmadTx, pUartTx->ChNum, &xdmadTxCfg, xdmaCndc, (uint32_t)pUartTx->pLLIview, xdmaInt)) return USARTD_ERROR; return 0; }
/** * \brief Receive and play audio with DMA. */ static void PlayRecording(void) { uint32_t src; uint8_t i; uint32_t xdmaCndc; src = 0x20440000; for(i = 0; i < TOTAL_Buffers; i++){ dmaReadLinkList[i].mbr_ubc = XDMA_UBC_NVIEW_NDV1 | XDMA_UBC_NDE_FETCH_EN | XDMA_UBC_NSEN_UPDATED | XDMAC_CUBC_UBLEN(0x1000); dmaReadLinkList[i].mbr_sa = (uint32_t)&(AUDIO_IF->SSC_RHR); dmaReadLinkList[i].mbr_da = (uint32_t)(src ); if ( i == (TOTAL_Buffers - 1)){ dmaReadLinkList[i].mbr_nda = (uint32_t)&dmaReadLinkList[0]; } else { dmaReadLinkList[i].mbr_nda = (uint32_t)&dmaReadLinkList[i + 1]; } src += (0x1000 * (BITS_BY_SLOT/8)); } xdmadCfg.mbr_cfg = XDMAC_CC_TYPE_PER_TRAN | XDMAC_CC_MBSIZE_SINGLE | XDMAC_CC_DSYNC_PER2MEM | XDMAC_CC_CSIZE_CHK_1 | XDMAC_CC_DWIDTH_HALFWORD | XDMAC_CC_SIF_AHB_IF1 | XDMAC_CC_DIF_AHB_IF0 | XDMAC_CC_SAM_FIXED_AM | XDMAC_CC_DAM_INCREMENTED_AM | XDMAC_CC_PERID(XDMAIF_Get_ChannelNumber(ID_SSC, XDMAD_TRANSFER_RX )); xdmaCndc = XDMAC_CNDC_NDVIEW_NDV1 | XDMAC_CNDC_NDE_DSCR_FETCH_EN | XDMAC_CNDC_NDSUP_SRC_PARAMS_UPDATED | XDMAC_CNDC_NDDUP_DST_PARAMS_UPDATED ; XDMAD_ConfigureTransfer( &dmad, sscDmaRxChannel, &xdmadCfg, xdmaCndc, (uint32_t)&dmaReadLinkList[0],XDMAC_CIE_LIE); SCB_CleanInvalidateDCache(); src = 0x20440000; for(i = 0; i < TOTAL_Buffers; i++){ dmaWriteLinkList[i].mbr_ubc = XDMA_UBC_NVIEW_NDV1 | XDMA_UBC_NDE_FETCH_EN | XDMA_UBC_NSEN_UPDATED | XDMAC_CUBC_UBLEN(0x1000); dmaWriteLinkList[i].mbr_sa = (uint32_t)(src ); dmaWriteLinkList[i].mbr_da = (uint32_t)&(AUDIO_IF->SSC_THR); if ( i == (TOTAL_Buffers - 1 )) { dmaWriteLinkList[i].mbr_nda = (uint32_t)&dmaWriteLinkList[0]; } else { dmaWriteLinkList[i].mbr_nda = (uint32_t)&dmaWriteLinkList[i+1]; } src += (0x1000 * (BITS_BY_SLOT/8)); } xdmadCfg.mbr_cfg = XDMAC_CC_TYPE_PER_TRAN | XDMAC_CC_MBSIZE_SINGLE | XDMAC_CC_DSYNC_MEM2PER | XDMAC_CC_CSIZE_CHK_1 | XDMAC_CC_DWIDTH_HALFWORD | XDMAC_CC_SIF_AHB_IF0 | XDMAC_CC_DIF_AHB_IF1 | XDMAC_CC_SAM_INCREMENTED_AM | XDMAC_CC_DAM_FIXED_AM | XDMAC_CC_PERID(XDMAIF_Get_ChannelNumber(ID_SSC, XDMAD_TRANSFER_TX )); xdmaCndc = XDMAC_CNDC_NDVIEW_NDV1 | XDMAC_CNDC_NDE_DSCR_FETCH_EN | XDMAC_CNDC_NDSUP_SRC_PARAMS_UPDATED | XDMAC_CNDC_NDDUP_DST_PARAMS_UPDATED ; XDMAD_ConfigureTransfer( &dmad, sscDmaTxChannel, &xdmadCfg, xdmaCndc, (uint32_t)&dmaWriteLinkList[0],XDMAC_CIE_LIE); SCB_CleanInvalidateDCache(); XDMAD_StartTransfer( &dmad, sscDmaRxChannel ); SSC_EnableReceiver(AUDIO_IF); Wait(3000); /* Enable playback(SSC TX) */ SCB_CleanInvalidateDCache(); XDMAD_StartTransfer( &dmad, sscDmaTxChannel); SSC_EnableTransmitter(AUDIO_IF); }
/** * \brief Configures the DMA for QSPI * * \param pQspidma Pointer to QSPI DMA structure * \param Addr Address to Read or write of QSPI flash memory * \param pBuffer Pointer input/output buffer * \param ReadWrite Read or write memory flag * \returns 0 if the dma multibuffer configuration successfully; otherwise returns * QSPID_ERROR_XXX. */ static uint8_t QSPID_configureQpsiDma(QspiDma_t *pQspidma, uint32_t Addr, QspiBuffer_t *pBuffer, Access_t const ReadWrite) { sXdmadCfg xdmadCfg, xdmadRxCfg, xdmadTxCfg; uint8_t chanNum; uint8_t qspi_id = pQspidma->Qspid.qspiId; Qspi *pQspiHw = pQspidma->Qspid.pQspiHw; uint32_t xdmaCndc, xdmaInt, BurstSize, ChannelWidth; /* Setup DMA for QSPI */ if (pQspidma->Qspid.qspiMode == QSPI_MR_SMM_SPI) { // SPI mode /* SPI TX DMA config */ xdmadTxCfg.mbr_sa = (uint32_t)pBuffer->pDataTx; xdmadTxCfg.mbr_da = (uint32_t)&pQspiHw->QSPI_TDR; xdmadTxCfg.mbr_ubc = (pBuffer->TxDataSize); xdmadTxCfg.mbr_cfg = XDMAC_CC_TYPE_PER_TRAN | XDMAC_CC_MBSIZE_SINGLE | XDMAC_CC_DSYNC_MEM2PER | XDMAC_CC_CSIZE_CHK_1 | XDMAC_CC_DWIDTH_BYTE | XDMAC_CC_SIF_AHB_IF0 | XDMAC_CC_DIF_AHB_IF1 | XDMAC_CC_SAM_INCREMENTED_AM | XDMAC_CC_DAM_FIXED_AM | XDMAC_CC_PERID(XDMAIF_Get_ChannelNumber (qspi_id, XDMAD_TRANSFER_TX)); xdmadTxCfg.mbr_bc = 0; xdmadTxCfg.mbr_sus = 0; xdmadTxCfg.mbr_dus = 0; /* SPI RX DMA config */ xdmadRxCfg.mbr_da = (uint32_t)pBuffer->pDataRx; xdmadRxCfg.mbr_sa = (uint32_t)&pQspiHw->QSPI_RDR; xdmadRxCfg.mbr_ubc = (pBuffer->RxDataSize); xdmadRxCfg.mbr_cfg = XDMAC_CC_TYPE_PER_TRAN | XDMAC_CC_MBSIZE_SINGLE | XDMAC_CC_DSYNC_PER2MEM | XDMAC_CC_CSIZE_CHK_1 | XDMAC_CC_DWIDTH_BYTE | XDMAC_CC_SIF_AHB_IF1 | XDMAC_CC_DIF_AHB_IF0 | XDMAC_CC_SAM_FIXED_AM | XDMAC_CC_DAM_INCREMENTED_AM | XDMAC_CC_PERID(XDMAIF_Get_ChannelNumber (qspi_id, XDMAD_TRANSFER_RX)); xdmadRxCfg.mbr_bc = 0; xdmadRxCfg.mbr_sus = 0; xdmadRxCfg.mbr_dus = 0; xdmaCndc = 0; /* Put all interrupts on for non LLI list setup of DMA */ xdmaInt = (XDMAC_CIE_BIE | XDMAC_CIE_RBIE | XDMAC_CIE_WBIE | XDMAC_CIE_ROIE); memory_barrier(); if (XDMAD_ConfigureTransfer (pQspidma->pXdmad, pQspidma->RxChNum, &xdmadRxCfg, xdmaCndc, 0, xdmaInt)) return QSPID_ERROR; if (XDMAD_ConfigureTransfer (pQspidma->pXdmad, pQspidma->TxChNum, &xdmadTxCfg, xdmaCndc, 0, xdmaInt)) return QSPID_ERROR; return 0; } else { if (ReadWrite == WriteAccess) { xdmadCfg.mbr_sa = (uint32_t)pBuffer->pDataTx; xdmadCfg.mbr_da = (uint32_t)(QSPIMEM_ADDR | Addr); xdmadCfg.mbr_ubc = (pBuffer->TxDataSize); chanNum = pQspidma->TxChNum; ChannelWidth = XDMAC_CC_DWIDTH_BYTE; BurstSize = XDMAC_CC_MBSIZE_SIXTEEN; } else if (ReadWrite == ReadAccess) { xdmadCfg.mbr_da = (uint32_t)pBuffer->pDataRx; xdmadCfg.mbr_sa = (uint32_t)(QSPIMEM_ADDR | Addr); xdmadCfg.mbr_ubc = ((pBuffer->RxDataSize >> 2)); chanNum = pQspidma->RxChNum; ChannelWidth = XDMAC_CC_DWIDTH_WORD; BurstSize = XDMAC_CC_MBSIZE_SIXTEEN; } else {
/** * \brief Configure the UART Rx DMA mode. * * \param pUartHw Pointer to UART instance * \param pXdmad Pointer to XDMA instance * \param pUsartRx Pointer to Usart Rx channel * \returns 0 if the dma multibuffer configuration successfully; otherwise * returns USARTD_ERROR_XXX. */ static uint8_t _configureUartRxDma(UartDma *pUartd , UartChannel *pUartRx) { sXdmadCfg xdmadRxCfg; uint32_t xdmaCndc, xdmaInt; uint32_t i, LLI_Size; Uart *pUartHwRx = pUartd->pUartHw; sXdmad* pXdmadRx = pUartd->pXdmad; uint8_t *pBuff = 0; /* Setup RX Single block */ if(pUartRx->dmaProgrammingMode < XDMAD_LLI) { xdmadRxCfg.mbr_ubc = pUartRx->BuffSize; xdmadRxCfg.mbr_da = (uint32_t)pUartRx->pBuff; xdmadRxCfg.mbr_sa = (uint32_t)&pUartHwRx->UART_RHR; xdmadRxCfg.mbr_cfg = XDMAC_CC_TYPE_PER_TRAN | XDMAC_CC_MBSIZE_SIXTEEN | XDMAC_CC_DSYNC_PER2MEM | XDMAC_CC_CSIZE_CHK_1 | XDMAC_CC_DWIDTH_BYTE | XDMAC_CC_SIF_AHB_IF1 | XDMAC_CC_DIF_AHB_IF0 | XDMAC_CC_SAM_FIXED_AM | XDMAC_CC_DAM_INCREMENTED_AM | XDMAC_CC_PERID(XDMAIF_Get_ChannelNumber ( pUartd->uartId, XDMAD_TRANSFER_RX )); xdmadRxCfg.mbr_bc = 0; if(pUartRx->dmaProgrammingMode == XDMAD_MULTI) { xdmadRxCfg.mbr_bc = pUartRx->dmaBlockSize; } xdmadRxCfg.mbr_sus = 0; xdmadRxCfg.mbr_dus =0; xdmaCndc = 0; /* Put all interrupts on for non LLI list setup of DMA */ xdmaInt = (XDMAC_CIE_BIE | XDMAC_CIE_DIE | XDMAC_CIE_FIE | XDMAC_CIE_RBIE | XDMAC_CIE_WBIE | XDMAC_CIE_ROIE); } else if(pUartRx->dmaProgrammingMode == XDMAD_LLI) { /* Setup RX Link List */ LLI_Size = pUartRx->dmaBlockSize; pBuff = pUartRx->pBuff; if(pUartRx->pLLIview != NULL) { free(pUartRx->pLLIview); pUartRx->pLLIview = NULL; } pUartRx->pLLIview = malloc(sizeof(LinkedListDescriporView1)*LLI_Size); if( pUartRx->pLLIview == NULL) { TRACE_ERROR(" Can not allocate memory to Rx LLI"); return USARTD_ERROR; } xdmadRxCfg.mbr_cfg = XDMAC_CC_TYPE_PER_TRAN | XDMAC_CC_MBSIZE_SIXTEEN | XDMAC_CC_DSYNC_PER2MEM | XDMAC_CC_MEMSET_NORMAL_MODE | XDMAC_CC_CSIZE_CHK_1 | XDMAC_CC_DWIDTH_BYTE | XDMAC_CC_SIF_AHB_IF1 | XDMAC_CC_DIF_AHB_IF0 | XDMAC_CC_SAM_FIXED_AM | XDMAC_CC_DAM_INCREMENTED_AM | XDMAC_CC_PERID(XDMAIF_Get_ChannelNumber( pUartd->uartId, XDMAD_TRANSFER_RX )); xdmadRxCfg.mbr_bc = 0; for (i = 0; i < LLI_Size; i++) { pUartRx->pLLIview[i].mbr_ubc = XDMA_UBC_NVIEW_NDV1 | XDMA_UBC_NSEN_UNCHANGED | XDMA_UBC_NDEN_UPDATED | ((i== LLI_Size- 1)? ( (pUartRx->dmaRingBuffer)? XDMA_UBC_NDE_FETCH_EN : 0): XDMA_UBC_NDE_FETCH_EN) | pUartRx->BuffSize; pUartRx->pLLIview[i].mbr_sa = (uint32_t)&pUartHwRx->UART_RHR; pUartRx->pLLIview[i].mbr_da = (uint32_t)pBuff; pUartRx->pLLIview[i].mbr_nda = (i == ( LLI_Size - 1))? ( (pUartRx->dmaRingBuffer)? (uint32_t)pUartRx->pLLIview : 0 ): (uint32_t)&pUartRx->pLLIview[ i + 1 ]; pBuff += pUartRx->BuffSize; } xdmaCndc = XDMAC_CNDC_NDVIEW_NDV1 | XDMAC_CNDC_NDE_DSCR_FETCH_EN | XDMAC_CNDC_NDSUP_SRC_PARAMS_UPDATED| XDMAC_CNDC_NDDUP_DST_PARAMS_UPDATED ; xdmaInt = ((pUartRx->dmaRingBuffer)? XDMAC_CIE_BIE : XDMAC_CIE_LIE); } else { return 1; } memory_barrier(); if (XDMAD_ConfigureTransfer( pXdmadRx, pUartRx->ChNum, &xdmadRxCfg, xdmaCndc, (uint32_t)pUartRx->pLLIview, xdmaInt)) return USARTD_ERROR; return 0; }
/** * \brief Configure the SPI/SMC tx/rx DMA. * \returns 0 if the xDMA configuration successfully; otherwise returns * ILI9488_ERROR_XXX. */ static uint8_t _ILI9488DmaConfigureRxTx(void) { uint32_t txAddress,rxAddress; sXdmad *pXdmad; pXdmad = ili9488Dma.xdmaD; #if !defined(BOARD_LCD_SMC) txAddress = (uint32_t)&ILI9488_SPI->SPI_TDR; rxAddress = (uint32_t)&ILI9488_SPI->SPI_RDR; ili9488Dma.xdmadExtTxCfg.mbr_cfg = XDMAC_CC_TYPE_PER_TRAN | XDMAC_CC_DSYNC_MEM2PER | XDMAC_CC_DWIDTH_BYTE | XDMAC_CC_PERID(XDMAIF_Get_ChannelNumber(ili9488Dma.spiId, XDMAD_TRANSFER_TX )); ili9488Dma.xdmadExtRxCfg.mbr_cfg = XDMAC_CC_TYPE_PER_TRAN | XDMAC_CC_DSYNC_PER2MEM | XDMAC_CC_PERID(XDMAIF_Get_ChannelNumber(ili9488Dma.spiId, XDMAD_TRANSFER_RX )); #else txAddress = rxAddress =(uint32_t)ILI9488_BASE_ADDRESS; ili9488Dma.xdmadExtTxCfg.mbr_cfg = XDMAC_CC_DWIDTH_HALFWORD; ili9488Dma.xdmadExtRxCfg.mbr_cfg = 0; #endif /* Setup DMA TX channel */ ili9488Dma.xdmadTxCfg.mbr_sa = 0; ili9488Dma.xdmadTxCfg.mbr_da = txAddress; ili9488Dma.xdmadTxCfg.mbr_ubc = XDMA_UBC_NVIEW_NDV0 | XDMA_UBC_NDE_FETCH_DIS| XDMA_UBC_NSEN_UPDATED ; ili9488Dma.xdmadTxCfg.mbr_cfg = XDMAC_CC_TYPE_MEM_TRAN | XDMAC_CC_MBSIZE_SINGLE | XDMAC_CC_CSIZE_CHK_1 | XDMAC_CC_SIF_AHB_IF0 | XDMAC_CC_DIF_AHB_IF1 | XDMAC_CC_SAM_INCREMENTED_AM | XDMAC_CC_DAM_FIXED_AM; ili9488Dma.xdmadTxCfg.mbr_cfg |= ili9488Dma.xdmadExtTxCfg.mbr_cfg; ili9488Dma.xdmadTxCfg.mbr_bc = 0; ili9488Dma.xdmadTxCfg.mbr_sus = 0; ili9488Dma.xdmadTxCfg.mbr_dus = 0; /* Setup RX DMA channel */ ili9488Dma.xdmadRxCfg.mbr_ubc = XDMA_UBC_NVIEW_NDV0 | XDMA_UBC_NDE_FETCH_DIS | XDMA_UBC_NDEN_UPDATED ; ili9488Dma.xdmadRxCfg.mbr_da = 0; ili9488Dma.xdmadRxCfg.mbr_sa = rxAddress; ili9488Dma.xdmadRxCfg.mbr_cfg = XDMAC_CC_TYPE_MEM_TRAN | XDMAC_CC_MBSIZE_SINGLE | XDMAC_CC_CSIZE_CHK_1 | XDMAC_CC_DWIDTH_WORD | XDMAC_CC_SIF_AHB_IF1 | XDMAC_CC_DIF_AHB_IF0 | XDMAC_CC_SAM_FIXED_AM | XDMAC_CC_DAM_INCREMENTED_AM; ili9488Dma.xdmadRxCfg.mbr_cfg |= ili9488Dma.xdmadExtRxCfg.mbr_cfg; ili9488Dma.xdmadRxCfg.mbr_bc = 0; ili9488Dma.xdmadRxCfg.mbr_sus = 0; ili9488Dma.xdmadRxCfg.mbr_dus =0; /* Put all interrupts on for non LLI list setup of DMA */ ili9488Dma.xdmaInt = (XDMAC_CIE_BIE | XDMAC_CIE_RBIE | XDMAC_CIE_WBIE | XDMAC_CIE_ROIE); if (XDMAD_ConfigureTransfer( pXdmad, ili9488Dma.ili9488DmaRxChannel, &ili9488Dma.xdmadRxCfg, 0, 0, ili9488Dma.xdmaInt)) return ILI9488_ERROR_DMA_CONFIGURE; if (XDMAD_ConfigureTransfer( pXdmad, ili9488Dma.ili9488DmaTxChannel, &ili9488Dma.xdmadTxCfg, 0, 0, ili9488Dma.xdmaInt)) return ILI9488_ERROR_DMA_CONFIGURE; return 0; }
static uint32_t _MciDMA(sMcid *pMcid, uint32_t bFByte, uint8_t bRd) { Hsmci *pHw = pMcid->pMciHw; sXdmad *pXdmad = pMcid->pXdmad; sSdmmcCommand *pCmd = pMcid->pCmd; sXdmadCfg xdmadRxCfg,xdmadTxCfg; uint32_t xdmaCndc; uint32_t hsmciId; uint8_t i; uint32_t totalSize = pCmd->wNbBlocks * pCmd->wBlockSize; uint32_t maxXSize; uint32_t memAddress; uint8_t bMByte; if (pMcid->dwXfrNdx >= totalSize) return 0; /* Prepare DMA transfer */ if(pCmd->wBlockSize != 1) { pMcid->dwXSize = totalSize - pMcid->dwXfrNdx; hsmciId = ((unsigned int)pHw == (unsigned int)HSMCI0 )? ID_HSMCI0: ID_HSMCI1; if (bRd) { //printf("_MciDMA read %d,%d \n\r",pCmd->wBlockSize, pCmd->bCmd ); for ( i = 0; i < pCmd->wNbBlocks; i++) { dmaLinkList[i].mbr_ubc = XDMA_UBC_NVIEW_NDV1 | (( i == pCmd->wNbBlocks - 1) ? 0: XDMA_UBC_NDE_FETCH_EN) | XDMA_UBC_NDEN_UPDATED | pCmd->wBlockSize /4 ; dmaLinkList[i].mbr_sa = (uint32_t)&(pHw->HSMCI_FIFO[i]); dmaLinkList[i].mbr_da = (uint32_t)&pCmd->pData[i * pCmd->wBlockSize]; if ( i == pCmd->wNbBlocks - 1) dmaLinkList[i].mbr_nda = 0; else dmaLinkList[i].mbr_nda = (uint32_t)&dmaLinkList[ i + 1 ]; } xdmadRxCfg.mbr_cfg = XDMAC_CC_TYPE_PER_TRAN | XDMAC_CC_MBSIZE_SINGLE | XDMAC_CC_DSYNC_PER2MEM | XDMAC_CC_CSIZE_CHK_1 | XDMAC_CC_DWIDTH_WORD | XDMAC_CC_SIF_AHB_IF1 | XDMAC_CC_DIF_AHB_IF0 | XDMAC_CC_SAM_FIXED_AM | XDMAC_CC_DAM_INCREMENTED_AM | XDMAC_CC_PERID(XDMAIF_Get_ChannelNumber( 0, hsmciId, XDMAD_TRANSFER_RX )); xdmaCndc = XDMAC_CNDC_NDVIEW_NDV1 | XDMAC_CNDC_NDE_DSCR_FETCH_EN | XDMAC_CNDC_NDSUP_SRC_PARAMS_UPDATED | XDMAC_CNDC_NDDUP_DST_PARAMS_UPDATED ; if (XDMAD_ConfigureTransfer( pXdmad, pMcid->dwDmaCh, &xdmadRxCfg, xdmaCndc, (uint32_t)&dmaLinkList[0])) { return 0; } if (XDMAD_StartTransfer(pXdmad,pMcid->dwDmaCh)) { return 0; } //Write } else { //printf("_MciDMA write %d,%d \n\r",pCmd->wBlockSize, pCmd->bCmd ); for ( i = 0; i < pCmd->wNbBlocks; i++) { dmaLinkList[i].mbr_ubc = XDMA_UBC_NVIEW_NDV1 |(( i == pCmd->wNbBlocks - 1) ? 0: XDMA_UBC_NDE_FETCH_EN) | XDMA_UBC_NDEN_UPDATED | pCmd->wBlockSize /4 ; dmaLinkList[i].mbr_sa = (uint32_t)&pCmd->pData[i * pCmd->wBlockSize]; dmaLinkList[i].mbr_da = (uint32_t)&(pHw->HSMCI_FIFO[i]); if ( i == pCmd->wNbBlocks - 1) dmaLinkList[i].mbr_nda = 0; else dmaLinkList[i].mbr_nda = (uint32_t)&dmaLinkList[ i + 1 ]; } xdmadTxCfg.mbr_cfg = XDMAC_CC_TYPE_PER_TRAN | XDMAC_CC_MBSIZE_SINGLE | XDMAC_CC_DSYNC_MEM2PER | XDMAC_CC_CSIZE_CHK_1 | XDMAC_CC_DWIDTH_WORD | XDMAC_CC_SIF_AHB_IF0 | XDMAC_CC_DIF_AHB_IF1 | XDMAC_CC_SAM_INCREMENTED_AM | XDMAC_CC_DAM_FIXED_AM | XDMAC_CC_PERID(XDMAIF_Get_ChannelNumber( 0, hsmciId, XDMAD_TRANSFER_TX )); xdmaCndc = XDMAC_CNDC_NDVIEW_NDV1 | XDMAC_CNDC_NDE_DSCR_FETCH_EN | XDMAC_CNDC_NDSUP_SRC_PARAMS_UPDATED | XDMAC_CNDC_NDDUP_DST_PARAMS_UPDATED ; if(XDMAD_ConfigureTransfer( pXdmad, pMcid->dwDmaCh, &xdmadTxCfg, xdmaCndc, (uint32_t)&dmaLinkList[0])) { return 0; } if (XDMAD_StartTransfer(pXdmad,pMcid->dwDmaCh)) { return 0; } } } else { /* Memory address and alignment */ memAddress = (uint32_t)&pCmd->pData[pMcid->dwXfrNdx]; bMByte = bFByte ? 1 : (((memAddress & 0x3) || (totalSize & 0x3))); /* P to M: Max size is P size */ if (bRd) { maxXSize = bFByte ? MAX_DMA_SIZE : (MAX_DMA_SIZE * 4); } /* M to P: Max size is M size */ else { maxXSize = bMByte ? MAX_DMA_SIZE : (MAX_DMA_SIZE * 4); } /* Update index */ pMcid->dwXSize = totalSize - pMcid->dwXfrNdx; if (pMcid->dwXSize > maxXSize) { pMcid->dwXSize = maxXSize; } /* Prepare DMA transfer */ if (bRd) { xdmadRxCfg.mbr_ubc = bFByte ? pMcid->dwXSize : toWCOUNT(pMcid->dwXSize); xdmadRxCfg.mbr_sa = (uint32_t)&(pHw->HSMCI_RDR); xdmadRxCfg.mbr_da = (uint32_t)memAddress; xdmadRxCfg.mbr_cfg = XDMAC_CC_TYPE_PER_TRAN | XDMAC_CC_MEMSET_NORMAL_MODE | XDMAC_CC_DSYNC_PER2MEM| XDMAC_CC_CSIZE_CHK_1 | (bFByte ? XDMAC_CC_DWIDTH_BYTE : XDMAC_CC_DWIDTH_WORD) | XDMAC_CC_SIF_AHB_IF1 | XDMAC_CC_DIF_AHB_IF0 | XDMAC_CC_SAM_FIXED_AM | XDMAC_CC_DAM_INCREMENTED_AM; xdmadRxCfg.mbr_bc = 0; XDMAD_ConfigureTransfer( pXdmad, pMcid->dwDmaCh, &xdmadRxCfg, 0, 0); //CP15_coherent_dcache_for_dma ((uint32_t)memAddress, ((uint32_t)memAddress + (pMcid->dwXSize))); } else { xdmadTxCfg.mbr_ubc = toWCOUNT(pMcid->dwXSize); xdmadTxCfg.mbr_sa = (uint32_t)memAddress; xdmadTxCfg.mbr_da = (uint32_t)&(pHw->HSMCI_TDR); xdmadTxCfg.mbr_cfg = XDMAC_CC_TYPE_PER_TRAN | XDMAC_CC_MEMSET_NORMAL_MODE | XDMAC_CC_DSYNC_MEM2PER | XDMAC_CC_CSIZE_CHK_1 | (bFByte ? XDMAC_CC_DWIDTH_BYTE : XDMAC_CC_DWIDTH_WORD) | XDMAC_CC_SIF_AHB_IF0 | XDMAC_CC_DIF_AHB_IF1 | XDMAC_CC_SAM_INCREMENTED_AM | XDMAC_CC_DAM_FIXED_AM; xdmadTxCfg.mbr_bc = 0; XDMAD_ConfigureTransfer( pXdmad, pMcid->dwDmaCh, &xdmadTxCfg, 0, 0); } XDMAD_StartTransfer(pXdmad, pMcid->dwDmaCh); } return 1; }