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