1 /*****************************************************************************
2  * Copyright (c) 2019, Nations Technologies Inc.
3  *
4  * All rights reserved.
5  * ****************************************************************************
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions are met:
9  *
10  * - Redistributions of source code must retain the above copyright notice,
11  * this list of conditions and the disclaimer below.
12  *
13  * Nations' name may not be used to endorse or promote products derived from
14  * this software without specific prior written permission.
15  *
16  * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY NATIONS "AS IS" AND ANY EXPRESS OR
17  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
19  * DISCLAIMED. IN NO EVENT SHALL NATIONS BE LIABLE FOR ANY DIRECT, INDIRECT,
20  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
22  * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
25  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  * ****************************************************************************/
27 
28 /**
29  * @file n32wb452_i2c.c
30  * @author Nations
31  * @version v1.0.2
32  *
33  * @copyright Copyright (c) 2019, Nations Technologies Inc. All rights reserved.
34  */
35 #include "n32wb452_i2c.h"
36 #include "n32wb452_rcc.h"
37 
38 /** @addtogroup N32WB452_StdPeriph_Driver
39  * @{
40  */
41 
42 /** @addtogroup I2C
43  * @brief I2C driver modules
44  * @{
45  */
46 
47 /** @addtogroup I2C_Private_TypesDefinitions
48  * @{
49  */
50 
51 /**
52  * @}
53  */
54 
55 /** @addtogroup I2C_Private_Defines
56  * @{
57  */
58 
59 /* I2C SPE mask */
60 #define CTRL1_SPEN_SET   ((uint16_t)0x0001)
61 #define CTRL1_SPEN_RESET ((uint16_t)0xFFFE)
62 
63 /* I2C START mask */
64 #define CTRL1_START_SET   ((uint16_t)0x0100)
65 #define CTRL1_START_RESET ((uint16_t)0xFEFF)
66 
67 /* I2C STOP mask */
68 #define CTRL1_STOP_SET   ((uint16_t)0x0200)
69 #define CTRL1_STOP_RESET ((uint16_t)0xFDFF)
70 
71 /* I2C ACK mask */
72 #define CTRL1_ACK_SET   ((uint16_t)0x0400)
73 #define CTRL1_ACK_RESET ((uint16_t)0xFBFF)
74 
75 /* I2C ENGC mask */
76 #define CTRL1_GCEN_SET   ((uint16_t)0x0040)
77 #define CTRL1_GCEN_RESET ((uint16_t)0xFFBF)
78 
79 /* I2C SWRST mask */
80 #define CTRL1_SWRESET_SET   ((uint16_t)0x8000)
81 #define CTRL1_SWRESET_RESET ((uint16_t)0x7FFF)
82 
83 /* I2C PEC mask */
84 #define CTRL1_PEC_SET   ((uint16_t)0x1000)
85 #define CTRL1_PEC_RESET ((uint16_t)0xEFFF)
86 
87 /* I2C ENPEC mask */
88 #define CTRL1_PECEN_SET   ((uint16_t)0x0020)
89 #define CTRL1_PECEN_RESET ((uint16_t)0xFFDF)
90 
91 /* I2C ENARP mask */
92 #define CTRL1_ARPEN_SET   ((uint16_t)0x0010)
93 #define CTRL1_ARPEN_RESET ((uint16_t)0xFFEF)
94 
95 /* I2C NOSTRETCH mask */
96 #define CTRL1_NOEXTEND_SET   ((uint16_t)0x0080)
97 #define CTRL1_NOEXTEND_RESET ((uint16_t)0xFF7F)
98 
99 /* I2C registers Masks */
100 #define CTRL1_CLR_MASK ((uint16_t)0xFBF5)
101 
102 /* I2C DMAEN mask */
103 #define CTRL2_DMAEN_SET   ((uint16_t)0x0800)
104 #define CTRL2_DMAEN_RESET ((uint16_t)0xF7FF)
105 
106 /* I2C LAST mask */
107 #define CTRL2_DMALAST_SET   ((uint16_t)0x1000)
108 #define CTRL2_DMALAST_RESET ((uint16_t)0xEFFF)
109 
110 /* I2C FREQ mask */
111 #define CTRL2_CLKFREQ_RESET ((uint16_t)0xFFC0)
112 
113 /* I2C ADD0 mask */
114 #define OADDR1_ADDR0_SET   ((uint16_t)0x0001)
115 #define OADDR1_ADDR0_RESET ((uint16_t)0xFFFE)
116 
117 /* I2C ENDUAL mask */
118 #define OADDR2_DUALEN_SET   ((uint16_t)0x0001)
119 #define OADDR2_DUALEN_RESET ((uint16_t)0xFFFE)
120 
121 /* I2C ADD2 mask */
122 #define OADDR2_ADDR2_RESET ((uint16_t)0xFF01)
123 
124 /* I2C F/S mask */
125 #define CLKCTRL_FSMODE_SET ((uint16_t)0x8000)
126 
127 /* I2C CHCFG mask */
128 #define CLKCTRL_CLKCTRL_SET ((uint16_t)0x0FFF)
129 
130 /* I2C FLAG mask */
131 #define FLAG_MASK ((uint32_t)0x00FFFFFF)
132 
133 /* I2C Interrupt Enable mask */
134 #define INTEN_MASK ((uint32_t)0x07000000)
135 
136 /**
137  * @}
138  */
139 
140 /** @addtogroup I2C_Private_Macros
141  * @{
142  */
143 
144 /**
145  * @}
146  */
147 
148 /** @addtogroup I2C_Private_Variables
149  * @{
150  */
151 
152 /**
153  * @}
154  */
155 
156 /** @addtogroup I2C_Private_FunctionPrototypes
157  * @{
158  */
159 
160 /**
161  * @}
162  */
163 
164 /** @addtogroup I2C_Private_Functions
165  * @{
166  */
167 
168 /**
169  * @brief  Deinitializes the I2Cx peripheral registers to their default reset values.
170  * @param I2Cx where x can be 1 or 2 to select the I2C peripheral.
171  */
I2C_DeInit(I2C_Module * I2Cx)172 void I2C_DeInit(I2C_Module* I2Cx)
173 {
174     /* Check the parameters */
175     assert_param(IS_I2C_PERIPH(I2Cx));
176 
177     if (I2Cx == I2C1)
178     {
179         /* Enable I2C1 reset state */
180         RCC_EnableAPB1PeriphReset(RCC_APB1_PERIPH_I2C1, ENABLE);
181         /* Release I2C1 from reset state */
182         RCC_EnableAPB1PeriphReset(RCC_APB1_PERIPH_I2C1, DISABLE);
183     }
184     else if (I2Cx == I2C2)
185     {
186         /* Enable I2C2 reset state */
187         RCC_EnableAPB1PeriphReset(RCC_APB1_PERIPH_I2C2, ENABLE);
188         /* Release I2C2 from reset state */
189         RCC_EnableAPB1PeriphReset(RCC_APB1_PERIPH_I2C2, DISABLE);
190     }
191     else if (I2Cx == I2C3)
192     {
193         /* Enable I2C3 reset state */
194         RCC_EnableAPB2PeriphReset(RCC_APB2_PERIPH_I2C3, ENABLE);
195         /* Release I2C3 from reset state */
196         RCC_EnableAPB2PeriphReset(RCC_APB2_PERIPH_I2C3, DISABLE);
197     }
198     else if (I2Cx == I2C4)
199     {
200         /* Enable I2C4 reset state */
201         RCC_EnableAPB2PeriphReset(RCC_APB2_PERIPH_I2C4, ENABLE);
202         /* Release I2C4 from reset state */
203         RCC_EnableAPB2PeriphReset(RCC_APB2_PERIPH_I2C4, DISABLE);
204     }
205     else
206     {
207 
208     }
209 }
210 
211 /**
212  * @brief  Initializes the I2Cx peripheral according to the specified
213  *   parameters in the I2C_InitStruct.
214  * @param I2Cx where x can be 1 or 2 to select the I2C peripheral.
215  * @param I2C_InitStruct pointer to a I2C_InitType structure that
216  *   contains the configuration information for the specified I2C peripheral.
217  */
I2C_Init(I2C_Module * I2Cx,I2C_InitType * I2C_InitStruct)218 void I2C_Init(I2C_Module* I2Cx, I2C_InitType* I2C_InitStruct)
219 {
220     uint16_t tmpregister = 0, freqrange = 0;
221     uint16_t result = 0x04;
222     uint32_t pclk  = 8000000;
223     RCC_ClocksType rcc_clocks;
224     /* Check the parameters */
225     assert_param(IS_I2C_PERIPH(I2Cx));
226     assert_param(IS_I2C_CLK_SPEED(I2C_InitStruct->ClkSpeed));
227     assert_param(IS_I2C_BUS_MODE(I2C_InitStruct->BusMode));
228     assert_param(IS_I2C_FM_DUTY_CYCLE(I2C_InitStruct->FmDutyCycle));
229     assert_param(IS_I2C_OWN_ADDR1(I2C_InitStruct->OwnAddr1));
230     assert_param(IS_I2C_ACK_STATE(I2C_InitStruct->AckEnable));
231     assert_param(IS_I2C_ADDR_MODE(I2C_InitStruct->AddrMode));
232 
233     /*---------------------------- I2Cx CTRL2 Configuration ------------------------*/
234     /* Get the I2Cx CTRL2 value */
235     tmpregister = I2Cx->CTRL2;
236     /* Clear frequency FREQ[5:0] bits */
237     tmpregister &= CTRL2_CLKFREQ_RESET;
238     /* Get APB1/2 frequency value */
239     RCC_GetClocksFreqValue(&rcc_clocks);
240 
241     if ((I2Cx == I2C1) || (I2Cx == I2C2))
242     {
243         pclk = rcc_clocks.Pclk1Freq;
244     }
245     else if ((I2Cx == I2C3) || (I2Cx == I2C4))
246     {
247         pclk = rcc_clocks.Pclk2Freq;
248     }
249 
250     /* Set frequency bits depending on pclk1 value */
251     freqrange = (uint16_t)(pclk / 1000000);
252     if (tmpregister > 36)
253     {
254         tmpregister = 36;
255     }
256     /* Write to I2Cx CTRL2 */
257     tmpregister |= freqrange;
258     I2Cx->CTRL2 = tmpregister;
259 
260     /*---------------------------- I2Cx CHCFG Configuration ------------------------*/
261     /* Disable the selected I2C peripheral to configure TMRISE */
262     I2Cx->CTRL1 &= CTRL1_SPEN_RESET;
263     /* Reset tmpregister value */
264     /* Clear F/S, DUTY and CHCFG[11:0] bits */
265     tmpregister = 0;
266 
267     /* Configure speed in standard mode */
268     if (I2C_InitStruct->ClkSpeed <= 100000)
269     {
270         /* Standard mode speed calculate */
271         result = (uint16_t)(pclk / (I2C_InitStruct->ClkSpeed << 1));
272         /* Test if CHCFG value is under 0x4*/
273         if (result < 0x04)
274         {
275             /* Set minimum allowed value */
276             result = 0x04;
277         }
278         /* Set speed value for standard mode */
279         tmpregister |= result;
280         /* Set Maximum Rise Time for standard mode */
281         I2Cx->TMRISE = freqrange + 1;
282     }
283     /* Configure speed in fast mode */
284     else
285     {
286         if (I2C_InitStruct->FmDutyCycle == I2C_FMDUTYCYCLE_2)
287         {
288             /* Fast mode speed calculate: Tlow/Thigh = 2 */
289             result = (uint16_t)(pclk / (I2C_InitStruct->ClkSpeed * 3));
290         }
291         else /*I2C_InitStruct->FmDutyCycle == I2C_FMDUTYCYCLE_16_9*/
292         {
293             /* Fast mode speed calculate: Tlow/Thigh = 16/9 */
294             result = (uint16_t)(pclk / (I2C_InitStruct->ClkSpeed * 25));
295             /* Set DUTY bit */
296             result |= I2C_FMDUTYCYCLE_16_9;
297         }
298 
299         /* Test if CHCFG value is under 0x1*/
300         if ((result & CLKCTRL_CLKCTRL_SET) == 0)
301         {
302             /* Set minimum allowed value */
303             result |= (uint16_t)0x0001;
304         }
305         /* Set speed value and set F/S bit for fast mode */
306         tmpregister |= (uint16_t)(result | CLKCTRL_FSMODE_SET);
307 
308         /* Set Maximum Rise Time for fast mode */
309         I2Cx->TMRISE = (uint16_t)(((freqrange * (uint16_t)300) / (uint16_t)1000) + (uint16_t)1);
310     }
311     /* Write to I2Cx CHCFG */
312     I2Cx->CLKCTRL = tmpregister;
313     /* Enable the selected I2C peripheral */
314     I2Cx->CTRL1 |= CTRL1_SPEN_SET;
315 
316     /*---------------------------- I2Cx CTRL1 Configuration ------------------------*/
317     /* Get the I2Cx CTRL1 value */
318     tmpregister = I2Cx->CTRL1;
319     /* Clear ACK, SMBTYPE and  SMBUS bits */
320     tmpregister &= CTRL1_CLR_MASK;
321     /* Configure I2Cx: mode and acknowledgement */
322     /* Set SMBTYPE and SMBUS bits according to BusMode value */
323     /* Set ACK bit according to AckEnable value */
324     tmpregister |= (uint16_t)((uint32_t)I2C_InitStruct->BusMode | I2C_InitStruct->AckEnable);
325     /* Write to I2Cx CTRL1 */
326     I2Cx->CTRL1 = tmpregister;
327 
328     /*---------------------------- I2Cx OADDR1 Configuration -----------------------*/
329     /* Set I2Cx Own Address1 and acknowledged address */
330     I2Cx->OADDR1 = (I2C_InitStruct->AddrMode | I2C_InitStruct->OwnAddr1);
331 }
332 
333 /**
334  * @brief  Fills each I2C_InitStruct member with its default value.
335  * @param I2C_InitStruct pointer to an I2C_InitType structure which will be initialized.
336  */
I2C_InitStruct(I2C_InitType * I2C_InitStruct)337 void I2C_InitStruct(I2C_InitType* I2C_InitStruct)
338 {
339     /*---------------- Reset I2C init structure parameters values ----------------*/
340     /* initialize the ClkSpeed member */
341     I2C_InitStruct->ClkSpeed = 5000;
342     /* Initialize the BusMode member */
343     I2C_InitStruct->BusMode = I2C_BUSMODE_I2C;
344     /* Initialize the FmDutyCycle member */
345     I2C_InitStruct->FmDutyCycle = I2C_FMDUTYCYCLE_2;
346     /* Initialize the OwnAddr1 member */
347     I2C_InitStruct->OwnAddr1 = 0;
348     /* Initialize the AckEnable member */
349     I2C_InitStruct->AckEnable = I2C_ACKDIS;
350     /* Initialize the AddrMode member */
351     I2C_InitStruct->AddrMode = I2C_ADDR_MODE_7BIT;
352 }
353 
354 /**
355  * @brief  Enables or disables the specified I2C peripheral.
356  * @param I2Cx where x can be 1 or 2 to select the I2C peripheral.
357  * @param Cmd new state of the I2Cx peripheral.
358  *   This parameter can be: ENABLE or DISABLE.
359  */
I2C_Enable(I2C_Module * I2Cx,FunctionalState Cmd)360 void I2C_Enable(I2C_Module* I2Cx, FunctionalState Cmd)
361 {
362     /* Check the parameters */
363     assert_param(IS_I2C_PERIPH(I2Cx));
364     assert_param(IS_FUNCTIONAL_STATE(Cmd));
365     if (Cmd != DISABLE)
366     {
367         /* Enable the selected I2C peripheral */
368         I2Cx->CTRL1 |= CTRL1_SPEN_SET;
369     }
370     else
371     {
372         /* Disable the selected I2C peripheral */
373         I2Cx->CTRL1 &= CTRL1_SPEN_RESET;
374     }
375 }
376 
377 /**
378  * @brief  Enables or disables the specified I2C DMA requests.
379  * @param I2Cx where x can be 1 or 2 to select the I2C peripheral.
380  * @param Cmd new state of the I2C DMA transfer.
381  *   This parameter can be: ENABLE or DISABLE.
382  */
I2C_EnableDMA(I2C_Module * I2Cx,FunctionalState Cmd)383 void I2C_EnableDMA(I2C_Module* I2Cx, FunctionalState Cmd)
384 {
385     /* Check the parameters */
386     assert_param(IS_I2C_PERIPH(I2Cx));
387     assert_param(IS_FUNCTIONAL_STATE(Cmd));
388     if (Cmd != DISABLE)
389     {
390         /* Enable the selected I2C DMA requests */
391         I2Cx->CTRL2 |= CTRL2_DMAEN_SET;
392     }
393     else
394     {
395         /* Disable the selected I2C DMA requests */
396         I2Cx->CTRL2 &= CTRL2_DMAEN_RESET;
397     }
398 }
399 
400 /**
401  * @brief  Specifies if the next DMA transfer will be the last one.
402  * @param I2Cx where x can be 1 or 2 to select the I2C peripheral.
403  * @param Cmd new state of the I2C DMA last transfer.
404  *   This parameter can be: ENABLE or DISABLE.
405  */
I2C_EnableDmaLastSend(I2C_Module * I2Cx,FunctionalState Cmd)406 void I2C_EnableDmaLastSend(I2C_Module* I2Cx, FunctionalState Cmd)
407 {
408     /* Check the parameters */
409     assert_param(IS_I2C_PERIPH(I2Cx));
410     assert_param(IS_FUNCTIONAL_STATE(Cmd));
411     if (Cmd != DISABLE)
412     {
413         /* Next DMA transfer is the last transfer */
414         I2Cx->CTRL2 |= CTRL2_DMALAST_SET;
415     }
416     else
417     {
418         /* Next DMA transfer is not the last transfer */
419         I2Cx->CTRL2 &= CTRL2_DMALAST_RESET;
420     }
421 }
422 
423 /**
424  * @brief  Generates I2Cx communication START condition.
425  * @param I2Cx where x can be 1 or 2 to select the I2C peripheral.
426  * @param Cmd new state of the I2C START condition generation.
427  *   This parameter can be: ENABLE or DISABLE.
428  */
I2C_GenerateStart(I2C_Module * I2Cx,FunctionalState Cmd)429 void I2C_GenerateStart(I2C_Module* I2Cx, FunctionalState Cmd)
430 {
431     /* Check the parameters */
432     assert_param(IS_I2C_PERIPH(I2Cx));
433     assert_param(IS_FUNCTIONAL_STATE(Cmd));
434     if (Cmd != DISABLE)
435     {
436         /* Generate a START condition */
437         I2Cx->CTRL1 |= CTRL1_START_SET;
438     }
439     else
440     {
441         /* Disable the START condition generation */
442         I2Cx->CTRL1 &= CTRL1_START_RESET;
443     }
444 }
445 
446 /**
447  * @brief  Generates I2Cx communication STOP condition.
448  * @param I2Cx where x can be 1 or 2 to select the I2C peripheral.
449  * @param Cmd new state of the I2C STOP condition generation.
450  *   This parameter can be: ENABLE or DISABLE.
451  */
I2C_GenerateStop(I2C_Module * I2Cx,FunctionalState Cmd)452 void I2C_GenerateStop(I2C_Module* I2Cx, FunctionalState Cmd)
453 {
454     /* Check the parameters */
455     assert_param(IS_I2C_PERIPH(I2Cx));
456     assert_param(IS_FUNCTIONAL_STATE(Cmd));
457     if (Cmd != DISABLE)
458     {
459         /* Generate a STOP condition */
460         I2Cx->CTRL1 |= CTRL1_STOP_SET;
461     }
462     else
463     {
464         /* Disable the STOP condition generation */
465         I2Cx->CTRL1 &= CTRL1_STOP_RESET;
466     }
467 }
468 
469 /**
470  * @brief  Enables or disables the specified I2C acknowledge feature.
471  * @param I2Cx where x can be 1 or 2 to select the I2C peripheral.
472  * @param Cmd new state of the I2C Acknowledgement.
473  *   This parameter can be: ENABLE or DISABLE.
474  */
I2C_ConfigAck(I2C_Module * I2Cx,FunctionalState Cmd)475 void I2C_ConfigAck(I2C_Module* I2Cx, FunctionalState Cmd)
476 {
477     /* Check the parameters */
478     assert_param(IS_I2C_PERIPH(I2Cx));
479     assert_param(IS_FUNCTIONAL_STATE(Cmd));
480     if (Cmd != DISABLE)
481     {
482         /* Enable the acknowledgement */
483         I2Cx->CTRL1 |= CTRL1_ACK_SET;
484     }
485     else
486     {
487         /* Disable the acknowledgement */
488         I2Cx->CTRL1 &= CTRL1_ACK_RESET;
489     }
490 }
491 
492 /**
493  * @brief  Configures the specified I2C own address2.
494  * @param I2Cx where x can be 1 or 2 to select the I2C peripheral.
495  * @param Address specifies the 7bit I2C own address2.
496  */
I2C_ConfigOwnAddr2(I2C_Module * I2Cx,uint8_t Address)497 void I2C_ConfigOwnAddr2(I2C_Module* I2Cx, uint8_t Address)
498 {
499     uint16_t tmpregister = 0;
500 
501     /* Check the parameters */
502     assert_param(IS_I2C_PERIPH(I2Cx));
503 
504     /* Get the old register value */
505     tmpregister = I2Cx->OADDR2;
506 
507     /* Reset I2Cx Own address2 bit [7:1] */
508     tmpregister &= OADDR2_ADDR2_RESET;
509 
510     /* Set I2Cx Own address2 */
511     tmpregister |= (uint16_t)((uint16_t)Address & (uint16_t)0x00FE);
512 
513     /* Store the new register value */
514     I2Cx->OADDR2 = tmpregister;
515 }
516 
517 /**
518  * @brief  Enables or disables the specified I2C dual addressing mode.
519  * @param I2Cx where x can be 1 or 2 to select the I2C peripheral.
520  * @param Cmd new state of the I2C dual addressing mode.
521  *   This parameter can be: ENABLE or DISABLE.
522  */
I2C_EnableDualAddr(I2C_Module * I2Cx,FunctionalState Cmd)523 void I2C_EnableDualAddr(I2C_Module* I2Cx, FunctionalState Cmd)
524 {
525     /* Check the parameters */
526     assert_param(IS_I2C_PERIPH(I2Cx));
527     assert_param(IS_FUNCTIONAL_STATE(Cmd));
528     if (Cmd != DISABLE)
529     {
530         /* Enable dual addressing mode */
531         I2Cx->OADDR2 |= OADDR2_DUALEN_SET;
532     }
533     else
534     {
535         /* Disable dual addressing mode */
536         I2Cx->OADDR2 &= OADDR2_DUALEN_RESET;
537     }
538 }
539 
540 /**
541  * @brief  Enables or disables the specified I2C general call feature.
542  * @param I2Cx where x can be 1 or 2 to select the I2C peripheral.
543  * @param Cmd new state of the I2C General call.
544  *   This parameter can be: ENABLE or DISABLE.
545  */
I2C_EnableGeneralCall(I2C_Module * I2Cx,FunctionalState Cmd)546 void I2C_EnableGeneralCall(I2C_Module* I2Cx, FunctionalState Cmd)
547 {
548     /* Check the parameters */
549     assert_param(IS_I2C_PERIPH(I2Cx));
550     assert_param(IS_FUNCTIONAL_STATE(Cmd));
551     if (Cmd != DISABLE)
552     {
553         /* Enable generall call */
554         I2Cx->CTRL1 |= CTRL1_GCEN_SET;
555     }
556     else
557     {
558         /* Disable generall call */
559         I2Cx->CTRL1 &= CTRL1_GCEN_RESET;
560     }
561 }
562 
563 /**
564  * @brief  Enables or disables the specified I2C interrupts.
565  * @param I2Cx where x can be 1 or 2 to select the I2C peripheral.
566  * @param I2C_IT specifies the I2C interrupts sources to be enabled or disabled.
567  *   This parameter can be any combination of the following values:
568  *     @arg I2C_INT_BUF Buffer interrupt mask
569  *     @arg I2C_INT_EVENT Event interrupt mask
570  *     @arg I2C_INT_ERR Error interrupt mask
571  * @param Cmd new state of the specified I2C interrupts.
572  *   This parameter can be: ENABLE or DISABLE.
573  */
I2C_ConfigInt(I2C_Module * I2Cx,uint16_t I2C_IT,FunctionalState Cmd)574 void I2C_ConfigInt(I2C_Module* I2Cx, uint16_t I2C_IT, FunctionalState Cmd)
575 {
576     /* Check the parameters */
577     assert_param(IS_I2C_PERIPH(I2Cx));
578     assert_param(IS_FUNCTIONAL_STATE(Cmd));
579     assert_param(IS_I2C_CFG_INT(I2C_IT));
580 
581     if (Cmd != DISABLE)
582     {
583         /* Enable the selected I2C interrupts */
584         I2Cx->CTRL2 |= I2C_IT;
585     }
586     else
587     {
588         /* Disable the selected I2C interrupts */
589         I2Cx->CTRL2 &= (uint16_t)~I2C_IT;
590     }
591 }
592 
593 /**
594  * @brief  Sends a data byte through the I2Cx peripheral.
595  * @param I2Cx where x can be 1 or 2 to select the I2C peripheral.
596  * @param Data Byte to be transmitted..
597  */
I2C_SendData(I2C_Module * I2Cx,uint8_t Data)598 void I2C_SendData(I2C_Module* I2Cx, uint8_t Data)
599 {
600     /* Check the parameters */
601     assert_param(IS_I2C_PERIPH(I2Cx));
602     /* Write in the DAT register the data to be sent */
603     I2Cx->DAT = Data;
604 }
605 
606 /**
607  * @brief  Returns the most recent received data by the I2Cx peripheral.
608  * @param I2Cx where x can be 1 or 2 to select the I2C peripheral.
609  * @return The value of the received data.
610  */
I2C_RecvData(I2C_Module * I2Cx)611 uint8_t I2C_RecvData(I2C_Module* I2Cx)
612 {
613     /* Check the parameters */
614     assert_param(IS_I2C_PERIPH(I2Cx));
615     /* Return the data in the DAT register */
616     return (uint8_t)I2Cx->DAT;
617 }
618 
619 /**
620  * @brief  Transmits the address byte to select the slave device.
621  * @param I2Cx where x can be 1 or 2 to select the I2C peripheral.
622  * @param Address specifies the slave address which will be transmitted
623  * @param I2C_Direction specifies whether the I2C device will be a
624  *   Transmitter or a Receiver. This parameter can be one of the following values
625  *     @arg I2C_DIRECTION_SEND Transmitter mode
626  *     @arg I2C_DIRECTION_RECV Receiver mode
627  */
I2C_SendAddr7bit(I2C_Module * I2Cx,uint8_t Address,uint8_t I2C_Direction)628 void I2C_SendAddr7bit(I2C_Module* I2Cx, uint8_t Address, uint8_t I2C_Direction)
629 {
630     /* Check the parameters */
631     assert_param(IS_I2C_PERIPH(I2Cx));
632     assert_param(IS_I2C_DIRECTION(I2C_Direction));
633     /* Test on the direction to set/reset the read/write bit */
634     if (I2C_Direction != I2C_DIRECTION_SEND)
635     {
636         /* Set the address bit0 for read */
637         Address |= OADDR1_ADDR0_SET;
638     }
639     else
640     {
641         /* Reset the address bit0 for write */
642         Address &= OADDR1_ADDR0_RESET;
643     }
644     /* Send the address */
645     I2Cx->DAT = Address;
646 }
647 
648 /**
649  * @brief  Reads the specified I2C register and returns its value.
650  * @param I2Cx where x can be 1 or 2 to select the I2C peripheral.
651  * @param I2C_Register specifies the register to read.
652  *   This parameter can be one of the following values:
653  *     @arg I2C_REG_CTRL1 CTRL1 register.
654  *     @arg I2C_REG_CTRL2 CTRL2 register.
655  *     @arg I2C_REG_OADDR1 OADDR1 register.
656  *     @arg I2C_REG_OADDR2 OADDR2 register.
657  *     @arg I2C_REG_DAT DAT register.
658  *     @arg I2C_REG_STS1 STS1 register.
659  *     @arg I2C_REG_STS2 STS2 register.
660  *     @arg I2C_REG_CLKCTRL CHCFG register.
661  *     @arg I2C_REG_TMRISE TMRISE register.
662  * @return The value of the read register.
663  */
I2C_GetRegister(I2C_Module * I2Cx,uint8_t I2C_Register)664 uint16_t I2C_GetRegister(I2C_Module* I2Cx, uint8_t I2C_Register)
665 {
666     __IO uint32_t tmp = 0;
667 
668     /* Check the parameters */
669     assert_param(IS_I2C_PERIPH(I2Cx));
670     assert_param(IS_I2C_REG(I2C_Register));
671 
672     tmp = (uint32_t)I2Cx;
673     tmp += I2C_Register;
674 
675     /* Return the selected register value */
676     return (*(__IO uint16_t*)tmp);
677 }
678 
679 /**
680  * @brief  Enables or disables the specified I2C software reset.
681  * @param I2Cx where x can be 1 or 2 to select the I2C peripheral.
682  * @param Cmd new state of the I2C software reset.
683  *   This parameter can be: ENABLE or DISABLE.
684  */
I2C_EnableSoftwareReset(I2C_Module * I2Cx,FunctionalState Cmd)685 void I2C_EnableSoftwareReset(I2C_Module* I2Cx, FunctionalState Cmd)
686 {
687     /* Check the parameters */
688     assert_param(IS_I2C_PERIPH(I2Cx));
689     assert_param(IS_FUNCTIONAL_STATE(Cmd));
690     if (Cmd != DISABLE)
691     {
692         /* Peripheral under reset */
693         I2Cx->CTRL1 |= CTRL1_SWRESET_SET;
694     }
695     else
696     {
697         /* Peripheral not under reset */
698         I2Cx->CTRL1 &= CTRL1_SWRESET_RESET;
699     }
700 }
701 
702 /**
703  * @brief  Selects the specified I2C NACK position in master receiver mode.
704  *         This function is useful in I2C Master Receiver mode when the number
705  *         of data to be received is equal to 2. In this case, this function
706  *         should be called (with parameter I2C_NACK_POS_NEXT) before data
707  *         reception starts,as described in the 2-byte reception procedure
708  *         recommended in Reference Manual in Section: Master receiver.
709  * @param I2Cx where x can be 1 or 2 to select the I2C peripheral.
710  * @param I2C_NACKPosition specifies the NACK position.
711  *   This parameter can be one of the following values:
712  *     @arg I2C_NACK_POS_NEXT indicates that the next byte will be the last
713  *          received byte.
714  *     @arg I2C_NACK_POS_CURRENT indicates that current byte is the last
715  *          received byte.
716  *
717  * @note    This function configures the same bit (POS) as I2C_ConfigPecLocation()
718  *          but is intended to be used in I2C mode while I2C_ConfigPecLocation()
719  *          is intended to used in SMBUS mode.
720  *
721  */
I2C_ConfigNackLocation(I2C_Module * I2Cx,uint16_t I2C_NACKPosition)722 void I2C_ConfigNackLocation(I2C_Module* I2Cx, uint16_t I2C_NACKPosition)
723 {
724     /* Check the parameters */
725     assert_param(IS_I2C_PERIPH(I2Cx));
726     assert_param(IS_I2C_NACK_POS(I2C_NACKPosition));
727 
728     /* Check the input parameter */
729     if (I2C_NACKPosition == I2C_NACK_POS_NEXT)
730     {
731         /* Next byte in shift register is the last received byte */
732         I2Cx->CTRL1 |= I2C_NACK_POS_NEXT;
733     }
734     else
735     {
736         /* Current byte in shift register is the last received byte */
737         I2Cx->CTRL1 &= I2C_NACK_POS_CURRENT;
738     }
739 }
740 
741 /**
742  * @brief  Drives the SMBusAlert pin high or low for the specified I2C.
743  * @param I2Cx where x can be 1 or 2 to select the I2C peripheral.
744  * @param I2C_SMBusAlert specifies SMBAlert pin level.
745  *   This parameter can be one of the following values:
746  *     @arg I2C_SMBALERT_LOW SMBAlert pin driven low
747  *     @arg I2C_SMBALERT_HIGH SMBAlert pin driven high
748  */
I2C_ConfigSmbusAlert(I2C_Module * I2Cx,uint16_t I2C_SMBusAlert)749 void I2C_ConfigSmbusAlert(I2C_Module* I2Cx, uint16_t I2C_SMBusAlert)
750 {
751     /* Check the parameters */
752     assert_param(IS_I2C_PERIPH(I2Cx));
753     assert_param(IS_I2C_SMB_ALERT(I2C_SMBusAlert));
754     if (I2C_SMBusAlert == I2C_SMBALERT_LOW)
755     {
756         /* Drive the SMBusAlert pin Low */
757         I2Cx->CTRL1 |= I2C_SMBALERT_LOW;
758     }
759     else
760     {
761         /* Drive the SMBusAlert pin High  */
762         I2Cx->CTRL1 &= I2C_SMBALERT_HIGH;
763     }
764 }
765 
766 /**
767  * @brief  Enables or disables the specified I2C PEC transfer.
768  * @param I2Cx where x can be 1 or 2 to select the I2C peripheral.
769  * @param Cmd new state of the I2C PEC transmission.
770  *   This parameter can be: ENABLE or DISABLE.
771  */
I2C_SendPEC(I2C_Module * I2Cx,FunctionalState Cmd)772 void I2C_SendPEC(I2C_Module* I2Cx, FunctionalState Cmd)
773 {
774     /* Check the parameters */
775     assert_param(IS_I2C_PERIPH(I2Cx));
776     assert_param(IS_FUNCTIONAL_STATE(Cmd));
777     if (Cmd != DISABLE)
778     {
779         /* Enable the selected I2C PEC transmission */
780         I2Cx->CTRL1 |= CTRL1_PEC_SET;
781     }
782     else
783     {
784         /* Disable the selected I2C PEC transmission */
785         I2Cx->CTRL1 &= CTRL1_PEC_RESET;
786     }
787 }
788 
789 /**
790  * @brief  Selects the specified I2C PEC position.
791  * @param I2Cx where x can be 1 or 2 to select the I2C peripheral.
792  * @param I2C_PECPosition specifies the PEC position.
793  *   This parameter can be one of the following values:
794  *     @arg I2C_PEC_POS_NEXT indicates that the next byte is PEC
795  *     @arg I2C_PEC_POS_CURRENT indicates that current byte is PEC
796  *
797  * @note    This function configures the same bit (POS) as I2C_ConfigNackLocation()
798  *          but is intended to be used in SMBUS mode while I2C_ConfigNackLocation()
799  *          is intended to used in I2C mode.
800  *
801  */
I2C_ConfigPecLocation(I2C_Module * I2Cx,uint16_t I2C_PECPosition)802 void I2C_ConfigPecLocation(I2C_Module* I2Cx, uint16_t I2C_PECPosition)
803 {
804     /* Check the parameters */
805     assert_param(IS_I2C_PERIPH(I2Cx));
806     assert_param(IS_I2C_PEC_POS(I2C_PECPosition));
807     if (I2C_PECPosition == I2C_PEC_POS_NEXT)
808     {
809         /* Next byte in shift register is PEC */
810         I2Cx->CTRL1 |= I2C_PEC_POS_NEXT;
811     }
812     else
813     {
814         /* Current byte in shift register is PEC */
815         I2Cx->CTRL1 &= I2C_PEC_POS_CURRENT;
816     }
817 }
818 
819 /**
820  * @brief  Enables or disables the PEC value calculation of the transferred bytes.
821  * @param I2Cx where x can be 1 or 2 to select the I2C peripheral.
822  * @param Cmd new state of the I2Cx PEC value calculation.
823  *   This parameter can be: ENABLE or DISABLE.
824  */
I2C_ComputePec(I2C_Module * I2Cx,FunctionalState Cmd)825 void I2C_ComputePec(I2C_Module* I2Cx, FunctionalState Cmd)
826 {
827     /* Check the parameters */
828     assert_param(IS_I2C_PERIPH(I2Cx));
829     assert_param(IS_FUNCTIONAL_STATE(Cmd));
830     if (Cmd != DISABLE)
831     {
832         /* Enable the selected I2C PEC calculation */
833         I2Cx->CTRL1 |= CTRL1_PECEN_SET;
834     }
835     else
836     {
837         /* Disable the selected I2C PEC calculation */
838         I2Cx->CTRL1 &= CTRL1_PECEN_RESET;
839     }
840 }
841 
842 /**
843  * @brief  Returns the PEC value for the specified I2C.
844  * @param I2Cx where x can be 1 or 2 to select the I2C peripheral.
845  * @return The PEC value.
846  */
I2C_GetPec(I2C_Module * I2Cx)847 uint8_t I2C_GetPec(I2C_Module* I2Cx)
848 {
849     /* Check the parameters */
850     assert_param(IS_I2C_PERIPH(I2Cx));
851     /* Return the selected I2C PEC value */
852     return ((I2Cx->STS2) >> 8);
853 }
854 
855 /**
856  * @brief  Enables or disables the specified I2C ARP.
857  * @param I2Cx where x can be 1 or 2 to select the I2C peripheral.
858  * @param Cmd new state of the I2Cx ARP.
859  *   This parameter can be: ENABLE or DISABLE.
860  */
I2C_EnableArp(I2C_Module * I2Cx,FunctionalState Cmd)861 void I2C_EnableArp(I2C_Module* I2Cx, FunctionalState Cmd)
862 {
863     /* Check the parameters */
864     assert_param(IS_I2C_PERIPH(I2Cx));
865     assert_param(IS_FUNCTIONAL_STATE(Cmd));
866     if (Cmd != DISABLE)
867     {
868         /* Enable the selected I2C ARP */
869         I2Cx->CTRL1 |= CTRL1_ARPEN_SET;
870     }
871     else
872     {
873         /* Disable the selected I2C ARP */
874         I2Cx->CTRL1 &= CTRL1_ARPEN_RESET;
875     }
876 }
877 
878 /**
879  * @brief  Enables or disables the specified I2C Clock stretching.
880  * @param I2Cx where x can be 1 or 2 to select the I2C peripheral.
881  * @param Cmd new state of the I2Cx Clock stretching.
882  *   This parameter can be: ENABLE or DISABLE.
883  */
I2C_EnableExtendClk(I2C_Module * I2Cx,FunctionalState Cmd)884 void I2C_EnableExtendClk(I2C_Module* I2Cx, FunctionalState Cmd)
885 {
886     /* Check the parameters */
887     assert_param(IS_I2C_PERIPH(I2Cx));
888     assert_param(IS_FUNCTIONAL_STATE(Cmd));
889     if (Cmd == DISABLE)
890     {
891         /* Enable the selected I2C Clock stretching */
892         I2Cx->CTRL1 |= CTRL1_NOEXTEND_SET;
893     }
894     else
895     {
896         /* Disable the selected I2C Clock stretching */
897         I2Cx->CTRL1 &= CTRL1_NOEXTEND_RESET;
898     }
899 }
900 
901 /**
902  * @brief  Selects the specified I2C fast mode duty cycle.
903  * @param I2Cx where x can be 1 or 2 to select the I2C peripheral.
904  * @param FmDutyCycle specifies the fast mode duty cycle.
905  *   This parameter can be one of the following values:
906  *     @arg I2C_FMDUTYCYCLE_2 I2C fast mode Tlow/Thigh = 2
907  *     @arg I2C_FMDUTYCYCLE_16_9 I2C fast mode Tlow/Thigh = 16/9
908  */
I2C_ConfigFastModeDutyCycle(I2C_Module * I2Cx,uint16_t FmDutyCycle)909 void I2C_ConfigFastModeDutyCycle(I2C_Module* I2Cx, uint16_t FmDutyCycle)
910 {
911     /* Check the parameters */
912     assert_param(IS_I2C_PERIPH(I2Cx));
913     assert_param(IS_I2C_FM_DUTY_CYCLE(FmDutyCycle));
914     if (FmDutyCycle != I2C_FMDUTYCYCLE_16_9)
915     {
916         /* I2C fast mode Tlow/Thigh=2 */
917         I2Cx->CLKCTRL &= I2C_FMDUTYCYCLE_2;
918     }
919     else
920     {
921         /* I2C fast mode Tlow/Thigh=16/9 */
922         I2Cx->CLKCTRL |= I2C_FMDUTYCYCLE_16_9;
923     }
924 }
925 
926 /**
927  * @brief
928  ****************************************************************************************
929  *
930  *                         I2C State Monitoring Functions
931  *
932  ****************************************************************************************
933  * This I2C driver provides three different ways for I2C state monitoring
934  *  depending on the application requirements and constraints:
935  *
936  *
937  * 1) Basic state monitoring:
938  *    Using I2C_CheckEvent() function:
939  *    It compares the status registers (STS1 and STS2) content to a given event
940  *    (can be the combination of one or more flags).
941  *    It returns SUCCESS if the current status includes the given flags
942  *    and returns ERROR if one or more flags are missing in the current status.
943  *    - When to use:
944  *      - This function is suitable for most applications as well as for startup
945  *      activity since the events are fully described in the product reference manual
946  *      (RM0008).
947  *      - It is also suitable for users who need to define their own events.
948  *    - Limitations:
949  *      - If an error occurs (ie. error flags are set besides to the monitored flags),
950  *        the I2C_CheckEvent() function may return SUCCESS despite the communication
951  *        hold or corrupted real state.
952  *        In this case, it is advised to use error interrupts to monitor the error
953  *        events and handle them in the interrupt IRQ handler.
954  *
955  *        @note
956  *        For error management, it is advised to use the following functions:
957  *          - I2C_ConfigInt() to configure and enable the error interrupts (I2C_INT_ERR).
958  *          - I2Cx_ER_IRQHandler() which is called when the error interrupt occurs.
959  *            Where x is the peripheral instance (I2C1, I2C2 ...)
960  *          - I2C_GetFlag() or I2C_GetIntStatus() to be called into I2Cx_ER_IRQHandler()
961  *            in order to determine which error occured.
962  *          - I2C_ClrFlag() or I2C_ClrIntPendingBit() and/or I2C_EnableSoftwareReset()
963  *            and/or I2C_GenerateStop() in order to clear the error flag and source,
964  *            and return to correct communication status.
965  *
966  *
967  *  2) Advanced state monitoring:
968  *     Using the function I2C_GetLastEvent() which returns the image of both status
969  *     registers in a single word (uint32_t) (Status Register 2 value is shifted left
970  *     by 16 bits and concatenated to Status Register 1).
971  *     - When to use:
972  *       - This function is suitable for the same applications above but it allows to
973  *         overcome the mentioned limitation of I2C_GetFlag() function.
974  *         The returned value could be compared to events already defined in the
975  *         library (n32wb452_i2c.h) or to custom values defined by user.
976  *       - This function is suitable when multiple flags are monitored at the same time.
977  *       - At the opposite of I2C_CheckEvent() function, this function allows user to
978  *         choose when an event is accepted (when all events flags are set and no
979  *         other flags are set or just when the needed flags are set like
980  *         I2C_CheckEvent() function).
981  *     - Limitations:
982  *       - User may need to define his own events.
983  *       - Same remark concerning the error management is applicable for this
984  *         function if user decides to check only regular communication flags (and
985  *         ignores error flags).
986  *
987  *
988  *  3) Flag-based state monitoring:
989  *     Using the function I2C_GetFlag() which simply returns the status of
990  *     one single flag (ie. I2C_FLAG_RXDATNE ...).
991  *     - When to use:
992  *        - This function could be used for specific applications or in debug phase.
993  *        - It is suitable when only one flag checking is needed (most I2C events
994  *          are monitored through multiple flags).
995  *     - Limitations:
996  *        - When calling this function, the Status register is accessed. Some flags are
997  *          cleared when the status register is accessed. So checking the status
998  *          of one Flag, may clear other ones.
999  *        - Function may need to be called twice or more in order to monitor one
1000  *          single event.
1001  *
1002  *  For detailed description of Events, please refer to section I2C_Events in
1003  *  n32wb452_i2c.h file.
1004  *
1005  */
1006 
1007 /**
1008  * @brief  Checks whether the last I2Cx Event is equal to the one passed
1009  *   as parameter.
1010  * @param I2Cx where x can be 1 or 2 to select the I2C peripheral.
1011  * @param I2C_EVENT specifies the event to be checked.
1012  *   This parameter can be one of the following values:
1013  *     @arg I2C_EVT_SLAVE_SEND_ADDR_MATCHED EV1
1014  *     @arg I2C_EVT_SLAVE_RECV_ADDR_MATCHED EV1
1015  *     @arg I2C_EVT_SLAVE_SEND_ADDR2_MATCHED EV1
1016  *     @arg I2C_EVT_SLAVE_RECV_ADDR2_MATCHED EV1
1017  *     @arg I2C_EVT_SLAVE_GCALLADDR_MATCHED EV1
1018  *     @arg I2C_EVT_SLAVE_DATA_RECVD EV2
1019  *     @arg (I2C_EVT_SLAVE_DATA_RECVD | I2C_FLAG_DUALFLAG)  EV2
1020  *     @arg (I2C_EVT_SLAVE_DATA_RECVD | I2C_FLAG_GCALLADDR) EV2
1021  *     @arg I2C_EVT_SLAVE_DATA_SENDED EV3
1022  *     @arg (I2C_EVT_SLAVE_DATA_SENDED | I2C_FLAG_DUALFLAG) EV3
1023  *     @arg (I2C_EVT_SLAVE_DATA_SENDED | I2C_FLAG_GCALLADDR) EV3
1024  *     @arg I2C_EVT_SLAVE_ACK_MISS EV3_2
1025  *     @arg I2C_EVT_SLAVE_STOP_RECVD EV4
1026  *     @arg I2C_EVT_MASTER_MODE_FLAG EV5
1027  *     @arg I2C_EVT_MASTER_TXMODE_FLAG EV6
1028  *     @arg I2C_EVT_MASTER_RXMODE_FLAG EV6
1029  *     @arg I2C_EVT_MASTER_DATA_RECVD_FLAG EV7
1030  *     @arg I2C_EVT_MASTER_DATA_SENDING EV8
1031  *     @arg I2C_EVT_MASTER_DATA_SENDED EV8_2
1032  *     @arg I2C_EVT_MASTER_MODE_ADDRESS10_FLAG EV9
1033  *
1034  * @note: For detailed description of Events, please refer to section
1035  *    I2C_Events in n32wb452_i2c.h file.
1036  *
1037  * @return An ErrorStatus enumeration value:
1038  * - SUCCESS: Last event is equal to the I2C_EVENT
1039  * - ERROR: Last event is different from the I2C_EVENT
1040  */
I2C_CheckEvent(I2C_Module * I2Cx,uint32_t I2C_EVENT)1041 ErrorStatus I2C_CheckEvent(I2C_Module* I2Cx, uint32_t I2C_EVENT)
1042 {
1043     uint32_t lastevent = 0;
1044     uint32_t flag1 = 0, flag2 = 0;
1045     ErrorStatus status = ERROR;
1046 
1047     /* Check the parameters */
1048     assert_param(IS_I2C_PERIPH(I2Cx));
1049     assert_param(IS_I2C_EVT(I2C_EVENT));
1050 
1051     /* Read the I2Cx status register */
1052     flag1 = I2Cx->STS1;
1053     flag2 = I2Cx->STS2;
1054     flag2 = flag2 << 16;
1055 
1056     /* Get the last event value from I2C status register */
1057     lastevent = (flag1 | flag2) & FLAG_MASK;
1058 
1059     /* Check whether the last event contains the I2C_EVENT */
1060     if ((lastevent & I2C_EVENT) == I2C_EVENT)
1061     {
1062         /* SUCCESS: last event is equal to I2C_EVENT */
1063         status = SUCCESS;
1064     }
1065     else
1066     {
1067         /* ERROR: last event is different from I2C_EVENT */
1068         status = ERROR;
1069     }
1070     /* Return status */
1071     return status;
1072 }
1073 
1074 /**
1075  * @brief  Returns the last I2Cx Event.
1076  * @param I2Cx where x can be 1 or 2 to select the I2C peripheral.
1077  *
1078  * @note: For detailed description of Events, please refer to section
1079  *    I2C_Events in n32wb452_i2c.h file.
1080  *
1081  * @return The last event
1082  */
I2C_GetLastEvent(I2C_Module * I2Cx)1083 uint32_t I2C_GetLastEvent(I2C_Module* I2Cx)
1084 {
1085     uint32_t lastevent = 0;
1086     uint32_t flag1 = 0, flag2 = 0;
1087 
1088     /* Check the parameters */
1089     assert_param(IS_I2C_PERIPH(I2Cx));
1090 
1091     /* Read the I2Cx status register */
1092     flag1 = I2Cx->STS1;
1093     flag2 = I2Cx->STS2;
1094     flag2 = flag2 << 16;
1095 
1096     /* Get the last event value from I2C status register */
1097     lastevent = (flag1 | flag2) & FLAG_MASK;
1098 
1099     /* Return status */
1100     return lastevent;
1101 }
1102 
1103 /**
1104  * @brief  Checks whether the specified I2C flag is set or not.
1105  * @param I2Cx where x can be 1 or 2 to select the I2C peripheral.
1106  * @param I2C_FLAG specifies the flag to check.
1107  *   This parameter can be one of the following values:
1108  *     @arg I2C_FLAG_DUALFLAG Dual flag (Slave mode)
1109  *     @arg I2C_FLAG_SMBHADDR SMBus host header (Slave mode)
1110  *     @arg I2C_FLAG_SMBDADDR SMBus default header (Slave mode)
1111  *     @arg I2C_FLAG_GCALLADDR General call header flag (Slave mode)
1112  *     @arg I2C_FLAG_TRF Transmitter/Receiver flag
1113  *     @arg I2C_FLAG_BUSY Bus busy flag
1114  *     @arg I2C_FLAG_MSMODE Master/Slave flag
1115  *     @arg I2C_FLAG_SMBALERT SMBus Alert flag
1116  *     @arg I2C_FLAG_TIMOUT Timeout or Tlow error flag
1117  *     @arg I2C_FLAG_PECERR PEC error in reception flag
1118  *     @arg I2C_FLAG_OVERRUN Overrun/Underrun flag (Slave mode)
1119  *     @arg I2C_FLAG_ACKFAIL Acknowledge failure flag
1120  *     @arg I2C_FLAG_ARLOST Arbitration lost flag (Master mode)
1121  *     @arg I2C_FLAG_BUSERR Bus error flag
1122  *     @arg I2C_FLAG_TXDATE Data register empty flag (Transmitter)
1123  *     @arg I2C_FLAG_RXDATNE Data register not empty (Receiver) flag
1124  *     @arg I2C_FLAG_STOPF Stop detection flag (Slave mode)
1125  *     @arg I2C_FLAG_ADDR10F 10-bit header sent flag (Master mode)
1126  *     @arg I2C_FLAG_BYTEF Byte transfer finished flag
1127  *     @arg I2C_FLAG_ADDRF Address sent flag (Master mode) "ADSL"
1128  *   Address matched flag (Slave mode)"ENDA"
1129  *     @arg I2C_FLAG_STARTBF Start bit flag (Master mode)
1130  * @return The new state of I2C_FLAG (SET or RESET).
1131  */
I2C_GetFlag(I2C_Module * I2Cx,uint32_t I2C_FLAG)1132 FlagStatus I2C_GetFlag(I2C_Module* I2Cx, uint32_t I2C_FLAG)
1133 {
1134     FlagStatus bitstatus = RESET;
1135     __IO uint32_t i2creg = 0, i2cxbase = 0;
1136 
1137     /* Check the parameters */
1138     assert_param(IS_I2C_PERIPH(I2Cx));
1139     assert_param(IS_I2C_GET_FLAG(I2C_FLAG));
1140 
1141     /* Get the I2Cx peripheral base address */
1142     i2cxbase = (uint32_t)I2Cx;
1143 
1144     /* Read flag register index */
1145     i2creg = I2C_FLAG >> 28;
1146 
1147     /* Get bit[23:0] of the flag */
1148     I2C_FLAG &= FLAG_MASK;
1149 
1150     if (i2creg != 0)
1151     {
1152         /* Get the I2Cx STS1 register address */
1153         i2cxbase += 0x14;
1154     }
1155     else
1156     {
1157         /* Flag in I2Cx STS2 Register */
1158         I2C_FLAG = (uint32_t)(I2C_FLAG >> 16);
1159         /* Get the I2Cx STS2 register address */
1160         i2cxbase += 0x18;
1161     }
1162 
1163     if (((*(__IO uint32_t*)i2cxbase) & I2C_FLAG) != (uint32_t)RESET)
1164     {
1165         /* I2C_FLAG is set */
1166         bitstatus = SET;
1167     }
1168     else
1169     {
1170         /* I2C_FLAG is reset */
1171         bitstatus = RESET;
1172     }
1173 
1174     /* Return the I2C_FLAG status */
1175     return bitstatus;
1176 }
1177 
1178 /**
1179  * @brief  Clears the I2Cx's pending flags.
1180  * @param I2Cx where x can be 1 or 2 to select the I2C peripheral.
1181  * @param I2C_FLAG specifies the flag to clear.
1182  *   This parameter can be any combination of the following values:
1183  *     @arg I2C_FLAG_SMBALERT SMBus Alert flag
1184  *     @arg I2C_FLAG_TIMOUT Timeout or Tlow error flag
1185  *     @arg I2C_FLAG_PECERR PEC error in reception flag
1186  *     @arg I2C_FLAG_OVERRUN Overrun/Underrun flag (Slave mode)
1187  *     @arg I2C_FLAG_ACKFAIL Acknowledge failure flag
1188  *     @arg I2C_FLAG_ARLOST Arbitration lost flag (Master mode)
1189  *     @arg I2C_FLAG_BUSERR Bus error flag
1190  *
1191  * @note
1192  *   - STOPF (STOP detection) is cleared by software sequence: a read operation
1193  *     to I2C_STS1 register (I2C_GetFlag()) followed by a write operation
1194  *     to I2C_CTRL1 register (I2C_Enable() to re-enable the I2C peripheral).
1195  *   - ADD10 (10-bit header sent) is cleared by software sequence: a read
1196  *     operation to I2C_STS1 (I2C_GetFlag()) followed by writing the
1197  *     second byte of the address in DAT register.
1198  *   - BTF (Byte Transfer Finished) is cleared by software sequence: a read
1199  *     operation to I2C_STS1 register (I2C_GetFlag()) followed by a
1200  *     read/write to I2C_DAT register (I2C_SendData()).
1201  *   - ADDR (Address sent) is cleared by software sequence: a read operation to
1202  *     I2C_STS1 register (I2C_GetFlag()) followed by a read operation to
1203  *     I2C_STS2 register ((void)(I2Cx->STS2)).
1204  *   - SB (Start Bit) is cleared software sequence: a read operation to I2C_STS1
1205  *     register (I2C_GetFlag()) followed by a write operation to I2C_DAT
1206  *     register  (I2C_SendData()).
1207  */
I2C_ClrFlag(I2C_Module * I2Cx,uint32_t I2C_FLAG)1208 void I2C_ClrFlag(I2C_Module* I2Cx, uint32_t I2C_FLAG)
1209 {
1210     uint32_t flagpos = 0;
1211     /* Check the parameters */
1212     assert_param(IS_I2C_PERIPH(I2Cx));
1213     assert_param(IS_I2C_CLR_FLAG(I2C_FLAG));
1214     /* Get the I2C flag position */
1215     flagpos = I2C_FLAG & FLAG_MASK;
1216     /* Clear the selected I2C flag */
1217     I2Cx->STS1 = (uint16_t)~flagpos;
1218 }
1219 
1220 /**
1221  * @brief  Checks whether the specified I2C interrupt has occurred or not.
1222  * @param I2Cx where x can be 1 or 2 to select the I2C peripheral.
1223  * @param I2C_IT specifies the interrupt source to check.
1224  *   This parameter can be one of the following values:
1225  *     @arg I2C_INT_SMBALERT SMBus Alert flag
1226  *     @arg I2C_INT_TIMOUT Timeout or Tlow error flag
1227  *     @arg I2C_INT_PECERR PEC error in reception flag
1228  *     @arg I2C_INT_OVERRUN Overrun/Underrun flag (Slave mode)
1229  *     @arg I2C_INT_ACKFAIL Acknowledge failure flag
1230  *     @arg I2C_INT_ARLOST Arbitration lost flag (Master mode)
1231  *     @arg I2C_INT_BUSERR Bus error flag
1232  *     @arg I2C_INT_TXDATE Data register empty flag (Transmitter)
1233  *     @arg I2C_INT_RXDATNE Data register not empty (Receiver) flag
1234  *     @arg I2C_INT_STOPF Stop detection flag (Slave mode)
1235  *     @arg I2C_INT_ADDR10F 10-bit header sent flag (Master mode)
1236  *     @arg I2C_INT_BYTEF Byte transfer finished flag
1237  *     @arg I2C_INT_ADDRF Address sent flag (Master mode) "ADSL"
1238  *                       Address matched flag (Slave mode)"ENDAD"
1239  *     @arg I2C_INT_STARTBF Start bit flag (Master mode)
1240  * @return The new state of I2C_IT (SET or RESET).
1241  */
I2C_GetIntStatus(I2C_Module * I2Cx,uint32_t I2C_IT)1242 INTStatus I2C_GetIntStatus(I2C_Module* I2Cx, uint32_t I2C_IT)
1243 {
1244     INTStatus bitstatus   = RESET;
1245     uint32_t enablestatus = 0;
1246 
1247     /* Check the parameters */
1248     assert_param(IS_I2C_PERIPH(I2Cx));
1249     assert_param(IS_I2C_GET_INT(I2C_IT));
1250 
1251     /* Check if the interrupt source is enabled or not */
1252     enablestatus = (uint32_t)(((I2C_IT & INTEN_MASK) >> 16) & (I2Cx->CTRL2));
1253 
1254     /* Get bit[23:0] of the flag */
1255     I2C_IT &= FLAG_MASK;
1256 
1257     /* Check the status of the specified I2C flag */
1258     if (((I2Cx->STS1 & I2C_IT) != (uint32_t)RESET) && enablestatus)
1259     {
1260         /* I2C_IT is set */
1261         bitstatus = SET;
1262     }
1263     else
1264     {
1265         /* I2C_IT is reset */
1266         bitstatus = RESET;
1267     }
1268     /* Return the I2C_IT status */
1269     return bitstatus;
1270 }
1271 
1272 /**
1273  * @brief  Clears the I2Cx's interrupt pending bits.
1274  * @param I2Cx where x can be 1 or 2 to select the I2C peripheral.
1275  * @param I2C_IT specifies the interrupt pending bit to clear.
1276  *   This parameter can be any combination of the following values:
1277  *     @arg I2C_INT_SMBALERT SMBus Alert interrupt
1278  *     @arg I2C_INT_TIMOUT Timeout or Tlow error interrupt
1279  *     @arg I2C_INT_PECERR PEC error in reception  interrupt
1280  *     @arg I2C_INT_OVERRUN Overrun/Underrun interrupt (Slave mode)
1281  *     @arg I2C_INT_ACKFAIL Acknowledge failure interrupt
1282  *     @arg I2C_INT_ARLOST Arbitration lost interrupt (Master mode)
1283  *     @arg I2C_INT_BUSERR Bus error interrupt
1284  *
1285  * @note
1286  *   - STOPF (STOP detection) is cleared by software sequence: a read operation
1287  *     to I2C_STS1 register (I2C_GetIntStatus()) followed by a write operation to
1288  *     I2C_CTRL1 register (I2C_Enable() to re-enable the I2C peripheral).
1289  *   - ADD10 (10-bit header sent) is cleared by software sequence: a read
1290  *     operation to I2C_STS1 (I2C_GetIntStatus()) followed by writing the second
1291  *     byte of the address in I2C_DAT register.
1292  *   - BTF (Byte Transfer Finished) is cleared by software sequence: a read
1293  *     operation to I2C_STS1 register (I2C_GetIntStatus()) followed by a
1294  *     read/write to I2C_DAT register (I2C_SendData()).
1295  *   - ADDR (Address sent) is cleared by software sequence: a read operation to
1296  *     I2C_STS1 register (I2C_GetIntStatus()) followed by a read operation to
1297  *     I2C_STS2 register ((void)(I2Cx->STS2)).
1298  *   - SB (Start Bit) is cleared by software sequence: a read operation to
1299  *     I2C_STS1 register (I2C_GetIntStatus()) followed by a write operation to
1300  *     I2C_DAT register (I2C_SendData()).
1301  */
I2C_ClrIntPendingBit(I2C_Module * I2Cx,uint32_t I2C_IT)1302 void I2C_ClrIntPendingBit(I2C_Module* I2Cx, uint32_t I2C_IT)
1303 {
1304     uint32_t flagpos = 0;
1305     /* Check the parameters */
1306     assert_param(IS_I2C_PERIPH(I2Cx));
1307     assert_param(IS_I2C_CLR_INT(I2C_IT));
1308     /* Get the I2C flag position */
1309     flagpos = I2C_IT & FLAG_MASK;
1310     /* Clear the selected I2C flag */
1311     I2Cx->STS1 = (uint16_t)~flagpos;
1312 }
1313 
1314 /**
1315  * @}
1316  */
1317 
1318 /**
1319  * @}
1320  */
1321 
1322 /**
1323  * @}
1324  */
1325