Esempio n. 1
0
void SpiInit(Spi_t *obj, PinNames mosi, PinNames miso, PinNames sclk, PinNames nss)
{
    /* Check if a proper channel was selected */
    if (g_dspiBase[obj->instance] == NULL) return;

    obj->Spi = g_dspiBase[obj->instance];

    GpioInit(&obj->Mosi, mosi, PIN_ALTERNATE_FCT, PIN_PUSH_PULL, PIN_PULL_DOWN, 0);
    GpioInit(&obj->Miso, miso, PIN_ALTERNATE_FCT, PIN_PUSH_PULL, PIN_PULL_DOWN, 0);
    GpioInit(&obj->Sclk, sclk, PIN_ALTERNATE_FCT, PIN_PUSH_PULL, PIN_PULL_DOWN, 0);
    if (nss != NC) GpioInit(&obj->Nss, nss, PIN_ALTERNATE_FCT, PIN_PUSH_PULL, PIN_PULL_UP, 1);

    if (!obj->isSlave) {
        // Enable DSPI clock.
        CLOCK_SYS_EnableSpiClock(obj->instance);
        // Initialize the DSPI module registers to default value, which disables the module
        DSPI_HAL_Init(obj->Spi);
        // Set to master mode.
        DSPI_HAL_SetMasterSlaveMode(obj->Spi, kDspiMaster);
        // Configure for continuous SCK operation
        DSPI_HAL_SetContinuousSckCmd(obj->Spi, false);
        // Configure for peripheral chip select polarity
        DSPI_HAL_SetPcsPolarityMode(obj->Spi, kDspiPcs0, kDspiPcs_ActiveLow);
        // Disable FIFO operation.
        DSPI_HAL_SetFifoCmd(obj->Spi, false, false);
        // Initialize the configurable delays: PCS-to-SCK, prescaler = 0, scaler = 1
        DSPI_HAL_SetDelay(obj->Spi, kDspiCtar0, 0, 1, kDspiPcsToSck);
        // DSPI system enable
        DSPI_HAL_Enable(obj->Spi);

        // 8 bits, CPOL = 0, CPHA = 0, MASTER
        SpiFormat(obj, 8, 0, 0, 0);
    } else {
        // 8 bits, CPOL = 0, CPHA = 0, SLAVE
        SpiFormat(obj, 8, 0, 0, 1);
    }
    SpiFrequency(obj, 10000000);
}
Esempio n. 2
0
/*!
 * @brief DSPI master Polling.
 *
 * Thid function uses DSPI master to send an array to slave
 * and receive the array back from slave,
 * thencompare whether the two buffers are the same.
 */
int main(void)
{
    uint32_t i;
    uint32_t loopCount = 1;
    SPI_Type * dspiBaseAddr = (SPI_Type*)SPI0_BASE;
    uint32_t dspiSourceClock;
    uint32_t calculatedBaudRate;
    dspi_device_t masterDevice;
    dspi_command_config_t commandConfig = 
    {
        .isChipSelectContinuous = false,
        .whichCtar              = kDspiCtar0,
        .whichPcs               = kDspiPcs0,
        .clearTransferCount     = true,
        .isEndOfQueue           = false
    };

    // Init hardware
    hardware_init();
    // Init OSA layer, used in DSPI_DRV_MasterTransferBlocking.
    OSA_Init();
    // Call this function to initialize the console UART.  This function
    // enables the use of STDIO functions (printf, scanf, etc.)
    dbg_uart_init();
    // Print a note.
    printf("\r\n DSPI board to board polling example");
    printf("\r\n This example run on instance 0 ");
    printf("\r\n Be sure DSPI0-DSPI0 are connected ");

    // Configure SPI pins.
    configure_spi_pins(DSPI_MASTER_INSTANCE);

    // Enable DSPI clock.
    CLOCK_SYS_EnableSpiClock(DSPI_MASTER_INSTANCE);
    // Initialize the DSPI module registers to default value, which disables the module
    DSPI_HAL_Init(dspiBaseAddr);
    // Set to master mode.
    DSPI_HAL_SetMasterSlaveMode(dspiBaseAddr, kDspiMaster);
    // Configure for continuous SCK operation
    DSPI_HAL_SetContinuousSckCmd(dspiBaseAddr, false);
    // Configure for peripheral chip select polarity
    DSPI_HAL_SetPcsPolarityMode(dspiBaseAddr, kDspiPcs0, kDspiPcs_ActiveLow);
    // Disable FIFO operation.
    DSPI_HAL_SetFifoCmd(dspiBaseAddr, false, false);
    // Initialize the configurable delays: PCS-to-SCK, prescaler = 0, scaler = 1
    DSPI_HAL_SetDelay(dspiBaseAddr, kDspiCtar0, 0, 1, kDspiPcsToSck);
    // DSPI system enable
    DSPI_HAL_Enable(dspiBaseAddr);

    // Configure baudrate.
    masterDevice.dataBusConfig.bitsPerFrame = 8;
    masterDevice.dataBusConfig.clkPhase     = kDspiClockPhase_FirstEdge;
    masterDevice.dataBusConfig.clkPolarity  = kDspiClockPolarity_ActiveHigh;
    masterDevice.dataBusConfig.direction    = kDspiMsbFirst;

    DSPI_HAL_SetDataFormat(dspiBaseAddr, kDspiCtar0, &masterDevice.dataBusConfig);
    // Get DSPI source clock.
    dspiSourceClock = CLOCK_SYS_GetSpiFreq(DSPI_MASTER_INSTANCE);
    calculatedBaudRate = DSPI_HAL_SetBaudRate(dspiBaseAddr, kDspiCtar0, TRANSFER_BAUDRATE, dspiSourceClock);
    printf("\r\n Transfer at baudrate %lu \r\n", calculatedBaudRate);

    while(1)
    {
        // Initialize the transmit buffer.
        for (i = 0; i < TRANSFER_SIZE; i++)
        {
            sendBuffer[i] = i + loopCount;
        }

        // Print out transmit buffer.
        printf("\r\n Master transmit:");
        for (i = 0; i < TRANSFER_SIZE; i++)
        {
            // Print 16 numbers in a line.
            if ((i & 0x0F) == 0)
            {
                printf("\r\n    ");
            }
            printf(" %02X", sendBuffer[i]);
        }

        // Reset the receive buffer.
        for (i = 0; i < TRANSFER_SIZE; i++)
        {
            receiveBuffer[i] = 0;
        }

        // Restart the transfer by stop then start again, this will clear out the shift register
        DSPI_HAL_StopTransfer(dspiBaseAddr);
        // Flush the FIFOs
        DSPI_HAL_SetFlushFifoCmd(dspiBaseAddr, true, true);
        // Clear status flags that may have been set from previous transfers.
        DSPI_HAL_ClearStatusFlag(dspiBaseAddr, kDspiTxComplete);
        DSPI_HAL_ClearStatusFlag(dspiBaseAddr, kDspiEndOfQueue);
        DSPI_HAL_ClearStatusFlag(dspiBaseAddr, kDspiTxFifoUnderflow);
        DSPI_HAL_ClearStatusFlag(dspiBaseAddr, kDspiTxFifoFillRequest);
        DSPI_HAL_ClearStatusFlag(dspiBaseAddr, kDspiRxFifoOverflow);
        DSPI_HAL_ClearStatusFlag(dspiBaseAddr, kDspiRxFifoDrainRequest);
        // Clear the transfer count.
        DSPI_HAL_PresetTransferCount(dspiBaseAddr, 0);
        // Start the transfer process in the hardware
        DSPI_HAL_StartTransfer(dspiBaseAddr);
        // Send the data to slave.
        for (i = 0; i < TRANSFER_SIZE; i++)
        {
            // Write data to PUSHR
            DSPI_HAL_WriteDataMastermodeBlocking(dspiBaseAddr, &commandConfig, sendBuffer[i]);
            // Delay to wait slave is ready.
            OSA_TimeDelay(1);
        }

        // Delay to wait slave is ready.
        OSA_TimeDelay(10);

        // Restart the transfer by stop then start again, this will clear out the shift register
        DSPI_HAL_StopTransfer(dspiBaseAddr);
        // Flush the FIFOs
        DSPI_HAL_SetFlushFifoCmd(dspiBaseAddr, true, true);
        //Clear status flags that may have been set from previous transfers.
        DSPI_HAL_ClearStatusFlag(dspiBaseAddr, kDspiTxComplete);
        DSPI_HAL_ClearStatusFlag(dspiBaseAddr, kDspiEndOfQueue);
        DSPI_HAL_ClearStatusFlag(dspiBaseAddr, kDspiTxFifoUnderflow);
        DSPI_HAL_ClearStatusFlag(dspiBaseAddr, kDspiTxFifoFillRequest);
        DSPI_HAL_ClearStatusFlag(dspiBaseAddr, kDspiRxFifoOverflow);
        DSPI_HAL_ClearStatusFlag(dspiBaseAddr, kDspiRxFifoDrainRequest);
        // Clear the transfer count.
        DSPI_HAL_PresetTransferCount(dspiBaseAddr, 0);
        // Start the transfer process in the hardware
        DSPI_HAL_StartTransfer(dspiBaseAddr);
        // Receive the data from slave.
        for (i = 0; i < TRANSFER_SIZE; i++)
        {
            // Write command to PUSHR.
            DSPI_HAL_WriteDataMastermodeBlocking(dspiBaseAddr, &commandConfig, 0);
            // Check RFDR flag
            while (DSPI_HAL_GetStatusFlag(dspiBaseAddr, kDspiRxFifoDrainRequest)== false)
            {}
            // Read data from POPR
            receiveBuffer[i] = DSPI_HAL_ReadData(dspiBaseAddr);
            // Clear RFDR flag
            DSPI_HAL_ClearStatusFlag(dspiBaseAddr,kDspiRxFifoDrainRequest);
            // Delay to wait slave is ready.
            OSA_TimeDelay(1);
        }

        // Print out receive buffer.
        printf("\r\n Master receive:");
        for (i = 0; i < TRANSFER_SIZE; i++)
        {
            // Print 16 numbers in a line.
            if ((i & 0x0F) == 0)
            {
                printf("\r\n    ");
            }
            printf(" %02X", receiveBuffer[i]);
        }

        // Check receiveBuffer.
        for (i = 0; i < TRANSFER_SIZE; ++i)
        {
            if (receiveBuffer[i] != sendBuffer[i])
            {
                // Master received incorrect.
                printf("\r\n ERROR: master received incorrect ");
                return -1;
            }
        }

        printf("\r\n DSPI Master Sends/ Recevies Successfully");
        // Wait for press any key.
        printf("\r\n Press any key to run again");
        getchar();
        // Increase loop count to change transmit buffer.
        loopCount++;
    }
}
Esempio n. 3
0
/*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;
}
Esempio n. 4
0
/*FUNCTION**********************************************************************
 *
 * Function Name : DSPI_DRV_MasterInit
 * Description   : Initialize a DSPI instance for master mode operation.
 * This function uses a CPU interrupt driven method for transferring data.
 * This function will initialize the run-time state structure to keep track of the on-going
 * transfers, ungate the clock to the DSPI module, reset the DSPI module, initialize the module
 * to user defined settings and default settings, configure the IRQ state structure and enable
 * the module-level interrupt to the core, and enable 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 conjunction with different peripheral chip
 * selects. Each CTAR contains the bus attributes associated with that particular SPI device.
 * For simplicity and for most use cases where only one SPI device is connected per DSPI module
 * instance, it is recommended to use CTAR0.
 * The following is an example of how to set up the dspi_master_state_t and the
 * dspi_master_user_config_t parameters and how to call the DSPI_DRV_MasterInit function by passing
 * in these parameters:
 *   dspi_master_state_t dspiMasterState; <- the user simply allocates memory for this struct
 *   uint32_t calculatedBaudRate;
 *   dspi_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_MasterInit(masterInstance, &dspiMasterState, &userConfig);
 *
 *END**************************************************************************/
dspi_status_t DSPI_DRV_MasterInit(uint32_t instance,
                                  dspi_master_state_t * dspiState,
                                  const dspi_master_user_config_t * userConfig)
{
    uint32_t dspiSourceClock;
    dspi_status_t errorCode = kStatus_DSPI_Success;

    SPI_Type *base = g_dspiBase[instance];

    /* Clear the run-time state struct for this instance.*/
    memset(dspiState, 0, sizeof(* dspiState));

    /* 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 */
    dspiState->dspiSourceClock = dspiSourceClock;

    /* Configure the run-time state struct with the data command parameters*/
    dspiState->whichCtar = userConfig->whichCtar;  /* set the dspiState struct CTAR*/
    dspiState->whichPcs = userConfig->whichPcs;  /* set the dspiState struct whichPcs*/
    dspiState->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.*/
    OSA_SemaCreate(&dspiState->irqSync, 0);

    /* Initialize the DSPI module with user config */

    /* 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] = dspiState;

    /* enable the interrupt*/
    INT_SYS_EnableIRQ(g_dspiIrqId[instance]);

    /* DSPI system enable */
    DSPI_HAL_Enable(base);

    /* Start the transfer process in the hardware */
    DSPI_HAL_StartTransfer(base);

    return errorCode;
}