void SpiFormat(Spi_t *obj, int8_t bits, int8_t cpol, int8_t cpha, int8_t slave) { spi_clock_polarity_t clockPolarity; spi_clock_phase_t clockPhase; spi_data_bitcount_mode_t bitCount; /* Disable Spi module */ SPI_HAL_Disable(obj->Spi); clockPolarity = ((cpol != 1) ? kSpiClockPolarity_ActiveHigh : kSpiClockPolarity_ActiveLow); clockPhase = ((cpha != 1) ? kSpiClockPhase_FirstEdge : kSpiClockPhase_SecondEdge); bitCount = ((bits != 8) ? kSpi16BitMode : kSpi8BitMode); if (obj->isSlave) { /* Set SPI to master mode */ SPI_HAL_SetMasterSlave(obj->Spi, kSpiSlave); } else { /* Set SPI to master mode */ SPI_HAL_SetMasterSlave(obj->Spi, kSpiMaster); // Set slave select to automatic output mode SPI_HAL_SetSlaveSelectOutputMode(obj->Spi, kSpiSlaveSelect_AutomaticOutput); } SPI_HAL_SetDataFormat(obj->Spi, clockPolarity, clockPhase, kSpiMsbFirst); SPI_HAL_Set8or16BitMode(obj->Spi, bitCount); /* Enable Spi module */ SPI_HAL_Enable(obj->Spi); }
/*FUNCTION********************************************************************** * * Function Name : SPI_DRV_MasterConfigureBus * Description : Configures the SPI port to access a device on the bus. * The term "device" is used to indicate the SPI device for which the SPI master is communicating. * The user has two options to configure the device parameters: either pass in the * pointer to the device configuration structure to the desired transfer function (see * SPI_DRV_MasterTransferDataBlocking or SPI_DRV_MasterTransferData) or pass it in to the * SPI_DRV_MasterConfigureBus function. The user can pass in a device structure to the transfer * function which contains the parameters for the bus (the transfer function will then call * this function). However, the user has the option to call this function directly especially * to get the calculated baud rate, at which point they may pass in NULL for the device * struct in the transfer function (assuming they have called this configure bus function * first). * *END**************************************************************************/ void SPI_DRV_MasterConfigureBus(uint32_t instance, const spi_master_user_config_t * device, uint32_t * calculatedBaudRate) { assert(device); /* instantiate local variable of type spi_master_state_t and point to global state */ spi_master_state_t * spiState = (spi_master_state_t *)g_spiStatePtr[instance]; SPI_Type *base = g_spiBase[instance]; /* Configure the bus to access the provided device.*/ *calculatedBaudRate = SPI_HAL_SetBaud(base, device->bitsPerSec, spiState->spiSourceClock); SPI_HAL_SetDataFormat(base, device->polarity, device->phase, device->direction); #if FSL_FEATURE_SPI_16BIT_TRANSFERS SPI_HAL_Set8or16BitMode(base, device->bitCount); #endif }
/*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; }
/*! * @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]); } } }