1 /*
2  * Copyright (c) 2016, Freescale Semiconductor, Inc.
3  * Copyright 2016-2020,2022 NXP
4  * All rights reserved.
5  *
6  * SPDX-License-Identifier: BSD-3-Clause
7  */
8 #ifndef FSL_SPI_H_
9 #define FSL_SPI_H_
10 
11 #include "fsl_common.h"
12 #include "fsl_flexcomm.h"
13 
14 /*!
15  * @addtogroup spi_driver
16  * @{
17  */
18 
19 /*! @file */
20 
21 /*******************************************************************************
22  * Definitions
23  ******************************************************************************/
24 
25 /*! @name Driver version */
26 /*! @{ */
27 /*! @brief SPI driver version. */
28 #define FSL_SPI_DRIVER_VERSION (MAKE_VERSION(2, 3, 2))
29 /*! @} */
30 /*! @brief SPI default SSEL COUNT*/
31 #if !(defined(FSL_FEATURE_SPI_SSEL_COUNT) || defined(FSL_FEATURE_SPI_IS_SSEL_PIN_COUNT_EQUAL_TO_THREE))
32 #define FSL_FEATURE_SPI_SSEL_COUNT (4U)
33 #endif
34 
35 /*! @brief Global variable for dummy data value setting. */
36 extern volatile uint8_t s_dummyData[];
37 
38 #ifndef SPI_DUMMYDATA
39 /*! @brief SPI dummy transfer data, the data is sent while txBuff is NULL. */
40 #define SPI_DUMMYDATA (0x00U)
41 #endif
42 
43 /*! @brief Retry times for waiting flag. */
44 #ifndef SPI_RETRY_TIMES
45 #define SPI_RETRY_TIMES 0U /* Define to zero means keep waiting until the flag is assert/deassert. */
46 #endif
47 
48 #define SPI_DATA(n)  (((uint32_t)(n)) & 0xFFFFUL)
49 #define SPI_CTRLMASK (0xFFFF0000U)
50 
51 #define SPI_ASSERTNUM_SSEL(n)   ((~(1UL << ((n) + 16UL))) & 0xF0000UL)
52 #define SPI_DEASSERTNUM_SSEL(n) (1UL << ((n) + 16UL))
53 #define SPI_DEASSERT_ALL        (0xF0000UL)
54 
55 #define SPI_FIFOWR_FLAGS_MASK (~(SPI_DEASSERT_ALL | SPI_FIFOWR_TXDATA_MASK | SPI_FIFOWR_LEN_MASK))
56 
57 #define SPI_FIFOTRIG_TXLVL_GET(base) (((base)->FIFOTRIG & SPI_FIFOTRIG_TXLVL_MASK) >> SPI_FIFOTRIG_TXLVL_SHIFT)
58 #define SPI_FIFOTRIG_RXLVL_GET(base) (((base)->FIFOTRIG & SPI_FIFOTRIG_RXLVL_MASK) >> SPI_FIFOTRIG_RXLVL_SHIFT)
59 
60 /*! @brief SPI transfer option.*/
61 typedef enum _spi_xfer_option
62 {
63     kSPI_FrameDelay  = (SPI_FIFOWR_EOF_MASK), /*!< A delay may be inserted, defined in the DLY register.*/
64     kSPI_FrameAssert = (SPI_FIFOWR_EOT_MASK), /*!< SSEL will be deasserted at the end of a transfer */
65 } spi_xfer_option_t;
66 
67 /*! @brief SPI data shifter direction options.*/
68 typedef enum _spi_shift_direction
69 {
70     kSPI_MsbFirst = 0U, /*!< Data transfers start with most significant bit. */
71     kSPI_LsbFirst = 1U  /*!< Data transfers start with least significant bit. */
72 } spi_shift_direction_t;
73 
74 /*! @brief SPI clock polarity configuration.*/
75 typedef enum _spi_clock_polarity
76 {
77     kSPI_ClockPolarityActiveHigh = 0x0U, /*!< Active-high SPI clock (idles low). */
78     kSPI_ClockPolarityActiveLow          /*!< Active-low SPI clock (idles high). */
79 } spi_clock_polarity_t;
80 
81 /*! @brief SPI clock phase configuration.*/
82 typedef enum _spi_clock_phase
83 {
84     kSPI_ClockPhaseFirstEdge = 0x0U, /*!< First edge on SCK occurs at the middle of the first
85                                       *   cycle of a data transfer. */
86     kSPI_ClockPhaseSecondEdge        /*!< First edge on SCK occurs at the start of the
87                                       *   first cycle of a data transfer. */
88 } spi_clock_phase_t;
89 
90 /*! @brief txFIFO watermark values */
91 typedef enum _spi_txfifo_watermark
92 {
93     kSPI_TxFifo0 = 0, /*!< SPI tx watermark is empty */
94     kSPI_TxFifo1 = 1, /*!< SPI tx watermark at 1 item */
95     kSPI_TxFifo2 = 2, /*!< SPI tx watermark at 2 items */
96     kSPI_TxFifo3 = 3, /*!< SPI tx watermark at 3 items */
97     kSPI_TxFifo4 = 4, /*!< SPI tx watermark at 4 items */
98     kSPI_TxFifo5 = 5, /*!< SPI tx watermark at 5 items */
99     kSPI_TxFifo6 = 6, /*!< SPI tx watermark at 6 items */
100     kSPI_TxFifo7 = 7, /*!< SPI tx watermark at 7 items */
101 } spi_txfifo_watermark_t;
102 
103 /*! @brief rxFIFO watermark values */
104 typedef enum _spi_rxfifo_watermark
105 {
106     kSPI_RxFifo1 = 0, /*!< SPI rx watermark at 1 item */
107     kSPI_RxFifo2 = 1, /*!< SPI rx watermark at 2 items */
108     kSPI_RxFifo3 = 2, /*!< SPI rx watermark at 3 items */
109     kSPI_RxFifo4 = 3, /*!< SPI rx watermark at 4 items */
110     kSPI_RxFifo5 = 4, /*!< SPI rx watermark at 5 items */
111     kSPI_RxFifo6 = 5, /*!< SPI rx watermark at 6 items */
112     kSPI_RxFifo7 = 6, /*!< SPI rx watermark at 7 items */
113     kSPI_RxFifo8 = 7, /*!< SPI rx watermark at 8 items */
114 } spi_rxfifo_watermark_t;
115 
116 /*! @brief Transfer data width */
117 typedef enum _spi_data_width
118 {
119     kSPI_Data4Bits  = 3,  /*!< 4 bits data width */
120     kSPI_Data5Bits  = 4,  /*!< 5 bits data width */
121     kSPI_Data6Bits  = 5,  /*!< 6 bits data width */
122     kSPI_Data7Bits  = 6,  /*!< 7 bits data width */
123     kSPI_Data8Bits  = 7,  /*!< 8 bits data width */
124     kSPI_Data9Bits  = 8,  /*!< 9 bits data width */
125     kSPI_Data10Bits = 9,  /*!< 10 bits data width */
126     kSPI_Data11Bits = 10, /*!< 11 bits data width */
127     kSPI_Data12Bits = 11, /*!< 12 bits data width */
128     kSPI_Data13Bits = 12, /*!< 13 bits data width */
129     kSPI_Data14Bits = 13, /*!< 14 bits data width */
130     kSPI_Data15Bits = 14, /*!< 15 bits data width */
131     kSPI_Data16Bits = 15, /*!< 16 bits data width */
132 } spi_data_width_t;
133 
134 /*! @brief Slave select */
135 typedef enum _spi_ssel
136 {
137     kSPI_Ssel0 = 0, /*!< Slave select 0 */
138     kSPI_Ssel1 = 1, /*!< Slave select 1 */
139     kSPI_Ssel2 = 2, /*!< Slave select 2 */
140     kSPI_Ssel3 = 3, /*!< Slave select 3 */
141 } spi_ssel_t;
142 
143 /*! @brief ssel polarity */
144 typedef enum _spi_spol
145 {
146     kSPI_Spol0ActiveHigh = SPI_CFG_SPOL0(1),
147     kSPI_Spol1ActiveHigh = SPI_CFG_SPOL1(1),
148 #if ((defined(FSL_FEATURE_SPI_SSEL_COUNT) && (FSL_FEATURE_SPI_SSEL_COUNT > 2)) || \
149      (defined(FSL_FEATURE_SPI_IS_SSEL_PIN_COUNT_EQUAL_TO_THREE) &&                \
150       (FSL_FEATURE_SPI_IS_SSEL_PIN_COUNT_EQUAL_TO_THREE)))
151     kSPI_Spol2ActiveHigh = SPI_CFG_SPOL2(1),
152 #endif
153 #if defined(FSL_FEATURE_SPI_IS_SSEL_PIN_COUNT_EQUAL_TO_THREE) && (FSL_FEATURE_SPI_IS_SSEL_PIN_COUNT_EQUAL_TO_THREE)
154     kSPI_SpolActiveAllHigh = (kSPI_Spol0ActiveHigh | kSPI_Spol1ActiveHigh | kSPI_Spol2ActiveHigh),
155 #else
156 #if (defined(FSL_FEATURE_SPI_SSEL_COUNT) && (FSL_FEATURE_SPI_SSEL_COUNT == 2))
157     kSPI_SpolActiveAllHigh = (kSPI_Spol0ActiveHigh | kSPI_Spol1ActiveHigh),
158 #else
159     kSPI_Spol3ActiveHigh = SPI_CFG_SPOL3(1),
160     kSPI_SpolActiveAllHigh =
161         (kSPI_Spol0ActiveHigh | kSPI_Spol1ActiveHigh | kSPI_Spol2ActiveHigh | kSPI_Spol3ActiveHigh),
162 #endif /* FSL_FEATURE_SPI_SSEL_COUNT == 2 */
163 #endif /* FSL_FEATURE_SPI_IS_SSEL_PIN_COUNT_EQUAL_TO_THREE */
164     kSPI_SpolActiveAllLow = 0,
165 } spi_spol_t;
166 
167 /*!
168  * @brief SPI delay time configure structure.
169  * Note:
170  *   The DLY register controls several programmable delays related to SPI signalling,
171  *   it stands for how many SPI clock time will be inserted.
172  *   The maxinun value of these delay time is 15.
173  */
174 typedef struct _spi_delay_config
175 {
176     uint8_t preDelay;      /*!< Delay between SSEL assertion and the beginning of transfer. */
177     uint8_t postDelay;     /*!< Delay between the end of transfer and SSEL deassertion. */
178     uint8_t frameDelay;    /*!< Delay between frame to frame. */
179     uint8_t transferDelay; /*!< Delay between transfer to transfer. */
180 } spi_delay_config_t;
181 
182 /*! @brief SPI master user configure structure.*/
183 typedef struct _spi_master_config
184 {
185     bool enableLoopback;             /*!< Enable loopback for test purpose */
186     bool enableMaster;               /*!< Enable SPI at initialization time */
187     spi_clock_polarity_t polarity;   /*!< Clock polarity */
188     spi_clock_phase_t phase;         /*!< Clock phase */
189     spi_shift_direction_t direction; /*!< MSB or LSB */
190     uint32_t baudRate_Bps;           /*!< Baud Rate for SPI in Hz */
191     spi_data_width_t dataWidth;      /*!< Width of the data */
192     spi_ssel_t sselNum;              /*!< Slave select number */
193     spi_spol_t sselPol;              /*!< Configure active CS polarity */
194     uint8_t txWatermark;             /*!< txFIFO watermark */
195     uint8_t rxWatermark;             /*!< rxFIFO watermark */
196     spi_delay_config_t delayConfig;  /*!< Delay configuration. */
197 } spi_master_config_t;
198 
199 /*! @brief SPI slave user configure structure.*/
200 typedef struct _spi_slave_config
201 {
202     bool enableSlave;                /*!< Enable SPI at initialization time */
203     spi_clock_polarity_t polarity;   /*!< Clock polarity */
204     spi_clock_phase_t phase;         /*!< Clock phase */
205     spi_shift_direction_t direction; /*!< MSB or LSB */
206     spi_data_width_t dataWidth;      /*!< Width of the data */
207     spi_spol_t sselPol;              /*!< Configure active CS polarity */
208     uint8_t txWatermark;             /*!< txFIFO watermark */
209     uint8_t rxWatermark;             /*!< rxFIFO watermark */
210 } spi_slave_config_t;
211 
212 /*! @brief SPI transfer status.*/
213 enum
214 {
215     kStatus_SPI_Busy  = MAKE_STATUS(kStatusGroup_LPC_SPI, 0), /*!< SPI bus is busy */
216     kStatus_SPI_Idle  = MAKE_STATUS(kStatusGroup_LPC_SPI, 1), /*!< SPI is idle */
217     kStatus_SPI_Error = MAKE_STATUS(kStatusGroup_LPC_SPI, 2), /*!< SPI  error */
218     kStatus_SPI_BaudrateNotSupport =
219         MAKE_STATUS(kStatusGroup_LPC_SPI, 3),                  /*!< Baudrate is not support in current clock source */
220     kStatus_SPI_Timeout = MAKE_STATUS(kStatusGroup_LPC_SPI, 4) /*!< SPI timeout polling status flags. */
221 };
222 
223 /*! @brief SPI interrupt sources.*/
224 enum _spi_interrupt_enable
225 {
226     kSPI_RxLvlIrq = SPI_FIFOINTENSET_RXLVL_MASK, /*!< Rx level interrupt */
227     kSPI_TxLvlIrq = SPI_FIFOINTENSET_TXLVL_MASK, /*!< Tx level interrupt */
228 };
229 
230 /*! @brief SPI status flags.*/
231 enum _spi_statusflags
232 {
233     kSPI_TxEmptyFlag    = SPI_FIFOSTAT_TXEMPTY_MASK,    /*!< txFifo is empty */
234     kSPI_TxNotFullFlag  = SPI_FIFOSTAT_TXNOTFULL_MASK,  /*!< txFifo is not full */
235     kSPI_RxNotEmptyFlag = SPI_FIFOSTAT_RXNOTEMPTY_MASK, /*!< rxFIFO is not empty */
236     kSPI_RxFullFlag     = SPI_FIFOSTAT_RXFULL_MASK,     /*!< rxFIFO is full */
237 };
238 
239 /*! @brief SPI transfer structure */
240 typedef struct _spi_transfer
241 {
242     const uint8_t *txData; /*!< Send buffer */
243     uint8_t *rxData;      /*!< Receive buffer */
244     uint32_t configFlags; /*!< Additional option to control transfer, @ref spi_xfer_option_t. */
245     size_t dataSize;      /*!< Transfer bytes */
246 } spi_transfer_t;
247 
248 /*! @brief SPI half-duplex(master only) transfer structure */
249 typedef struct _spi_half_duplex_transfer
250 {
251     const uint8_t *txData;      /*!< Send buffer */
252     uint8_t *rxData;            /*!< Receive buffer */
253     size_t txDataSize;          /*!< Transfer bytes for transmit */
254     size_t rxDataSize;          /*!< Transfer bytes */
255     uint32_t configFlags;       /*!< Transfer configuration flags, @ref spi_xfer_option_t. */
256     bool isPcsAssertInTransfer; /*!< If PCS pin keep assert between transmit and receive. true for assert and false for
257                                    deassert. */
258     bool isTransmitFirst;       /*!< True for transmit first and false for receive first. */
259 } spi_half_duplex_transfer_t;
260 
261 /*! @brief Internal configuration structure used in 'spi' and 'spi_dma' driver */
262 typedef struct _spi_config
263 {
264     spi_data_width_t dataWidth;
265     spi_ssel_t sselNum;
266 } spi_config_t;
267 
268 /*! @brief  Master handle type */
269 typedef struct _spi_master_handle spi_master_handle_t;
270 
271 /*! @brief  Slave handle type */
272 typedef spi_master_handle_t spi_slave_handle_t;
273 
274 /*! @brief SPI master callback for finished transmit */
275 typedef void (*spi_master_callback_t)(SPI_Type *base, spi_master_handle_t *handle, status_t status, void *userData);
276 
277 /*! @brief SPI slave callback for finished transmit */
278 typedef void (*spi_slave_callback_t)(SPI_Type *base, spi_slave_handle_t *handle, status_t status, void *userData);
279 
280 /*! @brief SPI transfer handle structure */
281 struct _spi_master_handle
282 {
283     const uint8_t *volatile txData;   /*!< Transfer buffer */
284     uint8_t *volatile rxData;         /*!< Receive buffer */
285     volatile size_t txRemainingBytes; /*!< Number of data to be transmitted [in bytes] */
286     volatile size_t rxRemainingBytes; /*!< Number of data to be received [in bytes] */
287     volatile int8_t toReceiveCount; /*!< The number of data expected to receive in data width. Since the received count
288                                        and sent count should be the same to complete the transfer, if the sent count is
289                                        x and the received count is y, toReceiveCount is x-y. */
290     size_t totalByteCount;          /*!< A number of transfer bytes */
291     volatile uint32_t state;        /*!< SPI internal state */
292     spi_master_callback_t callback; /*!< SPI callback */
293     void *userData;                 /*!< Callback parameter */
294     uint8_t dataWidth;              /*!< Width of the data [Valid values: 1 to 16] */
295     uint8_t sselNum;      /*!< Slave select number to be asserted when transferring data [Valid values: 0 to 3] */
296     uint32_t configFlags; /*!< Additional option to control transfer */
297     uint8_t txWatermark;  /*!< txFIFO watermark */
298     uint8_t rxWatermark;  /*!< rxFIFO watermark */
299 };
300 
301 /*! @brief Typedef for master interrupt handler. */
302 typedef void (*flexcomm_spi_master_irq_handler_t)(SPI_Type *base, spi_master_handle_t *handle);
303 
304 /*! @brief Typedef for slave interrupt handler. */
305 typedef void (*flexcomm_spi_slave_irq_handler_t)(SPI_Type *base, spi_slave_handle_t *handle);
306 /*! @} */
307 
308 /*******************************************************************************
309  * API
310  ******************************************************************************/
311 
312 #if defined(__cplusplus)
313 extern "C" {
314 #endif
315 
316 /*! @brief Returns instance number for SPI peripheral base address. */
317 uint32_t SPI_GetInstance(SPI_Type *base);
318 
319 /*!
320  * @name Initialization and deinitialization
321  * @{
322  */
323 
324 /*!
325  * @brief  Sets the SPI master configuration structure to default values.
326  *
327  * The purpose of this API is to get the configuration structure initialized for use in SPI_MasterInit().
328  * User may use the initialized structure unchanged in SPI_MasterInit(), or modify
329  * some fields of the structure before calling SPI_MasterInit(). After calling this API,
330  * the master is ready to transfer.
331  * Example:
332    @code
333    spi_master_config_t config;
334    SPI_MasterGetDefaultConfig(&config);
335    @endcode
336  *
337  * @param config pointer to master config structure
338  */
339 void SPI_MasterGetDefaultConfig(spi_master_config_t *config);
340 
341 /*!
342  * @brief Initializes the SPI with master configuration.
343  *
344  * The configuration structure can be filled by user from scratch, or be set with default
345  * values by SPI_MasterGetDefaultConfig(). After calling this API, the slave is ready to transfer.
346  * Example
347    @code
348    spi_master_config_t config = {
349    .baudRate_Bps = 400000,
350    ...
351    };
352    SPI_MasterInit(SPI0, &config);
353    @endcode
354  *
355  * @param base SPI base pointer
356  * @param config pointer to master configuration structure
357  * @param srcClock_Hz Source clock frequency.
358  */
359 status_t SPI_MasterInit(SPI_Type *base, const spi_master_config_t *config, uint32_t srcClock_Hz);
360 
361 /*!
362  * @brief  Sets the SPI slave configuration structure to default values.
363  *
364  * The purpose of this API is to get the configuration structure initialized for use in SPI_SlaveInit().
365  * Modify some fields of the structure before calling SPI_SlaveInit().
366  * Example:
367    @code
368    spi_slave_config_t config;
369    SPI_SlaveGetDefaultConfig(&config);
370    @endcode
371  *
372  * @param config pointer to slave configuration structure
373  */
374 void SPI_SlaveGetDefaultConfig(spi_slave_config_t *config);
375 
376 /*!
377  * @brief Initializes the SPI with slave configuration.
378  *
379  * The configuration structure can be filled by user from scratch or be set with
380  * default values by SPI_SlaveGetDefaultConfig().
381  * After calling this API, the slave is ready to transfer.
382  * Example
383    @code
384     spi_slave_config_t config = {
385     .polarity = flexSPIClockPolarity_ActiveHigh;
386     .phase = flexSPIClockPhase_FirstEdge;
387     .direction = flexSPIMsbFirst;
388     ...
389     };
390     SPI_SlaveInit(SPI0, &config);
391    @endcode
392  *
393  * @param base SPI base pointer
394  * @param config pointer to slave configuration structure
395  */
396 status_t SPI_SlaveInit(SPI_Type *base, const spi_slave_config_t *config);
397 
398 /*!
399  * @brief De-initializes the SPI.
400  *
401  * Calling this API resets the SPI module, gates the SPI clock.
402  * The SPI module can't work unless calling the SPI_MasterInit/SPI_SlaveInit to initialize module.
403  *
404  * @param base SPI base pointer
405  */
406 void SPI_Deinit(SPI_Type *base);
407 
408 /*!
409  * @brief Enable or disable the SPI Master or Slave
410  * @param base SPI base pointer
411  * @param enable or disable ( true = enable, false = disable)
412  */
SPI_Enable(SPI_Type * base,bool enable)413 static inline void SPI_Enable(SPI_Type *base, bool enable)
414 {
415     if (enable)
416     {
417         base->CFG |= SPI_CFG_ENABLE_MASK;
418     }
419     else
420     {
421         base->CFG &= ~SPI_CFG_ENABLE_MASK;
422     }
423 }
424 
425 /*! @} */
426 
427 /*!
428  * @name Status
429  * @{
430  */
431 
432 /*!
433  * @brief Gets the status flag.
434  *
435  * @param base SPI base pointer
436  * @return SPI Status, use status flag to AND @ref _spi_statusflags could get the related status.
437  */
SPI_GetStatusFlags(SPI_Type * base)438 static inline uint32_t SPI_GetStatusFlags(SPI_Type *base)
439 {
440     assert(NULL != base);
441     return base->FIFOSTAT;
442 }
443 
444 /*! @} */
445 
446 /*!
447  * @name Interrupts
448  * @{
449  */
450 
451 /*!
452  * @brief Enables the interrupt for the SPI.
453  *
454  * @param base SPI base pointer
455  * @param irqs SPI interrupt source. The parameter can be any combination of the following values:
456  *        @arg kSPI_RxLvlIrq
457  *        @arg kSPI_TxLvlIrq
458  */
SPI_EnableInterrupts(SPI_Type * base,uint32_t irqs)459 static inline void SPI_EnableInterrupts(SPI_Type *base, uint32_t irqs)
460 {
461     assert(NULL != base);
462     base->FIFOINTENSET = irqs;
463 }
464 
465 /*!
466  * @brief Disables the interrupt for the SPI.
467  *
468  * @param base SPI base pointer
469  * @param irqs SPI interrupt source. The parameter can be any combination of the following values:
470  *        @arg kSPI_RxLvlIrq
471  *        @arg kSPI_TxLvlIrq
472  */
SPI_DisableInterrupts(SPI_Type * base,uint32_t irqs)473 static inline void SPI_DisableInterrupts(SPI_Type *base, uint32_t irqs)
474 {
475     assert(NULL != base);
476     base->FIFOINTENCLR = irqs;
477 }
478 
479 /*! @} */
480 
481 /*!
482  * @name DMA Control
483  * @{
484  */
485 
486 /*!
487  * @brief Enables the DMA request from SPI txFIFO.
488  *
489  * @param base SPI base pointer
490  * @param enable True means enable DMA, false means disable DMA
491  */
492 void SPI_EnableTxDMA(SPI_Type *base, bool enable);
493 
494 /*!
495  * @brief Enables the DMA request from SPI rxFIFO.
496  *
497  * @param base SPI base pointer
498  * @param enable True means enable DMA, false means disable DMA
499  */
500 void SPI_EnableRxDMA(SPI_Type *base, bool enable);
501 
502 /*! @} */
503 
504 /*!
505  * @name Bus Operations
506  * @{
507  */
508 /*!
509  * @brief Returns the configurations.
510  *
511  * @param base SPI peripheral address.
512  * @return return configurations which contain datawidth and SSEL numbers.
513  *         return data type is a pointer of spi_config_t.
514  */
515 void *SPI_GetConfig(SPI_Type *base);
516 
517 /*!
518  * @brief Sets the baud rate for SPI transfer. This is only used in master.
519  *
520  * @param base SPI base pointer
521  * @param baudrate_Bps baud rate needed in Hz.
522  * @param srcClock_Hz SPI source clock frequency in Hz.
523  */
524 status_t SPI_MasterSetBaud(SPI_Type *base, uint32_t baudrate_Bps, uint32_t srcClock_Hz);
525 
526 /*!
527  * @brief Writes a data into the SPI data register.
528  *
529  * @param base SPI base pointer
530  * @param data needs to be write.
531  * @param configFlags transfer configuration options @ref spi_xfer_option_t
532  */
533 void SPI_WriteData(SPI_Type *base, uint16_t data, uint32_t configFlags);
534 
535 /*!
536  * @brief Gets a data from the SPI data register.
537  *
538  * @param base SPI base pointer
539  * @return Data in the register.
540  */
SPI_ReadData(SPI_Type * base)541 static inline uint32_t SPI_ReadData(SPI_Type *base)
542 {
543     assert(NULL != base);
544     return base->FIFORD;
545 }
546 
547 /*!
548  * @brief Set delay time for transfer.
549  *        the delay uint is SPI clock time, maximum value is 0xF.
550  * @param base SPI base pointer
551  * @param config configuration for delay option @ref spi_delay_config_t.
552  */
SPI_SetTransferDelay(SPI_Type * base,const spi_delay_config_t * config)553 static inline void SPI_SetTransferDelay(SPI_Type *base, const spi_delay_config_t *config)
554 {
555     assert(NULL != base);
556     assert(NULL != config);
557     base->DLY = (SPI_DLY_PRE_DELAY(config->preDelay) | SPI_DLY_POST_DELAY(config->postDelay) |
558                  SPI_DLY_FRAME_DELAY(config->frameDelay) | SPI_DLY_TRANSFER_DELAY(config->transferDelay));
559 }
560 
561 /*!
562  * @brief Set up the dummy data.
563  *
564  * @param base SPI peripheral address.
565  * @param dummyData Data to be transferred when tx buffer is NULL.
566  */
567 void SPI_SetDummyData(SPI_Type *base, uint8_t dummyData);
568 
569 /*! @} */
570 
571 /*!
572  * @name Transactional
573  * @{
574  */
575 
576 /*!
577  * @brief Initializes the SPI master handle.
578  *
579  * This function initializes the SPI master handle which can be used for other SPI master transactional APIs. Usually,
580  * for a specified SPI instance, call this API once to get the initialized handle.
581  *
582  * @param base SPI peripheral base address.
583  * @param handle SPI handle pointer.
584  * @param callback Callback function.
585  * @param userData User data.
586  */
587 status_t SPI_MasterTransferCreateHandle(SPI_Type *base,
588                                         spi_master_handle_t *handle,
589                                         spi_master_callback_t callback,
590                                         void *userData);
591 
592 /*!
593  * @brief Transfers a block of data using a polling method.
594  *
595  * @param base SPI base pointer
596  * @param xfer pointer to spi_xfer_config_t structure
597  * @retval kStatus_Success Successfully start a transfer.
598  * @retval kStatus_InvalidArgument Input argument is invalid.
599  * @retval kStatus_SPI_Timeout The transfer timed out and was aborted.
600  */
601 status_t SPI_MasterTransferBlocking(SPI_Type *base, spi_transfer_t *xfer);
602 
603 /*!
604  * @brief Performs a non-blocking SPI interrupt transfer.
605  *
606  * @param base SPI peripheral base address.
607  * @param handle pointer to spi_master_handle_t structure which stores the transfer state
608  * @param xfer pointer to spi_xfer_config_t structure
609  * @retval kStatus_Success Successfully start a transfer.
610  * @retval kStatus_InvalidArgument Input argument is invalid.
611  * @retval kStatus_SPI_Busy SPI is not idle, is running another transfer.
612  */
613 status_t SPI_MasterTransferNonBlocking(SPI_Type *base, spi_master_handle_t *handle, spi_transfer_t *xfer);
614 
615 /*!
616  * @brief Transfers a block of data using a polling method.
617  *
618  * This function will do a half-duplex transfer for SPI master, This is a blocking function,
619  * which does not retuen until all transfer have been completed. And data transfer mechanism is half-duplex,
620  * users can set transmit first or receive first.
621  *
622  * @param base SPI base pointer
623  * @param xfer pointer to spi_half_duplex_transfer_t structure
624  * @return status of status_t.
625  */
626 status_t SPI_MasterHalfDuplexTransferBlocking(SPI_Type *base, spi_half_duplex_transfer_t *xfer);
627 
628 /*!
629  * @brief Performs a non-blocking SPI interrupt transfer.
630  *
631  * This function using polling way to do the first half transimission and using interrupts to
632  * do the second half transimission, the transfer mechanism is half-duplex.
633  * When do the second half transimission, code will return right away. When all data is transferred,
634  * the callback function is called.
635  *
636  * @param base SPI peripheral base address.
637  * @param handle pointer to spi_master_handle_t structure which stores the transfer state
638  * @param xfer pointer to spi_half_duplex_transfer_t structure
639  * @return status of status_t.
640  */
641 status_t SPI_MasterHalfDuplexTransferNonBlocking(SPI_Type *base,
642                                                  spi_master_handle_t *handle,
643                                                  spi_half_duplex_transfer_t *xfer);
644 
645 /*!
646  * @brief Gets the master transfer count.
647  *
648  * This function gets the master transfer count.
649  *
650  * @param base SPI peripheral base address.
651  * @param handle Pointer to the spi_master_handle_t structure which stores the transfer state.
652  * @param count The number of bytes transferred by using the non-blocking transaction.
653  * @return status of status_t.
654  */
655 status_t SPI_MasterTransferGetCount(SPI_Type *base, spi_master_handle_t *handle, size_t *count);
656 
657 /*!
658  * @brief SPI master aborts a transfer using an interrupt.
659  *
660  * This function aborts a transfer using an interrupt.
661  *
662  * @param base SPI peripheral base address.
663  * @param handle Pointer to the spi_master_handle_t structure which stores the transfer state.
664  */
665 void SPI_MasterTransferAbort(SPI_Type *base, spi_master_handle_t *handle);
666 
667 /*!
668  * @brief Interrupts the handler for the SPI.
669  *
670  * @param base SPI peripheral base address.
671  * @param handle pointer to spi_master_handle_t structure which stores the transfer state.
672  */
673 void SPI_MasterTransferHandleIRQ(SPI_Type *base, spi_master_handle_t *handle);
674 
675 /*!
676  * @brief Initializes the SPI slave handle.
677  *
678  * This function initializes the SPI slave handle which can be used for other SPI slave transactional APIs. Usually,
679  * for a specified SPI instance, call this API once to get the initialized handle.
680  *
681  * @param base SPI peripheral base address.
682  * @param handle SPI handle pointer.
683  * @param callback Callback function.
684  * @param userData User data.
685  */
SPI_SlaveTransferCreateHandle(SPI_Type * base,spi_slave_handle_t * handle,spi_slave_callback_t callback,void * userData)686 static inline status_t SPI_SlaveTransferCreateHandle(SPI_Type *base,
687                                                      spi_slave_handle_t *handle,
688                                                      spi_slave_callback_t callback,
689                                                      void *userData)
690 {
691     return SPI_MasterTransferCreateHandle(base, handle, callback, userData);
692 }
693 
694 /*!
695  * @brief Performs a non-blocking SPI slave interrupt transfer.
696  *
697  * @note The API returns immediately after the transfer initialization is finished.
698  *
699  * @param base SPI peripheral base address.
700  * @param handle pointer to spi_master_handle_t structure which stores the transfer state
701  * @param xfer pointer to spi_xfer_config_t structure
702  * @retval kStatus_Success Successfully start a transfer.
703  * @retval kStatus_InvalidArgument Input argument is invalid.
704  * @retval kStatus_SPI_Busy SPI is not idle, is running another transfer.
705  */
SPI_SlaveTransferNonBlocking(SPI_Type * base,spi_slave_handle_t * handle,spi_transfer_t * xfer)706 static inline status_t SPI_SlaveTransferNonBlocking(SPI_Type *base, spi_slave_handle_t *handle, spi_transfer_t *xfer)
707 {
708     return SPI_MasterTransferNonBlocking(base, handle, xfer);
709 }
710 
711 /*!
712  * @brief Gets the slave transfer count.
713  *
714  * This function gets the slave transfer count.
715  *
716  * @param base SPI peripheral base address.
717  * @param handle Pointer to the spi_master_handle_t structure which stores the transfer state.
718  * @param count The number of bytes transferred by using the non-blocking transaction.
719  * @return status of status_t.
720  */
SPI_SlaveTransferGetCount(SPI_Type * base,spi_slave_handle_t * handle,size_t * count)721 static inline status_t SPI_SlaveTransferGetCount(SPI_Type *base, spi_slave_handle_t *handle, size_t *count)
722 {
723     return SPI_MasterTransferGetCount(base, (spi_master_handle_t *)handle, count);
724 }
725 
726 /*!
727  * @brief SPI slave aborts a transfer using an interrupt.
728  *
729  * This function aborts a transfer using an interrupt.
730  *
731  * @param base SPI peripheral base address.
732  * @param handle Pointer to the spi_slave_handle_t structure which stores the transfer state.
733  */
SPI_SlaveTransferAbort(SPI_Type * base,spi_slave_handle_t * handle)734 static inline void SPI_SlaveTransferAbort(SPI_Type *base, spi_slave_handle_t *handle)
735 {
736     SPI_MasterTransferAbort(base, (spi_master_handle_t *)handle);
737 }
738 
739 /*!
740  * @brief Interrupts a handler for the SPI slave.
741  *
742  * @param base SPI peripheral base address.
743  * @param handle pointer to spi_slave_handle_t structure which stores the transfer state
744  */
SPI_SlaveTransferHandleIRQ(SPI_Type * base,spi_slave_handle_t * handle)745 static inline void SPI_SlaveTransferHandleIRQ(SPI_Type *base, spi_slave_handle_t *handle)
746 {
747     SPI_MasterTransferHandleIRQ(base, handle);
748 }
749 
750 /*! @} */
751 
752 #if defined(__cplusplus)
753 }
754 #endif
755 
756 /*! @} */
757 
758 #endif /* FSL_SPI_H_*/
759