1 /*!
2  * @file        apm32f0xx_i2c.c
3  *
4  * @brief       This file contains all the functions for the I2C peripheral
5  *
6  * @version     V1.0.3
7  *
8  * @date        2022-09-20
9  *
10  * @attention
11  *
12  *  Copyright (C) 2020-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 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 /* Includes */
27 #include "apm32f0xx_i2c.h"
28 #include "apm32f0xx_rcm.h"
29 
30 /** @addtogroup APM32F0xx_StdPeriphDriver
31   @{
32 */
33 
34 /** @addtogroup I2C_Driver
35   @{
36 */
37 
38 /** @defgroup I2C_Macros Macros
39   @{
40   */
41 
42 /**@} end of group I2C_Macros */
43 
44 /** @defgroup I2C_Enumerates Enumerates
45   @{
46   */
47 
48 /**@} end of group I2C_Enumerates */
49 
50 /** @defgroup I2C_Structures Structures
51   @{
52   */
53 
54 /**@} end of group I2C_Structures */
55 
56 /** @defgroup I2C_Variables Variables
57   @{
58   */
59 
60 /**@} end of group I2C_Variables */
61 
62 /** @defgroup I2C_Functions Functions
63   @{
64   */
65 
66 /*!
67  * @brief     Set the I2C peripheral registers to their default reset values
68  *
69  * @param     i2c: Select I2C peripheral,it can be I2C1/I2C2.
70  *
71  * @retval    None
72  */
I2C_Reset(I2C_T * i2c)73 void I2C_Reset(I2C_T* i2c)
74 {
75     if (i2c == I2C1)
76     {
77         RCM_EnableAPB1PeriphReset(RCM_APB1_PERIPH_I2C1);
78         RCM_DisableAPB1PeriphReset(RCM_APB1_PERIPH_I2C1);
79     }
80     else
81     {
82         RCM_EnableAPB1PeriphReset(RCM_APB1_PERIPH_I2C2);
83         RCM_DisableAPB1PeriphReset(RCM_APB1_PERIPH_I2C2);
84     }
85 }
86 
87 /*!
88  * @brief       Config the I2C peripheral according to the specified parameters in the adcConfig
89  *
90  * @param       i2c: Select I2C peripheral,it can be I2C1/I2C2.
91  *
92  * @param       adcConfig:  Pointer to a I2C_Config_T structure that
93  *                          contains the configuration information for the I2C peripheral
94  *
95  * @retval      None
96  */
I2C_Config(I2C_T * i2c,I2C_Config_T * i2cConfig)97 void I2C_Config(I2C_T* i2c, I2C_Config_T* i2cConfig)
98 {
99     uint32_t temp = 0;
100 
101     /* Disable I2C */
102     i2c->CTRL1_B.I2CEN = BIT_RESET;
103 
104     /* FILTERS Configuration */
105     temp = i2c->CTRL1;
106     temp &= ((uint32_t)0x00CFE0FF);
107     i2c->CTRL1_B.DNFCFG = i2cConfig->digitalfilter;
108     i2c->CTRL1_B.ANFD = i2cConfig->analogfilter;
109 
110     /* TIMING Configuration */
111     i2c->TIMING = i2cConfig-> timing & ((uint32_t)0xF0FFFFFF);
112 
113     /* Enable I2C */
114     i2c->CTRL1_B.I2CEN = BIT_SET;
115 
116     /* ADDR1 Configuration */
117     temp = 0;
118     i2c->ADDR1 = 0;
119     i2c->ADDR2 = 0;
120 
121     temp = (uint32_t)((uint32_t)i2cConfig->ackaddress << 10 | \
122                       (uint32_t)i2cConfig->address1);
123 
124     /* Write to I2C ADDR1 */
125     i2c->ADDR1 = temp;
126 
127     /* Enable Own Address1 acknowledgement */
128     i2c->ADDR1_B.ADDR1EN  = BIT_SET;
129 
130     /* Mode Configuration */
131     i2c->CTRL1 &= 0xFFCFFFF;
132     temp = i2cConfig->mode;
133     i2c->CTRL1 |= temp;
134 
135     /* Ack Configuration */
136     i2c->CTRL2_B.NACKEN = i2cConfig->ack;
137 }
138 
139 /*!
140  * @brief       Fills each i2cConfig member with its default value
141  *
142  * @param       i2cConfig:    Pointer to a I2C_Config_T structure which will be initialized
143  *
144  * @retval      None
145  */
I2C_ConfigStructInit(I2C_Config_T * i2cConfig)146 void I2C_ConfigStructInit(I2C_Config_T* i2cConfig)
147 {
148     i2cConfig->timing   = 0;
149     i2cConfig->address1 = 0;
150     i2cConfig->mode     = I2C_MODE_I2C;
151     i2cConfig->analogfilter  = I2C_ANALOG_FILTER_ENABLE;
152     i2cConfig->digitalfilter = I2C_DIGITAL_FILTER_0;
153 
154     i2cConfig->ack = I2C_ACK_DISABLE;
155     i2cConfig->ackaddress = I2C_ACK_ADDRESS_7BIT;
156 }
157 
158 /*!
159  * @brief       Enable the I2C peripheral
160  *
161  * @param       i2c: Select I2C peripheral,it can be I2C1/I2C2.
162  *
163  * @retval      None
164  */
I2C_Enable(I2C_T * i2c)165 void I2C_Enable(I2C_T* i2c)
166 {
167     i2c->CTRL1_B.I2CEN = BIT_SET;
168 }
169 
170 /*!
171  * @brief       Disable the I2C peripheral
172  *
173  * @param       i2c: Select I2C peripheral,it can be I2C1/I2C2.
174  *
175  * @retval      None
176  */
I2C_Disable(I2C_T * i2c)177 void I2C_Disable(I2C_T* i2c)
178 {
179     i2c->CTRL1_B.I2CEN = BIT_RESET;
180 }
181 
182 /*!
183  * @brief       I2C Soft ware Reset
184  *
185  * @param       i2c: Select I2C peripheral,it can be I2C1/I2C2.
186  *
187  * @retval      None
188  */
I2C_SoftwareReset(I2C_T * i2c)189 void I2C_SoftwareReset(I2C_T* i2c)
190 {
191     i2c->CTRL1_B.I2CEN = BIT_RESET;
192     *(__IO uint32_t*)(uint32_t)i2c;
193     i2c->CTRL1_B.I2CEN = BIT_SET;
194 }
195 
196 /*!
197  * @brief       Enables the specified interrupts
198  *
199  * @param       i2c: Select I2C peripheral,it can be I2C1/I2C2.
200  *
201  * @param       interrupt:  Specifies the I2C interrupts sources
202  *                          The parameter can be combination of following values:
203  *                          @arg I2C_INT_TXIE:    TX Interrupt enable
204  *                          @arg I2C_INT_RXIE:    RX Interrupt enable
205  *                          @arg I2C_INT_ADDRIE:  Address match interrupt enable (slave only)
206  *                          @arg I2C_INT_NACKIE:  Not acknowledge received interrupt enable
207  *                          @arg I2C_INT_STOPIE:  STOP detection Interrupt enable
208  *                          @arg I2C_INT_TXCIE:   Transfer complete interrupt enable
209  *                          @arg I2C_INT_ERRIE:   Error interrupts enable
210  *
211  * @retval      None
212  */
I2C_EnableInterrupt(I2C_T * i2c,uint8_t interrupt)213 void I2C_EnableInterrupt(I2C_T* i2c, uint8_t interrupt)
214 {
215     i2c->CTRL1 |= (uint32_t)interrupt;
216 }
217 
218 /*!
219  * @brief       Disable the specified interrupts
220  *
221  * @param       i2c: Select I2C peripheral,it can be I2C1/I2C2.
222  *
223  * @param       interrupt:  Specifies the I2C interrupts sources
224  *                          The parameter can be combination of following values:
225  *                          @arg I2C_INT_TXIE:    TX Interrupt enable
226  *                          @arg I2C_INT_RXIE:    RX Interrupt enable
227  *                          @arg I2C_INT_ADDRIE:  Address match interrupt enable (slave only)
228  *                          @arg I2C_INT_NACKIE:  Not acknowledge received interrupt enable
229  *                          @arg I2C_INT_STOPIE:  STOP detection Interrupt enable
230  *                          @arg I2C_INT_TXCIE:   Transfer complete interrupt enable
231  *                          @arg I2C_INT_ERRIE:   Error interrupts enable
232  *
233  * @retval      None
234  */
I2C_DisableInterrupt(I2C_T * i2c,uint8_t interrupt)235 void I2C_DisableInterrupt(I2C_T* i2c, uint8_t interrupt)
236 {
237     i2c->CTRL1 &= (uint32_t)~interrupt;
238 }
239 
240 /*!
241  * @brief       Enables the stretch clock
242  *
243  * @param       i2c: Select I2C peripheral,it can be I2C1/I2C2.
244  *
245  * @retval      None
246  */
I2C_EnableStretchClock(I2C_T * i2c)247 void I2C_EnableStretchClock(I2C_T* i2c)
248 {
249     i2c->CTRL1_B.CLKSTRETCHD = BIT_RESET;
250 }
251 
252 /*!
253  * @brief       Disables the stretch clock
254  *
255  * @param       i2c: Select I2C peripheral,it can be I2C1/I2C2.
256  *
257  * @retval      None
258  */
I2C_DisableStretchClock(I2C_T * i2c)259 void I2C_DisableStretchClock(I2C_T* i2c)
260 {
261     i2c->CTRL1_B.CLKSTRETCHD = BIT_SET;
262 }
263 
264 /*!
265  * @brief       Enables the stop mode
266  *
267  * @param       i2c:   Select I2C peripheral, It can be I2C1.
268  *
269  * @retval      None
270  *
271  * @note        It's not for APM32F030 devices
272  */
I2C_EnableStopMode(I2C_T * i2c)273 void I2C_EnableStopMode(I2C_T* i2c)
274 {
275     i2c->CTRL1_B.WUPEN = BIT_SET;
276 }
277 
278 /*!
279  * @brief       Disable the stop mode
280  *
281  * @param       i2c:   Select I2C peripheral, It can be I2C1.
282  *
283  * @retval      None
284  *
285  * @note        It's not for APM32F030 devices
286  */
I2C_DisableStopMode(I2C_T * i2c)287 void I2C_DisableStopMode(I2C_T* i2c)
288 {
289     i2c->CTRL1_B.WUPEN = BIT_RESET;
290 }
291 
292 /*!
293  * @brief       Enables the I2C own address 2
294  *
295  * @param       i2c: Select I2C peripheral,it can be I2C1/I2C2.
296  *
297  * @retval      None
298  */
I2C_EnableOwnAddress2(I2C_T * i2c)299 void I2C_EnableOwnAddress2(I2C_T* i2c)
300 {
301     i2c->ADDR2_B.ADDR2EN = BIT_SET;
302 }
303 
304 /*!
305  * @brief       Disables the I2C own address 2
306  *
307  * @param       i2c: Select I2C peripheral,it can be I2C1/I2C2.
308  *
309  * @retval      None
310  */
I2C_DisableOwnAddress2(I2C_T * i2c)311 void I2C_DisableOwnAddress2(I2C_T* i2c)
312 {
313     i2c->ADDR2_B.ADDR2EN = BIT_RESET;
314 }
315 
316 /*!
317  * @brief       I2C slave own address 2 and mask
318  *
319  * @param       i2c:  Select I2C peripheral,it can be I2C1/I2C2.
320  *
321  * @param       mask: Own address 2 mask selection
322  *                    The parameter can be one of following values:
323  *                    @arg I2C_ADDR2MSK_NOMASK: No masked
324  *                    @arg I2C_ADDR2MSK_MASK01: Don't care masked ADDR2[1:0]
325  *                    @arg I2C_ADDR2MSK_MASK02: Don't care masked ADDR2[2:1]
326  *                    @arg I2C_ADDR2MSK_MASK03: Don't care masked ADDR2[3:1]
327  *                    @arg I2C_ADDR2MSK_MASK04: Don't care masked ADDR2[4:1]
328  *                    @arg I2C_ADDR2MSK_MASK05: Don't care masked ADDR2[5:1]
329  *                    @arg I2C_ADDR2MSK_MASK06: Don't care masked ADDR2[6:1]
330  *                    @arg I2C_ADDR2MSK_MASK07: Don't care masked ADDR2[7:1]
331  *
332  * @retval      None
333  */
I2C_OwnAddress2Mask(I2C_T * i2c,uint16_t address,I2C_ADDR2MSK_T mask)334 void I2C_OwnAddress2Mask(I2C_T* i2c, uint16_t address, I2C_ADDR2MSK_T mask)
335 {
336     i2c->ADDR2_B.ADDR2 = address;
337     i2c->ADDR2_B.ADDR2MSK = mask;
338 
339 }
340 
341 /*!
342  * @brief       Enables the Broadcast call mode
343  *
344  * @param       i2c: Select I2C peripheral,it can be I2C1/I2C2.
345  *
346  * @retval      None
347  */
I2C_EnableBroadcastCall(I2C_T * i2c)348 void I2C_EnableBroadcastCall(I2C_T* i2c)
349 {
350     i2c->CTRL1_B.RBEN = BIT_SET;
351 }
352 
353 /*!
354  * @brief       Disables the Broadcast call mode
355  *
356  * @param       i2c: Select I2C peripheral,it can be I2C1/I2C2.
357  *
358  * @retval      None
359  */
I2C_DisableBroadcastCall(I2C_T * i2c)360 void I2C_DisableBroadcastCall(I2C_T* i2c)
361 {
362     i2c->CTRL1_B.RBEN = BIT_RESET;
363 }
364 
365 /*!
366  * @brief       Enables the slave byte control
367  *
368  * @param       i2c: Select I2C peripheral,it can be I2C1/I2C2.
369  *
370  * @retval      None
371  */
I2C_EnableSlaveByteControl(I2C_T * i2c)372 void I2C_EnableSlaveByteControl(I2C_T* i2c)
373 {
374     i2c->CTRL1_B.SBCEN = BIT_SET;
375 }
376 
377 /*!
378  * @brief       Disables the slave byte control
379  *
380  * @param       i2c: Select I2C peripheral,it can be I2C1/I2C2.
381  *
382  * @retval      None
383  */
I2C_DisableSlaveByteControl(I2C_T * i2c)384 void I2C_DisableSlaveByteControl(I2C_T* i2c)
385 {
386     i2c->CTRL1_B.SBCEN = BIT_RESET;
387 }
388 
389 /*!
390  * @brief       Configures the slave address
391  *
392  * @param       i2c: Select I2C peripheral,it can be I2C1/I2C2.
393  *
394  * @param       address: set I2C slave uint16_t Address
395  *
396  * @retval      None
397  */
I2C_SlaveAddress(I2C_T * i2c,uint16_t address)398 void I2C_SlaveAddress(I2C_T* i2c, uint16_t address)
399 {
400     uint32_t temp = 0;
401     temp = i2c->CTRL2;
402 
403     temp &= (uint32_t)~((uint32_t)0x000003FF);
404     i2c->CTRL2 = temp;
405 
406     i2c->ADDR2_B.ADDR2 = address;
407 }
408 
409 /*!
410  * @brief       Enables I2C 10-bit addressing mode for the master
411  *
412  * @param       i2c: Select I2C peripheral,it can be I2C1/I2C2.
413  *
414  * @retval      None
415  */
I2C_Enable10BitAddressingMode(I2C_T * i2c)416 void I2C_Enable10BitAddressingMode(I2C_T* i2c)
417 {
418     i2c->CTRL2_B.SADDRLEN = BIT_SET;
419 }
420 
421 /*!
422  * @brief       Disables I2C 10-bit addressing mode for the master
423  *
424  * @param       i2c: Select I2C peripheral,it can be I2C1/I2C2.
425  *
426  * @retval      None
427  */
I2C_Disable10BitAddressingMode(I2C_T * i2c)428 void I2C_Disable10BitAddressingMode(I2C_T* i2c)
429 {
430     i2c->CTRL2_B.SADDRLEN = BIT_RESET;
431 }
432 
433 /*!
434  * @brief       Enables the I2C automatic end mode
435  *
436  * @param       i2c: Select I2C peripheral,it can be I2C1/I2C2.
437  *
438  * @retval      None
439  */
I2C_EnableAutoEnd(I2C_T * i2c)440 void I2C_EnableAutoEnd(I2C_T* i2c)
441 {
442     i2c->CTRL2_B.ENDCFG = BIT_SET;
443 }
444 
445 /*!
446  * @brief       Disables the I2C automatic end mode
447  *
448  * @param       i2c: Select I2C peripheral,it can be I2C1/I2C2.
449  *
450  * @retval      None
451  */
I2C_DisableAutoEnd(I2C_T * i2c)452 void I2C_DisableAutoEnd(I2C_T* i2c)
453 {
454     i2c->CTRL2_B.ENDCFG = BIT_RESET;
455 }
456 
457 /*!
458  * @brief       Enables the I2C nbytes reload mode
459  *
460  * @param       i2c: Select I2C peripheral,it can be I2C1/I2C2.
461  *
462  * @retval      None
463  */
I2C_EnableReload(I2C_T * i2c)464 void I2C_EnableReload(I2C_T* i2c)
465 {
466     i2c->CTRL2_B.RELOADEN = BIT_SET;
467 }
468 
469 /*!
470  * @brief       Disables the I2C nbytes reload mode
471  *
472  * @param       i2c: Select I2C peripheral,it can be I2C1/I2C2.
473  *
474  * @retval      None
475  */
I2C_DisableReload(I2C_T * i2c)476 void I2C_DisableReload(I2C_T* i2c)
477 {
478     i2c->CTRL2_B.RELOADEN = BIT_RESET;
479 }
480 
481 /*!
482  * @brief       Configures the number of bytes to be transmitted/received
483  *
484  * @param       i2c: Select I2C peripheral,it can be I2C1/I2C2.
485  *
486  * @param       number:Set uint8_t bytes to read or write
487  *
488  * @retval      None
489  */
I2C_ConfigNumberOfBytes(I2C_T * i2c,uint8_t number)490 void I2C_ConfigNumberOfBytes(I2C_T* i2c, uint8_t number)
491 {
492     i2c->CTRL2_B.NUMBYT = 0xFF;
493     i2c->CTRL2_B.NUMBYT  &= (uint8_t) number ;
494 }
495 
496 /*!
497  * @brief       Configures the type of transfer request for the master
498  *
499  * @param       i2c: Select I2C peripheral,it can be I2C1/I2C2.
500  *
501  * @param       direction: selects the I2C transfer direction.
502  *                         The parameter can be one of following values:
503  *                         @arg I2C_DIRECTION_TX:   Transmission direction
504  *                         @arg I2C_DIRECTION_RX:   Reception direction
505  *
506  * @retval      None
507  */
I2C_ConfigMasterRequest(I2C_T * i2c,I2C_DIRECTION_T direction)508 void I2C_ConfigMasterRequest(I2C_T* i2c, I2C_DIRECTION_T  direction)
509 {
510     i2c->CTRL2_B.TXDIR  =  direction ;
511 }
512 
513 /*!
514  * @brief       Enables the generates i2c communication start condition
515  *
516  * @param       i2c: Select I2C peripheral,it can be I2C1/I2C2.
517  *
518  * @retval      None
519  */
I2C_EnableGenerateStart(I2C_T * i2c)520 void I2C_EnableGenerateStart(I2C_T* i2c)
521 {
522     i2c->CTRL2_B.START = BIT_SET;
523 }
524 
525 /*!
526  * @brief       Disables the generates i2c communication start condition
527  *
528  * @param       i2c: Select I2C peripheral,it can be I2C1/I2C2.
529  *
530  * @retval      None
531  */
I2C_DisableGenerateStart(I2C_T * i2c)532 void I2C_DisableGenerateStart(I2C_T* i2c)
533 {
534     i2c->CTRL2_B.START = BIT_RESET;
535 }
536 
537 /*!
538  * @brief       Enables the generates i2c communication stop condition
539  *
540  * @param       i2c:   Select I2C peripheral
541  *                      This parameter can be any combination of the following values:
542  *                     @arg I2C1
543  *                     @arg I2C2
544  *
545  * @retval      None
546  */
I2C_EnableGenerateStop(I2C_T * i2c)547 void I2C_EnableGenerateStop(I2C_T* i2c)
548 {
549     i2c->CTRL2_B.STOP = BIT_SET;
550 }
551 
552 /*!
553  * @brief       Disables the generates i2c communication stop condition
554  *
555  * @param       i2c: Select I2C peripheral,it can be I2C1/I2C2.
556  *
557  * @retval      None
558  */
I2C_DisableGenerateStop(I2C_T * i2c)559 void I2C_DisableGenerateStop(I2C_T* i2c)
560 {
561     i2c->CTRL2_B.STOP = BIT_RESET;
562 }
563 
564 /*!
565  * @brief       Enables I2C 10-bit header only mode with read direction
566  *
567  * @param       i2c: Select I2C peripheral,it can be I2C1/I2C2.
568  *
569  * @retval      None
570  */
I2C_Enable10BitAddressHeader(I2C_T * i2c)571 void I2C_Enable10BitAddressHeader(I2C_T* i2c)
572 {
573     i2c->CTRL2_B.ADDR10 = BIT_SET;
574 }
575 
576 /*!
577  * @brief       Disables I2C 10-bit header only mode with read direction
578  *
579  * @param       i2c: Select I2C peripheral,it can be I2C1/I2C2.
580  *
581  * @retval      None
582  */
I2C_Disable10BitAddressHeader(I2C_T * i2c)583 void I2C_Disable10BitAddressHeader(I2C_T* i2c)
584 {
585     i2c->CTRL2_B.ADDR10 = BIT_RESET;
586 }
587 
588 /*!
589  * @brief       Enables I2C communication Acknowledge
590  *
591  * @param       i2c: Select I2C peripheral,it can be I2C1/I2C2.
592  *
593  * @retval      None
594  */
I2C_EnableAcknowledge(I2C_T * i2c)595 void I2C_EnableAcknowledge(I2C_T* i2c)
596 {
597     i2c->CTRL2_B.NACKEN = BIT_RESET;
598 }
599 
600 /*!
601  * @brief       Disables I2C communication Acknowledge
602  *
603  * @param       i2c: Select I2C peripheral,it can be I2C1/I2C2.
604  *
605  * @retval      None
606  */
I2C_DisableAcknowledge(I2C_T * i2c)607 void I2C_DisableAcknowledge(I2C_T* i2c)
608 {
609     i2c->CTRL2_B.NACKEN = BIT_SET;
610 }
611 
612 /*!
613  * @brief       Returns the I2C slave matched address
614  *
615  * @param       i2c: Select I2C peripheral,it can be I2C1/I2C2.
616  *
617  * @retval      The value is slave matched address
618  */
I2C_ReadAddressMatched(I2C_T * i2c)619 uint8_t I2C_ReadAddressMatched(I2C_T* i2c)
620 {
621     return ((uint8_t)i2c->STS_B.ADDRCMFLG);
622 }
623 
624 /*!
625  * @brief       Returns the I2C slave received request
626  *
627  * @param       i2c: Select I2C peripheral,it can be I2C1/I2C2.
628  *
629  * @retval      The value of the received request
630  */
I2C_ReadTransferDirection(I2C_T * i2c)631 uint16_t I2C_ReadTransferDirection(I2C_T* i2c)
632 {
633     uint16_t direction = 0;
634     uint32_t temp = 0;
635 
636     temp = (uint32_t) i2c->STS_B.TXDIRFLG;
637 
638     if (temp == 0)
639     {
640         direction = (uint16_t)I2C_DIRECTION_TX;
641     }
642     else
643     {
644         direction = (uint16_t)(I2C_DIRECTION_RX << 10);
645     }
646 
647     return direction;
648 }
649 
650 /*!
651  * @brief       Handles I2Cx communication when starting transfer or during transfer
652  *
653  * @param       i2c: Select I2C peripheral,it can be I2C1/I2C2.
654  *
655  * @param       address:    specifies the slave address to be programmed.
656  *
657  * @param       number:     specifies the number of bytes to be programmed.
658  *                          This parameter must be a value between 0 and 255.
659  *
660  * @param       reloadend:  the I2C reload end mode
661  *                          The parameter can be one of following values:
662  *                          @arg I2C_RELOAD_MODE_RELOAD:  Enable Reload mode.
663  *                          @arg I2C_RELOAD_MODE_AUTOEND: Enable Automatic end mode.
664  *                          @arg I2C_RELOAD_MODE_SOFTEND: Enable Software end mode.
665  *
666  * @param       generates:  the I2C start/stop mode
667  *                          The parameter can be one of following values:
668  *                          @arg I2C_GENERATE_NO_STARTSTOP: Don't Generate stop and start condition.
669  *                          @arg I2C_GENERATE_START_WRITE:  Generate Restart for write request.
670  *                          @arg I2C_GENERATE_STOP:         Generate stop condition
671  *                          @arg I2C_GENERATE_START_READ:   Generate Restart for read request.
672  *
673  * @retval      None
674  */
I2C_HandlingTransfer(I2C_T * i2c,uint16_t address,uint8_t number,I2C_RELOAD_MODE_T reloadend,I2C_GENERATE_T generates)675 void I2C_HandlingTransfer(I2C_T* i2c, uint16_t address, uint8_t number, I2C_RELOAD_MODE_T reloadend, I2C_GENERATE_T generates)
676 {
677     uint32_t temp = 0;
678 
679     /* Get the CTRL2 register value */
680     temp = i2c->CTRL2;
681 
682     /* clear temp specific bits */
683     temp &= (uint32_t)~((uint32_t)(I2C_CTRL2_SADD | I2C_CTRL2_NUMBYT | I2C_CTRL2_MASK));
684 
685     /* update temp */
686     temp |= (uint32_t)(((uint32_t)address & I2C_CTRL2_SADD) | (((uint32_t)number << 16) & I2C_CTRL2_NUMBYT) | \
687                        (uint32_t)reloadend | (uint32_t)generates);
688 
689     /* update CTRL2 register */
690     i2c->CTRL2 = temp;
691 }
692 
693 /*!
694  * @brief       Enables I2C SMBus alert
695  *
696  * @param       i2c: Select I2C peripheral,it can be I2C1.
697  *
698  * @retval      None
699  */
I2C_EnableSMBusAlert(I2C_T * i2c)700 void I2C_EnableSMBusAlert(I2C_T* i2c)
701 {
702     i2c->CTRL1_B.ALTEN = BIT_SET;
703 }
704 
705 /*!
706  * @brief       Disables I2C SMBus alert
707  *
708  * @param       i2c: Select I2C peripheral,it can be I2C1.
709  *
710  * @retval      None
711  */
I2C_DisableSMBusAlert(I2C_T * i2c)712 void I2C_DisableSMBusAlert(I2C_T* i2c)
713 {
714     i2c->CTRL1_B.ALTEN = BIT_RESET;
715 }
716 
717 /*!
718  * @brief       Enable I2C SMBus HADDREN
719  *
720  * @param       i2c: Select I2C peripheral,it can be I2C1/I2C2.
721  *
722  * @retval      None
723  */
I2C_EnableSMBusHAEN(I2C_T * i2c)724 void I2C_EnableSMBusHAEN(I2C_T* i2c)
725 {
726     i2c->CTRL1_B.HADDREN = BIT_SET;
727 }
728 
729 /*!
730  * @brief       Disable I2C SMBus HADDREN
731  *
732  * @param       i2c: Select I2C peripheral,it can be I2C1/I2C2.
733  *
734  * @retval      None
735  */
I2C_DisableSMBusHAEN(I2C_T * i2c)736 void I2C_DisableSMBusHAEN(I2C_T* i2c)
737 {
738     i2c->CTRL1_B.HADDREN = BIT_RESET;
739 }
740 
741 /*!
742  * @brief       Enable I2C SMBus DEADDREN
743  *
744  * @param       i2c: Select I2C peripheral,it can be I2C1/I2C2.
745  *
746  * @retval      None
747  */
748 
I2C_EnableSMBusDAEN(I2C_T * i2c)749 void I2C_EnableSMBusDAEN(I2C_T* i2c)
750 {
751     i2c->CTRL1_B.DEADDREN = BIT_SET;
752 }
753 
754 /*!
755  * @brief       Disable I2C SMBus DEADDREN
756  *
757  * @param       i2c: Select I2C peripheral,it can be I2C1/I2C2.
758  *
759  * @retval      None
760  */
I2C_DisableSMBusDAEN(I2C_T * i2c)761 void I2C_DisableSMBusDAEN(I2C_T* i2c)
762 {
763     i2c->CTRL1_B.DEADDREN = BIT_RESET;
764 }
765 
766 /*!
767  * @brief       Enables I2C Clock Timeout
768  *
769  * @param       i2c: Select I2C peripheral,it can be I2C1.
770  *
771  * @retval      None
772  */
I2C_EnableClockTimeout(I2C_T * i2c)773 void I2C_EnableClockTimeout(I2C_T* i2c)
774 {
775     i2c->TIMEOUT_B.CLKTOEN = BIT_SET;
776 }
777 
778 /*!
779  * @brief       Disables I2C Clock Timeout
780  *
781  * @param       i2c: Select I2C peripheral,it can be I2C1.
782  *
783  * @retval      None
784  */
I2C_DisableClockTimeout(I2C_T * i2c)785 void I2C_DisableClockTimeout(I2C_T* i2c)
786 {
787     i2c->TIMEOUT_B.CLKTOEN = BIT_RESET;
788 }
789 
790 /*!
791  * @brief       Enables I2C Extend Clock Timeout
792  *
793  * @param       i2c: Select I2C peripheral,it can be I2C1.
794  *
795  * @retval      None
796  */
I2C_EnableExtendClockTimeout(I2C_T * i2c)797 void I2C_EnableExtendClockTimeout(I2C_T* i2c)
798 {
799     i2c->TIMEOUT_B.EXCLKTOEN = BIT_SET;
800 }
801 
802 /*!
803  * @brief       Disables I2C Extend Clock Timeout
804  *
805  * @param       i2c: Select I2C peripheral,it can be I2C1.
806  *
807  * @retval      None
808  */
I2C_DisableExtendClockTimeout(I2C_T * i2c)809 void I2C_DisableExtendClockTimeout(I2C_T* i2c)
810 {
811     i2c->TIMEOUT_B.EXCLKTOEN = BIT_RESET;
812 }
813 
814 /*!
815  * @brief       Enables I2C Idle Clock Timeout
816  *
817  * @param       i2c: Select I2C peripheral,it can be I2C1.
818  *
819  * @retval      None
820  */
I2C_EnableIdleClockTimeout(I2C_T * i2c)821 void I2C_EnableIdleClockTimeout(I2C_T* i2c)
822 {
823     i2c->TIMEOUT_B.IDLECLKTO = BIT_SET;
824 }
825 
826 /*!
827  * @brief       Disables I2C Idle Clock Timeout
828  *
829  * @param       i2c: Select I2C peripheral,it can be I2C1.
830  *
831  * @retval      None
832  */
I2C_DisableIdleClockTimeout(I2C_T * i2c)833 void I2C_DisableIdleClockTimeout(I2C_T* i2c)
834 {
835     i2c->TIMEOUT_B.IDLECLKTO = BIT_RESET;
836 }
837 
838 /*!
839  * @brief       Configures the I2C Bus Timeout A
840  *
841  * @param       i2c: Select I2C peripheral,it can be I2C1.
842  *
843  * @param       timeout: specifies the Timeout A to be programmed
844  *
845  * @retval      None
846  */
I2C_ConfigTimeoutA(I2C_T * i2c,uint16_t timeout)847 void I2C_ConfigTimeoutA(I2C_T* i2c, uint16_t timeout)
848 {
849     i2c->TIMEOUT_B.TIMEOUTA = timeout;
850 }
851 
852 /*!
853  * @brief       Configures the I2C Bus Timeout B
854  *
855  * @param       i2c: Select I2C peripheral,it can be I2C1.
856  *
857  * @param       timeout: specifies the Timeout B to be programmed
858  *
859  * @retval      None
860  */
I2C_ConfigTimeoutB(I2C_T * i2c,uint16_t timeout)861 void I2C_ConfigTimeoutB(I2C_T* i2c, uint16_t timeout)
862 {
863     i2c->TIMEOUT_B.TIMEOUTB = timeout;
864 }
865 
866 /*!
867  * @brief       Enables I2C PEC calculation
868  *
869  * @param       i2c: Select I2C peripheral,it can be I2C1.
870  *
871  * @retval      None
872  */
I2C_EnablePEC(I2C_T * i2c)873 void I2C_EnablePEC(I2C_T* i2c)
874 {
875     i2c->CTRL1_B.PECEN = BIT_SET;
876 }
877 
878 /*!
879  * @brief       Disables I2C PEC calculation
880  *
881  * @param       i2c: Select I2C peripheral,it can be I2C1.
882  *
883  * @retval      None
884  */
I2C_DisablePEC(I2C_T * i2c)885 void I2C_DisablePEC(I2C_T* i2c)
886 {
887     i2c->CTRL1_B.PECEN = BIT_RESET;
888 }
889 
890 /*!
891  * @brief       Enables I2C PEC transmission/reception request
892  *
893  * @param       i2c: Select I2C peripheral,it can be I2C1.
894  *
895  * @retval      None
896  */
I2C_EnablePECRequest(I2C_T * i2c)897 void I2C_EnablePECRequest(I2C_T* i2c)
898 {
899     i2c->CTRL2_B.PEC = BIT_SET;
900 }
901 
902 /*!
903  * @brief       Disables I2C PEC transmission/reception request
904  *
905  * @param       i2c: Select I2C peripheral,it can be I2C1.
906  *
907  * @retval      None
908  */
I2C_DisablePECRequest(I2C_T * i2c)909 void I2C_DisablePECRequest(I2C_T* i2c)
910 {
911     i2c->CTRL2_B.PEC = BIT_RESET;
912 }
913 
914 /*!
915  * @brief       Returns the I2C PEC
916  *
917  * @param       i2c: Select I2C peripheral,it can be I2C1.
918  *
919  * @retval      The value is PEC
920  */
I2C_ReadPEC(I2C_T * i2c)921 uint8_t I2C_ReadPEC(I2C_T* i2c)
922 {
923     return ((uint8_t)i2c->PEC_B.PEC);
924 }
925 
926 /*!
927  * @brief       Reads the specified I2C register and returns its value
928  *
929  * @param       i2c: Select I2C peripheral,it can be I2C1/I2C2.
930  *
931  * @param       registers:  Specifies the I2C interrupts sources
932  *                          The parameter can be one of following values:
933  *                          @arg I2C_REGISTER_CTRL1:    CTRL1 register
934  *                          @arg I2C_REGISTER_CTRL2:    CTRL2 register
935  *                          @arg I2C_REGISTER_ADDR1:    ADDR1 register
936  *                          @arg I2C_REGISTER_ADDR2:    ADDR2 register
937  *                          @arg I2C_REGISTER_TIMING:   TIMING register
938  *                          @arg I2C_REGISTER_TIMEOUT:  TIMEOUT register
939  *                          @arg I2C_REGISTER_STS:      STS register
940  *                          @arg I2C_REGISTER_INTFCLR:  INTFCLR register
941  *                          @arg I2C_REGISTER_PEC:      PEC register
942  *                          @arg I2C_REGISTER_RXDATA:   RXDATA register
943  *                          @arg I2C_REGISTER_TXDATA:   TXDATA register
944  *
945  * @retval      None
946  */
I2C_ReadRegister(I2C_T * i2c,uint8_t registers)947 uint32_t I2C_ReadRegister(I2C_T* i2c, uint8_t registers)
948 {
949     __IO uint32_t temp = 0;
950 
951     temp = (uint32_t)i2c;
952     temp += registers;
953 
954     return (*(__IO uint32_t*) temp);
955 }
956 
957 /*!
958  * @brief       Send a byte by writing in the TXDATA register
959  *
960  * @param       i2c: Select I2C peripheral,it can be I2C1/I2C2.
961  *
962  * @param       data:   Byte to be sent
963  *
964  * @retval      None
965  */
I2C_TxData(I2C_T * i2c,uint8_t data)966 void I2C_TxData(I2C_T* i2c, uint8_t data)
967 {
968     i2c->TXDATA = (uint32_t)data;
969 }
970 
971 /*!
972  * @brief       Returns the most recent received data
973  *
974  * @param       i2c: Select I2C peripheral,it can be I2C1/I2C2.
975  *
976  * @retval      The value of the received byte data
977  */
I2C_RxData(I2C_T * i2c)978 uint8_t I2C_RxData(I2C_T* i2c)
979 {
980     return (uint8_t)i2c->RXDATA;
981 }
982 
983 /*!
984  * @brief       Enables the I2C DMA interface
985  *
986  * @param       i2c: Select I2C peripheral,it can be I2C1/I2C2.
987  *
988  * @param       request: DMA transfer request
989  *                       The parameter can be one of following values:
990  *                       @arg I2C_DMA_REQ_TX:   TX DMA Transmission request
991  *                       @arg I2C_DMA_REQ_RX:   RX DMA Transmission request
992  *
993  * @retval      None
994  */
I2C_EnableDMA(I2C_T * i2c,I2C_DMA_REQ_T request)995 void I2C_EnableDMA(I2C_T* i2c, I2C_DMA_REQ_T request)
996 {
997     if (request == I2C_DMA_REQ_TX)
998     {
999         i2c->CTRL1_B.DMATXEN = BIT_SET;
1000     }
1001     else
1002     {
1003         i2c->CTRL1_B.DMARXEN = BIT_SET;
1004     }
1005 }
1006 
1007 /*!
1008  * @brief       Disables the I2C DMA interface
1009  *
1010  * @param       i2c: Select I2C peripheral,it can be I2C1/I2C2.
1011  *
1012  * @param       request: DMA transfer request
1013  *                       The parameter can be one of following values:
1014  *                       @arg I2C_DMA_REQ_TX:   TX DMA Transmission request
1015  *                       @arg I2C_DMA_REQ_RX:   RX DMA Transmission request
1016  *
1017  * @retval      None
1018  */
I2C_DisableDMA(I2C_T * i2c,I2C_DMA_REQ_T request)1019 void I2C_DisableDMA(I2C_T* i2c, I2C_DMA_REQ_T request)
1020 {
1021     if (request == I2C_DMA_REQ_TX)
1022     {
1023         i2c->CTRL1_B.DMATXEN = BIT_RESET;
1024     }
1025     else
1026     {
1027         i2c->CTRL1_B.DMARXEN = BIT_RESET;
1028     }
1029 }
1030 
1031 /*!
1032  * @brief       Checks whether the specified I2C flag is set or not
1033  *
1034  * @param       i2c: Select I2C peripheral,it can be I2C1/I2C2.
1035  *
1036  * @param       flag:    Specifies the flag to check
1037  *                       The parameter can be one of following values:
1038  *                       @arg I2C_FLAG_TXBE:  Transmit buffer data register empty flag
1039  *                       @arg I2C_FLAG_TXINT: Transmit interrupt flag
1040  *                       @arg I2C_FLAG_RXBNE: Read buffer data register not empty flag
1041  *                       @arg I2C_FLAG_ADDR:  Address Sent/Matched (master/slave) flag
1042  *                       @arg I2C_FLAG_NACK:  Not acknowledge received flag
1043  *                       @arg I2C_FLAG_STOP:  Stop detected flag
1044  *                       @arg I2C_FLAG_TXCF:  Transfer complete flag
1045  *                       @arg I2C_FLAG_TCRF:  Transfer complete reload flag
1046  *                       @arg I2C_FLAG_BUSERR:Bus error flag
1047  *                       @arg I2C_FLAG_ALF:   Arbitration Loss flag
1048  *                       @arg I2C_FLAG_OVR:   Overrun/Underrun flag
1049  *                       @arg I2C_FLAG_PECERR:PEC error flag
1050  *                       @arg I2C_FLAG_TIMEOUT: Timeout or t_low detection flag
1051  *                       @arg I2C_FLAG_ALERT: SMBus alert flag
1052  *                       @arg I2C_FLAG_BUSY:  Bus Busy Flag
1053  *
1054  * @retval      Status of interrupt flag(SET or RESET)
1055  */
I2C_ReadStatusFlag(I2C_T * i2c,I2C_FLAG_T flag)1056 uint8_t I2C_ReadStatusFlag(I2C_T* i2c, I2C_FLAG_T flag)
1057 {
1058     uint32_t status = 0;
1059 
1060     status = (uint32_t)(i2c->STS & (flag));
1061 
1062     if (status == flag)
1063     {
1064         return SET;
1065     }
1066 
1067     return RESET;
1068 }
1069 
1070 /*!
1071  * @brief       Clear flags
1072  *
1073  * @param       i2c: Select I2C peripheral,it can be I2C1/I2C2.
1074  *
1075  * @param       flag:   Specifies the flag to clear
1076  *                       The parameter can be combination of following values:
1077  *                       @arg I2C_FLAG_ADDR:  Address Sent/Matched (master/slave) flag
1078  *                       @arg I2C_FLAG_NACK:  Not acknowledge received flag
1079  *                       @arg I2C_FLAG_STOP:  Stop detected flag
1080  *                       @arg I2C_FLAG_BUSERR:Bus error flag
1081  *                       @arg I2C_FLAG_ALF:   Arbitration Loss flag
1082  *                       @arg I2C_FLAG_OVR:   Overrun/Underrun flag
1083  *                       @arg I2C_FLAG_PECERR:PEC error flag
1084  *                       @arg I2C_FLAG_TIMEOUT: Timeout or t_low detection flag
1085  *                       @arg I2C_FLAG_ALERT: SMBus alert flag
1086  *
1087  * @retval      None
1088  */
I2C_ClearStatusFlag(I2C_T * i2c,uint32_t flag)1089 void I2C_ClearStatusFlag(I2C_T* i2c, uint32_t flag)
1090 {
1091     i2c->INTFCLR = (uint32_t)flag;
1092 }
1093 
1094 /*!
1095  * @brief       Checks whether the specified interrupt has occurred or not
1096  *
1097  * @param       i2c: Select I2C peripheral,it can be I2C1/I2C2.
1098  *
1099  * @param       flag:   Specifies the I2C interrupt pending bit to check
1100  *                      The parameter can be one of following values:
1101  *                      @arg I2C_INT_FLAG_TXINT:    Transmit interrupt flag
1102  *                      @arg I2C_INT_FLAG_RXBNE:    Read Buffer Data Register Not Empty interrupt flag
1103  *                      @arg I2C_INT_FLAG_ADDR:     Address Sent/Matched (master/slave) interrupt flag
1104  *                      @arg I2C_INT_FLAG_NACK:     Not acknowledge received interrupt flag
1105  *                      @arg I2C_INT_FLAG_STOP:     Stop detected interrupt flag
1106  *                      @arg I2C_INT_FLAG_TXCF:     Transfer complete interrupt flag
1107  *                      @arg I2C_INT_FLAG_TCRF:     Transfer Complete Reloadinterrupt flag
1108 
1109  *                      @arg I2C_INT_FLAG_BUSERR:   Bus error interrupt flag
1110  *                      @arg I2C_INT_FLAG_ALF:      Arbitration Loss interrupt flag
1111  *                      @arg I2C_INT_FLAG_OVR:      Overrun/Underrun interrupt flag
1112  *                      @arg I2C_INT_FLAG_PECERR:   PEC error interrupt flag
1113  *                      @arg I2C_INT_FLAG_TIMEOUT:  Timeout or t_low detection interrupt flag
1114  *                      @arg I2C_INT_FLAG_ALERT:    SMBus alert interrupt flag
1115  *
1116  * @retval      Status of interrupt flag(SET or RESET)
1117  */
I2C_ReadIntFlag(I2C_T * i2c,I2C_INT_FLAG_T flag)1118 uint8_t I2C_ReadIntFlag(I2C_T* i2c, I2C_INT_FLAG_T flag)
1119 {
1120     uint32_t temp = 0;
1121     uint32_t enable = 0;
1122 
1123     if (flag & ((uint32_t)0x000000C0))
1124     {
1125         enable = (uint32_t)((BIT6) & (i2c->CTRL1));
1126     }
1127     else if (flag & ((uint32_t)0x00003F00))
1128     {
1129         enable = (uint32_t)((BIT7) & (i2c->CTRL1));
1130     }
1131     else
1132     {
1133         enable = (uint32_t)((flag) & (i2c->CTRL1));
1134     }
1135 
1136     temp = i2c->STS;
1137 
1138     temp &= flag;
1139 
1140     if ((temp != 0) && enable)
1141     {
1142         return SET;
1143     }
1144     else
1145     {
1146         return RESET;
1147     }
1148 }
1149 
1150 /*!
1151  * @brief       Clears the specified interrupt pending bits
1152  *
1153  * @param       i2c: Select I2C peripheral,it can be I2C1/I2C2.
1154  *
1155  * @param       flag:   Specifies the I2C interrupt pending bit to clear
1156  *                      The parameter can be combination of following values:
1157  *                       @arg I2C_INT_FLAG_ADDR:  Address Sent/Matched (master/slave) flag
1158  *                       @arg I2C_INT_FLAG_NACK:  Not acknowledge received flag
1159  *                       @arg I2C_INT_FLAG_STOP:  Stop detected flag
1160  *                       @arg I2C_INT_FLAG_BUSERR:Bus error flag
1161  *                       @arg I2C_INT_FLAG_ALF:   Arbitration Loss flag
1162  *                       @arg I2C_INT_FLAG_OVR:   Overrun/Underrun flag
1163  *                       @arg I2C_INT_FLAG_PECERR:PEC error flag
1164  *                       @arg I2C_INT_FLAG_TIMEOUT: Timeout or t_low detection flag
1165  *                       @arg I2C_INT_FLAG_ALERT: SMBus alert flag
1166  *
1167  * @retval
1168  */
1169 
I2C_ClearIntFlag(I2C_T * i2c,uint32_t flag)1170 void I2C_ClearIntFlag(I2C_T* i2c, uint32_t flag)
1171 {
1172     i2c->INTFCLR = (uint32_t)flag;
1173 }
1174 
1175 /**@} end of group I2C_Functions */
1176 /**@} end of group I2C_Driver */
1177 /**@} end of group APM32F0xx_StdPeriphDriver */
1178