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