1 /**************************************************************************//**
2 * @file i2c.c
3 * @version V3.00
4 * @brief M2L31 series I2C driver source file
5 *
6 * SPDX-License-Identifier: Apache-2.0
7 * @copyright (C) 2023 Nuvoton Technology Corp. All rights reserved.
8 *****************************************************************************/
9 #include "NuMicro.h"
10
11 /** @addtogroup Standard_Driver Standard Driver
12 @{
13 */
14
15 /** @addtogroup I2C_Driver I2C Driver
16 @{
17 */
18
19 int32_t g_I2C_i32ErrCode = 0; /*!< I2C global error code */
20
21 /** @addtogroup I2C_EXPORTED_FUNCTIONS I2C Exported Functions
22 @{
23 */
24
25 /**
26 * @brief Enable specify I2C Controller and set Clock Divider
27 *
28 * @param[in] i2c Specify I2C port
29 * @param[in] u32BusClock The target I2C bus clock in Hz
30 *
31 * @return Actual I2C bus clock frequency
32 *
33 * @details The function enable the specify I2C Controller and set proper Clock Divider
34 * in I2C CLOCK DIVIDED REGISTER (I2CLK) according to the target I2C Bus clock.
35 * I2C Bus clock = PCLK / (4*(divider+1).
36 *
37 */
I2C_Open(I2C_T * i2c,uint32_t u32BusClock)38 uint32_t I2C_Open(I2C_T *i2c, uint32_t u32BusClock)
39 {
40 uint32_t u32Div;
41 uint32_t u32Pclk;
42
43 if( (i2c == I2C1) || (i2c == I2C3) )
44 {
45 u32Pclk = CLK_GetPCLK1Freq();
46 }
47 else
48 {
49 u32Pclk = CLK_GetPCLK0Freq();
50 }
51
52 u32Div = (uint32_t)(((u32Pclk * 10U) / (u32BusClock * 4U) + 5U) / 10U - 1U); /* Compute proper divider for I2C clock */
53 i2c->CLKDIV = u32Div;
54
55 /* Enable I2C */
56 i2c->CTL0 |= I2C_CTL0_I2CEN_Msk;
57
58 return (u32Pclk / ((u32Div + 1U) << 2U));
59 }
60
61 /**
62 * @brief Disable specify I2C Controller
63 *
64 * @param[in] i2c Specify I2C port
65 *
66 * @return None
67 *
68 * @details Reset I2C Controller and disable specify I2C port.
69 *
70 */
71
I2C_Close(I2C_T * i2c)72 void I2C_Close(I2C_T *i2c)
73 {
74 /* Reset I2C Controller */
75 if(i2c == I2C0)
76 {
77 SYS->IPRST1 |= SYS_IPRST1_I2C0RST_Msk;
78 SYS->IPRST1 &= ~SYS_IPRST1_I2C0RST_Msk;
79 }
80 else if(i2c == I2C1)
81 {
82 SYS->IPRST1 |= SYS_IPRST1_I2C1RST_Msk;
83 SYS->IPRST1 &= ~SYS_IPRST1_I2C1RST_Msk;
84 }
85 else if(i2c == I2C2)
86 {
87 SYS->IPRST1 |= SYS_IPRST1_I2C2RST_Msk;
88 SYS->IPRST1 &= ~SYS_IPRST1_I2C2RST_Msk;
89 }
90 else if(i2c == I2C3)
91 {
92 SYS->IPRST1 |= SYS_IPRST1_I2C3RST_Msk;
93 SYS->IPRST1 &= ~SYS_IPRST1_I2C3RST_Msk;
94 }
95
96 /* Disable I2C */
97 i2c->CTL0 &= ~I2C_CTL0_I2CEN_Msk;
98 }
99
100 /**
101 * @brief Clear Time-out Counter flag
102 *
103 * @param[in] i2c Specify I2C port
104 *
105 * @return None
106 *
107 * @details When Time-out flag will be set, use this function to clear I2C Bus Time-out counter flag .
108 *
109 */
I2C_ClearTimeoutFlag(I2C_T * i2c)110 void I2C_ClearTimeoutFlag(I2C_T *i2c)
111 {
112 i2c->TOCTL |= I2C_TOCTL_TOIF_Msk;
113 }
114
115 /**
116 * @brief Set Control bit of I2C Controller
117 *
118 * @param[in] i2c Specify I2C port
119 * @param[in] u8Start Set I2C START condition
120 * @param[in] u8Stop Set I2C STOP condition
121 * @param[in] u8Si Clear SI flag
122 * @param[in] u8Ack Set I2C ACK bit
123 *
124 * @return None
125 *
126 * @details The function set I2C Control bit of I2C Bus protocol.
127 *
128 */
I2C_Trigger(I2C_T * i2c,uint8_t u8Start,uint8_t u8Stop,uint8_t u8Si,uint8_t u8Ack)129 void I2C_Trigger(I2C_T *i2c, uint8_t u8Start, uint8_t u8Stop, uint8_t u8Si, uint8_t u8Ack)
130 {
131 uint32_t u32Reg = 0U;
132
133 if(u8Start)
134 {
135 u32Reg |= I2C_CTL_STA;
136 }
137
138 if(u8Stop)
139 {
140 u32Reg |= I2C_CTL_STO;
141 }
142
143 if(u8Si)
144 {
145 u32Reg |= I2C_CTL_SI;
146 }
147
148 if(u8Ack)
149 {
150 u32Reg |= I2C_CTL_AA;
151 }
152
153 i2c->CTL0 = (i2c->CTL0 & ~0x3CU) | u32Reg;
154 }
155
156 /**
157 * @brief Disable Interrupt of I2C Controller
158 *
159 * @param[in] i2c Specify I2C port
160 *
161 * @return None
162 *
163 * @details The function is used for disable I2C interrupt
164 *
165 */
I2C_DisableInt(I2C_T * i2c)166 void I2C_DisableInt(I2C_T *i2c)
167 {
168 i2c->CTL0 &= ~I2C_CTL0_INTEN_Msk;
169 }
170
171 /**
172 * @brief Enable Interrupt of I2C Controller
173 *
174 * @param[in] i2c Specify I2C port
175 *
176 * @return None
177 *
178 * @details The function is used for enable I2C interrupt
179 *
180 */
I2C_EnableInt(I2C_T * i2c)181 void I2C_EnableInt(I2C_T *i2c)
182 {
183 i2c->CTL0 |= I2C_CTL0_INTEN_Msk;
184 }
185
186 /**
187 * @brief Get I2C Bus Clock
188 *
189 * @param[in] i2c Specify I2C port
190 *
191 * @return The actual I2C Bus clock in Hz
192 *
193 * @details To get the actual I2C Bus Clock frequency.
194 */
I2C_GetBusClockFreq(I2C_T * i2c)195 uint32_t I2C_GetBusClockFreq(I2C_T *i2c)
196 {
197 uint32_t u32Divider = i2c->CLKDIV;
198 uint32_t u32Pclk;
199
200 if( (i2c == I2C1) || (i2c == I2C3) )
201 {
202 u32Pclk = CLK_GetPCLK1Freq();
203 }
204 else
205 {
206 u32Pclk = CLK_GetPCLK0Freq();
207 }
208
209 return (u32Pclk / ((u32Divider + 1U) << 2U));
210 }
211
212 /**
213 * @brief Set I2C Bus Clock
214 *
215 * @param[in] i2c Specify I2C port
216 * @param[in] u32BusClock The target I2C Bus Clock in Hz
217 *
218 * @return The actual I2C Bus Clock in Hz
219 *
220 * @details To set the actual I2C Bus Clock frequency.
221 */
I2C_SetBusClockFreq(I2C_T * i2c,uint32_t u32BusClock)222 uint32_t I2C_SetBusClockFreq(I2C_T *i2c, uint32_t u32BusClock)
223 {
224 uint32_t u32Div;
225 uint32_t u32Pclk;
226
227 if( (i2c == I2C1) || (i2c == I2C3) )
228 {
229 u32Pclk = CLK_GetPCLK1Freq();
230 }
231 else
232 {
233 u32Pclk = CLK_GetPCLK0Freq();
234 }
235
236 u32Div = (uint32_t)(((u32Pclk * 10U) / (u32BusClock * 4U) + 5U) / 10U - 1U); /* Compute proper divider for I2C clock */
237 i2c->CLKDIV = u32Div;
238
239 return (u32Pclk / ((u32Div + 1U) << 2U));
240 }
241
242 /**
243 * @brief Get Interrupt Flag
244 *
245 * @param[in] i2c Specify I2C port
246 *
247 * @return I2C interrupt flag status
248 *
249 * @details To get I2C Bus interrupt flag.
250 */
I2C_GetIntFlag(I2C_T * i2c)251 uint32_t I2C_GetIntFlag(I2C_T *i2c)
252 {
253 uint32_t u32Value;
254
255 if((i2c->CTL0 & I2C_CTL0_SI_Msk) == I2C_CTL0_SI_Msk)
256 {
257 u32Value = 1U;
258 }
259 else
260 {
261 u32Value = 0U;
262 }
263
264 return u32Value;
265 }
266
267 /**
268 * @brief Get I2C Bus Status Code
269 *
270 * @param[in] i2c Specify I2C port
271 *
272 * @return I2C Status Code
273 *
274 * @details To get I2C Bus Status Code.
275 */
I2C_GetStatus(I2C_T * i2c)276 uint32_t I2C_GetStatus(I2C_T *i2c)
277 {
278 return (i2c->STATUS0);
279 }
280
281 /**
282 * @brief Read a Byte from I2C Bus
283 *
284 * @param[in] i2c Specify I2C port
285 *
286 * @return I2C Data
287 *
288 * @details To read a bytes data from specify I2C port.
289 */
I2C_GetData(I2C_T * i2c)290 uint8_t I2C_GetData(I2C_T *i2c)
291 {
292 return (uint8_t)(i2c->DAT);
293 }
294
295 /**
296 * @brief Send a byte to I2C Bus
297 *
298 * @param[in] i2c Specify I2C port
299 * @param[in] u8Data The data to send to I2C bus
300 *
301 * @return None
302 *
303 * @details This function is used to write a byte to specified I2C port
304 */
I2C_SetData(I2C_T * i2c,uint8_t u8Data)305 void I2C_SetData(I2C_T *i2c, uint8_t u8Data)
306 {
307 i2c->DAT = u8Data;
308 }
309
310 /**
311 * @brief Set 7-bit Slave Address and GC Mode
312 *
313 * @param[in] i2c Specify I2C port
314 * @param[in] u8SlaveNo Set the number of I2C address register (0~3)
315 * @param[in] u8SlaveAddr 7-bit slave address
316 * @param[in] u8GCMode Enable/Disable GC mode (I2C_GCMODE_ENABLE / I2C_GCMODE_DISABLE)
317 *
318 * @return None
319 *
320 * @details This function is used to set 7-bit slave addresses in I2C SLAVE ADDRESS REGISTER (I2CADDR0~3)
321 * and enable GC Mode.
322 *
323 */
I2C_SetSlaveAddr(I2C_T * i2c,uint8_t u8SlaveNo,uint8_t u8SlaveAddr,uint8_t u8GCMode)324 void I2C_SetSlaveAddr(I2C_T *i2c, uint8_t u8SlaveNo, uint8_t u8SlaveAddr, uint8_t u8GCMode)
325 {
326 switch(u8SlaveNo)
327 {
328 case 1:
329 i2c->ADDR1 = ((uint32_t)u8SlaveAddr << 1U) | u8GCMode;
330 break;
331 case 2:
332 i2c->ADDR2 = ((uint32_t)u8SlaveAddr << 1U) | u8GCMode;
333 break;
334 case 3:
335 i2c->ADDR3 = ((uint32_t)u8SlaveAddr << 1U) | u8GCMode;
336 break;
337 case 0:
338 default:
339 i2c->ADDR0 = ((uint32_t)u8SlaveAddr << 1U) | u8GCMode;
340 break;
341 }
342 }
343
344 /**
345 * @brief Configure the mask bits of 7-bit Slave Address
346 *
347 * @param[in] i2c Specify I2C port
348 * @param[in] u8SlaveNo Set the number of I2C address mask register (0~3)
349 * @param[in] u8SlaveAddrMask A byte for slave address mask
350 *
351 * @return None
352 *
353 * @details This function is used to set 7-bit slave addresses.
354 *
355 */
I2C_SetSlaveAddrMask(I2C_T * i2c,uint8_t u8SlaveNo,uint8_t u8SlaveAddrMask)356 void I2C_SetSlaveAddrMask(I2C_T *i2c, uint8_t u8SlaveNo, uint8_t u8SlaveAddrMask)
357 {
358 switch(u8SlaveNo)
359 {
360 case 1:
361 i2c->ADDRMSK1 = (uint32_t)u8SlaveAddrMask << 1U;
362 break;
363 case 2:
364 i2c->ADDRMSK2 = (uint32_t)u8SlaveAddrMask << 1U;
365 break;
366 case 3:
367 i2c->ADDRMSK3 = (uint32_t)u8SlaveAddrMask << 1U;
368 break;
369 case 0:
370 default:
371 i2c->ADDRMSK0 = (uint32_t)u8SlaveAddrMask << 1U;
372 break;
373 }
374 }
375
376 /**
377 * @brief Enable Time-out Counter Function and support Long Time-out
378 *
379 * @param[in] i2c Specify I2C port
380 * @param[in] u8LongTimeout Configure DIV4 to enable Long Time-out (0/1)
381 *
382 * @return None
383 *
384 * @details This function enable Time-out Counter function and configure DIV4 to support Long
385 * Time-out.
386 *
387 */
I2C_EnableTimeout(I2C_T * i2c,uint8_t u8LongTimeout)388 void I2C_EnableTimeout(I2C_T *i2c, uint8_t u8LongTimeout)
389 {
390 if(u8LongTimeout)
391 {
392 i2c->TOCTL |= I2C_TOCTL_TOCDIV4_Msk;
393 }
394 else
395 {
396 i2c->TOCTL &= ~I2C_TOCTL_TOCDIV4_Msk;
397 }
398
399 i2c->TOCTL |= I2C_TOCTL_TOCEN_Msk;
400 }
401
402 /**
403 * @brief Disable Time-out Counter Function
404 *
405 * @param[in] i2c Specify I2C port
406 *
407 * @return None
408 *
409 * @details To disable Time-out Counter function in I2C_TOCTL register.
410 *
411 */
I2C_DisableTimeout(I2C_T * i2c)412 void I2C_DisableTimeout(I2C_T *i2c)
413 {
414 i2c->TOCTL &= ~I2C_TOCTL_TOCEN_Msk;
415 }
416
417 /**
418 * @brief Enable I2C Wake-up Function
419 *
420 * @param[in] i2c Specify I2C port
421 *
422 * @return None
423 *
424 * @details To enable Wake-up function of I2C Wake-up control register.
425 *
426 */
I2C_EnableWakeup(I2C_T * i2c)427 void I2C_EnableWakeup(I2C_T *i2c)
428 {
429 i2c->WKCTL |= I2C_WKCTL_WKEN_Msk;
430 }
431
432 /**
433 * @brief Disable I2C Wake-up Function
434 *
435 * @param[in] i2c Specify I2C port
436 *
437 * @return None
438 *
439 * @details To disable Wake-up function of I2C Wake-up control register.
440 *
441 */
I2C_DisableWakeup(I2C_T * i2c)442 void I2C_DisableWakeup(I2C_T *i2c)
443 {
444 i2c->WKCTL &= ~I2C_WKCTL_WKEN_Msk;
445 }
446
447 /**
448 * @brief Enable I2C Two-level Buffer Function
449 *
450 * @param[in] i2c Specify I2C port
451 * @param[in] u32BitCount The bit count of date phase.
452 * - \ref I2C_DATA_PHASE_BIT_6
453 * - \ref I2C_DATA_PHASE_BIT_7
454 * - \ref I2C_DATA_PHASE_BIT_8
455 *
456 * @return None
457 *
458 * @details To enable I2C slave mode two-level buffer function.
459 *
460 */
I2C_EnableTwoBufferMode(I2C_T * i2c,uint32_t u32BitCount)461 void I2C_EnableTwoBufferMode(I2C_T *i2c, uint32_t u32BitCount)
462 {
463 /* Enable slave read and data phase interrupt and set data phase bit count */
464 i2c->CTL0 = (i2c->CTL0 & ~0xC33C) | (I2C_CTL0_SRCINTEN_Msk | I2C_CTL0_DPCINTEN_Msk | u32BitCount);
465
466 /* Enable Two-level buffer mode */
467 i2c->CTL1 |= I2C_CTL1_TWOBUFEN_Msk;
468 }
469
470 /**
471 * @brief Disable I2C Two-level Buffer Function
472 *
473 * @param[in] i2c Specify I2C port
474 *
475 * @return None
476 *
477 * @details To disable I2C slave mode two-level buffer function.
478 *
479 */
I2C_DisableTwoBufferMode(I2C_T * i2c)480 void I2C_DisableTwoBufferMode(I2C_T *i2c)
481 {
482 /* Disable slave read and data phase interrupt */
483 i2c->CTL0 = (i2c->CTL0 & ~0xC03C) & ~(I2C_CTL0_SRCINTEN_Msk | I2C_CTL0_DPCINTEN_Msk | I2C_CTL0_DPBITSEL_Msk);
484
485 /* Disable Two-level buffer mode */
486 i2c->CTL1 &= ~I2C_CTL1_TWOBUFEN_Msk;
487 }
488
489 /**
490 * @brief To get SMBus Status
491 *
492 * @param[in] i2c Specify I2C port
493 *
494 * @return SMBus status
495 *
496 * @details To get the Bus Management status of I2C_BUSSTS register
497 *
498 */
I2C_SMBusGetStatus(I2C_T * i2c)499 uint32_t I2C_SMBusGetStatus(I2C_T *i2c)
500 {
501 return (i2c->BUSSTS);
502 }
503
504 /**
505 * @brief Clear SMBus Interrupt Flag
506 *
507 * @param[in] i2c Specify I2C port
508 * @param[in] u8SMBusIntFlag Specify SMBus interrupt flag
509 *
510 * @return None
511 *
512 * @details To clear flags of I2C_BUSSTS status register if interrupt set.
513 *
514 */
I2C_SMBusClearInterruptFlag(I2C_T * i2c,uint8_t u8SMBusIntFlag)515 void I2C_SMBusClearInterruptFlag(I2C_T *i2c, uint8_t u8SMBusIntFlag)
516 {
517 i2c->BUSSTS = u8SMBusIntFlag;
518 }
519
520 /**
521 * @brief Set SMBus Bytes Counts of Transmission or Reception
522 *
523 * @param[in] i2c Specify I2C port
524 * @param[in] u32PktSize Transmit / Receive bytes
525 *
526 * @return None
527 *
528 * @details The transmission or receive byte number in one transaction when PECEN is set. The maximum is 255 bytes.
529 *
530 */
I2C_SMBusSetPacketByteCount(I2C_T * i2c,uint32_t u32PktSize)531 void I2C_SMBusSetPacketByteCount(I2C_T *i2c, uint32_t u32PktSize)
532 {
533 i2c->PKTSIZE = u32PktSize;
534 }
535
536 /**
537 * @brief Init SMBus Host/Device Mode
538 *
539 * @param[in] i2c Specify I2C port
540 * @param[in] u8HostDevice Init SMBus port mode(I2C_SMBH_ENABLE/I2C_SMBD_ENABLE)
541 *
542 * @return None
543 *
544 * @details Using SMBus communication must specify the port is a Host or a Device.
545 *
546 */
I2C_SMBusOpen(I2C_T * i2c,uint8_t u8HostDevice)547 void I2C_SMBusOpen(I2C_T *i2c, uint8_t u8HostDevice)
548 {
549 /* Clear BMHEN, BMDEN of BUSCTL Register */
550 i2c->BUSCTL &= ~(I2C_BUSCTL_BMHEN_Msk | I2C_BUSCTL_BMDEN_Msk);
551
552 /* Set SMBus Host/Device Mode, and enable Bus Management*/
553 if(u8HostDevice == (uint8_t)I2C_SMBH_ENABLE)
554 {
555 i2c->BUSCTL |= (I2C_BUSCTL_BMHEN_Msk | I2C_BUSCTL_BUSEN_Msk);
556 }
557 else
558 {
559 i2c->BUSCTL |= (I2C_BUSCTL_BMDEN_Msk | I2C_BUSCTL_BUSEN_Msk);
560 }
561 }
562
563 /**
564 * @brief Disable SMBus function
565 *
566 * @param[in] i2c Specify I2C port
567 *
568 * @return None
569 *
570 * @details Disable all SMBus function include Bus disable, CRC check, Acknowledge by manual, Host/Device Mode.
571 *
572 */
I2C_SMBusClose(I2C_T * i2c)573 void I2C_SMBusClose(I2C_T *i2c)
574 {
575
576 i2c->BUSCTL = 0x00U;
577 }
578
579 /**
580 * @brief Enable SMBus PEC Transmit Function
581 *
582 * @param[in] i2c Specify I2C port
583 * @param[in] u8PECTxEn CRC transmit enable(PECTX_ENABLE) or disable(PECTX_DISABLE)
584 *
585 * @return None
586 *
587 * @details When enable CRC check function, the Host or Device needs to transmit CRC byte.
588 *
589 */
I2C_SMBusPECTxEnable(I2C_T * i2c,uint8_t u8PECTxEn)590 void I2C_SMBusPECTxEnable(I2C_T *i2c, uint8_t u8PECTxEn)
591 {
592 i2c->BUSCTL &= ~I2C_BUSCTL_PECTXEN_Msk;
593
594 if(u8PECTxEn)
595 {
596 i2c->BUSCTL |= (I2C_BUSCTL_PECEN_Msk | I2C_BUSCTL_PECTXEN_Msk);
597 }
598 else
599 {
600 i2c->BUSCTL |= I2C_BUSCTL_PECEN_Msk;
601 }
602 }
603
604 /**
605 * @brief Get SMBus CRC value
606 *
607 * @param[in] i2c Specify I2C port
608 *
609 * @return A byte is packet error check value
610 *
611 * @details The CRC check value after a transmission or a reception by count by using CRC8
612 *
613 */
I2C_SMBusGetPECValue(I2C_T * i2c)614 uint8_t I2C_SMBusGetPECValue(I2C_T *i2c)
615 {
616 return (uint8_t)i2c->PKTCRC;
617 }
618
619 /**
620 * @brief Calculate Time-out of SMBus idle period
621 *
622 * @param[in] i2c Specify I2C port
623 * @param[in] us Time-out length(us)
624 * @param[in] u32Hclk I2C peripheral clock frequency
625 *
626 * @return None
627 *
628 * @details This function is used to set SMBus Time-out length when bus is in Idle state.
629 *
630 */
631
I2C_SMBusIdleTimeout(I2C_T * i2c,uint32_t us,uint32_t u32Hclk)632 void I2C_SMBusIdleTimeout(I2C_T *i2c, uint32_t us, uint32_t u32Hclk)
633 {
634 uint32_t u32Div, u32Hclk_kHz;
635
636 i2c->BUSCTL |= I2C_BUSCTL_TIDLE_Msk;
637 u32Hclk_kHz = u32Hclk / 1000U;
638 u32Div = (((us * u32Hclk_kHz) / 1000U) >> 2U) - 1U;
639 if(u32Div > 255U)
640 {
641 i2c->BUSTOUT = 0xFFU;
642 }
643 else
644 {
645 i2c->BUSTOUT = u32Div;
646 }
647
648 }
649
650 /**
651 * @brief Calculate Time-out of SMBus active period
652 *
653 * @param[in] i2c Specify I2C port
654 * @param[in] ms Time-out length(ms)
655 * @param[in] u32Pclk peripheral clock frequency
656 *
657 * @return None
658 *
659 * @details This function is used to set SMBus Time-out length when bus is in active state.
660 * Time-out length is calculate the SCL line "one clock" pull low timing.
661 *
662 */
663
I2C_SMBusTimeout(I2C_T * i2c,uint32_t ms,uint32_t u32Pclk)664 void I2C_SMBusTimeout(I2C_T *i2c, uint32_t ms, uint32_t u32Pclk)
665 {
666 uint32_t u32Div, u32Pclk_kHz;
667
668 i2c->BUSCTL &= ~I2C_BUSCTL_TIDLE_Msk;
669
670 /* DIV4 disabled */
671 i2c->TOCTL &= ~I2C_TOCTL_TOCEN_Msk;
672 u32Pclk_kHz = u32Pclk / 1000U;
673 u32Div = ((ms * u32Pclk_kHz) / (16U * 1024U)) - 1U;
674 if(u32Div <= 0xFFU)
675 {
676 i2c->BUSTOUT = u32Div;
677 }
678 else
679 {
680 /* DIV4 enabled */
681 i2c->TOCTL |= I2C_TOCTL_TOCEN_Msk;
682 i2c->BUSTOUT = (((ms * u32Pclk_kHz) / (16U * 1024U * 4U)) - 1U) & 0xFFU; /* The max value is 255 */
683 }
684 }
685
686 /**
687 * @brief Calculate Cumulative Clock low Time-out of SMBus active period
688 *
689 * @param[in] i2c Specify I2C port
690 * @param[in] ms Time-out length(ms)
691 * @param[in] u32Pclk peripheral clock frequency
692 *
693 * @return None
694 *
695 * @details This function is used to set SMBus Time-out length when bus is in Active state.
696 * Time-out length is calculate the SCL line "clocks" low cumulative timing.
697 *
698 */
699
I2C_SMBusClockLoTimeout(I2C_T * i2c,uint32_t ms,uint32_t u32Pclk)700 void I2C_SMBusClockLoTimeout(I2C_T *i2c, uint32_t ms, uint32_t u32Pclk)
701 {
702 uint32_t u32Div, u32Pclk_kHz;
703
704 i2c->BUSCTL &= ~I2C_BUSCTL_TIDLE_Msk;
705
706 /* DIV4 disabled */
707 i2c->TOCTL &= ~I2C_TOCTL_TOCEN_Msk;
708 u32Pclk_kHz = u32Pclk / 1000U;
709 u32Div = ((ms * u32Pclk_kHz) / (16U * 1024U)) - 1U;
710 if(u32Div <= 0xFFU)
711 {
712 i2c->CLKTOUT = u32Div;
713 }
714 else
715 {
716 /* DIV4 enabled */
717 i2c->TOCTL |= I2C_TOCTL_TOCEN_Msk;
718 i2c->CLKTOUT = (((ms * u32Pclk_kHz) / (16U * 1024U * 4U)) - 1U) & 0xFFU; /* The max value is 255 */
719 }
720 }
721
722
723 /**
724 * @brief Write a byte to Slave
725 *
726 * @param[in] i2c Point to I2C peripheral
727 * @param[in] u8SlaveAddr Access Slave address(7-bit)
728 * @param[in] data Write a byte data to Slave
729 *
730 * @retval 0 Write data success
731 * @retval 1 Write data fail, or bus occurs error events
732 *
733 * @details The function is used for I2C Master write a byte data to Slave.
734 *
735 */
736
I2C_WriteByte(I2C_T * i2c,uint8_t u8SlaveAddr,uint8_t data)737 uint8_t I2C_WriteByte(I2C_T *i2c, uint8_t u8SlaveAddr, uint8_t data)
738 {
739 uint8_t u8Xfering = 1u, u8Err = 0u, u8Ctrl = 0u;
740 uint32_t u32TimeOutCount;
741
742 g_I2C_i32ErrCode = 0;
743
744 I2C_START(i2c);
745 while(u8Xfering && (u8Err == 0u))
746 {
747 u32TimeOutCount = SystemCoreClock;
748 I2C_WAIT_READY(i2c)
749 {
750 u32TimeOutCount--;
751 if(u32TimeOutCount == 0)
752 {
753 g_I2C_i32ErrCode = I2C_TIMEOUT_ERR;
754 break;
755 }
756 }
757
758 switch(I2C_GET_STATUS(i2c))
759 {
760 case 0x08u:
761 I2C_SET_DATA(i2c, (uint8_t)(u8SlaveAddr << 1u | 0x00u)); /* Write SLA+W to Register I2CDAT */
762 u8Ctrl = I2C_CTL_SI; /* Clear SI */
763 break;
764 case 0x18u: /* Slave Address ACK */
765 I2C_SET_DATA(i2c, data); /* Write data to I2CDAT */
766 break;
767 case 0x20u: /* Slave Address NACK */
768 case 0x30u: /* Master transmit data NACK */
769 u8Ctrl = I2C_CTL_STO_SI; /* Clear SI and send STOP */
770 u8Err = 1u;
771 break;
772 case 0x28u:
773 u8Ctrl = I2C_CTL_STO_SI; /* Clear SI and send STOP */
774 u8Xfering = 0u;
775 break;
776 case 0x38u: /* Arbitration Lost */
777 default: /* Unknow status */
778 I2C_SET_CONTROL_REG(i2c, I2C_CTL_STO_SI); /* Clear SI and send STOP */
779 u8Ctrl = I2C_CTL_SI;
780 u8Err = 1u;
781 break;
782 }
783 I2C_SET_CONTROL_REG(i2c, u8Ctrl); /* Write controlbit to I2C_CTL register */
784 }
785 return (u8Err | u8Xfering); /* return (Success)/(Fail) status */
786 }
787
788 /**
789 * @brief Write multi bytes to Slave
790 *
791 * @param[in] i2c Point to I2C peripheral
792 * @param[in] u8SlaveAddr Access Slave address(7-bit)
793 * @param[in] data[] Pointer to array to write data to Slave
794 * @param[in] u32wLen How many bytes need to write to Slave
795 *
796 * @return A length of how many bytes have been transmitted.
797 *
798 * @details The function is used for I2C Master write multi bytes data to Slave.
799 *
800 */
801
I2C_WriteMultiBytes(I2C_T * i2c,uint8_t u8SlaveAddr,uint8_t data[],uint32_t u32wLen)802 uint32_t I2C_WriteMultiBytes(I2C_T *i2c, uint8_t u8SlaveAddr, uint8_t data[], uint32_t u32wLen)
803 {
804 uint8_t u8Xfering = 1u, u8Err = 0u, u8Ctrl = 0u;
805 uint32_t u32txLen = 0u;
806 uint32_t u32TimeOutCount;
807
808 g_I2C_i32ErrCode = 0;
809
810 I2C_START(i2c); /* Send START */
811 while(u8Xfering && (u8Err == 0u))
812 {
813 u32TimeOutCount = SystemCoreClock;
814 I2C_WAIT_READY(i2c)
815 {
816 u32TimeOutCount--;
817 if(u32TimeOutCount == 0)
818 {
819 g_I2C_i32ErrCode = I2C_TIMEOUT_ERR;
820 break;
821 }
822 }
823
824 switch(I2C_GET_STATUS(i2c))
825 {
826 case 0x08u:
827 I2C_SET_DATA(i2c, (uint8_t)(u8SlaveAddr << 1u | 0x00u)); /* Write SLA+W to Register I2CDAT */
828 u8Ctrl = I2C_CTL_SI; /* Clear SI */
829 break;
830 case 0x18u: /* Slave Address ACK */
831 case 0x28u:
832 if(u32txLen < u32wLen)
833 {
834 I2C_SET_DATA(i2c, data[u32txLen++]); /* Write Data to I2CDAT */
835 }
836 else
837 {
838 u8Ctrl = I2C_CTL_STO_SI; /* Clear SI and send STOP */
839 u8Xfering = 0u;
840 }
841 break;
842 case 0x20u: /* Slave Address NACK */
843 case 0x30u: /* Master transmit data NACK */
844 u8Ctrl = I2C_CTL_STO_SI; /* Clear SI and send STOP */
845 u8Err = 1u;
846 break;
847 case 0x38u: /* Arbitration Lost */
848 default: /* Unknow status */
849 I2C_SET_CONTROL_REG(i2c, I2C_CTL_STO_SI); /* Clear SI and send STOP */
850 u8Ctrl = I2C_CTL_SI;
851 u8Err = 1u;
852 break;
853 }
854 I2C_SET_CONTROL_REG(i2c, u8Ctrl); /* Write controlbit to I2C_CTL register */
855 }
856 return u32txLen; /* Return bytes length that have been transmitted */
857 }
858
859 /**
860 * @brief Specify a byte register address and write a byte to Slave
861 *
862 * @param[in] i2c Point to I2C peripheral
863 * @param[in] u8SlaveAddr Access Slave address(7-bit)
864 * @param[in] u8DataAddr Specify a address (1 byte) of data write to
865 * @param[in] data A byte data to write it to Slave
866 *
867 * @retval 0 Write data success
868 * @retval 1 Write data fail, or bus occurs error events
869 *
870 * @details The function is used for I2C Master specify a address that data write to in Slave.
871 *
872 */
873
I2C_WriteByteOneReg(I2C_T * i2c,uint8_t u8SlaveAddr,uint8_t u8DataAddr,uint8_t data)874 uint8_t I2C_WriteByteOneReg(I2C_T *i2c, uint8_t u8SlaveAddr, uint8_t u8DataAddr, uint8_t data)
875 {
876 uint8_t u8Xfering = 1u, u8Err = 0u, u8Ctrl = 0u;
877 uint32_t u32txLen = 0u;
878 uint32_t u32TimeOutCount;
879
880 g_I2C_i32ErrCode = 0;
881
882 I2C_START(i2c); /* Send START */
883 while(u8Xfering && (u8Err == 0u))
884 {
885 u32TimeOutCount = SystemCoreClock;
886 I2C_WAIT_READY(i2c)
887 {
888 u32TimeOutCount--;
889 if(u32TimeOutCount == 0)
890 {
891 g_I2C_i32ErrCode = I2C_TIMEOUT_ERR;
892 break;
893 }
894 }
895
896 switch(I2C_GET_STATUS(i2c))
897 {
898 case 0x08u:
899 I2C_SET_DATA(i2c, (uint8_t)(u8SlaveAddr << 1u | 0x00u)); /* Send Slave address with write bit */
900 u8Ctrl = I2C_CTL_SI; /* Clear SI */
901 break;
902 case 0x18u: /* Slave Address ACK */
903 I2C_SET_DATA(i2c, u8DataAddr); /* Write Lo byte address of register */
904 break;
905 case 0x20u: /* Slave Address NACK */
906 case 0x30u: /* Master transmit data NACK */
907 u8Ctrl = I2C_CTL_STO_SI; /* Clear SI and send STOP */
908 u8Err = 1u;
909 break;
910 case 0x28u:
911 if(u32txLen < 1u)
912 {
913 I2C_SET_DATA(i2c, data);
914 u32txLen++;
915 }
916 else
917 {
918 u8Ctrl = I2C_CTL_STO_SI; /* Clear SI and send STOP */
919 u8Xfering = 0u;
920 }
921 break;
922 case 0x38u: /* Arbitration Lost */
923 default: /* Unknow status */
924 I2C_SET_CONTROL_REG(i2c, I2C_CTL_STO_SI); /* Clear SI and send STOP */
925 u8Ctrl = I2C_CTL_SI;
926 u8Err = 1u;
927 break;
928 }
929 I2C_SET_CONTROL_REG(i2c, u8Ctrl); /* Write controlbit to I2C_CTL register */
930 }
931 return (u8Err | u8Xfering); /* return (Success)/(Fail) status */
932 }
933
934
935 /**
936 * @brief Specify a byte register address and write multi bytes to Slave
937 *
938 * @param[in] i2c Point to I2C peripheral
939 * @param[in] u8SlaveAddr Access Slave address(7-bit)
940 * @param[in] u8DataAddr Specify a address (1 byte) of data write to
941 * @param[in] data[] Pointer to array to write data to Slave
942 * @param[in] u32wLen How many bytes need to write to Slave
943 *
944 * @return A length of how many bytes have been transmitted.
945 *
946 * @details The function is used for I2C Master specify a byte address that multi data bytes write to in Slave.
947 *
948 */
949
I2C_WriteMultiBytesOneReg(I2C_T * i2c,uint8_t u8SlaveAddr,uint8_t u8DataAddr,uint8_t data[],uint32_t u32wLen)950 uint32_t I2C_WriteMultiBytesOneReg(I2C_T *i2c, uint8_t u8SlaveAddr, uint8_t u8DataAddr, uint8_t data[], uint32_t u32wLen)
951 {
952 uint8_t u8Xfering = 1u, u8Err = 0u, u8Ctrl = 0u;
953 uint32_t u32txLen = 0u;
954 uint32_t u32TimeOutCount;
955
956 g_I2C_i32ErrCode = 0;
957
958 I2C_START(i2c); /* Send START */
959 while(u8Xfering && (u8Err == 0u))
960 {
961 u32TimeOutCount = SystemCoreClock;
962 I2C_WAIT_READY(i2c)
963 {
964 u32TimeOutCount--;
965 if(u32TimeOutCount == 0)
966 {
967 g_I2C_i32ErrCode = I2C_TIMEOUT_ERR;
968 break;
969 }
970 }
971
972 switch(I2C_GET_STATUS(i2c))
973 {
974 case 0x08u:
975 I2C_SET_DATA(i2c, (uint8_t)(u8SlaveAddr << 1u | 0x00u)); /* Write SLA+W to Register I2CDAT */
976 u8Ctrl = I2C_CTL_SI;
977 break;
978 case 0x18u: /* Slave Address ACK */
979 I2C_SET_DATA(i2c, u8DataAddr); /* Write Lo byte address of register */
980 break;
981 case 0x20u: /* Slave Address NACK */
982 case 0x30u: /* Master transmit data NACK */
983 u8Ctrl = I2C_CTL_STO_SI; /* Clear SI and send STOP */
984 u8Err = 1u;
985 break;
986 case 0x28u:
987 if(u32txLen < u32wLen)
988 {
989 I2C_SET_DATA(i2c, data[u32txLen++]);
990 }
991 else
992 {
993 u8Ctrl = I2C_CTL_STO_SI; /* Clear SI and send STOP */
994 u8Xfering = 0u;
995 }
996 break;
997 case 0x38u: /* Arbitration Lost */
998 default: /* Unknow status */
999 I2C_SET_CONTROL_REG(i2c, I2C_CTL_STO_SI); /* Clear SI and send STOP */
1000 u8Ctrl = I2C_CTL_SI;
1001 u8Err = 1u;
1002 break;
1003 }
1004 I2C_SET_CONTROL_REG(i2c, u8Ctrl); /* Write controlbit to I2C_CTL register */
1005 }
1006
1007 return u32txLen; /* Return bytes length that have been transmitted */
1008 }
1009
1010 /**
1011 * @brief Specify two bytes register address and Write a byte to Slave
1012 *
1013 * @param[in] i2c Point to I2C peripheral
1014 * @param[in] u8SlaveAddr Access Slave address(7-bit)
1015 * @param[in] u16DataAddr Specify a address (2 byte) of data write to
1016 * @param[in] data Write a byte data to Slave
1017 *
1018 * @retval 0 Write data success
1019 * @retval 1 Write data fail, or bus occurs error events
1020 *
1021 * @details The function is used for I2C Master specify two bytes address that data write to in Slave.
1022 *
1023 */
1024
I2C_WriteByteTwoRegs(I2C_T * i2c,uint8_t u8SlaveAddr,uint16_t u16DataAddr,uint8_t data)1025 uint8_t I2C_WriteByteTwoRegs(I2C_T *i2c, uint8_t u8SlaveAddr, uint16_t u16DataAddr, uint8_t data)
1026 {
1027 uint8_t u8Xfering = 1u, u8Err = 0u, u8Addr = 1u, u8Ctrl = 0u;
1028 uint32_t u32txLen = 0u;
1029 uint32_t u32TimeOutCount;
1030
1031 g_I2C_i32ErrCode = 0;
1032
1033 I2C_START(i2c); /* Send START */
1034 while(u8Xfering && (u8Err == 0u))
1035 {
1036 u32TimeOutCount = SystemCoreClock;
1037 I2C_WAIT_READY(i2c)
1038 {
1039 u32TimeOutCount--;
1040 if(u32TimeOutCount == 0)
1041 {
1042 g_I2C_i32ErrCode = I2C_TIMEOUT_ERR;
1043 break;
1044 }
1045 }
1046
1047 switch(I2C_GET_STATUS(i2c))
1048 {
1049 case 0x08u:
1050 I2C_SET_DATA(i2c, (uint8_t)(u8SlaveAddr << 1u | 0x00u)); /* Write SLA+W to Register I2CDAT */
1051 u8Ctrl = I2C_CTL_SI; /* Clear SI */
1052 break;
1053 case 0x18u: /* Slave Address ACK */
1054 I2C_SET_DATA(i2c, (uint8_t)((u16DataAddr & 0xFF00u) >> 8u)); /* Write Hi byte address of register */
1055 break;
1056 case 0x20u: /* Slave Address NACK */
1057 case 0x30u: /* Master transmit data NACK */
1058 u8Ctrl = I2C_CTL_STO_SI; /* Clear SI and send STOP */
1059 u8Err = 1u;
1060 break;
1061 case 0x28u:
1062 if(u8Addr)
1063 {
1064 I2C_SET_DATA(i2c, (uint8_t)(u16DataAddr & 0xFFu)); /* Write Lo byte address of register */
1065 u8Addr = 0u;
1066 }
1067 else if((u32txLen < 1u) && (u8Addr == 0u))
1068 {
1069 I2C_SET_DATA(i2c, data);
1070 u32txLen++;
1071 }
1072 else
1073 {
1074 u8Ctrl = I2C_CTL_STO_SI; /* Clear SI and send STOP */
1075 u8Xfering = 0u;
1076 }
1077 break;
1078 case 0x38u: /* Arbitration Lost */
1079 default: /* Unknow status */
1080 I2C_SET_CONTROL_REG(i2c, I2C_CTL_STO_SI); /* Clear SI and send STOP */
1081 u8Ctrl = I2C_CTL_SI;
1082 u8Err = 1u;
1083 break;
1084 }
1085 I2C_SET_CONTROL_REG(i2c, u8Ctrl); /* Write controlbit to I2C_CTL register */
1086 }
1087 return (u8Err | u8Xfering); /* return (Success)/(Fail) status */
1088 }
1089
1090
1091 /**
1092 * @brief Specify two bytes register address and write multi bytes to Slave
1093 *
1094 * @param[in] i2c Point to I2C peripheral
1095 * @param[in] u8SlaveAddr Access Slave address(7-bit)
1096 * @param[in] u16DataAddr Specify a address (2 bytes) of data write to
1097 * @param[in] data[] A data array for write data to Slave
1098 * @param[in] u32wLen How many bytes need to write to Slave
1099 *
1100 * @return A length of how many bytes have been transmitted.
1101 *
1102 * @details The function is used for I2C Master specify two bytes address that multi data write to in Slave.
1103 *
1104 */
1105
I2C_WriteMultiBytesTwoRegs(I2C_T * i2c,uint8_t u8SlaveAddr,uint16_t u16DataAddr,uint8_t data[],uint32_t u32wLen)1106 uint32_t I2C_WriteMultiBytesTwoRegs(I2C_T *i2c, uint8_t u8SlaveAddr, uint16_t u16DataAddr, uint8_t data[], uint32_t u32wLen)
1107 {
1108 uint8_t u8Xfering = 1u, u8Err = 0u, u8Addr = 1u, u8Ctrl = 0u;
1109 uint32_t u32txLen = 0u;
1110 uint32_t u32TimeOutCount;
1111
1112 g_I2C_i32ErrCode = 0;
1113
1114 I2C_START(i2c); /* Send START */
1115 while(u8Xfering && (u8Err == 0u))
1116 {
1117 u32TimeOutCount = SystemCoreClock;
1118 I2C_WAIT_READY(i2c)
1119 {
1120 u32TimeOutCount--;
1121 if(u32TimeOutCount == 0)
1122 {
1123 g_I2C_i32ErrCode = I2C_TIMEOUT_ERR;
1124 break;
1125 }
1126 }
1127
1128 switch(I2C_GET_STATUS(i2c))
1129 {
1130 case 0x08u:
1131 I2C_SET_DATA(i2c, (uint8_t)(u8SlaveAddr << 1u | 0x00u)); /* Write SLA+W to Register I2CDAT */
1132 u8Ctrl = I2C_CTL_SI; /* Clear SI */
1133 break;
1134 case 0x18u: /* Slave Address ACK */
1135 I2C_SET_DATA(i2c, (uint8_t)((u16DataAddr & 0xFF00u) >> 8u)); /* Write Hi byte address of register */
1136 break;
1137 case 0x20u: /* Slave Address NACK */
1138 case 0x30u: /* Master transmit data NACK */
1139 u8Ctrl = I2C_CTL_STO_SI; /* Clear SI and send STOP */
1140 u8Err = 1u;
1141 break;
1142 case 0x28u:
1143 if(u8Addr)
1144 {
1145 I2C_SET_DATA(i2c, (uint8_t)(u16DataAddr & 0xFFu)); /* Write Lo byte address of register */
1146 u8Addr = 0u;
1147 }
1148 else if((u32txLen < u32wLen) && (u8Addr == 0u))
1149 {
1150 I2C_SET_DATA(i2c, data[u32txLen++]); /* Write data to Register I2CDAT*/
1151 }
1152 else
1153 {
1154 u8Ctrl = I2C_CTL_STO_SI; /* Clear SI and send STOP */
1155 u8Xfering = 0u;
1156 }
1157 break;
1158 case 0x38u: /* Arbitration Lost */
1159 default: /* Unknow status */
1160 I2C_SET_CONTROL_REG(i2c, I2C_CTL_STO_SI); /* Clear SI and send STOP */
1161 u8Ctrl = I2C_CTL_SI;
1162 u8Err = 1u;
1163 break;
1164 }
1165 I2C_SET_CONTROL_REG(i2c, u8Ctrl); /* Write controlbit to I2C_CTL register */
1166 }
1167 return u32txLen; /* Return bytes length that have been transmitted */
1168 }
1169
1170 /**
1171 * @brief Read a byte from Slave
1172 *
1173 * @param[in] i2c Point to I2C peripheral
1174 * @param[in] u8SlaveAddr Access Slave address(7-bit)
1175 *
1176 * @return Read a byte data from Slave
1177 *
1178 * @details The function is used for I2C Master to read a byte data from Slave.
1179 *
1180 */
I2C_ReadByte(I2C_T * i2c,uint8_t u8SlaveAddr)1181 uint8_t I2C_ReadByte(I2C_T *i2c, uint8_t u8SlaveAddr)
1182 {
1183 uint8_t u8Xfering = 1u, u8Err = 0u, rdata = 0u, u8Ctrl = 0u;
1184 uint32_t u32TimeOutCount;
1185
1186 g_I2C_i32ErrCode = 0;
1187
1188 I2C_START(i2c); /* Send START */
1189 while(u8Xfering && (u8Err == 0u))
1190 {
1191 u32TimeOutCount = SystemCoreClock;
1192 I2C_WAIT_READY(i2c)
1193 {
1194 u32TimeOutCount--;
1195 if(u32TimeOutCount == 0)
1196 {
1197 g_I2C_i32ErrCode = I2C_TIMEOUT_ERR;
1198 break;
1199 }
1200 }
1201
1202 switch(I2C_GET_STATUS(i2c))
1203 {
1204 case 0x08u:
1205 I2C_SET_DATA(i2c, (uint8_t)((u8SlaveAddr << 1u) | 0x01u)); /* Write SLA+R to Register I2CDAT */
1206 u8Ctrl = I2C_CTL_SI; /* Clear SI */
1207 break;
1208 case 0x40u: /* Slave Address ACK */
1209 u8Ctrl = I2C_CTL_SI; /* Clear SI */
1210 break;
1211 case 0x48u: /* Slave Address NACK */
1212 u8Ctrl = I2C_CTL_STO_SI; /* Clear SI and send STOP */
1213 u8Err = 1u;
1214 break;
1215 case 0x58u:
1216 rdata = (uint8_t) I2C_GET_DATA(i2c); /* Receive Data */
1217 u8Ctrl = I2C_CTL_STO_SI; /* Clear SI and send STOP */
1218 u8Xfering = 0u;
1219 break;
1220 case 0x38u: /* Arbitration Lost */
1221 default: /* Unknow status */
1222 I2C_SET_CONTROL_REG(i2c, I2C_CTL_STO_SI); /* Clear SI and send STOP */
1223 u8Ctrl = I2C_CTL_SI;
1224 u8Err = 1u;
1225 break;
1226 }
1227 I2C_SET_CONTROL_REG(i2c, u8Ctrl); /* Write controlbit to I2C_CTL register */
1228 }
1229 if(u8Err)
1230 {
1231 rdata = 0u; /* If occurs error, return 0 */
1232 }
1233 return rdata; /* Return read data */
1234 }
1235
1236
1237 /**
1238 * @brief Read multi bytes from Slave
1239 *
1240 * @param[in] i2c Point to I2C peripheral
1241 * @param[in] u8SlaveAddr Access Slave address(7-bit)
1242 * @param[out] rdata[] A data array to store data from Slave
1243 * @param[in] u32rLen How many bytes need to read from Slave
1244 *
1245 * @return A length of how many bytes have been received
1246 *
1247 * @details The function is used for I2C Master to read multi data bytes from Slave.
1248 *
1249 *
1250 */
I2C_ReadMultiBytes(I2C_T * i2c,uint8_t u8SlaveAddr,uint8_t rdata[],uint32_t u32rLen)1251 uint32_t I2C_ReadMultiBytes(I2C_T *i2c, uint8_t u8SlaveAddr, uint8_t rdata[], uint32_t u32rLen)
1252 {
1253 uint8_t u8Xfering = 1u, u8Err = 0u, u8Ctrl = 0u;
1254 uint32_t u32rxLen = 0u;
1255 uint32_t u32TimeOutCount;
1256
1257 g_I2C_i32ErrCode = 0;
1258
1259 I2C_START(i2c); /* Send START */
1260 while(u8Xfering && (u8Err == 0u))
1261 {
1262 u32TimeOutCount = SystemCoreClock;
1263 I2C_WAIT_READY(i2c)
1264 {
1265 u32TimeOutCount--;
1266 if(u32TimeOutCount == 0)
1267 {
1268 g_I2C_i32ErrCode = I2C_TIMEOUT_ERR;
1269 break;
1270 }
1271 }
1272
1273 switch(I2C_GET_STATUS(i2c))
1274 {
1275 case 0x08u:
1276 I2C_SET_DATA(i2c, (uint8_t)((u8SlaveAddr << 1u) | 0x01u)); /* Write SLA+R to Register I2CDAT */
1277 u8Ctrl = I2C_CTL_SI; /* Clear SI */
1278 break;
1279 case 0x40u: /* Slave Address ACK */
1280 u8Ctrl = I2C_CTL_SI_AA; /* Clear SI and set ACK */
1281 break;
1282 case 0x48u: /* Slave Address NACK */
1283 u8Ctrl = I2C_CTL_STO_SI; /* Clear SI and send STOP */
1284 u8Err = 1u;
1285 break;
1286 case 0x50u:
1287 rdata[u32rxLen++] = (uint8_t) I2C_GET_DATA(i2c); /* Receive Data */
1288 if(u32rxLen < (u32rLen - 1u))
1289 {
1290 u8Ctrl = I2C_CTL_SI_AA; /* Clear SI and set ACK */
1291 }
1292 else
1293 {
1294 u8Ctrl = I2C_CTL_SI; /* Clear SI */
1295 }
1296 break;
1297 case 0x58u:
1298 rdata[u32rxLen++] = (uint8_t) I2C_GET_DATA(i2c); /* Receive Data */
1299 u8Ctrl = I2C_CTL_STO_SI; /* Clear SI and send STOP */
1300 u8Xfering = 0u;
1301 break;
1302 case 0x38u: /* Arbitration Lost */
1303 default: /* Unknow status */
1304 I2C_SET_CONTROL_REG(i2c, I2C_CTL_STO_SI); /* Clear SI and send STOP */
1305 u8Ctrl = I2C_CTL_SI;
1306 u8Err = 1u;
1307 break;
1308 }
1309 I2C_SET_CONTROL_REG(i2c, u8Ctrl); /* Write controlbit to I2C_CTL register */
1310 }
1311 return u32rxLen; /* Return bytes length that have been received */
1312 }
1313
1314
1315 /**
1316 * @brief Specify a byte register address and read a byte from Slave
1317 *
1318 * @param[in] i2c Point to I2C peripheral
1319 * @param[in] u8SlaveAddr Access Slave address(7-bit)
1320 * @param[in] u8DataAddr Specify a address(1 byte) of data read from
1321 *
1322 * @return Read a byte data from Slave
1323 *
1324 * @details The function is used for I2C Master specify a byte address that a data byte read from Slave.
1325 *
1326 *
1327 */
I2C_ReadByteOneReg(I2C_T * i2c,uint8_t u8SlaveAddr,uint8_t u8DataAddr)1328 uint8_t I2C_ReadByteOneReg(I2C_T *i2c, uint8_t u8SlaveAddr, uint8_t u8DataAddr)
1329 {
1330 uint8_t u8Xfering = 1u, u8Err = 0u, rdata = 0u, u8Ctrl = 0u;
1331 uint32_t u32TimeOutCount;
1332
1333 g_I2C_i32ErrCode = 0;
1334
1335 I2C_START(i2c); /* Send START */
1336 while(u8Xfering && (u8Err == 0u))
1337 {
1338 u32TimeOutCount = SystemCoreClock;
1339 I2C_WAIT_READY(i2c)
1340 {
1341 u32TimeOutCount--;
1342 if(u32TimeOutCount == 0)
1343 {
1344 g_I2C_i32ErrCode = I2C_TIMEOUT_ERR;
1345 break;
1346 }
1347 }
1348
1349 switch(I2C_GET_STATUS(i2c))
1350 {
1351 case 0x08u:
1352 I2C_SET_DATA(i2c, (uint8_t)(u8SlaveAddr << 1u | 0x00u)); /* Write SLA+W to Register I2CDAT */
1353 u8Ctrl = I2C_CTL_SI; /* Clear SI */
1354 break;
1355 case 0x18u: /* Slave Address ACK */
1356 I2C_SET_DATA(i2c, u8DataAddr); /* Write Lo byte address of register */
1357 break;
1358 case 0x20u: /* Slave Address NACK */
1359 case 0x30u: /* Master transmit data NACK */
1360 u8Ctrl = I2C_CTL_STO_SI; /* Clear SI and send STOP */
1361 u8Err = 1u;
1362 break;
1363 case 0x28u:
1364 u8Ctrl = I2C_CTL_STA_SI; /* Send repeat START */
1365 break;
1366 case 0x10u:
1367 I2C_SET_DATA(i2c, (uint8_t)((u8SlaveAddr << 1u) | 0x01u)); /* Write SLA+R to Register I2CDAT */
1368 u8Ctrl = I2C_CTL_SI; /* Clear SI */
1369 break;
1370 case 0x40u: /* Slave Address ACK */
1371 u8Ctrl = I2C_CTL_SI; /* Clear SI */
1372 break;
1373 case 0x48u: /* Slave Address NACK */
1374 u8Ctrl = I2C_CTL_STO_SI; /* Clear SI and send STOP */
1375 u8Err = 1u;
1376 break;
1377 case 0x58u:
1378 rdata = (uint8_t) I2C_GET_DATA(i2c); /* Receive Data */
1379 u8Ctrl = I2C_CTL_STO_SI; /* Clear SI and send STOP */
1380 u8Xfering = 0u;
1381 break;
1382 case 0x38u: /* Arbitration Lost */
1383 default: /* Unknow status */
1384 I2C_SET_CONTROL_REG(i2c, I2C_CTL_STO_SI); /* Clear SI and send STOP */
1385 u8Ctrl = I2C_CTL_SI;
1386 u8Err = 1u;
1387 break;
1388 }
1389 I2C_SET_CONTROL_REG(i2c, u8Ctrl); /* Write controlbit to I2C_CTL register */
1390 }
1391 if(u8Err)
1392 {
1393 rdata = 0u; /* If occurs error, return 0 */
1394 }
1395 return rdata; /* Return read data */
1396 }
1397
1398 /**
1399 * @brief Specify a byte register address and read multi bytes from Slave
1400 *
1401 * @param[in] i2c Point to I2C peripheral
1402 * @param[in] u8SlaveAddr Access Slave address(7-bit)
1403 * @param[in] u8DataAddr Specify a address (1 byte) of data read from
1404 * @param[out] rdata[] A data array to store data from Slave
1405 * @param[in] u32rLen How many bytes need to read from Slave
1406 *
1407 * @return A length of how many bytes have been received
1408 *
1409 * @details The function is used for I2C Master specify a byte address that multi data bytes read from Slave.
1410 *
1411 *
1412 */
I2C_ReadMultiBytesOneReg(I2C_T * i2c,uint8_t u8SlaveAddr,uint8_t u8DataAddr,uint8_t rdata[],uint32_t u32rLen)1413 uint32_t I2C_ReadMultiBytesOneReg(I2C_T *i2c, uint8_t u8SlaveAddr, uint8_t u8DataAddr, uint8_t rdata[], uint32_t u32rLen)
1414 {
1415 uint8_t u8Xfering = 1u, u8Err = 0u, u8Ctrl = 0u;
1416 uint32_t u32rxLen = 0u;
1417 uint32_t u32TimeOutCount;
1418
1419 g_I2C_i32ErrCode = 0;
1420
1421 I2C_START(i2c); /* Send START */
1422 while(u8Xfering && (u8Err == 0u))
1423 {
1424 u32TimeOutCount = SystemCoreClock;
1425 I2C_WAIT_READY(i2c)
1426 {
1427 u32TimeOutCount--;
1428 if(u32TimeOutCount == 0)
1429 {
1430 g_I2C_i32ErrCode = I2C_TIMEOUT_ERR;
1431 break;
1432 }
1433 }
1434
1435 switch(I2C_GET_STATUS(i2c))
1436 {
1437 case 0x08u:
1438 I2C_SET_DATA(i2c, (uint8_t)(u8SlaveAddr << 1u | 0x00u)); /* Write SLA+W to Register I2CDAT */
1439 u8Ctrl = I2C_CTL_SI; /* Clear SI */
1440 break;
1441 case 0x18u: /* Slave Address ACK */
1442 I2C_SET_DATA(i2c, u8DataAddr); /* Write Lo byte address of register */
1443 break;
1444 case 0x20u: /* Slave Address NACK */
1445 case 0x30u: /* Master transmit data NACK */
1446 u8Ctrl = I2C_CTL_STO_SI; /* Clear SI and send STOP */
1447 u8Err = 1u;
1448 break;
1449 case 0x28u:
1450 u8Ctrl = I2C_CTL_STA_SI; /* Send repeat START */
1451 break;
1452 case 0x10u:
1453 I2C_SET_DATA(i2c, (uint8_t)((u8SlaveAddr << 1u) | 0x01u)); /* Write SLA+R to Register I2CDAT */
1454 u8Ctrl = I2C_CTL_SI; /* Clear SI */
1455 break;
1456 case 0x40u: /* Slave Address ACK */
1457 u8Ctrl = I2C_CTL_SI_AA; /* Clear SI and set ACK */
1458 break;
1459 case 0x48u: /* Slave Address NACK */
1460 u8Ctrl = I2C_CTL_STO_SI; /* Clear SI and send STOP */
1461 u8Err = 1u;
1462 break;
1463 case 0x50u:
1464 rdata[u32rxLen++] = (uint8_t) I2C_GET_DATA(i2c); /* Receive Data */
1465 if(u32rxLen < (u32rLen - 1u))
1466 {
1467 u8Ctrl = I2C_CTL_SI_AA; /* Clear SI and set ACK */
1468 }
1469 else
1470 {
1471 u8Ctrl = I2C_CTL_SI; /* Clear SI */
1472 }
1473 break;
1474 case 0x58u:
1475 rdata[u32rxLen++] = (uint8_t) I2C_GET_DATA(i2c); /* Receive Data */
1476 u8Ctrl = I2C_CTL_STO_SI; /* Clear SI and send STOP */
1477 u8Xfering = 0u;
1478 break;
1479 case 0x38u: /* Arbitration Lost */
1480 default: /* Unknow status */
1481 I2C_SET_CONTROL_REG(i2c, I2C_CTL_STO_SI); /* Clear SI and send STOP */
1482 u8Ctrl = I2C_CTL_SI;
1483 u8Err = 1u;
1484 break;
1485 }
1486 I2C_SET_CONTROL_REG(i2c, u8Ctrl); /* Write controlbit to I2C_CTL register */
1487 }
1488 return u32rxLen; /* Return bytes length that have been received */
1489 }
1490
1491 /**
1492 * @brief Specify two bytes register address and read a byte from Slave
1493 *
1494 * @param[in] i2c Point to I2C peripheral
1495 * @param[in] u8SlaveAddr Access Slave address(7-bit)
1496 * @param[in] u16DataAddr Specify an address(2 bytes) of data read from
1497 *
1498 * @return Read a byte data from Slave
1499 *
1500 * @details The function is used for I2C Master specify two bytes address that a data byte read from Slave.
1501 *
1502 *
1503 */
I2C_ReadByteTwoRegs(I2C_T * i2c,uint8_t u8SlaveAddr,uint16_t u16DataAddr)1504 uint8_t I2C_ReadByteTwoRegs(I2C_T *i2c, uint8_t u8SlaveAddr, uint16_t u16DataAddr)
1505 {
1506 uint8_t u8Xfering = 1u, u8Err = 0u, rdata = 0u, u8Addr = 1u, u8Ctrl = 0u;
1507 uint32_t u32TimeOutCount;
1508
1509 g_I2C_i32ErrCode = 0;
1510
1511 I2C_START(i2c); /* Send START */
1512 while(u8Xfering && (u8Err == 0u))
1513 {
1514 u32TimeOutCount = SystemCoreClock;
1515 I2C_WAIT_READY(i2c)
1516 {
1517 u32TimeOutCount--;
1518 if(u32TimeOutCount == 0)
1519 {
1520 g_I2C_i32ErrCode = I2C_TIMEOUT_ERR;
1521 break;
1522 }
1523 }
1524
1525 switch(I2C_GET_STATUS(i2c))
1526 {
1527 case 0x08u:
1528 I2C_SET_DATA(i2c, (uint8_t)(u8SlaveAddr << 1u | 0x00u)); /* Write SLA+W to Register I2CDAT */
1529 u8Ctrl = I2C_CTL_SI; /* Clear SI */
1530 break;
1531 case 0x18u: /* Slave Address ACK */
1532 I2C_SET_DATA(i2c, (uint8_t)((u16DataAddr & 0xFF00u) >> 8u)); /* Write Hi byte address of register */
1533 break;
1534 case 0x20u: /* Slave Address NACK */
1535 case 0x30u: /* Master transmit data NACK */
1536 u8Ctrl = I2C_CTL_STO_SI; /* Clear SI and send STOP */
1537 u8Err = 1u;
1538 break;
1539 case 0x28u:
1540 if(u8Addr)
1541 {
1542 I2C_SET_DATA(i2c, (uint8_t)(u16DataAddr & 0xFFu)); /* Write Lo byte address of register */
1543 u8Addr = 0u;
1544 }
1545 else
1546 {
1547 u8Ctrl = I2C_CTL_STA_SI; /* Clear SI and send repeat START */
1548 }
1549 break;
1550 case 0x10u:
1551 I2C_SET_DATA(i2c, (uint8_t)((u8SlaveAddr << 1u) | 0x01u)); /* Write SLA+R to Register I2CDAT */
1552 u8Ctrl = I2C_CTL_SI; /* Clear SI */
1553 break;
1554 case 0x40u: /* Slave Address ACK */
1555 u8Ctrl = I2C_CTL_SI; /* Clear SI */
1556 break;
1557 case 0x48u: /* Slave Address NACK */
1558 u8Ctrl = I2C_CTL_STO_SI; /* Clear SI and send STOP */
1559 u8Err = 1u;
1560 break;
1561 case 0x58u:
1562 rdata = (uint8_t) I2C_GET_DATA(i2c); /* Receive Data */
1563 u8Ctrl = I2C_CTL_STO_SI; /* Clear SI and send STOP */
1564 u8Xfering = 0u;
1565 break;
1566 case 0x38u: /* Arbitration Lost */
1567 default: /* Unknow status */
1568 I2C_SET_CONTROL_REG(i2c, I2C_CTL_STO_SI); /* Clear SI and send STOP */
1569 u8Ctrl = I2C_CTL_SI;
1570 u8Err = 1u;
1571 break;
1572 }
1573 I2C_SET_CONTROL_REG(i2c, u8Ctrl); /* Write controlbit to I2C_CTL register */
1574 }
1575 if(u8Err)
1576 {
1577 rdata = 0u; /* If occurs error, return 0 */
1578 }
1579 return rdata; /* Return read data */
1580 }
1581
1582 /**
1583 * @brief Specify two bytes register address and read multi bytes from Slave
1584 *
1585 * @param[in] i2c Point to I2C peripheral
1586 * @param[in] u8SlaveAddr Access Slave address(7-bit)
1587 * @param[in] u16DataAddr Specify a address (2 bytes) of data read from
1588 * @param[out] rdata[] A data array to store data from Slave
1589 * @param[in] u32rLen How many bytes need to read from Slave
1590 *
1591 * @return A length of how many bytes have been received
1592 *
1593 * @details The function is used for I2C Master specify two bytes address that multi data bytes read from Slave.
1594 *
1595 *
1596 */
I2C_ReadMultiBytesTwoRegs(I2C_T * i2c,uint8_t u8SlaveAddr,uint16_t u16DataAddr,uint8_t rdata[],uint32_t u32rLen)1597 uint32_t I2C_ReadMultiBytesTwoRegs(I2C_T *i2c, uint8_t u8SlaveAddr, uint16_t u16DataAddr, uint8_t rdata[], uint32_t u32rLen)
1598 {
1599 uint8_t u8Xfering = 1u, u8Err = 0u, u8Addr = 1u, u8Ctrl = 0u;
1600 uint32_t u32rxLen = 0u;
1601 uint32_t u32TimeOutCount;
1602
1603 g_I2C_i32ErrCode = 0;
1604
1605 I2C_START(i2c); /* Send START */
1606 while(u8Xfering && (u8Err == 0u))
1607 {
1608 u32TimeOutCount = SystemCoreClock;
1609 I2C_WAIT_READY(i2c)
1610 {
1611 u32TimeOutCount--;
1612 if(u32TimeOutCount == 0)
1613 {
1614 g_I2C_i32ErrCode = I2C_TIMEOUT_ERR;
1615 break;
1616 }
1617 }
1618
1619 switch(I2C_GET_STATUS(i2c))
1620 {
1621 case 0x08u:
1622 I2C_SET_DATA(i2c, (uint8_t)(u8SlaveAddr << 1u | 0x00u)); /* Write SLA+W to Register I2CDAT */
1623 u8Ctrl = I2C_CTL_SI; /* Clear SI */
1624 break;
1625 case 0x18u: /* Slave Address ACK */
1626 I2C_SET_DATA(i2c, (uint8_t)((u16DataAddr & 0xFF00u) >> 8u)); /* Write Hi byte address of register */
1627 break;
1628 case 0x20u: /* Slave Address NACK */
1629 case 0x30u: /* Master transmit data NACK */
1630 u8Ctrl = I2C_CTL_STO_SI; /* Clear SI and send STOP */
1631 u8Err = 1u;
1632 break;
1633 case 0x28u:
1634 if(u8Addr)
1635 {
1636 I2C_SET_DATA(i2c, (uint8_t)(u16DataAddr & 0xFFu)); /* Write Lo byte address of register */
1637 u8Addr = 0u;
1638 }
1639 else
1640 {
1641 u8Ctrl = I2C_CTL_STA_SI; /* Clear SI and send repeat START */
1642 }
1643 break;
1644 case 0x10u:
1645 I2C_SET_DATA(i2c, (uint8_t)((u8SlaveAddr << 1u) | 0x01u)); /* Write SLA+R to Register I2CDAT */
1646 u8Ctrl = I2C_CTL_SI; /* Clear SI */
1647 break;
1648 case 0x40u: /* Slave Address ACK */
1649 u8Ctrl = I2C_CTL_SI_AA; /* Clear SI and set ACK */
1650 break;
1651 case 0x48u: /* Slave Address NACK */
1652 u8Ctrl = I2C_CTL_STO_SI; /* Clear SI and send STOP */
1653 u8Err = 1u;
1654 break;
1655 case 0x50u:
1656 rdata[u32rxLen++] = (uint8_t) I2C_GET_DATA(i2c); /* Receive Data */
1657 if(u32rxLen < (u32rLen - 1u))
1658 {
1659 u8Ctrl = I2C_CTL_SI_AA; /* Clear SI and set ACK */
1660 }
1661 else
1662 {
1663 u8Ctrl = I2C_CTL_SI; /* Clear SI */
1664 }
1665 break;
1666 case 0x58u:
1667 rdata[u32rxLen++] = (uint8_t) I2C_GET_DATA(i2c); /* Receive Data */
1668 u8Ctrl = I2C_CTL_STO_SI; /* Clear SI and send STOP */
1669 u8Xfering = 0u;
1670 break;
1671 case 0x38u: /* Arbitration Lost */
1672 default: /* Unknow status */
1673 I2C_SET_CONTROL_REG(i2c, I2C_CTL_STO_SI); /* Clear SI and send STOP */
1674 u8Ctrl = I2C_CTL_SI;
1675 u8Err = 1u;
1676 break;
1677 }
1678 I2C_SET_CONTROL_REG(i2c, u8Ctrl); /* Write controlbit to I2C_CTL register */
1679 }
1680 return u32rxLen; /* Return bytes length that have been received */
1681 }
1682
1683
1684 /*@}*/ /* end of group I2C_EXPORTED_FUNCTIONS */
1685
1686 /*@}*/ /* end of group I2C_Driver */
1687
1688 /*@}*/ /* end of group Standard_Driver */
1689
1690 /*** (C) COPYRIGHT 2023 Nuvoton Technology Corp. ***/
1691