1 /*
2 * Copyright (c) 2015, Freescale Semiconductor, Inc.
3 * Copyright 2016-2020 NXP
4 * All rights reserved.
5 *
6 * SPDX-License-Identifier: BSD-3-Clause
7 */
8
9 #include "fsl_flexio_i2c_master.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_i2c_master"
18 #endif
19
20 /*! @brief FLEXIO I2C transfer state */
21 enum _flexio_i2c_master_transfer_states
22 {
23 kFLEXIO_I2C_Idle = 0x0U, /*!< I2C bus idle */
24 kFLEXIO_I2C_Start = 0x1U, /*!< I2C start phase */
25 kFLEXIO_I2C_SendCommand = 0x2U, /*!< Send command byte phase */
26 kFLEXIO_I2C_SendData = 0x3U, /*!< Send data transfer phase*/
27 kFLEXIO_I2C_ReceiveDataBegin = 0x4U, /*!< Receive data begin transfer phase*/
28 kFLEXIO_I2C_ReceiveData = 0x5U, /*!< Receive data transfer phase*/
29 };
30
31 /*******************************************************************************
32 * Prototypes
33 ******************************************************************************/
34
35 /*!
36 * @brief Set up master transfer, send slave address and decide the initial
37 * transfer state.
38 *
39 * @param base pointer to FLEXIO_I2C_Type structure
40 * @param handle pointer to flexio_i2c_master_handle_t structure which stores the transfer state
41 * @param transfer pointer to flexio_i2c_master_transfer_t structure
42 */
43 static status_t FLEXIO_I2C_MasterTransferInitStateMachine(FLEXIO_I2C_Type *base,
44 flexio_i2c_master_handle_t *handle,
45 flexio_i2c_master_transfer_t *xfer);
46
47 /*!
48 * @brief Master run transfer state machine to perform a byte of transfer.
49 *
50 * @param base pointer to FLEXIO_I2C_Type structure
51 * @param handle pointer to flexio_i2c_master_handle_t structure which stores the transfer state
52 * @param statusFlags flexio i2c hardware status
53 * @retval kStatus_Success Successfully run state machine
54 * @retval kStatus_FLEXIO_I2C_Nak Receive Nak during transfer
55 */
56 static status_t FLEXIO_I2C_MasterTransferRunStateMachine(FLEXIO_I2C_Type *base,
57 flexio_i2c_master_handle_t *handle,
58 uint32_t statusFlags);
59
60 /*!
61 * @brief Complete transfer, disable interrupt and call callback.
62 *
63 * @param base pointer to FLEXIO_I2C_Type structure
64 * @param handle pointer to flexio_i2c_master_handle_t structure which stores the transfer state
65 * @param status flexio transfer status
66 */
67 static void FLEXIO_I2C_MasterTransferComplete(FLEXIO_I2C_Type *base,
68 flexio_i2c_master_handle_t *handle,
69 status_t status);
70
71 /*******************************************************************************
72 * Codes
73 ******************************************************************************/
74
FLEXIO_I2C_GetInstance(FLEXIO_I2C_Type * base)75 static uint32_t FLEXIO_I2C_GetInstance(FLEXIO_I2C_Type *base)
76 {
77 return FLEXIO_GetInstance(base->flexioBase);
78 }
79
FLEXIO_I2C_MasterTransferInitStateMachine(FLEXIO_I2C_Type * base,flexio_i2c_master_handle_t * handle,flexio_i2c_master_transfer_t * xfer)80 static status_t FLEXIO_I2C_MasterTransferInitStateMachine(FLEXIO_I2C_Type *base,
81 flexio_i2c_master_handle_t *handle,
82 flexio_i2c_master_transfer_t *xfer)
83 {
84 bool needRestart;
85 uint32_t byteCount;
86
87 /* Init the handle member. */
88 handle->transfer.slaveAddress = xfer->slaveAddress;
89 handle->transfer.direction = xfer->direction;
90 handle->transfer.subaddress = xfer->subaddress;
91 handle->transfer.subaddressSize = xfer->subaddressSize;
92 handle->transfer.data = xfer->data;
93 handle->transfer.dataSize = xfer->dataSize;
94 handle->transfer.flags = xfer->flags;
95 handle->transferSize = xfer->dataSize;
96
97 /* Initial state, i2c start state. */
98 handle->state = (uint8_t)kFLEXIO_I2C_Start;
99
100 /* Clear all status before transfer. */
101 FLEXIO_I2C_MasterClearStatusFlags(base, (uint32_t)kFLEXIO_I2C_ReceiveNakFlag);
102
103 /* Calculate whether need to send re-start. */
104 needRestart = (handle->transfer.subaddressSize != 0U) && (handle->transfer.direction == kFLEXIO_I2C_Read);
105 handle->needRestart = needRestart;
106
107 /* Calculate total byte count in a frame. */
108 byteCount = 1U;
109
110 if (!needRestart)
111 {
112 byteCount += handle->transfer.dataSize;
113 }
114
115 if (handle->transfer.subaddressSize != 0U)
116 {
117 byteCount += handle->transfer.subaddressSize;
118 }
119
120 /* Configure data count. */
121 if (FLEXIO_I2C_MasterSetTransferCount(base, (uint16_t)byteCount) != kStatus_Success)
122 {
123 return kStatus_InvalidArgument;
124 }
125
126 /* Configure timer1 disable condition. */
127 uint32_t tmpConfig = base->flexioBase->TIMCFG[base->timerIndex[1]];
128 tmpConfig &= ~FLEXIO_TIMCFG_TIMDIS_MASK;
129 tmpConfig |= FLEXIO_TIMCFG_TIMDIS(kFLEXIO_TimerDisableOnPreTimerDisable);
130 base->flexioBase->TIMCFG[base->timerIndex[1]] = tmpConfig;
131
132 #if I2C_RETRY_TIMES
133 uint32_t waitTimes = I2C_RETRY_TIMES;
134 while ((0U == (FLEXIO_GetShifterStatusFlags(base->flexioBase) & (1UL << base->shifterIndex[0]))) &&
135 (0U != --waitTimes))
136 {
137 }
138 if (0U == waitTimes)
139 {
140 return kStatus_FLEXIO_I2C_Timeout;
141 }
142 #else
143 while (0U == (FLEXIO_GetShifterStatusFlags(base->flexioBase) & (1UL << base->shifterIndex[0])))
144 {
145 }
146 #endif
147
148 return kStatus_Success;
149 }
150
FLEXIO_I2C_MasterTransferRunStateMachine(FLEXIO_I2C_Type * base,flexio_i2c_master_handle_t * handle,uint32_t statusFlags)151 static status_t FLEXIO_I2C_MasterTransferRunStateMachine(FLEXIO_I2C_Type *base,
152 flexio_i2c_master_handle_t *handle,
153 uint32_t statusFlags)
154 {
155 #if I2C_RETRY_TIMES
156 uint32_t waitTimes = I2C_RETRY_TIMES;
157 #endif
158
159 if ((statusFlags & (uint32_t)kFLEXIO_I2C_ReceiveNakFlag) != 0U)
160 {
161 /* Clear receive nak flag. */
162 FLEXIO_ClearShifterErrorFlags(base->flexioBase, 1UL << base->shifterIndex[1]);
163
164 if ((!((handle->state == (uint8_t)kFLEXIO_I2C_SendData) && (handle->transfer.dataSize == 0U))) &&
165 (!(((handle->state == (uint8_t)kFLEXIO_I2C_ReceiveData) ||
166 (handle->state == (uint8_t)kFLEXIO_I2C_ReceiveDataBegin)) &&
167 (handle->transfer.dataSize == 1U))))
168 {
169 (void)FLEXIO_I2C_MasterReadByte(base);
170
171 FLEXIO_I2C_MasterAbortStop(base);
172
173 /* Delay one clk cycle to ensure the bus is idle. */
174 SDK_DelayAtLeastUs(1000000UL / base->baudrate, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
175
176 handle->state = (uint8_t)kFLEXIO_I2C_Idle;
177
178 return kStatus_FLEXIO_I2C_Nak;
179 }
180 }
181
182 if (((statusFlags & (uint8_t)kFLEXIO_I2C_RxFullFlag) != 0U) && (handle->state != (uint8_t)kFLEXIO_I2C_ReceiveData))
183 {
184 (void)FLEXIO_I2C_MasterReadByte(base);
185 }
186
187 switch (handle->state)
188 {
189 /* Initial state, i2c start state. */
190 case (uint8_t)kFLEXIO_I2C_Start:
191 /* Send address byte first. */
192 if (handle->needRestart)
193 {
194 FLEXIO_I2C_MasterStart(base, handle->transfer.slaveAddress, kFLEXIO_I2C_Write);
195 }
196 else
197 {
198 FLEXIO_I2C_MasterStart(base, handle->transfer.slaveAddress, handle->transfer.direction);
199 }
200 if (handle->transfer.subaddressSize == 0U)
201 {
202 if (handle->transfer.direction == kFLEXIO_I2C_Write)
203 {
204 /* Next state, send data. */
205 handle->state = (uint8_t)kFLEXIO_I2C_SendData;
206 }
207 else
208 {
209 /* Next state, receive data begin. */
210 handle->state = (uint8_t)kFLEXIO_I2C_ReceiveDataBegin;
211 }
212 }
213 else
214 {
215 /* Next state, send command byte. */
216 handle->state = (uint8_t)kFLEXIO_I2C_SendCommand;
217 }
218 break;
219
220 /* Check address only needed for transfer with subaddress */
221 case (uint8_t)kFLEXIO_I2C_SendCommand:
222 if ((statusFlags & (uint32_t)kFLEXIO_I2C_TxEmptyFlag) != 0U)
223 {
224 if (handle->transfer.subaddressSize > 0U)
225 {
226 handle->transfer.subaddressSize--;
227 FLEXIO_I2C_MasterWriteByte(
228 base, ((handle->transfer.subaddress) >> (8U * handle->transfer.subaddressSize)));
229
230 if (handle->transfer.subaddressSize == 0U)
231 {
232 /* Load re-start in advance. */
233 if (handle->transfer.direction == kFLEXIO_I2C_Read)
234 {
235 #if I2C_RETRY_TIMES
236 while ((0U == (FLEXIO_GetShifterStatusFlags(base->flexioBase) &
237 (1UL << base->shifterIndex[0]))) &&
238 (0U != --waitTimes))
239 {
240 }
241 if (0U == waitTimes)
242 {
243 return kStatus_FLEXIO_I2C_Timeout;
244 }
245 #else
246 while (0U ==
247 (FLEXIO_GetShifterStatusFlags(base->flexioBase) & (1UL << base->shifterIndex[0])))
248 {
249 }
250 #endif
251 FLEXIO_I2C_MasterRepeatedStart(base);
252 }
253 }
254 }
255 else
256 {
257 if (handle->transfer.direction == kFLEXIO_I2C_Write)
258 {
259 /* Send first byte of data. */
260 if (handle->transfer.dataSize > 0U)
261 {
262 /* Next state, send data. */
263 handle->state = (uint8_t)kFLEXIO_I2C_SendData;
264
265 FLEXIO_I2C_MasterWriteByte(base, *handle->transfer.data);
266 handle->transfer.data++;
267 handle->transfer.dataSize--;
268 }
269 else
270 {
271 FLEXIO_I2C_MasterStop(base);
272
273 #if I2C_RETRY_TIMES
274 while ((0U == (FLEXIO_I2C_MasterGetStatusFlags(base) & (uint32_t)kFLEXIO_I2C_RxFullFlag)) &&
275 (0U != --waitTimes))
276 {
277 }
278 if (0U == waitTimes)
279 {
280 return kStatus_FLEXIO_I2C_Timeout;
281 }
282 #else
283 while (0U == (FLEXIO_I2C_MasterGetStatusFlags(base) & (uint32_t)kFLEXIO_I2C_RxFullFlag))
284 {
285 }
286 #endif
287 (void)FLEXIO_I2C_MasterReadByte(base);
288
289 handle->state = (uint8_t)kFLEXIO_I2C_Idle;
290 }
291 }
292 else
293 {
294 (void)FLEXIO_I2C_MasterSetTransferCount(base, (uint16_t)(handle->transfer.dataSize + 1U));
295 /* Delay at least one clock cycle so that the restart setup time is up to spec standard. */
296 SDK_DelayAtLeastUs(1000000UL / base->baudrate, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
297 FLEXIO_I2C_MasterStart(base, handle->transfer.slaveAddress, kFLEXIO_I2C_Read);
298
299 /* Next state, receive data begin. */
300 handle->state = (uint8_t)kFLEXIO_I2C_ReceiveDataBegin;
301 }
302 }
303 }
304 break;
305
306 /* Send command byte. */
307 case (uint8_t)kFLEXIO_I2C_SendData:
308 if ((statusFlags & (uint32_t)kFLEXIO_I2C_TxEmptyFlag) != 0U)
309 {
310 /* Send one byte of data. */
311 if (handle->transfer.dataSize > 0U)
312 {
313 FLEXIO_I2C_MasterWriteByte(base, *handle->transfer.data);
314
315 handle->transfer.data++;
316 handle->transfer.dataSize--;
317 }
318 else
319 {
320 FLEXIO_I2C_MasterStop(base);
321
322 #if I2C_RETRY_TIMES
323 while ((0U == (FLEXIO_I2C_MasterGetStatusFlags(base) & (uint32_t)kFLEXIO_I2C_RxFullFlag)) &&
324 (0U != --waitTimes))
325 {
326 }
327 if (0U == waitTimes)
328 {
329 return kStatus_FLEXIO_I2C_Timeout;
330 }
331 #else
332 while (0U == (FLEXIO_I2C_MasterGetStatusFlags(base) & (uint32_t)kFLEXIO_I2C_RxFullFlag))
333 {
334 }
335 #endif
336 (void)FLEXIO_I2C_MasterReadByte(base);
337
338 handle->state = (uint8_t)kFLEXIO_I2C_Idle;
339 }
340 }
341 break;
342
343 case (uint8_t)kFLEXIO_I2C_ReceiveDataBegin:
344 if ((statusFlags & (uint32_t)kFLEXIO_I2C_RxFullFlag) != 0U)
345 {
346 handle->state = (uint8_t)kFLEXIO_I2C_ReceiveData;
347 /* Send nak at the last receive byte. */
348 if (handle->transfer.dataSize == 1U)
349 {
350 FLEXIO_I2C_MasterEnableAck(base, false);
351 #if I2C_RETRY_TIMES
352 while ((0U == (FLEXIO_GetShifterStatusFlags(base->flexioBase) & (1UL << base->shifterIndex[0]))) &&
353 (0U != --waitTimes))
354 {
355 }
356 if (0U == waitTimes)
357 {
358 return kStatus_FLEXIO_I2C_Timeout;
359 }
360 #else
361 while (0U == (FLEXIO_GetShifterStatusFlags(base->flexioBase) & (1UL << base->shifterIndex[0])))
362 {
363 }
364 #endif
365 FLEXIO_I2C_MasterStop(base);
366 }
367 else
368 {
369 FLEXIO_I2C_MasterEnableAck(base, true);
370 }
371 }
372 else if ((statusFlags & (uint32_t)kFLEXIO_I2C_TxEmptyFlag) != 0U)
373 {
374 /* Read one byte of data. */
375 FLEXIO_I2C_MasterWriteByte(base, 0xFFFFFFFFU);
376 }
377 else
378 {
379 ; /* Avoid MISRA 2012 rule 15.7 */
380 }
381 break;
382
383 case (uint8_t)kFLEXIO_I2C_ReceiveData:
384 if ((statusFlags & (uint32_t)kFLEXIO_I2C_RxFullFlag) != 0U)
385 {
386 *handle->transfer.data = FLEXIO_I2C_MasterReadByte(base);
387 handle->transfer.data++;
388 if (0U != handle->transfer.dataSize--)
389 {
390 if (handle->transfer.dataSize == 0U)
391 {
392 FLEXIO_I2C_MasterDisableInterrupts(base, (uint32_t)kFLEXIO_I2C_RxFullInterruptEnable);
393 handle->state = (uint8_t)kFLEXIO_I2C_Idle;
394 /* Return nak if ReceiveNakFlag is not set */
395 if ((statusFlags & (uint32_t)kFLEXIO_I2C_ReceiveNakFlag) == 0U)
396 {
397 return kStatus_FLEXIO_I2C_Nak;
398 }
399 }
400
401 /* Send nak at the last receive byte. */
402 if (handle->transfer.dataSize == 1U)
403 {
404 FLEXIO_I2C_MasterEnableAck(base, false);
405 #if I2C_RETRY_TIMES
406 while (
407 (0U == (FLEXIO_GetShifterStatusFlags(base->flexioBase) & (1UL << base->shifterIndex[0]))) &&
408 (0U != --waitTimes))
409 {
410 }
411 if (0U == waitTimes)
412 {
413 return kStatus_FLEXIO_I2C_Timeout;
414 }
415 #else
416 while (0U == (FLEXIO_GetShifterStatusFlags(base->flexioBase) & (1UL << base->shifterIndex[0])))
417 {
418 }
419 #endif
420 FLEXIO_I2C_MasterStop(base);
421 }
422 }
423 }
424 else if ((statusFlags & (uint32_t)kFLEXIO_I2C_TxEmptyFlag) != 0U)
425 {
426 if (handle->transfer.dataSize > 1U)
427 {
428 FLEXIO_I2C_MasterWriteByte(base, 0xFFFFFFFFU);
429 }
430 }
431 else
432 {
433 ; /* Avoid MISRA 2012 rule 15.7 */
434 }
435 break;
436
437 default:
438 /* Add comment to avoid MISRA violation */
439 break;
440 }
441
442 return kStatus_Success;
443 }
444
FLEXIO_I2C_MasterTransferComplete(FLEXIO_I2C_Type * base,flexio_i2c_master_handle_t * handle,status_t status)445 static void FLEXIO_I2C_MasterTransferComplete(FLEXIO_I2C_Type *base,
446 flexio_i2c_master_handle_t *handle,
447 status_t status)
448 {
449 FLEXIO_I2C_MasterDisableInterrupts(
450 base, (uint32_t)kFLEXIO_I2C_TxEmptyInterruptEnable | (uint32_t)kFLEXIO_I2C_RxFullInterruptEnable);
451
452 if (handle->completionCallback != NULL)
453 {
454 handle->completionCallback(base, handle, status, handle->userData);
455 }
456 }
457
458 #if defined(FSL_FEATURE_FLEXIO_HAS_PIN_STATUS) && FSL_FEATURE_FLEXIO_HAS_PIN_STATUS
459 /*!
460 * brief Make sure the bus isn't already pulled down.
461 *
462 * Check the FLEXIO pin status to see whether either of SDA and SCL pin is pulled down.
463 *
464 * param base Pointer to FLEXIO_I2C_Type structure..
465 * retval kStatus_Success
466 * retval kStatus_FLEXIO_I2C_Busy
467 */
FLEXIO_I2C_CheckForBusyBus(FLEXIO_I2C_Type * base)468 status_t FLEXIO_I2C_CheckForBusyBus(FLEXIO_I2C_Type *base)
469 {
470 uint32_t mask;
471 /* If in certain loops the SDA/SCL is continuously pulled down, then return bus busy status. */
472 /* The loop count is determined by maximum CPU clock frequency */
473 for (uint32_t i = 0U; i < SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY / 600000U; ++i)
474 {
475 mask = 1UL << base->SDAPinIndex | 1UL << base->SCLPinIndex;
476 if ((FLEXIO_ReadPinInput(base->flexioBase) & mask) == mask)
477 {
478 return kStatus_Success;
479 }
480 }
481 return kStatus_FLEXIO_I2C_Busy;
482 }
483 #endif /*FSL_FEATURE_FLEXIO_HAS_PIN_STATUS*/
484
485 /*!
486 * brief Ungates the FlexIO clock, resets the FlexIO module, and configures the FlexIO I2C
487 * hardware configuration.
488 *
489 * Example
490 code
491 FLEXIO_I2C_Type base = {
492 .flexioBase = FLEXIO,
493 .SDAPinIndex = 0,
494 .SCLPinIndex = 1,
495 .shifterIndex = {0,1},
496 .timerIndex = {0,1}
497 };
498 flexio_i2c_master_config_t config = {
499 .enableInDoze = false,
500 .enableInDebug = true,
501 .enableFastAccess = false,
502 .baudRate_Bps = 100000
503 };
504 FLEXIO_I2C_MasterInit(base, &config, srcClock_Hz);
505 endcode
506 *
507 * param base Pointer to FLEXIO_I2C_Type structure.
508 * param masterConfig Pointer to flexio_i2c_master_config_t structure.
509 * param srcClock_Hz FlexIO source clock in Hz.
510 * retval kStatus_Success Initialization successful
511 * retval kStatus_InvalidArgument The source clock exceed upper range limitation
512 */
FLEXIO_I2C_MasterInit(FLEXIO_I2C_Type * base,flexio_i2c_master_config_t * masterConfig,uint32_t srcClock_Hz)513 status_t FLEXIO_I2C_MasterInit(FLEXIO_I2C_Type *base, flexio_i2c_master_config_t *masterConfig, uint32_t srcClock_Hz)
514 {
515 assert((base != NULL) && (masterConfig != NULL));
516
517 flexio_shifter_config_t shifterConfig;
518 flexio_timer_config_t timerConfig;
519 uint32_t controlVal = 0;
520 uint16_t timerDiv = 0;
521 status_t result = kStatus_Success;
522
523 (void)memset(&shifterConfig, 0, sizeof(shifterConfig));
524 (void)memset(&timerConfig, 0, sizeof(timerConfig));
525
526 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
527 /* Ungate flexio clock. */
528 CLOCK_EnableClock(s_flexioClocks[FLEXIO_I2C_GetInstance(base)]);
529 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
530
531 /* Do hardware configuration. */
532 /* 1. Configure the shifter 0 for tx. */
533 shifterConfig.timerSelect = base->timerIndex[2];
534 shifterConfig.timerPolarity = kFLEXIO_ShifterTimerPolarityOnPositive;
535 shifterConfig.pinConfig = kFLEXIO_PinConfigOpenDrainOrBidirection;
536 shifterConfig.pinSelect = base->SDAPinIndex;
537 shifterConfig.pinPolarity = kFLEXIO_PinActiveLow;
538 shifterConfig.shifterMode = kFLEXIO_ShifterModeTransmit;
539 shifterConfig.inputSource = kFLEXIO_ShifterInputFromPin;
540 shifterConfig.shifterStop = kFLEXIO_ShifterStopBitHigh;
541 shifterConfig.shifterStart = kFLEXIO_ShifterStartBitLow;
542
543 FLEXIO_SetShifterConfig(base->flexioBase, base->shifterIndex[0], &shifterConfig);
544
545 /* 2. Configure the shifter 1 for rx. */
546 shifterConfig.timerSelect = base->timerIndex[2];
547 shifterConfig.timerPolarity = kFLEXIO_ShifterTimerPolarityOnNegitive;
548 shifterConfig.pinConfig = kFLEXIO_PinConfigOutputDisabled;
549 shifterConfig.pinSelect = base->SDAPinIndex;
550 shifterConfig.pinPolarity = kFLEXIO_PinActiveHigh;
551 shifterConfig.shifterMode = kFLEXIO_ShifterModeReceive;
552 shifterConfig.inputSource = kFLEXIO_ShifterInputFromPin;
553 shifterConfig.shifterStop = kFLEXIO_ShifterStopBitLow;
554 shifterConfig.shifterStart = kFLEXIO_ShifterStartBitDisabledLoadDataOnEnable;
555
556 FLEXIO_SetShifterConfig(base->flexioBase, base->shifterIndex[1], &shifterConfig);
557
558 /*3. Configure the timer 0 and timer 1 for generating bit clock. */
559 /* timer 1 is used to config baudrate */
560 timerConfig.triggerSelect = FLEXIO_TIMER_TRIGGER_SEL_SHIFTnSTAT(base->shifterIndex[0]);
561 timerConfig.triggerPolarity = kFLEXIO_TimerTriggerPolarityActiveLow;
562 timerConfig.triggerSource = kFLEXIO_TimerTriggerSourceInternal;
563 timerConfig.pinConfig = kFLEXIO_PinConfigOpenDrainOrBidirection;
564 timerConfig.pinSelect = base->SCLPinIndex;
565 timerConfig.pinPolarity = kFLEXIO_PinActiveHigh;
566 timerConfig.timerMode = kFLEXIO_TimerModeSingle16Bit;
567 timerConfig.timerOutput = kFLEXIO_TimerOutputZeroNotAffectedByReset;
568 timerConfig.timerDecrement = kFLEXIO_TimerDecSrcOnFlexIOClockShiftTimerOutput;
569 timerConfig.timerReset = kFLEXIO_TimerResetOnTimerPinEqualToTimerOutput;
570 timerConfig.timerDisable = kFLEXIO_TimerDisableOnPreTimerDisable;
571 timerConfig.timerEnable = kFLEXIO_TimerEnableOnTriggerHigh;
572 timerConfig.timerStop = kFLEXIO_TimerStopBitDisabled;
573 timerConfig.timerStart = kFLEXIO_TimerStartBitDisabled;
574
575 /* Set TIMCMP = (baud rate divider / 2) - 1. */
576 timerDiv = (uint16_t)(srcClock_Hz / masterConfig->baudRate_Bps) / 2U - 1U;
577 /* Calculate and assign the actual baudrate. */
578 base->baudrate = srcClock_Hz / (2U * ((uint32_t)timerDiv + 1U));
579
580 timerConfig.timerCompare = timerDiv;
581
582 FLEXIO_SetTimerConfig(base->flexioBase, base->timerIndex[1], &timerConfig);
583
584 /* timer 0 is used to config total shift clock edges */
585 timerConfig.triggerSelect = FLEXIO_TIMER_TRIGGER_SEL_SHIFTnSTAT(base->shifterIndex[0]);
586 timerConfig.triggerPolarity = kFLEXIO_TimerTriggerPolarityActiveLow;
587 timerConfig.triggerSource = kFLEXIO_TimerTriggerSourceInternal;
588 timerConfig.pinConfig = kFLEXIO_PinConfigOutputDisabled;
589 timerConfig.pinSelect = base->SCLPinIndex;
590 timerConfig.pinPolarity = kFLEXIO_PinActiveHigh;
591 timerConfig.timerMode = kFLEXIO_TimerModeSingle16Bit;
592 timerConfig.timerOutput = kFLEXIO_TimerOutputOneNotAffectedByReset;
593 timerConfig.timerDecrement = kFLEXIO_TimerDecSrcOnPinInputShiftPinInput;
594 timerConfig.timerReset = kFLEXIO_TimerResetNever;
595 timerConfig.timerDisable = kFLEXIO_TimerDisableOnTimerCompare;
596 timerConfig.timerEnable = kFLEXIO_TimerEnableOnTriggerHigh;
597 timerConfig.timerStop = kFLEXIO_TimerStopBitDisabled;
598 timerConfig.timerStart = kFLEXIO_TimerStartBitDisabled;
599
600 /* Set TIMCMP when confinguring transfer bytes. */
601 FLEXIO_SetTimerConfig(base->flexioBase, base->timerIndex[0], &timerConfig);
602
603 /* 4. Configure the timer 2 for controlling shifters. */
604 timerConfig.triggerSelect = FLEXIO_TIMER_TRIGGER_SEL_SHIFTnSTAT(base->shifterIndex[0]);
605 timerConfig.triggerPolarity = kFLEXIO_TimerTriggerPolarityActiveLow;
606 timerConfig.triggerSource = kFLEXIO_TimerTriggerSourceInternal;
607 timerConfig.pinConfig = kFLEXIO_PinConfigOutputDisabled;
608 timerConfig.pinSelect = base->SCLPinIndex;
609 timerConfig.pinPolarity = kFLEXIO_PinActiveLow;
610 timerConfig.timerMode = kFLEXIO_TimerModeSingle16Bit;
611 timerConfig.timerOutput = kFLEXIO_TimerOutputOneNotAffectedByReset;
612 timerConfig.timerDecrement = kFLEXIO_TimerDecSrcOnPinInputShiftPinInput;
613 timerConfig.timerReset = kFLEXIO_TimerResetNever;
614 timerConfig.timerDisable = kFLEXIO_TimerDisableOnPreTimerDisable;
615 timerConfig.timerEnable = kFLEXIO_TimerEnableOnPrevTimerEnable;
616 timerConfig.timerStop = kFLEXIO_TimerStopBitEnableOnTimerCompare;
617 timerConfig.timerStart = kFLEXIO_TimerStartBitEnabled;
618
619 /* Set TIMCMP[15:0] = (number of bits x 2) - 1. */
620 timerConfig.timerCompare = 8U * 2U - 1U;
621
622 FLEXIO_SetTimerConfig(base->flexioBase, base->timerIndex[2], &timerConfig);
623
624 /* Configure FLEXIO I2C Master. */
625 controlVal = base->flexioBase->CTRL;
626 controlVal &=
627 ~(FLEXIO_CTRL_DOZEN_MASK | FLEXIO_CTRL_DBGE_MASK | FLEXIO_CTRL_FASTACC_MASK | FLEXIO_CTRL_FLEXEN_MASK);
628 controlVal |= (FLEXIO_CTRL_DBGE(masterConfig->enableInDebug) | FLEXIO_CTRL_FASTACC(masterConfig->enableFastAccess) |
629 FLEXIO_CTRL_FLEXEN(masterConfig->enableMaster));
630 if (!masterConfig->enableInDoze)
631 {
632 controlVal |= FLEXIO_CTRL_DOZEN_MASK;
633 }
634
635 base->flexioBase->CTRL = controlVal;
636 /* Disable internal IRQs. */
637 FLEXIO_I2C_MasterDisableInterrupts(
638 base, (uint32_t)kFLEXIO_I2C_TxEmptyInterruptEnable | (uint32_t)kFLEXIO_I2C_RxFullInterruptEnable);
639 return result;
640 }
641
642 /*!
643 * brief De-initializes the FlexIO I2C master peripheral. Calling this API Resets the FlexIO I2C master
644 * shifer and timer config, module can't work unless the FLEXIO_I2C_MasterInit is called.
645 *
646 * param base pointer to FLEXIO_I2C_Type structure.
647 */
FLEXIO_I2C_MasterDeinit(FLEXIO_I2C_Type * base)648 void FLEXIO_I2C_MasterDeinit(FLEXIO_I2C_Type *base)
649 {
650 base->flexioBase->SHIFTCFG[base->shifterIndex[0]] = 0;
651 base->flexioBase->SHIFTCTL[base->shifterIndex[0]] = 0;
652 base->flexioBase->SHIFTCFG[base->shifterIndex[1]] = 0;
653 base->flexioBase->SHIFTCTL[base->shifterIndex[1]] = 0;
654 base->flexioBase->TIMCFG[base->timerIndex[0]] = 0;
655 base->flexioBase->TIMCMP[base->timerIndex[0]] = 0;
656 base->flexioBase->TIMCTL[base->timerIndex[0]] = 0;
657 base->flexioBase->TIMCFG[base->timerIndex[1]] = 0;
658 base->flexioBase->TIMCMP[base->timerIndex[1]] = 0;
659 base->flexioBase->TIMCTL[base->timerIndex[1]] = 0;
660 base->flexioBase->TIMCFG[base->timerIndex[2]] = 0;
661 base->flexioBase->TIMCMP[base->timerIndex[2]] = 0;
662 base->flexioBase->TIMCTL[base->timerIndex[2]] = 0;
663 /* Clear the shifter flag. */
664 base->flexioBase->SHIFTSTAT = (1UL << base->shifterIndex[0]);
665 base->flexioBase->SHIFTSTAT = (1UL << base->shifterIndex[1]);
666 /* Clear the timer flag. */
667 base->flexioBase->TIMSTAT = (1UL << base->timerIndex[0]);
668 base->flexioBase->TIMSTAT = (1UL << base->timerIndex[1]);
669 base->flexioBase->TIMSTAT = (1UL << base->timerIndex[2]);
670 }
671
672 /*!
673 * brief Gets the default configuration to configure the FlexIO module. The configuration
674 * can be used directly for calling the FLEXIO_I2C_MasterInit().
675 *
676 * Example:
677 code
678 flexio_i2c_master_config_t config;
679 FLEXIO_I2C_MasterGetDefaultConfig(&config);
680 endcode
681 * param masterConfig Pointer to flexio_i2c_master_config_t structure.
682 */
FLEXIO_I2C_MasterGetDefaultConfig(flexio_i2c_master_config_t * masterConfig)683 void FLEXIO_I2C_MasterGetDefaultConfig(flexio_i2c_master_config_t *masterConfig)
684 {
685 assert(masterConfig != NULL);
686
687 /* Initializes the configure structure to zero. */
688 (void)memset(masterConfig, 0, sizeof(*masterConfig));
689
690 masterConfig->enableMaster = true;
691 masterConfig->enableInDoze = false;
692 masterConfig->enableInDebug = true;
693 masterConfig->enableFastAccess = false;
694
695 /* Default baud rate at 100kbps. */
696 masterConfig->baudRate_Bps = 100000U;
697 }
698
699 /*!
700 * brief Gets the FlexIO I2C master status flags.
701 *
702 * param base Pointer to FLEXIO_I2C_Type structure
703 * return Status flag, use status flag to AND #_flexio_i2c_master_status_flags can get the related status.
704 */
705
FLEXIO_I2C_MasterGetStatusFlags(FLEXIO_I2C_Type * base)706 uint32_t FLEXIO_I2C_MasterGetStatusFlags(FLEXIO_I2C_Type *base)
707 {
708 uint32_t status = 0;
709
710 status =
711 ((FLEXIO_GetShifterStatusFlags(base->flexioBase) & (1UL << base->shifterIndex[0])) >> base->shifterIndex[0]);
712 status |=
713 (((FLEXIO_GetShifterStatusFlags(base->flexioBase) & (1UL << base->shifterIndex[1])) >> (base->shifterIndex[1]))
714 << 1U);
715 status |=
716 (((FLEXIO_GetShifterErrorFlags(base->flexioBase) & (1UL << base->shifterIndex[1])) >> (base->shifterIndex[1]))
717 << 2U);
718
719 return status;
720 }
721
722 /*!
723 * brief Clears the FlexIO I2C master status flags.
724 *
725 * param base Pointer to FLEXIO_I2C_Type structure.
726 * param mask Status flag.
727 * The parameter can be any combination of the following values:
728 * arg kFLEXIO_I2C_RxFullFlag
729 * arg kFLEXIO_I2C_ReceiveNakFlag
730 */
731
FLEXIO_I2C_MasterClearStatusFlags(FLEXIO_I2C_Type * base,uint32_t mask)732 void FLEXIO_I2C_MasterClearStatusFlags(FLEXIO_I2C_Type *base, uint32_t mask)
733 {
734 if ((mask & (uint32_t)kFLEXIO_I2C_TxEmptyFlag) != 0U)
735 {
736 FLEXIO_ClearShifterStatusFlags(base->flexioBase, 1UL << base->shifterIndex[0]);
737 }
738
739 if ((mask & (uint32_t)kFLEXIO_I2C_RxFullFlag) != 0U)
740 {
741 FLEXIO_ClearShifterStatusFlags(base->flexioBase, 1UL << base->shifterIndex[1]);
742 }
743
744 if ((mask & (uint32_t)kFLEXIO_I2C_ReceiveNakFlag) != 0U)
745 {
746 FLEXIO_ClearShifterErrorFlags(base->flexioBase, 1UL << base->shifterIndex[1]);
747 }
748 }
749
750 /*!
751 * brief Enables the FlexIO i2c master interrupt requests.
752 *
753 * param base Pointer to FLEXIO_I2C_Type structure.
754 * param mask Interrupt source.
755 * Currently only one interrupt request source:
756 * arg kFLEXIO_I2C_TransferCompleteInterruptEnable
757 */
FLEXIO_I2C_MasterEnableInterrupts(FLEXIO_I2C_Type * base,uint32_t mask)758 void FLEXIO_I2C_MasterEnableInterrupts(FLEXIO_I2C_Type *base, uint32_t mask)
759 {
760 if ((mask & (uint32_t)kFLEXIO_I2C_TxEmptyInterruptEnable) != 0U)
761 {
762 FLEXIO_EnableShifterStatusInterrupts(base->flexioBase, 1UL << base->shifterIndex[0]);
763 }
764 if ((mask & (uint32_t)kFLEXIO_I2C_RxFullInterruptEnable) != 0U)
765 {
766 FLEXIO_EnableShifterStatusInterrupts(base->flexioBase, 1UL << base->shifterIndex[1]);
767 }
768 }
769
770 /*!
771 * brief Disables the FlexIO I2C master interrupt requests.
772 *
773 * param base Pointer to FLEXIO_I2C_Type structure.
774 * param mask Interrupt source.
775 */
FLEXIO_I2C_MasterDisableInterrupts(FLEXIO_I2C_Type * base,uint32_t mask)776 void FLEXIO_I2C_MasterDisableInterrupts(FLEXIO_I2C_Type *base, uint32_t mask)
777 {
778 if ((mask & (uint32_t)kFLEXIO_I2C_TxEmptyInterruptEnable) != 0U)
779 {
780 FLEXIO_DisableShifterStatusInterrupts(base->flexioBase, 1UL << base->shifterIndex[0]);
781 }
782 if ((mask & (uint32_t)kFLEXIO_I2C_RxFullInterruptEnable) != 0U)
783 {
784 FLEXIO_DisableShifterStatusInterrupts(base->flexioBase, 1UL << base->shifterIndex[1]);
785 }
786 }
787
788 /*!
789 * brief Sets the FlexIO I2C master transfer baudrate.
790 *
791 * param base Pointer to FLEXIO_I2C_Type structure
792 * param baudRate_Bps the baud rate value in HZ
793 * param srcClock_Hz source clock in HZ
794 */
FLEXIO_I2C_MasterSetBaudRate(FLEXIO_I2C_Type * base,uint32_t baudRate_Bps,uint32_t srcClock_Hz)795 void FLEXIO_I2C_MasterSetBaudRate(FLEXIO_I2C_Type *base, uint32_t baudRate_Bps, uint32_t srcClock_Hz)
796 {
797 uint16_t timerDiv = 0;
798 FLEXIO_Type *flexioBase = base->flexioBase;
799
800 /* Set TIMCMP = (baud rate divider / 2) - 1.*/
801 timerDiv = (uint16_t)((srcClock_Hz / baudRate_Bps) / 2U - 1U);
802
803 flexioBase->TIMCMP[base->timerIndex[1]] = timerDiv;
804
805 /* Calculate and assign the actual baudrate. */
806 base->baudrate = srcClock_Hz / (2U * ((uint32_t)timerDiv + 1U));
807 }
808
809 /*!
810 * brief Sets the number of bytes to be transferred from a start signal to a stop signal.
811 *
812 * note Call this API before a transfer begins because the timer generates a number of clocks according
813 * to the number of bytes that need to be transferred.
814 *
815 * param base Pointer to FLEXIO_I2C_Type structure.
816 * param count Number of bytes need to be transferred from a start signal to a re-start/stop signal
817 * retval kStatus_Success Successfully configured the count.
818 * retval kStatus_InvalidArgument Input argument is invalid.
819 */
FLEXIO_I2C_MasterSetTransferCount(FLEXIO_I2C_Type * base,uint16_t count)820 status_t FLEXIO_I2C_MasterSetTransferCount(FLEXIO_I2C_Type *base, uint16_t count)
821 {
822 /* Calculate whether the transfer count is larger than the max value compare register can achieve */
823 if (count > ((0xFFFFUL - 1UL) / (16UL + 1UL + 1UL)))
824 {
825 return kStatus_InvalidArgument;
826 }
827
828 uint32_t timerConfig = 0U;
829 FLEXIO_Type *flexioBase = base->flexioBase;
830
831 flexioBase->TIMCMP[base->timerIndex[0]] = (uint32_t)count * 18U + 1U;
832 timerConfig = flexioBase->TIMCFG[base->timerIndex[0]];
833 timerConfig &= ~FLEXIO_TIMCFG_TIMDIS_MASK;
834 timerConfig |= FLEXIO_TIMCFG_TIMDIS(kFLEXIO_TimerDisableOnTimerCompare);
835 flexioBase->TIMCFG[base->timerIndex[0]] = timerConfig;
836
837 return kStatus_Success;
838 }
839
840 /*!
841 * brief Sends START + 7-bit address to the bus.
842 *
843 * note This API should be called when the transfer configuration is ready to send a START signal
844 * and 7-bit address to the bus. This is a non-blocking API, which returns directly after the address
845 * is put into the data register but the address transfer is not finished on the bus. Ensure that
846 * the kFLEXIO_I2C_RxFullFlag status is asserted before calling this API.
847 * param base Pointer to FLEXIO_I2C_Type structure.
848 * param address 7-bit address.
849 * param direction transfer direction.
850 * This parameter is one of the values in flexio_i2c_direction_t:
851 * arg kFLEXIO_I2C_Write: Transmit
852 * arg kFLEXIO_I2C_Read: Receive
853 */
854
FLEXIO_I2C_MasterStart(FLEXIO_I2C_Type * base,uint8_t address,flexio_i2c_direction_t direction)855 void FLEXIO_I2C_MasterStart(FLEXIO_I2C_Type *base, uint8_t address, flexio_i2c_direction_t direction)
856 {
857 uint32_t data;
858
859 data = ((uint32_t)address) << 1U | ((direction == kFLEXIO_I2C_Read) ? 1U : 0U);
860
861 FLEXIO_I2C_MasterWriteByte(base, data);
862 }
863
864 /*!
865 * brief Sends the repeated start signal on the bus.
866 *
867 * param base Pointer to FLEXIO_I2C_Type structure.
868 */
FLEXIO_I2C_MasterRepeatedStart(FLEXIO_I2C_Type * base)869 void FLEXIO_I2C_MasterRepeatedStart(FLEXIO_I2C_Type *base)
870 {
871 /* Prepare for RESTART condition, no stop.*/
872 FLEXIO_I2C_MasterWriteByte(base, 0xFFFFFFFFU);
873 }
874
875 /*!
876 * brief Sends the stop signal on the bus.
877 *
878 * param base Pointer to FLEXIO_I2C_Type structure.
879 */
FLEXIO_I2C_MasterStop(FLEXIO_I2C_Type * base)880 void FLEXIO_I2C_MasterStop(FLEXIO_I2C_Type *base)
881 {
882 /* Prepare normal stop. */
883 (void)FLEXIO_I2C_MasterSetTransferCount(base, 0x0U);
884 FLEXIO_I2C_MasterWriteByte(base, 0x0U);
885 }
886
887 /*!
888 * brief Sends the stop signal when transfer is still on-going.
889 *
890 * param base Pointer to FLEXIO_I2C_Type structure.
891 */
FLEXIO_I2C_MasterAbortStop(FLEXIO_I2C_Type * base)892 void FLEXIO_I2C_MasterAbortStop(FLEXIO_I2C_Type *base)
893 {
894 uint32_t tmpConfig;
895
896 /* Prepare abort stop. */
897 /* Disable timer 0. */
898 tmpConfig = base->flexioBase->TIMCFG[base->timerIndex[0]];
899 tmpConfig &= ~FLEXIO_TIMCFG_TIMDIS_MASK;
900 tmpConfig |= FLEXIO_TIMCFG_TIMDIS(kFLEXIO_TimerDisableOnPinBothEdge);
901 base->flexioBase->TIMCFG[base->timerIndex[0]] = tmpConfig;
902
903 /* Disable timer 1. */
904 tmpConfig = base->flexioBase->TIMCFG[base->timerIndex[1]];
905 tmpConfig &= ~FLEXIO_TIMCFG_TIMDIS_MASK;
906 tmpConfig |= FLEXIO_TIMCFG_TIMDIS(kFLEXIO_TimerDisableOnPinBothEdge);
907 base->flexioBase->TIMCFG[base->timerIndex[1]] = tmpConfig;
908 }
909
910 /*!
911 * brief Configures the sent ACK/NAK for the following byte.
912 *
913 * param base Pointer to FLEXIO_I2C_Type structure.
914 * param enable True to configure send ACK, false configure to send NAK.
915 */
FLEXIO_I2C_MasterEnableAck(FLEXIO_I2C_Type * base,bool enable)916 void FLEXIO_I2C_MasterEnableAck(FLEXIO_I2C_Type *base, bool enable)
917 {
918 uint32_t tmpConfig = 0;
919
920 tmpConfig = base->flexioBase->SHIFTCFG[base->shifterIndex[0]];
921 tmpConfig &= ~FLEXIO_SHIFTCFG_SSTOP_MASK;
922 if (enable)
923 {
924 tmpConfig |= FLEXIO_SHIFTCFG_SSTOP(kFLEXIO_ShifterStopBitLow);
925 }
926 else
927 {
928 tmpConfig |= FLEXIO_SHIFTCFG_SSTOP(kFLEXIO_ShifterStopBitHigh);
929 }
930 base->flexioBase->SHIFTCFG[base->shifterIndex[0]] = tmpConfig;
931 }
932
933 /*!
934 * brief Sends a buffer of data in bytes.
935 *
936 * note This function blocks via polling until all bytes have been sent.
937 *
938 * param base Pointer to FLEXIO_I2C_Type structure.
939 * param txBuff The data bytes to send.
940 * param txSize The number of data bytes to send.
941 * retval kStatus_Success Successfully write data.
942 * retval kStatus_FLEXIO_I2C_Nak Receive NAK during writing data.
943 * retval kStatus_FLEXIO_I2C_Timeout Timeout polling status flags.
944 */
FLEXIO_I2C_MasterWriteBlocking(FLEXIO_I2C_Type * base,const uint8_t * txBuff,uint8_t txSize)945 status_t FLEXIO_I2C_MasterWriteBlocking(FLEXIO_I2C_Type *base, const uint8_t *txBuff, uint8_t txSize)
946 {
947 assert(txBuff != NULL);
948 assert(txSize != 0U);
949
950 uint32_t status;
951 #if I2C_RETRY_TIMES
952 uint32_t waitTimes = I2C_RETRY_TIMES;
953 #endif
954
955 while (0U != txSize--)
956 {
957 FLEXIO_I2C_MasterWriteByte(base, *txBuff++);
958
959 /* Wait until data transfer complete. */
960 #if I2C_RETRY_TIMES
961 waitTimes = I2C_RETRY_TIMES;
962 while ((0U == ((status = FLEXIO_I2C_MasterGetStatusFlags(base)) & (uint32_t)kFLEXIO_I2C_RxFullFlag)) &&
963 (0U != --waitTimes))
964 {
965 }
966 if (0U == waitTimes)
967 {
968 return kStatus_FLEXIO_I2C_Timeout;
969 }
970 #else
971 while (0U == ((status = FLEXIO_I2C_MasterGetStatusFlags(base)) & (uint32_t)kFLEXIO_I2C_RxFullFlag))
972 {
973 }
974 #endif
975
976 if ((status & (uint32_t)kFLEXIO_I2C_ReceiveNakFlag) != 0U)
977 {
978 FLEXIO_ClearShifterErrorFlags(base->flexioBase, 1UL << base->shifterIndex[1]);
979 return kStatus_FLEXIO_I2C_Nak;
980 }
981 }
982 return kStatus_Success;
983 }
984
985 /*!
986 * brief Receives a buffer of bytes.
987 *
988 * note This function blocks via polling until all bytes have been received.
989 *
990 * param base Pointer to FLEXIO_I2C_Type structure.
991 * param rxBuff The buffer to store the received bytes.
992 * param rxSize The number of data bytes to be received.
993 * retval kStatus_Success Successfully read data.
994 * retval kStatus_FLEXIO_I2C_Timeout Timeout polling status flags.
995 */
FLEXIO_I2C_MasterReadBlocking(FLEXIO_I2C_Type * base,uint8_t * rxBuff,uint8_t rxSize)996 status_t FLEXIO_I2C_MasterReadBlocking(FLEXIO_I2C_Type *base, uint8_t *rxBuff, uint8_t rxSize)
997 {
998 assert(rxBuff != NULL);
999 assert(rxSize != 0U);
1000
1001 #if I2C_RETRY_TIMES
1002 uint32_t waitTimes = I2C_RETRY_TIMES;
1003 #endif
1004
1005 while (0U != rxSize--)
1006 {
1007 /* Wait until data transfer complete. */
1008 #if I2C_RETRY_TIMES
1009 waitTimes = I2C_RETRY_TIMES;
1010 while ((0U == (FLEXIO_I2C_MasterGetStatusFlags(base) & (uint32_t)kFLEXIO_I2C_RxFullFlag)) &&
1011 (0U != --waitTimes))
1012 {
1013 }
1014 if (0U == waitTimes)
1015 {
1016 return kStatus_FLEXIO_I2C_Timeout;
1017 }
1018 #else
1019 while (0U == (FLEXIO_I2C_MasterGetStatusFlags(base) & (uint32_t)kFLEXIO_I2C_RxFullFlag))
1020 {
1021 }
1022 #endif
1023 *rxBuff++ = FLEXIO_I2C_MasterReadByte(base);
1024 }
1025 return kStatus_Success;
1026 }
1027
1028 /*!
1029 * brief Performs a master polling transfer on the I2C bus.
1030 *
1031 * note The API does not return until the transfer succeeds or fails due
1032 * to receiving NAK.
1033 *
1034 * param base pointer to FLEXIO_I2C_Type structure.
1035 * param xfer pointer to flexio_i2c_master_transfer_t structure.
1036 * return status of status_t.
1037 */
FLEXIO_I2C_MasterTransferBlocking(FLEXIO_I2C_Type * base,flexio_i2c_master_transfer_t * xfer)1038 status_t FLEXIO_I2C_MasterTransferBlocking(FLEXIO_I2C_Type *base, flexio_i2c_master_transfer_t *xfer)
1039 {
1040 assert(xfer != NULL);
1041
1042 #if defined(FSL_FEATURE_FLEXIO_HAS_PIN_STATUS) && FSL_FEATURE_FLEXIO_HAS_PIN_STATUS
1043 /* Return an error if the bus is already in use not by us.*/
1044 status_t status = FLEXIO_I2C_CheckForBusyBus(base);
1045 if (status != kStatus_Success)
1046 {
1047 return status;
1048 }
1049 #endif /*FSL_FEATURE_FLEXIO_HAS_PIN_STATUS*/
1050
1051 flexio_i2c_master_handle_t tmpHandle;
1052 uint32_t statusFlags;
1053 status_t result = kStatus_Success;
1054 #if I2C_RETRY_TIMES
1055 uint32_t waitTimes = I2C_RETRY_TIMES;
1056 #endif
1057
1058 /* Zero the handle. */
1059 (void)memset(&tmpHandle, 0, sizeof(tmpHandle));
1060
1061 /* Set up transfer machine. */
1062 result = FLEXIO_I2C_MasterTransferInitStateMachine(base, &tmpHandle, xfer);
1063 if (result != kStatus_Success)
1064 {
1065 return result;
1066 }
1067
1068 do
1069 {
1070 /* Wait either tx empty or rx full flag is asserted. */
1071 #if I2C_RETRY_TIMES
1072 waitTimes = I2C_RETRY_TIMES;
1073 while ((0U == ((statusFlags = FLEXIO_I2C_MasterGetStatusFlags(base)) &
1074 ((uint32_t)kFLEXIO_I2C_TxEmptyFlag | (uint32_t)kFLEXIO_I2C_RxFullFlag))) &&
1075 (0U != --waitTimes))
1076 {
1077 }
1078 if (0U == waitTimes)
1079 {
1080 return kStatus_FLEXIO_I2C_Timeout;
1081 }
1082 #else
1083 while (0U == ((statusFlags = FLEXIO_I2C_MasterGetStatusFlags(base)) &
1084 ((uint32_t)kFLEXIO_I2C_TxEmptyFlag | (uint32_t)kFLEXIO_I2C_RxFullFlag)))
1085 {
1086 }
1087 #endif
1088 FLEXIO_ClearTimerStatusFlags(base->flexioBase, ((1UL << base->timerIndex[0]) | (1UL << base->timerIndex[1])));
1089 result = FLEXIO_I2C_MasterTransferRunStateMachine(base, &tmpHandle, statusFlags);
1090
1091 } while ((tmpHandle.state != (uint8_t)kFLEXIO_I2C_Idle) && (result == kStatus_Success));
1092
1093 /* Timer disable on timer compare, wait until bit clock TSF set, which means timer disable and stop has been sent.
1094 */
1095 while (0U == (FLEXIO_GetTimerStatusFlags(base->flexioBase) & (1UL << base->timerIndex[1])))
1096 {
1097 }
1098
1099 return result;
1100 }
1101
1102 /*!
1103 * brief Initializes the I2C handle which is used in transactional functions.
1104 *
1105 * param base Pointer to FLEXIO_I2C_Type structure.
1106 * param handle Pointer to flexio_i2c_master_handle_t structure to store the transfer state.
1107 * param callback Pointer to user callback function.
1108 * param userData User param passed to the callback function.
1109 * retval kStatus_Success Successfully create the handle.
1110 * retval kStatus_OutOfRange The FlexIO type/handle/isr table out of range.
1111 */
FLEXIO_I2C_MasterTransferCreateHandle(FLEXIO_I2C_Type * base,flexio_i2c_master_handle_t * handle,flexio_i2c_master_transfer_callback_t callback,void * userData)1112 status_t FLEXIO_I2C_MasterTransferCreateHandle(FLEXIO_I2C_Type *base,
1113 flexio_i2c_master_handle_t *handle,
1114 flexio_i2c_master_transfer_callback_t callback,
1115 void *userData)
1116 {
1117 assert(handle != NULL);
1118
1119 IRQn_Type flexio_irqs[] = FLEXIO_IRQS;
1120
1121 /* Zero the handle. */
1122 (void)memset(handle, 0, sizeof(*handle));
1123
1124 /* Register callback and userData. */
1125 handle->completionCallback = callback;
1126 handle->userData = userData;
1127
1128 /* Clear pending NVIC IRQ before enable NVIC IRQ. */
1129 NVIC_ClearPendingIRQ(flexio_irqs[FLEXIO_I2C_GetInstance(base)]);
1130 (void)EnableIRQ(flexio_irqs[FLEXIO_I2C_GetInstance(base)]);
1131
1132 /* Save the context in global variables to support the double weak mechanism. */
1133 return FLEXIO_RegisterHandleIRQ(base, handle, FLEXIO_I2C_MasterTransferHandleIRQ);
1134 }
1135
1136 /*!
1137 * brief Performs a master interrupt non-blocking transfer on the I2C bus.
1138 *
1139 * note The API returns immediately after the transfer initiates.
1140 * Call FLEXIO_I2C_MasterTransferGetCount to poll the transfer status to check whether
1141 * the transfer is finished. If the return status is not kStatus_FLEXIO_I2C_Busy, the transfer
1142 * is finished.
1143 *
1144 * param base Pointer to FLEXIO_I2C_Type structure
1145 * param handle Pointer to flexio_i2c_master_handle_t structure which stores the transfer state
1146 * param xfer pointer to flexio_i2c_master_transfer_t structure
1147 * retval kStatus_Success Successfully start a transfer.
1148 * retval kStatus_FLEXIO_I2C_Busy FlexIO I2C is not idle, is running another transfer.
1149 */
FLEXIO_I2C_MasterTransferNonBlocking(FLEXIO_I2C_Type * base,flexio_i2c_master_handle_t * handle,flexio_i2c_master_transfer_t * xfer)1150 status_t FLEXIO_I2C_MasterTransferNonBlocking(FLEXIO_I2C_Type *base,
1151 flexio_i2c_master_handle_t *handle,
1152 flexio_i2c_master_transfer_t *xfer)
1153 {
1154 assert(handle != NULL);
1155 assert(xfer != NULL);
1156
1157 status_t result = kStatus_Success;
1158
1159 #if defined(FSL_FEATURE_FLEXIO_HAS_PIN_STATUS) && FSL_FEATURE_FLEXIO_HAS_PIN_STATUS
1160 /* Return an error if the bus is already in use not by us.*/
1161 result = FLEXIO_I2C_CheckForBusyBus(base);
1162 if (result != kStatus_Success)
1163 {
1164 return result;
1165 }
1166 #endif /*FSL_FEATURE_FLEXIO_HAS_PIN_STATUS*/
1167
1168 if (handle->state != (uint8_t)kFLEXIO_I2C_Idle)
1169 {
1170 return kStatus_FLEXIO_I2C_Busy;
1171 }
1172 else
1173 {
1174 /* Set up transfer machine. */
1175 result = FLEXIO_I2C_MasterTransferInitStateMachine(base, handle, xfer);
1176 if (result != kStatus_Success)
1177 {
1178 return result;
1179 }
1180
1181 /* Enable both tx empty and rxfull interrupt. */
1182 FLEXIO_I2C_MasterEnableInterrupts(
1183 base, (uint32_t)kFLEXIO_I2C_TxEmptyInterruptEnable | (uint32_t)kFLEXIO_I2C_RxFullInterruptEnable);
1184
1185 return kStatus_Success;
1186 }
1187 }
1188
1189 /*!
1190 * brief Aborts an interrupt non-blocking transfer early.
1191 *
1192 * note This API can be called at any time when an interrupt non-blocking transfer initiates
1193 * to abort the transfer early.
1194 *
1195 * param base Pointer to FLEXIO_I2C_Type structure
1196 * param handle Pointer to flexio_i2c_master_handle_t structure which stores the transfer state
1197 */
FLEXIO_I2C_MasterTransferAbort(FLEXIO_I2C_Type * base,flexio_i2c_master_handle_t * handle)1198 void FLEXIO_I2C_MasterTransferAbort(FLEXIO_I2C_Type *base, flexio_i2c_master_handle_t *handle)
1199 {
1200 assert(handle != NULL);
1201
1202 /* Disable interrupts. */
1203 FLEXIO_I2C_MasterDisableInterrupts(
1204 base, (uint32_t)kFLEXIO_I2C_TxEmptyInterruptEnable | (uint32_t)kFLEXIO_I2C_RxFullInterruptEnable);
1205
1206 /* Reset to idle state. */
1207 handle->state = (uint8_t)kFLEXIO_I2C_Idle;
1208 }
1209
1210 /*!
1211 * brief Gets the master transfer status during a interrupt non-blocking transfer.
1212 *
1213 * param base Pointer to FLEXIO_I2C_Type structure.
1214 * param handle Pointer to flexio_i2c_master_handle_t structure which stores the transfer state.
1215 * param count Number of bytes transferred so far by the non-blocking transaction.
1216 * retval kStatus_InvalidArgument count is Invalid.
1217 * retval kStatus_NoTransferInProgress There is not a non-blocking transaction currently in progress.
1218 * retval kStatus_Success Successfully return the count.
1219 */
FLEXIO_I2C_MasterTransferGetCount(FLEXIO_I2C_Type * base,flexio_i2c_master_handle_t * handle,size_t * count)1220 status_t FLEXIO_I2C_MasterTransferGetCount(FLEXIO_I2C_Type *base, flexio_i2c_master_handle_t *handle, size_t *count)
1221 {
1222 if (NULL == count)
1223 {
1224 return kStatus_InvalidArgument;
1225 }
1226
1227 /* Catch when there is not an active transfer. */
1228 if (handle->state == (uint8_t)kFLEXIO_I2C_Idle)
1229 {
1230 *count = 0;
1231 return kStatus_NoTransferInProgress;
1232 }
1233
1234 *count = handle->transferSize - handle->transfer.dataSize;
1235
1236 return kStatus_Success;
1237 }
1238
1239 /*!
1240 * brief Master interrupt handler.
1241 *
1242 * param i2cType Pointer to FLEXIO_I2C_Type structure
1243 * param i2cHandle Pointer to flexio_i2c_master_transfer_t structure
1244 */
FLEXIO_I2C_MasterTransferHandleIRQ(void * i2cType,void * i2cHandle)1245 void FLEXIO_I2C_MasterTransferHandleIRQ(void *i2cType, void *i2cHandle)
1246 {
1247 FLEXIO_I2C_Type *base = (FLEXIO_I2C_Type *)i2cType;
1248 flexio_i2c_master_handle_t *handle = (flexio_i2c_master_handle_t *)i2cHandle;
1249 uint32_t statusFlags;
1250 status_t result;
1251
1252 statusFlags = FLEXIO_I2C_MasterGetStatusFlags(base);
1253
1254 result = FLEXIO_I2C_MasterTransferRunStateMachine(base, handle, statusFlags);
1255
1256 if (handle->state == (uint8_t)kFLEXIO_I2C_Idle)
1257 {
1258 FLEXIO_I2C_MasterTransferComplete(base, handle, result);
1259 }
1260 }
1261