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