1 /********************************** (C) COPYRIGHT  *******************************
2  * File Name          : ch32v10x_i2c.c
3  * Author             : WCH
4  * Version            : V1.0.0
5  * Date               : 2020/04/30
6  * Description        : This file provides all the I2C firmware functions.
7  * Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
8  * SPDX-License-Identifier: Apache-2.0
9  *******************************************************************************/
10 #include "ch32v10x_i2c.h"
11 #include "ch32v10x_rcc.h"
12 
13 /* I2C SPE mask */
14 #define CTLR1_PE_Set             ((uint16_t)0x0001)
15 #define CTLR1_PE_Reset           ((uint16_t)0xFFFE)
16 
17 /* I2C START mask */
18 #define CTLR1_START_Set          ((uint16_t)0x0100)
19 #define CTLR1_START_Reset        ((uint16_t)0xFEFF)
20 
21 /* I2C STOP mask */
22 #define CTLR1_STOP_Set           ((uint16_t)0x0200)
23 #define CTLR1_STOP_Reset         ((uint16_t)0xFDFF)
24 
25 /* I2C ACK mask */
26 #define CTLR1_ACK_Set            ((uint16_t)0x0400)
27 #define CTLR1_ACK_Reset          ((uint16_t)0xFBFF)
28 
29 /* I2C ENGC mask */
30 #define CTLR1_ENGC_Set           ((uint16_t)0x0040)
31 #define CTLR1_ENGC_Reset         ((uint16_t)0xFFBF)
32 
33 /* I2C SWRST mask */
34 #define CTLR1_SWRST_Set          ((uint16_t)0x8000)
35 #define CTLR1_SWRST_Reset        ((uint16_t)0x7FFF)
36 
37 /* I2C PEC mask */
38 #define CTLR1_PEC_Set            ((uint16_t)0x1000)
39 #define CTLR1_PEC_Reset          ((uint16_t)0xEFFF)
40 
41 /* I2C ENPEC mask */
42 #define CTLR1_ENPEC_Set          ((uint16_t)0x0020)
43 #define CTLR1_ENPEC_Reset        ((uint16_t)0xFFDF)
44 
45 /* I2C ENARP mask */
46 #define CTLR1_ENARP_Set          ((uint16_t)0x0010)
47 #define CTLR1_ENARP_Reset        ((uint16_t)0xFFEF)
48 
49 /* I2C NOSTRETCH mask */
50 #define CTLR1_NOSTRETCH_Set      ((uint16_t)0x0080)
51 #define CTLR1_NOSTRETCH_Reset    ((uint16_t)0xFF7F)
52 
53 /* I2C registers Masks */
54 #define CTLR1_CLEAR_Mask         ((uint16_t)0xFBF5)
55 
56 /* I2C DMAEN mask */
57 #define CTLR2_DMAEN_Set          ((uint16_t)0x0800)
58 #define CTLR2_DMAEN_Reset        ((uint16_t)0xF7FF)
59 
60 /* I2C LAST mask */
61 #define CTLR2_LAST_Set           ((uint16_t)0x1000)
62 #define CTLR2_LAST_Reset         ((uint16_t)0xEFFF)
63 
64 /* I2C FREQ mask */
65 #define CTLR2_FREQ_Reset         ((uint16_t)0xFFC0)
66 
67 /* I2C ADD0 mask */
68 #define OADDR1_ADD0_Set          ((uint16_t)0x0001)
69 #define OADDR1_ADD0_Reset        ((uint16_t)0xFFFE)
70 
71 /* I2C ENDUAL mask */
72 #define OADDR2_ENDUAL_Set        ((uint16_t)0x0001)
73 #define OADDR2_ENDUAL_Reset      ((uint16_t)0xFFFE)
74 
75 /* I2C ADD2 mask */
76 #define OADDR2_ADD2_Reset        ((uint16_t)0xFF01)
77 
78 /* I2C F/S mask */
79 #define CKCFGR_FS_Set            ((uint16_t)0x8000)
80 
81 /* I2C CCR mask */
82 #define CKCFGR_CCR_Set           ((uint16_t)0x0FFF)
83 
84 /* I2C FLAG mask */
85 #define FLAG_Mask                ((uint32_t)0x00FFFFFF)
86 
87 /* I2C Interrupt Enable mask */
88 #define ITEN_Mask                ((uint32_t)0x07000000)
89 
90 /*********************************************************************
91  * @fn      I2C_DeInit
92  *
93  * @brief   Deinitializes the I2Cx peripheral registers to their default
94  *        reset values.
95  *
96  * @param   I2Cx - where x can be 1 or 2 to select the I2C peripheral.
97  *
98  * @return  none
99  */
I2C_DeInit(I2C_TypeDef * I2Cx)100 void I2C_DeInit(I2C_TypeDef *I2Cx)
101 {
102     if(I2Cx == I2C1)
103     {
104         RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C1, ENABLE);
105         RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C1, DISABLE);
106     }
107     else
108     {
109         RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C2, ENABLE);
110         RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C2, DISABLE);
111     }
112 }
113 
114 /*********************************************************************
115  * @fn      I2C_Init
116  *
117  * @brief   Initializes the I2Cx peripheral according to the specified
118  *        parameters in the I2C_InitStruct.
119  * @param   I2Cx - where x can be 1 or 2 to select the I2C peripheral.
120  *          I2C_InitStruct - pointer to a I2C_InitTypeDef structure that
121  *        contains the configuration information for the specified I2C peripheral.
122  *
123  * @return  none
124  */
I2C_Init(I2C_TypeDef * I2Cx,I2C_InitTypeDef * I2C_InitStruct)125 void I2C_Init(I2C_TypeDef *I2Cx, I2C_InitTypeDef *I2C_InitStruct)
126 {
127     uint16_t tmpreg = 0, freqrange = 0;
128     uint16_t result = 0x04;
129     uint32_t pclk1 = 8000000;
130 
131     RCC_ClocksTypeDef rcc_clocks;
132 
133     tmpreg = I2Cx->CTLR2;
134     tmpreg &= CTLR2_FREQ_Reset;
135     RCC_GetClocksFreq(&rcc_clocks);
136     pclk1 = rcc_clocks.PCLK1_Frequency;
137     freqrange = (uint16_t)(pclk1 / 1000000);
138     tmpreg |= freqrange;
139     I2Cx->CTLR2 = tmpreg;
140 
141     I2Cx->CTLR1 &= CTLR1_PE_Reset;
142     tmpreg = 0;
143 
144     if(I2C_InitStruct->I2C_ClockSpeed <= 100000)
145     {
146         result = (uint16_t)(pclk1 / (I2C_InitStruct->I2C_ClockSpeed << 1));
147 
148         if(result < 0x04)
149         {
150             result = 0x04;
151         }
152 
153         tmpreg |= result;
154         I2Cx->RTR = freqrange + 1;
155     }
156     else
157     {
158         if(I2C_InitStruct->I2C_DutyCycle == I2C_DutyCycle_2)
159         {
160             result = (uint16_t)(pclk1 / (I2C_InitStruct->I2C_ClockSpeed * 3));
161         }
162         else
163         {
164             result = (uint16_t)(pclk1 / (I2C_InitStruct->I2C_ClockSpeed * 25));
165             result |= I2C_DutyCycle_16_9;
166         }
167 
168         if((result & CKCFGR_CCR_Set) == 0)
169         {
170             result |= (uint16_t)0x0001;
171         }
172 
173         tmpreg |= (uint16_t)(result | CKCFGR_FS_Set);
174         I2Cx->RTR = (uint16_t)(((freqrange * (uint16_t)300) / (uint16_t)1000) + (uint16_t)1);
175     }
176 
177     I2Cx->CKCFGR = tmpreg;
178     I2Cx->CTLR1 |= CTLR1_PE_Set;
179 
180     tmpreg = I2Cx->CTLR1;
181     tmpreg &= CTLR1_CLEAR_Mask;
182     tmpreg |= (uint16_t)((uint32_t)I2C_InitStruct->I2C_Mode | I2C_InitStruct->I2C_Ack);
183     I2Cx->CTLR1 = tmpreg;
184 
185     I2Cx->OADDR1 = (I2C_InitStruct->I2C_AcknowledgedAddress | I2C_InitStruct->I2C_OwnAddress1);
186 }
187 
188 /*********************************************************************
189  * @fn      I2C_StructInit
190  *
191  * @brief   Fills each I2C_InitStruct member with its default value.
192  *
193  * @param   I2C_InitStruct - pointer to an I2C_InitTypeDef structure which
194  *        will be initialized.
195  *
196  * @return  none
197  */
I2C_StructInit(I2C_InitTypeDef * I2C_InitStruct)198 void I2C_StructInit(I2C_InitTypeDef *I2C_InitStruct)
199 {
200     I2C_InitStruct->I2C_ClockSpeed = 5000;
201     I2C_InitStruct->I2C_Mode = I2C_Mode_I2C;
202     I2C_InitStruct->I2C_DutyCycle = I2C_DutyCycle_2;
203     I2C_InitStruct->I2C_OwnAddress1 = 0;
204     I2C_InitStruct->I2C_Ack = I2C_Ack_Disable;
205     I2C_InitStruct->I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
206 }
207 
208 /*********************************************************************
209  * @fn      I2C_Cmd
210  *
211  * @brief   Enables or disables the specified I2C peripheral.
212  *
213  * @param   I2Cx - where x can be 1 or 2 to select the I2C peripheral.
214  *          NewState - ENABLE or DISABLE.
215  *
216  * @return  none
217  */
I2C_Cmd(I2C_TypeDef * I2Cx,FunctionalState NewState)218 void I2C_Cmd(I2C_TypeDef *I2Cx, FunctionalState NewState)
219 {
220     if(NewState != DISABLE)
221     {
222         I2Cx->CTLR1 |= CTLR1_PE_Set;
223     }
224     else
225     {
226         I2Cx->CTLR1 &= CTLR1_PE_Reset;
227     }
228 }
229 
230 /*********************************************************************
231  * @fn      I2C_DMACmd
232  *
233  * @brief   Enables or disables the specified I2C DMA requests.
234  *
235  * @param   I2Cx - where x can be 1 or 2 to select the I2C peripheral.
236  *          NewState - ENABLE or DISABLE.
237  *
238  * @return  none
239  */
I2C_DMACmd(I2C_TypeDef * I2Cx,FunctionalState NewState)240 void I2C_DMACmd(I2C_TypeDef *I2Cx, FunctionalState NewState)
241 {
242     if(NewState != DISABLE)
243     {
244         I2Cx->CTLR2 |= CTLR2_DMAEN_Set;
245     }
246     else
247     {
248         I2Cx->CTLR2 &= CTLR2_DMAEN_Reset;
249     }
250 }
251 
252 /*********************************************************************
253  * @fn      I2C_DMALastTransferCmd
254  *
255  * @brief   Specifies if the next DMA transfer will be the last one.
256  *
257  * @param   I2Cx - where x can be 1 or 2 to select the I2C peripheral.
258  *          NewState - ENABLE or DISABLE.
259  *
260  * @return  none
261  */
I2C_DMALastTransferCmd(I2C_TypeDef * I2Cx,FunctionalState NewState)262 void I2C_DMALastTransferCmd(I2C_TypeDef *I2Cx, FunctionalState NewState)
263 {
264     if(NewState != DISABLE)
265     {
266         I2Cx->CTLR2 |= CTLR2_LAST_Set;
267     }
268     else
269     {
270         I2Cx->CTLR2 &= CTLR2_LAST_Reset;
271     }
272 }
273 
274 /*********************************************************************
275  * @fn      I2C_GenerateSTART
276  *
277  * @brief   Generates I2Cx communication START condition.
278  *
279  * @param   I2Cx - where x can be 1 or 2 to select the I2C peripheral.
280  *          NewState - ENABLE or DISABLE.
281  *
282  * @return  none
283  */
I2C_GenerateSTART(I2C_TypeDef * I2Cx,FunctionalState NewState)284 void I2C_GenerateSTART(I2C_TypeDef *I2Cx, FunctionalState NewState)
285 {
286     if(NewState != DISABLE)
287     {
288         I2Cx->CTLR1 |= CTLR1_START_Set;
289     }
290     else
291     {
292         I2Cx->CTLR1 &= CTLR1_START_Reset;
293     }
294 }
295 
296 /*********************************************************************
297  * @fn      I2C_GenerateSTOP
298  *
299  * @brief   Generates I2Cx communication STOP condition.
300  *
301  * @param   I2Cx - where x can be 1 or 2 to select the I2C peripheral.
302  *          NewState - ENABLE or DISABLE.
303  *
304  * @return  none
305  */
I2C_GenerateSTOP(I2C_TypeDef * I2Cx,FunctionalState NewState)306 void I2C_GenerateSTOP(I2C_TypeDef *I2Cx, FunctionalState NewState)
307 {
308     if(NewState != DISABLE)
309     {
310         I2Cx->CTLR1 |= CTLR1_STOP_Set;
311     }
312     else
313     {
314         I2Cx->CTLR1 &= CTLR1_STOP_Reset;
315     }
316 }
317 
318 /*********************************************************************
319  * @fn      I2C_AcknowledgeConfig
320  *
321  * @brief   Enables or disables the specified I2C acknowledge feature.
322  *
323  * @param   I2Cx - where x can be 1 or 2 to select the I2C peripheral.
324  *          NewState - ENABLE or DISABLE.
325  *
326  * @return  none
327  */
I2C_AcknowledgeConfig(I2C_TypeDef * I2Cx,FunctionalState NewState)328 void I2C_AcknowledgeConfig(I2C_TypeDef *I2Cx, FunctionalState NewState)
329 {
330     if(NewState != DISABLE)
331     {
332         I2Cx->CTLR1 |= CTLR1_ACK_Set;
333     }
334     else
335     {
336         I2Cx->CTLR1 &= CTLR1_ACK_Reset;
337     }
338 }
339 
340 /*********************************************************************
341  * @fn      I2C_OwnAddress2Config
342  *
343  * @brief   Configures the specified I2C own address2.
344  *
345  * @param   I2Cx - where x can be 1 or 2 to select the I2C peripheral.
346  *          Address - specifies the 7bit I2C own address2.
347  *
348  * @return  none
349  */
I2C_OwnAddress2Config(I2C_TypeDef * I2Cx,uint8_t Address)350 void I2C_OwnAddress2Config(I2C_TypeDef *I2Cx, uint8_t Address)
351 {
352     uint16_t tmpreg = 0;
353 
354     tmpreg = I2Cx->OADDR2;
355     tmpreg &= OADDR2_ADD2_Reset;
356     tmpreg |= (uint16_t)((uint16_t)Address & (uint16_t)0x00FE);
357     I2Cx->OADDR2 = tmpreg;
358 }
359 
360 /*********************************************************************
361  * @fn      I2C_DualAddressCmd
362  *
363  * @brief   Enables or disables the specified I2C dual addressing mode.
364  *
365  * @param   I2Cx - where x can be 1 or 2 to select the I2C peripheral.
366  *          NewState - ENABLE or DISABLE.
367  *
368  * @return  none
369  */
I2C_DualAddressCmd(I2C_TypeDef * I2Cx,FunctionalState NewState)370 void I2C_DualAddressCmd(I2C_TypeDef *I2Cx, FunctionalState NewState)
371 {
372     if(NewState != DISABLE)
373     {
374         I2Cx->OADDR2 |= OADDR2_ENDUAL_Set;
375     }
376     else
377     {
378         I2Cx->OADDR2 &= OADDR2_ENDUAL_Reset;
379     }
380 }
381 
382 /*********************************************************************
383  * @fn      I2C_GeneralCallCmd
384  *
385  * @brief   Enables or disables the specified I2C general call feature.
386  *
387  * @param   I2Cx - where x can be 1 or 2 to select the I2C peripheral.
388  *          NewState - ENABLE or DISABLE.
389  *
390  * @return  none
391  */
I2C_GeneralCallCmd(I2C_TypeDef * I2Cx,FunctionalState NewState)392 void I2C_GeneralCallCmd(I2C_TypeDef *I2Cx, FunctionalState NewState)
393 {
394     if(NewState != DISABLE)
395     {
396         I2Cx->CTLR1 |= CTLR1_ENGC_Set;
397     }
398     else
399     {
400         I2Cx->CTLR1 &= CTLR1_ENGC_Reset;
401     }
402 }
403 
404 /*********************************************************************
405  * @fn      I2C_ITConfig
406  *
407  * @brief   Enables or disables the specified I2C interrupts.
408  *
409  * @param   I2Cx - where x can be 1 or 2 to select the I2C peripheral.
410  *          I2C_IT - specifies the I2C interrupts sources to be enabled or disabled.
411  *            I2C_IT_BUF - Buffer interrupt mask.
412  *            I2C_IT_EVT - Event interrupt mask.
413  *            I2C_IT_ERR - Error interrupt mask.
414  *          NewState - ENABLE or DISABLE.
415  *
416  * @return  none
417  */
I2C_ITConfig(I2C_TypeDef * I2Cx,uint16_t I2C_IT,FunctionalState NewState)418 void I2C_ITConfig(I2C_TypeDef *I2Cx, uint16_t I2C_IT, FunctionalState NewState)
419 {
420     if(NewState != DISABLE)
421     {
422         I2Cx->CTLR2 |= I2C_IT;
423     }
424     else
425     {
426         I2Cx->CTLR2 &= (uint16_t)~I2C_IT;
427     }
428 }
429 
430 /*********************************************************************
431  * @fn      I2C_SendData
432  *
433  * @brief   Sends a data byte through the I2Cx peripheral.
434  *
435  * @param   I2Cx - where x can be 1 or 2 to select the I2C peripheral.
436  *          Data - Byte to be transmitted.
437  *
438  * @return  none
439  */
I2C_SendData(I2C_TypeDef * I2Cx,uint8_t Data)440 void I2C_SendData(I2C_TypeDef *I2Cx, uint8_t Data)
441 {
442     I2Cx->DATAR = Data;
443 }
444 
445 /*********************************************************************
446  * @fn      I2C_ReceiveData
447  *
448  * @brief   Returns the most recent received data by the I2Cx peripheral.
449  *
450  * @param   I2Cx - where x can be 1 or 2 to select the I2C peripheral.
451  *
452  * @return  The value of the received data.
453  */
I2C_ReceiveData(I2C_TypeDef * I2Cx)454 uint8_t I2C_ReceiveData(I2C_TypeDef *I2Cx)
455 {
456     return (uint8_t)I2Cx->DATAR;
457 }
458 
459 /*********************************************************************
460  * @fn      I2C_Send7bitAddress
461  *
462  * @brief   Transmits the address byte to select the slave device.
463  *
464  * @param   I2Cx - where x can be 1 or 2 to select the I2C peripheral.
465  *          Address - specifies the slave address which will be transmitted.
466  *          I2C_Direction - specifies whether the I2C device will be a
467  *        Transmitter or a Receiver.
468  *            I2C_Direction_Transmitter - Transmitter mode.
469  *            I2C_Direction_Receiver - Receiver mode.
470  *
471  * @return  none
472  */
I2C_Send7bitAddress(I2C_TypeDef * I2Cx,uint8_t Address,uint8_t I2C_Direction)473 void I2C_Send7bitAddress(I2C_TypeDef *I2Cx, uint8_t Address, uint8_t I2C_Direction)
474 {
475     if(I2C_Direction != I2C_Direction_Transmitter)
476     {
477         Address |= OADDR1_ADD0_Set;
478     }
479     else
480     {
481         Address &= OADDR1_ADD0_Reset;
482     }
483 
484     I2Cx->DATAR = Address;
485 }
486 
487 /*********************************************************************
488  * @fn      I2C_ReadRegister
489  *
490  * @brief   Reads the specified I2C register and returns its value.
491  *
492  * @param   I2Cx - where x can be 1 or 2 to select the I2C peripheral.
493  *          I2C_Register - specifies the register to read.
494  *            I2C_Register_CTLR1.
495  *            I2C_Register_CTLR2.
496  *            I2C_Register_OADDR1.
497  *            I2C_Register_OADDR2.
498  *            I2C_Register_DATAR.
499  *            I2C_Register_STAR1.
500  *            I2C_Register_STAR2.
501  *            I2C_Register_CKCFGR.
502  *            I2C_Register_RTR.
503  *
504  * @return  none
505  */
I2C_ReadRegister(I2C_TypeDef * I2Cx,uint8_t I2C_Register)506 uint16_t I2C_ReadRegister(I2C_TypeDef *I2Cx, uint8_t I2C_Register)
507 {
508     __IO uint32_t tmp = 0;
509 
510     tmp = (uint32_t)I2Cx;
511     tmp += I2C_Register;
512 
513     return (*(__IO uint16_t *)tmp);
514 }
515 
516 /*********************************************************************
517  * @fn      I2C_SoftwareResetCmd
518  *
519  * @brief   Enables or disables the specified I2C software reset.
520  *
521  * @param   I2Cx - where x can be 1 or 2 to select the I2C peripheral.
522  *          NewState - ENABLE or DISABLE.
523  *
524  * @return  none
525  */
I2C_SoftwareResetCmd(I2C_TypeDef * I2Cx,FunctionalState NewState)526 void I2C_SoftwareResetCmd(I2C_TypeDef *I2Cx, FunctionalState NewState)
527 {
528     if(NewState != DISABLE)
529     {
530         I2Cx->CTLR1 |= CTLR1_SWRST_Set;
531     }
532     else
533     {
534         I2Cx->CTLR1 &= CTLR1_SWRST_Reset;
535     }
536 }
537 
538 /*********************************************************************
539  * @fn      I2C_NACKPositionConfig
540  *
541  * @brief   Selects the specified I2C NACK position in master receiver mode.
542  *
543  * @param   I2Cx - where x can be 1 or 2 to select the I2C peripheral.
544  *          I2C_NACKPosition - specifies the NACK position.
545  *            I2C_NACKPosition_Next - indicates that the next byte will be
546  *        the last received byte.
547  *            I2C_NACKPosition_Current - indicates that current byte is the
548  *        last received byte.
549  *
550  * @return  none
551  */
I2C_NACKPositionConfig(I2C_TypeDef * I2Cx,uint16_t I2C_NACKPosition)552 void I2C_NACKPositionConfig(I2C_TypeDef *I2Cx, uint16_t I2C_NACKPosition)
553 {
554     if(I2C_NACKPosition == I2C_NACKPosition_Next)
555     {
556         I2Cx->CTLR1 |= I2C_NACKPosition_Next;
557     }
558     else
559     {
560         I2Cx->CTLR1 &= I2C_NACKPosition_Current;
561     }
562 }
563 
564 /*********************************************************************
565  * @fn      I2C_SMBusAlertConfig
566  *
567  * @brief   Drives the SMBusAlert pin high or low for the specified I2C.
568  *
569  * @param   I2Cx - where x can be 1 or 2 to select the I2C peripheral.
570  *          I2C_SMBusAlert - specifies SMBAlert pin level.
571  *            I2C_SMBusAlert_Low - SMBAlert pin driven low.
572  *            I2C_SMBusAlert_High - SMBAlert pin driven high.
573  *
574  * @return  none
575  */
I2C_SMBusAlertConfig(I2C_TypeDef * I2Cx,uint16_t I2C_SMBusAlert)576 void I2C_SMBusAlertConfig(I2C_TypeDef *I2Cx, uint16_t I2C_SMBusAlert)
577 {
578     if(I2C_SMBusAlert == I2C_SMBusAlert_Low)
579     {
580         I2Cx->CTLR1 |= I2C_SMBusAlert_Low;
581     }
582     else
583     {
584         I2Cx->CTLR1 &= I2C_SMBusAlert_High;
585     }
586 }
587 
588 /*********************************************************************
589  * @fn      I2C_TransmitPEC
590  *
591  * @brief   Enables or disables the specified I2C PEC transfer.
592  *
593  * @param   I2Cx - where x can be 1 or 2 to select the I2C peripheral.
594  *          NewState - ENABLE or DISABLE.
595  *
596  * @return  none
597  */
I2C_TransmitPEC(I2C_TypeDef * I2Cx,FunctionalState NewState)598 void I2C_TransmitPEC(I2C_TypeDef *I2Cx, FunctionalState NewState)
599 {
600     if(NewState != DISABLE)
601     {
602         I2Cx->CTLR1 |= CTLR1_PEC_Set;
603     }
604     else
605     {
606         I2Cx->CTLR1 &= CTLR1_PEC_Reset;
607     }
608 }
609 
610 /*********************************************************************
611  * @fn      I2C_PECPositionConfig
612  *
613  * @brief   Selects the specified I2C PEC position.
614  *
615  * @param   I2Cx - where x can be 1 or 2 to select the I2C peripheral.
616  *          I2C_PECPosition - specifies the PEC position.
617  *            I2C_PECPosition_Next - indicates that the next byte is PEC.
618  *            I2C_PECPosition_Current - indicates that current byte is PEC.
619  *
620  * @return  none
621  */
I2C_PECPositionConfig(I2C_TypeDef * I2Cx,uint16_t I2C_PECPosition)622 void I2C_PECPositionConfig(I2C_TypeDef *I2Cx, uint16_t I2C_PECPosition)
623 {
624     if(I2C_PECPosition == I2C_PECPosition_Next)
625     {
626         I2Cx->CTLR1 |= I2C_PECPosition_Next;
627     }
628     else
629     {
630         I2Cx->CTLR1 &= I2C_PECPosition_Current;
631     }
632 }
633 
634 /*********************************************************************
635  * @fn      I2C_CalculatePEC
636  *
637  * @brief   Enables or disables the PEC value calculation of the transferred bytes.
638  *
639  * @param   I2Cx- where x can be 1 or 2 to select the I2C peripheral.
640  *          NewState - ENABLE or DISABLE.
641  *
642  * @return  none
643  */
I2C_CalculatePEC(I2C_TypeDef * I2Cx,FunctionalState NewState)644 void I2C_CalculatePEC(I2C_TypeDef *I2Cx, FunctionalState NewState)
645 {
646     if(NewState != DISABLE)
647     {
648         I2Cx->CTLR1 |= CTLR1_ENPEC_Set;
649     }
650     else
651     {
652         I2Cx->CTLR1 &= CTLR1_ENPEC_Reset;
653     }
654 }
655 
656 /*********************************************************************
657  * @fn      I2C_GetPEC
658  *
659  * @brief   Returns the PEC value for the specified I2C.
660  *
661  * @param   I2Cx - where x can be 1 or 2 to select the I2C peripheral.
662  *
663  * @return  The PEC value.
664  */
I2C_GetPEC(I2C_TypeDef * I2Cx)665 uint8_t I2C_GetPEC(I2C_TypeDef *I2Cx)
666 {
667     return ((I2Cx->STAR2) >> 8);
668 }
669 
670 /*********************************************************************
671  * @fn      I2C_ARPCmd
672  *
673  * @brief   Enables or disables the specified I2C ARP.
674  *
675  * @param   I2Cx - where x can be 1 or 2 to select the I2C peripheral.
676  *            NewState - ENABLE or DISABLE.
677  *
678  * @return  The PEC value.
679  */
I2C_ARPCmd(I2C_TypeDef * I2Cx,FunctionalState NewState)680 void I2C_ARPCmd(I2C_TypeDef *I2Cx, FunctionalState NewState)
681 {
682     if(NewState != DISABLE)
683     {
684         I2Cx->CTLR1 |= CTLR1_ENARP_Set;
685     }
686     else
687     {
688         I2Cx->CTLR1 &= CTLR1_ENARP_Reset;
689     }
690 }
691 
692 /*********************************************************************
693  * @fn      I2C_StretchClockCmd
694  *
695  * @brief   Enables or disables the specified I2C Clock stretching.
696  *
697  * @param   I2Cx - where x can be 1 or 2 to select the I2C peripheral.
698  *          NewState - ENABLE or DISABLE.
699  *
700  * @return  none
701  */
I2C_StretchClockCmd(I2C_TypeDef * I2Cx,FunctionalState NewState)702 void I2C_StretchClockCmd(I2C_TypeDef *I2Cx, FunctionalState NewState)
703 {
704     if(NewState == DISABLE)
705     {
706         I2Cx->CTLR1 |= CTLR1_NOSTRETCH_Set;
707     }
708     else
709     {
710         I2Cx->CTLR1 &= CTLR1_NOSTRETCH_Reset;
711     }
712 }
713 
714 /*********************************************************************
715  * @fn      I2C_FastModeDutyCycleConfig
716  *
717  * @brief   Selects the specified I2C fast mode duty cycle.
718  *
719  * @param   I2Cx - where x can be 1 or 2 to select the I2C peripheral.
720  *          I2C_DutyCycle - specifies the fast mode duty cycle.
721  *            I2C_DutyCycle_2 - I2C fast mode Tlow/Thigh = 2.
722  *            I2C_DutyCycle_16_9 - I2C fast mode Tlow/Thigh = 16/9.
723  *
724  * @return  none
725  */
I2C_FastModeDutyCycleConfig(I2C_TypeDef * I2Cx,uint16_t I2C_DutyCycle)726 void I2C_FastModeDutyCycleConfig(I2C_TypeDef *I2Cx, uint16_t I2C_DutyCycle)
727 {
728     if(I2C_DutyCycle != I2C_DutyCycle_16_9)
729     {
730         I2Cx->CKCFGR &= I2C_DutyCycle_2;
731     }
732     else
733     {
734         I2Cx->CKCFGR |= I2C_DutyCycle_16_9;
735     }
736 }
737 
738 /*********************************************************************
739  * @fn      I2C_CheckEvent
740  *
741  * @brief   Checks whether the last I2Cx Event is equal to the one passed
742  *        as parameter.
743  *
744  * @param   I2Cx- where x can be 1 or 2 to select the I2C peripheral.
745  *          I2C_EVENT: specifies the event to be checked.
746  *             I2C_EVENT_SLAVE_TRANSMITTER_ADDRESS_MATCHED - EV1.
747  *             I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED - EV1.
748  *             I2C_EVENT_SLAVE_TRANSMITTER_SECONDADDRESS_MATCHED - EV1.
749  *             I2C_EVENT_SLAVE_RECEIVER_SECONDADDRESS_MATCHED - EV1.
750  *             I2C_EVENT_SLAVE_GENERALCALLADDRESS_MATCHED - EV1.
751  *             I2C_EVENT_SLAVE_BYTE_RECEIVED - EV2.
752  *             (I2C_EVENT_SLAVE_BYTE_RECEIVED | I2C_FLAG_DUALF) - EV2.
753  *             (I2C_EVENT_SLAVE_BYTE_RECEIVED | I2C_FLAG_GENCALL) - EV2.
754  *             I2C_EVENT_SLAVE_BYTE_TRANSMITTED - EV3.
755  *             (I2C_EVENT_SLAVE_BYTE_TRANSMITTED | I2C_FLAG_DUALF) - EV3.
756  *             (I2C_EVENT_SLAVE_BYTE_TRANSMITTED | I2C_FLAG_GENCALL) - EV3.
757  *             I2C_EVENT_SLAVE_ACK_FAILURE - EV3_2.
758  *             I2C_EVENT_SLAVE_STOP_DETECTED - EV4.
759  *             I2C_EVENT_MASTER_MODE_SELECT - EV5.
760  *             I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED - EV6.
761  *             I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED - EV6.
762  *             I2C_EVENT_MASTER_BYTE_RECEIVED - EV7.
763  *             I2C_EVENT_MASTER_BYTE_TRANSMITTING - EV8.
764  *             I2C_EVENT_MASTER_BYTE_TRANSMITTED - EV8_2.
765  *             I2C_EVENT_MASTER_MODE_ADDRESS10 - EV9.
766  *
767  * @return  none
768  */
I2C_CheckEvent(I2C_TypeDef * I2Cx,uint32_t I2C_EVENT)769 ErrorStatus I2C_CheckEvent(I2C_TypeDef *I2Cx, uint32_t I2C_EVENT)
770 {
771     uint32_t    lastevent = 0;
772     uint32_t    flag1 = 0, flag2 = 0;
773     ErrorStatus status = ERROR;
774 
775     flag1 = I2Cx->STAR1;
776     flag2 = I2Cx->STAR2;
777     flag2 = flag2 << 16;
778 
779     lastevent = (flag1 | flag2) & FLAG_Mask;
780 
781     if((lastevent & I2C_EVENT) == I2C_EVENT)
782     {
783         status = SUCCESS;
784     }
785     else
786     {
787         status = ERROR;
788     }
789 
790     return status;
791 }
792 
793 /*********************************************************************
794  * @fn      I2C_GetLastEvent
795  *
796  * @brief   Returns the last I2Cx Event.
797  *
798  * @param   I2Cx - where x can be 1 or 2 to select the I2C peripheral.
799  *
800  * @return  none
801  */
I2C_GetLastEvent(I2C_TypeDef * I2Cx)802 uint32_t I2C_GetLastEvent(I2C_TypeDef *I2Cx)
803 {
804     uint32_t lastevent = 0;
805     uint32_t flag1 = 0, flag2 = 0;
806 
807     flag1 = I2Cx->STAR1;
808     flag2 = I2Cx->STAR2;
809     flag2 = flag2 << 16;
810     lastevent = (flag1 | flag2) & FLAG_Mask;
811 
812     return lastevent;
813 }
814 
815 /*********************************************************************
816  * @fn      I2C_GetFlagStatus
817  *
818  * @brief   Checks whether the last I2Cx Event is equal to the one passed
819  *        as parameter.
820  *
821  * @param   I2Cx - where x can be 1 or 2 to select the I2C peripheral.
822  *          I2C_FLAG - specifies the flag to check.
823  *            I2C_FLAG_DUALF - Dual flag (Slave mode).
824  *            I2C_FLAG_SMBHOST - SMBus host header (Slave mode).
825  *            I2C_FLAG_SMBDEFAULT - SMBus default header (Slave mode).
826  *            I2C_FLAG_GENCALL - General call header flag (Slave mode).
827  *            I2C_FLAG_TRA - Transmitter/Receiver flag.
828  *            I2C_FLAG_BUSY - Bus busy flag.
829  *            I2C_FLAG_MSL - Master/Slave flag.
830  *            I2C_FLAG_SMBALERT - SMBus Alert flag.
831  *            I2C_FLAG_TIMEOUT - Timeout or Tlow error flag.
832  *            I2C_FLAG_PECERR - PEC error in reception flag.
833  *            I2C_FLAG_OVR - Overrun/Underrun flag (Slave mode).
834  *            I2C_FLAG_AF - Acknowledge failure flag.
835  *            I2C_FLAG_ARLO - Arbitration lost flag (Master mode).
836  *            I2C_FLAG_BERR - Bus error flag.
837  *            I2C_FLAG_TXE - Data register empty flag (Transmitter).
838  *            I2C_FLAG_RXNE- Data register not empty (Receiver) flag.
839  *            I2C_FLAG_STOPF - Stop detection flag (Slave mode).
840  *            I2C_FLAG_ADD10 - 10-bit header sent flag (Master mode).
841  *            I2C_FLAG_BTF - Byte transfer finished flag.
842  *            I2C_FLAG_ADDR - Address sent flag (Master mode) "ADSL"
843  *        Address matched flag (Slave mode)"ENDA".
844  *            I2C_FLAG_SB - Start bit flag (Master mode).
845  *
846  * @return  none
847  */
I2C_GetFlagStatus(I2C_TypeDef * I2Cx,uint32_t I2C_FLAG)848 FlagStatus I2C_GetFlagStatus(I2C_TypeDef *I2Cx, uint32_t I2C_FLAG)
849 {
850     FlagStatus    bitstatus = RESET;
851     __IO uint32_t i2creg = 0, i2cxbase = 0;
852 
853     i2cxbase = (uint32_t)I2Cx;
854     i2creg = I2C_FLAG >> 28;
855     I2C_FLAG &= FLAG_Mask;
856 
857     if(i2creg != 0)
858     {
859         i2cxbase += 0x14;
860     }
861     else
862     {
863         I2C_FLAG = (uint32_t)(I2C_FLAG >> 16);
864         i2cxbase += 0x18;
865     }
866 
867     if(((*(__IO uint32_t *)i2cxbase) & I2C_FLAG) != (uint32_t)RESET)
868     {
869         bitstatus = SET;
870     }
871     else
872     {
873         bitstatus = RESET;
874     }
875 
876     return bitstatus;
877 }
878 
879 /*********************************************************************
880  * @fn      I2C_ClearFlag
881  *
882  * @brief   Clears the I2Cx's pending flags.
883  *
884  * @param   I2Cx - where x can be 1 or 2 to select the I2C peripheral.
885  *          I2C_FLAG - specifies the flag to clear.
886  *            I2C_FLAG_SMBALERT - SMBus Alert flag.
887  *            I2C_FLAG_TIMEOUT - Timeout or Tlow error flag.
888  *            I2C_FLAG_PECERR - PEC error in reception flag.
889  *            I2C_FLAG_OVR - Overrun/Underrun flag (Slave mode).
890  *            I2C_FLAG_AF - Acknowledge failure flag.
891  *            I2C_FLAG_ARLO - Arbitration lost flag (Master mode).
892  *            I2C_FLAG_BERR - Bus error flag.
893  *
894  * @return  none
895  */
I2C_ClearFlag(I2C_TypeDef * I2Cx,uint32_t I2C_FLAG)896 void I2C_ClearFlag(I2C_TypeDef *I2Cx, uint32_t I2C_FLAG)
897 {
898     uint32_t flagpos = 0;
899 
900     flagpos = I2C_FLAG & FLAG_Mask;
901     I2Cx->STAR1 = (uint16_t)~flagpos;
902 }
903 
904 /*********************************************************************
905  * @fn      I2C_GetITStatus
906  *
907  * @brief   Checks whether the specified I2C interrupt has occurred or not.
908  *
909  * @param   I2Cx - where x can be 1 or 2 to select the I2C peripheral.
910  *          II2C_IT - specifies the interrupt source to check.
911  *            I2C_IT_SMBALERT - SMBus Alert flag.
912  *            I2C_IT_TIMEOUT - Timeout or Tlow error flag.
913  *            I2C_IT_PECERR - PEC error in reception flag.
914  *            I2C_IT_OVR - Overrun/Underrun flag (Slave mode).
915  *            I2C_IT_AF - Acknowledge failure flag.
916  *            I2C_IT_ARLO - Arbitration lost flag (Master mode).
917  *            I2C_IT_BERR - Bus error flag.
918  *            I2C_IT_TXE - Data register empty flag (Transmitter).
919  *            I2C_IT_RXNE - Data register not empty (Receiver) flag.
920  *            I2C_IT_STOPF - Stop detection flag (Slave mode).
921  *            I2C_IT_ADD10 - 10-bit header sent flag (Master mode).
922  *            I2C_IT_BTF - Byte transfer finished flag.
923  *            I2C_IT_ADDR - Address sent flag (Master mode) "ADSL"  Address matched
924  *        flag (Slave mode)"ENDAD".
925  *            I2C_IT_SB - Start bit flag (Master mode).
926  *
927  * @return  none
928  */
I2C_GetITStatus(I2C_TypeDef * I2Cx,uint32_t I2C_IT)929 ITStatus I2C_GetITStatus(I2C_TypeDef *I2Cx, uint32_t I2C_IT)
930 {
931     ITStatus bitstatus = RESET;
932     uint32_t enablestatus = 0;
933 
934     enablestatus = (uint32_t)(((I2C_IT & ITEN_Mask) >> 16) & (I2Cx->CTLR2));
935     I2C_IT &= FLAG_Mask;
936 
937     if(((I2Cx->STAR1 & I2C_IT) != (uint32_t)RESET) && enablestatus)
938     {
939         bitstatus = SET;
940     }
941     else
942     {
943         bitstatus = RESET;
944     }
945 
946     return bitstatus;
947 }
948 
949 /*********************************************************************
950  * @fn      I2C_ClearITPendingBit
951  *
952  * @brief   Clears the I2Cx interrupt pending bits.
953  *
954  * @param   I2Cx - where x can be 1 or 2 to select the I2C peripheral.
955  *          I2C_IT - specifies the interrupt pending bit to clear.
956  *            I2C_IT_SMBALERT - SMBus Alert interrupt.
957  *            I2C_IT_TIMEOUT - Timeout or Tlow error interrupt.
958  *            I2C_IT_PECERR - PEC error in reception  interrupt.
959  *            I2C_IT_OVR - Overrun/Underrun interrupt (Slave mode).
960  *            I2C_IT_AF - Acknowledge failure interrupt.
961  *            I2C_IT_ARLO - Arbitration lost interrupt (Master mode).
962  *            I2C_IT_BERR - Bus error interrupt.
963  *
964  * @return  none
965  */
I2C_ClearITPendingBit(I2C_TypeDef * I2Cx,uint32_t I2C_IT)966 void I2C_ClearITPendingBit(I2C_TypeDef *I2Cx, uint32_t I2C_IT)
967 {
968     uint32_t flagpos = 0;
969 
970     flagpos = I2C_IT & FLAG_Mask;
971     I2Cx->STAR1 = (uint16_t)~flagpos;
972 }
973 
974 
975 
976 
977 
978 
979 
980