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