1 /*!
2  * @file       apm32e10x_i2c.c
3  *
4  * @brief      This file provides all the I2C firmware functions
5  *
6  * @version     V1.0.2
7  *
8  * @date        2022-12-31
9  *
10  * @attention
11  *
12  *  Copyright (C) 2021-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 useful 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 "apm32e10x_i2c.h"
27 #include "apm32e10x_rcm.h"
28 
29 /** @addtogroup APM32E10x_StdPeriphDriver
30   @{
31 */
32 
33 /** @addtogroup I2C_Driver
34   * @brief I2C driver modules
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->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     Fills each I2C_InitStruct 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     Enables 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     Disables 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     Config 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     Enables 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     Disables 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     Enables 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     Disables 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     Returns 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     Transmits 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->I2C_SWITCH;
403     default:
404         return 0;
405     }
406 }
407 
408 /*!
409  * @brief     Enables 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     Disables 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     Selects 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  * @retval    None
463  */
I2C_ConfigSMBusAlert(I2C_T * i2c,I2C_SMBUSALER_T SMBusState)464 void I2C_ConfigSMBusAlert(I2C_T* i2c, I2C_SMBUSALER_T SMBusState)
465 {
466     if(SMBusState == I2C_SMBUSALER_LOW)
467     {
468         i2c->CTRL1_B.ALERTEN = BIT_SET;
469     }
470     else
471     {
472         i2c->CTRL1_B.ALERTEN = BIT_RESET;
473     }
474 }
475 
476 /*!
477  * @brief     Enables the I2C PEC transfer.
478  *
479  * @param     i2c: I2C selet 1 or 2
480  *
481  * @retval    None
482  */
I2C_EnablePECTransmit(I2C_T * i2c)483 void I2C_EnablePECTransmit(I2C_T* i2c)
484 {
485     i2c->CTRL1_B.PEC = BIT_SET;
486 }
487 
488 /*!
489  * @brief     Disables the I2C PEC transfer.
490  *
491  * @param     i2c: I2C selet 1 or 2
492  *
493  * @retval    None
494  */
I2C_DisablePECTransmit(I2C_T * i2c)495 void I2C_DisablePECTransmit(I2C_T* i2c)
496 {
497     i2c->CTRL1_B.PEC = BIT_RESET;
498 }
499 
500 /*!
501  * @brief     Selects the I2C PEC position.
502  *
503  * @param     i2c: I2C selet 1 or 2
504   *
505  * @param     PECPosition: PEC position
506  *              The parameter can be one of following values:
507  *              @arg I2C_PEC_POSITION_NEXT: indicates that the next byte is PEC
508  *              @arg I2C_PEC_POSITION_CURRENT: indicates that current byte is PEC
509  * @retval    None
510  */
I2C_ConfigPECPosition(I2C_T * i2c,I2C_PEC_POSITION_T PECPosition)511 void I2C_ConfigPECPosition(I2C_T* i2c, I2C_PEC_POSITION_T PECPosition)
512 {
513     if(PECPosition == I2C_PEC_POSITION_NEXT)
514     {
515         i2c->CTRL1_B.ACKPOS = BIT_SET;
516     }
517     else
518     {
519         i2c->CTRL1_B.ACKPOS = BIT_RESET;
520     }
521 }
522 
523 /*!
524  * @brief     Enables the PEC value calculation of the transferred bytes.
525  *
526  * @param     i2c: I2C selet 1 or 2
527  *
528  * @retval    None
529  */
I2C_EnablePEC(I2C_T * i2c)530 void I2C_EnablePEC(I2C_T* i2c)
531 {
532     i2c->CTRL1_B.PECEN = BIT_SET;
533 }
534 
535 /*!
536  * @brief     Disables the PEC value calculation of the transferred bytes.
537  *
538  * @param     i2c: I2C selet 1 or 2
539  *
540  * @retval    None
541  */
I2C_DisablePEC(I2C_T * i2c)542 void I2C_DisablePEC(I2C_T* i2c)
543 {
544     i2c->CTRL1_B.PECEN = BIT_RESET;
545 }
546 
547 /*!
548  * @brief     Read the PEC value for the I2C.
549  *
550  * @param     i2c: I2C selet 1 or 2
551  *
552  * @retval    value of PEC
553  */
I2C_ReadPEC(I2C_T * i2c)554 uint8_t I2C_ReadPEC(I2C_T* i2c)
555 {
556     return i2c->STS2_B.PECVALUE;
557 }
558 
559 /*!
560  * @brief     Enables the I2C ARP.
561  *
562  * @param     i2c: I2C selet 1 or 2
563  *
564  * @retval    None
565  */
I2C_EnableARP(I2C_T * i2c)566 void I2C_EnableARP(I2C_T* i2c)
567 {
568     i2c->CTRL1_B.ARPEN = BIT_SET;
569 }
570 
571 /*!
572 * @brief      Disables the I2C ARP.
573 *
574 * @param      i2c: I2C selet 1 or 2
575 *
576 * @retval     None
577 */
I2C_DisableARP(I2C_T * i2c)578 void I2C_DisableARP(I2C_T* i2c)
579 {
580     i2c->CTRL1_B.ARPEN = BIT_RESET;
581 }
582 
583 /*!
584  * @brief     Enables the I2C Clock stretching.
585  *
586  * @param     i2c: I2C selet 1 or 2
587  *
588  * @retval    None
589  */
I2C_EnableStretchClock(I2C_T * i2c)590 void I2C_EnableStretchClock(I2C_T* i2c)
591 {
592     i2c->CTRL1_B.CLKSTRETCHD = BIT_RESET;
593 }
594 
595 /*!
596  * @brief     Disables the I2C Clock stretching.
597  *
598  * @param     i2c: I2C selet 1 or 2
599  *
600  * @retval    None
601  */
I2C_DisableStretchClock(I2C_T * i2c)602 void I2C_DisableStretchClock(I2C_T* i2c)
603 {
604     i2c->CTRL1_B.CLKSTRETCHD = BIT_SET;
605 }
606 
607 /*!
608  * @brief     Selects the specified I2C fast mode duty cycle.
609  *
610  * @param     i2c: I2C selet 1 or 2
611  *
612  * @param     dutyCycle: the fast mode duty cycle.
613  *              The parameter can be one of following values:
614  *              @arg I2C_DUTYCYCLE_16_9: I2C fast mode Tlow/Thigh = 16/9
615  *              @arg I2C_DUTYCYCLE_2: I2C fast mode Tlow/Thigh = 2
616  * @retval    None
617  */
I2C_ConfigFastModeDutyCycle(I2C_T * i2c,I2C_DUTYCYCLE_T dutyCycle)618 void I2C_ConfigFastModeDutyCycle(I2C_T* i2c, I2C_DUTYCYCLE_T dutyCycle)
619 {
620     if(dutyCycle == I2C_DUTYCYCLE_16_9)
621     {
622         i2c->CLKCTRL_B.FDUTYCFG = BIT_SET;
623     }
624     else
625     {
626         i2c->CLKCTRL_B.FDUTYCFG = BIT_RESET;
627     }
628 }
629 
630 /*!
631  * @brief     Enables the specified I2C DMA requests.
632  *
633  * @param     i2c: I2C selet 1 or 2
634  *
635  * @retval    None
636  */
I2C_EnableDMA(I2C_T * i2c)637 void I2C_EnableDMA(I2C_T* i2c)
638 {
639     i2c->CTRL2_B.DMAEN = ENABLE;
640 }
641 
642 /*!
643  * @brief     Disable the specified I2C DMA requests.
644  *
645  * @param     i2c: I2C selet 1 or 2
646  *
647  * @retval    None
648  */
I2C_DisableDMA(I2C_T * i2c)649 void I2C_DisableDMA(I2C_T* i2c)
650 {
651     i2c->CTRL2_B.DMAEN = DISABLE;
652 }
653 
654 /*!
655  * @brief     Enable DMA to receive the last transfer
656  *
657  * @param     i2c: I2C selet 1 or 2
658  *
659  * @retval    None
660  */
I2C_EnableDMALastTransfer(I2C_T * i2c)661 void I2C_EnableDMALastTransfer(I2C_T* i2c)
662 {
663     i2c->CTRL2_B.LTCFG = BIT_SET;
664 }
665 
666 /*!
667  * @brief     Disable DMA to receive the last transfer
668  *
669  * @param     i2c: I2C selet 1 or 2
670  *
671  * @retval    None
672  */
I2C_DisableDMALastTransfer(I2C_T * i2c)673 void I2C_DisableDMALastTransfer(I2C_T* i2c)
674 {
675     i2c->CTRL2_B.LTCFG = BIT_RESET;
676 }
677 
678 /*!
679  * @brief     Enables the specified I2C interrupts.
680  *
681  * @param     i2c: I2C selet 1 or 2
682  *
683  * @param     interrupt:I2C interrupts sources
684  *              The parameter can be any combination of following values:
685  *              @arg I2C_INT_BUF: Buffer interrupt
686  *              @arg I2C_INT_EVT: Event interrupt
687  *              @arg I2C_INT_ERR: Error interrupt
688  *
689  * @retval    None
690  */
I2C_EnableInterrupt(I2C_T * i2c,uint16_t interrupt)691 void I2C_EnableInterrupt(I2C_T* i2c, uint16_t interrupt)
692 {
693     i2c->CTRL2 |= interrupt;
694 }
695 
696 /*!
697  * @brief     Disable the specified I2C interrupts.
698  *
699  * @param     i2c: I2C selet 1 or 2
700  *
701  * @param     interrupt:I2C interrupts sources
702  *              The parameter can be any combination of following values:
703  *              @arg I2C_INT_BUF: Buffer interrupt
704  *              @arg I2C_INT_EVT: Event interrupt
705  *              @arg I2C_INT_ERR: Error interrupt
706  *
707  * @retval    None
708  */
I2C_DisableInterrupt(I2C_T * i2c,uint16_t interrupt)709 void I2C_DisableInterrupt(I2C_T* i2c, uint16_t interrupt)
710 {
711     i2c->CTRL2 &= ~interrupt;
712 }
713 
714 /*!
715  * @brief     Check that the last event is equal to the last passed event
716  *
717  * @param     i2c: I2C selet 1 or 2
718  *
719  * @param     i2cEvent: the event to be checked.
720  *              The parameter can be one of the following values:
721  *              @arg I2C_EVENT_SLAVE_TRANSMITTER_ADDRESS_MATCHED           : EV1
722  *              @arg I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED              : EV1
723  *              @arg I2C_EVENT_SLAVE_TRANSMITTER_SECONDADDRESS_MATCHED     : EV1
724  *              @arg I2C_EVENT_SLAVE_RECEIVER_SECONDADDRESS_MATCHED        : EV1
725  *              @arg I2C_EVENT_SLAVE_GENERALCALLADDRESS_MATCHED            : EV1
726  *              @arg I2C_EVENT_SLAVE_BYTE_RECEIVED                         : EV2
727  *              @arg I2C_EVENT_SLAVE_BYTE_TRANSMITTED                      : EV3
728  *              @arg I2C_EVENT_SLAVE_ACK_FAILURE                           : EV3_2
729  *              @arg I2C_EVENT_SLAVE_STOP_DETECTED                         : EV4
730  *              @arg I2C_EVENT_MASTER_MODE_SELECT                          : EV5
731  *              @arg I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED            : EV6
732  *              @arg I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED               : EV6
733  *              @arg I2C_EVENT_MASTER_BYTE_RECEIVED                        : EV7
734  *              @arg I2C_EVENT_MASTER_BYTE_TRANSMITTING                    : EV8
735  *              @arg I2C_EVENT_MASTER_BYTE_TRANSMITTED                     : EV8_2
736  *              @arg I2C_EVENT_MASTER_MODE_ADDRESS10                       : EV9
737  *
738  * @retval    Status: SUCCESS or ERROR
739  */
I2C_ReadEventStatus(I2C_T * i2c,I2C_EVENT_T i2cEvent)740 uint8_t  I2C_ReadEventStatus(I2C_T* i2c, I2C_EVENT_T i2cEvent)
741 {
742     uint32_t lastevent = 0;
743     uint32_t flag1 = 0, flag2 = 0;
744 
745     flag1 = i2c->STS1 & 0x0000FFFF;
746     flag2 = i2c->STS2 & 0x0000FFFF;
747     flag2 = flag2 << 16;
748 
749     lastevent = (flag1 | flag2) & 0x00FFFFFF;
750 
751     if((lastevent & i2cEvent) == i2cEvent)
752     {
753         return SUCCESS;
754     }
755     return ERROR;
756 }
757 
758 /*!
759  * @brief     Read the last i2c Event.
760  *
761  * @param     i2c: I2C selet 1 or 2
762  *
763  * @retval    The last event
764  */
I2C_ReadLastEvent(I2C_T * i2c)765 uint32_t I2C_ReadLastEvent(I2C_T* i2c)
766 {
767     uint32_t lastevent = 0;
768     uint32_t flag1 = 0, flag2 = 0;
769 
770     flag1 = i2c->STS1 & 0x0000FFFF;
771     flag2 = i2c->STS2 & 0x0000FFFF;
772     flag2 = flag2 << 16;
773 
774     lastevent = (flag1 | flag2) & 0x00FFFFFF;
775 
776     return lastevent;
777 }
778 
779 /*!
780  * @brief     Check whether the I2C flag is set
781  *
782  * @param     i2c: I2C selet 1 or 2
783  *
784  * @param     flag: specifies the I2C flag
785  *              The parameter can be one of the following values:
786  *              @arg I2C_FLAG_DUALADDR: Dual flag (Slave mode)
787  *              @arg I2C_FLAG_SMMHADDR: SMBus host header (Slave mode)
788  *              @arg I2C_FLAG_SMBDADDR: SMBus default header (Slave mode)
789  *              @arg I2C_FLAG_GENCALL:  General call header flag (Slave mode)
790  *              @arg I2C_FLAG_TR:       Transmitter/Receiver flag
791  *              @arg I2C_FLAG_BUSBSY:   Bus busy flag
792  *              @arg I2C_FLAG_MS:       Master/Slave flag
793  *              @arg I2C_FLAG_SMBALT:   SMBus Alert flag
794  *              @arg I2C_FLAG_TTE:      Timeout or Tlow error flag
795  *              @arg I2C_FLAG_PECE:     PEC error in reception flag
796  *              @arg I2C_FLAG_OVRUR:    Overrun/Underrun flag (Slave mode)
797  *              @arg I2C_FLAG_AE:       Acknowledge error flag
798  *              @arg I2C_FLAG_AL:       Arbitration lost flag (Master mode)
799  *              @arg I2C_FLAG_BERR:     Bus error flag
800  *              @arg I2C_FLAG_TXBE:     Transmitter data register empty flag
801  *              @arg I2C_FLAG_RXBNE:    Receiver data register not empty flag
802  *              @arg I2C_FLAG_STOP:     Stop detection flag (Slave mode)
803  *              @arg I2C_FLAG_ADDR10:   10-bit header sent flag (Master mode)
804  *              @arg I2C_FLAG_BTC:      Byte transfer complete flag
805  *              @arg I2C_FLAG_ADDR:     Address sent flag (Master mode)
806  *              @arg I2C_FLAG_START:    Start bit flag (Master mode)
807  *
808  * @retval    Status: flag SET or RESET
809  */
I2C_ReadStatusFlag(I2C_T * i2c,I2C_FLAG_T flag)810 uint8_t I2C_ReadStatusFlag(I2C_T* i2c, I2C_FLAG_T flag)
811 {
812 
813     uint8_t status = 0;
814     switch (flag)
815     {
816     case I2C_FLAG_DUALADDR:
817         status = i2c->STS2_B.DUALADDRFLG;
818         break;
819     case I2C_FLAG_SMMHADDR:
820         status = i2c->STS2_B.SMMHADDR;
821         break;
822     case I2C_FLAG_SMBDADDR:
823         status = i2c->STS2_B.SMBDADDRFLG;
824         break;
825     case I2C_FLAG_GENCALL:
826         status = i2c->STS2_B.GENCALLFLG;
827         break;
828     case I2C_FLAG_TR:
829         status = i2c->STS2_B.TRFLG;
830         break;
831     case I2C_FLAG_BUSBSY:
832         status = i2c->STS2_B.BUSBSYFLG;
833         break;
834     case I2C_FLAG_MS:
835         status = i2c->STS2_B.MSFLG;
836         break;
837     case I2C_FLAG_SMBALT:
838         status = i2c->STS1_B.SMBALTFLG;
839         break;
840     case I2C_FLAG_TTE:
841         status = i2c->STS1_B.TTEFLG;
842         break;
843     case I2C_FLAG_PECE:
844         status = i2c->STS1_B.PECEFLG;
845         break;
846     case  I2C_FLAG_OVRUR:
847         status = i2c->STS1_B.OVRURFLG;
848         break;
849     case I2C_FLAG_AE:
850         status = i2c->STS1_B.AEFLG;
851         break;
852     case I2C_FLAG_AL:
853         status = i2c->STS1_B.ALFLG;
854         break;
855     case I2C_FLAG_BERR:
856         status = i2c->STS1_B.BERRFLG;
857         break;
858     case I2C_FLAG_TXBE:
859         status = i2c->STS1_B.TXBEFLG;
860         break;
861     case I2C_FLAG_RXBNE:
862         status = i2c->STS1_B.RXBNEFLG;
863         break;
864     case I2C_FLAG_STOP:
865         status = i2c->STS1_B.STOPFLG;
866         break;
867     case I2C_FLAG_ADDR10:
868         status = i2c->STS1_B.ADDR10FLG;
869         break;
870     case I2C_FLAG_BTC:
871         status = i2c->STS1_B.BTCFLG;
872         break;
873     case I2C_FLAG_ADDR:
874         status = i2c->STS1_B.ADDRFLG;
875         break;
876     case I2C_FLAG_START:
877         status = i2c->STS1_B.STARTFLG;
878         break;
879     default:
880         break;
881     }
882     return status;
883 }
884 
885 /*!
886  * @brief     Clear the I2C flag
887  *
888  * @param     i2c: I2C selet 1 or 2
889  *
890  * @param     flag: specifies the I2C flag
891  *              The parameter can be one of the following values:
892  *              @arg I2C_FLAG_SMBALT:   SMBus Alert flag
893  *              @arg I2C_FLAG_TTE:      Timeout or Tlow error flag
894  *              @arg I2C_FLAG_PECE:     PEC error in reception flag
895  *              @arg I2C_FLAG_OVRUR:    Overrun/Underrun flag (Slave mode)
896  *              @arg I2C_FLAG_AE:       Acknowledge error flag
897  *              @arg I2C_FLAG_AL:       Arbitration lost flag (Master mode)
898  *              @arg I2C_FLAG_BERR:     Bus error flag
899  *
900  * @retval    None
901  *
902  * @note      1)I2C_FLAG_STOP: Stop detection flag is cleared by software sequence:
903  *              a read operation to I2C_STS1 register (I2C_ReadStatusFlag())
904  *              followed by a write operation to I2C_CRTL1 register (I2C_Enable()).
905  *            2)I2C_FLAG_ADDR10: 10-bit header sent flag is cleared by software sequence:
906  *              a read operation to I2C_STS1 (I2C_ReadStatusFlag())
907  *              followed by writing the second byte of the address in I2C_DATA register.
908  *            3)I2C_FLAG_BTC: Byte transfer complete flag is cleared by software sequence:
909  *              a read operation to I2C_STS1 register (I2C_ReadStatusFlag())
910  *              followed by a read/write to I2C_DATA register (I2C_TxData()).
911  *            4)I2C_FLAG_ADDR: Address sent flag is cleared by software sequence:
912  *              a read operation to I2C_STS1 register (I2C_ReadStatusFlag())
913  *              followed by a read operation to I2C_STS2 register ((void)(I2Cx->STS2)).
914  *            5)I2C_FLAG_START: Start bit flag is cleared software sequence:
915  *              a read operation to I2C_STS1 register (I2C_ReadStatusFlag())
916  *              followed by a write operation to I2C_DATA register (I2C_TxData()).
917  */
I2C_ClearStatusFlag(I2C_T * i2c,I2C_FLAG_T flag)918 void I2C_ClearStatusFlag(I2C_T* i2c, I2C_FLAG_T flag)
919 {
920     switch (flag)
921     {
922     case I2C_FLAG_SMBALT:
923         i2c->STS1_B.SMBALTFLG = BIT_RESET;
924         break;
925     case I2C_FLAG_TTE:
926         i2c->STS1_B.TTEFLG = BIT_RESET;
927         break;
928     case I2C_FLAG_PECE:
929         i2c->STS1_B.PECEFLG = BIT_RESET;
930         break;
931     case  I2C_FLAG_OVRUR:
932         i2c->STS1_B.OVRURFLG = BIT_RESET;
933         break;
934     case I2C_FLAG_AE:
935         i2c->STS1_B.AEFLG = BIT_RESET;
936         break;
937     case I2C_FLAG_AL:
938         i2c->STS1_B.ALFLG = BIT_RESET;
939         break;
940     case I2C_FLAG_BERR:
941         i2c->STS1_B.BERRFLG = BIT_RESET;
942         break;
943     default:
944         break;
945     }
946 }
947 
948 /*!
949  * @brief     Check whether the I2C interrupts is set
950  *
951  * @param     i2c: I2C selet 1 or 2
952  *
953  * @param     flag: specifies the I2C interrupts
954  *              The parameter can be one of the following values:
955  *              @arg I2C_INT_FLAG_SMBALT:   SMBus Alert flag
956  *              @arg I2C_INT_FLAG_TTE:      Timeout or Tlow error flag
957  *              @arg I2C_INT_FLAG_PECE:     PEC error in reception flag
958  *              @arg I2C_INT_FLAG_OVRUR:    Overrun/Underrun flag (Slave mode)
959  *              @arg I2C_INT_FLAG_AE:       Acknowledge error flag
960  *              @arg I2C_INT_FLAG_AL:       Arbitration lost flag (Master mode)
961  *              @arg I2C_INT_FLAG_BERR:     Bus error flag
962  *              @arg I2C_INT_FLAG_TXBE:     Transmitter data register empty flag
963  *              @arg I2C_INT_FLAG_RXBNE:    Receiver data register not empty flag
964  *              @arg I2C_INT_FLAG_STOP:     Stop detection flag (Slave mode)
965  *              @arg I2C_INT_FLAG_ADDR10:   10-bit header sent flag (Master mode)
966  *              @arg I2C_INT_FLAG_BTC:      Byte transfer complete flag
967  *              @arg I2C_INT_FLAG_ADDR:     Address sent flag (Master mode)
968  *              @arg I2C_INT_FLAG_START:    Start bit flag (Master mode)
969  *
970  * @retval    Status: flag SET or RESET
971  */
I2C_ReadIntFlag(I2C_T * i2c,I2C_INT_FLAG_T flag)972 uint8_t I2C_ReadIntFlag(I2C_T* i2c, I2C_INT_FLAG_T flag)
973 {
974     uint32_t enablestatus = 0;
975 
976     enablestatus = ((flag & 0x07000000) >> 16) & (i2c->CTRL2);
977     flag &= 0x00FFFFFF;
978     if(((i2c->STS1 & flag) != RESET) && enablestatus)
979     {
980         return SET;
981     }
982     return RESET;
983 }
984 
985 /*!
986  * @brief     Clears the I2C interrupt flag bits.
987  *
988  * @param     i2c: I2C selet 1 or 2
989  *
990  * @param     flag: specifies the I2C flag
991  *              The parameter can be one of the following values:
992  *              @arg I2C_INT_FLAG_SMBALT:   SMBus Alert flag
993  *              @arg I2C_INT_FLAG_TTE:      Timeout or Tlow error flag
994  *              @arg I2C_INT_FLAG_PECE:     PEC error in reception flag
995  *              @arg I2C_INT_FLAG_OVRUR:    Overrun/Underrun flag (Slave mode)
996  *              @arg I2C_INT_FLAG_AE:       Acknowledge error flag
997  *              @arg I2C_INT_FLAG_AL:       Arbitration lost flag (Master mode)
998  *              @arg I2C_INT_FLAG_BERR:     Bus error flag
999  *
1000  * @retval    None
1001  *
1002  * @note      1)I2C_INT_FLAG_STOP: Stop detection flag is cleared by software sequence:
1003  *              a read operation to I2C_STS1 register (I2C_ReadIntFlag())
1004  *              followed by a write operation to I2C_CRTL1 register (I2C_Enable()).
1005  *            2)I2C_INT_FLAG_ADDR10: 10-bit header sent flag is cleared by software sequence:
1006  *              a read operation to I2C_STS1 (I2C_ReadIntFlag())
1007  *              followed by writing the second byte of the address in I2C_DATA register.
1008  *            3)I2C_INT_FLAG_BTC: Byte transfer complete flag is cleared by software sequence:
1009  *              a read operation to I2C_STS1 register (I2C_ReadIntFlag())
1010  *              followed by a read/write to I2C_DATA register (I2C_TxData()).
1011  *            4)I2C_INT_FLAG_ADDR: Address sent flag is cleared by software sequence:
1012  *              a read operation to I2C_STS1 register (I2C_ReadIntFlag())
1013  *              followed by a read operation to I2C_STS2 register ((void)(I2Cx->STS2)).
1014  *            5)I2C_INT_FLAG_START: Start bit flag is cleared software sequence:
1015  *              a read operation to I2C_STS1 register (I2C_ReadIntFlag())
1016  *              followed by a write operation to I2C_DATA register (I2C_TxData()).
1017  */
I2C_ClearIntFlag(I2C_T * i2c,uint32_t flag)1018 void I2C_ClearIntFlag(I2C_T* i2c, uint32_t flag)
1019 {
1020     i2c->STS1 = (uint16_t)~(flag & 0x00FFFFFF);
1021 
1022 }
1023 
1024 /**@} end of group I2C_Functions */
1025 /**@} end of group I2C_Driver */
1026 /**@} end of group APM32E10x_StdPeriphDriver */
1027