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