1 /*
2 * Copyright (c) 2015, Freescale Semiconductor, Inc.
3 * Copyright 2016-2020, 2022 NXP
4 * All rights reserved.
5 *
6 * SPDX-License-Identifier: BSD-3-Clause
7 */
8
9 #include "fsl_flexio_spi.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.flexio_spi"
18 #endif
19
20 /*! @brief FLEXIO SPI transfer state, which is used for SPI transactiaonl APIs' internal state. */
21 enum _flexio_spi_transfer_states
22 {
23 kFLEXIO_SPI_Idle = 0x0U, /*!< Nothing in the transmitter/receiver's queue. */
24 kFLEXIO_SPI_Busy, /*!< Transmiter/Receive's queue is not finished. */
25 };
26
27 /*******************************************************************************
28 * Prototypes
29 ******************************************************************************/
30
31 /*!
32 * @brief Send a piece of data for SPI.
33 *
34 * This function computes the number of data to be written into D register or Tx FIFO,
35 * and write the data into it. At the same time, this function updates the values in
36 * master handle structure.
37 *
38 * @param base pointer to FLEXIO_SPI_Type structure
39 * @param handle Pointer to SPI master handle structure.
40 */
41 static void FLEXIO_SPI_TransferSendTransaction(FLEXIO_SPI_Type *base, flexio_spi_master_handle_t *handle);
42
43 /*!
44 * @brief Receive a piece of data for SPI master.
45 *
46 * This function computes the number of data to receive from D register or Rx FIFO,
47 * and write the data to destination address. At the same time, this function updates
48 * the values in master handle structure.
49 *
50 * @param base pointer to FLEXIO_SPI_Type structure
51 * @param handle Pointer to SPI master handle structure.
52 */
53 static void FLEXIO_SPI_TransferReceiveTransaction(FLEXIO_SPI_Type *base, flexio_spi_master_handle_t *handle);
54
55 /*******************************************************************************
56 * Variables
57 ******************************************************************************/
58
59 /*******************************************************************************
60 * Codes
61 ******************************************************************************/
62
FLEXIO_SPI_GetInstance(FLEXIO_SPI_Type * base)63 static uint32_t FLEXIO_SPI_GetInstance(FLEXIO_SPI_Type *base)
64 {
65 return FLEXIO_GetInstance(base->flexioBase);
66 }
67
FLEXIO_SPI_TransferSendTransaction(FLEXIO_SPI_Type * base,flexio_spi_master_handle_t * handle)68 static void FLEXIO_SPI_TransferSendTransaction(FLEXIO_SPI_Type *base, flexio_spi_master_handle_t *handle)
69 {
70 uint32_t tmpData = FLEXIO_SPI_DUMMYDATA;
71
72 if (handle->txData != NULL)
73 {
74 /* Transmit data and update tx size/buff. */
75 if (handle->bytePerFrame == 1U)
76 {
77 tmpData = (uint32_t) * (handle->txData);
78 handle->txData++;
79 }
80 else if (handle->bytePerFrame == 2U)
81 {
82 if (handle->direction == kFLEXIO_SPI_MsbFirst)
83 {
84 tmpData = (uint32_t)(handle->txData[0]) << 8U;
85 tmpData += (uint32_t)handle->txData[1];
86 }
87 else
88 {
89 tmpData = (uint32_t)(handle->txData[1]) << 8U;
90 tmpData += (uint32_t)handle->txData[0];
91 }
92 handle->txData += 2U;
93 }
94 else
95 {
96 if (handle->direction == kFLEXIO_SPI_MsbFirst)
97 {
98 tmpData = (uint32_t)(handle->txData[0]) << 24U;
99 tmpData += (uint32_t)(handle->txData[1]) << 16U;
100 tmpData += (uint32_t)(handle->txData[2]) << 8U;
101 tmpData += (uint32_t)handle->txData[3];
102 }
103 else
104 {
105 tmpData = (uint32_t)(handle->txData[3]) << 24U;
106 tmpData += (uint32_t)(handle->txData[2]) << 16U;
107 tmpData += (uint32_t)(handle->txData[1]) << 8U;
108 tmpData += (uint32_t)handle->txData[0];
109 }
110 handle->txData += 4U;
111 }
112 }
113 else
114 {
115 tmpData = FLEXIO_SPI_DUMMYDATA;
116 }
117
118 handle->txRemainingBytes -= handle->bytePerFrame;
119
120 FLEXIO_SPI_WriteData(base, handle->direction, tmpData);
121
122 if (0U == handle->txRemainingBytes)
123 {
124 FLEXIO_SPI_DisableInterrupts(base, (uint32_t)kFLEXIO_SPI_TxEmptyInterruptEnable);
125 }
126 }
127
FLEXIO_SPI_TransferReceiveTransaction(FLEXIO_SPI_Type * base,flexio_spi_master_handle_t * handle)128 static void FLEXIO_SPI_TransferReceiveTransaction(FLEXIO_SPI_Type *base, flexio_spi_master_handle_t *handle)
129 {
130 uint32_t tmpData;
131
132 tmpData = FLEXIO_SPI_ReadData(base, handle->direction);
133
134 if (handle->rxData != NULL)
135 {
136 if (handle->bytePerFrame == 1U)
137 {
138 *handle->rxData = (uint8_t)tmpData;
139 }
140 else if (handle->bytePerFrame == 2U)
141 {
142 if (handle->direction == kFLEXIO_SPI_LsbFirst)
143 {
144 *handle->rxData = (uint8_t)(tmpData >> 8);
145 handle->rxData++;
146 *handle->rxData = (uint8_t)tmpData;
147 }
148 else
149 {
150 *handle->rxData = (uint8_t)tmpData;
151 handle->rxData++;
152 *handle->rxData = (uint8_t)(tmpData >> 8);
153 }
154 }
155 else
156 {
157 if (handle->direction == kFLEXIO_SPI_LsbFirst)
158 {
159 *handle->rxData = (uint8_t)(tmpData >> 24U);
160 handle->rxData++;
161 *handle->rxData = (uint8_t)(tmpData >> 16U);
162 handle->rxData++;
163 *handle->rxData = (uint8_t)(tmpData >> 8U);
164 handle->rxData++;
165 *handle->rxData = (uint8_t)tmpData;
166 }
167 else
168 {
169 *handle->rxData = (uint8_t)tmpData;
170 handle->rxData++;
171 *handle->rxData = (uint8_t)(tmpData >> 8U);
172 handle->rxData++;
173 *handle->rxData = (uint8_t)(tmpData >> 16U);
174 handle->rxData++;
175 *handle->rxData = (uint8_t)(tmpData >> 24U);
176 }
177 }
178 handle->rxData++;
179 }
180 handle->rxRemainingBytes -= handle->bytePerFrame;
181 }
182
183 /*!
184 * brief Ungates the FlexIO clock, resets the FlexIO module, configures the FlexIO SPI master hardware,
185 * and configures the FlexIO SPI with FlexIO SPI master configuration. The
186 * configuration structure can be filled by the user, or be set with default values
187 * by the FLEXIO_SPI_MasterGetDefaultConfig().
188 *
189 * note 1.FlexIO SPI master only support CPOL = 0, which means clock inactive low.
190 * 2.For FlexIO SPI master, the input valid time is 1.5 clock cycles, for slave the output valid time
191 * is 2.5 clock cycles. So if FlexIO SPI master communicates with other spi IPs, the maximum baud
192 * rate is FlexIO clock frequency divided by 2*2=4. If FlexIO SPI master communicates with FlexIO
193 * SPI slave, the maximum baud rate is FlexIO clock frequency divided by (1.5+2.5)*2=8.
194 *
195 * Example
196 code
197 FLEXIO_SPI_Type spiDev = {
198 .flexioBase = FLEXIO,
199 .SDOPinIndex = 0,
200 .SDIPinIndex = 1,
201 .SCKPinIndex = 2,
202 .CSnPinIndex = 3,
203 .shifterIndex = {0,1},
204 .timerIndex = {0,1}
205 };
206 flexio_spi_master_config_t config = {
207 .enableMaster = true,
208 .enableInDoze = false,
209 .enableInDebug = true,
210 .enableFastAccess = false,
211 .baudRate_Bps = 500000,
212 .phase = kFLEXIO_SPI_ClockPhaseFirstEdge,
213 .direction = kFLEXIO_SPI_MsbFirst,
214 .dataMode = kFLEXIO_SPI_8BitMode
215 };
216 FLEXIO_SPI_MasterInit(&spiDev, &config, srcClock_Hz);
217 endcode
218 *
219 * param base Pointer to the FLEXIO_SPI_Type structure.
220 * param masterConfig Pointer to the flexio_spi_master_config_t structure.
221 * param srcClock_Hz FlexIO source clock in Hz.
222 */
FLEXIO_SPI_MasterInit(FLEXIO_SPI_Type * base,flexio_spi_master_config_t * masterConfig,uint32_t srcClock_Hz)223 void FLEXIO_SPI_MasterInit(FLEXIO_SPI_Type *base, flexio_spi_master_config_t *masterConfig, uint32_t srcClock_Hz)
224 {
225 assert(base != NULL);
226 assert(masterConfig != NULL);
227
228 flexio_shifter_config_t shifterConfig;
229 flexio_timer_config_t timerConfig;
230 uint32_t ctrlReg = 0;
231 uint16_t timerDiv = 0;
232 uint16_t timerCmp = 0;
233
234 /* Clear the shifterConfig & timerConfig struct. */
235 (void)memset(&shifterConfig, 0, sizeof(shifterConfig));
236 (void)memset(&timerConfig, 0, sizeof(timerConfig));
237
238 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
239 /* Ungate flexio clock. */
240 CLOCK_EnableClock(s_flexioClocks[FLEXIO_SPI_GetInstance(base)]);
241 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
242
243 /* Configure FLEXIO SPI Master */
244 ctrlReg = base->flexioBase->CTRL;
245 ctrlReg &= ~(FLEXIO_CTRL_DOZEN_MASK | FLEXIO_CTRL_DBGE_MASK | FLEXIO_CTRL_FASTACC_MASK | FLEXIO_CTRL_FLEXEN_MASK);
246 ctrlReg |= (FLEXIO_CTRL_DBGE(masterConfig->enableInDebug) | FLEXIO_CTRL_FASTACC(masterConfig->enableFastAccess) |
247 FLEXIO_CTRL_FLEXEN(masterConfig->enableMaster));
248 if (!masterConfig->enableInDoze)
249 {
250 ctrlReg |= FLEXIO_CTRL_DOZEN_MASK;
251 }
252
253 base->flexioBase->CTRL = ctrlReg;
254
255 /* Do hardware configuration. */
256 /* 1. Configure the shifter 0 for tx. */
257 shifterConfig.timerSelect = base->timerIndex[0];
258 shifterConfig.pinConfig = kFLEXIO_PinConfigOutput;
259 shifterConfig.pinSelect = base->SDOPinIndex;
260 shifterConfig.pinPolarity = kFLEXIO_PinActiveHigh;
261 shifterConfig.shifterMode = kFLEXIO_ShifterModeTransmit;
262 shifterConfig.inputSource = kFLEXIO_ShifterInputFromPin;
263 if (masterConfig->phase == kFLEXIO_SPI_ClockPhaseFirstEdge)
264 {
265 shifterConfig.timerPolarity = kFLEXIO_ShifterTimerPolarityOnNegitive;
266 shifterConfig.shifterStop = kFLEXIO_ShifterStopBitDisable;
267 shifterConfig.shifterStart = kFLEXIO_ShifterStartBitDisabledLoadDataOnEnable;
268 }
269 else
270 {
271 shifterConfig.timerPolarity = kFLEXIO_ShifterTimerPolarityOnPositive;
272 shifterConfig.shifterStop = kFLEXIO_ShifterStopBitLow;
273 shifterConfig.shifterStart = kFLEXIO_ShifterStartBitDisabledLoadDataOnShift;
274 }
275
276 FLEXIO_SetShifterConfig(base->flexioBase, base->shifterIndex[0], &shifterConfig);
277
278 /* 2. Configure the shifter 1 for rx. */
279 shifterConfig.timerSelect = base->timerIndex[0];
280 shifterConfig.pinConfig = kFLEXIO_PinConfigOutputDisabled;
281 shifterConfig.pinSelect = base->SDIPinIndex;
282 shifterConfig.pinPolarity = kFLEXIO_PinActiveHigh;
283 shifterConfig.shifterMode = kFLEXIO_ShifterModeReceive;
284 shifterConfig.inputSource = kFLEXIO_ShifterInputFromPin;
285 shifterConfig.shifterStop = kFLEXIO_ShifterStopBitDisable;
286 shifterConfig.shifterStart = kFLEXIO_ShifterStartBitDisabledLoadDataOnEnable;
287 if (masterConfig->phase == kFLEXIO_SPI_ClockPhaseFirstEdge)
288 {
289 shifterConfig.timerPolarity = kFLEXIO_ShifterTimerPolarityOnPositive;
290 }
291 else
292 {
293 shifterConfig.timerPolarity = kFLEXIO_ShifterTimerPolarityOnNegitive;
294 }
295
296 FLEXIO_SetShifterConfig(base->flexioBase, base->shifterIndex[1], &shifterConfig);
297
298 /*3. Configure the timer 0 for SCK. */
299 timerConfig.triggerSelect = FLEXIO_TIMER_TRIGGER_SEL_SHIFTnSTAT(base->shifterIndex[0]);
300 timerConfig.triggerPolarity = kFLEXIO_TimerTriggerPolarityActiveLow;
301 timerConfig.triggerSource = kFLEXIO_TimerTriggerSourceInternal;
302 timerConfig.pinConfig = kFLEXIO_PinConfigOutput;
303 timerConfig.pinSelect = base->SCKPinIndex;
304 timerConfig.pinPolarity = kFLEXIO_PinActiveHigh;
305 timerConfig.timerMode = kFLEXIO_TimerModeDual8BitBaudBit;
306 timerConfig.timerOutput = kFLEXIO_TimerOutputZeroNotAffectedByReset;
307 timerConfig.timerDecrement = kFLEXIO_TimerDecSrcOnFlexIOClockShiftTimerOutput;
308 timerConfig.timerReset = kFLEXIO_TimerResetNever;
309 timerConfig.timerDisable = kFLEXIO_TimerDisableOnTimerCompare;
310 timerConfig.timerEnable = kFLEXIO_TimerEnableOnTriggerHigh;
311 timerConfig.timerStop = kFLEXIO_TimerStopBitEnableOnTimerDisable;
312 timerConfig.timerStart = kFLEXIO_TimerStartBitEnabled;
313 /* Low 8-bits are used to configure baudrate. */
314 timerDiv = (uint16_t)(srcClock_Hz / masterConfig->baudRate_Bps);
315 timerDiv = timerDiv / 2U - 1U;
316 /* High 8-bits are used to configure shift clock edges(transfer width). */
317 timerCmp = ((uint16_t)masterConfig->dataMode * 2U - 1U) << 8U;
318 timerCmp |= timerDiv;
319
320 timerConfig.timerCompare = timerCmp;
321
322 FLEXIO_SetTimerConfig(base->flexioBase, base->timerIndex[0], &timerConfig);
323
324 /* 4. Configure the timer 1 for CSn. */
325 timerConfig.triggerSelect = FLEXIO_TIMER_TRIGGER_SEL_TIMn(base->timerIndex[0]);
326 timerConfig.triggerPolarity = kFLEXIO_TimerTriggerPolarityActiveHigh;
327 timerConfig.triggerSource = kFLEXIO_TimerTriggerSourceInternal;
328 timerConfig.pinConfig = kFLEXIO_PinConfigOutput;
329 timerConfig.pinSelect = base->CSnPinIndex;
330 timerConfig.pinPolarity = kFLEXIO_PinActiveLow;
331 timerConfig.timerMode = kFLEXIO_TimerModeSingle16Bit;
332 timerConfig.timerOutput = kFLEXIO_TimerOutputOneNotAffectedByReset;
333 timerConfig.timerDecrement = kFLEXIO_TimerDecSrcOnFlexIOClockShiftTimerOutput;
334 timerConfig.timerReset = kFLEXIO_TimerResetNever;
335 timerConfig.timerDisable = kFLEXIO_TimerDisableOnPreTimerDisable;
336 timerConfig.timerEnable = kFLEXIO_TimerEnableOnPrevTimerEnable;
337 timerConfig.timerStop = kFLEXIO_TimerStopBitDisabled;
338 timerConfig.timerStart = kFLEXIO_TimerStartBitDisabled;
339
340 timerConfig.timerCompare = 0xFFFFU; /* Never compare. */
341
342 FLEXIO_SetTimerConfig(base->flexioBase, base->timerIndex[1], &timerConfig);
343 }
344
345 /*!
346 * brief Resets the FlexIO SPI timer and shifter config.
347 *
348 * param base Pointer to the FLEXIO_SPI_Type.
349 */
FLEXIO_SPI_MasterDeinit(FLEXIO_SPI_Type * base)350 void FLEXIO_SPI_MasterDeinit(FLEXIO_SPI_Type *base)
351 {
352 base->flexioBase->SHIFTCFG[base->shifterIndex[0]] = 0;
353 base->flexioBase->SHIFTCTL[base->shifterIndex[0]] = 0;
354 base->flexioBase->SHIFTCFG[base->shifterIndex[1]] = 0;
355 base->flexioBase->SHIFTCTL[base->shifterIndex[1]] = 0;
356 base->flexioBase->TIMCFG[base->timerIndex[0]] = 0;
357 base->flexioBase->TIMCMP[base->timerIndex[0]] = 0;
358 base->flexioBase->TIMCTL[base->timerIndex[0]] = 0;
359 base->flexioBase->TIMCFG[base->timerIndex[1]] = 0;
360 base->flexioBase->TIMCMP[base->timerIndex[1]] = 0;
361 base->flexioBase->TIMCTL[base->timerIndex[1]] = 0;
362 }
363
364 /*!
365 * brief Gets the default configuration to configure the FlexIO SPI master. The configuration
366 * can be used directly by calling the FLEXIO_SPI_MasterConfigure().
367 * Example:
368 code
369 flexio_spi_master_config_t masterConfig;
370 FLEXIO_SPI_MasterGetDefaultConfig(&masterConfig);
371 endcode
372 * param masterConfig Pointer to the flexio_spi_master_config_t structure.
373 */
FLEXIO_SPI_MasterGetDefaultConfig(flexio_spi_master_config_t * masterConfig)374 void FLEXIO_SPI_MasterGetDefaultConfig(flexio_spi_master_config_t *masterConfig)
375 {
376 assert(masterConfig != NULL);
377
378 /* Initializes the configure structure to zero. */
379 (void)memset(masterConfig, 0, sizeof(*masterConfig));
380
381 masterConfig->enableMaster = true;
382 masterConfig->enableInDoze = false;
383 masterConfig->enableInDebug = true;
384 masterConfig->enableFastAccess = false;
385 /* Default baud rate 500kbps. */
386 masterConfig->baudRate_Bps = 500000U;
387 /* Default CPHA = 0. */
388 masterConfig->phase = kFLEXIO_SPI_ClockPhaseFirstEdge;
389 /* Default bit count at 8. */
390 masterConfig->dataMode = kFLEXIO_SPI_8BitMode;
391 }
392
393 /*!
394 * brief Ungates the FlexIO clock, resets the FlexIO module, configures the FlexIO SPI slave hardware
395 * configuration, and configures the FlexIO SPI with FlexIO SPI slave configuration. The
396 * configuration structure can be filled by the user, or be set with default values
397 * by the FLEXIO_SPI_SlaveGetDefaultConfig().
398 *
399 * note 1.Only one timer is needed in the FlexIO SPI slave. As a result, the second timer index is ignored.
400 * 2.FlexIO SPI slave only support CPOL = 0, which means clock inactive low.
401 * 3.For FlexIO SPI master, the input valid time is 1.5 clock cycles, for slave the output valid time
402 * is 2.5 clock cycles. So if FlexIO SPI slave communicates with other spi IPs, the maximum baud
403 * rate is FlexIO clock frequency divided by 3*2=6. If FlexIO SPI slave communicates with FlexIO
404 * SPI master, the maximum baud rate is FlexIO clock frequency divided by (1.5+2.5)*2=8.
405 * Example
406 code
407 FLEXIO_SPI_Type spiDev = {
408 .flexioBase = FLEXIO,
409 .SDOPinIndex = 0,
410 .SDIPinIndex = 1,
411 .SCKPinIndex = 2,
412 .CSnPinIndex = 3,
413 .shifterIndex = {0,1},
414 .timerIndex = {0}
415 };
416 flexio_spi_slave_config_t config = {
417 .enableSlave = true,
418 .enableInDoze = false,
419 .enableInDebug = true,
420 .enableFastAccess = false,
421 .phase = kFLEXIO_SPI_ClockPhaseFirstEdge,
422 .direction = kFLEXIO_SPI_MsbFirst,
423 .dataMode = kFLEXIO_SPI_8BitMode
424 };
425 FLEXIO_SPI_SlaveInit(&spiDev, &config);
426 endcode
427 * param base Pointer to the FLEXIO_SPI_Type structure.
428 * param slaveConfig Pointer to the flexio_spi_slave_config_t structure.
429 */
FLEXIO_SPI_SlaveInit(FLEXIO_SPI_Type * base,flexio_spi_slave_config_t * slaveConfig)430 void FLEXIO_SPI_SlaveInit(FLEXIO_SPI_Type *base, flexio_spi_slave_config_t *slaveConfig)
431 {
432 assert((base != NULL) && (slaveConfig != NULL));
433
434 flexio_shifter_config_t shifterConfig;
435 flexio_timer_config_t timerConfig;
436 uint32_t ctrlReg = 0;
437
438 /* Clear the shifterConfig & timerConfig struct. */
439 (void)memset(&shifterConfig, 0, sizeof(shifterConfig));
440 (void)memset(&timerConfig, 0, sizeof(timerConfig));
441
442 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
443 /* Ungate flexio clock. */
444 CLOCK_EnableClock(s_flexioClocks[FLEXIO_SPI_GetInstance(base)]);
445 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
446
447 /* Configure FLEXIO SPI Slave */
448 ctrlReg = base->flexioBase->CTRL;
449 ctrlReg &= ~(FLEXIO_CTRL_DOZEN_MASK | FLEXIO_CTRL_DBGE_MASK | FLEXIO_CTRL_FASTACC_MASK | FLEXIO_CTRL_FLEXEN_MASK);
450 ctrlReg |= (FLEXIO_CTRL_DBGE(slaveConfig->enableInDebug) | FLEXIO_CTRL_FASTACC(slaveConfig->enableFastAccess) |
451 FLEXIO_CTRL_FLEXEN(slaveConfig->enableSlave));
452 if (!slaveConfig->enableInDoze)
453 {
454 ctrlReg |= FLEXIO_CTRL_DOZEN_MASK;
455 }
456
457 base->flexioBase->CTRL = ctrlReg;
458
459 /* Do hardware configuration. */
460 /* 1. Configure the shifter 0 for tx. */
461 shifterConfig.timerSelect = base->timerIndex[0];
462 shifterConfig.pinConfig = kFLEXIO_PinConfigOutput;
463 shifterConfig.pinSelect = base->SDOPinIndex;
464 shifterConfig.pinPolarity = kFLEXIO_PinActiveHigh;
465 shifterConfig.shifterMode = kFLEXIO_ShifterModeTransmit;
466 shifterConfig.inputSource = kFLEXIO_ShifterInputFromPin;
467 shifterConfig.shifterStop = kFLEXIO_ShifterStopBitDisable;
468 if (slaveConfig->phase == kFLEXIO_SPI_ClockPhaseFirstEdge)
469 {
470 shifterConfig.timerPolarity = kFLEXIO_ShifterTimerPolarityOnNegitive;
471 shifterConfig.shifterStart = kFLEXIO_ShifterStartBitDisabledLoadDataOnEnable;
472 }
473 else
474 {
475 shifterConfig.timerPolarity = kFLEXIO_ShifterTimerPolarityOnPositive;
476 shifterConfig.shifterStart = kFLEXIO_ShifterStartBitDisabledLoadDataOnShift;
477 }
478
479 FLEXIO_SetShifterConfig(base->flexioBase, base->shifterIndex[0], &shifterConfig);
480
481 /* 2. Configure the shifter 1 for rx. */
482 shifterConfig.timerSelect = base->timerIndex[0];
483 shifterConfig.pinConfig = kFLEXIO_PinConfigOutputDisabled;
484 shifterConfig.pinSelect = base->SDIPinIndex;
485 shifterConfig.pinPolarity = kFLEXIO_PinActiveHigh;
486 shifterConfig.shifterMode = kFLEXIO_ShifterModeReceive;
487 shifterConfig.inputSource = kFLEXIO_ShifterInputFromPin;
488 shifterConfig.shifterStop = kFLEXIO_ShifterStopBitDisable;
489 shifterConfig.shifterStart = kFLEXIO_ShifterStartBitDisabledLoadDataOnEnable;
490 if (slaveConfig->phase == kFLEXIO_SPI_ClockPhaseFirstEdge)
491 {
492 shifterConfig.timerPolarity = kFLEXIO_ShifterTimerPolarityOnPositive;
493 }
494 else
495 {
496 shifterConfig.timerPolarity = kFLEXIO_ShifterTimerPolarityOnNegitive;
497 }
498
499 FLEXIO_SetShifterConfig(base->flexioBase, base->shifterIndex[1], &shifterConfig);
500
501 /*3. Configure the timer 0 for shift clock. */
502 timerConfig.triggerSelect = FLEXIO_TIMER_TRIGGER_SEL_PININPUT(base->CSnPinIndex);
503 timerConfig.triggerPolarity = kFLEXIO_TimerTriggerPolarityActiveLow;
504 timerConfig.triggerSource = kFLEXIO_TimerTriggerSourceInternal;
505 timerConfig.pinConfig = kFLEXIO_PinConfigOutputDisabled;
506 timerConfig.pinSelect = base->SCKPinIndex;
507 timerConfig.pinPolarity = kFLEXIO_PinActiveHigh;
508 timerConfig.timerMode = kFLEXIO_TimerModeSingle16Bit;
509 timerConfig.timerOutput = kFLEXIO_TimerOutputZeroNotAffectedByReset;
510 timerConfig.timerDecrement = kFLEXIO_TimerDecSrcOnPinInputShiftPinInput;
511 timerConfig.timerReset = kFLEXIO_TimerResetNever;
512 timerConfig.timerEnable = kFLEXIO_TimerEnableOnTriggerRisingEdge;
513 timerConfig.timerStop = kFLEXIO_TimerStopBitDisabled;
514 if (slaveConfig->phase == kFLEXIO_SPI_ClockPhaseFirstEdge)
515 {
516 timerConfig.timerDisable = kFLEXIO_TimerDisableOnTimerCompare;
517 timerConfig.timerStart = kFLEXIO_TimerStartBitDisabled;
518 }
519 else
520 {
521 timerConfig.timerDisable = kFLEXIO_TimerDisableOnTriggerFallingEdge;
522 timerConfig.timerStart = kFLEXIO_TimerStartBitEnabled;
523 }
524
525 timerConfig.timerCompare = (uint32_t)slaveConfig->dataMode * 2U - 1U;
526
527 FLEXIO_SetTimerConfig(base->flexioBase, base->timerIndex[0], &timerConfig);
528 }
529
530 /*!
531 * brief Gates the FlexIO clock.
532 *
533 * param base Pointer to the FLEXIO_SPI_Type.
534 */
FLEXIO_SPI_SlaveDeinit(FLEXIO_SPI_Type * base)535 void FLEXIO_SPI_SlaveDeinit(FLEXIO_SPI_Type *base)
536 {
537 FLEXIO_SPI_MasterDeinit(base);
538 }
539
540 /*!
541 * brief Gets the default configuration to configure the FlexIO SPI slave. The configuration
542 * can be used directly for calling the FLEXIO_SPI_SlaveConfigure().
543 * Example:
544 code
545 flexio_spi_slave_config_t slaveConfig;
546 FLEXIO_SPI_SlaveGetDefaultConfig(&slaveConfig);
547 endcode
548 * param slaveConfig Pointer to the flexio_spi_slave_config_t structure.
549 */
FLEXIO_SPI_SlaveGetDefaultConfig(flexio_spi_slave_config_t * slaveConfig)550 void FLEXIO_SPI_SlaveGetDefaultConfig(flexio_spi_slave_config_t *slaveConfig)
551 {
552 assert(slaveConfig != NULL);
553
554 /* Initializes the configure structure to zero. */
555 (void)memset(slaveConfig, 0, sizeof(*slaveConfig));
556
557 slaveConfig->enableSlave = true;
558 slaveConfig->enableInDoze = false;
559 slaveConfig->enableInDebug = true;
560 slaveConfig->enableFastAccess = false;
561 /* Default CPHA = 0. */
562 slaveConfig->phase = kFLEXIO_SPI_ClockPhaseFirstEdge;
563 /* Default bit count at 8. */
564 slaveConfig->dataMode = kFLEXIO_SPI_8BitMode;
565 }
566
567 /*!
568 * brief Enables the FlexIO SPI interrupt.
569 *
570 * This function enables the FlexIO SPI interrupt.
571 *
572 * param base Pointer to the FLEXIO_SPI_Type structure.
573 * param mask interrupt source. The parameter can be any combination of the following values:
574 * arg kFLEXIO_SPI_RxFullInterruptEnable
575 * arg kFLEXIO_SPI_TxEmptyInterruptEnable
576 */
FLEXIO_SPI_EnableInterrupts(FLEXIO_SPI_Type * base,uint32_t mask)577 void FLEXIO_SPI_EnableInterrupts(FLEXIO_SPI_Type *base, uint32_t mask)
578 {
579 if ((mask & (uint32_t)kFLEXIO_SPI_TxEmptyInterruptEnable) != 0U)
580 {
581 FLEXIO_EnableShifterStatusInterrupts(base->flexioBase, 1UL << base->shifterIndex[0]);
582 }
583 if ((mask & (uint32_t)kFLEXIO_SPI_RxFullInterruptEnable) != 0U)
584 {
585 FLEXIO_EnableShifterStatusInterrupts(base->flexioBase, 1UL << base->shifterIndex[1]);
586 }
587 }
588
589 /*!
590 * brief Disables the FlexIO SPI interrupt.
591 *
592 * This function disables the FlexIO SPI interrupt.
593 *
594 * param base Pointer to the FLEXIO_SPI_Type structure.
595 * param mask interrupt source The parameter can be any combination of the following values:
596 * arg kFLEXIO_SPI_RxFullInterruptEnable
597 * arg kFLEXIO_SPI_TxEmptyInterruptEnable
598 */
FLEXIO_SPI_DisableInterrupts(FLEXIO_SPI_Type * base,uint32_t mask)599 void FLEXIO_SPI_DisableInterrupts(FLEXIO_SPI_Type *base, uint32_t mask)
600 {
601 if ((mask & (uint32_t)kFLEXIO_SPI_TxEmptyInterruptEnable) != 0U)
602 {
603 FLEXIO_DisableShifterStatusInterrupts(base->flexioBase, 1UL << base->shifterIndex[0]);
604 }
605 if ((mask & (uint32_t)kFLEXIO_SPI_RxFullInterruptEnable) != 0U)
606 {
607 FLEXIO_DisableShifterStatusInterrupts(base->flexioBase, 1UL << base->shifterIndex[1]);
608 }
609 }
610
611 /*!
612 * brief Enables/disables the FlexIO SPI transmit DMA. This function enables/disables the FlexIO SPI Tx DMA,
613 * which means that asserting the kFLEXIO_SPI_TxEmptyFlag does/doesn't trigger the DMA request.
614 *
615 * param base Pointer to the FLEXIO_SPI_Type structure.
616 * param mask SPI DMA source.
617 * param enable True means enable DMA, false means disable DMA.
618 */
FLEXIO_SPI_EnableDMA(FLEXIO_SPI_Type * base,uint32_t mask,bool enable)619 void FLEXIO_SPI_EnableDMA(FLEXIO_SPI_Type *base, uint32_t mask, bool enable)
620 {
621 if ((mask & (uint32_t)kFLEXIO_SPI_TxDmaEnable) != 0U)
622 {
623 FLEXIO_EnableShifterStatusDMA(base->flexioBase, 1UL << base->shifterIndex[0], enable);
624 }
625
626 if ((mask & (uint32_t)kFLEXIO_SPI_RxDmaEnable) != 0U)
627 {
628 FLEXIO_EnableShifterStatusDMA(base->flexioBase, 1UL << base->shifterIndex[1], enable);
629 }
630 }
631
632 /*!
633 * brief Gets FlexIO SPI status flags.
634 *
635 * param base Pointer to the FLEXIO_SPI_Type structure.
636 * return status flag; Use the status flag to AND the following flag mask and get the status.
637 * arg kFLEXIO_SPI_TxEmptyFlag
638 * arg kFLEXIO_SPI_RxEmptyFlag
639 */
640
FLEXIO_SPI_GetStatusFlags(FLEXIO_SPI_Type * base)641 uint32_t FLEXIO_SPI_GetStatusFlags(FLEXIO_SPI_Type *base)
642 {
643 uint32_t shifterStatus = FLEXIO_GetShifterStatusFlags(base->flexioBase);
644 uint32_t status = 0;
645
646 status = ((shifterStatus & (1UL << base->shifterIndex[0])) >> base->shifterIndex[0]);
647 status |= (((shifterStatus & (1UL << base->shifterIndex[1])) >> (base->shifterIndex[1])) << 1U);
648
649 return status;
650 }
651
652 /*!
653 * brief Clears FlexIO SPI status flags.
654 *
655 * param base Pointer to the FLEXIO_SPI_Type structure.
656 * param mask status flag
657 * The parameter can be any combination of the following values:
658 * arg kFLEXIO_SPI_TxEmptyFlag
659 * arg kFLEXIO_SPI_RxEmptyFlag
660 */
661
FLEXIO_SPI_ClearStatusFlags(FLEXIO_SPI_Type * base,uint32_t mask)662 void FLEXIO_SPI_ClearStatusFlags(FLEXIO_SPI_Type *base, uint32_t mask)
663 {
664 if ((mask & (uint32_t)kFLEXIO_SPI_TxBufferEmptyFlag) != 0U)
665 {
666 FLEXIO_ClearShifterStatusFlags(base->flexioBase, 1UL << base->shifterIndex[0]);
667 }
668 if ((mask & (uint32_t)kFLEXIO_SPI_RxBufferFullFlag) != 0U)
669 {
670 FLEXIO_ClearShifterStatusFlags(base->flexioBase, 1UL << base->shifterIndex[1]);
671 }
672 }
673
674 /*!
675 * brief Sets baud rate for the FlexIO SPI transfer, which is only used for the master.
676 *
677 * param base Pointer to the FLEXIO_SPI_Type structure.
678 * param baudRate_Bps Baud Rate needed in Hz.
679 * param srcClockHz SPI source clock frequency in Hz.
680 */
FLEXIO_SPI_MasterSetBaudRate(FLEXIO_SPI_Type * base,uint32_t baudRate_Bps,uint32_t srcClockHz)681 void FLEXIO_SPI_MasterSetBaudRate(FLEXIO_SPI_Type *base, uint32_t baudRate_Bps, uint32_t srcClockHz)
682 {
683 uint16_t timerDiv = 0;
684 uint16_t timerCmp = 0;
685 FLEXIO_Type *flexioBase = base->flexioBase;
686
687 /* Set TIMCMP[7:0] = (baud rate divider / 2) - 1.*/
688 timerDiv = (uint16_t)(srcClockHz / baudRate_Bps);
689 timerDiv = timerDiv / 2U - 1U;
690
691 timerCmp = (uint16_t)(flexioBase->TIMCMP[base->timerIndex[0]]);
692 timerCmp &= 0xFF00U;
693 timerCmp |= timerDiv;
694
695 flexioBase->TIMCMP[base->timerIndex[0]] = timerCmp;
696 }
697
698 /*!
699 * brief Sends a buffer of data bytes.
700 *
701 * note This function blocks using the polling method until all bytes have been sent.
702 *
703 * param base Pointer to the FLEXIO_SPI_Type structure.
704 * param direction Shift direction of MSB first or LSB first.
705 * param buffer The data bytes to send.
706 * param size The number of data bytes to send.
707 * retval kStatus_Success Successfully create the handle.
708 * retval kStatus_FLEXIO_SPI_Timeout The transfer timed out and was aborted.
709 */
FLEXIO_SPI_WriteBlocking(FLEXIO_SPI_Type * base,flexio_spi_shift_direction_t direction,const uint8_t * buffer,size_t size)710 status_t FLEXIO_SPI_WriteBlocking(FLEXIO_SPI_Type *base,
711 flexio_spi_shift_direction_t direction,
712 const uint8_t *buffer,
713 size_t size)
714 {
715 assert(buffer != NULL);
716 assert(size != 0U);
717
718 #if SPI_RETRY_TIMES
719 uint32_t waitTimes;
720 #endif
721
722 while (0U != size--)
723 {
724 /* Wait until data transfer complete. */
725 #if SPI_RETRY_TIMES
726 waitTimes = SPI_RETRY_TIMES;
727 while ((0U == (FLEXIO_SPI_GetStatusFlags(base) & (uint32_t)kFLEXIO_SPI_TxBufferEmptyFlag)) &&
728 (0U != --waitTimes))
729 #else
730 while (0U == (FLEXIO_SPI_GetStatusFlags(base) & (uint32_t)kFLEXIO_SPI_TxBufferEmptyFlag))
731 #endif
732 {
733 }
734 #if SPI_RETRY_TIMES
735 if (waitTimes == 0U)
736 {
737 return kStatus_FLEXIO_SPI_Timeout;
738 }
739 #endif
740 FLEXIO_SPI_WriteData(base, direction, *buffer++);
741 }
742
743 return kStatus_Success;
744 }
745
746 /*!
747 * brief Receives a buffer of bytes.
748 *
749 * note This function blocks using the polling method until all bytes have been received.
750 *
751 * param base Pointer to the FLEXIO_SPI_Type structure.
752 * param direction Shift direction of MSB first or LSB first.
753 * param buffer The buffer to store the received bytes.
754 * param size The number of data bytes to be received.
755 * param direction Shift direction of MSB first or LSB first.
756 * retval kStatus_Success Successfully create the handle.
757 * retval kStatus_FLEXIO_SPI_Timeout The transfer timed out and was aborted.
758 */
FLEXIO_SPI_ReadBlocking(FLEXIO_SPI_Type * base,flexio_spi_shift_direction_t direction,uint8_t * buffer,size_t size)759 status_t FLEXIO_SPI_ReadBlocking(FLEXIO_SPI_Type *base,
760 flexio_spi_shift_direction_t direction,
761 uint8_t *buffer,
762 size_t size)
763 {
764 assert(buffer != NULL);
765 assert(size != 0U);
766
767 #if SPI_RETRY_TIMES
768 uint32_t waitTimes;
769 #endif
770
771 while (0U != size--)
772 {
773 /* Wait until data transfer complete. */
774 #if SPI_RETRY_TIMES
775 waitTimes = SPI_RETRY_TIMES;
776 while ((0U == (FLEXIO_SPI_GetStatusFlags(base) & (uint32_t)kFLEXIO_SPI_RxBufferFullFlag)) &&
777 (0U != --waitTimes))
778 #else
779 while (0U == (FLEXIO_SPI_GetStatusFlags(base) & (uint32_t)kFLEXIO_SPI_RxBufferFullFlag))
780 #endif
781 {
782 }
783 #if SPI_RETRY_TIMES
784 if (waitTimes == 0U)
785 {
786 return kStatus_FLEXIO_SPI_Timeout;
787 }
788 #endif
789 *buffer++ = (uint8_t)FLEXIO_SPI_ReadData(base, direction);
790 }
791
792 return kStatus_Success;
793 }
794
795 /*!
796 * brief Receives a buffer of bytes.
797 *
798 * note This function blocks via polling until all bytes have been received.
799 *
800 * param base pointer to FLEXIO_SPI_Type structure
801 * param xfer FlexIO SPI transfer structure, see #flexio_spi_transfer_t.
802 * retval kStatus_Success Successfully create the handle.
803 * retval kStatus_FLEXIO_SPI_Timeout The transfer timed out and was aborted.
804 */
FLEXIO_SPI_MasterTransferBlocking(FLEXIO_SPI_Type * base,flexio_spi_transfer_t * xfer)805 status_t FLEXIO_SPI_MasterTransferBlocking(FLEXIO_SPI_Type *base, flexio_spi_transfer_t *xfer)
806 {
807 flexio_spi_shift_direction_t direction;
808 uint8_t bytesPerFrame;
809 uint32_t dataMode = 0;
810 uint16_t timerCmp = (uint16_t)(base->flexioBase->TIMCMP[base->timerIndex[0]]);
811 uint32_t tmpData = FLEXIO_SPI_DUMMYDATA;
812 uint8_t dataFormat = FLEXIO_SPI_XFER_DATA_FORMAT(xfer->flags);
813 #if SPI_RETRY_TIMES
814 uint32_t waitTimes;
815 #endif
816
817 timerCmp &= 0x00FFU;
818
819 if ((xfer->flags & (uint8_t)kFLEXIO_SPI_csContinuous) != 0U)
820 {
821 base->flexioBase->TIMCFG[base->timerIndex[0]] =
822 (base->flexioBase->TIMCFG[base->timerIndex[0]] & ~FLEXIO_TIMCFG_TSTOP_MASK) |
823 FLEXIO_TIMCFG_TSTOP(kFLEXIO_TimerStopBitDisabled);
824 }
825 else
826 {
827 base->flexioBase->TIMCFG[base->timerIndex[0]] =
828 (base->flexioBase->TIMCFG[base->timerIndex[0]] & ~FLEXIO_TIMCFG_TSTOP_MASK) |
829 FLEXIO_TIMCFG_TSTOP(kFLEXIO_TimerStopBitEnableOnTimerDisable);
830 }
831
832 /* Configure the values in handle. */
833 switch (dataFormat)
834 {
835 case (uint8_t)kFLEXIO_SPI_8bitMsb:
836 dataMode = (8UL * 2UL - 1UL) << 8U;
837 bytesPerFrame = 1U;
838 direction = kFLEXIO_SPI_MsbFirst;
839 break;
840
841 case (uint8_t)kFLEXIO_SPI_8bitLsb:
842 dataMode = (8UL * 2UL - 1UL) << 8U;
843 bytesPerFrame = 1U;
844 direction = kFLEXIO_SPI_LsbFirst;
845 break;
846
847 case (uint8_t)kFLEXIO_SPI_16bitMsb:
848 dataMode = (16UL * 2UL - 1UL) << 8U;
849 bytesPerFrame = 2U;
850 direction = kFLEXIO_SPI_MsbFirst;
851 break;
852
853 case (uint8_t)kFLEXIO_SPI_16bitLsb:
854 dataMode = (16UL * 2UL - 1UL) << 8U;
855 bytesPerFrame = 2U;
856 direction = kFLEXIO_SPI_LsbFirst;
857 break;
858
859 case (uint8_t)kFLEXIO_SPI_32bitMsb:
860 dataMode = (32UL * 2UL - 1UL) << 8U;
861 bytesPerFrame = 4U;
862 direction = kFLEXIO_SPI_MsbFirst;
863 break;
864
865 case (uint8_t)kFLEXIO_SPI_32bitLsb:
866 dataMode = (32UL * 2UL - 1UL) << 8U;
867 bytesPerFrame = 4U;
868 direction = kFLEXIO_SPI_LsbFirst;
869 break;
870
871 default:
872 dataMode = (8UL * 2UL - 1UL) << 8U;
873 bytesPerFrame = 1U;
874 direction = kFLEXIO_SPI_MsbFirst;
875 assert(true);
876 break;
877 }
878
879 dataMode |= timerCmp;
880
881 /* Transfer size should be bytesPerFrame divisible. */
882 if ((xfer->dataSize % bytesPerFrame) != 0U)
883 {
884 return kStatus_InvalidArgument;
885 }
886
887 /* Configure transfer size. */
888 base->flexioBase->TIMCMP[base->timerIndex[0]] = dataMode;
889
890 while (xfer->dataSize != 0U)
891 {
892 /* Wait until data transfer complete. */
893 #if SPI_RETRY_TIMES
894 waitTimes = SPI_RETRY_TIMES;
895 while ((0U == (FLEXIO_SPI_GetStatusFlags(base) & (uint32_t)kFLEXIO_SPI_TxBufferEmptyFlag)) &&
896 (0U != --waitTimes))
897 #else
898 while (0U == (FLEXIO_SPI_GetStatusFlags(base) & (uint32_t)kFLEXIO_SPI_TxBufferEmptyFlag))
899 #endif
900 {
901 }
902 #if SPI_RETRY_TIMES
903 if (waitTimes == 0U)
904 {
905 return kStatus_FLEXIO_SPI_Timeout;
906 }
907 #endif
908 if (xfer->txData != NULL)
909 {
910 /* Transmit data and update tx size/buff. */
911 if (bytesPerFrame == 1U)
912 {
913 tmpData = (uint32_t) * (xfer->txData);
914 xfer->txData++;
915 }
916 else if (bytesPerFrame == 2U)
917 {
918 if (direction == kFLEXIO_SPI_MsbFirst)
919 {
920 tmpData = (uint32_t)(xfer->txData[0]) << 8U;
921 tmpData += (uint32_t)xfer->txData[1];
922 }
923 else
924 {
925 tmpData = (uint32_t)(xfer->txData[1]) << 8U;
926 tmpData += (uint32_t)xfer->txData[0];
927 }
928 xfer->txData += 2U;
929 }
930 else
931 {
932 if (direction == kFLEXIO_SPI_MsbFirst)
933 {
934 tmpData = (uint32_t)(xfer->txData[0]) << 24U;
935 tmpData += (uint32_t)(xfer->txData[1]) << 16U;
936 tmpData += (uint32_t)(xfer->txData[2]) << 8U;
937 tmpData += (uint32_t)xfer->txData[3];
938 }
939 else
940 {
941 tmpData = (uint32_t)(xfer->txData[3]) << 24U;
942 tmpData += (uint32_t)(xfer->txData[2]) << 16U;
943 tmpData += (uint32_t)(xfer->txData[1]) << 8U;
944 tmpData += (uint32_t)xfer->txData[0];
945 }
946 xfer->txData += 4U;
947 }
948 }
949 else
950 {
951 tmpData = FLEXIO_SPI_DUMMYDATA;
952 }
953
954 xfer->dataSize -= bytesPerFrame;
955
956 FLEXIO_SPI_WriteData(base, direction, tmpData);
957
958 #if SPI_RETRY_TIMES
959 waitTimes = SPI_RETRY_TIMES;
960 while ((0U == (FLEXIO_SPI_GetStatusFlags(base) & (uint32_t)kFLEXIO_SPI_RxBufferFullFlag)) &&
961 (0U != --waitTimes))
962 #else
963 while (0U == (FLEXIO_SPI_GetStatusFlags(base) & (uint32_t)kFLEXIO_SPI_RxBufferFullFlag))
964 #endif
965 {
966 }
967 #if SPI_RETRY_TIMES
968 if (waitTimes == 0U)
969 {
970 return kStatus_FLEXIO_SPI_Timeout;
971 }
972 #endif
973 tmpData = FLEXIO_SPI_ReadData(base, direction);
974
975 if (xfer->rxData != NULL)
976 {
977 if (bytesPerFrame == 1U)
978 {
979 *xfer->rxData = (uint8_t)tmpData;
980 }
981 else if (bytesPerFrame == 2U)
982 {
983 if (direction == kFLEXIO_SPI_LsbFirst)
984 {
985 *xfer->rxData = (uint8_t)(tmpData >> 8);
986 xfer->rxData++;
987 *xfer->rxData = (uint8_t)tmpData;
988 }
989 else
990 {
991 *xfer->rxData = (uint8_t)tmpData;
992 xfer->rxData++;
993 *xfer->rxData = (uint8_t)(tmpData >> 8);
994 }
995 }
996 else
997 {
998 if (direction == kFLEXIO_SPI_LsbFirst)
999 {
1000 *xfer->rxData = (uint8_t)(tmpData >> 24U);
1001 xfer->rxData++;
1002 *xfer->rxData = (uint8_t)(tmpData >> 16U);
1003 xfer->rxData++;
1004 *xfer->rxData = (uint8_t)(tmpData >> 8U);
1005 xfer->rxData++;
1006 *xfer->rxData = (uint8_t)tmpData;
1007 }
1008 else
1009 {
1010 *xfer->rxData = (uint8_t)tmpData;
1011 xfer->rxData++;
1012 *xfer->rxData = (uint8_t)(tmpData >> 8U);
1013 xfer->rxData++;
1014 *xfer->rxData = (uint8_t)(tmpData >> 16U);
1015 xfer->rxData++;
1016 *xfer->rxData = (uint8_t)(tmpData >> 24U);
1017 }
1018 }
1019 xfer->rxData++;
1020 }
1021 }
1022
1023 return kStatus_Success;
1024 }
1025
1026 /*!
1027 * brief Initializes the FlexIO SPI Master handle, which is used in transactional functions.
1028 *
1029 * param base Pointer to the FLEXIO_SPI_Type structure.
1030 * param handle Pointer to the flexio_spi_master_handle_t structure to store the transfer state.
1031 * param callback The callback function.
1032 * param userData The parameter of the callback function.
1033 * retval kStatus_Success Successfully create the handle.
1034 * retval kStatus_OutOfRange The FlexIO type/handle/ISR table out of range.
1035 */
FLEXIO_SPI_MasterTransferCreateHandle(FLEXIO_SPI_Type * base,flexio_spi_master_handle_t * handle,flexio_spi_master_transfer_callback_t callback,void * userData)1036 status_t FLEXIO_SPI_MasterTransferCreateHandle(FLEXIO_SPI_Type *base,
1037 flexio_spi_master_handle_t *handle,
1038 flexio_spi_master_transfer_callback_t callback,
1039 void *userData)
1040 {
1041 assert(handle != NULL);
1042
1043 IRQn_Type flexio_irqs[] = FLEXIO_IRQS;
1044
1045 /* Zero the handle. */
1046 (void)memset(handle, 0, sizeof(*handle));
1047
1048 /* Register callback and userData. */
1049 handle->callback = callback;
1050 handle->userData = userData;
1051
1052 /* Clear pending NVIC IRQ before enable NVIC IRQ. */
1053 NVIC_ClearPendingIRQ(flexio_irqs[FLEXIO_SPI_GetInstance(base)]);
1054 /* Enable interrupt in NVIC. */
1055 (void)EnableIRQ(flexio_irqs[FLEXIO_SPI_GetInstance(base)]);
1056
1057 /* Save the context in global variables to support the double weak mechanism. */
1058 return FLEXIO_RegisterHandleIRQ(base, handle, FLEXIO_SPI_MasterTransferHandleIRQ);
1059 }
1060
1061 /*!
1062 * brief Master transfer data using IRQ.
1063 *
1064 * This function sends data using IRQ. This is a non-blocking function, which returns
1065 * right away. When all data is sent out/received, the callback function is called.
1066 *
1067 * param base Pointer to the FLEXIO_SPI_Type structure.
1068 * param handle Pointer to the flexio_spi_master_handle_t structure to store the transfer state.
1069 * param xfer FlexIO SPI transfer structure. See #flexio_spi_transfer_t.
1070 * retval kStatus_Success Successfully start a transfer.
1071 * retval kStatus_InvalidArgument Input argument is invalid.
1072 * retval kStatus_FLEXIO_SPI_Busy SPI is not idle, is running another transfer.
1073 */
FLEXIO_SPI_MasterTransferNonBlocking(FLEXIO_SPI_Type * base,flexio_spi_master_handle_t * handle,flexio_spi_transfer_t * xfer)1074 status_t FLEXIO_SPI_MasterTransferNonBlocking(FLEXIO_SPI_Type *base,
1075 flexio_spi_master_handle_t *handle,
1076 flexio_spi_transfer_t *xfer)
1077 {
1078 assert(handle != NULL);
1079 assert(xfer != NULL);
1080
1081 uint32_t dataMode = 0;
1082 uint16_t timerCmp = (uint16_t)base->flexioBase->TIMCMP[base->timerIndex[0]];
1083 uint32_t tmpData = FLEXIO_SPI_DUMMYDATA;
1084 uint8_t dataFormat = FLEXIO_SPI_XFER_DATA_FORMAT(xfer->flags);
1085
1086 timerCmp &= 0x00FFU;
1087
1088 /* Check if SPI is busy. */
1089 if (handle->state == (uint32_t)kFLEXIO_SPI_Busy)
1090 {
1091 return kStatus_FLEXIO_SPI_Busy;
1092 }
1093
1094 /* Check if the argument is legal. */
1095 if ((xfer->txData == NULL) && (xfer->rxData == NULL))
1096 {
1097 return kStatus_InvalidArgument;
1098 }
1099
1100 /* Timer1 controls the CS signal which enables/disables(asserts/deasserts) when timer0 enable/disable. Timer0
1101 enables when tx shifter is written and disables when timer compare. The timer compare event causes the
1102 transmit shift registers to load which generates a tx register empty event. Since when timer stop bit is
1103 disabled, a timer enable condition can be detected in the same cycle as a timer disable condition, so if
1104 software writes the tx register upon the detection of tx register empty event, the timer enable condition
1105 is triggered again, then the CS signal can remain low until software no longer writes the tx register. */
1106 if ((xfer->flags & (uint8_t)kFLEXIO_SPI_csContinuous) != 0U)
1107 {
1108 base->flexioBase->TIMCFG[base->timerIndex[0]] =
1109 (base->flexioBase->TIMCFG[base->timerIndex[0]] & ~FLEXIO_TIMCFG_TSTOP_MASK) |
1110 FLEXIO_TIMCFG_TSTOP(kFLEXIO_TimerStopBitDisabled);
1111 }
1112 else
1113 {
1114 base->flexioBase->TIMCFG[base->timerIndex[0]] =
1115 (base->flexioBase->TIMCFG[base->timerIndex[0]] & ~FLEXIO_TIMCFG_TSTOP_MASK) |
1116 FLEXIO_TIMCFG_TSTOP(kFLEXIO_TimerStopBitEnableOnTimerDisable);
1117 }
1118
1119 /* Configure the values in handle */
1120 switch (dataFormat)
1121 {
1122 case (uint8_t)kFLEXIO_SPI_8bitMsb:
1123 dataMode = (8UL * 2UL - 1UL) << 8U;
1124 handle->bytePerFrame = 1U;
1125 handle->direction = kFLEXIO_SPI_MsbFirst;
1126 break;
1127 case (uint8_t)kFLEXIO_SPI_8bitLsb:
1128 dataMode = (8UL * 2UL - 1UL) << 8U;
1129 handle->bytePerFrame = 1U;
1130 handle->direction = kFLEXIO_SPI_LsbFirst;
1131 break;
1132 case (uint8_t)kFLEXIO_SPI_16bitMsb:
1133 dataMode = (16UL * 2UL - 1UL) << 8U;
1134 handle->bytePerFrame = 2U;
1135 handle->direction = kFLEXIO_SPI_MsbFirst;
1136 break;
1137 case (uint8_t)kFLEXIO_SPI_16bitLsb:
1138 dataMode = (16UL * 2UL - 1UL) << 8U;
1139 handle->bytePerFrame = 2U;
1140 handle->direction = kFLEXIO_SPI_LsbFirst;
1141 break;
1142 case (uint8_t)kFLEXIO_SPI_32bitMsb:
1143 dataMode = (32UL * 2UL - 1UL) << 8U;
1144 handle->bytePerFrame = 4U;
1145 handle->direction = kFLEXIO_SPI_MsbFirst;
1146 break;
1147 case (uint8_t)kFLEXIO_SPI_32bitLsb:
1148 dataMode = (32UL * 2UL - 1UL) << 8U;
1149 handle->bytePerFrame = 4U;
1150 handle->direction = kFLEXIO_SPI_LsbFirst;
1151 break;
1152 default:
1153 dataMode = (8UL * 2UL - 1UL) << 8U;
1154 handle->bytePerFrame = 1U;
1155 handle->direction = kFLEXIO_SPI_MsbFirst;
1156 assert(true);
1157 break;
1158 }
1159
1160 dataMode |= timerCmp;
1161
1162 /* Transfer size should be bytesPerFrame divisible. */
1163 if ((xfer->dataSize % handle->bytePerFrame) != 0U)
1164 {
1165 return kStatus_InvalidArgument;
1166 }
1167
1168 /* Configure transfer size. */
1169 base->flexioBase->TIMCMP[base->timerIndex[0]] = dataMode;
1170
1171 handle->state = (uint32_t)kFLEXIO_SPI_Busy;
1172 handle->txData = xfer->txData;
1173 handle->rxData = xfer->rxData;
1174 handle->rxRemainingBytes = xfer->dataSize;
1175
1176 /* Save total transfer size. */
1177 handle->transferSize = xfer->dataSize;
1178
1179 /* Send first byte of data to trigger the rx interrupt. */
1180 if (handle->txData != NULL)
1181 {
1182 /* Transmit data and update tx size/buff. */
1183 if (handle->bytePerFrame == 1U)
1184 {
1185 tmpData = (uint32_t) * (handle->txData);
1186 handle->txData++;
1187 }
1188 else if (handle->bytePerFrame == 2U)
1189 {
1190 if (handle->direction == kFLEXIO_SPI_MsbFirst)
1191 {
1192 tmpData = (uint32_t)(handle->txData[0]) << 8U;
1193 tmpData += (uint32_t)handle->txData[1];
1194 }
1195 else
1196 {
1197 tmpData = (uint32_t)(handle->txData[1]) << 8U;
1198 tmpData += (uint32_t)handle->txData[0];
1199 }
1200 handle->txData += 2U;
1201 }
1202 else
1203 {
1204 if (handle->direction == kFLEXIO_SPI_MsbFirst)
1205 {
1206 tmpData = (uint32_t)(handle->txData[0]) << 24U;
1207 tmpData += (uint32_t)(handle->txData[1]) << 16U;
1208 tmpData += (uint32_t)(handle->txData[2]) << 8U;
1209 tmpData += (uint32_t)handle->txData[3];
1210 }
1211 else
1212 {
1213 tmpData = (uint32_t)(handle->txData[3]) << 24U;
1214 tmpData += (uint32_t)(handle->txData[2]) << 16U;
1215 tmpData += (uint32_t)(handle->txData[1]) << 8U;
1216 tmpData += (uint32_t)handle->txData[0];
1217 }
1218 handle->txData += 4U;
1219 }
1220 }
1221 else
1222 {
1223 tmpData = FLEXIO_SPI_DUMMYDATA;
1224 }
1225
1226 handle->txRemainingBytes = xfer->dataSize - handle->bytePerFrame;
1227
1228 FLEXIO_SPI_WriteData(base, handle->direction, tmpData);
1229
1230 /* Enable transmit and receive interrupt to handle rx. */
1231 FLEXIO_SPI_EnableInterrupts(base, (uint32_t)kFLEXIO_SPI_RxFullInterruptEnable);
1232
1233 if ((xfer->flags & (uint8_t)kFLEXIO_SPI_csContinuous) != 0U)
1234 {
1235 FLEXIO_SPI_EnableInterrupts(base, (uint32_t)kFLEXIO_SPI_TxEmptyInterruptEnable);
1236 }
1237
1238 return kStatus_Success;
1239 }
1240
1241 /*!
1242 * brief Gets the data transfer status which used IRQ.
1243 *
1244 * param base Pointer to the FLEXIO_SPI_Type structure.
1245 * param handle Pointer to the flexio_spi_master_handle_t structure to store the transfer state.
1246 * param count Number of bytes transferred so far by the non-blocking transaction.
1247 * retval kStatus_InvalidArgument count is Invalid.
1248 * retval kStatus_Success Successfully return the count.
1249 */
FLEXIO_SPI_MasterTransferGetCount(FLEXIO_SPI_Type * base,flexio_spi_master_handle_t * handle,size_t * count)1250 status_t FLEXIO_SPI_MasterTransferGetCount(FLEXIO_SPI_Type *base, flexio_spi_master_handle_t *handle, size_t *count)
1251 {
1252 assert(handle != NULL);
1253
1254 if (NULL == count)
1255 {
1256 return kStatus_InvalidArgument;
1257 }
1258
1259 /* Return remaing bytes in different cases. */
1260 if (handle->rxData != NULL)
1261 {
1262 *count = handle->transferSize - handle->rxRemainingBytes;
1263 }
1264 else
1265 {
1266 *count = handle->transferSize - handle->txRemainingBytes;
1267 }
1268
1269 return kStatus_Success;
1270 }
1271
1272 /*!
1273 * brief Aborts the master data transfer, which used IRQ.
1274 *
1275 * param base Pointer to the FLEXIO_SPI_Type structure.
1276 * param handle Pointer to the flexio_spi_master_handle_t structure to store the transfer state.
1277 */
FLEXIO_SPI_MasterTransferAbort(FLEXIO_SPI_Type * base,flexio_spi_master_handle_t * handle)1278 void FLEXIO_SPI_MasterTransferAbort(FLEXIO_SPI_Type *base, flexio_spi_master_handle_t *handle)
1279 {
1280 assert(handle != NULL);
1281
1282 FLEXIO_SPI_DisableInterrupts(base, (uint32_t)kFLEXIO_SPI_RxFullInterruptEnable);
1283 FLEXIO_SPI_DisableInterrupts(base, (uint32_t)kFLEXIO_SPI_TxEmptyInterruptEnable);
1284
1285 /* Transfer finished, set the state to idle. */
1286 handle->state = (uint32_t)kFLEXIO_SPI_Idle;
1287
1288 /* Clear the internal state. */
1289 handle->rxRemainingBytes = 0;
1290 handle->txRemainingBytes = 0;
1291 }
1292
1293 /*!
1294 * brief FlexIO SPI master IRQ handler function.
1295 *
1296 * param spiType Pointer to the FLEXIO_SPI_Type structure.
1297 * param spiHandle Pointer to the flexio_spi_master_handle_t structure to store the transfer state.
1298 */
FLEXIO_SPI_MasterTransferHandleIRQ(void * spiType,void * spiHandle)1299 void FLEXIO_SPI_MasterTransferHandleIRQ(void *spiType, void *spiHandle)
1300 {
1301 assert(spiHandle != NULL);
1302
1303 flexio_spi_master_handle_t *handle = (flexio_spi_master_handle_t *)spiHandle;
1304 FLEXIO_SPI_Type *base;
1305 uint32_t status;
1306
1307 if (handle->state == (uint32_t)kFLEXIO_SPI_Idle)
1308 {
1309 return;
1310 }
1311
1312 base = (FLEXIO_SPI_Type *)spiType;
1313 status = FLEXIO_SPI_GetStatusFlags(base);
1314
1315 /* Receive interrupt. */
1316 if ((status & (uint32_t)kFLEXIO_SPI_RxBufferFullFlag) == 0U)
1317 {
1318 FLEXIO_SPI_TransferSendTransaction(base, handle);
1319 return;
1320 }
1321
1322 /* Handle rx. */
1323 if (handle->rxRemainingBytes != 0U)
1324 {
1325 FLEXIO_SPI_TransferReceiveTransaction(base, handle);
1326 }
1327
1328 /* Handle tx. */
1329 if (((status & (uint32_t)kFLEXIO_SPI_TxBufferEmptyFlag) != 0U) && (handle->txRemainingBytes != 0U))
1330 {
1331 FLEXIO_SPI_TransferSendTransaction(base, handle);
1332 }
1333
1334 /* All the transfer finished. */
1335 if ((handle->txRemainingBytes == 0U) && (handle->rxRemainingBytes == 0U))
1336 {
1337 FLEXIO_SPI_MasterTransferAbort(base, handle);
1338 if (handle->callback != NULL)
1339 {
1340 (handle->callback)(base, handle, kStatus_FLEXIO_SPI_Idle, handle->userData);
1341 }
1342 }
1343 }
1344
1345 /*!
1346 * brief Initializes the FlexIO SPI Slave handle, which is used in transactional functions.
1347 *
1348 * param base Pointer to the FLEXIO_SPI_Type structure.
1349 * param handle Pointer to the flexio_spi_slave_handle_t structure to store the transfer state.
1350 * param callback The callback function.
1351 * param userData The parameter of the callback function.
1352 * retval kStatus_Success Successfully create the handle.
1353 * retval kStatus_OutOfRange The FlexIO type/handle/ISR table out of range.
1354 */
FLEXIO_SPI_SlaveTransferCreateHandle(FLEXIO_SPI_Type * base,flexio_spi_slave_handle_t * handle,flexio_spi_slave_transfer_callback_t callback,void * userData)1355 status_t FLEXIO_SPI_SlaveTransferCreateHandle(FLEXIO_SPI_Type *base,
1356 flexio_spi_slave_handle_t *handle,
1357 flexio_spi_slave_transfer_callback_t callback,
1358 void *userData)
1359 {
1360 assert(handle != NULL);
1361
1362 IRQn_Type flexio_irqs[] = FLEXIO_IRQS;
1363
1364 /* Zero the handle. */
1365 (void)memset(handle, 0, sizeof(*handle));
1366
1367 /* Register callback and userData. */
1368 handle->callback = callback;
1369 handle->userData = userData;
1370
1371 /* Clear pending NVIC IRQ before enable NVIC IRQ. */
1372 NVIC_ClearPendingIRQ(flexio_irqs[FLEXIO_SPI_GetInstance(base)]);
1373 /* Enable interrupt in NVIC. */
1374 (void)EnableIRQ(flexio_irqs[FLEXIO_SPI_GetInstance(base)]);
1375
1376 /* Save the context in global variables to support the double weak mechanism. */
1377 return FLEXIO_RegisterHandleIRQ(base, handle, FLEXIO_SPI_SlaveTransferHandleIRQ);
1378 }
1379
1380 /*!
1381 * brief Slave transfer data using IRQ.
1382 *
1383 * This function sends data using IRQ. This is a non-blocking function, which returns
1384 * right away. When all data is sent out/received, the callback function is called.
1385 * param handle Pointer to the flexio_spi_slave_handle_t structure to store the transfer state.
1386 *
1387 * param base Pointer to the FLEXIO_SPI_Type structure.
1388 * param xfer FlexIO SPI transfer structure. See #flexio_spi_transfer_t.
1389 * retval kStatus_Success Successfully start a transfer.
1390 * retval kStatus_InvalidArgument Input argument is invalid.
1391 * retval kStatus_FLEXIO_SPI_Busy SPI is not idle; it is running another transfer.
1392 */
FLEXIO_SPI_SlaveTransferNonBlocking(FLEXIO_SPI_Type * base,flexio_spi_slave_handle_t * handle,flexio_spi_transfer_t * xfer)1393 status_t FLEXIO_SPI_SlaveTransferNonBlocking(FLEXIO_SPI_Type *base,
1394 flexio_spi_slave_handle_t *handle,
1395 flexio_spi_transfer_t *xfer)
1396 {
1397 assert(handle != NULL);
1398 assert(xfer != NULL);
1399
1400 uint32_t dataMode = 0;
1401 uint8_t dataFormat = FLEXIO_SPI_XFER_DATA_FORMAT(xfer->flags);
1402
1403 /* Check if SPI is busy. */
1404 if (handle->state == (uint32_t)kFLEXIO_SPI_Busy)
1405 {
1406 return kStatus_FLEXIO_SPI_Busy;
1407 }
1408
1409 /* Check if the argument is legal. */
1410 if ((xfer->txData == NULL) && (xfer->rxData == NULL))
1411 {
1412 return kStatus_InvalidArgument;
1413 }
1414
1415 /* SCK timer use CS pin as inverted trigger so timer should be disbaled on trigger falling edge(CS re-asserts). */
1416 /* However if CPHA is first edge mode, timer will restart each time right after timer compare event occur and
1417 before CS pin re-asserts, which triggers another shifter load. To avoid this, when in CS dis-continuous mode,
1418 timer should disable in timer compare rather than trigger falling edge(CS re-asserts), and in CS continuous mode,
1419 tx/rx shifters should be flushed after transfer finishes and before next transfer starts. */
1420 FLEXIO_SPI_FlushShifters(base);
1421 if ((xfer->flags & (uint8_t)kFLEXIO_SPI_csContinuous) != 0U)
1422 {
1423 base->flexioBase->TIMCFG[base->timerIndex[0]] |= FLEXIO_TIMCFG_TIMDIS(kFLEXIO_TimerDisableOnTriggerFallingEdge);
1424 }
1425 else
1426 {
1427 if ((base->flexioBase->SHIFTCTL[base->shifterIndex[0]] & FLEXIO_SHIFTCTL_TIMPOL_MASK) ==
1428 FLEXIO_SHIFTCTL_TIMPOL(kFLEXIO_ShifterTimerPolarityOnNegitive))
1429 {
1430 base->flexioBase->TIMCFG[base->timerIndex[0]] =
1431 (base->flexioBase->TIMCFG[base->timerIndex[0]] & ~FLEXIO_TIMCFG_TIMDIS_MASK) |
1432 FLEXIO_TIMCFG_TIMDIS(kFLEXIO_TimerDisableOnTimerCompare);
1433 }
1434 else
1435 {
1436 base->flexioBase->TIMCFG[base->timerIndex[0]] =
1437 (base->flexioBase->TIMCFG[base->timerIndex[0]] & ~FLEXIO_TIMCFG_TIMDIS_MASK) |
1438 FLEXIO_TIMCFG_TIMDIS(kFLEXIO_TimerDisableOnTriggerFallingEdge);
1439 }
1440 }
1441
1442 /* Configure the values in handle */
1443 switch (dataFormat)
1444 {
1445 case (uint8_t)kFLEXIO_SPI_8bitMsb:
1446 dataMode = 8U * 2U - 1U;
1447 handle->bytePerFrame = 1U;
1448 handle->direction = kFLEXIO_SPI_MsbFirst;
1449 break;
1450 case (uint8_t)kFLEXIO_SPI_8bitLsb:
1451 dataMode = 8U * 2U - 1U;
1452 handle->bytePerFrame = 1U;
1453 handle->direction = kFLEXIO_SPI_LsbFirst;
1454 break;
1455 case (uint8_t)kFLEXIO_SPI_16bitMsb:
1456 dataMode = 16U * 2U - 1U;
1457 handle->bytePerFrame = 2U;
1458 handle->direction = kFLEXIO_SPI_MsbFirst;
1459 break;
1460 case (uint8_t)kFLEXIO_SPI_16bitLsb:
1461 dataMode = 16U * 2U - 1U;
1462 handle->bytePerFrame = 2U;
1463 handle->direction = kFLEXIO_SPI_LsbFirst;
1464 break;
1465 case (uint8_t)kFLEXIO_SPI_32bitMsb:
1466 dataMode = 32UL * 2UL - 1UL;
1467 handle->bytePerFrame = 4U;
1468 handle->direction = kFLEXIO_SPI_MsbFirst;
1469 break;
1470 case (uint8_t)kFLEXIO_SPI_32bitLsb:
1471 dataMode = 32UL * 2UL - 1UL;
1472 handle->bytePerFrame = 4U;
1473 handle->direction = kFLEXIO_SPI_LsbFirst;
1474 break;
1475 default:
1476 dataMode = 8UL * 2UL - 1UL;
1477 handle->bytePerFrame = 1U;
1478 handle->direction = kFLEXIO_SPI_MsbFirst;
1479 assert(true);
1480 break;
1481 }
1482
1483 /* Transfer size should be bytesPerFrame divisible. */
1484 if ((xfer->dataSize % handle->bytePerFrame) != 0U)
1485 {
1486 return kStatus_InvalidArgument;
1487 }
1488
1489 /* Configure transfer size. */
1490 base->flexioBase->TIMCMP[base->timerIndex[0]] = dataMode;
1491
1492 handle->state = (uint32_t)kFLEXIO_SPI_Busy;
1493 handle->txData = xfer->txData;
1494 handle->rxData = xfer->rxData;
1495 handle->txRemainingBytes = xfer->dataSize;
1496 handle->rxRemainingBytes = xfer->dataSize;
1497
1498 /* Save total transfer size. */
1499 handle->transferSize = xfer->dataSize;
1500
1501 /* Enable transmit and receive interrupt to handle tx and rx. */
1502 FLEXIO_SPI_EnableInterrupts(base, (uint32_t)kFLEXIO_SPI_TxEmptyInterruptEnable);
1503 FLEXIO_SPI_EnableInterrupts(base, (uint32_t)kFLEXIO_SPI_RxFullInterruptEnable);
1504
1505 return kStatus_Success;
1506 }
1507
1508 /*!
1509 * brief FlexIO SPI slave IRQ handler function.
1510 *
1511 * param spiType Pointer to the FLEXIO_SPI_Type structure.
1512 * param spiHandle Pointer to the flexio_spi_slave_handle_t structure to store the transfer state.
1513 */
FLEXIO_SPI_SlaveTransferHandleIRQ(void * spiType,void * spiHandle)1514 void FLEXIO_SPI_SlaveTransferHandleIRQ(void *spiType, void *spiHandle)
1515 {
1516 assert(spiHandle != NULL);
1517
1518 flexio_spi_master_handle_t *handle = (flexio_spi_master_handle_t *)spiHandle;
1519 FLEXIO_SPI_Type *base;
1520 uint32_t status;
1521
1522 if (handle->state == (uint32_t)kFLEXIO_SPI_Idle)
1523 {
1524 return;
1525 }
1526
1527 base = (FLEXIO_SPI_Type *)spiType;
1528 status = FLEXIO_SPI_GetStatusFlags(base);
1529
1530 /* Handle tx. */
1531 if (((status & (uint32_t)kFLEXIO_SPI_TxBufferEmptyFlag) != 0U) && (handle->txRemainingBytes != 0U))
1532 {
1533 FLEXIO_SPI_TransferSendTransaction(base, handle);
1534 }
1535
1536 /* Handle rx. */
1537 if (((status & (uint32_t)kFLEXIO_SPI_RxBufferFullFlag) != 0U) && (handle->rxRemainingBytes != 0U))
1538 {
1539 FLEXIO_SPI_TransferReceiveTransaction(base, handle);
1540 }
1541
1542 /* All the transfer finished. */
1543 if ((handle->txRemainingBytes == 0U) && (handle->rxRemainingBytes == 0U))
1544 {
1545 FLEXIO_SPI_SlaveTransferAbort(base, handle);
1546 if (handle->callback != NULL)
1547 {
1548 (handle->callback)(base, handle, kStatus_FLEXIO_SPI_Idle, handle->userData);
1549 }
1550 }
1551 }
1552
1553 /*!
1554 * brief Flush tx/rx shifters.
1555 *
1556 * param base Pointer to the FLEXIO_SPI_Type structure.
1557 */
FLEXIO_SPI_FlushShifters(FLEXIO_SPI_Type * base)1558 void FLEXIO_SPI_FlushShifters(FLEXIO_SPI_Type *base)
1559 {
1560 /* Disable then re-enable to flush the tx shifter. */
1561 base->flexioBase->SHIFTCTL[base->shifterIndex[0]] &= ~FLEXIO_SHIFTCTL_SMOD_MASK;
1562 base->flexioBase->SHIFTCTL[base->shifterIndex[0]] |= FLEXIO_SHIFTCTL_SMOD(kFLEXIO_ShifterModeTransmit);
1563 /* Read to flush the rx shifter. */
1564 (void)base->flexioBase->SHIFTBUF[base->shifterIndex[1]];
1565 }
1566