1 /**
2   ******************************************************************************
3   * @file    stm32l0xx_hal_smbus.c
4   * @author  MCD Application Team
5   * @brief   SMBUS HAL module driver.
6   *          This file provides firmware functions to manage the following
7   *          functionalities of the System Management Bus (SMBus) peripheral,
8   *          based on I2C principles of operation :
9   *           + Initialization and de-initialization functions
10   *           + IO operation functions
11   *           + Peripheral State and Errors functions
12   *
13   @verbatim
14   ==============================================================================
15                         ##### How to use this driver #####
16   ==============================================================================
17     [..]
18     The SMBUS HAL driver can be used as follows:
19 
20     (#) Declare a SMBUS_HandleTypeDef handle structure, for example:
21         SMBUS_HandleTypeDef  hsmbus;
22 
23     (#)Initialize the SMBUS low level resources by implementing the HAL_SMBUS_MspInit() API:
24         (##) Enable the SMBUSx interface clock
25         (##) SMBUS pins configuration
26             (+++) Enable the clock for the SMBUS GPIOs
27             (+++) Configure SMBUS pins as alternate function open-drain
28         (##) NVIC configuration if you need to use interrupt process
29             (+++) Configure the SMBUSx interrupt priority
30             (+++) Enable the NVIC SMBUS IRQ Channel
31 
32     (#) Configure the Communication Clock Timing, Bus Timeout, Own Address1, Master Addressing mode,
33         Dual Addressing mode, Own Address2, Own Address2 Mask, General call, Nostretch mode,
34         Peripheral mode and Packet Error Check mode in the hsmbus Init structure.
35 
36     (#) Initialize the SMBUS registers by calling the HAL_SMBUS_Init() API:
37         (++) These API's configures also the low level Hardware GPIO, CLOCK, CORTEX...etc)
38              by calling the customized HAL_SMBUS_MspInit(&hsmbus) API.
39 
40     (#) To check if target device is ready for communication, use the function HAL_SMBUS_IsDeviceReady()
41 
42     (#) For SMBUS IO operations, only one mode of operations is available within this driver
43 
44     *** Interrupt mode IO operation ***
45     ===================================
46     [..]
47       (+) Transmit in master/host SMBUS mode an amount of data in non-blocking mode using HAL_SMBUS_Master_Transmit_IT()
48       (++) At transmission end of transfer HAL_SMBUS_MasterTxCpltCallback() is executed and user can
49            add his own code by customization of function pointer HAL_SMBUS_MasterTxCpltCallback()
50       (+) Receive in master/host SMBUS mode an amount of data in non-blocking mode using HAL_SMBUS_Master_Receive_IT()
51       (++) At reception end of transfer HAL_SMBUS_MasterRxCpltCallback() is executed and user can
52            add his own code by customization of function pointer HAL_SMBUS_MasterRxCpltCallback()
53       (+) Abort a master/host SMBUS process communication with Interrupt using HAL_SMBUS_Master_Abort_IT()
54       (++) The associated previous transfer callback is called at the end of abort process
55       (++) mean HAL_SMBUS_MasterTxCpltCallback() in case of previous state was master transmit
56       (++) mean HAL_SMBUS_MasterRxCpltCallback() in case of previous state was master receive
57       (+) Enable/disable the Address listen mode in slave/device or host/slave SMBUS mode
58            using HAL_SMBUS_EnableListen_IT() HAL_SMBUS_DisableListen_IT()
59       (++) When address slave/device SMBUS match, HAL_SMBUS_AddrCallback() is executed and user can
60            add his own code to check the Address Match Code and the transmission direction request by master/host (Write/Read).
61       (++) At Listen mode end HAL_SMBUS_ListenCpltCallback() is executed and user can
62            add his own code by customization of function pointer HAL_SMBUS_ListenCpltCallback()
63       (+) Transmit in slave/device SMBUS mode an amount of data in non-blocking mode using HAL_SMBUS_Slave_Transmit_IT()
64       (++) At transmission end of transfer HAL_SMBUS_SlaveTxCpltCallback() is executed and user can
65            add his own code by customization of function pointer HAL_SMBUS_SlaveTxCpltCallback()
66       (+) Receive in slave/device SMBUS mode an amount of data in non-blocking mode using HAL_SMBUS_Slave_Receive_IT()
67       (++) At reception end of transfer HAL_SMBUS_SlaveRxCpltCallback() is executed and user can
68            add his own code by customization of function pointer HAL_SMBUS_SlaveRxCpltCallback()
69       (+) Enable/Disable the SMBUS alert mode using HAL_SMBUS_EnableAlert_IT() HAL_SMBUS_DisableAlert_IT()
70       (++) When SMBUS Alert is generated HAL_SMBUS_ErrorCallback() is executed and user can
71            add his own code by customization of function pointer HAL_SMBUS_ErrorCallback()
72            to check the Alert Error Code using function HAL_SMBUS_GetError()
73       (+) Get HAL state machine or error values using HAL_SMBUS_GetState() or HAL_SMBUS_GetError()
74       (+) In case of transfer Error, HAL_SMBUS_ErrorCallback() function is executed and user can
75            add his own code by customization of function pointer HAL_SMBUS_ErrorCallback()
76            to check the Error Code using function HAL_SMBUS_GetError()
77 
78      *** SMBUS HAL driver macros list ***
79      ==================================
80      [..]
81        Below the list of most used macros in SMBUS HAL driver.
82 
83       (+) __HAL_SMBUS_ENABLE:      Enable the SMBUS peripheral
84       (+) __HAL_SMBUS_DISABLE:     Disable the SMBUS peripheral
85       (+) __HAL_SMBUS_GET_FLAG:    Check whether the specified SMBUS flag is set or not
86       (+) __HAL_SMBUS_CLEAR_FLAG:  Clear the specified SMBUS pending flag
87       (+) __HAL_SMBUS_ENABLE_IT:   Enable the specified SMBUS interrupt
88       (+) __HAL_SMBUS_DISABLE_IT:  Disable the specified SMBUS interrupt
89 
90      [..]
91        (@) You can refer to the SMBUS HAL driver header file for more useful macros
92 
93 
94   @endverbatim
95   ******************************************************************************
96   * @attention
97   *
98   * <h2><center>&copy; COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
99   *
100   * Redistribution and use in source and binary forms, with or without modification,
101   * are permitted provided that the following conditions are met:
102   *   1. Redistributions of source code must retain the above copyright notice,
103   *      this list of conditions and the following disclaimer.
104   *   2. Redistributions in binary form must reproduce the above copyright notice,
105   *      this list of conditions and the following disclaimer in the documentation
106   *      and/or other materials provided with the distribution.
107   *   3. Neither the name of STMicroelectronics nor the names of its contributors
108   *      may be used to endorse or promote products derived from this software
109   *      without specific prior written permission.
110   *
111   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
112   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
113   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
114   * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
115   * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
116   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
117   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
118   * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
119   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
120   * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
121   *
122   ******************************************************************************
123   */
124 
125 /* Includes ------------------------------------------------------------------*/
126 #include "stm32l0xx_hal.h"
127 
128 /** @addtogroup STM32L0xx_HAL_Driver
129   * @{
130   */
131 
132 /** @defgroup SMBUS SMBUS
133   * @brief SMBUS HAL module driver
134   * @{
135   */
136 
137 #ifdef HAL_SMBUS_MODULE_ENABLED
138 
139 /* Private typedef -----------------------------------------------------------*/
140 /* Private constants ---------------------------------------------------------*/
141 /** @defgroup SMBUS_Private_Define SMBUS Private Constants
142   * @{
143   */
144 #define TIMING_CLEAR_MASK   (0xF0FFFFFFU)      /*!< SMBUS TIMING clear register Mask */
145 #define HAL_TIMEOUT_ADDR    (10000U)           /*!< 10 s  */
146 #define HAL_TIMEOUT_BUSY    (25U)              /*!< 25 ms */
147 #define HAL_TIMEOUT_DIR     (25U)              /*!< 25 ms */
148 #define HAL_TIMEOUT_RXNE    (25U)              /*!< 25 ms */
149 #define HAL_TIMEOUT_STOPF   (25U)              /*!< 25 ms */
150 #define HAL_TIMEOUT_TC      (25U)              /*!< 25 ms */
151 #define HAL_TIMEOUT_TCR     (25U)              /*!< 25 ms */
152 #define HAL_TIMEOUT_TXIS    (25U)              /*!< 25 ms */
153 #define MAX_NBYTE_SIZE      255U
154 /**
155   * @}
156   */
157 
158 /* Private macro -------------------------------------------------------------*/
159 /* Private variables ---------------------------------------------------------*/
160 /* Private function prototypes -----------------------------------------------*/
161 /** @addtogroup SMBUS_Private_Functions SMBUS Private Functions
162   * @{
163   */
164 static HAL_StatusTypeDef SMBUS_WaitOnFlagUntilTimeout(SMBUS_HandleTypeDef *hsmbus, uint32_t Flag, FlagStatus Status, uint32_t Timeout);
165 
166 static HAL_StatusTypeDef SMBUS_Enable_IRQ(SMBUS_HandleTypeDef *hsmbus, uint16_t InterruptRequest);
167 static HAL_StatusTypeDef SMBUS_Disable_IRQ(SMBUS_HandleTypeDef *hsmbus, uint16_t InterruptRequest);
168 static HAL_StatusTypeDef SMBUS_Master_ISR(SMBUS_HandleTypeDef *hsmbus);
169 static HAL_StatusTypeDef SMBUS_Slave_ISR(SMBUS_HandleTypeDef *hsmbus);
170 
171 static void SMBUS_ConvertOtherXferOptions(SMBUS_HandleTypeDef *hsmbus);
172 
173 static void SMBUS_ITErrorHandler(SMBUS_HandleTypeDef *hsmbus);
174 
175 static void SMBUS_TransferConfig(SMBUS_HandleTypeDef *hsmbus,  uint16_t DevAddress, uint8_t Size, uint32_t Mode, uint32_t Request);
176 /**
177   * @}
178   */
179 
180 /* Exported functions --------------------------------------------------------*/
181 
182 /** @defgroup SMBUS_Exported_Functions SMBUS Exported Functions
183   * @{
184   */
185 
186 /** @defgroup SMBUS_Exported_Functions_Group1 Initialization and de-initialization functions
187  *  @brief    Initialization and Configuration functions
188  *
189 @verbatim
190  ===============================================================================
191               ##### Initialization and de-initialization functions #####
192  ===============================================================================
193     [..]  This subsection provides a set of functions allowing to initialize and
194           deinitialize the SMBUSx peripheral:
195 
196       (+) User must Implement HAL_SMBUS_MspInit() function in which he configures
197           all related peripherals resources (CLOCK, GPIO, IT and NVIC ).
198 
199       (+) Call the function HAL_SMBUS_Init() to configure the selected device with
200           the selected configuration:
201         (++) Clock Timing
202         (++) Bus Timeout
203         (++) Analog Filer mode
204         (++) Own Address 1
205         (++) Addressing mode (Master, Slave)
206         (++) Dual Addressing mode
207         (++) Own Address 2
208         (++) Own Address 2 Mask
209         (++) General call mode
210         (++) Nostretch mode
211         (++) Packet Error Check mode
212         (++) Peripheral mode
213 
214 
215       (+) Call the function HAL_SMBUS_DeInit() to restore the default configuration
216           of the selected SMBUSx peripheral.
217 
218       (+) Enable/Disable Analog/Digital filters with HAL_SMBUS_ConfigAnalogFilter() and
219           HAL_SMBUS_ConfigDigitalFilter().
220 
221 @endverbatim
222   * @{
223   */
224 
225 /**
226   * @brief  Initialize the SMBUS according to the specified parameters
227   *         in the SMBUS_InitTypeDef and initialize the associated handle.
228   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
229   *                the configuration information for the specified SMBUS.
230   * @retval HAL status
231   */
HAL_SMBUS_Init(SMBUS_HandleTypeDef * hsmbus)232 HAL_StatusTypeDef HAL_SMBUS_Init(SMBUS_HandleTypeDef *hsmbus)
233 {
234   /* Check the SMBUS handle allocation */
235   if (hsmbus == NULL)
236   {
237     return HAL_ERROR;
238   }
239 
240   /* Check the parameters */
241   assert_param(IS_SMBUS_INSTANCE(hsmbus->Instance));
242   assert_param(IS_SMBUS_ANALOG_FILTER(hsmbus->Init.AnalogFilter));
243   assert_param(IS_SMBUS_OWN_ADDRESS1(hsmbus->Init.OwnAddress1));
244   assert_param(IS_SMBUS_ADDRESSING_MODE(hsmbus->Init.AddressingMode));
245   assert_param(IS_SMBUS_DUAL_ADDRESS(hsmbus->Init.DualAddressMode));
246   assert_param(IS_SMBUS_OWN_ADDRESS2(hsmbus->Init.OwnAddress2));
247   assert_param(IS_SMBUS_OWN_ADDRESS2_MASK(hsmbus->Init.OwnAddress2Masks));
248   assert_param(IS_SMBUS_GENERAL_CALL(hsmbus->Init.GeneralCallMode));
249   assert_param(IS_SMBUS_NO_STRETCH(hsmbus->Init.NoStretchMode));
250   assert_param(IS_SMBUS_PEC(hsmbus->Init.PacketErrorCheckMode));
251   assert_param(IS_SMBUS_PERIPHERAL_MODE(hsmbus->Init.PeripheralMode));
252 
253   if (hsmbus->State == HAL_SMBUS_STATE_RESET)
254   {
255     /* Allocate lock resource and initialize it */
256     hsmbus->Lock = HAL_UNLOCKED;
257 
258     /* Init the low level hardware : GPIO, CLOCK, NVIC */
259     HAL_SMBUS_MspInit(hsmbus);
260   }
261 
262   hsmbus->State = HAL_SMBUS_STATE_BUSY;
263 
264   /* Disable the selected SMBUS peripheral */
265   __HAL_SMBUS_DISABLE(hsmbus);
266 
267   /*---------------------------- SMBUSx TIMINGR Configuration ------------------------*/
268   /* Configure SMBUSx: Frequency range */
269   hsmbus->Instance->TIMINGR = hsmbus->Init.Timing & TIMING_CLEAR_MASK;
270 
271   /*---------------------------- SMBUSx TIMEOUTR Configuration ------------------------*/
272   /* Configure SMBUSx: Bus Timeout  */
273   hsmbus->Instance->TIMEOUTR &= ~I2C_TIMEOUTR_TIMOUTEN;
274   hsmbus->Instance->TIMEOUTR &= ~I2C_TIMEOUTR_TEXTEN;
275   hsmbus->Instance->TIMEOUTR = hsmbus->Init.SMBusTimeout;
276 
277   /*---------------------------- SMBUSx OAR1 Configuration -----------------------*/
278   /* Configure SMBUSx: Own Address1 and ack own address1 mode */
279   hsmbus->Instance->OAR1 &= ~I2C_OAR1_OA1EN;
280 
281   if (hsmbus->Init.OwnAddress1 != 0U)
282   {
283     if (hsmbus->Init.AddressingMode == SMBUS_ADDRESSINGMODE_7BIT)
284     {
285       hsmbus->Instance->OAR1 = (I2C_OAR1_OA1EN | hsmbus->Init.OwnAddress1);
286     }
287     else /* SMBUS_ADDRESSINGMODE_10BIT */
288     {
289       hsmbus->Instance->OAR1 = (I2C_OAR1_OA1EN | I2C_OAR1_OA1MODE | hsmbus->Init.OwnAddress1);
290     }
291   }
292 
293   /*---------------------------- SMBUSx CR2 Configuration ------------------------*/
294   /* Configure SMBUSx: Addressing Master mode */
295   if (hsmbus->Init.AddressingMode == SMBUS_ADDRESSINGMODE_10BIT)
296   {
297     hsmbus->Instance->CR2 = (I2C_CR2_ADD10);
298   }
299   /* Enable the AUTOEND by default, and enable NACK (should be disable only during Slave process) */
300   /* AUTOEND and NACK bit will be manage during Transfer process */
301   hsmbus->Instance->CR2 |= (I2C_CR2_AUTOEND | I2C_CR2_NACK);
302 
303   /*---------------------------- SMBUSx OAR2 Configuration -----------------------*/
304   /* Configure SMBUSx: Dual mode and Own Address2 */
305   hsmbus->Instance->OAR2 = (hsmbus->Init.DualAddressMode | hsmbus->Init.OwnAddress2 | (hsmbus->Init.OwnAddress2Masks << 8U));
306 
307   /*---------------------------- SMBUSx CR1 Configuration ------------------------*/
308   /* Configure SMBUSx: Generalcall and NoStretch mode */
309   hsmbus->Instance->CR1 = (hsmbus->Init.GeneralCallMode | hsmbus->Init.NoStretchMode | hsmbus->Init.PacketErrorCheckMode | hsmbus->Init.PeripheralMode | hsmbus->Init.AnalogFilter);
310 
311   /* Enable Slave Byte Control only in case of Packet Error Check is enabled and SMBUS Peripheral is set in Slave mode */
312   if ((hsmbus->Init.PacketErrorCheckMode == SMBUS_PEC_ENABLE)
313       && ((hsmbus->Init.PeripheralMode == SMBUS_PERIPHERAL_MODE_SMBUS_SLAVE) || (hsmbus->Init.PeripheralMode == SMBUS_PERIPHERAL_MODE_SMBUS_SLAVE_ARP)))
314   {
315     hsmbus->Instance->CR1 |= I2C_CR1_SBC;
316   }
317 
318   /* Enable the selected SMBUS peripheral */
319   __HAL_SMBUS_ENABLE(hsmbus);
320 
321   hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE;
322   hsmbus->PreviousState = HAL_SMBUS_STATE_READY;
323   hsmbus->State = HAL_SMBUS_STATE_READY;
324 
325   return HAL_OK;
326 }
327 
328 /**
329   * @brief  DeInitialize the SMBUS peripheral.
330   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
331   *                the configuration information for the specified SMBUS.
332   * @retval HAL status
333   */
HAL_SMBUS_DeInit(SMBUS_HandleTypeDef * hsmbus)334 HAL_StatusTypeDef HAL_SMBUS_DeInit(SMBUS_HandleTypeDef *hsmbus)
335 {
336   /* Check the SMBUS handle allocation */
337   if (hsmbus == NULL)
338   {
339     return HAL_ERROR;
340   }
341 
342   /* Check the parameters */
343   assert_param(IS_SMBUS_INSTANCE(hsmbus->Instance));
344 
345   hsmbus->State = HAL_SMBUS_STATE_BUSY;
346 
347   /* Disable the SMBUS Peripheral Clock */
348   __HAL_SMBUS_DISABLE(hsmbus);
349 
350   /* DeInit the low level hardware: GPIO, CLOCK, NVIC */
351   HAL_SMBUS_MspDeInit(hsmbus);
352 
353   hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE;
354   hsmbus->PreviousState =  HAL_SMBUS_STATE_RESET;
355   hsmbus->State = HAL_SMBUS_STATE_RESET;
356 
357   /* Release Lock */
358   __HAL_UNLOCK(hsmbus);
359 
360   return HAL_OK;
361 }
362 
363 /**
364   * @brief Initialize the SMBUS MSP.
365   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
366   *                the configuration information for the specified SMBUS.
367   * @retval None
368   */
HAL_SMBUS_MspInit(SMBUS_HandleTypeDef * hsmbus)369 __weak void HAL_SMBUS_MspInit(SMBUS_HandleTypeDef *hsmbus)
370 {
371   /* Prevent unused argument(s) compilation warning */
372   UNUSED(hsmbus);
373 
374   /* NOTE : This function should not be modified, when the callback is needed,
375             the HAL_SMBUS_MspInit could be implemented in the user file
376    */
377 }
378 
379 /**
380   * @brief DeInitialize the SMBUS MSP.
381   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
382   *                the configuration information for the specified SMBUS.
383   * @retval None
384   */
HAL_SMBUS_MspDeInit(SMBUS_HandleTypeDef * hsmbus)385 __weak void HAL_SMBUS_MspDeInit(SMBUS_HandleTypeDef *hsmbus)
386 {
387   /* Prevent unused argument(s) compilation warning */
388   UNUSED(hsmbus);
389 
390   /* NOTE : This function should not be modified, when the callback is needed,
391             the HAL_SMBUS_MspDeInit could be implemented in the user file
392    */
393 }
394 
395 /**
396   * @brief  Configure Analog noise filter.
397   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
398   *                the configuration information for the specified SMBUS.
399   * @param  AnalogFilter This parameter can be one of the following values:
400   *         @arg @ref SMBUS_ANALOGFILTER_ENABLE
401   *         @arg @ref SMBUS_ANALOGFILTER_DISABLE
402   * @retval HAL status
403   */
HAL_SMBUS_ConfigAnalogFilter(SMBUS_HandleTypeDef * hsmbus,uint32_t AnalogFilter)404 HAL_StatusTypeDef HAL_SMBUS_ConfigAnalogFilter(SMBUS_HandleTypeDef *hsmbus, uint32_t AnalogFilter)
405 {
406   /* Check the parameters */
407   assert_param(IS_SMBUS_INSTANCE(hsmbus->Instance));
408   assert_param(IS_SMBUS_ANALOG_FILTER(AnalogFilter));
409 
410   if (hsmbus->State == HAL_SMBUS_STATE_READY)
411   {
412     /* Process Locked */
413     __HAL_LOCK(hsmbus);
414 
415     hsmbus->State = HAL_SMBUS_STATE_BUSY;
416 
417     /* Disable the selected SMBUS peripheral */
418     __HAL_SMBUS_DISABLE(hsmbus);
419 
420     /* Reset ANOFF bit */
421     hsmbus->Instance->CR1 &= ~(I2C_CR1_ANFOFF);
422 
423     /* Set analog filter bit*/
424     hsmbus->Instance->CR1 |= AnalogFilter;
425 
426     __HAL_SMBUS_ENABLE(hsmbus);
427 
428     hsmbus->State = HAL_SMBUS_STATE_READY;
429 
430     /* Process Unlocked */
431     __HAL_UNLOCK(hsmbus);
432 
433     return HAL_OK;
434   }
435   else
436   {
437     return HAL_BUSY;
438   }
439 }
440 
441 /**
442   * @brief  Configure Digital noise filter.
443   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
444   *                the configuration information for the specified SMBUS.
445   * @param  DigitalFilter Coefficient of digital noise filter between Min_Data=0x00 and Max_Data=0x0F.
446   * @retval HAL status
447   */
HAL_SMBUS_ConfigDigitalFilter(SMBUS_HandleTypeDef * hsmbus,uint32_t DigitalFilter)448 HAL_StatusTypeDef HAL_SMBUS_ConfigDigitalFilter(SMBUS_HandleTypeDef *hsmbus, uint32_t DigitalFilter)
449 {
450   uint32_t tmpreg = 0U;
451 
452   /* Check the parameters */
453   assert_param(IS_SMBUS_INSTANCE(hsmbus->Instance));
454   assert_param(IS_SMBUS_DIGITAL_FILTER(DigitalFilter));
455 
456   if (hsmbus->State == HAL_SMBUS_STATE_READY)
457   {
458     /* Process Locked */
459     __HAL_LOCK(hsmbus);
460 
461     hsmbus->State = HAL_SMBUS_STATE_BUSY;
462 
463     /* Disable the selected SMBUS peripheral */
464     __HAL_SMBUS_DISABLE(hsmbus);
465 
466     /* Get the old register value */
467     tmpreg = hsmbus->Instance->CR1;
468 
469     /* Reset I2C DNF bits [11:8] */
470     tmpreg &= ~(I2C_CR1_DNF);
471 
472     /* Set I2Cx DNF coefficient */
473     tmpreg |= DigitalFilter << I2C_CR1_DNF_Pos;
474 
475     /* Store the new register value */
476     hsmbus->Instance->CR1 = tmpreg;
477 
478     __HAL_SMBUS_ENABLE(hsmbus);
479 
480     hsmbus->State = HAL_SMBUS_STATE_READY;
481 
482     /* Process Unlocked */
483     __HAL_UNLOCK(hsmbus);
484 
485     return HAL_OK;
486   }
487   else
488   {
489     return HAL_BUSY;
490   }
491 }
492 
493 /**
494   * @}
495   */
496 
497 /** @defgroup SMBUS_Exported_Functions_Group2 Input and Output operation functions
498  *  @brief   Data transfers functions
499  *
500 @verbatim
501  ===============================================================================
502                       ##### IO operation functions #####
503  ===============================================================================
504     [..]
505     This subsection provides a set of functions allowing to manage the SMBUS data
506     transfers.
507 
508     (#) Blocking mode function to check if device is ready for usage is :
509         (++) HAL_SMBUS_IsDeviceReady()
510 
511     (#) There is only one mode of transfer:
512        (++) Non-Blocking mode : The communication is performed using Interrupts.
513             These functions return the status of the transfer startup.
514             The end of the data processing will be indicated through the
515             dedicated SMBUS IRQ when using Interrupt mode.
516 
517     (#) Non-Blocking mode functions with Interrupt are :
518         (++) HAL_SMBUS_Master_Transmit_IT()
519         (++) HAL_SMBUS_Master_Receive_IT()
520         (++) HAL_SMBUS_Slave_Transmit_IT()
521         (++) HAL_SMBUS_Slave_Receive_IT()
522         (++) HAL_SMBUS_EnableListen_IT() or alias HAL_SMBUS_EnableListen_IT()
523         (++) HAL_SMBUS_DisableListen_IT()
524         (++) HAL_SMBUS_EnableAlert_IT()
525         (++) HAL_SMBUS_DisableAlert_IT()
526 
527     (#) A set of Transfer Complete Callbacks are provided in non-Blocking mode:
528         (++) HAL_SMBUS_MasterTxCpltCallback()
529         (++) HAL_SMBUS_MasterRxCpltCallback()
530         (++) HAL_SMBUS_SlaveTxCpltCallback()
531         (++) HAL_SMBUS_SlaveRxCpltCallback()
532         (++) HAL_SMBUS_AddrCallback()
533         (++) HAL_SMBUS_ListenCpltCallback()
534         (++) HAL_SMBUS_ErrorCallback()
535 
536 @endverbatim
537   * @{
538   */
539 
540 /**
541   * @brief  Transmit in master/host SMBUS mode an amount of data in non-blocking mode with Interrupt.
542   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
543   *                the configuration information for the specified SMBUS.
544   * @param  DevAddress Target device address: The device 7 bits address value
545   *         in datasheet must be shift at right before call interface
546   * @param  pData Pointer to data buffer
547   * @param  Size Amount of data to be sent
548   * @param  XferOptions Options of Transfer, value of @ref SMBUS_XferOptions_definition
549   * @retval HAL status
550   */
HAL_SMBUS_Master_Transmit_IT(SMBUS_HandleTypeDef * hsmbus,uint16_t DevAddress,uint8_t * pData,uint16_t Size,uint32_t XferOptions)551 HAL_StatusTypeDef HAL_SMBUS_Master_Transmit_IT(SMBUS_HandleTypeDef *hsmbus, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t XferOptions)
552 {
553   /* Check the parameters */
554   assert_param(IS_SMBUS_TRANSFER_OPTIONS_REQUEST(XferOptions));
555 
556   if (hsmbus->State == HAL_SMBUS_STATE_READY)
557   {
558     /* Process Locked */
559     __HAL_LOCK(hsmbus);
560 
561     hsmbus->State = HAL_SMBUS_STATE_MASTER_BUSY_TX;
562     hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE;
563     /* Prepare transfer parameters */
564     hsmbus->pBuffPtr = pData;
565     hsmbus->XferCount = Size;
566     hsmbus->XferOptions = XferOptions;
567 
568     /* In case of Quick command, remove autoend mode */
569     /* Manage the stop generation by software */
570     if (hsmbus->pBuffPtr == NULL)
571     {
572       hsmbus->XferOptions &= ~SMBUS_AUTOEND_MODE;
573     }
574 
575     if (Size > MAX_NBYTE_SIZE)
576     {
577       hsmbus->XferSize = MAX_NBYTE_SIZE;
578     }
579     else
580     {
581       hsmbus->XferSize = Size;
582     }
583 
584     /* Send Slave Address */
585     /* Set NBYTES to write and reload if size > MAX_NBYTE_SIZE and generate RESTART */
586     if ((hsmbus->XferSize == MAX_NBYTE_SIZE) && (hsmbus->XferSize < hsmbus->XferCount))
587     {
588       SMBUS_TransferConfig(hsmbus, DevAddress, hsmbus->XferSize, SMBUS_RELOAD_MODE | (hsmbus->XferOptions & SMBUS_SENDPEC_MODE), SMBUS_GENERATE_START_WRITE);
589     }
590     else
591     {
592       /* If transfer direction not change, do not generate Restart Condition */
593       /* Mean Previous state is same as current state */
594       if ((hsmbus->PreviousState == HAL_SMBUS_STATE_MASTER_BUSY_TX) && (IS_SMBUS_TRANSFER_OTHER_OPTIONS_REQUEST(hsmbus->XferOptions) == 0))
595       {
596         SMBUS_TransferConfig(hsmbus, DevAddress, hsmbus->XferSize, hsmbus->XferOptions, SMBUS_NO_STARTSTOP);
597       }
598       /* Else transfer direction change, so generate Restart with new transfer direction */
599       else
600       {
601         /* Convert OTHER_xxx XferOptions if any */
602         SMBUS_ConvertOtherXferOptions(hsmbus);
603 
604         /* Handle Transfer */
605         SMBUS_TransferConfig(hsmbus, DevAddress, hsmbus->XferSize, hsmbus->XferOptions, SMBUS_GENERATE_START_WRITE);
606       }
607 
608       /* If PEC mode is enable, size to transmit manage by SW part should be Size-1 byte, corresponding to PEC byte */
609       /* PEC byte is automatically sent by HW block, no need to manage it in Transmit process */
610       if (SMBUS_GET_PEC_MODE(hsmbus) != RESET)
611       {
612         hsmbus->XferSize--;
613         hsmbus->XferCount--;
614       }
615     }
616 
617     /* Process Unlocked */
618     __HAL_UNLOCK(hsmbus);
619 
620     /* Note : The SMBUS interrupts must be enabled after unlocking current process
621               to avoid the risk of SMBUS interrupt handle execution before current
622               process unlock */
623     SMBUS_Enable_IRQ(hsmbus, SMBUS_IT_TX);
624 
625     return HAL_OK;
626   }
627   else
628   {
629     return HAL_BUSY;
630   }
631 }
632 
633 /**
634   * @brief  Receive in master/host SMBUS mode an amount of data in non-blocking mode with Interrupt.
635   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
636   *                the configuration information for the specified SMBUS.
637   * @param  DevAddress Target device address: The device 7 bits address value
638   *         in datasheet must be shift at right before call interface
639   * @param  pData Pointer to data buffer
640   * @param  Size Amount of data to be sent
641   * @param  XferOptions Options of Transfer, value of @ref SMBUS_XferOptions_definition
642   * @retval HAL status
643   */
HAL_SMBUS_Master_Receive_IT(SMBUS_HandleTypeDef * hsmbus,uint16_t DevAddress,uint8_t * pData,uint16_t Size,uint32_t XferOptions)644 HAL_StatusTypeDef HAL_SMBUS_Master_Receive_IT(SMBUS_HandleTypeDef *hsmbus, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t XferOptions)
645 {
646   /* Check the parameters */
647   assert_param(IS_SMBUS_TRANSFER_OPTIONS_REQUEST(XferOptions));
648 
649   if (hsmbus->State == HAL_SMBUS_STATE_READY)
650   {
651     /* Process Locked */
652     __HAL_LOCK(hsmbus);
653 
654     hsmbus->State = HAL_SMBUS_STATE_MASTER_BUSY_RX;
655     hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE;
656 
657     /* Prepare transfer parameters */
658     hsmbus->pBuffPtr = pData;
659     hsmbus->XferCount = Size;
660     hsmbus->XferOptions = XferOptions;
661 
662     /* In case of Quick command, remove autoend mode */
663     /* Manage the stop generation by software */
664     if (hsmbus->pBuffPtr == NULL)
665     {
666       hsmbus->XferOptions &= ~SMBUS_AUTOEND_MODE;
667     }
668 
669     if (Size > MAX_NBYTE_SIZE)
670     {
671       hsmbus->XferSize = MAX_NBYTE_SIZE;
672     }
673     else
674     {
675       hsmbus->XferSize = Size;
676     }
677 
678     /* Send Slave Address */
679     /* Set NBYTES to write and reload if size > MAX_NBYTE_SIZE and generate RESTART */
680     if ((hsmbus->XferSize == MAX_NBYTE_SIZE) && (hsmbus->XferSize < hsmbus->XferCount))
681     {
682       SMBUS_TransferConfig(hsmbus, DevAddress, hsmbus->XferSize, SMBUS_RELOAD_MODE  | (hsmbus->XferOptions & SMBUS_SENDPEC_MODE), SMBUS_GENERATE_START_READ);
683     }
684     else
685     {
686       /* If transfer direction not change, do not generate Restart Condition */
687       /* Mean Previous state is same as current state */
688       if ((hsmbus->PreviousState == HAL_SMBUS_STATE_MASTER_BUSY_RX) && (IS_SMBUS_TRANSFER_OTHER_OPTIONS_REQUEST(hsmbus->XferOptions) == 0))
689       {
690         SMBUS_TransferConfig(hsmbus, DevAddress, hsmbus->XferSize, hsmbus->XferOptions, SMBUS_NO_STARTSTOP);
691       }
692       /* Else transfer direction change, so generate Restart with new transfer direction */
693       else
694       {
695         /* Convert OTHER_xxx XferOptions if any */
696         SMBUS_ConvertOtherXferOptions(hsmbus);
697 
698         /* Handle Transfer */
699         SMBUS_TransferConfig(hsmbus, DevAddress, hsmbus->XferSize, hsmbus->XferOptions, SMBUS_GENERATE_START_READ);
700       }
701     }
702 
703     /* Process Unlocked */
704     __HAL_UNLOCK(hsmbus);
705 
706     /* Note : The SMBUS interrupts must be enabled after unlocking current process
707               to avoid the risk of SMBUS interrupt handle execution before current
708               process unlock */
709     SMBUS_Enable_IRQ(hsmbus, SMBUS_IT_RX);
710 
711     return HAL_OK;
712   }
713   else
714   {
715     return HAL_BUSY;
716   }
717 }
718 
719 /**
720   * @brief  Abort a master/host SMBUS process communication with Interrupt.
721   * @note   This abort can be called only if state is ready
722   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
723   *                the configuration information for the specified SMBUS.
724   * @param  DevAddress Target device address: The device 7 bits address value
725   *         in datasheet must be shift at right before call interface
726   * @retval HAL status
727   */
HAL_SMBUS_Master_Abort_IT(SMBUS_HandleTypeDef * hsmbus,uint16_t DevAddress)728 HAL_StatusTypeDef HAL_SMBUS_Master_Abort_IT(SMBUS_HandleTypeDef *hsmbus, uint16_t DevAddress)
729 {
730   if (hsmbus->State == HAL_SMBUS_STATE_READY)
731   {
732     /* Process Locked */
733     __HAL_LOCK(hsmbus);
734 
735     /* Keep the same state as previous */
736     /* to perform as well the call of the corresponding end of transfer callback */
737     if (hsmbus->PreviousState == HAL_SMBUS_STATE_MASTER_BUSY_TX)
738     {
739       hsmbus->State = HAL_SMBUS_STATE_MASTER_BUSY_TX;
740     }
741     else if (hsmbus->PreviousState == HAL_SMBUS_STATE_MASTER_BUSY_RX)
742     {
743       hsmbus->State = HAL_SMBUS_STATE_MASTER_BUSY_RX;
744     }
745     else
746     {
747       /* Wrong usage of abort function */
748       /* This function should be used only in case of abort monitored by master device */
749       return HAL_ERROR;
750     }
751     hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE;
752 
753     /* Set NBYTES to 1 to generate a dummy read on SMBUS peripheral */
754     /* Set AUTOEND mode, this will generate a NACK then STOP condition to abort the current transfer */
755     SMBUS_TransferConfig(hsmbus, DevAddress, 1U, SMBUS_AUTOEND_MODE, SMBUS_NO_STARTSTOP);
756 
757     /* Process Unlocked */
758     __HAL_UNLOCK(hsmbus);
759 
760     /* Note : The SMBUS interrupts must be enabled after unlocking current process
761               to avoid the risk of SMBUS interrupt handle execution before current
762               process unlock */
763     if (hsmbus->State == HAL_SMBUS_STATE_MASTER_BUSY_TX)
764     {
765       SMBUS_Enable_IRQ(hsmbus, SMBUS_IT_TX);
766     }
767     else if (hsmbus->State == HAL_SMBUS_STATE_MASTER_BUSY_RX)
768     {
769       SMBUS_Enable_IRQ(hsmbus, SMBUS_IT_RX);
770     }
771 
772     return HAL_OK;
773   }
774   else
775   {
776     return HAL_BUSY;
777   }
778 }
779 
780 /**
781   * @brief  Transmit in slave/device SMBUS mode an amount of data in non-blocking mode with Interrupt.
782   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
783   *                the configuration information for the specified SMBUS.
784   * @param  pData Pointer to data buffer
785   * @param  Size Amount of data to be sent
786   * @param  XferOptions Options of Transfer, value of @ref SMBUS_XferOptions_definition
787   * @retval HAL status
788   */
HAL_SMBUS_Slave_Transmit_IT(SMBUS_HandleTypeDef * hsmbus,uint8_t * pData,uint16_t Size,uint32_t XferOptions)789 HAL_StatusTypeDef HAL_SMBUS_Slave_Transmit_IT(SMBUS_HandleTypeDef *hsmbus, uint8_t *pData, uint16_t Size, uint32_t XferOptions)
790 {
791   /* Check the parameters */
792   assert_param(IS_SMBUS_TRANSFER_OPTIONS_REQUEST(XferOptions));
793 
794   if (hsmbus->State == HAL_SMBUS_STATE_LISTEN)
795   {
796     if ((pData == NULL) || (Size == 0U))
797     {
798       return  HAL_ERROR;
799     }
800 
801     /* Disable Interrupts, to prevent preemption during treatment in case of multicall */
802     SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_ADDR | SMBUS_IT_TX);
803 
804     /* Process Locked */
805     __HAL_LOCK(hsmbus);
806 
807     hsmbus->State |= HAL_SMBUS_STATE_SLAVE_BUSY_TX;
808     hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE;
809 
810     /* Set SBC bit to manage Acknowledge at each bit */
811     hsmbus->Instance->CR1 |= I2C_CR1_SBC;
812 
813     /* Enable Address Acknowledge */
814     hsmbus->Instance->CR2 &= ~I2C_CR2_NACK;
815 
816     /* Prepare transfer parameters */
817     hsmbus->pBuffPtr = pData;
818     hsmbus->XferCount = Size;
819     hsmbus->XferOptions = XferOptions;
820 
821     /* Convert OTHER_xxx XferOptions if any */
822     SMBUS_ConvertOtherXferOptions(hsmbus);
823 
824     if (Size > MAX_NBYTE_SIZE)
825     {
826       hsmbus->XferSize = MAX_NBYTE_SIZE;
827     }
828     else
829     {
830       hsmbus->XferSize = Size;
831     }
832 
833     /* Set NBYTES to write and reload if size > MAX_NBYTE_SIZE and generate RESTART */
834     if ((hsmbus->XferSize == MAX_NBYTE_SIZE) && (hsmbus->XferSize < hsmbus->XferCount))
835     {
836       SMBUS_TransferConfig(hsmbus, 0U, hsmbus->XferSize, SMBUS_RELOAD_MODE | (hsmbus->XferOptions & SMBUS_SENDPEC_MODE), SMBUS_NO_STARTSTOP);
837     }
838     else
839     {
840       /* Set NBYTE to transmit */
841       SMBUS_TransferConfig(hsmbus, 0U, hsmbus->XferSize, hsmbus->XferOptions, SMBUS_NO_STARTSTOP);
842 
843       /* If PEC mode is enable, size to transmit should be Size-1 byte, corresponding to PEC byte */
844       /* PEC byte is automatically sent by HW block, no need to manage it in Transmit process */
845       if (SMBUS_GET_PEC_MODE(hsmbus) != RESET)
846       {
847         hsmbus->XferSize--;
848         hsmbus->XferCount--;
849       }
850     }
851 
852     /* Clear ADDR flag after prepare the transfer parameters */
853     /* This action will generate an acknowledge to the HOST */
854     __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_ADDR);
855 
856     /* Process Unlocked */
857     __HAL_UNLOCK(hsmbus);
858 
859     /* Note : The SMBUS interrupts must be enabled after unlocking current process
860               to avoid the risk of SMBUS interrupt handle execution before current
861               process unlock */
862     /* REnable ADDR interrupt */
863     SMBUS_Enable_IRQ(hsmbus, SMBUS_IT_TX | SMBUS_IT_ADDR);
864 
865     return HAL_OK;
866   }
867   else
868   {
869     return HAL_ERROR;
870   }
871 }
872 
873 /**
874   * @brief  Receive in slave/device SMBUS mode an amount of data in non-blocking mode with Interrupt.
875   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
876   *                the configuration information for the specified SMBUS.
877   * @param  pData Pointer to data buffer
878   * @param  Size Amount of data to be sent
879   * @param  XferOptions Options of Transfer, value of @ref SMBUS_XferOptions_definition
880   * @retval HAL status
881   */
HAL_SMBUS_Slave_Receive_IT(SMBUS_HandleTypeDef * hsmbus,uint8_t * pData,uint16_t Size,uint32_t XferOptions)882 HAL_StatusTypeDef HAL_SMBUS_Slave_Receive_IT(SMBUS_HandleTypeDef *hsmbus, uint8_t *pData, uint16_t Size, uint32_t XferOptions)
883 {
884   /* Check the parameters */
885   assert_param(IS_SMBUS_TRANSFER_OPTIONS_REQUEST(XferOptions));
886 
887   if (hsmbus->State == HAL_SMBUS_STATE_LISTEN)
888   {
889     if ((pData == NULL) || (Size == 0U))
890     {
891       return  HAL_ERROR;
892     }
893 
894     /* Disable Interrupts, to prevent preemption during treatment in case of multicall */
895     SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_ADDR | SMBUS_IT_RX);
896 
897     /* Process Locked */
898     __HAL_LOCK(hsmbus);
899 
900     hsmbus->State |= HAL_SMBUS_STATE_SLAVE_BUSY_RX;
901     hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE;
902 
903     /* Set SBC bit to manage Acknowledge at each bit */
904     hsmbus->Instance->CR1 |= I2C_CR1_SBC;
905 
906     /* Enable Address Acknowledge */
907     hsmbus->Instance->CR2 &= ~I2C_CR2_NACK;
908 
909     /* Prepare transfer parameters */
910     hsmbus->pBuffPtr = pData;
911     hsmbus->XferSize = Size;
912     hsmbus->XferCount = Size;
913     hsmbus->XferOptions = XferOptions;
914 
915     /* Convert OTHER_xxx XferOptions if any */
916     SMBUS_ConvertOtherXferOptions(hsmbus);
917 
918     /* Set NBYTE to receive */
919     /* If XferSize equal "1", or XferSize equal "2" with PEC requested (mean 1 data byte + 1 PEC byte */
920     /* no need to set RELOAD bit mode, a ACK will be automatically generated in that case */
921     /* else need to set RELOAD bit mode to generate an automatic ACK at each byte Received */
922     /* This RELOAD bit will be reset for last BYTE to be receive in SMBUS_Slave_ISR */
923     if ((hsmbus->XferSize == 1U) || ((hsmbus->XferSize == 2U) && (SMBUS_GET_PEC_MODE(hsmbus) != RESET)))
924     {
925       SMBUS_TransferConfig(hsmbus, 0U, hsmbus->XferSize, hsmbus->XferOptions, SMBUS_NO_STARTSTOP);
926     }
927     else
928     {
929       SMBUS_TransferConfig(hsmbus, 0U, 1U, hsmbus->XferOptions | SMBUS_RELOAD_MODE, SMBUS_NO_STARTSTOP);
930     }
931 
932     /* Clear ADDR flag after prepare the transfer parameters */
933     /* This action will generate an acknowledge to the HOST */
934     __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_ADDR);
935 
936     /* Process Unlocked */
937     __HAL_UNLOCK(hsmbus);
938 
939     /* Note : The SMBUS interrupts must be enabled after unlocking current process
940               to avoid the risk of SMBUS interrupt handle execution before current
941               process unlock */
942     /* REnable ADDR interrupt */
943     SMBUS_Enable_IRQ(hsmbus, SMBUS_IT_RX | SMBUS_IT_ADDR);
944 
945     return HAL_OK;
946   }
947   else
948   {
949     return HAL_ERROR;
950   }
951 }
952 
953 /**
954   * @brief  Enable the Address listen mode with Interrupt.
955   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
956   *                the configuration information for the specified SMBUS.
957   * @retval HAL status
958   */
HAL_SMBUS_EnableListen_IT(SMBUS_HandleTypeDef * hsmbus)959 HAL_StatusTypeDef HAL_SMBUS_EnableListen_IT(SMBUS_HandleTypeDef *hsmbus)
960 {
961   hsmbus->State = HAL_SMBUS_STATE_LISTEN;
962 
963   /* Enable the Address Match interrupt */
964   SMBUS_Enable_IRQ(hsmbus, SMBUS_IT_ADDR);
965 
966   return HAL_OK;
967 }
968 
969 /**
970   * @brief  Disable the Address listen mode with Interrupt.
971   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
972   *                the configuration information for the specified SMBUS.
973   * @retval HAL status
974   */
HAL_SMBUS_DisableListen_IT(SMBUS_HandleTypeDef * hsmbus)975 HAL_StatusTypeDef HAL_SMBUS_DisableListen_IT(SMBUS_HandleTypeDef *hsmbus)
976 {
977   /* Disable Address listen mode only if a transfer is not ongoing */
978   if (hsmbus->State == HAL_SMBUS_STATE_LISTEN)
979   {
980     hsmbus->State = HAL_SMBUS_STATE_READY;
981 
982     /* Disable the Address Match interrupt */
983     SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_ADDR);
984 
985     return HAL_OK;
986   }
987   else
988   {
989     return HAL_BUSY;
990   }
991 }
992 
993 /**
994   * @brief  Enable the SMBUS alert mode with Interrupt.
995   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
996   *                the configuration information for the specified SMBUSx peripheral.
997   * @retval HAL status
998   */
HAL_SMBUS_EnableAlert_IT(SMBUS_HandleTypeDef * hsmbus)999 HAL_StatusTypeDef HAL_SMBUS_EnableAlert_IT(SMBUS_HandleTypeDef *hsmbus)
1000 {
1001   /* Enable SMBus alert */
1002   hsmbus->Instance->CR1 |= I2C_CR1_ALERTEN;
1003 
1004   /* Clear ALERT flag */
1005   __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_ALERT);
1006 
1007   /* Enable Alert Interrupt */
1008   SMBUS_Enable_IRQ(hsmbus, SMBUS_IT_ALERT);
1009 
1010   return HAL_OK;
1011 }
1012 /**
1013   * @brief  Disable the SMBUS alert mode with Interrupt.
1014   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1015   *                the configuration information for the specified SMBUSx peripheral.
1016   * @retval HAL status
1017   */
HAL_SMBUS_DisableAlert_IT(SMBUS_HandleTypeDef * hsmbus)1018 HAL_StatusTypeDef HAL_SMBUS_DisableAlert_IT(SMBUS_HandleTypeDef *hsmbus)
1019 {
1020   /* Enable SMBus alert */
1021   hsmbus->Instance->CR1 &= ~I2C_CR1_ALERTEN;
1022 
1023   /* Disable Alert Interrupt */
1024   SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_ALERT);
1025 
1026   return HAL_OK;
1027 }
1028 
1029 /**
1030   * @brief  Check if target device is ready for communication.
1031   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1032   *                the configuration information for the specified SMBUS.
1033   * @param  DevAddress Target device address: The device 7 bits address value
1034   *         in datasheet must be shift at right before call interface
1035   * @param  Trials Number of trials
1036   * @param  Timeout Timeout duration
1037   * @retval HAL status
1038   */
HAL_SMBUS_IsDeviceReady(SMBUS_HandleTypeDef * hsmbus,uint16_t DevAddress,uint32_t Trials,uint32_t Timeout)1039 HAL_StatusTypeDef HAL_SMBUS_IsDeviceReady(SMBUS_HandleTypeDef *hsmbus, uint16_t DevAddress, uint32_t Trials, uint32_t Timeout)
1040 {
1041   uint32_t tickstart = 0U;
1042 
1043   __IO uint32_t SMBUS_Trials = 0U;
1044 
1045   if (hsmbus->State == HAL_SMBUS_STATE_READY)
1046   {
1047     if (__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_BUSY) != RESET)
1048     {
1049       return HAL_BUSY;
1050     }
1051 
1052     /* Process Locked */
1053     __HAL_LOCK(hsmbus);
1054 
1055     hsmbus->State = HAL_SMBUS_STATE_BUSY;
1056     hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE;
1057 
1058     do
1059     {
1060       /* Generate Start */
1061       hsmbus->Instance->CR2 = SMBUS_GENERATE_START(hsmbus->Init.AddressingMode, DevAddress);
1062 
1063       /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */
1064       /* Wait until STOPF flag is set or a NACK flag is set*/
1065       tickstart = HAL_GetTick();
1066       while ((__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_STOPF) == RESET) && (__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_AF) == RESET) && (hsmbus->State != HAL_SMBUS_STATE_TIMEOUT))
1067       {
1068         if (Timeout != HAL_MAX_DELAY)
1069         {
1070           if ((Timeout == 0U) || ((HAL_GetTick() - tickstart) > Timeout))
1071           {
1072             /* Device is ready */
1073             hsmbus->State = HAL_SMBUS_STATE_READY;
1074 
1075             /* Process Unlocked */
1076             __HAL_UNLOCK(hsmbus);
1077             return HAL_TIMEOUT;
1078           }
1079         }
1080       }
1081 
1082       /* Check if the NACKF flag has not been set */
1083       if (__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_AF) == RESET)
1084       {
1085         /* Wait until STOPF flag is reset */
1086         if (SMBUS_WaitOnFlagUntilTimeout(hsmbus, SMBUS_FLAG_STOPF, RESET, Timeout) != HAL_OK)
1087         {
1088           return HAL_TIMEOUT;
1089         }
1090 
1091         /* Clear STOP Flag */
1092         __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_STOPF);
1093 
1094         /* Device is ready */
1095         hsmbus->State = HAL_SMBUS_STATE_READY;
1096 
1097         /* Process Unlocked */
1098         __HAL_UNLOCK(hsmbus);
1099 
1100         return HAL_OK;
1101       }
1102       else
1103       {
1104         /* Wait until STOPF flag is reset */
1105         if (SMBUS_WaitOnFlagUntilTimeout(hsmbus, SMBUS_FLAG_STOPF, RESET, Timeout) != HAL_OK)
1106         {
1107           return HAL_TIMEOUT;
1108         }
1109 
1110         /* Clear NACK Flag */
1111         __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_AF);
1112 
1113         /* Clear STOP Flag, auto generated with autoend*/
1114         __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_STOPF);
1115       }
1116 
1117       /* Check if the maximum allowed number of trials has been reached */
1118       if (SMBUS_Trials++ == Trials)
1119       {
1120         /* Generate Stop */
1121         hsmbus->Instance->CR2 |= I2C_CR2_STOP;
1122 
1123         /* Wait until STOPF flag is reset */
1124         if (SMBUS_WaitOnFlagUntilTimeout(hsmbus, SMBUS_FLAG_STOPF, RESET, Timeout) != HAL_OK)
1125         {
1126           return HAL_TIMEOUT;
1127         }
1128 
1129         /* Clear STOP Flag */
1130         __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_STOPF);
1131       }
1132     }
1133     while (SMBUS_Trials < Trials);
1134 
1135     hsmbus->State = HAL_SMBUS_STATE_READY;
1136 
1137     /* Process Unlocked */
1138     __HAL_UNLOCK(hsmbus);
1139 
1140     return HAL_TIMEOUT;
1141   }
1142   else
1143   {
1144     return HAL_BUSY;
1145   }
1146 }
1147 /**
1148   * @}
1149   */
1150 
1151 /** @defgroup SMBUS_IRQ_Handler_and_Callbacks IRQ Handler and Callbacks
1152  * @{
1153  */
1154 
1155 /**
1156   * @brief  Handle SMBUS event interrupt request.
1157   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1158   *                the configuration information for the specified SMBUS.
1159   * @retval None
1160   */
HAL_SMBUS_EV_IRQHandler(SMBUS_HandleTypeDef * hsmbus)1161 void HAL_SMBUS_EV_IRQHandler(SMBUS_HandleTypeDef *hsmbus)
1162 {
1163   uint32_t tmpisrvalue = 0U;
1164 
1165   /* Use a local variable to store the current ISR flags */
1166   /* This action will avoid a wrong treatment due to ISR flags change during interrupt handler */
1167   tmpisrvalue = SMBUS_GET_ISR_REG(hsmbus);
1168 
1169   /* SMBUS in mode Transmitter ---------------------------------------------------*/
1170   if (((SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_TXIS) != RESET) || (SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_TCR) != RESET) || (SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_TC) != RESET) || (SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_STOPF) != RESET) || (SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_AF) != RESET)) && (__HAL_SMBUS_GET_IT_SOURCE(hsmbus, (SMBUS_IT_TCI | SMBUS_IT_STOPI | SMBUS_IT_NACKI | SMBUS_IT_TXI)) != RESET))
1171   {
1172     /* Slave mode selected */
1173     if ((hsmbus->State & HAL_SMBUS_STATE_SLAVE_BUSY_TX) == HAL_SMBUS_STATE_SLAVE_BUSY_TX)
1174     {
1175       SMBUS_Slave_ISR(hsmbus);
1176     }
1177     /* Master mode selected */
1178     else if ((hsmbus->State & HAL_SMBUS_STATE_MASTER_BUSY_TX) == HAL_SMBUS_STATE_MASTER_BUSY_TX)
1179     {
1180       SMBUS_Master_ISR(hsmbus);
1181     }
1182   }
1183 
1184   /* SMBUS in mode Receiver ----------------------------------------------------*/
1185   if (((SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_RXNE) != RESET) || (SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_TCR) != RESET) || (SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_TC) != RESET) || (SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_STOPF) != RESET) || (SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_AF) != RESET)) && (__HAL_SMBUS_GET_IT_SOURCE(hsmbus, (SMBUS_IT_TCI | SMBUS_IT_STOPI | SMBUS_IT_NACKI | SMBUS_IT_RXI)) != RESET))
1186   {
1187     /* Slave mode selected */
1188     if ((hsmbus->State & HAL_SMBUS_STATE_SLAVE_BUSY_RX) == HAL_SMBUS_STATE_SLAVE_BUSY_RX)
1189     {
1190       SMBUS_Slave_ISR(hsmbus);
1191     }
1192     /* Master mode selected */
1193     else if ((hsmbus->State & HAL_SMBUS_STATE_MASTER_BUSY_RX) == HAL_SMBUS_STATE_MASTER_BUSY_RX)
1194     {
1195       SMBUS_Master_ISR(hsmbus);
1196     }
1197   }
1198 
1199   /* SMBUS in mode Listener Only --------------------------------------------------*/
1200   if (((SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_ADDR) != RESET) || (SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_STOPF) != RESET) || (SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_AF) != RESET))
1201       && ((__HAL_SMBUS_GET_IT_SOURCE(hsmbus, SMBUS_IT_ADDRI) != RESET) || (__HAL_SMBUS_GET_IT_SOURCE(hsmbus, SMBUS_IT_STOPI) != RESET) || (__HAL_SMBUS_GET_IT_SOURCE(hsmbus, SMBUS_IT_NACKI) != RESET)))
1202   {
1203     if (hsmbus->State == HAL_SMBUS_STATE_LISTEN)
1204     {
1205       SMBUS_Slave_ISR(hsmbus);
1206     }
1207   }
1208 }
1209 
1210 /**
1211   * @brief  Handle SMBUS error interrupt request.
1212   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1213   *                the configuration information for the specified SMBUS.
1214   * @retval None
1215   */
HAL_SMBUS_ER_IRQHandler(SMBUS_HandleTypeDef * hsmbus)1216 void HAL_SMBUS_ER_IRQHandler(SMBUS_HandleTypeDef *hsmbus)
1217 {
1218   SMBUS_ITErrorHandler(hsmbus);
1219 }
1220 
1221 /**
1222   * @brief  Master Tx Transfer completed callback.
1223   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1224   *                the configuration information for the specified SMBUS.
1225   * @retval None
1226   */
HAL_SMBUS_MasterTxCpltCallback(SMBUS_HandleTypeDef * hsmbus)1227 __weak void HAL_SMBUS_MasterTxCpltCallback(SMBUS_HandleTypeDef *hsmbus)
1228 {
1229   /* Prevent unused argument(s) compilation warning */
1230   UNUSED(hsmbus);
1231 
1232   /* NOTE : This function should not be modified, when the callback is needed,
1233             the HAL_SMBUS_MasterTxCpltCallback() could be implemented in the user file
1234    */
1235 }
1236 
1237 /**
1238   * @brief  Master Rx Transfer completed callback.
1239   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1240   *                the configuration information for the specified SMBUS.
1241   * @retval None
1242   */
HAL_SMBUS_MasterRxCpltCallback(SMBUS_HandleTypeDef * hsmbus)1243 __weak void HAL_SMBUS_MasterRxCpltCallback(SMBUS_HandleTypeDef *hsmbus)
1244 {
1245   /* Prevent unused argument(s) compilation warning */
1246   UNUSED(hsmbus);
1247 
1248   /* NOTE : This function should not be modified, when the callback is needed,
1249             the HAL_SMBUS_MasterRxCpltCallback() could be implemented in the user file
1250    */
1251 }
1252 
1253 /** @brief  Slave Tx Transfer completed callback.
1254   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1255   *                the configuration information for the specified SMBUS.
1256   * @retval None
1257   */
HAL_SMBUS_SlaveTxCpltCallback(SMBUS_HandleTypeDef * hsmbus)1258 __weak void HAL_SMBUS_SlaveTxCpltCallback(SMBUS_HandleTypeDef *hsmbus)
1259 {
1260   /* Prevent unused argument(s) compilation warning */
1261   UNUSED(hsmbus);
1262 
1263   /* NOTE : This function should not be modified, when the callback is needed,
1264             the HAL_SMBUS_SlaveTxCpltCallback() could be implemented in the user file
1265    */
1266 }
1267 
1268 /**
1269   * @brief  Slave Rx Transfer completed callback.
1270   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1271   *                the configuration information for the specified SMBUS.
1272   * @retval None
1273   */
HAL_SMBUS_SlaveRxCpltCallback(SMBUS_HandleTypeDef * hsmbus)1274 __weak void HAL_SMBUS_SlaveRxCpltCallback(SMBUS_HandleTypeDef *hsmbus)
1275 {
1276   /* Prevent unused argument(s) compilation warning */
1277   UNUSED(hsmbus);
1278 
1279   /* NOTE : This function should not be modified, when the callback is needed,
1280             the HAL_SMBUS_SlaveRxCpltCallback() could be implemented in the user file
1281    */
1282 }
1283 
1284 /**
1285   * @brief  Slave Address Match callback.
1286   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1287   *                the configuration information for the specified SMBUS.
1288   * @param  TransferDirection Master request Transfer Direction (Write/Read)
1289   * @param  AddrMatchCode Address Match Code
1290   * @retval None
1291   */
HAL_SMBUS_AddrCallback(SMBUS_HandleTypeDef * hsmbus,uint8_t TransferDirection,uint16_t AddrMatchCode)1292 __weak void HAL_SMBUS_AddrCallback(SMBUS_HandleTypeDef *hsmbus, uint8_t TransferDirection, uint16_t AddrMatchCode)
1293 {
1294   /* Prevent unused argument(s) compilation warning */
1295   UNUSED(hsmbus);
1296   UNUSED(TransferDirection);
1297   UNUSED(AddrMatchCode);
1298 
1299   /* NOTE : This function should not be modified, when the callback is needed,
1300             the HAL_SMBUS_AddrCallback() could be implemented in the user file
1301    */
1302 }
1303 
1304 /**
1305   * @brief  Listen Complete callback.
1306   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1307   *                the configuration information for the specified SMBUS.
1308   * @retval None
1309   */
HAL_SMBUS_ListenCpltCallback(SMBUS_HandleTypeDef * hsmbus)1310 __weak void HAL_SMBUS_ListenCpltCallback(SMBUS_HandleTypeDef *hsmbus)
1311 {
1312   /* Prevent unused argument(s) compilation warning */
1313   UNUSED(hsmbus);
1314 
1315   /* NOTE : This function should not be modified, when the callback is needed,
1316             the HAL_SMBUS_ListenCpltCallback() could be implemented in the user file
1317    */
1318 }
1319 
1320 /**
1321   * @brief  SMBUS error callback.
1322   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1323   *                the configuration information for the specified SMBUS.
1324   * @retval None
1325   */
HAL_SMBUS_ErrorCallback(SMBUS_HandleTypeDef * hsmbus)1326 __weak void HAL_SMBUS_ErrorCallback(SMBUS_HandleTypeDef *hsmbus)
1327 {
1328   /* Prevent unused argument(s) compilation warning */
1329   UNUSED(hsmbus);
1330 
1331   /* NOTE : This function should not be modified, when the callback is needed,
1332             the HAL_SMBUS_ErrorCallback() could be implemented in the user file
1333    */
1334 }
1335 
1336 /**
1337   * @}
1338   */
1339 
1340 /** @defgroup SMBUS_Exported_Functions_Group3 Peripheral State and Errors functions
1341  *  @brief   Peripheral State and Errors functions
1342  *
1343 @verbatim
1344  ===============================================================================
1345             ##### Peripheral State and Errors functions #####
1346  ===============================================================================
1347     [..]
1348     This subsection permits to get in run-time the status of the peripheral
1349     and the data flow.
1350 
1351 @endverbatim
1352   * @{
1353   */
1354 
1355 /**
1356   * @brief  Return the SMBUS handle state.
1357   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1358   *                the configuration information for the specified SMBUS.
1359   * @retval HAL state
1360   */
HAL_SMBUS_GetState(SMBUS_HandleTypeDef * hsmbus)1361 uint32_t HAL_SMBUS_GetState(SMBUS_HandleTypeDef *hsmbus)
1362 {
1363   /* Return SMBUS handle state */
1364   return hsmbus->State;
1365 }
1366 
1367 /**
1368 * @brief  Return the SMBUS error code.
1369   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1370   *              the configuration information for the specified SMBUS.
1371 * @retval SMBUS Error Code
1372 */
HAL_SMBUS_GetError(SMBUS_HandleTypeDef * hsmbus)1373 uint32_t HAL_SMBUS_GetError(SMBUS_HandleTypeDef *hsmbus)
1374 {
1375   return hsmbus->ErrorCode;
1376 }
1377 
1378 /**
1379   * @}
1380   */
1381 
1382 /**
1383   * @}
1384   */
1385 
1386 /** @addtogroup SMBUS_Private_Functions SMBUS Private Functions
1387  *  @brief   Data transfers Private functions
1388   * @{
1389   */
1390 
1391 /**
1392   * @brief  Interrupt Sub-Routine which handle the Interrupt Flags Master Mode.
1393   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1394   *                the configuration information for the specified SMBUS.
1395   * @retval HAL status
1396   */
SMBUS_Master_ISR(SMBUS_HandleTypeDef * hsmbus)1397 static HAL_StatusTypeDef SMBUS_Master_ISR(SMBUS_HandleTypeDef *hsmbus)
1398 {
1399   uint16_t DevAddress;
1400 
1401   /* Process Locked */
1402   __HAL_LOCK(hsmbus);
1403 
1404   if (__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_AF) != RESET)
1405   {
1406     /* Clear NACK Flag */
1407     __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_AF);
1408 
1409     /* Set corresponding Error Code */
1410     /* No need to generate STOP, it is automatically done */
1411     hsmbus->ErrorCode |= HAL_SMBUS_ERROR_ACKF;
1412 
1413     /* Process Unlocked */
1414     __HAL_UNLOCK(hsmbus);
1415 
1416     /* Call the Error callback to inform upper layer */
1417     HAL_SMBUS_ErrorCallback(hsmbus);
1418   }
1419   else if (__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_STOPF) != RESET)
1420   {
1421     /* Check and treat errors if errors occurs during STOP process */
1422     SMBUS_ITErrorHandler(hsmbus);
1423 
1424     /* Call the corresponding callback to inform upper layer of End of Transfer */
1425     if (hsmbus->State == HAL_SMBUS_STATE_MASTER_BUSY_TX)
1426     {
1427       /* Disable Interrupt */
1428       SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_TX);
1429 
1430       /* Clear STOP Flag */
1431       __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_STOPF);
1432 
1433       /* Clear Configuration Register 2 */
1434       SMBUS_RESET_CR2(hsmbus);
1435 
1436       /* Flush remaining data in Fifo register in case of error occurs before TXEmpty */
1437       /* Disable the selected SMBUS peripheral */
1438       __HAL_SMBUS_DISABLE(hsmbus);
1439 
1440       hsmbus->PreviousState = HAL_SMBUS_STATE_READY;
1441       hsmbus->State = HAL_SMBUS_STATE_READY;
1442 
1443       /* Process Unlocked */
1444       __HAL_UNLOCK(hsmbus);
1445 
1446       /* REenable the selected SMBUS peripheral */
1447       __HAL_SMBUS_ENABLE(hsmbus);
1448 
1449       HAL_SMBUS_MasterTxCpltCallback(hsmbus);
1450     }
1451     else if (hsmbus->State == HAL_SMBUS_STATE_MASTER_BUSY_RX)
1452     {
1453       /* Store Last receive data if any */
1454       if (__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_RXNE) != RESET)
1455       {
1456         /* Read data from RXDR */
1457         (*hsmbus->pBuffPtr++) = hsmbus->Instance->RXDR;
1458 
1459         if ((hsmbus->XferSize > 0U))
1460         {
1461           hsmbus->XferSize--;
1462           hsmbus->XferCount--;
1463         }
1464       }
1465 
1466       /* Disable Interrupt */
1467       SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_RX);
1468 
1469       /* Clear STOP Flag */
1470       __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_STOPF);
1471 
1472       /* Clear Configuration Register 2 */
1473       SMBUS_RESET_CR2(hsmbus);
1474 
1475       hsmbus->PreviousState = HAL_SMBUS_STATE_READY;
1476       hsmbus->State = HAL_SMBUS_STATE_READY;
1477 
1478       /* Process Unlocked */
1479       __HAL_UNLOCK(hsmbus);
1480 
1481       HAL_SMBUS_MasterRxCpltCallback(hsmbus);
1482     }
1483   }
1484   else if (__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_RXNE) != RESET)
1485   {
1486     /* Read data from RXDR */
1487     (*hsmbus->pBuffPtr++) = hsmbus->Instance->RXDR;
1488     hsmbus->XferSize--;
1489     hsmbus->XferCount--;
1490   }
1491   else if (__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_TXIS) != RESET)
1492   {
1493     /* Write data to TXDR */
1494     hsmbus->Instance->TXDR = (*hsmbus->pBuffPtr++);
1495     hsmbus->XferSize--;
1496     hsmbus->XferCount--;
1497   }
1498   else if (__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_TCR) != RESET)
1499   {
1500     if ((hsmbus->XferSize == 0U) && (hsmbus->XferCount != 0U))
1501     {
1502       DevAddress = (hsmbus->Instance->CR2 & I2C_CR2_SADD);
1503 
1504       if (hsmbus->XferCount > MAX_NBYTE_SIZE)
1505       {
1506         SMBUS_TransferConfig(hsmbus, DevAddress, MAX_NBYTE_SIZE, (SMBUS_RELOAD_MODE | (hsmbus->XferOptions & SMBUS_SENDPEC_MODE)), SMBUS_NO_STARTSTOP);
1507         hsmbus->XferSize = MAX_NBYTE_SIZE;
1508       }
1509       else
1510       {
1511         hsmbus->XferSize = hsmbus->XferCount;
1512         SMBUS_TransferConfig(hsmbus, DevAddress, hsmbus->XferSize, hsmbus->XferOptions, SMBUS_NO_STARTSTOP);
1513         /* If PEC mode is enable, size to transmit should be Size-1 byte, corresponding to PEC byte */
1514         /* PEC byte is automatically sent by HW block, no need to manage it in Transmit process */
1515         if (SMBUS_GET_PEC_MODE(hsmbus) != RESET)
1516         {
1517           hsmbus->XferSize--;
1518           hsmbus->XferCount--;
1519         }
1520       }
1521     }
1522     else if ((hsmbus->XferSize == 0U) && (hsmbus->XferCount == 0U))
1523     {
1524       /* Call TxCpltCallback() if no stop mode is set */
1525       if (SMBUS_GET_STOP_MODE(hsmbus) != SMBUS_AUTOEND_MODE)
1526       {
1527         /* Call the corresponding callback to inform upper layer of End of Transfer */
1528         if (hsmbus->State == HAL_SMBUS_STATE_MASTER_BUSY_TX)
1529         {
1530           /* Disable Interrupt */
1531           SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_TX);
1532           hsmbus->PreviousState = hsmbus->State;
1533           hsmbus->State = HAL_SMBUS_STATE_READY;
1534 
1535           /* Process Unlocked */
1536           __HAL_UNLOCK(hsmbus);
1537 
1538           HAL_SMBUS_MasterTxCpltCallback(hsmbus);
1539         }
1540         else if (hsmbus->State == HAL_SMBUS_STATE_MASTER_BUSY_RX)
1541         {
1542           SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_RX);
1543           hsmbus->PreviousState = hsmbus->State;
1544           hsmbus->State = HAL_SMBUS_STATE_READY;
1545 
1546           /* Process Unlocked */
1547           __HAL_UNLOCK(hsmbus);
1548 
1549           HAL_SMBUS_MasterRxCpltCallback(hsmbus);
1550         }
1551       }
1552     }
1553   }
1554   else if (__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_TC) != RESET)
1555   {
1556     if (hsmbus->XferCount == 0U)
1557     {
1558       /* Specific use case for Quick command */
1559       if (hsmbus->pBuffPtr == NULL)
1560       {
1561         /* Generate a Stop command */
1562         hsmbus->Instance->CR2 |= I2C_CR2_STOP;
1563       }
1564       /* Call TxCpltCallback() if no stop mode is set */
1565       else if (SMBUS_GET_STOP_MODE(hsmbus) != SMBUS_AUTOEND_MODE)
1566       {
1567         /* No Generate Stop, to permit restart mode */
1568         /* The stop will be done at the end of transfer, when SMBUS_AUTOEND_MODE enable */
1569 
1570         /* Call the corresponding callback to inform upper layer of End of Transfer */
1571         if (hsmbus->State == HAL_SMBUS_STATE_MASTER_BUSY_TX)
1572         {
1573           /* Disable Interrupt */
1574           SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_TX);
1575           hsmbus->PreviousState = hsmbus->State;
1576           hsmbus->State = HAL_SMBUS_STATE_READY;
1577 
1578           /* Process Unlocked */
1579           __HAL_UNLOCK(hsmbus);
1580 
1581           HAL_SMBUS_MasterTxCpltCallback(hsmbus);
1582         }
1583         else if (hsmbus->State == HAL_SMBUS_STATE_MASTER_BUSY_RX)
1584         {
1585           SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_RX);
1586           hsmbus->PreviousState = hsmbus->State;
1587           hsmbus->State = HAL_SMBUS_STATE_READY;
1588 
1589           /* Process Unlocked */
1590           __HAL_UNLOCK(hsmbus);
1591 
1592           HAL_SMBUS_MasterRxCpltCallback(hsmbus);
1593         }
1594       }
1595     }
1596   }
1597 
1598   /* Process Unlocked */
1599   __HAL_UNLOCK(hsmbus);
1600 
1601   return HAL_OK;
1602 }
1603 /**
1604   * @brief  Interrupt Sub-Routine which handle the Interrupt Flags Slave Mode.
1605   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1606   *                the configuration information for the specified SMBUS.
1607   * @retval HAL status
1608   */
SMBUS_Slave_ISR(SMBUS_HandleTypeDef * hsmbus)1609 static HAL_StatusTypeDef SMBUS_Slave_ISR(SMBUS_HandleTypeDef *hsmbus)
1610 {
1611   uint8_t TransferDirection = 0U;
1612   uint16_t SlaveAddrCode = 0U;
1613 
1614   /* Process Locked */
1615   __HAL_LOCK(hsmbus);
1616 
1617   if (__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_AF) != RESET)
1618   {
1619     /* Check that SMBUS transfer finished */
1620     /* if yes, normal usecase, a NACK is sent by the HOST when Transfer is finished */
1621     /* Mean XferCount == 0*/
1622     /* So clear Flag NACKF only */
1623     if (hsmbus->XferCount == 0U)
1624     {
1625       /* Clear NACK Flag */
1626       __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_AF);
1627 
1628       /* Process Unlocked */
1629       __HAL_UNLOCK(hsmbus);
1630     }
1631     else
1632     {
1633       /* if no, error usecase, a Non-Acknowledge of last Data is generated by the HOST*/
1634       /* Clear NACK Flag */
1635       __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_AF);
1636 
1637       /* Set HAL State to "Idle" State, mean to LISTEN state */
1638       /* So reset Slave Busy state */
1639       hsmbus->PreviousState = hsmbus->State;
1640       hsmbus->State &= ~((uint32_t)HAL_SMBUS_STATE_SLAVE_BUSY_TX);
1641       hsmbus->State &= ~((uint32_t)HAL_SMBUS_STATE_SLAVE_BUSY_RX);
1642 
1643       /* Disable RX/TX Interrupts, keep only ADDR Interrupt */
1644       SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_RX | SMBUS_IT_TX);
1645 
1646       /* Set ErrorCode corresponding to a Non-Acknowledge */
1647       hsmbus->ErrorCode |= HAL_SMBUS_ERROR_ACKF;
1648 
1649       /* Process Unlocked */
1650       __HAL_UNLOCK(hsmbus);
1651 
1652       /* Call the Error callback to inform upper layer */
1653       HAL_SMBUS_ErrorCallback(hsmbus);
1654     }
1655   }
1656   else if (__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_ADDR) != RESET)
1657   {
1658     TransferDirection = SMBUS_GET_DIR(hsmbus);
1659     SlaveAddrCode = SMBUS_GET_ADDR_MATCH(hsmbus);
1660 
1661     /* Disable ADDR interrupt to prevent multiple ADDRInterrupt*/
1662     /* Other ADDRInterrupt will be treat in next Listen usecase */
1663     __HAL_SMBUS_DISABLE_IT(hsmbus, SMBUS_IT_ADDRI);
1664 
1665     /* Process Unlocked */
1666     __HAL_UNLOCK(hsmbus);
1667 
1668     /* Call Slave Addr callback */
1669     HAL_SMBUS_AddrCallback(hsmbus, TransferDirection, SlaveAddrCode);
1670   }
1671   else if ((__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_RXNE) != RESET) || (__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_TCR) != RESET))
1672   {
1673     if ((hsmbus->State & HAL_SMBUS_STATE_SLAVE_BUSY_RX) == HAL_SMBUS_STATE_SLAVE_BUSY_RX)
1674     {
1675       /* Read data from RXDR */
1676       (*hsmbus->pBuffPtr++) = hsmbus->Instance->RXDR;
1677       hsmbus->XferSize--;
1678       hsmbus->XferCount--;
1679 
1680       if (hsmbus->XferCount == 1U)
1681       {
1682         /* Receive last Byte, can be PEC byte in case of PEC BYTE enabled */
1683         /* or only the last Byte of Transfer */
1684         /* So reset the RELOAD bit mode */
1685         hsmbus->XferOptions &= ~SMBUS_RELOAD_MODE;
1686         SMBUS_TransferConfig(hsmbus, 0U, 1U, hsmbus->XferOptions, SMBUS_NO_STARTSTOP);
1687       }
1688       else if (hsmbus->XferCount == 0U)
1689       {
1690         /* Last Byte is received, disable Interrupt */
1691         SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_RX);
1692 
1693         /* Remove HAL_SMBUS_STATE_SLAVE_BUSY_RX, keep only HAL_SMBUS_STATE_LISTEN */
1694         hsmbus->PreviousState = hsmbus->State;
1695         hsmbus->State &= ~((uint32_t)HAL_SMBUS_STATE_SLAVE_BUSY_RX);
1696 
1697         /* Process Unlocked */
1698         __HAL_UNLOCK(hsmbus);
1699 
1700         /* Call the Rx complete callback to inform upper layer of the end of receive process */
1701         HAL_SMBUS_SlaveRxCpltCallback(hsmbus);
1702       }
1703       else
1704       {
1705         /* Set Reload for next Bytes */
1706         SMBUS_TransferConfig(hsmbus, 0U, 1U, SMBUS_RELOAD_MODE  | (hsmbus->XferOptions & SMBUS_SENDPEC_MODE), SMBUS_NO_STARTSTOP);
1707 
1708         /* Ack last Byte Read */
1709         hsmbus->Instance->CR2 &= ~I2C_CR2_NACK;
1710       }
1711     }
1712     else if ((hsmbus->State & HAL_SMBUS_STATE_SLAVE_BUSY_TX) == HAL_SMBUS_STATE_SLAVE_BUSY_TX)
1713     {
1714       if ((hsmbus->XferSize == 0U) && (hsmbus->XferCount != 0U))
1715       {
1716         if (hsmbus->XferCount > MAX_NBYTE_SIZE)
1717         {
1718           SMBUS_TransferConfig(hsmbus, 0U, MAX_NBYTE_SIZE, (SMBUS_RELOAD_MODE | (hsmbus->XferOptions & SMBUS_SENDPEC_MODE)), SMBUS_NO_STARTSTOP);
1719           hsmbus->XferSize = MAX_NBYTE_SIZE;
1720         }
1721         else
1722         {
1723           hsmbus->XferSize = hsmbus->XferCount;
1724           SMBUS_TransferConfig(hsmbus, 0U, hsmbus->XferSize, hsmbus->XferOptions, SMBUS_NO_STARTSTOP);
1725           /* If PEC mode is enable, size to transmit should be Size-1 byte, corresponding to PEC byte */
1726           /* PEC byte is automatically sent by HW block, no need to manage it in Transmit process */
1727           if (SMBUS_GET_PEC_MODE(hsmbus) != RESET)
1728           {
1729             hsmbus->XferSize--;
1730             hsmbus->XferCount--;
1731           }
1732         }
1733       }
1734     }
1735   }
1736   else if (__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_TXIS) != RESET)
1737   {
1738     /* Write data to TXDR only if XferCount not reach "0" */
1739     /* A TXIS flag can be set, during STOP treatment      */
1740     /* Check if all Data have already been sent */
1741     /* If it is the case, this last write in TXDR is not sent, correspond to a dummy TXIS event */
1742     if (hsmbus->XferCount > 0U)
1743     {
1744       /* Write data to TXDR */
1745       hsmbus->Instance->TXDR = (*hsmbus->pBuffPtr++);
1746       hsmbus->XferCount--;
1747       hsmbus->XferSize--;
1748     }
1749 
1750     if (hsmbus->XferCount == 0U)
1751     {
1752       /* Last Byte is Transmitted */
1753       /* Remove HAL_SMBUS_STATE_SLAVE_BUSY_TX, keep only HAL_SMBUS_STATE_LISTEN */
1754       SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_TX);
1755       hsmbus->PreviousState = hsmbus->State;
1756       hsmbus->State &= ~((uint32_t)HAL_SMBUS_STATE_SLAVE_BUSY_TX);
1757 
1758       /* Process Unlocked */
1759       __HAL_UNLOCK(hsmbus);
1760 
1761       /* Call the Tx complete callback to inform upper layer of the end of transmit process */
1762       HAL_SMBUS_SlaveTxCpltCallback(hsmbus);
1763     }
1764   }
1765 
1766   /* Check if STOPF is set */
1767   if (__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_STOPF) != RESET)
1768   {
1769     if ((hsmbus->State & HAL_SMBUS_STATE_LISTEN) == HAL_SMBUS_STATE_LISTEN)
1770     {
1771       /* Store Last receive data if any */
1772       if (__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_RXNE) != RESET)
1773       {
1774         /* Read data from RXDR */
1775         (*hsmbus->pBuffPtr++) = hsmbus->Instance->RXDR;
1776 
1777         if ((hsmbus->XferSize > 0U))
1778         {
1779           hsmbus->XferSize--;
1780           hsmbus->XferCount--;
1781         }
1782       }
1783 
1784       /* Disable RX and TX Interrupts */
1785       SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_RX | SMBUS_IT_TX);
1786 
1787       /* Disable ADDR Interrupt */
1788       SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_ADDR);
1789 
1790       /* Disable Address Acknowledge */
1791       hsmbus->Instance->CR2 |= I2C_CR2_NACK;
1792 
1793       /* Clear Configuration Register 2 */
1794       SMBUS_RESET_CR2(hsmbus);
1795 
1796       /* Clear STOP Flag */
1797       __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_STOPF);
1798 
1799       /* Clear ADDR flag */
1800       __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_ADDR);
1801 
1802       hsmbus->XferOptions = 0U;
1803       hsmbus->PreviousState = hsmbus->State;
1804       hsmbus->State = HAL_SMBUS_STATE_READY;
1805 
1806       /* Process Unlocked */
1807       __HAL_UNLOCK(hsmbus);
1808 
1809       /* Call the Listen Complete callback, to inform upper layer of the end of Listen usecase */
1810       HAL_SMBUS_ListenCpltCallback(hsmbus);
1811     }
1812   }
1813 
1814   /* Process Unlocked */
1815   __HAL_UNLOCK(hsmbus);
1816 
1817   return HAL_OK;
1818 }
1819 /**
1820   * @brief  Manage the enabling of Interrupts.
1821   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1822   *                the configuration information for the specified SMBUS.
1823   * @param  InterruptRequest Value of @ref SMBUS_Interrupt_configuration_definition.
1824   * @retval HAL status
1825   */
SMBUS_Enable_IRQ(SMBUS_HandleTypeDef * hsmbus,uint16_t InterruptRequest)1826 static HAL_StatusTypeDef SMBUS_Enable_IRQ(SMBUS_HandleTypeDef *hsmbus, uint16_t InterruptRequest)
1827 {
1828   uint32_t tmpisr = 0U;
1829 
1830   if ((InterruptRequest & SMBUS_IT_ALERT) == SMBUS_IT_ALERT)
1831   {
1832     /* Enable ERR interrupt */
1833     tmpisr |= SMBUS_IT_ERRI;
1834   }
1835 
1836   if ((InterruptRequest & SMBUS_IT_ADDR) == SMBUS_IT_ADDR)
1837   {
1838     /* Enable ADDR, STOP interrupt */
1839     tmpisr |= SMBUS_IT_ADDRI | SMBUS_IT_STOPI | SMBUS_IT_NACKI | SMBUS_IT_ERRI;
1840   }
1841 
1842   if ((InterruptRequest & SMBUS_IT_TX) == SMBUS_IT_TX)
1843   {
1844     /* Enable ERR, TC, STOP, NACK, RXI interrupt */
1845     tmpisr |= SMBUS_IT_ERRI | SMBUS_IT_TCI | SMBUS_IT_STOPI | SMBUS_IT_NACKI | SMBUS_IT_TXI;
1846   }
1847 
1848   if ((InterruptRequest & SMBUS_IT_RX) == SMBUS_IT_RX)
1849   {
1850     /* Enable ERR, TC, STOP, NACK, TXI interrupt */
1851     tmpisr |= SMBUS_IT_ERRI | SMBUS_IT_TCI | SMBUS_IT_STOPI | SMBUS_IT_NACKI | SMBUS_IT_RXI;
1852   }
1853 
1854   /* Enable interrupts only at the end */
1855   /* to avoid the risk of SMBUS interrupt handle execution before */
1856   /* all interrupts requested done */
1857   __HAL_SMBUS_ENABLE_IT(hsmbus, tmpisr);
1858 
1859   return HAL_OK;
1860 }
1861 /**
1862   * @brief  Manage the disabling of Interrupts.
1863   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1864   *                the configuration information for the specified SMBUS.
1865   * @param  InterruptRequest Value of @ref SMBUS_Interrupt_configuration_definition.
1866   * @retval HAL status
1867   */
SMBUS_Disable_IRQ(SMBUS_HandleTypeDef * hsmbus,uint16_t InterruptRequest)1868 static HAL_StatusTypeDef SMBUS_Disable_IRQ(SMBUS_HandleTypeDef *hsmbus, uint16_t InterruptRequest)
1869 {
1870   uint32_t tmpisr = 0U;
1871 
1872   if (((InterruptRequest & SMBUS_IT_ALERT) == SMBUS_IT_ALERT) && (hsmbus->State == HAL_SMBUS_STATE_READY))
1873   {
1874     /* Disable ERR interrupt */
1875     tmpisr |= SMBUS_IT_ERRI;
1876   }
1877 
1878   if ((InterruptRequest & SMBUS_IT_TX) == SMBUS_IT_TX)
1879   {
1880     /* Disable TC, STOP, NACK, TXI interrupt */
1881     tmpisr |= SMBUS_IT_TCI | SMBUS_IT_TXI;
1882 
1883     if ((SMBUS_GET_ALERT_ENABLED(hsmbus) == RESET)
1884         && ((hsmbus->State & HAL_SMBUS_STATE_LISTEN) != HAL_SMBUS_STATE_LISTEN))
1885     {
1886       /* Disable ERR interrupt */
1887       tmpisr |= SMBUS_IT_ERRI;
1888     }
1889 
1890     if ((hsmbus->State & HAL_SMBUS_STATE_LISTEN) != HAL_SMBUS_STATE_LISTEN)
1891     {
1892       /* Disable STOPI, NACKI */
1893       tmpisr |= SMBUS_IT_STOPI | SMBUS_IT_NACKI;
1894     }
1895   }
1896 
1897   if ((InterruptRequest & SMBUS_IT_RX) == SMBUS_IT_RX)
1898   {
1899     /* Disable TC, STOP, NACK, RXI interrupt */
1900     tmpisr |= SMBUS_IT_TCI | SMBUS_IT_RXI;
1901 
1902     if ((SMBUS_GET_ALERT_ENABLED(hsmbus) == RESET)
1903         && ((hsmbus->State & HAL_SMBUS_STATE_LISTEN) != HAL_SMBUS_STATE_LISTEN))
1904     {
1905       /* Disable ERR interrupt */
1906       tmpisr |= SMBUS_IT_ERRI;
1907     }
1908 
1909     if ((hsmbus->State & HAL_SMBUS_STATE_LISTEN) != HAL_SMBUS_STATE_LISTEN)
1910     {
1911       /* Disable STOPI, NACKI */
1912       tmpisr |= SMBUS_IT_STOPI | SMBUS_IT_NACKI;
1913     }
1914   }
1915 
1916   if ((InterruptRequest & SMBUS_IT_ADDR) == SMBUS_IT_ADDR)
1917   {
1918     /* Enable ADDR, STOP interrupt */
1919     tmpisr |= SMBUS_IT_ADDRI | SMBUS_IT_STOPI | SMBUS_IT_NACKI;
1920 
1921     if (SMBUS_GET_ALERT_ENABLED(hsmbus) == RESET)
1922     {
1923       /* Disable ERR interrupt */
1924       tmpisr |= SMBUS_IT_ERRI;
1925     }
1926   }
1927 
1928   /* Disable interrupts only at the end */
1929   /* to avoid a breaking situation like at "t" time */
1930   /* all disable interrupts request are not done */
1931   __HAL_SMBUS_DISABLE_IT(hsmbus, tmpisr);
1932 
1933   return HAL_OK;
1934 }
1935 
1936 /**
1937   * @brief  SMBUS interrupts error handler.
1938   * @param  hsmbus SMBUS handle.
1939   * @retval None
1940   */
SMBUS_ITErrorHandler(SMBUS_HandleTypeDef * hsmbus)1941 static void SMBUS_ITErrorHandler(SMBUS_HandleTypeDef *hsmbus)
1942 {
1943   uint32_t itflags   = READ_REG(hsmbus->Instance->ISR);
1944   uint32_t itsources = READ_REG(hsmbus->Instance->CR1);
1945 
1946   /* SMBUS Bus error interrupt occurred ------------------------------------*/
1947   if (((itflags & SMBUS_FLAG_BERR) != RESET) && ((itsources & SMBUS_IT_ERRI) != RESET))
1948   {
1949     hsmbus->ErrorCode |= HAL_SMBUS_ERROR_BERR;
1950 
1951     /* Clear BERR flag */
1952     __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_BERR);
1953   }
1954 
1955   /* SMBUS Over-Run/Under-Run interrupt occurred ----------------------------------------*/
1956   if (((itflags & SMBUS_FLAG_OVR) != RESET) && ((itsources & SMBUS_IT_ERRI) != RESET))
1957   {
1958     hsmbus->ErrorCode |= HAL_SMBUS_ERROR_OVR;
1959 
1960     /* Clear OVR flag */
1961     __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_OVR);
1962   }
1963 
1964   /* SMBUS Arbitration Loss error interrupt occurred ------------------------------------*/
1965   if (((itflags & SMBUS_FLAG_ARLO) != RESET) && ((itsources & SMBUS_IT_ERRI) != RESET))
1966   {
1967     hsmbus->ErrorCode |= HAL_SMBUS_ERROR_ARLO;
1968 
1969     /* Clear ARLO flag */
1970     __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_ARLO);
1971   }
1972 
1973   /* SMBUS Timeout error interrupt occurred ---------------------------------------------*/
1974   if (((itflags & SMBUS_FLAG_TIMEOUT) != RESET) && ((itsources & SMBUS_IT_ERRI) != RESET))
1975   {
1976     hsmbus->ErrorCode |= HAL_SMBUS_ERROR_BUSTIMEOUT;
1977 
1978     /* Clear TIMEOUT flag */
1979     __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_TIMEOUT);
1980   }
1981 
1982   /* SMBUS Alert error interrupt occurred -----------------------------------------------*/
1983   if (((itflags & SMBUS_FLAG_ALERT) != RESET) && ((itsources & SMBUS_IT_ERRI) != RESET))
1984   {
1985     hsmbus->ErrorCode |= HAL_SMBUS_ERROR_ALERT;
1986 
1987     /* Clear ALERT flag */
1988     __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_ALERT);
1989   }
1990 
1991   /* SMBUS Packet Error Check error interrupt occurred ----------------------------------*/
1992   if (((itflags & SMBUS_FLAG_PECERR) != RESET) && ((itsources & SMBUS_IT_ERRI) != RESET))
1993   {
1994     hsmbus->ErrorCode |= HAL_SMBUS_ERROR_PECERR;
1995 
1996     /* Clear PEC error flag */
1997     __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_PECERR);
1998   }
1999 
2000   /* Call the Error Callback in case of Error detected */
2001   if ((hsmbus->ErrorCode != HAL_SMBUS_ERROR_NONE) && (hsmbus->ErrorCode != HAL_SMBUS_ERROR_ACKF))
2002   {
2003     /* Do not Reset the HAL state in case of ALERT error */
2004     if ((hsmbus->ErrorCode & HAL_SMBUS_ERROR_ALERT) != HAL_SMBUS_ERROR_ALERT)
2005     {
2006       if (((hsmbus->State & HAL_SMBUS_STATE_SLAVE_BUSY_TX) == HAL_SMBUS_STATE_SLAVE_BUSY_TX)
2007           || ((hsmbus->State & HAL_SMBUS_STATE_SLAVE_BUSY_RX) == HAL_SMBUS_STATE_SLAVE_BUSY_RX))
2008       {
2009         /* Reset only HAL_SMBUS_STATE_SLAVE_BUSY_XX */
2010         /* keep HAL_SMBUS_STATE_LISTEN if set */
2011         hsmbus->PreviousState = HAL_SMBUS_STATE_READY;
2012         hsmbus->State = HAL_SMBUS_STATE_LISTEN;
2013       }
2014     }
2015 
2016     /* Call the Error callback to inform upper layer */
2017     HAL_SMBUS_ErrorCallback(hsmbus);
2018   }
2019 }
2020 
2021 /**
2022   * @brief  Handle SMBUS Communication Timeout.
2023   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
2024   *                the configuration information for the specified SMBUS.
2025   * @param  Flag Specifies the SMBUS flag to check.
2026   * @param  Status The new Flag status (SET or RESET).
2027   * @param  Timeout Timeout duration
2028   * @retval HAL status
2029   */
SMBUS_WaitOnFlagUntilTimeout(SMBUS_HandleTypeDef * hsmbus,uint32_t Flag,FlagStatus Status,uint32_t Timeout)2030 static HAL_StatusTypeDef SMBUS_WaitOnFlagUntilTimeout(SMBUS_HandleTypeDef *hsmbus, uint32_t Flag, FlagStatus Status, uint32_t Timeout)
2031 {
2032   uint32_t tickstart = HAL_GetTick();
2033 
2034   /* Wait until flag is set */
2035   if (Status == RESET)
2036   {
2037     while (__HAL_SMBUS_GET_FLAG(hsmbus, Flag) == RESET)
2038     {
2039       /* Check for the Timeout */
2040       if (Timeout != HAL_MAX_DELAY)
2041       {
2042         if ((Timeout == 0U) || ((HAL_GetTick() - tickstart) > Timeout))
2043         {
2044           hsmbus->PreviousState = hsmbus->State;
2045           hsmbus->State = HAL_SMBUS_STATE_READY;
2046 
2047           /* Process Unlocked */
2048           __HAL_UNLOCK(hsmbus);
2049 
2050           return HAL_TIMEOUT;
2051         }
2052       }
2053     }
2054   }
2055   else
2056   {
2057     while (__HAL_SMBUS_GET_FLAG(hsmbus, Flag) != RESET)
2058     {
2059       /* Check for the Timeout */
2060       if (Timeout != HAL_MAX_DELAY)
2061       {
2062         if ((Timeout == 0U) || ((HAL_GetTick() - tickstart) > Timeout))
2063         {
2064           hsmbus->PreviousState = hsmbus->State;
2065           hsmbus->State = HAL_SMBUS_STATE_READY;
2066 
2067           /* Process Unlocked */
2068           __HAL_UNLOCK(hsmbus);
2069 
2070           return HAL_TIMEOUT;
2071         }
2072       }
2073     }
2074   }
2075   return HAL_OK;
2076 }
2077 
2078 /**
2079   * @brief  Handle SMBUSx communication when starting transfer or during transfer (TC or TCR flag are set).
2080   * @param  hsmbus SMBUS handle.
2081   * @param  DevAddress specifies the slave address to be programmed.
2082   * @param  Size specifies the number of bytes to be programmed.
2083   *   This parameter must be a value between 0 and 255.
2084   * @param  Mode New state of the SMBUS START condition generation.
2085   *   This parameter can be one or a combination  of the following values:
2086   *     @arg @ref SMBUS_RELOAD_MODE Enable Reload mode.
2087   *     @arg @ref SMBUS_AUTOEND_MODE Enable Automatic end mode.
2088   *     @arg @ref SMBUS_SOFTEND_MODE Enable Software end mode and Reload mode.
2089   *     @arg @ref SMBUS_SENDPEC_MODE Enable Packet Error Calculation mode.
2090   * @param  Request New state of the SMBUS START condition generation.
2091   *   This parameter can be one of the following values:
2092   *     @arg @ref SMBUS_NO_STARTSTOP Don't Generate stop and start condition.
2093   *     @arg @ref SMBUS_GENERATE_STOP Generate stop condition (Size should be set to 0).
2094   *     @arg @ref SMBUS_GENERATE_START_READ Generate Restart for read request.
2095   *     @arg @ref SMBUS_GENERATE_START_WRITE Generate Restart for write request.
2096   * @retval None
2097   */
SMBUS_TransferConfig(SMBUS_HandleTypeDef * hsmbus,uint16_t DevAddress,uint8_t Size,uint32_t Mode,uint32_t Request)2098 static void SMBUS_TransferConfig(SMBUS_HandleTypeDef *hsmbus,  uint16_t DevAddress, uint8_t Size, uint32_t Mode, uint32_t Request)
2099 {
2100   /* Check the parameters */
2101   assert_param(IS_SMBUS_INSTANCE(hsmbus->Instance));
2102   assert_param(IS_SMBUS_TRANSFER_MODE(Mode));
2103   assert_param(IS_SMBUS_TRANSFER_REQUEST(Request));
2104 
2105   /* update CR2 register */
2106   MODIFY_REG(hsmbus->Instance->CR2, ((I2C_CR2_SADD | I2C_CR2_NBYTES | I2C_CR2_RELOAD | I2C_CR2_AUTOEND | (I2C_CR2_RD_WRN & (uint32_t)(Request >> (31U - I2C_CR2_RD_WRN_Pos))) | I2C_CR2_START | I2C_CR2_STOP  | I2C_CR2_PECBYTE)), \
2107              (uint32_t)(((uint32_t)DevAddress & I2C_CR2_SADD) | (((uint32_t)Size << I2C_CR2_NBYTES_Pos) & I2C_CR2_NBYTES) | (uint32_t)Mode | (uint32_t)Request));
2108 }
2109 
2110 /**
2111   * @brief  Convert SMBUSx OTHER_xxx XferOptions to functionnal XferOptions.
2112   * @param  hsmbus SMBUS handle.
2113   * @retval None
2114   */
SMBUS_ConvertOtherXferOptions(SMBUS_HandleTypeDef * hsmbus)2115 static void SMBUS_ConvertOtherXferOptions(SMBUS_HandleTypeDef *hsmbus)
2116 {
2117   /* if user set XferOptions to SMBUS_OTHER_FRAME_NO_PEC   */
2118   /* it request implicitly to generate a restart condition */
2119   /* set XferOptions to SMBUS_FIRST_FRAME                  */
2120   if (hsmbus->XferOptions == SMBUS_OTHER_FRAME_NO_PEC)
2121   {
2122     hsmbus->XferOptions = SMBUS_FIRST_FRAME;
2123   }
2124   /* else if user set XferOptions to SMBUS_OTHER_FRAME_WITH_PEC */
2125   /* it request implicitly to generate a restart condition      */
2126   /* set XferOptions to SMBUS_FIRST_FRAME | SMBUS_SENDPEC_MODE  */
2127   else if (hsmbus->XferOptions == SMBUS_OTHER_FRAME_WITH_PEC)
2128   {
2129     hsmbus->XferOptions = SMBUS_FIRST_FRAME | SMBUS_SENDPEC_MODE;
2130   }
2131   /* else if user set XferOptions to SMBUS_OTHER_AND_LAST_FRAME_NO_PEC */
2132   /* it request implicitly to generate a restart condition             */
2133   /* then generate a stop condition at the end of transfer             */
2134   /* set XferOptions to SMBUS_FIRST_AND_LAST_FRAME_NO_PEC              */
2135   else if (hsmbus->XferOptions == SMBUS_OTHER_AND_LAST_FRAME_NO_PEC)
2136   {
2137     hsmbus->XferOptions = SMBUS_FIRST_AND_LAST_FRAME_NO_PEC;
2138   }
2139   /* else if user set XferOptions to SMBUS_OTHER_AND_LAST_FRAME_WITH_PEC */
2140   /* it request implicitly to generate a restart condition               */
2141   /* then generate a stop condition at the end of transfer               */
2142   /* set XferOptions to SMBUS_FIRST_AND_LAST_FRAME_WITH_PEC              */
2143   else if (hsmbus->XferOptions == SMBUS_OTHER_AND_LAST_FRAME_WITH_PEC)
2144   {
2145     hsmbus->XferOptions = SMBUS_FIRST_AND_LAST_FRAME_WITH_PEC;
2146   }
2147 }
2148 /**
2149   * @}
2150   */
2151 
2152 #endif /* HAL_SMBUS_MODULE_ENABLED */
2153 /**
2154   * @}
2155   */
2156 
2157 /**
2158   * @}
2159   */
2160 
2161 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
2162