void setup_edma_loop(edma_loop_setup_t *loopSetup) { #if 0 #if (defined(__ICCARM__) || defined(__CC_ARM)) loopSetup->dmaChStcd = (edma_software_tcd_t *)mem_align(2 * sizeof(edma_software_tcd_t) * loopSetup->period, 32); #elif defined(__GNUC__) loopSetup->dmaChStcd = (edma_software_tcd_t *)memalign(32, 2 * sizeof(edma_software_tcd_t) * loopSetup->period); #endif #endif loopSetup->dmaChStcd = (edma_software_tcd_t *)(((uint32_t)ptcd + 32)& 0xFFFFFFE0); //printf(" eDMA TCD address is %x, them\r\n", (uint32_t)loopSetup->dmaChStcd); memset(loopSetup->dmaChStcd, 0, sizeof(edma_software_tcd_t)); EDMA_DRV_RequestChannel(loopSetup->dmaChanNum, loopSetup->chSource, loopSetup->dmaCh); EDMA_DRV_ConfigLoopTransfer(loopSetup->dmaCh, loopSetup->dmaChStcd, loopSetup->type, loopSetup->srcAddr, loopSetup->destAddr, loopSetup->size, loopSetup->watermark, loopSetup->length, loopSetup->period); if(loopSetup->dmaCallBack != NULL) { EDMA_DRV_InstallCallback(loopSetup->dmaCh, loopSetup->dmaCallBack, loopSetup->dmaCh); } }
void setup_edma_loop(edma_loop_setup_t *loopSetup) { memset(loopSetup->dmaChStcd, 0, sizeof(edma_software_tcd_t)); EDMA_DRV_RequestChannel(loopSetup->dmaChanNum, loopSetup->chSource, loopSetup->dmaCh); EDMA_DRV_ConfigLoopTransfer(loopSetup->dmaCh, loopSetup->dmaChStcd, loopSetup->type, loopSetup->srcAddr, loopSetup->destAddr, loopSetup->size, loopSetup->watermark, loopSetup->length, loopSetup->period); if(loopSetup->dmaCallBack != NULL) { EDMA_DRV_InstallCallback(loopSetup->dmaCh, loopSetup->dmaCallBack, loopSetup->dmaCh); } }
/*FUNCTION********************************************************************** * * Function Name : QSPI_DRV_ReadDataEdma * Description : Read data from QSPI rx FIFO/Buffer using EDMA way. This function * will open dma enable bit and transfer data in ISR. * *END**************************************************************************/ void QSPI_DRV_ReadDataEdma(uint32_t instance, uint32_t * addr, uint32_t size) { QuadSPI_Type * base = g_qspiBase[instance]; edma_transfer_config_t config = {0}; /* Update internal state */ g_qspiState[instance]->rxSize = size; g_qspiState[instance]->rxAddr = addr; g_qspiState[instance]->rxFinishedBytes = 0; if (!g_qspiState[instance]->rxUseDma) { /* Request edma channel */ uint8_t channel = 0; channel = EDMA_DRV_RequestChannel(kEDMAAnyChannel, g_qspiState[instance]->rxSource, &g_qspiState[instance]->rxEdmaChn); if (channel == kEDMAInvalidChannel) { return; } EDMA_DRV_InstallCallback(&g_qspiState[instance]->rxEdmaChn, QSPI_DRV_RxEdmaCallback, g_qspiState[instance]); g_qspiState[instance]->rxUseDma = true; } config.destAddr = (uint32_t)addr; config.destOffset = 4; config.destTransferSize = kEDMATransferSize_4Bytes; /* AHB buffer or ARDB */ config.srcAddr = QSPI_HAL_GetRxFifoAddr(base); config.srcTransferSize = kEDMATransferSize_4Bytes; config.srcOffset = 0; config.minorLoopCount = 4 * g_qspiState[instance]->rxWatermark; config.majorLoopCount = size/config.minorLoopCount; EDMA_DRV_PrepareDescriptorTransfer(&g_qspiState[instance]->rxEdmaChn, STCD_ADDR(g_qspiState[instance]->rxEdmaTCD), &config, true, true); EDMA_DRV_PushDescriptorToReg(&g_qspiState[instance]->rxEdmaChn, STCD_ADDR(g_qspiState[instance]->rxEdmaTCD)); EDMA_DRV_StartChannel(&g_qspiState[instance]->rxEdmaChn); /* Enable dma request */ QSPI_HAL_SetDmaCmd(base, kQspiRxBufferDrainDmaFlag, true); /* Enable interrupt to clear the underrun. */ QSPI_HAL_SetIntCmd(base, kQspiRxBufferOverflow, true); /* Enable module */ QSPI_HAL_EnableModule(base); g_qspiState[instance]->isRxBusy = true; }
/*FUNCTION********************************************************************** * * Function Name : QSPI_DRV_WriteDataEdma * Description : Write data into QSPI tx FIFO using EDMA. This function * will open dma enable bit and transfer data using EDMA. * *END**************************************************************************/ qspi_status_t QSPI_DRV_WriteDataEdma(uint32_t instance, uint32_t * addr, uint32_t size) { QuadSPI_Type * base = g_qspiBase[instance]; edma_transfer_config_t config = {0}; /* Update internal state */ g_qspiState[instance]->txSize = size; g_qspiState[instance]->txAddr = addr; g_qspiState[instance]->txFinishedBytes = 0; /* Request edma channel */ if (!g_qspiState[instance]->txUseDma) { uint8_t channel = 0; channel = EDMA_DRV_RequestChannel(kEDMAAnyChannel, g_qspiState[instance]->txSource, &g_qspiState[instance]->txEdmaChn); if (channel == kEDMAInvalidChannel) { return kStatus_QSPI_Fail; } EDMA_DRV_InstallCallback(&g_qspiState[instance]->txEdmaChn, QSPI_DRV_TxEdmaCallback, g_qspiState[instance]); g_qspiState[instance]->txUseDma = true; } config.srcAddr = (uint32_t)addr; config.destAddr = QSPI_HAL_GetTxFifoAddr(base); config.destTransferSize = kEDMATransferSize_4Bytes; config.srcTransferSize = kEDMATransferSize_4Bytes; config.destOffset = 0; config.srcOffset = 4; config.minorLoopCount = 4 * (FSL_FEATURE_QSPI_TXFIFO_DEPTH -g_qspiState[instance]->txWatermark); config.majorLoopCount = size/config.minorLoopCount; EDMA_DRV_PrepareDescriptorTransfer(&g_qspiState[instance]->txEdmaChn, STCD_ADDR(g_qspiState[instance]->txEdmaTCD), &config, true, true); EDMA_DRV_PushDescriptorToReg(&g_qspiState[instance]->txEdmaChn, STCD_ADDR(g_qspiState[instance]->txEdmaTCD)); EDMA_DRV_StartChannel(&g_qspiState[instance]->txEdmaChn); /* Enable dma request */ QSPI_HAL_SetDmaCmd(base, kQspiTxBufferFillDmaFlag, true); /* Enable interrupt to clear the underrun. */ QSPI_HAL_SetIntCmd(base, kQspiTxBufferUnderrun, true); /* Enable module */ QSPI_HAL_EnableModule(base); g_qspiState[instance]->isTxBusy = true; return kStatus_QSPI_Success; }
/*FUNCTION********************************************************************** * * Function Name : SND_RxInit * Description : Initialize the Rx soundcard. * The soundcard includes a controller and a codec. *END**************************************************************************/ snd_status_t SND_RxInit( sound_card_t * card, void * ctrl_config, void * codec_config, ctrl_state_t *state) { audio_controller_t *ctrl = &card->controller; audio_codec_t *codec = &card->codec; /* Allocate space for buffer */ audio_buffer_t *buffer = &card->buffer; /* Buffer size and block settings */ if ((buffer->blocks == 0) || (buffer->size == 0)) { buffer->blocks = AUDIO_BUFFER_BLOCK; buffer->size = AUDIO_BUFFER_BLOCK_SIZE; } #if SOUNDCARD_USE_STATIC_MEM buffer->buff = &s_rx_buffer[ctrl->instance][0]; #else buffer->buff = (uint8_t *)OSA_MemAllocZero(buffer->size * buffer->blocks); if(!buffer->buff) { return kStatus_SND_BufferAllocateFail; } #endif buffer->input_curbuff = buffer->buff; buffer->output_curbuff = buffer->buff; /* Initialize the status structure */ buffer->empty_block = buffer->blocks; buffer->full_block = 0; OSA_SemaCreate(&buffer->sem, 0); /* Initialize audio controller and codec */ ctrl->ops->Ctrl_RxInit(ctrl->instance, ctrl_config,state); codec->ops->Codec_Init((void *)codec->handler, codec_config); #if USEDMA EDMA_DRV_RequestChannel(kEDMAAnyChannel, ctrl->dma_source, &ctrl->dma_channel); EDMA_DRV_InstallCallback(&ctrl->dma_channel, SND_RxDmaCallback, (void *)card); #else ctrl->ops->Ctrl_RxRegisterCallback(ctrl->instance, SND_RxCallback, card); #endif return kStatus_SND_Success; }
/*FUNCTION********************************************************************* * * Function Name : FLEXIO_Camera_DRV_InitEdmaRx * Description : Configures the FLEXIO working as a CPI interface, the indicated * EDMA channel moving data from flexio interface to user defined memory. * With this function, a image of camera sensor can be mapped into user defined * memory, then user can read the mapped memory anytime in application. * *END*************************************************************************/ flexio_camera_status_t FLEXIO_Camera_DRV_InitEdmaRx( flexio_camera_edma_handler_t *handler, /* Output. */ flexio_camera_user_config_t *userFlexioCameraConfigPtr, /* Input. */ camera_edma_user_config_t *userEdmaConfigPtr ) /* Input. */ { flexio_camera_dev_t *flexioCameraHwConfigPtr; edma_transfer_config_t rxEdmeConfigStruct; edma_software_tcd_t rxEdmaChnStcd[2]; uint32_t ret; if ( (!handler) || (!userFlexioCameraConfigPtr) || (!userEdmaConfigPtr) ) { return kStatus_FlexIO_Camera_InvalidArgument; } memset(handler, 0, sizeof(flexio_camera_edma_handler_t)); /* Reset the handler's memory. */ flexioCameraHwConfigPtr = &(handler->flexioCameraHwConfig); flexioCameraHwConfigPtr->flexioBase = g_flexioBase[userFlexioCameraConfigPtr->flexioInstance]; flexioCameraHwConfigPtr->datPinStartIdx = userFlexioCameraConfigPtr->datPinStartIdx; flexioCameraHwConfigPtr->pclkPinIdx = userFlexioCameraConfigPtr->pclkPinIdx; flexioCameraHwConfigPtr->hrefPinIdx = userFlexioCameraConfigPtr->hrefPinIdx; flexioCameraHwConfigPtr->shifterStartIdx= userFlexioCameraConfigPtr->shifterStartIdx; flexioCameraHwConfigPtr->shifterCount = FSL_FLEXIO_CAMERA_USING_SHIFTER_COUNT; flexioCameraHwConfigPtr->timerIdx = userFlexioCameraConfigPtr->timerIdx; handler->userEdmaChn = userEdmaConfigPtr->userEdmaChn; handler->userBufAddr = userEdmaConfigPtr->userBufAddr; handler->userBufLenByte = userEdmaConfigPtr->userBufLenByte; /* Fill the edma channel configuration. */ rxEdmeConfigStruct.srcAddr = FLEXIO_Camera_HAL_GetRxBufferAddr(flexioCameraHwConfigPtr); rxEdmeConfigStruct.destAddr = handler->userBufAddr; rxEdmeConfigStruct.srcTransferSize = kEDMATransferSize_32Bytes;/* Using FSL_FLEXIO_CAMERA_USING_SHIFTER_COUNT = 8U. */ rxEdmeConfigStruct.destTransferSize = kEDMATransferSize_32Bytes; rxEdmeConfigStruct.srcOffset = 0; rxEdmeConfigStruct.destOffset = 4U * flexioCameraHwConfigPtr->shifterCount; /* 4 byte per shifter, typically 32 byte for 8 shifters. */ rxEdmeConfigStruct.srcLastAddrAdjust = 0; rxEdmeConfigStruct.destLastAddrAdjust = -(int32_t)(handler->userBufLenByte); rxEdmeConfigStruct.srcModulo = kEDMAModuloDisable; rxEdmeConfigStruct.destModulo = kEDMAModuloDisable; rxEdmeConfigStruct.minorLoopCount = rxEdmeConfigStruct.destOffset; /* the minor loop would read all the data in shifters one time per trigger. */ rxEdmeConfigStruct.majorLoopCount = handler->userBufLenByte/rxEdmeConfigStruct.minorLoopCount; /* Pre-configure the edma. */ /* 1. Request channel. */ ret = EDMA_DRV_RequestChannel( handler->userEdmaChn, (dma_request_source_t)(kDmaRequestMux0Group1FlexIO0Channel0 + flexioCameraHwConfigPtr->shifterStartIdx), &(handler->rxEdmaChnState) ); if (ret == kEDMAInvalidChannel) { return kStatus_FlexIO_Camera_Failed; } /* 2. Install callback. */ ret = EDMA_DRV_PrepareDescriptorTransfer( &handler->rxEdmaChnState, rxEdmaChnStcd, &rxEdmeConfigStruct, false, /* always disable EDMA transfer done interrupt. */ //enIntOnEdmaTransferLoop, false /* always disable auto shutdown Req when transfer done. *///enDisableReqAfterTransferLoop ); if (ret == kEDMAInvalidChannel) { return kStatus_FlexIO_Camera_Failed; } ret = EDMA_DRV_PushDescriptorToReg( &handler->rxEdmaChnState, rxEdmaChnStcd); if (ret == kEDMAInvalidChannel) { return kStatus_FlexIO_Camera_Failed; } /* Configure the flexio_camera. */ if (kStatus_FLEXIO_Success != FLEXIO_Camera_HAL_Configure(flexioCameraHwConfigPtr) ) { return kStatus_FlexIO_Camera_Failed; } return kStatus_FlexIO_Camera_Success; }
/*FUNCTION********************************************************************** * * Function Name : UART_DRV_EdmaInit * Description : This function initializes a UART instance for operation. * This function will initialize the run-time state structure to keep track of * the on-going transfers, ungate the clock to the UART module, initialize the * module to user defined settings and default settings, configure UART DMA * and enable the UART module transmitter and receiver. * The following is an example of how to set up the uart_edma_state_t and the * uart_user_config_t parameters and how to call the UART_DRV_EdmaInit function * by passing in these parameters: * uart_user_config_t uartConfig; * uartConfig.baudRate = 9600; * uartConfig.bitCountPerChar = kUart8BitsPerChar; * uartConfig.parityMode = kUartParityDisabled; * uartConfig.stopBitCount = kUartOneStopBit; * uart_edma_state_t uartEdmaState; * UART_DRV_EdmaInit(instance, &uartEdmaState, &uartConfig); * *END**************************************************************************/ uart_status_t UART_DRV_EdmaInit(uint32_t instance, uart_edma_state_t * uartEdmaStatePtr, const uart_edma_user_config_t * uartUserConfig) { assert(uartEdmaStatePtr && uartUserConfig); assert(g_uartBase[instance]); assert(instance < UART_INSTANCE_COUNT); /* This driver only support UART instances with separate DMA channels for * both Tx and Rx.*/ assert(FSL_FEATURE_UART_HAS_SEPARATE_DMA_RX_TX_REQn(instance) == 1); UART_Type * base = g_uartBase[instance]; uint32_t uartSourceClock = 0; dma_request_source_t uartTxEdmaRequest = kDmaRequestMux0Disable; dma_request_source_t uartRxEdmaRequest = kDmaRequestMux0Disable; /* Exit if current instance is already initialized. */ if (g_uartStatePtr[instance]) { return kStatus_UART_Initialized; } /* Clear the state structure for this instance. */ memset(uartEdmaStatePtr, 0, sizeof(uart_edma_state_t)); /* Save runtime structure pointer.*/ g_uartStatePtr[instance] = uartEdmaStatePtr; /* Un-gate UART module clock */ CLOCK_SYS_EnableUartClock(instance); /* Initialize UART to a known state. */ UART_HAL_Init(base); /* Create Semaphore for txIrq and rxIrq. */ OSA_SemaCreate(&uartEdmaStatePtr->txIrqSync, 0); OSA_SemaCreate(&uartEdmaStatePtr->rxIrqSync, 0); /* UART clock source is either system or bus clock depending on instance */ uartSourceClock = CLOCK_SYS_GetUartFreq(instance); /* Initialize UART baud rate, bit count, parity and stop bit. */ UART_HAL_SetBaudRate(base, uartSourceClock, uartUserConfig->baudRate); UART_HAL_SetBitCountPerChar(base, uartUserConfig->bitCountPerChar); UART_HAL_SetParityMode(base, uartUserConfig->parityMode); #if FSL_FEATURE_UART_HAS_STOP_BIT_CONFIG_SUPPORT UART_HAL_SetStopBitCount(base, uartUserConfig->stopBitCount); #endif switch (instance) { #if (FSL_FEATURE_UART_HAS_SEPARATE_DMA_RX_TX_REQn(0) == 1) case 0: uartRxEdmaRequest = kDmaRequestMux0UART0Rx; uartTxEdmaRequest = kDmaRequestMux0UART0Tx; break; #endif #if (FSL_FEATURE_UART_HAS_SEPARATE_DMA_RX_TX_REQn(1) == 1) case 1: uartRxEdmaRequest = kDmaRequestMux0UART1Rx; uartTxEdmaRequest = kDmaRequestMux0UART1Tx; break; #endif #if (FSL_FEATURE_UART_HAS_SEPARATE_DMA_RX_TX_REQn(2) == 1) case 2: uartRxEdmaRequest = kDmaRequestMux0UART2Rx; uartTxEdmaRequest = kDmaRequestMux0UART2Tx; break; #endif #if (FSL_FEATURE_UART_HAS_SEPARATE_DMA_RX_TX_REQn(3) == 1) case 3: uartRxEdmaRequest = kDmaRequestMux0UART3Rx; uartTxEdmaRequest = kDmaRequestMux0UART3Tx; break; #endif #if (FSL_FEATURE_UART_HAS_SEPARATE_DMA_RX_TX_REQn(4) == 1) case 4: uartRxEdmaRequest = kDmaRequestMux0UART4Rx; uartTxEdmaRequest = kDmaRequestMux0UART4Tx; break; #endif #if (FSL_FEATURE_UART_HAS_SEPARATE_DMA_RX_TX_REQn(5) == 1) case 5: uartRxEdmaRequest = kDmaRequestMux0UART5Rx; uartTxEdmaRequest = kDmaRequestMux0UART5Tx; break; #endif default : break; } /*--------------- Setup RX ------------------*/ /* Request DMA channels for RX FIFO. */ EDMA_DRV_RequestChannel(kEDMAAnyChannel, uartRxEdmaRequest, &uartEdmaStatePtr->edmaUartRx); EDMA_DRV_InstallCallback(&uartEdmaStatePtr->edmaUartRx, UART_DRV_EdmaRxCallback, (void *)instance); /*--------------- Setup TX ------------------*/ /* Request DMA channels for TX FIFO. */ EDMA_DRV_RequestChannel(kEDMAAnyChannel, uartTxEdmaRequest, &uartEdmaStatePtr->edmaUartTx); EDMA_DRV_InstallCallback(&uartEdmaStatePtr->edmaUartTx, UART_DRV_EdmaTxCallback, (void *)instance); /* Finally, enable the UART transmitter and receiver. * Enable DMA trigger when transmit data register empty, * and receive data register full. */ UART_HAL_SetTxDmaCmd(base, true); UART_HAL_SetRxDmaCmd(base, true); UART_HAL_EnableTransmitter(base); UART_HAL_EnableReceiver(base); return kStatus_UART_Success; }