/** * \brief SPI xDMA Rx callback * Invoked on SPi DMA reception done. * \param channel DMA channel. * \param pArg Pointer to callback argument - Pointer to Spid instance. */ static void SPID_Rx_Cb(uint32_t channel, Spid* pArg) { SpidCmd *pSpidCmd = pArg->pCurrentCommand; Spi *pSpiHw = pArg->pSpiHw; if (channel != spiDmaRxChannel) return; /* Disable the SPI TX & RX */ SPI_Disable ( pSpiHw ); /* Configure and enable interrupt on RC compare */ NVIC_ClearPendingIRQ(XDMAC_IRQn); NVIC_DisableIRQ(XDMAC_IRQn); /* Disable the SPI Peripheral */ PMC_DisablePeripheral ( pArg->spiId ); /* Release CS */ SPI_ReleaseCS(pSpiHw); /* Release the DMA channels */ XDMAD_FreeChannel(pArg->pXdmad, spiDmaRxChannel); XDMAD_FreeChannel(pArg->pXdmad, spiDmaTxChannel); /* Release the dataflash semaphore */ pArg->semaphore++; printf("\n\r%s\n\r",pArg->pCurrentCommand->pRxBuff); /* Invoke the callback associated with the current command */ if (pSpidCmd && pSpidCmd->callback) { //printf("p %d", pArg->semaphore); pSpidCmd->callback(0, pSpidCmd->pArgument); } }
/** * \brief This function initialize the appropriate DMA channel for Rx/Tx channel of SPI or SMC * \returns 0 if the transfer has been started successfully; otherwise returns * ILI9488_ERROR_XX is the driver is in use, or ILI9488_ERROR_XX if the command is not * valid. */ static uint8_t _ILI9488DmaConfigChannels(void) { uint32_t srcType,dstType; /* Driver initialize */ XDMAD_Initialize( ili9488Dma.xdmaD, 0 ); XDMAD_FreeChannel( ili9488Dma.xdmaD, ili9488Dma.ili9488DmaTxChannel); XDMAD_FreeChannel( ili9488Dma.xdmaD, ili9488Dma.ili9488DmaRxChannel); #if !defined(BOARD_LCD_SMC) srcType = XDMAD_TRANSFER_MEMORY; dstType = ili9488Dma.spiId; #else srcType = XDMAD_TRANSFER_MEMORY; dstType = XDMAD_TRANSFER_MEMORY; #endif /* Allocate a DMA channel for ILI9488_SPI TX. */ ili9488Dma.ili9488DmaTxChannel = XDMAD_AllocateChannel( ili9488Dma.xdmaD, srcType, dstType); { if ( ili9488Dma.ili9488DmaTxChannel == XDMAD_ALLOC_FAILED ) { return ILI9488_ERROR_DMA_ALLOCATE_CHANNEL; } } /* Allocate a DMA channel for ILI9488_SPI RX. */ ili9488Dma.ili9488DmaRxChannel = XDMAD_AllocateChannel( ili9488Dma.xdmaD, dstType, srcType); { if ( ili9488Dma.ili9488DmaRxChannel == XDMAD_ALLOC_FAILED ) { return ILI9488_ERROR_DMA_ALLOCATE_CHANNEL; } } /* Setup callbacks for ILI9488_SPI RX */ XDMAD_SetCallback(ili9488Dma.xdmaD, ili9488Dma.ili9488DmaRxChannel, (XdmadTransferCallback)_ILI9488_Rx_CB, &ili9488Dma); if (XDMAD_PrepareChannel( ili9488Dma.xdmaD, ili9488Dma.ili9488DmaRxChannel )) return ILI9488_ERROR_DMA_ALLOCATE_CHANNEL; /* Setup callbacks for ILI9488_SPI TX (ignored) */ XDMAD_SetCallback(ili9488Dma.xdmaD, ili9488Dma.ili9488DmaTxChannel, (XdmadTransferCallback)_ILI9488_Tx_CB, &ili9488Dma); if ( XDMAD_PrepareChannel( ili9488Dma.xdmaD, ili9488Dma.ili9488DmaTxChannel )) return ILI9488_ERROR_DMA_ALLOCATE_CHANNEL; /* Check if DMA IRQ is enable; if not Enable it */ if(!(NVIC_GetActive(XDMAC_IRQn))) { /* Enable interrupt */ NVIC_EnableIRQ(XDMAC_IRQn); } return 0; }
uint32_t UARTD_DisableTxChannels( UartDma *pUartd, UartChannel *pTxCh) { assert(pTxCh); /* Enables the USART to transfer data. */ UART_SetTransmitterEnabled ( pUartd->pUartHw , DISABLE); XDMAD_StopTransfer(pUartd->pXdmad, pTxCh->ChNum); XDMAD_SetCallback(pUartd->pXdmad, pTxCh->ChNum, NULL, NULL); /* Free allocated DMA channel for USART TX. */ if(XDMAD_FreeChannel( pUartd->pXdmad, pTxCh->ChNum) != XDMAD_OK) { return USARTD_ERROR; } if (pTxCh->dmaProgrammingMode == XDMAD_LLI) { free(pTxCh->pLLIview); pTxCh->pLLIview = NULL; } pTxCh->sempaphore = 1; memory_barrier(); return 0; }
uint32_t USARTD_EnableTxChannels( UsartDma *pUsartd, UsartChannel *pTxCh) { Usart *pUsartHw = pUsartd->pUsartHw; // Initialize the callback pUsartd->pTxChannel = pTxCh; /* Enables the USART to transfer data. */ USART_SetTransmitterEnabled ( pUsartHw , 1); XDMAD_FreeChannel( pUsartd->pXdmad, pTxCh->ChNum); /* Allocate a DMA channel for USART0/1 TX. */ pTxCh->ChNum = XDMAD_AllocateChannel( pUsartd->pXdmad, XDMAD_TRANSFER_MEMORY, pUsartd->usartId); if ( pTxCh->ChNum == XDMAD_ALLOC_FAILED ) { return USARTD_ERROR; } /* Setup callbacks for USART0/1 TX */ XDMAD_SetCallback(pUsartd->pXdmad, pTxCh->ChNum, (XdmadTransferCallback)USARTD_Tx_Cb, pUsartd); if ( XDMAD_PrepareChannel( pUsartd->pXdmad, pTxCh->ChNum )) return USARTD_ERROR; /* Enable interrupt */ NVIC_EnableIRQ(XDMAC_IRQn); if (_configureTxLinkList(pUsartHw, pUsartd->pXdmad, pTxCh)) return USARTD_ERROR_LOCK; return 0; }
/** * \brief USART xDMA Rx callback * Invoked on USART DMA reception done. * \param channel DMA channel. * \param pArg Pointer to callback argument - Pointer to USARTDma instance. */ static void UARTD_Tx_Cb(uint32_t channel, UartDma* pArg) { UartChannel *pUartdCh = pArg->pTxChannel; if (channel != pUartdCh->ChNum) return; /* Release the DMA channels */ XDMAD_FreeChannel(pArg->pXdmad, pUartdCh->ChNum); pUartdCh->sempaphore = 1; memory_barrier(); }
/** * \brief USART xDMA Rx callback * Invoked on USART DMA reception done. * \param channel DMA channel. * \param pArg Pointer to callback argument - Pointer to USARTDma instance. */ static void USARTD_Tx_Cb(uint32_t channel, UsartDma *pArg) { UsartChannel *pUsartdCh = pArg->pTxChannel; if (channel != pUsartdCh->ChNum) return; /* Release the DMA channels */ XDMAD_FreeChannel(pArg->pXdmad, pUsartdCh->ChNum); pUsartdCh->dmaProgress = 1; }
/** * \brief Configure the DMA Channels: 0 RX, 1 TX. * Channels are disabled after configure. * \returns 0 if the dma channel configuration successfully; otherwise returns * SPID_ERROR_XXX. */ static uint8_t _spid_configureDmaChannels( Spid* pSpid ) { /* Driver initialize */ XDMAD_Initialize( pSpid->pXdmad, 0 ); XDMAD_FreeChannel( pSpid->pXdmad, spiDmaTxChannel); XDMAD_FreeChannel( pSpid->pXdmad, spiDmaRxChannel); /* Allocate a DMA channel for SPI0/1 TX. */ spiDmaTxChannel = XDMAD_AllocateChannel( pSpid->pXdmad, XDMAD_TRANSFER_MEMORY, pSpid->spiId); { if ( spiDmaTxChannel == XDMAD_ALLOC_FAILED ) { return SPID_ERROR; } } /* Allocate a DMA channel for SPI0/1 RX. */ spiDmaRxChannel = XDMAD_AllocateChannel( pSpid->pXdmad, pSpid->spiId, XDMAD_TRANSFER_MEMORY); { if ( spiDmaRxChannel == XDMAD_ALLOC_FAILED ) { return SPID_ERROR; } } /* Setup callbacks for SPI0/1 RX */ XDMAD_SetCallback(pSpid->pXdmad, spiDmaRxChannel, (XdmadTransferCallback)SPID_Rx_Cb, pSpid); if (XDMAD_PrepareChannel( pSpid->pXdmad, spiDmaRxChannel )) return SPID_ERROR; /* Setup callbacks for SPI0/1 TX (ignored) */ XDMAD_SetCallback(pSpid->pXdmad, spiDmaTxChannel, NULL, NULL); if ( XDMAD_PrepareChannel( pSpid->pXdmad, spiDmaTxChannel )) return SPID_ERROR; return 0; }
/** * \brief USART xDMA Rx callback * Invoked on USART DMA reception done. * \param channel DMA channel. * \param pArg Pointer to callback argument - Pointer to USARTDma instance. */ static void USARTD_Rx_Cb(uint32_t channel, UsartDma *pArg) { UsartChannel *pUsartdCh = pArg->pRxChannel; if (channel != pUsartdCh->ChNum) return; /* Release the DMA channels */ XDMAD_FreeChannel(pArg->pXdmad, pUsartdCh->ChNum); pUsartdCh->dmaProgress = 1; SCB_InvalidateDCache_by_Addr((uint32_t *)pUsartdCh->pBuff, pUsartdCh->BuffSize); }
/** * \brief USART xDMA Rx callback * Invoked on USART DMA reception done. * \param channel DMA channel. * \param pArg Pointer to callback argument - Pointer to USARTDma instance. */ static void USARTD_Tx_Cb(uint32_t channel, UsartDma* pArg) { UsartChannel *pUsartdCh = pArg->pTxChannel; if (channel != pUsartdCh->ChNum) return; // NVIC_ClearPendingIRQ(XDMAC_IRQn); /* Release the DMA channels */ XDMAD_FreeChannel(pArg->pXdmad, pUsartdCh->ChNum); /* Invoke the callback associated with the current command */ if (pUsartdCh && pUsartdCh->callback) { pUsartdCh->callback(0, pUsartdCh->pArgument); } pUsartdCh->Done = 1; memory_barrier(); }
static void _FinishCmd( sMcid* pMcid, uint8_t bStatus ) { sSdmmcCommand *pCmd = pMcid->pCmd; sXdmad *pXdmad = pMcid->pXdmad; //uint32_t memAddress; /* Release DMA channel (if used) */ if (pMcid->dwDmaCh != XDMAD_ALLOC_FAILED) { if (XDMAD_FreeChannel(pXdmad, pMcid->dwDmaCh)) printf("-E- Can't free channel \n\r"); pMcid->dwDmaCh = XDMAD_ALLOC_FAILED; } /* Release command */ pMcid->pCmd = NULL; pMcid->bState = MCID_LOCKED; pCmd->bStatus = bStatus; /* Invoke callback */ if (pCmd->fCallback) { (pCmd->fCallback)(pCmd->bStatus, pCmd->pArg); } }
/** * \brief Configure the DMA Channels: 0 RX. * Channels are disabled after configure. * \returns 0 if the dma channel configuration successfully; otherwise returns * DAC_ERROR_XXX. */ static uint8_t _DacConfigureDmaChannels(DacDma *pDacd) { /* Driver initialize */ XDMAD_Initialize(pDacd->pXdmad, 0); XDMAD_FreeChannel(pDacd->pXdmad, dacDmaTxChannel); /* Allocate a DMA channel for DAC0/1 TX. */ dacDmaTxChannel = XDMAD_AllocateChannel(pDacd->pXdmad, XDMAD_TRANSFER_MEMORY, ID_DACC); if (dacDmaTxChannel == XDMAD_ALLOC_FAILED) return DAC_ERROR; if (XDMAD_PrepareChannel(pDacd->pXdmad, dacDmaTxChannel)) return DAC_ERROR; return DAC_OK; }
/** * \brief AFE xDMA Rx callback * Invoked on AFE DMA reception done. * \param channel DMA channel. * \param pArg Pointer to callback argument - Pointer to AfeDma instance. */ static void Afe_Rx_Cb(uint32_t channel, AfeDma *pArg) { AfeCmd *pAfedCmd = pArg->pCurrentCommand; if (channel != afeDmaRxChannel) return; /* Configure and enable interrupt on RC compare */ NVIC_ClearPendingIRQ(XDMAC_IRQn); NVIC_DisableIRQ(XDMAC_IRQn); /* Release the DMA channels */ XDMAD_FreeChannel(pArg->pXdmad, afeDmaRxChannel); SCB_InvalidateDCache_by_Addr(pAfedCmd->pRxBuff, pAfedCmd->RxSize); /* Release the dataflash semaphore */ pArg->semaphore++; /* Invoke the callback associated with the current command */ if (pAfedCmd && pAfedCmd->callback) pAfedCmd->callback(0, pAfedCmd->pArgument); }
/** * \brief Configure the DMA Channels: 0 RX. * Channels are disabled after configure. * \param pXdmad Pointer to a AfeDma instance * \returns 0 if the dma channel configuration successfully; otherwise returns * AFE_ERROR_XXX. */ static uint8_t _AfeConfigureDmaChannels(AfeDma *pAfed) { /* Driver initialize */ XDMAD_FreeChannel(pAfed->pXdmad, afeDmaRxChannel); /* Allocate a DMA channel for AFE0/1 RX. */ afeDmaRxChannel = XDMAD_AllocateChannel(pAfed->pXdmad, pAfed->afeId, XDMAD_TRANSFER_MEMORY); if (afeDmaRxChannel == XDMAD_ALLOC_FAILED) return AFE_ERROR; /* Setup callbacks for AFE0/1 RX */ XDMAD_SetCallback(pAfed->pXdmad, afeDmaRxChannel, (XdmadTransferCallback)Afe_Rx_Cb, pAfed); if (XDMAD_PrepareChannel(pAfed->pXdmad, afeDmaRxChannel)) return AFE_ERROR; return AFE_OK; }
/** * \brief This function disables the appropriate DMA channel for Rx channel of * USART * \param pUsartd Pointer to a UsartDma instance. * \param pRxCh Pointer to TxChannel configuration * \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_DisableRxChannels(UsartDma *pUsartd, UsartChannel *pRxCh) { assert(pRxCh); /* Enables the USART to transfer data. */ USART_SetReceiverEnabled (pUsartd->pUsartHw , DISABLE); XDMAD_StopTransfer(pUsartd->pXdmad, pRxCh->ChNum); XDMAD_SetCallback(pUsartd->pXdmad, pRxCh->ChNum, NULL, NULL); /* Free allocated DMA channel for USART TX. */ if (XDMAD_FreeChannel(pUsartd->pXdmad, pRxCh->ChNum) != XDMAD_OK) return USARTD_ERROR; if (pRxCh->dmaProgrammingMode == XDMAD_LLI) { free(pRxCh->pLLIview); pRxCh->pLLIview = NULL; } pRxCh->dmaProgress = 1; return 0; }