Subversion Repositories FuelGauge

Rev

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