status_t USART_TransferCreateHandleDMA(USART_Type *base, usart_dma_handle_t *handle, usart_dma_transfer_callback_t callback, void *userData, dma_handle_t *txDmaHandle, dma_handle_t *rxDmaHandle) { int32_t instance = 0; /* check 'base' */ assert(!(NULL == base)); if (NULL == base) { return kStatus_InvalidArgument; } /* check 'handle' */ assert(!(NULL == handle)); if (NULL == handle) { return kStatus_InvalidArgument; } instance = FLEXCOMM_GetInstance(base); memset(handle, 0, sizeof(*handle)); /* assign 'base' and 'handle' */ s_dmaPrivateHandle[instance].base = base; s_dmaPrivateHandle[instance].handle = handle; /* set tx/rx 'idle' state */ handle->rxState = kUSART_RxIdle; handle->txState = kUSART_TxIdle; handle->callback = callback; handle->userData = userData; handle->rxDmaHandle = rxDmaHandle; handle->txDmaHandle = txDmaHandle; /* Configure TX. */ if (txDmaHandle) { DMA_SetCallback(txDmaHandle, USART_TransferSendDMACallback, &s_dmaPrivateHandle[instance]); } /* Configure RX. */ if (rxDmaHandle) { DMA_SetCallback(rxDmaHandle, USART_TransferReceiveDMACallback, &s_dmaPrivateHandle[instance]); } return kStatus_Success; }
void UART_TransferCreateHandleDMA(UART_Type *base, uart_dma_handle_t *handle, uart_dma_transfer_callback_t callback, void *userData, dma_handle_t *txDmaHandle, dma_handle_t *rxDmaHandle) { assert(handle); uint32_t instance = UART_GetInstance(base); memset(handle, 0, sizeof(*handle)); s_dmaPrivateHandle[instance].base = base; s_dmaPrivateHandle[instance].handle = handle; handle->rxState = kUART_RxIdle; handle->txState = kUART_TxIdle; handle->callback = callback; handle->userData = userData; #if defined(FSL_FEATURE_UART_HAS_FIFO) && FSL_FEATURE_UART_HAS_FIFO /* Note: Take care of the RX FIFO, DMA request only assert when received bytes equal or more than RX water mark, there is potential issue if RX water mark larger than 1. For example, if RX FIFO water mark is 2, upper layer needs 5 bytes and 5 bytes are received. the last byte will be saved in FIFO but not trigger DMA transfer because the water mark is 2. */ if (rxDmaHandle) { base->RWFIFO = 1U; } #endif handle->rxDmaHandle = rxDmaHandle; handle->txDmaHandle = txDmaHandle; /* Configure TX. */ if (txDmaHandle) { DMA_SetCallback(txDmaHandle, UART_TransferSendDMACallback, &s_dmaPrivateHandle[instance]); } /* Configure RX. */ if (rxDmaHandle) { DMA_SetCallback(rxDmaHandle, UART_TransferReceiveDMACallback, &s_dmaPrivateHandle[instance]); } }
void I2C_MasterTransferCreateHandleDMA(I2C_Type *base, i2c_master_dma_handle_t *handle, i2c_master_dma_transfer_callback_t callback, void *userData, dma_handle_t *dmaHandle) { assert(handle); assert(dmaHandle); uint32_t instance = I2C_GetInstance(base); /* Zero handle. */ memset(handle, 0, sizeof(*handle)); /* Set the user callback and userData. */ handle->completionCallback = callback; handle->userData = userData; /* Set the handle for DMA. */ handle->dmaHandle = dmaHandle; s_dmaPrivateHandle[instance].base = base; s_dmaPrivateHandle[instance].handle = handle; DMA_SetCallback(dmaHandle, (dma_callback)I2C_MasterTransferCallbackDMA, &s_dmaPrivateHandle[instance]); }
void SPIFI_TransferRxCreateHandleDMA(SPIFI_Type *base, spifi_dma_handle_t *handle, spifi_dma_callback_t callback, void *userData, dma_handle_t *dmaHandle) { assert(handle); uint32_t instance = SPIFI_GetInstance(base); s_dmaPrivateHandle[instance][1].base = base; s_dmaPrivateHandle[instance][1].handle = handle; memset(handle, 0, sizeof(*handle)); handle->state = kSPIFI_Idle; handle->dmaHandle = dmaHandle; handle->callback = callback; handle->userData = userData; /* Configure RX dma callback */ DMA_SetCallback(handle->dmaHandle, SPIFI_ReceiveDMACallback, &s_dmaPrivateHandle[instance][1]); }
void SPI_MasterTransferCreateHandleDMA(SPI_Type *base, spi_dma_handle_t *handle, spi_dma_callback_t callback, void *userData, dma_handle_t *txHandle, dma_handle_t *rxHandle) { assert(handle); dma_transfer_config_t config = {0}; uint32_t instance = SPI_GetInstance(base); /* Set spi base to handle */ handle->txHandle = txHandle; handle->rxHandle = rxHandle; handle->callback = callback; handle->userData = userData; /* Set SPI state to idle */ handle->state = kSPI_Idle; /* Set handle to global state */ s_dmaPrivateHandle[instance].base = base; s_dmaPrivateHandle[instance].handle = handle; /* Compute internal state */ #if defined(FSL_FEATURE_SPI_16BIT_TRANSFERS) && (FSL_FEATURE_SPI_16BIT_TRANSFERS) handle->bytesPerFrame = ((base->C2 & SPI_C2_SPIMODE_MASK) >> SPI_C2_SPIMODE_SHIFT) + 1U; #else handle->bytesPerFrame = 1U; #endif /* FSL_FEATURE_SPI_16BIT_TRANSFERS */ #if defined(FSL_FEATURE_SPI_HAS_FIFO) && (FSL_FEATURE_SPI_HAS_FIFO) /* If using DMA, disable FIFO, as the FIFO may cause data loss if the data size is not integer times of 2bytes. As SPI cannot set watermark to 0, only can set to 1/2 FIFO size or 3/4 FIFO size. */ if (FSL_FEATURE_SPI_FIFO_SIZEn(base) != 0) { base->C3 &= ~SPI_C3_FIFOMODE_MASK; } #endif /* FSL_FEATURE_SPI_HAS_FIFO */ /* Set the non-change attribute for Tx DMA transfer, to improve efficiency */ config.destAddr = SPI_GetDataRegisterAddress(base); config.enableDestIncrement = false; config.enableSrcIncrement = true; if (handle->bytesPerFrame == 1U) { config.srcSize = kDMA_Transfersize8bits; config.destSize = kDMA_Transfersize8bits; } else { config.srcSize = kDMA_Transfersize16bits; config.destSize = kDMA_Transfersize16bits; } DMA_SubmitTransfer(handle->txHandle, &config, true); /* Set non-change attribute for Rx DMA */ config.srcAddr = SPI_GetDataRegisterAddress(base); config.destAddr = 0U; config.enableDestIncrement = true; config.enableSrcIncrement = false; DMA_SubmitTransfer(handle->rxHandle, &config, true); /* Install callback for Tx dma channel */ DMA_SetCallback(handle->txHandle, SPI_TxDMACallback, &s_dmaPrivateHandle[instance]); DMA_SetCallback(handle->rxHandle, SPI_RxDMACallback, &s_dmaPrivateHandle[instance]); }