1 /*!
2 * @file apm32s10x_i2c.c
3 *
4 * @brief This file provides all the I2C firmware functions
5 *
6 * @version V1.0.1
7 *
8 * @date 2022-12-31
9 *
10 * @attention
11 *
12 * Copyright (C) 2022-2023 Geehy Semiconductor
13 *
14 * You may not use this file except in compliance with the
15 * GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
16 *
17 * The program is only for reference, which is distributed in the hope
18 * that it will be usefull and instructional for customers to develop
19 * their software. Unless required by applicable law or agreed to in
20 * writing, the program is distributed on an "AS IS" BASIS, WITHOUT
21 * ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
22 * See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
23 * and limitations under the License.
24 */
25
26 /* Includes */
27 #include "apm32s10x_i2c.h"
28 #include "apm32s10x_rcm.h"
29
30 /** @addtogroup APM32S10x_StdPeriphDriver
31 @{
32 */
33
34 /** @addtogroup I2C_Driver I2C Driver
35 @{
36 */
37
38 /** @defgroup I2C_Functions Functions
39 @{
40 */
41
42 /*!
43 * @brief Reset I2C
44 *
45 * @param i2c: I2C selet 1 or 2
46 *
47 * @retval None
48 */
I2C_Reset(I2C_T * i2c)49 void I2C_Reset(I2C_T* i2c)
50 {
51 if (i2c == I2C1)
52 {
53 RCM_EnableAPB1PeriphReset(RCM_APB1_PERIPH_I2C1);
54 RCM_DisableAPB1PeriphReset(RCM_APB1_PERIPH_I2C1);
55 }
56 else
57 {
58 RCM_EnableAPB1PeriphReset(RCM_APB1_PERIPH_I2C2);
59 RCM_DisableAPB1PeriphReset(RCM_APB1_PERIPH_I2C2);
60 }
61 }
62
63 /*!
64 * @brief Configure I2C by configuring the structure
65 *
66 * @param i2c: I2C selet 1 or 2
67 *
68 * @param i2cConfig: pointer to a I2C_Config_T structure
69 *
70 * @retval None
71 */
I2C_Config(I2C_T * i2c,I2C_Config_T * i2cConfig)72 void I2C_Config(I2C_T* i2c, I2C_Config_T* i2cConfig)
73 {
74 uint16_t tmpreg = 0, freqrange = 0;
75 uint32_t PCLK1 = 8000000, PCLK2 = 0;
76 uint16_t result = 0x04;
77
78 i2c->SWITCH = 0;
79
80 /* I2C CTRL2 Configuration */
81 RCM_ReadPCLKFreq(&PCLK1, &PCLK2);
82 freqrange = PCLK1 / 1000000;
83 i2c->CTRL2_B.CLKFCFG = freqrange;
84
85 /* I2C CLKCTRL Configuration */
86 i2c->CTRL1_B.I2CEN = BIT_RESET;
87
88 if (i2cConfig->clockSpeed <= 100000)
89 {
90 result = (PCLK1 / (i2cConfig->clockSpeed << 1));
91 if (result < 0x04)
92 {
93 result = 0x04;
94 }
95 i2c->RISETMAX = freqrange + 1;
96 tmpreg |= result;
97 }
98 /* Configure speed in fast mode */
99 else
100 {
101 if (i2cConfig->dutyCycle == I2C_DUTYCYCLE_2)
102 {
103 result = (PCLK1 / (i2cConfig->clockSpeed * 3));
104 }
105 else
106 {
107 result = (PCLK1 / (i2cConfig->clockSpeed * 25));
108 result |= I2C_DUTYCYCLE_16_9;
109 }
110
111 if ((result & 0x0FFF) == 0)
112 {
113 result |= 0x0001;
114 }
115
116 tmpreg |= (uint16_t)(result | 0x8000);
117 i2c->RISETMAX = ((((freqrange) * 300) / 1000) + 1);
118 }
119 i2c->CLKCTRL = tmpreg;
120 i2c->CTRL1_B.I2CEN = BIT_SET;
121
122 /* i2c CTRL1 Configuration */
123 i2c->CTRL1_B.ACKEN = BIT_RESET;
124 i2c->CTRL1_B.SMBTCFG = BIT_RESET;
125 i2c->CTRL1_B.SMBEN = BIT_RESET;
126
127 i2c->CTRL1 |= i2cConfig->mode;
128 i2c->CTRL1_B.ACKEN = i2cConfig->ack;
129
130 i2c->SADDR1 = i2cConfig->ackAddress | i2cConfig->ownAddress1;
131 }
132
133 /*!
134 * @brief Fill each I2C_Config_T member with its default value.
135 *
136 * @param i2cConfig: pointer to a I2C_Config_T structure
137 *
138 * @retval None
139 */
I2C_ConfigStructInit(I2C_Config_T * i2cConfig)140 void I2C_ConfigStructInit(I2C_Config_T* i2cConfig)
141 {
142 i2cConfig->clockSpeed = 5000;
143 i2cConfig->mode = I2C_MODE_I2C;
144 i2cConfig->dutyCycle = I2C_DUTYCYCLE_2;
145 i2cConfig->ownAddress1 = 0;
146 i2cConfig->ack = I2C_ACK_DISABLE;
147 i2cConfig->ackAddress = I2C_ACK_ADDRESS_7BIT;
148 }
149
150 /*!
151 * @brief Enable I2C
152 *
153 * @param i2c: I2C selet 1 or 2
154 *
155 * @retval None
156 */
I2C_Enable(I2C_T * i2c)157 void I2C_Enable(I2C_T* i2c)
158 {
159 i2c->CTRL1_B.I2CEN = ENABLE;
160 }
161
162 /*!
163 * @brief Disable I2C
164 *
165 * @param i2c: I2C selet 1 or 2
166 *
167 * @retval None
168 */
I2C_Disable(I2C_T * i2c)169 void I2C_Disable(I2C_T* i2c)
170 {
171 i2c->CTRL1_B.I2CEN = DISABLE;
172 }
173
174 /*!
175 * @brief Enable Generates i2c communication START condition.
176 *
177 * @param i2c: I2C selet 1 or 2
178 *
179 * @retval None
180 */
I2C_EnableGenerateStart(I2C_T * i2c)181 void I2C_EnableGenerateStart(I2C_T* i2c)
182 {
183 i2c->CTRL1_B.START = BIT_SET;
184 }
185
186 /*!
187 * @brief Disable Generates i2c communication START condition.
188 *
189 * @param i2c: I2C selet 1 or 2
190 *
191 * @retval None
192 */
I2C_DisableGenerateStart(I2C_T * i2c)193 void I2C_DisableGenerateStart(I2C_T* i2c)
194 {
195 i2c->CTRL1_B.START = BIT_RESET;
196 }
197
198 /*!
199 * @brief Enable Generates i2c communication STOP condition.
200 *
201 * @param i2c: I2C selet 1 or 2
202 *
203 * @retval None
204 */
I2C_EnableGenerateStop(I2C_T * i2c)205 void I2C_EnableGenerateStop(I2C_T* i2c)
206 {
207 i2c->CTRL1_B.STOP = BIT_SET;
208 }
209
210 /*!
211 * @brief Disable Generates i2c communication STOP condition.
212 *
213 * @param i2c: I2C selet 1 or 2
214 *
215 * @retval None
216 */
I2C_DisableGenerateStop(I2C_T * i2c)217 void I2C_DisableGenerateStop(I2C_T* i2c)
218 {
219 i2c->CTRL1_B.STOP = BIT_RESET;
220 }
221
222 /*!
223 * @brief Enable the specified I2C acknowledge feature.
224 *
225 * @param i2c: I2C selet 1 or 2
226 *
227 * @retval None
228 */
I2C_EnableAcknowledge(I2C_T * i2c)229 void I2C_EnableAcknowledge(I2C_T* i2c)
230 {
231 i2c->CTRL1_B.ACKEN = ENABLE;
232 }
233
234 /*!
235 * @brief Disable the specified I2C acknowledge feature.
236 *
237 * @param i2c: I2C selet 1 or 2
238 *
239 * @retval None
240 */
I2C_DisableAcknowledge(I2C_T * i2c)241 void I2C_DisableAcknowledge(I2C_T* i2c)
242 {
243 i2c->CTRL1_B.ACKEN = DISABLE;
244 }
245
246 /*!
247 * @brief Configure the specified I2C own address2.
248 *
249 * @param i2c: I2C selet 1 or 2
250 *
251 * @param address:specifies the 7bit I2C own address2.
252 *
253 * @retval None
254 */
I2C_ConfigOwnAddress2(I2C_T * i2c,uint8_t address)255 void I2C_ConfigOwnAddress2(I2C_T* i2c, uint8_t address)
256 {
257 i2c->SADDR2_B.ADDR2 = address;
258 }
259
260 /*!
261 * @brief Enable the specified I2C dual addressing mode.
262 *
263 * @param i2c: I2C selet 1 or 2
264 *
265 * @retval None
266 */
I2C_EnableDualAddress(I2C_T * i2c)267 void I2C_EnableDualAddress(I2C_T* i2c)
268 {
269 i2c->SADDR2_B.ADDRNUM = ENABLE;
270 }
271
272 /*!
273 * @brief Disable the specified I2C dual addressing mode.
274 *
275 * @param i2c: I2C selet 1 or 2
276 *
277 * @retval None
278 */
I2C_DisableDualAddress(I2C_T * i2c)279 void I2C_DisableDualAddress(I2C_T* i2c)
280 {
281 i2c->SADDR2_B.ADDRNUM = DISABLE;
282 }
283
284 /*!
285 * @brief Enable the specified I2C general call feature.
286 *
287 * @param i2c: I2C selet 1 or 2
288 *
289 * @retval None
290 */
I2C_EnableGeneralCall(I2C_T * i2c)291 void I2C_EnableGeneralCall(I2C_T* i2c)
292 {
293 i2c->CTRL1_B.SRBEN = ENABLE;
294 }
295
296 /*!
297 * @brief Disable the specified I2C general call feature.
298 *
299 * @param i2c: I2C selet 1 or 2
300 *
301 * @retval None
302 */
I2C_DisableGeneralCall(I2C_T * i2c)303 void I2C_DisableGeneralCall(I2C_T* i2c)
304 {
305 i2c->CTRL1_B.SRBEN = DISABLE;
306 }
307
308 /*!
309 * @brief Send one byte
310 *
311 * @param i2c: I2C selet 1 or 2
312 *
313 * @param data: data to send
314 *
315 * @retval None
316 */
I2C_TxData(I2C_T * i2c,uint8_t data)317 void I2C_TxData(I2C_T* i2c, uint8_t data)
318 {
319 i2c->DATA_B.DATA = data;
320 }
321
322 /*!
323 * @brief Return the recevie data
324 *
325 * @param i2c: I2C selet 1 or 2
326 *
327 * @retval received data
328 */
I2C_RxData(I2C_T * i2c)329 uint8_t I2C_RxData(I2C_T* i2c)
330 {
331 return i2c->DATA_B.DATA;
332 }
333
334 /*!
335 * @brief Transmit the address byte to select the slave device.
336 *
337 * @param i2c: I2C selet 1 or 2
338 *
339 * @param address: slave address which will be transmitted
340 *
341 * @param direction: Direction mode
342 * The parameter can be one of following values:
343 * @arg I2C_DIRECTION_TX: Transmitter mode
344 * @arg I2C_DIRECTION_RX: Receiver mode
345 * @retval None
346 */
I2C_Tx7BitAddress(I2C_T * i2c,uint8_t address,I2C_DIRECTION_T direction)347 void I2C_Tx7BitAddress(I2C_T* i2c, uint8_t address, I2C_DIRECTION_T direction)
348 {
349 if (direction != I2C_DIRECTION_TX)
350 {
351 i2c->DATA_B.DATA = address | 0x0001;
352 }
353 else
354 {
355 i2c->DATA_B.DATA = address & 0xFFFE;
356 }
357 }
358
359 /*!
360 * @brief Reads the I2C register and returns its value.
361 *
362 * @param i2c: I2C selet 1 or 2
363 *
364 * @param i2cRegister : register to read
365 * The parameter can be one of following values:
366 * @arg I2C_REGISTER_CTRL1: CTRL1 register
367 * @arg I2C_REGISTER_CTRL2: CTRL2 register
368 * @arg I2C_REGISTER_SADDR1: SADDR1 register
369 * @arg I2C_REGISTER_SADDR2: SADDR2 register
370 * @arg I2C_REGISTER_DATA: DATA register
371 * @arg I2C_REGISTER_STS1: STS1 register
372 * @arg I2C_REGISTER_STS2: STS2 register
373 * @arg I2C_REGISTER_CLKCTRL: CLKCTRL register
374 * @arg I2C_REGISTER_RISETMAX: RISETMAX register
375 * @arg I2C_REGISTER_SWITCH: SWITCH register
376 *
377 * @retval The value of the read register
378 */
I2C_ReadRegister(I2C_T * i2c,I2C_REGISTER_T i2cRegister)379 uint16_t I2C_ReadRegister(I2C_T* i2c, I2C_REGISTER_T i2cRegister)
380 {
381 switch (i2cRegister)
382 {
383 case I2C_REGISTER_CTRL1:
384 return i2c->CTRL1;
385 case I2C_REGISTER_CTRL2:
386 return i2c->CTRL2;
387 case I2C_REGISTER_SADDR1:
388 return i2c->SADDR1;
389 case I2C_REGISTER_SADDR2:
390 return i2c->SADDR2;
391 case I2C_REGISTER_DATA:
392 return i2c->DATA;
393 case I2C_REGISTER_STS1:
394 return i2c->STS1;
395 case I2C_REGISTER_STS2:
396 return i2c->STS2;
397 case I2C_REGISTER_CLKCTRL:
398 return i2c->CLKCTRL;
399 case I2C_REGISTER_RISETMAX:
400 return i2c->RISETMAX;
401 case I2C_REGISTER_SWITCH:
402 return i2c->SWITCH;
403 default:
404 return 0;
405 }
406 }
407
408 /*!
409 * @brief Enable the I2C software reset.
410 *
411 * @param i2c: I2C selet 1 or 2
412 *
413 * @retval None
414 */
I2C_EnableSoftwareReset(I2C_T * i2c)415 void I2C_EnableSoftwareReset(I2C_T* i2c)
416 {
417 i2c->CTRL1_B.SWRST = ENABLE;
418 }
419
420 /*!
421 * @brief Disable the I2C software reset.
422 *
423 * @param i2c: I2C selet 1 or 2
424 *
425 * @retval None
426 */
I2C_DisableSoftwareReset(I2C_T * i2c)427 void I2C_DisableSoftwareReset(I2C_T* i2c)
428 {
429 i2c->CTRL1_B.SWRST = DISABLE;
430 }
431
432 /*!
433 * @brief Select the specified I2C NACK position in master receiver mode.
434 *
435 * @param i2c: I2C selet 1 or 2
436 *
437 * @param NACKPosition: specifies the NACK position.
438 *
439 * @retval None
440 */
I2C_ConfigNACKPosition(I2C_T * i2c,I2C_NACK_POSITION_T NACKPosition)441 void I2C_ConfigNACKPosition(I2C_T* i2c, I2C_NACK_POSITION_T NACKPosition)
442 {
443 if (NACKPosition == I2C_NACK_POSITION_NEXT)
444 {
445 i2c->CTRL1_B.ACKPOS = BIT_SET;
446 }
447 else
448 {
449 i2c->CTRL1_B.ACKPOS = BIT_RESET;
450 }
451 }
452
453 /*!
454 * @brief Control the height of pin of SMBusAlert
455 *
456 * @param i2c: I2C selet 1 or 2
457 *
458 * @param SMBusState: SMBAlert pin level.
459 * The parameter can be one of following values:
460 * @arg I2C_SMBUSALER_LOW: SMBus Alert pin low
461 * @arg I2C_SMBUSALER_HIGH: SMBus Alert pin high
462 *
463 * @retval None
464 */
I2C_ConfigSMBusAlert(I2C_T * i2c,I2C_SMBUSALER_T SMBusState)465 void I2C_ConfigSMBusAlert(I2C_T* i2c, I2C_SMBUSALER_T SMBusState)
466 {
467 if (SMBusState == I2C_SMBUSALER_LOW)
468 {
469 i2c->CTRL1_B.ALERTEN = BIT_SET;
470 }
471 else
472 {
473 i2c->CTRL1_B.ALERTEN = BIT_RESET;
474 }
475 }
476
477 /*!
478 * @brief Enable the I2C PEC transfer.
479 *
480 * @param i2c: I2C selet 1 or 2
481 *
482 * @retval None
483 */
I2C_EnablePECTransmit(I2C_T * i2c)484 void I2C_EnablePECTransmit(I2C_T* i2c)
485 {
486 i2c->CTRL1_B.PEC = BIT_SET;
487 }
488
489 /*!
490 * @brief Disable the I2C PEC transfer.
491 *
492 * @param i2c: I2C selet 1 or 2
493 *
494 * @retval None
495 */
I2C_DisablePECTransmit(I2C_T * i2c)496 void I2C_DisablePECTransmit(I2C_T* i2c)
497 {
498 i2c->CTRL1_B.PEC = BIT_RESET;
499 }
500
501 /*!
502 * @brief Select the I2C PEC position.
503 *
504 * @param i2c: I2C selet 1 or 2
505 *
506 * @param PECPosition: PEC position
507 * The parameter can be one of following values:
508 * @arg I2C_PEC_POSITION_NEXT: indicates that the next byte is PEC
509 * @arg I2C_PEC_POSITION_CURRENT: indicates that current byte is PEC
510 *
511 * @retval None
512 */
I2C_ConfigPECPosition(I2C_T * i2c,I2C_PEC_POSITION_T PECPosition)513 void I2C_ConfigPECPosition(I2C_T* i2c, I2C_PEC_POSITION_T PECPosition)
514 {
515 if (PECPosition == I2C_PEC_POSITION_NEXT)
516 {
517 i2c->CTRL1_B.ACKPOS = BIT_SET;
518 }
519 else
520 {
521 i2c->CTRL1_B.ACKPOS = BIT_RESET;
522 }
523 }
524
525 /*!
526 * @brief Enable the PEC value calculation of the transferred bytes.
527 *
528 * @param i2c: I2C selet 1 or 2
529 *
530 * @retval None
531 */
I2C_EnablePEC(I2C_T * i2c)532 void I2C_EnablePEC(I2C_T* i2c)
533 {
534 i2c->CTRL1_B.PECEN = BIT_SET;
535 }
536
537 /*!
538 * @brief Disable the PEC value calculation of the transferred bytes.
539 *
540 * @param i2c: I2C selet 1 or 2
541 *
542 * @retval None
543 */
I2C_DisablePEC(I2C_T * i2c)544 void I2C_DisablePEC(I2C_T* i2c)
545 {
546 i2c->CTRL1_B.PECEN = BIT_RESET;
547 }
548
549 /*!
550 * @brief Read the PEC value for the I2C.
551 *
552 * @param i2c: I2C selet 1 or 2
553 *
554 * @retval value of PEC
555 */
I2C_ReadPEC(I2C_T * i2c)556 uint8_t I2C_ReadPEC(I2C_T* i2c)
557 {
558 return i2c->STS2_B.PECVALUE;
559 }
560
561 /*!
562 * @brief Enable the I2C ARP.
563 *
564 * @param i2c: I2C selet 1 or 2
565 *
566 * @retval None
567 */
I2C_EnableARP(I2C_T * i2c)568 void I2C_EnableARP(I2C_T* i2c)
569 {
570 i2c->CTRL1_B.ARPEN = BIT_SET;
571 }
572
573 /*!
574 * @brief Disable the I2C ARP.
575 *
576 * @param i2c: I2C selet 1 or 2
577 *
578 * @retval None
579 */
I2C_DisableARP(I2C_T * i2c)580 void I2C_DisableARP(I2C_T* i2c)
581 {
582 i2c->CTRL1_B.ARPEN = BIT_RESET;
583 }
584
585 /*!
586 * @brief Enable the I2C Clock stretching.
587 *
588 * @param i2c: I2C selet 1 or 2
589 *
590 * @retval None
591 */
I2C_EnableStretchClock(I2C_T * i2c)592 void I2C_EnableStretchClock(I2C_T* i2c)
593 {
594 i2c->CTRL1_B.CLKSTRETCHD = BIT_RESET;
595 }
596
597 /*!
598 * @brief Disable the I2C Clock stretching.
599 *
600 * @param i2c: I2C selet 1 or 2
601 *
602 * @retval None
603 */
I2C_DisableStretchClock(I2C_T * i2c)604 void I2C_DisableStretchClock(I2C_T* i2c)
605 {
606 i2c->CTRL1_B.CLKSTRETCHD = BIT_SET;
607 }
608
609 /*!
610 * @brief Select the specified I2C fast mode duty cycle.
611 *
612 * @param i2c: I2C selet 1 or 2
613 *
614 * @param dutyCycle: the fast mode duty cycle.
615 * The parameter can be one of following values:
616 * @arg I2C_DUTYCYCLE_16_9: I2C fast mode Tlow/Thigh = 16/9
617 * @arg I2C_DUTYCYCLE_2: I2C fast mode Tlow/Thigh = 2
618 *
619 * @retval None
620 */
I2C_ConfigFastModeDutyCycle(I2C_T * i2c,I2C_DUTYCYCLE_T dutyCycle)621 void I2C_ConfigFastModeDutyCycle(I2C_T* i2c, I2C_DUTYCYCLE_T dutyCycle)
622 {
623 if (dutyCycle == I2C_DUTYCYCLE_16_9)
624 {
625 i2c->CLKCTRL_B.FDUTYCFG = BIT_SET;
626 }
627 else
628 {
629 i2c->CLKCTRL_B.FDUTYCFG = BIT_RESET;
630 }
631 }
632
633 /*!
634 * @brief Enable the specified I2C DMA requests.
635 *
636 * @param i2c: I2C selet 1 or 2
637 *
638 * @retval None
639 */
I2C_EnableDMA(I2C_T * i2c)640 void I2C_EnableDMA(I2C_T* i2c)
641 {
642 i2c->CTRL2_B.DMAEN = ENABLE;
643 }
644
645 /*!
646 * @brief Disable the specified I2C DMA requests.
647 *
648 * @param i2c: I2C selet 1 or 2
649 *
650 * @retval None
651 */
I2C_DisableDMA(I2C_T * i2c)652 void I2C_DisableDMA(I2C_T* i2c)
653 {
654 i2c->CTRL2_B.DMAEN = DISABLE;
655 }
656
657 /*!
658 * @brief Enable DMA to receive the last transfer
659 *
660 * @param i2c: I2C selet 1 or 2
661 *
662 * @retval None
663 */
I2C_EnableDMALastTransfer(I2C_T * i2c)664 void I2C_EnableDMALastTransfer(I2C_T* i2c)
665 {
666 i2c->CTRL2_B.LTCFG = BIT_SET;
667 }
668
669 /*!
670 * @brief Disable DMA to receive the last transfer
671 *
672 * @param i2c: I2C selet 1 or 2
673 *
674 * @retval None
675 */
I2C_DisableDMALastTransfer(I2C_T * i2c)676 void I2C_DisableDMALastTransfer(I2C_T* i2c)
677 {
678 i2c->CTRL2_B.LTCFG = BIT_RESET;
679 }
680
681 /*!
682 * @brief Enable the specified I2C interrupts.
683 *
684 * @param i2c: I2C selet 1 or 2
685 *
686 * @param interrupt:I2C interrupts sources
687 * The parameter can be any combination of following values:
688 * @arg I2C_INT_BUF: Buffer interrupt
689 * @arg I2C_INT_EVT: Event interrupt
690 * @arg I2C_INT_ERR: Error interrupt
691 *
692 * @retval None
693 */
I2C_EnableInterrupt(I2C_T * i2c,uint16_t interrupt)694 void I2C_EnableInterrupt(I2C_T* i2c, uint16_t interrupt)
695 {
696 i2c->CTRL2 |= interrupt;
697 }
698
699 /*!
700 * @brief Disable the specified I2C interrupts.
701 *
702 * @param i2c: I2C selet 1 or 2
703 *
704 * @param interrupt:I2C interrupts sources
705 * The parameter can be any combination of following values:
706 * @arg I2C_INT_BUF: Buffer interrupt
707 * @arg I2C_INT_EVT: Event interrupt
708 * @arg I2C_INT_ERR: Error interrupt
709 *
710 * @retval None
711 */
I2C_DisableInterrupt(I2C_T * i2c,uint16_t interrupt)712 void I2C_DisableInterrupt(I2C_T* i2c, uint16_t interrupt)
713 {
714 i2c->CTRL2 &= ~interrupt;
715 }
716
717 /*!
718 * @brief Check that the last event is equal to the last passed event
719 *
720 * @param i2c: I2C selet 1 or 2
721 *
722 * @param i2cEvent: the event to be checked.
723 * The parameter can be one of the following values:
724 * @arg I2C_EVENT_SLAVE_TRANSMITTER_ADDRESS_MATCHED : EV1
725 * @arg I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED : EV1
726 * @arg I2C_EVENT_SLAVE_TRANSMITTER_SECONDADDRESS_MATCHED : EV1
727 * @arg I2C_EVENT_SLAVE_RECEIVER_SECONDADDRESS_MATCHED : EV1
728 * @arg I2C_EVENT_SLAVE_GENERALCALLADDRESS_MATCHED : EV1
729 * @arg I2C_EVENT_SLAVE_BYTE_RECEIVED : EV2
730 * @arg I2C_EVENT_SLAVE_BYTE_TRANSMITTED : EV3
731 * @arg I2C_EVENT_SLAVE_ACK_FAILURE : EV3_2
732 * @arg I2C_EVENT_SLAVE_STOP_DETECTED : EV4
733 * @arg I2C_EVENT_MASTER_MODE_SELECT : EV5
734 * @arg I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED : EV6
735 * @arg I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED : EV6
736 * @arg I2C_EVENT_MASTER_BYTE_RECEIVED : EV7
737 * @arg I2C_EVENT_MASTER_BYTE_TRANSMITTING : EV8
738 * @arg I2C_EVENT_MASTER_BYTE_TRANSMITTED : EV8_2
739 * @arg I2C_EVENT_MASTER_MODE_ADDRESS10 : EV9
740 *
741 * @retval Status: SUCCESS or ERROR
742 */
I2C_ReadEventStatus(I2C_T * i2c,I2C_EVENT_T i2cEvent)743 uint8_t I2C_ReadEventStatus(I2C_T* i2c, I2C_EVENT_T i2cEvent)
744 {
745 uint32_t lastevent = 0;
746 uint32_t flag1 = 0, flag2 = 0;
747
748 flag1 = i2c->STS1 & 0x0000FFFF;
749 flag2 = i2c->STS2 & 0x0000FFFF;
750 flag2 = flag2 << 16;
751
752 lastevent = (flag1 | flag2) & 0x00FFFFFF;
753
754 if ((lastevent & i2cEvent) == i2cEvent)
755 {
756 return SUCCESS;
757 }
758 return ERROR;
759 }
760
761 /*!
762 * @brief Read the last i2c Event.
763 *
764 * @param i2c: I2C selet 1 or 2
765 *
766 * @retval The last event
767 */
I2C_ReadLastEvent(I2C_T * i2c)768 uint32_t I2C_ReadLastEvent(I2C_T* i2c)
769 {
770 uint32_t lastevent = 0;
771 uint32_t flag1 = 0, flag2 = 0;
772
773 flag1 = i2c->STS1 & 0x0000FFFF;
774 flag2 = i2c->STS2 & 0x0000FFFF;
775 flag2 = flag2 << 16;
776
777 lastevent = (flag1 | flag2) & 0x00FFFFFF;
778
779 return lastevent;
780 }
781
782 /*!
783 * @brief Check whether the I2C flag is set
784 *
785 * @param i2c: I2C selet 1 or 2
786 *
787 * @param flag: specify the I2C flag
788 * The parameter can be one of the following values:
789 * @arg I2C_FLAG_DUALADDR: Dual flag (Slave mode)
790 * @arg I2C_FLAG_SMMHADDR: SMBus host header (Slave mode)
791 * @arg I2C_FLAG_SMBDADDR: SMBus default header (Slave mode)
792 * @arg I2C_FLAG_GENCALL: General call header flag (Slave mode)
793 * @arg I2C_FLAG_TR: Transmitter/Receiver flag
794 * @arg I2C_FLAG_BUSBSY: Bus busy flag
795 * @arg I2C_FLAG_MS: Master/Slave flag
796 * @arg I2C_FLAG_SMBALT: SMBus Alert flag
797 * @arg I2C_FLAG_TTE: Timeout or Tlow error flag
798 * @arg I2C_FLAG_PECE: PEC error in reception flag
799 * @arg I2C_FLAG_OVRUR: Overrun/Underrun flag (Slave mode)
800 * @arg I2C_FLAG_AE: Acknowledge error flag
801 * @arg I2C_FLAG_AL: Arbitration lost flag (Master mode)
802 * @arg I2C_FLAG_BERR: Bus error flag
803 * @arg I2C_FLAG_TXBE: Transmitter data register empty flag
804 * @arg I2C_FLAG_RXBNE: Receiver data register not empty flag
805 * @arg I2C_FLAG_STOP: Stop detection flag (Slave mode)
806 * @arg I2C_FLAG_ADDR10: 10-bit header sent flag (Master mode)
807 * @arg I2C_FLAG_BTC: Byte transfer complete flag
808 * @arg I2C_FLAG_ADDR: Address sent flag (Master mode)
809 * @arg I2C_FLAG_START: Start bit flag (Master mode)
810 *
811 * @retval Status: flag SET or RESET
812 */
I2C_ReadStatusFlag(I2C_T * i2c,I2C_FLAG_T flag)813 uint8_t I2C_ReadStatusFlag(I2C_T* i2c, I2C_FLAG_T flag)
814 {
815 uint8_t status = 0;
816 switch (flag)
817 {
818 case I2C_FLAG_DUALADDR:
819 status = i2c->STS2_B.DUALADDRFLG;
820 break;
821 case I2C_FLAG_SMMHADDR:
822 status = i2c->STS2_B.SMMHADDR;
823 break;
824 case I2C_FLAG_SMBDADDR:
825 status = i2c->STS2_B.SMBDADDRFLG;
826 break;
827 case I2C_FLAG_GENCALL:
828 status = i2c->STS2_B.GENCALLFLG;
829 break;
830 case I2C_FLAG_TR:
831 status = i2c->STS2_B.TRFLG;
832 break;
833 case I2C_FLAG_BUSBSY:
834 status = i2c->STS2_B.BUSBSYFLG;
835 break;
836 case I2C_FLAG_MS:
837 status = i2c->STS2_B.MSFLG;
838 break;
839 case I2C_FLAG_SMBALT:
840 status = i2c->STS1_B.SMBALTFLG;
841 break;
842 case I2C_FLAG_TTE:
843 status = i2c->STS1_B.TTEFLG;
844 break;
845 case I2C_FLAG_PECE:
846 status = i2c->STS1_B.PECEFLG;
847 break;
848 case I2C_FLAG_OVRUR:
849 status = i2c->STS1_B.OVRURFLG;
850 break;
851 case I2C_FLAG_AE:
852 status = i2c->STS1_B.AEFLG;
853 break;
854 case I2C_FLAG_AL:
855 status = i2c->STS1_B.ALFLG;
856 break;
857 case I2C_FLAG_BERR:
858 status = i2c->STS1_B.BERRFLG;
859 break;
860 case I2C_FLAG_TXBE:
861 status = i2c->STS1_B.TXBEFLG;
862 break;
863 case I2C_FLAG_RXBNE:
864 status = i2c->STS1_B.RXBNEFLG;
865 break;
866 case I2C_FLAG_STOP:
867 status = i2c->STS1_B.STOPFLG;
868 break;
869 case I2C_FLAG_ADDR10:
870 status = i2c->STS1_B.ADDR10FLG;
871 break;
872 case I2C_FLAG_BTC:
873 status = i2c->STS1_B.BTCFLG;
874 break;
875 case I2C_FLAG_ADDR:
876 status = i2c->STS1_B.ADDRFLG;
877 break;
878 case I2C_FLAG_START:
879 status = i2c->STS1_B.STARTFLG;
880 break;
881 default:
882 break;
883 }
884 return status;
885 }
886
887 /*!
888 * @brief Clear the I2C flag
889 *
890 * @param i2c: I2C selet 1 or 2
891 *
892 * @param flag: specify the I2C flag
893 * The parameter can be one of the following values:
894 * @arg I2C_FLAG_SMBALT: SMBus Alert flag
895 * @arg I2C_FLAG_TTE: Timeout or Tlow error flag
896 * @arg I2C_FLAG_PECE: PEC error in reception flag
897 * @arg I2C_FLAG_OVRUR: Overrun/Underrun flag (Slave mode)
898 * @arg I2C_FLAG_AE: Acknowledge error flag
899 * @arg I2C_FLAG_AL: Arbitration lost flag (Master mode)
900 * @arg I2C_FLAG_BERR: Bus error flag
901 *
902 * @retval None
903 *
904 * @note 1)I2C_FLAG_STOP: Stop detection flag is cleared by software sequence:
905 * a read operation to I2C_STS1 register (I2C_ReadStatusFlag())
906 * followed by a write operation to I2C_CRTL1 register (I2C_Enable()).
907 * 2)I2C_FLAG_ADDR10: 10-bit header sent flag is cleared by software sequence:
908 * a read operation to I2C_STS1 (I2C_ReadStatusFlag())
909 * followed by writing the second byte of the address in I2C_DATA register.
910 * 3)I2C_FLAG_BTC: Byte transfer complete flag is cleared by software sequence:
911 * a read operation to I2C_STS1 register (I2C_ReadStatusFlag())
912 * followed by a read/write to I2C_DATA register (I2C_TxData()).
913 * 4)I2C_FLAG_ADDR: Address sent flag is cleared by software sequence:
914 * a read operation to I2C_STS1 register (I2C_ReadStatusFlag())
915 * followed by a read operation to I2C_STS2 register ((void)(I2Cx->STS2)).
916 * 5)I2C_FLAG_START: Start bit flag is cleared software sequence:
917 * a read operation to I2C_STS1 register (I2C_ReadStatusFlag())
918 * followed by a write operation to I2C_DATA register (I2C_TxData()).
919 */
I2C_ClearStatusFlag(I2C_T * i2c,I2C_FLAG_T flag)920 void I2C_ClearStatusFlag(I2C_T* i2c, I2C_FLAG_T flag)
921 {
922 switch (flag)
923 {
924 case I2C_FLAG_SMBALT:
925 i2c->STS1_B.SMBALTFLG = BIT_RESET;
926 break;
927 case I2C_FLAG_TTE:
928 i2c->STS1_B.TTEFLG = BIT_RESET;
929 break;
930 case I2C_FLAG_PECE:
931 i2c->STS1_B.PECEFLG = BIT_RESET;
932 break;
933 case I2C_FLAG_OVRUR:
934 i2c->STS1_B.OVRURFLG = BIT_RESET;
935 break;
936 case I2C_FLAG_AE:
937 i2c->STS1_B.AEFLG = BIT_RESET;
938 break;
939 case I2C_FLAG_AL:
940 i2c->STS1_B.ALFLG = BIT_RESET;
941 break;
942 case I2C_FLAG_BERR:
943 i2c->STS1_B.BERRFLG = BIT_RESET;
944 break;
945 default:
946 break;
947 }
948 }
949
950 /*!
951 * @brief Check whether the I2C interrupts is set
952 *
953 * @param i2c: I2C selet 1 or 2
954 *
955 * @param flag: specify the I2C interrupts
956 * The parameter can be one of the following values:
957 * @arg I2C_INT_FLAG_SMBALT: SMBus Alert flag
958 * @arg I2C_INT_FLAG_TTE: Timeout or Tlow error flag
959 * @arg I2C_INT_FLAG_PECE: PEC error in reception flag
960 * @arg I2C_INT_FLAG_OVRUR: Overrun/Underrun flag (Slave mode)
961 * @arg I2C_INT_FLAG_AE: Acknowledge error flag
962 * @arg I2C_INT_FLAG_AL: Arbitration lost flag (Master mode)
963 * @arg I2C_INT_FLAG_BERR: Bus error flag
964 * @arg I2C_INT_FLAG_TXBE: Transmitter data register empty flag
965 * @arg I2C_INT_FLAG_RXBNE: Receiver data register not empty flag
966 * @arg I2C_INT_FLAG_STOP: Stop detection flag (Slave mode)
967 * @arg I2C_INT_FLAG_ADDR10: 10-bit header sent flag (Master mode)
968 * @arg I2C_INT_FLAG_BTC: Byte transfer complete flag
969 * @arg I2C_INT_FLAG_ADDR: Address sent flag (Master mode)
970 * @arg I2C_INT_FLAG_START: Start bit flag (Master mode)
971 *
972 * @retval Status: flag SET or RESET
973 */
I2C_ReadIntFlag(I2C_T * i2c,I2C_INT_FLAG_T flag)974 uint8_t I2C_ReadIntFlag(I2C_T* i2c, I2C_INT_FLAG_T flag)
975 {
976 uint32_t enablestatus = 0;
977
978 enablestatus = ((flag & 0x07000000) >> 16) & (i2c->CTRL2);
979 flag &= 0x00FFFFFF;
980 if (((i2c->STS1 & flag) != RESET) && enablestatus)
981 {
982 return SET;
983 }
984 return RESET;
985 }
986
987 /*!
988 * @brief Clears the I2C interrupt flag bits.
989 *
990 * @param i2c: I2C selet 1 or 2
991 *
992 * @param flag: specify the I2C flag
993 * The parameter can be any combination of the following values:
994 * @arg I2C_INT_FLAG_SMBALT: SMBus Alert flag
995 * @arg I2C_INT_FLAG_TTE: Timeout or Tlow error flag
996 * @arg I2C_INT_FLAG_PECE: PEC error in reception flag
997 * @arg I2C_INT_FLAG_OVRUR: Overrun/Underrun flag (Slave mode)
998 * @arg I2C_INT_FLAG_AE: Acknowledge error flag
999 * @arg I2C_INT_FLAG_AL: Arbitration lost flag (Master mode)
1000 * @arg I2C_INT_FLAG_BERR: Bus error flag
1001 *
1002 * @retval None
1003 *
1004 * @note 1)I2C_INT_FLAG_STOP: Stop detection flag is cleared by software sequence:
1005 * a read operation to I2C_STS1 register (I2C_ReadIntFlag())
1006 * followed by a write operation to I2C_CRTL1 register (I2C_Enable()).
1007 * 2)I2C_INT_FLAG_ADDR10: 10-bit header sent flag is cleared by software sequence:
1008 * a read operation to I2C_STS1 (I2C_ReadIntFlag())
1009 * followed by writing the second byte of the address in I2C_DATA register.
1010 * 3)I2C_INT_FLAG_BTC: Byte transfer complete flag is cleared by software sequence:
1011 * a read operation to I2C_STS1 register (I2C_ReadIntFlag())
1012 * followed by a read/write to I2C_DATA register (I2C_TxData()).
1013 * 4)I2C_INT_FLAG_ADDR: Address sent flag is cleared by software sequence:
1014 * a read operation to I2C_STS1 register (I2C_ReadIntFlag())
1015 * followed by a read operation to I2C_STS2 register ((void)(I2Cx->STS2)).
1016 * 5)I2C_INT_FLAG_START: Start bit flag is cleared software sequence:
1017 * a read operation to I2C_STS1 register (I2C_ReadIntFlag())
1018 * followed by a write operation to I2C_DATA register (I2C_TxData()).
1019 */
I2C_ClearIntFlag(I2C_T * i2c,uint32_t flag)1020 void I2C_ClearIntFlag(I2C_T* i2c, uint32_t flag)
1021 {
1022 i2c->STS1 = (uint16_t)~(flag & 0x00FFFFFF);
1023 }
1024
1025 /**@} end of group I2C_Functions */
1026 /**@} end of group I2C_Driver */
1027 /**@} end of group APM32S10x_StdPeriphDriver */
1028