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