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