1 /*
2  * Copyright (c) 2015, Freescale Semiconductor, Inc.
3  * Copyright 2016-2020 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 
13 /*!
14  * @addtogroup spi_driver
15  * @{
16  */
17 
18 /*******************************************************************************
19  * Definitions
20  ******************************************************************************/
21 
22 /*! @name Driver version */
23 /*! @{ */
24 /*! @brief SPI driver version. */
25 #define FSL_SPI_DRIVER_VERSION (MAKE_VERSION(2, 1, 3))
26 /*! @} */
27 
28 #ifndef SPI_DUMMYDATA
29 /*! @brief SPI dummy transfer data, the data is sent while txBuff is NULL. */
30 #define SPI_DUMMYDATA (0x00U)
31 #endif
32 
33 /*! @brief Retry times for waiting flag. */
34 #ifndef SPI_RETRY_TIMES
35 #define SPI_RETRY_TIMES 0U /* Define to zero means keep waiting until the flag is assert/deassert. */
36 #endif
37 
38 /*! @brief Global variable for dummy data value setting. */
39 extern volatile uint8_t g_spiDummyData[];
40 
41 /*! @brief Return status for the SPI driver.*/
42 enum
43 {
44     kStatus_SPI_Busy    = MAKE_STATUS(kStatusGroup_SPI, 0), /*!< SPI bus is busy */
45     kStatus_SPI_Idle    = MAKE_STATUS(kStatusGroup_SPI, 1), /*!< SPI is idle */
46     kStatus_SPI_Error   = MAKE_STATUS(kStatusGroup_SPI, 2), /*!< SPI error */
47     kStatus_SPI_Timeout = MAKE_STATUS(kStatusGroup_SPI, 3)  /*!< SPI timeout polling status flags. */
48 };
49 
50 /*! @brief SPI clock polarity configuration.*/
51 typedef enum _spi_clock_polarity
52 {
53     kSPI_ClockPolarityActiveHigh = 0x0U, /*!< Active-high SPI clock (idles low). */
54     kSPI_ClockPolarityActiveLow          /*!< Active-low SPI clock (idles high). */
55 } spi_clock_polarity_t;
56 
57 /*! @brief SPI clock phase configuration.*/
58 typedef enum _spi_clock_phase
59 {
60     kSPI_ClockPhaseFirstEdge = 0x0U, /*!< First edge on SPSCK occurs at the middle of the first
61                                       *   cycle of a data transfer. */
62     kSPI_ClockPhaseSecondEdge        /*!< First edge on SPSCK occurs at the start of the
63                                       *   first cycle of a data transfer. */
64 } spi_clock_phase_t;
65 
66 /*! @brief SPI data shifter direction options.*/
67 typedef enum _spi_shift_direction
68 {
69     kSPI_MsbFirst = 0x0U, /*!< Data transfers start with most significant bit. */
70     kSPI_LsbFirst         /*!< Data transfers start with least significant bit. */
71 } spi_shift_direction_t;
72 
73 /*! @brief SPI slave select output mode options.*/
74 typedef enum _spi_ss_output_mode
75 {
76     kSPI_SlaveSelectAsGpio          = 0x0U, /*!< Slave select pin configured as GPIO. */
77     kSPI_SlaveSelectFaultInput      = 0x2U, /*!< Slave select pin configured for fault detection. */
78     kSPI_SlaveSelectAutomaticOutput = 0x3U  /*!< Slave select pin configured for automatic SPI output. */
79 } spi_ss_output_mode_t;
80 
81 /*! @brief SPI pin mode options.*/
82 typedef enum _spi_pin_mode
83 {
84     kSPI_PinModeNormal = 0x0U, /*!< Pins operate in normal, single-direction mode.*/
85     kSPI_PinModeInput  = 0x1U, /*!< Bidirectional mode. Master: MOSI pin is input;
86                                 *   Slave: MISO pin is input. */
87     kSPI_PinModeOutput = 0x3U  /*!< Bidirectional mode. Master: MOSI pin is output;
88                                 *   Slave: MISO pin is output. */
89 } spi_pin_mode_t;
90 
91 /*! @brief SPI data length mode options.*/
92 typedef enum _spi_data_bitcount_mode
93 {
94     kSPI_8BitMode = 0x0U, /*!< 8-bit data transmission mode*/
95     kSPI_16BitMode        /*!< 16-bit data transmission mode*/
96 } spi_data_bitcount_mode_t;
97 
98 /*! @brief SPI interrupt sources.*/
99 enum _spi_interrupt_enable
100 {
101     kSPI_RxFullAndModfInterruptEnable = 0x1U, /*!< Receive buffer full (SPRF) and mode fault (MODF) interrupt */
102     kSPI_TxEmptyInterruptEnable       = 0x2U, /*!< Transmit buffer empty interrupt */
103     kSPI_MatchInterruptEnable         = 0x4U, /*!< Match interrupt */
104 #if defined(FSL_FEATURE_SPI_HAS_FIFO) && FSL_FEATURE_SPI_HAS_FIFO
105     kSPI_RxFifoNearFullInterruptEnable  = 0x8U,  /*!< Receive FIFO nearly full interrupt */
106     kSPI_TxFifoNearEmptyInterruptEnable = 0x10U, /*!< Transmit FIFO nearly empty interrupt */
107 #endif                                           /* FSL_FEATURE_SPI_HAS_FIFO */
108 };
109 
110 /*! @brief SPI status flags.*/
111 enum _spi_flags
112 {
113     kSPI_RxBufferFullFlag  = SPI_S_SPRF_MASK,  /*!< Read buffer full flag */
114     kSPI_MatchFlag         = SPI_S_SPMF_MASK,  /*!< Match flag */
115     kSPI_TxBufferEmptyFlag = SPI_S_SPTEF_MASK, /*!< Transmit buffer empty flag */
116     kSPI_ModeFaultFlag     = SPI_S_MODF_MASK,  /*!< Mode fault flag */
117 #if defined(FSL_FEATURE_SPI_HAS_FIFO) && FSL_FEATURE_SPI_HAS_FIFO
118     kSPI_RxFifoNearFullFlag  = SPI_S_RNFULLF_MASK,       /*!< Rx FIFO near full */
119     kSPI_TxFifoNearEmptyFlag = SPI_S_TNEAREF_MASK,       /*!< Tx FIFO near empty */
120     kSPI_TxFifoFullFlag      = SPI_S_TXFULLF_MASK,       /*!< Tx FIFO full */
121     kSPI_RxFifoEmptyFlag     = SPI_S_RFIFOEF_MASK,       /*!< Rx FIFO empty */
122     kSPI_TxFifoError         = SPI_CI_TXFERR_MASK << 8U, /*!< Tx FIFO error */
123     kSPI_RxFifoError         = SPI_CI_RXFERR_MASK << 8U, /*!< Rx FIFO error */
124     kSPI_TxOverflow          = SPI_CI_TXFOF_MASK << 8U,  /*!< Tx FIFO Overflow */
125     kSPI_RxOverflow          = SPI_CI_RXFOF_MASK << 8U   /*!< Rx FIFO Overflow */
126 #endif                                                   /* FSL_FEATURE_SPI_HAS_FIFO */
127 };
128 
129 #if defined(FSL_FEATURE_SPI_HAS_FIFO) && FSL_FEATURE_SPI_HAS_FIFO
130 /*! @brief SPI FIFO write-1-to-clear interrupt flags.*/
131 typedef enum _spi_w1c_interrupt
132 {
133     kSPI_RxFifoFullClearInterrupt  = SPI_CI_SPRFCI_MASK,    /*!< Receive FIFO full interrupt */
134     kSPI_TxFifoEmptyClearInterrupt = SPI_CI_SPTEFCI_MASK,   /*!< Transmit FIFO empty interrupt */
135     kSPI_RxNearFullClearInterrupt  = SPI_CI_RNFULLFCI_MASK, /*!< Receive FIFO nearly full interrupt */
136     kSPI_TxNearEmptyClearInterrupt = SPI_CI_TNEAREFCI_MASK  /*!< Transmit FIFO nearly empty interrupt */
137 } spi_w1c_interrupt_t;
138 
139 /*! @brief SPI TX FIFO watermark settings.*/
140 typedef enum _spi_txfifo_watermark
141 {
142     kSPI_TxFifoOneFourthEmpty = 0, /*!< SPI tx watermark at 1/4 FIFO size */
143     kSPI_TxFifoOneHalfEmpty   = 1  /*!< SPI tx watermark at 1/2 FIFO size */
144 } spi_txfifo_watermark_t;
145 
146 /*! @brief SPI RX FIFO watermark settings.*/
147 typedef enum _spi_rxfifo_watermark
148 {
149     kSPI_RxFifoThreeFourthsFull = 0, /*!< SPI rx watermark at 3/4 FIFO size */
150     kSPI_RxFifoOneHalfFull      = 1  /*!< SPI rx watermark at 1/2 FIFO size */
151 } spi_rxfifo_watermark_t;
152 #endif /* FSL_FEATURE_SPI_HAS_FIFO */
153 
154 #if defined(FSL_FEATURE_SPI_HAS_DMA_SUPPORT) && FSL_FEATURE_SPI_HAS_DMA_SUPPORT
155 /*! @brief SPI DMA source*/
156 enum _spi_dma_enable_t
157 {
158     kSPI_TxDmaEnable  = SPI_C2_TXDMAE_MASK,                       /*!< Tx DMA request source */
159     kSPI_RxDmaEnable  = SPI_C2_RXDMAE_MASK,                       /*!< Rx DMA request source */
160     kSPI_DmaAllEnable = (SPI_C2_TXDMAE_MASK | SPI_C2_RXDMAE_MASK) /*!< All DMA request source*/
161 };
162 #endif /* FSL_FEATURE_SPI_HAS_DMA_SUPPORT */
163 
164 /*! @brief SPI master user configure structure.*/
165 typedef struct _spi_master_config
166 {
167     bool enableMaster;               /*!< Enable SPI at initialization time */
168     bool enableStopInWaitMode;       /*!< SPI stop in wait mode */
169     spi_clock_polarity_t polarity;   /*!< Clock polarity */
170     spi_clock_phase_t phase;         /*!< Clock phase */
171     spi_shift_direction_t direction; /*!< MSB or LSB */
172 #if defined(FSL_FEATURE_SPI_16BIT_TRANSFERS) && FSL_FEATURE_SPI_16BIT_TRANSFERS
173     spi_data_bitcount_mode_t dataMode; /*!< 8bit or 16bit mode */
174 #endif                                 /* FSL_FEATURE_SPI_16BIT_TRANSFERS */
175 #if defined(FSL_FEATURE_SPI_HAS_FIFO) && FSL_FEATURE_SPI_HAS_FIFO
176     spi_txfifo_watermark_t txWatermark; /*!< Tx watermark settings */
177     spi_rxfifo_watermark_t rxWatermark; /*!< Rx watermark settings */
178 #endif                                  /* FSL_FEATURE_SPI_HAS_FIFO */
179     spi_ss_output_mode_t outputMode;    /*!< SS pin setting */
180     spi_pin_mode_t pinMode;             /*!< SPI pin mode select */
181     uint32_t baudRate_Bps;              /*!< Baud Rate for SPI in Hz */
182 } spi_master_config_t;
183 
184 /*! @brief SPI slave user configure structure.*/
185 typedef struct _spi_slave_config
186 {
187     bool enableSlave;                /*!< Enable SPI at initialization time */
188     bool enableStopInWaitMode;       /*!< SPI stop in wait mode */
189     spi_clock_polarity_t polarity;   /*!< Clock polarity */
190     spi_clock_phase_t phase;         /*!< Clock phase */
191     spi_shift_direction_t direction; /*!< MSB or LSB */
192 #if defined(FSL_FEATURE_SPI_16BIT_TRANSFERS) && FSL_FEATURE_SPI_16BIT_TRANSFERS
193     spi_data_bitcount_mode_t dataMode; /*!< 8bit or 16bit mode */
194 #endif                                 /* FSL_FEATURE_SPI_16BIT_TRANSFERS */
195 #if defined(FSL_FEATURE_SPI_HAS_FIFO) && FSL_FEATURE_SPI_HAS_FIFO
196     spi_txfifo_watermark_t txWatermark; /*!< Tx watermark settings */
197     spi_rxfifo_watermark_t rxWatermark; /*!< Rx watermark settings */
198 #endif                                  /* FSL_FEATURE_SPI_HAS_FIFO */
199     spi_pin_mode_t pinMode;             /*!< SPI pin mode select */
200 } spi_slave_config_t;
201 
202 /*! @brief SPI transfer structure */
203 typedef struct _spi_transfer
204 {
205     const uint8_t *txData; /*!< Send buffer */
206     uint8_t *rxData; /*!< Receive buffer */
207     size_t dataSize; /*!< Transfer bytes */
208     uint32_t flags;  /*!< SPI control flag, useless to SPI.*/
209 } spi_transfer_t;
210 
211 typedef struct _spi_master_handle spi_master_handle_t;
212 
213 /*! @brief  Slave handle is the same with master handle  */
214 typedef spi_master_handle_t spi_slave_handle_t;
215 
216 /*! @brief SPI master callback for finished transmit */
217 typedef void (*spi_master_callback_t)(SPI_Type *base, spi_master_handle_t *handle, status_t status, void *userData);
218 
219 /*! @brief SPI master callback for finished transmit */
220 typedef void (*spi_slave_callback_t)(SPI_Type *base, spi_slave_handle_t *handle, status_t status, void *userData);
221 
222 /*! @brief SPI transfer handle structure */
223 struct _spi_master_handle
224 {
225     const uint8_t *volatile txData;   /*!< Transfer buffer */
226     uint8_t *volatile rxData;         /*!< Receive buffer */
227     volatile size_t txRemainingBytes; /*!< Send data remaining in bytes */
228     volatile size_t rxRemainingBytes; /*!< Receive data remaining in bytes */
229     volatile uint32_t state;          /*!< SPI internal state */
230     size_t transferSize;              /*!< Bytes to be transferred */
231     uint8_t bytePerFrame;             /*!< SPI mode, 2bytes or 1byte in a frame */
232     uint8_t watermark;                /*!< Watermark value for SPI transfer */
233     spi_master_callback_t callback;   /*!< SPI callback */
234     void *userData;                   /*!< Callback parameter */
235 };
236 
237 #if defined(__cplusplus)
238 extern "C" {
239 #endif
240 /*******************************************************************************
241  * APIs
242  ******************************************************************************/
243 /*!
244  * @name Initialization and deinitialization
245  * @{
246  */
247 
248 /*!
249  * @brief  Sets the SPI master configuration structure to default values.
250  *
251  * The purpose of this API is to get the configuration structure initialized for use in SPI_MasterInit().
252  * User may use the initialized structure unchanged in SPI_MasterInit(), or modify
253  * some fields of the structure before calling SPI_MasterInit(). After calling this API,
254  * the master is ready to transfer.
255  * Example:
256    @code
257    spi_master_config_t config;
258    SPI_MasterGetDefaultConfig(&config);
259    @endcode
260  *
261  * @param config pointer to master config structure
262  */
263 void SPI_MasterGetDefaultConfig(spi_master_config_t *config);
264 
265 /*!
266  * @brief Initializes the SPI with master configuration.
267  *
268  * The configuration structure can be filled by user from scratch, or be set with default
269  * values by SPI_MasterGetDefaultConfig(). After calling this API, the slave is ready to transfer.
270  * Example
271    @code
272    spi_master_config_t config = {
273    .baudRate_Bps = 400000,
274    ...
275    };
276    SPI_MasterInit(SPI0, &config);
277    @endcode
278  *
279  * @param base SPI base pointer
280  * @param config pointer to master configuration structure
281  * @param srcClock_Hz Source clock frequency.
282  */
283 void SPI_MasterInit(SPI_Type *base, const spi_master_config_t *config, uint32_t srcClock_Hz);
284 
285 /*!
286  * @brief  Sets the SPI slave configuration structure to default values.
287  *
288  * The purpose of this API is to get the configuration structure initialized for use in SPI_SlaveInit().
289  * Modify some fields of the structure before calling SPI_SlaveInit().
290  * Example:
291    @code
292    spi_slave_config_t config;
293    SPI_SlaveGetDefaultConfig(&config);
294    @endcode
295  *
296  * @param config pointer to slave configuration structure
297  */
298 void SPI_SlaveGetDefaultConfig(spi_slave_config_t *config);
299 
300 /*!
301  * @brief Initializes the SPI with slave configuration.
302  *
303  * The configuration structure can be filled by user from scratch or be set with
304  * default values by SPI_SlaveGetDefaultConfig().
305  * After calling this API, the slave is ready to transfer.
306  * Example
307    @code
308     spi_slave_config_t config = {
309     .polarity = kSPIClockPolarity_ActiveHigh;
310     .phase = kSPIClockPhase_FirstEdge;
311     .direction = kSPIMsbFirst;
312     ...
313     };
314     SPI_MasterInit(SPI0, &config);
315    @endcode
316  *
317  * @param base SPI base pointer
318  * @param config pointer to master configuration structure
319  */
320 void SPI_SlaveInit(SPI_Type *base, const spi_slave_config_t *config);
321 
322 /*!
323  * @brief De-initializes the SPI.
324  *
325  * Calling this API resets the SPI module, gates the SPI clock.
326  * The SPI module can't work unless calling the SPI_MasterInit/SPI_SlaveInit to initialize module.
327  *
328  * @param base SPI base pointer
329  */
330 void SPI_Deinit(SPI_Type *base);
331 
332 /*!
333  * @brief Enables or disables the SPI.
334  *
335  * @param base SPI base pointer
336  * @param enable pass true to enable module, false to disable module
337  */
SPI_Enable(SPI_Type * base,bool enable)338 static inline void SPI_Enable(SPI_Type *base, bool enable)
339 {
340     if (enable)
341     {
342         base->C1 |= SPI_C1_SPE_MASK;
343     }
344     else
345     {
346         base->C1 &= (uint8_t)~SPI_C1_SPE_MASK;
347     }
348 }
349 
350 /*! @} */
351 
352 /*!
353  * @name Status
354  * @{
355  */
356 
357 /*!
358  * @brief Gets the status flag.
359  *
360  * @param base SPI base pointer
361  * @return SPI Status, use status flag to AND #_spi_flags could get the related status.
362  */
363 uint32_t SPI_GetStatusFlags(SPI_Type *base);
364 
365 #if defined(FSL_FEATURE_SPI_HAS_FIFO) && FSL_FEATURE_SPI_HAS_FIFO
366 /*!
367  * @brief Clear the interrupt if enable INCTLR.
368  *
369  * @param base SPI base pointer
370  * @param mask Interrupt need to be cleared
371  *      The parameter could be any combination of the following values:
372  *          @arg kSPI_RxFullAndModfInterruptEnable
373  *          @arg kSPI_TxEmptyInterruptEnable
374  *          @arg kSPI_MatchInterruptEnable
375  *          @arg kSPI_RxFifoNearFullInterruptEnable
376  *          @arg kSPI_TxFifoNearEmptyInterruptEnable
377  */
SPI_ClearInterrupt(SPI_Type * base,uint8_t mask)378 static inline void SPI_ClearInterrupt(SPI_Type *base, uint8_t mask)
379 {
380     base->CI |= mask;
381 }
382 #endif /* FSL_FEATURE_SPI_HAS_FIFO */
383 
384 /*! @} */
385 
386 /*!
387  * @name Interrupts
388  * @{
389  */
390 
391 /*!
392  * @brief Enables the interrupt for the SPI.
393  *
394  * @param base SPI base pointer
395  * @param mask SPI interrupt source. The parameter can be any combination of the following values:
396  *        @arg kSPI_RxFullAndModfInterruptEnable
397  *        @arg kSPI_TxEmptyInterruptEnable
398  *        @arg kSPI_MatchInterruptEnable
399  *        @arg kSPI_RxFifoNearFullInterruptEnable
400  *        @arg kSPI_TxFifoNearEmptyInterruptEnable
401  */
402 void SPI_EnableInterrupts(SPI_Type *base, uint32_t mask);
403 
404 /*!
405  * @brief Disables the interrupt for the SPI.
406  *
407  * @param base SPI base pointer
408  * @param mask SPI interrupt source. The parameter can be any combination of the following values:
409  *        @arg kSPI_RxFullAndModfInterruptEnable
410  *        @arg kSPI_TxEmptyInterruptEnable
411  *        @arg kSPI_MatchInterruptEnable
412  *        @arg kSPI_RxFifoNearFullInterruptEnable
413  *        @arg kSPI_TxFifoNearEmptyInterruptEnable
414  */
415 void SPI_DisableInterrupts(SPI_Type *base, uint32_t mask);
416 
417 /*! @} */
418 
419 /*!
420  * @name DMA Control
421  * @{
422  */
423 
424 #if defined(FSL_FEATURE_SPI_HAS_DMA_SUPPORT) && FSL_FEATURE_SPI_HAS_DMA_SUPPORT
425 /*!
426  * @brief Enables the DMA source for SPI.
427  *
428  * @param base SPI base pointer
429  * @param mask SPI DMA source.
430  * @param enable True means enable DMA, false means disable DMA
431  */
SPI_EnableDMA(SPI_Type * base,uint8_t mask,bool enable)432 static inline void SPI_EnableDMA(SPI_Type *base, uint8_t mask, bool enable)
433 {
434     if (enable)
435     {
436         base->C2 |= mask;
437     }
438     else
439     {
440         base->C2 &= ~mask;
441     }
442 }
443 #endif /* FSL_FEATURE_SPI_HAS_DMA_SUPPORT */
444 
445 /*!
446  * @brief  Gets the SPI tx/rx data register address.
447  *
448  * This API is used to provide a transfer address for the SPI DMA transfer configuration.
449  *
450  * @param base SPI base pointer
451  * @return data register address
452  */
SPI_GetDataRegisterAddress(SPI_Type * base)453 static inline uint32_t SPI_GetDataRegisterAddress(SPI_Type *base)
454 {
455 #if defined(FSL_FEATURE_SPI_16BIT_TRANSFERS) && FSL_FEATURE_SPI_16BIT_TRANSFERS
456     return (uint32_t)(&(base->DL));
457 #else
458     return (uint32_t)(&(base->D));
459 #endif /* FSL_FEATURE_SPI_16BIT_TRANSFERS */
460 }
461 
462 /*! @} */
463 
464 /*!
465  * @name Bus Operations
466  * @{
467  */
468 
469 /*!
470  * @brief Get the instance for SPI module.
471  *
472  * @param base SPI base address
473  */
474 uint32_t SPI_GetInstance(SPI_Type *base);
475 
476 /*!
477  * @brief Sets the pin mode for transfer.
478  *
479  * @param base SPI base pointer
480  * @param pinMode pin mode for transfer AND _spi_pin_mode could get the related configuration.
481  */
SPI_SetPinMode(SPI_Type * base,spi_pin_mode_t pinMode)482 static inline void SPI_SetPinMode(SPI_Type *base, spi_pin_mode_t pinMode)
483 {
484     /* Clear SPC0 and BIDIROE bit. */
485     base->C2 &= (uint8_t) ~(SPI_C2_BIDIROE_MASK | SPI_C2_SPC0_MASK);
486     /* Set pin mode for transfer. */
487     base->C2 |= SPI_C2_BIDIROE((uint8_t)pinMode >> 1U) | SPI_C2_SPC0((uint8_t)pinMode & 1U);
488 }
489 
490 /*!
491  * @brief Sets the baud rate for SPI transfer. This is only used in master.
492  *
493  * @param base SPI base pointer
494  * @param baudRate_Bps baud rate needed in Hz.
495  * @param srcClock_Hz SPI source clock frequency in Hz.
496  */
497 void SPI_MasterSetBaudRate(SPI_Type *base, uint32_t baudRate_Bps, uint32_t srcClock_Hz);
498 
499 /*!
500  * @brief Sets the match data for SPI.
501  *
502  * The match data is a hardware comparison value. When the value received in the SPI receive data
503  * buffer equals the hardware comparison value, the SPI Match Flag in the S register (S[SPMF]) sets.
504  * This can also generate an interrupt if the enable bit sets.
505  *
506  * @param base SPI base pointer
507  * @param matchData Match data.
508  */
SPI_SetMatchData(SPI_Type * base,uint32_t matchData)509 static inline void SPI_SetMatchData(SPI_Type *base, uint32_t matchData)
510 {
511 #if defined(FSL_FEATURE_SPI_16BIT_TRANSFERS) && FSL_FEATURE_SPI_16BIT_TRANSFERS
512     base->ML = (uint8_t)matchData & 0xFFU;
513     base->MH = (uint8_t)(matchData >> 8U) & 0xFFU;
514 #else
515     base->M = (uint8_t)matchData;
516 #endif /* FSL_FEATURE_SPI_16BIT_TRANSFERS */
517 }
518 
519 #if defined(FSL_FEATURE_SPI_HAS_FIFO) && FSL_FEATURE_SPI_HAS_FIFO
520 /*!
521  * @brief Enables or disables the FIFO if there is a FIFO.
522  *
523  * @param base SPI base pointer
524  * @param enable True means enable FIFO, false means disable FIFO.
525  */
526 void SPI_EnableFIFO(SPI_Type *base, bool enable);
527 #endif
528 
529 /*!
530  * @brief Sends a buffer of data bytes using a blocking method.
531  *
532  * @note This function blocks via polling until all bytes have been sent.
533  *
534  * @param base SPI base pointer
535  * @param buffer The data bytes to send
536  * @param size The number of data bytes to send
537  * @return kStatus_SPI_Timeout The transfer timed out and was aborted.
538  */
539 status_t SPI_WriteBlocking(SPI_Type *base, uint8_t *buffer, size_t size);
540 
541 /*!
542  * @brief Writes a data into the SPI data register.
543  *
544  * @param base SPI base pointer
545  * @param data needs to be write.
546  */
547 void SPI_WriteData(SPI_Type *base, uint16_t data);
548 
549 /*!
550  * @brief Gets a data from the SPI data register.
551  *
552  * @param base SPI base pointer
553  * @return Data in the register.
554  */
555 uint16_t SPI_ReadData(SPI_Type *base);
556 
557 /*!
558  * @brief Set up the dummy data.
559  *
560  * @param base SPI peripheral address.
561  * @param dummyData Data to be transferred when tx buffer is NULL.
562  */
563 void SPI_SetDummyData(SPI_Type *base, uint8_t dummyData);
564 /*! @} */
565 
566 /*!
567  * @name Transactional
568  * @{
569  */
570 
571 /*!
572  * @brief Initializes the SPI master handle.
573  *
574  * This function initializes the SPI master handle which can be used for other SPI master transactional APIs. Usually,
575  * for a specified SPI instance, call this API once to get the initialized handle.
576  *
577  * @param base SPI peripheral base address.
578  * @param handle SPI handle pointer.
579  * @param callback Callback function.
580  * @param userData User data.
581  */
582 void SPI_MasterTransferCreateHandle(SPI_Type *base,
583                                     spi_master_handle_t *handle,
584                                     spi_master_callback_t callback,
585                                     void *userData);
586 
587 /*!
588  * @brief Transfers a block of data using a polling method.
589  *
590  * @param base SPI base pointer
591  * @param xfer pointer to spi_xfer_config_t structure
592  * @retval kStatus_Success Successfully start a transfer.
593  * @retval kStatus_InvalidArgument Input argument is invalid.
594  */
595 status_t SPI_MasterTransferBlocking(SPI_Type *base, spi_transfer_t *xfer);
596 
597 /*!
598  * @brief Performs a non-blocking SPI interrupt transfer.
599  *
600  * @note The API immediately returns after transfer initialization is finished.
601  * Call SPI_GetStatusIRQ() to get the transfer status.
602  * @note If SPI transfer data frame size is 16 bits, the transfer size cannot be an odd number.
603  *
604  * @param base SPI peripheral base address.
605  * @param handle pointer to spi_master_handle_t structure which stores the transfer state
606  * @param xfer pointer to spi_xfer_config_t structure
607  * @retval kStatus_Success Successfully start a transfer.
608  * @retval kStatus_InvalidArgument Input argument is invalid.
609  * @retval kStatus_SPI_Busy SPI is not idle, is running another transfer.
610  */
611 status_t SPI_MasterTransferNonBlocking(SPI_Type *base, spi_master_handle_t *handle, spi_transfer_t *xfer);
612 
613 /*!
614  * @brief Gets the bytes of the SPI interrupt transferred.
615  *
616  * @param base SPI peripheral base address.
617  * @param handle Pointer to SPI transfer handle, this should be a static variable.
618  * @param count Transferred bytes of SPI master.
619  * @retval kStatus_SPI_Success Succeed get the transfer count.
620  * @retval kStatus_NoTransferInProgress There is not a non-blocking transaction currently in progress.
621  */
622 status_t SPI_MasterTransferGetCount(SPI_Type *base, spi_master_handle_t *handle, size_t *count);
623 
624 /*!
625  * @brief Aborts an SPI transfer using interrupt.
626  *
627  * @param base SPI peripheral base address.
628  * @param handle Pointer to SPI transfer handle, this should be a static variable.
629  */
630 void SPI_MasterTransferAbort(SPI_Type *base, spi_master_handle_t *handle);
631 
632 /*!
633  * @brief Interrupts the handler for the SPI.
634  *
635  * @param base SPI peripheral base address.
636  * @param handle pointer to spi_master_handle_t structure which stores the transfer state.
637  */
638 void SPI_MasterTransferHandleIRQ(SPI_Type *base, spi_master_handle_t *handle);
639 
640 /*!
641  * @brief Initializes the SPI slave handle.
642  *
643  * This function initializes the SPI slave handle which can be used for other SPI slave transactional APIs. Usually,
644  * for a specified SPI instance, call this API once to get the initialized handle.
645  *
646  * @param base SPI peripheral base address.
647  * @param handle SPI handle pointer.
648  * @param callback Callback function.
649  * @param userData User data.
650  */
651 void SPI_SlaveTransferCreateHandle(SPI_Type *base,
652                                    spi_slave_handle_t *handle,
653                                    spi_slave_callback_t callback,
654                                    void *userData);
655 
656 /*!
657  * @brief Performs a non-blocking SPI slave interrupt transfer.
658  *
659  * @note The API returns immediately after the transfer initialization is finished.
660  * Call SPI_GetStatusIRQ() to get the transfer status.
661  * @note If SPI transfer data frame size is 16 bits, the transfer size cannot be an odd number.
662  *
663  * @param base SPI peripheral base address.
664  * @param handle pointer to spi_slave_handle_t structure which stores the transfer state
665  * @param xfer pointer to spi_xfer_config_t structure
666  * @retval kStatus_Success Successfully start a transfer.
667  * @retval kStatus_InvalidArgument Input argument is invalid.
668  * @retval kStatus_SPI_Busy SPI is not idle, is running another transfer.
669  */
670 status_t SPI_SlaveTransferNonBlocking(SPI_Type *base, spi_slave_handle_t *handle, spi_transfer_t *xfer);
671 
672 /*!
673  * @brief Gets the bytes of the SPI interrupt transferred.
674  *
675  * @param base SPI peripheral base address.
676  * @param handle Pointer to SPI transfer handle, this should be a static variable.
677  * @param count Transferred bytes of SPI slave.
678  * @retval kStatus_SPI_Success Succeed get the transfer count.
679  * @retval kStatus_NoTransferInProgress There is not a non-blocking transaction currently in progress.
680  */
SPI_SlaveTransferGetCount(SPI_Type * base,spi_slave_handle_t * handle,size_t * count)681 static inline status_t SPI_SlaveTransferGetCount(SPI_Type *base, spi_slave_handle_t *handle, size_t *count)
682 {
683     return SPI_MasterTransferGetCount(base, handle, count);
684 }
685 
686 /*!
687  * @brief Aborts an SPI slave transfer using interrupt.
688  *
689  * @param base SPI peripheral base address.
690  * @param handle Pointer to SPI transfer handle, this should be a static variable.
691  */
SPI_SlaveTransferAbort(SPI_Type * base,spi_slave_handle_t * handle)692 static inline void SPI_SlaveTransferAbort(SPI_Type *base, spi_slave_handle_t *handle)
693 {
694     SPI_MasterTransferAbort(base, handle);
695 }
696 
697 /*!
698  * @brief Interrupts a handler for the SPI slave.
699  *
700  * @param base SPI peripheral base address.
701  * @param handle pointer to spi_slave_handle_t structure which stores the transfer state
702  */
703 void SPI_SlaveTransferHandleIRQ(SPI_Type *base, spi_slave_handle_t *handle);
704 
705 /*! @} */
706 
707 #if defined(__cplusplus)
708 }
709 #endif
710 
711 /*! @} */
712 
713 #endif /* FSL_SPI_H_*/
714