/** * \brief Starts a AFE transfer. This is a non blocking function. It will * return as soon as the transfer is started. * * \param pAfed Pointer to a AfeDma instance. * \param pCommand Pointer to the Afe command to execute. * \returns 0 if the transfer has been started successfully; otherwise returns * AFE_ERROR_LOCK is the driver is in use, or AFE_ERROR if the command is not * valid. */ uint32_t Afe_SendData(AfeDma *pAfed, AfeCmd *pCommand) { Afec *pAfeHw = pAfed->pAfeHw; /* Try to get the dataflash semaphore */ if (pAfed->semaphore == 0) return AFE_ERROR_LOCK; pAfed->semaphore--; // Initialize the callback pAfed->pCurrentCommand = pCommand; /* Initialize DMA controller using channel 0 for RX. */ if (_AfeConfigureDmaChannels(pAfed)) return AFE_ERROR_LOCK; /* Configure and enable interrupt on RC compare */ NVIC_ClearPendingIRQ(XDMAC_IRQn); NVIC_SetPriority(XDMAC_IRQn , 1); NVIC_EnableIRQ(XDMAC_IRQn); if (_Afe_configureLinkList(pAfeHw, pAfed->pXdmad, pCommand)) return AFE_ERROR_LOCK; AFEC_StartConversion(pAfeHw); /* Start DMA 0(RX) */ if (XDMAD_StartTransfer(pAfed->pXdmad, afeDmaRxChannel)) return AFE_ERROR_LOCK; return AFE_OK;; }
/** * \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 Starts a DAC transfer. This is a non blocking function. It will * return as soon as the transfer is started. * * \param pDacd Pointer to a DacDma instance. * \param pCommand Pointer to the Dac command to execute. * \returns 0 if the transfer has been started successfully; otherwise returns * DAC_ERROR_LOCK is the driver is in use, or DAC_ERROR if the command is not * valid. */ uint32_t Dac_SendData(DacDma *pDacd, DacCmd *pCommand) { Dacc *pDacHw = pDacd->pDacHw; /* Try to get the dataflash semaphore */ if (pDacd->semaphore == 0) return DAC_ERROR_LOCK; pDacd->semaphore--; // Initialize the callback pDacd->pCurrentCommand = pCommand; /* Initialize DMA controller using channel 0 for RX. */ if (_DacConfigureDmaChannels(pDacd)) return DAC_ERROR_LOCK; if (_Dac_configureLinkList(pDacHw, pDacd->pXdmad, pCommand)) return DAC_ERROR_LOCK; SCB_CleanDCache(); /* Start DMA TX */ if (XDMAD_StartTransfer(pDacd->pXdmad, dacDmaTxChannel)) return DAC_ERROR_LOCK; return DAC_OK;; }
/** * \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); }
/** * \brief DMA TX callback */ static void _SscTxCallback(uint8_t status, void *pArg) { sXdmad *pDmad = &dmad; Xdmac *pXdmac = pDmad->pXdmacs; /*dummy */ status = status; pArg = pArg; if (numBuffersToSend == 0) { /* End of transmission */ isDacActive = 0; return; } /* Load next buffer */ memory_sync(); XDMAC_SetSourceAddr(pXdmac, sscDmaTxChannel, (uint32_t) buffers[outBufferIndex]); XDMAC_SetMicroblockControl(pXdmac, sscDmaTxChannel, bufferSizes[outBufferIndex]); SCB_CleanDCache_by_Addr((uint32_t *) buffers[outBufferIndex], bufferSizes[outBufferIndex]); outBufferIndex = (outBufferIndex + 1) % BUFFER_NUMBER; numBuffersToSend --; XDMAD_StartTransfer(pDmad, sscDmaTxChannel); }
/** * \brief Start ILI9488 DMA Rx transfer . * \param pRxBuffer point to Rx buffer address * \param wRxSize Rx buffer size in byte * \returns 0 if the xDMA transfer successfully; otherwise returns ILI9488_DMA_ERROR_XXX. */ uint8_t ILI9488DmaRxTransfer(uint32_t *pRxBuffer,uint32_t wRxSize) { uint16_t dummyTxBuffer[5]; _ILI9488DmaUpdateBuffer(dummyTxBuffer, wRxSize, pRxBuffer, wRxSize); SCB_CleanInvalidateDCache(); if (XDMAD_StartTransfer( ili9488Dma.xdmaD, ili9488Dma.ili9488DmaRxChannel)) return ILI9488_ERROR_DMA_TRANSFER; #if !defined(BOARD_LCD_SMC) if (XDMAD_StartTransfer( ili9488Dma.xdmaD, ili9488Dma.ili9488DmaTxChannel)) return ILI9488_ERROR_DMA_TRANSFER; #endif return 0; }
/** * \brief Starts a SPI master transfer. This is a non blocking function. It will * return as soon as the transfer is started. * * \param pSpid Pointer to a Spid instance. * \param pCommand Pointer to the SPI command to execute. * \returns 0 if the transfer has been started successfully; otherwise returns * SPID_ERROR_LOCK is the driver is in use, or SPID_ERROR if the command is not * valid. */ uint32_t SPID_SendCommand(Spid *pSpid, SpidCmd *pCommand) { Spi *pSpiHw = pSpid->pSpiHw; /* Try to get the dataflash semaphore */ if (pSpid->semaphore == 0) return SPID_ERROR_LOCK; pSpid->semaphore--; /* Enable the SPI Peripheral */ PMC_EnablePeripheral (pSpid->spiId); /* SPI chip select */ SPI_ChipSelect (pSpiHw, 1 << pCommand->spiCs); // Initialize the callback pSpid->pCurrentCommand = pCommand; /* Initialize DMA controller using channel 0 for RX, 1 for TX. */ if (_spid_configureDmaChannels(pSpid)) return SPID_ERROR_LOCK; /* Configure and enable interrupt on RC compare */ NVIC_ClearPendingIRQ(XDMAC_IRQn); NVIC_SetPriority(XDMAC_IRQn , 1); NVIC_EnableIRQ(XDMAC_IRQn); if (_spid_configureLinkList(pSpiHw, pSpid->pXdmad, pCommand)) return SPID_ERROR_LOCK; /* Enables the SPI to transfer and receive data. */ SPI_Enable (pSpiHw); SCB_CleanDCache_by_Addr((uint32_t *)pCommand->pTxBuff, pCommand->TxSize); /* Start DMA 0(RX) && 1(TX) */ if (XDMAD_StartTransfer(pSpid->pXdmad, spiDmaRxChannel)) return SPID_ERROR_LOCK; if (XDMAD_StartTransfer(pSpid->pXdmad, spiDmaTxChannel)) return SPID_ERROR_LOCK; return 0; }
/** * \brief Starts a USART master transfer. This is a non blocking function. It will * return as soon as the transfer is started. * * \param pUSARTD Pointer to a USARTDma instance. * \returns 0 if the transfer has been started successfully; otherwise returns * USARTD_ERROR_LOCK is the driver is in use, or USARTD_ERROR if the command is not * valid. */ uint32_t USARTD_RcvData(UsartDma *pUsartd) { /* Start DMA 0(RX) && 1(TX) */ pUsartd->pRxChannel->dmaProgress = 0; if (XDMAD_StartTransfer(pUsartd->pXdmad, pUsartd->pRxChannel->ChNum)) return USARTD_ERROR_LOCK; return 0; }
/** * \brief Starts a USART master transfer. This is a non blocking function. It will * return as soon as the transfer is started. * * \param pUSARTd Pointer to a USARTDma instance. * \param pCommand Pointer to the USART command to execute. * \returns 0 if the transfer has been started successfully; otherwise returns * USARTD_ERROR_LOCK is the driver is in use, or USARTD_ERROR if the command is not * valid. */ uint32_t USARTD_RcvData( UsartDma *pUsartd) { while(!pUsartd->pRxChannel->Done); /* Start DMA 0(RX) && 1(TX) */ if (XDMAD_StartTransfer( pUsartd->pXdmad, pUsartd->pRxChannel->ChNum )) return USARTD_ERROR_LOCK; pUsartd->pRxChannel->Done=0; memory_barrier(); return 0; }
uint8_t ILI9488_EbiDmaRxTransfer(uint32_t *pRxBuffer, uint32_t wRxSize) { SCB_CleanDCache_by_Addr((uint32_t *)pRxBuffer, wRxSize * 4); _ILI9488_EbiDmaUpdateBuffer(dummyTxBuffer, wRxSize, pRxBuffer, wRxSize); if (XDMAD_StartTransfer(ili9488EbiDma.xdmaD, ili9488EbiDma.ili9488DmaRxChannel)) return ILI9488_ERROR_DMA_TRANSFER; return 0; }
/** * \brief Start ILI9488 DMA transfer . * \param pTxBuffer point to Tx buffer address * \param wTxSize Tx buffer size in byte * \returns 0 if the xDMA configuration successfully; otherwise returns * ILI9488_DMA_ERROR_XXX. */ uint8_t ILI9488DmaTxTransfer( uint16_t *pTxBuffer,uint32_t wTxSize) { _ILI9488DmaUpdateBuffer(pTxBuffer, wTxSize, 0, 0); SCB_CleanInvalidateDCache(); if (XDMAD_StartTransfer( ili9488Dma.xdmaD, ili9488Dma.ili9488DmaTxChannel)) return ILI9488_ERROR_DMA_TRANSFER; while(!ili9488DmaCtl.txDone); ili9488DmaCtl.txDone = 0; return 0; }
/** * \brief Starts a UART master transfer. This is a non blocking function. It will * return as soon as the transfer is started. * * \param pUartd Pointer to a UartDma instance. * \returns 0 if the transfer has been started successfully; otherwise returns * UARTD_ERROR_LOCK is the driver is in use, or UARTD_ERROR if the command is not * valid. */ uint32_t UARTD_RcvData( UartDma *pUartd) { pUartd->pRxChannel->sempaphore=0; memory_barrier(); /* Start DMA 0(RX) && 1(TX) */ if (XDMAD_StartTransfer( pUartd->pXdmad, pUartd->pRxChannel->ChNum )) return USARTD_ERROR_LOCK; return 0; }
/** * \brief Starts a UART master transfer. This is a non blocking function. It * will return as soon as the transfer is started. * * \param pUartd Pointer to a UartDma instance. * \returns 0 if the transfer has been started successfully; otherwise returns * UARTD_ERROR_LOCK is the driver is in use, or UARTD_ERROR if the command is * not valid. */ uint32_t UARTD_SendData( UartDma *pUartd) { /* Start DMA 0(RX) && 1(TX) */ SCB_CleanInvalidateDCache(); pUartd->pTxChannel->sempaphore=0; memory_barrier(); if (XDMAD_StartTransfer( pUartd->pXdmad, pUartd->pTxChannel->ChNum )) return USARTD_ERROR_LOCK; return 0; }
/** * \brief Starts a USART master transfer. This is a non blocking function. It * will return as soon as the transfer is started. * * \param pUSARTD Pointer to a USARTDma instance. * \returns 0 if the transfer has been started successfully; otherwise returns * USARTD_ERROR_LOCK is the driver is in use, or USARTD_ERROR if the command is * not valid. */ uint32_t USARTD_SendData(UsartDma *pUsartd) { /* Start DMA 0(RX) && 1(TX) */ pUsartd->pTxChannel->dmaProgress = 0; SCB_CleanDCache_by_Addr((uint32_t *)pUsartd->pTxChannel->pBuff, pUsartd->pTxChannel->BuffSize); if (XDMAD_StartTransfer(pUsartd->pXdmad, pUsartd->pTxChannel->ChNum)) return USARTD_ERROR_LOCK; return 0; }
/** * \brief Start ILI9488 DMA transfer in SMC mode. * \param pTxBuffer point to Tx buffer address * \param wTxSize Tx buffer size in byte * \returns 0 if the xDMA configuration successfully; otherwise returns * ILI9488_DMA_ERROR_XXX. */ uint8_t ILI9488_EbiDmaTxTransfer(uint16_t *pTxBuffer, uint32_t wTxSize) { _ILI9488_EbiDmaUpdateBuffer(pTxBuffer, wTxSize, 0, 0); //SCB_CleanDCache_by_Addr((uint32_t *)&ili9488EbiDma,sizeof(ili9488EbiDma)); SCB_CleanDCache_by_Addr((uint32_t *)pTxBuffer, wTxSize * 2); if (XDMAD_StartTransfer(ili9488EbiDma.xdmaD, ili9488EbiDma.ili9488DmaTxChannel)) { printf("111"); return ILI9488_ERROR_DMA_TRANSFER; } while (!ili9488DmaCtlInEbiMode.txDoneFlag); ili9488DmaCtlInEbiMode.txDoneFlag = 0; return 0; }
/** * \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); }
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; }
/** * \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); }