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