1 /**************************************************************************//**
2 * @file lpi2c.c
3 * @version V3.00
4 * @brief M2L31 series LPI2C driver source file
5 *
6 * SPDX-License-Identifier: Apache-2.0
7 * @copyright (C) 2023 Nuvoton Technology Corp. All rights reserved.
8 *****************************************************************************/
9 #include "NuMicro.h"
10
11 /** @addtogroup Standard_Driver Standard Driver
12 @{
13 */
14
15 /** @addtogroup LPI2C_Driver LPI2C Driver
16 @{
17 */
18
19 int32_t g_LPI2C_i32ErrCode = 0; /*!< LPI2C global error code */
20
21 /** @addtogroup LPI2C_EXPORTED_FUNCTIONS LPI2C Exported Functions
22 @{
23 */
24
25 /**
26 * @brief Enable specify LPI2C Controller and set Clock Divider
27 *
28 * @param[in] lpi2c Specify LPI2C port
29 * @param[in] u32BusClock The target LPI2C bus clock in Hz
30 *
31 * @return Actual LPI2C bus clock frequency
32 *
33 * @details The function enable the specify LPI2C Controller and set proper Clock Divider
34 * in LPI2C CLOCK DIVIDED REGISTER (LPI2CLK) according to the target LPI2C Bus clock.
35 * LPI2C Bus clock = PCLK / (4*(divider+1).
36 *
37 */
LPI2C_Open(LPI2C_T * lpi2c,uint32_t u32BusClock)38 uint32_t LPI2C_Open(LPI2C_T *lpi2c, uint32_t u32BusClock)
39 {
40 uint32_t u32Div;
41 uint32_t u32Pclk;
42
43 u32Pclk = CLK_GetPCLK2Freq();
44
45 u32Div = (uint32_t)(((u32Pclk * 10U) / (u32BusClock * 4U) + 5U) / 10U - 1U); /* Compute proper divider for LPI2C clock */
46 lpi2c->CLKDIV = u32Div;
47
48 /* Enable LPI2C */
49 lpi2c->CTL0 |= LPI2C_CTL0_LPI2CEN_Msk;
50
51 return (u32Pclk / ((u32Div + 1U) << 2U));
52 }
53
54 /**
55 * @brief Disable specify LPI2C Controller
56 *
57 * @param[in] lpi2c Specify LPI2C port
58 *
59 * @return None
60 *
61 * @details Reset LPI2C Controller and disable specify LPI2C port.
62 *
63 */
64
LPI2C_Close(LPI2C_T * lpi2c)65 void LPI2C_Close(LPI2C_T *lpi2c)
66 {
67 /* Reset LPI2C Controller */
68 LPSCC->IPRST0 |= LPSCC_IPRST0_LPI2C0RST_Msk;
69 LPSCC->IPRST0 &= ~LPSCC_IPRST0_LPI2C0RST_Msk;
70
71 /* Disable LPI2C */
72 lpi2c->CTL0 &= ~LPI2C_CTL0_LPI2CEN_Msk;
73 }
74
75 /**
76 * @brief Clear Time-out Counter flag
77 *
78 * @param[in] lpi2c Specify LPI2C port
79 *
80 * @return None
81 *
82 * @details When Time-out flag will be set, use this function to clear LPI2C Bus Time-out counter flag .
83 *
84 */
LPI2C_ClearTimeoutFlag(LPI2C_T * lpi2c)85 void LPI2C_ClearTimeoutFlag(LPI2C_T *lpi2c)
86 {
87 lpi2c->TOCTL |= LPI2C_TOCTL_TOIF_Msk;
88 }
89
90 /**
91 * @brief Set Control bit of LPI2C Controller
92 *
93 * @param[in] lpi2c Specify LPI2C port
94 * @param[in] u8Start Set LPI2C START condition
95 * @param[in] u8Stop Set LPI2C STOP condition
96 * @param[in] u8Si Clear SI flag
97 * @param[in] u8Ack Set LPI2C ACK bit
98 *
99 * @return None
100 *
101 * @details The function set LPI2C Control bit of LPI2C Bus protocol.
102 *
103 */
LPI2C_Trigger(LPI2C_T * lpi2c,uint8_t u8Start,uint8_t u8Stop,uint8_t u8Si,uint8_t u8Ack)104 void LPI2C_Trigger(LPI2C_T *lpi2c, uint8_t u8Start, uint8_t u8Stop, uint8_t u8Si, uint8_t u8Ack)
105 {
106 uint32_t u32Reg = 0U;
107
108 if(u8Start)
109 {
110 u32Reg |= LPI2C_CTL_STA;
111 }
112
113 if(u8Stop)
114 {
115 u32Reg |= LPI2C_CTL_STO;
116 }
117
118 if(u8Si)
119 {
120 u32Reg |= LPI2C_CTL_SI;
121 }
122
123 if(u8Ack)
124 {
125 u32Reg |= LPI2C_CTL_AA;
126 }
127
128 lpi2c->CTL0 = (lpi2c->CTL0 & ~0x3CU) | u32Reg;
129 }
130
131 /**
132 * @brief Disable Interrupt of LPI2C Controller
133 *
134 * @param[in] lpi2c Specify LPI2C port
135 *
136 * @return None
137 *
138 * @details The function is used for disable LPI2C interrupt
139 *
140 */
LPI2C_DisableInt(LPI2C_T * lpi2c)141 void LPI2C_DisableInt(LPI2C_T *lpi2c)
142 {
143 lpi2c->CTL0 &= ~LPI2C_CTL0_INTEN_Msk;
144 }
145
146 /**
147 * @brief Enable Interrupt of LPI2C Controller
148 *
149 * @param[in] lpi2c Specify LPI2C port
150 *
151 * @return None
152 *
153 * @details The function is used for enable LPI2C interrupt
154 *
155 */
LPI2C_EnableInt(LPI2C_T * lpi2c)156 void LPI2C_EnableInt(LPI2C_T *lpi2c)
157 {
158 lpi2c->CTL0 |= LPI2C_CTL0_INTEN_Msk;
159 }
160
161 /**
162 * @brief Get LPI2C Bus Clock
163 *
164 * @param[in] lpi2c Specify LPI2C port
165 *
166 * @return The actual LPI2C Bus clock in Hz
167 *
168 * @details To get the actual LPI2C Bus Clock frequency.
169 */
LPI2C_GetBusClockFreq(LPI2C_T * lpi2c)170 uint32_t LPI2C_GetBusClockFreq(LPI2C_T *lpi2c)
171 {
172 uint32_t u32Divider = lpi2c->CLKDIV;
173 uint32_t u32Pclk;
174
175 u32Pclk = CLK_GetPCLK2Freq();
176
177 return (u32Pclk / ((u32Divider + 1U) << 2U));
178 }
179
180 /**
181 * @brief Set LPI2C Bus Clock
182 *
183 * @param[in] lpi2c Specify LPI2C port
184 * @param[in] u32BusClock The target LPI2C Bus Clock in Hz
185 *
186 * @return The actual LPI2C Bus Clock in Hz
187 *
188 * @details To set the actual LPI2C Bus Clock frequency.
189 */
LPI2C_SetBusClockFreq(LPI2C_T * lpi2c,uint32_t u32BusClock)190 uint32_t LPI2C_SetBusClockFreq(LPI2C_T *lpi2c, uint32_t u32BusClock)
191 {
192 uint32_t u32Div;
193 uint32_t u32Pclk;
194
195 u32Pclk = CLK_GetPCLK2Freq();
196
197 u32Div = (uint32_t)(((u32Pclk * 10U) / (u32BusClock * 4U) + 5U) / 10U - 1U); /* Compute proper divider for LPI2C clock */
198 lpi2c->CLKDIV = u32Div;
199
200 return (u32Pclk / ((u32Div + 1U) << 2U));
201 }
202
203 /**
204 * @brief Get Interrupt Flag
205 *
206 * @param[in] lpi2c Specify LPI2C port
207 *
208 * @return LPI2C interrupt flag status
209 *
210 * @details To get LPI2C Bus interrupt flag.
211 */
LPI2C_GetIntFlag(LPI2C_T * lpi2c)212 uint32_t LPI2C_GetIntFlag(LPI2C_T *lpi2c)
213 {
214 uint32_t u32Value;
215
216 if((lpi2c->CTL0 & LPI2C_CTL0_SI_Msk) == LPI2C_CTL0_SI_Msk)
217 {
218 u32Value = 1U;
219 }
220 else
221 {
222 u32Value = 0U;
223 }
224
225 return u32Value;
226 }
227
228 /**
229 * @brief Get LPI2C Bus Status Code
230 *
231 * @param[in] lpi2c Specify LPI2C port
232 *
233 * @return LPI2C Status Code
234 *
235 * @details To get LPI2C Bus Status Code.
236 */
LPI2C_GetStatus(LPI2C_T * lpi2c)237 uint32_t LPI2C_GetStatus(LPI2C_T *lpi2c)
238 {
239 return (lpi2c->STATUS0);
240 }
241
242 /**
243 * @brief Read a Byte from LPI2C Bus
244 *
245 * @param[in] lpi2c Specify LPI2C port
246 *
247 * @return LPI2C Data
248 *
249 * @details To read a bytes data from specify LPI2C port.
250 */
LPI2C_GetData(LPI2C_T * lpi2c)251 uint8_t LPI2C_GetData(LPI2C_T *lpi2c)
252 {
253 return (uint8_t)(lpi2c->DAT);
254 }
255
256 /**
257 * @brief Send a byte to LPI2C Bus
258 *
259 * @param[in] lpi2c Specify LPI2C port
260 * @param[in] u8Data The data to send to LPI2C bus
261 *
262 * @return None
263 *
264 * @details This function is used to write a byte to specified LPI2C port
265 */
LPI2C_SetData(LPI2C_T * lpi2c,uint8_t u8Data)266 void LPI2C_SetData(LPI2C_T *lpi2c, uint8_t u8Data)
267 {
268 lpi2c->DAT = u8Data;
269 }
270
271 /**
272 * @brief Set 7-bit Slave Address and GC Mode
273 *
274 * @param[in] lpi2c Specify LPI2C port
275 * @param[in] u8SlaveNo Set the number of LPI2C address register (0~3)
276 * @param[in] u8SlaveAddr 7-bit slave address
277 * @param[in] u8GCMode Enable/Disable GC mode (LPI2C_GCMODE_ENABLE / LPI2C_GCMODE_DISABLE)
278 *
279 * @return None
280 *
281 * @details This function is used to set 7-bit slave addresses in LPI2C SLAVE ADDRESS REGISTER (LPI2CADDR0~3)
282 * and enable GC Mode.
283 *
284 */
LPI2C_SetSlaveAddr(LPI2C_T * lpi2c,uint8_t u8SlaveNo,uint8_t u8SlaveAddr,uint8_t u8GCMode)285 void LPI2C_SetSlaveAddr(LPI2C_T *lpi2c, uint8_t u8SlaveNo, uint8_t u8SlaveAddr, uint8_t u8GCMode)
286 {
287 switch(u8SlaveNo)
288 {
289 case 1:
290 lpi2c->ADDR1 = ((uint32_t)u8SlaveAddr << 1U) | u8GCMode;
291 break;
292 case 2:
293 lpi2c->ADDR2 = ((uint32_t)u8SlaveAddr << 1U) | u8GCMode;
294 break;
295 case 3:
296 lpi2c->ADDR3 = ((uint32_t)u8SlaveAddr << 1U) | u8GCMode;
297 break;
298 case 0:
299 default:
300 lpi2c->ADDR0 = ((uint32_t)u8SlaveAddr << 1U) | u8GCMode;
301 break;
302 }
303 }
304
305 /**
306 * @brief Configure the mask bits of 7-bit Slave Address
307 *
308 * @param[in] lpi2c Specify LPI2C port
309 * @param[in] u8SlaveNo Set the number of LPI2C address mask register (0~3)
310 * @param[in] u8SlaveAddrMask A byte for slave address mask
311 *
312 * @return None
313 *
314 * @details This function is used to set 7-bit slave addresses.
315 *
316 */
LPI2C_SetSlaveAddrMask(LPI2C_T * lpi2c,uint8_t u8SlaveNo,uint8_t u8SlaveAddrMask)317 void LPI2C_SetSlaveAddrMask(LPI2C_T *lpi2c, uint8_t u8SlaveNo, uint8_t u8SlaveAddrMask)
318 {
319 switch(u8SlaveNo)
320 {
321 case 1:
322 lpi2c->ADDRMSK1 = (uint32_t)u8SlaveAddrMask << 1U;
323 break;
324 case 2:
325 lpi2c->ADDRMSK2 = (uint32_t)u8SlaveAddrMask << 1U;
326 break;
327 case 3:
328 lpi2c->ADDRMSK3 = (uint32_t)u8SlaveAddrMask << 1U;
329 break;
330 case 0:
331 default:
332 lpi2c->ADDRMSK0 = (uint32_t)u8SlaveAddrMask << 1U;
333 break;
334 }
335 }
336
337 /**
338 * @brief Enable Time-out Counter Function and support Long Time-out
339 *
340 * @param[in] lpi2c Specify LPI2C port
341 * @param[in] u8LongTimeout Configure DIV4 to enable Long Time-out (0/1)
342 *
343 * @return None
344 *
345 * @details This function enable Time-out Counter function and configure DIV4 to support Long
346 * Time-out.
347 *
348 */
LPI2C_EnableTimeout(LPI2C_T * lpi2c,uint8_t u8LongTimeout)349 void LPI2C_EnableTimeout(LPI2C_T *lpi2c, uint8_t u8LongTimeout)
350 {
351 if(u8LongTimeout)
352 {
353 lpi2c->TOCTL |= LPI2C_TOCTL_TOCDIV4_Msk;
354 }
355 else
356 {
357 lpi2c->TOCTL &= ~LPI2C_TOCTL_TOCDIV4_Msk;
358 }
359
360 lpi2c->TOCTL |= LPI2C_TOCTL_TOCEN_Msk;
361 }
362
363 /**
364 * @brief Disable Time-out Counter Function
365 *
366 * @param[in] lpi2c Specify LPI2C port
367 *
368 * @return None
369 *
370 * @details To disable Time-out Counter function in LPI2C_TOCTL register.
371 *
372 */
LPI2C_DisableTimeout(LPI2C_T * lpi2c)373 void LPI2C_DisableTimeout(LPI2C_T *lpi2c)
374 {
375 lpi2c->TOCTL &= ~LPI2C_TOCTL_TOCEN_Msk;
376 }
377
378 /**
379 * @brief Enable LPI2C Wake-up Function
380 *
381 * @param[in] lpi2c Specify LPI2C port
382 *
383 * @return None
384 *
385 * @details To enable Wake-up function of LPI2C Wake-up control register.
386 *
387 */
LPI2C_EnableWakeup(LPI2C_T * lpi2c)388 void LPI2C_EnableWakeup(LPI2C_T *lpi2c)
389 {
390 lpi2c->WKCTL |= LPI2C_WKCTL_WKEN_Msk;
391 }
392
393 /**
394 * @brief Disable LPI2C Wake-up Function
395 *
396 * @param[in] lpi2c Specify LPI2C port
397 *
398 * @return None
399 *
400 * @details To disable Wake-up function of LPI2C Wake-up control register.
401 *
402 */
LPI2C_DisableWakeup(LPI2C_T * lpi2c)403 void LPI2C_DisableWakeup(LPI2C_T *lpi2c)
404 {
405 lpi2c->WKCTL &= ~LPI2C_WKCTL_WKEN_Msk;
406 }
407
408 /**
409 * @brief Enable specified auto-operation mode and set trigger source
410 *
411 * @param[in] lpi2c Specify LPI2C port
412 * @param[in] u8Mode The specified auto-operation mode of LPI2C module:
413 * - \ref LPI2C_AUTO_TXPDMA : Auto TXPDMA transfer mode
414 * - \ref LPI2C_AUTO_RXPDMA : Auto RXPDMA transfer mode
415 * - \ref LPI2C_RANDOM_REPEAT_STA : Random Read mode, repeat start between TX/RX
416 * - \ref LPI2C_RANDOM_STO_STA : Random Read mode, stop and start between TX/RX
417 * @param[in] u8Src Set auto-operation mode trigger source
418 * - \ref LPI2C_TRGSRC_LPTMR0 : Auto-operation trigger source from LPTMR0
419 * - \ref LPI2C_TRGSRC_LPTMR1 : Auto-operation trigger source from LPTMR1
420 * - \ref LPI2C_TRGSRC_TTMR0 : Auto-operation trigger source from TTMR0
421 * - \ref LPI2C_TRGSRC_TTMR1 : Auto-operation trigger source from TTMR1
422 * - \ref LPI2C_TRGSRC_WKIOA0 : Auto-operation trigger source from WKIOA0
423 * - \ref LPI2C_TRGSRC_WKIOB0 : Auto-operation trigger source from WKIOB0
424 * - \ref LPI2C_TRGSRC_WKIOC0 : Auto-operation trigger source from WKIOC0
425 * - \ref LPI2C_TRGSRC_WKIOD0 : Auto-operation trigger source from WKIOD0
426 * - \ref LPI2C_TRGSRC_SWTRG : Auto-operation trigger source from Software setting
427 *
428 * @return None
429 *
430 * @details This function enable specified auto-operation mode and set trigger source
431 *
432 */
LPI2C_EnableAutoMode(LPI2C_T * lpi2c,uint8_t u8Mode,uint8_t u8Src)433 void LPI2C_EnableAutoMode(LPI2C_T *lpi2c, uint8_t u8Mode, uint8_t u8Src)
434 {
435 /* Auto-operation mode select*/
436 lpi2c->AUTOCTL = (lpi2c->AUTOCTL & ~LPI2C_AUTOCTL_AUTOMODE_Msk) | (u8Mode);
437
438 /* Trigger source select*/
439 lpi2c->AUTOCTL = (lpi2c->AUTOCTL & ~LPI2C_AUTOCTL_TGSRCSEL_Msk) | (u8Src);
440
441 lpi2c->AUTOCTL |= LPI2C_AUTOCTL_TRGEN_Msk;
442 }
443
444 /**
445 * @brief Disable auto-operation mode
446 *
447 * @param[in] lpi2c Specify LPI2C port
448 *
449 * @return None
450 *
451 * @details This function disable auto-operation mode
452 *
453 */
LPI2C_DisableAutoMode(LPI2C_T * lpi2c)454 void LPI2C_DisableAutoMode(LPI2C_T *lpi2c)
455 {
456 lpi2c->AUTOCTL &= ~(LPI2C_AUTOCTL_AUTOMODE_Msk | LPI2C_AUTOCTL_TRGEN_Msk);
457 }
458
459 /**
460 * @brief Set auto-operation mode transfer count
461 *
462 * @param[in] lpi2c Specify LPI2C port
463 * @param[in] u32RxCount Rx transfer count. Valid values are between 0~255.
464 * @param[in] u32TxCount Tx transfer count. Valid values are between 0~255.
465 *
466 * @return None
467 *
468 * @details This function is used to set auto-operation mode transfer count
469 *
470 */
LPI2C_SetAutoModeTransferCnt(LPI2C_T * lpi2c,uint32_t u32RxCount,uint32_t u32TxCount)471 void LPI2C_SetAutoModeTransferCnt(LPI2C_T *lpi2c, uint32_t u32RxCount, uint32_t u32TxCount)
472 {
473 if(u32RxCount != 0)
474 lpi2c->AUTOCNT = (lpi2c->AUTOCNT & ~LPI2C_AUTOCNT_RXCNT_Msk) | ((u32RxCount -1) << LPI2C_AUTOCNT_RXCNT_Pos);
475
476 if(u32TxCount != 0)
477 lpi2c->AUTOCNT = (lpi2c->AUTOCNT & ~LPI2C_AUTOCNT_TXCNT_Msk) | (u32TxCount -1);
478 }
479
480 /**
481 * @brief Write a byte to Slave
482 *
483 * @param[in] lpi2c Point to LPI2C peripheral
484 * @param[in] u8SlaveAddr Access Slave address(7-bit)
485 * @param[in] data Write a byte data to Slave
486 *
487 * @retval 0 Write data success
488 * @retval 1 Write data fail, or bus occurs error events
489 *
490 * @details The function is used for LPI2C Master write a byte data to Slave.
491 *
492 */
493
LPI2C_WriteByte(LPI2C_T * lpi2c,uint8_t u8SlaveAddr,uint8_t data)494 uint8_t LPI2C_WriteByte(LPI2C_T *lpi2c, uint8_t u8SlaveAddr, uint8_t data)
495 {
496 uint8_t u8Xfering = 1u, u8Err = 0u, u8Ctrl = 0u;
497 uint32_t u32TimeOutCount;
498
499 g_LPI2C_i32ErrCode = 0;
500
501 LPI2C_START(lpi2c);
502 while(u8Xfering && (u8Err == 0u))
503 {
504 u32TimeOutCount = SystemCoreClock;
505 LPI2C_WAIT_READY(lpi2c)
506 {
507 u32TimeOutCount--;
508 if(u32TimeOutCount == 0)
509 {
510 g_LPI2C_i32ErrCode = LPI2C_TIMEOUT_ERR;
511 break;
512 }
513 }
514
515 switch(LPI2C_GET_STATUS(lpi2c))
516 {
517 case 0x08u:
518 LPI2C_SET_DATA(lpi2c, (uint8_t)(u8SlaveAddr << 1u | 0x00u)); /* Write SLA+W to Register LPI2CDAT */
519 u8Ctrl = LPI2C_CTL_SI; /* Clear SI */
520 break;
521 case 0x18u: /* Slave Address ACK */
522 LPI2C_SET_DATA(lpi2c, data); /* Write data to LPI2CDAT */
523 break;
524 case 0x20u: /* Slave Address NACK */
525 case 0x30u: /* Master transmit data NACK */
526 u8Ctrl = LPI2C_CTL_STO_SI; /* Clear SI and send STOP */
527 u8Err = 1u;
528 break;
529 case 0x28u:
530 u8Ctrl = LPI2C_CTL_STO_SI; /* Clear SI and send STOP */
531 u8Xfering = 0u;
532 break;
533 case 0x38u: /* Arbitration Lost */
534 default: /* Unknow status */
535 LPI2C_SET_CONTROL_REG(lpi2c, LPI2C_CTL_STO_SI); /* Clear SI and send STOP */
536 u8Ctrl = LPI2C_CTL_SI;
537 u8Err = 1u;
538 break;
539 }
540 LPI2C_SET_CONTROL_REG(lpi2c, u8Ctrl); /* Write controlbit to LPI2C_CTL register */
541 }
542 return (u8Err | u8Xfering); /* return (Success)/(Fail) status */
543 }
544
545 /**
546 * @brief Write multi bytes to Slave
547 *
548 * @param[in] lpi2c Point to LPI2C peripheral
549 * @param[in] u8SlaveAddr Access Slave address(7-bit)
550 * @param[in] data[] Pointer to array to write data to Slave
551 * @param[in] u32wLen How many bytes need to write to Slave
552 *
553 * @return A length of how many bytes have been transmitted.
554 *
555 * @details The function is used for LPI2C Master write multi bytes data to Slave.
556 *
557 */
558
LPI2C_WriteMultiBytes(LPI2C_T * lpi2c,uint8_t u8SlaveAddr,uint8_t data[],uint32_t u32wLen)559 uint32_t LPI2C_WriteMultiBytes(LPI2C_T *lpi2c, uint8_t u8SlaveAddr, uint8_t data[], uint32_t u32wLen)
560 {
561 uint8_t u8Xfering = 1u, u8Err = 0u, u8Ctrl = 0u;
562 uint32_t u32txLen = 0u;
563 uint32_t u32TimeOutCount;
564
565 g_LPI2C_i32ErrCode = 0;
566
567 LPI2C_START(lpi2c); /* Send START */
568 while(u8Xfering && (u8Err == 0u))
569 {
570 u32TimeOutCount = SystemCoreClock;
571 LPI2C_WAIT_READY(lpi2c)
572 {
573 u32TimeOutCount--;
574 if(u32TimeOutCount == 0)
575 {
576 g_LPI2C_i32ErrCode = LPI2C_TIMEOUT_ERR;
577 break;
578 }
579 }
580
581 switch(LPI2C_GET_STATUS(lpi2c))
582 {
583 case 0x08u:
584 LPI2C_SET_DATA(lpi2c, (uint8_t)(u8SlaveAddr << 1u | 0x00u)); /* Write SLA+W to Register LPI2CDAT */
585 u8Ctrl = LPI2C_CTL_SI; /* Clear SI */
586 break;
587 case 0x18u: /* Slave Address ACK */
588 case 0x28u:
589 if(u32txLen < u32wLen)
590 {
591 LPI2C_SET_DATA(lpi2c, data[u32txLen++]); /* Write Data to LPI2CDAT */
592 }
593 else
594 {
595 u8Ctrl = LPI2C_CTL_STO_SI; /* Clear SI and send STOP */
596 u8Xfering = 0u;
597 }
598 break;
599 case 0x20u: /* Slave Address NACK */
600 case 0x30u: /* Master transmit data NACK */
601 u8Ctrl = LPI2C_CTL_STO_SI; /* Clear SI and send STOP */
602 u8Err = 1u;
603 break;
604 case 0x38u: /* Arbitration Lost */
605 default: /* Unknow status */
606 LPI2C_SET_CONTROL_REG(lpi2c, LPI2C_CTL_STO_SI); /* Clear SI and send STOP */
607 u8Ctrl = LPI2C_CTL_SI;
608 u8Err = 1u;
609 break;
610 }
611 LPI2C_SET_CONTROL_REG(lpi2c, u8Ctrl); /* Write controlbit to LPI2C_CTL register */
612 }
613 return u32txLen; /* Return bytes length that have been transmitted */
614 }
615
616 /**
617 * @brief Specify a byte register address and write a byte to Slave
618 *
619 * @param[in] lpi2c Point to LPI2C peripheral
620 * @param[in] u8SlaveAddr Access Slave address(7-bit)
621 * @param[in] u8DataAddr Specify a address (1 byte) of data write to
622 * @param[in] data A byte data to write it to Slave
623 *
624 * @retval 0 Write data success
625 * @retval 1 Write data fail, or bus occurs error events
626 *
627 * @details The function is used for LPI2C Master specify a address that data write to in Slave.
628 *
629 */
630
LPI2C_WriteByteOneReg(LPI2C_T * lpi2c,uint8_t u8SlaveAddr,uint8_t u8DataAddr,uint8_t data)631 uint8_t LPI2C_WriteByteOneReg(LPI2C_T *lpi2c, uint8_t u8SlaveAddr, uint8_t u8DataAddr, uint8_t data)
632 {
633 uint8_t u8Xfering = 1u, u8Err = 0u, u8Ctrl = 0u;
634 uint32_t u32txLen = 0u;
635 uint32_t u32TimeOutCount;
636
637 g_LPI2C_i32ErrCode = 0;
638
639 LPI2C_START(lpi2c); /* Send START */
640 while(u8Xfering && (u8Err == 0u))
641 {
642 u32TimeOutCount = SystemCoreClock;
643 LPI2C_WAIT_READY(lpi2c)
644 {
645 u32TimeOutCount--;
646 if(u32TimeOutCount == 0)
647 {
648 g_LPI2C_i32ErrCode = LPI2C_TIMEOUT_ERR;
649 break;
650 }
651 }
652
653 switch(LPI2C_GET_STATUS(lpi2c))
654 {
655 case 0x08u:
656 LPI2C_SET_DATA(lpi2c, (uint8_t)(u8SlaveAddr << 1u | 0x00u)); /* Send Slave address with write bit */
657 u8Ctrl = LPI2C_CTL_SI; /* Clear SI */
658 break;
659 case 0x18u: /* Slave Address ACK */
660 LPI2C_SET_DATA(lpi2c, u8DataAddr); /* Write Lo byte address of register */
661 break;
662 case 0x20u: /* Slave Address NACK */
663 case 0x30u: /* Master transmit data NACK */
664 u8Ctrl = LPI2C_CTL_STO_SI; /* Clear SI and send STOP */
665 u8Err = 1u;
666 break;
667 case 0x28u:
668 if(u32txLen < 1u)
669 {
670 LPI2C_SET_DATA(lpi2c, data);
671 u32txLen++;
672 }
673 else
674 {
675 u8Ctrl = LPI2C_CTL_STO_SI; /* Clear SI and send STOP */
676 u8Xfering = 0u;
677 }
678 break;
679 case 0x38u: /* Arbitration Lost */
680 default: /* Unknow status */
681 LPI2C_SET_CONTROL_REG(lpi2c, LPI2C_CTL_STO_SI); /* Clear SI and send STOP */
682 u8Ctrl = LPI2C_CTL_SI;
683 u8Err = 1u;
684 break;
685 }
686 LPI2C_SET_CONTROL_REG(lpi2c, u8Ctrl); /* Write controlbit to LPI2C_CTL register */
687 }
688 return (u8Err | u8Xfering); /* return (Success)/(Fail) status */
689 }
690
691
692 /**
693 * @brief Specify a byte register address and write multi bytes to Slave
694 *
695 * @param[in] lpi2c Point to LPI2C peripheral
696 * @param[in] u8SlaveAddr Access Slave address(7-bit)
697 * @param[in] u8DataAddr Specify a address (1 byte) of data write to
698 * @param[in] data[] Pointer to array to write data to Slave
699 * @param[in] u32wLen How many bytes need to write to Slave
700 *
701 * @return A length of how many bytes have been transmitted.
702 *
703 * @details The function is used for LPI2C Master specify a byte address that multi data bytes write to in Slave.
704 *
705 */
706
LPI2C_WriteMultiBytesOneReg(LPI2C_T * lpi2c,uint8_t u8SlaveAddr,uint8_t u8DataAddr,uint8_t data[],uint32_t u32wLen)707 uint32_t LPI2C_WriteMultiBytesOneReg(LPI2C_T *lpi2c, uint8_t u8SlaveAddr, uint8_t u8DataAddr, uint8_t data[], uint32_t u32wLen)
708 {
709 uint8_t u8Xfering = 1u, u8Err = 0u, u8Ctrl = 0u;
710 uint32_t u32txLen = 0u;
711 uint32_t u32TimeOutCount;
712
713 g_LPI2C_i32ErrCode = 0;
714
715 LPI2C_START(lpi2c); /* Send START */
716 while(u8Xfering && (u8Err == 0u))
717 {
718 u32TimeOutCount = SystemCoreClock;
719 LPI2C_WAIT_READY(lpi2c)
720 {
721 u32TimeOutCount--;
722 if(u32TimeOutCount == 0)
723 {
724 g_LPI2C_i32ErrCode = LPI2C_TIMEOUT_ERR;
725 break;
726 }
727 }
728
729 switch(LPI2C_GET_STATUS(lpi2c))
730 {
731 case 0x08u:
732 LPI2C_SET_DATA(lpi2c, (uint8_t)(u8SlaveAddr << 1u | 0x00u)); /* Write SLA+W to Register LPI2CDAT */
733 u8Ctrl = LPI2C_CTL_SI;
734 break;
735 case 0x18u: /* Slave Address ACK */
736 LPI2C_SET_DATA(lpi2c, u8DataAddr); /* Write Lo byte address of register */
737 break;
738 case 0x20u: /* Slave Address NACK */
739 case 0x30u: /* Master transmit data NACK */
740 u8Ctrl = LPI2C_CTL_STO_SI; /* Clear SI and send STOP */
741 u8Err = 1u;
742 break;
743 case 0x28u:
744 if(u32txLen < u32wLen)
745 {
746 LPI2C_SET_DATA(lpi2c, data[u32txLen++]);
747 }
748 else
749 {
750 u8Ctrl = LPI2C_CTL_STO_SI; /* Clear SI and send STOP */
751 u8Xfering = 0u;
752 }
753 break;
754 case 0x38u: /* Arbitration Lost */
755 default: /* Unknow status */
756 LPI2C_SET_CONTROL_REG(lpi2c, LPI2C_CTL_STO_SI); /* Clear SI and send STOP */
757 u8Ctrl = LPI2C_CTL_SI;
758 u8Err = 1u;
759 break;
760 }
761 LPI2C_SET_CONTROL_REG(lpi2c, u8Ctrl); /* Write controlbit to LPI2C_CTL register */
762 }
763
764 return u32txLen; /* Return bytes length that have been transmitted */
765 }
766
767 /**
768 * @brief Specify two bytes register address and Write a byte to Slave
769 *
770 * @param[in] lpi2c Point to LPI2C peripheral
771 * @param[in] u8SlaveAddr Access Slave address(7-bit)
772 * @param[in] u16DataAddr Specify a address (2 byte) of data write to
773 * @param[in] data Write a byte data to Slave
774 *
775 * @retval 0 Write data success
776 * @retval 1 Write data fail, or bus occurs error events
777 *
778 * @details The function is used for LPI2C Master specify two bytes address that data write to in Slave.
779 *
780 */
781
LPI2C_WriteByteTwoRegs(LPI2C_T * lpi2c,uint8_t u8SlaveAddr,uint16_t u16DataAddr,uint8_t data)782 uint8_t LPI2C_WriteByteTwoRegs(LPI2C_T *lpi2c, uint8_t u8SlaveAddr, uint16_t u16DataAddr, uint8_t data)
783 {
784 uint8_t u8Xfering = 1u, u8Err = 0u, u8Addr = 1u, u8Ctrl = 0u;
785 uint32_t u32txLen = 0u;
786 uint32_t u32TimeOutCount;
787
788 g_LPI2C_i32ErrCode = 0;
789
790 LPI2C_START(lpi2c); /* Send START */
791 while(u8Xfering && (u8Err == 0u))
792 {
793 u32TimeOutCount = SystemCoreClock;
794 LPI2C_WAIT_READY(lpi2c)
795 {
796 u32TimeOutCount--;
797 if(u32TimeOutCount == 0)
798 {
799 g_LPI2C_i32ErrCode = LPI2C_TIMEOUT_ERR;
800 break;
801 }
802 }
803
804 switch(LPI2C_GET_STATUS(lpi2c))
805 {
806 case 0x08u:
807 LPI2C_SET_DATA(lpi2c, (uint8_t)(u8SlaveAddr << 1u | 0x00u)); /* Write SLA+W to Register LPI2CDAT */
808 u8Ctrl = LPI2C_CTL_SI; /* Clear SI */
809 break;
810 case 0x18u: /* Slave Address ACK */
811 LPI2C_SET_DATA(lpi2c, (uint8_t)((u16DataAddr & 0xFF00u) >> 8u)); /* Write Hi byte address of register */
812 break;
813 case 0x20u: /* Slave Address NACK */
814 case 0x30u: /* Master transmit data NACK */
815 u8Ctrl = LPI2C_CTL_STO_SI; /* Clear SI and send STOP */
816 u8Err = 1u;
817 break;
818 case 0x28u:
819 if(u8Addr)
820 {
821 LPI2C_SET_DATA(lpi2c, (uint8_t)(u16DataAddr & 0xFFu)); /* Write Lo byte address of register */
822 u8Addr = 0u;
823 }
824 else if((u32txLen < 1u) && (u8Addr == 0u))
825 {
826 LPI2C_SET_DATA(lpi2c, data);
827 u32txLen++;
828 }
829 else
830 {
831 u8Ctrl = LPI2C_CTL_STO_SI; /* Clear SI and send STOP */
832 u8Xfering = 0u;
833 }
834 break;
835 case 0x38u: /* Arbitration Lost */
836 default: /* Unknow status */
837 LPI2C_SET_CONTROL_REG(lpi2c, LPI2C_CTL_STO_SI); /* Clear SI and send STOP */
838 u8Ctrl = LPI2C_CTL_SI;
839 u8Err = 1u;
840 break;
841 }
842 LPI2C_SET_CONTROL_REG(lpi2c, u8Ctrl); /* Write controlbit to LPI2C_CTL register */
843 }
844 return (u8Err | u8Xfering); /* return (Success)/(Fail) status */
845 }
846
847
848 /**
849 * @brief Specify two bytes register address and write multi bytes to Slave
850 *
851 * @param[in] lpi2c Point to LPI2C peripheral
852 * @param[in] u8SlaveAddr Access Slave address(7-bit)
853 * @param[in] u16DataAddr Specify a address (2 bytes) of data write to
854 * @param[in] data[] A data array for write data to Slave
855 * @param[in] u32wLen How many bytes need to write to Slave
856 *
857 * @return A length of how many bytes have been transmitted.
858 *
859 * @details The function is used for LPI2C Master specify two bytes address that multi data write to in Slave.
860 *
861 */
862
LPI2C_WriteMultiBytesTwoRegs(LPI2C_T * lpi2c,uint8_t u8SlaveAddr,uint16_t u16DataAddr,uint8_t data[],uint32_t u32wLen)863 uint32_t LPI2C_WriteMultiBytesTwoRegs(LPI2C_T *lpi2c, uint8_t u8SlaveAddr, uint16_t u16DataAddr, uint8_t data[], uint32_t u32wLen)
864 {
865 uint8_t u8Xfering = 1u, u8Err = 0u, u8Addr = 1u, u8Ctrl = 0u;
866 uint32_t u32txLen = 0u;
867 uint32_t u32TimeOutCount;
868
869 g_LPI2C_i32ErrCode = 0;
870
871 LPI2C_START(lpi2c); /* Send START */
872 while(u8Xfering && (u8Err == 0u))
873 {
874 u32TimeOutCount = SystemCoreClock;
875 LPI2C_WAIT_READY(lpi2c)
876 {
877 u32TimeOutCount--;
878 if(u32TimeOutCount == 0)
879 {
880 g_LPI2C_i32ErrCode = LPI2C_TIMEOUT_ERR;
881 break;
882 }
883 }
884
885 switch(LPI2C_GET_STATUS(lpi2c))
886 {
887 case 0x08u:
888 LPI2C_SET_DATA(lpi2c, (uint8_t)(u8SlaveAddr << 1u | 0x00u)); /* Write SLA+W to Register LPI2CDAT */
889 u8Ctrl = LPI2C_CTL_SI; /* Clear SI */
890 break;
891 case 0x18u: /* Slave Address ACK */
892 LPI2C_SET_DATA(lpi2c, (uint8_t)((u16DataAddr & 0xFF00u) >> 8u)); /* Write Hi byte address of register */
893 break;
894 case 0x20u: /* Slave Address NACK */
895 case 0x30u: /* Master transmit data NACK */
896 u8Ctrl = LPI2C_CTL_STO_SI; /* Clear SI and send STOP */
897 u8Err = 1u;
898 break;
899 case 0x28u:
900 if(u8Addr)
901 {
902 LPI2C_SET_DATA(lpi2c, (uint8_t)(u16DataAddr & 0xFFu)); /* Write Lo byte address of register */
903 u8Addr = 0u;
904 }
905 else if((u32txLen < u32wLen) && (u8Addr == 0u))
906 {
907 LPI2C_SET_DATA(lpi2c, data[u32txLen++]); /* Write data to Register LPI2CDAT*/
908 }
909 else
910 {
911 u8Ctrl = LPI2C_CTL_STO_SI; /* Clear SI and send STOP */
912 u8Xfering = 0u;
913 }
914 break;
915 case 0x38u: /* Arbitration Lost */
916 default: /* Unknow status */
917 LPI2C_SET_CONTROL_REG(lpi2c, LPI2C_CTL_STO_SI); /* Clear SI and send STOP */
918 u8Ctrl = LPI2C_CTL_SI;
919 u8Err = 1u;
920 break;
921 }
922 LPI2C_SET_CONTROL_REG(lpi2c, u8Ctrl); /* Write controlbit to LPI2C_CTL register */
923 }
924 return u32txLen; /* Return bytes length that have been transmitted */
925 }
926
927 /**
928 * @brief Read a byte from Slave
929 *
930 * @param[in] lpi2c Point to LPI2C peripheral
931 * @param[in] u8SlaveAddr Access Slave address(7-bit)
932 *
933 * @return Read a byte data from Slave
934 *
935 * @details The function is used for LPI2C Master to read a byte data from Slave.
936 *
937 */
LPI2C_ReadByte(LPI2C_T * lpi2c,uint8_t u8SlaveAddr)938 uint8_t LPI2C_ReadByte(LPI2C_T *lpi2c, uint8_t u8SlaveAddr)
939 {
940 uint8_t u8Xfering = 1u, u8Err = 0u, rdata = 0u, u8Ctrl = 0u;
941 uint32_t u32TimeOutCount;
942
943 g_LPI2C_i32ErrCode = 0;
944
945 LPI2C_START(lpi2c); /* Send START */
946 while(u8Xfering && (u8Err == 0u))
947 {
948 u32TimeOutCount = SystemCoreClock;
949 LPI2C_WAIT_READY(lpi2c)
950 {
951 u32TimeOutCount--;
952 if(u32TimeOutCount == 0)
953 {
954 g_LPI2C_i32ErrCode = LPI2C_TIMEOUT_ERR;
955 break;
956 }
957 }
958
959 switch(LPI2C_GET_STATUS(lpi2c))
960 {
961 case 0x08u:
962 LPI2C_SET_DATA(lpi2c, (uint8_t)((u8SlaveAddr << 1u) | 0x01u)); /* Write SLA+R to Register LPI2CDAT */
963 u8Ctrl = LPI2C_CTL_SI; /* Clear SI */
964 break;
965 case 0x40u: /* Slave Address ACK */
966 u8Ctrl = LPI2C_CTL_SI; /* Clear SI */
967 break;
968 case 0x48u: /* Slave Address NACK */
969 u8Ctrl = LPI2C_CTL_STO_SI; /* Clear SI and send STOP */
970 u8Err = 1u;
971 break;
972 case 0x58u:
973 rdata = (uint8_t) LPI2C_GET_DATA(lpi2c); /* Receive Data */
974 u8Ctrl = LPI2C_CTL_STO_SI; /* Clear SI and send STOP */
975 u8Xfering = 0u;
976 break;
977 case 0x38u: /* Arbitration Lost */
978 default: /* Unknow status */
979 LPI2C_SET_CONTROL_REG(lpi2c, LPI2C_CTL_STO_SI); /* Clear SI and send STOP */
980 u8Ctrl = LPI2C_CTL_SI;
981 u8Err = 1u;
982 break;
983 }
984 LPI2C_SET_CONTROL_REG(lpi2c, u8Ctrl); /* Write controlbit to LPI2C_CTL register */
985 }
986 if(u8Err)
987 {
988 rdata = 0u; /* If occurs error, return 0 */
989 }
990 return rdata; /* Return read data */
991 }
992
993
994 /**
995 * @brief Read multi bytes from Slave
996 *
997 * @param[in] lpi2c Point to LPI2C peripheral
998 * @param[in] u8SlaveAddr Access Slave address(7-bit)
999 * @param[out] rdata[] A data array to store data from Slave
1000 * @param[in] u32rLen How many bytes need to read from Slave
1001 *
1002 * @return A length of how many bytes have been received
1003 *
1004 * @details The function is used for LPI2C Master to read multi data bytes from Slave.
1005 *
1006 *
1007 */
LPI2C_ReadMultiBytes(LPI2C_T * lpi2c,uint8_t u8SlaveAddr,uint8_t rdata[],uint32_t u32rLen)1008 uint32_t LPI2C_ReadMultiBytes(LPI2C_T *lpi2c, uint8_t u8SlaveAddr, uint8_t rdata[], uint32_t u32rLen)
1009 {
1010 uint8_t u8Xfering = 1u, u8Err = 0u, u8Ctrl = 0u;
1011 uint32_t u32rxLen = 0u;
1012 uint32_t u32TimeOutCount;
1013
1014 g_LPI2C_i32ErrCode = 0;
1015
1016 LPI2C_START(lpi2c); /* Send START */
1017 while(u8Xfering && (u8Err == 0u))
1018 {
1019 u32TimeOutCount = SystemCoreClock;
1020 LPI2C_WAIT_READY(lpi2c)
1021 {
1022 u32TimeOutCount--;
1023 if(u32TimeOutCount == 0)
1024 {
1025 g_LPI2C_i32ErrCode = LPI2C_TIMEOUT_ERR;
1026 break;
1027 }
1028 }
1029
1030 switch(LPI2C_GET_STATUS(lpi2c))
1031 {
1032 case 0x08u:
1033 LPI2C_SET_DATA(lpi2c, (uint8_t)((u8SlaveAddr << 1u) | 0x01u)); /* Write SLA+R to Register LPI2CDAT */
1034 u8Ctrl = LPI2C_CTL_SI; /* Clear SI */
1035 break;
1036 case 0x40u: /* Slave Address ACK */
1037 u8Ctrl = LPI2C_CTL_SI_AA; /* Clear SI and set ACK */
1038 break;
1039 case 0x48u: /* Slave Address NACK */
1040 u8Ctrl = LPI2C_CTL_STO_SI; /* Clear SI and send STOP */
1041 u8Err = 1u;
1042 break;
1043 case 0x50u:
1044 rdata[u32rxLen++] = (uint8_t) LPI2C_GET_DATA(lpi2c); /* Receive Data */
1045 if(u32rxLen < (u32rLen - 1u))
1046 {
1047 u8Ctrl = LPI2C_CTL_SI_AA; /* Clear SI and set ACK */
1048 }
1049 else
1050 {
1051 u8Ctrl = LPI2C_CTL_SI; /* Clear SI */
1052 }
1053 break;
1054 case 0x58u:
1055 rdata[u32rxLen++] = (uint8_t) LPI2C_GET_DATA(lpi2c); /* Receive Data */
1056 u8Ctrl = LPI2C_CTL_STO_SI; /* Clear SI and send STOP */
1057 u8Xfering = 0u;
1058 break;
1059 case 0x38u: /* Arbitration Lost */
1060 default: /* Unknow status */
1061 LPI2C_SET_CONTROL_REG(lpi2c, LPI2C_CTL_STO_SI); /* Clear SI and send STOP */
1062 u8Ctrl = LPI2C_CTL_SI;
1063 u8Err = 1u;
1064 break;
1065 }
1066 LPI2C_SET_CONTROL_REG(lpi2c, u8Ctrl); /* Write controlbit to LPI2C_CTL register */
1067 }
1068 return u32rxLen; /* Return bytes length that have been received */
1069 }
1070
1071
1072 /**
1073 * @brief Specify a byte register address and read a byte from Slave
1074 *
1075 * @param[in] lpi2c Point to LPI2C peripheral
1076 * @param[in] u8SlaveAddr Access Slave address(7-bit)
1077 * @param[in] u8DataAddr Specify a address(1 byte) of data read from
1078 *
1079 * @return Read a byte data from Slave
1080 *
1081 * @details The function is used for LPI2C Master specify a byte address that a data byte read from Slave.
1082 *
1083 *
1084 */
LPI2C_ReadByteOneReg(LPI2C_T * lpi2c,uint8_t u8SlaveAddr,uint8_t u8DataAddr)1085 uint8_t LPI2C_ReadByteOneReg(LPI2C_T *lpi2c, uint8_t u8SlaveAddr, uint8_t u8DataAddr)
1086 {
1087 uint8_t u8Xfering = 1u, u8Err = 0u, rdata = 0u, u8Ctrl = 0u;
1088 uint32_t u32TimeOutCount;
1089
1090 g_LPI2C_i32ErrCode = 0;
1091
1092 LPI2C_START(lpi2c); /* Send START */
1093 while(u8Xfering && (u8Err == 0u))
1094 {
1095 u32TimeOutCount = SystemCoreClock;
1096 LPI2C_WAIT_READY(lpi2c)
1097 {
1098 u32TimeOutCount--;
1099 if(u32TimeOutCount == 0)
1100 {
1101 g_LPI2C_i32ErrCode = LPI2C_TIMEOUT_ERR;
1102 break;
1103 }
1104 }
1105
1106 switch(LPI2C_GET_STATUS(lpi2c))
1107 {
1108 case 0x08u:
1109 LPI2C_SET_DATA(lpi2c, (uint8_t)(u8SlaveAddr << 1u | 0x00u)); /* Write SLA+W to Register LPI2CDAT */
1110 u8Ctrl = LPI2C_CTL_SI; /* Clear SI */
1111 break;
1112 case 0x18u: /* Slave Address ACK */
1113 LPI2C_SET_DATA(lpi2c, u8DataAddr); /* Write Lo byte address of register */
1114 break;
1115 case 0x20u: /* Slave Address NACK */
1116 case 0x30u: /* Master transmit data NACK */
1117 u8Ctrl = LPI2C_CTL_STO_SI; /* Clear SI and send STOP */
1118 u8Err = 1u;
1119 break;
1120 case 0x28u:
1121 u8Ctrl = LPI2C_CTL_STA_SI; /* Send repeat START */
1122 break;
1123 case 0x10u:
1124 LPI2C_SET_DATA(lpi2c, (uint8_t)((u8SlaveAddr << 1u) | 0x01u)); /* Write SLA+R to Register LPI2CDAT */
1125 u8Ctrl = LPI2C_CTL_SI; /* Clear SI */
1126 break;
1127 case 0x40u: /* Slave Address ACK */
1128 u8Ctrl = LPI2C_CTL_SI; /* Clear SI */
1129 break;
1130 case 0x48u: /* Slave Address NACK */
1131 u8Ctrl = LPI2C_CTL_STO_SI; /* Clear SI and send STOP */
1132 u8Err = 1u;
1133 break;
1134 case 0x58u:
1135 rdata = (uint8_t) LPI2C_GET_DATA(lpi2c); /* Receive Data */
1136 u8Ctrl = LPI2C_CTL_STO_SI; /* Clear SI and send STOP */
1137 u8Xfering = 0u;
1138 break;
1139 case 0x38u: /* Arbitration Lost */
1140 default: /* Unknow status */
1141 LPI2C_SET_CONTROL_REG(lpi2c, LPI2C_CTL_STO_SI); /* Clear SI and send STOP */
1142 u8Ctrl = LPI2C_CTL_SI;
1143 u8Err = 1u;
1144 break;
1145 }
1146 LPI2C_SET_CONTROL_REG(lpi2c, u8Ctrl); /* Write controlbit to LPI2C_CTL register */
1147 }
1148 if(u8Err)
1149 {
1150 rdata = 0u; /* If occurs error, return 0 */
1151 }
1152 return rdata; /* Return read data */
1153 }
1154
1155 /**
1156 * @brief Specify a byte register address and read multi bytes from Slave
1157 *
1158 * @param[in] lpi2c Point to LPI2C peripheral
1159 * @param[in] u8SlaveAddr Access Slave address(7-bit)
1160 * @param[in] u8DataAddr Specify a address (1 byte) of data read from
1161 * @param[out] rdata[] A data 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 LPI2C Master specify a byte address that multi data bytes read from Slave.
1167 *
1168 *
1169 */
LPI2C_ReadMultiBytesOneReg(LPI2C_T * lpi2c,uint8_t u8SlaveAddr,uint8_t u8DataAddr,uint8_t rdata[],uint32_t u32rLen)1170 uint32_t LPI2C_ReadMultiBytesOneReg(LPI2C_T *lpi2c, uint8_t u8SlaveAddr, uint8_t u8DataAddr, uint8_t rdata[], uint32_t u32rLen)
1171 {
1172 uint8_t u8Xfering = 1u, u8Err = 0u, u8Ctrl = 0u;
1173 uint32_t u32rxLen = 0u;
1174 uint32_t u32TimeOutCount;
1175
1176 g_LPI2C_i32ErrCode = 0;
1177
1178 LPI2C_START(lpi2c); /* Send START */
1179 while(u8Xfering && (u8Err == 0u))
1180 {
1181 u32TimeOutCount = SystemCoreClock;
1182 LPI2C_WAIT_READY(lpi2c)
1183 {
1184 u32TimeOutCount--;
1185 if(u32TimeOutCount == 0)
1186 {
1187 g_LPI2C_i32ErrCode = LPI2C_TIMEOUT_ERR;
1188 break;
1189 }
1190 }
1191
1192 switch(LPI2C_GET_STATUS(lpi2c))
1193 {
1194 case 0x08u:
1195 LPI2C_SET_DATA(lpi2c, (uint8_t)(u8SlaveAddr << 1u | 0x00u)); /* Write SLA+W to Register LPI2CDAT */
1196 u8Ctrl = LPI2C_CTL_SI; /* Clear SI */
1197 break;
1198 case 0x18u: /* Slave Address ACK */
1199 LPI2C_SET_DATA(lpi2c, u8DataAddr); /* Write Lo byte address of register */
1200 break;
1201 case 0x20u: /* Slave Address NACK */
1202 case 0x30u: /* Master transmit data NACK */
1203 u8Ctrl = LPI2C_CTL_STO_SI; /* Clear SI and send STOP */
1204 u8Err = 1u;
1205 break;
1206 case 0x28u:
1207 u8Ctrl = LPI2C_CTL_STA_SI; /* Send repeat START */
1208 break;
1209 case 0x10u:
1210 LPI2C_SET_DATA(lpi2c, (uint8_t)((u8SlaveAddr << 1u) | 0x01u)); /* Write SLA+R to Register LPI2CDAT */
1211 u8Ctrl = LPI2C_CTL_SI; /* Clear SI */
1212 break;
1213 case 0x40u: /* Slave Address ACK */
1214 u8Ctrl = LPI2C_CTL_SI_AA; /* Clear SI and set ACK */
1215 break;
1216 case 0x48u: /* Slave Address NACK */
1217 u8Ctrl = LPI2C_CTL_STO_SI; /* Clear SI and send STOP */
1218 u8Err = 1u;
1219 break;
1220 case 0x50u:
1221 rdata[u32rxLen++] = (uint8_t) LPI2C_GET_DATA(lpi2c); /* Receive Data */
1222 if(u32rxLen < (u32rLen - 1u))
1223 {
1224 u8Ctrl = LPI2C_CTL_SI_AA; /* Clear SI and set ACK */
1225 }
1226 else
1227 {
1228 u8Ctrl = LPI2C_CTL_SI; /* Clear SI */
1229 }
1230 break;
1231 case 0x58u:
1232 rdata[u32rxLen++] = (uint8_t) LPI2C_GET_DATA(lpi2c); /* Receive Data */
1233 u8Ctrl = LPI2C_CTL_STO_SI; /* Clear SI and send STOP */
1234 u8Xfering = 0u;
1235 break;
1236 case 0x38u: /* Arbitration Lost */
1237 default: /* Unknow status */
1238 LPI2C_SET_CONTROL_REG(lpi2c, LPI2C_CTL_STO_SI); /* Clear SI and send STOP */
1239 u8Ctrl = LPI2C_CTL_SI;
1240 u8Err = 1u;
1241 break;
1242 }
1243 LPI2C_SET_CONTROL_REG(lpi2c, u8Ctrl); /* Write controlbit to LPI2C_CTL register */
1244 }
1245 return u32rxLen; /* Return bytes length that have been received */
1246 }
1247
1248 /**
1249 * @brief Specify two bytes register address and read a byte from Slave
1250 *
1251 * @param[in] lpi2c Point to LPI2C peripheral
1252 * @param[in] u8SlaveAddr Access Slave address(7-bit)
1253 * @param[in] u16DataAddr Specify an address(2 bytes) of data read from
1254 *
1255 * @return Read a byte data from Slave
1256 *
1257 * @details The function is used for LPI2C Master specify two bytes address that a data byte read from Slave.
1258 *
1259 *
1260 */
LPI2C_ReadByteTwoRegs(LPI2C_T * lpi2c,uint8_t u8SlaveAddr,uint16_t u16DataAddr)1261 uint8_t LPI2C_ReadByteTwoRegs(LPI2C_T *lpi2c, uint8_t u8SlaveAddr, uint16_t u16DataAddr)
1262 {
1263 uint8_t u8Xfering = 1u, u8Err = 0u, rdata = 0u, u8Addr = 1u, u8Ctrl = 0u;
1264 uint32_t u32TimeOutCount;
1265
1266 g_LPI2C_i32ErrCode = 0;
1267
1268 LPI2C_START(lpi2c); /* Send START */
1269 while(u8Xfering && (u8Err == 0u))
1270 {
1271 u32TimeOutCount = SystemCoreClock;
1272 LPI2C_WAIT_READY(lpi2c)
1273 {
1274 u32TimeOutCount--;
1275 if(u32TimeOutCount == 0)
1276 {
1277 g_LPI2C_i32ErrCode = LPI2C_TIMEOUT_ERR;
1278 break;
1279 }
1280 }
1281
1282 switch(LPI2C_GET_STATUS(lpi2c))
1283 {
1284 case 0x08u:
1285 LPI2C_SET_DATA(lpi2c, (uint8_t)(u8SlaveAddr << 1u | 0x00u)); /* Write SLA+W to Register LPI2CDAT */
1286 u8Ctrl = LPI2C_CTL_SI; /* Clear SI */
1287 break;
1288 case 0x18u: /* Slave Address ACK */
1289 LPI2C_SET_DATA(lpi2c, (uint8_t)((u16DataAddr & 0xFF00u) >> 8u)); /* Write Hi byte address of register */
1290 break;
1291 case 0x20u: /* Slave Address NACK */
1292 case 0x30u: /* Master transmit data NACK */
1293 u8Ctrl = LPI2C_CTL_STO_SI; /* Clear SI and send STOP */
1294 u8Err = 1u;
1295 break;
1296 case 0x28u:
1297 if(u8Addr)
1298 {
1299 LPI2C_SET_DATA(lpi2c, (uint8_t)(u16DataAddr & 0xFFu)); /* Write Lo byte address of register */
1300 u8Addr = 0u;
1301 }
1302 else
1303 {
1304 u8Ctrl = LPI2C_CTL_STA_SI; /* Clear SI and send repeat START */
1305 }
1306 break;
1307 case 0x10u:
1308 LPI2C_SET_DATA(lpi2c, (uint8_t)((u8SlaveAddr << 1u) | 0x01u)); /* Write SLA+R to Register LPI2CDAT */
1309 u8Ctrl = LPI2C_CTL_SI; /* Clear SI */
1310 break;
1311 case 0x40u: /* Slave Address ACK */
1312 u8Ctrl = LPI2C_CTL_SI; /* Clear SI */
1313 break;
1314 case 0x48u: /* Slave Address NACK */
1315 u8Ctrl = LPI2C_CTL_STO_SI; /* Clear SI and send STOP */
1316 u8Err = 1u;
1317 break;
1318 case 0x58u:
1319 rdata = (uint8_t) LPI2C_GET_DATA(lpi2c); /* Receive Data */
1320 u8Ctrl = LPI2C_CTL_STO_SI; /* Clear SI and send STOP */
1321 u8Xfering = 0u;
1322 break;
1323 case 0x38u: /* Arbitration Lost */
1324 default: /* Unknow status */
1325 LPI2C_SET_CONTROL_REG(lpi2c, LPI2C_CTL_STO_SI); /* Clear SI and send STOP */
1326 u8Ctrl = LPI2C_CTL_SI;
1327 u8Err = 1u;
1328 break;
1329 }
1330 LPI2C_SET_CONTROL_REG(lpi2c, u8Ctrl); /* Write controlbit to LPI2C_CTL register */
1331 }
1332 if(u8Err)
1333 {
1334 rdata = 0u; /* If occurs error, return 0 */
1335 }
1336 return rdata; /* Return read data */
1337 }
1338
1339 /**
1340 * @brief Specify two bytes register address and read multi bytes from Slave
1341 *
1342 * @param[in] lpi2c Point to LPI2C peripheral
1343 * @param[in] u8SlaveAddr Access Slave address(7-bit)
1344 * @param[in] u16DataAddr Specify a address (2 bytes) of data read from
1345 * @param[out] rdata[] A data array to store data from Slave
1346 * @param[in] u32rLen How many bytes need to read from Slave
1347 *
1348 * @return A length of how many bytes have been received
1349 *
1350 * @details The function is used for LPI2C Master specify two bytes address that multi data bytes read from Slave.
1351 *
1352 *
1353 */
LPI2C_ReadMultiBytesTwoRegs(LPI2C_T * lpi2c,uint8_t u8SlaveAddr,uint16_t u16DataAddr,uint8_t rdata[],uint32_t u32rLen)1354 uint32_t LPI2C_ReadMultiBytesTwoRegs(LPI2C_T *lpi2c, uint8_t u8SlaveAddr, uint16_t u16DataAddr, uint8_t rdata[], uint32_t u32rLen)
1355 {
1356 uint8_t u8Xfering = 1u, u8Err = 0u, u8Addr = 1u, u8Ctrl = 0u;
1357 uint32_t u32rxLen = 0u;
1358 uint32_t u32TimeOutCount;
1359
1360 g_LPI2C_i32ErrCode = 0;
1361
1362 LPI2C_START(lpi2c); /* Send START */
1363 while(u8Xfering && (u8Err == 0u))
1364 {
1365 u32TimeOutCount = SystemCoreClock;
1366 LPI2C_WAIT_READY(lpi2c)
1367 {
1368 u32TimeOutCount--;
1369 if(u32TimeOutCount == 0)
1370 {
1371 g_LPI2C_i32ErrCode = LPI2C_TIMEOUT_ERR;
1372 break;
1373 }
1374 }
1375
1376 switch(LPI2C_GET_STATUS(lpi2c))
1377 {
1378 case 0x08u:
1379 LPI2C_SET_DATA(lpi2c, (uint8_t)(u8SlaveAddr << 1u | 0x00u)); /* Write SLA+W to Register LPI2CDAT */
1380 u8Ctrl = LPI2C_CTL_SI; /* Clear SI */
1381 break;
1382 case 0x18u: /* Slave Address ACK */
1383 LPI2C_SET_DATA(lpi2c, (uint8_t)((u16DataAddr & 0xFF00u) >> 8u)); /* Write Hi byte address of register */
1384 break;
1385 case 0x20u: /* Slave Address NACK */
1386 case 0x30u: /* Master transmit data NACK */
1387 u8Ctrl = LPI2C_CTL_STO_SI; /* Clear SI and send STOP */
1388 u8Err = 1u;
1389 break;
1390 case 0x28u:
1391 if(u8Addr)
1392 {
1393 LPI2C_SET_DATA(lpi2c, (uint8_t)(u16DataAddr & 0xFFu)); /* Write Lo byte address of register */
1394 u8Addr = 0u;
1395 }
1396 else
1397 {
1398 u8Ctrl = LPI2C_CTL_STA_SI; /* Clear SI and send repeat START */
1399 }
1400 break;
1401 case 0x10u:
1402 LPI2C_SET_DATA(lpi2c, (uint8_t)((u8SlaveAddr << 1u) | 0x01u)); /* Write SLA+R to Register LPI2CDAT */
1403 u8Ctrl = LPI2C_CTL_SI; /* Clear SI */
1404 break;
1405 case 0x40u: /* Slave Address ACK */
1406 u8Ctrl = LPI2C_CTL_SI_AA; /* Clear SI and set ACK */
1407 break;
1408 case 0x48u: /* Slave Address NACK */
1409 u8Ctrl = LPI2C_CTL_STO_SI; /* Clear SI and send STOP */
1410 u8Err = 1u;
1411 break;
1412 case 0x50u:
1413 rdata[u32rxLen++] = (uint8_t) LPI2C_GET_DATA(lpi2c); /* Receive Data */
1414 if(u32rxLen < (u32rLen - 1u))
1415 {
1416 u8Ctrl = LPI2C_CTL_SI_AA; /* Clear SI and set ACK */
1417 }
1418 else
1419 {
1420 u8Ctrl = LPI2C_CTL_SI; /* Clear SI */
1421 }
1422 break;
1423 case 0x58u:
1424 rdata[u32rxLen++] = (uint8_t) LPI2C_GET_DATA(lpi2c); /* Receive Data */
1425 u8Ctrl = LPI2C_CTL_STO_SI; /* Clear SI and send STOP */
1426 u8Xfering = 0u;
1427 break;
1428 case 0x38u: /* Arbitration Lost */
1429 default: /* Unknow status */
1430 LPI2C_SET_CONTROL_REG(lpi2c, LPI2C_CTL_STO_SI); /* Clear SI and send STOP */
1431 u8Ctrl = LPI2C_CTL_SI;
1432 u8Err = 1u;
1433 break;
1434 }
1435 LPI2C_SET_CONTROL_REG(lpi2c, u8Ctrl); /* Write controlbit to LPI2C_CTL register */
1436 }
1437 return u32rxLen; /* Return bytes length that have been received */
1438 }
1439
1440
1441 /*@}*/ /* end of group LPI2C_EXPORTED_FUNCTIONS */
1442
1443 /*@}*/ /* end of group LPI2C_Driver */
1444
1445 /*@}*/ /* end of group Standard_Driver */
1446
1447 /*** (C) COPYRIGHT 2023 Nuvoton Technology Corp. ***/
1448