1 /*
2 * Copyright (c) 2015, Freescale Semiconductor, Inc.
3 * Copyright 2016-2019 NXP
4 * All rights reserved.
5 *
6 * SPDX-License-Identifier: BSD-3-Clause
7 */
8
9 #include "fsl_dspi.h"
10
11 /*******************************************************************************
12 * Definitions
13 ******************************************************************************/
14
15 /* Component ID definition, used by tools. */
16 #ifndef FSL_COMPONENT_ID
17 #define FSL_COMPONENT_ID "platform.drivers.dspi"
18 #endif
19
20 /*! @brief Typedef for master interrupt handler. */
21 typedef void (*dspi_master_isr_t)(SPI_Type *base, dspi_master_handle_t *handle);
22
23 #if !(defined(FSL_FEATURE_DSPI_HAS_NO_SLAVE_SUPPORT) && FSL_FEATURE_DSPI_HAS_NO_SLAVE_SUPPORT)
24 /*! @brief Typedef for slave interrupt handler. */
25 typedef void (*dspi_slave_isr_t)(SPI_Type *base, dspi_slave_handle_t *handle);
26 #endif
27
28 /*******************************************************************************
29 * Prototypes
30 ******************************************************************************/
31 /*!
32 * @brief Configures the DSPI peripheral chip select polarity.
33 *
34 * This function takes in the desired peripheral chip select (Pcs) and it's corresponding desired polarity and
35 * configures the Pcs signal to operate with the desired characteristic.
36 *
37 * @param base DSPI peripheral address.
38 * @param pcs The particular peripheral chip select (parameter value is of type dspi_which_pcs_t) for which we wish to
39 * apply the active high or active low characteristic.
40 * @param activeLowOrHigh The setting for either "active high, inactive low (0)" or "active low, inactive high(1)" of
41 * type dspi_pcs_polarity_config_t.
42 */
43 static void DSPI_SetOnePcsPolarity(SPI_Type *base, dspi_which_pcs_t pcs, dspi_pcs_polarity_config_t activeLowOrHigh);
44
45 /*!
46 * @brief Master fill up the TX FIFO with data.
47 * This is not a public API.
48 */
49 static void DSPI_MasterTransferFillUpTxFifo(SPI_Type *base, dspi_master_handle_t *handle);
50
51 /*!
52 * @brief Master finish up a transfer.
53 * It would call back if there is callback function and set the state to idle.
54 * This is not a public API.
55 */
56 static void DSPI_MasterTransferComplete(SPI_Type *base, dspi_master_handle_t *handle);
57
58 #if !(defined(FSL_FEATURE_DSPI_HAS_NO_SLAVE_SUPPORT) && FSL_FEATURE_DSPI_HAS_NO_SLAVE_SUPPORT)
59 /*!
60 * @brief Slave fill up the TX FIFO with data.
61 * This is not a public API.
62 */
63 static void DSPI_SlaveTransferFillUpTxFifo(SPI_Type *base, dspi_slave_handle_t *handle);
64 #endif
65
66 #if !(defined(FSL_FEATURE_DSPI_HAS_NO_SLAVE_SUPPORT) && FSL_FEATURE_DSPI_HAS_NO_SLAVE_SUPPORT)
67 /*!
68 * @brief Slave finish up a transfer.
69 * It would call back if there is callback function and set the state to idle.
70 * This is not a public API.
71 */
72 static void DSPI_SlaveTransferComplete(SPI_Type *base, dspi_slave_handle_t *handle);
73 #endif
74
75 /*!
76 * @brief DSPI common interrupt handler.
77 *
78 * @param base DSPI peripheral address.
79 * @param handle pointer to g_dspiHandle which stores the transfer state.
80 */
81 static void DSPI_CommonIRQHandler(SPI_Type *base, void *param);
82
83 /*!
84 * @brief Master prepare the transfer.
85 * Basically it set up dspi_master_handle .
86 * This is not a public API.
87 */
88 static void DSPI_MasterTransferPrepare(SPI_Type *base, dspi_master_handle_t *handle, dspi_transfer_t *transfer);
89
90 /*******************************************************************************
91 * Variables
92 ******************************************************************************/
93
94 /* Defines constant value arrays for the baud rate pre-scalar and scalar divider values.*/
95 static const uint32_t s_baudratePrescaler[] = {2, 3, 5, 7};
96 static const uint32_t s_baudrateScaler[] = {2, 4, 6, 8, 16, 32, 64, 128,
97 256, 512, 1024, 2048, 4096, 8192, 16384, 32768};
98
99 static const uint32_t s_delayPrescaler[] = {1, 3, 5, 7};
100 static const uint32_t s_delayScaler[] = {2, 4, 8, 16, 32, 64, 128, 256,
101 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536};
102
103 /*! @brief Pointers to dspi bases for each instance. */
104 static SPI_Type *const s_dspiBases[] = SPI_BASE_PTRS;
105
106 /*! @brief Pointers to dspi IRQ number for each instance. */
107 static IRQn_Type const s_dspiIRQ[] = SPI_IRQS;
108
109 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
110 /*! @brief Pointers to dspi clocks for each instance. */
111 static clock_ip_name_t const s_dspiClock[] = DSPI_CLOCKS;
112 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
113
114 /*! @brief Pointers to dspi handles for each instance. */
115 static void *g_dspiHandle[ARRAY_SIZE(s_dspiBases)];
116
117 /*! @brief Pointer to master IRQ handler for each instance. */
118 static dspi_master_isr_t s_dspiMasterIsr;
119
120 #if !(defined(FSL_FEATURE_DSPI_HAS_NO_SLAVE_SUPPORT) && FSL_FEATURE_DSPI_HAS_NO_SLAVE_SUPPORT)
121 /*! @brief Pointer to slave IRQ handler for each instance. */
122 static dspi_slave_isr_t s_dspiSlaveIsr;
123 #endif
124
125 /* @brief Dummy data for each instance. This data is used when user's tx buffer is NULL*/
126 volatile uint8_t g_dspiDummyData[ARRAY_SIZE(s_dspiBases)] = {0};
127 /**********************************************************************************************************************
128 * Code
129 *********************************************************************************************************************/
130 /*!
131 * brief Get instance number for DSPI module.
132 *
133 * param base DSPI peripheral base address.
134 */
DSPI_GetInstance(SPI_Type * base)135 uint32_t DSPI_GetInstance(SPI_Type *base)
136 {
137 uint32_t instance;
138
139 /* Find the instance index from base address mappings. */
140 for (instance = 0; instance < ARRAY_SIZE(s_dspiBases); instance++)
141 {
142 if (s_dspiBases[instance] == base)
143 {
144 break;
145 }
146 }
147
148 assert(instance < ARRAY_SIZE(s_dspiBases));
149
150 return instance;
151 }
152
153 /*!
154 * brief Dummy data for each instance.
155 *
156 * The purpose of this API is to avoid MISRA rule8.5 : Multiple declarations of
157 * externally-linked object or function g_dspiDummyData.
158 *
159 * param base DSPI peripheral base address.
160 */
DSPI_GetDummyDataInstance(SPI_Type * base)161 uint8_t DSPI_GetDummyDataInstance(SPI_Type *base)
162 {
163 uint8_t instance = g_dspiDummyData[DSPI_GetInstance(base)];
164
165 return instance;
166 }
167
168 /*!
169 * brief Set up the dummy data.
170 *
171 * param base DSPI peripheral address.
172 * param dummyData Data to be transferred when tx buffer is NULL.
173 */
DSPI_SetDummyData(SPI_Type * base,uint8_t dummyData)174 void DSPI_SetDummyData(SPI_Type *base, uint8_t dummyData)
175 {
176 uint32_t instance = DSPI_GetInstance(base);
177 g_dspiDummyData[instance] = dummyData;
178 }
179
180 /*!
181 * brief Initializes the DSPI master.
182 *
183 * This function initializes the DSPI master configuration. This is an example use case.
184 * code
185 * dspi_master_config_t masterConfig;
186 * masterConfig.whichCtar = kDSPI_Ctar0;
187 * masterConfig.ctarConfig.baudRate = 500000000U;
188 * masterConfig.ctarConfig.bitsPerFrame = 8;
189 * masterConfig.ctarConfig.cpol = kDSPI_ClockPolarityActiveHigh;
190 * masterConfig.ctarConfig.cpha = kDSPI_ClockPhaseFirstEdge;
191 * masterConfig.ctarConfig.direction = kDSPI_MsbFirst;
192 * masterConfig.ctarConfig.pcsToSckDelayInNanoSec = 1000000000U / masterConfig.ctarConfig.baudRate ;
193 * masterConfig.ctarConfig.lastSckToPcsDelayInNanoSec = 1000000000U / masterConfig.ctarConfig.baudRate ;
194 * masterConfig.ctarConfig.betweenTransferDelayInNanoSec = 1000000000U / masterConfig.ctarConfig.baudRate ;
195 * masterConfig.whichPcs = kDSPI_Pcs0;
196 * masterConfig.pcsActiveHighOrLow = kDSPI_PcsActiveLow;
197 * masterConfig.enableContinuousSCK = false;
198 * masterConfig.enableRxFifoOverWrite = false;
199 * masterConfig.enableModifiedTimingFormat = false;
200 * masterConfig.samplePoint = kDSPI_SckToSin0Clock;
201 * DSPI_MasterInit(base, &masterConfig, srcClock_Hz);
202 * endcode
203 *
204 * param base DSPI peripheral address.
205 * param masterConfig Pointer to the structure dspi_master_config_t.
206 * param srcClock_Hz Module source input clock in Hertz.
207 */
DSPI_MasterInit(SPI_Type * base,const dspi_master_config_t * masterConfig,uint32_t srcClock_Hz)208 void DSPI_MasterInit(SPI_Type *base, const dspi_master_config_t *masterConfig, uint32_t srcClock_Hz)
209 {
210 assert(NULL != masterConfig);
211
212 uint32_t temp;
213 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
214 /* enable DSPI clock */
215 CLOCK_EnableClock(s_dspiClock[DSPI_GetInstance(base)]);
216 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
217
218 DSPI_Enable(base, true);
219 DSPI_StopTransfer(base);
220
221 DSPI_SetOnePcsPolarity(base, masterConfig->whichPcs, masterConfig->pcsActiveHighOrLow);
222 DSPI_SetMasterSlaveMode(base, kDSPI_Master);
223
224 temp = base->MCR & (~(SPI_MCR_CONT_SCKE_MASK | SPI_MCR_MTFE_MASK | SPI_MCR_ROOE_MASK | SPI_MCR_SMPL_PT_MASK |
225 SPI_MCR_DIS_TXF_MASK | SPI_MCR_DIS_RXF_MASK));
226
227 base->MCR = temp | SPI_MCR_CONT_SCKE(masterConfig->enableContinuousSCK) |
228 SPI_MCR_MTFE(masterConfig->enableModifiedTimingFormat) |
229 SPI_MCR_ROOE(masterConfig->enableRxFifoOverWrite) | SPI_MCR_SMPL_PT(masterConfig->samplePoint) |
230 SPI_MCR_DIS_TXF(0U) | SPI_MCR_DIS_RXF(0U);
231
232 if (0U == DSPI_MasterSetBaudRate(base, masterConfig->whichCtar, masterConfig->ctarConfig.baudRate, srcClock_Hz))
233 {
234 assert(false);
235 }
236
237 temp = base->CTAR[masterConfig->whichCtar] &
238 ~(SPI_CTAR_FMSZ_MASK | SPI_CTAR_CPOL_MASK | SPI_CTAR_CPHA_MASK | SPI_CTAR_LSBFE_MASK);
239
240 base->CTAR[masterConfig->whichCtar] = temp | SPI_CTAR_FMSZ(masterConfig->ctarConfig.bitsPerFrame - 1U) |
241 SPI_CTAR_CPOL(masterConfig->ctarConfig.cpol) |
242 SPI_CTAR_CPHA(masterConfig->ctarConfig.cpha) |
243 SPI_CTAR_LSBFE(masterConfig->ctarConfig.direction);
244
245 (void)DSPI_MasterSetDelayTimes(base, masterConfig->whichCtar, kDSPI_PcsToSck, srcClock_Hz,
246 masterConfig->ctarConfig.pcsToSckDelayInNanoSec);
247 (void)DSPI_MasterSetDelayTimes(base, masterConfig->whichCtar, kDSPI_LastSckToPcs, srcClock_Hz,
248 masterConfig->ctarConfig.lastSckToPcsDelayInNanoSec);
249 (void)DSPI_MasterSetDelayTimes(base, masterConfig->whichCtar, kDSPI_BetweenTransfer, srcClock_Hz,
250 masterConfig->ctarConfig.betweenTransferDelayInNanoSec);
251
252 DSPI_SetDummyData(base, DSPI_DUMMY_DATA);
253 DSPI_StartTransfer(base);
254 }
255
256 /*!
257 * brief Sets the dspi_master_config_t structure to default values.
258 *
259 * The purpose of this API is to get the configuration structure initialized for the DSPI_MasterInit().
260 * Users may use the initialized structure unchanged in the DSPI_MasterInit() or modify the structure
261 * before calling the DSPI_MasterInit().
262 * Example:
263 * code
264 * dspi_master_config_t masterConfig;
265 * DSPI_MasterGetDefaultConfig(&masterConfig);
266 * endcode
267 * param masterConfig pointer to dspi_master_config_t structure
268 */
DSPI_MasterGetDefaultConfig(dspi_master_config_t * masterConfig)269 void DSPI_MasterGetDefaultConfig(dspi_master_config_t *masterConfig)
270 {
271 assert(NULL != masterConfig);
272
273 /* Initializes the configure structure to zero. */
274 (void)memset(masterConfig, 0, sizeof(*masterConfig));
275
276 masterConfig->whichCtar = kDSPI_Ctar0;
277 masterConfig->ctarConfig.baudRate = 500000;
278 masterConfig->ctarConfig.bitsPerFrame = 8;
279 masterConfig->ctarConfig.cpol = kDSPI_ClockPolarityActiveHigh;
280 masterConfig->ctarConfig.cpha = kDSPI_ClockPhaseFirstEdge;
281 masterConfig->ctarConfig.direction = kDSPI_MsbFirst;
282
283 masterConfig->ctarConfig.pcsToSckDelayInNanoSec = 1000;
284 masterConfig->ctarConfig.lastSckToPcsDelayInNanoSec = 1000;
285 masterConfig->ctarConfig.betweenTransferDelayInNanoSec = 1000;
286
287 masterConfig->whichPcs = kDSPI_Pcs0;
288 masterConfig->pcsActiveHighOrLow = kDSPI_PcsActiveLow;
289
290 masterConfig->enableContinuousSCK = false;
291 masterConfig->enableRxFifoOverWrite = false;
292 masterConfig->enableModifiedTimingFormat = false;
293 masterConfig->samplePoint = kDSPI_SckToSin0Clock;
294 }
295
296 #if !(defined(FSL_FEATURE_DSPI_HAS_NO_SLAVE_SUPPORT) && FSL_FEATURE_DSPI_HAS_NO_SLAVE_SUPPORT)
297 /*!
298 * brief DSPI slave configuration.
299 *
300 * This function initializes the DSPI slave configuration. This is an example use case.
301 * code
302 * dspi_slave_config_t slaveConfig;
303 * slaveConfig->whichCtar = kDSPI_Ctar0;
304 * slaveConfig->ctarConfig.bitsPerFrame = 8;
305 * slaveConfig->ctarConfig.cpol = kDSPI_ClockPolarityActiveHigh;
306 * slaveConfig->ctarConfig.cpha = kDSPI_ClockPhaseFirstEdge;
307 * slaveConfig->enableContinuousSCK = false;
308 * slaveConfig->enableRxFifoOverWrite = false;
309 * slaveConfig->enableModifiedTimingFormat = false;
310 * slaveConfig->samplePoint = kDSPI_SckToSin0Clock;
311 * DSPI_SlaveInit(base, &slaveConfig);
312 * endcode
313 *
314 * param base DSPI peripheral address.
315 * param slaveConfig Pointer to the structure dspi_master_config_t.
316 */
DSPI_SlaveInit(SPI_Type * base,const dspi_slave_config_t * slaveConfig)317 void DSPI_SlaveInit(SPI_Type *base, const dspi_slave_config_t *slaveConfig)
318 {
319 assert(NULL != slaveConfig);
320
321 uint32_t temp = 0;
322
323 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
324 /* enable DSPI clock */
325 CLOCK_EnableClock(s_dspiClock[DSPI_GetInstance(base)]);
326 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
327
328 DSPI_Enable(base, true);
329 DSPI_StopTransfer(base);
330
331 DSPI_SetMasterSlaveMode(base, kDSPI_Slave);
332
333 temp = base->MCR & (~(SPI_MCR_CONT_SCKE_MASK | SPI_MCR_MTFE_MASK | SPI_MCR_ROOE_MASK | SPI_MCR_SMPL_PT_MASK |
334 SPI_MCR_DIS_TXF_MASK | SPI_MCR_DIS_RXF_MASK));
335
336 base->MCR = temp | SPI_MCR_CONT_SCKE(slaveConfig->enableContinuousSCK) |
337 SPI_MCR_MTFE(slaveConfig->enableModifiedTimingFormat) |
338 SPI_MCR_ROOE(slaveConfig->enableRxFifoOverWrite) | SPI_MCR_SMPL_PT(slaveConfig->samplePoint) |
339 SPI_MCR_DIS_TXF(0U) | SPI_MCR_DIS_RXF(0U);
340
341 DSPI_SetOnePcsPolarity(base, kDSPI_Pcs0, kDSPI_PcsActiveLow);
342
343 temp = base->CTAR[slaveConfig->whichCtar] &
344 ~(SPI_CTAR_FMSZ_MASK | SPI_CTAR_CPOL_MASK | SPI_CTAR_CPHA_MASK | SPI_CTAR_LSBFE_MASK);
345
346 base->CTAR[slaveConfig->whichCtar] = temp | SPI_CTAR_SLAVE_FMSZ(slaveConfig->ctarConfig.bitsPerFrame - 1U) |
347 SPI_CTAR_SLAVE_CPOL(slaveConfig->ctarConfig.cpol) |
348 SPI_CTAR_SLAVE_CPHA(slaveConfig->ctarConfig.cpha);
349
350 DSPI_SetDummyData(base, DSPI_DUMMY_DATA);
351
352 DSPI_StartTransfer(base);
353 }
354 #endif
355
356 #if !(defined(FSL_FEATURE_DSPI_HAS_NO_SLAVE_SUPPORT) && FSL_FEATURE_DSPI_HAS_NO_SLAVE_SUPPORT)
357 /*!
358 * brief Sets the dspi_slave_config_t structure to a default value.
359 *
360 * The purpose of this API is to get the configuration structure initialized for the DSPI_SlaveInit().
361 * Users may use the initialized structure unchanged in the DSPI_SlaveInit() or modify the structure
362 * before calling the DSPI_SlaveInit().
363 * This is an example.
364 * code
365 * dspi_slave_config_t slaveConfig;
366 * DSPI_SlaveGetDefaultConfig(&slaveConfig);
367 * endcode
368 * param slaveConfig Pointer to the dspi_slave_config_t structure.
369 */
DSPI_SlaveGetDefaultConfig(dspi_slave_config_t * slaveConfig)370 void DSPI_SlaveGetDefaultConfig(dspi_slave_config_t *slaveConfig)
371 {
372 assert(NULL != slaveConfig);
373
374 /* Initializes the configure structure to zero. */
375 (void)memset(slaveConfig, 0, sizeof(*slaveConfig));
376
377 slaveConfig->whichCtar = kDSPI_Ctar0;
378 slaveConfig->ctarConfig.bitsPerFrame = 8;
379 slaveConfig->ctarConfig.cpol = kDSPI_ClockPolarityActiveHigh;
380 slaveConfig->ctarConfig.cpha = kDSPI_ClockPhaseFirstEdge;
381
382 slaveConfig->enableContinuousSCK = false;
383 slaveConfig->enableRxFifoOverWrite = false;
384 slaveConfig->enableModifiedTimingFormat = false;
385 slaveConfig->samplePoint = kDSPI_SckToSin0Clock;
386 }
387 #endif
388
389 /*!
390 * brief De-initializes the DSPI peripheral. Call this API to disable the DSPI clock.
391 * param base DSPI peripheral address.
392 */
DSPI_Deinit(SPI_Type * base)393 void DSPI_Deinit(SPI_Type *base)
394 {
395 DSPI_StopTransfer(base);
396 DSPI_Enable(base, false);
397
398 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
399 /* disable DSPI clock */
400 CLOCK_DisableClock(s_dspiClock[DSPI_GetInstance(base)]);
401 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
402 }
403
DSPI_SetOnePcsPolarity(SPI_Type * base,dspi_which_pcs_t pcs,dspi_pcs_polarity_config_t activeLowOrHigh)404 static void DSPI_SetOnePcsPolarity(SPI_Type *base, dspi_which_pcs_t pcs, dspi_pcs_polarity_config_t activeLowOrHigh)
405 {
406 uint32_t temp;
407
408 temp = base->MCR;
409
410 if (activeLowOrHigh == kDSPI_PcsActiveLow)
411 {
412 temp |= SPI_MCR_PCSIS(pcs);
413 }
414 else
415 {
416 temp &= ~SPI_MCR_PCSIS(pcs);
417 }
418
419 base->MCR = temp;
420 }
421
422 /*!
423 * brief Sets the DSPI baud rate in bits per second.
424 *
425 * This function takes in the desired baudRate_Bps (baud rate) and calculates the nearest possible baud rate without
426 * exceeding the desired baud rate, and returns the calculated baud rate in bits-per-second. It requires that the
427 * caller also provide the frequency of the module source clock (in Hertz).
428 *
429 * param base DSPI peripheral address.
430 * param whichCtar The desired Clock and Transfer Attributes Register (CTAR) of the type dspi_ctar_selection_t
431 * param baudRate_Bps The desired baud rate in bits per second
432 * param srcClock_Hz Module source input clock in Hertz
433 * return The actual calculated baud rate
434 */
DSPI_MasterSetBaudRate(SPI_Type * base,dspi_ctar_selection_t whichCtar,uint32_t baudRate_Bps,uint32_t srcClock_Hz)435 uint32_t DSPI_MasterSetBaudRate(SPI_Type *base,
436 dspi_ctar_selection_t whichCtar,
437 uint32_t baudRate_Bps,
438 uint32_t srcClock_Hz)
439 {
440 /* for master mode configuration, if slave mode detected, return 0*/
441 if (!DSPI_IsMaster(base))
442 {
443 return 0U;
444 }
445 uint32_t temp;
446 uint32_t prescaler, bestPrescaler;
447 uint32_t scaler, bestScaler;
448 uint32_t dbr, bestDbr;
449 uint32_t realBaudrate, bestBaudrate;
450 uint32_t diff, min_diff;
451 uint32_t baudrate = baudRate_Bps;
452
453 /* find combination of prescaler and scaler resulting in baudrate closest to the requested value */
454 min_diff = 0xFFFFFFFFU;
455 bestPrescaler = 0;
456 bestScaler = 0;
457 bestDbr = 1;
458 bestBaudrate = 0; /* required to avoid compilation warning */
459
460 /* In all for loops, if min_diff = 0, the exit for loop*/
461 for (prescaler = 0U; prescaler < 4U; prescaler++)
462 {
463 for (scaler = 0U; scaler < 16U; scaler++)
464 {
465 for (dbr = 1U; dbr < 3U; dbr++)
466 {
467 realBaudrate = ((srcClock_Hz * dbr) / (s_baudratePrescaler[prescaler] * (s_baudrateScaler[scaler])));
468
469 /* calculate the baud rate difference based on the conditional statement that states that the calculated
470 * baud rate must not exceed the desired baud rate.
471 */
472 if (baudrate >= realBaudrate)
473 {
474 diff = baudrate - realBaudrate;
475 if (min_diff > diff)
476 {
477 /* a better match found */
478 min_diff = diff;
479 bestPrescaler = prescaler;
480 bestScaler = scaler;
481 bestBaudrate = realBaudrate;
482 bestDbr = dbr;
483 }
484 }
485 if (0U == min_diff)
486 {
487 break;
488 }
489 }
490
491 if (0U == min_diff)
492 {
493 break;
494 }
495 }
496 if (0U == min_diff)
497 {
498 break;
499 }
500 }
501
502 /* write the best dbr, prescalar, and baud rate scalar to the CTAR */
503 temp = base->CTAR[whichCtar] & ~(SPI_CTAR_DBR_MASK | SPI_CTAR_PBR_MASK | SPI_CTAR_BR_MASK);
504
505 base->CTAR[whichCtar] = temp | ((bestDbr - 1U) << SPI_CTAR_DBR_SHIFT) | (bestPrescaler << SPI_CTAR_PBR_SHIFT) |
506 (bestScaler << SPI_CTAR_BR_SHIFT);
507
508 /* return the actual calculated baud rate */
509 return bestBaudrate;
510 }
511
512 /*!
513 * brief Manually configures the delay prescaler and scaler for a particular CTAR.
514 *
515 * This function configures the PCS to SCK delay pre-scalar (PcsSCK) and scalar (CSSCK), after SCK delay pre-scalar
516 * (PASC) and scalar (ASC), and the delay after transfer pre-scalar (PDT) and scalar (DT).
517 *
518 * These delay names are available in the type dspi_delay_type_t.
519 *
520 * The user passes the delay to the configuration along with the prescaler and scaler value.
521 * This allows the user to directly set the prescaler/scaler values if pre-calculated or
522 * to manually increment either value.
523 *
524 * param base DSPI peripheral address.
525 * param whichCtar The desired Clock and Transfer Attributes Register (CTAR) of type dspi_ctar_selection_t.
526 * param prescaler The prescaler delay value (can be an integer 0, 1, 2, or 3).
527 * param scaler The scaler delay value (can be any integer between 0 to 15).
528 * param whichDelay The desired delay to configure; must be of type dspi_delay_type_t
529 */
DSPI_MasterSetDelayScaler(SPI_Type * base,dspi_ctar_selection_t whichCtar,uint32_t prescaler,uint32_t scaler,dspi_delay_type_t whichDelay)530 void DSPI_MasterSetDelayScaler(
531 SPI_Type *base, dspi_ctar_selection_t whichCtar, uint32_t prescaler, uint32_t scaler, dspi_delay_type_t whichDelay)
532 {
533 /* these settings are only relevant in master mode */
534 if (DSPI_IsMaster(base))
535 {
536 switch (whichDelay)
537 {
538 case kDSPI_PcsToSck:
539 base->CTAR[whichCtar] = (base->CTAR[whichCtar] & (~SPI_CTAR_PCSSCK_MASK) & (~SPI_CTAR_CSSCK_MASK)) |
540 SPI_CTAR_PCSSCK(prescaler) | SPI_CTAR_CSSCK(scaler);
541 break;
542 case kDSPI_LastSckToPcs:
543 base->CTAR[whichCtar] = (base->CTAR[whichCtar] & (~SPI_CTAR_PASC_MASK) & (~SPI_CTAR_ASC_MASK)) |
544 SPI_CTAR_PASC(prescaler) | SPI_CTAR_ASC(scaler);
545 break;
546 case kDSPI_BetweenTransfer:
547 base->CTAR[whichCtar] = (base->CTAR[whichCtar] & (~SPI_CTAR_PDT_MASK) & (~SPI_CTAR_DT_MASK)) |
548 SPI_CTAR_PDT(prescaler) | SPI_CTAR_DT(scaler);
549 break;
550 default:
551 /* All cases have been listed above, the default clause should not be reached. */
552 assert(false);
553 break;
554 }
555 }
556 }
557
558 /*!
559 * brief Calculates the delay prescaler and scaler based on the desired delay input in nanoseconds.
560 *
561 * This function calculates the values for the following.
562 * PCS to SCK delay pre-scalar (PCSSCK) and scalar (CSSCK), or
563 * After SCK delay pre-scalar (PASC) and scalar (ASC), or
564 * Delay after transfer pre-scalar (PDT) and scalar (DT).
565 *
566 * These delay names are available in the type dspi_delay_type_t.
567 *
568 * The user passes which delay to configure along with the desired delay value in nanoseconds. The function
569 * calculates the values needed for the prescaler and scaler. Note that returning the calculated delay as an exact
570 * delay match may not be possible. In this case, the closest match is calculated without going below the desired
571 * delay value input.
572 * It is possible to input a very large delay value that exceeds the capability of the part, in which case the maximum
573 * supported delay is returned. The higher-level peripheral driver alerts the user of an out of range delay
574 * input.
575 *
576 * param base DSPI peripheral address.
577 * param whichCtar The desired Clock and Transfer Attributes Register (CTAR) of type dspi_ctar_selection_t.
578 * param whichDelay The desired delay to configure, must be of type dspi_delay_type_t
579 * param srcClock_Hz Module source input clock in Hertz
580 * param delayTimeInNanoSec The desired delay value in nanoseconds.
581 * return The actual calculated delay value.
582 */
DSPI_MasterSetDelayTimes(SPI_Type * base,dspi_ctar_selection_t whichCtar,dspi_delay_type_t whichDelay,uint32_t srcClock_Hz,uint32_t delayTimeInNanoSec)583 uint32_t DSPI_MasterSetDelayTimes(SPI_Type *base,
584 dspi_ctar_selection_t whichCtar,
585 dspi_delay_type_t whichDelay,
586 uint32_t srcClock_Hz,
587 uint32_t delayTimeInNanoSec)
588 {
589 /* for master mode configuration, if slave mode detected, return 0 */
590 if (!DSPI_IsMaster(base))
591 {
592 return 0U;
593 }
594
595 uint32_t prescaler, bestPrescaler;
596 uint32_t scaler, bestScaler;
597 uint32_t realDelay, bestDelay;
598 uint32_t diff, min_diff;
599 uint32_t initialDelayNanoSec;
600
601 /* find combination of prescaler and scaler resulting in the delay closest to the
602 * requested value
603 */
604 min_diff = 0xFFFFFFFFU;
605 /* Initialize prescaler and scaler to their max values to generate the max delay */
606 bestPrescaler = 0x3;
607 bestScaler = 0xF;
608 bestDelay = (((1000000000U * 4U) / srcClock_Hz) * s_delayPrescaler[bestPrescaler] * s_delayScaler[bestScaler]) / 4U;
609
610 /* First calculate the initial, default delay */
611 initialDelayNanoSec = 1000000000U / srcClock_Hz * 2U;
612
613 /* If the initial, default delay is already greater than the desired delay, then
614 * set the delays to their initial value (0) and return the delay. In other words,
615 * there is no way to decrease the delay value further.
616 */
617 if (initialDelayNanoSec >= delayTimeInNanoSec)
618 {
619 DSPI_MasterSetDelayScaler(base, whichCtar, 0, 0, whichDelay);
620 return initialDelayNanoSec;
621 }
622
623 /* In all for loops, if min_diff = 0, the exit for loop */
624 for (prescaler = 0; prescaler < 4U; prescaler++)
625 {
626 for (scaler = 0; scaler < 16U; scaler++)
627 {
628 realDelay = ((4000000000U / srcClock_Hz) * s_delayPrescaler[prescaler] * s_delayScaler[scaler]) / 4U;
629
630 /* calculate the delay difference based on the conditional statement
631 * that states that the calculated delay must not be less then the desired delay
632 */
633 if (realDelay >= delayTimeInNanoSec)
634 {
635 diff = realDelay - delayTimeInNanoSec;
636 if (min_diff > diff)
637 {
638 /* a better match found */
639 min_diff = diff;
640 bestPrescaler = prescaler;
641 bestScaler = scaler;
642 bestDelay = realDelay;
643 }
644 }
645
646 if (0U == min_diff)
647 {
648 break;
649 }
650 }
651 if (0U == min_diff)
652 {
653 break;
654 }
655 }
656
657 /* write the best dbr, prescalar, and baud rate scalar to the CTAR */
658 DSPI_MasterSetDelayScaler(base, whichCtar, bestPrescaler, bestScaler, whichDelay);
659
660 /* return the actual calculated baud rate */
661 return bestDelay;
662 }
663
664 /*!
665 * brief Sets the dspi_command_data_config_t structure to default values.
666 *
667 * The purpose of this API is to get the configuration structure initialized for use in the DSPI_MasterWrite_xx().
668 * Users may use the initialized structure unchanged in the DSPI_MasterWrite_xx() or modify the structure
669 * before calling the DSPI_MasterWrite_xx().
670 * This is an example.
671 * code
672 * dspi_command_data_config_t command;
673 * DSPI_GetDefaultDataCommandConfig(&command);
674 * endcode
675 * param command Pointer to the dspi_command_data_config_t structure.
676 */
DSPI_GetDefaultDataCommandConfig(dspi_command_data_config_t * command)677 void DSPI_GetDefaultDataCommandConfig(dspi_command_data_config_t *command)
678 {
679 assert(NULL != command);
680
681 /* Initializes the configure structure to zero. */
682 (void)memset(command, 0, sizeof(*command));
683
684 command->isPcsContinuous = false;
685 command->whichCtar = (uint8_t)kDSPI_Ctar0;
686 command->whichPcs = (uint8_t)kDSPI_Pcs0;
687 command->isEndOfQueue = false;
688 command->clearTransferCount = false;
689 }
690
691 /*!
692 * brief Writes data into the data buffer master mode and waits till complete to return.
693 *
694 * In master mode, the 16-bit data is appended to the 16-bit command info. The command portion
695 * provides characteristics of the data, such as the optional continuous chip select
696 * operation between transfers, the desired Clock and Transfer Attributes register to use for the
697 * associated SPI frame, the desired PCS signal to use for the data transfer, whether the current
698 * transfer is the last in the queue, and whether to clear the transfer count (normally needed when
699 * sending the first frame of a data packet). This is an example.
700 * code
701 * dspi_command_config_t commandConfig;
702 * commandConfig.isPcsContinuous = true;
703 * commandConfig.whichCtar = kDSPICtar0;
704 * commandConfig.whichPcs = kDSPIPcs1;
705 * commandConfig.clearTransferCount = false;
706 * commandConfig.isEndOfQueue = false;
707 * DSPI_MasterWriteDataBlocking(base, &commandConfig, dataWord);
708 * endcode
709 *
710 * Note that this function does not return until after the transmit is complete. Also note that the DSPI must be
711 * enabled and running to transmit data (MCR[MDIS] & [HALT] = 0). Because the SPI is a synchronous protocol,
712 * the received data is available when the transmit completes.
713 *
714 * param base DSPI peripheral address.
715 * param command Pointer to the command structure.
716 * param data The data word to be sent.
717 */
DSPI_MasterWriteDataBlocking(SPI_Type * base,dspi_command_data_config_t * command,uint16_t data)718 void DSPI_MasterWriteDataBlocking(SPI_Type *base, dspi_command_data_config_t *command, uint16_t data)
719 {
720 assert(NULL != command);
721
722 /* First, clear Transmit Complete Flag (TCF) */
723 DSPI_ClearStatusFlags(base, (uint32_t)kDSPI_TxCompleteFlag);
724
725 while (0U == (DSPI_GetStatusFlags(base) & (uint32_t)kDSPI_TxFifoFillRequestFlag))
726 {
727 DSPI_ClearStatusFlags(base, (uint32_t)kDSPI_TxFifoFillRequestFlag);
728 }
729
730 base->PUSHR = SPI_PUSHR_CONT(command->isPcsContinuous) | SPI_PUSHR_CTAS(command->whichCtar) |
731 SPI_PUSHR_PCS(command->whichPcs) | SPI_PUSHR_EOQ(command->isEndOfQueue) |
732 SPI_PUSHR_CTCNT(command->clearTransferCount) | SPI_PUSHR_TXDATA(data);
733 DSPI_ClearStatusFlags(base, (uint32_t)kDSPI_TxFifoFillRequestFlag);
734
735 /* Wait till TCF sets */
736 while (0U == (DSPI_GetStatusFlags(base) & (uint32_t)kDSPI_TxCompleteFlag))
737 {
738 }
739 }
740
741 /*!
742 * brief Writes a 32-bit data word (16-bit command appended with 16-bit data) into the data
743 * buffer master mode and waits till complete to return.
744 *
745 * In this function, the user must append the 16-bit data to the 16-bit command information and then provide the total
746 * 32-bit word
747 * as the data to send.
748 * The command portion provides characteristics of the data, such as the optional continuous chip select operation
749 * between transfers, the desired Clock and Transfer Attributes register to use for the associated SPI frame, the
750 * desired PCS
751 * signal to use for the data transfer, whether the current transfer is the last in the queue, and whether to clear the
752 * transfer count (normally needed when sending the first frame of a data packet). The user is responsible for
753 * appending this command with the data to send. This is an example:
754 * code
755 * dataWord = <16-bit command> | <16-bit data>;
756 * DSPI_MasterWriteCommandDataBlocking(base, dataWord);
757 * endcode
758 *
759 * Note that this function does not return until after the transmit is complete. Also note that the DSPI must be
760 * enabled and running to transmit data (MCR[MDIS] & [HALT] = 0).
761 * Because the SPI is a synchronous protocol, the received data is available when the transmit completes.
762 *
763 * For a blocking polling transfer, see methods below.
764 * Option 1:
765 * uint32_t command_to_send = DSPI_MasterGetFormattedCommand(&command);
766 * uint32_t data0 = command_to_send | data_need_to_send_0;
767 * uint32_t data1 = command_to_send | data_need_to_send_1;
768 * uint32_t data2 = command_to_send | data_need_to_send_2;
769 *
770 * DSPI_MasterWriteCommandDataBlocking(base,data0);
771 * DSPI_MasterWriteCommandDataBlocking(base,data1);
772 * DSPI_MasterWriteCommandDataBlocking(base,data2);
773 *
774 * Option 2:
775 * DSPI_MasterWriteDataBlocking(base,&command,data_need_to_send_0);
776 * DSPI_MasterWriteDataBlocking(base,&command,data_need_to_send_1);
777 * DSPI_MasterWriteDataBlocking(base,&command,data_need_to_send_2);
778 *
779 * param base DSPI peripheral address.
780 * param data The data word (command and data combined) to be sent.
781 */
DSPI_MasterWriteCommandDataBlocking(SPI_Type * base,uint32_t data)782 void DSPI_MasterWriteCommandDataBlocking(SPI_Type *base, uint32_t data)
783 {
784 /* First, clear Transmit Complete Flag (TCF) */
785 DSPI_ClearStatusFlags(base, (uint32_t)kDSPI_TxCompleteFlag);
786
787 while (0U == (DSPI_GetStatusFlags(base) & (uint32_t)kDSPI_TxFifoFillRequestFlag))
788 {
789 DSPI_ClearStatusFlags(base, (uint32_t)kDSPI_TxFifoFillRequestFlag);
790 }
791
792 base->PUSHR = data;
793
794 DSPI_ClearStatusFlags(base, (uint32_t)kDSPI_TxFifoFillRequestFlag);
795
796 /* Wait till TCF sets */
797 while (0U == (DSPI_GetStatusFlags(base) & (uint32_t)kDSPI_TxCompleteFlag))
798 {
799 }
800 }
801
802 #if !(defined(FSL_FEATURE_DSPI_HAS_NO_SLAVE_SUPPORT) && FSL_FEATURE_DSPI_HAS_NO_SLAVE_SUPPORT)
803 /*!
804 * brief Writes data into the data buffer in slave mode, waits till data was transmitted, and returns.
805 *
806 * In slave mode, up to 16-bit words may be written. The function first clears the transmit complete flag, writes data
807 * into data register, and finally waits until the data is transmitted.
808 *
809 * param base DSPI peripheral address.
810 * param data The data to send.
811 */
DSPI_SlaveWriteDataBlocking(SPI_Type * base,uint32_t data)812 void DSPI_SlaveWriteDataBlocking(SPI_Type *base, uint32_t data)
813 {
814 /* First, clear Transmit Complete Flag (TCF) */
815 DSPI_ClearStatusFlags(base, (uint32_t)kDSPI_TxCompleteFlag);
816
817 while (0U == (DSPI_GetStatusFlags(base) & (uint32_t)kDSPI_TxFifoFillRequestFlag))
818 {
819 DSPI_ClearStatusFlags(base, (uint32_t)kDSPI_TxFifoFillRequestFlag);
820 }
821
822 base->PUSHR_SLAVE = data;
823
824 DSPI_ClearStatusFlags(base, (uint32_t)kDSPI_TxFifoFillRequestFlag);
825
826 /* Wait till TCF sets */
827 while (0U == (DSPI_GetStatusFlags(base) & (uint32_t)kDSPI_TxCompleteFlag))
828 {
829 }
830 }
831 #endif
832
833 /*!
834 * brief Enables the DSPI interrupts.
835 *
836 * This function configures the various interrupt masks of the DSPI. The parameters are a base and an interrupt mask.
837 * Note, for Tx Fill and Rx FIFO drain requests, enable the interrupt request and disable the DMA request.
838 * Do not use this API(write to RSER register) while DSPI is in running state.
839 *
840 * code
841 * DSPI_EnableInterrupts(base, kDSPI_TxCompleteInterruptEnable | kDSPI_EndOfQueueInterruptEnable );
842 * endcode
843 *
844 * param base DSPI peripheral address.
845 * param mask The interrupt mask; use the enum _dspi_interrupt_enable.
846 */
DSPI_EnableInterrupts(SPI_Type * base,uint32_t mask)847 void DSPI_EnableInterrupts(SPI_Type *base, uint32_t mask)
848 {
849 if (0U != (mask & SPI_RSER_TFFF_RE_MASK))
850 {
851 base->RSER &= ~SPI_RSER_TFFF_DIRS_MASK;
852 }
853 if (0U != (mask & SPI_RSER_RFDF_RE_MASK))
854 {
855 base->RSER &= ~SPI_RSER_RFDF_DIRS_MASK;
856 }
857 base->RSER |= mask;
858 }
859
860 /*Transactional APIs -- Master*/
861
862 /*!
863 * brief Initializes the DSPI master handle.
864 *
865 * This function initializes the DSPI handle, which can be used for other DSPI transactional APIs. Usually, for a
866 * specified DSPI instance, call this API once to get the initialized handle.
867 *
868 * param base DSPI peripheral base address.
869 * param handle DSPI handle pointer to dspi_master_handle_t.
870 * param callback DSPI callback.
871 * param userData Callback function parameter.
872 */
DSPI_MasterTransferCreateHandle(SPI_Type * base,dspi_master_handle_t * handle,dspi_master_transfer_callback_t callback,void * userData)873 void DSPI_MasterTransferCreateHandle(SPI_Type *base,
874 dspi_master_handle_t *handle,
875 dspi_master_transfer_callback_t callback,
876 void *userData)
877 {
878 assert(NULL != handle);
879
880 /* Zero the handle. */
881 (void)memset(handle, 0, sizeof(*handle));
882
883 g_dspiHandle[DSPI_GetInstance(base)] = handle;
884
885 handle->callback = callback;
886 handle->userData = userData;
887 }
888
889 /*!
890 * brief DSPI master transfer data using polling.
891 *
892 * This function transfers data using polling. This is a blocking function, which does not return until all transfers
893 * have been completed.
894 *
895 * param base DSPI peripheral base address.
896 * param transfer Pointer to the dspi_transfer_t structure.
897 * return status of status_t.
898 */
DSPI_MasterTransferBlocking(SPI_Type * base,dspi_transfer_t * transfer)899 status_t DSPI_MasterTransferBlocking(SPI_Type *base, dspi_transfer_t *transfer)
900 {
901 assert(NULL != transfer);
902
903 uint16_t wordToSend = 0;
904 uint16_t wordReceived = 0;
905 uint8_t dummyData = DSPI_GetDummyDataInstance(base);
906 uint8_t bitsPerFrame;
907
908 uint32_t command;
909 uint32_t lastCommand;
910
911 const uint8_t *txData;
912 uint8_t *rxData;
913 uint32_t remainingSendByteCount;
914 uint32_t remainingReceiveByteCount;
915
916 uint32_t fifoSize;
917 uint32_t tmpMCR = 0;
918 dspi_command_data_config_t commandStruct;
919
920 /* If the transfer count is zero, then return immediately.*/
921 if (transfer->dataSize == 0U)
922 {
923 return kStatus_InvalidArgument;
924 }
925
926 DSPI_StopTransfer(base);
927 DSPI_DisableInterrupts(base, (uint32_t)kDSPI_AllInterruptEnable);
928 DSPI_FlushFifo(base, true, true);
929 DSPI_ClearStatusFlags(base, (uint32_t)kDSPI_AllStatusFlag);
930
931 /*Calculate the command and lastCommand*/
932 commandStruct.whichPcs =
933 (uint8_t)((uint32_t)1U << ((transfer->configFlags & DSPI_MASTER_PCS_MASK) >> DSPI_MASTER_PCS_SHIFT));
934 commandStruct.isEndOfQueue = false;
935 commandStruct.clearTransferCount = false;
936 commandStruct.whichCtar = (uint8_t)((transfer->configFlags & DSPI_MASTER_CTAR_MASK) >> DSPI_MASTER_CTAR_SHIFT);
937 commandStruct.isPcsContinuous =
938 (0U != (transfer->configFlags & (uint32_t)kDSPI_MasterPcsContinuous)) ? true : false;
939
940 command = DSPI_MasterGetFormattedCommand(&(commandStruct));
941
942 commandStruct.isEndOfQueue = true;
943 commandStruct.isPcsContinuous =
944 (0U != (transfer->configFlags & (uint32_t)kDSPI_MasterActiveAfterTransfer)) ? true : false;
945 lastCommand = DSPI_MasterGetFormattedCommand(&(commandStruct));
946
947 /*Calculate the bitsPerFrame*/
948 bitsPerFrame = (uint8_t)(((base->CTAR[commandStruct.whichCtar] & SPI_CTAR_FMSZ_MASK) >> SPI_CTAR_FMSZ_SHIFT) + 1U);
949
950 txData = transfer->txData;
951 rxData = transfer->rxData;
952 remainingSendByteCount = transfer->dataSize;
953 remainingReceiveByteCount = transfer->dataSize;
954
955 tmpMCR = base->MCR;
956 if ((0U != (tmpMCR & SPI_MCR_DIS_RXF_MASK)) || (0U != (tmpMCR & SPI_MCR_DIS_TXF_MASK)))
957 {
958 fifoSize = 1U;
959 }
960 else
961 {
962 fifoSize = (uint32_t)FSL_FEATURE_DSPI_FIFO_SIZEn(base);
963 }
964
965 DSPI_StartTransfer(base);
966
967 if (bitsPerFrame <= 8U)
968 {
969 while (remainingSendByteCount > 0U)
970 {
971 if (remainingSendByteCount == 1U)
972 {
973 while (0U == (DSPI_GetStatusFlags(base) & (uint32_t)kDSPI_TxFifoFillRequestFlag))
974 {
975 DSPI_ClearStatusFlags(base, (uint32_t)kDSPI_TxFifoFillRequestFlag);
976 }
977
978 if (txData != NULL)
979 {
980 base->PUSHR = (*txData) | (lastCommand);
981 txData++;
982 }
983 else
984 {
985 base->PUSHR = (lastCommand) | (dummyData);
986 }
987 DSPI_ClearStatusFlags(base, (uint32_t)kDSPI_TxFifoFillRequestFlag);
988 remainingSendByteCount--;
989
990 while (remainingReceiveByteCount > 0U)
991 {
992 if ((uint32_t)kDSPI_RxFifoDrainRequestFlag ==
993 (DSPI_GetStatusFlags(base) & (uint32_t)kDSPI_RxFifoDrainRequestFlag))
994 {
995 if (rxData != NULL)
996 {
997 /* Read data from POPR*/
998 *(rxData) = (uint8_t)DSPI_ReadData(base);
999 rxData++;
1000 }
1001 else
1002 {
1003 (void)DSPI_ReadData(base);
1004 }
1005 remainingReceiveByteCount--;
1006
1007 DSPI_ClearStatusFlags(base, (uint32_t)kDSPI_RxFifoDrainRequestFlag);
1008 }
1009 }
1010 }
1011 else
1012 {
1013 /*Wait until Tx Fifo is not full*/
1014 while (0U == (DSPI_GetStatusFlags(base) & (uint32_t)kDSPI_TxFifoFillRequestFlag))
1015 {
1016 DSPI_ClearStatusFlags(base, (uint32_t)kDSPI_TxFifoFillRequestFlag);
1017 }
1018 if (txData != NULL)
1019 {
1020 base->PUSHR = command | (uint16_t)(*txData);
1021 txData++;
1022 }
1023 else
1024 {
1025 base->PUSHR = command | dummyData;
1026 }
1027 remainingSendByteCount--;
1028
1029 DSPI_ClearStatusFlags(base, (uint32_t)kDSPI_TxFifoFillRequestFlag);
1030
1031 while ((remainingReceiveByteCount - remainingSendByteCount) >= fifoSize)
1032 {
1033 if ((uint32_t)kDSPI_RxFifoDrainRequestFlag ==
1034 (DSPI_GetStatusFlags(base) & (uint32_t)kDSPI_RxFifoDrainRequestFlag))
1035 {
1036 if (rxData != NULL)
1037 {
1038 *(rxData) = (uint8_t)DSPI_ReadData(base);
1039 rxData++;
1040 }
1041 else
1042 {
1043 (void)DSPI_ReadData(base);
1044 }
1045 remainingReceiveByteCount--;
1046
1047 DSPI_ClearStatusFlags(base, (uint32_t)kDSPI_RxFifoDrainRequestFlag);
1048 }
1049 }
1050 }
1051 }
1052 }
1053 else
1054 {
1055 while (remainingSendByteCount > 0U)
1056 {
1057 if (remainingSendByteCount <= 2U)
1058 {
1059 while (0U == (DSPI_GetStatusFlags(base) & (uint32_t)kDSPI_TxFifoFillRequestFlag))
1060 {
1061 DSPI_ClearStatusFlags(base, (uint32_t)kDSPI_TxFifoFillRequestFlag);
1062 }
1063
1064 if (txData != NULL)
1065 {
1066 wordToSend = *(txData);
1067 ++txData;
1068
1069 if (remainingSendByteCount > 1U)
1070 {
1071 wordToSend |= (uint16_t)(*(txData)) << 8U;
1072 ++txData;
1073 }
1074 }
1075 else
1076 {
1077 wordToSend = dummyData;
1078 }
1079
1080 base->PUSHR = lastCommand | wordToSend;
1081
1082 DSPI_ClearStatusFlags(base, (uint32_t)kDSPI_TxFifoFillRequestFlag);
1083 remainingSendByteCount = 0;
1084
1085 while (remainingReceiveByteCount > 0U)
1086 {
1087 if ((uint32_t)kDSPI_RxFifoDrainRequestFlag ==
1088 (DSPI_GetStatusFlags(base) & (uint32_t)kDSPI_RxFifoDrainRequestFlag))
1089 {
1090 wordReceived = (uint16_t)DSPI_ReadData(base);
1091
1092 if (remainingReceiveByteCount != 1U)
1093 {
1094 if (rxData != NULL)
1095 {
1096 *(rxData) = (uint8_t)wordReceived;
1097 ++rxData;
1098 *(rxData) = (uint8_t)(wordReceived >> 8U);
1099 ++rxData;
1100 }
1101 remainingReceiveByteCount -= 2U;
1102 }
1103 else
1104 {
1105 if (rxData != NULL)
1106 {
1107 *(rxData) = (uint8_t)wordReceived;
1108 ++rxData;
1109 }
1110 remainingReceiveByteCount--;
1111 }
1112 DSPI_ClearStatusFlags(base, (uint32_t)kDSPI_RxFifoDrainRequestFlag);
1113 }
1114 }
1115 }
1116 else
1117 {
1118 /*Wait until Tx Fifo is not full*/
1119 while (0U == (DSPI_GetStatusFlags(base) & (uint32_t)kDSPI_TxFifoFillRequestFlag))
1120 {
1121 DSPI_ClearStatusFlags(base, (uint32_t)kDSPI_TxFifoFillRequestFlag);
1122 }
1123
1124 if (txData != NULL)
1125 {
1126 wordToSend = *(txData);
1127 ++txData;
1128 wordToSend |= (uint16_t)(*(txData)) << 8U;
1129 ++txData;
1130 }
1131 else
1132 {
1133 wordToSend = dummyData;
1134 }
1135 base->PUSHR = command | wordToSend;
1136 remainingSendByteCount -= 2U;
1137
1138 DSPI_ClearStatusFlags(base, (uint32_t)kDSPI_TxFifoFillRequestFlag);
1139
1140 while (((remainingReceiveByteCount - remainingSendByteCount) / 2U) >= fifoSize)
1141 {
1142 if ((uint32_t)kDSPI_RxFifoDrainRequestFlag ==
1143 (DSPI_GetStatusFlags(base) & (uint32_t)kDSPI_RxFifoDrainRequestFlag))
1144 {
1145 wordReceived = (uint16_t)DSPI_ReadData(base);
1146
1147 if (rxData != NULL)
1148 {
1149 *rxData = (uint8_t)wordReceived;
1150 ++rxData;
1151 *rxData = (uint8_t)(wordReceived >> 8U);
1152 ++rxData;
1153 }
1154 remainingReceiveByteCount -= 2U;
1155
1156 DSPI_ClearStatusFlags(base, (uint32_t)kDSPI_RxFifoDrainRequestFlag);
1157 }
1158 }
1159 }
1160 }
1161 }
1162
1163 return kStatus_Success;
1164 }
1165
DSPI_MasterTransferPrepare(SPI_Type * base,dspi_master_handle_t * handle,dspi_transfer_t * transfer)1166 static void DSPI_MasterTransferPrepare(SPI_Type *base, dspi_master_handle_t *handle, dspi_transfer_t *transfer)
1167 {
1168 assert(NULL != handle);
1169 assert(NULL != transfer);
1170
1171 uint32_t tmpMCR = 0;
1172 dspi_command_data_config_t commandStruct = {false, (uint8_t)kDSPI_Ctar0, (uint8_t)kDSPI_Pcs0, false, false};
1173
1174 DSPI_StopTransfer(base);
1175 DSPI_FlushFifo(base, true, true);
1176 DSPI_ClearStatusFlags(base, (uint32_t)kDSPI_AllStatusFlag);
1177
1178 commandStruct.whichPcs =
1179 (uint8_t)((uint32_t)1U << ((transfer->configFlags & DSPI_MASTER_PCS_MASK) >> DSPI_MASTER_PCS_SHIFT));
1180 commandStruct.isEndOfQueue = false;
1181 commandStruct.clearTransferCount = false;
1182 commandStruct.whichCtar = (uint8_t)((transfer->configFlags & DSPI_MASTER_CTAR_MASK) >> DSPI_MASTER_CTAR_SHIFT);
1183 commandStruct.isPcsContinuous =
1184 (0U != (transfer->configFlags & (uint32_t)kDSPI_MasterPcsContinuous)) ? true : false;
1185 handle->command = DSPI_MasterGetFormattedCommand(&(commandStruct));
1186
1187 commandStruct.isEndOfQueue = true;
1188 commandStruct.isPcsContinuous =
1189 (0U != (transfer->configFlags & (uint32_t)kDSPI_MasterActiveAfterTransfer)) ? true : false;
1190 handle->lastCommand = DSPI_MasterGetFormattedCommand(&(commandStruct));
1191
1192 handle->bitsPerFrame = ((base->CTAR[commandStruct.whichCtar] & SPI_CTAR_FMSZ_MASK) >> SPI_CTAR_FMSZ_SHIFT) + 1U;
1193
1194 tmpMCR = base->MCR;
1195 if ((0U != (tmpMCR & SPI_MCR_DIS_RXF_MASK)) || (0U != (tmpMCR & SPI_MCR_DIS_TXF_MASK)))
1196 {
1197 handle->fifoSize = 1U;
1198 }
1199 else
1200 {
1201 handle->fifoSize = (uint8_t)FSL_FEATURE_DSPI_FIFO_SIZEn(base);
1202 }
1203 handle->txData = transfer->txData;
1204 handle->rxData = transfer->rxData;
1205 handle->remainingSendByteCount = transfer->dataSize;
1206 handle->remainingReceiveByteCount = transfer->dataSize;
1207 handle->totalByteCount = transfer->dataSize;
1208 }
1209
1210 /*!
1211 * brief DSPI master transfer data using interrupts.
1212 *
1213 * This function transfers data using interrupts. This is a non-blocking function, which returns right away. When all
1214 * data is transferred, the callback function is called.
1215
1216 * param base DSPI peripheral base address.
1217 * param handle Pointer to the dspi_master_handle_t structure which stores the transfer state.
1218 * param transfer Pointer to the dspi_transfer_t structure.
1219 * return status of status_t.
1220 */
DSPI_MasterTransferNonBlocking(SPI_Type * base,dspi_master_handle_t * handle,dspi_transfer_t * transfer)1221 status_t DSPI_MasterTransferNonBlocking(SPI_Type *base, dspi_master_handle_t *handle, dspi_transfer_t *transfer)
1222 {
1223 assert(NULL != handle);
1224 assert(NULL != transfer);
1225
1226 /* If the transfer count is zero, then return immediately.*/
1227 if (transfer->dataSize == 0U)
1228 {
1229 return kStatus_InvalidArgument;
1230 }
1231
1232 /* Check that we're not busy.*/
1233 if (handle->state == (uint8_t)kDSPI_Busy)
1234 {
1235 return kStatus_DSPI_Busy;
1236 }
1237
1238 handle->state = (uint8_t)kDSPI_Busy;
1239
1240 /* Disable the NVIC for DSPI peripheral. */
1241 (void)DisableIRQ(s_dspiIRQ[DSPI_GetInstance(base)]);
1242
1243 DSPI_MasterTransferPrepare(base, handle, transfer);
1244
1245 /* RX FIFO Drain request: RFDF_RE to enable RFDF interrupt
1246 * Since SPI is a synchronous interface, we only need to enable the RX interrupt.
1247 * The IRQ handler will get the status of RX and TX interrupt flags.
1248 */
1249 s_dspiMasterIsr = DSPI_MasterTransferHandleIRQ;
1250
1251 DSPI_EnableInterrupts(base, (uint32_t)kDSPI_RxFifoDrainRequestInterruptEnable);
1252 DSPI_StartTransfer(base);
1253
1254 /* Fill up the Tx FIFO to trigger the transfer. */
1255 DSPI_MasterTransferFillUpTxFifo(base, handle);
1256
1257 /* Enable the NVIC for DSPI peripheral. */
1258 (void)EnableIRQ(s_dspiIRQ[DSPI_GetInstance(base)]);
1259
1260 return kStatus_Success;
1261 }
1262
1263 /*!
1264 * brief Transfers a block of data using a polling method.
1265 *
1266 * This function will do a half-duplex transfer for DSPI master, This is a blocking function,
1267 * which does not retuen until all transfer have been completed. And data transfer will be half-duplex,
1268 * users can set transmit first or receive first.
1269 *
1270 * param base DSPI base pointer
1271 * param xfer pointer to dspi_half_duplex_transfer_t structure
1272 * return status of status_t.
1273 */
DSPI_MasterHalfDuplexTransferBlocking(SPI_Type * base,dspi_half_duplex_transfer_t * xfer)1274 status_t DSPI_MasterHalfDuplexTransferBlocking(SPI_Type *base, dspi_half_duplex_transfer_t *xfer)
1275 {
1276 assert(NULL != xfer);
1277
1278 dspi_transfer_t tempXfer = {0};
1279 status_t status;
1280
1281 if (true == xfer->isTransmitFirst)
1282 {
1283 tempXfer.txData = xfer->txData;
1284 tempXfer.rxData = NULL;
1285 tempXfer.dataSize = xfer->txDataSize;
1286 }
1287 else
1288 {
1289 tempXfer.txData = NULL;
1290 tempXfer.rxData = xfer->rxData;
1291 tempXfer.dataSize = xfer->rxDataSize;
1292 }
1293 /* If the pcs pin keep assert between transmit and receive. */
1294 if (true == xfer->isPcsAssertInTransfer)
1295 {
1296 tempXfer.configFlags = (xfer->configFlags) | (uint32_t)kDSPI_MasterActiveAfterTransfer;
1297 }
1298 else
1299 {
1300 tempXfer.configFlags = (xfer->configFlags) & (~(uint32_t)kDSPI_MasterActiveAfterTransfer);
1301 }
1302
1303 status = DSPI_MasterTransferBlocking(base, &tempXfer);
1304 if (status != kStatus_Success)
1305 {
1306 return status;
1307 }
1308
1309 if (true == xfer->isTransmitFirst)
1310 {
1311 tempXfer.txData = NULL;
1312 tempXfer.rxData = xfer->rxData;
1313 tempXfer.dataSize = xfer->rxDataSize;
1314 }
1315 else
1316 {
1317 tempXfer.txData = xfer->txData;
1318 tempXfer.rxData = NULL;
1319 tempXfer.dataSize = xfer->txDataSize;
1320 }
1321 tempXfer.configFlags = xfer->configFlags;
1322
1323 /* DSPI transfer blocking. */
1324 status = DSPI_MasterTransferBlocking(base, &tempXfer);
1325
1326 return status;
1327 }
1328
1329 /*!
1330 * brief Performs a non-blocking DSPI interrupt transfer.
1331 *
1332 * This function transfers data using interrupts, the transfer mechanism is half-duplex. This is a non-blocking
1333 * function,
1334 * which returns right away. When all data is transferred, the callback function is called.
1335 *
1336 * param base DSPI peripheral base address.
1337 * param handle pointer to dspi_master_handle_t structure which stores the transfer state
1338 * param xfer pointer to dspi_half_duplex_transfer_t structure
1339 * return status of status_t.
1340 */
DSPI_MasterHalfDuplexTransferNonBlocking(SPI_Type * base,dspi_master_handle_t * handle,dspi_half_duplex_transfer_t * xfer)1341 status_t DSPI_MasterHalfDuplexTransferNonBlocking(SPI_Type *base,
1342 dspi_master_handle_t *handle,
1343 dspi_half_duplex_transfer_t *xfer)
1344 {
1345 assert(NULL != xfer);
1346 assert(NULL != handle);
1347 dspi_transfer_t tempXfer = {0};
1348 status_t status;
1349
1350 if (true == xfer->isTransmitFirst)
1351 {
1352 tempXfer.txData = xfer->txData;
1353 tempXfer.rxData = NULL;
1354 tempXfer.dataSize = xfer->txDataSize;
1355 }
1356 else
1357 {
1358 tempXfer.txData = NULL;
1359 tempXfer.rxData = xfer->rxData;
1360 tempXfer.dataSize = xfer->rxDataSize;
1361 }
1362 /* If the pcs pin keep assert between transmit and receive. */
1363 if (true == xfer->isPcsAssertInTransfer)
1364 {
1365 tempXfer.configFlags = (xfer->configFlags) | (uint32_t)kDSPI_MasterActiveAfterTransfer;
1366 }
1367 else
1368 {
1369 tempXfer.configFlags = (xfer->configFlags) & (~(uint32_t)kDSPI_MasterActiveAfterTransfer);
1370 }
1371
1372 status = DSPI_MasterTransferBlocking(base, &tempXfer);
1373 if (status != kStatus_Success)
1374 {
1375 return status;
1376 }
1377
1378 if (true == xfer->isTransmitFirst)
1379 {
1380 tempXfer.txData = NULL;
1381 tempXfer.rxData = xfer->rxData;
1382 tempXfer.dataSize = xfer->rxDataSize;
1383 }
1384 else
1385 {
1386 tempXfer.txData = xfer->txData;
1387 tempXfer.rxData = NULL;
1388 tempXfer.dataSize = xfer->txDataSize;
1389 }
1390 tempXfer.configFlags = xfer->configFlags;
1391
1392 status = DSPI_MasterTransferNonBlocking(base, handle, &tempXfer);
1393
1394 return status;
1395 }
1396
1397 /*!
1398 * brief Gets the master transfer count.
1399 *
1400 * This function gets the master transfer count.
1401 *
1402 * param base DSPI peripheral base address.
1403 * param handle Pointer to the dspi_master_handle_t structure which stores the transfer state.
1404 * param count The number of bytes transferred by using the non-blocking transaction.
1405 * return status of status_t.
1406 */
DSPI_MasterTransferGetCount(SPI_Type * base,dspi_master_handle_t * handle,size_t * count)1407 status_t DSPI_MasterTransferGetCount(SPI_Type *base, dspi_master_handle_t *handle, size_t *count)
1408 {
1409 assert(NULL != handle);
1410
1411 if (NULL == count)
1412 {
1413 return kStatus_InvalidArgument;
1414 }
1415
1416 /* Catch when there is not an active transfer. */
1417 if (handle->state != (uint8_t)kDSPI_Busy)
1418 {
1419 *count = 0;
1420 return kStatus_NoTransferInProgress;
1421 }
1422
1423 *count = handle->totalByteCount - handle->remainingReceiveByteCount;
1424 return kStatus_Success;
1425 }
1426
DSPI_MasterTransferComplete(SPI_Type * base,dspi_master_handle_t * handle)1427 static void DSPI_MasterTransferComplete(SPI_Type *base, dspi_master_handle_t *handle)
1428 {
1429 assert(NULL != handle);
1430
1431 /* Disable interrupt requests*/
1432 DSPI_DisableInterrupts(
1433 base, ((uint32_t)kDSPI_RxFifoDrainRequestInterruptEnable | (uint32_t)kDSPI_TxFifoFillRequestInterruptEnable));
1434
1435 status_t status = 0;
1436 if (handle->state == (uint8_t)kDSPI_Error)
1437 {
1438 status = kStatus_DSPI_Error;
1439 }
1440 else
1441 {
1442 status = kStatus_Success;
1443 }
1444
1445 if ((NULL != handle->callback) && ((uint8_t)kDSPI_Idle != handle->state))
1446 {
1447 handle->state = (uint8_t)kDSPI_Idle;
1448 handle->callback(base, handle, status, handle->userData);
1449 }
1450 }
1451
DSPI_MasterTransferFillUpTxFifo(SPI_Type * base,dspi_master_handle_t * handle)1452 static void DSPI_MasterTransferFillUpTxFifo(SPI_Type *base, dspi_master_handle_t *handle)
1453 {
1454 assert(NULL != handle);
1455
1456 uint16_t wordToSend = 0;
1457 uint8_t dummyData = DSPI_GetDummyDataInstance(base);
1458 size_t tmpRemainingSendByteCount = handle->remainingSendByteCount;
1459 size_t tmpRemainingReceiveByteCount = handle->remainingReceiveByteCount;
1460 uint8_t tmpFifoSize = handle->fifoSize;
1461
1462 /* If bits/frame is greater than one byte */
1463 if (handle->bitsPerFrame > 8U)
1464 {
1465 /* Fill the fifo until it is full or until the send word count is 0 or until the difference
1466 * between the remainingReceiveByteCount and remainingSendByteCount equals the FIFO depth.
1467 * The reason for checking the difference is to ensure we only send as much as the
1468 * RX FIFO can receive.
1469 * For this case where bitsPerFrame > 8, each entry in the FIFO contains 2 bytes of the
1470 * send data, hence the difference between the remainingReceiveByteCount and
1471 * remainingSendByteCount must be divided by 2 to convert this difference into a
1472 * 16-bit (2 byte) value.
1473 */
1474 while ((0U != (DSPI_GetStatusFlags(base) & (uint32_t)kDSPI_TxFifoFillRequestFlag)) &&
1475 (((tmpRemainingReceiveByteCount - tmpRemainingSendByteCount) / 2U) < tmpFifoSize))
1476 {
1477 if (handle->remainingSendByteCount <= 2U)
1478 {
1479 if (NULL != handle->txData)
1480 {
1481 if (handle->remainingSendByteCount == 1U)
1482 {
1483 wordToSend = *(handle->txData);
1484 }
1485 else
1486 {
1487 wordToSend = *(handle->txData);
1488 ++handle->txData; /* increment to next data byte */
1489 wordToSend |= (uint16_t)(*(handle->txData)) << 8U;
1490 }
1491 }
1492 else
1493 {
1494 wordToSend = dummyData;
1495 }
1496 handle->remainingSendByteCount = 0;
1497 base->PUSHR = handle->lastCommand | wordToSend;
1498 }
1499 /* For all words except the last word */
1500 else
1501 {
1502 if (NULL != handle->txData)
1503 {
1504 wordToSend = *(handle->txData);
1505 ++handle->txData; /* increment to next data byte */
1506 wordToSend |= (uint16_t)(*(handle->txData)) << 8U;
1507 ++handle->txData; /* increment to next data byte */
1508 }
1509 else
1510 {
1511 wordToSend = dummyData;
1512 }
1513 handle->remainingSendByteCount -= 2U; /* decrement remainingSendByteCount by 2 */
1514 base->PUSHR = handle->command | wordToSend;
1515 }
1516
1517 /* Try to clear the TFFF; if the TX FIFO is full this will clear */
1518 DSPI_ClearStatusFlags(base, (uint32_t)kDSPI_TxFifoFillRequestFlag);
1519
1520 /* exit loop if send count is zero, else update local variables for next loop.
1521 * If this is the first time write to the PUSHR, write only once.
1522 */
1523 tmpRemainingSendByteCount = handle->remainingSendByteCount;
1524 if ((tmpRemainingSendByteCount == 0U) || (tmpRemainingSendByteCount == handle->totalByteCount - 2U))
1525 {
1526 break;
1527 }
1528 tmpRemainingReceiveByteCount = handle->remainingReceiveByteCount;
1529 tmpRemainingSendByteCount = handle->remainingSendByteCount;
1530 tmpFifoSize = handle->fifoSize;
1531 } /* End of TX FIFO fill while loop */
1532 }
1533 /* Optimized for bits/frame less than or equal to one byte. */
1534 else
1535 {
1536 /* Fill the fifo until it is full or until the send word count is 0 or until the difference
1537 * between the remainingReceiveByteCount and remainingSendByteCount equals the FIFO depth.
1538 * The reason for checking the difference is to ensure we only send as much as the
1539 * RX FIFO can receive.
1540 */
1541 while ((0U != (DSPI_GetStatusFlags(base) & (uint32_t)kDSPI_TxFifoFillRequestFlag)) &&
1542 ((tmpRemainingReceiveByteCount - tmpRemainingSendByteCount) < tmpFifoSize))
1543 {
1544 if (NULL != handle->txData)
1545 {
1546 wordToSend = *(handle->txData);
1547 ++handle->txData;
1548 }
1549 else
1550 {
1551 wordToSend = dummyData;
1552 }
1553
1554 if (handle->remainingSendByteCount == 1U)
1555 {
1556 base->PUSHR = handle->lastCommand | wordToSend;
1557 }
1558 else
1559 {
1560 base->PUSHR = handle->command | wordToSend;
1561 }
1562
1563 /* Try to clear the TFFF; if the TX FIFO is full this will clear */
1564 DSPI_ClearStatusFlags(base, (uint32_t)kDSPI_TxFifoFillRequestFlag);
1565
1566 --handle->remainingSendByteCount;
1567
1568 /* exit loop if send count is zero, else update local variables for next loop
1569 * If this is the first time write to the PUSHR, write only once.
1570 */
1571 tmpRemainingSendByteCount = handle->remainingSendByteCount;
1572 if ((tmpRemainingSendByteCount == 0U) || (tmpRemainingSendByteCount == (handle->totalByteCount - 1U)))
1573 {
1574 break;
1575 }
1576 tmpRemainingReceiveByteCount = handle->remainingReceiveByteCount;
1577 tmpRemainingSendByteCount = handle->remainingSendByteCount;
1578 tmpFifoSize = handle->fifoSize;
1579 }
1580 }
1581 }
1582
1583 /*!
1584 * brief DSPI master aborts a transfer using an interrupt.
1585 *
1586 * This function aborts a transfer using an interrupt.
1587 *
1588 * param base DSPI peripheral base address.
1589 * param handle Pointer to the dspi_master_handle_t structure which stores the transfer state.
1590 */
DSPI_MasterTransferAbort(SPI_Type * base,dspi_master_handle_t * handle)1591 void DSPI_MasterTransferAbort(SPI_Type *base, dspi_master_handle_t *handle)
1592 {
1593 assert(NULL != handle);
1594
1595 DSPI_StopTransfer(base);
1596
1597 /* Disable interrupt requests*/
1598 DSPI_DisableInterrupts(
1599 base, ((uint32_t)kDSPI_RxFifoDrainRequestInterruptEnable | (uint32_t)kDSPI_TxFifoFillRequestInterruptEnable));
1600
1601 handle->state = (uint8_t)kDSPI_Idle;
1602 }
1603
1604 /*!
1605 * brief DSPI Master IRQ handler function.
1606 *
1607 * This function processes the DSPI transmit and receive IRQ.
1608
1609 * param base DSPI peripheral base address.
1610 * param handle Pointer to the dspi_master_handle_t structure which stores the transfer state.
1611 */
DSPI_MasterTransferHandleIRQ(SPI_Type * base,dspi_master_handle_t * handle)1612 void DSPI_MasterTransferHandleIRQ(SPI_Type *base, dspi_master_handle_t *handle)
1613 {
1614 assert(NULL != handle);
1615
1616 /* RECEIVE IRQ handler: Check read buffer only if there are remaining bytes to read. */
1617 if (0U != (handle->remainingReceiveByteCount))
1618 {
1619 /* Check read buffer.*/
1620 uint16_t wordReceived; /* Maximum supported data bit length in master mode is 16-bits */
1621
1622 /* If bits/frame is greater than one byte */
1623 if (handle->bitsPerFrame > 8U)
1624 {
1625 while ((uint32_t)kDSPI_RxFifoDrainRequestFlag ==
1626 (DSPI_GetStatusFlags(base) & (uint32_t)kDSPI_RxFifoDrainRequestFlag))
1627 {
1628 wordReceived = (uint16_t)DSPI_ReadData(base);
1629 /* clear the rx fifo drain request, needed for non-DMA applications as this flag
1630 * will remain set even if the rx fifo is empty. By manually clearing this flag, it
1631 * either remain clear if no more data is in the fifo, or it will set if there is
1632 * more data in the fifo.
1633 */
1634 DSPI_ClearStatusFlags(base, (uint32_t)kDSPI_RxFifoDrainRequestFlag);
1635
1636 /* Store read bytes into rx buffer only if a buffer pointer was provided */
1637 if (NULL != handle->rxData)
1638 {
1639 /* For the last word received, if there is an extra byte due to the odd transfer
1640 * byte count, only save the last byte and discard the upper byte
1641 */
1642 if (handle->remainingReceiveByteCount == 1U)
1643 {
1644 *handle->rxData = (uint8_t)wordReceived; /* Write first data byte */
1645 --handle->remainingReceiveByteCount;
1646 }
1647 else
1648 {
1649 *handle->rxData = (uint8_t)wordReceived; /* Write first data byte */
1650 ++handle->rxData; /* increment to next data byte */
1651 *handle->rxData = (uint8_t)(wordReceived >> 8U); /* Write second data byte */
1652 ++handle->rxData; /* increment to next data byte */
1653 handle->remainingReceiveByteCount -= 2U;
1654 }
1655 }
1656 else
1657 {
1658 if (handle->remainingReceiveByteCount == 1U)
1659 {
1660 --handle->remainingReceiveByteCount;
1661 }
1662 else
1663 {
1664 handle->remainingReceiveByteCount -= 2U;
1665 }
1666 }
1667 if (handle->remainingReceiveByteCount == 0U)
1668 {
1669 break;
1670 }
1671 } /* End of RX FIFO drain while loop */
1672 }
1673 /* Optimized for bits/frame less than or equal to one byte. */
1674 else
1675 {
1676 while ((uint32_t)kDSPI_RxFifoDrainRequestFlag ==
1677 (DSPI_GetStatusFlags(base) & (uint32_t)kDSPI_RxFifoDrainRequestFlag))
1678 {
1679 wordReceived = (uint16_t)DSPI_ReadData(base);
1680 /* clear the rx fifo drain request, needed for non-DMA applications as this flag
1681 * will remain set even if the rx fifo is empty. By manually clearing this flag, it
1682 * either remain clear if no more data is in the fifo, or it will set if there is
1683 * more data in the fifo.
1684 */
1685 DSPI_ClearStatusFlags(base, (uint32_t)kDSPI_RxFifoDrainRequestFlag);
1686
1687 /* Store read bytes into rx buffer only if a buffer pointer was provided */
1688 if (NULL != handle->rxData)
1689 {
1690 *handle->rxData = (uint8_t)wordReceived;
1691 ++handle->rxData;
1692 }
1693
1694 --handle->remainingReceiveByteCount;
1695
1696 if (handle->remainingReceiveByteCount == 0U)
1697 {
1698 break;
1699 }
1700 } /* End of RX FIFO drain while loop */
1701 }
1702 }
1703
1704 /* Check write buffer. We always have to send a word in order to keep the transfer
1705 * moving. So if the caller didn't provide a send buffer, we just send a zero.
1706 */
1707 if (0U != (handle->remainingSendByteCount))
1708 {
1709 DSPI_MasterTransferFillUpTxFifo(base, handle);
1710 }
1711
1712 /* Check if we're done with this transfer.*/
1713 if (handle->remainingSendByteCount == 0U)
1714 {
1715 if (handle->remainingReceiveByteCount == 0U)
1716 {
1717 /* Complete the transfer and disable the interrupts */
1718 DSPI_MasterTransferComplete(base, handle);
1719 }
1720 }
1721 }
1722
1723 /*Transactional APIs -- Slave*/
1724 #if !(defined(FSL_FEATURE_DSPI_HAS_NO_SLAVE_SUPPORT) && FSL_FEATURE_DSPI_HAS_NO_SLAVE_SUPPORT)
1725 /*!
1726 * brief Initializes the DSPI slave handle.
1727 *
1728 * This function initializes the DSPI handle, which can be used for other DSPI transactional APIs. Usually, for a
1729 * specified DSPI instance, call this API once to get the initialized handle.
1730 *
1731 * param handle DSPI handle pointer to the dspi_slave_handle_t.
1732 * param base DSPI peripheral base address.
1733 * param callback DSPI callback.
1734 * param userData Callback function parameter.
1735 */
DSPI_SlaveTransferCreateHandle(SPI_Type * base,dspi_slave_handle_t * handle,dspi_slave_transfer_callback_t callback,void * userData)1736 void DSPI_SlaveTransferCreateHandle(SPI_Type *base,
1737 dspi_slave_handle_t *handle,
1738 dspi_slave_transfer_callback_t callback,
1739 void *userData)
1740 {
1741 assert(NULL != handle);
1742
1743 /* Zero the handle. */
1744 (void)memset(handle, 0, sizeof(*handle));
1745
1746 g_dspiHandle[DSPI_GetInstance(base)] = handle;
1747
1748 handle->callback = callback;
1749 handle->userData = userData;
1750 }
1751 #endif
1752
1753 #if !(defined(FSL_FEATURE_DSPI_HAS_NO_SLAVE_SUPPORT) && FSL_FEATURE_DSPI_HAS_NO_SLAVE_SUPPORT)
1754 /*!
1755 * brief DSPI slave transfers data using an interrupt.
1756 *
1757 * This function transfers data using an interrupt. This is a non-blocking function, which returns right away. When all
1758 * data is transferred, the callback function is called.
1759 *
1760 * param base DSPI peripheral base address.
1761 * param handle Pointer to the dspi_slave_handle_t structure which stores the transfer state.
1762 * param transfer Pointer to the dspi_transfer_t structure.
1763 * return status of status_t.
1764 */
DSPI_SlaveTransferNonBlocking(SPI_Type * base,dspi_slave_handle_t * handle,dspi_transfer_t * transfer)1765 status_t DSPI_SlaveTransferNonBlocking(SPI_Type *base, dspi_slave_handle_t *handle, dspi_transfer_t *transfer)
1766 {
1767 assert(NULL != handle);
1768 assert(NULL != transfer);
1769
1770 /* If receive length is zero */
1771 if (transfer->dataSize == 0U)
1772 {
1773 return kStatus_InvalidArgument;
1774 }
1775
1776 /* If both send buffer and receive buffer is null */
1777 if ((NULL == (transfer->txData)) && (NULL == (transfer->rxData)))
1778 {
1779 return kStatus_InvalidArgument;
1780 }
1781
1782 /* Check that we're not busy.*/
1783 if (handle->state == (uint8_t)kDSPI_Busy)
1784 {
1785 return kStatus_DSPI_Busy;
1786 }
1787 handle->state = (uint8_t)kDSPI_Busy;
1788
1789 /* Enable the NVIC for DSPI peripheral. */
1790 (void)EnableIRQ(s_dspiIRQ[DSPI_GetInstance(base)]);
1791
1792 /* Store transfer information */
1793 handle->txData = transfer->txData;
1794 handle->rxData = transfer->rxData;
1795 handle->remainingSendByteCount = transfer->dataSize;
1796 handle->remainingReceiveByteCount = transfer->dataSize;
1797 handle->totalByteCount = transfer->dataSize;
1798
1799 handle->errorCount = 0;
1800
1801 uint8_t whichCtar = (uint8_t)((transfer->configFlags & DSPI_SLAVE_CTAR_MASK) >> DSPI_SLAVE_CTAR_SHIFT);
1802 handle->bitsPerFrame =
1803 (((base->CTAR_SLAVE[whichCtar]) & SPI_CTAR_SLAVE_FMSZ_MASK) >> SPI_CTAR_SLAVE_FMSZ_SHIFT) + 1U;
1804
1805 DSPI_StopTransfer(base);
1806
1807 DSPI_FlushFifo(base, true, true);
1808 DSPI_ClearStatusFlags(base, (uint32_t)kDSPI_AllStatusFlag);
1809
1810 s_dspiSlaveIsr = DSPI_SlaveTransferHandleIRQ;
1811
1812 /* Enable RX FIFO drain request, the slave only use this interrupt */
1813 DSPI_EnableInterrupts(base, (uint32_t)kDSPI_RxFifoDrainRequestInterruptEnable);
1814
1815 if (NULL != handle->rxData)
1816 {
1817 /* RX FIFO overflow request enable */
1818 DSPI_EnableInterrupts(base, (uint32_t)kDSPI_RxFifoOverflowInterruptEnable);
1819 }
1820 #if !(defined(FSL_FEATURE_FLEXCAN_HAS_NO_RSER_TFUF_SUPPORT) && FSL_FEATURE_FLEXCAN_HAS_NO_RSER_TFUF_SUPPORT)
1821 if (NULL != handle->txData)
1822 {
1823 /* TX FIFO underflow request enable */
1824 DSPI_EnableInterrupts(base, (uint32_t)kDSPI_TxFifoUnderflowInterruptEnable);
1825 }
1826 #endif
1827
1828 DSPI_StartTransfer(base);
1829
1830 /* Prepare data to transmit */
1831 DSPI_SlaveTransferFillUpTxFifo(base, handle);
1832
1833 return kStatus_Success;
1834 }
1835 #endif
1836
1837 #if !(defined(FSL_FEATURE_DSPI_HAS_NO_SLAVE_SUPPORT) && FSL_FEATURE_DSPI_HAS_NO_SLAVE_SUPPORT)
1838 /*!
1839 * brief Gets the slave transfer count.
1840 *
1841 * This function gets the slave transfer count.
1842 *
1843 * param base DSPI peripheral base address.
1844 * param handle Pointer to the dspi_master_handle_t structure which stores the transfer state.
1845 * param count The number of bytes transferred by using the non-blocking transaction.
1846 * return status of status_t.
1847 */
DSPI_SlaveTransferGetCount(SPI_Type * base,dspi_slave_handle_t * handle,size_t * count)1848 status_t DSPI_SlaveTransferGetCount(SPI_Type *base, dspi_slave_handle_t *handle, size_t *count)
1849 {
1850 assert(NULL != handle);
1851
1852 if (NULL == count)
1853 {
1854 return kStatus_InvalidArgument;
1855 }
1856
1857 /* Catch when there is not an active transfer. */
1858 if (handle->state != (uint8_t)kDSPI_Busy)
1859 {
1860 *count = 0;
1861 return kStatus_NoTransferInProgress;
1862 }
1863
1864 *count = handle->totalByteCount - handle->remainingReceiveByteCount;
1865 return kStatus_Success;
1866 }
1867 #endif
1868
1869 #if !(defined(FSL_FEATURE_DSPI_HAS_NO_SLAVE_SUPPORT) && FSL_FEATURE_DSPI_HAS_NO_SLAVE_SUPPORT)
DSPI_SlaveTransferFillUpTxFifo(SPI_Type * base,dspi_slave_handle_t * handle)1870 static void DSPI_SlaveTransferFillUpTxFifo(SPI_Type *base, dspi_slave_handle_t *handle)
1871 {
1872 assert(NULL != handle);
1873
1874 uint16_t transmitData = 0;
1875 uint8_t dummyPattern = DSPI_GetDummyDataInstance(base);
1876
1877 /* Service the transmitter, if transmit buffer provided, transmit the data,
1878 * else transmit dummy pattern
1879 */
1880 while ((uint32_t)kDSPI_TxFifoFillRequestFlag == (DSPI_GetStatusFlags(base) & (uint32_t)kDSPI_TxFifoFillRequestFlag))
1881 {
1882 /* Transmit data */
1883 if (handle->remainingSendByteCount > 0U)
1884 {
1885 /* Have data to transmit, update the transmit data and push to FIFO */
1886 if (handle->bitsPerFrame <= 8U)
1887 {
1888 /* bits/frame is 1 byte */
1889 if (NULL != handle->txData)
1890 {
1891 /* Update transmit data and transmit pointer */
1892 transmitData = *handle->txData;
1893 handle->txData++;
1894 }
1895 else
1896 {
1897 transmitData = dummyPattern;
1898 }
1899
1900 /* Decrease remaining dataSize */
1901 --handle->remainingSendByteCount;
1902 }
1903 /* bits/frame is 2 bytes */
1904 else
1905 {
1906 /* With multibytes per frame transmission, the transmit frame contains data from
1907 * transmit buffer until sent dataSize matches user request. Other bytes will set to
1908 * dummy pattern value.
1909 */
1910 if (NULL != handle->txData)
1911 {
1912 /* Update first byte of transmit data and transmit pointer */
1913 transmitData = *handle->txData;
1914 handle->txData++;
1915
1916 if (handle->remainingSendByteCount == 1U)
1917 {
1918 /* Decrease remaining dataSize */
1919 --handle->remainingSendByteCount;
1920 /* Update second byte of transmit data to second byte of dummy pattern */
1921 transmitData = transmitData | (uint16_t)(((uint16_t)dummyPattern) << 8U);
1922 }
1923 else
1924 {
1925 /* Update second byte of transmit data and transmit pointer */
1926 transmitData = transmitData | (uint16_t)((uint16_t)(*handle->txData) << 8U);
1927 handle->txData++;
1928 handle->remainingSendByteCount -= 2U;
1929 }
1930 }
1931 else
1932 {
1933 if (handle->remainingSendByteCount == 1U)
1934 {
1935 --handle->remainingSendByteCount;
1936 }
1937 else
1938 {
1939 handle->remainingSendByteCount -= 2U;
1940 }
1941 transmitData = (uint16_t)((uint16_t)(dummyPattern) << 8U) | dummyPattern;
1942 }
1943 }
1944 }
1945 else
1946 {
1947 break;
1948 }
1949
1950 /* Write the data to the DSPI data register */
1951 base->PUSHR_SLAVE = transmitData;
1952
1953 /* Try to clear TFFF by writing a one to it; it will not clear if TX FIFO not full */
1954 DSPI_ClearStatusFlags(base, (uint32_t)kDSPI_TxFifoFillRequestFlag);
1955 }
1956 }
1957 #endif
1958
1959 #if !(defined(FSL_FEATURE_DSPI_HAS_NO_SLAVE_SUPPORT) && FSL_FEATURE_DSPI_HAS_NO_SLAVE_SUPPORT)
DSPI_SlaveTransferComplete(SPI_Type * base,dspi_slave_handle_t * handle)1960 static void DSPI_SlaveTransferComplete(SPI_Type *base, dspi_slave_handle_t *handle)
1961 {
1962 assert(NULL != handle);
1963
1964 /* Disable interrupt requests */
1965 DSPI_DisableInterrupts(
1966 base, (
1967 #if !(defined(FSL_FEATURE_FLEXCAN_HAS_NO_RSER_TFUF_SUPPORT) && FSL_FEATURE_FLEXCAN_HAS_NO_RSER_TFUF_SUPPORT)
1968 (uint32_t)kDSPI_TxFifoUnderflowInterruptEnable |
1969 #endif
1970 (uint32_t)kDSPI_TxFifoFillRequestInterruptEnable |
1971 (uint32_t)kDSPI_RxFifoOverflowInterruptEnable | (uint32_t)kDSPI_RxFifoDrainRequestInterruptEnable));
1972
1973 /* The transfer is complete. */
1974 handle->txData = NULL;
1975 handle->rxData = NULL;
1976 handle->remainingReceiveByteCount = 0;
1977 handle->remainingSendByteCount = 0;
1978
1979 status_t status;
1980 if (handle->state == (uint8_t)kDSPI_Error)
1981 {
1982 status = kStatus_DSPI_Error;
1983 }
1984 else
1985 {
1986 status = kStatus_Success;
1987 }
1988
1989 handle->state = (uint8_t)kDSPI_Idle;
1990
1991 if (NULL != handle->callback)
1992 {
1993 handle->callback(base, handle, status, handle->userData);
1994 }
1995 }
1996 #endif
1997
1998 #if !(defined(FSL_FEATURE_DSPI_HAS_NO_SLAVE_SUPPORT) && FSL_FEATURE_DSPI_HAS_NO_SLAVE_SUPPORT)
1999 /*!
2000 * brief DSPI slave aborts a transfer using an interrupt.
2001 *
2002 * This function aborts a transfer using an interrupt.
2003 *
2004 * param base DSPI peripheral base address.
2005 * param handle Pointer to the dspi_slave_handle_t structure which stores the transfer state.
2006 */
DSPI_SlaveTransferAbort(SPI_Type * base,dspi_slave_handle_t * handle)2007 void DSPI_SlaveTransferAbort(SPI_Type *base, dspi_slave_handle_t *handle)
2008 {
2009 assert(NULL != handle);
2010
2011 DSPI_StopTransfer(base);
2012
2013 /* Disable interrupt requests */
2014 DSPI_DisableInterrupts(
2015 base, (
2016 #if !(defined(FSL_FEATURE_FLEXCAN_HAS_NO_RSER_TFUF_SUPPORT) && FSL_FEATURE_FLEXCAN_HAS_NO_RSER_TFUF_SUPPORT)
2017 (uint32_t)kDSPI_TxFifoUnderflowInterruptEnable |
2018 #endif
2019 (uint32_t)kDSPI_TxFifoFillRequestInterruptEnable |
2020 (uint32_t)kDSPI_RxFifoOverflowInterruptEnable | (uint32_t)kDSPI_RxFifoDrainRequestInterruptEnable));
2021
2022 handle->state = (uint8_t)kDSPI_Idle;
2023 handle->remainingSendByteCount = 0;
2024 handle->remainingReceiveByteCount = 0;
2025 }
2026 #endif
2027
2028 #if !(defined(FSL_FEATURE_DSPI_HAS_NO_SLAVE_SUPPORT) && FSL_FEATURE_DSPI_HAS_NO_SLAVE_SUPPORT)
2029 /*!
2030 * brief DSPI Master IRQ handler function.
2031 *
2032 * This function processes the DSPI transmit and receive IRQ.
2033 *
2034 * param base DSPI peripheral base address.
2035 * param handle Pointer to the dspi_slave_handle_t structure which stores the transfer state.
2036 */
DSPI_SlaveTransferHandleIRQ(SPI_Type * base,dspi_slave_handle_t * handle)2037 void DSPI_SlaveTransferHandleIRQ(SPI_Type *base, dspi_slave_handle_t *handle)
2038 {
2039 assert(NULL != handle);
2040
2041 uint8_t dummyPattern = DSPI_GetDummyDataInstance(base);
2042 uint32_t dataReceived;
2043 uint32_t dataSend = 0;
2044 uint32_t tmpRemainingReceiveByteCount = 0;
2045
2046 /* Because SPI protocol is synchronous, the number of bytes that that slave received from the
2047 * master is the actual number of bytes that the slave transmitted to the master. So we only
2048 * monitor the received dataSize to know when the transfer is complete.
2049 */
2050 if (handle->remainingReceiveByteCount > 0U)
2051 {
2052 while ((uint32_t)kDSPI_RxFifoDrainRequestFlag ==
2053 (DSPI_GetStatusFlags(base) & (uint32_t)kDSPI_RxFifoDrainRequestFlag))
2054 {
2055 /* Have received data in the buffer. */
2056 dataReceived = base->POPR;
2057 /*Clear the rx fifo drain request, needed for non-DMA applications as this flag
2058 * will remain set even if the rx fifo is empty. By manually clearing this flag, it
2059 * either remain clear if no more data is in the fifo, or it will set if there is
2060 * more data in the fifo.
2061 */
2062 DSPI_ClearStatusFlags(base, (uint32_t)kDSPI_RxFifoDrainRequestFlag);
2063
2064 /* If bits/frame is one byte */
2065 if (handle->bitsPerFrame <= 8U)
2066 {
2067 if (NULL != handle->rxData)
2068 {
2069 /* Receive buffer is not null, store data into it */
2070 *handle->rxData = (uint8_t)dataReceived;
2071 ++handle->rxData;
2072 }
2073 /* Descrease remaining receive byte count */
2074 --handle->remainingReceiveByteCount;
2075
2076 if (handle->remainingSendByteCount > 0U)
2077 {
2078 if (NULL != handle->txData)
2079 {
2080 dataSend = *handle->txData;
2081 ++handle->txData;
2082 }
2083 else
2084 {
2085 dataSend = dummyPattern;
2086 }
2087
2088 --handle->remainingSendByteCount;
2089 /* Write the data to the DSPI data register */
2090 base->PUSHR_SLAVE = dataSend;
2091 }
2092 }
2093 else /* If bits/frame is 2 bytes */
2094 {
2095 /* With multibytes frame receiving, we only receive till the received dataSize
2096 * matches user request. Other bytes will be ignored.
2097 */
2098 if (NULL != handle->rxData)
2099 {
2100 /* Receive buffer is not null, store first byte into it */
2101 *handle->rxData = (uint8_t)dataReceived;
2102 ++handle->rxData;
2103
2104 if (handle->remainingReceiveByteCount == 1U)
2105 {
2106 /* Decrease remaining receive byte count */
2107 --handle->remainingReceiveByteCount;
2108 }
2109 else
2110 {
2111 /* Receive buffer is not null, store second byte into it */
2112 *handle->rxData = (uint8_t)(dataReceived >> 8U);
2113 ++handle->rxData;
2114 handle->remainingReceiveByteCount -= 2U;
2115 }
2116 }
2117 /* If no handle->rxData*/
2118 else
2119 {
2120 if (handle->remainingReceiveByteCount == 1U)
2121 {
2122 /* Decrease remaining receive byte count */
2123 --handle->remainingReceiveByteCount;
2124 }
2125 else
2126 {
2127 handle->remainingReceiveByteCount -= 2U;
2128 }
2129 }
2130
2131 if (handle->remainingSendByteCount > 0U)
2132 {
2133 if (NULL != handle->txData)
2134 {
2135 dataSend = *handle->txData;
2136 ++handle->txData;
2137
2138 if (handle->remainingSendByteCount == 1U)
2139 {
2140 --handle->remainingSendByteCount;
2141 dataSend |= (uint16_t)((uint16_t)(dummyPattern) << 8U);
2142 }
2143 else
2144 {
2145 dataSend |= (uint32_t)(*handle->txData) << 8U;
2146 ++handle->txData;
2147 handle->remainingSendByteCount -= 2U;
2148 }
2149 }
2150 /* If no handle->txData*/
2151 else
2152 {
2153 if (handle->remainingSendByteCount == 1U)
2154 {
2155 --handle->remainingSendByteCount;
2156 }
2157 else
2158 {
2159 handle->remainingSendByteCount -= 2U;
2160 }
2161 dataSend = ((uint32_t)(dummyPattern) << 8U) | dummyPattern;
2162 }
2163 /* Write the data to the DSPI data register */
2164 base->PUSHR_SLAVE = dataSend;
2165 }
2166 }
2167 /* Try to clear TFFF by writing a one to it; it will not clear if TX FIFO not full */
2168 DSPI_ClearStatusFlags(base, (uint32_t)kDSPI_TxFifoFillRequestFlag);
2169
2170 if (handle->remainingReceiveByteCount == 0U)
2171 {
2172 break;
2173 }
2174 }
2175 }
2176 /* Check if remaining receive byte count matches user request */
2177 tmpRemainingReceiveByteCount = handle->remainingReceiveByteCount;
2178 if ((handle->state == (uint8_t)(kDSPI_Error)) || (tmpRemainingReceiveByteCount == 0U))
2179 {
2180 /* Other cases, stop the transfer. */
2181 DSPI_SlaveTransferComplete(base, handle);
2182 return;
2183 }
2184
2185 #if !(defined(FSL_FEATURE_DSPI_HAS_NO_SR_TFUF_SUPPORT) && FSL_FEATURE_DSPI_HAS_NO_SR_TFUF_SUPPORT)
2186 /* Catch tx fifo underflow conditions, service only if tx under flow interrupt enabled */
2187 if (0U != (DSPI_GetStatusFlags(base) & (uint32_t)kDSPI_TxFifoUnderflowFlag))
2188 {
2189 if (0U != (base->RSER & SPI_RSER_TFUF_RE_MASK))
2190 {
2191 DSPI_ClearStatusFlags(base, (uint32_t)kDSPI_TxFifoUnderflowFlag);
2192 /* Change state to error and clear flag */
2193 if (NULL != handle->txData)
2194 {
2195 handle->state = (uint8_t)kDSPI_Error;
2196 }
2197 handle->errorCount++;
2198 }
2199 }
2200 #endif
2201
2202 /* Catch rx fifo overflow conditions, service only if rx over flow interrupt enabled */
2203 if (0U != (DSPI_GetStatusFlags(base) & (uint32_t)kDSPI_RxFifoOverflowFlag))
2204 {
2205 if (0U != (base->RSER & SPI_RSER_RFOF_RE_MASK))
2206 {
2207 DSPI_ClearStatusFlags(base, (uint32_t)kDSPI_RxFifoOverflowFlag);
2208 /* Change state to error and clear flag */
2209 if (NULL != handle->txData)
2210 {
2211 handle->state = (uint8_t)kDSPI_Error;
2212 }
2213 handle->errorCount++;
2214 }
2215 }
2216 }
2217 #endif
2218
DSPI_CommonIRQHandler(SPI_Type * base,void * param)2219 static void DSPI_CommonIRQHandler(SPI_Type *base, void *param)
2220 {
2221 if (DSPI_IsMaster(base))
2222 {
2223 s_dspiMasterIsr(base, (dspi_master_handle_t *)param);
2224 }
2225 #if !(defined(FSL_FEATURE_DSPI_HAS_NO_SLAVE_SUPPORT) && FSL_FEATURE_DSPI_HAS_NO_SLAVE_SUPPORT)
2226 else
2227 {
2228 s_dspiSlaveIsr(base, (dspi_slave_handle_t *)param);
2229 }
2230 #endif
2231 SDK_ISR_EXIT_BARRIER;
2232 }
2233
2234 #if defined(SPI0)
2235 void SPI0_DriverIRQHandler(void);
SPI0_DriverIRQHandler(void)2236 void SPI0_DriverIRQHandler(void)
2237 {
2238 assert(NULL != g_dspiHandle[0]);
2239 DSPI_CommonIRQHandler(SPI0, g_dspiHandle[0]);
2240 }
2241 #endif
2242
2243 #if defined(SPI1)
2244 void SPI1_DriverIRQHandler(void);
SPI1_DriverIRQHandler(void)2245 void SPI1_DriverIRQHandler(void)
2246 {
2247 assert(NULL != g_dspiHandle[1]);
2248 DSPI_CommonIRQHandler(SPI1, g_dspiHandle[1]);
2249 }
2250 #endif
2251
2252 #if defined(SPI2)
2253 void SPI2_DriverIRQHandler(void);
SPI2_DriverIRQHandler(void)2254 void SPI2_DriverIRQHandler(void)
2255 {
2256 assert(NULL != g_dspiHandle[2]);
2257 DSPI_CommonIRQHandler(SPI2, g_dspiHandle[2]);
2258 }
2259 #endif
2260
2261 #if defined(SPI3)
2262 void SPI3_DriverIRQHandler(void);
SPI3_DriverIRQHandler(void)2263 void SPI3_DriverIRQHandler(void)
2264 {
2265 assert(NULL != g_dspiHandle[3]);
2266 DSPI_CommonIRQHandler(SPI3, g_dspiHandle[3]);
2267 }
2268 #endif
2269
2270 #if defined(SPI4)
2271 void SPI4_DriverIRQHandler(void);
SPI4_DriverIRQHandler(void)2272 void SPI4_DriverIRQHandler(void)
2273 {
2274 assert(NULL != g_dspiHandle[4]);
2275 DSPI_CommonIRQHandler(SPI4, g_dspiHandle[4]);
2276 }
2277 #endif
2278
2279 #if defined(SPI5)
2280 void SPI5_DriverIRQHandler(void);
SPI5_DriverIRQHandler(void)2281 void SPI5_DriverIRQHandler(void)
2282 {
2283 assert(NULL != g_dspiHandle[5]);
2284 DSPI_CommonIRQHandler(SPI5, g_dspiHandle[5]);
2285 }
2286 #endif
2287
2288 #if (FSL_FEATURE_SOC_DSPI_COUNT > 6)
2289 #error "Should write the SPIx_DriverIRQHandler function that instance greater than 5 !"
2290 #endif
2291