1 /**
2   ******************************************************************************
3   * @file    stm32l4xx_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   *           + Extended features functions
9   *
10   @verbatim
11   ==============================================================================
12                ##### I2C peripheral Extended features  #####
13   ==============================================================================
14 
15   [..] Comparing to other previous devices, the I2C interface for STM32L4xx
16        devices contains the following additional features
17 
18        (+) Possibility to disable or enable Analog Noise Filter
19        (+) Use of a configured Digital Noise Filter
20        (+) Disable or enable wakeup from Stop mode(s)
21        (+) Disable or enable Fast Mode Plus
22 
23                      ##### How to use this driver #####
24   ==============================================================================
25   [..] This driver provides functions to configure Noise Filter and Wake Up Feature
26     (#) Configure I2C Analog noise filter using the function HAL_I2CEx_ConfigAnalogFilter()
27     (#) Configure I2C Digital noise filter using the function HAL_I2CEx_ConfigDigitalFilter()
28     (#) Configure the enable or disable of I2C Wake Up Mode using the functions :
29           (++) HAL_I2CEx_EnableWakeUp()
30           (++) HAL_I2CEx_DisableWakeUp()
31     (#) Configure the enable or disable of fast mode plus driving capability using the functions :
32           (++) HAL_I2CEx_EnableFastModePlus()
33           (++) HAL_I2CEx_DisableFastModePlus()
34   @endverbatim
35   ******************************************************************************
36   * @attention
37   *
38   * <h2><center>&copy; COPYRIGHT(c) 2017 STMicroelectronics</center></h2>
39   *
40   * Redistribution and use in source and binary forms, with or without modification,
41   * are permitted provided that the following conditions are met:
42   *   1. Redistributions of source code must retain the above copyright notice,
43   *      this list of conditions and the following disclaimer.
44   *   2. Redistributions in binary form must reproduce the above copyright notice,
45   *      this list of conditions and the following disclaimer in the documentation
46   *      and/or other materials provided with the distribution.
47   *   3. Neither the name of STMicroelectronics nor the names of its contributors
48   *      may be used to endorse or promote products derived from this software
49   *      without specific prior written permission.
50   *
51   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
52   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
53   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
54   * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
55   * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
56   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
57   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
58   * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
59   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
60   * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
61   *
62   ******************************************************************************
63   */
64 
65 /* Includes ------------------------------------------------------------------*/
66 #include "stm32l4xx_hal.h"
67 
68 /** @addtogroup STM32L4xx_HAL_Driver
69   * @{
70   */
71 
72 /** @defgroup I2CEx I2CEx
73   * @brief I2C Extended HAL module driver
74   * @{
75   */
76 
77 #ifdef HAL_I2C_MODULE_ENABLED
78 
79 /* Private typedef -----------------------------------------------------------*/
80 /* Private define ------------------------------------------------------------*/
81 /* Private macro -------------------------------------------------------------*/
82 /* Private variables ---------------------------------------------------------*/
83 /* Private function prototypes -----------------------------------------------*/
84 /* Private functions ---------------------------------------------------------*/
85 
86 /** @defgroup I2CEx_Exported_Functions I2C Extended Exported Functions
87   * @{
88   */
89 
90 /** @defgroup I2CEx_Exported_Functions_Group1 Extended features functions
91   * @brief    Extended features functions
92  *
93 @verbatim
94  ===============================================================================
95                       ##### Extended features functions #####
96  ===============================================================================
97     [..] This section provides functions allowing to:
98       (+) Configure Noise Filters
99       (+) Configure Wake Up Feature
100       (+) Configure Fast Mode Plus
101 
102 @endverbatim
103   * @{
104   */
105 
106 /**
107   * @brief  Configure I2C Analog noise filter.
108   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
109   *                the configuration information for the specified I2Cx peripheral.
110   * @param  AnalogFilter New state of the Analog filter.
111   * @retval HAL status
112   */
HAL_I2CEx_ConfigAnalogFilter(I2C_HandleTypeDef * hi2c,uint32_t AnalogFilter)113 HAL_StatusTypeDef HAL_I2CEx_ConfigAnalogFilter(I2C_HandleTypeDef *hi2c, uint32_t AnalogFilter)
114 {
115   /* Check the parameters */
116   assert_param(IS_I2C_ALL_INSTANCE(hi2c->Instance));
117   assert_param(IS_I2C_ANALOG_FILTER(AnalogFilter));
118 
119   if (hi2c->State == HAL_I2C_STATE_READY)
120   {
121     /* Process Locked */
122     __HAL_LOCK(hi2c);
123 
124     hi2c->State = HAL_I2C_STATE_BUSY;
125 
126     /* Disable the selected I2C peripheral */
127     __HAL_I2C_DISABLE(hi2c);
128 
129     /* Reset I2Cx ANOFF bit */
130     hi2c->Instance->CR1 &= ~(I2C_CR1_ANFOFF);
131 
132     /* Set analog filter bit*/
133     hi2c->Instance->CR1 |= AnalogFilter;
134 
135     __HAL_I2C_ENABLE(hi2c);
136 
137     hi2c->State = HAL_I2C_STATE_READY;
138 
139     /* Process Unlocked */
140     __HAL_UNLOCK(hi2c);
141 
142     return HAL_OK;
143   }
144   else
145   {
146     return HAL_BUSY;
147   }
148 }
149 
150 /**
151   * @brief  Configure I2C Digital noise filter.
152   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
153   *                the configuration information for the specified I2Cx peripheral.
154   * @param  DigitalFilter Coefficient of digital noise filter between Min_Data=0x00 and Max_Data=0x0F.
155   * @retval HAL status
156   */
HAL_I2CEx_ConfigDigitalFilter(I2C_HandleTypeDef * hi2c,uint32_t DigitalFilter)157 HAL_StatusTypeDef HAL_I2CEx_ConfigDigitalFilter(I2C_HandleTypeDef *hi2c, uint32_t DigitalFilter)
158 {
159   uint32_t tmpreg;
160 
161   /* Check the parameters */
162   assert_param(IS_I2C_ALL_INSTANCE(hi2c->Instance));
163   assert_param(IS_I2C_DIGITAL_FILTER(DigitalFilter));
164 
165   if (hi2c->State == HAL_I2C_STATE_READY)
166   {
167     /* Process Locked */
168     __HAL_LOCK(hi2c);
169 
170     hi2c->State = HAL_I2C_STATE_BUSY;
171 
172     /* Disable the selected I2C peripheral */
173     __HAL_I2C_DISABLE(hi2c);
174 
175     /* Get the old register value */
176     tmpreg = hi2c->Instance->CR1;
177 
178     /* Reset I2Cx DNF bits [11:8] */
179     tmpreg &= ~(I2C_CR1_DNF);
180 
181     /* Set I2Cx DNF coefficient */
182     tmpreg |= DigitalFilter << 8U;
183 
184     /* Store the new register value */
185     hi2c->Instance->CR1 = tmpreg;
186 
187     __HAL_I2C_ENABLE(hi2c);
188 
189     hi2c->State = HAL_I2C_STATE_READY;
190 
191     /* Process Unlocked */
192     __HAL_UNLOCK(hi2c);
193 
194     return HAL_OK;
195   }
196   else
197   {
198     return HAL_BUSY;
199   }
200 }
201 
202 /**
203   * @brief  Enable I2C wakeup from Stop mode(s).
204   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
205   *                the configuration information for the specified I2Cx peripheral.
206   * @retval HAL status
207   */
HAL_I2CEx_EnableWakeUp(I2C_HandleTypeDef * hi2c)208 HAL_StatusTypeDef HAL_I2CEx_EnableWakeUp(I2C_HandleTypeDef *hi2c)
209 {
210   /* Check the parameters */
211   assert_param(IS_I2C_WAKEUP_FROMSTOP_INSTANCE(hi2c->Instance));
212 
213   if (hi2c->State == HAL_I2C_STATE_READY)
214   {
215     /* Process Locked */
216     __HAL_LOCK(hi2c);
217 
218     hi2c->State = HAL_I2C_STATE_BUSY;
219 
220     /* Disable the selected I2C peripheral */
221     __HAL_I2C_DISABLE(hi2c);
222 
223     /* Enable wakeup from stop mode */
224     hi2c->Instance->CR1 |= I2C_CR1_WUPEN;
225 
226     __HAL_I2C_ENABLE(hi2c);
227 
228     hi2c->State = HAL_I2C_STATE_READY;
229 
230     /* Process Unlocked */
231     __HAL_UNLOCK(hi2c);
232 
233     return HAL_OK;
234   }
235   else
236   {
237     return HAL_BUSY;
238   }
239 }
240 
241 /**
242   * @brief  Disable I2C wakeup from Stop mode(s).
243   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
244   *                the configuration information for the specified I2Cx peripheral.
245   * @retval HAL status
246   */
HAL_I2CEx_DisableWakeUp(I2C_HandleTypeDef * hi2c)247 HAL_StatusTypeDef HAL_I2CEx_DisableWakeUp(I2C_HandleTypeDef *hi2c)
248 {
249   /* Check the parameters */
250   assert_param(IS_I2C_WAKEUP_FROMSTOP_INSTANCE(hi2c->Instance));
251 
252   if (hi2c->State == HAL_I2C_STATE_READY)
253   {
254     /* Process Locked */
255     __HAL_LOCK(hi2c);
256 
257     hi2c->State = HAL_I2C_STATE_BUSY;
258 
259     /* Disable the selected I2C peripheral */
260     __HAL_I2C_DISABLE(hi2c);
261 
262     /* Enable wakeup from stop mode */
263     hi2c->Instance->CR1 &= ~(I2C_CR1_WUPEN);
264 
265     __HAL_I2C_ENABLE(hi2c);
266 
267     hi2c->State = HAL_I2C_STATE_READY;
268 
269     /* Process Unlocked */
270     __HAL_UNLOCK(hi2c);
271 
272     return HAL_OK;
273   }
274   else
275   {
276     return HAL_BUSY;
277   }
278 }
279 
280 /**
281   * @brief Enable the I2C fast mode plus driving capability.
282   * @param ConfigFastModePlus Selects the pin.
283   *   This parameter can be one of the @ref I2CEx_FastModePlus values
284   * @note  For I2C1, fast mode plus driving capability can be enabled on all selected
285   *        I2C1 pins using I2C_FASTMODEPLUS_I2C1 parameter or independently
286   *        on each one of the following pins PB6, PB7, PB8 and PB9.
287   * @note  For remaining I2C1 pins (PA14, PA15...) fast mode plus driving capability
288   *        can be enabled only by using I2C_FASTMODEPLUS_I2C1 parameter.
289   * @note  For all I2C2 pins fast mode plus driving capability can be enabled
290   *        only by using I2C_FASTMODEPLUS_I2C2 parameter.
291   * @note  For all I2C3 pins fast mode plus driving capability can be enabled
292   *        only by using I2C_FASTMODEPLUS_I2C3 parameter.
293   * @note  For all I2C4 pins fast mode plus driving capability can be enabled
294   *        only by using I2C_FASTMODEPLUS_I2C4 parameter.
295   * @retval None
296   */
HAL_I2CEx_EnableFastModePlus(uint32_t ConfigFastModePlus)297 void HAL_I2CEx_EnableFastModePlus(uint32_t ConfigFastModePlus)
298 {
299   /* Check the parameter */
300   assert_param(IS_I2C_FASTMODEPLUS(ConfigFastModePlus));
301 
302   /* Enable SYSCFG clock */
303   __HAL_RCC_SYSCFG_CLK_ENABLE();
304 
305   /* Enable fast mode plus driving capability for selected pin */
306   SET_BIT(SYSCFG->CFGR1, (uint32_t)ConfigFastModePlus);
307 }
308 
309 /**
310   * @brief Disable the I2C fast mode plus driving capability.
311   * @param ConfigFastModePlus Selects the pin.
312   *   This parameter can be one of the @ref I2CEx_FastModePlus values
313   * @note  For I2C1, fast mode plus driving capability can be disabled on all selected
314   *        I2C1 pins using I2C_FASTMODEPLUS_I2C1 parameter or independently
315   *        on each one of the following pins PB6, PB7, PB8 and PB9.
316   * @note  For remaining I2C1 pins (PA14, PA15...) fast mode plus driving capability
317   *        can be disabled only by using I2C_FASTMODEPLUS_I2C1 parameter.
318   * @note  For all I2C2 pins fast mode plus driving capability can be disabled
319   *        only by using I2C_FASTMODEPLUS_I2C2 parameter.
320   * @note  For all I2C3 pins fast mode plus driving capability can be disabled
321   *        only by using I2C_FASTMODEPLUS_I2C3 parameter.
322   * @note  For all I2C4 pins fast mode plus driving capability can be disabled
323   *        only by using I2C_FASTMODEPLUS_I2C4 parameter.
324   * @retval None
325   */
HAL_I2CEx_DisableFastModePlus(uint32_t ConfigFastModePlus)326 void HAL_I2CEx_DisableFastModePlus(uint32_t ConfigFastModePlus)
327 {
328   /* Check the parameter */
329   assert_param(IS_I2C_FASTMODEPLUS(ConfigFastModePlus));
330 
331   /* Enable SYSCFG clock */
332   __HAL_RCC_SYSCFG_CLK_ENABLE();
333 
334   /* Disable fast mode plus driving capability for selected pin */
335   CLEAR_BIT(SYSCFG->CFGR1, (uint32_t)ConfigFastModePlus);
336 }
337 
338 /**
339   * @}
340   */
341 
342 /**
343   * @}
344   */
345 
346 #endif /* HAL_I2C_MODULE_ENABLED */
347 /**
348   * @}
349   */
350 
351 /**
352   * @}
353   */
354 
355 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
356