1 /*
2 * Copyright (c) 2015, Freescale Semiconductor, Inc.
3 * Copyright 2016-2017 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 /*! @brief FLEXIO I2C transfer state */
16 enum _flexio_i2c_master_transfer_states
17 {
18 kFLEXIO_I2C_Idle = 0x0U, /*!< I2C bus idle */
19 kFLEXIO_I2C_CheckAddress = 0x1U, /*!< 7-bit address check state */
20 kFLEXIO_I2C_SendCommand = 0x2U, /*!< Send command byte phase */
21 kFLEXIO_I2C_SendData = 0x3U, /*!< Send data transfer phase*/
22 kFLEXIO_I2C_ReceiveDataBegin = 0x4U, /*!< Receive data begin transfer phase*/
23 kFLEXIO_I2C_ReceiveData = 0x5U, /*!< Receive data transfer phase*/
24 };
25
26 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
27 extern const clock_ip_name_t s_flexioClocks[];
28 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
29
30 extern FLEXIO_Type *const s_flexioBases[];
31
32 /*******************************************************************************
33 * Prototypes
34 ******************************************************************************/
35
36 extern uint32_t FLEXIO_GetInstance(FLEXIO_Type *base);
37
38 /*!
39 * @brief Set up master transfer, send slave address and decide the initial
40 * transfer state.
41 *
42 * @param base pointer to FLEXIO_I2C_Type structure
43 * @param handle pointer to flexio_i2c_master_handle_t structure which stores the transfer state
44 * @param transfer pointer to flexio_i2c_master_transfer_t structure
45 */
46 static status_t FLEXIO_I2C_MasterTransferInitStateMachine(FLEXIO_I2C_Type *base,
47 flexio_i2c_master_handle_t *handle,
48 flexio_i2c_master_transfer_t *xfer);
49
50 /*!
51 * @brief Master run transfer state machine to perform a byte of transfer.
52 *
53 * @param base pointer to FLEXIO_I2C_Type structure
54 * @param handle pointer to flexio_i2c_master_handle_t structure which stores the transfer state
55 * @param statusFlags flexio i2c hardware status
56 * @retval kStatus_Success Successfully run state machine
57 * @retval kStatus_FLEXIO_I2C_Nak Receive Nak during transfer
58 */
59 static status_t FLEXIO_I2C_MasterTransferRunStateMachine(FLEXIO_I2C_Type *base,
60 flexio_i2c_master_handle_t *handle,
61 uint32_t statusFlags);
62
63 /*!
64 * @brief Complete transfer, disable interrupt and call callback.
65 *
66 * @param base pointer to FLEXIO_I2C_Type structure
67 * @param handle pointer to flexio_i2c_master_handle_t structure which stores the transfer state
68 * @param status flexio transfer status
69 */
70 static void FLEXIO_I2C_MasterTransferComplete(FLEXIO_I2C_Type *base,
71 flexio_i2c_master_handle_t *handle,
72 status_t status);
73
74 /*******************************************************************************
75 * Codes
76 ******************************************************************************/
77
FLEXIO_I2C_GetInstance(FLEXIO_I2C_Type * base)78 uint32_t FLEXIO_I2C_GetInstance(FLEXIO_I2C_Type *base)
79 {
80 return FLEXIO_GetInstance(base->flexioBase);
81 }
82
FLEXIO_I2C_MasterTransferInitStateMachine(FLEXIO_I2C_Type * base,flexio_i2c_master_handle_t * handle,flexio_i2c_master_transfer_t * xfer)83 static status_t FLEXIO_I2C_MasterTransferInitStateMachine(FLEXIO_I2C_Type *base,
84 flexio_i2c_master_handle_t *handle,
85 flexio_i2c_master_transfer_t *xfer)
86 {
87 bool needRestart;
88 uint32_t byteCount;
89
90 /* Init the handle member. */
91 handle->transfer.slaveAddress = xfer->slaveAddress;
92 handle->transfer.direction = xfer->direction;
93 handle->transfer.subaddress = xfer->subaddress;
94 handle->transfer.subaddressSize = xfer->subaddressSize;
95 handle->transfer.data = xfer->data;
96 handle->transfer.dataSize = xfer->dataSize;
97 handle->transfer.flags = xfer->flags;
98 handle->transferSize = xfer->dataSize;
99
100 /* Initial state, i2c check address state. */
101 handle->state = kFLEXIO_I2C_CheckAddress;
102
103 /* Clear all status before transfer. */
104 FLEXIO_I2C_MasterClearStatusFlags(base, kFLEXIO_I2C_ReceiveNakFlag);
105
106 /* Calculate whether need to send re-start. */
107 needRestart = (handle->transfer.subaddressSize != 0) && (handle->transfer.direction == kFLEXIO_I2C_Read);
108
109 /* Calculate total byte count in a frame. */
110 byteCount = 1;
111
112 if (!needRestart)
113 {
114 byteCount += handle->transfer.dataSize;
115 }
116
117 if (handle->transfer.subaddressSize != 0)
118 {
119 byteCount += handle->transfer.subaddressSize;
120 /* Next state, send command byte. */
121 handle->state = kFLEXIO_I2C_SendCommand;
122 }
123
124 /* Configure data count. */
125 if (FLEXIO_I2C_MasterSetTransferCount(base, byteCount) != kStatus_Success)
126 {
127 return kStatus_InvalidArgument;
128 }
129
130 while (!((FLEXIO_GetShifterStatusFlags(base->flexioBase) & (1U << base->shifterIndex[0]))))
131 {
132 }
133
134 /* Send address byte first. */
135 if (needRestart)
136 {
137 FLEXIO_I2C_MasterStart(base, handle->transfer.slaveAddress, kFLEXIO_I2C_Write);
138 }
139 else
140 {
141 FLEXIO_I2C_MasterStart(base, handle->transfer.slaveAddress, handle->transfer.direction);
142 }
143
144 return kStatus_Success;
145 }
146
FLEXIO_I2C_MasterTransferRunStateMachine(FLEXIO_I2C_Type * base,flexio_i2c_master_handle_t * handle,uint32_t statusFlags)147 static status_t FLEXIO_I2C_MasterTransferRunStateMachine(FLEXIO_I2C_Type *base,
148 flexio_i2c_master_handle_t *handle,
149 uint32_t statusFlags)
150 {
151 if (statusFlags & kFLEXIO_I2C_ReceiveNakFlag)
152 {
153 /* Clear receive nak flag. */
154 FLEXIO_ClearShifterErrorFlags(base->flexioBase, 1U << base->shifterIndex[1]);
155
156 if ((!((handle->state == kFLEXIO_I2C_SendData) && (handle->transfer.dataSize == 0U))) &&
157 (!(((handle->state == kFLEXIO_I2C_ReceiveData) || (handle->state == kFLEXIO_I2C_ReceiveDataBegin)) &&
158 (handle->transfer.dataSize == 1U))))
159 {
160 FLEXIO_I2C_MasterReadByte(base);
161
162 FLEXIO_I2C_MasterAbortStop(base);
163
164 handle->state = kFLEXIO_I2C_Idle;
165
166 return kStatus_FLEXIO_I2C_Nak;
167 }
168 }
169
170 if (handle->state == kFLEXIO_I2C_CheckAddress)
171 {
172 if (handle->transfer.direction == kFLEXIO_I2C_Write)
173 {
174 /* Next state, send data. */
175 handle->state = kFLEXIO_I2C_SendData;
176 }
177 else
178 {
179 /* Next state, receive data begin. */
180 handle->state = kFLEXIO_I2C_ReceiveDataBegin;
181 }
182 }
183
184 if ((statusFlags & kFLEXIO_I2C_RxFullFlag) && (handle->state != kFLEXIO_I2C_ReceiveData))
185 {
186 FLEXIO_I2C_MasterReadByte(base);
187 }
188
189 switch (handle->state)
190 {
191 case kFLEXIO_I2C_SendCommand:
192 if (statusFlags & kFLEXIO_I2C_TxEmptyFlag)
193 {
194 if (handle->transfer.subaddressSize > 0)
195 {
196 handle->transfer.subaddressSize--;
197 FLEXIO_I2C_MasterWriteByte(
198 base, ((handle->transfer.subaddress) >> (8 * handle->transfer.subaddressSize)));
199
200 if (handle->transfer.subaddressSize == 0)
201 {
202 /* Load re-start in advance. */
203 if (handle->transfer.direction == kFLEXIO_I2C_Read)
204 {
205 while (!((FLEXIO_GetShifterStatusFlags(base->flexioBase) & (1U << base->shifterIndex[0]))))
206 {
207 }
208 FLEXIO_I2C_MasterRepeatedStart(base);
209 }
210 }
211 }
212 else
213 {
214 if (handle->transfer.direction == kFLEXIO_I2C_Write)
215 {
216 /* Next state, send data. */
217 handle->state = kFLEXIO_I2C_SendData;
218
219 /* Send first byte of data. */
220 if (handle->transfer.dataSize > 0)
221 {
222 FLEXIO_I2C_MasterWriteByte(base, *handle->transfer.data);
223
224 handle->transfer.data++;
225 handle->transfer.dataSize--;
226 }
227 }
228 else
229 {
230 FLEXIO_I2C_MasterSetTransferCount(base, (handle->transfer.dataSize + 1));
231 FLEXIO_I2C_MasterStart(base, handle->transfer.slaveAddress, kFLEXIO_I2C_Read);
232
233 /* Next state, receive data begin. */
234 handle->state = kFLEXIO_I2C_ReceiveDataBegin;
235 }
236 }
237 }
238 break;
239
240 /* Send command byte. */
241 case kFLEXIO_I2C_SendData:
242 if (statusFlags & kFLEXIO_I2C_TxEmptyFlag)
243 {
244 /* Send one byte of data. */
245 if (handle->transfer.dataSize > 0)
246 {
247 FLEXIO_I2C_MasterWriteByte(base, *handle->transfer.data);
248
249 handle->transfer.data++;
250 handle->transfer.dataSize--;
251 }
252 else
253 {
254 FLEXIO_I2C_MasterStop(base);
255
256 while (!(FLEXIO_I2C_MasterGetStatusFlags(base) & kFLEXIO_I2C_RxFullFlag))
257 {
258 }
259 FLEXIO_I2C_MasterReadByte(base);
260
261 handle->state = kFLEXIO_I2C_Idle;
262 }
263 }
264 break;
265
266 case kFLEXIO_I2C_ReceiveDataBegin:
267 if (statusFlags & kFLEXIO_I2C_RxFullFlag)
268 {
269 handle->state = kFLEXIO_I2C_ReceiveData;
270 /* Send nak at the last receive byte. */
271 if (handle->transfer.dataSize == 1)
272 {
273 FLEXIO_I2C_MasterEnableAck(base, false);
274 while (!((FLEXIO_GetShifterStatusFlags(base->flexioBase) & (1U << base->shifterIndex[0]))))
275 {
276 }
277 FLEXIO_I2C_MasterStop(base);
278 }
279 else
280 {
281 FLEXIO_I2C_MasterEnableAck(base, true);
282 }
283 }
284 else if (statusFlags & kFLEXIO_I2C_TxEmptyFlag)
285 {
286 /* Read one byte of data. */
287 FLEXIO_I2C_MasterWriteByte(base, 0xFFFFFFFFU);
288 }
289 else
290 {
291 }
292 break;
293
294 case kFLEXIO_I2C_ReceiveData:
295 if (statusFlags & kFLEXIO_I2C_RxFullFlag)
296 {
297 *handle->transfer.data = FLEXIO_I2C_MasterReadByte(base);
298 handle->transfer.data++;
299 if (handle->transfer.dataSize--)
300 {
301 if (handle->transfer.dataSize == 0)
302 {
303 FLEXIO_I2C_MasterDisableInterrupts(base, kFLEXIO_I2C_RxFullInterruptEnable);
304 handle->state = kFLEXIO_I2C_Idle;
305 }
306
307 /* Send nak at the last receive byte. */
308 if (handle->transfer.dataSize == 1)
309 {
310 FLEXIO_I2C_MasterEnableAck(base, false);
311 while (!((FLEXIO_GetShifterStatusFlags(base->flexioBase) & (1U << base->shifterIndex[0]))))
312 {
313 }
314 FLEXIO_I2C_MasterStop(base);
315 }
316 }
317 }
318 else if (statusFlags & kFLEXIO_I2C_TxEmptyFlag)
319 {
320 if (handle->transfer.dataSize > 1)
321 {
322 FLEXIO_I2C_MasterWriteByte(base, 0xFFFFFFFFU);
323 }
324 }
325 else
326 {
327 }
328 break;
329
330 default:
331 break;
332 }
333
334 return kStatus_Success;
335 }
336
FLEXIO_I2C_MasterTransferComplete(FLEXIO_I2C_Type * base,flexio_i2c_master_handle_t * handle,status_t status)337 static void FLEXIO_I2C_MasterTransferComplete(FLEXIO_I2C_Type *base,
338 flexio_i2c_master_handle_t *handle,
339 status_t status)
340 {
341 FLEXIO_I2C_MasterDisableInterrupts(base, kFLEXIO_I2C_TxEmptyInterruptEnable | kFLEXIO_I2C_RxFullInterruptEnable);
342
343 if (handle->completionCallback)
344 {
345 handle->completionCallback(base, handle, status, handle->userData);
346 }
347 }
348
FLEXIO_I2C_MasterInit(FLEXIO_I2C_Type * base,flexio_i2c_master_config_t * masterConfig,uint32_t srcClock_Hz)349 status_t FLEXIO_I2C_MasterInit(FLEXIO_I2C_Type *base, flexio_i2c_master_config_t *masterConfig, uint32_t srcClock_Hz)
350 {
351 assert(base && masterConfig);
352
353 flexio_shifter_config_t shifterConfig;
354 flexio_timer_config_t timerConfig;
355 uint32_t controlVal = 0;
356 uint16_t timerDiv = 0;
357 status_t result = kStatus_Success;
358
359 memset(&shifterConfig, 0, sizeof(shifterConfig));
360 memset(&timerConfig, 0, sizeof(timerConfig));
361
362 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
363 /* Ungate flexio clock. */
364 CLOCK_EnableClock(s_flexioClocks[FLEXIO_I2C_GetInstance(base)]);
365 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
366
367 FLEXIO_Reset(base->flexioBase);
368
369 /* Do hardware configuration. */
370 /* 1. Configure the shifter 0 for tx. */
371 shifterConfig.timerSelect = base->timerIndex[1];
372 shifterConfig.timerPolarity = kFLEXIO_ShifterTimerPolarityOnPositive;
373 shifterConfig.pinConfig = kFLEXIO_PinConfigOpenDrainOrBidirection;
374 shifterConfig.pinSelect = base->SDAPinIndex;
375 shifterConfig.pinPolarity = kFLEXIO_PinActiveLow;
376 shifterConfig.shifterMode = kFLEXIO_ShifterModeTransmit;
377 shifterConfig.inputSource = kFLEXIO_ShifterInputFromPin;
378 shifterConfig.shifterStop = kFLEXIO_ShifterStopBitHigh;
379 shifterConfig.shifterStart = kFLEXIO_ShifterStartBitLow;
380
381 FLEXIO_SetShifterConfig(base->flexioBase, base->shifterIndex[0], &shifterConfig);
382
383 /* 2. Configure the shifter 1 for rx. */
384 shifterConfig.timerSelect = base->timerIndex[1];
385 shifterConfig.timerPolarity = kFLEXIO_ShifterTimerPolarityOnNegitive;
386 shifterConfig.pinConfig = kFLEXIO_PinConfigOutputDisabled;
387 shifterConfig.pinSelect = base->SDAPinIndex;
388 shifterConfig.pinPolarity = kFLEXIO_PinActiveHigh;
389 shifterConfig.shifterMode = kFLEXIO_ShifterModeReceive;
390 shifterConfig.inputSource = kFLEXIO_ShifterInputFromPin;
391 shifterConfig.shifterStop = kFLEXIO_ShifterStopBitLow;
392 shifterConfig.shifterStart = kFLEXIO_ShifterStartBitDisabledLoadDataOnEnable;
393
394 FLEXIO_SetShifterConfig(base->flexioBase, base->shifterIndex[1], &shifterConfig);
395
396 /*3. Configure the timer 0 for generating bit clock. */
397 timerConfig.triggerSelect = FLEXIO_TIMER_TRIGGER_SEL_SHIFTnSTAT(base->shifterIndex[0]);
398 timerConfig.triggerPolarity = kFLEXIO_TimerTriggerPolarityActiveLow;
399 timerConfig.triggerSource = kFLEXIO_TimerTriggerSourceInternal;
400 timerConfig.pinConfig = kFLEXIO_PinConfigOpenDrainOrBidirection;
401 timerConfig.pinSelect = base->SCLPinIndex;
402 timerConfig.pinPolarity = kFLEXIO_PinActiveHigh;
403 timerConfig.timerMode = kFLEXIO_TimerModeDual8BitBaudBit;
404 timerConfig.timerOutput = kFLEXIO_TimerOutputZeroNotAffectedByReset;
405 timerConfig.timerDecrement = kFLEXIO_TimerDecSrcOnFlexIOClockShiftTimerOutput;
406 timerConfig.timerReset = kFLEXIO_TimerResetOnTimerPinEqualToTimerOutput;
407 timerConfig.timerDisable = kFLEXIO_TimerDisableOnTimerCompare;
408 timerConfig.timerEnable = kFLEXIO_TimerEnableOnTriggerHigh;
409 timerConfig.timerStop = kFLEXIO_TimerStopBitEnableOnTimerDisable;
410 timerConfig.timerStart = kFLEXIO_TimerStartBitEnabled;
411
412 /* Set TIMCMP[7:0] = (baud rate divider / 2) - 1. */
413 timerDiv = (srcClock_Hz / masterConfig->baudRate_Bps) / 2 - 1;
414
415 if (timerDiv > 0xFFU)
416 {
417 result = kStatus_InvalidArgument;
418 return result;
419 }
420
421 timerConfig.timerCompare = timerDiv;
422
423 FLEXIO_SetTimerConfig(base->flexioBase, base->timerIndex[0], &timerConfig);
424
425 /* 4. Configure the timer 1 for controlling shifters. */
426 timerConfig.triggerSelect = FLEXIO_TIMER_TRIGGER_SEL_SHIFTnSTAT(base->shifterIndex[0]);
427 timerConfig.triggerPolarity = kFLEXIO_TimerTriggerPolarityActiveLow;
428 timerConfig.triggerSource = kFLEXIO_TimerTriggerSourceInternal;
429 timerConfig.pinConfig = kFLEXIO_PinConfigOutputDisabled;
430 timerConfig.pinSelect = base->SCLPinIndex;
431 timerConfig.pinPolarity = kFLEXIO_PinActiveLow;
432 timerConfig.timerMode = kFLEXIO_TimerModeSingle16Bit;
433 timerConfig.timerOutput = kFLEXIO_TimerOutputOneNotAffectedByReset;
434 timerConfig.timerDecrement = kFLEXIO_TimerDecSrcOnPinInputShiftPinInput;
435 timerConfig.timerReset = kFLEXIO_TimerResetNever;
436 timerConfig.timerDisable = kFLEXIO_TimerDisableOnPreTimerDisable;
437 timerConfig.timerEnable = kFLEXIO_TimerEnableOnPrevTimerEnable;
438 timerConfig.timerStop = kFLEXIO_TimerStopBitEnableOnTimerCompare;
439 timerConfig.timerStart = kFLEXIO_TimerStartBitEnabled;
440
441 /* Set TIMCMP[15:0] = (number of bits x 2) - 1. */
442 timerConfig.timerCompare = 8 * 2 - 1;
443
444 FLEXIO_SetTimerConfig(base->flexioBase, base->timerIndex[1], &timerConfig);
445
446 /* Configure FLEXIO I2C Master. */
447 controlVal = base->flexioBase->CTRL;
448 controlVal &=
449 ~(FLEXIO_CTRL_DOZEN_MASK | FLEXIO_CTRL_DBGE_MASK | FLEXIO_CTRL_FASTACC_MASK | FLEXIO_CTRL_FLEXEN_MASK);
450 controlVal |= (FLEXIO_CTRL_DBGE(masterConfig->enableInDebug) | FLEXIO_CTRL_FASTACC(masterConfig->enableFastAccess) |
451 FLEXIO_CTRL_FLEXEN(masterConfig->enableMaster));
452 if (!masterConfig->enableInDoze)
453 {
454 controlVal |= FLEXIO_CTRL_DOZEN_MASK;
455 }
456
457 base->flexioBase->CTRL = controlVal;
458 return result;
459 }
460
FLEXIO_I2C_MasterDeinit(FLEXIO_I2C_Type * base)461 void FLEXIO_I2C_MasterDeinit(FLEXIO_I2C_Type *base)
462 {
463 FLEXIO_Deinit(base->flexioBase);
464 }
465
FLEXIO_I2C_MasterGetDefaultConfig(flexio_i2c_master_config_t * masterConfig)466 void FLEXIO_I2C_MasterGetDefaultConfig(flexio_i2c_master_config_t *masterConfig)
467 {
468 assert(masterConfig);
469
470 masterConfig->enableMaster = true;
471 masterConfig->enableInDoze = false;
472 masterConfig->enableInDebug = true;
473 masterConfig->enableFastAccess = false;
474
475 /* Default baud rate at 100kbps. */
476 masterConfig->baudRate_Bps = 100000U;
477 }
478
FLEXIO_I2C_MasterGetStatusFlags(FLEXIO_I2C_Type * base)479 uint32_t FLEXIO_I2C_MasterGetStatusFlags(FLEXIO_I2C_Type *base)
480 {
481 uint32_t status = 0;
482
483 status =
484 ((FLEXIO_GetShifterStatusFlags(base->flexioBase) & (1U << base->shifterIndex[0])) >> base->shifterIndex[0]);
485 status |=
486 (((FLEXIO_GetShifterStatusFlags(base->flexioBase) & (1U << base->shifterIndex[1])) >> (base->shifterIndex[1]))
487 << 1U);
488 status |=
489 (((FLEXIO_GetShifterErrorFlags(base->flexioBase) & (1U << base->shifterIndex[1])) >> (base->shifterIndex[1]))
490 << 2U);
491
492 return status;
493 }
494
FLEXIO_I2C_MasterClearStatusFlags(FLEXIO_I2C_Type * base,uint32_t mask)495 void FLEXIO_I2C_MasterClearStatusFlags(FLEXIO_I2C_Type *base, uint32_t mask)
496 {
497 if (mask & kFLEXIO_I2C_TxEmptyFlag)
498 {
499 FLEXIO_ClearShifterStatusFlags(base->flexioBase, 1U << base->shifterIndex[0]);
500 }
501
502 if (mask & kFLEXIO_I2C_RxFullFlag)
503 {
504 FLEXIO_ClearShifterStatusFlags(base->flexioBase, 1U << base->shifterIndex[1]);
505 }
506
507 if (mask & kFLEXIO_I2C_ReceiveNakFlag)
508 {
509 FLEXIO_ClearShifterErrorFlags(base->flexioBase, 1U << base->shifterIndex[1]);
510 }
511 }
512
FLEXIO_I2C_MasterEnableInterrupts(FLEXIO_I2C_Type * base,uint32_t mask)513 void FLEXIO_I2C_MasterEnableInterrupts(FLEXIO_I2C_Type *base, uint32_t mask)
514 {
515 if (mask & kFLEXIO_I2C_TxEmptyInterruptEnable)
516 {
517 FLEXIO_EnableShifterStatusInterrupts(base->flexioBase, 1U << base->shifterIndex[0]);
518 }
519 if (mask & kFLEXIO_I2C_RxFullInterruptEnable)
520 {
521 FLEXIO_EnableShifterStatusInterrupts(base->flexioBase, 1U << base->shifterIndex[1]);
522 }
523 }
524
FLEXIO_I2C_MasterDisableInterrupts(FLEXIO_I2C_Type * base,uint32_t mask)525 void FLEXIO_I2C_MasterDisableInterrupts(FLEXIO_I2C_Type *base, uint32_t mask)
526 {
527 if (mask & kFLEXIO_I2C_TxEmptyInterruptEnable)
528 {
529 FLEXIO_DisableShifterStatusInterrupts(base->flexioBase, 1U << base->shifterIndex[0]);
530 }
531 if (mask & kFLEXIO_I2C_RxFullInterruptEnable)
532 {
533 FLEXIO_DisableShifterStatusInterrupts(base->flexioBase, 1U << base->shifterIndex[1]);
534 }
535 }
536
FLEXIO_I2C_MasterSetBaudRate(FLEXIO_I2C_Type * base,uint32_t baudRate_Bps,uint32_t srcClock_Hz)537 void FLEXIO_I2C_MasterSetBaudRate(FLEXIO_I2C_Type *base, uint32_t baudRate_Bps, uint32_t srcClock_Hz)
538 {
539 uint16_t timerDiv = 0;
540 uint16_t timerCmp = 0;
541 FLEXIO_Type *flexioBase = base->flexioBase;
542
543 /* Set TIMCMP[7:0] = (baud rate divider / 2) - 1.*/
544 timerDiv = srcClock_Hz / baudRate_Bps;
545 timerDiv = timerDiv / 2 - 1U;
546
547 timerCmp = flexioBase->TIMCMP[base->timerIndex[0]];
548 timerCmp &= 0xFF00;
549 timerCmp |= timerDiv;
550
551 flexioBase->TIMCMP[base->timerIndex[0]] = timerCmp;
552 }
553
FLEXIO_I2C_MasterSetTransferCount(FLEXIO_I2C_Type * base,uint8_t count)554 status_t FLEXIO_I2C_MasterSetTransferCount(FLEXIO_I2C_Type *base, uint8_t count)
555 {
556 if (count > 14U)
557 {
558 return kStatus_InvalidArgument;
559 }
560
561 uint16_t timerCmp = 0;
562 uint32_t timerConfig = 0;
563 FLEXIO_Type *flexioBase = base->flexioBase;
564
565 timerCmp = flexioBase->TIMCMP[base->timerIndex[0]];
566 timerCmp &= 0x00FFU;
567 timerCmp |= (count * 18 + 1U) << 8U;
568 flexioBase->TIMCMP[base->timerIndex[0]] = timerCmp;
569 timerConfig = flexioBase->TIMCFG[base->timerIndex[0]];
570 timerConfig &= ~FLEXIO_TIMCFG_TIMDIS_MASK;
571 timerConfig |= FLEXIO_TIMCFG_TIMDIS(kFLEXIO_TimerDisableOnTimerCompare);
572 flexioBase->TIMCFG[base->timerIndex[0]] = timerConfig;
573
574 return kStatus_Success;
575 }
576
FLEXIO_I2C_MasterStart(FLEXIO_I2C_Type * base,uint8_t address,flexio_i2c_direction_t direction)577 void FLEXIO_I2C_MasterStart(FLEXIO_I2C_Type *base, uint8_t address, flexio_i2c_direction_t direction)
578 {
579 uint32_t data;
580
581 data = ((uint32_t)address) << 1U | ((direction == kFLEXIO_I2C_Read) ? 1U : 0U);
582
583 FLEXIO_I2C_MasterWriteByte(base, data);
584 }
585
FLEXIO_I2C_MasterRepeatedStart(FLEXIO_I2C_Type * base)586 void FLEXIO_I2C_MasterRepeatedStart(FLEXIO_I2C_Type *base)
587 {
588 /* Prepare for RESTART condition, no stop.*/
589 FLEXIO_I2C_MasterWriteByte(base, 0xFFFFFFFFU);
590 }
591
FLEXIO_I2C_MasterStop(FLEXIO_I2C_Type * base)592 void FLEXIO_I2C_MasterStop(FLEXIO_I2C_Type *base)
593 {
594 /* Prepare normal stop. */
595 FLEXIO_I2C_MasterSetTransferCount(base, 0x0U);
596 FLEXIO_I2C_MasterWriteByte(base, 0x0U);
597 }
598
FLEXIO_I2C_MasterAbortStop(FLEXIO_I2C_Type * base)599 void FLEXIO_I2C_MasterAbortStop(FLEXIO_I2C_Type *base)
600 {
601 uint32_t tmpConfig;
602
603 /* Prepare abort stop. */
604 tmpConfig = base->flexioBase->TIMCFG[base->timerIndex[0]];
605 tmpConfig &= ~FLEXIO_TIMCFG_TIMDIS_MASK;
606 tmpConfig |= FLEXIO_TIMCFG_TIMDIS(kFLEXIO_TimerDisableOnPinBothEdge);
607 base->flexioBase->TIMCFG[base->timerIndex[0]] = tmpConfig;
608 }
609
FLEXIO_I2C_MasterEnableAck(FLEXIO_I2C_Type * base,bool enable)610 void FLEXIO_I2C_MasterEnableAck(FLEXIO_I2C_Type *base, bool enable)
611 {
612 uint32_t tmpConfig = 0;
613
614 tmpConfig = base->flexioBase->SHIFTCFG[base->shifterIndex[0]];
615 tmpConfig &= ~FLEXIO_SHIFTCFG_SSTOP_MASK;
616 if (enable)
617 {
618 tmpConfig |= FLEXIO_SHIFTCFG_SSTOP(kFLEXIO_ShifterStopBitLow);
619 }
620 else
621 {
622 tmpConfig |= FLEXIO_SHIFTCFG_SSTOP(kFLEXIO_ShifterStopBitHigh);
623 }
624 base->flexioBase->SHIFTCFG[base->shifterIndex[0]] = tmpConfig;
625 }
626
FLEXIO_I2C_MasterWriteBlocking(FLEXIO_I2C_Type * base,const uint8_t * txBuff,uint8_t txSize)627 status_t FLEXIO_I2C_MasterWriteBlocking(FLEXIO_I2C_Type *base, const uint8_t *txBuff, uint8_t txSize)
628 {
629 assert(txBuff);
630 assert(txSize);
631
632 uint32_t status;
633
634 while (txSize--)
635 {
636 FLEXIO_I2C_MasterWriteByte(base, *txBuff++);
637
638 /* Wait until data transfer complete. */
639 while (!((status = FLEXIO_I2C_MasterGetStatusFlags(base)) & kFLEXIO_I2C_RxFullFlag))
640 {
641 }
642
643 if (status & kFLEXIO_I2C_ReceiveNakFlag)
644 {
645 FLEXIO_ClearShifterErrorFlags(base->flexioBase, 1U << base->shifterIndex[1]);
646 return kStatus_FLEXIO_I2C_Nak;
647 }
648 }
649 return kStatus_Success;
650 }
651
FLEXIO_I2C_MasterReadBlocking(FLEXIO_I2C_Type * base,uint8_t * rxBuff,uint8_t rxSize)652 void FLEXIO_I2C_MasterReadBlocking(FLEXIO_I2C_Type *base, uint8_t *rxBuff, uint8_t rxSize)
653 {
654 assert(rxBuff);
655 assert(rxSize);
656
657 while (rxSize--)
658 {
659 /* Wait until data transfer complete. */
660 while (!(FLEXIO_I2C_MasterGetStatusFlags(base) & kFLEXIO_I2C_RxFullFlag))
661 {
662 }
663
664 *rxBuff++ = FLEXIO_I2C_MasterReadByte(base);
665 }
666 }
667
FLEXIO_I2C_MasterTransferBlocking(FLEXIO_I2C_Type * base,flexio_i2c_master_transfer_t * xfer)668 status_t FLEXIO_I2C_MasterTransferBlocking(FLEXIO_I2C_Type *base, flexio_i2c_master_transfer_t *xfer)
669 {
670 assert(xfer);
671
672 flexio_i2c_master_handle_t tmpHandle;
673 uint32_t statusFlags;
674 uint32_t result = kStatus_Success;
675
676 /* Zero the handle. */
677 memset(&tmpHandle, 0, sizeof(tmpHandle));
678
679 /* Set up transfer machine. */
680 FLEXIO_I2C_MasterTransferInitStateMachine(base, &tmpHandle, xfer);
681
682 do
683 {
684 /* Wait either tx empty or rx full flag is asserted. */
685 while (!((statusFlags = FLEXIO_I2C_MasterGetStatusFlags(base)) &
686 (kFLEXIO_I2C_TxEmptyFlag | kFLEXIO_I2C_RxFullFlag)))
687 {
688 }
689
690 result = FLEXIO_I2C_MasterTransferRunStateMachine(base, &tmpHandle, statusFlags);
691
692 } while ((tmpHandle.state != kFLEXIO_I2C_Idle) && (result == kStatus_Success));
693
694 return result;
695 }
696
FLEXIO_I2C_MasterTransferCreateHandle(FLEXIO_I2C_Type * base,flexio_i2c_master_handle_t * handle,flexio_i2c_master_transfer_callback_t callback,void * userData)697 status_t FLEXIO_I2C_MasterTransferCreateHandle(FLEXIO_I2C_Type *base,
698 flexio_i2c_master_handle_t *handle,
699 flexio_i2c_master_transfer_callback_t callback,
700 void *userData)
701 {
702 assert(handle);
703
704 IRQn_Type flexio_irqs[] = FLEXIO_IRQS;
705
706 /* Zero the handle. */
707 memset(handle, 0, sizeof(*handle));
708
709 /* Register callback and userData. */
710 handle->completionCallback = callback;
711 handle->userData = userData;
712
713 /* Enable interrupt in NVIC. */
714 EnableIRQ(flexio_irqs[FLEXIO_I2C_GetInstance(base)]);
715
716 /* Save the context in global variables to support the double weak mechanism. */
717 return FLEXIO_RegisterHandleIRQ(base, handle, FLEXIO_I2C_MasterTransferHandleIRQ);
718 }
719
FLEXIO_I2C_MasterTransferNonBlocking(FLEXIO_I2C_Type * base,flexio_i2c_master_handle_t * handle,flexio_i2c_master_transfer_t * xfer)720 status_t FLEXIO_I2C_MasterTransferNonBlocking(FLEXIO_I2C_Type *base,
721 flexio_i2c_master_handle_t *handle,
722 flexio_i2c_master_transfer_t *xfer)
723 {
724 assert(handle);
725 assert(xfer);
726
727 if (handle->state != kFLEXIO_I2C_Idle)
728 {
729 return kStatus_FLEXIO_I2C_Busy;
730 }
731 else
732 {
733 /* Set up transfer machine. */
734 FLEXIO_I2C_MasterTransferInitStateMachine(base, handle, xfer);
735
736 /* Enable both tx empty and rxfull interrupt. */
737 FLEXIO_I2C_MasterEnableInterrupts(base, kFLEXIO_I2C_TxEmptyInterruptEnable | kFLEXIO_I2C_RxFullInterruptEnable);
738
739 return kStatus_Success;
740 }
741 }
742
FLEXIO_I2C_MasterTransferAbort(FLEXIO_I2C_Type * base,flexio_i2c_master_handle_t * handle)743 void FLEXIO_I2C_MasterTransferAbort(FLEXIO_I2C_Type *base, flexio_i2c_master_handle_t *handle)
744 {
745 assert(handle);
746
747 /* Disable interrupts. */
748 FLEXIO_I2C_MasterDisableInterrupts(base, kFLEXIO_I2C_TxEmptyInterruptEnable | kFLEXIO_I2C_RxFullInterruptEnable);
749
750 /* Reset to idle state. */
751 handle->state = kFLEXIO_I2C_Idle;
752 }
753
FLEXIO_I2C_MasterTransferGetCount(FLEXIO_I2C_Type * base,flexio_i2c_master_handle_t * handle,size_t * count)754 status_t FLEXIO_I2C_MasterTransferGetCount(FLEXIO_I2C_Type *base, flexio_i2c_master_handle_t *handle, size_t *count)
755 {
756 if (!count)
757 {
758 return kStatus_InvalidArgument;
759 }
760
761 *count = handle->transferSize - handle->transfer.dataSize;
762
763 return kStatus_Success;
764 }
765
FLEXIO_I2C_MasterTransferHandleIRQ(void * i2cType,void * i2cHandle)766 void FLEXIO_I2C_MasterTransferHandleIRQ(void *i2cType, void *i2cHandle)
767 {
768 FLEXIO_I2C_Type *base = (FLEXIO_I2C_Type *)i2cType;
769 flexio_i2c_master_handle_t *handle = (flexio_i2c_master_handle_t *)i2cHandle;
770 uint32_t statusFlags;
771 status_t result;
772
773 statusFlags = FLEXIO_I2C_MasterGetStatusFlags(base);
774
775 result = FLEXIO_I2C_MasterTransferRunStateMachine(base, handle, statusFlags);
776
777 if (handle->state == kFLEXIO_I2C_Idle)
778 {
779 FLEXIO_I2C_MasterTransferComplete(base, handle, result);
780 }
781 }
782