/*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;
}
Example #8
0
/*!
 * @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
    }
}