1 /*
2  * Copyright (c) 2015, Freescale Semiconductor, Inc.
3  * Copyright 2016-2017 NXP
4  *
5  * Redistribution and use in source and binary forms, with or without modification,
6  * are permitted provided that the following conditions are met:
7  *
8  * o Redistributions of source code must retain the above copyright notice, this list
9  *   of conditions and the following disclaimer.
10  *
11  * o Redistributions in binary form must reproduce the above copyright notice, this
12  *   list of conditions and the following disclaimer in the documentation and/or
13  *   other materials provided with the distribution.
14  *
15  * o Neither the name of the copyright holder nor the names of its
16  *   contributors may be used to endorse or promote products derived from this
17  *   software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
23  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
26  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30 #include "fsl_i2c.h"
31 
32 /*******************************************************************************
33  * Definitions
34  ******************************************************************************/
35 
36 /*! @brief i2c transfer state. */
37 enum _i2c_transfer_states
38 {
39     kIdleState = 0x0U,             /*!< I2C bus idle. */
40     kCheckAddressState = 0x1U,     /*!< 7-bit address check state. */
41     kSendCommandState = 0x2U,      /*!< Send command byte phase. */
42     kSendDataState = 0x3U,         /*!< Send data transfer phase. */
43     kReceiveDataBeginState = 0x4U, /*!< Receive data transfer phase begin. */
44     kReceiveDataState = 0x5U,      /*!< Receive data transfer phase. */
45 };
46 
47 /*! @brief Common sets of flags used by the driver. */
48 enum _i2c_flag_constants
49 {
50 /*! All flags which are cleared by the driver upon starting a transfer. */
51 #if defined(FSL_FEATURE_I2C_HAS_START_STOP_DETECT) && FSL_FEATURE_I2C_HAS_START_STOP_DETECT
52     kClearFlags = kI2C_ArbitrationLostFlag | kI2C_IntPendingFlag | kI2C_StartDetectFlag | kI2C_StopDetectFlag,
53     kIrqFlags = kI2C_GlobalInterruptEnable | kI2C_StartStopDetectInterruptEnable,
54 #elif defined(FSL_FEATURE_I2C_HAS_STOP_DETECT) && FSL_FEATURE_I2C_HAS_STOP_DETECT
55     kClearFlags = kI2C_ArbitrationLostFlag | kI2C_IntPendingFlag | kI2C_StopDetectFlag,
56     kIrqFlags = kI2C_GlobalInterruptEnable | kI2C_StopDetectInterruptEnable,
57 #else
58     kClearFlags = kI2C_ArbitrationLostFlag | kI2C_IntPendingFlag,
59     kIrqFlags = kI2C_GlobalInterruptEnable,
60 #endif
61 
62 };
63 
64 /*! @brief Typedef for interrupt handler. */
65 typedef void (*i2c_isr_t)(I2C_Type *base, void *i2cHandle);
66 
67 /*******************************************************************************
68  * Prototypes
69  ******************************************************************************/
70 
71 /*!
72  * @brief Get instance number for I2C module.
73  *
74  * @param base I2C peripheral base address.
75  */
76 uint32_t I2C_GetInstance(I2C_Type *base);
77 
78 /*!
79 * @brief Set SCL/SDA hold time, this API receives SCL stop hold time, calculate the
80 * closest SCL divider and MULT value for the SDA hold time, SCL start and SCL stop
81 * hold time. To reduce the ROM size, SDA/SCL hold value mapping table is not provided,
82 * assume SCL divider = SCL stop hold value *2 to get the closest SCL divider value and MULT
83 * value, then the related SDA hold time, SCL start and SCL stop hold time is used.
84 *
85 * @param base I2C peripheral base address.
86 * @param sourceClock_Hz I2C functional clock frequency in Hertz.
87 * @param sclStopHoldTime_ns SCL stop hold time in ns.
88 */
89 static void I2C_SetHoldTime(I2C_Type *base, uint32_t sclStopHoldTime_ns, uint32_t sourceClock_Hz);
90 
91 /*!
92  * @brief Set up master transfer, send slave address and decide the initial
93  * transfer state.
94  *
95  * @param base I2C peripheral base address.
96  * @param handle pointer to i2c_master_handle_t structure which stores the transfer state.
97  * @param xfer pointer to i2c_master_transfer_t structure.
98  */
99 static status_t I2C_InitTransferStateMachine(I2C_Type *base, i2c_master_handle_t *handle, i2c_master_transfer_t *xfer);
100 
101 /*!
102  * @brief Check and clear status operation.
103  *
104  * @param base I2C peripheral base address.
105  * @param status current i2c hardware status.
106  * @retval kStatus_Success No error found.
107  * @retval kStatus_I2C_ArbitrationLost Transfer error, arbitration lost.
108  * @retval kStatus_I2C_Nak Received Nak error.
109  */
110 static status_t I2C_CheckAndClearError(I2C_Type *base, uint32_t status);
111 
112 /*!
113  * @brief Master run transfer state machine to perform a byte of transfer.
114  *
115  * @param base I2C peripheral base address.
116  * @param handle pointer to i2c_master_handle_t structure which stores the transfer state
117  * @param isDone input param to get whether the thing is done, true is done
118  * @retval kStatus_Success No error found.
119  * @retval kStatus_I2C_ArbitrationLost Transfer error, arbitration lost.
120  * @retval kStatus_I2C_Nak Received Nak error.
121  * @retval kStatus_I2C_Timeout Transfer error, wait signal timeout.
122  */
123 static status_t I2C_MasterTransferRunStateMachine(I2C_Type *base, i2c_master_handle_t *handle, bool *isDone);
124 
125 /*!
126  * @brief I2C common interrupt handler.
127  *
128  * @param base I2C peripheral base address.
129  * @param handle pointer to i2c_master_handle_t structure which stores the transfer state
130  */
131 static void I2C_TransferCommonIRQHandler(I2C_Type *base, void *handle);
132 
133 /*******************************************************************************
134  * Variables
135  ******************************************************************************/
136 
137 /*! @brief Pointers to i2c handles for each instance. */
138 static void *s_i2cHandle[FSL_FEATURE_SOC_I2C_COUNT] = {NULL};
139 
140 /*! @brief SCL clock divider used to calculate baudrate. */
141 static const uint16_t s_i2cDividerTable[] = {
142     20,  22,  24,  26,   28,   30,   34,   40,   28,   32,   36,   40,   44,   48,   56,   68,
143     48,  56,  64,  72,   80,   88,   104,  128,  80,   96,   112,  128,  144,  160,  192,  240,
144     160, 192, 224, 256,  288,  320,  384,  480,  320,  384,  448,  512,  576,  640,  768,  960,
145     640, 768, 896, 1024, 1152, 1280, 1536, 1920, 1280, 1536, 1792, 2048, 2304, 2560, 3072, 3840};
146 
147 /*! @brief Pointers to i2c bases for each instance. */
148 static I2C_Type *const s_i2cBases[] = I2C_BASE_PTRS;
149 
150 /*! @brief Pointers to i2c IRQ number for each instance. */
151 static const IRQn_Type s_i2cIrqs[] = I2C_IRQS;
152 
153 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
154 /*! @brief Pointers to i2c clocks for each instance. */
155 static const clock_ip_name_t s_i2cClocks[] = I2C_CLOCKS;
156 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
157 
158 /*! @brief Pointer to master IRQ handler for each instance. */
159 static i2c_isr_t s_i2cMasterIsr;
160 
161 /*! @brief Pointer to slave IRQ handler for each instance. */
162 static i2c_isr_t s_i2cSlaveIsr;
163 
164 /*******************************************************************************
165  * Codes
166  ******************************************************************************/
167 
I2C_GetInstance(I2C_Type * base)168 uint32_t I2C_GetInstance(I2C_Type *base)
169 {
170     uint32_t instance;
171 
172     /* Find the instance index from base address mappings. */
173     for (instance = 0; instance < ARRAY_SIZE(s_i2cBases); instance++)
174     {
175         if (s_i2cBases[instance] == base)
176         {
177             break;
178         }
179     }
180 
181     assert(instance < ARRAY_SIZE(s_i2cBases));
182 
183     return instance;
184 }
185 
I2C_SetHoldTime(I2C_Type * base,uint32_t sclStopHoldTime_ns,uint32_t sourceClock_Hz)186 static void I2C_SetHoldTime(I2C_Type *base, uint32_t sclStopHoldTime_ns, uint32_t sourceClock_Hz)
187 {
188     uint32_t multiplier;
189     uint32_t computedSclHoldTime;
190     uint32_t absError;
191     uint32_t bestError = UINT32_MAX;
192     uint32_t bestMult = 0u;
193     uint32_t bestIcr = 0u;
194     uint8_t mult;
195     uint8_t i;
196 
197     /* Search for the settings with the lowest error. Mult is the MULT field of the I2C_F register,
198      * and ranges from 0-2. It selects the multiplier factor for the divider. */
199     /* SDA hold time = bus period (s) * mul * SDA hold value. */
200     /* SCL start hold time = bus period (s) * mul * SCL start hold value. */
201     /* SCL stop hold time = bus period (s) * mul * SCL stop hold value. */
202 
203     for (mult = 0u; (mult <= 2u) && (bestError != 0); ++mult)
204     {
205         multiplier = 1u << mult;
206 
207         /* Scan table to find best match. */
208         for (i = 0u; i < sizeof(s_i2cDividerTable) / sizeof(s_i2cDividerTable[0]); ++i)
209         {
210             /* Assume SCL hold(stop) value = s_i2cDividerTable[i]/2. */
211             computedSclHoldTime = ((multiplier * s_i2cDividerTable[i]) * 500000000U) / sourceClock_Hz;
212             absError = sclStopHoldTime_ns > computedSclHoldTime ? (sclStopHoldTime_ns - computedSclHoldTime) :
213                                                                   (computedSclHoldTime - sclStopHoldTime_ns);
214 
215             if (absError < bestError)
216             {
217                 bestMult = mult;
218                 bestIcr = i;
219                 bestError = absError;
220 
221                 /* If the error is 0, then we can stop searching because we won't find a better match. */
222                 if (absError == 0)
223                 {
224                     break;
225                 }
226             }
227         }
228     }
229 
230     /* Set frequency register based on best settings. */
231     base->F = I2C_F_MULT(bestMult) | I2C_F_ICR(bestIcr);
232 }
233 
I2C_InitTransferStateMachine(I2C_Type * base,i2c_master_handle_t * handle,i2c_master_transfer_t * xfer)234 static status_t I2C_InitTransferStateMachine(I2C_Type *base, i2c_master_handle_t *handle, i2c_master_transfer_t *xfer)
235 {
236     status_t result = kStatus_Success;
237     i2c_direction_t direction = xfer->direction;
238 
239     /* Initialize the handle transfer information. */
240     handle->transfer = *xfer;
241 
242     /* Save total transfer size. */
243     handle->transferSize = xfer->dataSize;
244 
245     /* Initial transfer state. */
246     if (handle->transfer.subaddressSize > 0)
247     {
248         if (xfer->direction == kI2C_Read)
249         {
250             direction = kI2C_Write;
251         }
252     }
253 
254     handle->state = kCheckAddressState;
255 
256     /* Clear all status before transfer. */
257     I2C_MasterClearStatusFlags(base, kClearFlags);
258 
259     /* If repeated start is requested, send repeated start. */
260     if (handle->transfer.flags & kI2C_TransferRepeatedStartFlag)
261     {
262         result = I2C_MasterRepeatedStart(base, handle->transfer.slaveAddress, direction);
263     }
264     else /* For normal transfer, send start. */
265     {
266         result = I2C_MasterStart(base, handle->transfer.slaveAddress, direction);
267     }
268 
269     return result;
270 }
271 
I2C_CheckAndClearError(I2C_Type * base,uint32_t status)272 static status_t I2C_CheckAndClearError(I2C_Type *base, uint32_t status)
273 {
274     status_t result = kStatus_Success;
275 
276     /* Check arbitration lost. */
277     if (status & kI2C_ArbitrationLostFlag)
278     {
279         /* Clear arbitration lost flag. */
280         base->S = kI2C_ArbitrationLostFlag;
281         result = kStatus_I2C_ArbitrationLost;
282     }
283     /* Check NAK */
284     else if (status & kI2C_ReceiveNakFlag)
285     {
286         result = kStatus_I2C_Nak;
287     }
288     else
289     {
290     }
291 
292     return result;
293 }
294 
I2C_MasterTransferRunStateMachine(I2C_Type * base,i2c_master_handle_t * handle,bool * isDone)295 static status_t I2C_MasterTransferRunStateMachine(I2C_Type *base, i2c_master_handle_t *handle, bool *isDone)
296 {
297     status_t result = kStatus_Success;
298     uint32_t statusFlags = base->S;
299     *isDone = false;
300     volatile uint8_t dummy = 0;
301     bool ignoreNak = ((handle->state == kSendDataState) && (handle->transfer.dataSize == 0U)) ||
302                      ((handle->state == kReceiveDataState) && (handle->transfer.dataSize == 1U));
303 
304     /* Add this to avoid build warning. */
305     dummy++;
306 
307     /* Check & clear error flags. */
308     result = I2C_CheckAndClearError(base, statusFlags);
309 
310     /* Ignore Nak when it's appeared for last byte. */
311     if ((result == kStatus_I2C_Nak) && ignoreNak)
312     {
313         result = kStatus_Success;
314     }
315 
316     /* Handle Check address state to check the slave address is Acked in slave
317        probe application. */
318     if (handle->state == kCheckAddressState)
319     {
320         if (statusFlags & kI2C_ReceiveNakFlag)
321         {
322             result = kStatus_I2C_Addr_Nak;
323         }
324         else
325         {
326             if (handle->transfer.subaddressSize > 0)
327             {
328                 handle->state = kSendCommandState;
329             }
330             else
331             {
332                 if (handle->transfer.direction == kI2C_Write)
333                 {
334                     /* Next state, send data. */
335                     handle->state = kSendDataState;
336                 }
337                 else
338                 {
339                     /* Next state, receive data begin. */
340                     handle->state = kReceiveDataBeginState;
341                 }
342             }
343         }
344     }
345 
346     if (result)
347     {
348         return result;
349     }
350 
351     /* Run state machine. */
352     switch (handle->state)
353     {
354         /* Send I2C command. */
355         case kSendCommandState:
356             if (handle->transfer.subaddressSize)
357             {
358                 handle->transfer.subaddressSize--;
359                 base->D = ((handle->transfer.subaddress) >> (8 * handle->transfer.subaddressSize));
360             }
361             else
362             {
363                 if (handle->transfer.direction == kI2C_Write)
364                 {
365                     /* Next state, send data. */
366                     handle->state = kSendDataState;
367 
368                     /* Send first byte of data. */
369                     if (handle->transfer.dataSize > 0)
370                     {
371                         base->D = *handle->transfer.data;
372                         handle->transfer.data++;
373                         handle->transfer.dataSize--;
374                     }
375                 }
376                 else
377                 {
378                     /* Send repeated start and slave address. */
379                     result = I2C_MasterRepeatedStart(base, handle->transfer.slaveAddress, kI2C_Read);
380 
381                     /* Next state, receive data begin. */
382                     handle->state = kReceiveDataBeginState;
383                 }
384             }
385             break;
386 
387         /* Send I2C data. */
388         case kSendDataState:
389             /* Send one byte of data. */
390             if (handle->transfer.dataSize > 0)
391             {
392                 base->D = *handle->transfer.data;
393                 handle->transfer.data++;
394                 handle->transfer.dataSize--;
395             }
396             else
397             {
398                 *isDone = true;
399             }
400             break;
401 
402         /* Start I2C data receive. */
403         case kReceiveDataBeginState:
404             base->C1 &= ~(I2C_C1_TX_MASK | I2C_C1_TXAK_MASK);
405 
406             /* Send nak at the last receive byte. */
407             if (handle->transfer.dataSize == 1)
408             {
409                 base->C1 |= I2C_C1_TXAK_MASK;
410             }
411 
412             /* Read dummy to release the bus. */
413             dummy = base->D;
414 
415             /* Next state, receive data. */
416             handle->state = kReceiveDataState;
417             break;
418 
419         /* Receive I2C data. */
420         case kReceiveDataState:
421             /* Receive one byte of data. */
422             if (handle->transfer.dataSize--)
423             {
424                 if (handle->transfer.dataSize == 0)
425                 {
426                     *isDone = true;
427 
428                     /* Send stop if kI2C_TransferNoStop is not asserted. */
429                     if (!(handle->transfer.flags & kI2C_TransferNoStopFlag))
430                     {
431                         result = I2C_MasterStop(base);
432                     }
433                     else
434                     {
435                         base->C1 |= I2C_C1_TX_MASK;
436                     }
437                 }
438 
439                 /* Send NAK at the last receive byte. */
440                 if (handle->transfer.dataSize == 1)
441                 {
442                     base->C1 |= I2C_C1_TXAK_MASK;
443                 }
444 
445                 /* Read the data byte into the transfer buffer. */
446                 *handle->transfer.data = base->D;
447                 handle->transfer.data++;
448             }
449             break;
450 
451         default:
452             break;
453     }
454 
455     return result;
456 }
457 
I2C_TransferCommonIRQHandler(I2C_Type * base,void * handle)458 static void I2C_TransferCommonIRQHandler(I2C_Type *base, void *handle)
459 {
460     /* Check if master interrupt. */
461     if ((base->S & kI2C_ArbitrationLostFlag) || (base->C1 & I2C_C1_MST_MASK))
462     {
463         s_i2cMasterIsr(base, handle);
464     }
465     else
466     {
467         s_i2cSlaveIsr(base, handle);
468     }
469     __DSB();
470 }
471 
I2C_MasterInit(I2C_Type * base,const i2c_master_config_t * masterConfig,uint32_t srcClock_Hz)472 void I2C_MasterInit(I2C_Type *base, const i2c_master_config_t *masterConfig, uint32_t srcClock_Hz)
473 {
474     assert(masterConfig && srcClock_Hz);
475 
476     /* Temporary register for filter read. */
477     uint8_t fltReg;
478 #if defined(FSL_FEATURE_I2C_HAS_DOUBLE_BUFFER_ENABLE) && FSL_FEATURE_I2C_HAS_DOUBLE_BUFFER_ENABLE
479     uint8_t s2Reg;
480 #endif
481 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
482     /* Enable I2C clock. */
483     CLOCK_EnableClock(s_i2cClocks[I2C_GetInstance(base)]);
484 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
485 
486     /* Reset the module. */
487     base->A1 = 0;
488     base->F = 0;
489     base->C1 = 0;
490     base->S = 0xFFU;
491     base->C2 = 0;
492 #if defined(FSL_FEATURE_I2C_HAS_START_STOP_DETECT) && FSL_FEATURE_I2C_HAS_START_STOP_DETECT
493     base->FLT = 0x50U;
494 #elif defined(FSL_FEATURE_I2C_HAS_STOP_DETECT) && FSL_FEATURE_I2C_HAS_STOP_DETECT
495     base->FLT = 0x40U;
496 #endif
497     base->RA = 0;
498 
499     /* Disable I2C prior to configuring it. */
500     base->C1 &= ~(I2C_C1_IICEN_MASK);
501 
502     /* Clear all flags. */
503     I2C_MasterClearStatusFlags(base, kClearFlags);
504 
505     /* Configure baud rate. */
506     I2C_MasterSetBaudRate(base, masterConfig->baudRate_Bps, srcClock_Hz);
507 
508     /* Read out the FLT register. */
509     fltReg = base->FLT;
510 
511 #if defined(FSL_FEATURE_I2C_HAS_STOP_HOLD_OFF) && FSL_FEATURE_I2C_HAS_STOP_HOLD_OFF
512     /* Configure the stop / hold enable. */
513     fltReg &= ~(I2C_FLT_SHEN_MASK);
514     fltReg |= I2C_FLT_SHEN(masterConfig->enableStopHold);
515 #endif
516 
517     /* Configure the glitch filter value. */
518     fltReg &= ~(I2C_FLT_FLT_MASK);
519     fltReg |= I2C_FLT_FLT(masterConfig->glitchFilterWidth);
520 
521     /* Write the register value back to the filter register. */
522     base->FLT = fltReg;
523 
524 /* Enable/Disable double buffering. */
525 #if defined(FSL_FEATURE_I2C_HAS_DOUBLE_BUFFER_ENABLE) && FSL_FEATURE_I2C_HAS_DOUBLE_BUFFER_ENABLE
526     s2Reg = base->S2 & (~I2C_S2_DFEN_MASK);
527     base->S2 = s2Reg | I2C_S2_DFEN(masterConfig->enableDoubleBuffering);
528 #endif
529 
530     /* Enable the I2C peripheral based on the configuration. */
531     base->C1 = I2C_C1_IICEN(masterConfig->enableMaster);
532 }
533 
I2C_MasterDeinit(I2C_Type * base)534 void I2C_MasterDeinit(I2C_Type *base)
535 {
536     /* Disable I2C module. */
537     I2C_Enable(base, false);
538 
539 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
540     /* Disable I2C clock. */
541     CLOCK_DisableClock(s_i2cClocks[I2C_GetInstance(base)]);
542 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
543 }
544 
I2C_MasterGetDefaultConfig(i2c_master_config_t * masterConfig)545 void I2C_MasterGetDefaultConfig(i2c_master_config_t *masterConfig)
546 {
547     assert(masterConfig);
548 
549     /* Default baud rate at 100kbps. */
550     masterConfig->baudRate_Bps = 100000U;
551 
552 /* Default stop hold enable is disabled. */
553 #if defined(FSL_FEATURE_I2C_HAS_STOP_HOLD_OFF) && FSL_FEATURE_I2C_HAS_STOP_HOLD_OFF
554     masterConfig->enableStopHold = false;
555 #endif
556 
557     /* Default glitch filter value is no filter. */
558     masterConfig->glitchFilterWidth = 0U;
559 
560 /* Default enable double buffering. */
561 #if defined(FSL_FEATURE_I2C_HAS_DOUBLE_BUFFER_ENABLE) && FSL_FEATURE_I2C_HAS_DOUBLE_BUFFER_ENABLE
562     masterConfig->enableDoubleBuffering = true;
563 #endif
564 
565     /* Enable the I2C peripheral. */
566     masterConfig->enableMaster = true;
567 }
568 
I2C_EnableInterrupts(I2C_Type * base,uint32_t mask)569 void I2C_EnableInterrupts(I2C_Type *base, uint32_t mask)
570 {
571 #ifdef I2C_HAS_STOP_DETECT
572     uint8_t fltReg;
573 #endif
574 
575     if (mask & kI2C_GlobalInterruptEnable)
576     {
577         base->C1 |= I2C_C1_IICIE_MASK;
578     }
579 
580 #if defined(FSL_FEATURE_I2C_HAS_STOP_DETECT) && FSL_FEATURE_I2C_HAS_STOP_DETECT
581     if (mask & kI2C_StopDetectInterruptEnable)
582     {
583         fltReg = base->FLT;
584 
585         /* Keep STOPF flag. */
586         fltReg &= ~I2C_FLT_STOPF_MASK;
587 
588         /* Stop detect enable. */
589         fltReg |= I2C_FLT_STOPIE_MASK;
590         base->FLT = fltReg;
591     }
592 #endif /* FSL_FEATURE_I2C_HAS_STOP_DETECT */
593 
594 #if defined(FSL_FEATURE_I2C_HAS_START_STOP_DETECT) && FSL_FEATURE_I2C_HAS_START_STOP_DETECT
595     if (mask & kI2C_StartStopDetectInterruptEnable)
596     {
597         fltReg = base->FLT;
598 
599         /* Keep STARTF and STOPF flags. */
600         fltReg &= ~(I2C_FLT_STOPF_MASK | I2C_FLT_STARTF_MASK);
601 
602         /* Start and stop detect enable. */
603         fltReg |= I2C_FLT_SSIE_MASK;
604         base->FLT = fltReg;
605     }
606 #endif /* FSL_FEATURE_I2C_HAS_START_STOP_DETECT */
607 }
608 
I2C_DisableInterrupts(I2C_Type * base,uint32_t mask)609 void I2C_DisableInterrupts(I2C_Type *base, uint32_t mask)
610 {
611     if (mask & kI2C_GlobalInterruptEnable)
612     {
613         base->C1 &= ~I2C_C1_IICIE_MASK;
614     }
615 
616 #if defined(FSL_FEATURE_I2C_HAS_STOP_DETECT) && FSL_FEATURE_I2C_HAS_STOP_DETECT
617     if (mask & kI2C_StopDetectInterruptEnable)
618     {
619         base->FLT &= ~(I2C_FLT_STOPIE_MASK | I2C_FLT_STOPF_MASK);
620     }
621 #endif /* FSL_FEATURE_I2C_HAS_STOP_DETECT */
622 
623 #if defined(FSL_FEATURE_I2C_HAS_START_STOP_DETECT) && FSL_FEATURE_I2C_HAS_START_STOP_DETECT
624     if (mask & kI2C_StartStopDetectInterruptEnable)
625     {
626         base->FLT &= ~(I2C_FLT_SSIE_MASK | I2C_FLT_STOPF_MASK | I2C_FLT_STARTF_MASK);
627     }
628 #endif /* FSL_FEATURE_I2C_HAS_START_STOP_DETECT */
629 }
630 
I2C_MasterSetBaudRate(I2C_Type * base,uint32_t baudRate_Bps,uint32_t srcClock_Hz)631 void I2C_MasterSetBaudRate(I2C_Type *base, uint32_t baudRate_Bps, uint32_t srcClock_Hz)
632 {
633     uint32_t multiplier;
634     uint32_t computedRate;
635     uint32_t absError;
636     uint32_t bestError = UINT32_MAX;
637     uint32_t bestMult = 0u;
638     uint32_t bestIcr = 0u;
639     uint8_t mult;
640     uint8_t i;
641 
642     /* Search for the settings with the lowest error. Mult is the MULT field of the I2C_F register,
643      * and ranges from 0-2. It selects the multiplier factor for the divider. */
644     for (mult = 0u; (mult <= 2u) && (bestError != 0); ++mult)
645     {
646         multiplier = 1u << mult;
647 
648         /* Scan table to find best match. */
649         for (i = 0u; i < sizeof(s_i2cDividerTable) / sizeof(uint16_t); ++i)
650         {
651             computedRate = srcClock_Hz / (multiplier * s_i2cDividerTable[i]);
652             absError = baudRate_Bps > computedRate ? (baudRate_Bps - computedRate) : (computedRate - baudRate_Bps);
653 
654             if (absError < bestError)
655             {
656                 bestMult = mult;
657                 bestIcr = i;
658                 bestError = absError;
659 
660                 /* If the error is 0, then we can stop searching because we won't find a better match. */
661                 if (absError == 0)
662                 {
663                     break;
664                 }
665             }
666         }
667     }
668 
669     /* Set frequency register based on best settings. */
670     base->F = I2C_F_MULT(bestMult) | I2C_F_ICR(bestIcr);
671 }
672 
I2C_MasterStart(I2C_Type * base,uint8_t address,i2c_direction_t direction)673 status_t I2C_MasterStart(I2C_Type *base, uint8_t address, i2c_direction_t direction)
674 {
675     status_t result = kStatus_Success;
676     uint32_t statusFlags = I2C_MasterGetStatusFlags(base);
677 
678     /* Return an error if the bus is already in use. */
679     if (statusFlags & kI2C_BusBusyFlag)
680     {
681         result = kStatus_I2C_Busy;
682     }
683     else
684     {
685         /* Send the START signal. */
686         base->C1 |= I2C_C1_MST_MASK | I2C_C1_TX_MASK;
687 
688 #if defined(FSL_FEATURE_I2C_HAS_DOUBLE_BUFFERING) && FSL_FEATURE_I2C_HAS_DOUBLE_BUFFERING
689         while (!(base->S2 & I2C_S2_EMPTY_MASK))
690         {
691         }
692 #endif /* FSL_FEATURE_I2C_HAS_DOUBLE_BUFFERING */
693 
694         base->D = (((uint32_t)address) << 1U | ((direction == kI2C_Read) ? 1U : 0U));
695     }
696 
697     return result;
698 }
699 
I2C_MasterRepeatedStart(I2C_Type * base,uint8_t address,i2c_direction_t direction)700 status_t I2C_MasterRepeatedStart(I2C_Type *base, uint8_t address, i2c_direction_t direction)
701 {
702     status_t result = kStatus_Success;
703     uint8_t savedMult;
704     uint32_t statusFlags = I2C_MasterGetStatusFlags(base);
705     uint8_t timeDelay = 6;
706 
707     /* Return an error if the bus is already in use, but not by us. */
708     if ((statusFlags & kI2C_BusBusyFlag) && ((base->C1 & I2C_C1_MST_MASK) == 0))
709     {
710         result = kStatus_I2C_Busy;
711     }
712     else
713     {
714         savedMult = base->F;
715         base->F = savedMult & (~I2C_F_MULT_MASK);
716 
717         /* We are already in a transfer, so send a repeated start. */
718         base->C1 |= I2C_C1_RSTA_MASK | I2C_C1_TX_MASK;
719 
720         /* Restore the multiplier factor. */
721         base->F = savedMult;
722 
723         /* Add some delay to wait the Re-Start signal. */
724         while (timeDelay--)
725         {
726             __NOP();
727         }
728 
729 #if defined(FSL_FEATURE_I2C_HAS_DOUBLE_BUFFERING) && FSL_FEATURE_I2C_HAS_DOUBLE_BUFFERING
730         while (!(base->S2 & I2C_S2_EMPTY_MASK))
731         {
732         }
733 #endif /* FSL_FEATURE_I2C_HAS_DOUBLE_BUFFERING */
734 
735         base->D = (((uint32_t)address) << 1U | ((direction == kI2C_Read) ? 1U : 0U));
736     }
737 
738     return result;
739 }
740 
I2C_MasterStop(I2C_Type * base)741 status_t I2C_MasterStop(I2C_Type *base)
742 {
743     status_t result = kStatus_Success;
744     uint16_t timeout = UINT16_MAX;
745 
746     /* Issue the STOP command on the bus. */
747     base->C1 &= ~(I2C_C1_MST_MASK | I2C_C1_TX_MASK | I2C_C1_TXAK_MASK);
748 
749     /* Wait until data transfer complete. */
750     while ((base->S & kI2C_BusBusyFlag) && (--timeout))
751     {
752     }
753 
754     if (timeout == 0)
755     {
756         result = kStatus_I2C_Timeout;
757     }
758 
759     return result;
760 }
761 
I2C_MasterGetStatusFlags(I2C_Type * base)762 uint32_t I2C_MasterGetStatusFlags(I2C_Type *base)
763 {
764     uint32_t statusFlags = base->S;
765 
766 #ifdef I2C_HAS_STOP_DETECT
767     /* Look up the STOPF bit from the filter register. */
768     if (base->FLT & I2C_FLT_STOPF_MASK)
769     {
770         statusFlags |= kI2C_StopDetectFlag;
771     }
772 #endif
773 
774 #if defined(FSL_FEATURE_I2C_HAS_START_STOP_DETECT) && FSL_FEATURE_I2C_HAS_START_STOP_DETECT
775     /* Look up the STARTF bit from the filter register. */
776     if (base->FLT & I2C_FLT_STARTF_MASK)
777     {
778         statusFlags |= kI2C_StartDetectFlag;
779     }
780 #endif /* FSL_FEATURE_I2C_HAS_START_STOP_DETECT */
781 
782     return statusFlags;
783 }
784 
I2C_MasterWriteBlocking(I2C_Type * base,const uint8_t * txBuff,size_t txSize,uint32_t flags)785 status_t I2C_MasterWriteBlocking(I2C_Type *base, const uint8_t *txBuff, size_t txSize, uint32_t flags)
786 {
787     status_t result = kStatus_Success;
788     uint8_t statusFlags = 0;
789 
790     /* Wait until the data register is ready for transmit. */
791     while (!(base->S & kI2C_TransferCompleteFlag))
792     {
793     }
794 
795     /* Clear the IICIF flag. */
796     base->S = kI2C_IntPendingFlag;
797 
798     /* Setup the I2C peripheral to transmit data. */
799     base->C1 |= I2C_C1_TX_MASK;
800 
801     while (txSize--)
802     {
803         /* Send a byte of data. */
804         base->D = *txBuff++;
805 
806         /* Wait until data transfer complete. */
807         while (!(base->S & kI2C_IntPendingFlag))
808         {
809         }
810 
811         statusFlags = base->S;
812 
813         /* Clear the IICIF flag. */
814         base->S = kI2C_IntPendingFlag;
815 
816         /* Check if arbitration lost or no acknowledgement (NAK), return failure status. */
817         if (statusFlags & kI2C_ArbitrationLostFlag)
818         {
819             base->S = kI2C_ArbitrationLostFlag;
820             result = kStatus_I2C_ArbitrationLost;
821         }
822 
823         if ((statusFlags & kI2C_ReceiveNakFlag) && txSize)
824         {
825             base->S = kI2C_ReceiveNakFlag;
826             result = kStatus_I2C_Nak;
827         }
828 
829         if (result != kStatus_Success)
830         {
831             /* Breaking out of the send loop. */
832             break;
833         }
834     }
835 
836     if (((result == kStatus_Success) && (!(flags & kI2C_TransferNoStopFlag))) || (result == kStatus_I2C_Nak))
837     {
838         /* Clear the IICIF flag. */
839         base->S = kI2C_IntPendingFlag;
840 
841         /* Send stop. */
842         result = I2C_MasterStop(base);
843     }
844 
845     return result;
846 }
847 
I2C_MasterReadBlocking(I2C_Type * base,uint8_t * rxBuff,size_t rxSize,uint32_t flags)848 status_t I2C_MasterReadBlocking(I2C_Type *base, uint8_t *rxBuff, size_t rxSize, uint32_t flags)
849 {
850     status_t result = kStatus_Success;
851     volatile uint8_t dummy = 0;
852 
853     /* Add this to avoid build warning. */
854     dummy++;
855 
856     /* Wait until the data register is ready for transmit. */
857     while (!(base->S & kI2C_TransferCompleteFlag))
858     {
859     }
860 
861     /* Clear the IICIF flag. */
862     base->S = kI2C_IntPendingFlag;
863 
864     /* Setup the I2C peripheral to receive data. */
865     base->C1 &= ~(I2C_C1_TX_MASK | I2C_C1_TXAK_MASK);
866 
867     /* If rxSize equals 1, configure to send NAK. */
868     if (rxSize == 1)
869     {
870         /* Issue NACK on read. */
871         base->C1 |= I2C_C1_TXAK_MASK;
872     }
873 
874     /* Do dummy read. */
875     dummy = base->D;
876 
877     while ((rxSize--))
878     {
879         /* Wait until data transfer complete. */
880         while (!(base->S & kI2C_IntPendingFlag))
881         {
882         }
883 
884         /* Clear the IICIF flag. */
885         base->S = kI2C_IntPendingFlag;
886 
887         /* Single byte use case. */
888         if (rxSize == 0)
889         {
890             if (!(flags & kI2C_TransferNoStopFlag))
891             {
892                 /* Issue STOP command before reading last byte. */
893                 result = I2C_MasterStop(base);
894             }
895             else
896             {
897                 /* Change direction to Tx to avoid extra clocks. */
898                 base->C1 |= I2C_C1_TX_MASK;
899             }
900         }
901 
902         if (rxSize == 1)
903         {
904             /* Issue NACK on read. */
905             base->C1 |= I2C_C1_TXAK_MASK;
906         }
907 
908         /* Read from the data register. */
909         *rxBuff++ = base->D;
910     }
911 
912     return result;
913 }
914 
I2C_MasterTransferBlocking(I2C_Type * base,i2c_master_transfer_t * xfer)915 status_t I2C_MasterTransferBlocking(I2C_Type *base, i2c_master_transfer_t *xfer)
916 {
917     assert(xfer);
918 
919     i2c_direction_t direction = xfer->direction;
920     status_t result = kStatus_Success;
921 
922     /* Clear all status before transfer. */
923     I2C_MasterClearStatusFlags(base, kClearFlags);
924 
925     /* Wait until ready to complete. */
926     while (!(base->S & kI2C_TransferCompleteFlag))
927     {
928     }
929 
930     /* Change to send write address when it's a read operation with command. */
931     if ((xfer->subaddressSize > 0) && (xfer->direction == kI2C_Read))
932     {
933         direction = kI2C_Write;
934     }
935 
936     /* If repeated start is requested, send repeated start. */
937     if (xfer->flags & kI2C_TransferRepeatedStartFlag)
938     {
939         result = I2C_MasterRepeatedStart(base, xfer->slaveAddress, direction);
940     }
941     else /* For normal transfer, send start. */
942     {
943         result = I2C_MasterStart(base, xfer->slaveAddress, direction);
944     }
945 
946     /* Return if error. */
947     if (result)
948     {
949         return result;
950     }
951 
952     while (!(base->S & kI2C_IntPendingFlag))
953     {
954     }
955 
956     /* Check if there's transfer error. */
957     result = I2C_CheckAndClearError(base, base->S);
958 
959     /* Return if error. */
960     if (result)
961     {
962         if (result == kStatus_I2C_Nak)
963         {
964             result = kStatus_I2C_Addr_Nak;
965 
966             I2C_MasterStop(base);
967         }
968 
969         return result;
970     }
971 
972     /* Send subaddress. */
973     if (xfer->subaddressSize)
974     {
975         do
976         {
977             /* Clear interrupt pending flag. */
978             base->S = kI2C_IntPendingFlag;
979 
980             xfer->subaddressSize--;
981             base->D = ((xfer->subaddress) >> (8 * xfer->subaddressSize));
982 
983             /* Wait until data transfer complete. */
984             while (!(base->S & kI2C_IntPendingFlag))
985             {
986             }
987 
988             /* Check if there's transfer error. */
989             result = I2C_CheckAndClearError(base, base->S);
990 
991             if (result)
992             {
993                 if (result == kStatus_I2C_Nak)
994                 {
995                     I2C_MasterStop(base);
996                 }
997 
998                 return result;
999             }
1000 
1001         } while ((xfer->subaddressSize > 0) && (result == kStatus_Success));
1002 
1003         if (xfer->direction == kI2C_Read)
1004         {
1005             /* Clear pending flag. */
1006             base->S = kI2C_IntPendingFlag;
1007 
1008             /* Send repeated start and slave address. */
1009             result = I2C_MasterRepeatedStart(base, xfer->slaveAddress, kI2C_Read);
1010 
1011             /* Return if error. */
1012             if (result)
1013             {
1014                 return result;
1015             }
1016 
1017             /* Wait until data transfer complete. */
1018             while (!(base->S & kI2C_IntPendingFlag))
1019             {
1020             }
1021 
1022             /* Check if there's transfer error. */
1023             result = I2C_CheckAndClearError(base, base->S);
1024 
1025             if (result)
1026             {
1027                 if (result == kStatus_I2C_Nak)
1028                 {
1029                     result = kStatus_I2C_Addr_Nak;
1030 
1031                     I2C_MasterStop(base);
1032                 }
1033 
1034                 return result;
1035             }
1036         }
1037     }
1038 
1039     /* Transmit data. */
1040     if ((xfer->direction == kI2C_Write) && (xfer->dataSize > 0))
1041     {
1042         /* Send Data. */
1043         result = I2C_MasterWriteBlocking(base, xfer->data, xfer->dataSize, xfer->flags);
1044     }
1045 
1046     /* Receive Data. */
1047     if ((xfer->direction == kI2C_Read) && (xfer->dataSize > 0))
1048     {
1049         result = I2C_MasterReadBlocking(base, xfer->data, xfer->dataSize, xfer->flags);
1050     }
1051 
1052     return result;
1053 }
1054 
I2C_MasterTransferCreateHandle(I2C_Type * base,i2c_master_handle_t * handle,i2c_master_transfer_callback_t callback,void * userData)1055 void I2C_MasterTransferCreateHandle(I2C_Type *base,
1056                                     i2c_master_handle_t *handle,
1057                                     i2c_master_transfer_callback_t callback,
1058                                     void *userData)
1059 {
1060     assert(handle);
1061 
1062     uint32_t instance = I2C_GetInstance(base);
1063 
1064     /* Zero handle. */
1065     memset(handle, 0, sizeof(*handle));
1066 
1067     /* Set callback and userData. */
1068     handle->completionCallback = callback;
1069     handle->userData = userData;
1070 
1071     /* Save the context in global variables to support the double weak mechanism. */
1072     s_i2cHandle[instance] = handle;
1073 
1074     /* Save master interrupt handler. */
1075     s_i2cMasterIsr = I2C_MasterTransferHandleIRQ;
1076 
1077     /* Enable NVIC interrupt. */
1078     EnableIRQ(s_i2cIrqs[instance]);
1079 }
1080 
I2C_MasterTransferNonBlocking(I2C_Type * base,i2c_master_handle_t * handle,i2c_master_transfer_t * xfer)1081 status_t I2C_MasterTransferNonBlocking(I2C_Type *base, i2c_master_handle_t *handle, i2c_master_transfer_t *xfer)
1082 {
1083     assert(handle);
1084     assert(xfer);
1085 
1086     status_t result = kStatus_Success;
1087 
1088     /* Check if the I2C bus is idle - if not return busy status. */
1089     if (handle->state != kIdleState)
1090     {
1091         result = kStatus_I2C_Busy;
1092     }
1093     else
1094     {
1095         /* Start up the master transfer state machine. */
1096         result = I2C_InitTransferStateMachine(base, handle, xfer);
1097 
1098         if (result == kStatus_Success)
1099         {
1100             /* Enable the I2C interrupts. */
1101             I2C_EnableInterrupts(base, kI2C_GlobalInterruptEnable);
1102         }
1103     }
1104 
1105     return result;
1106 }
1107 
I2C_MasterTransferAbort(I2C_Type * base,i2c_master_handle_t * handle)1108 void I2C_MasterTransferAbort(I2C_Type *base, i2c_master_handle_t *handle)
1109 {
1110     assert(handle);
1111 
1112     volatile uint8_t dummy = 0;
1113 
1114     /* Add this to avoid build warning. */
1115     dummy++;
1116 
1117     /* Disable interrupt. */
1118     I2C_DisableInterrupts(base, kI2C_GlobalInterruptEnable);
1119 
1120     /* Reset the state to idle. */
1121     handle->state = kIdleState;
1122 
1123     /* Send STOP signal. */
1124     if (handle->transfer.direction == kI2C_Read)
1125     {
1126         base->C1 |= I2C_C1_TXAK_MASK;
1127         while (!(base->S & kI2C_IntPendingFlag))
1128         {
1129         }
1130         base->S = kI2C_IntPendingFlag;
1131 
1132         base->C1 &= ~(I2C_C1_MST_MASK | I2C_C1_TX_MASK | I2C_C1_TXAK_MASK);
1133         dummy = base->D;
1134     }
1135     else
1136     {
1137         while (!(base->S & kI2C_IntPendingFlag))
1138         {
1139         }
1140         base->S = kI2C_IntPendingFlag;
1141         base->C1 &= ~(I2C_C1_MST_MASK | I2C_C1_TX_MASK | I2C_C1_TXAK_MASK);
1142     }
1143 }
1144 
I2C_MasterTransferGetCount(I2C_Type * base,i2c_master_handle_t * handle,size_t * count)1145 status_t I2C_MasterTransferGetCount(I2C_Type *base, i2c_master_handle_t *handle, size_t *count)
1146 {
1147     assert(handle);
1148 
1149     if (!count)
1150     {
1151         return kStatus_InvalidArgument;
1152     }
1153 
1154     *count = handle->transferSize - handle->transfer.dataSize;
1155 
1156     return kStatus_Success;
1157 }
1158 
I2C_MasterTransferHandleIRQ(I2C_Type * base,void * i2cHandle)1159 void I2C_MasterTransferHandleIRQ(I2C_Type *base, void *i2cHandle)
1160 {
1161     assert(i2cHandle);
1162 
1163     i2c_master_handle_t *handle = (i2c_master_handle_t *)i2cHandle;
1164     status_t result = kStatus_Success;
1165     bool isDone;
1166 
1167     /* Clear the interrupt flag. */
1168     base->S = kI2C_IntPendingFlag;
1169 
1170     /* Check transfer complete flag. */
1171     result = I2C_MasterTransferRunStateMachine(base, handle, &isDone);
1172 
1173     if (isDone || result)
1174     {
1175         /* Send stop command if transfer done or received Nak. */
1176         if ((!(handle->transfer.flags & kI2C_TransferNoStopFlag)) || (result == kStatus_I2C_Nak) ||
1177             (result == kStatus_I2C_Addr_Nak))
1178         {
1179             /* Ensure stop command is a need. */
1180             if ((base->C1 & I2C_C1_MST_MASK))
1181             {
1182                 if (I2C_MasterStop(base) != kStatus_Success)
1183                 {
1184                     result = kStatus_I2C_Timeout;
1185                 }
1186             }
1187         }
1188 
1189         /* Restore handle to idle state. */
1190         handle->state = kIdleState;
1191 
1192         /* Disable interrupt. */
1193         I2C_DisableInterrupts(base, kI2C_GlobalInterruptEnable);
1194 
1195         /* Call the callback function after the function has completed. */
1196         if (handle->completionCallback)
1197         {
1198             handle->completionCallback(base, handle, result, handle->userData);
1199         }
1200     }
1201 }
1202 
I2C_SlaveInit(I2C_Type * base,const i2c_slave_config_t * slaveConfig,uint32_t srcClock_Hz)1203 void I2C_SlaveInit(I2C_Type *base, const i2c_slave_config_t *slaveConfig, uint32_t srcClock_Hz)
1204 {
1205     assert(slaveConfig);
1206 
1207     uint8_t tmpReg;
1208 
1209 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
1210     CLOCK_EnableClock(s_i2cClocks[I2C_GetInstance(base)]);
1211 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
1212 
1213     /* Reset the module. */
1214     base->A1 = 0;
1215     base->F = 0;
1216     base->C1 = 0;
1217     base->S = 0xFFU;
1218     base->C2 = 0;
1219 #if defined(FSL_FEATURE_I2C_HAS_START_STOP_DETECT) && FSL_FEATURE_I2C_HAS_START_STOP_DETECT
1220     base->FLT = 0x50U;
1221 #elif defined(FSL_FEATURE_I2C_HAS_STOP_DETECT) && FSL_FEATURE_I2C_HAS_STOP_DETECT
1222     base->FLT = 0x40U;
1223 #endif
1224     base->RA = 0;
1225 
1226     /* Configure addressing mode. */
1227     switch (slaveConfig->addressingMode)
1228     {
1229         case kI2C_Address7bit:
1230             base->A1 = ((uint32_t)(slaveConfig->slaveAddress)) << 1U;
1231             break;
1232 
1233         case kI2C_RangeMatch:
1234             assert(slaveConfig->slaveAddress < slaveConfig->upperAddress);
1235             base->A1 = ((uint32_t)(slaveConfig->slaveAddress)) << 1U;
1236             base->RA = ((uint32_t)(slaveConfig->upperAddress)) << 1U;
1237             base->C2 |= I2C_C2_RMEN_MASK;
1238             break;
1239 
1240         default:
1241             break;
1242     }
1243 
1244     /* Configure low power wake up feature. */
1245     tmpReg = base->C1;
1246     tmpReg &= ~I2C_C1_WUEN_MASK;
1247     base->C1 = tmpReg | I2C_C1_WUEN(slaveConfig->enableWakeUp) | I2C_C1_IICEN(slaveConfig->enableSlave);
1248 
1249     /* Configure general call & baud rate control. */
1250     tmpReg = base->C2;
1251     tmpReg &= ~(I2C_C2_SBRC_MASK | I2C_C2_GCAEN_MASK);
1252     tmpReg |= I2C_C2_SBRC(slaveConfig->enableBaudRateCtl) | I2C_C2_GCAEN(slaveConfig->enableGeneralCall);
1253     base->C2 = tmpReg;
1254 
1255 /* Enable/Disable double buffering. */
1256 #if defined(FSL_FEATURE_I2C_HAS_DOUBLE_BUFFER_ENABLE) && FSL_FEATURE_I2C_HAS_DOUBLE_BUFFER_ENABLE
1257     tmpReg = base->S2 & (~I2C_S2_DFEN_MASK);
1258     base->S2 = tmpReg | I2C_S2_DFEN(slaveConfig->enableDoubleBuffering);
1259 #endif
1260 
1261     /* Set hold time. */
1262     I2C_SetHoldTime(base, slaveConfig->sclStopHoldTime_ns, srcClock_Hz);
1263 }
1264 
I2C_SlaveDeinit(I2C_Type * base)1265 void I2C_SlaveDeinit(I2C_Type *base)
1266 {
1267     /* Disable I2C module. */
1268     I2C_Enable(base, false);
1269 
1270 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
1271     /* Disable I2C clock. */
1272     CLOCK_DisableClock(s_i2cClocks[I2C_GetInstance(base)]);
1273 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
1274 }
1275 
I2C_SlaveGetDefaultConfig(i2c_slave_config_t * slaveConfig)1276 void I2C_SlaveGetDefaultConfig(i2c_slave_config_t *slaveConfig)
1277 {
1278     assert(slaveConfig);
1279 
1280     /* By default slave is addressed with 7-bit address. */
1281     slaveConfig->addressingMode = kI2C_Address7bit;
1282 
1283     /* General call mode is disabled by default. */
1284     slaveConfig->enableGeneralCall = false;
1285 
1286     /* Slave address match waking up MCU from low power mode is disabled. */
1287     slaveConfig->enableWakeUp = false;
1288 
1289     /* Independent slave mode baud rate at maximum frequency is disabled. */
1290     slaveConfig->enableBaudRateCtl = false;
1291 
1292 /* Default enable double buffering. */
1293 #if defined(FSL_FEATURE_I2C_HAS_DOUBLE_BUFFER_ENABLE) && FSL_FEATURE_I2C_HAS_DOUBLE_BUFFER_ENABLE
1294     slaveConfig->enableDoubleBuffering = true;
1295 #endif
1296 
1297     /* Set default SCL stop hold time to 4us which is minimum requirement in I2C spec. */
1298     slaveConfig->sclStopHoldTime_ns = 4000;
1299 
1300     /* Enable the I2C peripheral. */
1301     slaveConfig->enableSlave = true;
1302 }
1303 
I2C_SlaveWriteBlocking(I2C_Type * base,const uint8_t * txBuff,size_t txSize)1304 status_t I2C_SlaveWriteBlocking(I2C_Type *base, const uint8_t *txBuff, size_t txSize)
1305 {
1306     status_t result = kStatus_Success;
1307     volatile uint8_t dummy = 0;
1308 
1309     /* Add this to avoid build warning. */
1310     dummy++;
1311 
1312 #if defined(FSL_FEATURE_I2C_HAS_START_STOP_DETECT) && FSL_FEATURE_I2C_HAS_START_STOP_DETECT
1313     /* Check start flag. */
1314     while (!(base->FLT & I2C_FLT_STARTF_MASK))
1315     {
1316     }
1317     /* Clear STARTF flag. */
1318     base->FLT |= I2C_FLT_STARTF_MASK;
1319     /* Clear the IICIF flag. */
1320     base->S = kI2C_IntPendingFlag;
1321 #endif /* FSL_FEATURE_I2C_HAS_START_STOP_DETECT */
1322 
1323     /* Wait for address match flag. */
1324     while (!(base->S & kI2C_AddressMatchFlag))
1325     {
1326     }
1327 
1328     /* Read dummy to release bus. */
1329     dummy = base->D;
1330 
1331     result = I2C_MasterWriteBlocking(base, txBuff, txSize, kI2C_TransferDefaultFlag);
1332 
1333     /* Switch to receive mode. */
1334     base->C1 &= ~(I2C_C1_TX_MASK | I2C_C1_TXAK_MASK);
1335 
1336     /* Read dummy to release bus. */
1337     dummy = base->D;
1338 
1339     return result;
1340 }
1341 
I2C_SlaveReadBlocking(I2C_Type * base,uint8_t * rxBuff,size_t rxSize)1342 void I2C_SlaveReadBlocking(I2C_Type *base, uint8_t *rxBuff, size_t rxSize)
1343 {
1344     volatile uint8_t dummy = 0;
1345 
1346     /* Add this to avoid build warning. */
1347     dummy++;
1348 
1349 /* Wait until address match. */
1350 #if defined(FSL_FEATURE_I2C_HAS_START_STOP_DETECT) && FSL_FEATURE_I2C_HAS_START_STOP_DETECT
1351     /* Check start flag. */
1352     while (!(base->FLT & I2C_FLT_STARTF_MASK))
1353     {
1354     }
1355     /* Clear STARTF flag. */
1356     base->FLT |= I2C_FLT_STARTF_MASK;
1357     /* Clear the IICIF flag. */
1358     base->S = kI2C_IntPendingFlag;
1359 #endif /* FSL_FEATURE_I2C_HAS_START_STOP_DETECT */
1360 
1361     /* Wait for address match and int pending flag. */
1362     while (!(base->S & kI2C_AddressMatchFlag))
1363     {
1364     }
1365     while (!(base->S & kI2C_IntPendingFlag))
1366     {
1367     }
1368 
1369     /* Read dummy to release bus. */
1370     dummy = base->D;
1371 
1372     /* Clear the IICIF flag. */
1373     base->S = kI2C_IntPendingFlag;
1374 
1375     /* Setup the I2C peripheral to receive data. */
1376     base->C1 &= ~(I2C_C1_TX_MASK);
1377 
1378     while (rxSize--)
1379     {
1380         /* Wait until data transfer complete. */
1381         while (!(base->S & kI2C_IntPendingFlag))
1382         {
1383         }
1384         /* Clear the IICIF flag. */
1385         base->S = kI2C_IntPendingFlag;
1386 
1387         /* Read from the data register. */
1388         *rxBuff++ = base->D;
1389     }
1390 }
1391 
I2C_SlaveTransferCreateHandle(I2C_Type * base,i2c_slave_handle_t * handle,i2c_slave_transfer_callback_t callback,void * userData)1392 void I2C_SlaveTransferCreateHandle(I2C_Type *base,
1393                                    i2c_slave_handle_t *handle,
1394                                    i2c_slave_transfer_callback_t callback,
1395                                    void *userData)
1396 {
1397     assert(handle);
1398 
1399     uint32_t instance = I2C_GetInstance(base);
1400 
1401     /* Zero handle. */
1402     memset(handle, 0, sizeof(*handle));
1403 
1404     /* Set callback and userData. */
1405     handle->callback = callback;
1406     handle->userData = userData;
1407 
1408     /* Save the context in global variables to support the double weak mechanism. */
1409     s_i2cHandle[instance] = handle;
1410 
1411     /* Save slave interrupt handler. */
1412     s_i2cSlaveIsr = I2C_SlaveTransferHandleIRQ;
1413 
1414     /* Enable NVIC interrupt. */
1415     EnableIRQ(s_i2cIrqs[instance]);
1416 }
1417 
I2C_SlaveTransferNonBlocking(I2C_Type * base,i2c_slave_handle_t * handle,uint32_t eventMask)1418 status_t I2C_SlaveTransferNonBlocking(I2C_Type *base, i2c_slave_handle_t *handle, uint32_t eventMask)
1419 {
1420     assert(handle);
1421 
1422     /* Check if the I2C bus is idle - if not return busy status. */
1423     if (handle->isBusy)
1424     {
1425         return kStatus_I2C_Busy;
1426     }
1427     else
1428     {
1429         /* Disable LPI2C IRQ sources while we configure stuff. */
1430         I2C_DisableInterrupts(base, kIrqFlags);
1431 
1432         /* Clear transfer in handle. */
1433         memset(&handle->transfer, 0, sizeof(handle->transfer));
1434 
1435         /* Record that we're busy. */
1436         handle->isBusy = true;
1437 
1438         /* Set up event mask. tx and rx are always enabled. */
1439         handle->eventMask = eventMask | kI2C_SlaveTransmitEvent | kI2C_SlaveReceiveEvent | kI2C_SlaveGenaralcallEvent;
1440 
1441         /* Clear all flags. */
1442         I2C_SlaveClearStatusFlags(base, kClearFlags);
1443 
1444         /* Enable I2C internal IRQ sources. NVIC IRQ was enabled in CreateHandle() */
1445         I2C_EnableInterrupts(base, kIrqFlags);
1446     }
1447 
1448     return kStatus_Success;
1449 }
1450 
I2C_SlaveTransferAbort(I2C_Type * base,i2c_slave_handle_t * handle)1451 void I2C_SlaveTransferAbort(I2C_Type *base, i2c_slave_handle_t *handle)
1452 {
1453     assert(handle);
1454 
1455     if (handle->isBusy)
1456     {
1457         /* Disable interrupts. */
1458         I2C_DisableInterrupts(base, kIrqFlags);
1459 
1460         /* Reset transfer info. */
1461         memset(&handle->transfer, 0, sizeof(handle->transfer));
1462 
1463         /* Reset the state to idle. */
1464         handle->isBusy = false;
1465     }
1466 }
1467 
I2C_SlaveTransferGetCount(I2C_Type * base,i2c_slave_handle_t * handle,size_t * count)1468 status_t I2C_SlaveTransferGetCount(I2C_Type *base, i2c_slave_handle_t *handle, size_t *count)
1469 {
1470     assert(handle);
1471 
1472     if (!count)
1473     {
1474         return kStatus_InvalidArgument;
1475     }
1476 
1477     /* Catch when there is not an active transfer. */
1478     if (!handle->isBusy)
1479     {
1480         *count = 0;
1481         return kStatus_NoTransferInProgress;
1482     }
1483 
1484     /* For an active transfer, just return the count from the handle. */
1485     *count = handle->transfer.transferredCount;
1486 
1487     return kStatus_Success;
1488 }
1489 
I2C_SlaveTransferHandleIRQ(I2C_Type * base,void * i2cHandle)1490 void I2C_SlaveTransferHandleIRQ(I2C_Type *base, void *i2cHandle)
1491 {
1492     assert(i2cHandle);
1493 
1494     uint16_t status;
1495     bool doTransmit = false;
1496     i2c_slave_handle_t *handle = (i2c_slave_handle_t *)i2cHandle;
1497     i2c_slave_transfer_t *xfer;
1498     volatile uint8_t dummy = 0;
1499 
1500     /* Add this to avoid build warning. */
1501     dummy++;
1502 
1503     status = I2C_SlaveGetStatusFlags(base);
1504     xfer = &(handle->transfer);
1505 
1506 #ifdef I2C_HAS_STOP_DETECT
1507     /* Check stop flag. */
1508     if (status & kI2C_StopDetectFlag)
1509     {
1510         I2C_MasterClearStatusFlags(base, kI2C_StopDetectFlag);
1511 
1512         /* Clear the interrupt flag. */
1513         base->S = kI2C_IntPendingFlag;
1514 
1515         /* Call slave callback if this is the STOP of the transfer. */
1516         if (handle->isBusy)
1517         {
1518             xfer->event = kI2C_SlaveCompletionEvent;
1519             xfer->completionStatus = kStatus_Success;
1520             handle->isBusy = false;
1521 
1522             if ((handle->eventMask & xfer->event) && (handle->callback))
1523             {
1524                 handle->callback(base, xfer, handle->userData);
1525             }
1526         }
1527 
1528         if (!(status & kI2C_AddressMatchFlag))
1529         {
1530             return;
1531         }
1532     }
1533 #endif /* I2C_HAS_STOP_DETECT */
1534 
1535 #if defined(FSL_FEATURE_I2C_HAS_START_STOP_DETECT) && FSL_FEATURE_I2C_HAS_START_STOP_DETECT
1536     /* Check start flag. */
1537     if (status & kI2C_StartDetectFlag)
1538     {
1539         I2C_MasterClearStatusFlags(base, kI2C_StartDetectFlag);
1540 
1541         /* Clear the interrupt flag. */
1542         base->S = kI2C_IntPendingFlag;
1543 
1544         xfer->event = kI2C_SlaveStartEvent;
1545 
1546         if ((handle->eventMask & xfer->event) && (handle->callback))
1547         {
1548             handle->callback(base, xfer, handle->userData);
1549         }
1550 
1551         if (!(status & kI2C_AddressMatchFlag))
1552         {
1553             return;
1554         }
1555     }
1556 #endif /* FSL_FEATURE_I2C_HAS_START_STOP_DETECT */
1557 
1558     /* Clear the interrupt flag. */
1559     base->S = kI2C_IntPendingFlag;
1560 
1561     /* Check NAK */
1562     if (status & kI2C_ReceiveNakFlag)
1563     {
1564         /* Set receive mode. */
1565         base->C1 &= ~(I2C_C1_TX_MASK | I2C_C1_TXAK_MASK);
1566 
1567         /* Read dummy. */
1568         dummy = base->D;
1569 
1570         if (handle->transfer.dataSize != 0)
1571         {
1572             xfer->event = kI2C_SlaveCompletionEvent;
1573             xfer->completionStatus = kStatus_I2C_Nak;
1574             handle->isBusy = false;
1575 
1576             if ((handle->eventMask & xfer->event) && (handle->callback))
1577             {
1578                 handle->callback(base, xfer, handle->userData);
1579             }
1580         }
1581         else
1582         {
1583 #ifndef I2C_HAS_STOP_DETECT
1584             xfer->event = kI2C_SlaveCompletionEvent;
1585             xfer->completionStatus = kStatus_Success;
1586             handle->isBusy = false;
1587 
1588             if ((handle->eventMask & xfer->event) && (handle->callback))
1589             {
1590                 handle->callback(base, xfer, handle->userData);
1591             }
1592 #endif /* !FSL_FEATURE_I2C_HAS_START_STOP_DETECT or !FSL_FEATURE_I2C_HAS_STOP_DETECT */
1593         }
1594     }
1595     /* Check address match. */
1596     else if (status & kI2C_AddressMatchFlag)
1597     {
1598         handle->isBusy = true;
1599         xfer->event = kI2C_SlaveAddressMatchEvent;
1600 
1601         /* Slave transmit, master reading from slave. */
1602         if (status & kI2C_TransferDirectionFlag)
1603         {
1604             /* Change direction to send data. */
1605             base->C1 |= I2C_C1_TX_MASK;
1606 
1607             doTransmit = true;
1608         }
1609         else
1610         {
1611             /* Slave receive, master writing to slave. */
1612             base->C1 &= ~(I2C_C1_TX_MASK | I2C_C1_TXAK_MASK);
1613 
1614             /* Read dummy to release the bus. */
1615             dummy = base->D;
1616 
1617             if (dummy == 0)
1618             {
1619                 xfer->event = kI2C_SlaveGenaralcallEvent;
1620             }
1621         }
1622 
1623         if ((handle->eventMask & xfer->event) && (handle->callback))
1624         {
1625             handle->callback(base, xfer, handle->userData);
1626         }
1627     }
1628     /* Check transfer complete flag. */
1629     else if (status & kI2C_TransferCompleteFlag)
1630     {
1631         /* Slave transmit, master reading from slave. */
1632         if (status & kI2C_TransferDirectionFlag)
1633         {
1634             doTransmit = true;
1635         }
1636         else
1637         {
1638             /* If we're out of data, invoke callback to get more. */
1639             if ((!xfer->data) || (!xfer->dataSize))
1640             {
1641                 xfer->event = kI2C_SlaveReceiveEvent;
1642 
1643                 if (handle->callback)
1644                 {
1645                     handle->callback(base, xfer, handle->userData);
1646                 }
1647 
1648                 /* Clear the transferred count now that we have a new buffer. */
1649                 xfer->transferredCount = 0;
1650             }
1651 
1652             /* Slave receive, master writing to slave. */
1653             uint8_t data = base->D;
1654 
1655             if (handle->transfer.dataSize)
1656             {
1657                 /* Receive data. */
1658                 *handle->transfer.data++ = data;
1659                 handle->transfer.dataSize--;
1660                 xfer->transferredCount++;
1661                 if (!handle->transfer.dataSize)
1662                 {
1663 #ifndef I2C_HAS_STOP_DETECT
1664                     xfer->event = kI2C_SlaveCompletionEvent;
1665                     xfer->completionStatus = kStatus_Success;
1666                     handle->isBusy = false;
1667 
1668                     /* Proceed receive complete event. */
1669                     if ((handle->eventMask & xfer->event) && (handle->callback))
1670                     {
1671                         handle->callback(base, xfer, handle->userData);
1672                     }
1673 #endif /* !FSL_FEATURE_I2C_HAS_START_STOP_DETECT or !FSL_FEATURE_I2C_HAS_STOP_DETECT */
1674                 }
1675             }
1676         }
1677     }
1678     else
1679     {
1680         /* Read dummy to release bus. */
1681         dummy = base->D;
1682     }
1683 
1684     /* Send data if there is the need. */
1685     if (doTransmit)
1686     {
1687         /* If we're out of data, invoke callback to get more. */
1688         if ((!xfer->data) || (!xfer->dataSize))
1689         {
1690             xfer->event = kI2C_SlaveTransmitEvent;
1691 
1692             if (handle->callback)
1693             {
1694                 handle->callback(base, xfer, handle->userData);
1695             }
1696 
1697             /* Clear the transferred count now that we have a new buffer. */
1698             xfer->transferredCount = 0;
1699         }
1700 
1701         if (handle->transfer.dataSize)
1702         {
1703             /* Send data. */
1704             base->D = *handle->transfer.data++;
1705             handle->transfer.dataSize--;
1706             xfer->transferredCount++;
1707         }
1708         else
1709         {
1710             /* Switch to receive mode. */
1711             base->C1 &= ~(I2C_C1_TX_MASK | I2C_C1_TXAK_MASK);
1712 
1713             /* Read dummy to release bus. */
1714             dummy = base->D;
1715 
1716 #ifndef I2C_HAS_STOP_DETECT
1717             xfer->event = kI2C_SlaveCompletionEvent;
1718             xfer->completionStatus = kStatus_Success;
1719             handle->isBusy = false;
1720 
1721             /* Proceed txdone event. */
1722             if ((handle->eventMask & xfer->event) && (handle->callback))
1723             {
1724                 handle->callback(base, xfer, handle->userData);
1725             }
1726 #endif /* !FSL_FEATURE_I2C_HAS_START_STOP_DETECT or !FSL_FEATURE_I2C_HAS_STOP_DETECT */
1727         }
1728     }
1729 }
1730 
1731 #if defined(I2C0)
I2C0_DriverIRQHandler(void)1732 void I2C0_DriverIRQHandler(void)
1733 {
1734     I2C_TransferCommonIRQHandler(I2C0, s_i2cHandle[0]);
1735 }
1736 #endif
1737 
1738 #if defined(I2C1)
I2C1_DriverIRQHandler(void)1739 void I2C1_DriverIRQHandler(void)
1740 {
1741     I2C_TransferCommonIRQHandler(I2C1, s_i2cHandle[1]);
1742 }
1743 #endif
1744 
1745 #if defined(I2C2)
I2C2_DriverIRQHandler(void)1746 void I2C2_DriverIRQHandler(void)
1747 {
1748     I2C_TransferCommonIRQHandler(I2C2, s_i2cHandle[2]);
1749 }
1750 #endif
1751 
1752 #if defined(I2C3)
I2C3_DriverIRQHandler(void)1753 void I2C3_DriverIRQHandler(void)
1754 {
1755     I2C_TransferCommonIRQHandler(I2C3, s_i2cHandle[3]);
1756 }
1757 #endif
1758