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