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