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