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