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