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