Subversion Repositories FuelGauge

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

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