1 /*
2  * Copyright (c) 2016, Freescale Semiconductor, Inc.
3  * Copyright 2016-2019 NXP
4  * All rights reserved.
5  *
6  * SPDX-License-Identifier: BSD-3-Clause
7  */
8 
9 #include "fsl_i2c.h"
10 #include <stdlib.h>
11 #include <string.h>
12 
13 /*******************************************************************************
14  * Definitions
15  ******************************************************************************/
16 
17 /* Component ID definition, used by tools. */
18 #ifndef FSL_COMPONENT_ID
19 #define FSL_COMPONENT_ID "platform.drivers.lpc_i2c"
20 #endif
21 
22 /*! @brief Common sets of flags used by the driver. */
23 enum _i2c_flag_constants
24 {
25     kI2C_MasterIrqFlags = I2C_INTSTAT_MSTPENDING_MASK | I2C_INTSTAT_MSTARBLOSS_MASK | I2C_INTSTAT_MSTSTSTPERR_MASK,
26     kI2C_SlaveIrqFlags  = I2C_INTSTAT_SLVPENDING_MASK | I2C_INTSTAT_SLVDESEL_MASK,
27 };
28 
29 /*******************************************************************************
30  * Prototypes
31  ******************************************************************************/
32 #if defined(FSL_SDK_ENABLE_I2C_DRIVER_TRANSACTIONAL_APIS) && (FSL_SDK_ENABLE_I2C_DRIVER_TRANSACTIONAL_APIS)
33 static status_t I2C_InitTransferStateMachine(I2C_Type *base, i2c_master_handle_t *handle, i2c_master_transfer_t *xfer);
34 static void I2C_SlaveInvokeEvent(I2C_Type *base, i2c_slave_handle_t *handle, i2c_slave_transfer_event_t event);
35 static bool I2C_SlaveAddressIRQ(I2C_Type *base, i2c_slave_handle_t *handle);
36 static status_t I2C_SlaveTransferNonBlockingInternal(I2C_Type *base,
37                                                      i2c_slave_handle_t *handle,
38                                                      const void *txData,
39                                                      size_t txSize,
40                                                      void *rxData,
41                                                      size_t rxSize,
42                                                      uint32_t eventMask);
43 #endif /* FSL_SDK_ENABLE_I2C_DRIVER_TRANSACTIONAL_APIS */
44 
45 static void I2C_SlaveInternalStateMachineReset(I2C_Type *base);
46 static status_t I2C_SlaveDivVal(uint32_t srcClock_Hz, i2c_slave_bus_speed_t busSpeed, uint32_t *divVal);
47 static uint32_t I2C_SlavePollPending(I2C_Type *base);
48 
49 /*******************************************************************************
50  * Variables
51  ******************************************************************************/
52 
53 /*! @brief Array to map i2c instance number to base address. */
54 static I2C_Type *const s_i2cBases[] = I2C_BASE_PTRS;
55 
56 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
57 /*! @brief Pointers to i2c clocks for each instance. */
58 static const clock_ip_name_t s_i2cClocks[] = I2C_CLOCKS;
59 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
60 
61 #if !(defined(FSL_FEATURE_I2C_HAS_NO_RESET) && FSL_FEATURE_I2C_HAS_NO_RESET)
62 static const reset_ip_name_t s_i2cResets[] = I2C_RSTS_N;
63 #endif
64 
65 #if defined(FSL_SDK_ENABLE_I2C_DRIVER_TRANSACTIONAL_APIS) && (FSL_SDK_ENABLE_I2C_DRIVER_TRANSACTIONAL_APIS)
66 /*! @brief Pointers to i2c handles for each instance. */
67 static void *s_i2cHandle[FSL_FEATURE_SOC_I2C_COUNT];
68 
69 /*! @brief IRQ name array */
70 static IRQn_Type const s_i2cIRQ[] = I2C_IRQS;
71 
72 /*! @brief Pointer to master IRQ handler for each instance. */
73 static i2c_isr_t s_i2cMasterIsr;
74 
75 /*! @brief Pointer to slave IRQ handler for each instance. */
76 static i2c_isr_t s_i2cSlaveIsr;
77 #endif /* FSL_SDK_ENABLE_I2C_DRIVER_TRANSACTIONAL_APIS */
78 
79 /*******************************************************************************
80  * Code
81  ******************************************************************************/
82 
83 /*!
84  * @brief Returns an instance number given a base address.
85  *
86  * If an invalid base address is passed, debug builds will assert. Release builds will just return
87  * instance number 0.
88  *
89  * @param base The I2C peripheral base address.
90  * @return I2C instance number starting from 0.
91  */
92 /*!
93  * brief Returns an instance number given a base address.
94  *
95  * If an invalid base address is passed, debug builds will assert. Release builds will just return
96  * instance number 0.
97  *
98  * param base The I2C peripheral base address.
99  * return I2C instance number starting from 0.
100  */
I2C_GetInstance(I2C_Type * base)101 uint32_t I2C_GetInstance(I2C_Type *base)
102 {
103     uint32_t instance;
104 
105     /* Find the instance index from base address mappings. */
106     for (instance = 0U; instance < ARRAY_SIZE(s_i2cBases); instance++)
107     {
108         if (s_i2cBases[instance] == base)
109         {
110             break;
111         }
112     }
113 
114     assert(instance < ARRAY_SIZE(s_i2cBases));
115 
116     return instance;
117 }
118 
119 /*!
120  * brief Provides a default configuration for the I2C master peripheral.
121  *
122  * This function provides the following default configuration for the I2C master peripheral:
123  * code
124  *  masterConfig->enableMaster            = true;
125  *  masterConfig->baudRate_Bps            = 100000U;
126  *  masterConfig->enableTimeout           = false;
127  * endcode
128  *
129  * After calling this function, you can override any settings in order to customize the configuration,
130  * prior to initializing the master driver with I2C_MasterInit().
131  *
132  * param[out] masterConfig User provided configuration structure for default values. Refer to #i2c_master_config_t.
133  */
I2C_MasterGetDefaultConfig(i2c_master_config_t * masterConfig)134 void I2C_MasterGetDefaultConfig(i2c_master_config_t *masterConfig)
135 {
136     /* Initializes the configure structure to zero. */
137     (void)memset(masterConfig, 0, sizeof(*masterConfig));
138 
139     masterConfig->enableMaster  = true;
140     masterConfig->baudRate_Bps  = 100000U;
141     masterConfig->enableTimeout = false;
142 }
143 
144 /*!
145  * brief Initializes the I2C master peripheral.
146  *
147  * This function enables the peripheral clock and initializes the I2C master peripheral as described by the user
148  * provided configuration. A software reset is performed prior to configuration.
149  *
150  * param base The I2C peripheral base address.
151  * param masterConfig User provided peripheral configuration. Use I2C_MasterGetDefaultConfig() to get a set of
152  * defaults
153  *      that you can override.
154  * param srcClock_Hz Frequency in Hertz of the I2C functional clock. Used to calculate the baud rate divisors,
155  *      filter widths, and timeout periods.
156  */
I2C_MasterInit(I2C_Type * base,const i2c_master_config_t * masterConfig,uint32_t srcClock_Hz)157 void I2C_MasterInit(I2C_Type *base, const i2c_master_config_t *masterConfig, uint32_t srcClock_Hz)
158 {
159 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
160     /* Enable the clock. */
161     CLOCK_EnableClock(s_i2cClocks[I2C_GetInstance(base)]);
162 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
163 
164 #if !(defined(FSL_FEATURE_I2C_HAS_NO_RESET) && FSL_FEATURE_I2C_HAS_NO_RESET)
165     RESET_PeripheralReset(s_i2cResets[I2C_GetInstance(base)]);
166 #endif
167 
168     I2C_MasterEnable(base, masterConfig->enableMaster);
169     I2C_MasterSetBaudRate(base, masterConfig->baudRate_Bps, srcClock_Hz);
170 }
171 
172 /*!
173  * brief Deinitializes the I2C master peripheral.
174  *
175  * This function disables the I2C master peripheral and gates the clock. It also performs a software
176  * reset to restore the peripheral to reset conditions.
177  *
178  * param base The I2C peripheral base address.
179  */
I2C_MasterDeinit(I2C_Type * base)180 void I2C_MasterDeinit(I2C_Type *base)
181 {
182     I2C_MasterEnable(base, false);
183 
184 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
185     /* Disable the clock. */
186     CLOCK_DisableClock(s_i2cClocks[I2C_GetInstance(base)]);
187 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
188 }
189 
190 /*!
191  * brief Sets the I2C bus frequency for master transactions.
192  *
193  * The I2C master is automatically disabled and re-enabled as necessary to configure the baud
194  * rate. Do not call this function during a transfer, or the transfer is aborted.
195  *
196  * param base The I2C peripheral base address.
197  * param srcClock_Hz I2C functional clock frequency in Hertz.
198  * param baudRate_Bps Requested bus frequency in bits per second.
199  */
I2C_MasterSetBaudRate(I2C_Type * base,uint32_t baudRate_Bps,uint32_t srcClock_Hz)200 void I2C_MasterSetBaudRate(I2C_Type *base, uint32_t baudRate_Bps, uint32_t srcClock_Hz)
201 {
202     uint32_t scl, divider;
203     uint32_t best_scl = 0;
204     uint32_t best_div = 0;
205     uint32_t err, best_err;
206 
207     best_err = 0U;
208 
209     for (scl = 9U; scl >= 2U; scl--)
210     {
211         /* calculated ideal divider value for given scl, round up the result */
212         divider = ((srcClock_Hz * 10U) / (baudRate_Bps * scl * 2U) + 5U) / 10U;
213 
214         /* adjust it if it is out of range */
215         divider = ((divider > 0x10000U) ? 0x10000U : divider);
216 
217         /* calculate error */
218         err = srcClock_Hz - (baudRate_Bps * scl * 2U * divider);
219         if ((err < best_err) || (best_err == 0U))
220         {
221             best_div = divider;
222             best_scl = scl;
223             best_err = err;
224         }
225 
226         if ((err == 0U) || (divider >= 0x10000U))
227         {
228             /* either exact value was found
229                or divider is at its max (it would even greater in the next iteration for sure) */
230             break;
231         }
232     }
233 
234     base->CLKDIV  = I2C_CLKDIV_DIVVAL(best_div - 1U);
235     base->MSTTIME = I2C_MSTTIME_MSTSCLLOW(best_scl - 2U) | I2C_MSTTIME_MSTSCLHIGH(best_scl - 2U);
236 }
237 
I2C_PendingStatusWait(I2C_Type * base)238 static uint32_t I2C_PendingStatusWait(I2C_Type *base)
239 {
240     uint32_t status;
241 
242 #if I2C_RETRY_TIMES
243     uint32_t waitTimes = I2C_RETRY_TIMES;
244 #endif
245 
246     do
247     {
248         status = I2C_GetStatusFlags(base);
249 #if I2C_RETRY_TIMES
250     } while (((status & I2C_STAT_MSTPENDING_MASK) == 0) && (0U != --waitTimes));
251 
252     if (0U == waitTimes)
253     {
254         return (uint32_t)kStatus_I2C_Timeout;
255     }
256 #else
257     } while ((status & I2C_STAT_MSTPENDING_MASK) == 0U);
258 #endif
259 
260     /* Clear controller state. */
261     I2C_MasterClearStatusFlags(base, I2C_STAT_MSTARBLOSS_MASK | I2C_STAT_MSTSTSTPERR_MASK);
262 
263     return status;
264 }
265 
266 /*!
267  * brief Sends a START on the I2C bus.
268  *
269  * This function is used to initiate a new master mode transfer by sending the START signal.
270  * The slave address is sent following the I2C START signal.
271  *
272  * param base I2C peripheral base pointer
273  * param address 7-bit slave device address.
274  * param direction Master transfer directions(transmit/receive).
275  * retval kStatus_Success Successfully send the start signal.
276  * retval kStatus_I2C_Busy Current bus is busy.
277  */
I2C_MasterStart(I2C_Type * base,uint8_t address,i2c_direction_t direction)278 status_t I2C_MasterStart(I2C_Type *base, uint8_t address, i2c_direction_t direction)
279 {
280     if (I2C_PendingStatusWait(base) == (uint32_t)kStatus_I2C_Timeout)
281     {
282         return kStatus_I2C_Timeout;
283     }
284 
285     /* Write Address and RW bit to data register */
286     base->MSTDAT = ((uint32_t)address << 1) | ((uint32_t)direction & 1u);
287     /* Start the transfer */
288     base->MSTCTL = I2C_MSTCTL_MSTSTART_MASK;
289 
290     return kStatus_Success;
291 }
292 
293 /*!
294  * brief Sends a STOP signal on the I2C bus.
295  *
296  * retval kStatus_Success Successfully send the stop signal.
297  * retval kStatus_I2C_Timeout Send stop signal failed, timeout.
298  */
I2C_MasterStop(I2C_Type * base)299 status_t I2C_MasterStop(I2C_Type *base)
300 {
301     if (I2C_PendingStatusWait(base) == (uint32_t)kStatus_I2C_Timeout)
302     {
303         return kStatus_I2C_Timeout;
304     }
305 
306     base->MSTCTL = I2C_MSTCTL_MSTSTOP_MASK;
307     return kStatus_Success;
308 }
309 
310 /*!
311  * brief Performs a polling send transfer on the I2C bus.
312  *
313  * Sends up to a txSize number of bytes to the previously addressed slave device. The slave may
314  * reply with a NAK to any byte in order to terminate the transfer early. If this happens, this
315  * function returns #kStatus_I2C_Nak.
316  *
317  * param base  The I2C peripheral base address.
318  * param txBuff The pointer to the data to be transferred.
319  * param txSize The length in bytes of the data to be transferred.
320  * param flags Transfer control flag to control special behavior like suppressing start or stop, for normal transfers
321  * use kI2C_TransferDefaultFlag
322  * retval kStatus_Success Data was sent successfully.
323  * retval #kStatus_I2C_Busy Another master is currently utilizing the bus.
324  * retval #kStatus_I2C_Nak The slave device sent a NAK in response to a byte.
325  * retval #kStatus_I2C_ArbitrationLost Arbitration lost error.
326  */
I2C_MasterWriteBlocking(I2C_Type * base,const void * txBuff,size_t txSize,uint32_t flags)327 status_t I2C_MasterWriteBlocking(I2C_Type *base, const void *txBuff, size_t txSize, uint32_t flags)
328 {
329     assert(txBuff != NULL);
330 
331     uint32_t status;
332     uint32_t master_state;
333     status_t err;
334 
335     const uint8_t *buf = (const uint8_t *)txBuff;
336 
337     err = kStatus_Success;
338     while (txSize != 0U)
339     {
340         status = I2C_PendingStatusWait(base);
341 
342 #if I2C_RETRY_TIMES
343         if (status == kStatus_I2C_Timeout)
344         {
345             return kStatus_I2C_Timeout;
346         }
347 #endif
348 
349         if ((status & I2C_STAT_MSTARBLOSS_MASK) != 0U)
350         {
351             return kStatus_I2C_ArbitrationLost;
352         }
353 
354         if ((status & I2C_STAT_MSTSTSTPERR_MASK) != 0U)
355         {
356             return kStatus_I2C_StartStopError;
357         }
358 
359         master_state = (status & I2C_STAT_MSTSTATE_MASK) >> I2C_STAT_MSTSTATE_SHIFT;
360         switch (master_state)
361         {
362             case I2C_STAT_MSTCODE_TXREADY:
363                 /* ready to send next byte */
364                 base->MSTDAT = *buf++;
365                 txSize--;
366                 base->MSTCTL = I2C_MSTCTL_MSTCONTINUE_MASK;
367                 break;
368 
369             case I2C_STAT_MSTCODE_NACKADR:
370                 /* slave nacked the address */
371                 err = kStatus_I2C_Addr_Nak;
372                 break;
373 
374             case I2C_STAT_MSTCODE_NACKDAT:
375                 /* slave nacked the last byte */
376                 err = kStatus_I2C_Nak;
377                 break;
378 
379             default:
380                 /* unexpected state */
381                 err = kStatus_I2C_UnexpectedState;
382                 break;
383         }
384 
385         if (err != kStatus_Success)
386         {
387             return err;
388         }
389     }
390 
391     status = I2C_PendingStatusWait(base);
392 
393 #if I2C_RETRY_TIMES
394     if (status == kStatus_I2C_Timeout)
395     {
396         return kStatus_I2C_Timeout;
397     }
398 #endif
399 
400     if ((status & (I2C_STAT_MSTARBLOSS_MASK | I2C_STAT_MSTSTSTPERR_MASK)) == 0U)
401     {
402         if ((flags & (uint32_t)kI2C_TransferNoStopFlag) == 0U)
403         {
404             /* Initiate stop */
405             base->MSTCTL = I2C_MSTCTL_MSTSTOP_MASK;
406             status       = I2C_PendingStatusWait(base);
407 
408 #if I2C_RETRY_TIMES
409             if (status == kStatus_I2C_Timeout)
410             {
411                 return kStatus_I2C_Timeout;
412             }
413 #endif
414         }
415     }
416 
417     if ((status & I2C_STAT_MSTARBLOSS_MASK) != 0U)
418     {
419         return kStatus_I2C_ArbitrationLost;
420     }
421 
422     if ((status & I2C_STAT_MSTSTSTPERR_MASK) != 0U)
423     {
424         return kStatus_I2C_StartStopError;
425     }
426 
427     return kStatus_Success;
428 }
429 
430 /*!
431  * brief Performs a polling receive transfer on the I2C bus.
432  *
433  * param base  The I2C peripheral base address.
434  * param rxBuff The pointer to the data to be transferred.
435  * param rxSize The length in bytes of the data to be transferred.
436  * param flags Transfer control flag to control special behavior like suppressing start or stop, for normal transfers
437  * use kI2C_TransferDefaultFlag
438  * retval kStatus_Success Data was received successfully.
439  * retval #kStatus_I2C_Busy Another master is currently utilizing the bus.
440  * retval #kStatus_I2C_Nak The slave device sent a NAK in response to a byte.
441  * retval #kStatus_I2C_ArbitrationLost Arbitration lost error.
442  */
I2C_MasterReadBlocking(I2C_Type * base,void * rxBuff,size_t rxSize,uint32_t flags)443 status_t I2C_MasterReadBlocking(I2C_Type *base, void *rxBuff, size_t rxSize, uint32_t flags)
444 {
445     assert(rxBuff != NULL);
446 
447     uint32_t status = 0;
448     uint32_t master_state;
449     status_t err;
450 
451     uint8_t *buf = (uint8_t *)(rxBuff);
452 
453     err = kStatus_Success;
454     while (rxSize != 0U)
455     {
456         status = I2C_PendingStatusWait(base);
457 
458 #if I2C_RETRY_TIMES
459         if (status == kStatus_I2C_Timeout)
460         {
461             return kStatus_I2C_Timeout;
462         }
463 #endif
464 
465         if ((status & (I2C_STAT_MSTARBLOSS_MASK | I2C_STAT_MSTSTSTPERR_MASK)) != 0U)
466         {
467             break;
468         }
469 
470         master_state = (status & I2C_STAT_MSTSTATE_MASK) >> I2C_STAT_MSTSTATE_SHIFT;
471         switch (master_state)
472         {
473             case I2C_STAT_MSTCODE_RXREADY:
474                 /* ready to receive next byte */
475                 *(buf++) = (uint8_t)base->MSTDAT;
476                 if (--rxSize != 0U)
477                 {
478                     base->MSTCTL = I2C_MSTCTL_MSTCONTINUE_MASK;
479                 }
480                 else
481                 {
482                     if ((flags & (uint32_t)kI2C_TransferNoStopFlag) == 0U)
483                     {
484                         /* initiate NAK and stop */
485                         base->MSTCTL = I2C_MSTCTL_MSTSTOP_MASK;
486                         status       = I2C_PendingStatusWait(base);
487 #if I2C_RETRY_TIMES
488                         if (status == kStatus_I2C_Timeout)
489                         {
490                             return kStatus_I2C_Timeout;
491                         }
492 #endif
493                     }
494                 }
495                 break;
496 
497             case I2C_STAT_MSTCODE_NACKADR:
498             case I2C_STAT_MSTCODE_NACKDAT:
499                 /* slave nacked the last byte */
500                 err = kStatus_I2C_Nak;
501                 break;
502 
503             default:
504                 /* unexpected state */
505                 err = kStatus_I2C_UnexpectedState;
506                 break;
507         }
508 
509         if (err != kStatus_Success)
510         {
511             return err;
512         }
513     }
514 
515     if ((status & I2C_STAT_MSTARBLOSS_MASK) != 0U)
516     {
517         return kStatus_I2C_ArbitrationLost;
518     }
519 
520     if ((status & I2C_STAT_MSTSTSTPERR_MASK) != 0U)
521     {
522         return kStatus_I2C_StartStopError;
523     }
524 
525     return kStatus_Success;
526 }
527 
528 /*!
529  * brief Performs a master polling transfer on the I2C bus.
530  *
531  * note The API does not return until the transfer succeeds or fails due
532  * to arbitration lost or receiving a NAK.
533  *
534  * param base I2C peripheral base address.
535  * param xfer Pointer to the transfer structure.
536  * retval kStatus_Success Successfully complete the data transmission.
537  * retval kStatus_I2C_Busy Previous transmission still not finished.
538  * retval kStatus_I2C_Timeout Transfer error, wait signal timeout.
539  * retval kStatus_I2C_ArbitrationLost Transfer error, arbitration lost.
540  * retval kStataus_I2C_Nak Transfer error, receive NAK during transfer.
541  */
I2C_MasterTransferBlocking(I2C_Type * base,i2c_master_transfer_t * xfer)542 status_t I2C_MasterTransferBlocking(I2C_Type *base, i2c_master_transfer_t *xfer)
543 {
544     status_t result = kStatus_Success;
545     uint32_t subaddress;
546     uint8_t subaddrBuf[4];
547     int i;
548 
549     assert(xfer != NULL);
550 
551     /* If repeated start is requested, send repeated start. */
552     if ((xfer->flags & (uint32_t)kI2C_TransferNoStartFlag) == 0U)
553     {
554         if (xfer->subaddressSize != 0U)
555         {
556             result = I2C_MasterStart(base, (uint8_t)xfer->slaveAddress, kI2C_Write);
557             if (result == kStatus_Success)
558             {
559                 /* Prepare subaddress transmit buffer, most significant byte is stored at the lowest address */
560                 subaddress = xfer->subaddress;
561                 for (i = (int)xfer->subaddressSize - 1; i >= 0; i--)
562                 {
563                     subaddrBuf[i] = (uint8_t)subaddress & 0xffU;
564                     subaddress >>= 8;
565                 }
566                 /* Send subaddress. */
567                 result =
568                     I2C_MasterWriteBlocking(base, subaddrBuf, xfer->subaddressSize, (uint32_t)kI2C_TransferNoStopFlag);
569                 if ((result == kStatus_Success) && (xfer->direction == kI2C_Read))
570                 {
571                     result = I2C_MasterRepeatedStart(base, (uint8_t)xfer->slaveAddress, xfer->direction);
572                 }
573             }
574         }
575         else if ((xfer->flags & (uint32_t)kI2C_TransferRepeatedStartFlag) != 0U)
576         {
577             result = I2C_MasterRepeatedStart(base, (uint8_t)xfer->slaveAddress, xfer->direction);
578         }
579         else
580         {
581             result = I2C_MasterStart(base, (uint8_t)xfer->slaveAddress, xfer->direction);
582         }
583     }
584 
585     if (result == kStatus_Success)
586     {
587         if ((xfer->direction == kI2C_Write) && (xfer->dataSize > 0U))
588         {
589             /* Transmit data. */
590             result = I2C_MasterWriteBlocking(base, xfer->data, xfer->dataSize, xfer->flags);
591         }
592         else
593         {
594             if ((xfer->direction == kI2C_Read) && (xfer->dataSize > 0U))
595             {
596                 /* Receive Data. */
597                 result = I2C_MasterReadBlocking(base, xfer->data, xfer->dataSize, xfer->flags);
598             }
599         }
600     }
601 
602     if (result == kStatus_I2C_Nak)
603     {
604         (void)I2C_MasterStop(base);
605     }
606 
607     return result;
608 }
609 
610 #if defined(FSL_SDK_ENABLE_I2C_DRIVER_TRANSACTIONAL_APIS) && (FSL_SDK_ENABLE_I2C_DRIVER_TRANSACTIONAL_APIS)
611 /*!
612  * brief Creates a new handle for the I2C master non-blocking APIs.
613  *
614  * The creation of a handle is for use with the non-blocking APIs. Once a handle
615  * is created, there is not a corresponding destroy handle. If the user wants to
616  * terminate a transfer, the I2C_MasterTransferAbort() API shall be called.
617  *
618  * param base The I2C peripheral base address.
619  * param[out] handle Pointer to the I2C master driver handle.
620  * param callback User provided pointer to the asynchronous callback function.
621  * param userData User provided pointer to the application callback data.
622  */
I2C_MasterTransferCreateHandle(I2C_Type * base,i2c_master_handle_t * handle,i2c_master_transfer_callback_t callback,void * userData)623 void I2C_MasterTransferCreateHandle(I2C_Type *base,
624                                     i2c_master_handle_t *handle,
625                                     i2c_master_transfer_callback_t callback,
626                                     void *userData)
627 {
628     uint32_t instance;
629 
630     assert(handle != NULL);
631 
632     /* Clear out the handle. */
633     (void)memset(handle, 0, sizeof(*handle));
634 
635     /* Look up instance number */
636     instance = I2C_GetInstance(base);
637 
638     /* Save base and instance. */
639     handle->completionCallback = callback;
640     handle->userData           = userData;
641 
642     /* Save the context in global variables to support the double weak mechanism. */
643     s_i2cHandle[instance] = handle;
644 
645     /* Save master interrupt handler. */
646     s_i2cMasterIsr = I2C_MasterTransferHandleIRQ;
647 
648     /* Clear internal IRQ enables and enable NVIC IRQ. */
649     I2C_DisableInterrupts(base, (uint32_t)kI2C_MasterIrqFlags);
650     (void)EnableIRQ(s_i2cIRQ[instance]);
651 }
652 
653 /*!
654  * brief Performs a non-blocking transaction on the I2C bus.
655  *
656  * param base The I2C peripheral base address.
657  * param handle Pointer to the I2C master driver handle.
658  * param xfer The pointer to the transfer descriptor.
659  * retval kStatus_Success The transaction was started successfully.
660  * retval #kStatus_I2C_Busy Either another master is currently utilizing the bus, or a non-blocking
661  *      transaction is already in progress.
662  */
I2C_MasterTransferNonBlocking(I2C_Type * base,i2c_master_handle_t * handle,i2c_master_transfer_t * xfer)663 status_t I2C_MasterTransferNonBlocking(I2C_Type *base, i2c_master_handle_t *handle, i2c_master_transfer_t *xfer)
664 {
665     status_t result;
666 
667     assert(handle != NULL);
668     assert(xfer != NULL);
669     assert(xfer->subaddressSize <= sizeof(xfer->subaddress));
670 
671     /* Return busy if another transaction is in progress. */
672     if (handle->state != (uint8_t)kIdleState)
673     {
674         return kStatus_I2C_Busy;
675     }
676 
677     /* Disable I2C IRQ sources while we configure stuff. */
678     I2C_DisableInterrupts(base, (uint32_t)kI2C_MasterIrqFlags);
679 
680     /* Prepare transfer state machine. */
681     result = I2C_InitTransferStateMachine(base, handle, xfer);
682 
683     /* Clear error flags. */
684     I2C_MasterClearStatusFlags(base, I2C_STAT_MSTARBLOSS_MASK | I2C_STAT_MSTSTSTPERR_MASK);
685 
686     /* Enable I2C internal IRQ sources. */
687     I2C_EnableInterrupts(base, (uint32_t)kI2C_MasterIrqFlags);
688 
689     return result;
690 }
691 
692 /*!
693  * brief Returns number of bytes transferred so far.
694  * param base The I2C peripheral base address.
695  * param handle Pointer to the I2C master driver handle.
696  * param[out] count Number of bytes transferred so far by the non-blocking transaction.
697  * retval kStatus_Success
698  * retval #kStatus_I2C_Busy
699  */
I2C_MasterTransferGetCount(I2C_Type * base,i2c_master_handle_t * handle,size_t * count)700 status_t I2C_MasterTransferGetCount(I2C_Type *base, i2c_master_handle_t *handle, size_t *count)
701 {
702     assert(handle != NULL);
703 
704     if (count == NULL)
705     {
706         return kStatus_InvalidArgument;
707     }
708 
709     /* Catch when there is not an active transfer. */
710     if (handle->state == (uint8_t)kIdleState)
711     {
712         *count = 0;
713         return kStatus_NoTransferInProgress;
714     }
715 
716     /* There is no necessity to disable interrupts as we read a single integer value */
717     *count = handle->transferCount;
718     return kStatus_Success;
719 }
720 
721 /*!
722  * brief Terminates a non-blocking I2C master transmission early.
723  *
724  * note It is not safe to call this function from an IRQ handler that has a higher priority than the
725  *      I2C peripheral's IRQ priority.
726  *
727  * param base The I2C peripheral base address.
728  * param handle Pointer to the I2C master driver handle.
729  * retval kStatus_Success A transaction was successfully aborted.
730  * retval #kStatus_I2C_Timeout Abort failure due to flags polling timeout.
731  */
I2C_MasterTransferAbort(I2C_Type * base,i2c_master_handle_t * handle)732 status_t I2C_MasterTransferAbort(I2C_Type *base, i2c_master_handle_t *handle)
733 {
734     uint32_t status;
735     uint32_t master_state;
736 
737     if (handle->state != (uint8_t)kIdleState)
738     {
739         /* Disable internal IRQ enables. */
740         I2C_DisableInterrupts(base, (uint32_t)kI2C_MasterIrqFlags);
741 
742         /* Wait until module is ready */
743         status = I2C_PendingStatusWait(base);
744 
745 #if I2C_RETRY_TIMES
746         if (status == kStatus_I2C_Timeout)
747         {
748             handle->state = kIdleState;
749             return kStatus_I2C_Timeout;
750         }
751 #endif
752 
753         /* Get the state of the I2C module */
754         master_state = (status & I2C_STAT_MSTSTATE_MASK) >> I2C_STAT_MSTSTATE_SHIFT;
755 
756         if (master_state != (uint32_t)I2C_STAT_MSTCODE_IDLE)
757         {
758             /* Send a stop command to finalize the transfer. */
759             base->MSTCTL = I2C_MSTCTL_MSTSTOP_MASK;
760 
761             /* Wait until the STOP is completed */
762             (void)I2C_PendingStatusWait(base);
763 
764 #if I2C_RETRY_TIMES
765             if (status == kStatus_I2C_Timeout)
766             {
767                 return kStatus_I2C_Timeout;
768             }
769 #endif
770         }
771 
772         /* Reset handle. */
773         handle->state = (uint8_t)kIdleState;
774     }
775 
776     return kStatus_Success;
777 }
778 
779 /*!
780  * @brief Prepares the transfer state machine and fills in the command buffer.
781  * @param handle Master nonblocking driver handle.
782  */
I2C_InitTransferStateMachine(I2C_Type * base,i2c_master_handle_t * handle,i2c_master_transfer_t * xfer)783 static status_t I2C_InitTransferStateMachine(I2C_Type *base, i2c_master_handle_t *handle, i2c_master_transfer_t *xfer)
784 {
785     struct _i2c_master_transfer *transfer;
786 
787     handle->transfer = *xfer;
788     transfer         = &(handle->transfer);
789 
790     handle->transferCount    = 0;
791     handle->remainingBytes   = transfer->dataSize;
792     handle->buf              = (uint8_t *)transfer->data;
793     handle->remainingSubaddr = 0;
794 
795     if ((transfer->flags & (uint32_t)kI2C_TransferNoStartFlag) != 0U)
796     {
797         /* Start condition shall be ommited, switch directly to next phase */
798         if (transfer->dataSize == 0U)
799         {
800             handle->state = (uint8_t)kStopState;
801         }
802         else if (handle->transfer.direction == kI2C_Write)
803         {
804             handle->state = (uint8_t)kTransmitDataState;
805         }
806         else if (handle->transfer.direction == kI2C_Read)
807         {
808             handle->state = (uint8_t)kReceiveDataBeginState;
809         }
810         else
811         {
812             return kStatus_I2C_InvalidParameter;
813         }
814     }
815     else
816     {
817         if (transfer->subaddressSize != 0U)
818         {
819             int i;
820             uint32_t subaddress;
821 
822             if (transfer->subaddressSize > sizeof(handle->subaddrBuf))
823             {
824                 return kStatus_I2C_InvalidParameter;
825             }
826 
827             /* Prepare subaddress transmit buffer, most significant byte is stored at the lowest address */
828             subaddress = xfer->subaddress;
829             for (i = (int)xfer->subaddressSize - 1; i >= 0; i--)
830             {
831                 handle->subaddrBuf[i] = (uint8_t)subaddress & 0xffU;
832                 subaddress >>= 8;
833             }
834             handle->remainingSubaddr = transfer->subaddressSize;
835         }
836         handle->state = (uint8_t)kStartState;
837     }
838 
839     return kStatus_Success;
840 }
841 
842 /*!
843  * @brief Execute states until FIFOs are exhausted.
844  * @param handle Master nonblocking driver handle.
845  * @param[out] isDone Set to true if the transfer has completed.
846  * @retval #kStatus_Success
847  * @retval #kStatus_I2C_ArbitrationLost
848  * @retval #kStatus_I2C_Nak
849  */
I2C_RunTransferStateMachine(I2C_Type * base,i2c_master_handle_t * handle,bool * isDone)850 static status_t I2C_RunTransferStateMachine(I2C_Type *base, i2c_master_handle_t *handle, bool *isDone)
851 {
852     uint32_t status;
853     uint32_t master_state;
854     struct _i2c_master_transfer *transfer;
855     status_t err;
856 
857     transfer       = &(handle->transfer);
858     bool ignoreNak = ((handle->state == (uint8_t)kStopState) && (handle->remainingBytes == 0U)) ||
859                      ((handle->state == (uint8_t)kWaitForCompletionState) && (handle->remainingBytes == 0U));
860 
861     *isDone = false;
862 
863     status = I2C_GetStatusFlags(base);
864 
865     if ((status & I2C_STAT_MSTARBLOSS_MASK) != 0U)
866     {
867         I2C_MasterClearStatusFlags(base, I2C_STAT_MSTARBLOSS_MASK);
868         return kStatus_I2C_ArbitrationLost;
869     }
870 
871     if ((status & I2C_STAT_MSTSTSTPERR_MASK) != 0U)
872     {
873         I2C_MasterClearStatusFlags(base, I2C_STAT_MSTSTSTPERR_MASK);
874         return kStatus_I2C_StartStopError;
875     }
876 
877     if ((status & I2C_STAT_MSTPENDING_MASK) == 0U)
878     {
879         return kStatus_I2C_Busy;
880     }
881 
882     /* Get the state of the I2C module */
883     master_state = (status & I2C_STAT_MSTSTATE_MASK) >> I2C_STAT_MSTSTATE_SHIFT;
884 
885     if (((master_state == (uint32_t)I2C_STAT_MSTCODE_NACKADR) ||
886          (master_state == (uint32_t)I2C_STAT_MSTCODE_NACKDAT)) &&
887         (ignoreNak != true))
888     {
889         /* Slave NACKed last byte, issue stop and return error */
890         base->MSTCTL  = I2C_MSTCTL_MSTSTOP_MASK;
891         handle->state = (uint8_t)kWaitForCompletionState;
892         return kStatus_I2C_Nak;
893     }
894 
895     err = kStatus_Success;
896     switch (handle->state)
897     {
898         case (uint8_t)kStartState:
899             if (handle->remainingSubaddr != 0U)
900             {
901                 /* Subaddress takes precedence over the data transfer, direction is always "write" in this case */
902                 base->MSTDAT  = (uint32_t)transfer->slaveAddress << 1;
903                 handle->state = (uint8_t)kTransmitSubaddrState;
904             }
905             else if (transfer->direction == kI2C_Write)
906             {
907                 base->MSTDAT  = (uint32_t)transfer->slaveAddress << 1;
908                 handle->state = (handle->remainingBytes != 0U) ? (uint8_t)kTransmitDataState : (uint8_t)kStopState;
909             }
910             else
911             {
912                 base->MSTDAT  = ((uint32_t)transfer->slaveAddress << 1) | 1u;
913                 handle->state = (handle->remainingBytes != 0U) ? (uint8_t)kReceiveDataState : (uint8_t)kStopState;
914             }
915             /* Send start condition */
916             base->MSTCTL = I2C_MSTCTL_MSTSTART_MASK;
917             break;
918 
919         case (uint8_t)kTransmitSubaddrState:
920             if (master_state != (uint32_t)I2C_STAT_MSTCODE_TXREADY)
921             {
922                 return kStatus_I2C_UnexpectedState;
923             }
924 
925             /* Most significant subaddress byte comes first */
926             base->MSTDAT = handle->subaddrBuf[handle->transfer.subaddressSize - handle->remainingSubaddr];
927             base->MSTCTL = I2C_MSTCTL_MSTCONTINUE_MASK;
928             if (--(handle->remainingSubaddr) != 0U)
929             {
930                 /* There are still subaddress bytes to be transmitted */
931                 break;
932             }
933             if (handle->remainingBytes != 0U)
934             {
935                 /* There is data to be transferred, if there is write to read turnaround it is necessary to perform
936                  * repeated start */
937                 handle->state = (transfer->direction == kI2C_Read) ? (uint8_t)kStartState : (uint8_t)kTransmitDataState;
938             }
939             else
940             {
941                 /* No more data, schedule stop condition */
942                 handle->state = (uint8_t)kStopState;
943             }
944             break;
945 
946         case (uint8_t)kTransmitDataState:
947             if (master_state != (uint32_t)I2C_STAT_MSTCODE_TXREADY)
948             {
949                 return kStatus_I2C_UnexpectedState;
950             }
951             base->MSTDAT = *(handle->buf)++;
952             base->MSTCTL = I2C_MSTCTL_MSTCONTINUE_MASK;
953             if (--handle->remainingBytes == 0U)
954             {
955                 /* No more data, schedule stop condition */
956                 handle->state = (uint8_t)kStopState;
957             }
958             handle->transferCount++;
959             break;
960 
961         case (uint8_t)kReceiveDataBeginState:
962             if (master_state != (uint32_t)I2C_STAT_MSTCODE_RXREADY)
963             {
964                 return kStatus_I2C_UnexpectedState;
965             }
966             (void)base->MSTDAT;
967             base->MSTCTL  = I2C_MSTCTL_MSTCONTINUE_MASK;
968             handle->state = (uint8_t)kReceiveDataState;
969             break;
970 
971         case (uint8_t)kReceiveDataState:
972             if (master_state != (uint32_t)I2C_STAT_MSTCODE_RXREADY)
973             {
974                 return kStatus_I2C_UnexpectedState;
975             }
976             *(handle->buf)++ = (uint8_t)base->MSTDAT;
977             if (--handle->remainingBytes != 0U)
978             {
979                 base->MSTCTL = I2C_MSTCTL_MSTCONTINUE_MASK;
980             }
981             else
982             {
983                 /* No more data expected, issue NACK and STOP right away */
984                 if ((transfer->flags & (uint32_t)kI2C_TransferNoStopFlag) == 0U)
985                 {
986                     base->MSTCTL = I2C_MSTCTL_MSTSTOP_MASK;
987                 }
988                 handle->state = (uint8_t)kWaitForCompletionState;
989             }
990             handle->transferCount++;
991             break;
992 
993         case (uint8_t)kStopState:
994             if ((transfer->flags & (uint32_t)kI2C_TransferNoStopFlag) != 0U)
995             {
996                 /* Stop condition is omitted, we are done */
997                 *isDone       = true;
998                 handle->state = (uint8_t)kIdleState;
999                 break;
1000             }
1001             /* Send stop condition */
1002             base->MSTCTL  = I2C_MSTCTL_MSTSTOP_MASK;
1003             handle->state = (uint8_t)kWaitForCompletionState;
1004             break;
1005 
1006         case (uint8_t)kWaitForCompletionState:
1007             *isDone       = true;
1008             handle->state = (uint8_t)kIdleState;
1009             break;
1010 
1011         case (uint8_t)kIdleState:
1012         default:
1013             /* State machine shall not be invoked again once it enters the idle state */
1014             err = kStatus_I2C_UnexpectedState;
1015             break;
1016     }
1017 
1018     return err;
1019 }
1020 
1021 /*!
1022  * brief Reusable routine to handle master interrupts.
1023  * note This function does not need to be called unless you are reimplementing the
1024  *  nonblocking API's interrupt handler routines to add special functionality.
1025  * param base The I2C peripheral base address.
1026  * param handle Pointer to the I2C master driver handle i2c_master_handle_t.
1027  */
I2C_MasterTransferHandleIRQ(I2C_Type * base,void * i2cHandle)1028 void I2C_MasterTransferHandleIRQ(I2C_Type *base, void *i2cHandle)
1029 {
1030     assert(i2cHandle != NULL);
1031 
1032     i2c_master_handle_t *handle = (i2c_master_handle_t *)i2cHandle;
1033     bool isDone;
1034     status_t result;
1035 
1036     result = I2C_RunTransferStateMachine(base, handle, &isDone);
1037 
1038     if ((result != kStatus_Success) || isDone)
1039     {
1040         /* Restore handle to idle state. */
1041         handle->state = (uint8_t)kIdleState;
1042 
1043         /* Disable internal IRQ enables. */
1044         I2C_DisableInterrupts(base, (uint32_t)kI2C_MasterIrqFlags);
1045 
1046         /* Invoke callback. */
1047         if (handle->completionCallback != NULL)
1048         {
1049             handle->completionCallback(base, handle, result, handle->userData);
1050         }
1051     }
1052 }
1053 #endif /* FSL_SDK_ENABLE_I2C_DRIVER_TRANSACTIONAL_APIS */
1054 
1055 /*!
1056  * @brief Sets the hardware slave state machine to reset
1057  *
1058  * Per documentation, the only the state machine is reset, the configuration settings remain.
1059  *
1060  * @param base The I2C peripheral base address.
1061  */
I2C_SlaveInternalStateMachineReset(I2C_Type * base)1062 static void I2C_SlaveInternalStateMachineReset(I2C_Type *base)
1063 {
1064     I2C_SlaveEnable(base, false); /* clear SLVEN Slave enable bit */
1065 }
1066 
1067 /*!
1068  * @brief Compute CLKDIV
1069  *
1070  * This function computes CLKDIV value according to the given bus speed and Flexcomm source clock frequency.
1071  * This setting is used by hardware during slave clock stretching.
1072  *
1073  * @param base The I2C peripheral base address.
1074  * @return status of the operation
1075  */
I2C_SlaveDivVal(uint32_t srcClock_Hz,i2c_slave_bus_speed_t busSpeed,uint32_t * divVal)1076 static status_t I2C_SlaveDivVal(uint32_t srcClock_Hz, i2c_slave_bus_speed_t busSpeed, uint32_t *divVal)
1077 {
1078     uint32_t dataSetupTime_ns;
1079 
1080     switch (busSpeed)
1081     {
1082         case kI2C_SlaveStandardMode:
1083             dataSetupTime_ns = 250u;
1084             break;
1085 
1086         case kI2C_SlaveFastMode:
1087             dataSetupTime_ns = 100u;
1088             break;
1089 
1090         case kI2C_SlaveFastModePlus:
1091             dataSetupTime_ns = 50u;
1092             break;
1093 
1094         case kI2C_SlaveHsMode:
1095             dataSetupTime_ns = 10u;
1096             break;
1097 
1098         default:
1099             dataSetupTime_ns = 0;
1100             break;
1101     }
1102 
1103     if (0U == dataSetupTime_ns)
1104     {
1105         return kStatus_InvalidArgument;
1106     }
1107 
1108     /* divVal = (sourceClock_Hz / 1000000) * (dataSetupTime_ns / 1000) */
1109     *divVal = srcClock_Hz / 1000u;
1110     *divVal = (*divVal) * dataSetupTime_ns;
1111     *divVal = (*divVal) / 1000000u;
1112 
1113     if ((*divVal) > I2C_CLKDIV_DIVVAL_MASK)
1114     {
1115         *divVal = I2C_CLKDIV_DIVVAL_MASK;
1116     }
1117 
1118     return kStatus_Success;
1119 }
1120 
1121 /*!
1122  * @brief Poll wait for the SLVPENDING flag.
1123  *
1124  * Wait for the pending status to be set (SLVPENDING = 1) by polling the STAT register.
1125  *
1126  * @param base The I2C peripheral base address.
1127  * @return status register at time the SLVPENDING bit is read as set
1128  */
I2C_SlavePollPending(I2C_Type * base)1129 static uint32_t I2C_SlavePollPending(I2C_Type *base)
1130 {
1131     uint32_t stat;
1132 
1133 #if I2C_RETRY_TIMES
1134     uint32_t waitTimes = I2C_RETRY_TIMES;
1135 #endif
1136 
1137     do
1138     {
1139         stat = base->STAT;
1140 #if I2C_RETRY_TIMES
1141     } while ((0U == (stat & I2C_STAT_SLVPENDING_MASK)) && (0U != --waitTimes));
1142 
1143     if (0U == waitTimes)
1144     {
1145         return kStatus_I2C_Timeout;
1146     }
1147 #else
1148     } while (0U == (stat & I2C_STAT_SLVPENDING_MASK));
1149 #endif
1150     return stat;
1151 }
1152 
1153 #if defined(FSL_SDK_ENABLE_I2C_DRIVER_TRANSACTIONAL_APIS) && (FSL_SDK_ENABLE_I2C_DRIVER_TRANSACTIONAL_APIS)
1154 /*!
1155  * @brief Invoke event from I2C_SlaveTransferHandleIRQ().
1156  *
1157  * Sets the event type to transfer structure and invokes the event callback, if it has been
1158  * enabled by eventMask.
1159  *
1160  * @param base The I2C peripheral base address.
1161  * @param handle The I2C slave handle for non-blocking APIs.
1162  * @param event The I2C slave event to invoke.
1163  */
I2C_SlaveInvokeEvent(I2C_Type * base,i2c_slave_handle_t * handle,i2c_slave_transfer_event_t event)1164 static void I2C_SlaveInvokeEvent(I2C_Type *base, i2c_slave_handle_t *handle, i2c_slave_transfer_event_t event)
1165 {
1166     handle->transfer.event = event;
1167     uint32_t eventMask     = handle->transfer.eventMask;
1168     if ((handle->callback != NULL) && ((eventMask & (uint32_t)event) != 0U))
1169     {
1170         handle->callback(base, &handle->transfer, handle->userData);
1171 
1172         size_t txSize = handle->transfer.txSize;
1173         size_t rxSize = handle->transfer.rxSize;
1174         /* if after event callback we have data buffer (callback func has added new data), keep transfer busy */
1175         if (false == handle->isBusy)
1176         {
1177             if (((handle->transfer.txData != NULL) && (txSize != 0U)) ||
1178                 ((handle->transfer.rxData != NULL) && (rxSize != 0U)))
1179             {
1180                 handle->isBusy = true;
1181             }
1182         }
1183 
1184         /* Clear the transferred count now that we have a new buffer. */
1185         if ((event == kI2C_SlaveReceiveEvent) || (event == kI2C_SlaveTransmitEvent))
1186         {
1187             handle->transfer.transferredCount = 0;
1188         }
1189     }
1190 }
1191 
1192 /*!
1193  * @brief Handle slave address match event.
1194  *
1195  * Called by Slave interrupt routine to ACK or NACK the matched address.
1196  * It also determines master direction (read or write).
1197  *
1198  * @param base The I2C peripheral base address.
1199  * @return true if the matched address is ACK'ed
1200  * @return false if the matched address is NACK'ed
1201  */
I2C_SlaveAddressIRQ(I2C_Type * base,i2c_slave_handle_t * handle)1202 static bool I2C_SlaveAddressIRQ(I2C_Type *base, i2c_slave_handle_t *handle)
1203 {
1204     uint8_t addressByte0;
1205     addressByte0 = (uint8_t)base->SLVDAT;
1206     size_t txSize;
1207     size_t rxSize;
1208 
1209     /* store the matched address */
1210     handle->transfer.receivedAddress = addressByte0;
1211 
1212     /* R/nW */
1213     if ((addressByte0 & 1U) != 0U)
1214     {
1215         txSize = handle->transfer.txSize;
1216         /* if we have no data in this transfer, call callback to get new */
1217         if ((handle->transfer.txData == NULL) || (txSize == 0U))
1218         {
1219             I2C_SlaveInvokeEvent(base, handle, kI2C_SlaveTransmitEvent);
1220         }
1221 
1222         txSize = handle->transfer.txSize;
1223         /* NACK if we have no data in this transfer. */
1224         if ((handle->transfer.txData == NULL) || (txSize == 0U))
1225         {
1226             base->SLVCTL = I2C_SLVCTL_SLVNACK_MASK;
1227             return false;
1228         }
1229 
1230         /* master wants to read, so slave transmit is next state */
1231         handle->slaveFsm = kI2C_SlaveFsmTransmit;
1232     }
1233     else
1234     {
1235         rxSize = handle->transfer.rxSize;
1236         /* if we have no receive buffer in this transfer, call callback to get new */
1237         if ((handle->transfer.rxData == NULL) || (rxSize == 0U))
1238         {
1239             I2C_SlaveInvokeEvent(base, handle, kI2C_SlaveReceiveEvent);
1240         }
1241 
1242         rxSize = handle->transfer.rxSize;
1243         /* NACK if we have no data in this transfer */
1244         if ((handle->transfer.rxData == NULL) || (rxSize == 0U))
1245         {
1246             base->SLVCTL = I2C_SLVCTL_SLVNACK_MASK;
1247             return false;
1248         }
1249 
1250         /* master wants write, so slave receive is next state */
1251         handle->slaveFsm = kI2C_SlaveFsmReceive;
1252     }
1253 
1254     /* continue transaction */
1255     base->SLVCTL = I2C_SLVCTL_SLVCONTINUE_MASK;
1256 
1257     return true;
1258 }
1259 
1260 /*!
1261  * @brief Starts accepting slave transfers.
1262  *
1263  * Call this API after calling I2C_SlaveInit() and I2C_SlaveTransferCreateHandle() to start processing
1264  * transactions driven by an I2C master. The slave monitors the I2C bus and pass events to the
1265  * callback that was passed into the call to I2C_SlaveTransferCreateHandle(). The callback is always invoked
1266  * from the interrupt context.
1267  *
1268  * @param base The I2C peripheral base address.
1269  * @param handle Pointer to #i2c_slave_handle_t structure which stores the transfer state.
1270  * @param txData Data to be transmitted to master in response to master read from slave requests. NULL if slave RX only.
1271  * @param txSize Size of txData buffer in bytes.
1272  * @param rxData Data where received data from master will be stored in response to master write to slave requests. NULL
1273  *               if slave TX only.
1274  * @param rxSize Size of rxData buffer in bytes.
1275  *
1276  * @retval #kStatus_Success Slave transfers were successfully started.
1277  * @retval #kStatus_I2C_Busy Slave transfers have already been started on this handle.
1278  */
I2C_SlaveTransferNonBlockingInternal(I2C_Type * base,i2c_slave_handle_t * handle,const void * txData,size_t txSize,void * rxData,size_t rxSize,uint32_t eventMask)1279 static status_t I2C_SlaveTransferNonBlockingInternal(I2C_Type *base,
1280                                                      i2c_slave_handle_t *handle,
1281                                                      const void *txData,
1282                                                      size_t txSize,
1283                                                      void *rxData,
1284                                                      size_t rxSize,
1285                                                      uint32_t eventMask)
1286 {
1287     status_t status;
1288 
1289     assert(handle != NULL);
1290 
1291     status = kStatus_Success;
1292 
1293     /* Disable I2C IRQ sources while we configure stuff. */
1294     I2C_DisableInterrupts(base, (uint32_t)kI2C_SlaveIrqFlags);
1295 
1296     /* Return busy if another transaction is in progress. */
1297     if (handle->isBusy)
1298     {
1299         status = kStatus_I2C_Busy;
1300     }
1301 
1302     /* Save transfer into handle. */
1303     handle->transfer.txData           = (const uint8_t *)txData;
1304     handle->transfer.txSize           = txSize;
1305     handle->transfer.rxData           = (uint8_t *)rxData;
1306     handle->transfer.rxSize           = rxSize;
1307     handle->transfer.transferredCount = 0;
1308     handle->transfer.eventMask = eventMask | (uint32_t)kI2C_SlaveTransmitEvent | (uint32_t)kI2C_SlaveReceiveEvent;
1309     handle->isBusy             = true;
1310 
1311     /* Set the SLVEN bit to 1 in the CFG register. */
1312     I2C_SlaveEnable(base, true);
1313 
1314     /* Clear w1c flags. */
1315     base->STAT |= 0U;
1316 
1317     /* Enable I2C internal IRQ sources. */
1318     I2C_EnableInterrupts(base, (uint32_t)kI2C_SlaveIrqFlags);
1319 
1320     return status;
1321 }
1322 
1323 /*!
1324  * brief Starts accepting master read from slave requests.
1325  *
1326  * The function can be called in response to #kI2C_SlaveTransmitEvent callback to start a new slave Tx transfer
1327  * from within the transfer callback.
1328  *
1329  * The set of events received by the callback is customizable. To do so, set the a eventMask parameter to
1330  * the OR'd combination of #i2c_slave_transfer_event_t enumerators for the events you wish to receive.
1331  * The #kI2C_SlaveTransmitEvent and #kI2C_SlaveReceiveEvent events are always enabled and do not need
1332  * to be included in the mask. Alternatively, you can pass 0 to get a default set of only the transmit and
1333  * receive events that are always enabled. In addition, the #kI2C_SlaveAllEvents constant is provided as
1334  * a convenient way to enable all events.
1335  *
1336  * param base The I2C peripheral base address.
1337  * param transfer Pointer to #i2c_slave_transfer_t structure.
1338  * param txData Pointer to data to send to master.
1339  * param txSize Size of txData in bytes.
1340  * param eventMask Bit mask formed by OR'ing together #i2c_slave_transfer_event_t enumerators to specify
1341  *      which events to send to the callback. Other accepted values are 0 to get a default set of
1342  *      only the transmit and receive events, and #kI2C_SlaveAllEvents to enable all events.
1343  *
1344  * retval kStatus_Success Slave transfers were successfully started.
1345  * retval #kStatus_I2C_Busy Slave transfers have already been started on this handle.
1346  */
I2C_SlaveSetSendBuffer(I2C_Type * base,volatile i2c_slave_transfer_t * transfer,const void * txData,size_t txSize,uint32_t eventMask)1347 status_t I2C_SlaveSetSendBuffer(
1348     I2C_Type *base, volatile i2c_slave_transfer_t *transfer, const void *txData, size_t txSize, uint32_t eventMask)
1349 {
1350     return I2C_SlaveTransferNonBlockingInternal(base, transfer->handle, txData, txSize, NULL, 0U, eventMask);
1351 }
1352 
1353 /*!
1354  * brief Starts accepting master write to slave requests.
1355  *
1356  * The function can be called in response to #kI2C_SlaveReceiveEvent callback to start a new slave Rx transfer
1357  * from within the transfer callback.
1358  *
1359  * The set of events received by the callback is customizable. To do so, set the a eventMask parameter to
1360  * the OR'd combination of #i2c_slave_transfer_event_t enumerators for the events you wish to receive.
1361  * The #kI2C_SlaveTransmitEvent and #kI2C_SlaveReceiveEvent events are always enabled and do not need
1362  * to be included in the mask. Alternatively, you can pass 0 to get a default set of only the transmit and
1363  * receive events that are always enabled. In addition, the #kI2C_SlaveAllEvents constant is provided as
1364  * a convenient way to enable all events.
1365  *
1366  * param base The I2C peripheral base address.
1367  * param transfer Pointer to #i2c_slave_transfer_t structure.
1368  * param rxData Pointer to data to store data from master.
1369  * param rxSize Size of rxData in bytes.
1370  * param eventMask Bit mask formed by OR'ing together #i2c_slave_transfer_event_t enumerators to specify
1371  *      which events to send to the callback. Other accepted values are 0 to get a default set of
1372  *      only the transmit and receive events, and #kI2C_SlaveAllEvents to enable all events.
1373  *
1374  * retval kStatus_Success Slave transfers were successfully started.
1375  * retval #kStatus_I2C_Busy Slave transfers have already been started on this handle.
1376  */
I2C_SlaveSetReceiveBuffer(I2C_Type * base,volatile i2c_slave_transfer_t * transfer,void * rxData,size_t rxSize,uint32_t eventMask)1377 status_t I2C_SlaveSetReceiveBuffer(
1378     I2C_Type *base, volatile i2c_slave_transfer_t *transfer, void *rxData, size_t rxSize, uint32_t eventMask)
1379 {
1380     return I2C_SlaveTransferNonBlockingInternal(base, transfer->handle, NULL, 0U, rxData, rxSize, eventMask);
1381 }
1382 #endif /* FSL_SDK_ENABLE_I2C_DRIVER_TRANSACTIONAL_APIS */
1383 
1384 /*!
1385  * brief Configures Slave Address n register.
1386  *
1387  * This function writes new value to Slave Address register.
1388  *
1389  * param base The I2C peripheral base address.
1390  * param addressRegister The module supports multiple address registers. The parameter determines which one shall be
1391  * changed.
1392  * param address The slave address to be stored to the address register for matching.
1393  * param addressDisable Disable matching of the specified address register.
1394  */
I2C_SlaveSetAddress(I2C_Type * base,i2c_slave_address_register_t addressRegister,uint8_t address,bool addressDisable)1395 void I2C_SlaveSetAddress(I2C_Type *base,
1396                          i2c_slave_address_register_t addressRegister,
1397                          uint8_t address,
1398                          bool addressDisable)
1399 {
1400     base->SLVADR[addressRegister] = I2C_SLVADR_SLVADR(address) | I2C_SLVADR_SADISABLE(addressDisable);
1401 }
1402 
1403 /*!
1404  * brief Provides a default configuration for the I2C slave peripheral.
1405  *
1406  * This function provides the following default configuration for the I2C slave peripheral:
1407  * code
1408  *  slaveConfig->enableSlave = true;
1409  *  slaveConfig->address0.disable = false;
1410  *  slaveConfig->address0.address = 0U;
1411  *  slaveConfig->address1.disable = true;
1412  *  slaveConfig->address2.disable = true;
1413  *  slaveConfig->address3.disable = true;
1414  *  slaveConfig->busSpeed = kI2C_SlaveStandardMode;
1415  * endcode
1416  *
1417  * After calling this function, override any settings  to customize the configuration,
1418  * prior to initializing the master driver with I2C_SlaveInit(). Be sure to override at least the a
1419  * address0.address member of the configuration structure with the desired slave address.
1420  *
1421  * param[out] slaveConfig User provided configuration structure that is set to default values. Refer to
1422  *      #i2c_slave_config_t.
1423  */
I2C_SlaveGetDefaultConfig(i2c_slave_config_t * slaveConfig)1424 void I2C_SlaveGetDefaultConfig(i2c_slave_config_t *slaveConfig)
1425 {
1426     assert(slaveConfig != NULL);
1427 
1428     /* Initializes the configure structure to zero. */
1429     (void)memset(slaveConfig, 0, sizeof(*slaveConfig));
1430 
1431     i2c_slave_config_t mySlaveConfig = {0};
1432 
1433     /* default config enables slave address 0 match to general I2C call address zero */
1434     mySlaveConfig.enableSlave             = true;
1435     mySlaveConfig.address1.addressDisable = true;
1436     mySlaveConfig.address2.addressDisable = true;
1437     mySlaveConfig.address3.addressDisable = true;
1438 
1439     *slaveConfig = mySlaveConfig;
1440 }
1441 
1442 /*!
1443  * brief Initializes the I2C slave peripheral.
1444  *
1445  * This function enables the peripheral clock and initializes the I2C slave peripheral as described by the user
1446  * provided configuration.
1447  *
1448  * param base The I2C peripheral base address.
1449  * param slaveConfig User provided peripheral configuration. Use I2C_SlaveGetDefaultConfig() to get a set of defaults
1450  *      that you can override.
1451  * param srcClock_Hz Frequency in Hertz of the I2C functional clock. Used to calculate CLKDIV value to provide
1452  * enough
1453  *                       data setup time for master when slave stretches the clock.
1454  */
I2C_SlaveInit(I2C_Type * base,const i2c_slave_config_t * slaveConfig,uint32_t srcClock_Hz)1455 status_t I2C_SlaveInit(I2C_Type *base, const i2c_slave_config_t *slaveConfig, uint32_t srcClock_Hz)
1456 {
1457     status_t status;
1458     uint32_t divVal = 0;
1459 
1460 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
1461     /* Enable the clock. */
1462     CLOCK_EnableClock(s_i2cClocks[I2C_GetInstance(base)]);
1463 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
1464 
1465 #if !(defined(FSL_FEATURE_I2C_HAS_NO_RESET) && FSL_FEATURE_I2C_HAS_NO_RESET)
1466     RESET_PeripheralReset(s_i2cResets[I2C_GetInstance(base)]);
1467 #endif
1468 
1469     /* configure data setup time used when slave stretches clock */
1470     status = I2C_SlaveDivVal(srcClock_Hz, slaveConfig->busSpeed, &divVal);
1471     if (kStatus_Success != status)
1472     {
1473         return status;
1474     }
1475 
1476     /* I2C Clock Divider register */
1477     base->CLKDIV = divVal;
1478 
1479     /* set Slave address */
1480     I2C_SlaveSetAddress(base, kI2C_SlaveAddressRegister0, slaveConfig->address0.address,
1481                         slaveConfig->address0.addressDisable);
1482     I2C_SlaveSetAddress(base, kI2C_SlaveAddressRegister1, slaveConfig->address1.address,
1483                         slaveConfig->address1.addressDisable);
1484     I2C_SlaveSetAddress(base, kI2C_SlaveAddressRegister2, slaveConfig->address2.address,
1485                         slaveConfig->address2.addressDisable);
1486     I2C_SlaveSetAddress(base, kI2C_SlaveAddressRegister3, slaveConfig->address3.address,
1487                         slaveConfig->address3.addressDisable);
1488 
1489     /* set Slave address 0 qual */
1490     base->SLVQUAL0 = I2C_SLVQUAL0_QUALMODE0(slaveConfig->qualMode) | I2C_SLVQUAL0_SLVQUAL0(slaveConfig->qualAddress);
1491 
1492     /* set Slave enable */
1493     base->CFG = I2C_CFG_SLVEN(slaveConfig->enableSlave);
1494 
1495     return status;
1496 }
1497 
1498 /*!
1499  * brief Deinitializes the I2C slave peripheral.
1500  *
1501  * This function disables the I2C slave peripheral and gates the clock. It also performs a software
1502  * reset to restore the peripheral to reset conditions.
1503  *
1504  * param base The I2C peripheral base address.
1505  */
I2C_SlaveDeinit(I2C_Type * base)1506 void I2C_SlaveDeinit(I2C_Type *base)
1507 {
1508     I2C_SlaveEnable(base, false);
1509 
1510 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
1511     /* Disable the clock. */
1512     CLOCK_DisableClock(s_i2cClocks[I2C_GetInstance(base)]);
1513 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
1514 }
1515 
1516 /*!
1517  * brief Performs a polling send transfer on the I2C bus.
1518  *
1519  * The function executes blocking address phase and blocking data phase.
1520  *
1521  * param base  The I2C peripheral base address.
1522  * param txBuff The pointer to the data to be transferred.
1523  * param txSize The length in bytes of the data to be transferred.
1524  * return kStatus_Success Data has been sent.
1525  * return kStatus_Fail Unexpected slave state (master data write while master read from slave is expected).
1526  */
I2C_SlaveWriteBlocking(I2C_Type * base,const uint8_t * txBuff,size_t txSize)1527 status_t I2C_SlaveWriteBlocking(I2C_Type *base, const uint8_t *txBuff, size_t txSize)
1528 {
1529     const uint8_t *buf = txBuff;
1530     uint32_t stat;
1531     bool slaveAddress;
1532     bool slaveTransmit;
1533 
1534     /* Set the SLVEN bit to 1 in the CFG register. */
1535     I2C_SlaveEnable(base, true);
1536 
1537     /* wait for SLVPENDING */
1538     stat = I2C_SlavePollPending(base);
1539     if (stat == (uint32_t)kStatus_I2C_Timeout)
1540     {
1541         return kStatus_I2C_Timeout;
1542     }
1543 
1544     /* Get slave machine state */
1545     slaveAddress  = (((stat & I2C_STAT_SLVSTATE_MASK) >> I2C_STAT_SLVSTATE_SHIFT) == (uint32_t)I2C_STAT_SLVST_ADDR);
1546     slaveTransmit = (((stat & I2C_STAT_SLVSTATE_MASK) >> I2C_STAT_SLVSTATE_SHIFT) == (uint32_t)I2C_STAT_SLVST_TX);
1547 
1548     /* in I2C_SlaveSend() it shall be either slaveAddress or slaveTransmit */
1549     if (!(slaveAddress || slaveTransmit))
1550     {
1551         I2C_SlaveInternalStateMachineReset(base);
1552         return kStatus_Fail;
1553     }
1554 
1555     if (slaveAddress)
1556     {
1557         /* Acknowledge (ack) the address by setting SLVCONTINUE = 1 in the slave control register */
1558         base->SLVCTL = I2C_SLVCTL_SLVCONTINUE_MASK;
1559 
1560         /* wait for SLVPENDING */
1561         stat = I2C_SlavePollPending(base);
1562         if (stat == (uint32_t)kStatus_I2C_Timeout)
1563         {
1564             return kStatus_I2C_Timeout;
1565         }
1566     }
1567 
1568     /* send bytes up to txSize */
1569     while (txSize != 0U)
1570     {
1571         slaveTransmit = (((stat & I2C_STAT_SLVSTATE_MASK) >> I2C_STAT_SLVSTATE_SHIFT) == (uint32_t)I2C_STAT_SLVST_TX);
1572 
1573         if (!slaveTransmit)
1574         {
1575             I2C_SlaveInternalStateMachineReset(base);
1576             return kStatus_Fail;
1577         }
1578 
1579         /* Write 8 bits of data to the SLVDAT register */
1580         base->SLVDAT = I2C_SLVDAT_DATA(*buf);
1581 
1582         /* continue transaction */
1583         base->SLVCTL = I2C_SLVCTL_SLVCONTINUE_MASK;
1584 
1585         /* advance counters and pointers for next data */
1586         buf++;
1587         txSize--;
1588 
1589         if (txSize != 0U)
1590         {
1591             /* wait for SLVPENDING */
1592             stat = I2C_SlavePollPending(base);
1593             if (stat == (uint32_t)kStatus_I2C_Timeout)
1594             {
1595                 return kStatus_I2C_Timeout;
1596             }
1597         }
1598     }
1599 
1600     return kStatus_Success;
1601 }
1602 
1603 /*!
1604  * brief Performs a polling receive transfer on the I2C bus.
1605  *
1606  * The function executes blocking address phase and blocking data phase.
1607  *
1608  * param base  The I2C peripheral base address.
1609  * param rxBuff The pointer to the data to be transferred.
1610  * param rxSize The length in bytes of the data to be transferred.
1611  * return kStatus_Success Data has been received.
1612  * return kStatus_Fail Unexpected slave state (master data read while master write to slave is expected).
1613  */
I2C_SlaveReadBlocking(I2C_Type * base,uint8_t * rxBuff,size_t rxSize)1614 status_t I2C_SlaveReadBlocking(I2C_Type *base, uint8_t *rxBuff, size_t rxSize)
1615 {
1616     uint8_t *buf = rxBuff;
1617     uint32_t stat;
1618     bool slaveAddress;
1619     bool slaveReceive;
1620 
1621     /* Set the SLVEN bit to 1 in the CFG register. */
1622     I2C_SlaveEnable(base, true);
1623 
1624     /* wait for SLVPENDING */
1625     stat = I2C_SlavePollPending(base);
1626     if (stat == (uint32_t)kStatus_I2C_Timeout)
1627     {
1628         return kStatus_I2C_Timeout;
1629     }
1630 
1631     /* Get slave machine state */
1632     slaveAddress = (((stat & I2C_STAT_SLVSTATE_MASK) >> I2C_STAT_SLVSTATE_SHIFT) == (uint32_t)I2C_STAT_SLVST_ADDR);
1633     slaveReceive = (((stat & I2C_STAT_SLVSTATE_MASK) >> I2C_STAT_SLVSTATE_SHIFT) == (uint32_t)I2C_STAT_SLVST_RX);
1634 
1635     /* in I2C_SlaveReceive() it shall be either slaveAddress or slaveReceive */
1636     if (!(slaveAddress || slaveReceive))
1637     {
1638         I2C_SlaveInternalStateMachineReset(base);
1639         return kStatus_Fail;
1640     }
1641 
1642     if (slaveAddress)
1643     {
1644         /* Acknowledge (ack) the address by setting SLVCONTINUE = 1 in the slave control register */
1645         base->SLVCTL = I2C_SLVCTL_SLVCONTINUE_MASK;
1646 
1647         /* wait for SLVPENDING */
1648         stat = I2C_SlavePollPending(base);
1649         if (stat == (uint32_t)kStatus_I2C_Timeout)
1650         {
1651             return kStatus_I2C_Timeout;
1652         }
1653     }
1654 
1655     /* receive bytes up to rxSize */
1656     while (rxSize != 0U)
1657     {
1658         slaveReceive = (((stat & I2C_STAT_SLVSTATE_MASK) >> I2C_STAT_SLVSTATE_SHIFT) == (uint32_t)I2C_STAT_SLVST_RX);
1659 
1660         if (!slaveReceive)
1661         {
1662             I2C_SlaveInternalStateMachineReset(base);
1663             return kStatus_Fail;
1664         }
1665 
1666         /* Read 8 bits of data from the SLVDAT register */
1667         *buf = (uint8_t)base->SLVDAT;
1668 
1669         /* continue transaction */
1670         base->SLVCTL = I2C_SLVCTL_SLVCONTINUE_MASK;
1671 
1672         /* advance counters and pointers for next data */
1673         buf++;
1674         rxSize--;
1675 
1676         if (rxSize != 0U)
1677         {
1678             /* wait for SLVPENDING */
1679             stat = I2C_SlavePollPending(base);
1680             if (stat == (uint32_t)kStatus_I2C_Timeout)
1681             {
1682                 return kStatus_I2C_Timeout;
1683             }
1684         }
1685     }
1686 
1687     return kStatus_Success;
1688 }
1689 
1690 #if defined(FSL_SDK_ENABLE_I2C_DRIVER_TRANSACTIONAL_APIS) && (FSL_SDK_ENABLE_I2C_DRIVER_TRANSACTIONAL_APIS)
1691 /*!
1692  * brief Creates a new handle for the I2C slave non-blocking APIs.
1693  *
1694  * The creation of a handle is for use with the non-blocking APIs. Once a handle
1695  * is created, there is not a corresponding destroy handle. If the user wants to
1696  * terminate a transfer, the I2C_SlaveTransferAbort() API shall be called.
1697  *
1698  * param base The I2C peripheral base address.
1699  * param[out] handle Pointer to the I2C slave driver handle.
1700  * param callback User provided pointer to the asynchronous callback function.
1701  * param userData User provided pointer to the application callback data.
1702  */
I2C_SlaveTransferCreateHandle(I2C_Type * base,i2c_slave_handle_t * handle,i2c_slave_transfer_callback_t callback,void * userData)1703 void I2C_SlaveTransferCreateHandle(I2C_Type *base,
1704                                    i2c_slave_handle_t *handle,
1705                                    i2c_slave_transfer_callback_t callback,
1706                                    void *userData)
1707 {
1708     uint32_t instance;
1709 
1710     assert(handle != NULL);
1711 
1712     /* Clear out the handle. */
1713     (void)memset(handle, 0, sizeof(*handle));
1714 
1715     /* Look up instance number */
1716     instance = I2C_GetInstance(base);
1717 
1718     /* Save base and instance. */
1719     handle->callback = callback;
1720     handle->userData = userData;
1721 
1722     /* initialize fsm */
1723     handle->slaveFsm = kI2C_SlaveFsmAddressMatch;
1724 
1725     /* store pointer to handle into transfer struct */
1726     handle->transfer.handle = handle;
1727 
1728     /* Save the context in global variables to support the double weak mechanism. */
1729     s_i2cHandle[instance] = handle;
1730 
1731     /* Save slave interrupt handler. */
1732     s_i2cSlaveIsr = I2C_SlaveTransferHandleIRQ;
1733 
1734     /* Clear internal IRQ enables and enable NVIC IRQ. */
1735     I2C_DisableInterrupts(base, (uint32_t)kI2C_SlaveIrqFlags);
1736     (void)EnableIRQ(s_i2cIRQ[instance]);
1737 }
1738 
1739 /*!
1740  * brief Starts accepting slave transfers.
1741  *
1742  * Call this API after calling I2C_SlaveInit() and I2C_SlaveTransferCreateHandle() to start processing
1743  * transactions driven by an I2C master. The slave monitors the I2C bus and pass events to the
1744  * callback that was passed into the call to I2C_SlaveTransferCreateHandle(). The callback is always invoked
1745  * from the interrupt context.
1746  *
1747  * If no slave Tx transfer is busy, a master read from slave request invokes #kI2C_SlaveTransmitEvent callback.
1748  * If no slave Rx transfer is busy, a master write to slave request invokes #kI2C_SlaveReceiveEvent callback.
1749  *
1750  * The set of events received by the callback is customizable. To do so, set the a eventMask parameter to
1751  * the OR'd combination of #i2c_slave_transfer_event_t enumerators for the events you wish to receive.
1752  * The #kI2C_SlaveTransmitEvent and #kI2C_SlaveReceiveEvent events are always enabled and do not need
1753  * to be included in the mask. Alternatively, you can pass 0 to get a default set of only the transmit and
1754  * receive events that are always enabled. In addition, the #kI2C_SlaveAllEvents constant is provided as
1755  * a convenient way to enable all events.
1756  *
1757  * param base The I2C peripheral base address.
1758  * param handle Pointer to i2c_slave_handle_t structure which stores the transfer state.
1759  * param eventMask Bit mask formed by OR'ing together #i2c_slave_transfer_event_t enumerators to specify
1760  *      which events to send to the callback. Other accepted values are 0 to get a default set of
1761  *      only the transmit and receive events, and #kI2C_SlaveAllEvents to enable all events.
1762  *
1763  * retval kStatus_Success Slave transfers were successfully started.
1764  * retval #kStatus_I2C_Busy Slave transfers have already been started on this handle.
1765  */
I2C_SlaveTransferNonBlocking(I2C_Type * base,i2c_slave_handle_t * handle,uint32_t eventMask)1766 status_t I2C_SlaveTransferNonBlocking(I2C_Type *base, i2c_slave_handle_t *handle, uint32_t eventMask)
1767 {
1768     return I2C_SlaveTransferNonBlockingInternal(base, handle, NULL, 0U, NULL, 0U, eventMask);
1769 }
1770 
1771 /*!
1772  * brief Gets the slave transfer remaining bytes during a interrupt non-blocking transfer.
1773  *
1774  * param base I2C base pointer.
1775  * param handle pointer to i2c_slave_handle_t structure.
1776  * param count Number of bytes transferred so far by the non-blocking transaction.
1777  * retval kStatus_InvalidArgument count is Invalid.
1778  * retval kStatus_Success Successfully return the count.
1779  */
I2C_SlaveTransferGetCount(I2C_Type * base,i2c_slave_handle_t * handle,size_t * count)1780 status_t I2C_SlaveTransferGetCount(I2C_Type *base, i2c_slave_handle_t *handle, size_t *count)
1781 {
1782     assert(handle != NULL);
1783 
1784     if (count == NULL)
1785     {
1786         return kStatus_InvalidArgument;
1787     }
1788 
1789     /* Catch when there is not an active transfer. */
1790     if (!handle->isBusy)
1791     {
1792         *count = 0;
1793         return kStatus_NoTransferInProgress;
1794     }
1795 
1796     /* For an active transfer, just return the count from the handle. */
1797     *count = handle->transfer.transferredCount;
1798 
1799     return kStatus_Success;
1800 }
1801 
1802 /*!
1803  * brief Aborts the slave non-blocking transfers.
1804  * note This API could be called at any time to stop slave for handling the bus events.
1805  * param base The I2C peripheral base address.
1806  * param handle Pointer to i2c_slave_handle_t structure which stores the transfer state.
1807  * retval kStatus_Success
1808  * retval #kStatus_I2C_Idle
1809  */
I2C_SlaveTransferAbort(I2C_Type * base,i2c_slave_handle_t * handle)1810 void I2C_SlaveTransferAbort(I2C_Type *base, i2c_slave_handle_t *handle)
1811 {
1812     /* Disable I2C IRQ sources while we configure stuff. */
1813     I2C_DisableInterrupts(base, (uint32_t)kI2C_SlaveIrqFlags);
1814 
1815     /* Set the SLVEN bit to 0 in the CFG register. */
1816     I2C_SlaveEnable(base, false);
1817 
1818     handle->isBusy          = false;
1819     handle->transfer.txSize = 0;
1820     handle->transfer.rxSize = 0;
1821 }
1822 
1823 /*!
1824  * brief Reusable routine to handle slave interrupts.
1825  * note This function does not need to be called unless you are reimplementing the
1826  *  non blocking API's interrupt handler routines to add special functionality.
1827  * param base The I2C peripheral base address.
1828  * param handle Pointer to i2c_slave_handle_t structure which stores the transfer state.
1829  */
I2C_SlaveTransferHandleIRQ(I2C_Type * base,void * i2cHandle)1830 void I2C_SlaveTransferHandleIRQ(I2C_Type *base, void *i2cHandle)
1831 {
1832     assert(i2cHandle != NULL);
1833 
1834     i2c_slave_handle_t *handle = (i2c_slave_handle_t *)i2cHandle;
1835     uint32_t i2cStatus         = base->STAT;
1836     uint8_t tmpdata;
1837 
1838     size_t rxSize = handle->transfer.rxSize;
1839     size_t txSize = handle->transfer.txSize;
1840 
1841     if ((i2cStatus & I2C_STAT_SLVDESEL_MASK) != 0U)
1842     {
1843         I2C_SlaveInvokeEvent(base, handle, kI2C_SlaveDeselectedEvent);
1844         I2C_SlaveClearStatusFlags(base, I2C_STAT_SLVDESEL_MASK);
1845     }
1846 
1847     /* SLVPENDING flag is cleared by writing I2C_SLVCTL_SLVCONTINUE_MASK to SLVCTL register */
1848     if ((i2cStatus & I2C_STAT_SLVPENDING_MASK) != 0U)
1849     {
1850         bool slaveAddress =
1851             (((i2cStatus & I2C_STAT_SLVSTATE_MASK) >> I2C_STAT_SLVSTATE_SHIFT) == (uint32_t)I2C_STAT_SLVST_ADDR);
1852 
1853         if (slaveAddress)
1854         {
1855             (void)I2C_SlaveAddressIRQ(base, handle);
1856             I2C_SlaveInvokeEvent(base, handle, kI2C_SlaveAddressMatchEvent);
1857         }
1858         else
1859         {
1860             switch (handle->slaveFsm)
1861             {
1862                 case kI2C_SlaveFsmReceive:
1863                 {
1864                     bool slaveReceive = (((i2cStatus & I2C_STAT_SLVSTATE_MASK) >> I2C_STAT_SLVSTATE_SHIFT) ==
1865                                          (uint32_t)I2C_STAT_SLVST_RX);
1866 
1867                     if (slaveReceive)
1868                     {
1869                         rxSize = handle->transfer.rxSize;
1870                         /* if we have no receive buffer in this transfer, call callback to get new */
1871                         if ((handle->transfer.rxData == NULL) || (rxSize == 0U))
1872                         {
1873                             I2C_SlaveInvokeEvent(base, handle, kI2C_SlaveReceiveEvent);
1874                         }
1875 
1876                         rxSize = handle->transfer.rxSize;
1877                         /* receive a byte */
1878                         if ((handle->transfer.rxData != NULL) && (rxSize != 0U))
1879                         {
1880                             tmpdata                    = (uint8_t)base->SLVDAT;
1881                             *(handle->transfer.rxData) = tmpdata;
1882                             (handle->transfer.rxSize)--;
1883                             (handle->transfer.rxData)++;
1884                             (handle->transfer.transferredCount)++;
1885 
1886                             /* continue transaction */
1887                             base->SLVCTL = I2C_SLVCTL_SLVCONTINUE_MASK;
1888                         }
1889 
1890                         txSize = handle->transfer.txSize;
1891                         rxSize = handle->transfer.rxSize;
1892                         /* is this last transaction for this transfer? allow next transaction */
1893                         if ((0U == rxSize) && (0U == txSize))
1894                         {
1895                             handle->isBusy = false;
1896                             I2C_SlaveInvokeEvent(base, handle, kI2C_SlaveCompletionEvent);
1897                         }
1898                     }
1899                     else
1900                     {
1901                         base->SLVCTL = I2C_SLVCTL_SLVNACK_MASK;
1902                     }
1903                 }
1904                 break;
1905 
1906                 case kI2C_SlaveFsmTransmit:
1907                 {
1908                     bool slaveTransmit = (((i2cStatus & I2C_STAT_SLVSTATE_MASK) >> I2C_STAT_SLVSTATE_SHIFT) ==
1909                                           (uint32_t)I2C_STAT_SLVST_TX);
1910 
1911                     if (slaveTransmit)
1912                     {
1913                         txSize = handle->transfer.txSize;
1914                         /* if we have no data in this transfer, call callback to get new */
1915                         if ((handle->transfer.txData == NULL) || (txSize == 0U))
1916                         {
1917                             I2C_SlaveInvokeEvent(base, handle, kI2C_SlaveTransmitEvent);
1918                         }
1919 
1920                         txSize = handle->transfer.txSize;
1921                         /* transmit a byte */
1922                         if ((handle->transfer.txData != NULL) && (txSize != 0U))
1923                         {
1924                             base->SLVDAT = *(handle->transfer.txData);
1925                             (handle->transfer.txSize)--;
1926                             (handle->transfer.txData)++;
1927                             (handle->transfer.transferredCount)++;
1928 
1929                             /* continue transaction */
1930                             base->SLVCTL = I2C_SLVCTL_SLVCONTINUE_MASK;
1931                         }
1932 
1933                         txSize = handle->transfer.txSize;
1934                         rxSize = handle->transfer.rxSize;
1935                         /* is this last transaction for this transfer? allow next transaction */
1936                         if ((0U == rxSize) && (0U == txSize))
1937                         {
1938                             handle->isBusy = false;
1939                             I2C_SlaveInvokeEvent(base, handle, kI2C_SlaveCompletionEvent);
1940                         }
1941                     }
1942                     else
1943                     {
1944                         base->SLVCTL = I2C_SLVCTL_SLVNACK_MASK;
1945                     }
1946                 }
1947                 break;
1948 
1949                 default:
1950                     /* incorrect state, slv_abort()? */
1951                     break;
1952             }
1953         }
1954     }
1955 }
1956 
I2C_TransferCommonIRQHandler(I2C_Type * base,void * handle)1957 static void I2C_TransferCommonIRQHandler(I2C_Type *base, void *handle)
1958 {
1959     /* Check if master interrupt. */
1960     if ((base->CFG & I2C_CFG_MSTEN_MASK) != 0U)
1961     {
1962         s_i2cMasterIsr(base, handle);
1963     }
1964     else
1965     {
1966         s_i2cSlaveIsr(base, handle);
1967     }
1968     SDK_ISR_EXIT_BARRIER;
1969 }
1970 
1971 #if defined(I2C0)
1972 void I2C0_DriverIRQHandler(void);
I2C0_DriverIRQHandler(void)1973 void I2C0_DriverIRQHandler(void)
1974 {
1975     I2C_TransferCommonIRQHandler(I2C0, s_i2cHandle[0]);
1976 }
1977 #endif
1978 
1979 #if defined(I2C1)
1980 void I2C1_DriverIRQHandler(void);
I2C1_DriverIRQHandler(void)1981 void I2C1_DriverIRQHandler(void)
1982 {
1983     I2C_TransferCommonIRQHandler(I2C1, s_i2cHandle[1]);
1984 }
1985 #endif
1986 
1987 #if defined(I2C2)
1988 void I2C2_DriverIRQHandler(void);
I2C2_DriverIRQHandler(void)1989 void I2C2_DriverIRQHandler(void)
1990 {
1991     I2C_TransferCommonIRQHandler(I2C2, s_i2cHandle[2]);
1992 }
1993 #endif
1994 #endif /* FSL_SDK_ENABLE_I2C_DRIVER_TRANSACTIONAL_APIS */
1995