2 ******************************************************************************
3 * @file stm32f0xx_hal_smbus.c
4 * @author MCD Application Team
6 * @date 11-December-2014
7 * @brief SMBUS HAL module driver.
9 * This file provides firmware functions to manage the following
10 * functionalities of the System Management Bus (SMBus) peripheral,
11 * based on I2C principales of operation :
12 * + Initialization and de-initialization functions
13 * + IO operation functions
14 * + Peripheral State and Errors functions
16 ==============================================================================
17 ##### How to use this driver #####
18 ==============================================================================
20 The SMBUS HAL driver can be used as follows:
22 (#) Declare a SMBUS_HandleTypeDef handle structure, for example:
23 SMBUS_HandleTypeDef hsmbus;
25 (#)Initialize the SMBUS low level resources by implement the HAL_SMBUS_MspInit ()API:
26 (##) Enable the SMBUSx interface clock
27 (##) SMBUS pins configuration
28 (+++) Enable the clock for the SMBUS GPIOs
29 (+++) Configure SMBUS pins as alternate function open-drain
30 (##) NVIC configuration if you need to use interrupt process
31 (+++) Configure the SMBUSx interrupt priority
32 (+++) Enable the NVIC SMBUS IRQ Channel
34 (#) Configure the Communication Clock Timing, Bus Timeout, Own Address1, Master Adressing Mode,
35 Dual Addressing mode, Own Address2, Own Address2 Mask, General call, Nostretch mode,
36 Peripheral mode and Packet Error Check mode in the hsmbus Init structure.
38 (#) Initialize the SMBUS registers by calling the HAL_SMBUS_Init() API:
39 (++) These API s configures also the low level Hardware GPIO, CLOCK, CORTEX...etc)
40 by calling the customed HAL_SMBUS_MspInit(&hsmbus) API.
42 (#) To check if target device is ready for communication, use the function HAL_SMBUS_IsDeviceReady()
44 (#) For SMBUS IO operations, only one mode of operations is available within this driver :
46 *** Interrupt mode IO operation ***
47 ===================================
49 (+) Transmit in master/host SMBUS mode an amount of data in non blocking mode using HAL_SMBUS_Master_Transmit_IT()
50 (++) At transmission end of transfer HAL_SMBUS_MasterTxCpltCallback is executed and user can
51 add his own code by customization of function pointer HAL_SMBUS_MasterTxCpltCallback
52 (+) Receive in master/host SMBUS mode an amount of data in non blocking mode using HAL_SMBUS_Master_Receive_IT()
53 (++) At reception end of transfer HAL_SMBUS_MasterRxCpltCallback is executed and user can
54 add his own code by customization of function pointer HAL_SMBUS_MasterRxCpltCallback
55 (+) Abort a master/host SMBUS process commnunication with Interrupt using HAL_SMBUS_Master_Abort_IT()
56 (++) The associated previous transfer callback is called at the end of abort process
57 (++) mean HAL_SMBUS_MasterTxCpltCallback in case of previous state was master transmit
58 (++) mean HAL_SMBUS_MasterRxCpltCallback in case of previous state was master receive
59 (+) Enable/disable the Address listen mode in slave/device or host/slave SMBUS mode
60 using HAL_SMBUS_Slave_Listen_IT() HAL_SMBUS_DisableListen_IT()
61 (++) When address slave/device SMBUS match, HAL_SMBUS_SlaveAddrCallback is executed and user can
62 add his own code to check the Address Match Code and the transmission direction request by master/host (Write/Read).
63 (++) At Listen mode end HAL_SMBUS_SlaveListenCpltCallback is executed and user can
64 add his own code by customization of function pointer HAL_SMBUS_SlaveListenCpltCallback
65 (+) Transmit in slave/device SMBUS mode an amount of data in non blocking mode using HAL_SMBUS_Slave_Transmit_IT()
66 (++) At transmission end of transfer HAL_SMBUS_SlaveTxCpltCallback is executed and user can
67 add his own code by customization of function pointer HAL_SMBUS_SlaveTxCpltCallback
68 (+) Receive in slave/device SMBUS mode an amount of data in non blocking mode using HAL_SMBUS_Slave_Receive_IT()
69 (++) At reception end of transfer HAL_SMBUS_SlaveRxCpltCallback is executed and user can
70 add his own code by customization of function pointer HAL_SMBUS_SlaveRxCpltCallback
71 (+) Enable/Disable the SMBUS alert mode using HAL_SMBUS_EnableAlert_IT() HAL_SMBUS_DisableAlert_IT()
72 (++) When SMBUS Alert is generated HAL_SMBUS_ErrorCallback() is executed and user can
73 add his own code by customization of function pointer HAL_SMBUS_ErrorCallback
74 to check the Alert Error Code using function HAL_SMBUS_GetError()
75 (+) Get HAL state machine or error values using HAL_SMBUS_GetState() or HAL_SMBUS_GetError()
76 (+) In case of transfer Error, HAL_SMBUS_ErrorCallback() function is executed and user can
77 add his own code by customization of function pointer HAL_SMBUS_ErrorCallback
78 to check the Error Code using function HAL_SMBUS_GetError()
80 *** SMBUS HAL driver macros list ***
81 ==================================
83 Below the list of most used macros in SMBUS HAL driver.
85 (+) __HAL_SMBUS_ENABLE: Enable the SMBUS peripheral
86 (+) __HAL_SMBUS_DISABLE: Disable the SMBUS peripheral
87 (+) __HAL_SMBUS_GET_FLAG : Checks whether the specified SMBUS flag is set or not
88 (+) __HAL_SMBUS_CLEAR_FLAG : Clears the specified SMBUS pending flag
89 (+) __HAL_SMBUS_ENABLE_IT: Enables the specified SMBUS interrupt
90 (+) __HAL_SMBUS_DISABLE_IT: Disables the specified SMBUS interrupt
93 (@) You can refer to the SMBUS HAL driver header file for more useful macros
97 ******************************************************************************
100 * <h2><center>© COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
102 * Redistribution and use in source and binary forms, with or without modification,
103 * are permitted provided that the following conditions are met:
104 * 1. Redistributions of source code must retain the above copyright notice,
105 * this list of conditions and the following disclaimer.
106 * 2. Redistributions in binary form must reproduce the above copyright notice,
107 * this list of conditions and the following disclaimer in the documentation
108 * and/or other materials provided with the distribution.
109 * 3. Neither the name of STMicroelectronics nor the names of its contributors
110 * may be used to endorse or promote products derived from this software
111 * without specific prior written permission.
113 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
114 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
115 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
116 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
117 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
118 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
119 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
120 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
121 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
122 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
124 ******************************************************************************
127 /* Includes ------------------------------------------------------------------*/
128 #include "stm32f0xx_hal.h"
130 /** @addtogroup STM32F0xx_HAL_Driver
134 /** @defgroup SMBUS SMBUS HAL module driver
135 * @brief SMBUS HAL module driver
139 #ifdef HAL_SMBUS_MODULE_ENABLED
141 /* Private typedef -----------------------------------------------------------*/
142 /* Private define ------------------------------------------------------------*/
143 /** @defgroup SMBUS_Private_Define SMBUS Private Define
146 #define TIMING_CLEAR_MASK ((uint32_t)0xF0FFFFFF) /*<! SMBUS TIMING clear register Mask */
147 #define HAL_TIMEOUT_ADDR ((uint32_t)10000) /* 10 s */
148 #define HAL_TIMEOUT_BUSY ((uint32_t)25) /* 25 ms */
149 #define HAL_TIMEOUT_DIR ((uint32_t)25) /* 25 ms */
150 #define HAL_TIMEOUT_RXNE ((uint32_t)25) /* 25 ms */
151 #define HAL_TIMEOUT_STOPF ((uint32_t)25) /* 25 ms */
152 #define HAL_TIMEOUT_TC ((uint32_t)25) /* 25 ms */
153 #define HAL_TIMEOUT_TCR ((uint32_t)25) /* 25 ms */
154 #define HAL_TIMEOUT_TXIS ((uint32_t)25) /* 25 ms */
155 #define MAX_NBYTE_SIZE 255
160 /* Private macro -------------------------------------------------------------*/
161 /** @defgroup SMBUS_Private_Macros SMBUS Private Macros
164 #define __SMBUS_GET_ISR_REG(__HANDLE__) ((__HANDLE__)->Instance->ISR)
165 #define __SMBUS_CHECK_FLAG(__ISR__, __FLAG__) ((((__ISR__) & ((__FLAG__) & SMBUS_FLAG_MASK)) == ((__FLAG__) & SMBUS_FLAG_MASK)))
170 /* Private variables ---------------------------------------------------------*/
171 /* Private function prototypes -----------------------------------------------*/
172 /** @defgroup SMBUS_Private_Functions SMBUS Private Functions
175 static HAL_StatusTypeDef SMBUS_WaitOnFlagUntilTimeout(SMBUS_HandleTypeDef *hsmbus, uint32_t Flag, FlagStatus Status, uint32_t Timeout);
177 static HAL_StatusTypeDef SMBUS_Enable_IRQ(SMBUS_HandleTypeDef *hsmbus, uint16_t InterruptRequest);
178 static HAL_StatusTypeDef SMBUS_Disable_IRQ(SMBUS_HandleTypeDef *hsmbus, uint16_t InterruptRequest);
179 static HAL_StatusTypeDef SMBUS_Master_ISR(SMBUS_HandleTypeDef *hsmbus);
180 static HAL_StatusTypeDef SMBUS_Slave_ISR(SMBUS_HandleTypeDef *hsmbus);
182 static void SMBUS_TransferConfig(SMBUS_HandleTypeDef *hsmbus, uint16_t DevAddress, uint8_t Size, uint32_t Mode, uint32_t Request);
187 /* Exported functions ---------------------------------------------------------*/
189 /** @defgroup SMBUS_Exported_Functions SMBUS Exported Functions
193 /** @defgroup SMBUS_Exported_Functions_Group1 Initialization and de-initialization functions
194 * @brief Initialization and Configuration functions
197 ===============================================================================
198 ##### Initialization and de-initialization functions #####
199 ===============================================================================
200 [..] This subsection provides a set of functions allowing to initialize and
201 de-initialiaze the SMBUSx peripheral:
203 (+) User must Implement HAL_SMBUS_MspInit() function in which he configures
204 all related peripherals resources (CLOCK, GPIO, IT and NVIC ).
206 (+) Call the function HAL_SMBUS_Init() to configure the selected device with
207 the selected configuration:
210 (++) Analog Filer mode
212 (++) Addressing mode (Master, Slave)
213 (++) Dual Addressing mode
215 (++) Own Address 2 Mask
216 (++) General call mode
218 (++) Packet Error Check mode
222 (+) Call the function HAL_SMBUS_DeInit() to restore the default configuration
223 of the selected SMBUSx periperal.
230 * @brief Initializes the SMBUS according to the specified parameters
231 * in the SMBUS_InitTypeDef and create the associated handle.
232 * @param hsmbus : Pointer to a SMBUS_HandleTypeDef structure that contains
233 * the configuration information for the specified SMBUS.
236 HAL_StatusTypeDef HAL_SMBUS_Init(SMBUS_HandleTypeDef *hsmbus)
238 /* Check the SMBUS handle allocation */
244 /* Check the parameters */
245 assert_param(IS_SMBUS_ALL_INSTANCE(hsmbus->Instance));
246 assert_param(IS_SMBUS_ANALOG_FILTER(hsmbus->Init.AnalogFilter));
247 assert_param(IS_SMBUS_OWN_ADDRESS1(hsmbus->Init.OwnAddress1));
248 assert_param(IS_SMBUS_ADDRESSING_MODE(hsmbus->Init.AddressingMode));
249 assert_param(IS_SMBUS_DUAL_ADDRESS(hsmbus->Init.DualAddressMode));
250 assert_param(IS_SMBUS_OWN_ADDRESS2(hsmbus->Init.OwnAddress2));
251 assert_param(IS_SMBUS_OWN_ADDRESS2_MASK(hsmbus->Init.OwnAddress2Masks));
252 assert_param(IS_SMBUS_GENERAL_CALL(hsmbus->Init.GeneralCallMode));
253 assert_param(IS_SMBUS_NO_STRETCH(hsmbus->Init.NoStretchMode));
254 assert_param(IS_SMBUS_PEC(hsmbus->Init.PacketErrorCheckMode));
255 assert_param(IS_SMBUS_PERIPHERAL_MODE(hsmbus->Init.PeripheralMode));
257 if(hsmbus->State == HAL_SMBUS_STATE_RESET)
259 /* Init the low level hardware : GPIO, CLOCK, NVIC */
260 HAL_SMBUS_MspInit(hsmbus);
263 hsmbus->State = HAL_SMBUS_STATE_BUSY;
265 /* Disable the selected SMBUS peripheral */
266 __HAL_SMBUS_DISABLE(hsmbus);
268 /*---------------------------- SMBUSx TIMINGR Configuration ------------------------*/
269 /* Configure SMBUSx: Frequency range */
270 hsmbus->Instance->TIMINGR = hsmbus->Init.Timing & TIMING_CLEAR_MASK;
272 /*---------------------------- SMBUSx TIMEOUTR Configuration ------------------------*/
273 /* Configure SMBUSx: Bus Timeout */
274 hsmbus->Instance->TIMEOUTR &= ~I2C_TIMEOUTR_TIMOUTEN;
275 hsmbus->Instance->TIMEOUTR &= ~I2C_TIMEOUTR_TEXTEN;
276 hsmbus->Instance->TIMEOUTR = hsmbus->Init.SMBusTimeout;
278 /*---------------------------- SMBUSx OAR1 Configuration -----------------------*/
279 /* Configure SMBUSx: Own Address1 and ack own address1 mode */
280 hsmbus->Instance->OAR1 &= ~I2C_OAR1_OA1EN;
282 if(hsmbus->Init.OwnAddress1 != 0)
284 if(hsmbus->Init.AddressingMode == SMBUS_ADDRESSINGMODE_7BIT)
286 hsmbus->Instance->OAR1 = (I2C_OAR1_OA1EN | hsmbus->Init.OwnAddress1);
288 else /* SMBUS_ADDRESSINGMODE_10BIT */
290 hsmbus->Instance->OAR1 = (I2C_OAR1_OA1EN | I2C_OAR1_OA1MODE | hsmbus->Init.OwnAddress1);
294 /*---------------------------- SMBUSx CR2 Configuration ------------------------*/
295 /* Configure SMBUSx: Addressing Master mode */
296 if(hsmbus->Init.AddressingMode == SMBUS_ADDRESSINGMODE_10BIT)
298 hsmbus->Instance->CR2 = (I2C_CR2_ADD10);
300 /* Enable the AUTOEND by default, and enable NACK (should be disable only during Slave process) */
301 /* AUTOEND and NACK bit will be manage during Transfer process */
302 hsmbus->Instance->CR2 |= (I2C_CR2_AUTOEND | I2C_CR2_NACK);
304 /*---------------------------- SMBUSx OAR2 Configuration -----------------------*/
305 /* Configure SMBUSx: Dual mode and Own Address2 */
306 hsmbus->Instance->OAR2 = (hsmbus->Init.DualAddressMode | hsmbus->Init.OwnAddress2 | (hsmbus->Init.OwnAddress2Masks << 8));
308 /*---------------------------- SMBUSx CR1 Configuration ------------------------*/
309 /* Configure SMBUSx: Generalcall and NoStretch mode */
310 hsmbus->Instance->CR1 = (hsmbus->Init.GeneralCallMode | hsmbus->Init.NoStretchMode | hsmbus->Init.PacketErrorCheckMode | hsmbus->Init.PeripheralMode | hsmbus->Init.AnalogFilter);
312 /* Enable Slave Byte Control only in case of Packet Error Check is enabled and SMBUS Peripheral is set in Slave mode */
313 if( (hsmbus->Init.PacketErrorCheckMode == SMBUS_PEC_ENABLED)
314 && ( (hsmbus->Init.PeripheralMode == SMBUS_PERIPHERAL_MODE_SMBUS_SLAVE) || (hsmbus->Init.PeripheralMode == SMBUS_PERIPHERAL_MODE_SMBUS_SLAVE_ARP) ) )
316 hsmbus->Instance->CR1 |= I2C_CR1_SBC;
319 /* Enable the selected SMBUS peripheral */
320 __HAL_SMBUS_ENABLE(hsmbus);
322 hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE;
323 hsmbus->PreviousState = HAL_SMBUS_STATE_READY;
324 hsmbus->State = HAL_SMBUS_STATE_READY;
330 * @brief DeInitializes the SMBUS peripheral.
331 * @param hsmbus : Pointer to a SMBUS_HandleTypeDef structure that contains
332 * the configuration information for the specified SMBUS.
335 HAL_StatusTypeDef HAL_SMBUS_DeInit(SMBUS_HandleTypeDef *hsmbus)
337 /* Check the SMBUS handle allocation */
343 /* Check the parameters */
344 assert_param(IS_SMBUS_ALL_INSTANCE(hsmbus->Instance));
346 hsmbus->State = HAL_SMBUS_STATE_BUSY;
348 /* Disable the SMBUS Peripheral Clock */
349 __HAL_SMBUS_DISABLE(hsmbus);
351 /* DeInit the low level hardware: GPIO, CLOCK, NVIC */
352 HAL_SMBUS_MspDeInit(hsmbus);
354 hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE;
355 hsmbus->PreviousState = HAL_SMBUS_STATE_RESET;
356 hsmbus->State = HAL_SMBUS_STATE_RESET;
359 __HAL_UNLOCK(hsmbus);
365 * @brief SMBUS MSP Init.
366 * @param hsmbus : Pointer to a SMBUS_HandleTypeDef structure that contains
367 * the configuration information for the specified SMBUS.
370 __weak void HAL_SMBUS_MspInit(SMBUS_HandleTypeDef *hsmbus)
372 /* NOTE : This function Should not be modified, when the callback is needed,
373 the HAL_SMBUS_MspInit could be implemented in the user file
378 * @brief SMBUS MSP DeInit
379 * @param hsmbus : Pointer to a SMBUS_HandleTypeDef structure that contains
380 * the configuration information for the specified SMBUS.
383 __weak void HAL_SMBUS_MspDeInit(SMBUS_HandleTypeDef *hsmbus)
385 /* NOTE : This function Should not be modified, when the callback is needed,
386 the HAL_SMBUS_MspDeInit could be implemented in the user file
394 /** @defgroup SMBUS_Exported_Functions_Group2 Input and Output operation functions
395 * @brief Data transfers functions
398 ===============================================================================
399 ##### IO operation functions #####
400 ===============================================================================
402 This subsection provides a set of functions allowing to manage the SMBUS data
405 (#) Blocking mode function to check if device is ready for usage is :
406 (++) HAL_SMBUS_IsDeviceReady()
408 (#) There is only one mode of transfer:
409 (++) No-Blocking mode : The communication is performed using Interrupts.
410 These functions return the status of the transfer startup.
411 The end of the data processing will be indicated through the
412 dedicated SMBUS IRQ when using Interrupt mode.
414 (#) No-Blocking mode functions with Interrupt are :
415 (++) HAL_SMBUS_Master_Transmit_IT()
416 (++) HAL_SMBUS_Master_Receive_IT()
417 (++) HAL_SMBUS_Slave_Transmit_IT()
418 (++) HAL_SMBUS_Slave_Receive_IT()
419 (++) HAL_SMBUS_Slave_Listen_IT() or alias HAL_SMBUS_EnableListen_IT()
420 (++) HAL_SMBUS_DisableListen_IT()
421 (++) HAL_SMBUS_EnableAlert_IT()
422 (++) HAL_SMBUS_DisableAlert_IT()
424 (#) A set of Transfer Complete Callbacks are provided in No_Blocking mode:
425 (++) HAL_SMBUS_MasterTxCpltCallback()
426 (++) HAL_SMBUS_MasterRxCpltCallback()
427 (++) HAL_SMBUS_SlaveTxCpltCallback()
428 (++) HAL_SMBUS_SlaveRxCpltCallback()
429 (++) HAL_SMBUS_SlaveAddrCallback() or alias HAL_SMBUS_AddrCallback()
430 (++) HAL_SMBUS_SlaveListenCpltCallback() or alias HAL_SMBUS_ListenCpltCallback()
431 (++) HAL_SMBUS_ErrorCallback()
438 * @brief Transmit in master/host SMBUS mode an amount of data in no-blocking mode with Interrupt
439 * @param hsmbus : Pointer to a SMBUS_HandleTypeDef structure that contains
440 * the configuration information for the specified SMBUS.
441 * @param DevAddress: Target device address
442 * @param pData: Pointer to data buffer
443 * @param Size: Amount of data to be sent
444 * @param XferOptions: Options of Transfer, value of @ref SMBUS_XferOptions_definition
447 HAL_StatusTypeDef HAL_SMBUS_Master_Transmit_IT(SMBUS_HandleTypeDef *hsmbus, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t XferOptions)
449 /* Check the parameters */
450 assert_param(IS_SMBUS_TRANSFER_OPTIONS_REQUEST(XferOptions));
452 if(hsmbus->State == HAL_SMBUS_STATE_READY)
457 hsmbus->State = HAL_SMBUS_STATE_MASTER_BUSY_TX;
458 hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE;
459 /* Prepare transfer parameters */
460 hsmbus->pBuffPtr = pData;
461 hsmbus->XferCount = Size;
462 hsmbus->XferOptions = XferOptions;
464 /* In case of Quick command, remove autoend mode */
465 /* Manage the stop generation by software */
466 if(hsmbus->pBuffPtr == NULL)
468 hsmbus->XferOptions &= ~SMBUS_AUTOEND_MODE;
471 if(Size > MAX_NBYTE_SIZE)
473 hsmbus->XferSize = MAX_NBYTE_SIZE;
477 hsmbus->XferSize = Size;
480 /* Send Slave Address */
481 /* Set NBYTES to write and reload if size > MAX_NBYTE_SIZE and generate RESTART */
482 if( (hsmbus->XferSize == MAX_NBYTE_SIZE) && (hsmbus->XferSize < hsmbus->XferCount) )
484 SMBUS_TransferConfig(hsmbus,DevAddress,hsmbus->XferSize, SMBUS_RELOAD_MODE | (hsmbus->XferOptions & SMBUS_SENDPEC_MODE), SMBUS_GENERATE_START_WRITE);
488 /* If transfer direction not change, do not generate Restart Condition */
489 /* Mean Previous state is same as current state */
490 if(hsmbus->PreviousState == HAL_SMBUS_STATE_MASTER_BUSY_TX)
492 SMBUS_TransferConfig(hsmbus,DevAddress,hsmbus->XferSize, hsmbus->XferOptions, SMBUS_NO_STARTSTOP);
494 /* Else transfer direction change, so generate Restart with new transfer direction */
497 SMBUS_TransferConfig(hsmbus,DevAddress,hsmbus->XferSize, hsmbus->XferOptions, SMBUS_GENERATE_START_WRITE);
500 /* If PEC mode is enable, size to transmit manage by SW part should be Size-1 byte, corresponding to PEC byte */
501 /* PEC byte is automatically sent by HW block, no need to manage it in Transmit process */
502 if(__HAL_SMBUS_GET_PEC_MODE(hsmbus) != RESET)
509 /* Process Unlocked */
510 __HAL_UNLOCK(hsmbus);
512 /* Note : The SMBUS interrupts must be enabled after unlocking current process
513 to avoid the risk of SMBUS interrupt handle execution before current
515 SMBUS_Enable_IRQ(hsmbus, SMBUS_IT_TX);
526 * @brief Receive in master/host SMBUS mode an amount of data in no-blocking mode with Interrupt
527 * @param hsmbus : Pointer to a SMBUS_HandleTypeDef structure that contains
528 * the configuration information for the specified SMBUS.
529 * @param DevAddress: Target device address
530 * @param pData: Pointer to data buffer
531 * @param Size: Amount of data to be sent
532 * @param XferOptions: Options of Transfer, value of @ref SMBUS_XferOptions_definition
535 HAL_StatusTypeDef HAL_SMBUS_Master_Receive_IT(SMBUS_HandleTypeDef *hsmbus, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t XferOptions)
537 /* Check the parameters */
538 assert_param(IS_SMBUS_TRANSFER_OPTIONS_REQUEST(XferOptions));
540 if(hsmbus->State == HAL_SMBUS_STATE_READY)
545 hsmbus->State = HAL_SMBUS_STATE_MASTER_BUSY_RX;
546 hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE;
548 /* Prepare transfer parameters */
549 hsmbus->pBuffPtr = pData;
550 hsmbus->XferCount = Size;
551 hsmbus->XferOptions = XferOptions;
553 /* In case of Quick command, remove autoend mode */
554 /* Manage the stop generation by software */
555 if(hsmbus->pBuffPtr == NULL)
557 hsmbus->XferOptions &= ~SMBUS_AUTOEND_MODE;
560 if(Size > MAX_NBYTE_SIZE)
562 hsmbus->XferSize = MAX_NBYTE_SIZE;
566 hsmbus->XferSize = Size;
569 /* Send Slave Address */
570 /* Set NBYTES to write and reload if size > MAX_NBYTE_SIZE and generate RESTART */
571 if( (hsmbus->XferSize == MAX_NBYTE_SIZE) && (hsmbus->XferSize < hsmbus->XferCount) )
573 SMBUS_TransferConfig(hsmbus,DevAddress,hsmbus->XferSize, SMBUS_RELOAD_MODE | (hsmbus->XferOptions & SMBUS_SENDPEC_MODE), SMBUS_GENERATE_START_READ);
577 /* If transfer direction not change, do not generate Restart Condition */
578 /* Mean Previous state is same as current state */
579 if(hsmbus->PreviousState == HAL_SMBUS_STATE_MASTER_BUSY_RX)
581 SMBUS_TransferConfig(hsmbus,DevAddress,hsmbus->XferSize, hsmbus->XferOptions, SMBUS_NO_STARTSTOP);
583 /* Else transfer direction change, so generate Restart with new transfer direction */
586 SMBUS_TransferConfig(hsmbus,DevAddress,hsmbus->XferSize, hsmbus->XferOptions, SMBUS_GENERATE_START_READ);
590 /* Process Unlocked */
591 __HAL_UNLOCK(hsmbus);
593 /* Note : The SMBUS interrupts must be enabled after unlocking current process
594 to avoid the risk of SMBUS interrupt handle execution before current
596 SMBUS_Enable_IRQ(hsmbus, SMBUS_IT_RX);
607 * @brief Abort a master/host SMBUS process commnunication with Interrupt
608 * @note : This abort can be called only if state is ready
609 * @param hsmbus : Pointer to a SMBUS_HandleTypeDef structure that contains
610 * the configuration information for the specified SMBUS.
611 * @param DevAddress: Target device address
614 HAL_StatusTypeDef HAL_SMBUS_Master_Abort_IT(SMBUS_HandleTypeDef *hsmbus, uint16_t DevAddress)
616 if(hsmbus->State == HAL_SMBUS_STATE_READY)
621 /* Keep the same state as previous */
622 /* to perform as well the call of the corresponding end of transfer callback */
623 if(hsmbus->PreviousState == HAL_SMBUS_STATE_MASTER_BUSY_TX)
625 hsmbus->State = HAL_SMBUS_STATE_MASTER_BUSY_TX;
627 else if(hsmbus->PreviousState == HAL_SMBUS_STATE_MASTER_BUSY_RX)
629 hsmbus->State = HAL_SMBUS_STATE_MASTER_BUSY_RX;
633 /* Wrong usage of abort function */
634 /* This function should be used only in case of abort monitored by master device */
637 hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE;
639 /* Set NBYTES to 1 to generate a dummy read on SMBUS peripheral */
640 /* Set AUTOEND mode, this will generate a NACK then STOP condition to abort the current transfer */
641 SMBUS_TransferConfig(hsmbus, DevAddress, 1, SMBUS_AUTOEND_MODE, SMBUS_NO_STARTSTOP);
643 /* Process Unlocked */
644 __HAL_UNLOCK(hsmbus);
646 /* Note : The SMBUS interrupts must be enabled after unlocking current process
647 to avoid the risk of SMBUS interrupt handle execution before current
649 if(hsmbus->State == HAL_SMBUS_STATE_MASTER_BUSY_TX)
651 SMBUS_Enable_IRQ(hsmbus, SMBUS_IT_TX);
653 else if(hsmbus->State == HAL_SMBUS_STATE_MASTER_BUSY_RX)
655 SMBUS_Enable_IRQ(hsmbus, SMBUS_IT_RX);
667 * @brief Transmit in slave/device SMBUS mode an amount of data in no-blocking mode with Interrupt
668 * @param hsmbus : Pointer to a SMBUS_HandleTypeDef structure that contains
669 * the configuration information for the specified SMBUS.
670 * @param pData: Pointer to data buffer
671 * @param Size: Amount of data to be sent
672 * @param XferOptions: Options of Transfer, value of @ref SMBUS_XferOptions_definition
675 HAL_StatusTypeDef HAL_SMBUS_Slave_Transmit_IT(SMBUS_HandleTypeDef *hsmbus, uint8_t *pData, uint16_t Size, uint32_t XferOptions)
677 /* Check the parameters */
678 assert_param(IS_SMBUS_TRANSFER_OPTIONS_REQUEST(XferOptions));
680 if(hsmbus->State == HAL_SMBUS_STATE_LISTEN)
682 if((pData == NULL) || (Size == 0))
687 /* Disable Interrupts, to prevent preemption during treatment in case of multicall */
688 SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_ADDR | SMBUS_IT_TX);
693 hsmbus->State |= HAL_SMBUS_STATE_SLAVE_BUSY_TX;
694 hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE;
696 /* Set SBC bit to manage Acknowledge at each bit */
697 hsmbus->Instance->CR1 |= I2C_CR1_SBC;
699 /* Enable Address Acknowledge */
700 hsmbus->Instance->CR2 &= ~I2C_CR2_NACK;
702 /* Prepare transfer parameters */
703 hsmbus->pBuffPtr = pData;
704 hsmbus->XferSize = Size;
705 hsmbus->XferCount = Size;
706 hsmbus->XferOptions = XferOptions;
708 if(Size > MAX_NBYTE_SIZE)
710 hsmbus->XferSize = MAX_NBYTE_SIZE;
714 hsmbus->XferSize = Size;
717 /* Set NBYTES to write and reload if size > MAX_NBYTE_SIZE and generate RESTART */
718 if( (hsmbus->XferSize == MAX_NBYTE_SIZE) && (hsmbus->XferSize < hsmbus->XferCount) )
720 SMBUS_TransferConfig(hsmbus,0,hsmbus->XferSize, SMBUS_RELOAD_MODE | (hsmbus->XferOptions & SMBUS_SENDPEC_MODE), SMBUS_NO_STARTSTOP);
724 /* Set NBYTE to transmit */
725 SMBUS_TransferConfig(hsmbus,0,hsmbus->XferSize, hsmbus->XferOptions, SMBUS_NO_STARTSTOP);
727 /* If PEC mode is enable, size to transmit should be Size-1 byte, corresponding to PEC byte */
728 /* PEC byte is automatically sent by HW block, no need to manage it in Transmit process */
729 if(__HAL_SMBUS_GET_PEC_MODE(hsmbus) != RESET)
736 /* Clear ADDR flag after prepare the transfer parameters */
737 /* This action will generate an acknowledge to the HOST */
738 __HAL_SMBUS_CLEAR_FLAG(hsmbus,SMBUS_FLAG_ADDR);
740 /* Process Unlocked */
741 __HAL_UNLOCK(hsmbus);
743 /* Note : The SMBUS interrupts must be enabled after unlocking current process
744 to avoid the risk of SMBUS interrupt handle execution before current
746 /* REnable ADDR interrupt */
747 SMBUS_Enable_IRQ(hsmbus, SMBUS_IT_TX | SMBUS_IT_ADDR);
758 * @brief Receive in slave/device SMBUS mode an amount of data in no-blocking mode with Interrupt
759 * @param hsmbus : Pointer to a SMBUS_HandleTypeDef structure that contains
760 * the configuration information for the specified SMBUS.
761 * @param pData: Pointer to data buffer
762 * @param Size: Amount of data to be sent
763 * @param XferOptions: Options of Transfer, value of @ref SMBUS_XferOptions_definition
766 HAL_StatusTypeDef HAL_SMBUS_Slave_Receive_IT(SMBUS_HandleTypeDef *hsmbus, uint8_t *pData, uint16_t Size, uint32_t XferOptions)
768 /* Check the parameters */
769 assert_param(IS_SMBUS_TRANSFER_OPTIONS_REQUEST(XferOptions));
771 if(hsmbus->State == HAL_SMBUS_STATE_LISTEN)
773 if((pData == NULL) || (Size == 0))
778 /* Disable Interrupts, to prevent preemption during treatment in case of multicall */
779 SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_ADDR | SMBUS_IT_RX);
784 hsmbus->State |= HAL_SMBUS_STATE_SLAVE_BUSY_RX;
785 hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE;
787 /* Set SBC bit to manage Acknowledge at each bit */
788 hsmbus->Instance->CR1 |= I2C_CR1_SBC;
790 /* Enable Address Acknowledge */
791 hsmbus->Instance->CR2 &= ~I2C_CR2_NACK;
793 /* Prepare transfer parameters */
794 hsmbus->pBuffPtr = pData;
795 hsmbus->XferSize = Size;
796 hsmbus->XferCount = Size;
797 hsmbus->XferOptions = XferOptions;
799 /* Set NBYTE to receive */
800 /* If XferSize equal "1", or XferSize equal "2" with PEC requested (mean 1 data byte + 1 PEC byte */
801 /* no need to set RELOAD bit mode, a ACK will be automatically generated in that case */
802 /* else need to set RELOAD bit mode to generate an automatic ACK at each byte Received */
803 /* This RELOAD bit will be reset for last BYTE to be receive in SMBUS_Slave_ISR */
804 if((hsmbus->XferSize == 1) || ((hsmbus->XferSize == 2) && (__HAL_SMBUS_GET_PEC_MODE(hsmbus) != RESET)))
806 SMBUS_TransferConfig(hsmbus,0,hsmbus->XferSize, hsmbus->XferOptions, SMBUS_NO_STARTSTOP);
810 SMBUS_TransferConfig(hsmbus,0, 1, hsmbus->XferOptions | SMBUS_RELOAD_MODE, SMBUS_NO_STARTSTOP);
813 /* Clear ADDR flag after prepare the transfer parameters */
814 /* This action will generate an acknowledge to the HOST */
815 __HAL_SMBUS_CLEAR_FLAG(hsmbus,SMBUS_FLAG_ADDR);
817 /* Process Unlocked */
818 __HAL_UNLOCK(hsmbus);
820 /* Note : The SMBUS interrupts must be enabled after unlocking current process
821 to avoid the risk of SMBUS interrupt handle execution before current
823 /* REnable ADDR interrupt */
824 SMBUS_Enable_IRQ(hsmbus, SMBUS_IT_RX | SMBUS_IT_ADDR);
835 * @brief This function enable the Address listen mode
836 * @param hsmbus : Pointer to a SMBUS_HandleTypeDef structure that contains
837 * the configuration information for the specified SMBUS.
840 HAL_StatusTypeDef HAL_SMBUS_Slave_Listen_IT(SMBUS_HandleTypeDef *hsmbus)
842 hsmbus->State = HAL_SMBUS_STATE_LISTEN;
844 /* Enable the Address Match interrupt */
845 SMBUS_Enable_IRQ(hsmbus, SMBUS_IT_ADDR);
851 * @brief This function disable the Address listen mode
852 * @param hsmbus : Pointer to a SMBUS_HandleTypeDef structure that contains
853 * the configuration information for the specified SMBUS.
856 HAL_StatusTypeDef HAL_SMBUS_DisableListen_IT(SMBUS_HandleTypeDef *hsmbus)
858 /* Disable Address listen mode only if a transfer is not ongoing */
859 if(hsmbus->State == HAL_SMBUS_STATE_LISTEN)
861 hsmbus->State = HAL_SMBUS_STATE_READY;
863 /* Disable the Address Match interrupt */
864 SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_ADDR);
875 * @brief This function enable the SMBUS alert mode.
876 * @param hsmbus : pointer to a SMBUS_HandleTypeDef structure that contains
877 * the configuration information for the specified SMBUSx peripheral.
880 HAL_StatusTypeDef HAL_SMBUS_EnableAlert_IT(SMBUS_HandleTypeDef *hsmbus)
882 /* Enable SMBus alert */
883 hsmbus->Instance->CR1 |= I2C_CR1_ALERTEN;
885 /* Clear ALERT flag */
886 __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_ALERT);
888 /* Enable Alert Interrupt */
889 SMBUS_Enable_IRQ(hsmbus, SMBUS_IT_ALERT);
894 * @brief This function disable the SMBUS alert mode.
895 * @param hsmbus : pointer to a SMBUS_HandleTypeDef structure that contains
896 * the configuration information for the specified SMBUSx peripheral.
899 HAL_StatusTypeDef HAL_SMBUS_DisableAlert_IT(SMBUS_HandleTypeDef *hsmbus)
901 /* Enable SMBus alert */
902 hsmbus->Instance->CR1 &= ~I2C_CR1_ALERTEN;
904 /* Disable Alert Interrupt */
905 SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_ALERT);
911 * @brief Checks if target device is ready for communication.
912 * @note This function is used with Memory devices
913 * @param hsmbus : Pointer to a SMBUS_HandleTypeDef structure that contains
914 * the configuration information for the specified SMBUS.
915 * @param DevAddress: Target device address
916 * @param Trials: Number of trials
917 * @param Timeout: Timeout duration
920 HAL_StatusTypeDef HAL_SMBUS_IsDeviceReady(SMBUS_HandleTypeDef *hsmbus, uint16_t DevAddress, uint32_t Trials, uint32_t Timeout)
922 uint32_t tickstart = 0;
924 __IO uint32_t SMBUS_Trials = 0;
926 if(hsmbus->State == HAL_SMBUS_STATE_READY)
928 if(__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_BUSY) != RESET)
936 hsmbus->State = HAL_SMBUS_STATE_BUSY;
937 hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE;
942 hsmbus->Instance->CR2 = __HAL_SMBUS_GENERATE_START(hsmbus->Init.AddressingMode,DevAddress);
944 /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */
945 /* Wait until STOPF flag is set or a NACK flag is set*/
946 tickstart = HAL_GetTick();
947 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))
949 if(Timeout != HAL_MAX_DELAY)
951 if((Timeout == 0) || ((HAL_GetTick() - tickstart) > Timeout))
953 /* Device is ready */
954 hsmbus->State = HAL_SMBUS_STATE_READY;
956 /* Process Unlocked */
957 __HAL_UNLOCK(hsmbus);
963 /* Check if the NACKF flag has not been set */
964 if (__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_AF) == RESET)
966 /* Wait until STOPF flag is reset */
967 if(SMBUS_WaitOnFlagUntilTimeout(hsmbus, SMBUS_FLAG_STOPF, RESET, Timeout) != HAL_OK)
972 /* Clear STOP Flag */
973 __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_STOPF);
975 /* Device is ready */
976 hsmbus->State = HAL_SMBUS_STATE_READY;
978 /* Process Unlocked */
979 __HAL_UNLOCK(hsmbus);
985 /* Wait until STOPF flag is reset */
986 if(SMBUS_WaitOnFlagUntilTimeout(hsmbus, SMBUS_FLAG_STOPF, RESET, Timeout) != HAL_OK)
991 /* Clear NACK Flag */
992 __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_AF);
994 /* Clear STOP Flag, auto generated with autoend*/
995 __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_STOPF);
998 /* Check if the maximum allowed number of trials has been reached */
999 if (SMBUS_Trials++ == Trials)
1002 hsmbus->Instance->CR2 |= I2C_CR2_STOP;
1004 /* Wait until STOPF flag is reset */
1005 if(SMBUS_WaitOnFlagUntilTimeout(hsmbus, SMBUS_FLAG_STOPF, RESET, Timeout) != HAL_OK)
1010 /* Clear STOP Flag */
1011 __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_STOPF);
1013 }while(SMBUS_Trials < Trials);
1015 hsmbus->State = HAL_SMBUS_STATE_READY;
1017 /* Process Unlocked */
1018 __HAL_UNLOCK(hsmbus);
1029 * @brief This function handles SMBUS event interrupt request.
1030 * @param hsmbus : Pointer to a SMBUS_HandleTypeDef structure that contains
1031 * the configuration information for the specified SMBUS.
1034 void HAL_SMBUS_EV_IRQHandler(SMBUS_HandleTypeDef *hsmbus)
1036 uint32_t tmpisrvalue = 0;
1038 /* Use a local variable to store the current ISR flags */
1039 /* This action will avoid a wrong treatment due to ISR flags change during interrupt handler */
1040 tmpisrvalue = __SMBUS_GET_ISR_REG(hsmbus);
1042 /* SMBUS in mode Transmitter ---------------------------------------------------*/
1043 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))
1045 /* Slave mode selected */
1046 if ((hsmbus->State & HAL_SMBUS_STATE_SLAVE_BUSY_TX) == HAL_SMBUS_STATE_SLAVE_BUSY_TX)
1048 SMBUS_Slave_ISR(hsmbus);
1050 /* Master mode selected */
1051 else if((hsmbus->State & HAL_SMBUS_STATE_MASTER_BUSY_TX) == HAL_SMBUS_STATE_MASTER_BUSY_TX)
1053 SMBUS_Master_ISR(hsmbus);
1057 /* SMBUS in mode Receiver ----------------------------------------------------*/
1058 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))
1060 /* Slave mode selected */
1061 if ((hsmbus->State & HAL_SMBUS_STATE_SLAVE_BUSY_RX) == HAL_SMBUS_STATE_SLAVE_BUSY_RX)
1063 SMBUS_Slave_ISR(hsmbus);
1065 /* Master mode selected */
1066 else if((hsmbus->State & HAL_SMBUS_STATE_MASTER_BUSY_RX) == HAL_SMBUS_STATE_MASTER_BUSY_RX)
1068 SMBUS_Master_ISR(hsmbus);
1072 /* SMBUS in mode Listener Only --------------------------------------------------*/
1073 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))
1074 && ((__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)))
1076 if (hsmbus->State == HAL_SMBUS_STATE_LISTEN)
1078 SMBUS_Slave_ISR(hsmbus);
1084 * @brief This function handles SMBUS error interrupt request.
1085 * @param hsmbus : Pointer to a SMBUS_HandleTypeDef structure that contains
1086 * the configuration information for the specified SMBUS.
1089 void HAL_SMBUS_ER_IRQHandler(SMBUS_HandleTypeDef *hsmbus)
1091 /* SMBUS Bus error interrupt occurred ------------------------------------*/
1092 if((__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_BERR) != RESET) && (__HAL_SMBUS_GET_IT_SOURCE(hsmbus, SMBUS_IT_ERRI) != RESET))
1094 hsmbus->ErrorCode |= HAL_SMBUS_ERROR_BERR;
1096 /* Clear BERR flag */
1097 __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_BERR);
1100 /* SMBUS Over-Run/Under-Run interrupt occurred ----------------------------------------*/
1101 if((__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_OVR) != RESET) && (__HAL_SMBUS_GET_IT_SOURCE(hsmbus, SMBUS_IT_ERRI) != RESET))
1103 hsmbus->ErrorCode |= HAL_SMBUS_ERROR_OVR;
1105 /* Clear OVR flag */
1106 __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_OVR);
1109 /* SMBUS Arbitration Loss error interrupt occurred ------------------------------------*/
1110 if((__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_ARLO) != RESET) && (__HAL_SMBUS_GET_IT_SOURCE(hsmbus, SMBUS_IT_ERRI) != RESET))
1112 hsmbus->ErrorCode |= HAL_SMBUS_ERROR_ARLO;
1114 /* Clear ARLO flag */
1115 __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_ARLO);
1118 /* SMBUS Timeout error interrupt occurred ---------------------------------------------*/
1119 if((__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_TIMEOUT) != RESET) && (__HAL_SMBUS_GET_IT_SOURCE(hsmbus, SMBUS_IT_ERRI) != RESET))
1121 hsmbus->ErrorCode |= HAL_SMBUS_ERROR_BUSTIMEOUT;
1123 /* Clear TIMEOUT flag */
1124 __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_TIMEOUT);
1127 /* SMBUS Alert error interrupt occurred -----------------------------------------------*/
1128 if((__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_ALERT) != RESET) && (__HAL_SMBUS_GET_IT_SOURCE(hsmbus, SMBUS_IT_ERRI) != RESET))
1130 hsmbus->ErrorCode |= HAL_SMBUS_ERROR_ALERT;
1132 /* Clear ALERT flag */
1133 __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_ALERT);
1136 /* SMBUS Packet Error Check error interrupt occurred ----------------------------------*/
1137 if((__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_PECERR) != RESET) && (__HAL_SMBUS_GET_IT_SOURCE(hsmbus, SMBUS_IT_ERRI) != RESET))
1139 hsmbus->ErrorCode |= HAL_SMBUS_ERROR_PECERR;
1141 /* Clear PEC error flag */
1142 __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_PECERR);
1145 /* Call the Error Callback in case of Error detected */
1146 if((hsmbus->ErrorCode != HAL_SMBUS_ERROR_NONE)&&(hsmbus->ErrorCode != HAL_SMBUS_ERROR_ACKF))
1148 /* Do not Reset the the HAL state in case of ALERT error */
1149 if((hsmbus->ErrorCode & HAL_SMBUS_ERROR_ALERT) != HAL_SMBUS_ERROR_ALERT)
1151 if(((hsmbus->State & HAL_SMBUS_STATE_SLAVE_BUSY_TX) == HAL_SMBUS_STATE_SLAVE_BUSY_TX)
1152 || ((hsmbus->State & HAL_SMBUS_STATE_SLAVE_BUSY_RX) == HAL_SMBUS_STATE_SLAVE_BUSY_RX))
1154 /* Reset only HAL_SMBUS_STATE_SLAVE_BUSY_XX */
1155 /* keep HAL_SMBUS_STATE_LISTEN if set */
1156 hsmbus->PreviousState = HAL_SMBUS_STATE_READY;
1157 hsmbus->State = HAL_SMBUS_STATE_LISTEN;
1161 /* Call the Error callback to prevent upper layer */
1162 HAL_SMBUS_ErrorCallback(hsmbus);
1167 * @brief Master Tx Transfer completed callbacks.
1168 * @param hsmbus : Pointer to a SMBUS_HandleTypeDef structure that contains
1169 * the configuration information for the specified SMBUS.
1172 __weak void HAL_SMBUS_MasterTxCpltCallback(SMBUS_HandleTypeDef *hsmbus)
1174 /* NOTE : This function Should not be modified, when the callback is needed,
1175 the HAL_SMBUS_TxCpltCallback could be implemented in the user file
1180 * @brief Master Rx Transfer completed callbacks.
1181 * @param hsmbus : Pointer to a SMBUS_HandleTypeDef structure that contains
1182 * the configuration information for the specified SMBUS.
1185 __weak void HAL_SMBUS_MasterRxCpltCallback(SMBUS_HandleTypeDef *hsmbus)
1187 /* NOTE : This function Should not be modified, when the callback is needed,
1188 the HAL_SMBUS_TxCpltCallback could be implemented in the user file
1192 /** @brief Slave Tx Transfer completed callbacks.
1193 * @param hsmbus : Pointer to a SMBUS_HandleTypeDef structure that contains
1194 * the configuration information for the specified SMBUS.
1197 __weak void HAL_SMBUS_SlaveTxCpltCallback(SMBUS_HandleTypeDef *hsmbus)
1199 /* NOTE : This function Should not be modified, when the callback is needed,
1200 the HAL_SMBUS_TxCpltCallback could be implemented in the user file
1205 * @brief Slave Rx Transfer completed callbacks.
1206 * @param hsmbus : Pointer to a SMBUS_HandleTypeDef structure that contains
1207 * the configuration information for the specified SMBUS.
1210 __weak void HAL_SMBUS_SlaveRxCpltCallback(SMBUS_HandleTypeDef *hsmbus)
1212 /* NOTE : This function Should not be modified, when the callback is needed,
1213 the HAL_SMBUS_TxCpltCallback could be implemented in the user file
1218 * @brief Slave Address Match callbacks.
1219 * @param hsmbus : Pointer to a SMBUS_HandleTypeDef structure that contains
1220 * the configuration information for the specified SMBUS.
1221 * @param TransferDirection: Master request Transfer Direction (Write/Read)
1222 * @param AddrMatchCode: Address Match Code
1225 __weak void HAL_SMBUS_SlaveAddrCallback(SMBUS_HandleTypeDef *hsmbus, uint8_t TransferDirection, uint16_t AddrMatchCode)
1227 /* NOTE : This function Should not be modified, when the callback is needed,
1228 the HAL_SMBUS_SlaveAddrCallback could be implemented in the user file
1233 * @brief Listen Complete callbacks.
1234 * @param hsmbus : Pointer to a SMBUS_HandleTypeDef structure that contains
1235 * the configuration information for the specified SMBUS.
1238 __weak void HAL_SMBUS_SlaveListenCpltCallback(SMBUS_HandleTypeDef *hsmbus)
1240 /* NOTE : This function Should not be modified, when the callback is needed,
1241 the HAL_SMBUS_SlaveListenCpltCallback could be implemented in the user file
1246 * @brief SMBUS error callbacks.
1247 * @param hsmbus : Pointer to a SMBUS_HandleTypeDef structure that contains
1248 * the configuration information for the specified SMBUS.
1251 __weak void HAL_SMBUS_ErrorCallback(SMBUS_HandleTypeDef *hsmbus)
1253 /* NOTE : This function Should not be modified, when the callback is needed,
1254 the HAL_SMBUS_ErrorCallback could be implemented in the user file
1262 /** @defgroup SMBUS_Exported_Functions_Group3 Peripheral State and Errors functions
1263 * @brief Peripheral State and Errors functions
1266 ===============================================================================
1267 ##### Peripheral State and Errors functions #####
1268 ===============================================================================
1270 This subsection permit to get in run-time the status of the peripheral
1278 * @brief Returns the SMBUS state.
1279 * @param hsmbus : SMBUS handle
1282 uint32_t HAL_SMBUS_GetState(SMBUS_HandleTypeDef *hsmbus)
1284 return hsmbus->State;
1288 * @brief Return the SMBUS error code
1289 * @param hsmbus : pointer to a SMBUS_HandleTypeDef structure that contains
1290 * the configuration information for the specified SMBUS.
1291 * @retval SMBUS Error Code
1293 uint32_t HAL_SMBUS_GetError(SMBUS_HandleTypeDef *hsmbus)
1295 return hsmbus->ErrorCode;
1306 /** @addtogroup SMBUS_Private_Functions SMBUS Private Functions
1307 * @brief Data transfers Private functions
1312 * @brief Interrupt Sub-Routine which handle the Interrupt Flags Master Mode
1313 * @param hsmbus : Pointer to a SMBUS_HandleTypeDef structure that contains
1314 * the configuration information for the specified SMBUS.
1315 * @retval HAL status
1317 static HAL_StatusTypeDef SMBUS_Master_ISR(SMBUS_HandleTypeDef *hsmbus)
1319 uint16_t DevAddress;
1321 /* Process Locked */
1324 if(__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_AF) != RESET)
1326 /* Clear NACK Flag */
1327 __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_AF);
1329 /* Set corresponding Error Code */
1330 /* No need to generate STOP, it is automatically done */
1331 hsmbus->ErrorCode |= HAL_SMBUS_ERROR_ACKF;
1333 /* Process Unlocked */
1334 __HAL_UNLOCK(hsmbus);
1336 /* Call the Error callback to prevent upper layer */
1337 HAL_SMBUS_ErrorCallback(hsmbus);
1339 else if(__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_STOPF) != RESET)
1342 /* Call the corresponding callback to inform upper layer of End of Transfer */
1343 if(hsmbus->State == HAL_SMBUS_STATE_MASTER_BUSY_TX)
1345 /* Disable Interrupt */
1346 SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_TX);
1348 /* Clear STOP Flag */
1349 __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_STOPF);
1351 /* Clear Configuration Register 2 */
1352 __HAL_SMBUS_RESET_CR2(hsmbus);
1354 /* Flush remaining data in Fifo register in case of error occurs before TXEmpty */
1355 /* Disable the selected SMBUS peripheral */
1356 __HAL_SMBUS_DISABLE(hsmbus);
1358 hsmbus->PreviousState = HAL_SMBUS_STATE_READY;
1359 hsmbus->State = HAL_SMBUS_STATE_READY;
1361 /* Process Unlocked */
1362 __HAL_UNLOCK(hsmbus);
1364 /* REenable the selected SMBUS peripheral */
1365 __HAL_SMBUS_ENABLE(hsmbus);
1367 HAL_SMBUS_MasterTxCpltCallback(hsmbus);
1369 else if(hsmbus->State == HAL_SMBUS_STATE_MASTER_BUSY_RX)
1371 /* Disable Interrupt */
1372 SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_RX);
1374 /* Clear STOP Flag */
1375 __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_STOPF);
1377 /* Clear Configuration Register 2 */
1378 __HAL_SMBUS_RESET_CR2(hsmbus);
1380 hsmbus->PreviousState = HAL_SMBUS_STATE_READY;
1381 hsmbus->State = HAL_SMBUS_STATE_READY;
1383 /* Process Unlocked */
1384 __HAL_UNLOCK(hsmbus);
1386 HAL_SMBUS_MasterRxCpltCallback(hsmbus);
1389 else if(__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_RXNE) != RESET)
1391 /* Read data from RXDR */
1392 (*hsmbus->pBuffPtr++) = hsmbus->Instance->RXDR;
1394 hsmbus->XferCount--;
1396 else if(__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_TXIS) != RESET)
1398 /* Write data to TXDR */
1399 hsmbus->Instance->TXDR = (*hsmbus->pBuffPtr++);
1401 hsmbus->XferCount--;
1403 else if(__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_TCR) != RESET)
1405 if((hsmbus->XferSize == 0)&&(hsmbus->XferCount!=0))
1407 DevAddress = (hsmbus->Instance->CR2 & I2C_CR2_SADD);
1409 if(hsmbus->XferCount > MAX_NBYTE_SIZE)
1411 SMBUS_TransferConfig(hsmbus, DevAddress, MAX_NBYTE_SIZE, (SMBUS_RELOAD_MODE | (hsmbus->XferOptions & SMBUS_SENDPEC_MODE)), SMBUS_NO_STARTSTOP);
1412 hsmbus->XferSize = MAX_NBYTE_SIZE;
1416 hsmbus->XferSize = hsmbus->XferCount;
1417 SMBUS_TransferConfig(hsmbus,DevAddress,hsmbus->XferSize, hsmbus->XferOptions, SMBUS_NO_STARTSTOP);
1418 /* If PEC mode is enable, size to transmit should be Size-1 byte, corresponding to PEC byte */
1419 /* PEC byte is automatically sent by HW block, no need to manage it in Transmit process */
1420 if(__HAL_SMBUS_GET_PEC_MODE(hsmbus) != RESET)
1423 hsmbus->XferCount--;
1427 else if((hsmbus->XferSize == 0)&&(hsmbus->XferCount==0))
1429 /* Call TxCpltCallback if no stop mode is set */
1430 if(__HAL_SMBUS_GET_STOP_MODE(hsmbus) != SMBUS_AUTOEND_MODE)
1432 /* Call the corresponding callback to inform upper layer of End of Transfer */
1433 if(hsmbus->State == HAL_SMBUS_STATE_MASTER_BUSY_TX)
1435 /* Disable Interrupt */
1436 SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_TX);
1437 hsmbus->PreviousState = hsmbus->State;
1438 hsmbus->State = HAL_SMBUS_STATE_READY;
1440 /* Process Unlocked */
1441 __HAL_UNLOCK(hsmbus);
1443 HAL_SMBUS_MasterTxCpltCallback(hsmbus);
1445 else if(hsmbus->State == HAL_SMBUS_STATE_MASTER_BUSY_RX)
1447 SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_RX);
1448 hsmbus->PreviousState = hsmbus->State;
1449 hsmbus->State = HAL_SMBUS_STATE_READY;
1451 /* Process Unlocked */
1452 __HAL_UNLOCK(hsmbus);
1454 HAL_SMBUS_MasterRxCpltCallback(hsmbus);
1459 else if(__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_TC) != RESET)
1461 if(hsmbus->XferCount == 0)
1463 /* Specific use case for Quick command */
1464 if(hsmbus->pBuffPtr == NULL)
1466 /* Generate a Stop command */
1467 hsmbus->Instance->CR2 |= I2C_CR2_STOP;
1469 /* Call TxCpltCallback if no stop mode is set */
1470 else if(__HAL_SMBUS_GET_STOP_MODE(hsmbus) != SMBUS_AUTOEND_MODE)
1472 /* No Generate Stop, to permit restart mode */
1473 /* The stop will be done at the end of transfer, when SMBUS_AUTOEND_MODE enable */
1475 /* Call the corresponding callback to inform upper layer of End of Transfer */
1476 if(hsmbus->State == HAL_SMBUS_STATE_MASTER_BUSY_TX)
1478 /* Disable Interrupt */
1479 SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_TX);
1480 hsmbus->PreviousState = hsmbus->State;
1481 hsmbus->State = HAL_SMBUS_STATE_READY;
1483 /* Process Unlocked */
1484 __HAL_UNLOCK(hsmbus);
1486 HAL_SMBUS_MasterTxCpltCallback(hsmbus);
1488 else if(hsmbus->State == HAL_SMBUS_STATE_MASTER_BUSY_RX)
1490 SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_RX);
1491 hsmbus->PreviousState = hsmbus->State;
1492 hsmbus->State = HAL_SMBUS_STATE_READY;
1494 /* Process Unlocked */
1495 __HAL_UNLOCK(hsmbus);
1497 HAL_SMBUS_MasterRxCpltCallback(hsmbus);
1503 /* Process Unlocked */
1504 __HAL_UNLOCK(hsmbus);
1509 * @brief Interrupt Sub-Routine which handle the Interrupt Flags Slave Mode
1510 * @param hsmbus : Pointer to a SMBUS_HandleTypeDef structure that contains
1511 * the configuration information for the specified SMBUS.
1512 * @retval HAL status
1514 static HAL_StatusTypeDef SMBUS_Slave_ISR(SMBUS_HandleTypeDef *hsmbus)
1516 uint8_t TransferDirection = 0;
1517 uint16_t SlaveAddrCode = 0;
1519 /* Process Locked */
1522 if(__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_AF) != RESET)
1524 /* Check that SMBUS transfer finished */
1525 /* if yes, normal usecase, a NACK is sent by the HOST when Transfer is finished */
1526 /* Mean XferCount == 0*/
1527 /* So clear Flag NACKF only */
1528 if(hsmbus->XferCount == 0)
1530 /* Clear NACK Flag */
1531 __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_AF);
1533 /* Process Unlocked */
1534 __HAL_UNLOCK(hsmbus);
1538 /* if no, error usecase, a Non-Acknowledge of last Data is generated by the HOST*/
1539 /* Clear NACK Flag */
1540 __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_AF);
1542 /* Set HAL State to "Idle" State, mean to LISTEN state */
1543 /* So reset Slave Busy state */
1544 hsmbus->PreviousState = hsmbus->State;
1545 hsmbus->State &= ~((uint32_t)HAL_SMBUS_STATE_SLAVE_BUSY_TX);
1546 hsmbus->State &= ~((uint32_t)HAL_SMBUS_STATE_SLAVE_BUSY_RX);
1548 /* Disable RX/TX Interrupts, keep only ADDR Interrupt */
1549 SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_RX | SMBUS_IT_TX);
1551 /* Set ErrorCode corresponding to a Non-Acknowledge */
1552 hsmbus->ErrorCode |= HAL_SMBUS_ERROR_ACKF;
1554 /* Process Unlocked */
1555 __HAL_UNLOCK(hsmbus);
1557 /* Call the Error callback to prevent upper layer */
1558 HAL_SMBUS_ErrorCallback(hsmbus);
1561 else if(__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_ADDR) != RESET)
1563 TransferDirection = __HAL_SMBUS_GET_DIR(hsmbus);
1564 SlaveAddrCode = __HAL_SMBUS_GET_ADDR_MATCH(hsmbus);
1566 /* Disable ADDR interrupt to prevent multiple ADDRInterrupt*/
1567 /* Other ADDRInterrupt will be treat in next Listen usecase */
1568 __HAL_SMBUS_DISABLE_IT(hsmbus, SMBUS_IT_ADDRI);
1570 /* Process Unlocked */
1571 __HAL_UNLOCK(hsmbus);
1573 /* Call Slave Addr callback */
1574 HAL_SMBUS_SlaveAddrCallback(hsmbus, TransferDirection, SlaveAddrCode);
1576 else if((__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_RXNE) != RESET) || (__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_TCR) != RESET))
1578 if( (hsmbus->State & HAL_SMBUS_STATE_SLAVE_BUSY_RX) == HAL_SMBUS_STATE_SLAVE_BUSY_RX)
1580 /* Read data from RXDR */
1581 (*hsmbus->pBuffPtr++) = hsmbus->Instance->RXDR;
1583 hsmbus->XferCount--;
1585 if(hsmbus->XferCount == 1)
1587 /* Receive last Byte, can be PEC byte in case of PEC BYTE enabled */
1588 /* or only the last Byte of Transfer */
1589 /* So reset the RELOAD bit mode */
1590 hsmbus->XferOptions &= ~SMBUS_RELOAD_MODE;
1591 SMBUS_TransferConfig(hsmbus,0 ,1 , hsmbus->XferOptions, SMBUS_NO_STARTSTOP);
1593 else if(hsmbus->XferCount == 0)
1595 /* Last Byte is received, disable Interrupt */
1596 SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_RX);
1598 /* Remove HAL_SMBUS_STATE_SLAVE_BUSY_RX, keep only HAL_SMBUS_STATE_LISTEN */
1599 hsmbus->PreviousState = hsmbus->State;
1600 hsmbus->State &= ~((uint32_t)HAL_SMBUS_STATE_SLAVE_BUSY_RX);
1602 /* Process Unlocked */
1603 __HAL_UNLOCK(hsmbus);
1605 /* Call the Rx complete callback to inform upper layer of the end of receive process */
1606 HAL_SMBUS_SlaveRxCpltCallback(hsmbus);
1610 /* Set Reload for next Bytes */
1611 SMBUS_TransferConfig(hsmbus,0, 1, SMBUS_RELOAD_MODE | (hsmbus->XferOptions & SMBUS_SENDPEC_MODE), SMBUS_NO_STARTSTOP);
1613 /* Ack last Byte Read */
1614 hsmbus->Instance->CR2 &= ~I2C_CR2_NACK;
1617 else if( (hsmbus->State & HAL_SMBUS_STATE_SLAVE_BUSY_TX) == HAL_SMBUS_STATE_SLAVE_BUSY_TX)
1619 if((hsmbus->XferSize == 0)&&(hsmbus->XferCount!=0))
1621 if(hsmbus->XferCount > MAX_NBYTE_SIZE)
1623 SMBUS_TransferConfig(hsmbus, 0, MAX_NBYTE_SIZE, (SMBUS_RELOAD_MODE | (hsmbus->XferOptions & SMBUS_SENDPEC_MODE)), SMBUS_NO_STARTSTOP);
1624 hsmbus->XferSize = MAX_NBYTE_SIZE;
1628 hsmbus->XferSize = hsmbus->XferCount;
1629 SMBUS_TransferConfig(hsmbus, 0, hsmbus->XferSize, hsmbus->XferOptions, SMBUS_NO_STARTSTOP);
1630 /* If PEC mode is enable, size to transmit should be Size-1 byte, corresponding to PEC byte */
1631 /* PEC byte is automatically sent by HW block, no need to manage it in Transmit process */
1632 if(__HAL_SMBUS_GET_PEC_MODE(hsmbus) != RESET)
1635 hsmbus->XferCount--;
1641 else if(__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_TXIS) != RESET)
1643 /* Write data to TXDR only if XferCount not reach "0" */
1644 /* A TXIS flag can be set, during STOP treatment */
1645 /* Check if all Datas have already been sent */
1646 /* If it is the case, this last write in TXDR is not sent, correspond to a dummy TXIS event */
1647 if(hsmbus->XferCount > 0)
1649 /* Write data to TXDR */
1650 hsmbus->Instance->TXDR = (*hsmbus->pBuffPtr++);
1651 hsmbus->XferCount--;
1655 if(hsmbus->XferCount == 0)
1657 /* Last Byte is Transmitted */
1658 /* Remove HAL_SMBUS_STATE_SLAVE_BUSY_TX, keep only HAL_SMBUS_STATE_LISTEN */
1659 SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_TX);
1660 hsmbus->PreviousState = hsmbus->State;
1661 hsmbus->State &= ~((uint32_t)HAL_SMBUS_STATE_SLAVE_BUSY_TX);
1663 /* Process Unlocked */
1664 __HAL_UNLOCK(hsmbus);
1666 /* Call the Tx complete callback to inform upper layer of the end of transmit process */
1667 HAL_SMBUS_SlaveTxCpltCallback(hsmbus);
1671 /* Check if STOPF is set */
1672 if(__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_STOPF) != RESET)
1674 if((hsmbus->State & HAL_SMBUS_STATE_LISTEN) == HAL_SMBUS_STATE_LISTEN)
1676 /* Disable RX and TX Interrupts */
1677 SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_RX | SMBUS_IT_TX);
1679 /* Disable ADDR Interrupt */
1680 SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_ADDR);
1682 /* Disable Address Acknowledge */
1683 hsmbus->Instance->CR2 |= I2C_CR2_NACK;
1685 /* Clear Configuration Register 2 */
1686 __HAL_SMBUS_RESET_CR2(hsmbus);
1688 /* Clear STOP Flag */
1689 __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_STOPF);
1691 /* Clear ADDR flag */
1692 __HAL_SMBUS_CLEAR_FLAG(hsmbus,SMBUS_FLAG_ADDR);
1694 hsmbus->XferOptions = 0;
1695 hsmbus->PreviousState = hsmbus->State;
1696 hsmbus->State = HAL_SMBUS_STATE_READY;
1698 /* Process Unlocked */
1699 __HAL_UNLOCK(hsmbus);
1701 /* Call the Listen Complete callback, to prevent upper layer of the end of Listen usecase */
1702 HAL_SMBUS_SlaveListenCpltCallback(hsmbus);
1706 /* Process Unlocked */
1707 __HAL_UNLOCK(hsmbus);
1712 * @brief Manage the enabling of Interrupts
1713 * @param hsmbus : Pointer to a SMBUS_HandleTypeDef structure that contains
1714 * the configuration information for the specified SMBUS.
1715 * @param InterruptRequest : Value of @ref SMBUS_Interrupt_configuration_definition.
1716 * @retval HAL status
1718 static HAL_StatusTypeDef SMBUS_Enable_IRQ(SMBUS_HandleTypeDef *hsmbus, uint16_t InterruptRequest)
1720 uint32_t tmpisr = 0;
1722 if((InterruptRequest & SMBUS_IT_ALERT) == SMBUS_IT_ALERT)
1724 /* Enable ERR interrupt */
1725 tmpisr |= SMBUS_IT_ERRI;
1728 if((InterruptRequest & SMBUS_IT_ADDR) == SMBUS_IT_ADDR)
1730 /* Enable ADDR, STOP interrupt */
1731 tmpisr |= SMBUS_IT_ADDRI | SMBUS_IT_STOPI | SMBUS_IT_NACKI | SMBUS_IT_ERRI;
1734 if((InterruptRequest & SMBUS_IT_TX) == SMBUS_IT_TX)
1736 /* Enable ERR, TC, STOP, NACK, RXI interrupt */
1737 tmpisr |= SMBUS_IT_ERRI | SMBUS_IT_TCI | SMBUS_IT_STOPI | SMBUS_IT_NACKI | SMBUS_IT_TXI;
1740 if((InterruptRequest & SMBUS_IT_RX) == SMBUS_IT_RX)
1742 /* Enable ERR, TC, STOP, NACK, TXI interrupt */
1743 tmpisr |= SMBUS_IT_ERRI | SMBUS_IT_TCI | SMBUS_IT_STOPI | SMBUS_IT_NACKI | SMBUS_IT_RXI;
1746 /* Enable interrupts only at the end */
1747 /* to avoid the risk of SMBUS interrupt handle execution before */
1748 /* all interrupts requested done */
1749 __HAL_SMBUS_ENABLE_IT(hsmbus, tmpisr);
1754 * @brief Manage the disabling of Interrupts
1755 * @param hsmbus : Pointer to a SMBUS_HandleTypeDef structure that contains
1756 * the configuration information for the specified SMBUS.
1757 * @param InterruptRequest : Value of @ref SMBUS_Interrupt_configuration_definition.
1758 * @retval HAL status
1760 static HAL_StatusTypeDef SMBUS_Disable_IRQ(SMBUS_HandleTypeDef *hsmbus, uint16_t InterruptRequest)
1762 uint32_t tmpisr = 0;
1764 if( ((InterruptRequest & SMBUS_IT_ALERT) == SMBUS_IT_ALERT) && (hsmbus->State == HAL_SMBUS_STATE_READY) )
1766 /* Disable ERR interrupt */
1767 tmpisr |= SMBUS_IT_ERRI;
1770 if((InterruptRequest & SMBUS_IT_TX) == SMBUS_IT_TX)
1772 /* Disable TC, STOP, NACK, TXI interrupt */
1773 tmpisr |= SMBUS_IT_TCI | SMBUS_IT_TXI;
1775 if((__HAL_SMBUS_GET_ALERT_ENABLED(hsmbus) == RESET)
1776 && ((hsmbus->State & HAL_SMBUS_STATE_LISTEN) != HAL_SMBUS_STATE_LISTEN))
1778 /* Disable ERR interrupt */
1779 tmpisr |= SMBUS_IT_ERRI;
1782 if((hsmbus->State & HAL_SMBUS_STATE_LISTEN) != HAL_SMBUS_STATE_LISTEN)
1784 /* Disable STOPI, NACKI */
1785 tmpisr |= SMBUS_IT_STOPI | SMBUS_IT_NACKI;
1789 if((InterruptRequest & SMBUS_IT_RX) == SMBUS_IT_RX)
1791 /* Disable TC, STOP, NACK, RXI interrupt */
1792 tmpisr |= SMBUS_IT_TCI | SMBUS_IT_RXI;
1794 if((__HAL_SMBUS_GET_ALERT_ENABLED(hsmbus) == RESET)
1795 && ((hsmbus->State & HAL_SMBUS_STATE_LISTEN) != HAL_SMBUS_STATE_LISTEN))
1797 /* Disable ERR interrupt */
1798 tmpisr |= SMBUS_IT_ERRI;
1801 if((hsmbus->State & HAL_SMBUS_STATE_LISTEN) != HAL_SMBUS_STATE_LISTEN)
1803 /* Disable STOPI, NACKI */
1804 tmpisr |= SMBUS_IT_STOPI | SMBUS_IT_NACKI;
1808 if((InterruptRequest & SMBUS_IT_ADDR) == SMBUS_IT_ADDR)
1810 /* Enable ADDR, STOP interrupt */
1811 tmpisr |= SMBUS_IT_ADDRI | SMBUS_IT_STOPI | SMBUS_IT_NACKI;
1813 if(__HAL_SMBUS_GET_ALERT_ENABLED(hsmbus) == RESET)
1815 /* Disable ERR interrupt */
1816 tmpisr |= SMBUS_IT_ERRI;
1820 /* Disable interrupts only at the end */
1821 /* to avoid a breaking situation like at "t" time */
1822 /* all disable interrupts request are not done */
1823 __HAL_SMBUS_DISABLE_IT(hsmbus, tmpisr);
1828 * @brief This function handles SMBUS Communication Timeout.
1829 * @param hsmbus : Pointer to a SMBUS_HandleTypeDef structure that contains
1830 * the configuration information for the specified SMBUS.
1831 * @param Flag: specifies the SMBUS flag to check.
1832 * @param Status: The new Flag status (SET or RESET).
1833 * @param Timeout: Timeout duration
1834 * @retval HAL status
1836 static HAL_StatusTypeDef SMBUS_WaitOnFlagUntilTimeout(SMBUS_HandleTypeDef *hsmbus, uint32_t Flag, FlagStatus Status, uint32_t Timeout)
1838 uint32_t tickstart = HAL_GetTick();
1840 /* Wait until flag is set */
1843 while(__HAL_SMBUS_GET_FLAG(hsmbus, Flag) == RESET)
1845 /* Check for the Timeout */
1846 if(Timeout != HAL_MAX_DELAY)
1848 if((Timeout == 0) || ((HAL_GetTick() - tickstart) > Timeout))
1850 hsmbus->PreviousState = hsmbus->State;
1851 hsmbus->State= HAL_SMBUS_STATE_READY;
1853 /* Process Unlocked */
1854 __HAL_UNLOCK(hsmbus);
1863 while(__HAL_SMBUS_GET_FLAG(hsmbus, Flag) != RESET)
1865 /* Check for the Timeout */
1866 if(Timeout != HAL_MAX_DELAY)
1868 if((Timeout == 0) || ((HAL_GetTick() - tickstart) > Timeout))
1870 hsmbus->PreviousState = hsmbus->State;
1871 hsmbus->State= HAL_SMBUS_STATE_READY;
1873 /* Process Unlocked */
1874 __HAL_UNLOCK(hsmbus);
1885 * @brief Handles SMBUSx communication when starting transfer or during transfer (TC or TCR flag are set).
1886 * @param hsmbus: SMBUS handle.
1887 * @param DevAddress: specifies the slave address to be programmed.
1888 * @param Size: specifies the number of bytes to be programmed.
1889 * This parameter must be a value between 0 and 255.
1890 * @param Mode: new state of the SMBUS START condition generation.
1891 * This parameter can be one or a combination of the following values:
1892 * @arg SMBUS_NO_MODE: No specific mode enabled.
1893 * @arg SMBUS_RELOAD_MODE: Enable Reload mode.
1894 * @arg SMBUS_AUTOEND_MODE: Enable Automatic end mode.
1895 * @arg SMBUS_SOFTEND_MODE: Enable Software end mode and Reload mode.
1896 * @param Request: new state of the SMBUS START condition generation.
1897 * This parameter can be one of the following values:
1898 * @arg SMBUS_NO_STARTSTOP: Don't Generate stop and start condition.
1899 * @arg SMBUS_GENERATE_STOP: Generate stop condition (Size should be set to 0).
1900 * @arg SMBUS_GENERATE_START_READ: Generate Restart for read request.
1901 * @arg SMBUS_GENERATE_START_WRITE: Generate Restart for write request.
1904 static void SMBUS_TransferConfig(SMBUS_HandleTypeDef *hsmbus, uint16_t DevAddress, uint8_t Size, uint32_t Mode, uint32_t Request)
1906 uint32_t tmpreg = 0;
1908 /* Check the parameters */
1909 assert_param(IS_SMBUS_ALL_INSTANCE(hsmbus->Instance));
1910 assert_param(IS_SMBUS_TRANSFER_MODE(Mode));
1911 assert_param(IS_SMBUS_TRANSFER_REQUEST(Request));
1913 /* Get the CR2 register value */
1914 tmpreg = hsmbus->Instance->CR2;
1916 /* clear tmpreg specific bits */
1917 tmpreg &= (uint32_t)~((uint32_t)(I2C_CR2_SADD | I2C_CR2_NBYTES | I2C_CR2_RELOAD | I2C_CR2_AUTOEND | I2C_CR2_RD_WRN | I2C_CR2_START | I2C_CR2_STOP | I2C_CR2_PECBYTE));
1920 tmpreg |= (uint32_t)(((uint32_t)DevAddress & I2C_CR2_SADD) | (((uint32_t)Size << 16 ) & I2C_CR2_NBYTES) | \
1921 (uint32_t)Mode | (uint32_t)Request);
1923 /* update CR2 register */
1924 hsmbus->Instance->CR2 = tmpreg;
1930 #endif /* HAL_SMBUS_MODULE_ENABLED */
1939 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/