TUKS MCU Introductory course / TUKS-COURSE-2-LED
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers stm32l4xx_hal_smbus.c Source File

stm32l4xx_hal_smbus.c

Go to the documentation of this file.
00001 /**
00002   ******************************************************************************
00003   * @file    stm32l4xx_hal_smbus.c
00004   * @author  MCD Application Team
00005   * @version V1.5.1
00006   * @date    31-May-2016
00007   * @brief   SMBUS HAL module driver. 
00008   *          This file provides firmware functions to manage the following 
00009   *          functionalities of the System Management Bus (SMBus) peripheral,
00010   *          based on I2C principles of operation :
00011   *           + Initialization and de-initialization functions
00012   *           + IO operation functions
00013   *           + Peripheral State and Errors functions
00014   *         
00015   @verbatim
00016   ==============================================================================
00017                         ##### How to use this driver #####
00018   ==============================================================================
00019     [..]
00020     The SMBUS HAL driver can be used as follows:
00021     
00022     (#) Declare a SMBUS_HandleTypeDef handle structure, for example:
00023         SMBUS_HandleTypeDef  hsmbus; 
00024 
00025     (#)Initialize the SMBUS low level resources by implementing the HAL_SMBUS_MspInit() API:
00026         (++) Enable the SMBUSx interface clock with __HAL_RCC_I2Cx_CLK_ENABLE()
00027         (++) SMBUS pins configuration
00028             (+++) Enable the clock for the SMBUS GPIOs
00029             (+++) Configure SMBUS pins as alternate function open-drain
00030         (++) NVIC configuration if you need to use interrupt process
00031             (+++) Configure the SMBUSx interrupt priority 
00032             (+++) Enable the NVIC SMBUS IRQ Channel
00033 
00034     (#) Configure the Communication Clock Timing, Bus Timeout, Own Address1, Master Addressing Mode,
00035         Dual Addressing mode, Own Address2, Own Address2 Mask, General call, Nostretch mode,
00036         Peripheral mode and Packet Error Check mode in the hsmbus Init structure.
00037 
00038     (#) Initialize the SMBUS registers by calling the HAL_SMBUS_Init() API:
00039         (++) These API's configures also the low level Hardware GPIO, CLOCK, CORTEX...etc)
00040              by calling the customized HAL_SMBUS_MspInit(&hsmbus) API.
00041 
00042     (#) To check if target device is ready for communication, use the function HAL_SMBUS_IsDeviceReady()
00043 
00044     (#) For SMBUS IO operations, only one mode of operations is available within this driver :
00045             
00046     *** Interrupt mode IO operation ***
00047     ===================================
00048     [..]
00049       (+) Transmit in master/host SMBUS mode an amount of data in non-blocking mode using HAL_SMBUS_Master_Transmit_IT()
00050       (++) At transmission end of transfer HAL_SMBUS_MasterTxCpltCallback() is executed and user can
00051            add his own code by customization of function pointer HAL_SMBUS_MasterTxCpltCallback()
00052       (+) Receive in master/host SMBUS mode an amount of data in non-blocking mode using HAL_SMBUS_Master_Receive_IT()
00053       (++) At reception end of transfer HAL_SMBUS_MasterRxCpltCallback() is executed and user can
00054            add his own code by customization of function pointer HAL_SMBUS_MasterRxCpltCallback()
00055       (+) Abort a master/host SMBUS process communication with Interrupt using HAL_SMBUS_Master_Abort_IT()
00056       (++) The associated previous transfer callback is called at the end of abort process
00057       (++) mean HAL_SMBUS_MasterTxCpltCallback() in case of previous state was master transmit
00058       (++) mean HAL_SMBUS_MasterRxCpltCallback() in case of previous state was master receive
00059       (+) Enable/disable the Address listen mode in slave/device or host/slave SMBUS mode
00060            using HAL_SMBUS_EnableListen_IT() HAL_SMBUS_DisableListen_IT()
00061       (++) When address slave/device SMBUS match, HAL_SMBUS_AddrCallback() is executed and user can
00062            add his own code to check the Address Match Code and the transmission direction request by master/host (Write/Read).
00063       (++) At Listen mode end HAL_SMBUS_ListenCpltCallback() is executed and user can
00064            add his own code by customization of function pointer HAL_SMBUS_ListenCpltCallback()
00065       (+) Transmit in slave/device SMBUS mode an amount of data in non-blocking mode using HAL_SMBUS_Slave_Transmit_IT()
00066       (++) At transmission end of transfer HAL_SMBUS_SlaveTxCpltCallback() is executed and user can
00067            add his own code by customization of function pointer HAL_SMBUS_SlaveTxCpltCallback()
00068       (+) Receive in slave/device SMBUS mode an amount of data in non-blocking mode using HAL_SMBUS_Slave_Receive_IT()
00069       (++) At reception end of transfer HAL_SMBUS_SlaveRxCpltCallback() is executed and user can
00070            add his own code by customization of function pointer HAL_SMBUS_SlaveRxCpltCallback()
00071       (+) Enable/Disable the SMBUS alert mode using HAL_SMBUS_EnableAlert_IT() HAL_SMBUS_DisableAlert_IT()
00072       (++) When SMBUS Alert is generated HAL_SMBUS_ErrorCallback() is executed and user can
00073            add his own code by customization of function pointer HAL_SMBUS_ErrorCallback()
00074            to check the Alert Error Code using function HAL_SMBUS_GetError()
00075       (+) Get HAL state machine or error values using HAL_SMBUS_GetState() or HAL_SMBUS_GetError()
00076       (+) In case of transfer Error, HAL_SMBUS_ErrorCallback() function is executed and user can
00077            add his own code by customization of function pointer HAL_SMBUS_ErrorCallback()
00078            to check the Error Code using function HAL_SMBUS_GetError()
00079 
00080      *** SMBUS HAL driver macros list ***
00081      ==================================
00082      [..]
00083        Below the list of most used macros in SMBUS HAL driver.
00084 
00085       (+) __HAL_SMBUS_ENABLE: Enable the SMBUS peripheral
00086       (+) __HAL_SMBUS_DISABLE: Disable the SMBUS peripheral
00087       (+) __HAL_SMBUS_GET_FLAG : Checks whether the specified SMBUS flag is set or not
00088       (+) __HAL_SMBUS_CLEAR_FLAG : Clears the specified SMBUS pending flag
00089       (+) __HAL_SMBUS_ENABLE_IT: Enables the specified SMBUS interrupt
00090       (+) __HAL_SMBUS_DISABLE_IT: Disables the specified SMBUS interrupt
00091 
00092      [..]
00093        (@) You can refer to the SMBUS HAL driver header file for more useful macros
00094 
00095             
00096   @endverbatim
00097   ******************************************************************************
00098   * @attention
00099   *
00100   * <h2><center>&copy; COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
00101   *
00102   * Redistribution and use in source and binary forms, with or without modification,
00103   * are permitted provided that the following conditions are met:
00104   *   1. Redistributions of source code must retain the above copyright notice,
00105   *      this list of conditions and the following disclaimer.
00106   *   2. Redistributions in binary form must reproduce the above copyright notice,
00107   *      this list of conditions and the following disclaimer in the documentation
00108   *      and/or other materials provided with the distribution.
00109   *   3. Neither the name of STMicroelectronics nor the names of its contributors
00110   *      may be used to endorse or promote products derived from this software
00111   *      without specific prior written permission.
00112   *
00113   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00114   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00115   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00116   * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
00117   * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00118   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
00119   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00120   * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00121   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00122   * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00123   *
00124   ******************************************************************************  
00125   */ 
00126 
00127 /* Includes ------------------------------------------------------------------*/
00128 #include "stm32l4xx_hal.h"
00129 
00130 /** @addtogroup STM32L4xx_HAL_Driver
00131   * @{
00132   */
00133 
00134 /** @defgroup SMBUS SMBUS
00135   * @brief SMBUS HAL module driver
00136   * @{
00137   */
00138 
00139 #ifdef HAL_SMBUS_MODULE_ENABLED
00140 
00141 /* Private typedef -----------------------------------------------------------*/
00142 /* Private constants ---------------------------------------------------------*/
00143 /** @defgroup SMBUS_Private_Define SMBUS Private Constants
00144  * @{
00145  */
00146 #define TIMING_CLEAR_MASK   ((uint32_t)0xF0FFFFFF)      /*<! SMBUS TIMING clear register Mask */
00147 #define HAL_TIMEOUT_ADDR    ((uint32_t)10000)           /* 10 s  */
00148 #define HAL_TIMEOUT_BUSY    ((uint32_t)25)              /* 25 ms */
00149 #define HAL_TIMEOUT_DIR     ((uint32_t)25)              /* 25 ms */
00150 #define HAL_TIMEOUT_RXNE    ((uint32_t)25)              /* 25 ms */
00151 #define HAL_TIMEOUT_STOPF   ((uint32_t)25)              /* 25 ms */
00152 #define HAL_TIMEOUT_TC      ((uint32_t)25)              /* 25 ms */
00153 #define HAL_TIMEOUT_TCR     ((uint32_t)25)              /* 25 ms */
00154 #define HAL_TIMEOUT_TXIS    ((uint32_t)25)              /* 25 ms */
00155 #define MAX_NBYTE_SIZE      255
00156 /**
00157   * @}
00158   */
00159 
00160 /* Private macro -------------------------------------------------------------*/
00161 /* Private variables ---------------------------------------------------------*/
00162 /* Private function prototypes -----------------------------------------------*/
00163 /** @addtogroup SMBUS_Private_Functions SMBUS Private Functions
00164   * @{
00165   */
00166 static HAL_StatusTypeDef SMBUS_WaitOnFlagUntilTimeout(SMBUS_HandleTypeDef *hsmbus, uint32_t Flag, FlagStatus Status, uint32_t Timeout);
00167 
00168 static HAL_StatusTypeDef SMBUS_Enable_IRQ(SMBUS_HandleTypeDef *hsmbus, uint16_t InterruptRequest);
00169 static HAL_StatusTypeDef SMBUS_Disable_IRQ(SMBUS_HandleTypeDef *hsmbus, uint16_t InterruptRequest);
00170 static HAL_StatusTypeDef SMBUS_Master_ISR(SMBUS_HandleTypeDef *hsmbus);
00171 static HAL_StatusTypeDef SMBUS_Slave_ISR(SMBUS_HandleTypeDef *hsmbus);
00172 
00173 static void SMBUS_TransferConfig(SMBUS_HandleTypeDef *hsmbus,  uint16_t DevAddress, uint8_t Size, uint32_t Mode, uint32_t Request);
00174 /**
00175   * @}
00176   */
00177 
00178 /* Exported functions --------------------------------------------------------*/
00179 
00180 /** @defgroup SMBUS_Exported_Functions SMBUS Exported Functions
00181   * @{
00182   */
00183 
00184 /** @defgroup SMBUS_Exported_Functions_Group1 Initialization and de-initialization functions
00185  *  @brief    Initialization and Configuration functions 
00186  *
00187 @verbatim    
00188  ===============================================================================
00189               ##### Initialization and de-initialization functions #####
00190  ===============================================================================
00191     [..]  This subsection provides a set of functions allowing to initialize and 
00192           de-initialize the SMBUSx peripheral:
00193 
00194       (+) User must Implement HAL_SMBUS_MspInit() function in which he configures 
00195           all related peripherals resources (CLOCK, GPIO, IT and NVIC ).
00196 
00197       (+) Call the function HAL_SMBUS_Init() to configure the selected device with 
00198           the selected configuration:
00199         (++) Clock Timing
00200         (++) Bus Timeout
00201         (++) Analog Filer mode
00202         (++) Own Address 1
00203         (++) Addressing mode (Master, Slave)
00204         (++) Dual Addressing mode
00205         (++) Own Address 2
00206         (++) Own Address 2 Mask
00207         (++) General call mode
00208         (++) Nostretch mode
00209         (++) Packet Error Check mode
00210         (++) Peripheral mode
00211 
00212 
00213       (+) Call the function HAL_SMBUS_DeInit() to restore the default configuration 
00214           of the selected SMBUSx peripheral.       
00215 
00216 @endverbatim
00217   * @{
00218   */
00219 
00220 /**
00221   * @brief  Initialize the SMBUS according to the specified parameters 
00222   *         in the SMBUS_InitTypeDef and initialize the associated handle.
00223   * @param  hsmbus : Pointer to a SMBUS_HandleTypeDef structure that contains
00224   *                the configuration information for the specified SMBUS.
00225   * @retval HAL status
00226   */
00227 HAL_StatusTypeDef HAL_SMBUS_Init(SMBUS_HandleTypeDef *hsmbus)
00228 { 
00229   /* Check the SMBUS handle allocation */
00230   if(hsmbus == NULL)
00231   {
00232     return HAL_ERROR;
00233   }
00234   
00235   /* Check the parameters */
00236   assert_param(IS_SMBUS_ALL_INSTANCE(hsmbus->Instance));
00237   assert_param(IS_SMBUS_ANALOG_FILTER(hsmbus->Init.AnalogFilter));
00238   assert_param(IS_SMBUS_OWN_ADDRESS1(hsmbus->Init.OwnAddress1));
00239   assert_param(IS_SMBUS_ADDRESSING_MODE(hsmbus->Init.AddressingMode));
00240   assert_param(IS_SMBUS_DUAL_ADDRESS(hsmbus->Init.DualAddressMode));
00241   assert_param(IS_SMBUS_OWN_ADDRESS2(hsmbus->Init.OwnAddress2));
00242   assert_param(IS_SMBUS_OWN_ADDRESS2_MASK(hsmbus->Init.OwnAddress2Masks));
00243   assert_param(IS_SMBUS_GENERAL_CALL(hsmbus->Init.GeneralCallMode));
00244   assert_param(IS_SMBUS_NO_STRETCH(hsmbus->Init.NoStretchMode));
00245   assert_param(IS_SMBUS_PEC(hsmbus->Init.PacketErrorCheckMode));
00246   assert_param(IS_SMBUS_PERIPHERAL_MODE(hsmbus->Init.PeripheralMode));
00247 
00248   if(hsmbus->State == HAL_SMBUS_STATE_RESET)
00249   {
00250     /* Allocate lock resource and initialize it */
00251     hsmbus->Lock = HAL_UNLOCKED;
00252 
00253     /* Init the low level hardware : GPIO, CLOCK, NVIC */
00254     HAL_SMBUS_MspInit(hsmbus);
00255   }
00256   
00257   hsmbus->State = HAL_SMBUS_STATE_BUSY;
00258   
00259   /* Disable the selected SMBUS peripheral */
00260   __HAL_SMBUS_DISABLE(hsmbus);
00261   
00262   /*---------------------------- SMBUSx TIMINGR Configuration ------------------------*/  
00263   /* Configure SMBUSx: Frequency range */
00264   hsmbus->Instance->TIMINGR = hsmbus->Init.Timing & TIMING_CLEAR_MASK;
00265   
00266   /*---------------------------- SMBUSx TIMEOUTR Configuration ------------------------*/  
00267   /* Configure SMBUSx: Bus Timeout  */
00268   hsmbus->Instance->TIMEOUTR &= ~I2C_TIMEOUTR_TIMOUTEN;
00269   hsmbus->Instance->TIMEOUTR &= ~I2C_TIMEOUTR_TEXTEN;
00270   hsmbus->Instance->TIMEOUTR = hsmbus->Init.SMBusTimeout;
00271 
00272   /*---------------------------- SMBUSx OAR1 Configuration -----------------------*/
00273   /* Configure SMBUSx: Own Address1 and ack own address1 mode */
00274   hsmbus->Instance->OAR1 &= ~I2C_OAR1_OA1EN;
00275   
00276   if(hsmbus->Init.OwnAddress1 != 0)
00277   {
00278     if(hsmbus->Init.AddressingMode == SMBUS_ADDRESSINGMODE_7BIT)
00279   {
00280     hsmbus->Instance->OAR1 = (I2C_OAR1_OA1EN | hsmbus->Init.OwnAddress1);
00281   }
00282     else /* SMBUS_ADDRESSINGMODE_10BIT */
00283   {
00284     hsmbus->Instance->OAR1 = (I2C_OAR1_OA1EN | I2C_OAR1_OA1MODE | hsmbus->Init.OwnAddress1);
00285   }
00286   }
00287 
00288   /*---------------------------- SMBUSx CR2 Configuration ------------------------*/
00289   /* Configure SMBUSx: Addressing Master mode */
00290   if(hsmbus->Init.AddressingMode == SMBUS_ADDRESSINGMODE_10BIT)
00291   {
00292     hsmbus->Instance->CR2 = (I2C_CR2_ADD10);
00293   }
00294   /* Enable the AUTOEND by default, and enable NACK (should be disable only during Slave process) */
00295   /* AUTOEND and NACK bit will be manage during Transfer process */
00296   hsmbus->Instance->CR2 |= (I2C_CR2_AUTOEND | I2C_CR2_NACK);
00297   
00298   /*---------------------------- SMBUSx OAR2 Configuration -----------------------*/  
00299   /* Configure SMBUSx: Dual mode and Own Address2 */
00300   hsmbus->Instance->OAR2 = (hsmbus->Init.DualAddressMode | hsmbus->Init.OwnAddress2 | (hsmbus->Init.OwnAddress2Masks << 8));
00301 
00302   /*---------------------------- SMBUSx CR1 Configuration ------------------------*/
00303   /* Configure SMBUSx: Generalcall and NoStretch mode */
00304   hsmbus->Instance->CR1 = (hsmbus->Init.GeneralCallMode | hsmbus->Init.NoStretchMode | hsmbus->Init.PacketErrorCheckMode | hsmbus->Init.PeripheralMode | hsmbus->Init.AnalogFilter);
00305   
00306   /* Enable Slave Byte Control only in case of Packet Error Check is enabled and SMBUS Peripheral is set in Slave mode */
00307   if( (hsmbus->Init.PacketErrorCheckMode == SMBUS_PEC_ENABLE)
00308      && ( (hsmbus->Init.PeripheralMode == SMBUS_PERIPHERAL_MODE_SMBUS_SLAVE) || (hsmbus->Init.PeripheralMode == SMBUS_PERIPHERAL_MODE_SMBUS_SLAVE_ARP) ) )
00309   {
00310     hsmbus->Instance->CR1 |= I2C_CR1_SBC;
00311   }
00312 
00313   /* Enable the selected SMBUS peripheral */
00314   __HAL_SMBUS_ENABLE(hsmbus);
00315   
00316   hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE;
00317   hsmbus->PreviousState = HAL_SMBUS_STATE_READY;
00318   hsmbus->State = HAL_SMBUS_STATE_READY;
00319   
00320   return HAL_OK;
00321 }
00322 
00323 /**
00324   * @brief  DeInitialize the SMBUS peripheral. 
00325   * @param  hsmbus : Pointer to a SMBUS_HandleTypeDef structure that contains
00326   *                the configuration information for the specified SMBUS.
00327   * @retval HAL status
00328   */
00329 HAL_StatusTypeDef HAL_SMBUS_DeInit(SMBUS_HandleTypeDef *hsmbus)
00330 {
00331   /* Check the SMBUS handle allocation */
00332   if(hsmbus == NULL)
00333   {
00334     return HAL_ERROR;
00335   }
00336   
00337   /* Check the parameters */
00338   assert_param(IS_SMBUS_ALL_INSTANCE(hsmbus->Instance));
00339   
00340   hsmbus->State = HAL_SMBUS_STATE_BUSY;
00341   
00342   /* Disable the SMBUS Peripheral Clock */
00343   __HAL_SMBUS_DISABLE(hsmbus);
00344   
00345   /* DeInit the low level hardware: GPIO, CLOCK, NVIC */
00346   HAL_SMBUS_MspDeInit(hsmbus);
00347   
00348   hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE;
00349   hsmbus->PreviousState =  HAL_SMBUS_STATE_RESET;
00350   hsmbus->State = HAL_SMBUS_STATE_RESET;
00351   
00352    /* Release Lock */
00353   __HAL_UNLOCK(hsmbus);
00354   
00355   return HAL_OK;
00356 }
00357 
00358 /**
00359   * @brief Initialize the SMBUS MSP.
00360   * @param  hsmbus : Pointer to a SMBUS_HandleTypeDef structure that contains
00361   *                the configuration information for the specified SMBUS.
00362   * @retval None
00363   */
00364 __weak void HAL_SMBUS_MspInit(SMBUS_HandleTypeDef *hsmbus)
00365 {
00366   /* Prevent unused argument(s) compilation warning */
00367   UNUSED(hsmbus);
00368 
00369   /* NOTE : This function should not be modified, when the callback is needed,
00370             the HAL_SMBUS_MspInit could be implemented in the user file
00371    */ 
00372 }
00373 
00374 /**
00375   * @brief DeInitialize the SMBUS MSP.
00376   * @param  hsmbus : Pointer to a SMBUS_HandleTypeDef structure that contains
00377   *                the configuration information for the specified SMBUS.
00378   * @retval None
00379   */
00380 __weak void HAL_SMBUS_MspDeInit(SMBUS_HandleTypeDef *hsmbus)
00381 {
00382   /* Prevent unused argument(s) compilation warning */
00383   UNUSED(hsmbus);
00384 
00385   /* NOTE : This function should not be modified, when the callback is needed,
00386             the HAL_SMBUS_MspDeInit could be implemented in the user file
00387    */ 
00388 }
00389 
00390 /**
00391   * @}
00392   */
00393 
00394 /** @defgroup SMBUS_Exported_Functions_Group2 Input and Output operation functions
00395  *  @brief   Data transfers functions 
00396  *
00397 @verbatim   
00398  ===============================================================================
00399                       ##### IO operation functions #####
00400  ===============================================================================  
00401     [..]
00402     This subsection provides a set of functions allowing to manage the SMBUS data 
00403     transfers.
00404 
00405     (#) Blocking mode function to check if device is ready for usage is :
00406         (++) HAL_SMBUS_IsDeviceReady()
00407 
00408     (#) There is only one mode of transfer:
00409        (++) No-Blocking mode : The communication is performed using Interrupts.
00410             These functions return the status of the transfer startup.
00411             The end of the data processing will be indicated through the 
00412             dedicated SMBUS IRQ when using Interrupt mode.
00413 
00414     (#) No-Blocking mode functions with Interrupt are :
00415         (++) HAL_SMBUS_Master_Transmit_IT()
00416         (++) HAL_SMBUS_Master_Receive_IT()
00417         (++) HAL_SMBUS_Slave_Transmit_IT()
00418         (++) HAL_SMBUS_Slave_Receive_IT()
00419         (++) HAL_SMBUS_EnableListen_IT() or alias HAL_SMBUS_EnableListen_IT()
00420         (++) HAL_SMBUS_DisableListen_IT()
00421         (++) HAL_SMBUS_EnableAlert_IT()
00422         (++) HAL_SMBUS_DisableAlert_IT()
00423 
00424     (#) A set of Transfer Complete Callbacks are provided in No_Blocking mode:
00425         (++) HAL_SMBUS_MasterTxCpltCallback()
00426         (++) HAL_SMBUS_MasterRxCpltCallback()
00427         (++) HAL_SMBUS_SlaveTxCpltCallback()
00428         (++) HAL_SMBUS_SlaveRxCpltCallback()
00429         (++) HAL_SMBUS_AddrCallback()
00430         (++) HAL_SMBUS_ListenCpltCallback()
00431         (++) HAL_SMBUS_ErrorCallback()
00432 
00433 @endverbatim
00434   * @{
00435   */
00436 
00437 /**
00438   * @brief  Transmit in master/host SMBUS mode an amount of data in non-blocking mode with Interrupt.
00439   * @param  hsmbus : Pointer to a SMBUS_HandleTypeDef structure that contains
00440   *                the configuration information for the specified SMBUS.
00441   * @param  DevAddress: Target device address
00442   * @param  pData: Pointer to data buffer
00443   * @param  Size: Amount of data to be sent
00444   * @param  XferOptions: Options of Transfer, value of @ref SMBUS_XferOptions_definition
00445   * @retval HAL status
00446   */
00447 HAL_StatusTypeDef HAL_SMBUS_Master_Transmit_IT(SMBUS_HandleTypeDef *hsmbus, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t XferOptions)
00448 {   
00449   /* Check the parameters */
00450   assert_param(IS_SMBUS_TRANSFER_OPTIONS_REQUEST(XferOptions));
00451 
00452   if(hsmbus->State == HAL_SMBUS_STATE_READY)
00453   {
00454     /* Process Locked */
00455     __HAL_LOCK(hsmbus);
00456     
00457     hsmbus->State = HAL_SMBUS_STATE_MASTER_BUSY_TX;
00458     hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE;
00459     /* Prepare transfer parameters */
00460     hsmbus->pBuffPtr = pData;
00461     hsmbus->XferCount = Size;
00462     hsmbus->XferOptions = XferOptions;
00463 
00464     /* In case of Quick command, remove autoend mode */
00465     /* Manage the stop generation by software */
00466     if(hsmbus->pBuffPtr == NULL)
00467     {
00468       hsmbus->XferOptions &= ~SMBUS_AUTOEND_MODE;
00469     }
00470 
00471     if(Size > MAX_NBYTE_SIZE)
00472     {
00473       hsmbus->XferSize = MAX_NBYTE_SIZE;
00474     }
00475     else
00476     {
00477       hsmbus->XferSize = Size;
00478     }
00479     
00480     /* Send Slave Address */
00481     /* Set NBYTES to write and reload if size > MAX_NBYTE_SIZE and generate RESTART */
00482     if( (hsmbus->XferSize == MAX_NBYTE_SIZE) && (hsmbus->XferSize < hsmbus->XferCount) )
00483     {
00484       SMBUS_TransferConfig(hsmbus,DevAddress,hsmbus->XferSize, SMBUS_RELOAD_MODE | (hsmbus->XferOptions & SMBUS_SENDPEC_MODE), SMBUS_GENERATE_START_WRITE);
00485     }
00486     else
00487     {
00488       /* If transfer direction not change, do not generate Restart Condition */
00489       /* Mean Previous state is same as current state */
00490       if(hsmbus->PreviousState == HAL_SMBUS_STATE_MASTER_BUSY_TX)
00491       {
00492         SMBUS_TransferConfig(hsmbus,DevAddress,hsmbus->XferSize, hsmbus->XferOptions, SMBUS_NO_STARTSTOP);
00493       }
00494       /* Else transfer direction change, so generate Restart with new transfer direction */
00495       else
00496       {
00497         SMBUS_TransferConfig(hsmbus,DevAddress,hsmbus->XferSize, hsmbus->XferOptions, SMBUS_GENERATE_START_WRITE);
00498       }
00499 
00500       /* If PEC mode is enable, size to transmit manage by SW part should be Size-1 byte, corresponding to PEC byte */
00501       /* PEC byte is automatically sent by HW block, no need to manage it in Transmit process */
00502       if(SMBUS_GET_PEC_MODE(hsmbus) != RESET)
00503       {
00504         hsmbus->XferSize--;
00505         hsmbus->XferCount--;
00506       }
00507     }
00508     
00509     /* Process Unlocked */
00510     __HAL_UNLOCK(hsmbus); 
00511 
00512     /* Note : The SMBUS interrupts must be enabled after unlocking current process 
00513               to avoid the risk of SMBUS interrupt handle execution before current
00514               process unlock */
00515     SMBUS_Enable_IRQ(hsmbus, SMBUS_IT_TX);
00516     
00517     return HAL_OK;
00518   }
00519   else
00520   {
00521     return HAL_BUSY;
00522   } 
00523 }
00524 
00525 /**
00526   * @brief  Receive in master/host SMBUS mode an amount of data in non-blocking mode with Interrupt.
00527   * @param  hsmbus : Pointer to a SMBUS_HandleTypeDef structure that contains
00528   *                the configuration information for the specified SMBUS.
00529   * @param  DevAddress: Target device address
00530   * @param  pData: Pointer to data buffer
00531   * @param  Size: Amount of data to be sent
00532   * @param  XferOptions: Options of Transfer, value of @ref SMBUS_XferOptions_definition
00533   * @retval HAL status
00534   */
00535 HAL_StatusTypeDef HAL_SMBUS_Master_Receive_IT(SMBUS_HandleTypeDef *hsmbus, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t XferOptions)
00536 {
00537   /* Check the parameters */
00538   assert_param(IS_SMBUS_TRANSFER_OPTIONS_REQUEST(XferOptions));
00539 
00540   if(hsmbus->State == HAL_SMBUS_STATE_READY)
00541   {
00542     /* Process Locked */
00543     __HAL_LOCK(hsmbus);
00544     
00545     hsmbus->State = HAL_SMBUS_STATE_MASTER_BUSY_RX;
00546     hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE;
00547     
00548     /* Prepare transfer parameters */
00549     hsmbus->pBuffPtr = pData;
00550     hsmbus->XferCount = Size;
00551     hsmbus->XferOptions = XferOptions;
00552     
00553     /* In case of Quick command, remove autoend mode */
00554     /* Manage the stop generation by software */
00555     if(hsmbus->pBuffPtr == NULL)
00556     {
00557       hsmbus->XferOptions &= ~SMBUS_AUTOEND_MODE;
00558     }
00559     
00560     if(Size > MAX_NBYTE_SIZE)
00561     {
00562       hsmbus->XferSize = MAX_NBYTE_SIZE;
00563     }
00564     else
00565     {
00566       hsmbus->XferSize = Size;
00567     }
00568     
00569     /* Send Slave Address */
00570     /* Set NBYTES to write and reload if size > MAX_NBYTE_SIZE and generate RESTART */
00571     if( (hsmbus->XferSize == MAX_NBYTE_SIZE) && (hsmbus->XferSize < hsmbus->XferCount) )
00572     {
00573       SMBUS_TransferConfig(hsmbus,DevAddress,hsmbus->XferSize, SMBUS_RELOAD_MODE  | (hsmbus->XferOptions & SMBUS_SENDPEC_MODE), SMBUS_GENERATE_START_READ);
00574     }
00575     else
00576     {
00577       /* If transfer direction not change, do not generate Restart Condition */
00578       /* Mean Previous state is same as current state */
00579       if(hsmbus->PreviousState == HAL_SMBUS_STATE_MASTER_BUSY_RX)
00580       {
00581         SMBUS_TransferConfig(hsmbus,DevAddress,hsmbus->XferSize, hsmbus->XferOptions, SMBUS_NO_STARTSTOP);
00582       }
00583       /* Else transfer direction change, so generate Restart with new transfer direction */
00584       else
00585       {
00586         SMBUS_TransferConfig(hsmbus,DevAddress,hsmbus->XferSize, hsmbus->XferOptions, SMBUS_GENERATE_START_READ);
00587       }
00588     }
00589     
00590     /* Process Unlocked */
00591     __HAL_UNLOCK(hsmbus); 
00592 
00593     /* Note : The SMBUS interrupts must be enabled after unlocking current process 
00594               to avoid the risk of SMBUS interrupt handle execution before current
00595               process unlock */
00596     SMBUS_Enable_IRQ(hsmbus, SMBUS_IT_RX);
00597     
00598     return HAL_OK;
00599   }
00600   else
00601   {
00602     return HAL_BUSY; 
00603   } 
00604 }
00605 
00606 /**
00607   * @brief  Abort a master/host SMBUS process communication with Interrupt.
00608   * @note   This abort can be called only if state is ready
00609   * @param  hsmbus : Pointer to a SMBUS_HandleTypeDef structure that contains
00610   *                the configuration information for the specified SMBUS.
00611   * @param  DevAddress: Target device address
00612   * @retval HAL status
00613   */
00614 HAL_StatusTypeDef HAL_SMBUS_Master_Abort_IT(SMBUS_HandleTypeDef *hsmbus, uint16_t DevAddress)
00615 {
00616   if(hsmbus->State == HAL_SMBUS_STATE_READY)
00617   {
00618     /* Process Locked */
00619     __HAL_LOCK(hsmbus);
00620     
00621     /* Keep the same state as previous */
00622     /* to perform as well the call of the corresponding end of transfer callback */
00623     if(hsmbus->PreviousState == HAL_SMBUS_STATE_MASTER_BUSY_TX)
00624     {
00625       hsmbus->State = HAL_SMBUS_STATE_MASTER_BUSY_TX;
00626     }
00627     else if(hsmbus->PreviousState == HAL_SMBUS_STATE_MASTER_BUSY_RX)
00628     {
00629       hsmbus->State = HAL_SMBUS_STATE_MASTER_BUSY_RX;
00630     }
00631     else
00632     {
00633       /* Wrong usage of abort function */
00634       /* This function should be used only in case of abort monitored by master device */
00635       return HAL_ERROR;
00636     }
00637     hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE;
00638     
00639     /* Set NBYTES to 1 to generate a dummy read on SMBUS peripheral */
00640     /* Set AUTOEND mode, this will generate a NACK then STOP condition to abort the current transfer */
00641     SMBUS_TransferConfig(hsmbus, DevAddress, 1, SMBUS_AUTOEND_MODE, SMBUS_NO_STARTSTOP);
00642     
00643     /* Process Unlocked */
00644     __HAL_UNLOCK(hsmbus); 
00645 
00646     /* Note : The SMBUS interrupts must be enabled after unlocking current process 
00647               to avoid the risk of SMBUS interrupt handle execution before current
00648               process unlock */
00649     if(hsmbus->State == HAL_SMBUS_STATE_MASTER_BUSY_TX)
00650     {
00651       SMBUS_Enable_IRQ(hsmbus, SMBUS_IT_TX);
00652     }
00653     else if(hsmbus->State == HAL_SMBUS_STATE_MASTER_BUSY_RX)
00654     {
00655       SMBUS_Enable_IRQ(hsmbus, SMBUS_IT_RX);
00656     }
00657     
00658     return HAL_OK;
00659   }
00660   else
00661   {
00662     return HAL_BUSY; 
00663   } 
00664 }
00665 
00666 /**
00667   * @brief  Transmit in slave/device SMBUS mode an amount of data in non-blocking mode with Interrupt.
00668   * @param  hsmbus : Pointer to a SMBUS_HandleTypeDef structure that contains
00669   *                the configuration information for the specified SMBUS.
00670   * @param  pData: Pointer to data buffer
00671   * @param  Size: Amount of data to be sent
00672   * @param  XferOptions: Options of Transfer, value of @ref SMBUS_XferOptions_definition
00673   * @retval HAL status
00674   */
00675 HAL_StatusTypeDef HAL_SMBUS_Slave_Transmit_IT(SMBUS_HandleTypeDef *hsmbus, uint8_t *pData, uint16_t Size, uint32_t XferOptions)
00676 {
00677   /* Check the parameters */
00678   assert_param(IS_SMBUS_TRANSFER_OPTIONS_REQUEST(XferOptions));
00679 
00680   if(hsmbus->State == HAL_SMBUS_STATE_LISTEN)
00681   {
00682     if((pData == NULL) || (Size == 0)) 
00683     {
00684       return  HAL_ERROR;                                    
00685     }
00686 
00687     /* Disable Interrupts, to prevent preemption during treatment in case of multicall */
00688     SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_ADDR | SMBUS_IT_TX);
00689 
00690     /* Process Locked */
00691     __HAL_LOCK(hsmbus);
00692     
00693     hsmbus->State |= HAL_SMBUS_STATE_SLAVE_BUSY_TX;
00694     hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE;
00695     
00696     /* Set SBC bit to manage Acknowledge at each bit */
00697     hsmbus->Instance->CR1 |= I2C_CR1_SBC;
00698 
00699     /* Enable Address Acknowledge */
00700     hsmbus->Instance->CR2 &= ~I2C_CR2_NACK;
00701 
00702     /* Prepare transfer parameters */
00703     hsmbus->pBuffPtr = pData;
00704     hsmbus->XferSize = Size;
00705     hsmbus->XferCount = Size;
00706     hsmbus->XferOptions = XferOptions;
00707 
00708     if(Size > MAX_NBYTE_SIZE)
00709     {
00710       hsmbus->XferSize = MAX_NBYTE_SIZE;
00711     }
00712     else
00713     {
00714       hsmbus->XferSize = Size;
00715     }
00716 
00717     /* Set NBYTES to write and reload if size > MAX_NBYTE_SIZE and generate RESTART */
00718     if( (hsmbus->XferSize == MAX_NBYTE_SIZE) && (hsmbus->XferSize < hsmbus->XferCount) )
00719     {
00720       SMBUS_TransferConfig(hsmbus,0,hsmbus->XferSize, SMBUS_RELOAD_MODE | (hsmbus->XferOptions & SMBUS_SENDPEC_MODE), SMBUS_NO_STARTSTOP);
00721     }
00722     else
00723     {
00724       /* Set NBYTE to transmit */
00725       SMBUS_TransferConfig(hsmbus,0,hsmbus->XferSize, hsmbus->XferOptions, SMBUS_NO_STARTSTOP);
00726 
00727       /* If PEC mode is enable, size to transmit should be Size-1 byte, corresponding to PEC byte */
00728       /* PEC byte is automatically sent by HW block, no need to manage it in Transmit process */
00729       if(SMBUS_GET_PEC_MODE(hsmbus) != RESET)
00730       {
00731         hsmbus->XferSize--;
00732         hsmbus->XferCount--;
00733       }
00734     }
00735     
00736     /* Clear ADDR flag after prepare the transfer parameters */
00737     /* This action will generate an acknowledge to the HOST */
00738     __HAL_SMBUS_CLEAR_FLAG(hsmbus,SMBUS_FLAG_ADDR);
00739 
00740     /* Process Unlocked */
00741     __HAL_UNLOCK(hsmbus); 
00742 
00743     /* Note : The SMBUS interrupts must be enabled after unlocking current process 
00744               to avoid the risk of SMBUS interrupt handle execution before current
00745               process unlock */
00746     /* REnable ADDR interrupt */
00747     SMBUS_Enable_IRQ(hsmbus, SMBUS_IT_TX | SMBUS_IT_ADDR);
00748 
00749     return HAL_OK;
00750   }
00751   else
00752   {
00753     return HAL_ERROR; 
00754   } 
00755 }
00756 
00757 /**
00758   * @brief  Receive in slave/device SMBUS mode an amount of data in non-blocking mode with Interrupt.
00759   * @param  hsmbus : Pointer to a SMBUS_HandleTypeDef structure that contains
00760   *                the configuration information for the specified SMBUS.
00761   * @param  pData: Pointer to data buffer
00762   * @param  Size: Amount of data to be sent
00763   * @param  XferOptions: Options of Transfer, value of @ref SMBUS_XferOptions_definition
00764   * @retval HAL status
00765   */
00766 HAL_StatusTypeDef HAL_SMBUS_Slave_Receive_IT(SMBUS_HandleTypeDef *hsmbus, uint8_t *pData, uint16_t Size, uint32_t XferOptions)
00767 {
00768   /* Check the parameters */
00769   assert_param(IS_SMBUS_TRANSFER_OPTIONS_REQUEST(XferOptions));
00770 
00771   if(hsmbus->State == HAL_SMBUS_STATE_LISTEN)
00772   {
00773     if((pData == NULL) || (Size == 0)) 
00774     {
00775       return  HAL_ERROR;                                    
00776     }
00777     
00778     /* Disable Interrupts, to prevent preemption during treatment in case of multicall */
00779     SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_ADDR | SMBUS_IT_RX);
00780 
00781     /* Process Locked */
00782     __HAL_LOCK(hsmbus);
00783     
00784     hsmbus->State |= HAL_SMBUS_STATE_SLAVE_BUSY_RX;
00785     hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE;
00786     
00787     /* Set SBC bit to manage Acknowledge at each bit */
00788     hsmbus->Instance->CR1 |= I2C_CR1_SBC;
00789 
00790     /* Enable Address Acknowledge */
00791     hsmbus->Instance->CR2 &= ~I2C_CR2_NACK;
00792 
00793     /* Prepare transfer parameters */
00794     hsmbus->pBuffPtr = pData;
00795     hsmbus->XferSize = Size;
00796     hsmbus->XferCount = Size;
00797     hsmbus->XferOptions = XferOptions;
00798     
00799     /* Set NBYTE to receive */
00800     /* If XferSize equal "1", or XferSize equal "2" with PEC requested (mean 1 data byte + 1 PEC byte */
00801     /* no need to set RELOAD bit mode, a ACK will be automatically generated in that case */
00802     /* else need to set RELOAD bit mode to generate an automatic ACK at each byte Received */
00803     /* This RELOAD bit will be reset for last BYTE to be receive in SMBUS_Slave_ISR */
00804     if((hsmbus->XferSize == 1) || ((hsmbus->XferSize == 2) && (SMBUS_GET_PEC_MODE(hsmbus) != RESET)))
00805     {
00806       SMBUS_TransferConfig(hsmbus,0,hsmbus->XferSize, hsmbus->XferOptions, SMBUS_NO_STARTSTOP);
00807     }
00808     else
00809     {
00810       SMBUS_TransferConfig(hsmbus,0, 1, hsmbus->XferOptions | SMBUS_RELOAD_MODE, SMBUS_NO_STARTSTOP);
00811     }
00812 
00813     /* Clear ADDR flag after prepare the transfer parameters */
00814     /* This action will generate an acknowledge to the HOST */
00815     __HAL_SMBUS_CLEAR_FLAG(hsmbus,SMBUS_FLAG_ADDR);
00816 
00817     /* Process Unlocked */
00818     __HAL_UNLOCK(hsmbus); 
00819 
00820     /* Note : The SMBUS interrupts must be enabled after unlocking current process 
00821               to avoid the risk of SMBUS interrupt handle execution before current
00822               process unlock */
00823     /* REnable ADDR interrupt */
00824     SMBUS_Enable_IRQ(hsmbus, SMBUS_IT_RX | SMBUS_IT_ADDR);
00825 
00826     return HAL_OK;
00827   }
00828   else
00829   {
00830     return HAL_ERROR; 
00831   }
00832 }
00833 
00834 /**
00835   * @brief  Enable the Address listen mode with Interrupt.
00836   * @param  hsmbus : Pointer to a SMBUS_HandleTypeDef structure that contains
00837   *                the configuration information for the specified SMBUS.
00838   * @retval HAL status
00839   */
00840 HAL_StatusTypeDef HAL_SMBUS_EnableListen_IT(SMBUS_HandleTypeDef *hsmbus)
00841 {
00842   hsmbus->State = HAL_SMBUS_STATE_LISTEN;
00843   
00844   /* Enable the Address Match interrupt */
00845   SMBUS_Enable_IRQ(hsmbus, SMBUS_IT_ADDR);
00846   
00847   return HAL_OK;
00848 }
00849 
00850 /**
00851   * @brief  Disable the Address listen mode with Interrupt.
00852   * @param  hsmbus : Pointer to a SMBUS_HandleTypeDef structure that contains
00853   *                the configuration information for the specified SMBUS.
00854   * @retval HAL status
00855   */
00856 HAL_StatusTypeDef HAL_SMBUS_DisableListen_IT(SMBUS_HandleTypeDef *hsmbus)
00857 {
00858   /* Disable Address listen mode only if a transfer is not ongoing */
00859   if(hsmbus->State == HAL_SMBUS_STATE_LISTEN)
00860   {
00861     hsmbus->State = HAL_SMBUS_STATE_READY;
00862   
00863     /* Disable the Address Match interrupt */
00864     SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_ADDR);
00865   
00866     return HAL_OK;
00867   }
00868   else
00869   {
00870     return HAL_BUSY;
00871   }
00872 }
00873 
00874 /**
00875   * @brief  Enable the SMBUS alert mode with Interrupt.
00876   * @param  hsmbus : pointer to a SMBUS_HandleTypeDef structure that contains
00877   *                the configuration information for the specified SMBUSx peripheral.
00878   * @retval HAL status
00879   */
00880 HAL_StatusTypeDef HAL_SMBUS_EnableAlert_IT(SMBUS_HandleTypeDef *hsmbus)
00881 {
00882   /* Enable SMBus alert */
00883   hsmbus->Instance->CR1 |= I2C_CR1_ALERTEN;   
00884 
00885   /* Clear ALERT flag */
00886   __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_ALERT);
00887 
00888   /* Enable Alert Interrupt */
00889   SMBUS_Enable_IRQ(hsmbus, SMBUS_IT_ALERT);
00890 
00891   return HAL_OK; 
00892 }
00893 /**
00894   * @brief  Disable the SMBUS alert mode with Interrupt.
00895   * @param  hsmbus : pointer to a SMBUS_HandleTypeDef structure that contains
00896   *                the configuration information for the specified SMBUSx peripheral.
00897   * @retval HAL status
00898   */
00899 HAL_StatusTypeDef HAL_SMBUS_DisableAlert_IT(SMBUS_HandleTypeDef *hsmbus)
00900 {
00901   /* Enable SMBus alert */
00902   hsmbus->Instance->CR1 &= ~I2C_CR1_ALERTEN;   
00903   
00904   /* Disable Alert Interrupt */
00905   SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_ALERT);
00906 
00907   return HAL_OK; 
00908 }
00909 
00910 /**
00911   * @brief  Check if target device is ready for communication. 
00912   * @note   This function is used with Memory devices
00913   * @param  hsmbus : Pointer to a SMBUS_HandleTypeDef structure that contains
00914   *                the configuration information for the specified SMBUS.
00915   * @param  DevAddress: Target device address
00916   * @param  Trials: Number of trials
00917   * @param  Timeout: Timeout duration
00918   * @retval HAL status
00919   */
00920 HAL_StatusTypeDef HAL_SMBUS_IsDeviceReady(SMBUS_HandleTypeDef *hsmbus, uint16_t DevAddress, uint32_t Trials, uint32_t Timeout)
00921 {  
00922   uint32_t tickstart = 0;
00923   
00924   __IO uint32_t SMBUS_Trials = 0;
00925  
00926   if(hsmbus->State == HAL_SMBUS_STATE_READY)
00927   {
00928     if(__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_BUSY) != RESET)
00929     {
00930       return HAL_BUSY;
00931     }
00932 
00933     /* Process Locked */
00934     __HAL_LOCK(hsmbus);
00935     
00936     hsmbus->State = HAL_SMBUS_STATE_BUSY;
00937     hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE;
00938     
00939     do
00940     {
00941       /* Generate Start */
00942       hsmbus->Instance->CR2 = SMBUS_GENERATE_START(hsmbus->Init.AddressingMode,DevAddress);
00943       
00944       /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */
00945       /* Wait until STOPF flag is set or a NACK flag is set*/
00946       tickstart = HAL_GetTick();
00947       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))
00948       {
00949         if(Timeout != HAL_MAX_DELAY)
00950         {    
00951           if((Timeout == 0) || ((HAL_GetTick()-tickstart) > Timeout))
00952           {
00953             /* Device is ready */
00954             hsmbus->State = HAL_SMBUS_STATE_READY;
00955         
00956             /* Process Unlocked */
00957             __HAL_UNLOCK(hsmbus);
00958             return HAL_TIMEOUT;
00959           }
00960         } 
00961       }
00962       
00963       /* Check if the NACKF flag has not been set */
00964       if (__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_AF) == RESET)
00965       {
00966         /* Wait until STOPF flag is reset */ 
00967         if(SMBUS_WaitOnFlagUntilTimeout(hsmbus, SMBUS_FLAG_STOPF, RESET, Timeout) != HAL_OK)      
00968         {
00969           return HAL_TIMEOUT;
00970         }
00971         
00972         /* Clear STOP Flag */
00973         __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_STOPF);
00974 
00975         /* Device is ready */
00976         hsmbus->State = HAL_SMBUS_STATE_READY;
00977         
00978         /* Process Unlocked */
00979         __HAL_UNLOCK(hsmbus);
00980         
00981         return HAL_OK;
00982       }
00983       else
00984       {
00985         /* Wait until STOPF flag is reset */ 
00986         if(SMBUS_WaitOnFlagUntilTimeout(hsmbus, SMBUS_FLAG_STOPF, RESET, Timeout) != HAL_OK)      
00987         {
00988           return HAL_TIMEOUT;
00989         }
00990 
00991         /* Clear NACK Flag */
00992         __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_AF);
00993 
00994         /* Clear STOP Flag, auto generated with autoend*/
00995         __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_STOPF);
00996       }
00997       
00998       /* Check if the maximum allowed number of trials has been reached */
00999       if (SMBUS_Trials++ == Trials)
01000       {
01001         /* Generate Stop */
01002         hsmbus->Instance->CR2 |= I2C_CR2_STOP;
01003         
01004         /* Wait until STOPF flag is reset */ 
01005         if(SMBUS_WaitOnFlagUntilTimeout(hsmbus, SMBUS_FLAG_STOPF, RESET, Timeout) != HAL_OK)      
01006         {
01007           return HAL_TIMEOUT;
01008         }
01009         
01010         /* Clear STOP Flag */
01011         __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_STOPF);
01012       }      
01013     }while(SMBUS_Trials < Trials);
01014 
01015     hsmbus->State = HAL_SMBUS_STATE_READY;
01016 
01017     /* Process Unlocked */
01018     __HAL_UNLOCK(hsmbus);
01019         
01020     return HAL_TIMEOUT;
01021   }      
01022   else
01023   {
01024     return HAL_BUSY;
01025   }
01026 }
01027 /**
01028   * @}
01029   */
01030 
01031 /** @defgroup SMBUS_IRQ_Handler_and_Callbacks IRQ Handler and Callbacks
01032  * @{
01033  */
01034 
01035 /**
01036   * @brief  Handle SMBUS event interrupt request.
01037   * @param  hsmbus : Pointer to a SMBUS_HandleTypeDef structure that contains
01038   *                the configuration information for the specified SMBUS.
01039   * @retval None
01040   */
01041 void HAL_SMBUS_EV_IRQHandler(SMBUS_HandleTypeDef *hsmbus)
01042 {
01043   uint32_t tmpisrvalue = 0;
01044   
01045   /* Use a local variable to store the current ISR flags */
01046   /* This action will avoid a wrong treatment due to ISR flags change during interrupt handler */
01047   tmpisrvalue = SMBUS_GET_ISR_REG(hsmbus);
01048     
01049   /* SMBUS in mode Transmitter ---------------------------------------------------*/
01050   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))
01051   {     
01052     /* Slave mode selected */
01053     if ((hsmbus->State & HAL_SMBUS_STATE_SLAVE_BUSY_TX) == HAL_SMBUS_STATE_SLAVE_BUSY_TX)
01054     {
01055       SMBUS_Slave_ISR(hsmbus);
01056     }
01057     /* Master mode selected */
01058     else if((hsmbus->State & HAL_SMBUS_STATE_MASTER_BUSY_TX) == HAL_SMBUS_STATE_MASTER_BUSY_TX)
01059     {
01060       SMBUS_Master_ISR(hsmbus);
01061     }
01062   }
01063     
01064   /* SMBUS in mode Receiver ----------------------------------------------------*/
01065   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))
01066   {
01067     /* Slave mode selected */
01068     if ((hsmbus->State & HAL_SMBUS_STATE_SLAVE_BUSY_RX) == HAL_SMBUS_STATE_SLAVE_BUSY_RX)
01069     {
01070       SMBUS_Slave_ISR(hsmbus);
01071     }
01072     /* Master mode selected */
01073     else if((hsmbus->State & HAL_SMBUS_STATE_MASTER_BUSY_RX) == HAL_SMBUS_STATE_MASTER_BUSY_RX)
01074     {
01075       SMBUS_Master_ISR(hsmbus);
01076     }
01077   } 
01078       
01079    /* SMBUS in mode Listener Only --------------------------------------------------*/
01080   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))
01081      && ((__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)))
01082   {
01083     if (hsmbus->State == HAL_SMBUS_STATE_LISTEN)
01084     {
01085       SMBUS_Slave_ISR(hsmbus);
01086     }
01087   }
01088 }
01089 
01090 /**
01091   * @brief  Handle SMBUS error interrupt request.
01092   * @param  hsmbus : Pointer to a SMBUS_HandleTypeDef structure that contains
01093   *                the configuration information for the specified SMBUS.
01094   * @retval None
01095   */
01096 void HAL_SMBUS_ER_IRQHandler(SMBUS_HandleTypeDef *hsmbus)
01097 {
01098   /* SMBUS Bus error interrupt occurred ------------------------------------*/
01099   if((__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_BERR) != RESET) && (__HAL_SMBUS_GET_IT_SOURCE(hsmbus, SMBUS_IT_ERRI) != RESET))
01100   { 
01101     hsmbus->ErrorCode |= HAL_SMBUS_ERROR_BERR;
01102    
01103     /* Clear BERR flag */
01104     __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_BERR);
01105   }
01106   
01107   /* SMBUS Over-Run/Under-Run interrupt occurred ----------------------------------------*/
01108   if((__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_OVR) != RESET) && (__HAL_SMBUS_GET_IT_SOURCE(hsmbus, SMBUS_IT_ERRI) != RESET))
01109   { 
01110     hsmbus->ErrorCode |= HAL_SMBUS_ERROR_OVR;
01111 
01112     /* Clear OVR flag */
01113     __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_OVR);
01114   }
01115 
01116   /* SMBUS Arbitration Loss error interrupt occurred ------------------------------------*/
01117   if((__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_ARLO) != RESET) && (__HAL_SMBUS_GET_IT_SOURCE(hsmbus, SMBUS_IT_ERRI) != RESET))
01118   { 
01119     hsmbus->ErrorCode |= HAL_SMBUS_ERROR_ARLO;
01120 
01121     /* Clear ARLO flag */
01122     __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_ARLO);
01123   }
01124 
01125   /* SMBUS Timeout error interrupt occurred ---------------------------------------------*/
01126   if((__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_TIMEOUT) != RESET) && (__HAL_SMBUS_GET_IT_SOURCE(hsmbus, SMBUS_IT_ERRI) != RESET))
01127   { 
01128     hsmbus->ErrorCode |= HAL_SMBUS_ERROR_BUSTIMEOUT;
01129 
01130     /* Clear TIMEOUT flag */
01131     __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_TIMEOUT);
01132   }
01133 
01134   /* SMBUS Alert error interrupt occurred -----------------------------------------------*/
01135   if((__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_ALERT) != RESET) && (__HAL_SMBUS_GET_IT_SOURCE(hsmbus, SMBUS_IT_ERRI) != RESET))
01136   { 
01137     hsmbus->ErrorCode |= HAL_SMBUS_ERROR_ALERT;
01138 
01139     /* Clear ALERT flag */
01140     __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_ALERT);
01141   }
01142 
01143   /* SMBUS Packet Error Check error interrupt occurred ----------------------------------*/
01144   if((__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_PECERR) != RESET) && (__HAL_SMBUS_GET_IT_SOURCE(hsmbus, SMBUS_IT_ERRI) != RESET))
01145   { 
01146     hsmbus->ErrorCode |= HAL_SMBUS_ERROR_PECERR;
01147 
01148     /* Clear PEC error flag */
01149     __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_PECERR);
01150   }
01151   
01152   /* Call the Error Callback() in case of Error detected */
01153   if((hsmbus->ErrorCode != HAL_SMBUS_ERROR_NONE)&&(hsmbus->ErrorCode != HAL_SMBUS_ERROR_ACKF))
01154   {
01155     /* Do not Reset the HAL state in case of ALERT error */
01156     if((hsmbus->ErrorCode & HAL_SMBUS_ERROR_ALERT) != HAL_SMBUS_ERROR_ALERT)
01157     {
01158       if(((hsmbus->State & HAL_SMBUS_STATE_SLAVE_BUSY_TX) == HAL_SMBUS_STATE_SLAVE_BUSY_TX)
01159          || ((hsmbus->State & HAL_SMBUS_STATE_SLAVE_BUSY_RX) == HAL_SMBUS_STATE_SLAVE_BUSY_RX))
01160       {
01161         /* Reset only HAL_SMBUS_STATE_SLAVE_BUSY_XX */
01162         /* keep HAL_SMBUS_STATE_LISTEN if set */
01163         hsmbus->PreviousState = HAL_SMBUS_STATE_READY;
01164         hsmbus->State = HAL_SMBUS_STATE_LISTEN;
01165       }
01166     }
01167     
01168     /* Call the Error callback to prevent upper layer */
01169     HAL_SMBUS_ErrorCallback(hsmbus);
01170   }
01171 }
01172 
01173 /**
01174   * @brief  Master Tx Transfer completed callback.
01175   * @param  hsmbus : Pointer to a SMBUS_HandleTypeDef structure that contains
01176   *                the configuration information for the specified SMBUS.
01177   * @retval None
01178   */
01179 __weak void HAL_SMBUS_MasterTxCpltCallback(SMBUS_HandleTypeDef *hsmbus)
01180 {
01181   /* Prevent unused argument(s) compilation warning */
01182   UNUSED(hsmbus);
01183 
01184   /* NOTE : This function should not be modified, when the callback is needed,
01185             the HAL_SMBUS_MasterTxCpltCallback() could be implemented in the user file
01186    */ 
01187 }
01188 
01189 /**
01190   * @brief  Master Rx Transfer completed callback.
01191   * @param  hsmbus : Pointer to a SMBUS_HandleTypeDef structure that contains
01192   *                the configuration information for the specified SMBUS.
01193   * @retval None
01194   */
01195 __weak void HAL_SMBUS_MasterRxCpltCallback(SMBUS_HandleTypeDef *hsmbus)
01196 {
01197   /* Prevent unused argument(s) compilation warning */
01198   UNUSED(hsmbus);
01199 
01200   /* NOTE : This function should not be modified, when the callback is needed,
01201             the HAL_SMBUS_MasterRxCpltCallback() could be implemented in the user file
01202    */
01203 }
01204 
01205 /** @brief  Slave Tx Transfer completed callback.
01206   * @param  hsmbus : Pointer to a SMBUS_HandleTypeDef structure that contains
01207   *                the configuration information for the specified SMBUS.
01208   * @retval None
01209   */
01210 __weak void HAL_SMBUS_SlaveTxCpltCallback(SMBUS_HandleTypeDef *hsmbus)
01211 {
01212   /* Prevent unused argument(s) compilation warning */
01213   UNUSED(hsmbus);
01214 
01215   /* NOTE : This function should not be modified, when the callback is needed,
01216             the HAL_SMBUS_SlaveTxCpltCallback() could be implemented in the user file
01217    */ 
01218 }
01219 
01220 /**
01221   * @brief  Slave Rx Transfer completed callback.
01222   * @param  hsmbus : Pointer to a SMBUS_HandleTypeDef structure that contains
01223   *                the configuration information for the specified SMBUS.
01224   * @retval None
01225   */
01226 __weak void HAL_SMBUS_SlaveRxCpltCallback(SMBUS_HandleTypeDef *hsmbus)
01227 {
01228   /* Prevent unused argument(s) compilation warning */
01229   UNUSED(hsmbus);
01230 
01231   /* NOTE : This function should not be modified, when the callback is needed,
01232             the HAL_SMBUS_SlaveRxCpltCallback() could be implemented in the user file
01233    */
01234 }
01235 
01236 /**
01237   * @brief  Slave Address Match callback.
01238   * @param  hsmbus : Pointer to a SMBUS_HandleTypeDef structure that contains
01239   *                the configuration information for the specified SMBUS.
01240   * @param  TransferDirection: Master request Transfer Direction (Write/Read)
01241   * @param  AddrMatchCode: Address Match Code
01242   * @retval None
01243   */
01244 __weak void HAL_SMBUS_AddrCallback(SMBUS_HandleTypeDef *hsmbus, uint8_t TransferDirection, uint16_t AddrMatchCode)
01245 {
01246   /* Prevent unused argument(s) compilation warning */
01247   UNUSED(hsmbus);
01248   UNUSED(TransferDirection);
01249   UNUSED(AddrMatchCode);
01250 
01251   /* NOTE : This function should not be modified, when the callback is needed,
01252             the HAL_SMBUS_AddrCallback() could be implemented in the user file
01253    */
01254 }
01255 
01256 /**
01257   * @brief  Listen Complete callback.
01258   * @param  hsmbus : Pointer to a SMBUS_HandleTypeDef structure that contains
01259   *                the configuration information for the specified SMBUS.
01260   * @retval None
01261   */
01262 __weak void HAL_SMBUS_ListenCpltCallback(SMBUS_HandleTypeDef *hsmbus)
01263 {
01264   /* Prevent unused argument(s) compilation warning */
01265   UNUSED(hsmbus);
01266 
01267   /* NOTE : This function should not be modified, when the callback is needed,
01268             the HAL_SMBUS_ListenCpltCallback() could be implemented in the user file
01269    */
01270 }
01271 
01272 /**
01273   * @brief  SMBUS error callback.
01274   * @param  hsmbus : Pointer to a SMBUS_HandleTypeDef structure that contains
01275   *                the configuration information for the specified SMBUS.
01276   * @retval None
01277   */
01278 __weak void HAL_SMBUS_ErrorCallback(SMBUS_HandleTypeDef *hsmbus)
01279 {
01280   /* Prevent unused argument(s) compilation warning */
01281   UNUSED(hsmbus);
01282 
01283   /* NOTE : This function should not be modified, when the callback is needed,
01284             the HAL_SMBUS_ErrorCallback() could be implemented in the user file
01285    */ 
01286 }
01287 
01288 /**
01289   * @}
01290   */
01291 
01292 /** @defgroup SMBUS_Exported_Functions_Group3 Peripheral State and Errors functions 
01293  *  @brief   Peripheral State and Errors functions 
01294  *
01295 @verbatim   
01296  ===============================================================================
01297             ##### Peripheral State and Errors functions #####
01298  ===============================================================================  
01299     [..]
01300     This subsection permits to get in run-time the status of the peripheral 
01301     and the data flow.
01302 
01303 @endverbatim
01304   * @{
01305   */
01306 
01307 /**
01308   * @brief  Return the SMBUS handle state.
01309   * @param  hsmbus : Pointer to a SMBUS_HandleTypeDef structure that contains
01310   *                the configuration information for the specified SMBUS.
01311   * @retval HAL state
01312   */
01313 uint32_t HAL_SMBUS_GetState(SMBUS_HandleTypeDef *hsmbus)
01314 {
01315   /* Return SMBUS handle state */
01316   return hsmbus->State;
01317 }
01318 
01319 /**
01320 * @brief  Return the SMBUS error code.
01321 * @param  hsmbus : pointer to a SMBUS_HandleTypeDef structure that contains
01322   *              the configuration information for the specified SMBUS.
01323 * @retval SMBUS Error Code
01324 */
01325 uint32_t HAL_SMBUS_GetError(SMBUS_HandleTypeDef *hsmbus)
01326 {
01327   return hsmbus->ErrorCode;
01328 }
01329 
01330 /**
01331   * @}
01332   */  
01333 
01334 /**
01335   * @}
01336   */  
01337 
01338 /** @addtogroup SMBUS_Private_Functions SMBUS Private Functions
01339  *  @brief   Data transfers Private functions 
01340   * @{
01341   */
01342 
01343 /**
01344   * @brief  Interrupt Sub-Routine which handle the Interrupt Flags Master Mode.
01345   * @param  hsmbus : Pointer to a SMBUS_HandleTypeDef structure that contains
01346   *                the configuration information for the specified SMBUS.
01347   * @retval HAL status
01348   */
01349 static HAL_StatusTypeDef SMBUS_Master_ISR(SMBUS_HandleTypeDef *hsmbus) 
01350 {
01351   uint16_t DevAddress;
01352 
01353   /* Process Locked */
01354   __HAL_LOCK(hsmbus);
01355   
01356   if(__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_AF) != RESET)
01357   {
01358     /* Clear NACK Flag */
01359     __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_AF);
01360     
01361     /* Set corresponding Error Code */
01362     /* No need to generate STOP, it is automatically done */
01363     hsmbus->ErrorCode |= HAL_SMBUS_ERROR_ACKF;
01364 
01365     /* Process Unlocked */
01366     __HAL_UNLOCK(hsmbus);
01367     
01368     /* Call the Error callback to prevent upper layer */
01369     HAL_SMBUS_ErrorCallback(hsmbus);
01370   }
01371   else if(__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_STOPF) != RESET)
01372   {
01373       
01374     /* Call the corresponding callback to inform upper layer of End of Transfer */
01375     if(hsmbus->State == HAL_SMBUS_STATE_MASTER_BUSY_TX)
01376     {
01377       /* Disable Interrupt */
01378       SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_TX);
01379 
01380       /* Clear STOP Flag */
01381       __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_STOPF);
01382       
01383       /* Clear Configuration Register 2 */
01384       SMBUS_RESET_CR2(hsmbus);
01385     
01386       /* Flush remaining data in Fifo register in case of error occurs before TXEmpty */
01387       /* Disable the selected SMBUS peripheral */
01388       __HAL_SMBUS_DISABLE(hsmbus);
01389 
01390       hsmbus->PreviousState = HAL_SMBUS_STATE_READY;
01391       hsmbus->State = HAL_SMBUS_STATE_READY;
01392 
01393       /* Process Unlocked */
01394       __HAL_UNLOCK(hsmbus);
01395   
01396       /* REenable the selected SMBUS peripheral */
01397       __HAL_SMBUS_ENABLE(hsmbus);
01398 
01399       HAL_SMBUS_MasterTxCpltCallback(hsmbus);
01400     }
01401     else if(hsmbus->State == HAL_SMBUS_STATE_MASTER_BUSY_RX)
01402     {
01403       /* Disable Interrupt */
01404       SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_RX);
01405 
01406       /* Clear STOP Flag */
01407       __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_STOPF);
01408       
01409       /* Clear Configuration Register 2 */
01410       SMBUS_RESET_CR2(hsmbus);
01411     
01412       hsmbus->PreviousState = HAL_SMBUS_STATE_READY;
01413       hsmbus->State = HAL_SMBUS_STATE_READY;
01414 
01415       /* Process Unlocked */
01416       __HAL_UNLOCK(hsmbus);
01417   
01418       HAL_SMBUS_MasterRxCpltCallback(hsmbus);
01419     }
01420   }
01421   else if(__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_RXNE) != RESET)
01422   {  
01423     /* Read data from RXDR */
01424     (*hsmbus->pBuffPtr++) = hsmbus->Instance->RXDR;
01425     hsmbus->XferSize--;
01426     hsmbus->XferCount--;
01427   }
01428   else if(__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_TXIS) != RESET)
01429   {
01430     /* Write data to TXDR */
01431     hsmbus->Instance->TXDR = (*hsmbus->pBuffPtr++);
01432     hsmbus->XferSize--;
01433     hsmbus->XferCount--;    
01434   }
01435   else if(__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_TCR) != RESET)
01436   {
01437     if((hsmbus->XferSize == 0)&&(hsmbus->XferCount!=0))
01438     {
01439       DevAddress = (hsmbus->Instance->CR2 & I2C_CR2_SADD);
01440       
01441       if(hsmbus->XferCount > MAX_NBYTE_SIZE)
01442       {    
01443         SMBUS_TransferConfig(hsmbus, DevAddress, MAX_NBYTE_SIZE, (SMBUS_RELOAD_MODE | (hsmbus->XferOptions & SMBUS_SENDPEC_MODE)), SMBUS_NO_STARTSTOP);
01444         hsmbus->XferSize = MAX_NBYTE_SIZE;
01445       }
01446       else
01447       {
01448         hsmbus->XferSize = hsmbus->XferCount;
01449         SMBUS_TransferConfig(hsmbus,DevAddress,hsmbus->XferSize, hsmbus->XferOptions, SMBUS_NO_STARTSTOP);
01450         /* If PEC mode is enable, size to transmit should be Size-1 byte, corresponding to PEC byte */
01451         /* PEC byte is automatically sent by HW block, no need to manage it in Transmit process */
01452         if(SMBUS_GET_PEC_MODE(hsmbus) != RESET)
01453         {
01454           hsmbus->XferSize--;
01455           hsmbus->XferCount--;
01456         }
01457       }
01458     }
01459     else if((hsmbus->XferSize == 0)&&(hsmbus->XferCount==0))
01460     {
01461       /* Call TxCpltCallback() if no stop mode is set */
01462       if(SMBUS_GET_STOP_MODE(hsmbus) != SMBUS_AUTOEND_MODE)
01463       {
01464         /* Call the corresponding callback to inform upper layer of End of Transfer */
01465         if(hsmbus->State == HAL_SMBUS_STATE_MASTER_BUSY_TX)
01466         {
01467           /* Disable Interrupt */
01468           SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_TX);
01469           hsmbus->PreviousState = hsmbus->State;
01470           hsmbus->State = HAL_SMBUS_STATE_READY;
01471 
01472           /* Process Unlocked */
01473           __HAL_UNLOCK(hsmbus);
01474       
01475           HAL_SMBUS_MasterTxCpltCallback(hsmbus);
01476         }
01477         else if(hsmbus->State == HAL_SMBUS_STATE_MASTER_BUSY_RX)
01478         {
01479           SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_RX);
01480           hsmbus->PreviousState = hsmbus->State;
01481           hsmbus->State = HAL_SMBUS_STATE_READY;
01482 
01483           /* Process Unlocked */
01484           __HAL_UNLOCK(hsmbus);
01485       
01486           HAL_SMBUS_MasterRxCpltCallback(hsmbus);
01487         }
01488       }
01489     }
01490   }
01491   else if(__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_TC) != RESET)
01492   {
01493     if(hsmbus->XferCount == 0)
01494     {
01495       /* Specific use case for Quick command */
01496       if(hsmbus->pBuffPtr == NULL)
01497       {
01498         /* Generate a Stop command */
01499         hsmbus->Instance->CR2 |= I2C_CR2_STOP;
01500       }
01501       /* Call TxCpltCallback() if no stop mode is set */
01502       else if(SMBUS_GET_STOP_MODE(hsmbus) != SMBUS_AUTOEND_MODE)
01503       {
01504         /* No Generate Stop, to permit restart mode */
01505         /* The stop will be done at the end of transfer, when SMBUS_AUTOEND_MODE enable */
01506         
01507         /* Call the corresponding callback to inform upper layer of End of Transfer */
01508         if(hsmbus->State == HAL_SMBUS_STATE_MASTER_BUSY_TX)
01509         {
01510           /* Disable Interrupt */
01511           SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_TX);
01512           hsmbus->PreviousState = hsmbus->State;
01513           hsmbus->State = HAL_SMBUS_STATE_READY;
01514 
01515           /* Process Unlocked */
01516           __HAL_UNLOCK(hsmbus);
01517       
01518           HAL_SMBUS_MasterTxCpltCallback(hsmbus);
01519         }
01520         else if(hsmbus->State == HAL_SMBUS_STATE_MASTER_BUSY_RX)
01521         {
01522           SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_RX);
01523           hsmbus->PreviousState = hsmbus->State;
01524           hsmbus->State = HAL_SMBUS_STATE_READY;
01525 
01526           /* Process Unlocked */
01527           __HAL_UNLOCK(hsmbus);
01528       
01529           HAL_SMBUS_MasterRxCpltCallback(hsmbus);
01530         }
01531       }
01532     }
01533   }
01534     
01535   /* Process Unlocked */
01536   __HAL_UNLOCK(hsmbus); 
01537   
01538   return HAL_OK; 
01539 }  
01540 /**
01541   * @brief  Interrupt Sub-Routine which handle the Interrupt Flags Slave Mode.
01542   * @param  hsmbus : Pointer to a SMBUS_HandleTypeDef structure that contains
01543   *                the configuration information for the specified SMBUS.
01544   * @retval HAL status
01545   */
01546 static HAL_StatusTypeDef SMBUS_Slave_ISR(SMBUS_HandleTypeDef *hsmbus) 
01547 {
01548   uint8_t TransferDirection = 0;
01549   uint16_t SlaveAddrCode = 0;
01550 
01551   /* Process Locked */
01552   __HAL_LOCK(hsmbus);
01553   
01554   if(__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_AF) != RESET)
01555   {
01556     /* Check that SMBUS transfer finished */
01557     /* if yes, normal use case, a NACK is sent by the HOST when Transfer is finished */
01558     /* Mean XferCount == 0*/
01559     /* So clear Flag NACKF only */
01560     if(hsmbus->XferCount == 0)
01561     {
01562       /* Clear NACK Flag */
01563       __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_AF);
01564 
01565       /* Process Unlocked */
01566       __HAL_UNLOCK(hsmbus);
01567     }
01568     else
01569     {
01570       /* if no, error use case, a Non-Acknowledge of last Data is generated by the HOST*/
01571       /* Clear NACK Flag */
01572       __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_AF);
01573 
01574       /* Set HAL State to "Idle" State, mean to LISTEN state */
01575       /* So reset Slave Busy state */
01576       hsmbus->PreviousState = hsmbus->State;
01577       hsmbus->State &= ~((uint32_t)HAL_SMBUS_STATE_SLAVE_BUSY_TX);
01578       hsmbus->State &= ~((uint32_t)HAL_SMBUS_STATE_SLAVE_BUSY_RX);
01579 
01580       /* Disable RX/TX Interrupts, keep only ADDR Interrupt */
01581       SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_RX | SMBUS_IT_TX);
01582 
01583       /* Set ErrorCode corresponding to a Non-Acknowledge */
01584       hsmbus->ErrorCode |= HAL_SMBUS_ERROR_ACKF;
01585 
01586       /* Process Unlocked */
01587       __HAL_UNLOCK(hsmbus);
01588     
01589       /* Call the Error callback to prevent upper layer */
01590       HAL_SMBUS_ErrorCallback(hsmbus);
01591     }
01592   }
01593   else if(__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_ADDR) != RESET)
01594   {
01595     TransferDirection = SMBUS_GET_DIR(hsmbus);
01596     SlaveAddrCode = SMBUS_GET_ADDR_MATCH(hsmbus);
01597       
01598     /* Disable ADDR interrupt to prevent multiple ADDRInterrupt*/
01599     /* Other ADDRInterrupt will be treat in next Listen use case */
01600     __HAL_SMBUS_DISABLE_IT(hsmbus, SMBUS_IT_ADDRI);
01601     
01602     /* Process Unlocked */
01603     __HAL_UNLOCK(hsmbus);
01604 
01605     /* Call Slave Addr callback */
01606     HAL_SMBUS_AddrCallback(hsmbus, TransferDirection, SlaveAddrCode);
01607   }
01608   else if((__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_RXNE) != RESET) || (__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_TCR) != RESET))
01609   {
01610     if( (hsmbus->State & HAL_SMBUS_STATE_SLAVE_BUSY_RX) == HAL_SMBUS_STATE_SLAVE_BUSY_RX)
01611     {
01612       /* Read data from RXDR */
01613       (*hsmbus->pBuffPtr++) = hsmbus->Instance->RXDR;
01614       hsmbus->XferSize--;
01615       hsmbus->XferCount--;
01616 
01617       if(hsmbus->XferCount == 1)
01618       {
01619         /* Receive last Byte, can be PEC byte in case of PEC BYTE enabled */
01620         /* or only the last Byte of Transfer */
01621         /* So reset the RELOAD bit mode */
01622         hsmbus->XferOptions &= ~SMBUS_RELOAD_MODE;
01623         SMBUS_TransferConfig(hsmbus,0 ,1 , hsmbus->XferOptions, SMBUS_NO_STARTSTOP);
01624       }
01625       else if(hsmbus->XferCount == 0)
01626       {
01627         /* Last Byte is received, disable Interrupt */
01628         SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_RX);
01629         
01630         /* Remove HAL_SMBUS_STATE_SLAVE_BUSY_RX, keep only HAL_SMBUS_STATE_LISTEN */
01631         hsmbus->PreviousState = hsmbus->State;
01632         hsmbus->State &= ~((uint32_t)HAL_SMBUS_STATE_SLAVE_BUSY_RX);
01633         
01634         /* Process Unlocked */
01635         __HAL_UNLOCK(hsmbus);
01636 
01637         /* Call the Rx complete callback to inform upper layer of the end of receive process */
01638         HAL_SMBUS_SlaveRxCpltCallback(hsmbus);
01639       }
01640       else
01641       {
01642         /* Set Reload for next Bytes */
01643         SMBUS_TransferConfig(hsmbus,0, 1, SMBUS_RELOAD_MODE  | (hsmbus->XferOptions & SMBUS_SENDPEC_MODE), SMBUS_NO_STARTSTOP);
01644 
01645         /* Ack last Byte Read */
01646         hsmbus->Instance->CR2 &= ~I2C_CR2_NACK;
01647       }
01648     }    
01649     else if( (hsmbus->State & HAL_SMBUS_STATE_SLAVE_BUSY_TX) == HAL_SMBUS_STATE_SLAVE_BUSY_TX)
01650     {
01651       if((hsmbus->XferSize == 0)&&(hsmbus->XferCount!=0))
01652       {
01653         if(hsmbus->XferCount > MAX_NBYTE_SIZE)
01654         {    
01655           SMBUS_TransferConfig(hsmbus, 0, MAX_NBYTE_SIZE, (SMBUS_RELOAD_MODE | (hsmbus->XferOptions & SMBUS_SENDPEC_MODE)), SMBUS_NO_STARTSTOP);
01656           hsmbus->XferSize = MAX_NBYTE_SIZE;
01657         }
01658         else
01659         {
01660           hsmbus->XferSize = hsmbus->XferCount;
01661           SMBUS_TransferConfig(hsmbus, 0, hsmbus->XferSize, hsmbus->XferOptions, SMBUS_NO_STARTSTOP);
01662           /* If PEC mode is enable, size to transmit should be Size-1 byte, corresponding to PEC byte */
01663           /* PEC byte is automatically sent by HW block, no need to manage it in Transmit process */
01664           if(SMBUS_GET_PEC_MODE(hsmbus) != RESET)
01665           {
01666             hsmbus->XferSize--;
01667             hsmbus->XferCount--;
01668           }
01669         }
01670       }
01671     }
01672   }
01673   else if(__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_TXIS) != RESET)
01674   {
01675     /* Write data to TXDR only if XferCount not reach "0" */
01676     /* A TXIS flag can be set, during STOP treatment      */
01677     /* Check if all Data have already been sent */
01678     /* If it is the case, this last write in TXDR is not sent, correspond to a dummy TXIS event */
01679     if(hsmbus->XferCount > 0)
01680     {
01681       /* Write data to TXDR */
01682       hsmbus->Instance->TXDR = (*hsmbus->pBuffPtr++);
01683       hsmbus->XferCount--;
01684       hsmbus->XferSize--;
01685     }
01686     
01687     if(hsmbus->XferCount == 0)
01688     {
01689       /* Last Byte is Transmitted */
01690       /* Remove HAL_SMBUS_STATE_SLAVE_BUSY_TX, keep only HAL_SMBUS_STATE_LISTEN */
01691       SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_TX);
01692       hsmbus->PreviousState = hsmbus->State;
01693       hsmbus->State &= ~((uint32_t)HAL_SMBUS_STATE_SLAVE_BUSY_TX);
01694 
01695       /* Process Unlocked */
01696       __HAL_UNLOCK(hsmbus);
01697 
01698       /* Call the Tx complete callback to inform upper layer of the end of transmit process */
01699       HAL_SMBUS_SlaveTxCpltCallback(hsmbus);
01700     }
01701   }
01702 
01703   /* Check if STOPF is set */
01704   if(__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_STOPF) != RESET)
01705   {
01706     if((hsmbus->State & HAL_SMBUS_STATE_LISTEN) == HAL_SMBUS_STATE_LISTEN)
01707     {
01708       /* Disable RX and TX Interrupts */
01709       SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_RX | SMBUS_IT_TX);
01710 
01711       /* Disable ADDR Interrupt */
01712       SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_ADDR);
01713 
01714       /* Disable Address Acknowledge */
01715       hsmbus->Instance->CR2 |= I2C_CR2_NACK;
01716 
01717       /* Clear Configuration Register 2 */
01718       SMBUS_RESET_CR2(hsmbus);
01719     
01720       /* Clear STOP Flag */
01721       __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_STOPF);
01722 
01723      /* Clear ADDR flag */
01724      __HAL_SMBUS_CLEAR_FLAG(hsmbus,SMBUS_FLAG_ADDR);
01725 
01726       hsmbus->XferOptions = 0;
01727       hsmbus->PreviousState = hsmbus->State;
01728       hsmbus->State = HAL_SMBUS_STATE_READY;
01729     
01730       /* Process Unlocked */
01731       __HAL_UNLOCK(hsmbus);
01732 
01733       /* Call the Listen Complete callback, to prevent upper layer of the end of Listen use case */
01734       HAL_SMBUS_ListenCpltCallback(hsmbus);
01735     }
01736   }
01737 
01738   /* Process Unlocked */
01739   __HAL_UNLOCK(hsmbus);
01740   
01741   return HAL_OK;     
01742 }  
01743 /**
01744   * @brief  Manage the enabling of Interrupts.
01745   * @param  hsmbus : Pointer to a SMBUS_HandleTypeDef structure that contains
01746   *                the configuration information for the specified SMBUS.
01747   * @param  InterruptRequest : Value of @ref SMBUS_Interrupt_configuration_definition.
01748   * @retval HAL status
01749   */
01750 static HAL_StatusTypeDef SMBUS_Enable_IRQ(SMBUS_HandleTypeDef *hsmbus, uint16_t InterruptRequest) 
01751 {
01752   uint32_t tmpisr = 0;
01753 
01754   if((InterruptRequest & SMBUS_IT_ALERT) == SMBUS_IT_ALERT)
01755   {
01756     /* Enable ERR interrupt */
01757     tmpisr |= SMBUS_IT_ERRI;
01758   }
01759   
01760   if((InterruptRequest & SMBUS_IT_ADDR) == SMBUS_IT_ADDR)
01761   {
01762     /* Enable ADDR, STOP interrupt */
01763     tmpisr |= SMBUS_IT_ADDRI | SMBUS_IT_STOPI | SMBUS_IT_NACKI | SMBUS_IT_ERRI;
01764   }
01765   
01766   if((InterruptRequest & SMBUS_IT_TX) == SMBUS_IT_TX)
01767   {
01768     /* Enable ERR, TC, STOP, NACK, RXI interrupt */
01769     tmpisr |= SMBUS_IT_ERRI | SMBUS_IT_TCI | SMBUS_IT_STOPI | SMBUS_IT_NACKI | SMBUS_IT_TXI;
01770   }
01771   
01772   if((InterruptRequest & SMBUS_IT_RX) == SMBUS_IT_RX)
01773   {
01774     /* Enable ERR, TC, STOP, NACK, TXI interrupt */
01775     tmpisr |= SMBUS_IT_ERRI | SMBUS_IT_TCI | SMBUS_IT_STOPI | SMBUS_IT_NACKI | SMBUS_IT_RXI;
01776   }
01777   
01778   /* Enable interrupts only at the end */
01779   /* to avoid the risk of SMBUS interrupt handle execution before */
01780   /* all interrupts requested done */
01781   __HAL_SMBUS_ENABLE_IT(hsmbus, tmpisr);
01782 
01783   return HAL_OK;     
01784 }
01785 /**
01786   * @brief  Manage the disabling of Interrupts.
01787   * @param  hsmbus : Pointer to a SMBUS_HandleTypeDef structure that contains
01788   *                the configuration information for the specified SMBUS.
01789   * @param  InterruptRequest : Value of @ref SMBUS_Interrupt_configuration_definition.
01790   * @retval HAL status
01791   */
01792 static HAL_StatusTypeDef SMBUS_Disable_IRQ(SMBUS_HandleTypeDef *hsmbus, uint16_t InterruptRequest) 
01793 {
01794   uint32_t tmpisr = 0;
01795 
01796   if( ((InterruptRequest & SMBUS_IT_ALERT) == SMBUS_IT_ALERT) && (hsmbus->State == HAL_SMBUS_STATE_READY) )
01797   {
01798     /* Disable ERR interrupt */
01799     tmpisr |= SMBUS_IT_ERRI;
01800   }
01801   
01802   if((InterruptRequest & SMBUS_IT_TX) == SMBUS_IT_TX)
01803   {
01804     /* Disable TC, STOP, NACK, TXI interrupt */
01805     tmpisr |= SMBUS_IT_TCI | SMBUS_IT_TXI;
01806     
01807     if((SMBUS_GET_ALERT_ENABLED(hsmbus) == RESET)
01808        && ((hsmbus->State & HAL_SMBUS_STATE_LISTEN) != HAL_SMBUS_STATE_LISTEN))
01809     {
01810       /* Disable ERR interrupt */
01811       tmpisr |= SMBUS_IT_ERRI;
01812     }
01813     
01814     if((hsmbus->State & HAL_SMBUS_STATE_LISTEN) != HAL_SMBUS_STATE_LISTEN)
01815     {
01816       /* Disable STOPI, NACKI */
01817       tmpisr |= SMBUS_IT_STOPI | SMBUS_IT_NACKI;
01818     }
01819   }
01820   
01821   if((InterruptRequest & SMBUS_IT_RX) == SMBUS_IT_RX)
01822   {
01823     /* Disable TC, STOP, NACK, RXI interrupt */
01824     tmpisr |= SMBUS_IT_TCI | SMBUS_IT_RXI;
01825     
01826     if((SMBUS_GET_ALERT_ENABLED(hsmbus) == RESET)
01827        && ((hsmbus->State & HAL_SMBUS_STATE_LISTEN) != HAL_SMBUS_STATE_LISTEN))
01828     {
01829       /* Disable ERR interrupt */
01830       tmpisr |= SMBUS_IT_ERRI;
01831     }
01832 
01833     if((hsmbus->State & HAL_SMBUS_STATE_LISTEN) != HAL_SMBUS_STATE_LISTEN)
01834     {
01835       /* Disable STOPI, NACKI */
01836       tmpisr |= SMBUS_IT_STOPI | SMBUS_IT_NACKI;
01837     }
01838   }
01839   
01840   if((InterruptRequest & SMBUS_IT_ADDR) == SMBUS_IT_ADDR)
01841   {
01842     /* Enable ADDR, STOP interrupt */
01843     tmpisr |= SMBUS_IT_ADDRI | SMBUS_IT_STOPI | SMBUS_IT_NACKI;
01844 
01845     if(SMBUS_GET_ALERT_ENABLED(hsmbus) == RESET) 
01846     {
01847       /* Disable ERR interrupt */
01848       tmpisr |= SMBUS_IT_ERRI;
01849     }
01850   }
01851 
01852   /* Disable interrupts only at the end */
01853   /* to avoid a breaking situation like at "t" time */
01854   /* all disable interrupts request are not done */
01855   __HAL_SMBUS_DISABLE_IT(hsmbus, tmpisr);
01856   
01857   return HAL_OK;
01858 }
01859 /**
01860   * @brief  Handle SMBUS Communication Timeout.
01861   * @param  hsmbus : Pointer to a SMBUS_HandleTypeDef structure that contains
01862   *                the configuration information for the specified SMBUS.
01863   * @param  Flag: specifies the SMBUS flag to check.
01864   * @param  Status: The new Flag status (SET or RESET).
01865   * @param  Timeout: Timeout duration
01866   * @retval HAL status
01867   */
01868 static HAL_StatusTypeDef SMBUS_WaitOnFlagUntilTimeout(SMBUS_HandleTypeDef *hsmbus, uint32_t Flag, FlagStatus Status, uint32_t Timeout)  
01869 {  
01870   uint32_t tickstart = HAL_GetTick();
01871   
01872   /* Wait until flag is set */
01873   if(Status == RESET)
01874   {    
01875     while(__HAL_SMBUS_GET_FLAG(hsmbus, Flag) == RESET)
01876     {
01877       /* Check for the Timeout */
01878       if(Timeout != HAL_MAX_DELAY)
01879       {
01880         if((Timeout == 0) || ((HAL_GetTick()-tickstart) > Timeout))
01881         {
01882           hsmbus->PreviousState = hsmbus->State;
01883           hsmbus->State= HAL_SMBUS_STATE_READY;
01884         
01885           /* Process Unlocked */
01886           __HAL_UNLOCK(hsmbus);
01887         
01888           return HAL_TIMEOUT;
01889         }
01890       }
01891     }
01892   }
01893   else
01894   {
01895     while(__HAL_SMBUS_GET_FLAG(hsmbus, Flag) != RESET)
01896     {
01897       /* Check for the Timeout */
01898       if(Timeout != HAL_MAX_DELAY)
01899       {
01900         if((Timeout == 0) || ((HAL_GetTick()-tickstart) > Timeout))
01901         {
01902           hsmbus->PreviousState = hsmbus->State;
01903           hsmbus->State= HAL_SMBUS_STATE_READY;
01904         
01905           /* Process Unlocked */
01906           __HAL_UNLOCK(hsmbus);
01907         
01908           return HAL_TIMEOUT;
01909         }
01910       }
01911     }
01912   }
01913   return HAL_OK;      
01914 }
01915 
01916 /**
01917   * @brief  Handle SMBUSx communication when starting transfer or during transfer (TC or TCR flag are set).
01918   * @param  hsmbus: SMBUS handle.
01919   * @param  DevAddress: specifies the slave address to be programmed.
01920   * @param  Size: specifies the number of bytes to be programmed.
01921   *   This parameter must be a value between 0 and 255.
01922   * @param  Mode: new state of the SMBUS START condition generation.
01923   *   This parameter can be one or a combination  of the following values:
01924   *     @arg SMBUS_NO_MODE: No specific mode enabled.
01925   *     @arg SMBUS_RELOAD_MODE: Enable Reload mode.
01926   *     @arg SMBUS_AUTOEND_MODE: Enable Automatic end mode.
01927   *     @arg SMBUS_SOFTEND_MODE: Enable Software end mode and Reload mode.
01928   * @param  Request: new state of the SMBUS START condition generation.
01929   *   This parameter can be one of the following values:
01930   *     @arg SMBUS_NO_STARTSTOP: Don't Generate stop and start condition.
01931   *     @arg SMBUS_GENERATE_STOP: Generate stop condition (Size should be set to 0).
01932   *     @arg SMBUS_GENERATE_START_READ: Generate Restart for read request.
01933   *     @arg SMBUS_GENERATE_START_WRITE: Generate Restart for write request.
01934   * @retval None
01935   */
01936 static void SMBUS_TransferConfig(SMBUS_HandleTypeDef *hsmbus,  uint16_t DevAddress, uint8_t Size, uint32_t Mode, uint32_t Request)
01937 {
01938   uint32_t tmpreg = 0;
01939   
01940   /* Check the parameters */
01941   assert_param(IS_SMBUS_ALL_INSTANCE(hsmbus->Instance));
01942   assert_param(IS_SMBUS_TRANSFER_MODE(Mode));
01943   assert_param(IS_SMBUS_TRANSFER_REQUEST(Request));
01944     
01945   /* Get the CR2 register value */
01946   tmpreg = hsmbus->Instance->CR2;
01947   
01948   /* clear tmpreg specific bits */
01949   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));
01950   
01951   /* update tmpreg */
01952   tmpreg |= (uint32_t)(((uint32_t)DevAddress & I2C_CR2_SADD) | (((uint32_t)Size << 16 ) & I2C_CR2_NBYTES) | \
01953               (uint32_t)Mode | (uint32_t)Request);
01954     
01955   /* update CR2 register */
01956   hsmbus->Instance->CR2 = tmpreg;  
01957 }  
01958 /**
01959   * @}
01960   */
01961 
01962 #endif /* HAL_SMBUS_MODULE_ENABLED */
01963 /**
01964   * @}
01965   */
01966 
01967 /**
01968   * @}
01969   */
01970 
01971 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/