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