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