1 /*
2 * Copyright (c) 2015, Freescale Semiconductor, Inc.
3 * Copyright 2016-2017 NXP
4 *
5 * Redistribution and use in source and binary forms, with or without modification,
6 * are permitted provided that the following conditions are met:
7 *
8 * o Redistributions of source code must retain the above copyright notice, this list
9 * of conditions and the following disclaimer.
10 *
11 * o Redistributions in binary form must reproduce the above copyright notice, this
12 * list of conditions and the following disclaimer in the documentation and/or
13 * other materials provided with the distribution.
14 *
15 * o Neither the name of the copyright holder nor the names of its
16 * contributors may be used to endorse or promote products derived from this
17 * software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
23 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
26 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30 #include "fsl_i2c.h"
31
32 /*******************************************************************************
33 * Definitions
34 ******************************************************************************/
35
36 /*! @brief i2c transfer state. */
37 enum _i2c_transfer_states
38 {
39 kIdleState = 0x0U, /*!< I2C bus idle. */
40 kCheckAddressState = 0x1U, /*!< 7-bit address check state. */
41 kSendCommandState = 0x2U, /*!< Send command byte phase. */
42 kSendDataState = 0x3U, /*!< Send data transfer phase. */
43 kReceiveDataBeginState = 0x4U, /*!< Receive data transfer phase begin. */
44 kReceiveDataState = 0x5U, /*!< Receive data transfer phase. */
45 };
46
47 /*! @brief Common sets of flags used by the driver. */
48 enum _i2c_flag_constants
49 {
50 /*! All flags which are cleared by the driver upon starting a transfer. */
51 #if defined(FSL_FEATURE_I2C_HAS_START_STOP_DETECT) && FSL_FEATURE_I2C_HAS_START_STOP_DETECT
52 kClearFlags = kI2C_ArbitrationLostFlag | kI2C_IntPendingFlag | kI2C_StartDetectFlag | kI2C_StopDetectFlag,
53 kIrqFlags = kI2C_GlobalInterruptEnable | kI2C_StartStopDetectInterruptEnable,
54 #elif defined(FSL_FEATURE_I2C_HAS_STOP_DETECT) && FSL_FEATURE_I2C_HAS_STOP_DETECT
55 kClearFlags = kI2C_ArbitrationLostFlag | kI2C_IntPendingFlag | kI2C_StopDetectFlag,
56 kIrqFlags = kI2C_GlobalInterruptEnable | kI2C_StopDetectInterruptEnable,
57 #else
58 kClearFlags = kI2C_ArbitrationLostFlag | kI2C_IntPendingFlag,
59 kIrqFlags = kI2C_GlobalInterruptEnable,
60 #endif
61
62 };
63
64 /*! @brief Typedef for interrupt handler. */
65 typedef void (*i2c_isr_t)(I2C_Type *base, void *i2cHandle);
66
67 /*******************************************************************************
68 * Prototypes
69 ******************************************************************************/
70
71 /*!
72 * @brief Get instance number for I2C module.
73 *
74 * @param base I2C peripheral base address.
75 */
76 uint32_t I2C_GetInstance(I2C_Type *base);
77
78 /*!
79 * @brief Set SCL/SDA hold time, this API receives SCL stop hold time, calculate the
80 * closest SCL divider and MULT value for the SDA hold time, SCL start and SCL stop
81 * hold time. To reduce the ROM size, SDA/SCL hold value mapping table is not provided,
82 * assume SCL divider = SCL stop hold value *2 to get the closest SCL divider value and MULT
83 * value, then the related SDA hold time, SCL start and SCL stop hold time is used.
84 *
85 * @param base I2C peripheral base address.
86 * @param sourceClock_Hz I2C functional clock frequency in Hertz.
87 * @param sclStopHoldTime_ns SCL stop hold time in ns.
88 */
89 static void I2C_SetHoldTime(I2C_Type *base, uint32_t sclStopHoldTime_ns, uint32_t sourceClock_Hz);
90
91 /*!
92 * @brief Set up master transfer, send slave address and decide the initial
93 * transfer state.
94 *
95 * @param base I2C peripheral base address.
96 * @param handle pointer to i2c_master_handle_t structure which stores the transfer state.
97 * @param xfer pointer to i2c_master_transfer_t structure.
98 */
99 static status_t I2C_InitTransferStateMachine(I2C_Type *base, i2c_master_handle_t *handle, i2c_master_transfer_t *xfer);
100
101 /*!
102 * @brief Check and clear status operation.
103 *
104 * @param base I2C peripheral base address.
105 * @param status current i2c hardware status.
106 * @retval kStatus_Success No error found.
107 * @retval kStatus_I2C_ArbitrationLost Transfer error, arbitration lost.
108 * @retval kStatus_I2C_Nak Received Nak error.
109 */
110 static status_t I2C_CheckAndClearError(I2C_Type *base, uint32_t status);
111
112 /*!
113 * @brief Master run transfer state machine to perform a byte of transfer.
114 *
115 * @param base I2C peripheral base address.
116 * @param handle pointer to i2c_master_handle_t structure which stores the transfer state
117 * @param isDone input param to get whether the thing is done, true is done
118 * @retval kStatus_Success No error found.
119 * @retval kStatus_I2C_ArbitrationLost Transfer error, arbitration lost.
120 * @retval kStatus_I2C_Nak Received Nak error.
121 * @retval kStatus_I2C_Timeout Transfer error, wait signal timeout.
122 */
123 static status_t I2C_MasterTransferRunStateMachine(I2C_Type *base, i2c_master_handle_t *handle, bool *isDone);
124
125 /*!
126 * @brief I2C common interrupt handler.
127 *
128 * @param base I2C peripheral base address.
129 * @param handle pointer to i2c_master_handle_t structure which stores the transfer state
130 */
131 static void I2C_TransferCommonIRQHandler(I2C_Type *base, void *handle);
132
133 /*******************************************************************************
134 * Variables
135 ******************************************************************************/
136
137 /*! @brief Pointers to i2c handles for each instance. */
138 static void *s_i2cHandle[FSL_FEATURE_SOC_I2C_COUNT] = {NULL};
139
140 /*! @brief SCL clock divider used to calculate baudrate. */
141 static const uint16_t s_i2cDividerTable[] = {
142 20, 22, 24, 26, 28, 30, 34, 40, 28, 32, 36, 40, 44, 48, 56, 68,
143 48, 56, 64, 72, 80, 88, 104, 128, 80, 96, 112, 128, 144, 160, 192, 240,
144 160, 192, 224, 256, 288, 320, 384, 480, 320, 384, 448, 512, 576, 640, 768, 960,
145 640, 768, 896, 1024, 1152, 1280, 1536, 1920, 1280, 1536, 1792, 2048, 2304, 2560, 3072, 3840};
146
147 /*! @brief Pointers to i2c bases for each instance. */
148 static I2C_Type *const s_i2cBases[] = I2C_BASE_PTRS;
149
150 /*! @brief Pointers to i2c IRQ number for each instance. */
151 static const IRQn_Type s_i2cIrqs[] = I2C_IRQS;
152
153 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
154 /*! @brief Pointers to i2c clocks for each instance. */
155 static const clock_ip_name_t s_i2cClocks[] = I2C_CLOCKS;
156 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
157
158 /*! @brief Pointer to master IRQ handler for each instance. */
159 static i2c_isr_t s_i2cMasterIsr;
160
161 /*! @brief Pointer to slave IRQ handler for each instance. */
162 static i2c_isr_t s_i2cSlaveIsr;
163
164 /*******************************************************************************
165 * Codes
166 ******************************************************************************/
167
I2C_GetInstance(I2C_Type * base)168 uint32_t I2C_GetInstance(I2C_Type *base)
169 {
170 uint32_t instance;
171
172 /* Find the instance index from base address mappings. */
173 for (instance = 0; instance < ARRAY_SIZE(s_i2cBases); instance++)
174 {
175 if (s_i2cBases[instance] == base)
176 {
177 break;
178 }
179 }
180
181 assert(instance < ARRAY_SIZE(s_i2cBases));
182
183 return instance;
184 }
185
I2C_SetHoldTime(I2C_Type * base,uint32_t sclStopHoldTime_ns,uint32_t sourceClock_Hz)186 static void I2C_SetHoldTime(I2C_Type *base, uint32_t sclStopHoldTime_ns, uint32_t sourceClock_Hz)
187 {
188 uint32_t multiplier;
189 uint32_t computedSclHoldTime;
190 uint32_t absError;
191 uint32_t bestError = UINT32_MAX;
192 uint32_t bestMult = 0u;
193 uint32_t bestIcr = 0u;
194 uint8_t mult;
195 uint8_t i;
196
197 /* Search for the settings with the lowest error. Mult is the MULT field of the I2C_F register,
198 * and ranges from 0-2. It selects the multiplier factor for the divider. */
199 /* SDA hold time = bus period (s) * mul * SDA hold value. */
200 /* SCL start hold time = bus period (s) * mul * SCL start hold value. */
201 /* SCL stop hold time = bus period (s) * mul * SCL stop hold value. */
202
203 for (mult = 0u; (mult <= 2u) && (bestError != 0); ++mult)
204 {
205 multiplier = 1u << mult;
206
207 /* Scan table to find best match. */
208 for (i = 0u; i < sizeof(s_i2cDividerTable) / sizeof(s_i2cDividerTable[0]); ++i)
209 {
210 /* Assume SCL hold(stop) value = s_i2cDividerTable[i]/2. */
211 computedSclHoldTime = ((multiplier * s_i2cDividerTable[i]) * 500000000U) / sourceClock_Hz;
212 absError = sclStopHoldTime_ns > computedSclHoldTime ? (sclStopHoldTime_ns - computedSclHoldTime) :
213 (computedSclHoldTime - sclStopHoldTime_ns);
214
215 if (absError < bestError)
216 {
217 bestMult = mult;
218 bestIcr = i;
219 bestError = absError;
220
221 /* If the error is 0, then we can stop searching because we won't find a better match. */
222 if (absError == 0)
223 {
224 break;
225 }
226 }
227 }
228 }
229
230 /* Set frequency register based on best settings. */
231 base->F = I2C_F_MULT(bestMult) | I2C_F_ICR(bestIcr);
232 }
233
I2C_InitTransferStateMachine(I2C_Type * base,i2c_master_handle_t * handle,i2c_master_transfer_t * xfer)234 static status_t I2C_InitTransferStateMachine(I2C_Type *base, i2c_master_handle_t *handle, i2c_master_transfer_t *xfer)
235 {
236 status_t result = kStatus_Success;
237 i2c_direction_t direction = xfer->direction;
238
239 /* Initialize the handle transfer information. */
240 handle->transfer = *xfer;
241
242 /* Save total transfer size. */
243 handle->transferSize = xfer->dataSize;
244
245 /* Initial transfer state. */
246 if (handle->transfer.subaddressSize > 0)
247 {
248 if (xfer->direction == kI2C_Read)
249 {
250 direction = kI2C_Write;
251 }
252 }
253
254 handle->state = kCheckAddressState;
255
256 /* Clear all status before transfer. */
257 I2C_MasterClearStatusFlags(base, kClearFlags);
258
259 /* If repeated start is requested, send repeated start. */
260 if (handle->transfer.flags & kI2C_TransferRepeatedStartFlag)
261 {
262 result = I2C_MasterRepeatedStart(base, handle->transfer.slaveAddress, direction);
263 }
264 else /* For normal transfer, send start. */
265 {
266 result = I2C_MasterStart(base, handle->transfer.slaveAddress, direction);
267 }
268
269 return result;
270 }
271
I2C_CheckAndClearError(I2C_Type * base,uint32_t status)272 static status_t I2C_CheckAndClearError(I2C_Type *base, uint32_t status)
273 {
274 status_t result = kStatus_Success;
275
276 /* Check arbitration lost. */
277 if (status & kI2C_ArbitrationLostFlag)
278 {
279 /* Clear arbitration lost flag. */
280 base->S = kI2C_ArbitrationLostFlag;
281 result = kStatus_I2C_ArbitrationLost;
282 }
283 /* Check NAK */
284 else if (status & kI2C_ReceiveNakFlag)
285 {
286 result = kStatus_I2C_Nak;
287 }
288 else
289 {
290 }
291
292 return result;
293 }
294
I2C_MasterTransferRunStateMachine(I2C_Type * base,i2c_master_handle_t * handle,bool * isDone)295 static status_t I2C_MasterTransferRunStateMachine(I2C_Type *base, i2c_master_handle_t *handle, bool *isDone)
296 {
297 status_t result = kStatus_Success;
298 uint32_t statusFlags = base->S;
299 *isDone = false;
300 volatile uint8_t dummy = 0;
301 bool ignoreNak = ((handle->state == kSendDataState) && (handle->transfer.dataSize == 0U)) ||
302 ((handle->state == kReceiveDataState) && (handle->transfer.dataSize == 1U));
303
304 /* Add this to avoid build warning. */
305 dummy++;
306
307 /* Check & clear error flags. */
308 result = I2C_CheckAndClearError(base, statusFlags);
309
310 /* Ignore Nak when it's appeared for last byte. */
311 if ((result == kStatus_I2C_Nak) && ignoreNak)
312 {
313 result = kStatus_Success;
314 }
315
316 /* Handle Check address state to check the slave address is Acked in slave
317 probe application. */
318 if (handle->state == kCheckAddressState)
319 {
320 if (statusFlags & kI2C_ReceiveNakFlag)
321 {
322 result = kStatus_I2C_Addr_Nak;
323 }
324 else
325 {
326 if (handle->transfer.subaddressSize > 0)
327 {
328 handle->state = kSendCommandState;
329 }
330 else
331 {
332 if (handle->transfer.direction == kI2C_Write)
333 {
334 /* Next state, send data. */
335 handle->state = kSendDataState;
336 }
337 else
338 {
339 /* Next state, receive data begin. */
340 handle->state = kReceiveDataBeginState;
341 }
342 }
343 }
344 }
345
346 if (result)
347 {
348 return result;
349 }
350
351 /* Run state machine. */
352 switch (handle->state)
353 {
354 /* Send I2C command. */
355 case kSendCommandState:
356 if (handle->transfer.subaddressSize)
357 {
358 handle->transfer.subaddressSize--;
359 base->D = ((handle->transfer.subaddress) >> (8 * handle->transfer.subaddressSize));
360 }
361 else
362 {
363 if (handle->transfer.direction == kI2C_Write)
364 {
365 /* Next state, send data. */
366 handle->state = kSendDataState;
367
368 /* Send first byte of data. */
369 if (handle->transfer.dataSize > 0)
370 {
371 base->D = *handle->transfer.data;
372 handle->transfer.data++;
373 handle->transfer.dataSize--;
374 }
375 }
376 else
377 {
378 /* Send repeated start and slave address. */
379 result = I2C_MasterRepeatedStart(base, handle->transfer.slaveAddress, kI2C_Read);
380
381 /* Next state, receive data begin. */
382 handle->state = kReceiveDataBeginState;
383 }
384 }
385 break;
386
387 /* Send I2C data. */
388 case kSendDataState:
389 /* Send one byte of data. */
390 if (handle->transfer.dataSize > 0)
391 {
392 base->D = *handle->transfer.data;
393 handle->transfer.data++;
394 handle->transfer.dataSize--;
395 }
396 else
397 {
398 *isDone = true;
399 }
400 break;
401
402 /* Start I2C data receive. */
403 case kReceiveDataBeginState:
404 base->C1 &= ~(I2C_C1_TX_MASK | I2C_C1_TXAK_MASK);
405
406 /* Send nak at the last receive byte. */
407 if (handle->transfer.dataSize == 1)
408 {
409 base->C1 |= I2C_C1_TXAK_MASK;
410 }
411
412 /* Read dummy to release the bus. */
413 dummy = base->D;
414
415 /* Next state, receive data. */
416 handle->state = kReceiveDataState;
417 break;
418
419 /* Receive I2C data. */
420 case kReceiveDataState:
421 /* Receive one byte of data. */
422 if (handle->transfer.dataSize--)
423 {
424 if (handle->transfer.dataSize == 0)
425 {
426 *isDone = true;
427
428 /* Send stop if kI2C_TransferNoStop is not asserted. */
429 if (!(handle->transfer.flags & kI2C_TransferNoStopFlag))
430 {
431 result = I2C_MasterStop(base);
432 }
433 else
434 {
435 base->C1 |= I2C_C1_TX_MASK;
436 }
437 }
438
439 /* Send NAK at the last receive byte. */
440 if (handle->transfer.dataSize == 1)
441 {
442 base->C1 |= I2C_C1_TXAK_MASK;
443 }
444
445 /* Read the data byte into the transfer buffer. */
446 *handle->transfer.data = base->D;
447 handle->transfer.data++;
448 }
449 break;
450
451 default:
452 break;
453 }
454
455 return result;
456 }
457
I2C_TransferCommonIRQHandler(I2C_Type * base,void * handle)458 static void I2C_TransferCommonIRQHandler(I2C_Type *base, void *handle)
459 {
460 /* Check if master interrupt. */
461 if ((base->S & kI2C_ArbitrationLostFlag) || (base->C1 & I2C_C1_MST_MASK))
462 {
463 s_i2cMasterIsr(base, handle);
464 }
465 else
466 {
467 s_i2cSlaveIsr(base, handle);
468 }
469 __DSB();
470 }
471
I2C_MasterInit(I2C_Type * base,const i2c_master_config_t * masterConfig,uint32_t srcClock_Hz)472 void I2C_MasterInit(I2C_Type *base, const i2c_master_config_t *masterConfig, uint32_t srcClock_Hz)
473 {
474 assert(masterConfig && srcClock_Hz);
475
476 /* Temporary register for filter read. */
477 uint8_t fltReg;
478 #if defined(FSL_FEATURE_I2C_HAS_DOUBLE_BUFFER_ENABLE) && FSL_FEATURE_I2C_HAS_DOUBLE_BUFFER_ENABLE
479 uint8_t s2Reg;
480 #endif
481 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
482 /* Enable I2C clock. */
483 CLOCK_EnableClock(s_i2cClocks[I2C_GetInstance(base)]);
484 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
485
486 /* Reset the module. */
487 base->A1 = 0;
488 base->F = 0;
489 base->C1 = 0;
490 base->S = 0xFFU;
491 base->C2 = 0;
492 #if defined(FSL_FEATURE_I2C_HAS_START_STOP_DETECT) && FSL_FEATURE_I2C_HAS_START_STOP_DETECT
493 base->FLT = 0x50U;
494 #elif defined(FSL_FEATURE_I2C_HAS_STOP_DETECT) && FSL_FEATURE_I2C_HAS_STOP_DETECT
495 base->FLT = 0x40U;
496 #endif
497 base->RA = 0;
498
499 /* Disable I2C prior to configuring it. */
500 base->C1 &= ~(I2C_C1_IICEN_MASK);
501
502 /* Clear all flags. */
503 I2C_MasterClearStatusFlags(base, kClearFlags);
504
505 /* Configure baud rate. */
506 I2C_MasterSetBaudRate(base, masterConfig->baudRate_Bps, srcClock_Hz);
507
508 /* Read out the FLT register. */
509 fltReg = base->FLT;
510
511 #if defined(FSL_FEATURE_I2C_HAS_STOP_HOLD_OFF) && FSL_FEATURE_I2C_HAS_STOP_HOLD_OFF
512 /* Configure the stop / hold enable. */
513 fltReg &= ~(I2C_FLT_SHEN_MASK);
514 fltReg |= I2C_FLT_SHEN(masterConfig->enableStopHold);
515 #endif
516
517 /* Configure the glitch filter value. */
518 fltReg &= ~(I2C_FLT_FLT_MASK);
519 fltReg |= I2C_FLT_FLT(masterConfig->glitchFilterWidth);
520
521 /* Write the register value back to the filter register. */
522 base->FLT = fltReg;
523
524 /* Enable/Disable double buffering. */
525 #if defined(FSL_FEATURE_I2C_HAS_DOUBLE_BUFFER_ENABLE) && FSL_FEATURE_I2C_HAS_DOUBLE_BUFFER_ENABLE
526 s2Reg = base->S2 & (~I2C_S2_DFEN_MASK);
527 base->S2 = s2Reg | I2C_S2_DFEN(masterConfig->enableDoubleBuffering);
528 #endif
529
530 /* Enable the I2C peripheral based on the configuration. */
531 base->C1 = I2C_C1_IICEN(masterConfig->enableMaster);
532 }
533
I2C_MasterDeinit(I2C_Type * base)534 void I2C_MasterDeinit(I2C_Type *base)
535 {
536 /* Disable I2C module. */
537 I2C_Enable(base, false);
538
539 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
540 /* Disable I2C clock. */
541 CLOCK_DisableClock(s_i2cClocks[I2C_GetInstance(base)]);
542 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
543 }
544
I2C_MasterGetDefaultConfig(i2c_master_config_t * masterConfig)545 void I2C_MasterGetDefaultConfig(i2c_master_config_t *masterConfig)
546 {
547 assert(masterConfig);
548
549 /* Default baud rate at 100kbps. */
550 masterConfig->baudRate_Bps = 100000U;
551
552 /* Default stop hold enable is disabled. */
553 #if defined(FSL_FEATURE_I2C_HAS_STOP_HOLD_OFF) && FSL_FEATURE_I2C_HAS_STOP_HOLD_OFF
554 masterConfig->enableStopHold = false;
555 #endif
556
557 /* Default glitch filter value is no filter. */
558 masterConfig->glitchFilterWidth = 0U;
559
560 /* Default enable double buffering. */
561 #if defined(FSL_FEATURE_I2C_HAS_DOUBLE_BUFFER_ENABLE) && FSL_FEATURE_I2C_HAS_DOUBLE_BUFFER_ENABLE
562 masterConfig->enableDoubleBuffering = true;
563 #endif
564
565 /* Enable the I2C peripheral. */
566 masterConfig->enableMaster = true;
567 }
568
I2C_EnableInterrupts(I2C_Type * base,uint32_t mask)569 void I2C_EnableInterrupts(I2C_Type *base, uint32_t mask)
570 {
571 #ifdef I2C_HAS_STOP_DETECT
572 uint8_t fltReg;
573 #endif
574
575 if (mask & kI2C_GlobalInterruptEnable)
576 {
577 base->C1 |= I2C_C1_IICIE_MASK;
578 }
579
580 #if defined(FSL_FEATURE_I2C_HAS_STOP_DETECT) && FSL_FEATURE_I2C_HAS_STOP_DETECT
581 if (mask & kI2C_StopDetectInterruptEnable)
582 {
583 fltReg = base->FLT;
584
585 /* Keep STOPF flag. */
586 fltReg &= ~I2C_FLT_STOPF_MASK;
587
588 /* Stop detect enable. */
589 fltReg |= I2C_FLT_STOPIE_MASK;
590 base->FLT = fltReg;
591 }
592 #endif /* FSL_FEATURE_I2C_HAS_STOP_DETECT */
593
594 #if defined(FSL_FEATURE_I2C_HAS_START_STOP_DETECT) && FSL_FEATURE_I2C_HAS_START_STOP_DETECT
595 if (mask & kI2C_StartStopDetectInterruptEnable)
596 {
597 fltReg = base->FLT;
598
599 /* Keep STARTF and STOPF flags. */
600 fltReg &= ~(I2C_FLT_STOPF_MASK | I2C_FLT_STARTF_MASK);
601
602 /* Start and stop detect enable. */
603 fltReg |= I2C_FLT_SSIE_MASK;
604 base->FLT = fltReg;
605 }
606 #endif /* FSL_FEATURE_I2C_HAS_START_STOP_DETECT */
607 }
608
I2C_DisableInterrupts(I2C_Type * base,uint32_t mask)609 void I2C_DisableInterrupts(I2C_Type *base, uint32_t mask)
610 {
611 if (mask & kI2C_GlobalInterruptEnable)
612 {
613 base->C1 &= ~I2C_C1_IICIE_MASK;
614 }
615
616 #if defined(FSL_FEATURE_I2C_HAS_STOP_DETECT) && FSL_FEATURE_I2C_HAS_STOP_DETECT
617 if (mask & kI2C_StopDetectInterruptEnable)
618 {
619 base->FLT &= ~(I2C_FLT_STOPIE_MASK | I2C_FLT_STOPF_MASK);
620 }
621 #endif /* FSL_FEATURE_I2C_HAS_STOP_DETECT */
622
623 #if defined(FSL_FEATURE_I2C_HAS_START_STOP_DETECT) && FSL_FEATURE_I2C_HAS_START_STOP_DETECT
624 if (mask & kI2C_StartStopDetectInterruptEnable)
625 {
626 base->FLT &= ~(I2C_FLT_SSIE_MASK | I2C_FLT_STOPF_MASK | I2C_FLT_STARTF_MASK);
627 }
628 #endif /* FSL_FEATURE_I2C_HAS_START_STOP_DETECT */
629 }
630
I2C_MasterSetBaudRate(I2C_Type * base,uint32_t baudRate_Bps,uint32_t srcClock_Hz)631 void I2C_MasterSetBaudRate(I2C_Type *base, uint32_t baudRate_Bps, uint32_t srcClock_Hz)
632 {
633 uint32_t multiplier;
634 uint32_t computedRate;
635 uint32_t absError;
636 uint32_t bestError = UINT32_MAX;
637 uint32_t bestMult = 0u;
638 uint32_t bestIcr = 0u;
639 uint8_t mult;
640 uint8_t i;
641
642 /* Search for the settings with the lowest error. Mult is the MULT field of the I2C_F register,
643 * and ranges from 0-2. It selects the multiplier factor for the divider. */
644 for (mult = 0u; (mult <= 2u) && (bestError != 0); ++mult)
645 {
646 multiplier = 1u << mult;
647
648 /* Scan table to find best match. */
649 for (i = 0u; i < sizeof(s_i2cDividerTable) / sizeof(uint16_t); ++i)
650 {
651 computedRate = srcClock_Hz / (multiplier * s_i2cDividerTable[i]);
652 absError = baudRate_Bps > computedRate ? (baudRate_Bps - computedRate) : (computedRate - baudRate_Bps);
653
654 if (absError < bestError)
655 {
656 bestMult = mult;
657 bestIcr = i;
658 bestError = absError;
659
660 /* If the error is 0, then we can stop searching because we won't find a better match. */
661 if (absError == 0)
662 {
663 break;
664 }
665 }
666 }
667 }
668
669 /* Set frequency register based on best settings. */
670 base->F = I2C_F_MULT(bestMult) | I2C_F_ICR(bestIcr);
671 }
672
I2C_MasterStart(I2C_Type * base,uint8_t address,i2c_direction_t direction)673 status_t I2C_MasterStart(I2C_Type *base, uint8_t address, i2c_direction_t direction)
674 {
675 status_t result = kStatus_Success;
676 uint32_t statusFlags = I2C_MasterGetStatusFlags(base);
677
678 /* Return an error if the bus is already in use. */
679 if (statusFlags & kI2C_BusBusyFlag)
680 {
681 result = kStatus_I2C_Busy;
682 }
683 else
684 {
685 /* Send the START signal. */
686 base->C1 |= I2C_C1_MST_MASK | I2C_C1_TX_MASK;
687
688 #if defined(FSL_FEATURE_I2C_HAS_DOUBLE_BUFFERING) && FSL_FEATURE_I2C_HAS_DOUBLE_BUFFERING
689 while (!(base->S2 & I2C_S2_EMPTY_MASK))
690 {
691 }
692 #endif /* FSL_FEATURE_I2C_HAS_DOUBLE_BUFFERING */
693
694 base->D = (((uint32_t)address) << 1U | ((direction == kI2C_Read) ? 1U : 0U));
695 }
696
697 return result;
698 }
699
I2C_MasterRepeatedStart(I2C_Type * base,uint8_t address,i2c_direction_t direction)700 status_t I2C_MasterRepeatedStart(I2C_Type *base, uint8_t address, i2c_direction_t direction)
701 {
702 status_t result = kStatus_Success;
703 uint8_t savedMult;
704 uint32_t statusFlags = I2C_MasterGetStatusFlags(base);
705 uint8_t timeDelay = 6;
706
707 /* Return an error if the bus is already in use, but not by us. */
708 if ((statusFlags & kI2C_BusBusyFlag) && ((base->C1 & I2C_C1_MST_MASK) == 0))
709 {
710 result = kStatus_I2C_Busy;
711 }
712 else
713 {
714 savedMult = base->F;
715 base->F = savedMult & (~I2C_F_MULT_MASK);
716
717 /* We are already in a transfer, so send a repeated start. */
718 base->C1 |= I2C_C1_RSTA_MASK | I2C_C1_TX_MASK;
719
720 /* Restore the multiplier factor. */
721 base->F = savedMult;
722
723 /* Add some delay to wait the Re-Start signal. */
724 while (timeDelay--)
725 {
726 __NOP();
727 }
728
729 #if defined(FSL_FEATURE_I2C_HAS_DOUBLE_BUFFERING) && FSL_FEATURE_I2C_HAS_DOUBLE_BUFFERING
730 while (!(base->S2 & I2C_S2_EMPTY_MASK))
731 {
732 }
733 #endif /* FSL_FEATURE_I2C_HAS_DOUBLE_BUFFERING */
734
735 base->D = (((uint32_t)address) << 1U | ((direction == kI2C_Read) ? 1U : 0U));
736 }
737
738 return result;
739 }
740
I2C_MasterStop(I2C_Type * base)741 status_t I2C_MasterStop(I2C_Type *base)
742 {
743 status_t result = kStatus_Success;
744 uint16_t timeout = UINT16_MAX;
745
746 /* Issue the STOP command on the bus. */
747 base->C1 &= ~(I2C_C1_MST_MASK | I2C_C1_TX_MASK | I2C_C1_TXAK_MASK);
748
749 /* Wait until data transfer complete. */
750 while ((base->S & kI2C_BusBusyFlag) && (--timeout))
751 {
752 }
753
754 if (timeout == 0)
755 {
756 result = kStatus_I2C_Timeout;
757 }
758
759 return result;
760 }
761
I2C_MasterGetStatusFlags(I2C_Type * base)762 uint32_t I2C_MasterGetStatusFlags(I2C_Type *base)
763 {
764 uint32_t statusFlags = base->S;
765
766 #ifdef I2C_HAS_STOP_DETECT
767 /* Look up the STOPF bit from the filter register. */
768 if (base->FLT & I2C_FLT_STOPF_MASK)
769 {
770 statusFlags |= kI2C_StopDetectFlag;
771 }
772 #endif
773
774 #if defined(FSL_FEATURE_I2C_HAS_START_STOP_DETECT) && FSL_FEATURE_I2C_HAS_START_STOP_DETECT
775 /* Look up the STARTF bit from the filter register. */
776 if (base->FLT & I2C_FLT_STARTF_MASK)
777 {
778 statusFlags |= kI2C_StartDetectFlag;
779 }
780 #endif /* FSL_FEATURE_I2C_HAS_START_STOP_DETECT */
781
782 return statusFlags;
783 }
784
I2C_MasterWriteBlocking(I2C_Type * base,const uint8_t * txBuff,size_t txSize,uint32_t flags)785 status_t I2C_MasterWriteBlocking(I2C_Type *base, const uint8_t *txBuff, size_t txSize, uint32_t flags)
786 {
787 status_t result = kStatus_Success;
788 uint8_t statusFlags = 0;
789
790 /* Wait until the data register is ready for transmit. */
791 while (!(base->S & kI2C_TransferCompleteFlag))
792 {
793 }
794
795 /* Clear the IICIF flag. */
796 base->S = kI2C_IntPendingFlag;
797
798 /* Setup the I2C peripheral to transmit data. */
799 base->C1 |= I2C_C1_TX_MASK;
800
801 while (txSize--)
802 {
803 /* Send a byte of data. */
804 base->D = *txBuff++;
805
806 /* Wait until data transfer complete. */
807 while (!(base->S & kI2C_IntPendingFlag))
808 {
809 }
810
811 statusFlags = base->S;
812
813 /* Clear the IICIF flag. */
814 base->S = kI2C_IntPendingFlag;
815
816 /* Check if arbitration lost or no acknowledgement (NAK), return failure status. */
817 if (statusFlags & kI2C_ArbitrationLostFlag)
818 {
819 base->S = kI2C_ArbitrationLostFlag;
820 result = kStatus_I2C_ArbitrationLost;
821 }
822
823 if ((statusFlags & kI2C_ReceiveNakFlag) && txSize)
824 {
825 base->S = kI2C_ReceiveNakFlag;
826 result = kStatus_I2C_Nak;
827 }
828
829 if (result != kStatus_Success)
830 {
831 /* Breaking out of the send loop. */
832 break;
833 }
834 }
835
836 if (((result == kStatus_Success) && (!(flags & kI2C_TransferNoStopFlag))) || (result == kStatus_I2C_Nak))
837 {
838 /* Clear the IICIF flag. */
839 base->S = kI2C_IntPendingFlag;
840
841 /* Send stop. */
842 result = I2C_MasterStop(base);
843 }
844
845 return result;
846 }
847
I2C_MasterReadBlocking(I2C_Type * base,uint8_t * rxBuff,size_t rxSize,uint32_t flags)848 status_t I2C_MasterReadBlocking(I2C_Type *base, uint8_t *rxBuff, size_t rxSize, uint32_t flags)
849 {
850 status_t result = kStatus_Success;
851 volatile uint8_t dummy = 0;
852
853 /* Add this to avoid build warning. */
854 dummy++;
855
856 /* Wait until the data register is ready for transmit. */
857 while (!(base->S & kI2C_TransferCompleteFlag))
858 {
859 }
860
861 /* Clear the IICIF flag. */
862 base->S = kI2C_IntPendingFlag;
863
864 /* Setup the I2C peripheral to receive data. */
865 base->C1 &= ~(I2C_C1_TX_MASK | I2C_C1_TXAK_MASK);
866
867 /* If rxSize equals 1, configure to send NAK. */
868 if (rxSize == 1)
869 {
870 /* Issue NACK on read. */
871 base->C1 |= I2C_C1_TXAK_MASK;
872 }
873
874 /* Do dummy read. */
875 dummy = base->D;
876
877 while ((rxSize--))
878 {
879 /* Wait until data transfer complete. */
880 while (!(base->S & kI2C_IntPendingFlag))
881 {
882 }
883
884 /* Clear the IICIF flag. */
885 base->S = kI2C_IntPendingFlag;
886
887 /* Single byte use case. */
888 if (rxSize == 0)
889 {
890 if (!(flags & kI2C_TransferNoStopFlag))
891 {
892 /* Issue STOP command before reading last byte. */
893 result = I2C_MasterStop(base);
894 }
895 else
896 {
897 /* Change direction to Tx to avoid extra clocks. */
898 base->C1 |= I2C_C1_TX_MASK;
899 }
900 }
901
902 if (rxSize == 1)
903 {
904 /* Issue NACK on read. */
905 base->C1 |= I2C_C1_TXAK_MASK;
906 }
907
908 /* Read from the data register. */
909 *rxBuff++ = base->D;
910 }
911
912 return result;
913 }
914
I2C_MasterTransferBlocking(I2C_Type * base,i2c_master_transfer_t * xfer)915 status_t I2C_MasterTransferBlocking(I2C_Type *base, i2c_master_transfer_t *xfer)
916 {
917 assert(xfer);
918
919 i2c_direction_t direction = xfer->direction;
920 status_t result = kStatus_Success;
921
922 /* Clear all status before transfer. */
923 I2C_MasterClearStatusFlags(base, kClearFlags);
924
925 /* Wait until ready to complete. */
926 while (!(base->S & kI2C_TransferCompleteFlag))
927 {
928 }
929
930 /* Change to send write address when it's a read operation with command. */
931 if ((xfer->subaddressSize > 0) && (xfer->direction == kI2C_Read))
932 {
933 direction = kI2C_Write;
934 }
935
936 /* If repeated start is requested, send repeated start. */
937 if (xfer->flags & kI2C_TransferRepeatedStartFlag)
938 {
939 result = I2C_MasterRepeatedStart(base, xfer->slaveAddress, direction);
940 }
941 else /* For normal transfer, send start. */
942 {
943 result = I2C_MasterStart(base, xfer->slaveAddress, direction);
944 }
945
946 /* Return if error. */
947 if (result)
948 {
949 return result;
950 }
951
952 while (!(base->S & kI2C_IntPendingFlag))
953 {
954 }
955
956 /* Check if there's transfer error. */
957 result = I2C_CheckAndClearError(base, base->S);
958
959 /* Return if error. */
960 if (result)
961 {
962 if (result == kStatus_I2C_Nak)
963 {
964 result = kStatus_I2C_Addr_Nak;
965
966 I2C_MasterStop(base);
967 }
968
969 return result;
970 }
971
972 /* Send subaddress. */
973 if (xfer->subaddressSize)
974 {
975 do
976 {
977 /* Clear interrupt pending flag. */
978 base->S = kI2C_IntPendingFlag;
979
980 xfer->subaddressSize--;
981 base->D = ((xfer->subaddress) >> (8 * xfer->subaddressSize));
982
983 /* Wait until data transfer complete. */
984 while (!(base->S & kI2C_IntPendingFlag))
985 {
986 }
987
988 /* Check if there's transfer error. */
989 result = I2C_CheckAndClearError(base, base->S);
990
991 if (result)
992 {
993 if (result == kStatus_I2C_Nak)
994 {
995 I2C_MasterStop(base);
996 }
997
998 return result;
999 }
1000
1001 } while ((xfer->subaddressSize > 0) && (result == kStatus_Success));
1002
1003 if (xfer->direction == kI2C_Read)
1004 {
1005 /* Clear pending flag. */
1006 base->S = kI2C_IntPendingFlag;
1007
1008 /* Send repeated start and slave address. */
1009 result = I2C_MasterRepeatedStart(base, xfer->slaveAddress, kI2C_Read);
1010
1011 /* Return if error. */
1012 if (result)
1013 {
1014 return result;
1015 }
1016
1017 /* Wait until data transfer complete. */
1018 while (!(base->S & kI2C_IntPendingFlag))
1019 {
1020 }
1021
1022 /* Check if there's transfer error. */
1023 result = I2C_CheckAndClearError(base, base->S);
1024
1025 if (result)
1026 {
1027 if (result == kStatus_I2C_Nak)
1028 {
1029 result = kStatus_I2C_Addr_Nak;
1030
1031 I2C_MasterStop(base);
1032 }
1033
1034 return result;
1035 }
1036 }
1037 }
1038
1039 /* Transmit data. */
1040 if ((xfer->direction == kI2C_Write) && (xfer->dataSize > 0))
1041 {
1042 /* Send Data. */
1043 result = I2C_MasterWriteBlocking(base, xfer->data, xfer->dataSize, xfer->flags);
1044 }
1045
1046 /* Receive Data. */
1047 if ((xfer->direction == kI2C_Read) && (xfer->dataSize > 0))
1048 {
1049 result = I2C_MasterReadBlocking(base, xfer->data, xfer->dataSize, xfer->flags);
1050 }
1051
1052 return result;
1053 }
1054
I2C_MasterTransferCreateHandle(I2C_Type * base,i2c_master_handle_t * handle,i2c_master_transfer_callback_t callback,void * userData)1055 void I2C_MasterTransferCreateHandle(I2C_Type *base,
1056 i2c_master_handle_t *handle,
1057 i2c_master_transfer_callback_t callback,
1058 void *userData)
1059 {
1060 assert(handle);
1061
1062 uint32_t instance = I2C_GetInstance(base);
1063
1064 /* Zero handle. */
1065 memset(handle, 0, sizeof(*handle));
1066
1067 /* Set callback and userData. */
1068 handle->completionCallback = callback;
1069 handle->userData = userData;
1070
1071 /* Save the context in global variables to support the double weak mechanism. */
1072 s_i2cHandle[instance] = handle;
1073
1074 /* Save master interrupt handler. */
1075 s_i2cMasterIsr = I2C_MasterTransferHandleIRQ;
1076
1077 /* Enable NVIC interrupt. */
1078 EnableIRQ(s_i2cIrqs[instance]);
1079 }
1080
I2C_MasterTransferNonBlocking(I2C_Type * base,i2c_master_handle_t * handle,i2c_master_transfer_t * xfer)1081 status_t I2C_MasterTransferNonBlocking(I2C_Type *base, i2c_master_handle_t *handle, i2c_master_transfer_t *xfer)
1082 {
1083 assert(handle);
1084 assert(xfer);
1085
1086 status_t result = kStatus_Success;
1087
1088 /* Check if the I2C bus is idle - if not return busy status. */
1089 if (handle->state != kIdleState)
1090 {
1091 result = kStatus_I2C_Busy;
1092 }
1093 else
1094 {
1095 /* Start up the master transfer state machine. */
1096 result = I2C_InitTransferStateMachine(base, handle, xfer);
1097
1098 if (result == kStatus_Success)
1099 {
1100 /* Enable the I2C interrupts. */
1101 I2C_EnableInterrupts(base, kI2C_GlobalInterruptEnable);
1102 }
1103 }
1104
1105 return result;
1106 }
1107
I2C_MasterTransferAbort(I2C_Type * base,i2c_master_handle_t * handle)1108 void I2C_MasterTransferAbort(I2C_Type *base, i2c_master_handle_t *handle)
1109 {
1110 assert(handle);
1111
1112 volatile uint8_t dummy = 0;
1113
1114 /* Add this to avoid build warning. */
1115 dummy++;
1116
1117 /* Disable interrupt. */
1118 I2C_DisableInterrupts(base, kI2C_GlobalInterruptEnable);
1119
1120 /* Reset the state to idle. */
1121 handle->state = kIdleState;
1122
1123 /* Send STOP signal. */
1124 if (handle->transfer.direction == kI2C_Read)
1125 {
1126 base->C1 |= I2C_C1_TXAK_MASK;
1127 while (!(base->S & kI2C_IntPendingFlag))
1128 {
1129 }
1130 base->S = kI2C_IntPendingFlag;
1131
1132 base->C1 &= ~(I2C_C1_MST_MASK | I2C_C1_TX_MASK | I2C_C1_TXAK_MASK);
1133 dummy = base->D;
1134 }
1135 else
1136 {
1137 while (!(base->S & kI2C_IntPendingFlag))
1138 {
1139 }
1140 base->S = kI2C_IntPendingFlag;
1141 base->C1 &= ~(I2C_C1_MST_MASK | I2C_C1_TX_MASK | I2C_C1_TXAK_MASK);
1142 }
1143 }
1144
I2C_MasterTransferGetCount(I2C_Type * base,i2c_master_handle_t * handle,size_t * count)1145 status_t I2C_MasterTransferGetCount(I2C_Type *base, i2c_master_handle_t *handle, size_t *count)
1146 {
1147 assert(handle);
1148
1149 if (!count)
1150 {
1151 return kStatus_InvalidArgument;
1152 }
1153
1154 *count = handle->transferSize - handle->transfer.dataSize;
1155
1156 return kStatus_Success;
1157 }
1158
I2C_MasterTransferHandleIRQ(I2C_Type * base,void * i2cHandle)1159 void I2C_MasterTransferHandleIRQ(I2C_Type *base, void *i2cHandle)
1160 {
1161 assert(i2cHandle);
1162
1163 i2c_master_handle_t *handle = (i2c_master_handle_t *)i2cHandle;
1164 status_t result = kStatus_Success;
1165 bool isDone;
1166
1167 /* Clear the interrupt flag. */
1168 base->S = kI2C_IntPendingFlag;
1169
1170 /* Check transfer complete flag. */
1171 result = I2C_MasterTransferRunStateMachine(base, handle, &isDone);
1172
1173 if (isDone || result)
1174 {
1175 /* Send stop command if transfer done or received Nak. */
1176 if ((!(handle->transfer.flags & kI2C_TransferNoStopFlag)) || (result == kStatus_I2C_Nak) ||
1177 (result == kStatus_I2C_Addr_Nak))
1178 {
1179 /* Ensure stop command is a need. */
1180 if ((base->C1 & I2C_C1_MST_MASK))
1181 {
1182 if (I2C_MasterStop(base) != kStatus_Success)
1183 {
1184 result = kStatus_I2C_Timeout;
1185 }
1186 }
1187 }
1188
1189 /* Restore handle to idle state. */
1190 handle->state = kIdleState;
1191
1192 /* Disable interrupt. */
1193 I2C_DisableInterrupts(base, kI2C_GlobalInterruptEnable);
1194
1195 /* Call the callback function after the function has completed. */
1196 if (handle->completionCallback)
1197 {
1198 handle->completionCallback(base, handle, result, handle->userData);
1199 }
1200 }
1201 }
1202
I2C_SlaveInit(I2C_Type * base,const i2c_slave_config_t * slaveConfig,uint32_t srcClock_Hz)1203 void I2C_SlaveInit(I2C_Type *base, const i2c_slave_config_t *slaveConfig, uint32_t srcClock_Hz)
1204 {
1205 assert(slaveConfig);
1206
1207 uint8_t tmpReg;
1208
1209 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
1210 CLOCK_EnableClock(s_i2cClocks[I2C_GetInstance(base)]);
1211 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
1212
1213 /* Reset the module. */
1214 base->A1 = 0;
1215 base->F = 0;
1216 base->C1 = 0;
1217 base->S = 0xFFU;
1218 base->C2 = 0;
1219 #if defined(FSL_FEATURE_I2C_HAS_START_STOP_DETECT) && FSL_FEATURE_I2C_HAS_START_STOP_DETECT
1220 base->FLT = 0x50U;
1221 #elif defined(FSL_FEATURE_I2C_HAS_STOP_DETECT) && FSL_FEATURE_I2C_HAS_STOP_DETECT
1222 base->FLT = 0x40U;
1223 #endif
1224 base->RA = 0;
1225
1226 /* Configure addressing mode. */
1227 switch (slaveConfig->addressingMode)
1228 {
1229 case kI2C_Address7bit:
1230 base->A1 = ((uint32_t)(slaveConfig->slaveAddress)) << 1U;
1231 break;
1232
1233 case kI2C_RangeMatch:
1234 assert(slaveConfig->slaveAddress < slaveConfig->upperAddress);
1235 base->A1 = ((uint32_t)(slaveConfig->slaveAddress)) << 1U;
1236 base->RA = ((uint32_t)(slaveConfig->upperAddress)) << 1U;
1237 base->C2 |= I2C_C2_RMEN_MASK;
1238 break;
1239
1240 default:
1241 break;
1242 }
1243
1244 /* Configure low power wake up feature. */
1245 tmpReg = base->C1;
1246 tmpReg &= ~I2C_C1_WUEN_MASK;
1247 base->C1 = tmpReg | I2C_C1_WUEN(slaveConfig->enableWakeUp) | I2C_C1_IICEN(slaveConfig->enableSlave);
1248
1249 /* Configure general call & baud rate control. */
1250 tmpReg = base->C2;
1251 tmpReg &= ~(I2C_C2_SBRC_MASK | I2C_C2_GCAEN_MASK);
1252 tmpReg |= I2C_C2_SBRC(slaveConfig->enableBaudRateCtl) | I2C_C2_GCAEN(slaveConfig->enableGeneralCall);
1253 base->C2 = tmpReg;
1254
1255 /* Enable/Disable double buffering. */
1256 #if defined(FSL_FEATURE_I2C_HAS_DOUBLE_BUFFER_ENABLE) && FSL_FEATURE_I2C_HAS_DOUBLE_BUFFER_ENABLE
1257 tmpReg = base->S2 & (~I2C_S2_DFEN_MASK);
1258 base->S2 = tmpReg | I2C_S2_DFEN(slaveConfig->enableDoubleBuffering);
1259 #endif
1260
1261 /* Set hold time. */
1262 I2C_SetHoldTime(base, slaveConfig->sclStopHoldTime_ns, srcClock_Hz);
1263 }
1264
I2C_SlaveDeinit(I2C_Type * base)1265 void I2C_SlaveDeinit(I2C_Type *base)
1266 {
1267 /* Disable I2C module. */
1268 I2C_Enable(base, false);
1269
1270 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
1271 /* Disable I2C clock. */
1272 CLOCK_DisableClock(s_i2cClocks[I2C_GetInstance(base)]);
1273 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
1274 }
1275
I2C_SlaveGetDefaultConfig(i2c_slave_config_t * slaveConfig)1276 void I2C_SlaveGetDefaultConfig(i2c_slave_config_t *slaveConfig)
1277 {
1278 assert(slaveConfig);
1279
1280 /* By default slave is addressed with 7-bit address. */
1281 slaveConfig->addressingMode = kI2C_Address7bit;
1282
1283 /* General call mode is disabled by default. */
1284 slaveConfig->enableGeneralCall = false;
1285
1286 /* Slave address match waking up MCU from low power mode is disabled. */
1287 slaveConfig->enableWakeUp = false;
1288
1289 /* Independent slave mode baud rate at maximum frequency is disabled. */
1290 slaveConfig->enableBaudRateCtl = false;
1291
1292 /* Default enable double buffering. */
1293 #if defined(FSL_FEATURE_I2C_HAS_DOUBLE_BUFFER_ENABLE) && FSL_FEATURE_I2C_HAS_DOUBLE_BUFFER_ENABLE
1294 slaveConfig->enableDoubleBuffering = true;
1295 #endif
1296
1297 /* Set default SCL stop hold time to 4us which is minimum requirement in I2C spec. */
1298 slaveConfig->sclStopHoldTime_ns = 4000;
1299
1300 /* Enable the I2C peripheral. */
1301 slaveConfig->enableSlave = true;
1302 }
1303
I2C_SlaveWriteBlocking(I2C_Type * base,const uint8_t * txBuff,size_t txSize)1304 status_t I2C_SlaveWriteBlocking(I2C_Type *base, const uint8_t *txBuff, size_t txSize)
1305 {
1306 status_t result = kStatus_Success;
1307 volatile uint8_t dummy = 0;
1308
1309 /* Add this to avoid build warning. */
1310 dummy++;
1311
1312 #if defined(FSL_FEATURE_I2C_HAS_START_STOP_DETECT) && FSL_FEATURE_I2C_HAS_START_STOP_DETECT
1313 /* Check start flag. */
1314 while (!(base->FLT & I2C_FLT_STARTF_MASK))
1315 {
1316 }
1317 /* Clear STARTF flag. */
1318 base->FLT |= I2C_FLT_STARTF_MASK;
1319 /* Clear the IICIF flag. */
1320 base->S = kI2C_IntPendingFlag;
1321 #endif /* FSL_FEATURE_I2C_HAS_START_STOP_DETECT */
1322
1323 /* Wait for address match flag. */
1324 while (!(base->S & kI2C_AddressMatchFlag))
1325 {
1326 }
1327
1328 /* Read dummy to release bus. */
1329 dummy = base->D;
1330
1331 result = I2C_MasterWriteBlocking(base, txBuff, txSize, kI2C_TransferDefaultFlag);
1332
1333 /* Switch to receive mode. */
1334 base->C1 &= ~(I2C_C1_TX_MASK | I2C_C1_TXAK_MASK);
1335
1336 /* Read dummy to release bus. */
1337 dummy = base->D;
1338
1339 return result;
1340 }
1341
I2C_SlaveReadBlocking(I2C_Type * base,uint8_t * rxBuff,size_t rxSize)1342 void I2C_SlaveReadBlocking(I2C_Type *base, uint8_t *rxBuff, size_t rxSize)
1343 {
1344 volatile uint8_t dummy = 0;
1345
1346 /* Add this to avoid build warning. */
1347 dummy++;
1348
1349 /* Wait until address match. */
1350 #if defined(FSL_FEATURE_I2C_HAS_START_STOP_DETECT) && FSL_FEATURE_I2C_HAS_START_STOP_DETECT
1351 /* Check start flag. */
1352 while (!(base->FLT & I2C_FLT_STARTF_MASK))
1353 {
1354 }
1355 /* Clear STARTF flag. */
1356 base->FLT |= I2C_FLT_STARTF_MASK;
1357 /* Clear the IICIF flag. */
1358 base->S = kI2C_IntPendingFlag;
1359 #endif /* FSL_FEATURE_I2C_HAS_START_STOP_DETECT */
1360
1361 /* Wait for address match and int pending flag. */
1362 while (!(base->S & kI2C_AddressMatchFlag))
1363 {
1364 }
1365 while (!(base->S & kI2C_IntPendingFlag))
1366 {
1367 }
1368
1369 /* Read dummy to release bus. */
1370 dummy = base->D;
1371
1372 /* Clear the IICIF flag. */
1373 base->S = kI2C_IntPendingFlag;
1374
1375 /* Setup the I2C peripheral to receive data. */
1376 base->C1 &= ~(I2C_C1_TX_MASK);
1377
1378 while (rxSize--)
1379 {
1380 /* Wait until data transfer complete. */
1381 while (!(base->S & kI2C_IntPendingFlag))
1382 {
1383 }
1384 /* Clear the IICIF flag. */
1385 base->S = kI2C_IntPendingFlag;
1386
1387 /* Read from the data register. */
1388 *rxBuff++ = base->D;
1389 }
1390 }
1391
I2C_SlaveTransferCreateHandle(I2C_Type * base,i2c_slave_handle_t * handle,i2c_slave_transfer_callback_t callback,void * userData)1392 void I2C_SlaveTransferCreateHandle(I2C_Type *base,
1393 i2c_slave_handle_t *handle,
1394 i2c_slave_transfer_callback_t callback,
1395 void *userData)
1396 {
1397 assert(handle);
1398
1399 uint32_t instance = I2C_GetInstance(base);
1400
1401 /* Zero handle. */
1402 memset(handle, 0, sizeof(*handle));
1403
1404 /* Set callback and userData. */
1405 handle->callback = callback;
1406 handle->userData = userData;
1407
1408 /* Save the context in global variables to support the double weak mechanism. */
1409 s_i2cHandle[instance] = handle;
1410
1411 /* Save slave interrupt handler. */
1412 s_i2cSlaveIsr = I2C_SlaveTransferHandleIRQ;
1413
1414 /* Enable NVIC interrupt. */
1415 EnableIRQ(s_i2cIrqs[instance]);
1416 }
1417
I2C_SlaveTransferNonBlocking(I2C_Type * base,i2c_slave_handle_t * handle,uint32_t eventMask)1418 status_t I2C_SlaveTransferNonBlocking(I2C_Type *base, i2c_slave_handle_t *handle, uint32_t eventMask)
1419 {
1420 assert(handle);
1421
1422 /* Check if the I2C bus is idle - if not return busy status. */
1423 if (handle->isBusy)
1424 {
1425 return kStatus_I2C_Busy;
1426 }
1427 else
1428 {
1429 /* Disable LPI2C IRQ sources while we configure stuff. */
1430 I2C_DisableInterrupts(base, kIrqFlags);
1431
1432 /* Clear transfer in handle. */
1433 memset(&handle->transfer, 0, sizeof(handle->transfer));
1434
1435 /* Record that we're busy. */
1436 handle->isBusy = true;
1437
1438 /* Set up event mask. tx and rx are always enabled. */
1439 handle->eventMask = eventMask | kI2C_SlaveTransmitEvent | kI2C_SlaveReceiveEvent | kI2C_SlaveGenaralcallEvent;
1440
1441 /* Clear all flags. */
1442 I2C_SlaveClearStatusFlags(base, kClearFlags);
1443
1444 /* Enable I2C internal IRQ sources. NVIC IRQ was enabled in CreateHandle() */
1445 I2C_EnableInterrupts(base, kIrqFlags);
1446 }
1447
1448 return kStatus_Success;
1449 }
1450
I2C_SlaveTransferAbort(I2C_Type * base,i2c_slave_handle_t * handle)1451 void I2C_SlaveTransferAbort(I2C_Type *base, i2c_slave_handle_t *handle)
1452 {
1453 assert(handle);
1454
1455 if (handle->isBusy)
1456 {
1457 /* Disable interrupts. */
1458 I2C_DisableInterrupts(base, kIrqFlags);
1459
1460 /* Reset transfer info. */
1461 memset(&handle->transfer, 0, sizeof(handle->transfer));
1462
1463 /* Reset the state to idle. */
1464 handle->isBusy = false;
1465 }
1466 }
1467
I2C_SlaveTransferGetCount(I2C_Type * base,i2c_slave_handle_t * handle,size_t * count)1468 status_t I2C_SlaveTransferGetCount(I2C_Type *base, i2c_slave_handle_t *handle, size_t *count)
1469 {
1470 assert(handle);
1471
1472 if (!count)
1473 {
1474 return kStatus_InvalidArgument;
1475 }
1476
1477 /* Catch when there is not an active transfer. */
1478 if (!handle->isBusy)
1479 {
1480 *count = 0;
1481 return kStatus_NoTransferInProgress;
1482 }
1483
1484 /* For an active transfer, just return the count from the handle. */
1485 *count = handle->transfer.transferredCount;
1486
1487 return kStatus_Success;
1488 }
1489
I2C_SlaveTransferHandleIRQ(I2C_Type * base,void * i2cHandle)1490 void I2C_SlaveTransferHandleIRQ(I2C_Type *base, void *i2cHandle)
1491 {
1492 assert(i2cHandle);
1493
1494 uint16_t status;
1495 bool doTransmit = false;
1496 i2c_slave_handle_t *handle = (i2c_slave_handle_t *)i2cHandle;
1497 i2c_slave_transfer_t *xfer;
1498 volatile uint8_t dummy = 0;
1499
1500 /* Add this to avoid build warning. */
1501 dummy++;
1502
1503 status = I2C_SlaveGetStatusFlags(base);
1504 xfer = &(handle->transfer);
1505
1506 #ifdef I2C_HAS_STOP_DETECT
1507 /* Check stop flag. */
1508 if (status & kI2C_StopDetectFlag)
1509 {
1510 I2C_MasterClearStatusFlags(base, kI2C_StopDetectFlag);
1511
1512 /* Clear the interrupt flag. */
1513 base->S = kI2C_IntPendingFlag;
1514
1515 /* Call slave callback if this is the STOP of the transfer. */
1516 if (handle->isBusy)
1517 {
1518 xfer->event = kI2C_SlaveCompletionEvent;
1519 xfer->completionStatus = kStatus_Success;
1520 handle->isBusy = false;
1521
1522 if ((handle->eventMask & xfer->event) && (handle->callback))
1523 {
1524 handle->callback(base, xfer, handle->userData);
1525 }
1526 }
1527
1528 if (!(status & kI2C_AddressMatchFlag))
1529 {
1530 return;
1531 }
1532 }
1533 #endif /* I2C_HAS_STOP_DETECT */
1534
1535 #if defined(FSL_FEATURE_I2C_HAS_START_STOP_DETECT) && FSL_FEATURE_I2C_HAS_START_STOP_DETECT
1536 /* Check start flag. */
1537 if (status & kI2C_StartDetectFlag)
1538 {
1539 I2C_MasterClearStatusFlags(base, kI2C_StartDetectFlag);
1540
1541 /* Clear the interrupt flag. */
1542 base->S = kI2C_IntPendingFlag;
1543
1544 xfer->event = kI2C_SlaveStartEvent;
1545
1546 if ((handle->eventMask & xfer->event) && (handle->callback))
1547 {
1548 handle->callback(base, xfer, handle->userData);
1549 }
1550
1551 if (!(status & kI2C_AddressMatchFlag))
1552 {
1553 return;
1554 }
1555 }
1556 #endif /* FSL_FEATURE_I2C_HAS_START_STOP_DETECT */
1557
1558 /* Clear the interrupt flag. */
1559 base->S = kI2C_IntPendingFlag;
1560
1561 /* Check NAK */
1562 if (status & kI2C_ReceiveNakFlag)
1563 {
1564 /* Set receive mode. */
1565 base->C1 &= ~(I2C_C1_TX_MASK | I2C_C1_TXAK_MASK);
1566
1567 /* Read dummy. */
1568 dummy = base->D;
1569
1570 if (handle->transfer.dataSize != 0)
1571 {
1572 xfer->event = kI2C_SlaveCompletionEvent;
1573 xfer->completionStatus = kStatus_I2C_Nak;
1574 handle->isBusy = false;
1575
1576 if ((handle->eventMask & xfer->event) && (handle->callback))
1577 {
1578 handle->callback(base, xfer, handle->userData);
1579 }
1580 }
1581 else
1582 {
1583 #ifndef I2C_HAS_STOP_DETECT
1584 xfer->event = kI2C_SlaveCompletionEvent;
1585 xfer->completionStatus = kStatus_Success;
1586 handle->isBusy = false;
1587
1588 if ((handle->eventMask & xfer->event) && (handle->callback))
1589 {
1590 handle->callback(base, xfer, handle->userData);
1591 }
1592 #endif /* !FSL_FEATURE_I2C_HAS_START_STOP_DETECT or !FSL_FEATURE_I2C_HAS_STOP_DETECT */
1593 }
1594 }
1595 /* Check address match. */
1596 else if (status & kI2C_AddressMatchFlag)
1597 {
1598 handle->isBusy = true;
1599 xfer->event = kI2C_SlaveAddressMatchEvent;
1600
1601 /* Slave transmit, master reading from slave. */
1602 if (status & kI2C_TransferDirectionFlag)
1603 {
1604 /* Change direction to send data. */
1605 base->C1 |= I2C_C1_TX_MASK;
1606
1607 doTransmit = true;
1608 }
1609 else
1610 {
1611 /* Slave receive, master writing to slave. */
1612 base->C1 &= ~(I2C_C1_TX_MASK | I2C_C1_TXAK_MASK);
1613
1614 /* Read dummy to release the bus. */
1615 dummy = base->D;
1616
1617 if (dummy == 0)
1618 {
1619 xfer->event = kI2C_SlaveGenaralcallEvent;
1620 }
1621 }
1622
1623 if ((handle->eventMask & xfer->event) && (handle->callback))
1624 {
1625 handle->callback(base, xfer, handle->userData);
1626 }
1627 }
1628 /* Check transfer complete flag. */
1629 else if (status & kI2C_TransferCompleteFlag)
1630 {
1631 /* Slave transmit, master reading from slave. */
1632 if (status & kI2C_TransferDirectionFlag)
1633 {
1634 doTransmit = true;
1635 }
1636 else
1637 {
1638 /* If we're out of data, invoke callback to get more. */
1639 if ((!xfer->data) || (!xfer->dataSize))
1640 {
1641 xfer->event = kI2C_SlaveReceiveEvent;
1642
1643 if (handle->callback)
1644 {
1645 handle->callback(base, xfer, handle->userData);
1646 }
1647
1648 /* Clear the transferred count now that we have a new buffer. */
1649 xfer->transferredCount = 0;
1650 }
1651
1652 /* Slave receive, master writing to slave. */
1653 uint8_t data = base->D;
1654
1655 if (handle->transfer.dataSize)
1656 {
1657 /* Receive data. */
1658 *handle->transfer.data++ = data;
1659 handle->transfer.dataSize--;
1660 xfer->transferredCount++;
1661 if (!handle->transfer.dataSize)
1662 {
1663 #ifndef I2C_HAS_STOP_DETECT
1664 xfer->event = kI2C_SlaveCompletionEvent;
1665 xfer->completionStatus = kStatus_Success;
1666 handle->isBusy = false;
1667
1668 /* Proceed receive complete event. */
1669 if ((handle->eventMask & xfer->event) && (handle->callback))
1670 {
1671 handle->callback(base, xfer, handle->userData);
1672 }
1673 #endif /* !FSL_FEATURE_I2C_HAS_START_STOP_DETECT or !FSL_FEATURE_I2C_HAS_STOP_DETECT */
1674 }
1675 }
1676 }
1677 }
1678 else
1679 {
1680 /* Read dummy to release bus. */
1681 dummy = base->D;
1682 }
1683
1684 /* Send data if there is the need. */
1685 if (doTransmit)
1686 {
1687 /* If we're out of data, invoke callback to get more. */
1688 if ((!xfer->data) || (!xfer->dataSize))
1689 {
1690 xfer->event = kI2C_SlaveTransmitEvent;
1691
1692 if (handle->callback)
1693 {
1694 handle->callback(base, xfer, handle->userData);
1695 }
1696
1697 /* Clear the transferred count now that we have a new buffer. */
1698 xfer->transferredCount = 0;
1699 }
1700
1701 if (handle->transfer.dataSize)
1702 {
1703 /* Send data. */
1704 base->D = *handle->transfer.data++;
1705 handle->transfer.dataSize--;
1706 xfer->transferredCount++;
1707 }
1708 else
1709 {
1710 /* Switch to receive mode. */
1711 base->C1 &= ~(I2C_C1_TX_MASK | I2C_C1_TXAK_MASK);
1712
1713 /* Read dummy to release bus. */
1714 dummy = base->D;
1715
1716 #ifndef I2C_HAS_STOP_DETECT
1717 xfer->event = kI2C_SlaveCompletionEvent;
1718 xfer->completionStatus = kStatus_Success;
1719 handle->isBusy = false;
1720
1721 /* Proceed txdone event. */
1722 if ((handle->eventMask & xfer->event) && (handle->callback))
1723 {
1724 handle->callback(base, xfer, handle->userData);
1725 }
1726 #endif /* !FSL_FEATURE_I2C_HAS_START_STOP_DETECT or !FSL_FEATURE_I2C_HAS_STOP_DETECT */
1727 }
1728 }
1729 }
1730
1731 #if defined(I2C0)
I2C0_DriverIRQHandler(void)1732 void I2C0_DriverIRQHandler(void)
1733 {
1734 I2C_TransferCommonIRQHandler(I2C0, s_i2cHandle[0]);
1735 }
1736 #endif
1737
1738 #if defined(I2C1)
I2C1_DriverIRQHandler(void)1739 void I2C1_DriverIRQHandler(void)
1740 {
1741 I2C_TransferCommonIRQHandler(I2C1, s_i2cHandle[1]);
1742 }
1743 #endif
1744
1745 #if defined(I2C2)
I2C2_DriverIRQHandler(void)1746 void I2C2_DriverIRQHandler(void)
1747 {
1748 I2C_TransferCommonIRQHandler(I2C2, s_i2cHandle[2]);
1749 }
1750 #endif
1751
1752 #if defined(I2C3)
I2C3_DriverIRQHandler(void)1753 void I2C3_DriverIRQHandler(void)
1754 {
1755 I2C_TransferCommonIRQHandler(I2C3, s_i2cHandle[3]);
1756 }
1757 #endif
1758