/*!
 * @brief SPI slave polling.
 *
 * This function sends back received buffer from master through SPI interface.
 */
int main (void)
{
    uint32_t j;
    SPI_Type * spiBaseAddr = g_spiBase[SPI_SLAVE_INSTANCE];

    // init the hardware, this also sets up up the SPI pins for each specific SoC
    hardware_init();

    OSA_Init();

    PRINTF("\r\nSPI board to board polling example");
    PRINTF("\r\nThis example run on instance %d", (uint32_t)SPI_SLAVE_INSTANCE);
    PRINTF("\r\nBe sure master's SPI%d and slave's SPI%d are connected",
                    (uint32_t)SPI_SLAVE_INSTANCE, (uint32_t)SPI_SLAVE_INSTANCE);

    // Enable clock for SPI
    CLOCK_SYS_EnableSpiClock(SPI_SLAVE_INSTANCE);

    // Reset the SPI module to its default settings including disabling SPI
    SPI_HAL_Init(spiBaseAddr);

    // Set SPI to slave mode
    SPI_HAL_SetMasterSlave(spiBaseAddr, kSpiSlave);

    // Set the SPI pin mode to normal mode
    SPI_HAL_SetPinMode(spiBaseAddr, kSpiPinMode_Normal);

#if FSL_FEATURE_SPI_FIFO_SIZE
    if (g_spiFifoSize[SPI_SLAVE_INSTANCE] != 0)
    {
        // If SPI module contains a FIFO, disable it and set watermarks to half full/empty
        SPI_HAL_SetFifoMode(spiBaseAddr, false, kSpiTxFifoOneHalfEmpty, kSpiRxFifoOneHalfFull);
    }
#endif

    //USER CONFIGURABLE OPTION FOR 8 or 16-BIT MODE (if applicable)
#if FSL_FEATURE_SPI_16BIT_TRANSFERS
    SPI_HAL_Set8or16BitMode(spiBaseAddr, kSpi8BitMode);
#endif
    // SPI system Enable
    SPI_HAL_Enable(spiBaseAddr);
    // Setup format as same as master
    SPI_HAL_SetDataFormat(spiBaseAddr, kSpiClockPolarity_ActiveHigh, kSpiClockPhase_FirstEdge, kSpiMsbFirst);

    while(1)
    {
        PRINTF("\r\nSlave example is running...\r\n");

        // Reset the sink buffer
        for (j = 0; j < TRANSFER_SIZE; j++)
        {
            s_spiSinkBuffer[j] = 0;
        }

        SPI_HAL_Disable(spiBaseAddr);
        SPI_HAL_Enable(spiBaseAddr);

        // Disable module to clear shift register
        for (j = 0; j <TRANSFER_SIZE; j++)
        {
            // Check if data received
            while(SPI_HAL_IsReadBuffFullPending(spiBaseAddr)==0){}

#if FSL_FEATURE_SPI_16BIT_TRANSFERS
            // Read data from data register
            s_spiSinkBuffer[j] = SPI_HAL_ReadDataLow(spiBaseAddr);
#else
            s_spiSinkBuffer[j] = SPI_HAL_ReadData(spiBaseAddr);
#endif
        }

        // Disable module to clear shift register
        SPI_HAL_Disable(spiBaseAddr);
        SPI_HAL_Enable(spiBaseAddr);

        // Send data back to master
        for (j = 0; j <TRANSFER_SIZE; j++)
        {
#if FSL_FEATURE_SPI_16BIT_TRANSFERS
            SPI_HAL_WriteDataBlocking(spiBaseAddr, kSpi8BitMode, 0, s_spiSinkBuffer[j]);
#else
            SPI_HAL_WriteDataBlocking(spiBaseAddr, s_spiSinkBuffer[j]);
#endif
        }

        // Print out receive buffer
        PRINTF("\r\nSlave receive:");
        for (j = 0; j < TRANSFER_SIZE; j++)
        {
            // Print 16 numbers in a line.
            if ((j & 0x0F) == 0)
            {
                PRINTF("\r\n    ");
            }
            PRINTF(" %02X", s_spiSinkBuffer[j]);
        }
    }
}
예제 #2
0
/*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**************************************************************************/
void SPI_DRV_DmaMasterInit(uint32_t instance, spi_dma_master_state_t * spiDmaState)
{
    uint32_t baseAddr = g_spiBaseAddr[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(baseAddr);

    /* Init the interrupt sync object.*/
    OSA_SemaCreate(&spiDmaState->irqSync, 0);

    /* Set SPI to master mode */
    SPI_HAL_SetMasterSlave(baseAddr, kSpiMaster);

    /* Set slave select to automatic output mode */
    SPI_HAL_SetSlaveSelectOutputMode(baseAddr, kSpiSlaveSelect_AutomaticOutput);

    /* Set the SPI pin mode to normal mode */
    SPI_HAL_SetPinMode(baseAddr, kSpiPinMode_Normal);

#if FSL_FEATURE_SPI_FIFO_SIZE
    if (FSL_FEATURE_SPI_FIFO_SIZEn(instance) != 0)
    {
        /* If SPI module contains a FIFO, enable it and set watermarks to half full/empty */
        SPI_HAL_SetFifoMode(baseAddr, true, kSpiTxFifoOneHalfEmpty, kSpiRxFifoOneHalfFull);

        /* Set the interrupt clearing mechansim select for later use in driver to clear
         * status flags
         */
        SPI_HAL_SetIntClearCmd(baseAddr, 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 (HW_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(baseAddr);
}