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