1 /*
2  * Copyright (c) 2015, Freescale Semiconductor, Inc.
3  * Copyright 2016-2022 NXP
4  * All rights reserved.
5  *
6  * SPDX-License-Identifier: BSD-3-Clause
7  */
8 #ifndef FSL_DSPI_H_
9 #define FSL_DSPI_H_
10 
11 #include "fsl_common.h"
12 
13 /*!
14  * @addtogroup dspi_driver
15  * @{
16  */
17 
18 /**********************************************************************************************************************
19  * Definitions
20  *********************************************************************************************************************/
21 
22 /*! @name Driver version */
23 /*! @{ */
24 /*! @brief DSPI driver version 2.2.6. */
25 #define FSL_DSPI_DRIVER_VERSION (MAKE_VERSION(2, 2, 6))
26 /*! @} */
27 
28 #ifndef DSPI_DUMMY_DATA
29 /*! @brief DSPI dummy data if there is no Tx data.*/
30 #define DSPI_DUMMY_DATA (0x00U) /*!< Dummy data used for Tx if there is no txData. */
31 #endif
32 
33 /*! @brief Global variable for dummy data value setting. */
34 extern volatile uint8_t g_dspiDummyData[];
35 
36 /*! @brief Status for the DSPI driver.*/
37 enum
38 {
39     kStatus_DSPI_Busy       = MAKE_STATUS(kStatusGroup_DSPI, 0), /*!< DSPI transfer is busy.*/
40     kStatus_DSPI_Error      = MAKE_STATUS(kStatusGroup_DSPI, 1), /*!< DSPI driver error. */
41     kStatus_DSPI_Idle       = MAKE_STATUS(kStatusGroup_DSPI, 2), /*!< DSPI is idle.*/
42     kStatus_DSPI_OutOfRange = MAKE_STATUS(kStatusGroup_DSPI, 3)  /*!< DSPI transfer out of range. */
43 };
44 
45 /*! @brief DSPI status flags in SPIx_SR register.*/
46 enum _dspi_flags
47 {
48     kDSPI_TxCompleteFlag         = (int)SPI_SR_TCF_MASK, /*!< Transfer Complete Flag. */
49     kDSPI_EndOfQueueFlag         = SPI_SR_EOQF_MASK,     /*!< End of Queue Flag.*/
50     kDSPI_TxFifoUnderflowFlag    = SPI_SR_TFUF_MASK,     /*!< Transmit FIFO Underflow Flag.*/
51     kDSPI_TxFifoFillRequestFlag  = SPI_SR_TFFF_MASK,     /*!< Transmit FIFO Fill Flag.*/
52     kDSPI_RxFifoOverflowFlag     = SPI_SR_RFOF_MASK,     /*!< Receive FIFO Overflow Flag.*/
53     kDSPI_RxFifoDrainRequestFlag = SPI_SR_RFDF_MASK,     /*!< Receive FIFO Drain Flag.*/
54     kDSPI_TxAndRxStatusFlag      = SPI_SR_TXRXS_MASK,    /*!< The module is in Stopped/Running state.*/
55     kDSPI_AllStatusFlag          = (int)(SPI_SR_TCF_MASK | SPI_SR_EOQF_MASK | SPI_SR_TFUF_MASK | SPI_SR_TFFF_MASK |
56                                 SPI_SR_RFOF_MASK | SPI_SR_RFDF_MASK | SPI_SR_TXRXS_MASK) /*!< All statuses above.*/
57 };
58 
59 /*! @brief DSPI interrupt source.*/
60 enum _dspi_interrupt_enable
61 {
62     kDSPI_TxCompleteInterruptEnable         = (int)SPI_RSER_TCF_RE_MASK, /*!< TCF  interrupt enable.*/
63     kDSPI_EndOfQueueInterruptEnable         = SPI_RSER_EOQF_RE_MASK,     /*!< EOQF interrupt enable.*/
64     kDSPI_TxFifoUnderflowInterruptEnable    = SPI_RSER_TFUF_RE_MASK,     /*!< TFUF interrupt enable.*/
65     kDSPI_TxFifoFillRequestInterruptEnable  = SPI_RSER_TFFF_RE_MASK,     /*!< TFFF interrupt enable, DMA disable.*/
66     kDSPI_RxFifoOverflowInterruptEnable     = SPI_RSER_RFOF_RE_MASK,     /*!< RFOF interrupt enable.*/
67     kDSPI_RxFifoDrainRequestInterruptEnable = SPI_RSER_RFDF_RE_MASK,     /*!< RFDF interrupt enable, DMA disable.*/
68     kDSPI_AllInterruptEnable = (int)(SPI_RSER_TCF_RE_MASK | SPI_RSER_EOQF_RE_MASK | SPI_RSER_TFUF_RE_MASK |
69                                      SPI_RSER_TFFF_RE_MASK | SPI_RSER_RFOF_RE_MASK | SPI_RSER_RFDF_RE_MASK)
70     /*!< All above interrupts enable.*/
71 };
72 
73 /*! @brief DSPI DMA source.*/
74 enum _dspi_dma_enable
75 {
76     kDSPI_TxDmaEnable = (SPI_RSER_TFFF_RE_MASK | SPI_RSER_TFFF_DIRS_MASK), /*!< TFFF flag generates DMA requests.
77                                                                                 No Tx interrupt request. */
78     kDSPI_RxDmaEnable = (SPI_RSER_RFDF_RE_MASK | SPI_RSER_RFDF_DIRS_MASK)  /*!< RFDF flag generates DMA requests.
79                                                                                 No Rx interrupt request. */
80 };
81 
82 /*! @brief DSPI master or slave mode configuration.*/
83 typedef enum _dspi_master_slave_mode
84 {
85     kDSPI_Master = 1U, /*!< DSPI peripheral operates in master mode.*/
86     kDSPI_Slave  = 0U  /*!< DSPI peripheral operates in slave mode.*/
87 } dspi_master_slave_mode_t;
88 
89 /*!
90  * @brief DSPI Sample Point: Controls when the DSPI master samples SIN in the Modified Transfer Format. This field is
91  * valid only when the CPHA bit in the CTAR register is 0.
92  */
93 typedef enum _dspi_master_sample_point
94 {
95     kDSPI_SckToSin0Clock = 0U, /*!< 0 system clocks between SCK edge and SIN sample.*/
96     kDSPI_SckToSin1Clock = 1U, /*!< 1 system clock  between SCK edge and SIN sample.*/
97     kDSPI_SckToSin2Clock = 2U  /*!< 2 system clocks between SCK edge and SIN sample.*/
98 } dspi_master_sample_point_t;
99 
100 /*! @brief DSPI Peripheral Chip Select (Pcs) configuration (which Pcs to configure).*/
101 typedef enum _dspi_which_pcs_config
102 {
103     kDSPI_Pcs0 = 1U << 0, /*!< Pcs[0] */
104     kDSPI_Pcs1 = 1U << 1, /*!< Pcs[1] */
105     kDSPI_Pcs2 = 1U << 2, /*!< Pcs[2] */
106     kDSPI_Pcs3 = 1U << 3, /*!< Pcs[3] */
107     kDSPI_Pcs4 = 1U << 4, /*!< Pcs[4] */
108     kDSPI_Pcs5 = 1U << 5  /*!< Pcs[5] */
109 } dspi_which_pcs_t;
110 
111 /*! @brief DSPI Peripheral Chip Select (Pcs) Polarity configuration.*/
112 typedef enum _dspi_pcs_polarity_config
113 {
114     kDSPI_PcsActiveHigh = 0U, /*!< Pcs Active High (idles low). */
115     kDSPI_PcsActiveLow  = 1U  /*!< Pcs Active Low (idles high). */
116 } dspi_pcs_polarity_config_t;
117 
118 /*! @brief DSPI Peripheral Chip Select (Pcs) Polarity.*/
119 enum _dspi_pcs_polarity
120 {
121     kDSPI_Pcs0ActiveLow   = 1U << 0, /*!< Pcs0 Active Low (idles high). */
122     kDSPI_Pcs1ActiveLow   = 1U << 1, /*!< Pcs1 Active Low (idles high). */
123     kDSPI_Pcs2ActiveLow   = 1U << 2, /*!< Pcs2 Active Low (idles high). */
124     kDSPI_Pcs3ActiveLow   = 1U << 3, /*!< Pcs3 Active Low (idles high). */
125     kDSPI_Pcs4ActiveLow   = 1U << 4, /*!< Pcs4 Active Low (idles high). */
126     kDSPI_Pcs5ActiveLow   = 1U << 5, /*!< Pcs5 Active Low (idles high). */
127     kDSPI_PcsAllActiveLow = 0xFFU    /*!< Pcs0 to Pcs5 Active Low (idles high). */
128 };
129 
130 /*! @brief DSPI clock polarity configuration for a given CTAR.*/
131 typedef enum _dspi_clock_polarity
132 {
133     kDSPI_ClockPolarityActiveHigh = 0U, /*!< CPOL=0. Active-high DSPI clock (idles low).*/
134     kDSPI_ClockPolarityActiveLow  = 1U  /*!< CPOL=1. Active-low DSPI clock (idles high).*/
135 } dspi_clock_polarity_t;
136 
137 /*! @brief DSPI clock phase configuration for a given CTAR.*/
138 typedef enum _dspi_clock_phase
139 {
140     kDSPI_ClockPhaseFirstEdge = 0U, /*!< CPHA=0. Data is captured on the leading edge of the SCK and changed on the
141                                          following edge.*/
142     kDSPI_ClockPhaseSecondEdge = 1U /*!< CPHA=1. Data is changed on the leading edge of the SCK and captured on the
143                                         following edge.*/
144 } dspi_clock_phase_t;
145 
146 /*! @brief DSPI data shifter direction options for a given CTAR.*/
147 typedef enum _dspi_shift_direction
148 {
149     kDSPI_MsbFirst = 0U, /*!< Data transfers start with most significant bit.*/
150     kDSPI_LsbFirst = 1U  /*!< Data transfers start with least significant bit.
151                               Shifting out of LSB is not supported for slave */
152 } dspi_shift_direction_t;
153 
154 /*! @brief DSPI delay type selection.*/
155 typedef enum _dspi_delay_type
156 {
157     kDSPI_PcsToSck = 1U,  /*!< Pcs-to-SCK delay. */
158     kDSPI_LastSckToPcs,   /*!< The last SCK edge to Pcs delay. */
159     kDSPI_BetweenTransfer /*!< Delay between transfers. */
160 } dspi_delay_type_t;
161 
162 /*! @brief DSPI Clock and Transfer Attributes Register (CTAR) selection.*/
163 typedef enum _dspi_ctar_selection
164 {
165     kDSPI_Ctar0 = 0U, /*!< CTAR0 selection option for master or slave mode; note that CTAR0 and CTAR0_SLAVE are the
166                          same register address. */
167     kDSPI_Ctar1 = 1U, /*!< CTAR1 selection option for master mode only. */
168     kDSPI_Ctar2 = 2U, /*!< CTAR2 selection option for master mode only; note that some devices do not support CTAR2. */
169     kDSPI_Ctar3 = 3U, /*!< CTAR3 selection option for master mode only; note that some devices do not support CTAR3. */
170     kDSPI_Ctar4 = 4U, /*!< CTAR4 selection option for master mode only; note that some devices do not support CTAR4. */
171     kDSPI_Ctar5 = 5U, /*!< CTAR5 selection option for master mode only; note that some devices do not support CTAR5. */
172     kDSPI_Ctar6 = 6U, /*!< CTAR6 selection option for master mode only; note that some devices do not support CTAR6. */
173     kDSPI_Ctar7 = 7U  /*!< CTAR7 selection option for master mode only; note that some devices do not support CTAR7. */
174 } dspi_ctar_selection_t;
175 
176 #define DSPI_MASTER_CTAR_SHIFT (0U)    /*!< DSPI master CTAR shift macro; used internally. */
177 #define DSPI_MASTER_CTAR_MASK  (0x0FU) /*!< DSPI master CTAR mask macro; used internally. */
178 #define DSPI_MASTER_PCS_SHIFT  (4U)    /*!< DSPI master PCS shift macro; used internally. */
179 #define DSPI_MASTER_PCS_MASK   (0xF0U) /*!< DSPI master PCS mask macro; used internally. */
180 /*! @brief Use this enumeration for the DSPI master transfer configFlags. */
181 enum _dspi_transfer_config_flag_for_master
182 {
183     kDSPI_MasterCtar0 = 0U << DSPI_MASTER_CTAR_SHIFT, /*!< DSPI master transfer use CTAR0 setting. */
184     kDSPI_MasterCtar1 = 1U << DSPI_MASTER_CTAR_SHIFT, /*!< DSPI master transfer use CTAR1 setting. */
185     kDSPI_MasterCtar2 = 2U << DSPI_MASTER_CTAR_SHIFT, /*!< DSPI master transfer use CTAR2 setting. */
186     kDSPI_MasterCtar3 = 3U << DSPI_MASTER_CTAR_SHIFT, /*!< DSPI master transfer use CTAR3 setting. */
187     kDSPI_MasterCtar4 = 4U << DSPI_MASTER_CTAR_SHIFT, /*!< DSPI master transfer use CTAR4 setting. */
188     kDSPI_MasterCtar5 = 5U << DSPI_MASTER_CTAR_SHIFT, /*!< DSPI master transfer use CTAR5 setting. */
189     kDSPI_MasterCtar6 = 6U << DSPI_MASTER_CTAR_SHIFT, /*!< DSPI master transfer use CTAR6 setting. */
190     kDSPI_MasterCtar7 = 7U << DSPI_MASTER_CTAR_SHIFT, /*!< DSPI master transfer use CTAR7 setting. */
191 
192     kDSPI_MasterPcs0 = 0U << DSPI_MASTER_PCS_SHIFT, /*!< DSPI master transfer use PCS0 signal. */
193     kDSPI_MasterPcs1 = 1U << DSPI_MASTER_PCS_SHIFT, /*!< DSPI master transfer use PCS1 signal. */
194     kDSPI_MasterPcs2 = 2U << DSPI_MASTER_PCS_SHIFT, /*!< DSPI master transfer use PCS2 signal.*/
195     kDSPI_MasterPcs3 = 3U << DSPI_MASTER_PCS_SHIFT, /*!< DSPI master transfer use PCS3 signal. */
196     kDSPI_MasterPcs4 = 4U << DSPI_MASTER_PCS_SHIFT, /*!< DSPI master transfer use PCS4 signal. */
197     kDSPI_MasterPcs5 = 5U << DSPI_MASTER_PCS_SHIFT, /*!< DSPI master transfer use PCS5 signal. */
198 
199     kDSPI_MasterPcsContinuous       = 1U << 20, /*!< Indicates whether the PCS signal is continuous. */
200     kDSPI_MasterActiveAfterTransfer = 1U << 21,
201     /*!< Indicates whether the PCS signal is active after the last frame transfer.*/
202 };
203 
204 #define DSPI_SLAVE_CTAR_SHIFT (0U)    /*!< DSPI slave CTAR shift macro; used internally. */
205 #define DSPI_SLAVE_CTAR_MASK  (0x07U) /*!< DSPI slave CTAR mask macro; used internally. */
206 /*! @brief Use this enumeration for the DSPI slave transfer configFlags. */
207 enum _dspi_transfer_config_flag_for_slave
208 {
209     kDSPI_SlaveCtar0 = 0U << DSPI_SLAVE_CTAR_SHIFT, /*!< DSPI slave transfer use CTAR0 setting.
210                                                          DSPI slave can only use PCS0. */
211 };
212 
213 /*! @brief DSPI transfer state, which is used for DSPI transactional API state machine. */
214 enum _dspi_transfer_state
215 {
216     kDSPI_Idle = 0x0U, /*!< Nothing in the transmitter/receiver. */
217     kDSPI_Busy,        /*!< Transfer queue is not finished. */
218     kDSPI_Error        /*!< Transfer error. */
219 };
220 
221 /*! @brief DSPI master command date configuration used for the SPIx_PUSHR.*/
222 typedef struct _dspi_command_data_config
223 {
224     bool isPcsContinuous;    /*!< Option to enable the continuous assertion of the chip select between transfers.*/
225     uint8_t whichCtar;       /*!< The desired Clock and Transfer Attributes
226                                                 Register (CTAR) to use for CTAS.*/
227     uint8_t whichPcs;        /*!< The desired PCS signal to use for the data transfer.*/
228     bool isEndOfQueue;       /*!< Signals that the current transfer is the last in the queue.*/
229     bool clearTransferCount; /*!< Clears the SPI Transfer Counter (SPI_TCNT) before transmission starts.*/
230 } dspi_command_data_config_t;
231 
232 /*! @brief DSPI master ctar configuration structure.*/
233 typedef struct _dspi_master_ctar_config
234 {
235     uint32_t baudRate;                /*!< Baud Rate for DSPI. */
236     uint32_t bitsPerFrame;            /*!< Bits per frame, minimum 4, maximum 16.*/
237     dspi_clock_polarity_t cpol;       /*!< Clock polarity. */
238     dspi_clock_phase_t cpha;          /*!< Clock phase. */
239     dspi_shift_direction_t direction; /*!< MSB or LSB data shift direction. */
240 
241     uint32_t pcsToSckDelayInNanoSec;     /*!< PCS to SCK delay time in nanoseconds; setting to 0 sets the minimum
242                                             delay. It also sets the boundary value if out of range.*/
243     uint32_t lastSckToPcsDelayInNanoSec; /*!< The last SCK to PCS delay time in nanoseconds; setting to 0 sets the
244                                             minimum delay. It also sets the boundary value if out of range.*/
245 
246     uint32_t betweenTransferDelayInNanoSec;
247     /*!< After the SCK delay time in nanoseconds; setting to 0 sets the minimum
248         delay. It also sets the boundary value if out of range.*/
249 } dspi_master_ctar_config_t;
250 
251 /*! @brief DSPI master configuration structure.*/
252 typedef struct _dspi_master_config
253 {
254     dspi_ctar_selection_t whichCtar;      /*!< The desired CTAR to use. */
255     dspi_master_ctar_config_t ctarConfig; /*!< Set the ctarConfig to the desired CTAR. */
256 
257     dspi_which_pcs_t whichPcs;                     /*!< The desired Peripheral Chip Select (pcs). */
258     dspi_pcs_polarity_config_t pcsActiveHighOrLow; /*!< The desired PCS active high or low. */
259 
260     bool enableContinuousSCK;   /*!< CONT_SCKE, continuous SCK enable. Note that the continuous SCK is only
261                                      supported for CPHA = 1.*/
262     bool enableRxFifoOverWrite; /*!< ROOE, receive FIFO overflow overwrite enable. If ROOE = 0, the incoming
263                                      data is ignored and the data from the transfer that generated the overflow
264                                      is also ignored. If ROOE = 1, the incoming data is shifted to the
265                                      shift register. */
266 
267     bool enableModifiedTimingFormat;        /*!< Enables a modified transfer format to be used if true.*/
268     dspi_master_sample_point_t samplePoint; /*!< Controls when the module master samples SIN in the Modified Transfer
269                                                  Format. It's valid only when CPHA=0. */
270 } dspi_master_config_t;
271 
272 /*! @brief DSPI slave ctar configuration structure.*/
273 typedef struct _dspi_slave_ctar_config
274 {
275     uint32_t bitsPerFrame;      /*!< Bits per frame, minimum 4, maximum 16.*/
276     dspi_clock_polarity_t cpol; /*!< Clock polarity. */
277     dspi_clock_phase_t cpha;    /*!< Clock phase. */
278                                 /*!< Slave only supports MSB and does not support LSB.*/
279 } dspi_slave_ctar_config_t;
280 
281 /*! @brief DSPI slave configuration structure.*/
282 typedef struct _dspi_slave_config
283 {
284     dspi_ctar_selection_t whichCtar;     /*!< The desired CTAR to use. */
285     dspi_slave_ctar_config_t ctarConfig; /*!< Set the ctarConfig to the desired CTAR. */
286 
287     bool enableContinuousSCK;               /*!< CONT_SCKE, continuous SCK enable. Note that the continuous SCK is only
288                                                  supported for CPHA = 1.*/
289     bool enableRxFifoOverWrite;             /*!< ROOE, receive FIFO overflow overwrite enable. If ROOE = 0, the incoming
290                                                  data is ignored and the data from the transfer that generated the overflow
291                                                  is also ignored. If ROOE = 1, the incoming data is shifted to the
292                                                  shift register. */
293     bool enableModifiedTimingFormat;        /*!< Enables a modified transfer format to be used if true.*/
294     dspi_master_sample_point_t samplePoint; /*!< Controls when the module master samples SIN in the Modified Transfer
295                                                Format. It's valid only when CPHA=0. */
296 } dspi_slave_config_t;
297 
298 /*!
299  * @brief Forward declaration of the @ref _dspi_master_handle typedefs.
300  */
301 typedef struct _dspi_master_handle dspi_master_handle_t; /*!< The master handle. */
302 
303 /*!
304  * @brief Forward declaration of the @ref _dspi_slave_handle typedefs.
305  */
306 typedef struct _dspi_slave_handle dspi_slave_handle_t; /*!< The slave handle. */
307 
308 /*!
309  * @brief Completion callback function pointer type.
310  *
311  * @param base DSPI peripheral address.
312  * @param handle Pointer to the handle for the DSPI master.
313  * @param status Success or error code describing whether the transfer completed.
314  * @param userData Arbitrary pointer-dataSized value passed from the application.
315  */
316 typedef void (*dspi_master_transfer_callback_t)(SPI_Type *base,
317                                                 dspi_master_handle_t *handle,
318                                                 status_t status,
319                                                 void *userData);
320 /*!
321  * @brief Completion callback function pointer type.
322  *
323  * @param base DSPI peripheral address.
324  * @param handle Pointer to the handle for the DSPI slave.
325  * @param status Success or error code describing whether the transfer completed.
326  * @param userData Arbitrary pointer-dataSized value passed from the application.
327  */
328 typedef void (*dspi_slave_transfer_callback_t)(SPI_Type *base,
329                                                dspi_slave_handle_t *handle,
330                                                status_t status,
331                                                void *userData);
332 
333 /*! @brief DSPI master/slave transfer structure.*/
334 typedef struct _dspi_transfer
335 {
336     const uint8_t *txData;    /*!< Send buffer. */
337     uint8_t *rxData;          /*!< Receive buffer. */
338     volatile size_t dataSize; /*!< Transfer bytes. */
339 
340     uint32_t configFlags; /*!< Transfer transfer configuration flags. Set from @ref
341                              _dspi_transfer_config_flag_for_master if the transfer is used for master or @ref
342                              _dspi_transfer_config_flag_for_slave enumeration if the transfer is used for slave.*/
343 } dspi_transfer_t;
344 
345 /*! @brief DSPI half-duplex(master) transfer structure */
346 typedef struct _dspi_half_duplex_transfer
347 {
348     const uint8_t *txData;/*!< Send buffer */
349     uint8_t *rxData;      /*!< Receive buffer */
350     size_t txDataSize;    /*!< Transfer bytes for transmit */
351     size_t rxDataSize;    /*!< Transfer bytes */
352     uint32_t configFlags; /*!< Transfer configuration flags; set from @ref _dspi_transfer_config_flag_for_master. */
353     bool isPcsAssertInTransfer; /*!< If Pcs pin keep assert between transmit and receive. true for assert and false for
354                                    de-assert. */
355     bool isTransmitFirst;       /*!< True for transmit first and false for receive first. */
356 } dspi_half_duplex_transfer_t;
357 
358 /*! @brief DSPI master transfer handle structure used for transactional API. */
359 struct _dspi_master_handle
360 {
361     uint32_t bitsPerFrame;         /*!< The desired number of bits per frame. */
362     volatile uint32_t command;     /*!< The desired data command. */
363     volatile uint32_t lastCommand; /*!< The desired last data command. */
364 
365     uint8_t fifoSize; /*!< FIFO dataSize. */
366 
367     volatile bool
368         isPcsActiveAfterTransfer;   /*!< Indicates whether the PCS signal is active after the last frame transfer.*/
369     volatile bool isThereExtraByte; /*!< Indicates whether there are extra bytes.*/
370 
371     const uint8_t *volatile txData;            /*!< Send buffer. */
372     uint8_t *volatile rxData;                  /*!< Receive buffer. */
373     volatile size_t remainingSendByteCount;    /*!< A number of bytes remaining to send.*/
374     volatile size_t remainingReceiveByteCount; /*!< A number of bytes remaining to receive.*/
375     size_t totalByteCount;                     /*!< A number of transfer bytes*/
376 
377     volatile uint8_t state; /*!< DSPI transfer state, see @ref _dspi_transfer_state.*/
378 
379     dspi_master_transfer_callback_t callback; /*!< Completion callback. */
380     void *userData;                           /*!< Callback user data. */
381 };
382 
383 /*! @brief DSPI slave transfer handle structure used for the transactional API. */
384 struct _dspi_slave_handle
385 {
386     uint32_t bitsPerFrame;          /*!< The desired number of bits per frame. */
387     volatile bool isThereExtraByte; /*!< Indicates whether there are extra bytes.*/
388 
389     const uint8_t *volatile txData;            /*!< Send buffer. */
390     uint8_t *volatile rxData;                  /*!< Receive buffer. */
391     volatile size_t remainingSendByteCount;    /*!< A number of bytes remaining to send.*/
392     volatile size_t remainingReceiveByteCount; /*!< A number of bytes remaining to receive.*/
393     size_t totalByteCount;                     /*!< A number of transfer bytes*/
394 
395     volatile uint8_t state; /*!< DSPI transfer state.*/
396 
397     volatile uint32_t errorCount; /*!< Error count for slave transfer.*/
398 
399     dspi_slave_transfer_callback_t callback; /*!< Completion callback. */
400     void *userData;                          /*!< Callback user data. */
401 };
402 
403 /**********************************************************************************************************************
404  * API
405  *********************************************************************************************************************/
406 #if defined(__cplusplus)
407 extern "C" {
408 #endif /*_cplusplus*/
409 
410 /*!
411  * @name Initialization and deinitialization
412  * @{
413  */
414 
415 /*!
416  * @brief Initializes the DSPI master.
417  *
418  * This function initializes the DSPI master configuration. This is an example use case.
419  *  @code
420  *   dspi_master_config_t  masterConfig;
421  *   masterConfig.whichCtar                                = kDSPI_Ctar0;
422  *   masterConfig.ctarConfig.baudRate                      = 500000000U;
423  *   masterConfig.ctarConfig.bitsPerFrame                  = 8;
424  *   masterConfig.ctarConfig.cpol                          = kDSPI_ClockPolarityActiveHigh;
425  *   masterConfig.ctarConfig.cpha                          = kDSPI_ClockPhaseFirstEdge;
426  *   masterConfig.ctarConfig.direction                     = kDSPI_MsbFirst;
427  *   masterConfig.ctarConfig.pcsToSckDelayInNanoSec        = 1000000000U / masterConfig.ctarConfig.baudRate ;
428  *   masterConfig.ctarConfig.lastSckToPcsDelayInNanoSec    = 1000000000U / masterConfig.ctarConfig.baudRate ;
429  *   masterConfig.ctarConfig.betweenTransferDelayInNanoSec = 1000000000U / masterConfig.ctarConfig.baudRate ;
430  *   masterConfig.whichPcs                                 = kDSPI_Pcs0;
431  *   masterConfig.pcsActiveHighOrLow                       = kDSPI_PcsActiveLow;
432  *   masterConfig.enableContinuousSCK                      = false;
433  *   masterConfig.enableRxFifoOverWrite                    = false;
434  *   masterConfig.enableModifiedTimingFormat               = false;
435  *   masterConfig.samplePoint                              = kDSPI_SckToSin0Clock;
436  *   DSPI_MasterInit(base, &masterConfig, srcClock_Hz);
437  *  @endcode
438  *
439  * @param base DSPI peripheral address.
440  * @param masterConfig Pointer to the structure @ref dspi_master_config_t.
441  * @param srcClock_Hz Module source input clock in Hertz.
442  */
443 void DSPI_MasterInit(SPI_Type *base, const dspi_master_config_t *masterConfig, uint32_t srcClock_Hz);
444 
445 /*!
446  * @brief Sets the @ref dspi_master_config_t structure to default values.
447  *
448  * The purpose of this API is to get the configuration structure initialized for the DSPI_MasterInit().
449  * Users may use the initialized structure unchanged in the DSPI_MasterInit() or modify the structure
450  * before calling the DSPI_MasterInit().
451  * Example:
452  * @code
453  *  dspi_master_config_t  masterConfig;
454  *  DSPI_MasterGetDefaultConfig(&masterConfig);
455  * @endcode
456  * @param masterConfig pointer to @ref dspi_master_config_t structure
457  */
458 void DSPI_MasterGetDefaultConfig(dspi_master_config_t *masterConfig);
459 
460 /*!
461  * @brief DSPI slave configuration.
462  *
463  * This function initializes the DSPI slave configuration. This is an example use case.
464  *  @code
465  *   dspi_slave_config_t  slaveConfig;
466  *  slaveConfig->whichCtar                  = kDSPI_Ctar0;
467  *  slaveConfig->ctarConfig.bitsPerFrame    = 8;
468  *  slaveConfig->ctarConfig.cpol            = kDSPI_ClockPolarityActiveHigh;
469  *  slaveConfig->ctarConfig.cpha            = kDSPI_ClockPhaseFirstEdge;
470  *  slaveConfig->enableContinuousSCK        = false;
471  *  slaveConfig->enableRxFifoOverWrite      = false;
472  *  slaveConfig->enableModifiedTimingFormat = false;
473  *  slaveConfig->samplePoint                = kDSPI_SckToSin0Clock;
474  *   DSPI_SlaveInit(base, &slaveConfig);
475  *  @endcode
476  *
477  * @param base DSPI peripheral address.
478  * @param slaveConfig Pointer to the structure @ref dspi_master_config_t.
479  */
480 void DSPI_SlaveInit(SPI_Type *base, const dspi_slave_config_t *slaveConfig);
481 
482 /*!
483  * @brief Sets the @ref dspi_slave_config_t structure to a default value.
484  *
485  * The purpose of this API is to get the configuration structure initialized for the DSPI_SlaveInit().
486  * Users may use the initialized structure unchanged in the DSPI_SlaveInit() or modify the structure
487  * before calling the DSPI_SlaveInit().
488  * This is an example.
489  * @code
490  *  dspi_slave_config_t  slaveConfig;
491  *  DSPI_SlaveGetDefaultConfig(&slaveConfig);
492  * @endcode
493  * @param slaveConfig Pointer to the @ref dspi_slave_config_t structure.
494  */
495 void DSPI_SlaveGetDefaultConfig(dspi_slave_config_t *slaveConfig);
496 
497 /*!
498  * @brief De-initializes the DSPI peripheral. Call this API to disable the DSPI clock.
499  * @param base DSPI peripheral address.
500  */
501 void DSPI_Deinit(SPI_Type *base);
502 
503 /*!
504  * @brief Enables the DSPI peripheral and sets the MCR MDIS to 0.
505  *
506  * @param base DSPI peripheral address.
507  * @param enable Pass true to enable module, false to disable module.
508  */
DSPI_Enable(SPI_Type * base,bool enable)509 static inline void DSPI_Enable(SPI_Type *base, bool enable)
510 {
511     if (enable)
512     {
513         base->MCR &= ~SPI_MCR_MDIS_MASK;
514     }
515     else
516     {
517         base->MCR |= SPI_MCR_MDIS_MASK;
518     }
519 }
520 
521 /*!
522  *@}
523  */
524 
525 /*!
526  * @name Status
527  * @{
528  */
529 
530 /*!
531  * @brief Gets the DSPI status flag state.
532  * @param base DSPI peripheral address.
533  * @return DSPI status (in SR register).
534  */
DSPI_GetStatusFlags(SPI_Type * base)535 static inline uint32_t DSPI_GetStatusFlags(SPI_Type *base)
536 {
537     return (base->SR);
538 }
539 
540 /*!
541  * @brief Clears the DSPI status flag.
542  *
543  * This function  clears the desired status bit by using a write-1-to-clear. The user passes in the base and the
544  * desired status bit to clear.  The list of status bits is defined in the <b>dspi_status_and_interrupt_request_t</b>.
545  * The function uses these bit positions in its algorithm to clear the desired flag state. This is an example.
546  * @code
547  *  DSPI_ClearStatusFlags(base, kDSPI_TxCompleteFlag|kDSPI_EndOfQueueFlag);
548  * @endcode
549  *
550  * @param base DSPI peripheral address.
551  * @param statusFlags The status flag used from the type dspi_flags.
552  */
DSPI_ClearStatusFlags(SPI_Type * base,uint32_t statusFlags)553 static inline void DSPI_ClearStatusFlags(SPI_Type *base, uint32_t statusFlags)
554 {
555     base->SR = statusFlags; /*!< The status flags are cleared by writing 1 (w1c).*/
556 }
557 
558 /*!
559  *@}
560  */
561 
562 /*!
563  * @name Interrupts
564  * @{
565  */
566 
567 /*!
568  * @brief Enables the DSPI interrupts.
569  *
570  * This function configures various interrupt masks of the DSPI.  The parameters are a base and an interrupt mask.
571  * @note For Tx Fill and Rx FIFO drain requests, enable the interrupt request and disable the DMA request.
572  *       Do not use this API(write to RSER register) while DSPI is in running state.
573  *
574  * @code
575  *  DSPI_EnableInterrupts(base, kDSPI_TxCompleteInterruptEnable | kDSPI_EndOfQueueInterruptEnable );
576  * @endcode
577  *
578  * @param base DSPI peripheral address.
579  * @param mask The interrupt mask; use the enum @ref _dspi_interrupt_enable.
580  */
581 void DSPI_EnableInterrupts(SPI_Type *base, uint32_t mask);
582 
583 /*!
584  * @brief Disables the DSPI interrupts.
585  *
586  * @code
587  *  DSPI_DisableInterrupts(base, kDSPI_TxCompleteInterruptEnable | kDSPI_EndOfQueueInterruptEnable );
588  * @endcode
589  *
590  * @param base DSPI peripheral address.
591  * @param mask The interrupt mask; use the enum @ref _dspi_interrupt_enable.
592  */
DSPI_DisableInterrupts(SPI_Type * base,uint32_t mask)593 static inline void DSPI_DisableInterrupts(SPI_Type *base, uint32_t mask)
594 {
595     base->RSER &= ~mask;
596 }
597 
598 /*!
599  *@}
600  */
601 
602 /*!
603  * @name DMA Control
604  * @{
605  */
606 
607 /*!
608  * @brief Enables the DSPI DMA request.
609  *
610  * This function configures the Rx and Tx DMA mask of the DSPI.  The parameters are a base and a DMA mask.
611  * @code
612  *  DSPI_EnableDMA(base, kDSPI_TxDmaEnable | kDSPI_RxDmaEnable);
613  * @endcode
614  *
615  * @param base DSPI peripheral address.
616  * @param mask The interrupt mask; use the enum @ref _dspi_dma_enable.
617  */
DSPI_EnableDMA(SPI_Type * base,uint32_t mask)618 static inline void DSPI_EnableDMA(SPI_Type *base, uint32_t mask)
619 {
620     base->RSER |= mask;
621 }
622 
623 /*!
624  * @brief Disables the DSPI DMA request.
625  *
626  * This function configures the Rx and Tx DMA mask of the DSPI.  The parameters are a base and a DMA mask.
627  * @code
628  *  SPI_DisableDMA(base, kDSPI_TxDmaEnable | kDSPI_RxDmaEnable);
629  * @endcode
630  *
631  * @param base DSPI peripheral address.
632  * @param mask The interrupt mask; use the enum @ref _dspi_dma_enable.
633  */
DSPI_DisableDMA(SPI_Type * base,uint32_t mask)634 static inline void DSPI_DisableDMA(SPI_Type *base, uint32_t mask)
635 {
636     base->RSER &= ~mask;
637 }
638 
639 /*!
640  * @brief Gets the DSPI master PUSHR data register address for the DMA operation.
641  *
642  * This function gets the DSPI master PUSHR data register address because this value is needed for the DMA operation.
643  *
644  * @param base DSPI peripheral address.
645  * @return The DSPI master PUSHR data register address.
646  */
DSPI_MasterGetTxRegisterAddress(SPI_Type * base)647 static inline uint32_t DSPI_MasterGetTxRegisterAddress(SPI_Type *base)
648 {
649     return (uint32_t) & (base->PUSHR);
650 }
651 
652 /*!
653  * @brief Gets the DSPI slave PUSHR data register address for the DMA operation.
654  *
655  * This function gets the DSPI slave PUSHR data register address as this value is needed for the DMA operation.
656  *
657  * @param base DSPI peripheral address.
658  * @return The DSPI slave PUSHR data register address.
659  */
DSPI_SlaveGetTxRegisterAddress(SPI_Type * base)660 static inline uint32_t DSPI_SlaveGetTxRegisterAddress(SPI_Type *base)
661 {
662     return (uint32_t) & (base->PUSHR_SLAVE);
663 }
664 
665 /*!
666  * @brief Gets the DSPI POPR data register address for the DMA operation.
667  *
668  * This function gets the DSPI POPR data register address as this value is needed for the DMA operation.
669  *
670  * @param base DSPI peripheral address.
671  * @return The DSPI POPR data register address.
672  */
DSPI_GetRxRegisterAddress(SPI_Type * base)673 static inline uint32_t DSPI_GetRxRegisterAddress(SPI_Type *base)
674 {
675     return (uint32_t) & (base->POPR);
676 }
677 
678 /*!
679  *@}
680  */
681 
682 /*!
683  * @name Bus Operations
684  * @{
685  */
686 /*!
687  * @brief Get instance number for DSPI module.
688  *
689  * @param base DSPI peripheral base address.
690  */
691 uint32_t DSPI_GetInstance(SPI_Type *base);
692 
693 /*!
694  * @brief Configures the DSPI for master or slave.
695  *
696  * @param base DSPI peripheral address.
697  * @param mode Mode setting (master or slave) of type @ref dspi_master_slave_mode_t.
698  */
DSPI_SetMasterSlaveMode(SPI_Type * base,dspi_master_slave_mode_t mode)699 static inline void DSPI_SetMasterSlaveMode(SPI_Type *base, dspi_master_slave_mode_t mode)
700 {
701     base->MCR = (base->MCR & (~SPI_MCR_MSTR_MASK)) | SPI_MCR_MSTR(mode);
702 }
703 
704 /*!
705  * @brief Returns whether the DSPI module is in master mode.
706  *
707  * @param base DSPI peripheral address.
708  * @return Returns true if the module is in master mode or false if the module is in slave mode.
709  */
DSPI_IsMaster(SPI_Type * base)710 static inline bool DSPI_IsMaster(SPI_Type *base)
711 {
712     bool ismaster = false;
713     if (0U != ((base->MCR) & SPI_MCR_MSTR_MASK))
714     {
715         ismaster = true;
716     }
717     return ismaster;
718 }
719 /*!
720  * @brief Starts the DSPI transfers and clears HALT bit in MCR.
721  *
722  * This function sets the module to start data transfer in either master or slave mode.
723  *
724  * @param base DSPI peripheral address.
725  */
DSPI_StartTransfer(SPI_Type * base)726 static inline void DSPI_StartTransfer(SPI_Type *base)
727 {
728     base->MCR &= ~SPI_MCR_HALT_MASK;
729 }
730 /*!
731  * @brief Stops DSPI transfers and sets the HALT bit in MCR.
732  *
733  * This function stops data transfers in either master or slave modes.
734  *
735  * @param base DSPI peripheral address.
736  */
DSPI_StopTransfer(SPI_Type * base)737 static inline void DSPI_StopTransfer(SPI_Type *base)
738 {
739     base->MCR |= SPI_MCR_HALT_MASK;
740 }
741 
742 /*!
743  * @brief Enables or disables the DSPI FIFOs.
744  *
745  * This function  allows the caller to disable/enable the Tx and Rx FIFOs independently.
746  * @note To disable, pass in a logic 0 (false) for the particular FIFO configuration.  To enable,
747  * pass in a logic 1 (true).
748  *
749  * @param base DSPI peripheral address.
750  * @param enableTxFifo Disables (false) the TX FIFO; Otherwise, enables (true) the TX FIFO
751  * @param enableRxFifo Disables (false) the RX FIFO; Otherwise, enables (true) the RX FIFO
752  */
DSPI_SetFifoEnable(SPI_Type * base,bool enableTxFifo,bool enableRxFifo)753 static inline void DSPI_SetFifoEnable(SPI_Type *base, bool enableTxFifo, bool enableRxFifo)
754 {
755     base->MCR = (base->MCR & (~(SPI_MCR_DIS_RXF_MASK | SPI_MCR_DIS_TXF_MASK))) |
756                 SPI_MCR_DIS_TXF((false == enableTxFifo ? 1U : 0U)) | SPI_MCR_DIS_RXF((false == enableRxFifo ? 1U : 0U));
757 }
758 
759 /*!
760  * @brief Flushes the DSPI FIFOs.
761  *
762  * @param base DSPI peripheral address.
763  * @param flushTxFifo Flushes (true) the Tx FIFO; Otherwise, does not flush (false) the Tx FIFO
764  * @param flushRxFifo Flushes (true) the Rx FIFO; Otherwise, does not flush (false) the Rx FIFO
765  */
DSPI_FlushFifo(SPI_Type * base,bool flushTxFifo,bool flushRxFifo)766 static inline void DSPI_FlushFifo(SPI_Type *base, bool flushTxFifo, bool flushRxFifo)
767 {
768     base->MCR = (base->MCR & (~(SPI_MCR_CLR_TXF_MASK | SPI_MCR_CLR_RXF_MASK))) |
769                 SPI_MCR_CLR_TXF((true == flushTxFifo ? 1U : 0U)) | SPI_MCR_CLR_RXF((true == flushRxFifo ? 1U : 0U));
770 }
771 
772 /*!
773  * @brief Configures the DSPI peripheral chip select polarity simultaneously.
774  * For example, PCS0 and PCS1 are set to active low and other PCS is set to active high. Note that the number of
775  * PCSs is specific to the device.
776  * @code
777  *  DSPI_SetAllPcsPolarity(base, kDSPI_Pcs0ActiveLow | kDSPI_Pcs1ActiveLow);
778    @endcode
779  * @param base DSPI peripheral address.
780  * @param mask The PCS polarity mask; use the enum @ref _dspi_pcs_polarity.
781  */
DSPI_SetAllPcsPolarity(SPI_Type * base,uint32_t mask)782 static inline void DSPI_SetAllPcsPolarity(SPI_Type *base, uint32_t mask)
783 {
784     base->MCR = (base->MCR & ~SPI_MCR_PCSIS_MASK) | SPI_MCR_PCSIS(mask);
785 }
786 
787 /*!
788  * @brief Sets the DSPI baud rate in bits per second.
789  *
790  * This function  takes in the desired baudRate_Bps (baud rate) and calculates the nearest possible baud rate without
791  * exceeding the desired baud rate, and returns the calculated baud rate in bits-per-second. It requires that the
792  * caller also provide the frequency of the module source clock (in Hertz).
793  *
794  * @param base DSPI peripheral address.
795  * @param whichCtar The desired Clock and Transfer Attributes Register (CTAR) of the type @ref dspi_ctar_selection_t
796  * @param baudRate_Bps The desired baud rate in bits per second
797  * @param srcClock_Hz Module source input clock in Hertz
798  * @return The actual calculated baud rate
799  */
800 uint32_t DSPI_MasterSetBaudRate(SPI_Type *base,
801                                 dspi_ctar_selection_t whichCtar,
802                                 uint32_t baudRate_Bps,
803                                 uint32_t srcClock_Hz);
804 
805 /*!
806  * @brief Manually configures the delay prescaler and scaler for a particular CTAR.
807  *
808  * This function configures the PCS to SCK delay pre-scalar (PcsSCK) and scalar (CSSCK), after SCK delay pre-scalar
809  * (PASC) and scalar (ASC), and the delay after transfer pre-scalar (PDT) and scalar (DT).
810  *
811  * These delay names are available in the type @ref dspi_delay_type_t.
812  *
813  * The user passes the delay to the configuration along with the prescaler and scaler value.
814  * This allows the user to directly set the prescaler/scaler values if pre-calculated or
815  * to manually increment either value.
816  *
817  * @param base DSPI peripheral address.
818  * @param whichCtar The desired Clock and Transfer Attributes Register (CTAR) of type @ref dspi_ctar_selection_t.
819  * @param prescaler The prescaler delay value (can be an integer 0, 1, 2, or 3).
820  * @param scaler The scaler delay value (can be any integer between 0 to 15).
821  * @param whichDelay The desired delay to configure; must be of type @ref dspi_delay_type_t
822  */
823 void DSPI_MasterSetDelayScaler(
824     SPI_Type *base, dspi_ctar_selection_t whichCtar, uint32_t prescaler, uint32_t scaler, dspi_delay_type_t whichDelay);
825 
826 /*!
827  * @brief Calculates the delay prescaler and scaler based on the desired delay input in nanoseconds.
828  *
829  * This function calculates the values for the following.
830  * PCS to SCK delay pre-scalar (PCSSCK) and scalar (CSSCK), or
831  * After SCK delay pre-scalar (PASC) and scalar (ASC), or
832  * Delay after transfer pre-scalar (PDT) and scalar (DT).
833  *
834  * These delay names are available in the type @ref dspi_delay_type_t.
835  *
836  * The user passes which delay to configure along with the desired delay value in nanoseconds.  The function
837  * calculates the values needed for the prescaler and scaler. Note that returning the calculated delay as an exact
838  * delay match may not be possible. In this case, the closest match is calculated without going below the desired
839  * delay value input.
840  * It is possible to input a very large delay value that exceeds the capability of the part, in which case the maximum
841  * supported delay is returned. The higher-level peripheral driver alerts the user of an out of range delay
842  * input.
843  *
844  * @param base DSPI peripheral address.
845  * @param whichCtar The desired Clock and Transfer Attributes Register (CTAR) of type @ref dspi_ctar_selection_t.
846  * @param whichDelay The desired delay to configure, must be of type @ref dspi_delay_type_t
847  * @param srcClock_Hz Module source input clock in Hertz
848  * @param delayTimeInNanoSec The desired delay value in nanoseconds.
849  * @return The actual calculated delay value.
850  */
851 uint32_t DSPI_MasterSetDelayTimes(SPI_Type *base,
852                                   dspi_ctar_selection_t whichCtar,
853                                   dspi_delay_type_t whichDelay,
854                                   uint32_t srcClock_Hz,
855                                   uint32_t delayTimeInNanoSec);
856 
857 /*!
858  * @brief Writes data into the data buffer for master mode.
859  *
860  * In master mode, the 16-bit data is appended to the 16-bit command info. The command portion
861  * provides characteristics of the data, such as the optional continuous chip select
862  * operation between transfers, the desired Clock and Transfer Attributes register to use for the
863  * associated SPI frame, the desired PCS signal to use for the data transfer, whether the current
864  * transfer is the last in the queue, and whether to clear the transfer count (normally needed when
865  * sending the first frame of a data packet). This is an example.
866  * @code
867  *  dspi_command_data_config_t commandConfig;
868  *  commandConfig.isPcsContinuous = true;
869  *  commandConfig.whichCtar = kDSPICtar0;
870  *  commandConfig.whichPcs = kDSPIPcs0;
871  *  commandConfig.clearTransferCount = false;
872  *  commandConfig.isEndOfQueue = false;
873  *  DSPI_MasterWriteData(base, &commandConfig, dataWord);
874    @endcode
875  *
876  * @param base DSPI peripheral address.
877  * @param command Pointer to the command structure.
878  * @param data The data word to be sent.
879  */
DSPI_MasterWriteData(SPI_Type * base,dspi_command_data_config_t * command,uint16_t data)880 static inline void DSPI_MasterWriteData(SPI_Type *base, dspi_command_data_config_t *command, uint16_t data)
881 {
882     base->PUSHR = SPI_PUSHR_CONT(command->isPcsContinuous) | SPI_PUSHR_CTAS(command->whichCtar) |
883                   SPI_PUSHR_PCS(command->whichPcs) | SPI_PUSHR_EOQ(command->isEndOfQueue) |
884                   SPI_PUSHR_CTCNT(command->clearTransferCount) | SPI_PUSHR_TXDATA(data);
885 }
886 
887 /*!
888  * @brief Sets the @ref dspi_command_data_config_t structure to default values.
889  *
890  * The purpose of this API is to get the configuration structure initialized for use in the
891  * <b>DSPI_MasterWrite_xx()</b>. Users may use the initialized structure unchanged in the DSPI_MasterWrite_xx() or
892  * modify the structure before calling the DSPI_MasterWrite_xx(). This is an example.
893  * @code
894  *  dspi_command_data_config_t  command;
895  *  DSPI_GetDefaultDataCommandConfig(&command);
896  * @endcode
897  * @param command Pointer to the @ref dspi_command_data_config_t structure.
898  */
899 void DSPI_GetDefaultDataCommandConfig(dspi_command_data_config_t *command);
900 
901 /*!
902  * @brief Writes data into the data buffer master mode and waits till complete to return.
903  *
904  * In master mode, the 16-bit data is appended to the 16-bit command info. The command portion
905  * provides characteristics of the data, such as the optional continuous chip select
906  * operation between transfers, the desired Clock and Transfer Attributes register to use for the
907  * associated SPI frame, the desired PCS signal to use for the data transfer, whether the current
908  * transfer is the last in the queue, and whether to clear the transfer count (normally needed when
909  * sending the first frame of a data packet). This is an example.
910  * @code
911  *  dspi_command_config_t commandConfig;
912  *  commandConfig.isPcsContinuous = true;
913  *  commandConfig.whichCtar = kDSPICtar0;
914  *  commandConfig.whichPcs = kDSPIPcs1;
915  *  commandConfig.clearTransferCount = false;
916  *  commandConfig.isEndOfQueue = false;
917  *  DSPI_MasterWriteDataBlocking(base, &commandConfig, dataWord);
918  * @endcode
919  *
920  * @note  This function does not return until after the transmit is complete. Also note that the DSPI must be
921  * enabled and running to transmit data (MCR[MDIS] & [HALT] = 0). Because the SPI is a synchronous protocol,
922  * the received data is available when the transmit completes.
923  *
924  * @param base DSPI peripheral address.
925  * @param command Pointer to the command structure.
926  * @param data The data word to be sent.
927  */
928 void DSPI_MasterWriteDataBlocking(SPI_Type *base, dspi_command_data_config_t *command, uint16_t data);
929 
930 /*!
931  * @brief Returns the DSPI command word formatted to the PUSHR data register bit field.
932  *
933  * This function allows the caller to pass in the data command structure and returns the command word formatted
934  * according to the DSPI PUSHR register bit field placement. The user can then "OR" the returned command word with the
935  * desired data to send and use the function <b>DSPI_HAL_WriteCommandDataMastermode</b> or
936  * <b>DSPI_HAL_WriteCommandDataMastermodeBlocking</b> to write the entire 32-bit command data word to the PUSHR. This
937  * helps improve performance in cases where the command structure is constant. For example, the user calls this function
938  * before starting a transfer to generate the command word. When they are ready to transmit the data, they OR
939  * this formatted command word with the desired data to transmit. This process increases transmit performance when
940  * compared to calling send functions, such as <b>DSPI_HAL_WriteDataMastermode</b>,  which format the command word each
941  * time a data word is to be sent.
942  *
943  * @param command Pointer to the command structure.
944  * @return The command word formatted to the PUSHR data register bit field.
945  */
DSPI_MasterGetFormattedCommand(dspi_command_data_config_t * command)946 static inline uint32_t DSPI_MasterGetFormattedCommand(dspi_command_data_config_t *command)
947 {
948     /* Format the 16-bit command word according to the PUSHR data register bit field*/
949     return (uint32_t)(SPI_PUSHR_CONT(command->isPcsContinuous) | SPI_PUSHR_CTAS(command->whichCtar) |
950                       SPI_PUSHR_PCS(command->whichPcs) | SPI_PUSHR_EOQ(command->isEndOfQueue) |
951                       SPI_PUSHR_CTCNT(command->clearTransferCount));
952 }
953 
954 /*!
955  * @brief Writes a 32-bit data word (16-bit command appended with 16-bit data) into the data
956  *        buffer master mode and waits till complete to return.
957  *
958  * In this function, the user must append the 16-bit data to the 16-bit command information and then provide the total
959  * 32-bit word
960  * as the data to send.
961  * The command portion provides characteristics of the data, such as the optional continuous chip select operation
962  * between transfers, the desired Clock and Transfer Attributes register to use for the associated SPI frame, the
963  * desired PCS
964  * signal to use for the data transfer, whether the current transfer is the last in the queue, and whether to clear the
965  * transfer count (normally needed when sending the first frame of a data packet). The user is responsible for
966  * appending this command with the data to send. This is an example:
967  * @code
968  *  dataWord = <16-bit command> | <16-bit data>;
969  *  DSPI_MasterWriteCommandDataBlocking(base, dataWord);
970  * @endcode
971  *
972  * @note This function does not return until after the transmit is complete. Also note that the DSPI must be
973  * enabled and running to transmit data (MCR[MDIS] & [HALT] = 0).
974  * Because the SPI is a synchronous protocol, the received data is available when the transmit completes.
975  *
976  *  For a blocking polling transfer, see methods below.
977  *    <table>
978  *    <tr><th>Option 1
979  *    <tr><td>uint32_t command_to_send = DSPI_MasterGetFormattedCommand(&command);
980  *    <tr><td>uint32_t data0 = command_to_send | data_need_to_send_0;
981  *    <tr><td>uint32_t data1 = command_to_send | data_need_to_send_1;
982  *    <tr><td>uint32_t data2 = command_to_send | data_need_to_send_2;
983  *    <tr><td>
984  *    <tr><td>DSPI_MasterWriteCommandDataBlocking(base,data0);
985  *    <tr><td>DSPI_MasterWriteCommandDataBlocking(base,data1);
986  *    <tr><td>DSPI_MasterWriteCommandDataBlocking(base,data2);
987  *    </table>
988  *
989  *    <table>
990  *    <tr><th>Option 2
991  *    <tr><td>DSPI_MasterWriteDataBlocking(base,&command,data_need_to_send_0);
992  *    <tr><td>DSPI_MasterWriteDataBlocking(base,&command,data_need_to_send_1);
993  *    <tr><td>DSPI_MasterWriteDataBlocking(base,&command,data_need_to_send_2);
994  *    </table>
995  *
996  * @param base DSPI peripheral address.
997  * @param data The data word (command and data combined) to be sent.
998  */
999 void DSPI_MasterWriteCommandDataBlocking(SPI_Type *base, uint32_t data);
1000 
1001 /*!
1002  * @brief Writes data into the data buffer in slave mode.
1003  *
1004  * In slave mode, up to 16-bit words may be written.
1005  *
1006  * @param base DSPI peripheral address.
1007  * @param data The data to send.
1008  */
DSPI_SlaveWriteData(SPI_Type * base,uint32_t data)1009 static inline void DSPI_SlaveWriteData(SPI_Type *base, uint32_t data)
1010 {
1011     base->PUSHR_SLAVE = data;
1012 }
1013 
1014 /*!
1015  * @brief Writes data into the data buffer in slave mode, waits till data was transmitted, and returns.
1016  *
1017  * In slave mode, up to 16-bit words may be written. The function first clears the transmit complete flag, writes data
1018  * into data register, and finally waits until the data is transmitted.
1019  *
1020  * @param base DSPI peripheral address.
1021  * @param data The data to send.
1022  */
1023 void DSPI_SlaveWriteDataBlocking(SPI_Type *base, uint32_t data);
1024 
1025 /*!
1026  * @brief Reads data from the data buffer.
1027  *
1028  * @param base DSPI peripheral address.
1029  * @return The data from the read data buffer.
1030  */
DSPI_ReadData(SPI_Type * base)1031 static inline uint32_t DSPI_ReadData(SPI_Type *base)
1032 {
1033     return (base->POPR);
1034 }
1035 
1036 /*!
1037  * @brief Set up the dummy data.
1038  *
1039  * @param base DSPI peripheral address.
1040  * @param dummyData Data to be transferred when tx buffer is NULL.
1041  */
1042 void DSPI_SetDummyData(SPI_Type *base, uint8_t dummyData);
1043 
1044 /*!
1045  *@}
1046  */
1047 
1048 /*!
1049  * @name Transactional APIs
1050  * @{
1051  */
1052 
1053 /*!
1054  * @brief Initializes the DSPI master handle.
1055  *
1056  * This function initializes the DSPI handle, which can be used for other DSPI transactional APIs.  Usually, for a
1057  * specified DSPI instance,  call this API once to get the initialized handle.
1058  *
1059  * @param base DSPI peripheral base address.
1060  * @param handle DSPI handle pointer to @ref _dspi_master_handle.
1061  * @param callback DSPI callback.
1062  * @param userData Callback function parameter.
1063  */
1064 void DSPI_MasterTransferCreateHandle(SPI_Type *base,
1065                                      dspi_master_handle_t *handle,
1066                                      dspi_master_transfer_callback_t callback,
1067                                      void *userData);
1068 
1069 /*!
1070  * @brief DSPI master transfer data using polling.
1071  *
1072  * This function transfers data using polling. This is a blocking function, which does not return until all transfers
1073  * have been completed.
1074  *
1075  * @param base DSPI peripheral base address.
1076  * @param transfer Pointer to the @ref dspi_transfer_t structure.
1077  * @return status of status_t.
1078  */
1079 status_t DSPI_MasterTransferBlocking(SPI_Type *base, dspi_transfer_t *transfer);
1080 
1081 /*!
1082  * @brief DSPI master transfer data using interrupts.
1083  *
1084  * This function transfers data using interrupts. This is a non-blocking function, which returns right away. When all
1085  * data is transferred, the callback function is called.
1086 
1087  * @param base DSPI peripheral base address.
1088  * @param handle Pointer to the @ref _dspi_master_handle structure which stores the transfer state.
1089  * @param transfer Pointer to the @ref dspi_transfer_t structure.
1090  * @return status of status_t.
1091  */
1092 status_t DSPI_MasterTransferNonBlocking(SPI_Type *base, dspi_master_handle_t *handle, dspi_transfer_t *transfer);
1093 
1094 /*!
1095  * @brief Transfers a block of data using a polling method.
1096  *
1097  * This function will do a half-duplex transfer for DSPI master, This is a blocking function,
1098  * which does not retuen until all transfer have been completed. And data transfer will be half-duplex,
1099  * users can set transmit first or receive first.
1100  *
1101  * @param base DSPI base pointer
1102  * @param xfer pointer to @ref dspi_half_duplex_transfer_t structure
1103  * @return status of status_t.
1104  */
1105 status_t DSPI_MasterHalfDuplexTransferBlocking(SPI_Type *base, dspi_half_duplex_transfer_t *xfer);
1106 
1107 /*!
1108  * @brief Performs a non-blocking DSPI interrupt transfer.
1109  *
1110  * This function transfers data using interrupts, the transfer mechanism is half-duplex. This is a non-blocking
1111  * function,
1112  * which returns right away. When all data is transferred, the callback function is called.
1113  *
1114  * @param base DSPI peripheral base address.
1115  * @param handle pointer to @ref _dspi_master_handle structure which stores the transfer state
1116  * @param xfer pointer to @ref dspi_half_duplex_transfer_t structure
1117  * @return status of status_t.
1118  */
1119 status_t DSPI_MasterHalfDuplexTransferNonBlocking(SPI_Type *base,
1120                                                   dspi_master_handle_t *handle,
1121                                                   dspi_half_duplex_transfer_t *xfer);
1122 
1123 /*!
1124  * @brief Gets the master transfer count.
1125  *
1126  * This function gets the master transfer count.
1127  *
1128  * @param base DSPI peripheral base address.
1129  * @param handle Pointer to the @ref _dspi_master_handle structure which stores the transfer state.
1130  * @param count The number of bytes transferred by using the non-blocking transaction.
1131  * @return status of status_t.
1132  */
1133 status_t DSPI_MasterTransferGetCount(SPI_Type *base, dspi_master_handle_t *handle, size_t *count);
1134 
1135 /*!
1136  * @brief DSPI master aborts a transfer using an interrupt.
1137  *
1138  * This function aborts a transfer using an interrupt.
1139  *
1140  * @param base DSPI peripheral base address.
1141  * @param handle Pointer to the @ref _dspi_master_handle structure which stores the transfer state.
1142  */
1143 void DSPI_MasterTransferAbort(SPI_Type *base, dspi_master_handle_t *handle);
1144 
1145 /*!
1146  * @brief DSPI Master IRQ handler function.
1147  *
1148  * This function processes the DSPI transmit and receive IRQ.
1149 
1150  * @param base DSPI peripheral base address.
1151  * @param handle Pointer to the @ref _dspi_master_handle structure which stores the transfer state.
1152  */
1153 void DSPI_MasterTransferHandleIRQ(SPI_Type *base, dspi_master_handle_t *handle);
1154 
1155 /*!
1156  * @brief Initializes the DSPI slave handle.
1157  *
1158  * This function initializes the DSPI handle, which can be used for other DSPI transactional APIs.  Usually, for a
1159  * specified DSPI instance, call this API once to get the initialized handle.
1160  *
1161  * @param handle DSPI handle pointer to the @ref _dspi_slave_handle.
1162  * @param base DSPI peripheral base address.
1163  * @param callback DSPI callback.
1164  * @param userData Callback function parameter.
1165  */
1166 void DSPI_SlaveTransferCreateHandle(SPI_Type *base,
1167                                     dspi_slave_handle_t *handle,
1168                                     dspi_slave_transfer_callback_t callback,
1169                                     void *userData);
1170 
1171 /*!
1172  * @brief DSPI slave transfers data using an interrupt.
1173  *
1174  * This function transfers data using an interrupt. This is a non-blocking function, which returns right away. When all
1175  * data is transferred, the callback function is called.
1176  *
1177  * @param base DSPI peripheral base address.
1178  * @param handle Pointer to the @ref _dspi_slave_handle structure which stores the transfer state.
1179  * @param transfer Pointer to the @ref dspi_transfer_t structure.
1180  * @return status of status_t.
1181  */
1182 status_t DSPI_SlaveTransferNonBlocking(SPI_Type *base, dspi_slave_handle_t *handle, dspi_transfer_t *transfer);
1183 
1184 /*!
1185  * @brief Gets the slave transfer count.
1186  *
1187  * This function gets the slave transfer count.
1188  *
1189  * @param base DSPI peripheral base address.
1190  * @param handle Pointer to the @ref _dspi_master_handle structure which stores the transfer state.
1191  * @param count The number of bytes transferred by using the non-blocking transaction.
1192  * @return status of status_t.
1193  */
1194 status_t DSPI_SlaveTransferGetCount(SPI_Type *base, dspi_slave_handle_t *handle, size_t *count);
1195 
1196 /*!
1197  * @brief DSPI slave aborts a transfer using an interrupt.
1198  *
1199  * This function aborts a transfer using an interrupt.
1200  *
1201  * @param base DSPI peripheral base address.
1202  * @param handle Pointer to the @ref _dspi_slave_handle structure which stores the transfer state.
1203  */
1204 void DSPI_SlaveTransferAbort(SPI_Type *base, dspi_slave_handle_t *handle);
1205 
1206 /*!
1207  * @brief DSPI Master IRQ handler function.
1208  *
1209  * This function processes the DSPI transmit and receive IRQ.
1210  *
1211  * @param base DSPI peripheral base address.
1212  * @param handle Pointer to the @ref _dspi_slave_handle structure which stores the transfer state.
1213  */
1214 void DSPI_SlaveTransferHandleIRQ(SPI_Type *base, dspi_slave_handle_t *handle);
1215 
1216 /*!
1217  * brief Dummy data for each instance.
1218  *
1219  * The purpose of this API is to avoid MISRA rule8.5 : Multiple declarations of
1220  * externally-linked object or function @ref g_dspiDummyData.
1221  *
1222  * param base DSPI peripheral base address.
1223  */
1224 uint8_t DSPI_GetDummyDataInstance(SPI_Type *base);
1225 
1226 /*!
1227  *@}
1228  */
1229 
1230 #if defined(__cplusplus)
1231 }
1232 #endif /*_cplusplus*/
1233 /*!
1234  *@}
1235  */
1236 
1237 #endif /*FSL_DSPI_H_*/
1238