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