1 /**
2   ******************************************************************************
3   * @file    stm32u5xx_hal_i2c_ex.c
4   * @author  MCD Application Team
5   * @brief   I2C Extended HAL module driver.
6   *          This file provides firmware functions to manage the following
7   *          functionalities of I2C Extended peripheral:
8   *           + Filter Mode Functions
9   *           + WakeUp Mode Functions
10   *           + FastModePlus Functions
11   *           + Autonomous Mode Functions
12   *
13   ******************************************************************************
14   * @attention
15   *
16   * Copyright (c) 2021 STMicroelectronics.
17   * All rights reserved.
18   *
19   * This software component is licensed by ST under BSD 3-Clause license,
20   * the "License"; You may not use this file except in compliance with the
21   * License. You may obtain a copy of the License at:
22   *                        opensource.org/licenses/BSD-3-Clause
23   *
24   ******************************************************************************
25   @verbatim
26   ==============================================================================
27                ##### I2C peripheral Extended features  #####
28   ==============================================================================
29 
30   [..] Comparing to other previous devices, the I2C interface for STM32U5xx
31        devices contains the following additional features
32 
33        (+) Possibility to disable or enable Analog Noise Filter
34        (+) Use of a configured Digital Noise Filter
35        (+) Disable or enable wakeup from Stop mode(s)
36        (+) Disable or enable Fast Mode Plus
37        (+) Configure Autonomous mode
38 
39                      ##### How to use this driver #####
40   ==============================================================================
41   [..] This driver provides functions to configure Noise Filter and Wake Up Feature
42     (#) Configure I2C Analog noise filter using the function HAL_I2CEx_ConfigAnalogFilter()
43     (#) Configure I2C Digital noise filter using the function HAL_I2CEx_ConfigDigitalFilter()
44     (#) Configure the enable or disable of I2C Wake Up Mode using the functions :
45           (++) HAL_I2CEx_EnableWakeUp()
46           (++) HAL_I2CEx_DisableWakeUp()
47     (#) Configure the enable or disable of fast mode plus driving capability using the functions :
48           (++) HAL_I2CEx_ConfigFastModePlus()
49     (#) Set or get or clear the autonomous mode configuration using these functions :
50           (++) HAL_I2CEx_SetConfigAutonomousMode()
51           (++) HAL_I2CEx_GetConfigAutonomousMode()
52           (++) HAL_I2CEx_ClearConfigAutonomousMode()
53   @endverbatim
54   */
55 
56 /* Includes ------------------------------------------------------------------*/
57 #include "stm32u5xx_hal.h"
58 
59 /** @addtogroup STM32U5xx_HAL_Driver
60   * @{
61   */
62 
63 /** @defgroup I2CEx I2CEx
64   * @brief I2C Extended HAL module driver
65   * @{
66   */
67 
68 #ifdef HAL_I2C_MODULE_ENABLED
69 
70 /* Private typedef -----------------------------------------------------------*/
71 /* Private define ------------------------------------------------------------*/
72 /* Private macro -------------------------------------------------------------*/
73 /* Private variables ---------------------------------------------------------*/
74 /* Private function prototypes -----------------------------------------------*/
75 /* Private functions ---------------------------------------------------------*/
76 
77 /** @defgroup I2CEx_Exported_Functions I2C Extended Exported Functions
78   * @{
79   */
80 
81 /** @defgroup I2CEx_Exported_Functions_Group1 Filter Mode Functions
82   * @brief    Filter Mode Functions
83   *
84 @verbatim
85  ===============================================================================
86                       ##### Filter Mode Functions #####
87  ===============================================================================
88     [..] This section provides functions allowing to:
89       (+) Configure Noise Filters
90 
91 @endverbatim
92   * @{
93   */
94 
95 /**
96   * @brief  Configure I2C Analog noise filter.
97   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
98   *                the configuration information for the specified I2Cx peripheral.
99   * @param  AnalogFilter New state of the Analog filter.
100   * @retval HAL status
101   */
HAL_I2CEx_ConfigAnalogFilter(I2C_HandleTypeDef * hi2c,uint32_t AnalogFilter)102 HAL_StatusTypeDef HAL_I2CEx_ConfigAnalogFilter(I2C_HandleTypeDef *hi2c, uint32_t AnalogFilter)
103 {
104   /* Check the parameters */
105   assert_param(IS_I2C_ALL_INSTANCE(hi2c->Instance));
106   assert_param(IS_I2C_ANALOG_FILTER(AnalogFilter));
107 
108   if (hi2c->State == HAL_I2C_STATE_READY)
109   {
110     /* Process Locked */
111     __HAL_LOCK(hi2c);
112 
113     hi2c->State = HAL_I2C_STATE_BUSY;
114 
115     /* Disable the selected I2C peripheral */
116     __HAL_I2C_DISABLE(hi2c);
117 
118     /* Reset I2Cx ANOFF bit */
119     hi2c->Instance->CR1 &= ~(I2C_CR1_ANFOFF);
120 
121     /* Set analog filter bit*/
122     hi2c->Instance->CR1 |= AnalogFilter;
123 
124     __HAL_I2C_ENABLE(hi2c);
125 
126     hi2c->State = HAL_I2C_STATE_READY;
127 
128     /* Process Unlocked */
129     __HAL_UNLOCK(hi2c);
130 
131     return HAL_OK;
132   }
133   else
134   {
135     return HAL_BUSY;
136   }
137 }
138 
139 /**
140   * @brief  Configure I2C Digital noise filter.
141   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
142   *                the configuration information for the specified I2Cx peripheral.
143   * @param  DigitalFilter Coefficient of digital noise filter between Min_Data=0x00 and Max_Data=0x0F.
144   * @retval HAL status
145   */
HAL_I2CEx_ConfigDigitalFilter(I2C_HandleTypeDef * hi2c,uint32_t DigitalFilter)146 HAL_StatusTypeDef HAL_I2CEx_ConfigDigitalFilter(I2C_HandleTypeDef *hi2c, uint32_t DigitalFilter)
147 {
148   uint32_t tmpreg;
149 
150   /* Check the parameters */
151   assert_param(IS_I2C_ALL_INSTANCE(hi2c->Instance));
152   assert_param(IS_I2C_DIGITAL_FILTER(DigitalFilter));
153 
154   if (hi2c->State == HAL_I2C_STATE_READY)
155   {
156     /* Process Locked */
157     __HAL_LOCK(hi2c);
158 
159     hi2c->State = HAL_I2C_STATE_BUSY;
160 
161     /* Disable the selected I2C peripheral */
162     __HAL_I2C_DISABLE(hi2c);
163 
164     /* Get the old register value */
165     tmpreg = hi2c->Instance->CR1;
166 
167     /* Reset I2Cx DNF bits [11:8] */
168     tmpreg &= ~(I2C_CR1_DNF);
169 
170     /* Set I2Cx DNF coefficient */
171     tmpreg |= DigitalFilter << 8U;
172 
173     /* Store the new register value */
174     hi2c->Instance->CR1 = tmpreg;
175 
176     __HAL_I2C_ENABLE(hi2c);
177 
178     hi2c->State = HAL_I2C_STATE_READY;
179 
180     /* Process Unlocked */
181     __HAL_UNLOCK(hi2c);
182 
183     return HAL_OK;
184   }
185   else
186   {
187     return HAL_BUSY;
188   }
189 }
190 /**
191   * @}
192   */
193 
194 /** @defgroup I2CEx_Exported_Functions_Group2 WakeUp Mode Functions
195   * @brief    WakeUp Mode Functions
196   *
197 @verbatim
198  ===============================================================================
199                       ##### WakeUp Mode Functions #####
200  ===============================================================================
201     [..] This section provides functions allowing to:
202       (+) Configure Wake Up Feature
203 
204 @endverbatim
205   * @{
206   */
207 
208 /**
209   * @brief  Enable I2C wakeup from Stop mode(s).
210   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
211   *                the configuration information for the specified I2Cx peripheral.
212   * @retval HAL status
213   */
HAL_I2CEx_EnableWakeUp(I2C_HandleTypeDef * hi2c)214 HAL_StatusTypeDef HAL_I2CEx_EnableWakeUp(I2C_HandleTypeDef *hi2c)
215 {
216   /* Check the parameters */
217   assert_param(IS_I2C_WAKEUP_FROMSTOP_INSTANCE(hi2c->Instance));
218 
219   if (hi2c->State == HAL_I2C_STATE_READY)
220   {
221     /* Process Locked */
222     __HAL_LOCK(hi2c);
223 
224     hi2c->State = HAL_I2C_STATE_BUSY;
225 
226     /* Disable the selected I2C peripheral */
227     __HAL_I2C_DISABLE(hi2c);
228 
229     /* Enable wakeup from stop mode */
230     hi2c->Instance->CR1 |= I2C_CR1_WUPEN;
231 
232     __HAL_I2C_ENABLE(hi2c);
233 
234     hi2c->State = HAL_I2C_STATE_READY;
235 
236     /* Process Unlocked */
237     __HAL_UNLOCK(hi2c);
238 
239     return HAL_OK;
240   }
241   else
242   {
243     return HAL_BUSY;
244   }
245 }
246 
247 /**
248   * @brief  Disable I2C wakeup from Stop mode(s).
249   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
250   *                the configuration information for the specified I2Cx peripheral.
251   * @retval HAL status
252   */
HAL_I2CEx_DisableWakeUp(I2C_HandleTypeDef * hi2c)253 HAL_StatusTypeDef HAL_I2CEx_DisableWakeUp(I2C_HandleTypeDef *hi2c)
254 {
255   /* Check the parameters */
256   assert_param(IS_I2C_WAKEUP_FROMSTOP_INSTANCE(hi2c->Instance));
257 
258   if (hi2c->State == HAL_I2C_STATE_READY)
259   {
260     /* Process Locked */
261     __HAL_LOCK(hi2c);
262 
263     hi2c->State = HAL_I2C_STATE_BUSY;
264 
265     /* Disable the selected I2C peripheral */
266     __HAL_I2C_DISABLE(hi2c);
267 
268     /* Enable wakeup from stop mode */
269     hi2c->Instance->CR1 &= ~(I2C_CR1_WUPEN);
270 
271     __HAL_I2C_ENABLE(hi2c);
272 
273     hi2c->State = HAL_I2C_STATE_READY;
274 
275     /* Process Unlocked */
276     __HAL_UNLOCK(hi2c);
277 
278     return HAL_OK;
279   }
280   else
281   {
282     return HAL_BUSY;
283   }
284 }
285 /**
286   * @}
287   */
288 
289 /** @defgroup I2CEx_Exported_Functions_Group3 Fast Mode Plus Functions
290   * @brief    Fast Mode Plus Functions
291   *
292 @verbatim
293  ===============================================================================
294                       ##### Fast Mode Plus Functions #####
295  ===============================================================================
296     [..] This section provides functions allowing to:
297       (+) Configure Fast Mode Plus
298 
299 @endverbatim
300   * @{
301   */
302 
303 /**
304   * @brief  Configure I2C Fast Mode Plus.
305   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
306   *                the configuration information for the specified I2Cx peripheral.
307   * @param  FastModePlus New state of the Fast Mode Plus.
308   * @retval HAL status
309   */
HAL_I2CEx_ConfigFastModePlus(I2C_HandleTypeDef * hi2c,uint32_t FastModePlus)310 HAL_StatusTypeDef HAL_I2CEx_ConfigFastModePlus(I2C_HandleTypeDef *hi2c, uint32_t FastModePlus)
311 {
312   /* Check the parameters */
313   assert_param(IS_I2C_ALL_INSTANCE(hi2c->Instance));
314   assert_param(IS_I2C_FASTMODEPLUS(FastModePlus));
315 
316   if (hi2c->State == HAL_I2C_STATE_READY)
317   {
318     /* Process Locked */
319     __HAL_LOCK(hi2c);
320 
321     hi2c->State = HAL_I2C_STATE_BUSY;
322 
323     /* Disable the selected I2C peripheral */
324     __HAL_I2C_DISABLE(hi2c);
325 
326     if (FastModePlus == I2C_FASTMODEPLUS_ENABLE)
327     {
328       /* Set I2Cx FMP bit */
329       hi2c->Instance->CR1 |= (I2C_CR1_FMP);
330     }
331     else
332     {
333       /* Reset I2Cx FMP bit */
334       hi2c->Instance->CR1 &= ~(I2C_CR1_FMP);
335     }
336 
337     __HAL_I2C_ENABLE(hi2c);
338 
339     hi2c->State = HAL_I2C_STATE_READY;
340 
341     /* Process Unlocked */
342     __HAL_UNLOCK(hi2c);
343 
344     return HAL_OK;
345   }
346   else
347   {
348     return HAL_BUSY;
349   }
350 }
351 
352 /**
353   * @}
354   */
355 
356 /** @defgroup I2CEx_Exported_Functions_Group4 Autonomous Mode Functions
357   * @brief    Autonomous Mode Functions
358   *
359 @verbatim
360  ===============================================================================
361                      ##### Autonomous Mode functions #####
362  ===============================================================================
363     [..] This section provides functions allowing to:
364       (+) Configure Autonomous Mode
365 
366 @endverbatim
367   * @{
368   */
369 
370 /**
371   * @brief  Set Autonomous Mode configuration
372   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
373   *                the configuration information for the specified I2Cx peripheral.
374   * @param  sConfig Pointer to a I2C_AutonomousModeConfTypeDef structure that contains
375   *                the configuration information of the autonomous mode for the specified I2Cx peripheral.
376   * @retval HAL status
377   */
HAL_I2CEx_SetConfigAutonomousMode(I2C_HandleTypeDef * hi2c,const I2C_AutonomousModeConfTypeDef * sConfig)378 HAL_StatusTypeDef HAL_I2CEx_SetConfigAutonomousMode(I2C_HandleTypeDef *hi2c,
379                                                     const I2C_AutonomousModeConfTypeDef *sConfig)
380 {
381   if (hi2c->State == HAL_I2C_STATE_READY)
382   {
383     /* Process Locked */
384     __HAL_LOCK(hi2c);
385 
386     hi2c->State = HAL_I2C_STATE_BUSY;
387 
388     /* Check the parameters */
389     assert_param(IS_I2C_TRIG_INPUT_INSTANCE(hi2c->Instance));
390     assert_param(IS_I2C_TRIG_SOURCE(hi2c->Instance, sConfig->TriggerSelection));
391     assert_param(IS_I2C_AUTO_MODE_TRG_POL(sConfig->TriggerPolarity));
392 
393     /* Disable the selected I2C peripheral to be able to configure AUTOCR */
394     __HAL_I2C_DISABLE(hi2c);
395 
396     /* I2Cx AUTOCR Configuration */
397     WRITE_REG(hi2c->Instance->AUTOCR,
398               (sConfig->TriggerState | \
399                ((sConfig->TriggerSelection) & I2C_AUTOCR_TRIGSEL_Msk) | \
400                sConfig->TriggerPolarity));
401 
402     /* Enable the selected I2C peripheral */
403     __HAL_I2C_ENABLE(hi2c);
404 
405     hi2c->State = HAL_I2C_STATE_READY;
406 
407     /* Process Unlocked */
408     __HAL_UNLOCK(hi2c);
409 
410     return HAL_OK;
411   }
412   else
413   {
414     return HAL_ERROR;
415   }
416 }
417 
418 /**
419   * @brief  Get Autonomous Mode configuration
420   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
421   *                the configuration information for the specified I2Cx peripheral.
422   * @param  sConfig Pointer to a I2C_AutonomousModeConfTypeDef structure that contains
423   *                the configuration information of the autonomous mode for the specified I2Cx peripheral.
424   * @retval HAL status
425   */
HAL_I2CEx_GetConfigAutonomousMode(const I2C_HandleTypeDef * hi2c,I2C_AutonomousModeConfTypeDef * sConfig)426 HAL_StatusTypeDef HAL_I2CEx_GetConfigAutonomousMode(const I2C_HandleTypeDef *hi2c,
427                                                     I2C_AutonomousModeConfTypeDef *sConfig)
428 {
429   uint32_t autocr_tmp;
430 
431   /* Check the parameters */
432   assert_param(IS_I2C_TRIG_INPUT_INSTANCE(hi2c->Instance));
433 
434   autocr_tmp = hi2c->Instance->AUTOCR;
435 
436   sConfig->TriggerState     = (autocr_tmp & I2C_AUTOCR_TRIGEN);
437   if (IS_I2C_GRP2_INSTANCE(hi2c->Instance))
438   {
439     sConfig->TriggerSelection = ((autocr_tmp & I2C_AUTOCR_TRIGSEL) | I2C_TRIG_GRP2);
440   }
441   else
442   {
443     sConfig->TriggerSelection = ((autocr_tmp & I2C_AUTOCR_TRIGSEL) | I2C_TRIG_GRP1);
444   }
445   sConfig->TriggerPolarity  = (autocr_tmp & I2C_AUTOCR_TRIGPOL);
446 
447   return HAL_OK;
448 }
449 
450 /**
451   * @brief  Clear Autonomous Mode configuration
452   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
453   *                the configuration information for the specified I2Cx peripheral.
454   * @retval HAL status
455   */
HAL_I2CEx_ClearConfigAutonomousMode(I2C_HandleTypeDef * hi2c)456 HAL_StatusTypeDef HAL_I2CEx_ClearConfigAutonomousMode(I2C_HandleTypeDef *hi2c)
457 {
458   if (hi2c->State == HAL_I2C_STATE_READY)
459   {
460     /* Process Locked */
461     __HAL_LOCK(hi2c);
462 
463     hi2c->State = HAL_I2C_STATE_BUSY;
464 
465     /* Check the parameters */
466     assert_param(IS_I2C_TRIG_INPUT_INSTANCE(hi2c->Instance));
467 
468     /* Disable the selected I2C peripheral to be able to clear AUTOCR */
469     __HAL_I2C_DISABLE(hi2c);
470 
471     CLEAR_REG(hi2c->Instance->AUTOCR);
472 
473     /* Enable the selected I2C peripheral */
474     __HAL_I2C_ENABLE(hi2c);
475 
476     hi2c->State = HAL_I2C_STATE_READY;
477 
478     /* Process Unlocked */
479     __HAL_UNLOCK(hi2c);
480 
481     return HAL_OK;
482   }
483   else
484   {
485     return HAL_ERROR;
486   }
487 }
488 /**
489   * @}
490   */
491 
492 /**
493   * @}
494   */
495 
496 #endif /* HAL_I2C_MODULE_ENABLED */
497 /**
498   * @}
499   */
500 
501 /**
502   * @}
503   */
504