1 /**
2   ******************************************************************************
3   * @file    stm32u5xx_hal_smbus_ex.c
4   * @author  MCD Application Team
5   * @brief   SMBUS Extended HAL module driver.
6   *          This file provides firmware functions to manage the following
7   *          functionalities of SMBUS Extended peripheral:
8   *           + Extended features 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                ##### SMBUS peripheral Extended features  #####
27   ==============================================================================
28 
29   [..] Comparing to other previous devices, the SMBUS interface for STM32U5xx
30        devices contains the following additional features
31 
32        (+) Disable or enable wakeup from Stop mode(s)
33 
34                      ##### How to use this driver #####
35   ==============================================================================
36     (#) Configure the enable or disable of SMBUS Wake Up Mode using the functions :
37           (++) HAL_SMBUSEx_EnableWakeUp()
38           (++) HAL_SMBUSEx_DisableWakeUp()
39     (#) Configure the enable or disable of fast mode plus driving capability using the functions :
40           (++) HAL_SMBUSEx_ConfigFastModePlus()
41     (#) Set or get or clear the autonomous mode configuration using these functions :
42           (++) HAL_SMBUSEx_SetConfigAutonomousMode()
43           (++) HAL_SMBUSEx_GetConfigAutonomousMode()
44           (++) HAL_SMBUSEx_ClearConfigAutonomousMode()
45   @endverbatim
46   */
47 
48 /* Includes ------------------------------------------------------------------*/
49 #include "stm32u5xx_hal.h"
50 
51 /** @addtogroup STM32U5xx_HAL_Driver
52   * @{
53   */
54 
55 /** @defgroup SMBUSEx SMBUSEx
56   * @brief SMBUS Extended HAL module driver
57   * @{
58   */
59 
60 #ifdef HAL_SMBUS_MODULE_ENABLED
61 
62 /* Private typedef -----------------------------------------------------------*/
63 /* Private define ------------------------------------------------------------*/
64 /* Private macro -------------------------------------------------------------*/
65 /* Private variables ---------------------------------------------------------*/
66 /* Private function prototypes -----------------------------------------------*/
67 /* Private functions ---------------------------------------------------------*/
68 
69 /** @defgroup SMBUSEx_Exported_Functions SMBUS Extended Exported Functions
70   * @{
71   */
72 
73 /** @defgroup SMBUSEx_Exported_Functions_Group2 WakeUp Mode Functions
74   * @brief    WakeUp Mode Functions
75   *
76 @verbatim
77  ===============================================================================
78                       ##### WakeUp Mode Functions #####
79  ===============================================================================
80     [..] This section provides functions allowing to:
81       (+) Configure Wake Up Feature
82 
83 @endverbatim
84   * @{
85   */
86 
87 /**
88   * @brief  Enable SMBUS wakeup from Stop mode(s).
89   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
90   *                the configuration information for the specified SMBUSx peripheral.
91   * @retval HAL status
92   */
HAL_SMBUSEx_EnableWakeUp(SMBUS_HandleTypeDef * hsmbus)93 HAL_StatusTypeDef HAL_SMBUSEx_EnableWakeUp(SMBUS_HandleTypeDef *hsmbus)
94 {
95   /* Check the parameters */
96   assert_param(IS_I2C_WAKEUP_FROMSTOP_INSTANCE(hsmbus->Instance));
97 
98   if (hsmbus->State == HAL_SMBUS_STATE_READY)
99   {
100     /* Process Locked */
101     __HAL_LOCK(hsmbus);
102 
103     hsmbus->State = HAL_SMBUS_STATE_BUSY;
104 
105     /* Disable the selected SMBUS peripheral */
106     __HAL_SMBUS_DISABLE(hsmbus);
107 
108     /* Enable wakeup from stop mode */
109     hsmbus->Instance->CR1 |= I2C_CR1_WUPEN;
110 
111     __HAL_SMBUS_ENABLE(hsmbus);
112 
113     hsmbus->State = HAL_SMBUS_STATE_READY;
114 
115     /* Process Unlocked */
116     __HAL_UNLOCK(hsmbus);
117 
118     return HAL_OK;
119   }
120   else
121   {
122     return HAL_BUSY;
123   }
124 }
125 
126 /**
127   * @brief  Disable SMBUS wakeup from Stop mode(s).
128   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
129   *                the configuration information for the specified SMBUSx peripheral.
130   * @retval HAL status
131   */
HAL_SMBUSEx_DisableWakeUp(SMBUS_HandleTypeDef * hsmbus)132 HAL_StatusTypeDef HAL_SMBUSEx_DisableWakeUp(SMBUS_HandleTypeDef *hsmbus)
133 {
134   /* Check the parameters */
135   assert_param(IS_I2C_WAKEUP_FROMSTOP_INSTANCE(hsmbus->Instance));
136 
137   if (hsmbus->State == HAL_SMBUS_STATE_READY)
138   {
139     /* Process Locked */
140     __HAL_LOCK(hsmbus);
141 
142     hsmbus->State = HAL_SMBUS_STATE_BUSY;
143 
144     /* Disable the selected SMBUS peripheral */
145     __HAL_SMBUS_DISABLE(hsmbus);
146 
147     /* Disable wakeup from stop mode */
148     hsmbus->Instance->CR1 &= ~(I2C_CR1_WUPEN);
149 
150     __HAL_SMBUS_ENABLE(hsmbus);
151 
152     hsmbus->State = HAL_SMBUS_STATE_READY;
153 
154     /* Process Unlocked */
155     __HAL_UNLOCK(hsmbus);
156 
157     return HAL_OK;
158   }
159   else
160   {
161     return HAL_BUSY;
162   }
163 }
164 /**
165   * @}
166   */
167 
168 /** @defgroup SMBUSEx_Exported_Functions_Group3 Fast Mode Plus Functions
169   * @brief    Fast Mode Plus Functions
170   *
171 @verbatim
172  ===============================================================================
173                       ##### Fast Mode Plus Functions #####
174  ===============================================================================
175     [..] This section provides functions allowing to:
176       (+) Configure Fast Mode Plus
177 
178 @endverbatim
179   * @{
180   */
181 
182 /**
183   * @brief  Configure SMBUS Fast Mode Plus.
184   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
185   *                the configuration information for the specified SMBUSx peripheral.
186   * @param  FastModePlus New state of the Fast Mode Plus.
187   * @retval HAL status
188   */
HAL_SMBUSEx_ConfigFastModePlus(SMBUS_HandleTypeDef * hsmbus,uint32_t FastModePlus)189 HAL_StatusTypeDef HAL_SMBUSEx_ConfigFastModePlus(SMBUS_HandleTypeDef *hsmbus, uint32_t FastModePlus)
190 {
191   /* Check the parameters */
192   assert_param(IS_SMBUS_ALL_INSTANCE(hsmbus->Instance));
193   assert_param(IS_SMBUS_FASTMODEPLUS(FastModePlus));
194 
195   if (hsmbus->State == HAL_SMBUS_STATE_READY)
196   {
197     /* Process Locked */
198     __HAL_LOCK(hsmbus);
199 
200     hsmbus->State = HAL_SMBUS_STATE_BUSY;
201 
202     /* Disable the selected SMBUS peripheral */
203     __HAL_SMBUS_DISABLE(hsmbus);
204 
205     if (FastModePlus == SMBUS_FASTMODEPLUS_ENABLE)
206     {
207       /* Set SMBUSx FMP bit */
208       hsmbus->Instance->CR1 |= (I2C_CR1_FMP);
209     }
210     else
211     {
212       /* Reset SMBUSx FMP bit */
213       hsmbus->Instance->CR1 &= ~(I2C_CR1_FMP);
214     }
215 
216     __HAL_SMBUS_ENABLE(hsmbus);
217 
218     hsmbus->State = HAL_SMBUS_STATE_READY;
219 
220     /* Process Unlocked */
221     __HAL_UNLOCK(hsmbus);
222 
223     return HAL_OK;
224   }
225   else
226   {
227     return HAL_BUSY;
228   }
229 }
230 
231 /**
232   * @}
233   */
234 
235 /**
236   * @}
237   */
238 
239 /** @defgroup SMBUSEx_Exported_Functions_Group4 Autonomous Mode Functions
240   * @brief    Autonomous Mode Functions
241   *
242 @verbatim
243  ===============================================================================
244                      ##### Autonomous Mode functions #####
245  ===============================================================================
246     [..] This section provides functions allowing to:
247       (+) Configure Autonomous Mode
248 
249 @endverbatim
250   * @{
251   */
252 
253 /**
254   * @brief  Set Autonomous Mode configuration
255   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
256   *                the configuration information for the specified SMBUSx peripheral.
257   * @param  sConfig Pointer to a SMBUS_AutonomousModeConfTypeDef structure that contains
258   *                the configuration information of the autonomous mode for the specified SMBUSx peripheral.
259   * @retval HAL status
260   */
HAL_SMBUSEx_SetConfigAutonomousMode(SMBUS_HandleTypeDef * hsmbus,const SMBUS_AutonomousModeConfTypeDef * sConfig)261 HAL_StatusTypeDef HAL_SMBUSEx_SetConfigAutonomousMode(SMBUS_HandleTypeDef *hsmbus,
262                                                       const SMBUS_AutonomousModeConfTypeDef *sConfig)
263 {
264   if (hsmbus->State == HAL_SMBUS_STATE_READY)
265   {
266     /* Process Locked */
267     __HAL_LOCK(hsmbus);
268 
269     hsmbus->State = HAL_SMBUS_STATE_BUSY;
270 
271     /* Check the parameters */
272     assert_param(IS_SMBUS_TRIG_INPUT_INSTANCE(hsmbus->Instance));
273     assert_param(IS_SMBUS_TRIG_SOURCE(hsmbus->Instance, sConfig->TriggerSelection));
274     assert_param(IS_SMBUS_AUTO_MODE_TRG_POL(sConfig->TriggerPolarity));
275 
276     /* Disable the selected SMBUS peripheral to be able to configure AUTOCR */
277     __HAL_SMBUS_DISABLE(hsmbus);
278 
279     /* SMBUSx AUTOCR Configuration */
280     WRITE_REG(hsmbus->Instance->AUTOCR,
281               (sConfig->TriggerState | \
282                ((sConfig->TriggerSelection) & I2C_AUTOCR_TRIGSEL_Msk) | \
283                sConfig->TriggerPolarity));
284 
285     /* Enable the selected SMBUS peripheral */
286     __HAL_SMBUS_ENABLE(hsmbus);
287 
288     hsmbus->State = HAL_SMBUS_STATE_READY;
289 
290     /* Process Unlocked */
291     __HAL_UNLOCK(hsmbus);
292 
293     return HAL_OK;
294   }
295   else
296   {
297     return HAL_ERROR;
298   }
299 }
300 
301 /**
302   * @brief  Get Autonomous Mode configuration
303   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
304   *                the configuration information for the specified SMBUSx peripheral.
305   * @param  sConfig Pointer to a SMBUS_AutonomousModeConfTypeDef structure that contains
306   *                the configuration information of the autonomous mode for the specified SMBUSx peripheral.
307   * @retval HAL status
308   */
HAL_SMBUSEx_GetConfigAutonomousMode(const SMBUS_HandleTypeDef * hsmbus,SMBUS_AutonomousModeConfTypeDef * sConfig)309 HAL_StatusTypeDef HAL_SMBUSEx_GetConfigAutonomousMode(const SMBUS_HandleTypeDef *hsmbus,
310                                                       SMBUS_AutonomousModeConfTypeDef *sConfig)
311 {
312   uint32_t autocr_tmp;
313 
314   /* Check the parameters */
315   assert_param(IS_SMBUS_TRIG_INPUT_INSTANCE(hsmbus->Instance));
316 
317   autocr_tmp = hsmbus->Instance->AUTOCR;
318 
319   sConfig->TriggerState     = (autocr_tmp & I2C_AUTOCR_TRIGEN);
320   if (IS_SMBUS_GRP2_INSTANCE(hsmbus->Instance))
321   {
322     sConfig->TriggerSelection = ((autocr_tmp & I2C_AUTOCR_TRIGSEL) | SMBUS_TRIG_GRP2);
323   }
324   else
325   {
326     sConfig->TriggerSelection = ((autocr_tmp & I2C_AUTOCR_TRIGSEL) | SMBUS_TRIG_GRP1);
327   }
328   sConfig->TriggerPolarity  = (autocr_tmp & I2C_AUTOCR_TRIGPOL);
329 
330   return HAL_OK;
331 }
332 
333 /**
334   * @brief  Clear Autonomous Mode configuration
335   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
336   *                the configuration information for the specified SMBUS peripheral.
337   * @retval HAL status
338   */
HAL_SMBUSEx_ClearConfigAutonomousMode(SMBUS_HandleTypeDef * hsmbus)339 HAL_StatusTypeDef HAL_SMBUSEx_ClearConfigAutonomousMode(SMBUS_HandleTypeDef *hsmbus)
340 {
341   if (hsmbus->State == HAL_SMBUS_STATE_READY)
342   {
343     /* Process Locked */
344     __HAL_LOCK(hsmbus);
345 
346     hsmbus->State = HAL_SMBUS_STATE_BUSY;
347 
348     /* Check the parameters */
349     assert_param(IS_SMBUS_TRIG_INPUT_INSTANCE(hsmbus->Instance));
350 
351     /* Disable the selected SMBUS peripheral to be able to clear AUTOCR */
352     __HAL_SMBUS_DISABLE(hsmbus);
353 
354     CLEAR_REG(hsmbus->Instance->AUTOCR);
355 
356     /* Enable the selected SMBUS peripheral */
357     __HAL_SMBUS_ENABLE(hsmbus);
358 
359     hsmbus->State = HAL_SMBUS_STATE_READY;
360 
361     /* Process Unlocked */
362     __HAL_UNLOCK(hsmbus);
363 
364     return HAL_OK;
365   }
366   else
367   {
368     return HAL_ERROR;
369   }
370 }
371 /**
372   * @}
373   */
374 
375 /**
376   * @}
377   */
378 
379 #endif /* HAL_SMBUS_MODULE_ENABLED */
380 /**
381   * @}
382   */
383 
384 /**
385   * @}
386   */
387