/*FUNCTION********************************************************************** * * Function Name : SPI_DRV_MasterInitDma * Description : Initialize a SPI instance for master mode operation with DMA support. * This function is exactly like the spi_master_init function but in addition, adds DMA support. * If the user desires to use DMA based transfers, then the user should use this function call * instead of the spi_master_init function call. Like the spi_master_init, * this function initializes the run-time state structure to track the ongoing * transfers, ungates the clock to the SPI module, resets the SPI module, initializes the module * to user defined settings and default settings, configures the IRQ state structure, enables * the module-level interrupt to the core, and enables the SPI module. * * This init function also configures the DMA module by requesting channels for DMA operation * and sets a "useDma" flag in the run-time state structure to notify transfer functions * to use DMA driven operations. * *END**************************************************************************/ void SPI_DRV_MasterInitDma(uint32_t instance, spi_master_state_t * spiState) { SPI_DRV_MasterInit(instance, spiState); /* Set the SPI run-time state struct flag to indicate it will use the DMA */ spiState->useDma = true; /*********************************** * Request DMA channel for RX FIFO ***********************************/ /* This channel transfers data from RX FIFO to receiveBuffer */ if (instance == 0) { DMA_DRV_RequestChannel(kDmaAnyChannel, kDmaRequestMux0SPI0Rx, &spiState->dmaReceive); } else { DMA_DRV_RequestChannel(kDmaAnyChannel, kDmaRequestMux0SPI1Rx, &spiState->dmaReceive); } /*********************************** * Request DMA channel for TX FIFO ***********************************/ if (instance == 0) { DMA_DRV_RequestChannel(kDmaAnyChannel, kDmaRequestMux0SPI0Tx, &spiState->dmaTransmit); } else { DMA_DRV_RequestChannel(kDmaAnyChannel, kDmaRequestMux0SPI1Tx, &spiState->dmaTransmit); } }
/*FUNCTION********************************************************************** * * Function Name : LPSCI_DRV_DmaInit * Description : This function initializes a LPSCI 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 LPSCI module, initialize the * module to user defined settings and default settings, configure LPSCI DMA * and enable the LPSCI module transmitter and receiver. * The following is an example of how to set up the lpsci_dma_state_t and the * lpsci_user_config_t parameters and how to call the LPSCI_DRV_DmaInit function * by passing in these parameters: * lpsci_user_config_t lpsciConfig; * lpsciConfig.baudRate = 9600; * lpsciConfig.bitCountPerChar = kLpsci8BitsPerChar; * lpsciConfig.parityMode = kLpsciParityDisabled; * lpsciConfig.stopBitCount = kLpsciOneStopBit; * lpsci_dma_state_t lpsciDmaState; * LPSCI_DRV_DmaInit(instance, &lpsciDmaState, &lpsciConfig); * *END**************************************************************************/ lpsci_status_t LPSCI_DRV_DmaInit(uint32_t instance, lpsci_dma_state_t * lpsciDmaStatePtr, const lpsci_dma_user_config_t * lpsciUserConfig) { assert(lpsciDmaStatePtr && lpsciUserConfig); assert(instance < UART0_INSTANCE_COUNT); UART0_Type * base = g_lpsciBase[instance]; uint32_t lpsciSourceClock = 0; dma_request_source_t lpsciTxDmaRequest = kDmaRequestMux0Disable; dma_request_source_t lpsciRxDmaRequest = kDmaRequestMux0Disable; dma_channel_t *chn; DMA_Type * dmaBase; dma_channel_link_config_t config; config.channel1 = 0; config.channel2 = 0; config.linkType = kDmaChannelLinkDisable; /* Exit if current instance is already initialized. */ if (g_lpsciStatePtr[instance]) { return kStatus_LPSCI_Initialized; } /* Clear the state structure for this instance. */ memset(lpsciDmaStatePtr, 0, sizeof(lpsci_dma_state_t)); /* Save runtime structure pointer.*/ g_lpsciStatePtr[instance] = lpsciDmaStatePtr; /* Un-gate LPSCI module clock */ CLOCK_SYS_EnableLpsciClock(instance); /* Set LPSCI clock source */ CLOCK_SYS_SetLpsciSrc(instance, lpsciUserConfig->clockSource); /* Initialize LPSCI to a known state. */ LPSCI_HAL_Init(base); /* Create Semaphore for txIrq and rxIrq. */ OSA_SemaCreate(&lpsciDmaStatePtr->txIrqSync, 0); OSA_SemaCreate(&lpsciDmaStatePtr->rxIrqSync, 0); /* LPSCI clock source is either system or bus clock depending on instance */ lpsciSourceClock = CLOCK_SYS_GetLpsciFreq(instance); /* Initialize LPSCI baud rate, bit count, parity and stop bit. */ LPSCI_HAL_SetBaudRate(base, lpsciSourceClock, lpsciUserConfig->baudRate); LPSCI_HAL_SetBitCountPerChar(base, lpsciUserConfig->bitCountPerChar); LPSCI_HAL_SetParityMode(base, lpsciUserConfig->parityMode); #if FSL_FEATURE_LPSCI_HAS_STOP_BIT_CONFIG_SUPPORT LPSCI_HAL_SetStopBitCount(base, lpsciUserConfig->stopBitCount); #endif /* Enable DMA trigger when transmit data register empty, * and receive data register full. */ LPSCI_HAL_SetTxDmaCmd(base, true); LPSCI_HAL_SetRxDmaCmd(base, true); switch (instance) { case 0: lpsciRxDmaRequest = kDmaRequestMux0LPSCI0Rx; lpsciTxDmaRequest = kDmaRequestMux0LPSCI0Tx; break; default : break; } /* Request DMA channels for RX FIFO. */ DMA_DRV_RequestChannel(kDmaAnyChannel, lpsciRxDmaRequest, &lpsciDmaStatePtr->dmaLpsciRx); DMA_DRV_RegisterCallback(&lpsciDmaStatePtr->dmaLpsciRx, LPSCI_DRV_DmaRxCallback, (void *)instance); chn = &lpsciDmaStatePtr->dmaLpsciRx; dmaBase = g_dmaBase[chn->channel/FSL_FEATURE_DMA_DMAMUX_CHANNELS]; DMA_HAL_SetAutoAlignCmd(dmaBase, chn->channel, false); DMA_HAL_SetCycleStealCmd(dmaBase, chn->channel, true); DMA_HAL_SetAsyncDmaRequestCmd(dmaBase, chn->channel, false); DMA_HAL_SetDisableRequestAfterDoneCmd(dmaBase, chn->channel, true); DMA_HAL_SetChanLink(dmaBase, chn->channel, &config); DMA_HAL_SetSourceAddr(dmaBase, chn->channel, LPSCI_HAL_GetDataRegAddr(base)); DMA_HAL_SetSourceModulo(dmaBase, chn->channel, kDmaModuloDisable); DMA_HAL_SetSourceTransferSize(dmaBase, chn->channel, kDmaTransfersize8bits); DMA_HAL_SetSourceIncrementCmd(dmaBase, chn->channel, false); DMA_HAL_SetDestModulo(dmaBase, chn->channel, kDmaModuloDisable); DMA_HAL_SetDestTransferSize(dmaBase, chn->channel, kDmaTransfersize8bits); DMA_HAL_SetDestIncrementCmd(dmaBase, chn->channel, true); DMA_HAL_SetIntCmd(dmaBase, chn->channel, true); /* Request DMA channels for TX FIFO. */ DMA_DRV_RequestChannel(kDmaAnyChannel, lpsciTxDmaRequest, &lpsciDmaStatePtr->dmaLpsciTx); DMA_DRV_RegisterCallback(&lpsciDmaStatePtr->dmaLpsciTx, LPSCI_DRV_DmaTxCallback, (void *)instance); chn = &lpsciDmaStatePtr->dmaLpsciTx; dmaBase = g_dmaBase[chn->channel/FSL_FEATURE_DMA_DMAMUX_CHANNELS]; DMA_HAL_SetAutoAlignCmd(dmaBase, chn->channel, false); DMA_HAL_SetCycleStealCmd(dmaBase, chn->channel, true); DMA_HAL_SetAsyncDmaRequestCmd(dmaBase, chn->channel, false); DMA_HAL_SetDisableRequestAfterDoneCmd(dmaBase, chn->channel, true); DMA_HAL_SetChanLink(dmaBase, chn->channel, &config); DMA_HAL_SetSourceModulo(dmaBase, chn->channel, kDmaModuloDisable); DMA_HAL_SetSourceTransferSize(dmaBase, chn->channel, kDmaTransfersize8bits); DMA_HAL_SetSourceIncrementCmd(dmaBase, chn->channel, true); DMA_HAL_SetDestAddr(dmaBase, chn->channel, LPSCI_HAL_GetDataRegAddr(base)); DMA_HAL_SetDestModulo(dmaBase, chn->channel, kDmaModuloDisable); DMA_HAL_SetDestTransferSize(dmaBase, chn->channel, kDmaTransfersize8bits); DMA_HAL_SetDestIncrementCmd(dmaBase, chn->channel, false); DMA_HAL_SetIntCmd(dmaBase, chn->channel, true); /* Finally, enable the LPSCI transmitter and receiver*/ LPSCI_HAL_EnableTransmitter(base); LPSCI_HAL_EnableReceiver(base); return kStatus_LPSCI_Success; }
/*FUNCTION********************************************************************** * * Function Name : DSPI_DRV_DmaMasterInit * Description : Initializes a DSPI instance for master mode operation to work with DMA. * This function uses a dma driven method for transferring data. * This function initializes the run-time state structure to track the ongoing * transfers, ungates the clock to the DSPI module, resets the DSPI module, initializes the module * to user defined settings and default settings, configures the IRQ state structure, enables * the module-level interrupt to the core, and enables the DSPI module. * The CTAR parameter is special in that it allows the user to have different SPI devices * connected to the same DSPI module instance in addition to different peripheral chip * selects. Each CTAR contains the bus attributes associated with that particular SPI device. * For most use cases where only one SPI device is connected per DSPI module * instance, use CTAR0. * This is an example to set up and call the DSPI_DRV_DmaMasterInit function by passing * in these parameters: * dspi_dma_master_state_t dspiDmaState; <- the user simply allocates memory for this struct * uint32_t calculatedBaudRate; * dspi_dma_master_user_config_t userConfig; <- the user fills out members for this struct * userConfig.isChipSelectContinuous = false; * userConfig.isSckContinuous = false; * userConfig.pcsPolarity = kDspiPcs_ActiveLow; * userConfig.whichCtar = kDspiCtar0; * userConfig.whichPcs = kDspiPcs0; * DSPI_DRV_DmaMasterInit(masterInstance, &dspiDmaState, &userConfig); * *END**************************************************************************/ dspi_status_t DSPI_DRV_DmaMasterInit(uint32_t instance, dspi_dma_master_state_t * dspiDmaState, const dspi_dma_master_user_config_t * userConfig) { uint32_t dspiSourceClock; SPI_Type *base = g_dspiBase[instance]; dma_request_source_t dspiTxDmaRequest = kDmaRequestMux0Disable; dma_request_source_t dspiRxDmaRequest = kDmaRequestMux0Disable; /* Check parameter pointers to make sure there are not NULL */ if ((dspiDmaState == NULL) || (userConfig == NULL)) { return kStatus_DSPI_InvalidParameter; } /* Clear the run-time state struct for this instance.*/ memset(dspiDmaState, 0, sizeof(* dspiDmaState)); /* Note, remember to first enable clocks to the DSPI module before making any register accesses * Enable clock for DSPI */ CLOCK_SYS_EnableSpiClock(instance); /* Get module clock freq*/ dspiSourceClock = CLOCK_SYS_GetSpiFreq(instance); /* Configure the run-time state struct with the DSPI source clock */ dspiDmaState->dspiSourceClock = dspiSourceClock; /* Configure the run-time state struct with the data command parameters*/ dspiDmaState->whichCtar = userConfig->whichCtar; /* set the dspiDmaState struct CTAR*/ dspiDmaState->whichPcs = userConfig->whichPcs; /* set the dspiDmaState struct whichPcs*/ dspiDmaState->isChipSelectContinuous = userConfig->isChipSelectContinuous; /* continuous PCS*/ /* Initialize the DSPI module registers to default value, which disables the module */ DSPI_HAL_Init(base); /* Init the interrupt sync object.*/ if (OSA_SemaCreate(&dspiDmaState->irqSync, 0) != kStatus_OSA_Success) { return kStatus_DSPI_Error; } /* Set to master mode.*/ DSPI_HAL_SetMasterSlaveMode(base, kDspiMaster); /* Configure for continuous SCK operation*/ DSPI_HAL_SetContinuousSckCmd(base, userConfig->isSckContinuous); /* Configure for peripheral chip select polarity*/ DSPI_HAL_SetPcsPolarityMode(base, userConfig->whichPcs, userConfig->pcsPolarity); /* Enable fifo operation (regardless of FIFO depth) */ DSPI_HAL_SetFifoCmd(base, true, true); /* Initialize the configurable delays: PCS-to-SCK, prescaler = 0, scaler = 1 */ DSPI_HAL_SetDelay(base, userConfig->whichCtar, 0, 1, kDspiPcsToSck); /* Save runtime structure pointers to irq handler can point to the correct state structure*/ g_dspiStatePtr[instance] = dspiDmaState; /* enable the interrupt*/ INT_SYS_EnableIRQ(g_dspiIrqId[instance]); /* DSPI system enable */ DSPI_HAL_Enable(base); /* Request DMA channels from the DMA peripheral driver. * Note, some MCUs have a separate RX and TX DMA request for each DSPI instance, while * other MCUs have a separate RX and TX DMA request for DSPI instance 0 only and shared DMA * requests for all other instances. Therefore, use the DSPI feature file to distinguish * how to request DMA channels between the various MCU DSPI instances. * For DSPI instances with shared RX/TX DMA requests, we'll use the RX DMA request to * trigger ongoing transfers and will link to the TX DMA channel from the RX DMA channel. */ switch (instance) { case 0: /* SPI0 */ #if FSL_FEATURE_DSPI_HAS_SEPARATE_DMA_RX_TX_REQn(0) dspiRxDmaRequest = kDmaRequestMux0SPI0Rx; dspiTxDmaRequest = kDmaRequestMux0SPI0Tx; #else /* DMA is simple link control, so DSPI - DMA driver does not support the case that DSPI have * shared DMA channels */ return kStatus_DSPI_DMAChannelInvalid; #endif break; #if (SPI_INSTANCE_COUNT > 1) case 1: /* SPI1 */ #if FSL_FEATURE_DSPI_HAS_SEPARATE_DMA_RX_TX_REQn(1) dspiRxDmaRequest = kDmaRequestMux0SPI1Rx; dspiTxDmaRequest = kDmaRequestMux0SPI1Tx; #else /* DMA is simple link control, so DSPI - DMA driver does not support the case that DSPI have * shared DMA channels */ return kStatus_DSPI_DMAChannelInvalid; #endif break; #endif #if (SPI_INSTANCE_COUNT > 2) case 2: /* SPI2 */ #if FSL_FEATURE_DSPI_HAS_SEPARATE_DMA_RX_TX_REQn(2) dspiRxDmaRequest = kDmaRequestMux0SPI2Rx; dspiTxDmaRequest = kDmaRequestMux0SPI2Tx; #else /* DMA is simple link control, so DSPI - DMA driver does not support the case that DSPI have * shared DMA channels */ return kStatus_DSPI_DMAChannelInvalid; #endif break; #endif default : return kStatus_DSPI_InvalidInstanceNumber; } /* This channel transfers data from RX FIFO to receiveBuffer */ if (kDmaInvalidChannel == DMA_DRV_RequestChannel(kDmaAnyChannel, dspiRxDmaRequest, &dspiDmaState->dmaRxChannel)) { return kStatus_DSPI_DMAChannelInvalid; } /* This channel transfers data from transmitBuffer to TX FIFO */ if (kDmaInvalidChannel == DMA_DRV_RequestChannel(kDmaAnyChannel, dspiTxDmaRequest, &dspiDmaState->dmaTxDataChannel)) { return kStatus_DSPI_DMAChannelInvalid; } /* Source buffer to intermediate command/data * This channel is not activated by dma request, but by channel link. */ if (DMA_DRV_RequestChannel(kDmaAnyChannel, kDmaRequestMux0Disable, &dspiDmaState->dmaTxCmdChannel) == kDmaInvalidChannel) { return kStatus_DSPI_DMAChannelInvalid; } /* Start the transfer process in the hardware */ DSPI_HAL_StartTransfer(base); return kStatus_DSPI_Success; }
/*FUNCTION********************************************************************** * * Function Name : UART_DRV_DmaInit * 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_dma_state_t and the * uart_user_config_t parameters and how to call the UART_DRV_DmaInit function * by passing in these parameters: * uart_user_config_t uartConfig; * uartConfig.baudRate = 9600; * uartConfig.bitCountPerChar = kUart8BitsPerChar; * uartConfig.parityMode = kUartParityDisabled; * uartConfig.stopBitCount = kUartOneStopBit; * uart_dma_state_t uartDmaState; * UART_DRV_DmaInit(instance, &uartDmaState, &uartConfig); * *END**************************************************************************/ uart_status_t UART_DRV_DmaInit(uint32_t instance, uart_dma_state_t * uartDmaStatePtr, const uart_dma_user_config_t * uartUserConfig) { assert(uartDmaStatePtr && 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 uartTxDmaRequest = kDmaRequestMux0Disable; dma_request_source_t uartRxDmaRequest = kDmaRequestMux0Disable; /* Exit if current instance is already initialized. */ if (g_uartStatePtr[instance]) { return kStatus_UART_Initialized; } /* Clear the state structure for this instance. */ memset(uartDmaStatePtr, 0, sizeof(uart_dma_state_t)); /* Save runtime structure pointer.*/ g_uartStatePtr[instance] = uartDmaStatePtr; /* 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(&uartDmaStatePtr->txIrqSync, 0); OSA_SemaCreate(&uartDmaStatePtr->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 /* Enable DMA trigger when transmit data register empty, * and receive data register full. */ UART_HAL_SetTxDmaCmd(base, true); UART_HAL_SetRxDmaCmd(base, true); switch (instance) { #if (FSL_FEATURE_UART_HAS_SEPARATE_DMA_RX_TX_REQn(0) == 1) case 0: uartRxDmaRequest = kDmaRequestMux0UART0Rx; uartTxDmaRequest = kDmaRequestMux0UART0Tx; break; #endif #if (FSL_FEATURE_UART_HAS_SEPARATE_DMA_RX_TX_REQn(1) == 1) case 1: uartRxDmaRequest = kDmaRequestMux0UART1Rx; uartTxDmaRequest = kDmaRequestMux0UART1Tx; break; #endif #if (FSL_FEATURE_UART_HAS_SEPARATE_DMA_RX_TX_REQn(2) == 1) case 2: uartRxDmaRequest = kDmaRequestMux0UART2Rx; uartTxDmaRequest = kDmaRequestMux0UART2Tx; break; #endif default : break; } /* Request DMA channels for RX FIFO. */ DMA_DRV_RequestChannel(kDmaAnyChannel, uartRxDmaRequest, &uartDmaStatePtr->dmaUartRx); DMA_DRV_RegisterCallback(&uartDmaStatePtr->dmaUartRx, UART_DRV_DmaRxCallback, (void *)instance); /* Request DMA channels for TX FIFO. */ DMA_DRV_RequestChannel(kDmaAnyChannel, uartTxDmaRequest, &uartDmaStatePtr->dmaUartTx); DMA_DRV_RegisterCallback(&uartDmaStatePtr->dmaUartTx, UART_DRV_DmaTxCallback, (void *)instance); /* Finally, enable the UART transmitter and receiver*/ UART_HAL_EnableTransmitter(base); UART_HAL_EnableReceiver(base); return kStatus_UART_Success; }
/*FUNCTION********************************************************************** * * Function Name : SPI_DRV_DmaSlaveInit * Description : Initializes the SPI module for slave mode. * Saves the application callback info, turns on the clock to the module, * enables the device, and enables interrupts. Sets the SPI to a slave mode. * *END**************************************************************************/ spi_status_t SPI_DRV_DmaSlaveInit(uint32_t instance, spi_dma_slave_state_t * spiState, const spi_dma_slave_user_config_t * slaveConfig) { SPI_Type *base = g_spiBase[instance]; assert(slaveConfig); assert(instance < SPI_INSTANCE_COUNT); assert(spiState); #if FSL_FEATURE_SPI_16BIT_TRANSFERS if (slaveConfig->bitCount > kSpi16BitMode) { /* bits/frame larger than hardware support */ return kStatus_SPI_InvalidParameter; } #endif /* FSL_FEATURE_SPI_16BIT_TRANSFERS */ /* Check if the slave already initialized */ if (g_spiStatePtr[instance]) { return kStatus_SPI_AlreadyInitialized; } /* Clear the state for this instance. */ memset(spiState, 0, sizeof(* spiState)); spiState->hasExtraByte = false; /* Update dummy pattern value */ spiState->dummyPattern = slaveConfig->dummyPattern; /* Enable clock for SPI */ CLOCK_SYS_EnableSpiClock(instance); /* Reset the SPI module to its default settings including disabling SPI */ SPI_HAL_Init(base); /* Initialize the event structure */ if (OSA_EventCreate(&spiState->event, kEventAutoClear) != kStatus_OSA_Success) { return kStatus_SPI_Error; } /* Set SPI to slave mode */ SPI_HAL_SetMasterSlave(base, kSpiSlave); /* Configure the slave clock polarity, phase and data direction */ SPI_HAL_SetDataFormat(base, slaveConfig->polarity, slaveConfig->phase, slaveConfig->direction); /* Set the SPI pin mode to normal mode */ SPI_HAL_SetPinMode(base, kSpiPinMode_Normal); #if FSL_FEATURE_SPI_16BIT_TRANSFERS SPI_HAL_Set8or16BitMode(base, slaveConfig->bitCount); #endif /* FSL_FEATURE_SPI_16BIT_TRANSFERS */ #if FSL_FEATURE_SPI_FIFO_SIZE if (g_spiFifoSize[instance] != 0) { /* If SPI module contains a FIFO, enable it and set watermarks to half full/empty */ SPI_HAL_SetFifoMode(base, true, kSpiTxFifoOneHalfEmpty, kSpiRxFifoOneHalfFull); /* Set the interrupt clearing mechansim select for later use in driver to clear * status flags */ SPI_HAL_SetIntClearCmd(base, true); } #endif /* FSL_FEATURE_SPI_FIFO_SIZE */ /***************************************** * Request DMA channel for RX and TX FIFO *****************************************/ /* This channel transfers data from RX FIFO to receiveBuffer */ if (instance == 0) { /* Request DMA channel for RX FIFO */ if (kDmaInvalidChannel == DMA_DRV_RequestChannel(kDmaAnyChannel, kDmaRequestMux0SPI0Rx, &spiState->dmaReceive)) { return kStatus_SPI_DMAChannelInvalid; } /* Request DMA channel for TX FIFO */ if (kDmaInvalidChannel == DMA_DRV_RequestChannel(kDmaAnyChannel, kDmaRequestMux0SPI0Tx, &spiState->dmaTransmit)) { return kStatus_SPI_DMAChannelInvalid; } } #if (SPI_INSTANCE_COUNT > 1) else if (instance == 1) { /* Request DMA channel for RX FIFO */ if (kDmaInvalidChannel == DMA_DRV_RequestChannel(kDmaAnyChannel, kDmaRequestMux0SPI1Rx, &spiState->dmaReceive)) { return kStatus_SPI_DMAChannelInvalid; } /* Request DMA channel for TX FIFO */ if (kDmaInvalidChannel == DMA_DRV_RequestChannel(kDmaAnyChannel, kDmaRequestMux0SPI1Tx, &spiState->dmaTransmit)) { return kStatus_SPI_DMAChannelInvalid; } } else { return kStatus_SPI_OutOfRange; } #endif /* Save runtime structure pointers to irq handler can point to the correct state structure */ g_spiStatePtr[instance] = spiState; /* Enable SPI interrupt. The transmit interrupt should immediately cause an interrupt * which will fill in the transmit buffer and will be ready to send once the slave initiates * transmission. */ INT_SYS_EnableIRQ(g_spiIrqId[instance]); /* SPI module enable */ SPI_HAL_Enable(base); return kStatus_SPI_Success; }
/*FUNCTION********************************************************************** * * Function Name : SPI_DRV_DmaMasterInit * Description : Initializes a SPI instance for master mode operation to work with DMA. * This function uses a dma driven method for transferring data. * this function initializes the run-time state structure to track the ongoing * transfers, ungates the clock to the SPI module, resets the SPI module, initializes the module * to user defined settings and default settings, configures the IRQ state structure, enables * the module-level interrupt to the core, and enables the SPI module. * * This initialization function also configures the DMA module by requesting channels for DMA * operation. * *END**************************************************************************/ spi_status_t SPI_DRV_DmaMasterInit(uint32_t instance, spi_dma_master_state_t * spiDmaState) { SPI_Type *base = g_spiBase[instance]; /* Clear the state for this instance.*/ memset(spiDmaState, 0, sizeof(* spiDmaState)); /* Enable clock for SPI*/ CLOCK_SYS_EnableSpiClock(instance); /* configure the run-time state struct with the source clock value */ spiDmaState->spiSourceClock = CLOCK_SYS_GetSpiFreq(instance); /* Reset the SPI module to it's default state, which includes SPI disabled */ SPI_HAL_Init(base); /* Init the interrupt sync object.*/ if (OSA_SemaCreate(&spiDmaState->irqSync, 0) != kStatus_OSA_Success) { return kStatus_SPI_Error; } /* Set SPI to master mode */ SPI_HAL_SetMasterSlave(base, kSpiMaster); /* Set slave select to automatic output mode */ SPI_HAL_SetSlaveSelectOutputMode(base, kSpiSlaveSelect_AutomaticOutput); /* Set the SPI pin mode to normal mode */ SPI_HAL_SetPinMode(base, kSpiPinMode_Normal); #if FSL_FEATURE_SPI_FIFO_SIZE if (g_spiFifoSize[instance] != 0) { /* If SPI module contains a FIFO, enable it and set watermarks to half full/empty */ SPI_HAL_SetFifoMode(base, true, kSpiTxFifoOneHalfEmpty, kSpiRxFifoOneHalfFull); /* Set the interrupt clearing mechansim select for later use in driver to clear * status flags */ SPI_HAL_SetIntClearCmd(base, true); } #endif /* Save runtime structure pointers to irq handler can point to the correct state structure*/ g_spiStatePtr[instance] = spiDmaState; /***************************************** * Request DMA channel for RX and TX FIFO *****************************************/ /* This channel transfers data from RX FIFO to receiveBuffer */ if (instance == 0) { /* Request DMA channel for RX FIFO */ DMA_DRV_RequestChannel(kDmaAnyChannel, kDmaRequestMux0SPI0Rx, &spiDmaState->dmaReceive); /* Request DMA channel for TX FIFO */ DMA_DRV_RequestChannel(kDmaAnyChannel, kDmaRequestMux0SPI0Tx, &spiDmaState->dmaTransmit); } #if (SPI_INSTANCE_COUNT > 1) else { /* Request DMA channel for RX FIFO */ DMA_DRV_RequestChannel(kDmaAnyChannel, kDmaRequestMux0SPI1Rx, &spiDmaState->dmaReceive); /* Request DMA channel for TX FIFO */ DMA_DRV_RequestChannel(kDmaAnyChannel, kDmaRequestMux0SPI1Tx, &spiDmaState->dmaTransmit); } #endif /* Enable SPI interrupt.*/ INT_SYS_EnableIRQ(g_spiIrqId[instance]); /* SPI system Enable */ SPI_HAL_Enable(base); return kStatus_SPI_Success; }
/*FUNCTION********************************************************************** * * Function Name : LPUART_DRV_DmaInit * Description : This function initializes a LPUART 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 LPUART module, initialize the * module to user defined settings and default settings, configure LPUART DMA * and enable the LPUART module transmitter and receiver. * The following is an example of how to set up the lpuart_dma_state_t and the * lpuart_user_config_t parameters and how to call the LPUART_DRV_DmaInit function * by passing in these parameters: * lpuart_user_config_t lpuartConfig; * lpuartConfig.baudRate = 9600; * lpuartConfig.bitCountPerChar = kLpuart8BitsPerChar; * lpuartConfig.parityMode = kLpuartParityDisabled; * lpuartConfig.stopBitCount = kLpuartOneStopBit; * lpuart_dma_state_t lpuartDmaState; * LPUART_DRV_DmaInit(instance, &lpuartDmaState, &lpuartConfig); * *END**************************************************************************/ lpuart_status_t LPUART_DRV_DmaInit(uint32_t instance, lpuart_dma_state_t * lpuartDmaStatePtr, const lpuart_dma_user_config_t * lpuartUserConfig) { assert(lpuartDmaStatePtr && lpuartUserConfig); assert(instance < LPUART_INSTANCE_COUNT); LPUART_Type * base = g_lpuartBase[instance]; uint32_t lpuartSourceClock = 0; dma_request_source_t lpuartTxDmaRequest = kDmaRequestMux0Disable; dma_request_source_t lpuartRxDmaRequest = kDmaRequestMux0Disable; /* Exit if current instance is already initialized. */ if (g_lpuartStatePtr[instance]) { return kStatus_LPUART_Initialized; } /* Clear the state structure for this instance. */ memset(lpuartDmaStatePtr, 0, sizeof(lpuart_dma_state_t)); /* Save runtime structure pointer.*/ g_lpuartStatePtr[instance] = lpuartDmaStatePtr; /* Un-gate LPUART module clock */ CLOCK_SYS_EnableLpuartClock(instance); /* Set LPUART clock source */ CLOCK_SYS_SetLpuartSrc(instance, lpuartUserConfig->clockSource); /* Initialize LPUART to a known state. */ LPUART_HAL_Init(base); /* Create Semaphore for txIrq and rxIrq. */ OSA_SemaCreate(&lpuartDmaStatePtr->txIrqSync, 0); OSA_SemaCreate(&lpuartDmaStatePtr->rxIrqSync, 0); /* LPUART clock source is either system or bus clock depending on instance */ lpuartSourceClock = CLOCK_SYS_GetLpuartFreq(instance); /* Initialize LPUART baud rate, bit count, parity and stop bit. */ LPUART_HAL_SetBaudRate(base, lpuartSourceClock, lpuartUserConfig->baudRate); LPUART_HAL_SetBitCountPerChar(base, lpuartUserConfig->bitCountPerChar); LPUART_HAL_SetParityMode(base, lpuartUserConfig->parityMode); #if FSL_FEATURE_LPUART_HAS_STOP_BIT_CONFIG_SUPPORT LPUART_HAL_SetStopBitCount(base, lpuartUserConfig->stopBitCount); #endif /* Enable DMA trigger when transmit data register empty, * and receive data register full. */ LPUART_HAL_SetTxDmaCmd(base, true); LPUART_HAL_SetRxDmaCmd(base, true); switch (instance) { case 0: lpuartRxDmaRequest = kDmaRequestMux0LPUART0Rx; lpuartTxDmaRequest = kDmaRequestMux0LPUART0Tx; break; default : break; } /* Request DMA channels for RX FIFO. */ DMA_DRV_RequestChannel(kDmaAnyChannel, lpuartRxDmaRequest, &lpuartDmaStatePtr->dmaLpuartRx); DMA_DRV_RegisterCallback(&lpuartDmaStatePtr->dmaLpuartRx, LPUART_DRV_DmaRxCallback, (void *)instance); /* Request DMA channels for TX FIFO. */ DMA_DRV_RequestChannel(kDmaAnyChannel, lpuartTxDmaRequest, &lpuartDmaStatePtr->dmaLpuartTx); DMA_DRV_RegisterCallback(&lpuartDmaStatePtr->dmaLpuartTx, LPUART_DRV_DmaTxCallback, (void *)instance); /* Finally, enable the LPUART transmitter and receiver*/ LPUART_HAL_SetTransmitterCmd(base, true); LPUART_HAL_SetReceiverCmd(base, true); return kStatus_LPUART_Success; }
/*! * @brief Main function */ int main (void) { /* enable clock for PORTs */ CLOCK_SYS_EnablePortClock(PORTA_IDX); //CLOCK_SYS_EnablePortClock(PORTB_IDX); CLOCK_SYS_EnablePortClock(PORTC_IDX); CLOCK_SYS_EnablePortClock(PORTD_IDX); CLOCK_SYS_EnablePortClock(PORTE_IDX); /* Set allowed power mode, allow all. */ SMC_HAL_SetProtection(SMC, kAllowPowerModeAll); /* Set system clock configuration. */ CLOCK_SYS_SetConfiguration(&g_defaultClockConfigVlpr); /* Initialize LPTMR */ lptmr_state_t lptmrState; LPTMR_DRV_Init(LPTMR0_IDX, &lptmrState, &g_lptmrConfig); LPTMR_DRV_SetTimerPeriodUs(LPTMR0_IDX, 100000); LPTMR_DRV_InstallCallback(LPTMR0_IDX, lptmr_call_back); /* Initialize DMA */ dma_state_t dma_state; DMA_DRV_Init(&dma_state); /* Initialize PIT */ PIT_DRV_Init(0, false); PIT_DRV_InitChannel(0, 0, &g_pitChan0); /* Initialize CMP */ CMP_DRV_Init(0, &g_cmpState, &g_cmpConf); CMP_DRV_ConfigDacChn(0, &g_cmpDacConf); PORT_HAL_SetMuxMode(g_portBase[GPIOC_IDX], 0, kPortMuxAlt5); CMP_DRV_Start(0); /* Buttons */ GPIO_DRV_InputPinInit(&g_switch1); GPIO_DRV_InputPinInit(&g_switch2); GPIO_DRV_InputPinInit(&g_switchUp); GPIO_DRV_InputPinInit(&g_switchDown); GPIO_DRV_InputPinInit(&g_switchLeft); GPIO_DRV_InputPinInit(&g_switchRight); GPIO_DRV_InputPinInit(&g_switchSelect); /* Start LPTMR */ LPTMR_DRV_Start(LPTMR0_IDX); /* Setup LPUART1 */ LPUART_DRV_Init(1, &g_lpuartState, &g_lpuartConfig); LPUART_DRV_InstallRxCallback(1, lpuartRxCallback, rxBuff, NULL, true); LPUART_DRV_InstallTxCallback(1, lpuartTxCallback, NULL, NULL); LPUART_BWR_CTRL_TXINV(g_lpuartBase[1], 1); PORT_HAL_SetMuxMode(g_portBase[GPIOE_IDX], 0, kPortMuxAlt3); PORT_HAL_SetMuxMode(g_portBase[GPIOE_IDX], 1, kPortMuxAlt3); /* Setup FlexIO for the WS2812B */ FLEXIO_Type *fiobase = g_flexioBase[0]; CLOCK_SYS_SetFlexioSrc(0, kClockFlexioSrcMcgIrClk); FLEXIO_DRV_Init(0, &g_flexioConfig); FLEXIO_HAL_ConfigureTimer(fiobase, 0, &g_timerConfig); FLEXIO_HAL_ConfigureShifter(fiobase, 0, &g_shifterConfig); PORT_HAL_SetMuxMode(g_portBase[GPIOE_IDX], 20, kPortMuxAlt6); FLEXIO_DRV_Start(0); FLEXIO_HAL_SetShifterStatusDmaCmd(fiobase, 1, true); DMA_DRV_RequestChannel(kDmaAnyChannel, kDmaRequestMux0FlexIOChannel0, &g_fioChan); DMA_DRV_RegisterCallback(&g_fioChan, fioDmaCallback, NULL); /* Connect buzzer to TPM0_CH3 */ PORT_HAL_SetMuxMode(g_portBase[GPIOE_IDX], 30, kPortMuxAlt3); tpm_general_config_t tmpConfig = { .isDBGMode = false, .isGlobalTimeBase = false, .isTriggerMode = false, .isStopCountOnOveflow = false, .isCountReloadOnTrig = false, .triggerSource = kTpmTrigSel0, }; TPM_DRV_Init(0, &tmpConfig); TPM_DRV_SetClock(0, kTpmClockSourceModuleMCGIRCLK, kTpmDividedBy1); /* Blank LED just in case, saves power */ led(0x00, 0x00, 0x00); /* Init e-paper display */ EPD_Init(); /* Throw up first image */ int ret = EPD_Draw(NULL, images[current_image]); if (-1 == ret) { led(0xff, 0x00, 0x00); } else if (-2 == ret) { led(0xff, 0xff, 0x00); } else if (-3 == ret) { led(0x00, 0x00, 0xff); } else { led(0x00, 0xff, 0x00); } blank_led = 30; /* Deinit so we can mess around on the bus pirate */ //EPD_Deinit(); /* We're done, everything else is triggered through interrupts */ for(;;) { if (cue_next_image) { int old_image = current_image; current_image = (current_image + 1) % image_count; EPD_Draw(images[old_image], images[current_image]); cue_next_image = 0; } #ifndef DEBUG SMC_HAL_SetMode(SMC, &g_idlePowerMode); #endif } }