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