]> git.donarmstrong.com Git - qmk_firmware.git/blob - tool/mbed/mbed-sdk/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_STM32F0/stm32f0xx_hal_smbus.c
Squashed 'tmk_core/' changes from 7967731..b9e0ea0
[qmk_firmware.git] / tool / mbed / mbed-sdk / libraries / mbed / targets / cmsis / TARGET_STM / TARGET_STM32F0 / stm32f0xx_hal_smbus.c
1 /**
2   ******************************************************************************
3   * @file    stm32f0xx_hal_smbus.c
4   * @author  MCD Application Team
5   * @version V1.2.0
6   * @date    11-December-2014
7   * @brief   SMBUS HAL module driver.
8   *    
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
15   @verbatim
16   ==============================================================================
17                         ##### How to use this driver #####
18   ==============================================================================
19     [..]
20     The SMBUS HAL driver can be used as follows:
21     
22     (#) Declare a SMBUS_HandleTypeDef handle structure, for example:
23         SMBUS_HandleTypeDef  hsmbus; 
24
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
33
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.
37
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.
41
42     (#) To check if target device is ready for communication, use the function HAL_SMBUS_IsDeviceReady()
43
44     (#) For SMBUS IO operations, only one mode of operations is available within this driver :
45             
46     *** Interrupt mode IO operation ***
47     ===================================
48     [..]
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()
79
80      *** SMBUS HAL driver macros list ***
81      ==================================
82      [..]
83        Below the list of most used macros in SMBUS HAL driver.
84
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
91
92      [..]
93        (@) You can refer to the SMBUS HAL driver header file for more useful macros
94
95             
96   @endverbatim
97   ******************************************************************************
98   * @attention
99   *
100   * <h2><center>&copy; COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
101   *
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.
112   *
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.
123   *
124   ******************************************************************************  
125   */ 
126
127 /* Includes ------------------------------------------------------------------*/
128 #include "stm32f0xx_hal.h"
129
130 /** @addtogroup STM32F0xx_HAL_Driver
131   * @{
132   */
133
134 /** @defgroup SMBUS SMBUS HAL module driver
135   * @brief SMBUS HAL module driver
136   * @{
137   */
138
139 #ifdef HAL_SMBUS_MODULE_ENABLED
140
141 /* Private typedef -----------------------------------------------------------*/
142 /* Private define ------------------------------------------------------------*/
143 /** @defgroup SMBUS_Private_Define SMBUS Private Define
144   * @{
145   */
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
156 /**
157   * @}
158   */
159   
160 /* Private macro -------------------------------------------------------------*/
161 /** @defgroup SMBUS_Private_Macros SMBUS Private Macros
162   * @{
163   */
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)))
166 /**
167   * @}
168   */
169
170 /* Private variables ---------------------------------------------------------*/
171 /* Private function prototypes -----------------------------------------------*/
172 /** @defgroup SMBUS_Private_Functions SMBUS Private Functions
173   * @{
174   */
175 static HAL_StatusTypeDef SMBUS_WaitOnFlagUntilTimeout(SMBUS_HandleTypeDef *hsmbus, uint32_t Flag, FlagStatus Status, uint32_t Timeout);
176
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);
181
182 static void SMBUS_TransferConfig(SMBUS_HandleTypeDef *hsmbus,  uint16_t DevAddress, uint8_t Size, uint32_t Mode, uint32_t Request);
183 /**
184   * @}
185   */
186
187 /* Exported functions ---------------------------------------------------------*/
188
189 /** @defgroup SMBUS_Exported_Functions SMBUS Exported Functions
190   * @{
191   */
192
193 /** @defgroup SMBUS_Exported_Functions_Group1 Initialization and de-initialization functions
194  *  @brief    Initialization and Configuration functions 
195  *
196 @verbatim    
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:
202
203       (+) User must Implement HAL_SMBUS_MspInit() function in which he configures 
204           all related peripherals resources (CLOCK, GPIO, IT and NVIC ).
205
206       (+) Call the function HAL_SMBUS_Init() to configure the selected device with 
207           the selected configuration:
208         (++) Clock Timing
209         (++) Bus Timeout
210         (++) Analog Filer mode
211         (++) Own Address 1
212         (++) Addressing mode (Master, Slave)
213         (++) Dual Addressing mode
214         (++) Own Address 2
215         (++) Own Address 2 Mask
216         (++) General call mode
217         (++) Nostretch mode
218         (++) Packet Error Check mode
219         (++) Peripheral mode
220
221
222       (+) Call the function HAL_SMBUS_DeInit() to restore the default configuration 
223           of the selected SMBUSx periperal.       
224
225 @endverbatim
226   * @{
227   */
228
229 /**
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.
234   * @retval HAL status
235   */
236 HAL_StatusTypeDef HAL_SMBUS_Init(SMBUS_HandleTypeDef *hsmbus)
237
238   /* Check the SMBUS handle allocation */
239   if(hsmbus == NULL)
240   {
241     return HAL_ERROR;
242   }
243   
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));
256
257   if(hsmbus->State == HAL_SMBUS_STATE_RESET)
258   {
259     /* Init the low level hardware : GPIO, CLOCK, NVIC */
260     HAL_SMBUS_MspInit(hsmbus);
261   }
262   
263   hsmbus->State = HAL_SMBUS_STATE_BUSY;
264   
265   /* Disable the selected SMBUS peripheral */
266   __HAL_SMBUS_DISABLE(hsmbus);
267   
268   /*---------------------------- SMBUSx TIMINGR Configuration ------------------------*/  
269   /* Configure SMBUSx: Frequency range */
270   hsmbus->Instance->TIMINGR = hsmbus->Init.Timing & TIMING_CLEAR_MASK;
271   
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;
277
278   /*---------------------------- SMBUSx OAR1 Configuration -----------------------*/
279   /* Configure SMBUSx: Own Address1 and ack own address1 mode */
280   hsmbus->Instance->OAR1 &= ~I2C_OAR1_OA1EN;
281   
282   if(hsmbus->Init.OwnAddress1 != 0)
283   {
284     if(hsmbus->Init.AddressingMode == SMBUS_ADDRESSINGMODE_7BIT)
285     {
286       hsmbus->Instance->OAR1 = (I2C_OAR1_OA1EN | hsmbus->Init.OwnAddress1);
287     }
288     else /* SMBUS_ADDRESSINGMODE_10BIT */
289     {
290       hsmbus->Instance->OAR1 = (I2C_OAR1_OA1EN | I2C_OAR1_OA1MODE | hsmbus->Init.OwnAddress1);
291     }
292   }
293
294   /*---------------------------- SMBUSx CR2 Configuration ------------------------*/
295   /* Configure SMBUSx: Addressing Master mode */
296   if(hsmbus->Init.AddressingMode == SMBUS_ADDRESSINGMODE_10BIT)
297   {
298     hsmbus->Instance->CR2 = (I2C_CR2_ADD10);
299   }
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);
303   
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));
307
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);
311   
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) ) )
315   {
316     hsmbus->Instance->CR1 |= I2C_CR1_SBC;
317   }
318
319   /* Enable the selected SMBUS peripheral */
320   __HAL_SMBUS_ENABLE(hsmbus);
321   
322   hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE;
323   hsmbus->PreviousState = HAL_SMBUS_STATE_READY;
324   hsmbus->State = HAL_SMBUS_STATE_READY;
325   
326   return HAL_OK;
327 }
328
329 /**
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.
333   * @retval HAL status
334   */
335 HAL_StatusTypeDef HAL_SMBUS_DeInit(SMBUS_HandleTypeDef *hsmbus)
336 {
337   /* Check the SMBUS handle allocation */
338   if(hsmbus == NULL)
339   {
340     return HAL_ERROR;
341   }
342   
343   /* Check the parameters */
344   assert_param(IS_SMBUS_ALL_INSTANCE(hsmbus->Instance));
345   
346   hsmbus->State = HAL_SMBUS_STATE_BUSY;
347   
348   /* Disable the SMBUS Peripheral Clock */
349   __HAL_SMBUS_DISABLE(hsmbus);
350   
351   /* DeInit the low level hardware: GPIO, CLOCK, NVIC */
352   HAL_SMBUS_MspDeInit(hsmbus);
353   
354   hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE;
355   hsmbus->PreviousState =  HAL_SMBUS_STATE_RESET;
356   hsmbus->State = HAL_SMBUS_STATE_RESET;
357   
358    /* Release Lock */
359   __HAL_UNLOCK(hsmbus);
360   
361   return HAL_OK;
362 }
363
364 /**
365   * @brief SMBUS MSP Init.
366   * @param  hsmbus : Pointer to a SMBUS_HandleTypeDef structure that contains
367   *                the configuration information for the specified SMBUS.
368   * @retval None
369   */
370  __weak void HAL_SMBUS_MspInit(SMBUS_HandleTypeDef *hsmbus)
371 {
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
374    */ 
375 }
376
377 /**
378   * @brief SMBUS MSP DeInit
379   * @param  hsmbus : Pointer to a SMBUS_HandleTypeDef structure that contains
380   *                the configuration information for the specified SMBUS.
381   * @retval None
382   */
383  __weak void HAL_SMBUS_MspDeInit(SMBUS_HandleTypeDef *hsmbus)
384 {
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
387    */ 
388 }
389
390 /**
391   * @}
392   */
393
394 /** @defgroup SMBUS_Exported_Functions_Group2 Input and Output operation functions
395  *  @brief   Data transfers functions 
396  *
397 @verbatim   
398  ===============================================================================
399                       ##### IO operation functions #####
400  ===============================================================================  
401     [..]
402     This subsection provides a set of functions allowing to manage the SMBUS data 
403     transfers.
404
405     (#) Blocking mode function to check if device is ready for usage is :
406         (++) HAL_SMBUS_IsDeviceReady()
407
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.
413
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()
423
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()
432
433 @endverbatim
434   * @{
435   */
436
437 /**
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
445   * @retval HAL status
446   */
447 HAL_StatusTypeDef HAL_SMBUS_Master_Transmit_IT(SMBUS_HandleTypeDef *hsmbus, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t XferOptions)
448 {   
449   /* Check the parameters */
450   assert_param(IS_SMBUS_TRANSFER_OPTIONS_REQUEST(XferOptions));
451
452   if(hsmbus->State == HAL_SMBUS_STATE_READY)
453   {
454     /* Process Locked */
455     __HAL_LOCK(hsmbus);
456     
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;
463
464     /* In case of Quick command, remove autoend mode */
465     /* Manage the stop generation by software */
466     if(hsmbus->pBuffPtr == NULL)
467     {
468       hsmbus->XferOptions &= ~SMBUS_AUTOEND_MODE;
469     }
470
471     if(Size > MAX_NBYTE_SIZE)
472     {
473       hsmbus->XferSize = MAX_NBYTE_SIZE;
474     }
475     else
476     {
477       hsmbus->XferSize = Size;
478     }
479     
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) )
483     {
484       SMBUS_TransferConfig(hsmbus,DevAddress,hsmbus->XferSize, SMBUS_RELOAD_MODE | (hsmbus->XferOptions & SMBUS_SENDPEC_MODE), SMBUS_GENERATE_START_WRITE);
485     }
486     else
487     {
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)
491       {
492         SMBUS_TransferConfig(hsmbus,DevAddress,hsmbus->XferSize, hsmbus->XferOptions, SMBUS_NO_STARTSTOP);
493       }
494       /* Else transfer direction change, so generate Restart with new transfer direction */
495       else
496       {
497         SMBUS_TransferConfig(hsmbus,DevAddress,hsmbus->XferSize, hsmbus->XferOptions, SMBUS_GENERATE_START_WRITE);
498       }
499
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)
503       {
504         hsmbus->XferSize--;
505         hsmbus->XferCount--;
506       }
507     }
508     
509     /* Process Unlocked */
510     __HAL_UNLOCK(hsmbus); 
511
512     /* Note : The SMBUS interrupts must be enabled after unlocking current process 
513               to avoid the risk of SMBUS interrupt handle execution before current
514               process unlock */
515     SMBUS_Enable_IRQ(hsmbus, SMBUS_IT_TX);
516     
517     return HAL_OK;
518   }
519   else
520   {
521     return HAL_BUSY;
522   } 
523 }
524
525 /**
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
533   * @retval HAL status
534   */
535 HAL_StatusTypeDef HAL_SMBUS_Master_Receive_IT(SMBUS_HandleTypeDef *hsmbus, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t XferOptions)
536 {
537   /* Check the parameters */
538   assert_param(IS_SMBUS_TRANSFER_OPTIONS_REQUEST(XferOptions));
539
540   if(hsmbus->State == HAL_SMBUS_STATE_READY)
541   {
542     /* Process Locked */
543     __HAL_LOCK(hsmbus);
544     
545     hsmbus->State = HAL_SMBUS_STATE_MASTER_BUSY_RX;
546     hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE;
547     
548     /* Prepare transfer parameters */
549     hsmbus->pBuffPtr = pData;
550     hsmbus->XferCount = Size;
551     hsmbus->XferOptions = XferOptions;
552     
553     /* In case of Quick command, remove autoend mode */
554     /* Manage the stop generation by software */
555     if(hsmbus->pBuffPtr == NULL)
556     {
557       hsmbus->XferOptions &= ~SMBUS_AUTOEND_MODE;
558     }
559     
560     if(Size > MAX_NBYTE_SIZE)
561     {
562       hsmbus->XferSize = MAX_NBYTE_SIZE;
563     }
564     else
565     {
566       hsmbus->XferSize = Size;
567     }
568     
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) )
572     {
573       SMBUS_TransferConfig(hsmbus,DevAddress,hsmbus->XferSize, SMBUS_RELOAD_MODE  | (hsmbus->XferOptions & SMBUS_SENDPEC_MODE), SMBUS_GENERATE_START_READ);
574     }
575     else
576     {
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)
580       {
581         SMBUS_TransferConfig(hsmbus,DevAddress,hsmbus->XferSize, hsmbus->XferOptions, SMBUS_NO_STARTSTOP);
582       }
583       /* Else transfer direction change, so generate Restart with new transfer direction */
584       else
585       {
586         SMBUS_TransferConfig(hsmbus,DevAddress,hsmbus->XferSize, hsmbus->XferOptions, SMBUS_GENERATE_START_READ);
587       }
588     }
589     
590     /* Process Unlocked */
591     __HAL_UNLOCK(hsmbus); 
592
593     /* Note : The SMBUS interrupts must be enabled after unlocking current process 
594               to avoid the risk of SMBUS interrupt handle execution before current
595               process unlock */
596     SMBUS_Enable_IRQ(hsmbus, SMBUS_IT_RX);
597     
598     return HAL_OK;
599   }
600   else
601   {
602     return HAL_BUSY; 
603   } 
604 }
605
606 /**
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
612   * @retval HAL status
613   */
614 HAL_StatusTypeDef HAL_SMBUS_Master_Abort_IT(SMBUS_HandleTypeDef *hsmbus, uint16_t DevAddress)
615 {
616   if(hsmbus->State == HAL_SMBUS_STATE_READY)
617   {
618     /* Process Locked */
619     __HAL_LOCK(hsmbus);
620     
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)
624     {
625       hsmbus->State = HAL_SMBUS_STATE_MASTER_BUSY_TX;
626     }
627     else if(hsmbus->PreviousState == HAL_SMBUS_STATE_MASTER_BUSY_RX)
628     {
629       hsmbus->State = HAL_SMBUS_STATE_MASTER_BUSY_RX;
630     }
631     else
632     {
633       /* Wrong usage of abort function */
634       /* This function should be used only in case of abort monitored by master device */
635       return HAL_ERROR;
636     }
637     hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE;
638     
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);
642     
643     /* Process Unlocked */
644     __HAL_UNLOCK(hsmbus); 
645
646     /* Note : The SMBUS interrupts must be enabled after unlocking current process 
647               to avoid the risk of SMBUS interrupt handle execution before current
648               process unlock */
649     if(hsmbus->State == HAL_SMBUS_STATE_MASTER_BUSY_TX)
650     {
651       SMBUS_Enable_IRQ(hsmbus, SMBUS_IT_TX);
652     }
653     else if(hsmbus->State == HAL_SMBUS_STATE_MASTER_BUSY_RX)
654     {
655       SMBUS_Enable_IRQ(hsmbus, SMBUS_IT_RX);
656     }
657     
658     return HAL_OK;
659   }
660   else
661   {
662     return HAL_BUSY; 
663   } 
664 }
665
666 /**
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
673   * @retval HAL status
674   */
675 HAL_StatusTypeDef HAL_SMBUS_Slave_Transmit_IT(SMBUS_HandleTypeDef *hsmbus, uint8_t *pData, uint16_t Size, uint32_t XferOptions)
676 {
677   /* Check the parameters */
678   assert_param(IS_SMBUS_TRANSFER_OPTIONS_REQUEST(XferOptions));
679
680   if(hsmbus->State == HAL_SMBUS_STATE_LISTEN)
681   {
682     if((pData == NULL) || (Size == 0)) 
683     {
684       return  HAL_ERROR;                                    
685     }
686
687     /* Disable Interrupts, to prevent preemption during treatment in case of multicall */
688     SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_ADDR | SMBUS_IT_TX);
689
690     /* Process Locked */
691     __HAL_LOCK(hsmbus);
692     
693     hsmbus->State |= HAL_SMBUS_STATE_SLAVE_BUSY_TX;
694     hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE;
695     
696     /* Set SBC bit to manage Acknowledge at each bit */
697     hsmbus->Instance->CR1 |= I2C_CR1_SBC;
698
699     /* Enable Address Acknowledge */
700     hsmbus->Instance->CR2 &= ~I2C_CR2_NACK;
701
702     /* Prepare transfer parameters */
703     hsmbus->pBuffPtr = pData;
704     hsmbus->XferSize = Size;
705     hsmbus->XferCount = Size;
706     hsmbus->XferOptions = XferOptions;
707
708     if(Size > MAX_NBYTE_SIZE)
709     {
710       hsmbus->XferSize = MAX_NBYTE_SIZE;
711     }
712     else
713     {
714       hsmbus->XferSize = Size;
715     }
716
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) )
719     {
720       SMBUS_TransferConfig(hsmbus,0,hsmbus->XferSize, SMBUS_RELOAD_MODE | (hsmbus->XferOptions & SMBUS_SENDPEC_MODE), SMBUS_NO_STARTSTOP);
721     }
722     else
723     {
724       /* Set NBYTE to transmit */
725       SMBUS_TransferConfig(hsmbus,0,hsmbus->XferSize, hsmbus->XferOptions, SMBUS_NO_STARTSTOP);
726
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)
730       {
731         hsmbus->XferSize--;
732         hsmbus->XferCount--;
733       }
734     }
735     
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);
739
740     /* Process Unlocked */
741     __HAL_UNLOCK(hsmbus); 
742
743     /* Note : The SMBUS interrupts must be enabled after unlocking current process 
744               to avoid the risk of SMBUS interrupt handle execution before current
745               process unlock */
746     /* REnable ADDR interrupt */
747     SMBUS_Enable_IRQ(hsmbus, SMBUS_IT_TX | SMBUS_IT_ADDR);
748
749     return HAL_OK;
750   }
751   else
752   {
753     return HAL_ERROR; 
754   } 
755 }
756
757 /**
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
764   * @retval HAL status
765   */
766 HAL_StatusTypeDef HAL_SMBUS_Slave_Receive_IT(SMBUS_HandleTypeDef *hsmbus, uint8_t *pData, uint16_t Size, uint32_t XferOptions)
767 {
768   /* Check the parameters */
769   assert_param(IS_SMBUS_TRANSFER_OPTIONS_REQUEST(XferOptions));
770
771   if(hsmbus->State == HAL_SMBUS_STATE_LISTEN)
772   {
773     if((pData == NULL) || (Size == 0)) 
774     {
775       return  HAL_ERROR;                                    
776     }
777     
778     /* Disable Interrupts, to prevent preemption during treatment in case of multicall */
779     SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_ADDR | SMBUS_IT_RX);
780
781     /* Process Locked */
782     __HAL_LOCK(hsmbus);
783     
784     hsmbus->State |= HAL_SMBUS_STATE_SLAVE_BUSY_RX;
785     hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE;
786     
787     /* Set SBC bit to manage Acknowledge at each bit */
788     hsmbus->Instance->CR1 |= I2C_CR1_SBC;
789
790     /* Enable Address Acknowledge */
791     hsmbus->Instance->CR2 &= ~I2C_CR2_NACK;
792
793     /* Prepare transfer parameters */
794     hsmbus->pBuffPtr = pData;
795     hsmbus->XferSize = Size;
796     hsmbus->XferCount = Size;
797     hsmbus->XferOptions = XferOptions;
798     
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)))
805     {
806       SMBUS_TransferConfig(hsmbus,0,hsmbus->XferSize, hsmbus->XferOptions, SMBUS_NO_STARTSTOP);
807     }
808     else
809     {
810       SMBUS_TransferConfig(hsmbus,0, 1, hsmbus->XferOptions | SMBUS_RELOAD_MODE, SMBUS_NO_STARTSTOP);
811     }
812
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);
816
817     /* Process Unlocked */
818     __HAL_UNLOCK(hsmbus); 
819
820     /* Note : The SMBUS interrupts must be enabled after unlocking current process 
821               to avoid the risk of SMBUS interrupt handle execution before current
822               process unlock */
823     /* REnable ADDR interrupt */
824     SMBUS_Enable_IRQ(hsmbus, SMBUS_IT_RX | SMBUS_IT_ADDR);
825
826     return HAL_OK;
827   }
828   else
829   {
830     return HAL_ERROR; 
831   }
832 }
833
834 /**
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.
838   * @retval HAL status
839   */
840 HAL_StatusTypeDef HAL_SMBUS_Slave_Listen_IT(SMBUS_HandleTypeDef *hsmbus)
841 {
842   hsmbus->State = HAL_SMBUS_STATE_LISTEN;
843   
844   /* Enable the Address Match interrupt */
845   SMBUS_Enable_IRQ(hsmbus, SMBUS_IT_ADDR);
846   
847   return HAL_OK;
848 }
849
850 /**
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.
854   * @retval HAL status
855   */
856 HAL_StatusTypeDef HAL_SMBUS_DisableListen_IT(SMBUS_HandleTypeDef *hsmbus)
857 {
858   /* Disable Address listen mode only if a transfer is not ongoing */
859   if(hsmbus->State == HAL_SMBUS_STATE_LISTEN)
860   {
861     hsmbus->State = HAL_SMBUS_STATE_READY;
862   
863     /* Disable the Address Match interrupt */
864     SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_ADDR);
865   
866     return HAL_OK;
867   }
868   else
869   {
870     return HAL_BUSY;
871   }
872 }
873
874 /**
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.
878   * @retval HAL status
879   */
880 HAL_StatusTypeDef HAL_SMBUS_EnableAlert_IT(SMBUS_HandleTypeDef *hsmbus)
881 {
882   /* Enable SMBus alert */
883   hsmbus->Instance->CR1 |= I2C_CR1_ALERTEN;   
884
885   /* Clear ALERT flag */
886   __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_ALERT);
887
888   /* Enable Alert Interrupt */
889   SMBUS_Enable_IRQ(hsmbus, SMBUS_IT_ALERT);
890
891   return HAL_OK; 
892 }
893 /**
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.
897   * @retval HAL status
898   */
899 HAL_StatusTypeDef HAL_SMBUS_DisableAlert_IT(SMBUS_HandleTypeDef *hsmbus)
900 {
901   /* Enable SMBus alert */
902   hsmbus->Instance->CR1 &= ~I2C_CR1_ALERTEN;   
903   
904   /* Disable Alert Interrupt */
905   SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_ALERT);
906
907   return HAL_OK; 
908 }
909
910 /**
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
918   * @retval HAL status
919   */
920 HAL_StatusTypeDef HAL_SMBUS_IsDeviceReady(SMBUS_HandleTypeDef *hsmbus, uint16_t DevAddress, uint32_t Trials, uint32_t Timeout)
921 {  
922   uint32_t tickstart = 0;
923   
924   __IO uint32_t SMBUS_Trials = 0;
925  
926   if(hsmbus->State == HAL_SMBUS_STATE_READY)
927   {
928     if(__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_BUSY) != RESET)
929     {
930       return HAL_BUSY;
931     }
932
933     /* Process Locked */
934     __HAL_LOCK(hsmbus);
935     
936     hsmbus->State = HAL_SMBUS_STATE_BUSY;
937     hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE;
938     
939     do
940     {
941       /* Generate Start */
942       hsmbus->Instance->CR2 = __HAL_SMBUS_GENERATE_START(hsmbus->Init.AddressingMode,DevAddress);
943       
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))
948       {
949         if(Timeout != HAL_MAX_DELAY)
950         {    
951           if((Timeout == 0) || ((HAL_GetTick() - tickstart) > Timeout))
952           {
953             /* Device is ready */
954             hsmbus->State = HAL_SMBUS_STATE_READY;
955         
956             /* Process Unlocked */
957             __HAL_UNLOCK(hsmbus);
958             return HAL_TIMEOUT;
959           }
960         } 
961       }
962       
963       /* Check if the NACKF flag has not been set */
964       if (__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_AF) == RESET)
965       {
966         /* Wait until STOPF flag is reset */ 
967         if(SMBUS_WaitOnFlagUntilTimeout(hsmbus, SMBUS_FLAG_STOPF, RESET, Timeout) != HAL_OK)      
968         {
969           return HAL_TIMEOUT;
970         }
971         
972         /* Clear STOP Flag */
973         __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_STOPF);
974
975         /* Device is ready */
976         hsmbus->State = HAL_SMBUS_STATE_READY;
977         
978         /* Process Unlocked */
979         __HAL_UNLOCK(hsmbus);
980         
981         return HAL_OK;
982       }
983       else
984       {
985         /* Wait until STOPF flag is reset */ 
986         if(SMBUS_WaitOnFlagUntilTimeout(hsmbus, SMBUS_FLAG_STOPF, RESET, Timeout) != HAL_OK)      
987         {
988           return HAL_TIMEOUT;
989         }
990
991         /* Clear NACK Flag */
992         __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_AF);
993
994         /* Clear STOP Flag, auto generated with autoend*/
995         __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_STOPF);
996       }
997       
998       /* Check if the maximum allowed number of trials has been reached */
999       if (SMBUS_Trials++ == Trials)
1000       {
1001         /* Generate Stop */
1002         hsmbus->Instance->CR2 |= I2C_CR2_STOP;
1003         
1004         /* Wait until STOPF flag is reset */ 
1005         if(SMBUS_WaitOnFlagUntilTimeout(hsmbus, SMBUS_FLAG_STOPF, RESET, Timeout) != HAL_OK)      
1006         {
1007           return HAL_TIMEOUT;
1008         }
1009         
1010         /* Clear STOP Flag */
1011         __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_STOPF);
1012       }      
1013     }while(SMBUS_Trials < Trials);
1014
1015     hsmbus->State = HAL_SMBUS_STATE_READY;
1016
1017     /* Process Unlocked */
1018     __HAL_UNLOCK(hsmbus);
1019         
1020     return HAL_TIMEOUT;
1021   }      
1022   else
1023   {
1024     return HAL_BUSY;
1025   }
1026 }
1027
1028 /**
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.
1032   * @retval None
1033   */
1034 void HAL_SMBUS_EV_IRQHandler(SMBUS_HandleTypeDef *hsmbus)
1035 {
1036   uint32_t tmpisrvalue = 0;
1037   
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);
1041     
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))
1044   {     
1045     /* Slave mode selected */
1046     if ((hsmbus->State & HAL_SMBUS_STATE_SLAVE_BUSY_TX) == HAL_SMBUS_STATE_SLAVE_BUSY_TX)
1047     {
1048       SMBUS_Slave_ISR(hsmbus);
1049     }
1050     /* Master mode selected */
1051     else if((hsmbus->State & HAL_SMBUS_STATE_MASTER_BUSY_TX) == HAL_SMBUS_STATE_MASTER_BUSY_TX)
1052     {
1053       SMBUS_Master_ISR(hsmbus);
1054     }
1055   }
1056     
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))
1059   {
1060     /* Slave mode selected */
1061     if ((hsmbus->State & HAL_SMBUS_STATE_SLAVE_BUSY_RX) == HAL_SMBUS_STATE_SLAVE_BUSY_RX)
1062     {
1063       SMBUS_Slave_ISR(hsmbus);
1064     }
1065     /* Master mode selected */
1066     else if((hsmbus->State & HAL_SMBUS_STATE_MASTER_BUSY_RX) == HAL_SMBUS_STATE_MASTER_BUSY_RX)
1067     {
1068       SMBUS_Master_ISR(hsmbus);
1069     }
1070   } 
1071       
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)))
1075   {
1076     if (hsmbus->State == HAL_SMBUS_STATE_LISTEN)
1077     {
1078       SMBUS_Slave_ISR(hsmbus);
1079     }
1080   }
1081 }
1082
1083 /**
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.
1087   * @retval None
1088   */
1089 void HAL_SMBUS_ER_IRQHandler(SMBUS_HandleTypeDef *hsmbus)
1090 {
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))
1093   { 
1094     hsmbus->ErrorCode |= HAL_SMBUS_ERROR_BERR;
1095    
1096     /* Clear BERR flag */
1097     __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_BERR);
1098   }
1099   
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))
1102   { 
1103     hsmbus->ErrorCode |= HAL_SMBUS_ERROR_OVR;
1104
1105     /* Clear OVR flag */
1106     __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_OVR);
1107   }
1108
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))
1111   { 
1112     hsmbus->ErrorCode |= HAL_SMBUS_ERROR_ARLO;
1113
1114     /* Clear ARLO flag */
1115     __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_ARLO);
1116   }
1117
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))
1120   { 
1121     hsmbus->ErrorCode |= HAL_SMBUS_ERROR_BUSTIMEOUT;
1122
1123     /* Clear TIMEOUT flag */
1124     __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_TIMEOUT);
1125   }
1126
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))
1129   { 
1130     hsmbus->ErrorCode |= HAL_SMBUS_ERROR_ALERT;
1131
1132     /* Clear ALERT flag */
1133     __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_ALERT);
1134   }
1135
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))
1138   { 
1139     hsmbus->ErrorCode |= HAL_SMBUS_ERROR_PECERR;
1140
1141     /* Clear PEC error flag */
1142     __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_PECERR);
1143   }
1144   
1145   /* Call the Error Callback in case of Error detected */
1146   if((hsmbus->ErrorCode != HAL_SMBUS_ERROR_NONE)&&(hsmbus->ErrorCode != HAL_SMBUS_ERROR_ACKF))
1147   {
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)
1150     {
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))
1153       {
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;
1158       }
1159     }
1160     
1161     /* Call the Error callback to prevent upper layer */
1162     HAL_SMBUS_ErrorCallback(hsmbus);
1163   }
1164 }
1165
1166 /**
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.
1170   * @retval None
1171   */
1172  __weak void HAL_SMBUS_MasterTxCpltCallback(SMBUS_HandleTypeDef *hsmbus)
1173 {
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
1176    */ 
1177 }
1178
1179 /**
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.
1183   * @retval None
1184   */
1185 __weak void HAL_SMBUS_MasterRxCpltCallback(SMBUS_HandleTypeDef *hsmbus)
1186 {
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
1189    */
1190 }
1191
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.
1195   * @retval None
1196   */
1197  __weak void HAL_SMBUS_SlaveTxCpltCallback(SMBUS_HandleTypeDef *hsmbus)
1198 {
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
1201    */ 
1202 }
1203
1204 /**
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.
1208   * @retval None
1209   */
1210 __weak void HAL_SMBUS_SlaveRxCpltCallback(SMBUS_HandleTypeDef *hsmbus)
1211 {
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
1214    */
1215 }
1216
1217 /**
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
1223   * @retval None
1224   */
1225 __weak void HAL_SMBUS_SlaveAddrCallback(SMBUS_HandleTypeDef *hsmbus, uint8_t TransferDirection, uint16_t AddrMatchCode)
1226 {
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
1229    */
1230 }
1231
1232 /**
1233   * @brief  Listen Complete callbacks.
1234   * @param  hsmbus : Pointer to a SMBUS_HandleTypeDef structure that contains
1235   *                the configuration information for the specified SMBUS.
1236   * @retval None
1237   */
1238 __weak void HAL_SMBUS_SlaveListenCpltCallback(SMBUS_HandleTypeDef *hsmbus)
1239 {
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
1242    */
1243 }
1244
1245 /**
1246   * @brief  SMBUS error callbacks.
1247   * @param  hsmbus : Pointer to a SMBUS_HandleTypeDef structure that contains
1248   *                the configuration information for the specified SMBUS.
1249   * @retval None
1250   */
1251  __weak void HAL_SMBUS_ErrorCallback(SMBUS_HandleTypeDef *hsmbus)
1252 {
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
1255    */ 
1256 }
1257
1258 /**
1259   * @}
1260   */  
1261
1262 /** @defgroup SMBUS_Exported_Functions_Group3 Peripheral State and Errors functions 
1263  *  @brief   Peripheral State and Errors functions 
1264  *
1265 @verbatim   
1266  ===============================================================================
1267             ##### Peripheral State and Errors functions #####
1268  ===============================================================================  
1269     [..]
1270     This subsection permit to get in run-time the status of the peripheral 
1271     and the data flow.
1272
1273 @endverbatim
1274   * @{
1275   */
1276
1277 /**
1278   * @brief  Returns the SMBUS state.
1279   * @param  hsmbus : SMBUS handle
1280   * @retval HAL state
1281   */
1282 uint32_t HAL_SMBUS_GetState(SMBUS_HandleTypeDef *hsmbus)
1283 {
1284   return hsmbus->State;
1285 }
1286
1287 /**
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
1292 */
1293 uint32_t HAL_SMBUS_GetError(SMBUS_HandleTypeDef *hsmbus)
1294 {
1295   return hsmbus->ErrorCode;
1296 }
1297
1298 /**
1299   * @}
1300   */  
1301
1302 /**
1303   * @}
1304   */  
1305
1306 /** @addtogroup SMBUS_Private_Functions SMBUS Private Functions
1307  *  @brief   Data transfers Private functions 
1308   * @{
1309   */
1310
1311 /**
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
1316   */
1317 static HAL_StatusTypeDef SMBUS_Master_ISR(SMBUS_HandleTypeDef *hsmbus) 
1318 {
1319   uint16_t DevAddress;
1320
1321   /* Process Locked */
1322   __HAL_LOCK(hsmbus);
1323   
1324   if(__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_AF) != RESET)
1325   {
1326     /* Clear NACK Flag */
1327     __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_AF);
1328     
1329     /* Set corresponding Error Code */
1330     /* No need to generate STOP, it is automatically done */
1331     hsmbus->ErrorCode |= HAL_SMBUS_ERROR_ACKF;
1332
1333     /* Process Unlocked */
1334     __HAL_UNLOCK(hsmbus);
1335     
1336     /* Call the Error callback to prevent upper layer */
1337     HAL_SMBUS_ErrorCallback(hsmbus);
1338   }
1339   else if(__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_STOPF) != RESET)
1340   {
1341       
1342     /* Call the corresponding callback to inform upper layer of End of Transfer */
1343     if(hsmbus->State == HAL_SMBUS_STATE_MASTER_BUSY_TX)
1344     {
1345       /* Disable Interrupt */
1346       SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_TX);
1347
1348       /* Clear STOP Flag */
1349       __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_STOPF);
1350       
1351       /* Clear Configuration Register 2 */
1352       __HAL_SMBUS_RESET_CR2(hsmbus);
1353     
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);
1357
1358       hsmbus->PreviousState = HAL_SMBUS_STATE_READY;
1359       hsmbus->State = HAL_SMBUS_STATE_READY;
1360
1361       /* Process Unlocked */
1362       __HAL_UNLOCK(hsmbus);
1363   
1364       /* REenable the selected SMBUS peripheral */
1365       __HAL_SMBUS_ENABLE(hsmbus);
1366
1367       HAL_SMBUS_MasterTxCpltCallback(hsmbus);
1368     }
1369     else if(hsmbus->State == HAL_SMBUS_STATE_MASTER_BUSY_RX)
1370     {
1371       /* Disable Interrupt */
1372       SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_RX);
1373
1374       /* Clear STOP Flag */
1375       __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_STOPF);
1376       
1377       /* Clear Configuration Register 2 */
1378       __HAL_SMBUS_RESET_CR2(hsmbus);
1379     
1380       hsmbus->PreviousState = HAL_SMBUS_STATE_READY;
1381       hsmbus->State = HAL_SMBUS_STATE_READY;
1382
1383       /* Process Unlocked */
1384       __HAL_UNLOCK(hsmbus);
1385   
1386       HAL_SMBUS_MasterRxCpltCallback(hsmbus);
1387     }
1388   }
1389   else if(__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_RXNE) != RESET)
1390   {  
1391     /* Read data from RXDR */
1392     (*hsmbus->pBuffPtr++) = hsmbus->Instance->RXDR;
1393     hsmbus->XferSize--;
1394     hsmbus->XferCount--;
1395   }
1396   else if(__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_TXIS) != RESET)
1397   {
1398     /* Write data to TXDR */
1399     hsmbus->Instance->TXDR = (*hsmbus->pBuffPtr++);
1400     hsmbus->XferSize--;
1401     hsmbus->XferCount--;        
1402   }
1403   else if(__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_TCR) != RESET)
1404   {
1405     if((hsmbus->XferSize == 0)&&(hsmbus->XferCount!=0))
1406     {
1407       DevAddress = (hsmbus->Instance->CR2 & I2C_CR2_SADD);
1408       
1409       if(hsmbus->XferCount > MAX_NBYTE_SIZE)
1410       {    
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;
1413       }
1414       else
1415       {
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)
1421         {
1422           hsmbus->XferSize--;
1423           hsmbus->XferCount--;
1424         }
1425       }
1426     }
1427     else if((hsmbus->XferSize == 0)&&(hsmbus->XferCount==0))
1428     {
1429       /* Call TxCpltCallback if no stop mode is set */
1430       if(__HAL_SMBUS_GET_STOP_MODE(hsmbus) != SMBUS_AUTOEND_MODE)
1431       {
1432         /* Call the corresponding callback to inform upper layer of End of Transfer */
1433         if(hsmbus->State == HAL_SMBUS_STATE_MASTER_BUSY_TX)
1434         {
1435           /* Disable Interrupt */
1436           SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_TX);
1437           hsmbus->PreviousState = hsmbus->State;
1438           hsmbus->State = HAL_SMBUS_STATE_READY;
1439
1440           /* Process Unlocked */
1441           __HAL_UNLOCK(hsmbus);
1442       
1443           HAL_SMBUS_MasterTxCpltCallback(hsmbus);
1444         }
1445         else if(hsmbus->State == HAL_SMBUS_STATE_MASTER_BUSY_RX)
1446         {
1447           SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_RX);
1448           hsmbus->PreviousState = hsmbus->State;
1449           hsmbus->State = HAL_SMBUS_STATE_READY;
1450
1451           /* Process Unlocked */
1452           __HAL_UNLOCK(hsmbus);
1453       
1454           HAL_SMBUS_MasterRxCpltCallback(hsmbus);
1455         }
1456       }
1457     }
1458   }
1459   else if(__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_TC) != RESET)
1460   {
1461     if(hsmbus->XferCount == 0)
1462     {
1463       /* Specific use case for Quick command */
1464       if(hsmbus->pBuffPtr == NULL)
1465       {
1466         /* Generate a Stop command */
1467         hsmbus->Instance->CR2 |= I2C_CR2_STOP;
1468       }
1469       /* Call TxCpltCallback if no stop mode is set */
1470       else if(__HAL_SMBUS_GET_STOP_MODE(hsmbus) != SMBUS_AUTOEND_MODE)
1471       {
1472         /* No Generate Stop, to permit restart mode */
1473         /* The stop will be done at the end of transfer, when SMBUS_AUTOEND_MODE enable */
1474         
1475         /* Call the corresponding callback to inform upper layer of End of Transfer */
1476         if(hsmbus->State == HAL_SMBUS_STATE_MASTER_BUSY_TX)
1477         {
1478           /* Disable Interrupt */
1479           SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_TX);
1480           hsmbus->PreviousState = hsmbus->State;
1481           hsmbus->State = HAL_SMBUS_STATE_READY;
1482
1483           /* Process Unlocked */
1484           __HAL_UNLOCK(hsmbus);
1485       
1486           HAL_SMBUS_MasterTxCpltCallback(hsmbus);
1487         }
1488         else if(hsmbus->State == HAL_SMBUS_STATE_MASTER_BUSY_RX)
1489         {
1490           SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_RX);
1491           hsmbus->PreviousState = hsmbus->State;
1492           hsmbus->State = HAL_SMBUS_STATE_READY;
1493
1494           /* Process Unlocked */
1495           __HAL_UNLOCK(hsmbus);
1496       
1497           HAL_SMBUS_MasterRxCpltCallback(hsmbus);
1498         }
1499       }
1500     }
1501   }
1502     
1503   /* Process Unlocked */
1504   __HAL_UNLOCK(hsmbus); 
1505   
1506   return HAL_OK; 
1507 }  
1508 /**
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
1513   */
1514 static HAL_StatusTypeDef SMBUS_Slave_ISR(SMBUS_HandleTypeDef *hsmbus) 
1515 {
1516   uint8_t TransferDirection = 0;
1517   uint16_t SlaveAddrCode = 0;
1518
1519   /* Process Locked */
1520   __HAL_LOCK(hsmbus);
1521   
1522   if(__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_AF) != RESET)
1523   {
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)
1529     {
1530       /* Clear NACK Flag */
1531       __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_AF);
1532
1533       /* Process Unlocked */
1534       __HAL_UNLOCK(hsmbus);
1535     }
1536     else
1537     {
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);
1541
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);
1547
1548       /* Disable RX/TX Interrupts, keep only ADDR Interrupt */
1549       SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_RX | SMBUS_IT_TX);
1550       
1551       /* Set ErrorCode corresponding to a Non-Acknowledge */
1552       hsmbus->ErrorCode |= HAL_SMBUS_ERROR_ACKF;
1553
1554       /* Process Unlocked */
1555       __HAL_UNLOCK(hsmbus);
1556     
1557       /* Call the Error callback to prevent upper layer */
1558       HAL_SMBUS_ErrorCallback(hsmbus);
1559     }
1560   }
1561   else if(__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_ADDR) != RESET)
1562   {
1563     TransferDirection = __HAL_SMBUS_GET_DIR(hsmbus);
1564     SlaveAddrCode = __HAL_SMBUS_GET_ADDR_MATCH(hsmbus);
1565       
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);
1569     
1570     /* Process Unlocked */
1571     __HAL_UNLOCK(hsmbus);
1572
1573     /* Call Slave Addr callback */
1574     HAL_SMBUS_SlaveAddrCallback(hsmbus, TransferDirection, SlaveAddrCode);
1575   }
1576   else if((__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_RXNE) != RESET) || (__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_TCR) != RESET))
1577   {
1578     if( (hsmbus->State & HAL_SMBUS_STATE_SLAVE_BUSY_RX) == HAL_SMBUS_STATE_SLAVE_BUSY_RX)
1579     {
1580       /* Read data from RXDR */
1581       (*hsmbus->pBuffPtr++) = hsmbus->Instance->RXDR;
1582       hsmbus->XferSize--;
1583       hsmbus->XferCount--;
1584
1585       if(hsmbus->XferCount == 1)
1586       {
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);
1592       }
1593       else if(hsmbus->XferCount == 0)
1594       {
1595         /* Last Byte is received, disable Interrupt */
1596         SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_RX);
1597         
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);
1601         
1602         /* Process Unlocked */
1603         __HAL_UNLOCK(hsmbus);
1604
1605         /* Call the Rx complete callback to inform upper layer of the end of receive process */
1606         HAL_SMBUS_SlaveRxCpltCallback(hsmbus);
1607       }
1608       else
1609       {
1610         /* Set Reload for next Bytes */
1611         SMBUS_TransferConfig(hsmbus,0, 1, SMBUS_RELOAD_MODE  | (hsmbus->XferOptions & SMBUS_SENDPEC_MODE), SMBUS_NO_STARTSTOP);
1612
1613         /* Ack last Byte Read */
1614         hsmbus->Instance->CR2 &= ~I2C_CR2_NACK;
1615       }
1616     }    
1617     else if( (hsmbus->State & HAL_SMBUS_STATE_SLAVE_BUSY_TX) == HAL_SMBUS_STATE_SLAVE_BUSY_TX)
1618     {
1619       if((hsmbus->XferSize == 0)&&(hsmbus->XferCount!=0))
1620       {
1621         if(hsmbus->XferCount > MAX_NBYTE_SIZE)
1622         {    
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;
1625         }
1626         else
1627         {
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)
1633           {
1634             hsmbus->XferSize--;
1635             hsmbus->XferCount--;
1636           }
1637         }
1638       }
1639     }
1640   }
1641   else if(__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_TXIS) != RESET)
1642   {
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)
1648     {
1649       /* Write data to TXDR */
1650       hsmbus->Instance->TXDR = (*hsmbus->pBuffPtr++);
1651       hsmbus->XferCount--;
1652       hsmbus->XferSize--;
1653     }
1654     
1655     if(hsmbus->XferCount == 0)
1656     {
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);
1662
1663       /* Process Unlocked */
1664       __HAL_UNLOCK(hsmbus);
1665
1666       /* Call the Tx complete callback to inform upper layer of the end of transmit process */
1667       HAL_SMBUS_SlaveTxCpltCallback(hsmbus);
1668     }
1669   }
1670
1671   /* Check if STOPF is set */
1672   if(__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_STOPF) != RESET)
1673   {
1674     if((hsmbus->State & HAL_SMBUS_STATE_LISTEN) == HAL_SMBUS_STATE_LISTEN)
1675     {
1676       /* Disable RX and TX Interrupts */
1677       SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_RX | SMBUS_IT_TX);
1678
1679       /* Disable ADDR Interrupt */
1680       SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_ADDR);
1681
1682       /* Disable Address Acknowledge */
1683       hsmbus->Instance->CR2 |= I2C_CR2_NACK;
1684
1685       /* Clear Configuration Register 2 */
1686       __HAL_SMBUS_RESET_CR2(hsmbus);
1687     
1688       /* Clear STOP Flag */
1689       __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_STOPF);
1690
1691      /* Clear ADDR flag */
1692      __HAL_SMBUS_CLEAR_FLAG(hsmbus,SMBUS_FLAG_ADDR);
1693
1694       hsmbus->XferOptions = 0;
1695       hsmbus->PreviousState = hsmbus->State;
1696       hsmbus->State = HAL_SMBUS_STATE_READY;
1697     
1698       /* Process Unlocked */
1699       __HAL_UNLOCK(hsmbus);
1700
1701       /* Call the Listen Complete callback, to prevent upper layer of the end of Listen usecase */
1702       HAL_SMBUS_SlaveListenCpltCallback(hsmbus);
1703     }
1704   }
1705
1706   /* Process Unlocked */
1707   __HAL_UNLOCK(hsmbus);
1708   
1709   return HAL_OK;     
1710 }  
1711 /**
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
1717   */
1718 static HAL_StatusTypeDef SMBUS_Enable_IRQ(SMBUS_HandleTypeDef *hsmbus, uint16_t InterruptRequest) 
1719 {
1720   uint32_t tmpisr = 0;
1721
1722   if((InterruptRequest & SMBUS_IT_ALERT) == SMBUS_IT_ALERT)
1723   {
1724     /* Enable ERR interrupt */
1725     tmpisr |= SMBUS_IT_ERRI;
1726   }
1727   
1728   if((InterruptRequest & SMBUS_IT_ADDR) == SMBUS_IT_ADDR)
1729   {
1730     /* Enable ADDR, STOP interrupt */
1731     tmpisr |= SMBUS_IT_ADDRI | SMBUS_IT_STOPI | SMBUS_IT_NACKI | SMBUS_IT_ERRI;
1732   }
1733   
1734   if((InterruptRequest & SMBUS_IT_TX) == SMBUS_IT_TX)
1735   {
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;
1738   }
1739   
1740   if((InterruptRequest & SMBUS_IT_RX) == SMBUS_IT_RX)
1741   {
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;
1744   }
1745   
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);
1750
1751   return HAL_OK;     
1752 }
1753 /**
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
1759   */
1760 static HAL_StatusTypeDef SMBUS_Disable_IRQ(SMBUS_HandleTypeDef *hsmbus, uint16_t InterruptRequest) 
1761 {
1762   uint32_t tmpisr = 0;
1763
1764   if( ((InterruptRequest & SMBUS_IT_ALERT) == SMBUS_IT_ALERT) && (hsmbus->State == HAL_SMBUS_STATE_READY) )
1765   {
1766     /* Disable ERR interrupt */
1767     tmpisr |= SMBUS_IT_ERRI;
1768   }
1769   
1770   if((InterruptRequest & SMBUS_IT_TX) == SMBUS_IT_TX)
1771   {
1772     /* Disable TC, STOP, NACK, TXI interrupt */
1773     tmpisr |= SMBUS_IT_TCI | SMBUS_IT_TXI;
1774     
1775     if((__HAL_SMBUS_GET_ALERT_ENABLED(hsmbus) == RESET)
1776        && ((hsmbus->State & HAL_SMBUS_STATE_LISTEN) != HAL_SMBUS_STATE_LISTEN))
1777     {
1778       /* Disable ERR interrupt */
1779       tmpisr |= SMBUS_IT_ERRI;
1780     }
1781     
1782     if((hsmbus->State & HAL_SMBUS_STATE_LISTEN) != HAL_SMBUS_STATE_LISTEN)
1783     {
1784       /* Disable STOPI, NACKI */
1785       tmpisr |= SMBUS_IT_STOPI | SMBUS_IT_NACKI;
1786     }
1787   }
1788   
1789   if((InterruptRequest & SMBUS_IT_RX) == SMBUS_IT_RX)
1790   {
1791     /* Disable TC, STOP, NACK, RXI interrupt */
1792     tmpisr |= SMBUS_IT_TCI | SMBUS_IT_RXI;
1793     
1794     if((__HAL_SMBUS_GET_ALERT_ENABLED(hsmbus) == RESET)
1795        && ((hsmbus->State & HAL_SMBUS_STATE_LISTEN) != HAL_SMBUS_STATE_LISTEN))
1796     {
1797       /* Disable ERR interrupt */
1798       tmpisr |= SMBUS_IT_ERRI;
1799     }
1800
1801     if((hsmbus->State & HAL_SMBUS_STATE_LISTEN) != HAL_SMBUS_STATE_LISTEN)
1802     {
1803       /* Disable STOPI, NACKI */
1804       tmpisr |= SMBUS_IT_STOPI | SMBUS_IT_NACKI;
1805     }
1806   }
1807   
1808   if((InterruptRequest & SMBUS_IT_ADDR) == SMBUS_IT_ADDR)
1809   {
1810     /* Enable ADDR, STOP interrupt */
1811     tmpisr |= SMBUS_IT_ADDRI | SMBUS_IT_STOPI | SMBUS_IT_NACKI;
1812
1813     if(__HAL_SMBUS_GET_ALERT_ENABLED(hsmbus) == RESET) 
1814     {
1815       /* Disable ERR interrupt */
1816       tmpisr |= SMBUS_IT_ERRI;
1817     }
1818   }
1819
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);
1824   
1825   return HAL_OK;
1826 }
1827 /**
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
1835   */
1836 static HAL_StatusTypeDef SMBUS_WaitOnFlagUntilTimeout(SMBUS_HandleTypeDef *hsmbus, uint32_t Flag, FlagStatus Status, uint32_t Timeout)  
1837 {  
1838   uint32_t tickstart = HAL_GetTick();
1839   
1840   /* Wait until flag is set */
1841   if(Status == RESET)
1842   {    
1843     while(__HAL_SMBUS_GET_FLAG(hsmbus, Flag) == RESET)
1844     {
1845       /* Check for the Timeout */
1846       if(Timeout != HAL_MAX_DELAY)
1847       {
1848         if((Timeout == 0) || ((HAL_GetTick() - tickstart) > Timeout))
1849         {
1850           hsmbus->PreviousState = hsmbus->State;
1851           hsmbus->State= HAL_SMBUS_STATE_READY;
1852         
1853           /* Process Unlocked */
1854           __HAL_UNLOCK(hsmbus);
1855         
1856           return HAL_TIMEOUT;
1857         }
1858       }
1859     }
1860   }
1861   else
1862   {
1863     while(__HAL_SMBUS_GET_FLAG(hsmbus, Flag) != RESET)
1864     {
1865       /* Check for the Timeout */
1866       if(Timeout != HAL_MAX_DELAY)
1867       {
1868         if((Timeout == 0) || ((HAL_GetTick() - tickstart) > Timeout))
1869         {
1870           hsmbus->PreviousState = hsmbus->State;
1871           hsmbus->State= HAL_SMBUS_STATE_READY;
1872         
1873           /* Process Unlocked */
1874           __HAL_UNLOCK(hsmbus);
1875         
1876           return HAL_TIMEOUT;
1877         }
1878       }
1879     }
1880   }
1881   return HAL_OK;      
1882 }
1883
1884 /**
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.
1902   * @retval None
1903   */
1904 static void SMBUS_TransferConfig(SMBUS_HandleTypeDef *hsmbus,  uint16_t DevAddress, uint8_t Size, uint32_t Mode, uint32_t Request)
1905 {
1906   uint32_t tmpreg = 0;
1907   
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));
1912     
1913   /* Get the CR2 register value */
1914   tmpreg = hsmbus->Instance->CR2;
1915   
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));
1918   
1919   /* update tmpreg */
1920   tmpreg |= (uint32_t)(((uint32_t)DevAddress & I2C_CR2_SADD) | (((uint32_t)Size << 16 ) & I2C_CR2_NBYTES) | \
1921               (uint32_t)Mode | (uint32_t)Request);
1922     
1923   /* update CR2 register */
1924   hsmbus->Instance->CR2 = tmpreg;  
1925 }  
1926 /**
1927   * @}
1928   */
1929
1930 #endif /* HAL_SMBUS_MODULE_ENABLED */
1931 /**
1932   * @}
1933   */
1934
1935 /**
1936   * @}
1937   */
1938
1939 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/