/*FUNCTION********************************************************************** * * Function Name : DSPI_DRV_DmaRxCallback * Description : Callback function, this called when DMA receiving data * completed * *END**************************************************************************/ static void DSPI_DRV_DmaRxCallback(void *param, dma_channel_status_t status) { uint32_t instance = (uint32_t)param; SPI_Type *base = g_dspiBase[instance]; dspi_dma_master_state_t * dspiDmaState = (dspi_dma_master_state_t *)g_dspiStatePtr[instance]; /* Stop DMA Rx channel */ DMA_DRV_StopChannel(&dspiDmaState->dmaRxChannel); if (dspiDmaState->extraByte != 0) { /* Have one more byte, config DMA Rx channel to receive this byte */ DMA_DRV_ConfigTransfer(&dspiDmaState->dmaRxChannel, kDmaPeripheralToPeripheral, 1u, DSPI_HAL_GetPoprRegAddr(base), /* src is data register */ (uint32_t)(&s_rxBuffIfNull), /* dest is temporary location */ (uint32_t)(1u)); /* Register callback */ DMA_DRV_RegisterCallback(&dspiDmaState->dmaRxChannel, DSPI_DRV_DmaRxCallback, (void *)instance); /* Enable the DMA peripheral request */ DMA_DRV_StartChannel(&dspiDmaState->dmaRxChannel); if (dspiDmaState->rxBuffer) { /* Update the receive pointer to extra byte */ dspiDmaState->rxBuffer = dspiDmaState->rxBuffer + dspiDmaState->rxTransferByteCnt; } dspiDmaState->rxTransferByteCnt = 0; dspiDmaState->extraByte = false; return; } /* If transmission completed, stop the transferring */ if ((dspiDmaState->isTransferInProgress) && (dspiDmaState->rxTransferByteCnt == 0)) { /* Extra byte completed */ if (dspiDmaState->rxBuffer) { /* Store the extra byte */ *dspiDmaState->rxBuffer = (uint8_t)s_rxBuffIfNull; } /* Stop DMA Rx channel */ DMA_DRV_StopChannel(&dspiDmaState->dmaRxChannel); DSPI_DRV_DmaMasterCompleteTransfer(instance); } else { /* Stop DMA Rx channel */ DMA_DRV_StopChannel(&dspiDmaState->dmaRxChannel); DSPI_DRV_DmaMasterCompleteTransfer(instance); } }
/*FUNCTION********************************************************************** * * Function Name : SPI_DRV_DmaSlaveCompleteTransfer * Description : Finish up a transfer. * Cleans up after a transfer is complete. Interrupts are disabled, and the SPI module * is disabled. This is not a public API as it is called from other driver functions. * *END**************************************************************************/ static void SPI_DRV_DmaSlaveCompleteTransfer(uint32_t instance) { spi_dma_slave_state_t * spiState = (spi_dma_slave_state_t *)g_spiStatePtr[instance]; SPI_Type *base = g_spiBase[instance]; /* Disable DMA requests and interrupts. */ SPI_HAL_SetRxDmaCmd(base, false); SPI_HAL_SetTxDmaCmd(base, false); SPI_HAL_SetIntMode(base, kSpiTxEmptyInt, false); /* Stop DMA channels */ DMA_DRV_StopChannel(&spiState->dmaTransmit); DMA_DRV_StopChannel(&spiState->dmaReceive); /* Disable interrupts */ SPI_HAL_SetIntMode(base, kSpiRxFullAndModfInt, false); #if FSL_FEATURE_SPI_16BIT_TRANSFERS if (g_spiFifoSize[instance] != 0) { /* Now disable the SPI FIFO interrupts */ SPI_HAL_SetFifoIntCmd(base, kSpiTxFifoNearEmptyInt, false); SPI_HAL_SetFifoIntCmd(base, kSpiRxFifoNearFullInt, false); } /* Receive extra byte if remaining receive byte is 0 */ if ((spiState->hasExtraByte) && (!spiState->remainingReceiveByteCount) && (spiState->receiveBuffer)) { spiState->receiveBuffer[spiState->remainingReceiveByteCount] = SPI_HAL_ReadDataLow(base); } #endif /* FSL_FEATURE_SPI_16BIT_TRANSFERS */ if (spiState->isSync) { /* Signal the synchronous completion object */ OSA_EventSet(&spiState->event, kSpiDmaTransferDone); } /* The transfer is complete, update the state structure */ spiState->isTransferInProgress = false; spiState->status = kStatus_SPI_Success; spiState->errorCount = 0; spiState->sendBuffer = NULL; spiState->receiveBuffer = NULL; spiState->remainingSendByteCount = 0; spiState->remainingReceiveByteCount = 0; }
/*FUNCTION********************************************************************** * * Function Name : DSPI_DRV_DmaTxCallback * Description : Callback function, this called when DMA transmitting data * completed * *END**************************************************************************/ static void DSPI_DRV_DmaTxCallback(void *param, dma_channel_status_t status) { uint32_t instance = (uint32_t)param; SPI_Type *base = g_dspiBase[instance]; dspi_dma_master_state_t * dspiDmaState = (dspi_dma_master_state_t *)g_dspiStatePtr[instance]; uint32_t dmaChannel; DMAMUX_Type *dmamuxbase; dmaChannel = dspiDmaState->dmaTxDataChannel.channel; dmamuxbase = g_dmamuxBase[dmaChannel/FSL_FEATURE_DMAMUX_MODULE_CHANNEL]; // DMA_DRV_ClearStatus(&dspiDmaState->dmaTxDataChannel); DMAMUX_HAL_SetChannelCmd(dmamuxbase, dmaChannel, false); DMAMUX_HAL_SetChannelCmd(dmamuxbase, dmaChannel, true); /* Stop DMA Tx channel */ DMA_DRV_StopChannel(&dspiDmaState->dmaTxDataChannel); /* Setup DMA to transmit the last frame */ /* Have one more byte, config DMA Rx channel to receive this byte */ DMA_DRV_ConfigTransfer(&dspiDmaState->dmaTxDataChannel, kDmaPeripheralToPeripheral, 4u, (uint32_t)(&s_lastCmdData), /* src is data register */ DSPI_HAL_GetMasterPushrRegAddr(base), /* dest is temporary location */ 4u); /* Register callback */ DMA_DRV_RegisterCallback(&dspiDmaState->dmaTxDataChannel, DSPI_DRV_DmaTxLastCallback, (void *)instance); /* Enable the DMA peripheral request */ DMA_DRV_StartChannel(&dspiDmaState->dmaTxDataChannel); }
/*FUNCTION********************************************************************** * * Function Name : DSPI_DRV_DmaTxLastCallback * Description : Callback function, this called when DMA transmitting the last frame * completed * *END**************************************************************************/ static void DSPI_DRV_DmaTxLastCallback(void *param, dma_channel_status_t status) { uint32_t instance = (uint32_t)param; SPI_Type *base = g_dspiBase[instance]; dspi_dma_master_state_t * dspiDmaState = (dspi_dma_master_state_t *)g_dspiStatePtr[instance]; /* Stop DMA Tx channel */ DMA_DRV_StopChannel(&dspiDmaState->dmaTxDataChannel); /* Disable Tx Fifo fill interrupt */ DSPI_HAL_SetTxFifoFillDmaIntMode(base, kDspiGenerateDmaReq, false); }
/*FUNCTION********************************************************************** * * Function Name : LPSCI_DRV_DmaCompleteReceiveData * Description : Finish up a receive by completing the process of receiving data * and disabling the interrupt. * This is not a public API as it is called from other driver functions. * *END**************************************************************************/ static void LPSCI_DRV_DmaCompleteReceiveData(uint32_t instance) { assert(instance < UART0_INSTANCE_COUNT); lpsci_dma_state_t * lpsciDmaState = (lpsci_dma_state_t *)g_lpsciStatePtr[instance]; /* Stop DMA channel. */ DMA_DRV_StopChannel(&lpsciDmaState->dmaLpsciRx); /* Signal the synchronous completion object. */ if (lpsciDmaState->isRxBlocking) { OSA_SemaPost(&lpsciDmaState->rxIrqSync); } /* Update the information of the module driver state */ lpsciDmaState->isRxBusy = false; }
/*FUNCTION********************************************************************** * * Function Name : UART_DRV_DmaCompleteReceiveData * Description : Finish up a receive by completing the process of receiving data * and disabling the interrupt. * This is not a public API as it is called from other driver functions. * *END**************************************************************************/ static void UART_DRV_DmaCompleteReceiveData(uint32_t instance) { assert(instance < UART_INSTANCE_COUNT); uart_dma_state_t * uartDmaState = (uart_dma_state_t *)g_uartStatePtr[instance]; /* Stop DMA channel. */ DMA_DRV_StopChannel(&uartDmaState->dmaUartRx); /* Signal the synchronous completion object. */ if (uartDmaState->isRxBlocking) { OSA_SemaPost(&uartDmaState->rxIrqSync); } /* Update the information of the module driver state */ uartDmaState->isRxBusy = false; }
/*FUNCTION********************************************************************** * * Function Name : LPUART_DRV_DmaCompleteSendData * Description : Finish up a transmit by completing the process of sending * data and disabling the interrupt. * This is not a public API as it is called from other driver functions. * *END**************************************************************************/ static void LPUART_DRV_DmaCompleteSendData(uint32_t instance) { assert(instance < LPUART_INSTANCE_COUNT); lpuart_dma_state_t * lpuartDmaState = (lpuart_dma_state_t *)g_lpuartStatePtr[instance]; /* Stop DMA channel. */ DMA_DRV_StopChannel(&lpuartDmaState->dmaLpuartTx); /* Signal the synchronous completion object. */ if (lpuartDmaState->isTxBlocking) { OSA_SemaPost(&lpuartDmaState->txIrqSync); } /* Update the information of the module driver state */ lpuartDmaState->isTxBusy = false; }
/*FUNCTION********************************************************************** * * Function Name : LPSCI_DRV_DmaSendDataBlocking * Description : Sends (transmits) data out through the LPSCI-DMA module * using a blocking method. * *END**************************************************************************/ lpsci_status_t LPSCI_DRV_DmaSendDataBlocking(uint32_t instance, const uint8_t * txBuff, uint32_t txSize, uint32_t timeout) { assert(txBuff); assert(instance < UART0_INSTANCE_COUNT); lpsci_dma_state_t * lpsciDmaState = (lpsci_dma_state_t *)g_lpsciStatePtr[instance]; lpsci_status_t retVal = kStatus_LPSCI_Success; osa_status_t syncStatus; /* Indicates current transaction is blocking. */ lpsciDmaState->isTxBlocking = true; /* Start the transmission process */ retVal = LPSCI_DRV_DmaStartSendData(instance, txBuff, txSize); if (retVal == kStatus_LPSCI_Success) { /* Wait until the transmit is complete. */ do { syncStatus = OSA_SemaWait(&lpsciDmaState->txIrqSync, timeout); }while(syncStatus == kStatus_OSA_Idle); if (syncStatus != kStatus_OSA_Success) { /* Stop DMA channel. */ DMA_DRV_StopChannel(&lpsciDmaState->dmaLpsciTx); /* Update the information of the module driver state */ lpsciDmaState->isTxBusy = false; retVal = kStatus_LPSCI_Timeout; } } return retVal; }
/*FUNCTION********************************************************************** * * Function Name : LPSCI_DRV_DmaReceiveDataBlocking * Description : This function gets (receives) data from the LPSCI module using * a blocking method. A blocking (also known as synchronous) function means that * the function does not return until the receive is complete. This blocking * function is used to send data through the LPSCI port. * *END**************************************************************************/ lpsci_status_t LPSCI_DRV_DmaReceiveDataBlocking(uint32_t instance, uint8_t * rxBuff, uint32_t rxSize, uint32_t timeout) { assert(rxBuff); assert(instance < UART0_INSTANCE_COUNT); lpsci_dma_state_t * lpsciDmaState = (lpsci_dma_state_t *)g_lpsciStatePtr[instance]; lpsci_status_t retVal = kStatus_LPSCI_Success; osa_status_t syncStatus; /* Indicates current transaction is blocking. */ lpsciDmaState->isRxBlocking = true; retVal = LPSCI_DRV_DmaStartReceiveData(instance, rxBuff, rxSize); if (retVal == kStatus_LPSCI_Success) { /* Wait until all the data is received or for timeout.*/ do { syncStatus = OSA_SemaWait(&lpsciDmaState->rxIrqSync, timeout); }while(syncStatus == kStatus_OSA_Idle); if (syncStatus != kStatus_OSA_Success) { /* Stop DMA channel. */ DMA_DRV_StopChannel(&lpsciDmaState->dmaLpsciRx); /* Update the information of the module driver state */ lpsciDmaState->isRxBusy = false; retVal = kStatus_LPSCI_Timeout; } } return retVal; }
static void fioDmaCallback(void *param, dma_channel_status_t status) { DMA_DRV_StopChannel(&g_fioChan); }