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