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