]> jspc29.x-matter.uni-frankfurt.de Git - mvd_firmware.git/blob
889672683fa9646c11ce36fbc51dbdc9f97f6b0a
[mvd_firmware.git] /
1 /**\r
2   ******************************************************************************\r
3   * @file    stm32f10x_i2c.c\r
4   * @author  MCD Application Team\r
5   * @version V3.5.0\r
6   * @date    11-March-2011\r
7   * @brief   This file provides all the I2C firmware functions.\r
8   ******************************************************************************\r
9   * @attention\r
10   *\r
11   * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS\r
12   * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE\r
13   * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY\r
14   * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING\r
15   * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE\r
16   * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.\r
17   *\r
18   * <h2><center>&copy; COPYRIGHT 2011 STMicroelectronics</center></h2>\r
19   ******************************************************************************\r
20   */\r
21 \r
22 /* Includes ------------------------------------------------------------------*/\r
23 #include "stm32f10x_i2c.h"\r
24 #include "stm32f10x_rcc.h"\r
25 \r
26 \r
27 /** @addtogroup STM32F10x_StdPeriph_Driver\r
28   * @{\r
29   */\r
30 \r
31 /** @defgroup I2C \r
32   * @brief I2C driver modules\r
33   * @{\r
34   */ \r
35 \r
36 /** @defgroup I2C_Private_TypesDefinitions\r
37   * @{\r
38   */\r
39 \r
40 /**\r
41   * @}\r
42   */\r
43 \r
44 /** @defgroup I2C_Private_Defines\r
45   * @{\r
46   */\r
47 \r
48 /* I2C SPE mask */\r
49 #define CR1_PE_Set              ((uint16_t)0x0001)\r
50 #define CR1_PE_Reset            ((uint16_t)0xFFFE)\r
51 \r
52 /* I2C START mask */\r
53 #define CR1_START_Set           ((uint16_t)0x0100)\r
54 #define CR1_START_Reset         ((uint16_t)0xFEFF)\r
55 \r
56 /* I2C STOP mask */\r
57 #define CR1_STOP_Set            ((uint16_t)0x0200)\r
58 #define CR1_STOP_Reset          ((uint16_t)0xFDFF)\r
59 \r
60 /* I2C ACK mask */\r
61 #define CR1_ACK_Set             ((uint16_t)0x0400)\r
62 #define CR1_ACK_Reset           ((uint16_t)0xFBFF)\r
63 \r
64 /* I2C ENGC mask */\r
65 #define CR1_ENGC_Set            ((uint16_t)0x0040)\r
66 #define CR1_ENGC_Reset          ((uint16_t)0xFFBF)\r
67 \r
68 /* I2C SWRST mask */\r
69 #define CR1_SWRST_Set           ((uint16_t)0x8000)\r
70 #define CR1_SWRST_Reset         ((uint16_t)0x7FFF)\r
71 \r
72 /* I2C PEC mask */\r
73 #define CR1_PEC_Set             ((uint16_t)0x1000)\r
74 #define CR1_PEC_Reset           ((uint16_t)0xEFFF)\r
75 \r
76 /* I2C ENPEC mask */\r
77 #define CR1_ENPEC_Set           ((uint16_t)0x0020)\r
78 #define CR1_ENPEC_Reset         ((uint16_t)0xFFDF)\r
79 \r
80 /* I2C ENARP mask */\r
81 #define CR1_ENARP_Set           ((uint16_t)0x0010)\r
82 #define CR1_ENARP_Reset         ((uint16_t)0xFFEF)\r
83 \r
84 /* I2C NOSTRETCH mask */\r
85 #define CR1_NOSTRETCH_Set       ((uint16_t)0x0080)\r
86 #define CR1_NOSTRETCH_Reset     ((uint16_t)0xFF7F)\r
87 \r
88 /* I2C registers Masks */\r
89 #define CR1_CLEAR_Mask          ((uint16_t)0xFBF5)\r
90 \r
91 /* I2C DMAEN mask */\r
92 #define CR2_DMAEN_Set           ((uint16_t)0x0800)\r
93 #define CR2_DMAEN_Reset         ((uint16_t)0xF7FF)\r
94 \r
95 /* I2C LAST mask */\r
96 #define CR2_LAST_Set            ((uint16_t)0x1000)\r
97 #define CR2_LAST_Reset          ((uint16_t)0xEFFF)\r
98 \r
99 /* I2C FREQ mask */\r
100 #define CR2_FREQ_Reset          ((uint16_t)0xFFC0)\r
101 \r
102 /* I2C ADD0 mask */\r
103 #define OAR1_ADD0_Set           ((uint16_t)0x0001)\r
104 #define OAR1_ADD0_Reset         ((uint16_t)0xFFFE)\r
105 \r
106 /* I2C ENDUAL mask */\r
107 #define OAR2_ENDUAL_Set         ((uint16_t)0x0001)\r
108 #define OAR2_ENDUAL_Reset       ((uint16_t)0xFFFE)\r
109 \r
110 /* I2C ADD2 mask */\r
111 #define OAR2_ADD2_Reset         ((uint16_t)0xFF01)\r
112 \r
113 /* I2C F/S mask */\r
114 #define CCR_FS_Set              ((uint16_t)0x8000)\r
115 \r
116 /* I2C CCR mask */\r
117 #define CCR_CCR_Set             ((uint16_t)0x0FFF)\r
118 \r
119 /* I2C FLAG mask */\r
120 #define FLAG_Mask               ((uint32_t)0x00FFFFFF)\r
121 \r
122 /* I2C Interrupt Enable mask */\r
123 #define ITEN_Mask               ((uint32_t)0x07000000)\r
124 \r
125 /**\r
126   * @}\r
127   */\r
128 \r
129 /** @defgroup I2C_Private_Macros\r
130   * @{\r
131   */\r
132 \r
133 /**\r
134   * @}\r
135   */\r
136 \r
137 /** @defgroup I2C_Private_Variables\r
138   * @{\r
139   */\r
140 \r
141 /**\r
142   * @}\r
143   */\r
144 \r
145 /** @defgroup I2C_Private_FunctionPrototypes\r
146   * @{\r
147   */\r
148 \r
149 /**\r
150   * @}\r
151   */\r
152 \r
153 /** @defgroup I2C_Private_Functions\r
154   * @{\r
155   */\r
156 \r
157 /**\r
158   * @brief  Deinitializes the I2Cx peripheral registers to their default reset values.\r
159   * @param  I2Cx: where x can be 1 or 2 to select the I2C peripheral.\r
160   * @retval None\r
161   */\r
162 void I2C_DeInit(I2C_TypeDef* I2Cx)\r
163 {\r
164   /* Check the parameters */\r
165   assert_param(IS_I2C_ALL_PERIPH(I2Cx));\r
166 \r
167   if (I2Cx == I2C1)\r
168   {\r
169     /* Enable I2C1 reset state */\r
170     RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C1, ENABLE);\r
171     /* Release I2C1 from reset state */\r
172     RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C1, DISABLE);\r
173   }\r
174   else\r
175   {\r
176     /* Enable I2C2 reset state */\r
177     RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C2, ENABLE);\r
178     /* Release I2C2 from reset state */\r
179     RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C2, DISABLE);\r
180   }\r
181 }\r
182 \r
183 /**\r
184   * @brief  Initializes the I2Cx peripheral according to the specified \r
185   *   parameters in the I2C_InitStruct.\r
186   * @param  I2Cx: where x can be 1 or 2 to select the I2C peripheral.\r
187   * @param  I2C_InitStruct: pointer to a I2C_InitTypeDef structure that\r
188   *   contains the configuration information for the specified I2C peripheral.\r
189   * @retval None\r
190   */\r
191 void I2C_Init(I2C_TypeDef* I2Cx, I2C_InitTypeDef* I2C_InitStruct)\r
192 {\r
193   uint16_t tmpreg = 0, freqrange = 0;\r
194   uint16_t result = 0x04;\r
195   uint32_t pclk1 = 8000000;\r
196   RCC_ClocksTypeDef  rcc_clocks;\r
197   /* Check the parameters */\r
198   assert_param(IS_I2C_ALL_PERIPH(I2Cx));\r
199   assert_param(IS_I2C_CLOCK_SPEED(I2C_InitStruct->I2C_ClockSpeed));\r
200   assert_param(IS_I2C_MODE(I2C_InitStruct->I2C_Mode));\r
201   assert_param(IS_I2C_DUTY_CYCLE(I2C_InitStruct->I2C_DutyCycle));\r
202   assert_param(IS_I2C_OWN_ADDRESS1(I2C_InitStruct->I2C_OwnAddress1));\r
203   assert_param(IS_I2C_ACK_STATE(I2C_InitStruct->I2C_Ack));\r
204   assert_param(IS_I2C_ACKNOWLEDGE_ADDRESS(I2C_InitStruct->I2C_AcknowledgedAddress));\r
205 \r
206 /*---------------------------- I2Cx CR2 Configuration ------------------------*/\r
207   /* Get the I2Cx CR2 value */\r
208   tmpreg = I2Cx->CR2;\r
209   /* Clear frequency FREQ[5:0] bits */\r
210   tmpreg &= CR2_FREQ_Reset;\r
211   /* Get pclk1 frequency value */\r
212   RCC_GetClocksFreq(&rcc_clocks);\r
213   pclk1 = rcc_clocks.PCLK1_Frequency;\r
214   /* Set frequency bits depending on pclk1 value */\r
215   freqrange = (uint16_t)(pclk1 / 1000000);\r
216   tmpreg |= freqrange;\r
217   /* Write to I2Cx CR2 */\r
218   I2Cx->CR2 = tmpreg;\r
219 \r
220 /*---------------------------- I2Cx CCR Configuration ------------------------*/\r
221   /* Disable the selected I2C peripheral to configure TRISE */\r
222   I2Cx->CR1 &= CR1_PE_Reset;\r
223   /* Reset tmpreg value */\r
224   /* Clear F/S, DUTY and CCR[11:0] bits */\r
225   tmpreg = 0;\r
226 \r
227   /* Configure speed in standard mode */\r
228   if (I2C_InitStruct->I2C_ClockSpeed <= 100000)\r
229   {\r
230     /* Standard mode speed calculate */\r
231     result = (uint16_t)(pclk1 / (I2C_InitStruct->I2C_ClockSpeed << 1));\r
232     /* Test if CCR value is under 0x4*/\r
233     if (result < 0x04)\r
234     {\r
235       /* Set minimum allowed value */\r
236       result = 0x04;  \r
237     }\r
238     /* Set speed value for standard mode */\r
239     tmpreg |= result;     \r
240     /* Set Maximum Rise Time for standard mode */\r
241     I2Cx->TRISE = freqrange + 1; \r
242   }\r
243   /* Configure speed in fast mode */\r
244   else /*(I2C_InitStruct->I2C_ClockSpeed <= 400000)*/\r
245   {\r
246     if (I2C_InitStruct->I2C_DutyCycle == I2C_DutyCycle_2)\r
247     {\r
248       /* Fast mode speed calculate: Tlow/Thigh = 2 */\r
249       result = (uint16_t)(pclk1 / (I2C_InitStruct->I2C_ClockSpeed * 3));\r
250     }\r
251     else /*I2C_InitStruct->I2C_DutyCycle == I2C_DutyCycle_16_9*/\r
252     {\r
253       /* Fast mode speed calculate: Tlow/Thigh = 16/9 */\r
254       result = (uint16_t)(pclk1 / (I2C_InitStruct->I2C_ClockSpeed * 25));\r
255       /* Set DUTY bit */\r
256       result |= I2C_DutyCycle_16_9;\r
257     }\r
258 \r
259     /* Test if CCR value is under 0x1*/\r
260     if ((result & CCR_CCR_Set) == 0)\r
261     {\r
262       /* Set minimum allowed value */\r
263       result |= (uint16_t)0x0001;  \r
264     }\r
265     /* Set speed value and set F/S bit for fast mode */\r
266     tmpreg |= (uint16_t)(result | CCR_FS_Set);\r
267     /* Set Maximum Rise Time for fast mode */\r
268     I2Cx->TRISE = (uint16_t)(((freqrange * (uint16_t)300) / (uint16_t)1000) + (uint16_t)1);  \r
269   }\r
270 \r
271   /* Write to I2Cx CCR */\r
272   I2Cx->CCR = tmpreg;\r
273   /* Enable the selected I2C peripheral */\r
274   I2Cx->CR1 |= CR1_PE_Set;\r
275 \r
276 /*---------------------------- I2Cx CR1 Configuration ------------------------*/\r
277   /* Get the I2Cx CR1 value */\r
278   tmpreg = I2Cx->CR1;\r
279   /* Clear ACK, SMBTYPE and  SMBUS bits */\r
280   tmpreg &= CR1_CLEAR_Mask;\r
281   /* Configure I2Cx: mode and acknowledgement */\r
282   /* Set SMBTYPE and SMBUS bits according to I2C_Mode value */\r
283   /* Set ACK bit according to I2C_Ack value */\r
284   tmpreg |= (uint16_t)((uint32_t)I2C_InitStruct->I2C_Mode | I2C_InitStruct->I2C_Ack);\r
285   /* Write to I2Cx CR1 */\r
286   I2Cx->CR1 = tmpreg;\r
287 \r
288 /*---------------------------- I2Cx OAR1 Configuration -----------------------*/\r
289   /* Set I2Cx Own Address1 and acknowledged address */\r
290   I2Cx->OAR1 = (I2C_InitStruct->I2C_AcknowledgedAddress | I2C_InitStruct->I2C_OwnAddress1);\r
291 }\r
292 \r
293 /**\r
294   * @brief  Fills each I2C_InitStruct member with its default value.\r
295   * @param  I2C_InitStruct: pointer to an I2C_InitTypeDef structure which will be initialized.\r
296   * @retval None\r
297   */\r
298 void I2C_StructInit(I2C_InitTypeDef* I2C_InitStruct)\r
299 {\r
300 /*---------------- Reset I2C init structure parameters values ----------------*/\r
301   /* initialize the I2C_ClockSpeed member */\r
302   I2C_InitStruct->I2C_ClockSpeed = 5000;\r
303   /* Initialize the I2C_Mode member */\r
304   I2C_InitStruct->I2C_Mode = I2C_Mode_I2C;\r
305   /* Initialize the I2C_DutyCycle member */\r
306   I2C_InitStruct->I2C_DutyCycle = I2C_DutyCycle_2;\r
307   /* Initialize the I2C_OwnAddress1 member */\r
308   I2C_InitStruct->I2C_OwnAddress1 = 0;\r
309   /* Initialize the I2C_Ack member */\r
310   I2C_InitStruct->I2C_Ack = I2C_Ack_Disable;\r
311   /* Initialize the I2C_AcknowledgedAddress member */\r
312   I2C_InitStruct->I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;\r
313 }\r
314 \r
315 /**\r
316   * @brief  Enables or disables the specified I2C peripheral.\r
317   * @param  I2Cx: where x can be 1 or 2 to select the I2C peripheral.\r
318   * @param  NewState: new state of the I2Cx peripheral. \r
319   *   This parameter can be: ENABLE or DISABLE.\r
320   * @retval None\r
321   */\r
322 void I2C_Cmd(I2C_TypeDef* I2Cx, FunctionalState NewState)\r
323 {\r
324   /* Check the parameters */\r
325   assert_param(IS_I2C_ALL_PERIPH(I2Cx));\r
326   assert_param(IS_FUNCTIONAL_STATE(NewState));\r
327   if (NewState != DISABLE)\r
328   {\r
329     /* Enable the selected I2C peripheral */\r
330     I2Cx->CR1 |= CR1_PE_Set;\r
331   }\r
332   else\r
333   {\r
334     /* Disable the selected I2C peripheral */\r
335     I2Cx->CR1 &= CR1_PE_Reset;\r
336   }\r
337 }\r
338 \r
339 /**\r
340   * @brief  Enables or disables the specified I2C DMA requests.\r
341   * @param  I2Cx: where x can be 1 or 2 to select the I2C peripheral.\r
342   * @param  NewState: new state of the I2C DMA transfer.\r
343   *   This parameter can be: ENABLE or DISABLE.\r
344   * @retval None\r
345   */\r
346 void I2C_DMACmd(I2C_TypeDef* I2Cx, FunctionalState NewState)\r
347 {\r
348   /* Check the parameters */\r
349   assert_param(IS_I2C_ALL_PERIPH(I2Cx));\r
350   assert_param(IS_FUNCTIONAL_STATE(NewState));\r
351   if (NewState != DISABLE)\r
352   {\r
353     /* Enable the selected I2C DMA requests */\r
354     I2Cx->CR2 |= CR2_DMAEN_Set;\r
355   }\r
356   else\r
357   {\r
358     /* Disable the selected I2C DMA requests */\r
359     I2Cx->CR2 &= CR2_DMAEN_Reset;\r
360   }\r
361 }\r
362 \r
363 /**\r
364   * @brief  Specifies if the next DMA transfer will be the last one.\r
365   * @param  I2Cx: where x can be 1 or 2 to select the I2C peripheral.\r
366   * @param  NewState: new state of the I2C DMA last transfer.\r
367   *   This parameter can be: ENABLE or DISABLE.\r
368   * @retval None\r
369   */\r
370 void I2C_DMALastTransferCmd(I2C_TypeDef* I2Cx, FunctionalState NewState)\r
371 {\r
372   /* Check the parameters */\r
373   assert_param(IS_I2C_ALL_PERIPH(I2Cx));\r
374   assert_param(IS_FUNCTIONAL_STATE(NewState));\r
375   if (NewState != DISABLE)\r
376   {\r
377     /* Next DMA transfer is the last transfer */\r
378     I2Cx->CR2 |= CR2_LAST_Set;\r
379   }\r
380   else\r
381   {\r
382     /* Next DMA transfer is not the last transfer */\r
383     I2Cx->CR2 &= CR2_LAST_Reset;\r
384   }\r
385 }\r
386 \r
387 /**\r
388   * @brief  Generates I2Cx communication START condition.\r
389   * @param  I2Cx: where x can be 1 or 2 to select the I2C peripheral.\r
390   * @param  NewState: new state of the I2C START condition generation.\r
391   *   This parameter can be: ENABLE or DISABLE.\r
392   * @retval None.\r
393   */\r
394 void I2C_GenerateSTART(I2C_TypeDef* I2Cx, FunctionalState NewState)\r
395 {\r
396   /* Check the parameters */\r
397   assert_param(IS_I2C_ALL_PERIPH(I2Cx));\r
398   assert_param(IS_FUNCTIONAL_STATE(NewState));\r
399   if (NewState != DISABLE)\r
400   {\r
401     /* Generate a START condition */\r
402     I2Cx->CR1 |= CR1_START_Set;\r
403   }\r
404   else\r
405   {\r
406     /* Disable the START condition generation */\r
407     I2Cx->CR1 &= CR1_START_Reset;\r
408   }\r
409 }\r
410 \r
411 /**\r
412   * @brief  Generates I2Cx communication STOP condition.\r
413   * @param  I2Cx: where x can be 1 or 2 to select the I2C peripheral.\r
414   * @param  NewState: new state of the I2C STOP condition generation.\r
415   *   This parameter can be: ENABLE or DISABLE.\r
416   * @retval None.\r
417   */\r
418 void I2C_GenerateSTOP(I2C_TypeDef* I2Cx, FunctionalState NewState)\r
419 {\r
420   /* Check the parameters */\r
421   assert_param(IS_I2C_ALL_PERIPH(I2Cx));\r
422   assert_param(IS_FUNCTIONAL_STATE(NewState));\r
423   if (NewState != DISABLE)\r
424   {\r
425     /* Generate a STOP condition */\r
426     I2Cx->CR1 |= CR1_STOP_Set;\r
427   }\r
428   else\r
429   {\r
430     /* Disable the STOP condition generation */\r
431     I2Cx->CR1 &= CR1_STOP_Reset;\r
432   }\r
433 }\r
434 \r
435 /**\r
436   * @brief  Enables or disables the specified I2C acknowledge feature.\r
437   * @param  I2Cx: where x can be 1 or 2 to select the I2C peripheral.\r
438   * @param  NewState: new state of the I2C Acknowledgement.\r
439   *   This parameter can be: ENABLE or DISABLE.\r
440   * @retval None.\r
441   */\r
442 void I2C_AcknowledgeConfig(I2C_TypeDef* I2Cx, FunctionalState NewState)\r
443 {\r
444   /* Check the parameters */\r
445   assert_param(IS_I2C_ALL_PERIPH(I2Cx));\r
446   assert_param(IS_FUNCTIONAL_STATE(NewState));\r
447   if (NewState != DISABLE)\r
448   {\r
449     /* Enable the acknowledgement */\r
450     I2Cx->CR1 |= CR1_ACK_Set;\r
451   }\r
452   else\r
453   {\r
454     /* Disable the acknowledgement */\r
455     I2Cx->CR1 &= CR1_ACK_Reset;\r
456   }\r
457 }\r
458 \r
459 /**\r
460   * @brief  Configures the specified I2C own address2.\r
461   * @param  I2Cx: where x can be 1 or 2 to select the I2C peripheral.\r
462   * @param  Address: specifies the 7bit I2C own address2.\r
463   * @retval None.\r
464   */\r
465 void I2C_OwnAddress2Config(I2C_TypeDef* I2Cx, uint8_t Address)\r
466 {\r
467   uint16_t tmpreg = 0;\r
468 \r
469   /* Check the parameters */\r
470   assert_param(IS_I2C_ALL_PERIPH(I2Cx));\r
471 \r
472   /* Get the old register value */\r
473   tmpreg = I2Cx->OAR2;\r
474 \r
475   /* Reset I2Cx Own address2 bit [7:1] */\r
476   tmpreg &= OAR2_ADD2_Reset;\r
477 \r
478   /* Set I2Cx Own address2 */\r
479   tmpreg |= (uint16_t)((uint16_t)Address & (uint16_t)0x00FE);\r
480 \r
481   /* Store the new register value */\r
482   I2Cx->OAR2 = tmpreg;\r
483 }\r
484 \r
485 /**\r
486   * @brief  Enables or disables the specified I2C dual addressing mode.\r
487   * @param  I2Cx: where x can be 1 or 2 to select the I2C peripheral.\r
488   * @param  NewState: new state of the I2C dual addressing mode.\r
489   *   This parameter can be: ENABLE or DISABLE.\r
490   * @retval None\r
491   */\r
492 void I2C_DualAddressCmd(I2C_TypeDef* I2Cx, FunctionalState NewState)\r
493 {\r
494   /* Check the parameters */\r
495   assert_param(IS_I2C_ALL_PERIPH(I2Cx));\r
496   assert_param(IS_FUNCTIONAL_STATE(NewState));\r
497   if (NewState != DISABLE)\r
498   {\r
499     /* Enable dual addressing mode */\r
500     I2Cx->OAR2 |= OAR2_ENDUAL_Set;\r
501   }\r
502   else\r
503   {\r
504     /* Disable dual addressing mode */\r
505     I2Cx->OAR2 &= OAR2_ENDUAL_Reset;\r
506   }\r
507 }\r
508 \r
509 /**\r
510   * @brief  Enables or disables the specified I2C general call feature.\r
511   * @param  I2Cx: where x can be 1 or 2 to select the I2C peripheral.\r
512   * @param  NewState: new state of the I2C General call.\r
513   *   This parameter can be: ENABLE or DISABLE.\r
514   * @retval None\r
515   */\r
516 void I2C_GeneralCallCmd(I2C_TypeDef* I2Cx, FunctionalState NewState)\r
517 {\r
518   /* Check the parameters */\r
519   assert_param(IS_I2C_ALL_PERIPH(I2Cx));\r
520   assert_param(IS_FUNCTIONAL_STATE(NewState));\r
521   if (NewState != DISABLE)\r
522   {\r
523     /* Enable generall call */\r
524     I2Cx->CR1 |= CR1_ENGC_Set;\r
525   }\r
526   else\r
527   {\r
528     /* Disable generall call */\r
529     I2Cx->CR1 &= CR1_ENGC_Reset;\r
530   }\r
531 }\r
532 \r
533 /**\r
534   * @brief  Enables or disables the specified I2C interrupts.\r
535   * @param  I2Cx: where x can be 1 or 2 to select the I2C peripheral.\r
536   * @param  I2C_IT: specifies the I2C interrupts sources to be enabled or disabled. \r
537   *   This parameter can be any combination of the following values:\r
538   *     @arg I2C_IT_BUF: Buffer interrupt mask\r
539   *     @arg I2C_IT_EVT: Event interrupt mask\r
540   *     @arg I2C_IT_ERR: Error interrupt mask\r
541   * @param  NewState: new state of the specified I2C interrupts.\r
542   *   This parameter can be: ENABLE or DISABLE.\r
543   * @retval None\r
544   */\r
545 void I2C_ITConfig(I2C_TypeDef* I2Cx, uint16_t I2C_IT, FunctionalState NewState)\r
546 {\r
547   /* Check the parameters */\r
548   assert_param(IS_I2C_ALL_PERIPH(I2Cx));\r
549   assert_param(IS_FUNCTIONAL_STATE(NewState));\r
550   assert_param(IS_I2C_CONFIG_IT(I2C_IT));\r
551   \r
552   if (NewState != DISABLE)\r
553   {\r
554     /* Enable the selected I2C interrupts */\r
555     I2Cx->CR2 |= I2C_IT;\r
556   }\r
557   else\r
558   {\r
559     /* Disable the selected I2C interrupts */\r
560     I2Cx->CR2 &= (uint16_t)~I2C_IT;\r
561   }\r
562 }\r
563 \r
564 /**\r
565   * @brief  Sends a data byte through the I2Cx peripheral.\r
566   * @param  I2Cx: where x can be 1 or 2 to select the I2C peripheral.\r
567   * @param  Data: Byte to be transmitted..\r
568   * @retval None\r
569   */\r
570 void I2C_SendData(I2C_TypeDef* I2Cx, uint8_t Data)\r
571 {\r
572   /* Check the parameters */\r
573   assert_param(IS_I2C_ALL_PERIPH(I2Cx));\r
574   /* Write in the DR register the data to be sent */\r
575   I2Cx->DR = Data;\r
576 }\r
577 \r
578 /**\r
579   * @brief  Returns the most recent received data by the I2Cx peripheral.\r
580   * @param  I2Cx: where x can be 1 or 2 to select the I2C peripheral.\r
581   * @retval The value of the received data.\r
582   */\r
583 uint8_t I2C_ReceiveData(I2C_TypeDef* I2Cx)\r
584 {\r
585   /* Check the parameters */\r
586   assert_param(IS_I2C_ALL_PERIPH(I2Cx));\r
587   /* Return the data in the DR register */\r
588   return (uint8_t)I2Cx->DR;\r
589 }\r
590 \r
591 /**\r
592   * @brief  Transmits the address byte to select the slave device.\r
593   * @param  I2Cx: where x can be 1 or 2 to select the I2C peripheral.\r
594   * @param  Address: specifies the slave address which will be transmitted\r
595   * @param  I2C_Direction: specifies whether the I2C device will be a\r
596   *   Transmitter or a Receiver. This parameter can be one of the following values\r
597   *     @arg I2C_Direction_Transmitter: Transmitter mode\r
598   *     @arg I2C_Direction_Receiver: Receiver mode\r
599   * @retval None.\r
600   */\r
601 void I2C_Send7bitAddress(I2C_TypeDef* I2Cx, uint8_t Address, uint8_t I2C_Direction)\r
602 {\r
603   /* Check the parameters */\r
604   assert_param(IS_I2C_ALL_PERIPH(I2Cx));\r
605   assert_param(IS_I2C_DIRECTION(I2C_Direction));\r
606   /* Test on the direction to set/reset the read/write bit */\r
607   if (I2C_Direction != I2C_Direction_Transmitter)\r
608   {\r
609     /* Set the address bit0 for read */\r
610     Address |= OAR1_ADD0_Set;\r
611   }\r
612   else\r
613   {\r
614     /* Reset the address bit0 for write */\r
615     Address &= OAR1_ADD0_Reset;\r
616   }\r
617   /* Send the address */\r
618   I2Cx->DR = Address;\r
619 }\r
620 \r
621 /**\r
622   * @brief  Reads the specified I2C register and returns its value.\r
623   * @param  I2C_Register: specifies the register to read.\r
624   *   This parameter can be one of the following values:\r
625   *     @arg I2C_Register_CR1:  CR1 register.\r
626   *     @arg I2C_Register_CR2:   CR2 register.\r
627   *     @arg I2C_Register_OAR1:  OAR1 register.\r
628   *     @arg I2C_Register_OAR2:  OAR2 register.\r
629   *     @arg I2C_Register_DR:    DR register.\r
630   *     @arg I2C_Register_SR1:   SR1 register.\r
631   *     @arg I2C_Register_SR2:   SR2 register.\r
632   *     @arg I2C_Register_CCR:   CCR register.\r
633   *     @arg I2C_Register_TRISE: TRISE register.\r
634   * @retval The value of the read register.\r
635   */\r
636 uint16_t I2C_ReadRegister(I2C_TypeDef* I2Cx, uint8_t I2C_Register)\r
637 {\r
638   __IO uint32_t tmp = 0;\r
639 \r
640   /* Check the parameters */\r
641   assert_param(IS_I2C_ALL_PERIPH(I2Cx));\r
642   assert_param(IS_I2C_REGISTER(I2C_Register));\r
643 \r
644   tmp = (uint32_t) I2Cx;\r
645   tmp += I2C_Register;\r
646 \r
647   /* Return the selected register value */\r
648   return (*(__IO uint16_t *) tmp);\r
649 }\r
650 \r
651 /**\r
652   * @brief  Enables or disables the specified I2C software reset.\r
653   * @param  I2Cx: where x can be 1 or 2 to select the I2C peripheral.\r
654   * @param  NewState: new state of the I2C software reset.\r
655   *   This parameter can be: ENABLE or DISABLE.\r
656   * @retval None\r
657   */\r
658 void I2C_SoftwareResetCmd(I2C_TypeDef* I2Cx, FunctionalState NewState)\r
659 {\r
660   /* Check the parameters */\r
661   assert_param(IS_I2C_ALL_PERIPH(I2Cx));\r
662   assert_param(IS_FUNCTIONAL_STATE(NewState));\r
663   if (NewState != DISABLE)\r
664   {\r
665     /* Peripheral under reset */\r
666     I2Cx->CR1 |= CR1_SWRST_Set;\r
667   }\r
668   else\r
669   {\r
670     /* Peripheral not under reset */\r
671     I2Cx->CR1 &= CR1_SWRST_Reset;\r
672   }\r
673 }\r
674 \r
675 /**\r
676   * @brief  Selects the specified I2C NACK position in master receiver mode.\r
677   *         This function is useful in I2C Master Receiver mode when the number\r
678   *         of data to be received is equal to 2. In this case, this function \r
679   *         should be called (with parameter I2C_NACKPosition_Next) before data \r
680   *         reception starts,as described in the 2-byte reception procedure \r
681   *         recommended in Reference Manual in Section: Master receiver.                \r
682   * @param  I2Cx: where x can be 1 or 2 to select the I2C peripheral.\r
683   * @param  I2C_NACKPosition: specifies the NACK position. \r
684   *   This parameter can be one of the following values:\r
685   *     @arg I2C_NACKPosition_Next: indicates that the next byte will be the last\r
686   *          received byte.  \r
687   *     @arg I2C_NACKPosition_Current: indicates that current byte is the last \r
688   *          received byte.\r
689   *            \r
690   * @note    This function configures the same bit (POS) as I2C_PECPositionConfig() \r
691   *          but is intended to be used in I2C mode while I2C_PECPositionConfig() \r
692   *          is intended to used in SMBUS mode. \r
693   *            \r
694   * @retval None\r
695   */\r
696 void I2C_NACKPositionConfig(I2C_TypeDef* I2Cx, uint16_t I2C_NACKPosition)\r
697 {\r
698   /* Check the parameters */\r
699   assert_param(IS_I2C_ALL_PERIPH(I2Cx));\r
700   assert_param(IS_I2C_NACK_POSITION(I2C_NACKPosition));\r
701   \r
702   /* Check the input parameter */\r
703   if (I2C_NACKPosition == I2C_NACKPosition_Next)\r
704   {\r
705     /* Next byte in shift register is the last received byte */\r
706     I2Cx->CR1 |= I2C_NACKPosition_Next;\r
707   }\r
708   else\r
709   {\r
710     /* Current byte in shift register is the last received byte */\r
711     I2Cx->CR1 &= I2C_NACKPosition_Current;\r
712   }\r
713 }\r
714 \r
715 /**\r
716   * @brief  Drives the SMBusAlert pin high or low for the specified I2C.\r
717   * @param  I2Cx: where x can be 1 or 2 to select the I2C peripheral.\r
718   * @param  I2C_SMBusAlert: specifies SMBAlert pin level. \r
719   *   This parameter can be one of the following values:\r
720   *     @arg I2C_SMBusAlert_Low: SMBAlert pin driven low\r
721   *     @arg I2C_SMBusAlert_High: SMBAlert pin driven high\r
722   * @retval None\r
723   */\r
724 void I2C_SMBusAlertConfig(I2C_TypeDef* I2Cx, uint16_t I2C_SMBusAlert)\r
725 {\r
726   /* Check the parameters */\r
727   assert_param(IS_I2C_ALL_PERIPH(I2Cx));\r
728   assert_param(IS_I2C_SMBUS_ALERT(I2C_SMBusAlert));\r
729   if (I2C_SMBusAlert == I2C_SMBusAlert_Low)\r
730   {\r
731     /* Drive the SMBusAlert pin Low */\r
732     I2Cx->CR1 |= I2C_SMBusAlert_Low;\r
733   }\r
734   else\r
735   {\r
736     /* Drive the SMBusAlert pin High  */\r
737     I2Cx->CR1 &= I2C_SMBusAlert_High;\r
738   }\r
739 }\r
740 \r
741 /**\r
742   * @brief  Enables or disables the specified I2C PEC transfer.\r
743   * @param  I2Cx: where x can be 1 or 2 to select the I2C peripheral.\r
744   * @param  NewState: new state of the I2C PEC transmission.\r
745   *   This parameter can be: ENABLE or DISABLE.\r
746   * @retval None\r
747   */\r
748 void I2C_TransmitPEC(I2C_TypeDef* I2Cx, FunctionalState NewState)\r
749 {\r
750   /* Check the parameters */\r
751   assert_param(IS_I2C_ALL_PERIPH(I2Cx));\r
752   assert_param(IS_FUNCTIONAL_STATE(NewState));\r
753   if (NewState != DISABLE)\r
754   {\r
755     /* Enable the selected I2C PEC transmission */\r
756     I2Cx->CR1 |= CR1_PEC_Set;\r
757   }\r
758   else\r
759   {\r
760     /* Disable the selected I2C PEC transmission */\r
761     I2Cx->CR1 &= CR1_PEC_Reset;\r
762   }\r
763 }\r
764 \r
765 /**\r
766   * @brief  Selects the specified I2C PEC position.\r
767   * @param  I2Cx: where x can be 1 or 2 to select the I2C peripheral.\r
768   * @param  I2C_PECPosition: specifies the PEC position. \r
769   *   This parameter can be one of the following values:\r
770   *     @arg I2C_PECPosition_Next: indicates that the next byte is PEC\r
771   *     @arg I2C_PECPosition_Current: indicates that current byte is PEC\r
772   *       \r
773   * @note    This function configures the same bit (POS) as I2C_NACKPositionConfig()\r
774   *          but is intended to be used in SMBUS mode while I2C_NACKPositionConfig() \r
775   *          is intended to used in I2C mode.\r
776   *               \r
777   * @retval None\r
778   */\r
779 void I2C_PECPositionConfig(I2C_TypeDef* I2Cx, uint16_t I2C_PECPosition)\r
780 {\r
781   /* Check the parameters */\r
782   assert_param(IS_I2C_ALL_PERIPH(I2Cx));\r
783   assert_param(IS_I2C_PEC_POSITION(I2C_PECPosition));\r
784   if (I2C_PECPosition == I2C_PECPosition_Next)\r
785   {\r
786     /* Next byte in shift register is PEC */\r
787     I2Cx->CR1 |= I2C_PECPosition_Next;\r
788   }\r
789   else\r
790   {\r
791     /* Current byte in shift register is PEC */\r
792     I2Cx->CR1 &= I2C_PECPosition_Current;\r
793   }\r
794 }\r
795 \r
796 /**\r
797   * @brief  Enables or disables the PEC value calculation of the transferred bytes.\r
798   * @param  I2Cx: where x can be 1 or 2 to select the I2C peripheral.\r
799   * @param  NewState: new state of the I2Cx PEC value calculation.\r
800   *   This parameter can be: ENABLE or DISABLE.\r
801   * @retval None\r
802   */\r
803 void I2C_CalculatePEC(I2C_TypeDef* I2Cx, FunctionalState NewState)\r
804 {\r
805   /* Check the parameters */\r
806   assert_param(IS_I2C_ALL_PERIPH(I2Cx));\r
807   assert_param(IS_FUNCTIONAL_STATE(NewState));\r
808   if (NewState != DISABLE)\r
809   {\r
810     /* Enable the selected I2C PEC calculation */\r
811     I2Cx->CR1 |= CR1_ENPEC_Set;\r
812   }\r
813   else\r
814   {\r
815     /* Disable the selected I2C PEC calculation */\r
816     I2Cx->CR1 &= CR1_ENPEC_Reset;\r
817   }\r
818 }\r
819 \r
820 /**\r
821   * @brief  Returns the PEC value for the specified I2C.\r
822   * @param  I2Cx: where x can be 1 or 2 to select the I2C peripheral.\r
823   * @retval The PEC value.\r
824   */\r
825 uint8_t I2C_GetPEC(I2C_TypeDef* I2Cx)\r
826 {\r
827   /* Check the parameters */\r
828   assert_param(IS_I2C_ALL_PERIPH(I2Cx));\r
829   /* Return the selected I2C PEC value */\r
830   return ((I2Cx->SR2) >> 8);\r
831 }\r
832 \r
833 /**\r
834   * @brief  Enables or disables the specified I2C ARP.\r
835   * @param  I2Cx: where x can be 1 or 2 to select the I2C peripheral.\r
836   * @param  NewState: new state of the I2Cx ARP. \r
837   *   This parameter can be: ENABLE or DISABLE.\r
838   * @retval None\r
839   */\r
840 void I2C_ARPCmd(I2C_TypeDef* I2Cx, FunctionalState NewState)\r
841 {\r
842   /* Check the parameters */\r
843   assert_param(IS_I2C_ALL_PERIPH(I2Cx));\r
844   assert_param(IS_FUNCTIONAL_STATE(NewState));\r
845   if (NewState != DISABLE)\r
846   {\r
847     /* Enable the selected I2C ARP */\r
848     I2Cx->CR1 |= CR1_ENARP_Set;\r
849   }\r
850   else\r
851   {\r
852     /* Disable the selected I2C ARP */\r
853     I2Cx->CR1 &= CR1_ENARP_Reset;\r
854   }\r
855 }\r
856 \r
857 /**\r
858   * @brief  Enables or disables the specified I2C Clock stretching.\r
859   * @param  I2Cx: where x can be 1 or 2 to select the I2C peripheral.\r
860   * @param  NewState: new state of the I2Cx Clock stretching.\r
861   *   This parameter can be: ENABLE or DISABLE.\r
862   * @retval None\r
863   */\r
864 void I2C_StretchClockCmd(I2C_TypeDef* I2Cx, FunctionalState NewState)\r
865 {\r
866   /* Check the parameters */\r
867   assert_param(IS_I2C_ALL_PERIPH(I2Cx));\r
868   assert_param(IS_FUNCTIONAL_STATE(NewState));\r
869   if (NewState == DISABLE)\r
870   {\r
871     /* Enable the selected I2C Clock stretching */\r
872     I2Cx->CR1 |= CR1_NOSTRETCH_Set;\r
873   }\r
874   else\r
875   {\r
876     /* Disable the selected I2C Clock stretching */\r
877     I2Cx->CR1 &= CR1_NOSTRETCH_Reset;\r
878   }\r
879 }\r
880 \r
881 /**\r
882   * @brief  Selects the specified I2C fast mode duty cycle.\r
883   * @param  I2Cx: where x can be 1 or 2 to select the I2C peripheral.\r
884   * @param  I2C_DutyCycle: specifies the fast mode duty cycle.\r
885   *   This parameter can be one of the following values:\r
886   *     @arg I2C_DutyCycle_2: I2C fast mode Tlow/Thigh = 2\r
887   *     @arg I2C_DutyCycle_16_9: I2C fast mode Tlow/Thigh = 16/9\r
888   * @retval None\r
889   */\r
890 void I2C_FastModeDutyCycleConfig(I2C_TypeDef* I2Cx, uint16_t I2C_DutyCycle)\r
891 {\r
892   /* Check the parameters */\r
893   assert_param(IS_I2C_ALL_PERIPH(I2Cx));\r
894   assert_param(IS_I2C_DUTY_CYCLE(I2C_DutyCycle));\r
895   if (I2C_DutyCycle != I2C_DutyCycle_16_9)\r
896   {\r
897     /* I2C fast mode Tlow/Thigh=2 */\r
898     I2Cx->CCR &= I2C_DutyCycle_2;\r
899   }\r
900   else\r
901   {\r
902     /* I2C fast mode Tlow/Thigh=16/9 */\r
903     I2Cx->CCR |= I2C_DutyCycle_16_9;\r
904   }\r
905 }\r
906 \r
907 \r
908 \r
909 /**\r
910  * @brief\r
911  ****************************************************************************************\r
912  *\r
913  *                         I2C State Monitoring Functions\r
914  *                       \r
915  ****************************************************************************************   \r
916  * This I2C driver provides three different ways for I2C state monitoring\r
917  *  depending on the application requirements and constraints:\r
918  *        \r
919  *  \r
920  * 1) Basic state monitoring:\r
921  *    Using I2C_CheckEvent() function:\r
922  *    It compares the status registers (SR1 and SR2) content to a given event\r
923  *    (can be the combination of one or more flags).\r
924  *    It returns SUCCESS if the current status includes the given flags \r
925  *    and returns ERROR if one or more flags are missing in the current status.\r
926  *    - When to use:\r
927  *      - This function is suitable for most applications as well as for startup \r
928  *      activity since the events are fully described in the product reference manual \r
929  *      (RM0008).\r
930  *      - It is also suitable for users who need to define their own events.\r
931  *    - Limitations:\r
932  *      - If an error occurs (ie. error flags are set besides to the monitored flags),\r
933  *        the I2C_CheckEvent() function may return SUCCESS despite the communication\r
934  *        hold or corrupted real state. \r
935  *        In this case, it is advised to use error interrupts to monitor the error\r
936  *        events and handle them in the interrupt IRQ handler.\r
937  *        \r
938  *        @note \r
939  *        For error management, it is advised to use the following functions:\r
940  *          - I2C_ITConfig() to configure and enable the error interrupts (I2C_IT_ERR).\r
941  *          - I2Cx_ER_IRQHandler() which is called when the error interrupt occurs.\r
942  *            Where x is the peripheral instance (I2C1, I2C2 ...)\r
943  *          - I2C_GetFlagStatus() or I2C_GetITStatus() to be called into I2Cx_ER_IRQHandler() \r
944  *            in order to determine which error occured.\r
945  *          - I2C_ClearFlag() or I2C_ClearITPendingBit() and/or I2C_SoftwareResetCmd()\r
946  *            and/or I2C_GenerateStop() in order to clear the error flag and source,\r
947  *            and return to correct communication status.\r
948  *            \r
949  *\r
950  *  2) Advanced state monitoring:\r
951  *     Using the function I2C_GetLastEvent() which returns the image of both status \r
952  *     registers in a single word (uint32_t) (Status Register 2 value is shifted left \r
953  *     by 16 bits and concatenated to Status Register 1).\r
954  *     - When to use:\r
955  *       - This function is suitable for the same applications above but it allows to\r
956  *         overcome the mentioned limitation of I2C_GetFlagStatus() function.\r
957  *         The returned value could be compared to events already defined in the \r
958  *         library (stm32f10x_i2c.h) or to custom values defined by user.\r
959  *       - This function is suitable when multiple flags are monitored at the same time.\r
960  *       - At the opposite of I2C_CheckEvent() function, this function allows user to\r
961  *         choose when an event is accepted (when all events flags are set and no \r
962  *         other flags are set or just when the needed flags are set like \r
963  *         I2C_CheckEvent() function).\r
964  *     - Limitations:\r
965  *       - User may need to define his own events.\r
966  *       - Same remark concerning the error management is applicable for this \r
967  *         function if user decides to check only regular communication flags (and \r
968  *         ignores error flags).\r
969  *     \r
970  *\r
971  *  3) Flag-based state monitoring:\r
972  *     Using the function I2C_GetFlagStatus() which simply returns the status of \r
973  *     one single flag (ie. I2C_FLAG_RXNE ...). \r
974  *     - When to use:\r
975  *        - This function could be used for specific applications or in debug phase.\r
976  *        - It is suitable when only one flag checking is needed (most I2C events \r
977  *          are monitored through multiple flags).\r
978  *     - Limitations: \r
979  *        - When calling this function, the Status register is accessed. Some flags are\r
980  *          cleared when the status register is accessed. So checking the status\r
981  *          of one Flag, may clear other ones.\r
982  *        - Function may need to be called twice or more in order to monitor one \r
983  *          single event.\r
984  *\r
985  *  For detailed description of Events, please refer to section I2C_Events in \r
986  *  stm32f10x_i2c.h file.\r
987  *  \r
988  */\r
989 \r
990 /**\r
991  * \r
992  *  1) Basic state monitoring\r
993  *******************************************************************************\r
994  */\r
995 \r
996 /**\r
997   * @brief  Checks whether the last I2Cx Event is equal to the one passed\r
998   *   as parameter.\r
999   * @param  I2Cx: where x can be 1 or 2 to select the I2C peripheral.\r
1000   * @param  I2C_EVENT: specifies the event to be checked. \r
1001   *   This parameter can be one of the following values:\r
1002   *     @arg I2C_EVENT_SLAVE_TRANSMITTER_ADDRESS_MATCHED           : EV1\r
1003   *     @arg I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED              : EV1\r
1004   *     @arg I2C_EVENT_SLAVE_TRANSMITTER_SECONDADDRESS_MATCHED     : EV1\r
1005   *     @arg I2C_EVENT_SLAVE_RECEIVER_SECONDADDRESS_MATCHED        : EV1\r
1006   *     @arg I2C_EVENT_SLAVE_GENERALCALLADDRESS_MATCHED            : EV1\r
1007   *     @arg I2C_EVENT_SLAVE_BYTE_RECEIVED                         : EV2\r
1008   *     @arg (I2C_EVENT_SLAVE_BYTE_RECEIVED | I2C_FLAG_DUALF)      : EV2\r
1009   *     @arg (I2C_EVENT_SLAVE_BYTE_RECEIVED | I2C_FLAG_GENCALL)    : EV2\r
1010   *     @arg I2C_EVENT_SLAVE_BYTE_TRANSMITTED                      : EV3\r
1011   *     @arg (I2C_EVENT_SLAVE_BYTE_TRANSMITTED | I2C_FLAG_DUALF)   : EV3\r
1012   *     @arg (I2C_EVENT_SLAVE_BYTE_TRANSMITTED | I2C_FLAG_GENCALL) : EV3\r
1013   *     @arg I2C_EVENT_SLAVE_ACK_FAILURE                           : EV3_2\r
1014   *     @arg I2C_EVENT_SLAVE_STOP_DETECTED                         : EV4\r
1015   *     @arg I2C_EVENT_MASTER_MODE_SELECT                          : EV5\r
1016   *     @arg I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED            : EV6     \r
1017   *     @arg I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED               : EV6\r
1018   *     @arg I2C_EVENT_MASTER_BYTE_RECEIVED                        : EV7\r
1019   *     @arg I2C_EVENT_MASTER_BYTE_TRANSMITTING                    : EV8\r
1020   *     @arg I2C_EVENT_MASTER_BYTE_TRANSMITTED                     : EV8_2\r
1021   *     @arg I2C_EVENT_MASTER_MODE_ADDRESS10                       : EV9\r
1022   *     \r
1023   * @note: For detailed description of Events, please refer to section \r
1024   *    I2C_Events in stm32f10x_i2c.h file.\r
1025   *    \r
1026   * @retval An ErrorStatus enumeration value:\r
1027   * - SUCCESS: Last event is equal to the I2C_EVENT\r
1028   * - ERROR: Last event is different from the I2C_EVENT\r
1029   */\r
1030 ErrorStatus I2C_CheckEvent(I2C_TypeDef* I2Cx, uint32_t I2C_EVENT)\r
1031 {\r
1032   uint32_t lastevent = 0;\r
1033   uint32_t flag1 = 0, flag2 = 0;\r
1034   ErrorStatus status = ERROR;\r
1035 \r
1036   /* Check the parameters */\r
1037   assert_param(IS_I2C_ALL_PERIPH(I2Cx));\r
1038   assert_param(IS_I2C_EVENT(I2C_EVENT));\r
1039 \r
1040   /* Read the I2Cx status register */\r
1041   flag1 = I2Cx->SR1;\r
1042   flag2 = I2Cx->SR2;\r
1043   flag2 = flag2 << 16;\r
1044 \r
1045   /* Get the last event value from I2C status register */\r
1046   lastevent = (flag1 | flag2) & FLAG_Mask;\r
1047 \r
1048   /* Check whether the last event contains the I2C_EVENT */\r
1049   if ((lastevent & I2C_EVENT) == I2C_EVENT)\r
1050   {\r
1051     /* SUCCESS: last event is equal to I2C_EVENT */\r
1052     status = SUCCESS;\r
1053   }\r
1054   else\r
1055   {\r
1056     /* ERROR: last event is different from I2C_EVENT */\r
1057     status = ERROR;\r
1058   }\r
1059   /* Return status */\r
1060   return status;\r
1061 }\r
1062 \r
1063 /**\r
1064  * \r
1065  *  2) Advanced state monitoring\r
1066  *******************************************************************************\r
1067  */\r
1068 \r
1069 /**\r
1070   * @brief  Returns the last I2Cx Event.\r
1071   * @param  I2Cx: where x can be 1 or 2 to select the I2C peripheral.\r
1072   *     \r
1073   * @note: For detailed description of Events, please refer to section \r
1074   *    I2C_Events in stm32f10x_i2c.h file.\r
1075   *    \r
1076   * @retval The last event\r
1077   */\r
1078 uint32_t I2C_GetLastEvent(I2C_TypeDef* I2Cx)\r
1079 {\r
1080   uint32_t lastevent = 0;\r
1081   uint32_t flag1 = 0, flag2 = 0;\r
1082 \r
1083   /* Check the parameters */\r
1084   assert_param(IS_I2C_ALL_PERIPH(I2Cx));\r
1085 \r
1086   /* Read the I2Cx status register */\r
1087   flag1 = I2Cx->SR1;\r
1088   flag2 = I2Cx->SR2;\r
1089   flag2 = flag2 << 16;\r
1090 \r
1091   /* Get the last event value from I2C status register */\r
1092   lastevent = (flag1 | flag2) & FLAG_Mask;\r
1093 \r
1094   /* Return status */\r
1095   return lastevent;\r
1096 }\r
1097 \r
1098 /**\r
1099  * \r
1100  *  3) Flag-based state monitoring\r
1101  *******************************************************************************\r
1102  */\r
1103 \r
1104 /**\r
1105   * @brief  Checks whether the specified I2C flag is set or not.\r
1106   * @param  I2Cx: where x can be 1 or 2 to select the I2C peripheral.\r
1107   * @param  I2C_FLAG: specifies the flag to check. \r
1108   *   This parameter can be one of the following values:\r
1109   *     @arg I2C_FLAG_DUALF: Dual flag (Slave mode)\r
1110   *     @arg I2C_FLAG_SMBHOST: SMBus host header (Slave mode)\r
1111   *     @arg I2C_FLAG_SMBDEFAULT: SMBus default header (Slave mode)\r
1112   *     @arg I2C_FLAG_GENCALL: General call header flag (Slave mode)\r
1113   *     @arg I2C_FLAG_TRA: Transmitter/Receiver flag\r
1114   *     @arg I2C_FLAG_BUSY: Bus busy flag\r
1115   *     @arg I2C_FLAG_MSL: Master/Slave flag\r
1116   *     @arg I2C_FLAG_SMBALERT: SMBus Alert flag\r
1117   *     @arg I2C_FLAG_TIMEOUT: Timeout or Tlow error flag\r
1118   *     @arg I2C_FLAG_PECERR: PEC error in reception flag\r
1119   *     @arg I2C_FLAG_OVR: Overrun/Underrun flag (Slave mode)\r
1120   *     @arg I2C_FLAG_AF: Acknowledge failure flag\r
1121   *     @arg I2C_FLAG_ARLO: Arbitration lost flag (Master mode)\r
1122   *     @arg I2C_FLAG_BERR: Bus error flag\r
1123   *     @arg I2C_FLAG_TXE: Data register empty flag (Transmitter)\r
1124   *     @arg I2C_FLAG_RXNE: Data register not empty (Receiver) flag\r
1125   *     @arg I2C_FLAG_STOPF: Stop detection flag (Slave mode)\r
1126   *     @arg I2C_FLAG_ADD10: 10-bit header sent flag (Master mode)\r
1127   *     @arg I2C_FLAG_BTF: Byte transfer finished flag\r
1128   *     @arg I2C_FLAG_ADDR: Address sent flag (Master mode) "ADSL"\r
1129   *   Address matched flag (Slave mode)"ENDA"\r
1130   *     @arg I2C_FLAG_SB: Start bit flag (Master mode)\r
1131   * @retval The new state of I2C_FLAG (SET or RESET).\r
1132   */\r
1133 FlagStatus I2C_GetFlagStatus(I2C_TypeDef* I2Cx, uint32_t I2C_FLAG)\r
1134 {\r
1135   FlagStatus bitstatus = RESET;\r
1136   __IO uint32_t i2creg = 0, i2cxbase = 0;\r
1137 \r
1138   /* Check the parameters */\r
1139   assert_param(IS_I2C_ALL_PERIPH(I2Cx));\r
1140   assert_param(IS_I2C_GET_FLAG(I2C_FLAG));\r
1141 \r
1142   /* Get the I2Cx peripheral base address */\r
1143   i2cxbase = (uint32_t)I2Cx;\r
1144   \r
1145   /* Read flag register index */\r
1146   i2creg = I2C_FLAG >> 28;\r
1147   \r
1148   /* Get bit[23:0] of the flag */\r
1149   I2C_FLAG &= FLAG_Mask;\r
1150   \r
1151   if(i2creg != 0)\r
1152   {\r
1153     /* Get the I2Cx SR1 register address */\r
1154     i2cxbase += 0x14;\r
1155   }\r
1156   else\r
1157   {\r
1158     /* Flag in I2Cx SR2 Register */\r
1159     I2C_FLAG = (uint32_t)(I2C_FLAG >> 16);\r
1160     /* Get the I2Cx SR2 register address */\r
1161     i2cxbase += 0x18;\r
1162   }\r
1163   \r
1164   if(((*(__IO uint32_t *)i2cxbase) & I2C_FLAG) != (uint32_t)RESET)\r
1165   {\r
1166     /* I2C_FLAG is set */\r
1167     bitstatus = SET;\r
1168   }\r
1169   else\r
1170   {\r
1171     /* I2C_FLAG is reset */\r
1172     bitstatus = RESET;\r
1173   }\r
1174   \r
1175   /* Return the I2C_FLAG status */\r
1176   return  bitstatus;\r
1177 }\r
1178 \r
1179 \r
1180 \r
1181 /**\r
1182   * @brief  Clears the I2Cx's pending flags.\r
1183   * @param  I2Cx: where x can be 1 or 2 to select the I2C peripheral.\r
1184   * @param  I2C_FLAG: specifies the flag to clear. \r
1185   *   This parameter can be any combination of the following values:\r
1186   *     @arg I2C_FLAG_SMBALERT: SMBus Alert flag\r
1187   *     @arg I2C_FLAG_TIMEOUT: Timeout or Tlow error flag\r
1188   *     @arg I2C_FLAG_PECERR: PEC error in reception flag\r
1189   *     @arg I2C_FLAG_OVR: Overrun/Underrun flag (Slave mode)\r
1190   *     @arg I2C_FLAG_AF: Acknowledge failure flag\r
1191   *     @arg I2C_FLAG_ARLO: Arbitration lost flag (Master mode)\r
1192   *     @arg I2C_FLAG_BERR: Bus error flag\r
1193   *   \r
1194   * @note\r
1195   *   - STOPF (STOP detection) is cleared by software sequence: a read operation \r
1196   *     to I2C_SR1 register (I2C_GetFlagStatus()) followed by a write operation \r
1197   *     to I2C_CR1 register (I2C_Cmd() to re-enable the I2C peripheral).\r
1198   *   - ADD10 (10-bit header sent) is cleared by software sequence: a read \r
1199   *     operation to I2C_SR1 (I2C_GetFlagStatus()) followed by writing the \r
1200   *     second byte of the address in DR register.\r
1201   *   - BTF (Byte Transfer Finished) is cleared by software sequence: a read \r
1202   *     operation to I2C_SR1 register (I2C_GetFlagStatus()) followed by a \r
1203   *     read/write to I2C_DR register (I2C_SendData()).\r
1204   *   - ADDR (Address sent) is cleared by software sequence: a read operation to \r
1205   *     I2C_SR1 register (I2C_GetFlagStatus()) followed by a read operation to \r
1206   *     I2C_SR2 register ((void)(I2Cx->SR2)).\r
1207   *   - SB (Start Bit) is cleared software sequence: a read operation to I2C_SR1\r
1208   *     register (I2C_GetFlagStatus()) followed by a write operation to I2C_DR\r
1209   *     register  (I2C_SendData()).\r
1210   * @retval None\r
1211   */\r
1212 void I2C_ClearFlag(I2C_TypeDef* I2Cx, uint32_t I2C_FLAG)\r
1213 {\r
1214   uint32_t flagpos = 0;\r
1215   /* Check the parameters */\r
1216   assert_param(IS_I2C_ALL_PERIPH(I2Cx));\r
1217   assert_param(IS_I2C_CLEAR_FLAG(I2C_FLAG));\r
1218   /* Get the I2C flag position */\r
1219   flagpos = I2C_FLAG & FLAG_Mask;\r
1220   /* Clear the selected I2C flag */\r
1221   I2Cx->SR1 = (uint16_t)~flagpos;\r
1222 }\r
1223 \r
1224 /**\r
1225   * @brief  Checks whether the specified I2C interrupt has occurred or not.\r
1226   * @param  I2Cx: where x can be 1 or 2 to select the I2C peripheral.\r
1227   * @param  I2C_IT: specifies the interrupt source to check. \r
1228   *   This parameter can be one of the following values:\r
1229   *     @arg I2C_IT_SMBALERT: SMBus Alert flag\r
1230   *     @arg I2C_IT_TIMEOUT: Timeout or Tlow error flag\r
1231   *     @arg I2C_IT_PECERR: PEC error in reception flag\r
1232   *     @arg I2C_IT_OVR: Overrun/Underrun flag (Slave mode)\r
1233   *     @arg I2C_IT_AF: Acknowledge failure flag\r
1234   *     @arg I2C_IT_ARLO: Arbitration lost flag (Master mode)\r
1235   *     @arg I2C_IT_BERR: Bus error flag\r
1236   *     @arg I2C_IT_TXE: Data register empty flag (Transmitter)\r
1237   *     @arg I2C_IT_RXNE: Data register not empty (Receiver) flag\r
1238   *     @arg I2C_IT_STOPF: Stop detection flag (Slave mode)\r
1239   *     @arg I2C_IT_ADD10: 10-bit header sent flag (Master mode)\r
1240   *     @arg I2C_IT_BTF: Byte transfer finished flag\r
1241   *     @arg I2C_IT_ADDR: Address sent flag (Master mode) "ADSL"\r
1242   *                       Address matched flag (Slave mode)"ENDAD"\r
1243   *     @arg I2C_IT_SB: Start bit flag (Master mode)\r
1244   * @retval The new state of I2C_IT (SET or RESET).\r
1245   */\r
1246 ITStatus I2C_GetITStatus(I2C_TypeDef* I2Cx, uint32_t I2C_IT)\r
1247 {\r
1248   ITStatus bitstatus = RESET;\r
1249   uint32_t enablestatus = 0;\r
1250 \r
1251   /* Check the parameters */\r
1252   assert_param(IS_I2C_ALL_PERIPH(I2Cx));\r
1253   assert_param(IS_I2C_GET_IT(I2C_IT));\r
1254 \r
1255   /* Check if the interrupt source is enabled or not */\r
1256   enablestatus = (uint32_t)(((I2C_IT & ITEN_Mask) >> 16) & (I2Cx->CR2)) ;\r
1257   \r
1258   /* Get bit[23:0] of the flag */\r
1259   I2C_IT &= FLAG_Mask;\r
1260 \r
1261   /* Check the status of the specified I2C flag */\r
1262   if (((I2Cx->SR1 & I2C_IT) != (uint32_t)RESET) && enablestatus)\r
1263   {\r
1264     /* I2C_IT is set */\r
1265     bitstatus = SET;\r
1266   }\r
1267   else\r
1268   {\r
1269     /* I2C_IT is reset */\r
1270     bitstatus = RESET;\r
1271   }\r
1272   /* Return the I2C_IT status */\r
1273   return  bitstatus;\r
1274 }\r
1275 \r
1276 /**\r
1277   * @brief  Clears the I2Cx\92s interrupt pending bits.\r
1278   * @param  I2Cx: where x can be 1 or 2 to select the I2C peripheral.\r
1279   * @param  I2C_IT: specifies the interrupt pending bit to clear. \r
1280   *   This parameter can be any combination of the following values:\r
1281   *     @arg I2C_IT_SMBALERT: SMBus Alert interrupt\r
1282   *     @arg I2C_IT_TIMEOUT: Timeout or Tlow error interrupt\r
1283   *     @arg I2C_IT_PECERR: PEC error in reception  interrupt\r
1284   *     @arg I2C_IT_OVR: Overrun/Underrun interrupt (Slave mode)\r
1285   *     @arg I2C_IT_AF: Acknowledge failure interrupt\r
1286   *     @arg I2C_IT_ARLO: Arbitration lost interrupt (Master mode)\r
1287   *     @arg I2C_IT_BERR: Bus error interrupt\r
1288   *   \r
1289   * @note\r
1290   *   - STOPF (STOP detection) is cleared by software sequence: a read operation \r
1291   *     to I2C_SR1 register (I2C_GetITStatus()) followed by a write operation to \r
1292   *     I2C_CR1 register (I2C_Cmd() to re-enable the I2C peripheral).\r
1293   *   - ADD10 (10-bit header sent) is cleared by software sequence: a read \r
1294   *     operation to I2C_SR1 (I2C_GetITStatus()) followed by writing the second \r
1295   *     byte of the address in I2C_DR register.\r
1296   *   - BTF (Byte Transfer Finished) is cleared by software sequence: a read \r
1297   *     operation to I2C_SR1 register (I2C_GetITStatus()) followed by a \r
1298   *     read/write to I2C_DR register (I2C_SendData()).\r
1299   *   - ADDR (Address sent) is cleared by software sequence: a read operation to \r
1300   *     I2C_SR1 register (I2C_GetITStatus()) followed by a read operation to \r
1301   *     I2C_SR2 register ((void)(I2Cx->SR2)).\r
1302   *   - SB (Start Bit) is cleared by software sequence: a read operation to \r
1303   *     I2C_SR1 register (I2C_GetITStatus()) followed by a write operation to \r
1304   *     I2C_DR register (I2C_SendData()).\r
1305   * @retval None\r
1306   */\r
1307 void I2C_ClearITPendingBit(I2C_TypeDef* I2Cx, uint32_t I2C_IT)\r
1308 {\r
1309   uint32_t flagpos = 0;\r
1310   /* Check the parameters */\r
1311   assert_param(IS_I2C_ALL_PERIPH(I2Cx));\r
1312   assert_param(IS_I2C_CLEAR_IT(I2C_IT));\r
1313   /* Get the I2C flag position */\r
1314   flagpos = I2C_IT & FLAG_Mask;\r
1315   /* Clear the selected I2C flag */\r
1316   I2Cx->SR1 = (uint16_t)~flagpos;\r
1317 }\r
1318 \r
1319 /**\r
1320   * @}\r
1321   */ \r
1322 \r
1323 /**\r
1324   * @}\r
1325   */ \r
1326 \r
1327 /**\r
1328   * @}\r
1329   */ \r
1330 \r
1331 /******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/\r