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