1 /*
2  * Copyright (c) 2015, Freescale Semiconductor, Inc.
3  * Copyright 2016-2022 NXP
4  * All rights reserved.
5  *
6  * SPDX-License-Identifier: BSD-3-Clause
7  */
8 
9 #include "fsl_lpi2c.h"
10 #include <stdlib.h>
11 #include <string.h>
12 
13 /*
14  * $Coverage Justification Reference$
15  *
16  * $Justification fsl_lpi2c_c_ref_1$
17  * The default branch cannot be executed in any circumstances, it is only added to avoid MISRA violation.
18  *
19  * $Justification fsl_lpi2c_c_ref_2$
20  * Two instances failed to simulate #kStatus_LPI2C_Busy.
21  *
22  * $Justification fsl_lpi2c_c_ref_3$
23  * When the transmission is completed (remaining == 0), the SDF and RSF will be set, and the flags are get before
24  * that(get before set), it will be over when the next cycle occurs, the first condition cannot be verified, and the
25  * remaining will not be verified.(will improve)
26  *
27  */
28 
29 /*******************************************************************************
30  * Definitions
31  ******************************************************************************/
32 
33 /* Component ID definition, used by tools. */
34 #ifndef FSL_COMPONENT_ID
35 #define FSL_COMPONENT_ID "platform.drivers.lpi2c"
36 #endif
37 
38 #if defined(LPI2C_RSTS)
39 #define LPI2C_RESETS_ARRAY LPI2C_RSTS
40 #endif
41 
42 /*! @brief LPI2C master fifo commands. */
43 enum
44 {
45     kTxDataCmd = LPI2C_MTDR_CMD(0x0U), /*!< Transmit DATA[7:0] */
46     kRxDataCmd = LPI2C_MTDR_CMD(0X1U), /*!< Receive (DATA[7:0] + 1) bytes */
47     kStopCmd   = LPI2C_MTDR_CMD(0x2U), /*!< Generate STOP condition */
48     kStartCmd  = LPI2C_MTDR_CMD(0x4U), /*!< Generate(repeated) START and transmit address in DATA[[7:0] */
49 };
50 
51 /*!
52  * @brief Default watermark values.
53  *
54  * The default watermarks are set to zero.
55  */
56 enum
57 {
58     kDefaultTxWatermark = 0,
59     kDefaultRxWatermark = 0,
60 };
61 
62 /*! @brief States for the state machine used by transactional APIs. */
63 enum
64 {
65     kIdleState = 0,
66     kSendCommandState,
67     kIssueReadCommandState,
68     kTransferDataState,
69     kStopState,
70     kWaitForCompletionState,
71 };
72 
73 /*!
74  * @brief Structure definition for variables that passed as parameters in LPI2C_RunTransferStateMachine.
75  * The structure is private.
76  */
77 typedef struct _lpi2c_state_machine_param
78 {
79     bool state_complete; /*!< status of complete */
80     size_t rxCount;      /*!< rx count */
81     size_t txCount;      /*!< tx count */
82     uint32_t status;     /*!< machine status */
83 } lpi2c_state_machine_param_t;
84 
85 /*! @brief Typedef for slave interrupt handler. */
86 typedef void (*lpi2c_slave_isr_t)(LPI2C_Type *base, lpi2c_slave_handle_t *handle);
87 
88 /*******************************************************************************
89  * Prototypes
90  ******************************************************************************/
91 static uint32_t LPI2C_GetCyclesForWidth(
92     uint32_t sourceClock_Hz, uint32_t width_ns, uint32_t minCycles, uint32_t maxCycles, uint32_t prescaler);
93 
94 static status_t LPI2C_MasterWaitForTxReady(LPI2C_Type *base);
95 
96 static status_t LPI2C_RunTransferStateMachine(LPI2C_Type *base, lpi2c_master_handle_t *handle, bool *isDone);
97 
98 static void LPI2C_InitTransferStateMachine(lpi2c_master_handle_t *handle);
99 
100 static status_t LPI2C_SlaveCheckAndClearError(LPI2C_Type *base, uint32_t flags);
101 
102 static void LPI2C_CommonIRQHandler(LPI2C_Type *base, uint32_t instance);
103 
104 /*!
105  * @brief introduce function LPI2C_TransferStateMachineSendCommandState.
106  * This function was deal with Send Command State.
107  *
108  * @param base The I2C peripheral base address.
109  * @param handle Master nonblocking driver handle.
110  * @param variable_set Pass the address of the parent function variable.
111  */
112 static void LPI2C_TransferStateMachineSendCommand(LPI2C_Type *base,
113                                                   lpi2c_master_handle_t *handle,
114                                                   lpi2c_state_machine_param_t *stateParams);
115 
116 /*!
117  * @brief introduce function LPI2C_TransferStateMachineIssueReadCommandState.
118  * This function was deal with Issue Read Command State.
119  *
120  * @param base The I2C peripheral base address.
121  * @param handle Master nonblocking driver handle.
122  * @param stateParams Pass the address of the parent function variable.
123  */
124 static void LPI2C_TransferStateMachineReadCommand(LPI2C_Type *base,
125                                                   lpi2c_master_handle_t *handle,
126                                                   lpi2c_state_machine_param_t *stateParams);
127 
128 /*!
129  * @brief introduce function LPI2C_TransferStateMachineTransferDataState.
130  * This function was deal with init Transfer Data State.
131  *
132  * @param base The I2C peripheral base address.
133  * @param handle Master nonblocking driver handle.
134  * @param stateParams Pass the address of the parent function variable.
135  */
136 static void LPI2C_TransferStateMachineTransferData(LPI2C_Type *base,
137                                                    lpi2c_master_handle_t *handle,
138                                                    lpi2c_state_machine_param_t *stateParams);
139 
140 /*!
141  * @brief introduce function LPI2C_TransferStateMachineStopState.
142  * This function was deal with Stop State.
143  *
144  * @param base The I2C peripheral base address.
145  * @param handle Master nonblocking driver handle.
146  * @param stateParams Pass the address of the parent function variable.
147  * @param[out] isDone Set to true if the transfer has completed.
148  */
149 static void LPI2C_TransferStateMachineStopState(LPI2C_Type *base,
150                                                 lpi2c_master_handle_t *handle,
151                                                 lpi2c_state_machine_param_t *stateParams,
152                                                 bool *isDone);
153 
154 /*!
155  * @brief introduce function LPI2C_TransferStateMachineWaitState.
156  * This function was deal with Wait For Completion State.
157  *
158  * @param base The I2C peripheral base address.
159  * @param handle Master nonblocking driver handle.
160  * @param stateParams Pass the address of the parent function variable.
161  * @param[out] isDone Set to true if the transfer has completed.
162  */
163 static void LPI2C_TransferStateMachineWaitState(LPI2C_Type *base,
164                                                 lpi2c_master_handle_t *handle,
165                                                 lpi2c_state_machine_param_t *stateParams,
166                                                 bool *isDone);
167 
168 /*******************************************************************************
169  * Variables
170  ******************************************************************************/
171 
172 /*! @brief Array to map LPI2C instance number to base pointer. */
173 static LPI2C_Type *const kLpi2cBases[] = LPI2C_BASE_PTRS;
174 
175 /*! @brief Array to map LPI2C instance number to IRQ number, used internally for LPI2C master interrupt and EDMA
176 transactional APIs. */
177 IRQn_Type const kLpi2cIrqs[] = LPI2C_IRQS;
178 
179 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
180 /*! @brief Array to map LPI2C instance number to clock gate enum. */
181 static clock_ip_name_t const kLpi2cClocks[] = LPI2C_CLOCKS;
182 
183 #if defined(LPI2C_PERIPH_CLOCKS)
184 /*! @brief Array to map LPI2C instance number to pheripheral clock gate enum. */
185 static const clock_ip_name_t kLpi2cPeriphClocks[] = LPI2C_PERIPH_CLOCKS;
186 #endif
187 
188 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
189 
190 /*! @brief Pointer to master IRQ handler for each instance, used internally for LPI2C master interrupt and EDMA
191 transactional APIs. */
192 lpi2c_master_isr_t s_lpi2cMasterIsr;
193 
194 /*! @brief Pointers to master handles for each instance, used internally for LPI2C master interrupt and EDMA
195 transactional APIs. */
196 void *s_lpi2cMasterHandle[ARRAY_SIZE(kLpi2cBases)];
197 
198 /*! @brief Pointer to slave IRQ handler for each instance. */
199 static lpi2c_slave_isr_t s_lpi2cSlaveIsr;
200 
201 /*! @brief Pointers to slave handles for each instance. */
202 static lpi2c_slave_handle_t *s_lpi2cSlaveHandle[ARRAY_SIZE(kLpi2cBases)];
203 
204 #if defined(LPI2C_RESETS_ARRAY)
205 /* Reset array */
206 static const reset_ip_name_t s_lpi2cResets[] = LPI2C_RESETS_ARRAY;
207 #endif
208 
209 /*******************************************************************************
210  * Code
211  ******************************************************************************/
212 
213 /*!
214  * brief Returns an instance number given a base address.
215  *
216  * If an invalid base address is passed, debug builds will assert. Release builds will just return
217  * instance number 0.
218  *
219  * param base The LPI2C peripheral base address.
220  * return LPI2C instance number starting from 0.
221  */
LPI2C_GetInstance(LPI2C_Type * base)222 uint32_t LPI2C_GetInstance(LPI2C_Type *base)
223 {
224     uint32_t instance;
225     for (instance = 0U; instance < ARRAY_SIZE(kLpi2cBases); ++instance)
226     {
227         if (kLpi2cBases[instance] == base)
228         {
229             break;
230         }
231     }
232 
233     assert(instance < ARRAY_SIZE(kLpi2cBases));
234     return instance;
235 }
236 
237 /*!
238  * @brief Computes a cycle count for a given time in nanoseconds.
239  * @param sourceClock_Hz LPI2C functional clock frequency in Hertz.
240  * @param width_ns Desired with in nanoseconds.
241  * @param minCycles Minimum cycle count.
242  * @param maxCycles Maximum cycle count.
243  * @param prescaler LPI2C prescaler setting. If the cycle period is not affected by the prescaler value, set it to 0.
244  */
LPI2C_GetCyclesForWidth(uint32_t sourceClock_Hz,uint32_t width_ns,uint32_t minCycles,uint32_t maxCycles,uint32_t prescaler)245 static uint32_t LPI2C_GetCyclesForWidth(
246     uint32_t sourceClock_Hz, uint32_t width_ns, uint32_t minCycles, uint32_t maxCycles, uint32_t prescaler)
247 {
248     assert(sourceClock_Hz > 0U);
249 
250     uint32_t divider = 1U;
251 
252     while (prescaler != 0U)
253     {
254         divider *= 2U;
255         prescaler--;
256     }
257 
258     uint32_t busCycle_ns = 1000000U / (sourceClock_Hz / divider / 1000U);
259     /* Calculate the cycle count, round up the calculated value. */
260     uint32_t cycles = (width_ns * 10U / busCycle_ns + 5U) / 10U;
261 
262     /* If the calculated value is smaller than the minimum value, use the minimum value */
263     if (cycles < minCycles)
264     {
265         cycles = minCycles;
266     }
267     /* If the calculated value is larger than the maximum value, use the maxmum value */
268     if (cycles > maxCycles)
269     {
270         cycles = maxCycles;
271     }
272 
273     return cycles;
274 }
275 
276 /*!
277  * brief Convert provided flags to status code, and clear any errors if present.
278  * param base The LPI2C peripheral base address.
279  * param status Current status flags value that will be checked.
280  * retval #kStatus_Success
281  * retval #kStatus_LPI2C_PinLowTimeout
282  * retval #kStatus_LPI2C_ArbitrationLost
283  * retval #kStatus_LPI2C_Nak
284  * retval #kStatus_LPI2C_FifoError
285  */
LPI2C_MasterCheckAndClearError(LPI2C_Type * base,uint32_t status)286 status_t LPI2C_MasterCheckAndClearError(LPI2C_Type *base, uint32_t status)
287 {
288     status_t result = kStatus_Success;
289 
290     /* Check for error. These errors cause a stop to automatically be sent. We must */
291     /* clear the errors before a new transfer can start. */
292     status &= (uint32_t)kLPI2C_MasterErrorFlags;
293     if (0U != status)
294     {
295         /* Select the correct error code. Ordered by severity, with bus issues first. */
296         if (0U != (status & (uint32_t)kLPI2C_MasterPinLowTimeoutFlag))
297         {
298             result = kStatus_LPI2C_PinLowTimeout;
299         }
300         else if (0U != (status & (uint32_t)kLPI2C_MasterArbitrationLostFlag))
301         {
302             result = kStatus_LPI2C_ArbitrationLost;
303         }
304         else if (0U != (status & (uint32_t)kLPI2C_MasterNackDetectFlag))
305         {
306             result = kStatus_LPI2C_Nak;
307         }
308         /*
309          * $Branch Coverage Justification$
310          * Before that, the state was stripped of other attributes, and it only contained the four brother flags.(will
311          * improve)
312          */
313         else if (0U != (status & (uint32_t)kLPI2C_MasterFifoErrFlag))
314         {
315             result = kStatus_LPI2C_FifoError;
316         }
317         else
318         {
319             ; /* Intentional empty */
320         }
321 
322         /* Clear the flags. */
323         LPI2C_MasterClearStatusFlags(base, status);
324 
325         if (((base->MCFGR1 & LPI2C_MCFGR1_IGNACK_MASK) != 0x00U) && (result == kStatus_LPI2C_Nak))
326         {
327             /* ERR051119: If IGNACK was set and nak detect , we will ignore the Nak status */
328             result = kStatus_Success;
329         }
330         else
331         {
332             /* Reset fifos. These flags clear automatically.*/
333             base->MCR |= LPI2C_MCR_RRF_MASK | LPI2C_MCR_RTF_MASK;
334         }
335     }
336     else
337     {
338         ; /* Intentional empty */
339     }
340 
341     return result;
342 }
343 
344 /*!
345  * @brief Wait until there is room in the tx fifo.
346  * @param base The LPI2C peripheral base address.
347  * @retval #kStatus_Success
348  * @retval #kStatus_LPI2C_PinLowTimeout
349  * @retval #kStatus_LPI2C_ArbitrationLost
350  * @retval #kStatus_LPI2C_Nak
351  * @retval #kStatus_LPI2C_FifoError
352  */
LPI2C_MasterWaitForTxReady(LPI2C_Type * base)353 static status_t LPI2C_MasterWaitForTxReady(LPI2C_Type *base)
354 {
355     status_t result = kStatus_Success;
356     uint32_t status;
357     size_t txCount;
358     size_t txFifoSize = (size_t)FSL_FEATURE_LPI2C_FIFO_SIZEn(base);
359 
360 #if I2C_RETRY_TIMES != 0U
361     uint32_t waitTimes = I2C_RETRY_TIMES;
362 #endif
363     do
364     {
365         /* Get the number of words in the tx fifo and compute empty slots. */
366         LPI2C_MasterGetFifoCounts(base, NULL, &txCount);
367         txCount = txFifoSize - txCount;
368 
369         /* Check for error flags. */
370         status = LPI2C_MasterGetStatusFlags(base);
371         result = LPI2C_MasterCheckAndClearError(base, status);
372         if (kStatus_Success != result)
373         {
374             break;
375         }
376 #if I2C_RETRY_TIMES != 0U
377         waitTimes--;
378     } while ((0U == txCount) && (0U != waitTimes));
379 
380     if (0U == waitTimes)
381     {
382         result = kStatus_LPI2C_Timeout;
383     }
384 #else
385     } while (0U == txCount);
386 #endif
387 
388     return result;
389 }
390 
391 /*!
392  * brief Make sure the bus isn't already busy.
393  *
394  * A busy bus is allowed if we are the one driving it.
395  *
396  * param base The LPI2C peripheral base address.
397  * retval #kStatus_Success
398  * retval #kStatus_LPI2C_Busy
399  */
400 /* Not static so it can be used from fsl_lpi2c_edma.c. */
LPI2C_CheckForBusyBus(LPI2C_Type * base)401 status_t LPI2C_CheckForBusyBus(LPI2C_Type *base)
402 {
403     status_t ret = kStatus_Success;
404 
405     uint32_t status = LPI2C_MasterGetStatusFlags(base);
406     /*
407      * $Branch Coverage Justification$
408      * $ref fsl_lpi2c_c_ref_2$
409      */
410     if ((0U != (status & (uint32_t)kLPI2C_MasterBusBusyFlag)) && (0U == (status & (uint32_t)kLPI2C_MasterBusyFlag)))
411     {
412         ret = kStatus_LPI2C_Busy;
413     }
414 
415     return ret;
416 }
417 
418 /*!
419  * brief Provides a default configuration for the LPI2C master peripheral.
420  *
421  * This function provides the following default configuration for the LPI2C master peripheral:
422  * code
423  *  masterConfig->enableMaster            = true;
424  *  masterConfig->debugEnable             = false;
425  *  masterConfig->ignoreAck               = false;
426  *  masterConfig->pinConfig               = kLPI2C_2PinOpenDrain;
427  *  masterConfig->baudRate_Hz             = 100000U;
428  *  masterConfig->busIdleTimeout_ns       = 0U;
429  *  masterConfig->pinLowTimeout_ns        = 0U;
430  *  masterConfig->sdaGlitchFilterWidth_ns = 0U;
431  *  masterConfig->sclGlitchFilterWidth_ns = 0U;
432  *  masterConfig->hostRequest.enable      = false;
433  *  masterConfig->hostRequest.source      = kLPI2C_HostRequestExternalPin;
434  *  masterConfig->hostRequest.polarity    = kLPI2C_HostRequestPinActiveHigh;
435  * endcode
436  *
437  * After calling this function, you can override any settings in order to customize the configuration,
438  * prior to initializing the master driver with LPI2C_MasterInit().
439  *
440  * param[out] masterConfig User provided configuration structure for default values. Refer to #lpi2c_master_config_t.
441  */
LPI2C_MasterGetDefaultConfig(lpi2c_master_config_t * masterConfig)442 void LPI2C_MasterGetDefaultConfig(lpi2c_master_config_t *masterConfig)
443 {
444     /* Initializes the configure structure to zero. */
445     (void)memset(masterConfig, 0, sizeof(*masterConfig));
446 
447     masterConfig->enableMaster            = true;
448     masterConfig->debugEnable             = false;
449     masterConfig->enableDoze              = true;
450     masterConfig->ignoreAck               = false;
451     masterConfig->pinConfig               = kLPI2C_2PinOpenDrain;
452     masterConfig->baudRate_Hz             = 100000U;
453     masterConfig->busIdleTimeout_ns       = 0U; /* Set to 0 to disable the function */
454     masterConfig->pinLowTimeout_ns        = 0U; /* Set to 0 to disable the function */
455     masterConfig->sdaGlitchFilterWidth_ns = 0U; /* Set to 0 to disable the function */
456     masterConfig->sclGlitchFilterWidth_ns = 0U; /* Set to 0 to disable the function */
457     masterConfig->hostRequest.enable      = false;
458     masterConfig->hostRequest.source      = kLPI2C_HostRequestExternalPin;
459     masterConfig->hostRequest.polarity    = kLPI2C_HostRequestPinActiveHigh;
460 }
461 
462 /*!
463  * brief Initializes the LPI2C master peripheral.
464  *
465  * This function enables the peripheral clock and initializes the LPI2C master peripheral as described by the user
466  * provided configuration. A software reset is performed prior to configuration.
467  *
468  * param base The LPI2C peripheral base address.
469  * param masterConfig User provided peripheral configuration. Use LPI2C_MasterGetDefaultConfig() to get a set of
470  * defaults
471  *      that you can override.
472  * param sourceClock_Hz Frequency in Hertz of the LPI2C functional clock. Used to calculate the baud rate divisors,
473  *      filter widths, and timeout periods.
474  */
LPI2C_MasterInit(LPI2C_Type * base,const lpi2c_master_config_t * masterConfig,uint32_t sourceClock_Hz)475 void LPI2C_MasterInit(LPI2C_Type *base, const lpi2c_master_config_t *masterConfig, uint32_t sourceClock_Hz)
476 {
477     uint32_t prescaler;
478     uint32_t cycles;
479     uint32_t cfgr2;
480     uint32_t value;
481 
482 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
483 
484     uint32_t instance = LPI2C_GetInstance(base);
485 
486     /* Ungate the clock. */
487     (void)CLOCK_EnableClock(kLpi2cClocks[instance]);
488 #if defined(LPI2C_PERIPH_CLOCKS)
489     /* Ungate the functional clock in initialize function. */
490     CLOCK_EnableClock(kLpi2cPeriphClocks[instance]);
491 #endif
492 
493 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
494 
495 #if defined(LPI2C_RESETS_ARRAY)
496     RESET_ReleasePeripheralReset(s_lpi2cResets[LPI2C_GetInstance(base)]);
497 #endif
498 
499     /* Reset peripheral before configuring it. */
500     LPI2C_MasterReset(base);
501 
502     /* Doze bit: 0 is enable, 1 is disable */
503     base->MCR = LPI2C_MCR_DBGEN(masterConfig->debugEnable) | LPI2C_MCR_DOZEN(!(masterConfig->enableDoze));
504 
505     /* host request */
506     value = base->MCFGR0;
507     value &= (~(LPI2C_MCFGR0_HREN_MASK | LPI2C_MCFGR0_HRPOL_MASK | LPI2C_MCFGR0_HRSEL_MASK));
508     value |= LPI2C_MCFGR0_HREN(masterConfig->hostRequest.enable) |
509              LPI2C_MCFGR0_HRPOL(masterConfig->hostRequest.polarity) |
510              LPI2C_MCFGR0_HRSEL(masterConfig->hostRequest.source);
511     base->MCFGR0 = value;
512 
513     /* pin config and ignore ack */
514     value = base->MCFGR1;
515     value &= ~(LPI2C_MCFGR1_PINCFG_MASK | LPI2C_MCFGR1_IGNACK_MASK);
516     value |= LPI2C_MCFGR1_PINCFG(masterConfig->pinConfig);
517     value |= LPI2C_MCFGR1_IGNACK(masterConfig->ignoreAck);
518     base->MCFGR1 = value;
519 
520     LPI2C_MasterSetWatermarks(base, (size_t)kDefaultTxWatermark, (size_t)kDefaultRxWatermark);
521 
522     /* Configure glitch filters. */
523     cfgr2 = base->MCFGR2;
524     if (0U != (masterConfig->sdaGlitchFilterWidth_ns))
525     {
526         /* Calculate SDA filter width. The width is equal to FILTSDA cycles of functional clock.
527            And set FILTSDA to 0 disables the fileter, so the min value is 1. */
528         cycles = LPI2C_GetCyclesForWidth(sourceClock_Hz, masterConfig->sdaGlitchFilterWidth_ns, 1U,
529                                          (LPI2C_MCFGR2_FILTSDA_MASK >> LPI2C_MCFGR2_FILTSDA_SHIFT), 0U);
530         cfgr2 &= ~LPI2C_MCFGR2_FILTSDA_MASK;
531         cfgr2 |= LPI2C_MCFGR2_FILTSDA(cycles);
532     }
533     if (0U != masterConfig->sclGlitchFilterWidth_ns)
534     {
535         /* Calculate SDL filter width. The width is equal to FILTSCL cycles of functional clock.
536            And set FILTSCL to 0 disables the fileter, so the min value is 1. */
537         cycles = LPI2C_GetCyclesForWidth(sourceClock_Hz, masterConfig->sclGlitchFilterWidth_ns, 1U,
538                                          (LPI2C_MCFGR2_FILTSCL_MASK >> LPI2C_MCFGR2_FILTSCL_SHIFT), 0U);
539         cfgr2 &= ~LPI2C_MCFGR2_FILTSCL_MASK;
540         cfgr2 |= LPI2C_MCFGR2_FILTSCL(cycles);
541     }
542     base->MCFGR2 = cfgr2;
543 
544     /* Configure baudrate after the SDA/SCL glitch filter setting,
545        since the baudrate calculation needs them as parameter. */
546     LPI2C_MasterSetBaudRate(base, sourceClock_Hz, masterConfig->baudRate_Hz);
547 
548     /* Configure bus idle and pin low timeouts after baudrate setting,
549        since the timeout calculation needs prescaler as parameter. */
550     prescaler = (base->MCFGR1 & LPI2C_MCFGR1_PRESCALE_MASK) >> LPI2C_MCFGR1_PRESCALE_SHIFT;
551 
552     if (0U != (masterConfig->busIdleTimeout_ns))
553     {
554         /* Calculate bus idle timeout value. The value is equal to BUSIDLE cycles of functional clock divided by
555            prescaler. And set BUSIDLE to 0 disables the fileter, so the min value is 1. */
556         cycles       = LPI2C_GetCyclesForWidth(sourceClock_Hz, masterConfig->busIdleTimeout_ns, 1U,
557                                                (LPI2C_MCFGR2_BUSIDLE_MASK >> LPI2C_MCFGR2_BUSIDLE_SHIFT), prescaler);
558         base->MCFGR2 = (base->MCFGR2 & (~LPI2C_MCFGR2_BUSIDLE_MASK)) | LPI2C_MCFGR2_BUSIDLE(cycles);
559     }
560     if (0U != masterConfig->pinLowTimeout_ns)
561     {
562         /* Calculate bus pin low timeout value. The value is equal to PINLOW cycles of functional clock divided by
563            prescaler. And set PINLOW to 0 disables the fileter, so the min value is 1. */
564         cycles       = LPI2C_GetCyclesForWidth(sourceClock_Hz, masterConfig->pinLowTimeout_ns / 256U, 1U,
565                                                (LPI2C_MCFGR2_BUSIDLE_MASK >> LPI2C_MCFGR2_BUSIDLE_SHIFT), prescaler);
566         base->MCFGR3 = (base->MCFGR3 & ~LPI2C_MCFGR3_PINLOW_MASK) | LPI2C_MCFGR3_PINLOW(cycles);
567     }
568 
569     LPI2C_MasterEnable(base, masterConfig->enableMaster);
570 }
571 
572 /*!
573  * brief Deinitializes the LPI2C master peripheral.
574  *
575  * This function disables the LPI2C master peripheral and gates the clock. It also performs a software
576  * reset to restore the peripheral to reset conditions.
577  *
578  * param base The LPI2C peripheral base address.
579  */
LPI2C_MasterDeinit(LPI2C_Type * base)580 void LPI2C_MasterDeinit(LPI2C_Type *base)
581 {
582     /* Restore to reset state. */
583     LPI2C_MasterReset(base);
584 
585 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
586 
587     uint32_t instance = LPI2C_GetInstance(base);
588 
589     /* Gate clock. */
590     (void)CLOCK_DisableClock(kLpi2cClocks[instance]);
591 #if defined(LPI2C_PERIPH_CLOCKS)
592     /* Gate the functional clock. */
593     CLOCK_DisableClock(kLpi2cPeriphClocks[instance]);
594 #endif
595 
596 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
597 }
598 
599 /*!
600  * brief Configures LPI2C master data match feature.
601  *
602  * param base The LPI2C peripheral base address.
603  * param matchConfig Settings for the data match feature.
604  */
LPI2C_MasterConfigureDataMatch(LPI2C_Type * base,const lpi2c_data_match_config_t * matchConfig)605 void LPI2C_MasterConfigureDataMatch(LPI2C_Type *base, const lpi2c_data_match_config_t *matchConfig)
606 {
607     /* Disable master mode. */
608     bool wasEnabled = (0U != ((base->MCR & LPI2C_MCR_MEN_MASK) >> LPI2C_MCR_MEN_SHIFT));
609     LPI2C_MasterEnable(base, false);
610 
611     base->MCFGR1 = (base->MCFGR1 & ~LPI2C_MCFGR1_MATCFG_MASK) | LPI2C_MCFGR1_MATCFG(matchConfig->matchMode);
612     base->MCFGR0 = (base->MCFGR0 & ~LPI2C_MCFGR0_RDMO_MASK) | LPI2C_MCFGR0_RDMO(matchConfig->rxDataMatchOnly);
613     base->MDMR   = LPI2C_MDMR_MATCH0(matchConfig->match0) | LPI2C_MDMR_MATCH1(matchConfig->match1);
614 
615     /* Restore master mode. */
616     if (wasEnabled)
617     {
618         LPI2C_MasterEnable(base, true);
619     }
620 }
621 
622 /*!
623  * brief Sets the I2C bus frequency for master transactions.
624  *
625  * The LPI2C master is automatically disabled and re-enabled as necessary to configure the baud
626  * rate. Do not call this function during a transfer, or the transfer is aborted.
627  *
628  * note Please note that the second parameter is the clock frequency of LPI2C module, the third
629  * parameter means user configured bus baudrate, this implementation is different from other I2C drivers
630  * which use baudrate configuration as second parameter and source clock frequency as third parameter.
631  *
632  * param base The LPI2C peripheral base address.
633  * param sourceClock_Hz LPI2C functional clock frequency in Hertz.
634  * param baudRate_Hz Requested bus frequency in Hertz.
635  */
LPI2C_MasterSetBaudRate(LPI2C_Type * base,uint32_t sourceClock_Hz,uint32_t baudRate_Hz)636 void LPI2C_MasterSetBaudRate(LPI2C_Type *base, uint32_t sourceClock_Hz, uint32_t baudRate_Hz)
637 {
638     bool wasEnabled;
639     uint8_t filtScl = (uint8_t)((base->MCFGR2 & LPI2C_MCFGR2_FILTSCL_MASK) >> LPI2C_MCFGR2_FILTSCL_SHIFT);
640 
641     uint8_t divider     = 1U;
642     uint8_t bestDivider = 1U;
643     uint8_t prescale    = 0U;
644     uint8_t bestPre     = 0U;
645 
646     uint8_t clkCycle;
647     uint8_t bestclkCycle = 0U;
648 
649     uint32_t absError  = 0U;
650     uint32_t bestError = 0xffffffffu;
651     uint32_t computedRate;
652 
653     uint32_t tmpReg = 0U;
654 
655     /* Disable master mode. */
656     wasEnabled = (0U != ((base->MCR & LPI2C_MCR_MEN_MASK) >> LPI2C_MCR_MEN_SHIFT));
657     LPI2C_MasterEnable(base, false);
658 
659     /* Baud rate = (sourceClock_Hz / 2 ^ prescale) / (CLKLO + 1 + CLKHI + 1 + SCL_LATENCY)
660      * SCL_LATENCY = ROUNDDOWN((2 + FILTSCL) / (2 ^ prescale))
661      */
662     for (prescale = 0U; prescale <= 7U; prescale++)
663     {
664         /* Calculate the clkCycle, clkCycle = CLKLO + CLKHI, divider = 2 ^ prescale */
665         clkCycle = (uint8_t)((10U * sourceClock_Hz / divider / baudRate_Hz + 5U) / 10U - (2U + filtScl) / divider - 2U);
666         /* According to register description, The max value for CLKLO and CLKHI is 63.
667            however to meet the I2C specification of tBUF, CLKHI should be less than
668            clkCycle - 0.52 x sourceClock_Hz / baudRate_Hz / divider + 1U. Refer to the comment of the tmpHigh's
669            calculation for details. So we have:
670            CLKHI < clkCycle - 0.52 x sourceClock_Hz / baudRate_Hz / divider + 1U,
671            clkCycle = CLKHI + CLKLO and
672            sourceClock_Hz / baudRate_Hz / divider = clkCycle + 2 + ROUNDDOWN((2 + FILTSCL) / divider),
673            we can come up with: CLKHI < 0.92 x CLKLO - ROUNDDOWN(2 + FILTSCL) / divider
674            so the max boundary of CLKHI should be 0.92 x 63 - ROUNDDOWN(2 + FILTSCL) / divider,
675            and the max boundary of clkCycle is 1.92 x 63 - ROUNDDOWN(2 + FILTSCL) / divider. */
676         if (clkCycle > (120U - (2U + filtScl) / divider))
677         {
678             divider *= 2U;
679             continue;
680         }
681         /* Calculate the computed baudrate and compare it with the desired baudrate */
682         computedRate = (sourceClock_Hz / (uint32_t)divider) /
683                        ((uint32_t)clkCycle + 2U + (2U + (uint32_t)filtScl) / (uint32_t)divider);
684         absError = baudRate_Hz > computedRate ? baudRate_Hz - computedRate : computedRate - baudRate_Hz;
685         if (absError < bestError)
686         {
687             bestPre      = prescale;
688             bestDivider  = divider;
689             bestclkCycle = clkCycle;
690             bestError    = absError;
691 
692             /* If the error is 0, then we can stop searching because we won't find a better match. */
693             if (absError == 0U)
694             {
695                 break;
696             }
697         }
698         divider *= 2U;
699     }
700 
701     /* SCL low time tLO should be larger than or equal to SCL high time tHI:
702        tLO = ((CLKLO + 1) x (2 ^ PRESCALE)) >= tHI = ((CLKHI + 1 + SCL_LATENCY) x (2 ^ PRESCALE)),
703        which is CLKLO >= CLKHI + (2U + filtScl) / bestDivider.
704        Also since bestclkCycle = CLKLO + CLKHI, bestDivider = 2 ^ PRESCALE
705        which makes CLKHI <= (bestclkCycle - (2U + filtScl) / bestDivider) / 2U.
706 
707        The max tBUF should be at least 0.52 times of the SCL clock cycle:
708        tBUF = ((CLKLO + 1) x (2 ^ PRESCALE) / sourceClock_Hz) > (0.52 / baudRate_Hz),
709        plus bestDivider = 2 ^ PRESCALE, bestclkCycle = CLKLO + CLKHI we can come up with
710        CLKHI <= (bestclkCycle - 0.52 x sourceClock_Hz / baudRate_Hz / bestDivider + 1U).
711        In this case to get a safe CLKHI calculation, we can assume:
712     */
713     uint8_t tmpHigh = (bestclkCycle - (2U + filtScl) / bestDivider) / 2U;
714     while (tmpHigh > (bestclkCycle - 52U * sourceClock_Hz / baudRate_Hz / bestDivider / 100U + 1U))
715     {
716         tmpHigh = tmpHigh - 1U;
717     }
718 
719     /* Calculate DATAVD and SETHOLD.
720        To meet the timing requirement of I2C spec for standard mode, fast mode and fast mode plus: */
721     /* The min tHD:STA/tSU:STA/tSU:STO should be at least 0.4 times of the SCL clock cycle, use 0.5 to be safe:
722        tHD:STA = ((SETHOLD + 1) x (2 ^ PRESCALE) / sourceClock_Hz) > (0.5 / baudRate_Hz), bestDivider = 2 ^ PRESCALE */
723     uint8_t tmpHold = (uint8_t)(sourceClock_Hz / baudRate_Hz / bestDivider / 2U) - 1U;
724 
725     /* The max tVD:DAT/tVD:ACK/tHD:DAT should be at most 0.345 times of the SCL clock cycle, use 0.25 to be safe:
726        tVD:DAT = ((DATAVD + 1) x (2 ^ PRESCALE) / sourceClock_Hz) < (0.25 / baudRate_Hz), bestDivider = 2 ^ PRESCALE */
727     uint8_t tmpDataVd = (uint8_t)(sourceClock_Hz / baudRate_Hz / bestDivider / 4U) - 1U;
728 
729     /* The min tSU:DAT should be at least 0.05 times of the SCL clock cycle:
730        tSU:DAT = ((2 + FILTSDA + 2 ^ PRESCALE) / sourceClock_Hz) >= (0.05 / baud),
731        plus bestDivider = 2 ^ PRESCALE, we can come up with:
732        FILTSDA >= (0.05 x sourceClock_Hz / baudRate_Hz - bestDivider - 2) */
733     if ((sourceClock_Hz / baudRate_Hz / 20U) > (bestDivider + 2U))
734     {
735         /* Read out the FILTSDA configuration, if it is smaller than expected, change the setting. */
736         uint8_t filtSda = (uint8_t)((base->MCFGR2 & LPI2C_MCFGR2_FILTSDA_MASK) >> LPI2C_MCFGR2_FILTSDA_SHIFT);
737         if (filtSda < (sourceClock_Hz / baudRate_Hz / 20U - bestDivider - 2U))
738         {
739             filtSda = (uint8_t)(sourceClock_Hz / baudRate_Hz / 20U) - bestDivider - 2U;
740         }
741         base->MCFGR2 = (base->MCFGR2 & ~LPI2C_MCFGR2_FILTSDA_MASK) | LPI2C_MCFGR2_FILTSDA(filtSda);
742     }
743 
744     /* Set CLKHI, CLKLO, SETHOLD, DATAVD value. */
745     tmpReg = LPI2C_MCCR0_CLKHI((uint32_t)tmpHigh) |
746              LPI2C_MCCR0_CLKLO((uint32_t)((uint32_t)bestclkCycle - (uint32_t)tmpHigh)) |
747              LPI2C_MCCR0_SETHOLD((uint32_t)tmpHold) | LPI2C_MCCR0_DATAVD((uint32_t)tmpDataVd);
748     base->MCCR0 = tmpReg;
749 
750     /* Set PRESCALE value. */
751     base->MCFGR1 = (base->MCFGR1 & ~LPI2C_MCFGR1_PRESCALE_MASK) | LPI2C_MCFGR1_PRESCALE(bestPre);
752 
753     /* Restore master mode. */
754     if (wasEnabled)
755     {
756         LPI2C_MasterEnable(base, true);
757     }
758 }
759 
760 /*!
761  * brief Sends a START signal and slave address on the I2C bus.
762  *
763  * This function is used to initiate a new master mode transfer. First, the bus state is checked to ensure
764  * that another master is not occupying the bus. Then a START signal is transmitted, followed by the
765  * 7-bit address specified in the a address parameter. Note that this function does not actually wait
766  * until the START and address are successfully sent on the bus before returning.
767  *
768  * param base The LPI2C peripheral base address.
769  * param address 7-bit slave device address, in bits [6:0].
770  * param dir Master transfer direction, either #kLPI2C_Read or #kLPI2C_Write. This parameter is used to set
771  *      the R/w bit (bit 0) in the transmitted slave address.
772  * retval #kStatus_Success START signal and address were successfully enqueued in the transmit FIFO.
773  * retval #kStatus_LPI2C_Busy Another master is currently utilizing the bus.
774  */
LPI2C_MasterStart(LPI2C_Type * base,uint8_t address,lpi2c_direction_t dir)775 status_t LPI2C_MasterStart(LPI2C_Type *base, uint8_t address, lpi2c_direction_t dir)
776 {
777     /* Return an error if the bus is already in use not by us. */
778     status_t result = LPI2C_CheckForBusyBus(base);
779     /*
780      * $Branch Coverage Justification$
781      * $ref fsl_lpi2c_c_ref_2$
782      */
783     if (kStatus_Success == result)
784     {
785         /* Clear all flags. */
786         LPI2C_MasterClearStatusFlags(base, (uint32_t)kLPI2C_MasterClearFlags);
787 
788         /* Turn off auto-stop option. */
789         base->MCFGR1 &= ~LPI2C_MCFGR1_AUTOSTOP_MASK;
790 
791         /* Wait until there is room in the fifo. */
792         result = LPI2C_MasterWaitForTxReady(base);
793         if (kStatus_Success == result)
794         {
795             /* Issue start command. */
796             base->MTDR = (uint32_t)kStartCmd | (((uint32_t)address << 1U) | (uint32_t)dir);
797         }
798     }
799 
800     return result;
801 }
802 
803 /*!
804  * brief Sends a STOP signal on the I2C bus.
805  *
806  * This function does not return until the STOP signal is seen on the bus, or an error occurs.
807  *
808  * param base The LPI2C peripheral base address.
809  * retval #kStatus_Success The STOP signal was successfully sent on the bus and the transaction terminated.
810  * retval #kStatus_LPI2C_Busy Another master is currently utilizing the bus.
811  * retval #kStatus_LPI2C_Nak The slave device sent a NAK in response to a byte.
812  * retval #kStatus_LPI2C_FifoError FIFO under run or overrun.
813  * retval #kStatus_LPI2C_ArbitrationLost Arbitration lost error.
814  * retval #kStatus_LPI2C_PinLowTimeout SCL or SDA were held low longer than the timeout.
815  */
LPI2C_MasterStop(LPI2C_Type * base)816 status_t LPI2C_MasterStop(LPI2C_Type *base)
817 {
818     /* Wait until there is room in the fifo. */
819     status_t result = LPI2C_MasterWaitForTxReady(base);
820     if (kStatus_Success == result)
821     {
822         /* Send the STOP signal */
823         base->MTDR = (uint32_t)kStopCmd;
824 
825         /* Wait for the stop detected flag to set, indicating the transfer has completed on the bus. */
826         /* Also check for errors while waiting. */
827 #if I2C_RETRY_TIMES != 0U
828         uint32_t waitTimes = I2C_RETRY_TIMES;
829 #endif
830 
831 #if I2C_RETRY_TIMES != 0U
832         while ((result == kStatus_Success) && (0U != waitTimes))
833         {
834             waitTimes--;
835 #else
836         while (result == kStatus_Success)
837         {
838 #endif
839             uint32_t status = LPI2C_MasterGetStatusFlags(base);
840 
841             /* Check for error flags. */
842             result = LPI2C_MasterCheckAndClearError(base, status);
843 
844             /* Check if the stop was sent successfully. */
845             if ((0U != (status & (uint32_t)kLPI2C_MasterStopDetectFlag)) &&
846                 (0U != (status & (uint32_t)kLPI2C_MasterTxReadyFlag)))
847             {
848                 LPI2C_MasterClearStatusFlags(base, (uint32_t)kLPI2C_MasterStopDetectFlag);
849                 break;
850             }
851         }
852 
853 #if I2C_RETRY_TIMES != 0U
854         if (0U == waitTimes)
855         {
856             result = kStatus_LPI2C_Timeout;
857         }
858 #endif
859     }
860 
861     return result;
862 }
863 
864 /*!
865  * brief Performs a polling receive transfer on the I2C bus.
866  *
867  * param base  The LPI2C peripheral base address.
868  * param rxBuff The pointer to the data to be transferred.
869  * param rxSize The length in bytes of the data to be transferred.
870  * retval #kStatus_Success Data was received successfully.
871  * retval #kStatus_LPI2C_Busy Another master is currently utilizing the bus.
872  * retval #kStatus_LPI2C_Nak The slave device sent a NAK in response to a byte.
873  * retval #kStatus_LPI2C_FifoError FIFO under run or overrun.
874  * retval #kStatus_LPI2C_ArbitrationLost Arbitration lost error.
875  * retval #kStatus_LPI2C_PinLowTimeout SCL or SDA were held low longer than the timeout.
876  */
877 status_t LPI2C_MasterReceive(LPI2C_Type *base, void *rxBuff, size_t rxSize)
878 {
879     assert(NULL != rxBuff);
880 
881     status_t result = kStatus_Success;
882     uint8_t *buf;
883     size_t tmpRxSize = rxSize;
884 #if I2C_RETRY_TIMES != 0U
885     uint32_t waitTimes;
886 #endif
887 
888     /* Check transfer data size. */
889     if (rxSize > ((size_t)256 * (size_t)FSL_FEATURE_LPI2C_FIFO_SIZEn(base)))
890     {
891         return kStatus_InvalidArgument;
892     }
893 
894     /* Handle empty read. */
895     if (rxSize != 0U)
896     {
897         /* Wait until there is room in the command fifo. */
898         result = LPI2C_MasterWaitForTxReady(base);
899         if (kStatus_Success == result)
900         {
901             /* Issue command to receive data. A single write to MTDR can issue read operation of 0xFFU + 1 byte of data
902                at most, so when the rxSize is larger than 0x100U, push multiple read commands to MTDR until rxSize is
903                reached. */
904             while (tmpRxSize != 0U)
905             {
906                 if (tmpRxSize > 256U)
907                 {
908                     base->MTDR = (uint32_t)(kRxDataCmd) | (uint32_t)LPI2C_MTDR_DATA(0xFFU);
909                     tmpRxSize -= 256U;
910                 }
911                 else
912                 {
913                     base->MTDR = (uint32_t)(kRxDataCmd) | (uint32_t)LPI2C_MTDR_DATA(tmpRxSize - 1U);
914                     tmpRxSize  = 0U;
915                 }
916             }
917 
918             /* Receive data */
919             buf = (uint8_t *)rxBuff;
920             while (0U != (rxSize--))
921             {
922 #if I2C_RETRY_TIMES != 0U
923                 waitTimes = I2C_RETRY_TIMES;
924 #endif
925                 /* Read LPI2C receive fifo register. The register includes a flag to indicate whether */
926                 /* the FIFO is empty, so we can both get the data and check if we need to keep reading */
927                 /* using a single register read. */
928                 uint32_t value = 0U;
929                 do
930                 {
931                     /* Check for errors. */
932                     result = LPI2C_MasterCheckAndClearError(base, LPI2C_MasterGetStatusFlags(base));
933                     if (kStatus_Success != result)
934                     {
935                         break;
936                     }
937 
938                     value = base->MRDR;
939 #if I2C_RETRY_TIMES != 0U
940                     waitTimes--;
941                 } while ((0U != (value & LPI2C_MRDR_RXEMPTY_MASK)) && (0U != waitTimes));
942                 if (0U == waitTimes)
943                 {
944                     result = kStatus_LPI2C_Timeout;
945                 }
946 #else
947                 } while (0U != (value & LPI2C_MRDR_RXEMPTY_MASK));
948 #endif
949                 if ((status_t)kStatus_Success != result)
950                 {
951                     break;
952                 }
953 
954                 *buf++ = (uint8_t)(value & LPI2C_MRDR_DATA_MASK);
955             }
956         }
957     }
958 
959     return result;
960 }
961 
962 /*!
963  * brief Performs a polling send transfer on the I2C bus.
964  *
965  * Sends up to a txSize number of bytes to the previously addressed slave device. The slave may
966  * reply with a NAK to any byte in order to terminate the transfer early. If this happens, this
967  * function returns #kStatus_LPI2C_Nak.
968  *
969  * param base  The LPI2C peripheral base address.
970  * param txBuff The pointer to the data to be transferred.
971  * param txSize The length in bytes of the data to be transferred.
972  * retval #kStatus_Success Data was sent successfully.
973  * retval #kStatus_LPI2C_Busy Another master is currently utilizing the bus.
974  * retval #kStatus_LPI2C_Nak The slave device sent a NAK in response to a byte.
975  * retval #kStatus_LPI2C_FifoError FIFO under run or over run.
976  * retval #kStatus_LPI2C_ArbitrationLost Arbitration lost error.
977  * retval #kStatus_LPI2C_PinLowTimeout SCL or SDA were held low longer than the timeout.
978  */
LPI2C_MasterSend(LPI2C_Type * base,void * txBuff,size_t txSize)979 status_t LPI2C_MasterSend(LPI2C_Type *base, void *txBuff, size_t txSize)
980 {
981     status_t result = kStatus_Success;
982     uint8_t *buf    = (uint8_t *)txBuff;
983 
984     assert(NULL != txBuff);
985 
986     /* Send data buffer */
987     while (0U != (txSize--))
988     {
989         /* Wait until there is room in the fifo. This also checks for errors. */
990         result = LPI2C_MasterWaitForTxReady(base);
991         if (kStatus_Success != result)
992         {
993             break;
994         }
995 
996         /* Write byte into LPI2C master data register. */
997         base->MTDR = *buf++;
998     }
999 
1000     return result;
1001 }
1002 
1003 /*!
1004  * brief Performs a master polling transfer on the I2C bus.
1005  *
1006  * note The API does not return until the transfer succeeds or fails due
1007  * to error happens during transfer.
1008  *
1009  * param base The LPI2C peripheral base address.
1010  * param transfer Pointer to the transfer structure.
1011  * retval #kStatus_Success Data was received successfully.
1012  * retval #kStatus_LPI2C_Busy Another master is currently utilizing the bus.
1013  * retval #kStatus_LPI2C_Nak The slave device sent a NAK in response to a byte.
1014  * retval #kStatus_LPI2C_FifoError FIFO under run or overrun.
1015  * retval #kStatus_LPI2C_ArbitrationLost Arbitration lost error.
1016  * retval #kStatus_LPI2C_PinLowTimeout SCL or SDA were held low longer than the timeout.
1017  */
LPI2C_MasterTransferBlocking(LPI2C_Type * base,lpi2c_master_transfer_t * transfer)1018 status_t LPI2C_MasterTransferBlocking(LPI2C_Type *base, lpi2c_master_transfer_t *transfer)
1019 {
1020     assert(NULL != transfer);
1021     assert(transfer->subaddressSize <= sizeof(transfer->subaddress));
1022 
1023     status_t result = kStatus_Success;
1024     uint16_t commandBuffer[7];
1025     uint32_t cmdCount = 0U;
1026 
1027     /* Check transfer data size in read operation. */
1028     if ((transfer->direction == kLPI2C_Read) &&
1029         (transfer->dataSize > ((size_t)256 * (size_t)FSL_FEATURE_LPI2C_FIFO_SIZEn(base))))
1030     {
1031         return kStatus_InvalidArgument;
1032     }
1033 
1034     /* Enable the master function and disable the slave function. */
1035     LPI2C_MasterEnable(base, true);
1036     LPI2C_SlaveEnable(base, false);
1037 
1038     /* Return an error if the bus is already in use not by us. */
1039     result = LPI2C_CheckForBusyBus(base);
1040     /*
1041      * $Branch Coverage Justification$
1042      * $ref fsl_lpi2c_c_ref_2$
1043      */
1044     if (kStatus_Success == result)
1045     {
1046         /* Clear all flags. */
1047         LPI2C_MasterClearStatusFlags(base, (uint32_t)kLPI2C_MasterClearFlags);
1048 
1049         /* Turn off auto-stop option. */
1050         base->MCFGR1 &= ~LPI2C_MCFGR1_AUTOSTOP_MASK;
1051 
1052         lpi2c_direction_t direction = (0U != transfer->subaddressSize) ? kLPI2C_Write : transfer->direction;
1053         if (0U == (transfer->flags & (uint32_t)kLPI2C_TransferNoStartFlag))
1054         {
1055             commandBuffer[cmdCount++] =
1056                 (uint16_t)kStartCmd |
1057                 (uint16_t)((uint16_t)((uint16_t)transfer->slaveAddress << 1U) | (uint16_t)direction);
1058         }
1059 
1060         /* Subaddress, MSB first. */
1061         if (0U != transfer->subaddressSize)
1062         {
1063             uint32_t subaddressRemaining = transfer->subaddressSize;
1064             while (0U != subaddressRemaining--)
1065             {
1066                 uint8_t subaddressByte    = (uint8_t)((transfer->subaddress >> (8U * subaddressRemaining)) & 0xffU);
1067                 commandBuffer[cmdCount++] = subaddressByte;
1068             }
1069         }
1070 
1071         /* Reads need special handling. */
1072         if ((0U != transfer->dataSize) && (transfer->direction == kLPI2C_Read))
1073         {
1074             /* Need to send repeated start if switching directions to read. */
1075             if (direction == kLPI2C_Write)
1076             {
1077                 commandBuffer[cmdCount++] =
1078                     (uint16_t)kStartCmd |
1079                     (uint16_t)((uint16_t)((uint16_t)transfer->slaveAddress << 1U) | (uint16_t)kLPI2C_Read);
1080             }
1081         }
1082 
1083         /* Send command buffer */
1084         uint32_t index = 0U;
1085         while (0U != cmdCount--)
1086         {
1087             /* Wait until there is room in the fifo. This also checks for errors. */
1088             result = LPI2C_MasterWaitForTxReady(base);
1089             if (kStatus_Success != result)
1090             {
1091                 break;
1092             }
1093 
1094             /* Write byte into LPI2C master data register. */
1095             base->MTDR = commandBuffer[index];
1096             index++;
1097         }
1098 
1099         if (kStatus_Success == result)
1100         {
1101             /* Transmit data. */
1102             if ((transfer->direction == kLPI2C_Write) && (transfer->dataSize > 0U))
1103             {
1104                 /* Send Data. */
1105                 result = LPI2C_MasterSend(base, transfer->data, transfer->dataSize);
1106             }
1107 
1108             /* Receive Data. */
1109             if ((transfer->direction == kLPI2C_Read) && (transfer->dataSize > 0U))
1110             {
1111                 result = LPI2C_MasterReceive(base, transfer->data, transfer->dataSize);
1112             }
1113             /*
1114              * $Branch Coverage Justification$
1115              * Errors cannot be simulated by software during transmission.(will improve)
1116              */
1117             if (kStatus_Success == result)
1118             {
1119                 if ((transfer->flags & (uint32_t)kLPI2C_TransferNoStopFlag) == 0U)
1120                 {
1121                     result = LPI2C_MasterStop(base);
1122                 }
1123             }
1124         }
1125 
1126         /* Transmit fail */
1127         if (kStatus_Success != result)
1128         {
1129             if ((transfer->flags & (uint32_t)kLPI2C_TransferNoStopFlag) == 0U)
1130             {
1131                 (void)LPI2C_MasterStop(base);
1132             }
1133         }
1134     }
1135 
1136     return result;
1137 }
1138 
1139 /*!
1140  * brief Creates a new handle for the LPI2C master non-blocking APIs.
1141  *
1142  * The creation of a handle is for use with the non-blocking APIs. Once a handle
1143  * is created, there is not a corresponding destroy handle. If the user wants to
1144  * terminate a transfer, the LPI2C_MasterTransferAbort() API shall be called.
1145  *
1146  *
1147  * note The function also enables the NVIC IRQ for the input LPI2C. Need to notice
1148  * that on some SoCs the LPI2C IRQ is connected to INTMUX, in this case user needs to
1149  * enable the associated INTMUX IRQ in application.
1150  *
1151  * param base The LPI2C peripheral base address.
1152  * param[out] handle Pointer to the LPI2C master driver handle.
1153  * param callback User provided pointer to the asynchronous callback function.
1154  * param userData User provided pointer to the application callback data.
1155  */
LPI2C_MasterTransferCreateHandle(LPI2C_Type * base,lpi2c_master_handle_t * handle,lpi2c_master_transfer_callback_t callback,void * userData)1156 void LPI2C_MasterTransferCreateHandle(LPI2C_Type *base,
1157                                       lpi2c_master_handle_t *handle,
1158                                       lpi2c_master_transfer_callback_t callback,
1159                                       void *userData)
1160 {
1161     uint32_t instance;
1162 
1163     assert(NULL != handle);
1164 
1165     /* Clear out the handle. */
1166     (void)memset(handle, 0, sizeof(*handle));
1167 
1168     /* Look up instance number */
1169     instance = LPI2C_GetInstance(base);
1170 
1171     /* Save base and instance. */
1172     handle->completionCallback = callback;
1173     handle->userData           = userData;
1174 
1175     /* Save this handle for IRQ use. */
1176     s_lpi2cMasterHandle[instance] = handle;
1177 
1178     /* Set irq handler. */
1179     s_lpi2cMasterIsr = LPI2C_MasterTransferHandleIRQ;
1180 
1181     /* Clear internal IRQ enables and enable NVIC IRQ. */
1182     LPI2C_MasterDisableInterrupts(base, (uint32_t)kLPI2C_MasterIrqFlags);
1183 
1184     /* Enable NVIC IRQ, this only enables the IRQ directly connected to the NVIC.
1185      In some cases the LPI2C IRQ is configured through INTMUX, user needs to enable
1186      INTMUX IRQ in application code. */
1187     (void)EnableIRQ(kLpi2cIrqs[instance]);
1188 }
1189 
LPI2C_TransferStateMachineSendCommand(LPI2C_Type * base,lpi2c_master_handle_t * handle,lpi2c_state_machine_param_t * stateParams)1190 static void LPI2C_TransferStateMachineSendCommand(LPI2C_Type *base,
1191                                                   lpi2c_master_handle_t *handle,
1192                                                   lpi2c_state_machine_param_t *stateParams)
1193 {
1194     assert(stateParams != NULL);
1195     uint16_t sendval;
1196 
1197     /* Make sure there is room in the tx fifo for the next command. */
1198     if (0U == (stateParams->txCount)--)
1199     {
1200         stateParams->state_complete = true;
1201         return;
1202     }
1203 
1204     /* Issue command. buf is a uint8_t* pointing at the uint16 command array. */
1205     sendval    = ((uint16_t)handle->buf[0]) | (((uint16_t)handle->buf[1]) << 8U);
1206     base->MTDR = sendval;
1207     handle->buf++;
1208     handle->buf++;
1209 
1210     /* Count down until all commands are sent. */
1211     if (--handle->remainingBytes == 0U)
1212     {
1213         /* Choose next state and set up buffer pointer and count. */
1214         if (0U != handle->transfer.dataSize)
1215         {
1216             /* Either a send or receive transfer is next. */
1217             handle->state          = (uint8_t)kTransferDataState;
1218             handle->buf            = (uint8_t *)handle->transfer.data;
1219             handle->remainingBytes = (uint16_t)handle->transfer.dataSize;
1220             if (handle->transfer.direction == kLPI2C_Read)
1221             {
1222                 /* Disable TX interrupt */
1223                 LPI2C_MasterDisableInterrupts(base, (uint32_t)kLPI2C_MasterTxReadyFlag);
1224                 /* Issue command to receive data. A single write to MTDR can issue read operation of
1225                     0xFFU + 1 byte of data at most, so when the dataSize is larger than 0x100U, push
1226                     multiple read commands to MTDR until dataSize is reached. */
1227                 size_t tmpRxSize = handle->transfer.dataSize;
1228                 while (tmpRxSize != 0U)
1229                 {
1230                     LPI2C_MasterGetFifoCounts(base, NULL, &stateParams->txCount);
1231                     /*
1232                      * $Branch Coverage Justification$
1233                      * The transmission commands will not exceed FIFO SIZE.(will improve)
1234                      */
1235                     while ((size_t)FSL_FEATURE_LPI2C_FIFO_SIZEn(base) == stateParams->txCount)
1236                     {
1237                         LPI2C_MasterGetFifoCounts(base, NULL, &stateParams->txCount);
1238                     }
1239 
1240                     if (tmpRxSize > 256U)
1241                     {
1242                         base->MTDR = (uint32_t)(kRxDataCmd) | (uint32_t)LPI2C_MTDR_DATA(0xFFU);
1243                         tmpRxSize -= 256U;
1244                     }
1245                     else
1246                     {
1247                         base->MTDR = (uint32_t)(kRxDataCmd) | (uint32_t)LPI2C_MTDR_DATA(tmpRxSize - 1U);
1248                         tmpRxSize  = 0U;
1249                     }
1250                 }
1251             }
1252         }
1253         else
1254         {
1255             /* No transfer, so move to stop state. */
1256             handle->state = (uint8_t)kStopState;
1257         }
1258     }
1259 }
1260 
LPI2C_TransferStateMachineReadCommand(LPI2C_Type * base,lpi2c_master_handle_t * handle,lpi2c_state_machine_param_t * stateParams)1261 static void LPI2C_TransferStateMachineReadCommand(LPI2C_Type *base,
1262                                                   lpi2c_master_handle_t *handle,
1263                                                   lpi2c_state_machine_param_t *stateParams)
1264 {
1265     assert(stateParams != NULL);
1266 
1267     /* Make sure there is room in the tx fifo for the read command. */
1268     if (0U == (stateParams->txCount)--)
1269     {
1270         stateParams->state_complete = true;
1271         return;
1272     }
1273 
1274     base->MTDR = (uint32_t)kRxDataCmd | LPI2C_MTDR_DATA(handle->transfer.dataSize - 1U);
1275 
1276     /* Move to transfer state. */
1277     handle->state = (uint8_t)kTransferDataState;
1278     if (handle->transfer.direction == kLPI2C_Read)
1279     {
1280         /* Disable TX interrupt */
1281         LPI2C_MasterDisableInterrupts(base, (uint32_t)kLPI2C_MasterTxReadyFlag);
1282     }
1283 }
1284 
LPI2C_TransferStateMachineTransferData(LPI2C_Type * base,lpi2c_master_handle_t * handle,lpi2c_state_machine_param_t * stateParams)1285 static void LPI2C_TransferStateMachineTransferData(LPI2C_Type *base,
1286                                                    lpi2c_master_handle_t *handle,
1287                                                    lpi2c_state_machine_param_t *stateParams)
1288 {
1289     assert(stateParams != NULL);
1290 
1291     if (handle->transfer.direction == kLPI2C_Write)
1292     {
1293         /* Make sure there is room in the tx fifo. */
1294         if (0U == stateParams->txCount--)
1295         {
1296             stateParams->state_complete = true;
1297             return;
1298         }
1299 
1300         /* Put byte to send in fifo. */
1301         base->MTDR = *(handle->buf)++;
1302     }
1303     else
1304     {
1305         /* XXX handle receive sizes > 256, use kIssueReadCommandState */
1306         /* Make sure there is data in the rx fifo. */
1307         if (0U == stateParams->rxCount--)
1308         {
1309             stateParams->state_complete = true;
1310             return;
1311         }
1312 
1313         /* Read byte from fifo. */
1314         *(handle->buf)++ = (uint8_t)(base->MRDR & LPI2C_MRDR_DATA_MASK);
1315     }
1316 
1317     /* Move to stop when the transfer is done. */
1318     if (--handle->remainingBytes == 0U)
1319     {
1320         if (handle->transfer.direction == kLPI2C_Write)
1321         {
1322             stateParams->state_complete = true;
1323         }
1324         handle->state = (uint8_t)kStopState;
1325     }
1326 }
1327 
LPI2C_TransferStateMachineStopState(LPI2C_Type * base,lpi2c_master_handle_t * handle,lpi2c_state_machine_param_t * stateParams,bool * isDone)1328 static void LPI2C_TransferStateMachineStopState(LPI2C_Type *base,
1329                                                 lpi2c_master_handle_t *handle,
1330                                                 lpi2c_state_machine_param_t *stateParams,
1331                                                 bool *isDone)
1332 {
1333     assert(stateParams != NULL);
1334 
1335     /* Only issue a stop transition if the caller requested it. */
1336     if ((handle->transfer.flags & (uint32_t)kLPI2C_TransferNoStopFlag) == 0U)
1337     {
1338         /* Make sure there is room in the tx fifo for the stop command. */
1339         if (0U == (stateParams->txCount)--)
1340         {
1341             stateParams->state_complete = true;
1342             return;
1343         }
1344 
1345         base->MTDR = (uint32_t)kStopCmd;
1346     }
1347     else
1348     {
1349         /* If all data is read and no stop flag is required to send, we are done. */
1350         if (handle->transfer.direction == kLPI2C_Read)
1351         {
1352             *isDone = true;
1353         }
1354         stateParams->state_complete = true;
1355     }
1356     handle->state = (uint8_t)kWaitForCompletionState;
1357 }
1358 
LPI2C_TransferStateMachineWaitState(LPI2C_Type * base,lpi2c_master_handle_t * handle,lpi2c_state_machine_param_t * stateParams,bool * isDone)1359 static void LPI2C_TransferStateMachineWaitState(LPI2C_Type *base,
1360                                                 lpi2c_master_handle_t *handle,
1361                                                 lpi2c_state_machine_param_t *stateParams,
1362                                                 bool *isDone)
1363 {
1364     assert(stateParams != NULL);
1365 
1366     if ((handle->transfer.flags & (uint32_t)kLPI2C_TransferNoStopFlag) == 0U)
1367     {
1368         /* We stay in this state until the stop state is detected. */
1369         if (0U != ((stateParams->status) & (uint32_t)kLPI2C_MasterStopDetectFlag))
1370         {
1371             *isDone = true;
1372         }
1373     }
1374     else
1375     {
1376         /* If all data is pushed to FIFO and no stop flag is required to send, we need to make sure they
1377             are all send out to bus. */
1378         if ((handle->transfer.direction == kLPI2C_Write) && ((base->MFSR & LPI2C_MFSR_TXCOUNT_MASK) == 0U))
1379         {
1380             /* We stay in this state until the data is sent out to bus. */
1381             *isDone = true;
1382         }
1383     }
1384     stateParams->state_complete = true;
1385 }
1386 
1387 /*!
1388  * @brief Execute states until FIFOs are exhausted.
1389  * @param handle Master nonblocking driver handle.
1390  * @param[out] isDone Set to true if the transfer has completed.
1391  * @retval #kStatus_Success
1392  * @retval #kStatus_LPI2C_PinLowTimeout
1393  * @retval #kStatus_LPI2C_ArbitrationLost
1394  * @retval #kStatus_LPI2C_Nak
1395  * @retval #kStatus_LPI2C_FifoError
1396  */
LPI2C_RunTransferStateMachine(LPI2C_Type * base,lpi2c_master_handle_t * handle,bool * isDone)1397 static status_t LPI2C_RunTransferStateMachine(LPI2C_Type *base, lpi2c_master_handle_t *handle, bool *isDone)
1398 {
1399     assert(NULL != base && NULL != handle && NULL != isDone);
1400 
1401     status_t result = kStatus_Success;
1402     lpi2c_state_machine_param_t stateParams;
1403     (void)memset(&stateParams, 0, sizeof(stateParams));
1404 
1405     stateParams.state_complete = false;
1406 
1407     /* Set default isDone return value. */
1408     *isDone = false;
1409 
1410     /* Check for errors. */
1411     stateParams.status = LPI2C_MasterGetStatusFlags(base);
1412 
1413     /* Get fifo counts. */
1414     LPI2C_MasterGetFifoCounts(base, &stateParams.rxCount, &stateParams.txCount);
1415 
1416     /* For the last byte, nack flag is expected.
1417        Do not check and clear kLPI2C_MasterNackDetectFlag for the last byte,
1418        in case FIFO is emptied when stop command has not been sent. */
1419     if (handle->remainingBytes == 0U)
1420     {
1421         /* When data size is not zero which means it is not only one byte of address is sent, and */
1422         /* when the txfifo is empty, or have one byte which is the stop command, then the nack status can be ignored. */
1423         if (((handle->transfer).dataSize != 0U) &&
1424             ((stateParams.txCount == 0U) ||
1425              (((stateParams.txCount) == 1U) && (handle->state == (uint8_t)kWaitForCompletionState) &&
1426               (((handle->transfer).flags & (uint32_t)kLPI2C_TransferNoStopFlag) == 0U))))
1427         {
1428             (stateParams.status) &= ~(uint32_t)kLPI2C_MasterNackDetectFlag;
1429         }
1430     }
1431 
1432     result = LPI2C_MasterCheckAndClearError(base, stateParams.status);
1433 
1434     if (kStatus_Success == result)
1435     {
1436         /* Compute room in tx fifo */
1437         stateParams.txCount = (size_t)FSL_FEATURE_LPI2C_FIFO_SIZEn(base) - stateParams.txCount;
1438 
1439         while (!stateParams.state_complete)
1440         {
1441             /* Execute the state. */
1442             /*
1443              * $Branch Coverage Justification$
1444              * $ref fsl_lpi2c_c_ref_1$
1445              */
1446             switch (handle->state)
1447             {
1448                 case (uint8_t)kSendCommandState:
1449                     LPI2C_TransferStateMachineSendCommand(base, handle, &stateParams);
1450                     break;
1451 
1452                 case (uint8_t)kIssueReadCommandState:
1453                     LPI2C_TransferStateMachineReadCommand(base, handle, &stateParams);
1454                     break;
1455 
1456                 case (uint8_t)kTransferDataState:
1457                     LPI2C_TransferStateMachineTransferData(base, handle, &stateParams);
1458                     break;
1459 
1460                 case (uint8_t)kStopState:
1461                     LPI2C_TransferStateMachineStopState(base, handle, &stateParams, isDone);
1462                     break;
1463 
1464                 case (uint8_t)kWaitForCompletionState:
1465                     LPI2C_TransferStateMachineWaitState(base, handle, &stateParams, isDone);
1466                     break;
1467                 default:
1468                     assert(false);
1469                     break;
1470             }
1471         }
1472     }
1473     return result;
1474 }
1475 
1476 /*!
1477  * @brief Prepares the transfer state machine and fills in the command buffer.
1478  * @param handle Master nonblocking driver handle.
1479  */
LPI2C_InitTransferStateMachine(lpi2c_master_handle_t * handle)1480 static void LPI2C_InitTransferStateMachine(lpi2c_master_handle_t *handle)
1481 {
1482     lpi2c_master_transfer_t *xfer = &handle->transfer;
1483 
1484     /* Handle no start option. */
1485     if (0U != (xfer->flags & (uint32_t)kLPI2C_TransferNoStartFlag))
1486     {
1487         if (xfer->direction == kLPI2C_Read)
1488         {
1489             /* Need to issue read command first. */
1490             handle->state = (uint8_t)kIssueReadCommandState;
1491         }
1492         else
1493         {
1494             /* Start immediately in the data transfer state. */
1495             handle->state = (uint8_t)kTransferDataState;
1496         }
1497 
1498         handle->buf            = (uint8_t *)xfer->data;
1499         handle->remainingBytes = (uint16_t)xfer->dataSize;
1500     }
1501     else
1502     {
1503         uint16_t *cmd     = (uint16_t *)&handle->commandBuffer;
1504         uint32_t cmdCount = 0U;
1505 
1506         /* Initial direction depends on whether a subaddress was provided, and of course the actual */
1507         /* data transfer direction. */
1508         lpi2c_direction_t direction = (0U != xfer->subaddressSize) ? kLPI2C_Write : xfer->direction;
1509 
1510         /* Start command. */
1511         cmd[cmdCount++] =
1512             (uint16_t)kStartCmd | (uint16_t)((uint16_t)((uint16_t)xfer->slaveAddress << 1U) | (uint16_t)direction);
1513 
1514         /* Subaddress, MSB first. */
1515         if (0U != xfer->subaddressSize)
1516         {
1517             uint32_t subaddressRemaining = xfer->subaddressSize;
1518             while (0U != (subaddressRemaining--))
1519             {
1520                 uint8_t subaddressByte = (uint8_t)((xfer->subaddress >> (8U * subaddressRemaining)) & 0xffU);
1521                 cmd[cmdCount++]        = subaddressByte;
1522             }
1523         }
1524 
1525         /* Reads need special handling. */
1526         if ((0U != xfer->dataSize) && (xfer->direction == kLPI2C_Read))
1527         {
1528             /* Need to send repeated start if switching directions to read. */
1529             if (direction == kLPI2C_Write)
1530             {
1531                 cmd[cmdCount++] = (uint16_t)kStartCmd |
1532                                   (uint16_t)((uint16_t)((uint16_t)xfer->slaveAddress << 1U) | (uint16_t)kLPI2C_Read);
1533             }
1534         }
1535 
1536         /* Set up state machine for transferring the commands. */
1537         handle->state          = (uint8_t)kSendCommandState;
1538         handle->remainingBytes = (uint16_t)cmdCount;
1539         handle->buf            = (uint8_t *)&handle->commandBuffer;
1540     }
1541 }
1542 
1543 /*!
1544  * brief Performs a non-blocking transaction on the I2C bus.
1545  *
1546  * param base The LPI2C peripheral base address.
1547  * param handle Pointer to the LPI2C master driver handle.
1548  * param transfer The pointer to the transfer descriptor.
1549  * retval #kStatus_Success The transaction was started successfully.
1550  * retval #kStatus_LPI2C_Busy Either another master is currently utilizing the bus, or a non-blocking
1551  *      transaction is already in progress.
1552  */
LPI2C_MasterTransferNonBlocking(LPI2C_Type * base,lpi2c_master_handle_t * handle,lpi2c_master_transfer_t * transfer)1553 status_t LPI2C_MasterTransferNonBlocking(LPI2C_Type *base,
1554                                          lpi2c_master_handle_t *handle,
1555                                          lpi2c_master_transfer_t *transfer)
1556 {
1557     assert(NULL != handle);
1558     assert(NULL != transfer);
1559     assert(transfer->subaddressSize <= sizeof(transfer->subaddress));
1560 
1561     status_t result;
1562 
1563     /* Check transfer data size in read operation. */
1564     if ((transfer->direction == kLPI2C_Read) &&
1565         (transfer->dataSize > (256U * (uint32_t)FSL_FEATURE_LPI2C_FIFO_SIZEn(base))))
1566     {
1567         return kStatus_InvalidArgument;
1568     }
1569 
1570     /* Return busy if another transaction is in progress. */
1571     if (handle->state != (uint8_t)kIdleState)
1572     {
1573         result = kStatus_LPI2C_Busy;
1574     }
1575     else
1576     {
1577         result = LPI2C_CheckForBusyBus(base);
1578     }
1579 
1580     if ((status_t)kStatus_Success == result)
1581     {
1582         /* Enable the master function and disable the slave function. */
1583         LPI2C_MasterEnable(base, true);
1584         LPI2C_SlaveEnable(base, false);
1585 
1586         /* Disable LPI2C IRQ sources while we configure stuff. */
1587         LPI2C_MasterDisableInterrupts(base, (uint32_t)kLPI2C_MasterIrqFlags);
1588 
1589         /* Reset FIFO in case there are data. */
1590         base->MCR |= LPI2C_MCR_RRF_MASK | LPI2C_MCR_RTF_MASK;
1591 
1592         /* Save transfer into handle. */
1593         handle->transfer = *transfer;
1594 
1595         /* Generate commands to send. */
1596         LPI2C_InitTransferStateMachine(handle);
1597 
1598         /* Clear all flags. */
1599         LPI2C_MasterClearStatusFlags(base, (uint32_t)kLPI2C_MasterClearFlags);
1600 
1601         /* Turn off auto-stop option. */
1602         base->MCFGR1 &= ~LPI2C_MCFGR1_AUTOSTOP_MASK;
1603 
1604         /* Enable LPI2C internal IRQ sources. NVIC IRQ was enabled in CreateHandle() */
1605         LPI2C_MasterEnableInterrupts(base, (uint32_t)kLPI2C_MasterIrqFlags);
1606     }
1607 
1608     return result;
1609 }
1610 
1611 /*!
1612  * brief Returns number of bytes transferred so far.
1613  * param base The LPI2C peripheral base address.
1614  * param handle Pointer to the LPI2C master driver handle.
1615  * param[out] count Number of bytes transferred so far by the non-blocking transaction.
1616  * retval #kStatus_Success
1617  * retval #kStatus_NoTransferInProgress There is not a non-blocking transaction currently in progress.
1618  */
LPI2C_MasterTransferGetCount(LPI2C_Type * base,lpi2c_master_handle_t * handle,size_t * count)1619 status_t LPI2C_MasterTransferGetCount(LPI2C_Type *base, lpi2c_master_handle_t *handle, size_t *count)
1620 {
1621     status_t result = kStatus_Success;
1622 
1623     assert(NULL != handle);
1624 
1625     if (NULL == count)
1626     {
1627         result = kStatus_InvalidArgument;
1628     }
1629 
1630     /* Catch when there is not an active transfer. */
1631     else if (handle->state == (uint8_t)kIdleState)
1632     {
1633         *count = 0;
1634         result = kStatus_NoTransferInProgress;
1635     }
1636     else
1637     {
1638         uint8_t state;
1639         uint16_t remainingBytes;
1640         uint32_t dataSize;
1641 
1642         /* Cache some fields with IRQs disabled. This ensures all field values */
1643         /* are synchronized with each other during an ongoing transfer. */
1644         uint32_t irqs = LPI2C_MasterGetEnabledInterrupts(base);
1645         LPI2C_MasterDisableInterrupts(base, irqs);
1646         state          = handle->state;
1647         remainingBytes = handle->remainingBytes;
1648         dataSize       = handle->transfer.dataSize;
1649         LPI2C_MasterEnableInterrupts(base, irqs);
1650 
1651         /* Get transfer count based on current transfer state. */
1652         switch (state)
1653         {
1654             case (uint8_t)kIdleState:
1655             case (uint8_t)kSendCommandState:
1656             case (uint8_t)
1657                 kIssueReadCommandState: /* XXX return correct value for this state when >256 reads are supported */
1658                 *count = 0;
1659                 break;
1660 
1661             case (uint8_t)kTransferDataState:
1662                 *count = dataSize - remainingBytes;
1663                 break;
1664 
1665             case (uint8_t)kStopState:
1666             case (uint8_t)kWaitForCompletionState:
1667             default:
1668                 *count = dataSize;
1669                 break;
1670         }
1671     }
1672 
1673     return result;
1674 }
1675 
1676 /*!
1677  * brief Terminates a non-blocking LPI2C master transmission early.
1678  *
1679  * note It is not safe to call this function from an IRQ handler that has a higher priority than the
1680  *      LPI2C peripheral's IRQ priority.
1681  *
1682  * param base The LPI2C peripheral base address.
1683  * param handle Pointer to the LPI2C master driver handle.
1684  */
LPI2C_MasterTransferAbort(LPI2C_Type * base,lpi2c_master_handle_t * handle)1685 void LPI2C_MasterTransferAbort(LPI2C_Type *base, lpi2c_master_handle_t *handle)
1686 {
1687     if (handle->state != (uint8_t)kIdleState)
1688     {
1689         /* Disable internal IRQ enables. */
1690         LPI2C_MasterDisableInterrupts(base, (uint32_t)kLPI2C_MasterIrqFlags);
1691 
1692         /* Reset fifos. */
1693         base->MCR |= LPI2C_MCR_RRF_MASK | LPI2C_MCR_RTF_MASK;
1694 
1695         /* If master is still busy and has not send out stop signal yet. */
1696         if ((LPI2C_MasterGetStatusFlags(base) & ((uint32_t)kLPI2C_MasterStopDetectFlag |
1697                                                  (uint32_t)kLPI2C_MasterBusyFlag)) == (uint32_t)kLPI2C_MasterBusyFlag)
1698         {
1699             /* Send a stop command to finalize the transfer. */
1700             base->MTDR = (uint32_t)kStopCmd;
1701         }
1702 
1703         /* Reset handle. */
1704         handle->state = (uint8_t)kIdleState;
1705     }
1706 }
1707 
1708 /*!
1709  * brief Reusable routine to handle master interrupts.
1710  * note This function does not need to be called unless you are reimplementing the
1711  *  nonblocking API's interrupt handler routines to add special functionality.
1712  * param base The LPI2C peripheral base address.
1713  * param lpi2cMasterHandle Pointer to the LPI2C master driver handle.
1714  */
LPI2C_MasterTransferHandleIRQ(LPI2C_Type * base,void * lpi2cMasterHandle)1715 void LPI2C_MasterTransferHandleIRQ(LPI2C_Type *base, void *lpi2cMasterHandle)
1716 {
1717     assert(lpi2cMasterHandle != NULL);
1718 
1719     lpi2c_master_handle_t *handle = (lpi2c_master_handle_t *)lpi2cMasterHandle;
1720     bool isDone                   = false;
1721     status_t result;
1722 
1723     /* Don't do anything if we don't have a valid handle. */
1724     if (NULL != handle)
1725     {
1726         if (handle->state != (uint8_t)kIdleState)
1727         {
1728             result = LPI2C_RunTransferStateMachine(base, handle, &isDone);
1729 
1730             if ((result != kStatus_Success) || isDone)
1731             {
1732                 /* Handle error, terminate xfer */
1733                 if (result != kStatus_Success)
1734                 {
1735                     LPI2C_MasterTransferAbort(base, handle);
1736                 }
1737 
1738                 /* Disable internal IRQ enables. */
1739                 LPI2C_MasterDisableInterrupts(base, (uint32_t)kLPI2C_MasterIrqFlags);
1740 
1741                 /* Set handle to idle state. */
1742                 handle->state = (uint8_t)kIdleState;
1743 
1744                 /* Invoke callback. */
1745                 if (NULL != handle->completionCallback)
1746                 {
1747                     handle->completionCallback(base, handle, result, handle->userData);
1748                 }
1749             }
1750         }
1751     }
1752 }
1753 
1754 /*!
1755  * brief Provides a default configuration for the LPI2C slave peripheral.
1756  *
1757  * This function provides the following default configuration for the LPI2C slave peripheral:
1758  * code
1759  *  slaveConfig->enableSlave               = true;
1760  *  slaveConfig->address0                  = 0U;
1761  *  slaveConfig->address1                  = 0U;
1762  *  slaveConfig->addressMatchMode          = kLPI2C_MatchAddress0;
1763  *  slaveConfig->filterDozeEnable          = true;
1764  *  slaveConfig->filterEnable              = true;
1765  *  slaveConfig->enableGeneralCall         = false;
1766  *  slaveConfig->sclStall.enableAck        = false;
1767  *  slaveConfig->sclStall.enableTx         = true;
1768  *  slaveConfig->sclStall.enableRx         = true;
1769  *  slaveConfig->sclStall.enableAddress    = true;
1770  *  slaveConfig->ignoreAck                 = false;
1771  *  slaveConfig->enableReceivedAddressRead = false;
1772  *  slaveConfig->sdaGlitchFilterWidth_ns   = 0;
1773  *  slaveConfig->sclGlitchFilterWidth_ns   = 0;
1774  *  slaveConfig->dataValidDelay_ns         = 0;
1775  *  slaveConfig->clockHoldTime_ns          = 0;
1776  * endcode
1777  *
1778  * After calling this function, override any settings  to customize the configuration,
1779  * prior to initializing the master driver with LPI2C_SlaveInit(). Be sure to override at least the a
1780  * address0 member of the configuration structure with the desired slave address.
1781  *
1782  * param[out] slaveConfig User provided configuration structure that is set to default values. Refer to
1783  *      #lpi2c_slave_config_t.
1784  */
LPI2C_SlaveGetDefaultConfig(lpi2c_slave_config_t * slaveConfig)1785 void LPI2C_SlaveGetDefaultConfig(lpi2c_slave_config_t *slaveConfig)
1786 {
1787     /* Initializes the configure structure to zero. */
1788     (void)memset(slaveConfig, 0, sizeof(*slaveConfig));
1789 
1790     slaveConfig->enableSlave               = true;
1791     slaveConfig->address0                  = 0U;
1792     slaveConfig->address1                  = 0U;
1793     slaveConfig->addressMatchMode          = kLPI2C_MatchAddress0;
1794     slaveConfig->filterDozeEnable          = true;
1795     slaveConfig->filterEnable              = true;
1796     slaveConfig->enableGeneralCall         = false;
1797     slaveConfig->sclStall.enableAck        = false;
1798     slaveConfig->sclStall.enableTx         = true;
1799     slaveConfig->sclStall.enableRx         = true;
1800     slaveConfig->sclStall.enableAddress    = false;
1801     slaveConfig->ignoreAck                 = false;
1802     slaveConfig->enableReceivedAddressRead = false;
1803     slaveConfig->sdaGlitchFilterWidth_ns   = 0U; /* Set to 0 to disable the function */
1804     slaveConfig->sclGlitchFilterWidth_ns   = 0U; /* Set to 0 to disable the function */
1805     slaveConfig->dataValidDelay_ns         = 0U;
1806     /* When enabling the slave tx SCL stall, set the default clock hold time to 250ns according
1807        to I2C spec for standard mode baudrate(100k). User can manually change it to 100ns or 50ns
1808        for fast-mode(400k) or fast-mode+(1m). */
1809     slaveConfig->clockHoldTime_ns = 250U;
1810 }
1811 
1812 /*!
1813  * brief Initializes the LPI2C slave peripheral.
1814  *
1815  * This function enables the peripheral clock and initializes the LPI2C slave peripheral as described by the user
1816  * provided configuration.
1817  *
1818  * param base The LPI2C peripheral base address.
1819  * param slaveConfig User provided peripheral configuration. Use LPI2C_SlaveGetDefaultConfig() to get a set of defaults
1820  *      that you can override.
1821  * param sourceClock_Hz Frequency in Hertz of the LPI2C functional clock. Used to calculate the filter widths,
1822  *      data valid delay, and clock hold time.
1823  */
LPI2C_SlaveInit(LPI2C_Type * base,const lpi2c_slave_config_t * slaveConfig,uint32_t sourceClock_Hz)1824 void LPI2C_SlaveInit(LPI2C_Type *base, const lpi2c_slave_config_t *slaveConfig, uint32_t sourceClock_Hz)
1825 {
1826     uint32_t tmpReg;
1827     uint32_t tmpCycle;
1828 
1829 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
1830 
1831     uint32_t instance = LPI2C_GetInstance(base);
1832 
1833     /* Ungate the clock. */
1834     (void)CLOCK_EnableClock(kLpi2cClocks[instance]);
1835 #if defined(LPI2C_PERIPH_CLOCKS)
1836     /* Ungate the functional clock in initialize function. */
1837     CLOCK_EnableClock(kLpi2cPeriphClocks[instance]);
1838 #endif
1839 
1840 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
1841 
1842 #if defined(LPI2C_RESETS_ARRAY)
1843     RESET_ReleasePeripheralReset(s_lpi2cResets[LPI2C_GetInstance(base)]);
1844 #endif
1845 
1846     /* Restore to reset conditions. */
1847     LPI2C_SlaveReset(base);
1848 
1849     /* Configure peripheral. */
1850     base->SAMR = LPI2C_SAMR_ADDR0(slaveConfig->address0) | LPI2C_SAMR_ADDR1(slaveConfig->address1);
1851 
1852     base->SCFGR1 =
1853         LPI2C_SCFGR1_ADDRCFG(slaveConfig->addressMatchMode) | LPI2C_SCFGR1_IGNACK(slaveConfig->ignoreAck) |
1854         LPI2C_SCFGR1_RXCFG(slaveConfig->enableReceivedAddressRead) | LPI2C_SCFGR1_GCEN(slaveConfig->enableGeneralCall) |
1855         LPI2C_SCFGR1_ACKSTALL(slaveConfig->sclStall.enableAck) | LPI2C_SCFGR1_TXDSTALL(slaveConfig->sclStall.enableTx) |
1856         LPI2C_SCFGR1_RXSTALL(slaveConfig->sclStall.enableRx) |
1857         LPI2C_SCFGR1_ADRSTALL(slaveConfig->sclStall.enableAddress);
1858 
1859     /* Calculate SDA filter width. The width is equal to FILTSDA+3 cycles of functional clock.
1860        And set FILTSDA to 0 disables the fileter, so the min value is 4. */
1861     tmpReg = LPI2C_SCFGR2_FILTSDA(
1862         LPI2C_GetCyclesForWidth(sourceClock_Hz, slaveConfig->sdaGlitchFilterWidth_ns, 4U,
1863                                 (LPI2C_SCFGR2_FILTSDA_MASK >> LPI2C_SCFGR2_FILTSDA_SHIFT) + 3U, 0U) -
1864         3U);
1865 
1866     /* Calculate SDL filter width. The width is equal to FILTSCL+3 cycles of functional clock.
1867        And set FILTSCL to 0 disables the fileter, so the min value is 4. */
1868     tmpCycle = LPI2C_GetCyclesForWidth(sourceClock_Hz, slaveConfig->sclGlitchFilterWidth_ns, 4U,
1869                                        (LPI2C_SCFGR2_FILTSCL_MASK >> LPI2C_SCFGR2_FILTSCL_SHIFT) + 3U, 0U);
1870     tmpReg |= LPI2C_SCFGR2_FILTSCL(tmpCycle - 3U);
1871 
1872     /* Calculate data valid time. The time is equal to FILTSCL+DATAVD+3 cycles of functional clock.
1873        So the min value is FILTSCL+3. */
1874     tmpReg |= LPI2C_SCFGR2_DATAVD(
1875         LPI2C_GetCyclesForWidth(sourceClock_Hz, slaveConfig->dataValidDelay_ns, tmpCycle,
1876                                 tmpCycle + (LPI2C_SCFGR2_DATAVD_MASK >> LPI2C_SCFGR2_DATAVD_SHIFT), 0U) -
1877         tmpCycle);
1878 
1879     /* Calculate clock hold time. The time is equal to CLKHOLD+3 cycles of functional clock.
1880        So the min value is 3. */
1881     base->SCFGR2 =
1882         tmpReg | LPI2C_SCFGR2_CLKHOLD(
1883                      LPI2C_GetCyclesForWidth(sourceClock_Hz, slaveConfig->clockHoldTime_ns, 3U,
1884                                              (LPI2C_SCFGR2_CLKHOLD_MASK >> LPI2C_SCFGR2_CLKHOLD_SHIFT) + 3U, 0U) -
1885                      3U);
1886 
1887     /* Save SCR to last so we don't enable slave until it is configured */
1888     base->SCR = LPI2C_SCR_FILTDZ(!slaveConfig->filterDozeEnable) | LPI2C_SCR_FILTEN(slaveConfig->filterEnable) |
1889                 LPI2C_SCR_SEN(slaveConfig->enableSlave);
1890 }
1891 
1892 /*!
1893  * brief Deinitializes the LPI2C slave peripheral.
1894  *
1895  * This function disables the LPI2C slave peripheral and gates the clock. It also performs a software
1896  * reset to restore the peripheral to reset conditions.
1897  *
1898  * param base The LPI2C peripheral base address.
1899  */
LPI2C_SlaveDeinit(LPI2C_Type * base)1900 void LPI2C_SlaveDeinit(LPI2C_Type *base)
1901 {
1902     LPI2C_SlaveReset(base);
1903 
1904 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
1905 
1906     uint32_t instance = LPI2C_GetInstance(base);
1907 
1908     /* Gate the clock. */
1909     (void)CLOCK_DisableClock(kLpi2cClocks[instance]);
1910 
1911 #if defined(LPI2C_PERIPH_CLOCKS)
1912     /* Gate the functional clock. */
1913     CLOCK_DisableClock(kLpi2cPeriphClocks[instance]);
1914 #endif
1915 
1916 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
1917 }
1918 
1919 /*!
1920  * @brief Convert provided flags to status code, and clear any errors if present.
1921  * @param base The LPI2C peripheral base address.
1922  * @param status Current status flags value that will be checked.
1923  * @retval #kStatus_Success
1924  * @retval #kStatus_LPI2C_BitError
1925  * @retval #kStatus_LPI2C_FifoError
1926  */
LPI2C_SlaveCheckAndClearError(LPI2C_Type * base,uint32_t flags)1927 static status_t LPI2C_SlaveCheckAndClearError(LPI2C_Type *base, uint32_t flags)
1928 {
1929     status_t result = kStatus_Success;
1930 
1931     flags &= (uint32_t)kLPI2C_SlaveErrorFlags;
1932     if (0U != flags)
1933     {
1934         /*
1935          * $Branch Coverage Justification$
1936          * It is hard to simulate bitError in automation test environment, need interference on bus.(will improve)
1937          */
1938         if (0U != (flags & (uint32_t)kLPI2C_SlaveBitErrFlag))
1939         {
1940             result = kStatus_LPI2C_BitError;
1941         }
1942         else if (0U != (flags & (uint32_t)kLPI2C_SlaveFifoErrFlag))
1943         {
1944             result = kStatus_LPI2C_FifoError;
1945         }
1946         else
1947         {
1948             ; /* Intentional empty */
1949         }
1950 
1951         /* Clear the errors. */
1952         LPI2C_SlaveClearStatusFlags(base, flags);
1953     }
1954     else
1955     {
1956         ; /* Intentional empty */
1957     }
1958 
1959     return result;
1960 }
1961 
1962 /*!
1963  * brief Performs a polling send transfer on the I2C bus.
1964  *
1965  * param base  The LPI2C peripheral base address.
1966  * param txBuff The pointer to the data to be transferred.
1967  * param txSize The length in bytes of the data to be transferred.
1968  * param[out] actualTxSize
1969  * return Error or success status returned by API.
1970  */
LPI2C_SlaveSend(LPI2C_Type * base,void * txBuff,size_t txSize,size_t * actualTxSize)1971 status_t LPI2C_SlaveSend(LPI2C_Type *base, void *txBuff, size_t txSize, size_t *actualTxSize)
1972 {
1973     status_t result  = kStatus_Success;
1974     uint8_t *buf     = (uint8_t *)txBuff;
1975     size_t remaining = txSize;
1976 
1977     assert(NULL != txBuff);
1978 
1979 #if I2C_RETRY_TIMES != 0U
1980     uint32_t waitTimes = I2C_RETRY_TIMES;
1981 #endif
1982 
1983     /* Clear stop flag. */
1984     LPI2C_SlaveClearStatusFlags(base,
1985                                 (uint32_t)kLPI2C_SlaveStopDetectFlag | (uint32_t)kLPI2C_SlaveRepeatedStartDetectFlag);
1986 
1987     while (0U != remaining)
1988     {
1989         uint32_t flags;
1990 
1991         /* Wait until we can transmit. */
1992         do
1993         {
1994             /* Check for errors */
1995             flags  = LPI2C_SlaveGetStatusFlags(base);
1996             result = LPI2C_SlaveCheckAndClearError(base, flags);
1997             if (kStatus_Success != result)
1998             {
1999                 if (NULL != actualTxSize)
2000                 {
2001                     *actualTxSize = txSize - remaining;
2002                 }
2003                 break;
2004             }
2005 #if I2C_RETRY_TIMES != 0U
2006             waitTimes--;
2007         } while ((0U == (flags & ((uint32_t)kLPI2C_SlaveTxReadyFlag | (uint32_t)kLPI2C_SlaveStopDetectFlag |
2008                                   (uint32_t)kLPI2C_SlaveRepeatedStartDetectFlag))) &&
2009                  (0U != waitTimes));
2010         if (0U == waitTimes)
2011         {
2012             result = kStatus_LPI2C_Timeout;
2013         }
2014 #else
2015         } while (0U == (flags & ((uint32_t)kLPI2C_SlaveTxReadyFlag | (uint32_t)kLPI2C_SlaveStopDetectFlag |
2016                                  (uint32_t)kLPI2C_SlaveRepeatedStartDetectFlag)));
2017 #endif
2018 
2019         if (kStatus_Success != result)
2020         {
2021             break;
2022         }
2023 
2024         /* Send a byte. */
2025         if (0U != (flags & (uint32_t)kLPI2C_SlaveTxReadyFlag))
2026         {
2027             base->STDR = *buf++;
2028             --remaining;
2029         }
2030 
2031         /* Exit loop if we see a stop or restart in transfer*/
2032         /*
2033          * $Branch Coverage Justification$
2034          * $ref fsl_lpi2c_c_ref_3$
2035          */
2036         if ((0U != (flags & ((uint32_t)kLPI2C_SlaveStopDetectFlag | (uint32_t)kLPI2C_SlaveRepeatedStartDetectFlag))) &&
2037             (remaining != 0U))
2038         {
2039             LPI2C_SlaveClearStatusFlags(
2040                 base, (uint32_t)kLPI2C_SlaveStopDetectFlag | (uint32_t)kLPI2C_SlaveRepeatedStartDetectFlag);
2041             break;
2042         }
2043     }
2044 
2045     if (NULL != actualTxSize)
2046     {
2047         *actualTxSize = txSize - remaining;
2048     }
2049 
2050     return result;
2051 }
2052 
2053 /*!
2054  * brief Performs a polling receive transfer on the I2C bus.
2055  *
2056  * param base  The LPI2C peripheral base address.
2057  * param rxBuff The pointer to the data to be transferred.
2058  * param rxSize The length in bytes of the data to be transferred.
2059  * param[out] actualRxSize
2060  * return Error or success status returned by API.
2061  */
LPI2C_SlaveReceive(LPI2C_Type * base,void * rxBuff,size_t rxSize,size_t * actualRxSize)2062 status_t LPI2C_SlaveReceive(LPI2C_Type *base, void *rxBuff, size_t rxSize, size_t *actualRxSize)
2063 {
2064     status_t result  = kStatus_Success;
2065     uint8_t *buf     = (uint8_t *)rxBuff;
2066     size_t remaining = rxSize;
2067 
2068     assert(NULL != rxBuff);
2069 
2070 #if I2C_RETRY_TIMES != 0U
2071     uint32_t waitTimes = I2C_RETRY_TIMES;
2072 #endif
2073 
2074     /* Clear stop flag. */
2075     LPI2C_SlaveClearStatusFlags(base,
2076                                 (uint32_t)kLPI2C_SlaveStopDetectFlag | (uint32_t)kLPI2C_SlaveRepeatedStartDetectFlag);
2077 
2078     while (0U != remaining)
2079     {
2080         uint32_t flags;
2081 
2082         /* Wait until we can receive. */
2083         do
2084         {
2085             /* Check for errors */
2086             flags  = LPI2C_SlaveGetStatusFlags(base);
2087             result = LPI2C_SlaveCheckAndClearError(base, flags);
2088             if (kStatus_Success != result)
2089             {
2090                 if (NULL != actualRxSize)
2091                 {
2092                     *actualRxSize = rxSize - remaining;
2093                 }
2094                 break;
2095             }
2096 #if I2C_RETRY_TIMES != 0U
2097             waitTimes--;
2098         } while ((0U == (flags & ((uint32_t)kLPI2C_SlaveRxReadyFlag | (uint32_t)kLPI2C_SlaveStopDetectFlag |
2099                                   (uint32_t)kLPI2C_SlaveRepeatedStartDetectFlag))) &&
2100                  (0U != waitTimes));
2101         if (0U == waitTimes)
2102         {
2103             result = kStatus_LPI2C_Timeout;
2104         }
2105 #else
2106         } while (0U == (flags & ((uint32_t)kLPI2C_SlaveRxReadyFlag | (uint32_t)kLPI2C_SlaveStopDetectFlag |
2107                                  (uint32_t)kLPI2C_SlaveRepeatedStartDetectFlag)));
2108 #endif
2109 
2110         if ((status_t)kStatus_Success != result)
2111         {
2112             break;
2113         }
2114 
2115         /* Receive a byte. */
2116         if (0U != (flags & (uint32_t)kLPI2C_SlaveRxReadyFlag))
2117         {
2118             *buf++ = (uint8_t)(base->SRDR & LPI2C_SRDR_DATA_MASK);
2119             --remaining;
2120         }
2121 
2122         /* Exit loop if we see a stop or restart */
2123         /*
2124          * $Branch Coverage Justification$
2125          * $ref fsl_lpi2c_c_ref_3$
2126          */
2127         if ((0U != (flags & ((uint32_t)kLPI2C_SlaveStopDetectFlag | (uint32_t)kLPI2C_SlaveRepeatedStartDetectFlag))) &&
2128             (remaining != 0U))
2129         {
2130             LPI2C_SlaveClearStatusFlags(
2131                 base, (uint32_t)kLPI2C_SlaveStopDetectFlag | (uint32_t)kLPI2C_SlaveRepeatedStartDetectFlag);
2132             break;
2133         }
2134     }
2135 
2136     if (NULL != actualRxSize)
2137     {
2138         *actualRxSize = rxSize - remaining;
2139     }
2140 
2141     return result;
2142 }
2143 
2144 /*!
2145  * brief Creates a new handle for the LPI2C slave non-blocking APIs.
2146  *
2147  * The creation of a handle is for use with the non-blocking APIs. Once a handle
2148  * is created, there is not a corresponding destroy handle. If the user wants to
2149  * terminate a transfer, the LPI2C_SlaveTransferAbort() API shall be called.
2150  *
2151  * note The function also enables the NVIC IRQ for the input LPI2C. Need to notice
2152  * that on some SoCs the LPI2C IRQ is connected to INTMUX, in this case user needs to
2153  * enable the associated INTMUX IRQ in application.
2154 
2155  * param base The LPI2C peripheral base address.
2156  * param[out] handle Pointer to the LPI2C slave driver handle.
2157  * param callback User provided pointer to the asynchronous callback function.
2158  * param userData User provided pointer to the application callback data.
2159  */
LPI2C_SlaveTransferCreateHandle(LPI2C_Type * base,lpi2c_slave_handle_t * handle,lpi2c_slave_transfer_callback_t callback,void * userData)2160 void LPI2C_SlaveTransferCreateHandle(LPI2C_Type *base,
2161                                      lpi2c_slave_handle_t *handle,
2162                                      lpi2c_slave_transfer_callback_t callback,
2163                                      void *userData)
2164 {
2165     uint32_t instance;
2166 
2167     assert(NULL != handle);
2168 
2169     /* Clear out the handle. */
2170     (void)memset(handle, 0, sizeof(*handle));
2171 
2172     /* Look up instance number */
2173     instance = LPI2C_GetInstance(base);
2174 
2175     /* Save base and instance. */
2176     handle->callback = callback;
2177     handle->userData = userData;
2178 
2179     /* Save this handle for IRQ use. */
2180     s_lpi2cSlaveHandle[instance] = handle;
2181 
2182     /* Set irq handler. */
2183     s_lpi2cSlaveIsr = LPI2C_SlaveTransferHandleIRQ;
2184 
2185     /* Clear internal IRQ enables and enable NVIC IRQ. */
2186     LPI2C_SlaveDisableInterrupts(base, (uint32_t)kLPI2C_SlaveIrqFlags);
2187     (void)EnableIRQ(kLpi2cIrqs[instance]);
2188 
2189     /* Nack by default. */
2190     base->STAR = LPI2C_STAR_TXNACK_MASK;
2191 }
2192 
2193 /*!
2194  * brief Starts accepting slave transfers.
2195  *
2196  * Call this API after calling I2C_SlaveInit() and LPI2C_SlaveTransferCreateHandle() to start processing
2197  * transactions driven by an I2C master. The slave monitors the I2C bus and pass events to the
2198  * callback that was passed into the call to LPI2C_SlaveTransferCreateHandle(). The callback is always invoked
2199  * from the interrupt context.
2200  *
2201  * The set of events received by the callback is customizable. To do so, set the a eventMask parameter to
2202  * the OR'd combination of #lpi2c_slave_transfer_event_t enumerators for the events you wish to receive.
2203  * The #kLPI2C_SlaveTransmitEvent and #kLPI2C_SlaveReceiveEvent events are always enabled and do not need
2204  * to be included in the mask. Alternatively, you can pass 0 to get a default set of only the transmit and
2205  * receive events that are always enabled. In addition, the #kLPI2C_SlaveAllEvents constant is provided as
2206  * a convenient way to enable all events.
2207  *
2208  * param base The LPI2C peripheral base address.
2209  * param handle Pointer to #lpi2c_slave_handle_t structure which stores the transfer state.
2210  * param eventMask Bit mask formed by OR'ing together #lpi2c_slave_transfer_event_t enumerators to specify
2211  *      which events to send to the callback. Other accepted values are 0 to get a default set of
2212  *      only the transmit and receive events, and #kLPI2C_SlaveAllEvents to enable all events.
2213  *
2214  * retval #kStatus_Success Slave transfers were successfully started.
2215  * retval #kStatus_LPI2C_Busy Slave transfers have already been started on this handle.
2216  */
LPI2C_SlaveTransferNonBlocking(LPI2C_Type * base,lpi2c_slave_handle_t * handle,uint32_t eventMask)2217 status_t LPI2C_SlaveTransferNonBlocking(LPI2C_Type *base, lpi2c_slave_handle_t *handle, uint32_t eventMask)
2218 {
2219     status_t result = kStatus_Success;
2220 
2221     assert(NULL != handle);
2222 
2223     /* Return busy if another transaction is in progress. */
2224     if (handle->isBusy)
2225     {
2226         result = kStatus_LPI2C_Busy;
2227     }
2228     else
2229     {
2230         /* Enable the slave function and disable the master function. */
2231         LPI2C_MasterEnable(base, false);
2232         LPI2C_SlaveEnable(base, true);
2233         /* Return an error if the bus is already in use not by us. */
2234         uint32_t status = LPI2C_SlaveGetStatusFlags(base);
2235         /*
2236          * $Branch Coverage Justification$
2237          * $ref fsl_lpi2c_c_ref_2$
2238          */
2239         if ((0U != (status & (uint32_t)kLPI2C_SlaveBusBusyFlag)) && (0U == (status & (uint32_t)kLPI2C_SlaveBusyFlag)))
2240         {
2241             result = kStatus_LPI2C_Busy;
2242         }
2243     }
2244 
2245     if ((status_t)kStatus_Success == result)
2246     {
2247         /* Disable LPI2C IRQ sources while we configure stuff. */
2248         LPI2C_SlaveDisableInterrupts(base, (uint32_t)kLPI2C_SlaveIrqFlags);
2249 
2250         /* Clear transfer in handle. */
2251         (void)memset(&handle->transfer, 0, sizeof(handle->transfer));
2252 
2253         /* Record that we're busy. */
2254         handle->isBusy = true;
2255 
2256         /* Set up event mask. tx and rx are always enabled. */
2257         handle->eventMask = eventMask | (uint32_t)kLPI2C_SlaveTransmitEvent | (uint32_t)kLPI2C_SlaveReceiveEvent;
2258 
2259         /* Ack by default. */
2260         base->STAR = 0U;
2261 
2262         /* Clear all flags. */
2263         LPI2C_SlaveClearStatusFlags(base, (uint32_t)kLPI2C_SlaveClearFlags);
2264 
2265         /* Enable LPI2C internal IRQ sources. NVIC IRQ was enabled in CreateHandle() */
2266         LPI2C_SlaveEnableInterrupts(base, (uint32_t)kLPI2C_SlaveIrqFlags);
2267     }
2268 
2269     return result;
2270 }
2271 
2272 /*!
2273  * brief Gets the slave transfer status during a non-blocking transfer.
2274  * param base The LPI2C peripheral base address.
2275  * param handle Pointer to i2c_slave_handle_t structure.
2276  * param[out] count Pointer to a value to hold the number of bytes transferred. May be NULL if the count is not
2277  *      required.
2278  * retval #kStatus_Success
2279  * retval #kStatus_NoTransferInProgress
2280  */
LPI2C_SlaveTransferGetCount(LPI2C_Type * base,lpi2c_slave_handle_t * handle,size_t * count)2281 status_t LPI2C_SlaveTransferGetCount(LPI2C_Type *base, lpi2c_slave_handle_t *handle, size_t *count)
2282 {
2283     status_t status = kStatus_Success;
2284 
2285     assert(NULL != handle);
2286 
2287     if (count == NULL)
2288     {
2289         status = kStatus_InvalidArgument;
2290     }
2291 
2292     /* Catch when there is not an active transfer. */
2293     else if (!handle->isBusy)
2294     {
2295         *count = 0;
2296         status = kStatus_NoTransferInProgress;
2297     }
2298 
2299     /* For an active transfer, just return the count from the handle. */
2300     else
2301     {
2302         *count = handle->transferredCount;
2303     }
2304 
2305     return status;
2306 }
2307 
2308 /*!
2309  * brief Aborts the slave non-blocking transfers.
2310  * note This API could be called at any time to stop slave for handling the bus events.
2311  * param base The LPI2C peripheral base address.
2312  * param handle Pointer to #lpi2c_slave_handle_t structure which stores the transfer state.
2313  */
LPI2C_SlaveTransferAbort(LPI2C_Type * base,lpi2c_slave_handle_t * handle)2314 void LPI2C_SlaveTransferAbort(LPI2C_Type *base, lpi2c_slave_handle_t *handle)
2315 {
2316     assert(NULL != handle);
2317 
2318     /* Return idle if no transaction is in progress. */
2319     if (handle->isBusy)
2320     {
2321         /* Disable LPI2C IRQ sources. */
2322         LPI2C_SlaveDisableInterrupts(base, (uint32_t)kLPI2C_SlaveIrqFlags);
2323 
2324         /* Nack by default. */
2325         base->STAR = LPI2C_STAR_TXNACK_MASK;
2326 
2327         /* Reset transfer info. */
2328         (void)memset(&handle->transfer, 0, sizeof(handle->transfer));
2329 
2330         /* We're no longer busy. */
2331         handle->isBusy = false;
2332     }
2333 }
2334 
2335 /*!
2336  * brief Reusable routine to handle slave interrupts.
2337  * note This function does not need to be called unless you are reimplementing the
2338  *  non blocking API's interrupt handler routines to add special functionality.
2339  * param base The LPI2C peripheral base address.
2340  * param handle Pointer to #lpi2c_slave_handle_t structure which stores the transfer state.
2341  */
LPI2C_SlaveTransferHandleIRQ(LPI2C_Type * base,lpi2c_slave_handle_t * handle)2342 void LPI2C_SlaveTransferHandleIRQ(LPI2C_Type *base, lpi2c_slave_handle_t *handle)
2343 {
2344     uint32_t flags;
2345     lpi2c_slave_transfer_t *xfer;
2346 
2347     /* Check for a valid handle in case of a spurious interrupt. */
2348     if (NULL != handle)
2349     {
2350         xfer = &handle->transfer;
2351 
2352         /* Get status flags. */
2353         flags = LPI2C_SlaveGetStatusFlags(base);
2354 
2355         if (0U != (flags & ((uint32_t)kLPI2C_SlaveBitErrFlag | (uint32_t)kLPI2C_SlaveFifoErrFlag)))
2356         {
2357             xfer->event            = kLPI2C_SlaveCompletionEvent;
2358             xfer->completionStatus = LPI2C_SlaveCheckAndClearError(base, flags);
2359 
2360             if ((0U != (handle->eventMask & (uint32_t)kLPI2C_SlaveCompletionEvent)) && (NULL != handle->callback))
2361             {
2362                 handle->callback(base, xfer, handle->userData);
2363             }
2364         }
2365         else
2366         {
2367             if (0U !=
2368                 (flags & (((uint32_t)kLPI2C_SlaveRepeatedStartDetectFlag) | ((uint32_t)kLPI2C_SlaveStopDetectFlag))))
2369             {
2370                 xfer->event            = (0U != (flags & (uint32_t)kLPI2C_SlaveRepeatedStartDetectFlag)) ?
2371                                              kLPI2C_SlaveRepeatedStartEvent :
2372                                              kLPI2C_SlaveCompletionEvent;
2373                 xfer->receivedAddress  = 0U;
2374                 xfer->completionStatus = kStatus_Success;
2375                 xfer->transferredCount = handle->transferredCount;
2376 
2377                 if (xfer->event == kLPI2C_SlaveCompletionEvent)
2378                 {
2379                     handle->isBusy = false;
2380                 }
2381 
2382                 if (handle->wasTransmit)
2383                 {
2384                     /* Subtract one from the transmit count to offset the fact that LPI2C asserts the */
2385                     /* tx flag before it sees the nack from the master-receiver, thus causing one more */
2386                     /* count that the master actually receives. */
2387                     --xfer->transferredCount;
2388                     handle->wasTransmit = false;
2389                 }
2390 
2391                 /* Clear the flag. */
2392                 LPI2C_SlaveClearStatusFlags(base, flags & ((uint32_t)kLPI2C_SlaveRepeatedStartDetectFlag |
2393                                                            (uint32_t)kLPI2C_SlaveStopDetectFlag));
2394 
2395                 /* Revert to sending an Ack by default, in case we sent a Nack for receive. */
2396                 base->STAR = 0U;
2397 
2398                 if ((0U != (handle->eventMask & (uint32_t)xfer->event)) && (NULL != handle->callback))
2399                 {
2400                     handle->callback(base, xfer, handle->userData);
2401                 }
2402 
2403                 if (0U != (flags & (uint32_t)kLPI2C_SlaveStopDetectFlag))
2404                 {
2405                     /* Clean up transfer info on completion, after the callback has been invoked. */
2406                     (void)memset(&handle->transfer, 0, sizeof(handle->transfer));
2407                 }
2408             }
2409             if (0U != (flags & (uint32_t)kLPI2C_SlaveAddressValidFlag))
2410             {
2411                 xfer->event           = kLPI2C_SlaveAddressMatchEvent;
2412                 xfer->receivedAddress = (uint8_t)(base->SASR & LPI2C_SASR_RADDR_MASK);
2413 
2414                 /* Update handle status to busy because slave is addressed. */
2415                 handle->isBusy = true;
2416                 if ((0U != (handle->eventMask & (uint32_t)kLPI2C_SlaveAddressMatchEvent)) && (NULL != handle->callback))
2417                 {
2418                     handle->callback(base, xfer, handle->userData);
2419                 }
2420             }
2421             if (0U != (flags & (uint32_t)kLPI2C_SlaveTransmitAckFlag))
2422             {
2423                 xfer->event = kLPI2C_SlaveTransmitAckEvent;
2424 
2425                 if ((0U != (handle->eventMask & (uint32_t)kLPI2C_SlaveTransmitAckEvent)) && (NULL != handle->callback))
2426                 {
2427                     handle->callback(base, xfer, handle->userData);
2428                 }
2429             }
2430 
2431             /* Handle transmit and receive. */
2432             if (0U != (flags & (uint32_t)kLPI2C_SlaveTxReadyFlag))
2433             {
2434                 handle->wasTransmit = true;
2435 
2436                 /* If we're out of data, invoke callback to get more. */
2437                 if ((NULL == xfer->data) || (0U == xfer->dataSize))
2438                 {
2439                     xfer->event = kLPI2C_SlaveTransmitEvent;
2440                     if (NULL != handle->callback)
2441                     {
2442                         handle->callback(base, xfer, handle->userData);
2443                     }
2444 
2445                     /* Clear the transferred count now that we have a new buffer. */
2446                     handle->transferredCount = 0U;
2447                 }
2448 
2449                 /* Transmit a byte. */
2450                 if ((NULL != xfer->data) && (0U != xfer->dataSize))
2451                 {
2452                     base->STDR = *xfer->data++;
2453                     --xfer->dataSize;
2454                     ++handle->transferredCount;
2455                 }
2456             }
2457             if (0U != (flags & (uint32_t)kLPI2C_SlaveRxReadyFlag))
2458             {
2459                 /* If we're out of room in the buffer, invoke callback to get another. */
2460                 if ((NULL == xfer->data) || (0U == xfer->dataSize))
2461                 {
2462                     xfer->event = kLPI2C_SlaveReceiveEvent;
2463                     if (NULL != handle->callback)
2464                     {
2465                         handle->callback(base, xfer, handle->userData);
2466                     }
2467 
2468                     /* Clear the transferred count now that we have a new buffer. */
2469                     handle->transferredCount = 0U;
2470                 }
2471 
2472                 /* Receive a byte. */
2473                 if ((NULL != xfer->data) && (0U != xfer->dataSize))
2474                 {
2475                     *xfer->data++ = (uint8_t)base->SRDR;
2476                     --xfer->dataSize;
2477                     ++handle->transferredCount;
2478                 }
2479                 else
2480                 {
2481                     /* We don't have any room to receive more data, so send a nack. */
2482                     base->STAR = LPI2C_STAR_TXNACK_MASK;
2483                 }
2484             }
2485         }
2486     }
2487 }
2488 
2489 #if !(defined(FSL_FEATURE_I2C_HAS_NO_IRQ) && FSL_FEATURE_I2C_HAS_NO_IRQ)
2490 /*!
2491  * @brief Shared IRQ handler that can call both master and slave ISRs.
2492  *
2493  * The master and slave ISRs are called through function pointers in order to decouple
2494  * this code from the ISR functions. Without this, the linker would always pull in both
2495  * ISRs and every function they call, even if only the functional API was used.
2496  *
2497  * @param base The LPI2C peripheral base address.
2498  * @param instance The LPI2C peripheral instance number.
2499  */
LPI2C_CommonIRQHandler(LPI2C_Type * base,uint32_t instance)2500 static void LPI2C_CommonIRQHandler(LPI2C_Type *base, uint32_t instance)
2501 {
2502     /* Check for master IRQ. */
2503     if ((0U != (base->MCR & LPI2C_MCR_MEN_MASK)) && (NULL != s_lpi2cMasterIsr))
2504     {
2505         /* Master mode. */
2506         s_lpi2cMasterIsr(base, s_lpi2cMasterHandle[instance]);
2507     }
2508 
2509     /* Check for slave IRQ. */
2510     if ((0U != (base->SCR & LPI2C_SCR_SEN_MASK)) && (NULL != s_lpi2cSlaveIsr))
2511     {
2512         /* Slave mode. */
2513         s_lpi2cSlaveIsr(base, s_lpi2cSlaveHandle[instance]);
2514     }
2515     SDK_ISR_EXIT_BARRIER;
2516 }
2517 #endif
2518 
2519 #if defined(LPI2C0)
2520 /* Implementation of LPI2C0 handler named in startup code. */
2521 void LPI2C0_DriverIRQHandler(void);
LPI2C0_DriverIRQHandler(void)2522 void LPI2C0_DriverIRQHandler(void)
2523 {
2524     LPI2C_CommonIRQHandler(LPI2C0, 0U);
2525 }
2526 #endif
2527 
2528 #if defined(LPI2C1)
2529 /* Implementation of LPI2C1 handler named in startup code. */
2530 void LPI2C1_DriverIRQHandler(void);
LPI2C1_DriverIRQHandler(void)2531 void LPI2C1_DriverIRQHandler(void)
2532 {
2533     LPI2C_CommonIRQHandler(LPI2C1, 1U);
2534 }
2535 #endif
2536 
2537 #if defined(LPI2C2)
2538 /* Implementation of LPI2C2 handler named in startup code. */
2539 void LPI2C2_DriverIRQHandler(void);
LPI2C2_DriverIRQHandler(void)2540 void LPI2C2_DriverIRQHandler(void)
2541 {
2542     LPI2C_CommonIRQHandler(LPI2C2, 2U);
2543 }
2544 #endif
2545 
2546 #if defined(LPI2C3)
2547 /* Implementation of LPI2C3 handler named in startup code. */
2548 void LPI2C3_DriverIRQHandler(void);
LPI2C3_DriverIRQHandler(void)2549 void LPI2C3_DriverIRQHandler(void)
2550 {
2551     LPI2C_CommonIRQHandler(LPI2C3, 3U);
2552 }
2553 #endif
2554 
2555 #if defined(LPI2C4)
2556 /* Implementation of LPI2C4 handler named in startup code. */
2557 void LPI2C4_DriverIRQHandler(void);
LPI2C4_DriverIRQHandler(void)2558 void LPI2C4_DriverIRQHandler(void)
2559 {
2560     LPI2C_CommonIRQHandler(LPI2C4, 4U);
2561 }
2562 #endif
2563 
2564 #if defined(LPI2C5)
2565 /* Implementation of LPI2C5 handler named in startup code. */
2566 void LPI2C5_DriverIRQHandler(void);
LPI2C5_DriverIRQHandler(void)2567 void LPI2C5_DriverIRQHandler(void)
2568 {
2569     LPI2C_CommonIRQHandler(LPI2C5, 5U);
2570 }
2571 #endif
2572 
2573 #if defined(LPI2C6)
2574 /* Implementation of LPI2C6 handler named in startup code. */
2575 void LPI2C6_DriverIRQHandler(void);
LPI2C6_DriverIRQHandler(void)2576 void LPI2C6_DriverIRQHandler(void)
2577 {
2578     LPI2C_CommonIRQHandler(LPI2C6, 6U);
2579 }
2580 #endif
2581 
2582 #if defined(LPI2C7)
2583 /* Implementation of LPI2C7 handler named in startup code. */
2584 void LPI2C7_DriverIRQHandler(void);
LPI2C7_DriverIRQHandler(void)2585 void LPI2C7_DriverIRQHandler(void)
2586 {
2587     LPI2C_CommonIRQHandler(LPI2C7, 7U);
2588 }
2589 #endif
2590 
2591 #if defined(LPI2C8)
2592 /* Implementation of LPI2C8 handler named in startup code. */
2593 void LPI2C8_DriverIRQHandler(void);
LPI2C8_DriverIRQHandler(void)2594 void LPI2C8_DriverIRQHandler(void)
2595 {
2596     LPI2C_CommonIRQHandler(LPI2C8, 8U);
2597 }
2598 #endif
2599 
2600 #if defined(CM4_0__LPI2C)
2601 /* Implementation of CM4_0__LPI2C handler named in startup code. */
2602 void M4_0_LPI2C_DriverIRQHandler(void);
M4_0_LPI2C_DriverIRQHandler(void)2603 void M4_0_LPI2C_DriverIRQHandler(void)
2604 {
2605     LPI2C_CommonIRQHandler(CM4_0__LPI2C, LPI2C_GetInstance(CM4_0__LPI2C));
2606 }
2607 #endif
2608 
2609 #if defined(CM4__LPI2C)
2610 /* Implementation of CM4__LPI2C handler named in startup code. */
2611 void M4_LPI2C_DriverIRQHandler(void);
M4_LPI2C_DriverIRQHandler(void)2612 void M4_LPI2C_DriverIRQHandler(void)
2613 {
2614     LPI2C_CommonIRQHandler(CM4__LPI2C, LPI2C_GetInstance(CM4__LPI2C));
2615 }
2616 #endif
2617 
2618 #if defined(CM4_1__LPI2C)
2619 /* Implementation of CM4_1__LPI2C handler named in startup code. */
2620 void M4_1_LPI2C_DriverIRQHandler(void);
M4_1_LPI2C_DriverIRQHandler(void)2621 void M4_1_LPI2C_DriverIRQHandler(void)
2622 {
2623     LPI2C_CommonIRQHandler(CM4_1__LPI2C, LPI2C_GetInstance(CM4_1__LPI2C));
2624 }
2625 #endif
2626 
2627 #if defined(DMA__LPI2C0)
2628 /* Implementation of DMA__LPI2C0 handler named in startup code. */
2629 void DMA_I2C0_INT_DriverIRQHandler(void);
DMA_I2C0_INT_DriverIRQHandler(void)2630 void DMA_I2C0_INT_DriverIRQHandler(void)
2631 {
2632     LPI2C_CommonIRQHandler(DMA__LPI2C0, LPI2C_GetInstance(DMA__LPI2C0));
2633 }
2634 #endif
2635 
2636 #if defined(DMA__LPI2C1)
2637 /* Implementation of DMA__LPI2C1 handler named in startup code. */
2638 void DMA_I2C1_INT_DriverIRQHandler(void);
DMA_I2C1_INT_DriverIRQHandler(void)2639 void DMA_I2C1_INT_DriverIRQHandler(void)
2640 {
2641     LPI2C_CommonIRQHandler(DMA__LPI2C1, LPI2C_GetInstance(DMA__LPI2C1));
2642 }
2643 #endif
2644 
2645 #if defined(DMA__LPI2C2)
2646 /* Implementation of DMA__LPI2C2 handler named in startup code. */
2647 void DMA_I2C2_INT_DriverIRQHandler(void);
DMA_I2C2_INT_DriverIRQHandler(void)2648 void DMA_I2C2_INT_DriverIRQHandler(void)
2649 {
2650     LPI2C_CommonIRQHandler(DMA__LPI2C2, LPI2C_GetInstance(DMA__LPI2C2));
2651 }
2652 #endif
2653 
2654 #if defined(DMA__LPI2C3)
2655 /* Implementation of DMA__LPI2C3 handler named in startup code. */
2656 void DMA_I2C3_INT_DriverIRQHandler(void);
DMA_I2C3_INT_DriverIRQHandler(void)2657 void DMA_I2C3_INT_DriverIRQHandler(void)
2658 {
2659     LPI2C_CommonIRQHandler(DMA__LPI2C3, LPI2C_GetInstance(DMA__LPI2C3));
2660 }
2661 #endif
2662 
2663 #if defined(DMA__LPI2C4)
2664 /* Implementation of DMA__LPI2C3 handler named in startup code. */
2665 void DMA_I2C4_INT_DriverIRQHandler(void);
DMA_I2C4_INT_DriverIRQHandler(void)2666 void DMA_I2C4_INT_DriverIRQHandler(void)
2667 {
2668     LPI2C_CommonIRQHandler(DMA__LPI2C4, LPI2C_GetInstance(DMA__LPI2C4));
2669 }
2670 #endif
2671 
2672 #if defined(ADMA__LPI2C0)
2673 /* Implementation of DMA__LPI2C0 handler named in startup code. */
2674 void ADMA_I2C0_INT_DriverIRQHandler(void);
ADMA_I2C0_INT_DriverIRQHandler(void)2675 void ADMA_I2C0_INT_DriverIRQHandler(void)
2676 {
2677     LPI2C_CommonIRQHandler(ADMA__LPI2C0, LPI2C_GetInstance(ADMA__LPI2C0));
2678 }
2679 #endif
2680 
2681 #if defined(ADMA__LPI2C1)
2682 /* Implementation of DMA__LPI2C1 handler named in startup code. */
2683 void ADMA_I2C1_INT_DriverIRQHandler(void);
ADMA_I2C1_INT_DriverIRQHandler(void)2684 void ADMA_I2C1_INT_DriverIRQHandler(void)
2685 {
2686     LPI2C_CommonIRQHandler(ADMA__LPI2C1, LPI2C_GetInstance(ADMA__LPI2C1));
2687 }
2688 #endif
2689 
2690 #if defined(ADMA__LPI2C2)
2691 /* Implementation of DMA__LPI2C2 handler named in startup code. */
2692 void ADMA_I2C2_INT_DriverIRQHandler(void);
ADMA_I2C2_INT_DriverIRQHandler(void)2693 void ADMA_I2C2_INT_DriverIRQHandler(void)
2694 {
2695     LPI2C_CommonIRQHandler(ADMA__LPI2C2, LPI2C_GetInstance(ADMA__LPI2C2));
2696 }
2697 #endif
2698 
2699 #if defined(ADMA__LPI2C3)
2700 /* Implementation of DMA__LPI2C3 handler named in startup code. */
2701 void ADMA_I2C3_INT_DriverIRQHandler(void);
ADMA_I2C3_INT_DriverIRQHandler(void)2702 void ADMA_I2C3_INT_DriverIRQHandler(void)
2703 {
2704     LPI2C_CommonIRQHandler(ADMA__LPI2C3, LPI2C_GetInstance(ADMA__LPI2C3));
2705 }
2706 #endif
2707 
2708 #if defined(ADMA__LPI2C4)
2709 /* Implementation of DMA__LPI2C3 handler named in startup code. */
2710 void ADMA_I2C4_INT_DriverIRQHandler(void);
ADMA_I2C4_INT_DriverIRQHandler(void)2711 void ADMA_I2C4_INT_DriverIRQHandler(void)
2712 {
2713     LPI2C_CommonIRQHandler(ADMA__LPI2C4, LPI2C_GetInstance(ADMA__LPI2C4));
2714 }
2715 #endif
2716