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_i2c.c
4
  * @author  MCD Application Team
5
  * @brief   I2C HAL module driver.
6
  *          This file provides firmware functions to manage the following
7
  *          functionalities of the Inter Integrated Circuit (I2C) peripheral:
8
  *           + Initialization and de-initialization functions
9
  *           + IO operation functions
10
  *           + Peripheral State and Errors functions
11
  *
12
  @verbatim
13
  ==============================================================================
14
                        ##### How to use this driver #####
15
  ==============================================================================
16
    [..]
17
    The I2C HAL driver can be used as follows:
18
 
19
    (#) Declare a I2C_HandleTypeDef handle structure, for example:
20
        I2C_HandleTypeDef  hi2c;
21
 
6 mjames 22
    (#)Initialize the I2C low level resources by implementing the HAL_I2C_MspInit() API:
2 mjames 23
        (##) Enable the I2Cx interface clock
24
        (##) I2C pins configuration
25
            (+++) Enable the clock for the I2C GPIOs
26
            (+++) Configure I2C pins as alternate function open-drain
27
        (##) NVIC configuration if you need to use interrupt process
28
            (+++) Configure the I2Cx interrupt priority
29
            (+++) Enable the NVIC I2C IRQ Channel
30
        (##) DMA Configuration if you need to use DMA process
6 mjames 31
            (+++) Declare a DMA_HandleTypeDef handle structure for
32
                  the transmit or receive channel
2 mjames 33
            (+++) Enable the DMAx interface clock using
34
            (+++) Configure the DMA handle parameters
35
            (+++) Configure the DMA Tx or Rx channel
36
            (+++) Associate the initialized DMA handle to the hi2c DMA Tx or Rx handle
37
            (+++) Configure the priority and enable the NVIC for the transfer complete interrupt on
38
                  the DMA Tx or Rx channel
39
 
40
    (#) Configure the Communication Clock Timing, Own Address1, Master Addressing mode, Dual Addressing mode,
41
        Own Address2, Own Address2 Mask, General call and Nostretch mode in the hi2c Init structure.
42
 
6 mjames 43
    (#) Initialize the I2C registers by calling the HAL_I2C_Init(), configures also the low level Hardware
44
        (GPIO, CLOCK, NVIC...etc) by calling the customized HAL_I2C_MspInit(&hi2c) API.
2 mjames 45
 
6 mjames 46
    (#) To check if target device is ready for communication, use the function HAL_I2C_IsDeviceReady()
2 mjames 47
 
48
    (#) For I2C IO and IO MEM operations, three operation modes are available within this driver :
49
 
50
    *** Polling mode IO operation ***
51
    =================================
52
    [..]
6 mjames 53
      (+) Transmit in master mode an amount of data in blocking mode using HAL_I2C_Master_Transmit()
54
      (+) Receive in master mode an amount of data in blocking mode using HAL_I2C_Master_Receive()
55
      (+) Transmit in slave mode an amount of data in blocking mode using HAL_I2C_Slave_Transmit()
56
      (+) Receive in slave mode an amount of data in blocking mode using HAL_I2C_Slave_Receive()
2 mjames 57
 
58
    *** Polling mode IO MEM operation ***
59
    =====================================
60
    [..]
6 mjames 61
      (+) Write an amount of data in blocking mode to a specific memory address using HAL_I2C_Mem_Write()
62
      (+) Read an amount of data in blocking mode from a specific memory address using HAL_I2C_Mem_Read()
2 mjames 63
 
64
 
65
    *** Interrupt mode IO operation ***
66
    ===================================
67
    [..]
6 mjames 68
      (+) Transmit in master mode an amount of data in non-blocking mode using HAL_I2C_Master_Transmit_IT()
69
      (+) At transmission end of transfer, HAL_I2C_MasterTxCpltCallback() is executed and users can
70
           add their own code by customization of function pointer HAL_I2C_MasterTxCpltCallback()
71
      (+) Receive in master mode an amount of data in non-blocking mode using HAL_I2C_Master_Receive_IT()
72
      (+) At reception end of transfer, HAL_I2C_MasterRxCpltCallback() is executed and users can
73
           add their own code by customization of function pointer HAL_I2C_MasterRxCpltCallback()
74
      (+) Transmit in slave mode an amount of data in non-blocking mode using HAL_I2C_Slave_Transmit_IT()
75
      (+) At transmission end of transfer, HAL_I2C_SlaveTxCpltCallback() is executed and users can
76
           add their own code by customization of function pointer HAL_I2C_SlaveTxCpltCallback()
77
      (+) Receive in slave mode an amount of data in non-blocking mode using HAL_I2C_Slave_Receive_IT()
78
      (+) At reception end of transfer, HAL_I2C_SlaveRxCpltCallback() is executed and users can
79
           add their own code by customization of function pointer HAL_I2C_SlaveRxCpltCallback()
80
      (+) In case of transfer Error, HAL_I2C_ErrorCallback() function is executed and users can
81
           add their own code by customization of function pointer HAL_I2C_ErrorCallback()
82
      (+) Abort a master I2C process communication with Interrupt using HAL_I2C_Master_Abort_IT()
83
      (+) End of abort process, HAL_I2C_AbortCpltCallback() is executed and users can
84
           add their own code by customization of function pointer HAL_I2C_AbortCpltCallback()
85
      (+) Discard a slave I2C process communication using __HAL_I2C_GENERATE_NACK() macro.
2 mjames 86
           This action will inform Master to generate a Stop condition to discard the communication.
87
 
88
 
89
    *** Interrupt mode or DMA mode IO sequential operation ***
90
    ==========================================================
91
    [..]
92
      (@) These interfaces allow to manage a sequential transfer with a repeated start condition
93
          when a direction change during transfer
94
    [..]
95
      (+) A specific option field manage the different steps of a sequential transfer
6 mjames 96
      (+) Option field values are defined through I2C_XFEROPTIONS and are listed below:
97
      (++) I2C_FIRST_AND_LAST_FRAME: No sequential usage, functional is same as associated interfaces in
98
           no sequential mode
2 mjames 99
      (++) I2C_FIRST_FRAME: Sequential usage, this option allow to manage a sequence with start condition, address
100
                            and data to transfer without a final stop condition
6 mjames 101
      (++) I2C_FIRST_AND_NEXT_FRAME: Sequential usage (Master only), this option allow to manage a sequence with
102
                            start condition, address and data to transfer without a final stop condition,
103
                            an then permit a call the same master sequential interface several times
104
                            (like HAL_I2C_Master_Seq_Transmit_IT() then HAL_I2C_Master_Seq_Transmit_IT()
105
                            or HAL_I2C_Master_Seq_Transmit_DMA() then HAL_I2C_Master_Seq_Transmit_DMA())
2 mjames 106
      (++) I2C_NEXT_FRAME: Sequential usage, this option allow to manage a sequence with a restart condition, address
6 mjames 107
                            and with new data to transfer if the direction change or manage only the new data to
108
                            transfer
2 mjames 109
                            if no direction change and without a final stop condition in both cases
110
      (++) I2C_LAST_FRAME: Sequential usage, this option allow to manage a sequance with a restart condition, address
6 mjames 111
                            and with new data to transfer if the direction change or manage only the new data to
112
                            transfer
2 mjames 113
                            if no direction change and with a final stop condition in both cases
6 mjames 114
      (++) I2C_LAST_FRAME_NO_STOP: Sequential usage (Master only), this option allow to manage a restart condition
115
                            after several call of the same master sequential interface several times
116
                            (link with option I2C_FIRST_AND_NEXT_FRAME).
117
                            Usage can, transfer several bytes one by one using
118
                              HAL_I2C_Master_Seq_Transmit_IT
119
                              or HAL_I2C_Master_Seq_Receive_IT
120
                              or HAL_I2C_Master_Seq_Transmit_DMA
121
                              or HAL_I2C_Master_Seq_Receive_DMA
122
                              with option I2C_FIRST_AND_NEXT_FRAME then I2C_NEXT_FRAME.
123
                             Then usage of this option I2C_LAST_FRAME_NO_STOP at the last Transmit or
124
                              Receive sequence permit to call the opposite interface Receive or Transmit
2 mjames 125
                              without stopping the communication and so generate a restart condition.
6 mjames 126
      (++) I2C_OTHER_FRAME: Sequential usage (Master only), this option allow to manage a restart condition after
127
                            each call of the same master sequential
2 mjames 128
                            interface.
6 mjames 129
                            Usage can, transfer several bytes one by one with a restart with slave address between
130
                            each bytes using
131
                              HAL_I2C_Master_Seq_Transmit_IT
132
                              or HAL_I2C_Master_Seq_Receive_IT
133
                              or HAL_I2C_Master_Seq_Transmit_DMA
134
                              or HAL_I2C_Master_Seq_Receive_DMA
135
                              with option I2C_FIRST_FRAME then I2C_OTHER_FRAME.
136
                            Then usage of this option I2C_OTHER_AND_LAST_FRAME at the last frame to help automatic
137
                            generation of STOP condition.
2 mjames 138
 
6 mjames 139
      (+) Different sequential I2C interfaces are listed below:
140
      (++) Sequential transmit in master I2C mode an amount of data in non-blocking mode using
141
            HAL_I2C_Master_Seq_Transmit_IT() or using HAL_I2C_Master_Seq_Transmit_DMA()
142
      (+++) At transmission end of current frame transfer, HAL_I2C_MasterTxCpltCallback() is executed and
143
            users can add their own code by customization of function pointer HAL_I2C_MasterTxCpltCallback()
144
      (++) Sequential receive in master I2C mode an amount of data in non-blocking mode using
145
            HAL_I2C_Master_Seq_Receive_IT() or using HAL_I2C_Master_Seq_Receive_DMA()
146
      (+++) At reception end of current frame transfer, HAL_I2C_MasterRxCpltCallback() is executed and users can
147
           add their own code by customization of function pointer HAL_I2C_MasterRxCpltCallback()
148
      (++) Abort a master IT or DMA I2C process communication with Interrupt using HAL_I2C_Master_Abort_IT()
149
      (+++) End of abort process, HAL_I2C_AbortCpltCallback() is executed and users can
150
           add their own code by customization of function pointer HAL_I2C_AbortCpltCallback()
151
      (++) Enable/disable the Address listen mode in slave I2C mode using HAL_I2C_EnableListen_IT()
152
            HAL_I2C_DisableListen_IT()
153
      (+++) When address slave I2C match, HAL_I2C_AddrCallback() is executed and users can
154
           add their own code to check the Address Match Code and the transmission direction request by master
155
           (Write/Read).
156
      (+++) At Listen mode end HAL_I2C_ListenCpltCallback() is executed and users can
157
          add their own code by customization of function pointer HAL_I2C_ListenCpltCallback()
158
      (++) Sequential transmit in slave I2C mode an amount of data in non-blocking mode using
159
            HAL_I2C_Slave_Seq_Transmit_IT() or using HAL_I2C_Slave_Seq_Transmit_DMA()
160
      (+++) At transmission end of current frame transfer, HAL_I2C_SlaveTxCpltCallback() is executed and
161
            users can add their own code by customization of function pointer HAL_I2C_SlaveTxCpltCallback()
162
      (++) Sequential receive in slave I2C mode an amount of data in non-blocking mode using
163
            HAL_I2C_Slave_Seq_Receive_IT() or using HAL_I2C_Slave_Seq_Receive_DMA()
164
      (+++) At reception end of current frame transfer, HAL_I2C_SlaveRxCpltCallback() is executed and users can
165
           add their own code by customization of function pointer HAL_I2C_SlaveRxCpltCallback()
166
      (++) In case of transfer Error, HAL_I2C_ErrorCallback() function is executed and users can
167
           add their own code by customization of function pointer HAL_I2C_ErrorCallback()
168
      (++) Discard a slave I2C process communication using __HAL_I2C_GENERATE_NACK() macro.
2 mjames 169
           This action will inform Master to generate a Stop condition to discard the communication.
170
 
171
    *** Interrupt mode IO MEM operation ***
172
    =======================================
173
    [..]
174
      (+) Write an amount of data in non-blocking mode with Interrupt to a specific memory address using
6 mjames 175
          HAL_I2C_Mem_Write_IT()
176
      (+) At Memory end of write transfer, HAL_I2C_MemTxCpltCallback() is executed and users can
177
           add their own code by customization of function pointer HAL_I2C_MemTxCpltCallback()
2 mjames 178
      (+) Read an amount of data in non-blocking mode with Interrupt from a specific memory address using
6 mjames 179
          HAL_I2C_Mem_Read_IT()
180
      (+) At Memory end of read transfer, HAL_I2C_MemRxCpltCallback() is executed and users can
181
           add their own code by customization of function pointer HAL_I2C_MemRxCpltCallback()
182
      (+) In case of transfer Error, HAL_I2C_ErrorCallback() function is executed and users can
183
           add their own code by customization of function pointer HAL_I2C_ErrorCallback()
2 mjames 184
 
185
    *** DMA mode IO operation ***
186
    ==============================
187
    [..]
188
      (+) Transmit in master mode an amount of data in non-blocking mode (DMA) using
6 mjames 189
          HAL_I2C_Master_Transmit_DMA()
190
      (+) At transmission end of transfer, HAL_I2C_MasterTxCpltCallback() is executed and users can
191
           add their own code by customization of function pointer HAL_I2C_MasterTxCpltCallback()
2 mjames 192
      (+) Receive in master mode an amount of data in non-blocking mode (DMA) using
6 mjames 193
          HAL_I2C_Master_Receive_DMA()
194
      (+) At reception end of transfer, HAL_I2C_MasterRxCpltCallback() is executed and users can
195
           add their own code by customization of function pointer HAL_I2C_MasterRxCpltCallback()
2 mjames 196
      (+) Transmit in slave mode an amount of data in non-blocking mode (DMA) using
6 mjames 197
          HAL_I2C_Slave_Transmit_DMA()
198
      (+) At transmission end of transfer, HAL_I2C_SlaveTxCpltCallback() is executed and users can
199
           add their own code by customization of function pointer HAL_I2C_SlaveTxCpltCallback()
2 mjames 200
      (+) Receive in slave mode an amount of data in non-blocking mode (DMA) using
6 mjames 201
          HAL_I2C_Slave_Receive_DMA()
202
      (+) At reception end of transfer, HAL_I2C_SlaveRxCpltCallback() is executed and users can
203
           add their own code by customization of function pointer HAL_I2C_SlaveRxCpltCallback()
204
      (+) In case of transfer Error, HAL_I2C_ErrorCallback() function is executed and users can
205
           add their own code by customization of function pointer HAL_I2C_ErrorCallback()
206
      (+) Abort a master I2C process communication with Interrupt using HAL_I2C_Master_Abort_IT()
207
      (+) End of abort process, HAL_I2C_AbortCpltCallback() is executed and users can
208
           add their own code by customization of function pointer HAL_I2C_AbortCpltCallback()
209
      (+) Discard a slave I2C process communication using __HAL_I2C_GENERATE_NACK() macro.
2 mjames 210
           This action will inform Master to generate a Stop condition to discard the communication.
211
 
212
    *** DMA mode IO MEM operation ***
213
    =================================
214
    [..]
215
      (+) Write an amount of data in non-blocking mode with DMA to a specific memory address using
6 mjames 216
          HAL_I2C_Mem_Write_DMA()
217
      (+) At Memory end of write transfer, HAL_I2C_MemTxCpltCallback() is executed and users can
218
           add their own code by customization of function pointer HAL_I2C_MemTxCpltCallback()
2 mjames 219
      (+) Read an amount of data in non-blocking mode with DMA from a specific memory address using
6 mjames 220
          HAL_I2C_Mem_Read_DMA()
221
      (+) At Memory end of read transfer, HAL_I2C_MemRxCpltCallback() is executed and users can
222
           add their own code by customization of function pointer HAL_I2C_MemRxCpltCallback()
223
      (+) In case of transfer Error, HAL_I2C_ErrorCallback() function is executed and users can
224
           add their own code by customization of function pointer HAL_I2C_ErrorCallback()
2 mjames 225
 
226
 
227
     *** I2C HAL driver macros list ***
228
     ==================================
229
     [..]
230
       Below the list of most used macros in I2C HAL driver.
231
 
6 mjames 232
      (+) __HAL_I2C_ENABLE: Enable the I2C peripheral
233
      (+) __HAL_I2C_DISABLE: Disable the I2C peripheral
234
      (+) __HAL_I2C_GENERATE_NACK: Generate a Non-Acknowledge I2C peripheral in Slave mode
235
      (+) __HAL_I2C_GET_FLAG: Check whether the specified I2C flag is set or not
236
      (+) __HAL_I2C_CLEAR_FLAG: Clear the specified I2C pending flag
237
      (+) __HAL_I2C_ENABLE_IT: Enable the specified I2C interrupt
238
      (+) __HAL_I2C_DISABLE_IT: Disable the specified I2C interrupt
2 mjames 239
 
240
     *** Callback registration ***
241
     =============================================
242
    [..]
243
     The compilation flag USE_HAL_I2C_REGISTER_CALLBACKS when set to 1
244
     allows the user to configure dynamically the driver callbacks.
6 mjames 245
     Use Functions HAL_I2C_RegisterCallback() or HAL_I2C_RegisterAddrCallback()
2 mjames 246
     to register an interrupt callback.
247
    [..]
6 mjames 248
     Function HAL_I2C_RegisterCallback() allows to register following callbacks:
2 mjames 249
       (+) MasterTxCpltCallback : callback for Master transmission end of transfer.
250
       (+) MasterRxCpltCallback : callback for Master reception end of transfer.
251
       (+) SlaveTxCpltCallback  : callback for Slave transmission end of transfer.
252
       (+) SlaveRxCpltCallback  : callback for Slave reception end of transfer.
253
       (+) ListenCpltCallback   : callback for end of listen mode.
254
       (+) MemTxCpltCallback    : callback for Memory transmission end of transfer.
255
       (+) MemRxCpltCallback    : callback for Memory reception end of transfer.
256
       (+) ErrorCallback        : callback for error detection.
257
       (+) AbortCpltCallback    : callback for abort completion process.
258
       (+) MspInitCallback      : callback for Msp Init.
259
       (+) MspDeInitCallback    : callback for Msp DeInit.
260
     This function takes as parameters the HAL peripheral handle, the Callback ID
261
     and a pointer to the user callback function.
262
    [..]
6 mjames 263
     For specific callback AddrCallback use dedicated register callbacks : HAL_I2C_RegisterAddrCallback().
2 mjames 264
    [..]
6 mjames 265
     Use function HAL_I2C_UnRegisterCallback to reset a callback to the default
2 mjames 266
     weak function.
6 mjames 267
     HAL_I2C_UnRegisterCallback takes as parameters the HAL peripheral handle,
2 mjames 268
     and the Callback ID.
269
     This function allows to reset following callbacks:
270
       (+) MasterTxCpltCallback : callback for Master transmission end of transfer.
271
       (+) MasterRxCpltCallback : callback for Master reception end of transfer.
272
       (+) SlaveTxCpltCallback  : callback for Slave transmission end of transfer.
273
       (+) SlaveRxCpltCallback  : callback for Slave reception end of transfer.
274
       (+) ListenCpltCallback   : callback for end of listen mode.
275
       (+) MemTxCpltCallback    : callback for Memory transmission end of transfer.
276
       (+) MemRxCpltCallback    : callback for Memory reception end of transfer.
277
       (+) ErrorCallback        : callback for error detection.
278
       (+) AbortCpltCallback    : callback for abort completion process.
279
       (+) MspInitCallback      : callback for Msp Init.
280
       (+) MspDeInitCallback    : callback for Msp DeInit.
281
    [..]
6 mjames 282
     For callback AddrCallback use dedicated register callbacks : HAL_I2C_UnRegisterAddrCallback().
2 mjames 283
    [..]
6 mjames 284
     By default, after the HAL_I2C_Init() and when the state is HAL_I2C_STATE_RESET
2 mjames 285
     all callbacks are set to the corresponding weak functions:
6 mjames 286
     examples HAL_I2C_MasterTxCpltCallback(), HAL_I2C_MasterRxCpltCallback().
2 mjames 287
     Exception done for MspInit and MspDeInit functions that are
6 mjames 288
     reset to the legacy weak functions in the HAL_I2C_Init()/ HAL_I2C_DeInit() only when
2 mjames 289
     these callbacks are null (not registered beforehand).
6 mjames 290
     If MspInit or MspDeInit are not null, the HAL_I2C_Init()/ HAL_I2C_DeInit()
2 mjames 291
     keep and use the user MspInit/MspDeInit callbacks (registered beforehand) whatever the state.
292
    [..]
6 mjames 293
     Callbacks can be registered/unregistered in HAL_I2C_STATE_READY state only.
2 mjames 294
     Exception done MspInit/MspDeInit functions that can be registered/unregistered
6 mjames 295
     in HAL_I2C_STATE_READY or HAL_I2C_STATE_RESET state,
2 mjames 296
     thus registered (user) MspInit/DeInit callbacks can be used during the Init/DeInit.
297
     Then, the user first registers the MspInit/MspDeInit user callbacks
6 mjames 298
     using HAL_I2C_RegisterCallback() before calling HAL_I2C_DeInit()
299
     or HAL_I2C_Init() function.
2 mjames 300
    [..]
301
     When the compilation flag USE_HAL_I2C_REGISTER_CALLBACKS is set to 0 or
302
     not defined, the callback registration feature is not available and all callbacks
303
     are set to the corresponding weak functions.
304
 
305
     [..]
306
       (@) You can refer to the I2C HAL driver header file for more useful macros
307
 
308
  @endverbatim
309
  ******************************************************************************
310
  * @attention
311
  *
312
  * <h2><center>&copy; Copyright (c) 2016 STMicroelectronics.
313
  * All rights reserved.</center></h2>
314
  *
315
  * This software component is licensed by ST under BSD 3-Clause license,
316
  * the "License"; You may not use this file except in compliance with the
317
  * License. You may obtain a copy of the License at:
318
  *                        opensource.org/licenses/BSD-3-Clause
319
  *
320
  ******************************************************************************
321
  */
322
 
323
/* Includes ------------------------------------------------------------------*/
324
#include "stm32f0xx_hal.h"
325
 
326
/** @addtogroup STM32F0xx_HAL_Driver
327
  * @{
328
  */
329
 
330
/** @defgroup I2C I2C
331
  * @brief I2C HAL module driver
332
  * @{
333
  */
334
 
335
#ifdef HAL_I2C_MODULE_ENABLED
336
 
337
/* Private typedef -----------------------------------------------------------*/
338
/* Private define ------------------------------------------------------------*/
339
 
340
/** @defgroup I2C_Private_Define I2C Private Define
341
  * @{
342
  */
343
#define TIMING_CLEAR_MASK   (0xF0FFFFFFU)  /*!< I2C TIMING clear register Mask */
344
#define I2C_TIMEOUT_ADDR    (10000U)       /*!< 10 s  */
345
#define I2C_TIMEOUT_BUSY    (25U)          /*!< 25 ms */
346
#define I2C_TIMEOUT_DIR     (25U)          /*!< 25 ms */
347
#define I2C_TIMEOUT_RXNE    (25U)          /*!< 25 ms */
348
#define I2C_TIMEOUT_STOPF   (25U)          /*!< 25 ms */
349
#define I2C_TIMEOUT_TC      (25U)          /*!< 25 ms */
350
#define I2C_TIMEOUT_TCR     (25U)          /*!< 25 ms */
351
#define I2C_TIMEOUT_TXIS    (25U)          /*!< 25 ms */
352
#define I2C_TIMEOUT_FLAG    (25U)          /*!< 25 ms */
353
 
354
#define MAX_NBYTE_SIZE      255U
6 mjames 355
#define SLAVE_ADDR_SHIFT     7U
356
#define SLAVE_ADDR_MSK       0x06U
2 mjames 357
 
358
/* Private define for @ref PreviousState usage */
6 mjames 359
#define I2C_STATE_MSK             ((uint32_t)((uint32_t)((uint32_t)HAL_I2C_STATE_BUSY_TX | \
360
                                                         (uint32_t)HAL_I2C_STATE_BUSY_RX) & \
361
                                              (uint32_t)(~((uint32_t)HAL_I2C_STATE_READY))))
362
/*!< Mask State define, keep only RX and TX bits */
363
#define I2C_STATE_NONE            ((uint32_t)(HAL_I2C_MODE_NONE))
364
/*!< Default Value */
365
#define I2C_STATE_MASTER_BUSY_TX  ((uint32_t)(((uint32_t)HAL_I2C_STATE_BUSY_TX & I2C_STATE_MSK) | \
366
                                              (uint32_t)HAL_I2C_MODE_MASTER))
367
/*!< Master Busy TX, combinaison of State LSB and Mode enum */
368
#define I2C_STATE_MASTER_BUSY_RX  ((uint32_t)(((uint32_t)HAL_I2C_STATE_BUSY_RX & I2C_STATE_MSK) | \
369
                                              (uint32_t)HAL_I2C_MODE_MASTER))
370
/*!< Master Busy RX, combinaison of State LSB and Mode enum */
371
#define I2C_STATE_SLAVE_BUSY_TX   ((uint32_t)(((uint32_t)HAL_I2C_STATE_BUSY_TX & I2C_STATE_MSK) | \
372
                                              (uint32_t)HAL_I2C_MODE_SLAVE))
373
/*!< Slave Busy TX, combinaison of State LSB and Mode enum */
374
#define I2C_STATE_SLAVE_BUSY_RX   ((uint32_t)(((uint32_t)HAL_I2C_STATE_BUSY_RX & I2C_STATE_MSK) | \
375
                                              (uint32_t)HAL_I2C_MODE_SLAVE))
376
/*!< Slave Busy RX, combinaison of State LSB and Mode enum  */
377
#define I2C_STATE_MEM_BUSY_TX     ((uint32_t)(((uint32_t)HAL_I2C_STATE_BUSY_TX & I2C_STATE_MSK) | \
378
                                              (uint32_t)HAL_I2C_MODE_MEM))
379
/*!< Memory Busy TX, combinaison of State LSB and Mode enum */
380
#define I2C_STATE_MEM_BUSY_RX     ((uint32_t)(((uint32_t)HAL_I2C_STATE_BUSY_RX & I2C_STATE_MSK) | \
381
                                              (uint32_t)HAL_I2C_MODE_MEM))
382
/*!< Memory Busy RX, combinaison of State LSB and Mode enum */
2 mjames 383
 
384
 
385
/* Private define to centralize the enable/disable of Interrupts */
6 mjames 386
#define I2C_XFER_TX_IT          (uint16_t)(0x0001U)   /*!< Bit field can be combinated with
387
                                                         @ref I2C_XFER_LISTEN_IT */
388
#define I2C_XFER_RX_IT          (uint16_t)(0x0002U)   /*!< Bit field can be combinated with
389
                                                         @ref I2C_XFER_LISTEN_IT */
390
#define I2C_XFER_LISTEN_IT      (uint16_t)(0x8000U)   /*!< Bit field can be combinated with @ref I2C_XFER_TX_IT
391
                                                         and @ref I2C_XFER_RX_IT */
2 mjames 392
 
6 mjames 393
#define I2C_XFER_ERROR_IT       (uint16_t)(0x0010U)   /*!< Bit definition to manage addition of global Error
394
                                                         and NACK treatment */
395
#define I2C_XFER_CPLT_IT        (uint16_t)(0x0020U)   /*!< Bit definition to manage only STOP evenement */
396
#define I2C_XFER_RELOAD_IT      (uint16_t)(0x0040U)   /*!< Bit definition to manage only Reload of NBYTE */
2 mjames 397
 
398
/* Private define Sequential Transfer Options default/reset value */
399
#define I2C_NO_OPTION_FRAME     (0xFFFF0000U)
400
/**
401
  * @}
402
  */
403
 
404
/* Private macro -------------------------------------------------------------*/
405
/* Private variables ---------------------------------------------------------*/
406
/* Private function prototypes -----------------------------------------------*/
407
 
408
/** @defgroup I2C_Private_Functions I2C Private Functions
409
  * @{
410
  */
411
/* Private functions to handle DMA transfer */
412
static void I2C_DMAMasterTransmitCplt(DMA_HandleTypeDef *hdma);
413
static void I2C_DMAMasterReceiveCplt(DMA_HandleTypeDef *hdma);
414
static void I2C_DMASlaveTransmitCplt(DMA_HandleTypeDef *hdma);
415
static void I2C_DMASlaveReceiveCplt(DMA_HandleTypeDef *hdma);
416
static void I2C_DMAError(DMA_HandleTypeDef *hdma);
417
static void I2C_DMAAbort(DMA_HandleTypeDef *hdma);
418
 
419
/* Private functions to handle IT transfer */
420
static void I2C_ITAddrCplt(I2C_HandleTypeDef *hi2c, uint32_t ITFlags);
421
static void I2C_ITMasterSeqCplt(I2C_HandleTypeDef *hi2c);
422
static void I2C_ITSlaveSeqCplt(I2C_HandleTypeDef *hi2c);
423
static void I2C_ITMasterCplt(I2C_HandleTypeDef *hi2c, uint32_t ITFlags);
424
static void I2C_ITSlaveCplt(I2C_HandleTypeDef *hi2c, uint32_t ITFlags);
425
static void I2C_ITListenCplt(I2C_HandleTypeDef *hi2c, uint32_t ITFlags);
426
static void I2C_ITError(I2C_HandleTypeDef *hi2c, uint32_t ErrorCode);
427
 
428
/* Private functions to handle IT transfer */
6 mjames 429
static HAL_StatusTypeDef I2C_RequestMemoryWrite(I2C_HandleTypeDef *hi2c, uint16_t DevAddress,
430
                                                uint16_t MemAddress, uint16_t MemAddSize, uint32_t Timeout,
431
                                                uint32_t Tickstart);
432
static HAL_StatusTypeDef I2C_RequestMemoryRead(I2C_HandleTypeDef *hi2c, uint16_t DevAddress,
433
                                               uint16_t MemAddress, uint16_t MemAddSize, uint32_t Timeout,
434
                                               uint32_t Tickstart);
2 mjames 435
 
436
/* Private functions for I2C transfer IRQ handler */
6 mjames 437
static HAL_StatusTypeDef I2C_Master_ISR_IT(struct __I2C_HandleTypeDef *hi2c, uint32_t ITFlags,
438
                                           uint32_t ITSources);
439
static HAL_StatusTypeDef I2C_Slave_ISR_IT(struct __I2C_HandleTypeDef *hi2c, uint32_t ITFlags,
440
                                          uint32_t ITSources);
441
static HAL_StatusTypeDef I2C_Master_ISR_DMA(struct __I2C_HandleTypeDef *hi2c, uint32_t ITFlags,
442
                                            uint32_t ITSources);
443
static HAL_StatusTypeDef I2C_Slave_ISR_DMA(struct __I2C_HandleTypeDef *hi2c, uint32_t ITFlags,
444
                                           uint32_t ITSources);
2 mjames 445
 
446
/* Private functions to handle flags during polling transfer */
6 mjames 447
static HAL_StatusTypeDef I2C_WaitOnFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Flag, FlagStatus Status,
448
                                                    uint32_t Timeout, uint32_t Tickstart);
449
static HAL_StatusTypeDef I2C_WaitOnTXISFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Timeout,
450
                                                        uint32_t Tickstart);
451
static HAL_StatusTypeDef I2C_WaitOnRXNEFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Timeout,
452
                                                        uint32_t Tickstart);
453
static HAL_StatusTypeDef I2C_WaitOnSTOPFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Timeout,
454
                                                        uint32_t Tickstart);
455
static HAL_StatusTypeDef I2C_IsAcknowledgeFailed(I2C_HandleTypeDef *hi2c, uint32_t Timeout,
456
                                                 uint32_t Tickstart);
2 mjames 457
 
458
/* Private functions to centralize the enable/disable of Interrupts */
459
static void I2C_Enable_IRQ(I2C_HandleTypeDef *hi2c, uint16_t InterruptRequest);
460
static void I2C_Disable_IRQ(I2C_HandleTypeDef *hi2c, uint16_t InterruptRequest);
461
 
6 mjames 462
/* Private function to treat different error callback */
463
static void I2C_TreatErrorCallback(I2C_HandleTypeDef *hi2c);
464
 
2 mjames 465
/* Private function to flush TXDR register */
466
static void I2C_Flush_TXDR(I2C_HandleTypeDef *hi2c);
467
 
468
/* Private function to handle  start, restart or stop a transfer */
6 mjames 469
static void I2C_TransferConfig(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t Size, uint32_t Mode,
470
                               uint32_t Request);
2 mjames 471
 
472
/* Private function to Convert Specific options */
473
static void I2C_ConvertOtherXferOptions(I2C_HandleTypeDef *hi2c);
474
/**
475
  * @}
476
  */
477
 
478
/* Exported functions --------------------------------------------------------*/
479
 
480
/** @defgroup I2C_Exported_Functions I2C Exported Functions
481
  * @{
482
  */
483
 
484
/** @defgroup I2C_Exported_Functions_Group1 Initialization and de-initialization functions
6 mjames 485
  *  @brief    Initialization and Configuration functions
486
  *
2 mjames 487
@verbatim
488
 ===============================================================================
489
              ##### Initialization and de-initialization functions #####
490
 ===============================================================================
491
    [..]  This subsection provides a set of functions allowing to initialize and
492
          deinitialize the I2Cx peripheral:
493
 
494
      (+) User must Implement HAL_I2C_MspInit() function in which he configures
495
          all related peripherals resources (CLOCK, GPIO, DMA, IT and NVIC ).
496
 
497
      (+) Call the function HAL_I2C_Init() to configure the selected device with
498
          the selected configuration:
499
        (++) Clock Timing
500
        (++) Own Address 1
501
        (++) Addressing mode (Master, Slave)
502
        (++) Dual Addressing mode
503
        (++) Own Address 2
504
        (++) Own Address 2 Mask
505
        (++) General call mode
506
        (++) Nostretch mode
507
 
508
      (+) Call the function HAL_I2C_DeInit() to restore the default configuration
509
          of the selected I2Cx peripheral.
510
 
511
@endverbatim
512
  * @{
513
  */
514
 
515
/**
516
  * @brief  Initializes the I2C according to the specified parameters
517
  *         in the I2C_InitTypeDef and initialize the associated handle.
518
  * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
519
  *                the configuration information for the specified I2C.
520
  * @retval HAL status
521
  */
522
HAL_StatusTypeDef HAL_I2C_Init(I2C_HandleTypeDef *hi2c)
523
{
524
  /* Check the I2C handle allocation */
525
  if (hi2c == NULL)
526
  {
527
    return HAL_ERROR;
528
  }
529
 
530
  /* Check the parameters */
531
  assert_param(IS_I2C_ALL_INSTANCE(hi2c->Instance));
532
  assert_param(IS_I2C_OWN_ADDRESS1(hi2c->Init.OwnAddress1));
533
  assert_param(IS_I2C_ADDRESSING_MODE(hi2c->Init.AddressingMode));
534
  assert_param(IS_I2C_DUAL_ADDRESS(hi2c->Init.DualAddressMode));
535
  assert_param(IS_I2C_OWN_ADDRESS2(hi2c->Init.OwnAddress2));
536
  assert_param(IS_I2C_OWN_ADDRESS2_MASK(hi2c->Init.OwnAddress2Masks));
537
  assert_param(IS_I2C_GENERAL_CALL(hi2c->Init.GeneralCallMode));
538
  assert_param(IS_I2C_NO_STRETCH(hi2c->Init.NoStretchMode));
539
 
540
  if (hi2c->State == HAL_I2C_STATE_RESET)
541
  {
542
    /* Allocate lock resource and initialize it */
543
    hi2c->Lock = HAL_UNLOCKED;
544
 
545
#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1)
546
    /* Init the I2C Callback settings */
547
    hi2c->MasterTxCpltCallback = HAL_I2C_MasterTxCpltCallback; /* Legacy weak MasterTxCpltCallback */
548
    hi2c->MasterRxCpltCallback = HAL_I2C_MasterRxCpltCallback; /* Legacy weak MasterRxCpltCallback */
549
    hi2c->SlaveTxCpltCallback  = HAL_I2C_SlaveTxCpltCallback;  /* Legacy weak SlaveTxCpltCallback  */
550
    hi2c->SlaveRxCpltCallback  = HAL_I2C_SlaveRxCpltCallback;  /* Legacy weak SlaveRxCpltCallback  */
551
    hi2c->ListenCpltCallback   = HAL_I2C_ListenCpltCallback;   /* Legacy weak ListenCpltCallback   */
552
    hi2c->MemTxCpltCallback    = HAL_I2C_MemTxCpltCallback;    /* Legacy weak MemTxCpltCallback    */
553
    hi2c->MemRxCpltCallback    = HAL_I2C_MemRxCpltCallback;    /* Legacy weak MemRxCpltCallback    */
554
    hi2c->ErrorCallback        = HAL_I2C_ErrorCallback;        /* Legacy weak ErrorCallback        */
555
    hi2c->AbortCpltCallback    = HAL_I2C_AbortCpltCallback;    /* Legacy weak AbortCpltCallback    */
556
    hi2c->AddrCallback         = HAL_I2C_AddrCallback;         /* Legacy weak AddrCallback         */
557
 
558
    if (hi2c->MspInitCallback == NULL)
559
    {
560
      hi2c->MspInitCallback = HAL_I2C_MspInit; /* Legacy weak MspInit  */
561
    }
562
 
563
    /* Init the low level hardware : GPIO, CLOCK, CORTEX...etc */
564
    hi2c->MspInitCallback(hi2c);
565
#else
566
    /* Init the low level hardware : GPIO, CLOCK, CORTEX...etc */
567
    HAL_I2C_MspInit(hi2c);
568
#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */
569
  }
570
 
571
  hi2c->State = HAL_I2C_STATE_BUSY;
572
 
573
  /* Disable the selected I2C peripheral */
574
  __HAL_I2C_DISABLE(hi2c);
575
 
576
  /*---------------------------- I2Cx TIMINGR Configuration ------------------*/
577
  /* Configure I2Cx: Frequency range */
578
  hi2c->Instance->TIMINGR = hi2c->Init.Timing & TIMING_CLEAR_MASK;
579
 
580
  /*---------------------------- I2Cx OAR1 Configuration ---------------------*/
581
  /* Disable Own Address1 before set the Own Address1 configuration */
582
  hi2c->Instance->OAR1 &= ~I2C_OAR1_OA1EN;
583
 
584
  /* Configure I2Cx: Own Address1 and ack own address1 mode */
585
  if (hi2c->Init.AddressingMode == I2C_ADDRESSINGMODE_7BIT)
586
  {
587
    hi2c->Instance->OAR1 = (I2C_OAR1_OA1EN | hi2c->Init.OwnAddress1);
588
  }
589
  else /* I2C_ADDRESSINGMODE_10BIT */
590
  {
591
    hi2c->Instance->OAR1 = (I2C_OAR1_OA1EN | I2C_OAR1_OA1MODE | hi2c->Init.OwnAddress1);
592
  }
593
 
594
  /*---------------------------- I2Cx CR2 Configuration ----------------------*/
595
  /* Configure I2Cx: Addressing Master mode */
596
  if (hi2c->Init.AddressingMode == I2C_ADDRESSINGMODE_10BIT)
597
  {
598
    hi2c->Instance->CR2 = (I2C_CR2_ADD10);
599
  }
600
  /* Enable the AUTOEND by default, and enable NACK (should be disable only during Slave process */
601
  hi2c->Instance->CR2 |= (I2C_CR2_AUTOEND | I2C_CR2_NACK);
602
 
603
  /*---------------------------- I2Cx OAR2 Configuration ---------------------*/
604
  /* Disable Own Address2 before set the Own Address2 configuration */
605
  hi2c->Instance->OAR2 &= ~I2C_DUALADDRESS_ENABLE;
606
 
607
  /* Configure I2Cx: Dual mode and Own Address2 */
6 mjames 608
  hi2c->Instance->OAR2 = (hi2c->Init.DualAddressMode | hi2c->Init.OwnAddress2 | \
609
                          (hi2c->Init.OwnAddress2Masks << 8));
2 mjames 610
 
611
  /*---------------------------- I2Cx CR1 Configuration ----------------------*/
612
  /* Configure I2Cx: Generalcall and NoStretch mode */
613
  hi2c->Instance->CR1 = (hi2c->Init.GeneralCallMode | hi2c->Init.NoStretchMode);
614
 
615
  /* Enable the selected I2C peripheral */
616
  __HAL_I2C_ENABLE(hi2c);
617
 
618
  hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
619
  hi2c->State = HAL_I2C_STATE_READY;
620
  hi2c->PreviousState = I2C_STATE_NONE;
621
  hi2c->Mode = HAL_I2C_MODE_NONE;
622
 
623
  return HAL_OK;
624
}
625
 
626
/**
627
  * @brief  DeInitialize the I2C peripheral.
628
  * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
629
  *                the configuration information for the specified I2C.
630
  * @retval HAL status
631
  */
632
HAL_StatusTypeDef HAL_I2C_DeInit(I2C_HandleTypeDef *hi2c)
633
{
634
  /* Check the I2C handle allocation */
635
  if (hi2c == NULL)
636
  {
637
    return HAL_ERROR;
638
  }
639
 
640
  /* Check the parameters */
641
  assert_param(IS_I2C_ALL_INSTANCE(hi2c->Instance));
642
 
643
  hi2c->State = HAL_I2C_STATE_BUSY;
644
 
645
  /* Disable the I2C Peripheral Clock */
646
  __HAL_I2C_DISABLE(hi2c);
647
 
648
#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1)
649
  if (hi2c->MspDeInitCallback == NULL)
650
  {
651
    hi2c->MspDeInitCallback = HAL_I2C_MspDeInit; /* Legacy weak MspDeInit  */
652
  }
653
 
654
  /* DeInit the low level hardware: GPIO, CLOCK, NVIC */
655
  hi2c->MspDeInitCallback(hi2c);
656
#else
657
  /* DeInit the low level hardware: GPIO, CLOCK, NVIC */
658
  HAL_I2C_MspDeInit(hi2c);
659
#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */
660
 
661
  hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
662
  hi2c->State = HAL_I2C_STATE_RESET;
663
  hi2c->PreviousState = I2C_STATE_NONE;
664
  hi2c->Mode = HAL_I2C_MODE_NONE;
665
 
666
  /* Release Lock */
667
  __HAL_UNLOCK(hi2c);
668
 
669
  return HAL_OK;
670
}
671
 
672
/**
673
  * @brief Initialize the I2C MSP.
674
  * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
675
  *                the configuration information for the specified I2C.
676
  * @retval None
677
  */
678
__weak void HAL_I2C_MspInit(I2C_HandleTypeDef *hi2c)
679
{
680
  /* Prevent unused argument(s) compilation warning */
681
  UNUSED(hi2c);
682
 
683
  /* NOTE : This function should not be modified, when the callback is needed,
684
            the HAL_I2C_MspInit could be implemented in the user file
685
   */
686
}
687
 
688
/**
689
  * @brief DeInitialize the I2C MSP.
690
  * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
691
  *                the configuration information for the specified I2C.
692
  * @retval None
693
  */
694
__weak void HAL_I2C_MspDeInit(I2C_HandleTypeDef *hi2c)
695
{
696
  /* Prevent unused argument(s) compilation warning */
697
  UNUSED(hi2c);
698
 
699
  /* NOTE : This function should not be modified, when the callback is needed,
700
            the HAL_I2C_MspDeInit could be implemented in the user file
701
   */
702
}
703
 
704
#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1)
705
/**
706
  * @brief  Register a User I2C Callback
707
  *         To be used instead of the weak predefined callback
708
  * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
709
  *                the configuration information for the specified I2C.
710
  * @param  CallbackID ID of the callback to be registered
711
  *         This parameter can be one of the following values:
712
  *          @arg @ref HAL_I2C_MASTER_TX_COMPLETE_CB_ID Master Tx Transfer completed callback ID
713
  *          @arg @ref HAL_I2C_MASTER_RX_COMPLETE_CB_ID Master Rx Transfer completed callback ID
714
  *          @arg @ref HAL_I2C_SLAVE_TX_COMPLETE_CB_ID Slave Tx Transfer completed callback ID
715
  *          @arg @ref HAL_I2C_SLAVE_RX_COMPLETE_CB_ID Slave Rx Transfer completed callback ID
716
  *          @arg @ref HAL_I2C_LISTEN_COMPLETE_CB_ID Listen Complete callback ID
717
  *          @arg @ref HAL_I2C_MEM_TX_COMPLETE_CB_ID Memory Tx Transfer callback ID
718
  *          @arg @ref HAL_I2C_MEM_RX_COMPLETE_CB_ID Memory Rx Transfer completed callback ID
719
  *          @arg @ref HAL_I2C_ERROR_CB_ID Error callback ID
720
  *          @arg @ref HAL_I2C_ABORT_CB_ID Abort callback ID
721
  *          @arg @ref HAL_I2C_MSPINIT_CB_ID MspInit callback ID
722
  *          @arg @ref HAL_I2C_MSPDEINIT_CB_ID MspDeInit callback ID
723
  * @param  pCallback pointer to the Callback function
724
  * @retval HAL status
725
  */
6 mjames 726
HAL_StatusTypeDef HAL_I2C_RegisterCallback(I2C_HandleTypeDef *hi2c, HAL_I2C_CallbackIDTypeDef CallbackID,
727
                                           pI2C_CallbackTypeDef pCallback)
2 mjames 728
{
729
  HAL_StatusTypeDef status = HAL_OK;
730
 
731
  if (pCallback == NULL)
732
  {
733
    /* Update the error code */
734
    hi2c->ErrorCode |= HAL_I2C_ERROR_INVALID_CALLBACK;
735
 
736
    return HAL_ERROR;
737
  }
738
  /* Process locked */
739
  __HAL_LOCK(hi2c);
740
 
741
  if (HAL_I2C_STATE_READY == hi2c->State)
742
  {
743
    switch (CallbackID)
744
    {
745
      case HAL_I2C_MASTER_TX_COMPLETE_CB_ID :
746
        hi2c->MasterTxCpltCallback = pCallback;
747
        break;
748
 
749
      case HAL_I2C_MASTER_RX_COMPLETE_CB_ID :
750
        hi2c->MasterRxCpltCallback = pCallback;
751
        break;
752
 
753
      case HAL_I2C_SLAVE_TX_COMPLETE_CB_ID :
754
        hi2c->SlaveTxCpltCallback = pCallback;
755
        break;
756
 
757
      case HAL_I2C_SLAVE_RX_COMPLETE_CB_ID :
758
        hi2c->SlaveRxCpltCallback = pCallback;
759
        break;
760
 
761
      case HAL_I2C_LISTEN_COMPLETE_CB_ID :
762
        hi2c->ListenCpltCallback = pCallback;
763
        break;
764
 
765
      case HAL_I2C_MEM_TX_COMPLETE_CB_ID :
766
        hi2c->MemTxCpltCallback = pCallback;
767
        break;
768
 
769
      case HAL_I2C_MEM_RX_COMPLETE_CB_ID :
770
        hi2c->MemRxCpltCallback = pCallback;
771
        break;
772
 
773
      case HAL_I2C_ERROR_CB_ID :
774
        hi2c->ErrorCallback = pCallback;
775
        break;
776
 
777
      case HAL_I2C_ABORT_CB_ID :
778
        hi2c->AbortCpltCallback = pCallback;
779
        break;
780
 
781
      case HAL_I2C_MSPINIT_CB_ID :
782
        hi2c->MspInitCallback = pCallback;
783
        break;
784
 
785
      case HAL_I2C_MSPDEINIT_CB_ID :
786
        hi2c->MspDeInitCallback = pCallback;
787
        break;
788
 
789
      default :
790
        /* Update the error code */
791
        hi2c->ErrorCode |= HAL_I2C_ERROR_INVALID_CALLBACK;
792
 
793
        /* Return error status */
794
        status =  HAL_ERROR;
795
        break;
796
    }
797
  }
798
  else if (HAL_I2C_STATE_RESET == hi2c->State)
799
  {
800
    switch (CallbackID)
801
    {
802
      case HAL_I2C_MSPINIT_CB_ID :
803
        hi2c->MspInitCallback = pCallback;
804
        break;
805
 
806
      case HAL_I2C_MSPDEINIT_CB_ID :
807
        hi2c->MspDeInitCallback = pCallback;
808
        break;
809
 
810
      default :
811
        /* Update the error code */
812
        hi2c->ErrorCode |= HAL_I2C_ERROR_INVALID_CALLBACK;
813
 
814
        /* Return error status */
815
        status =  HAL_ERROR;
816
        break;
817
    }
818
  }
819
  else
820
  {
821
    /* Update the error code */
822
    hi2c->ErrorCode |= HAL_I2C_ERROR_INVALID_CALLBACK;
823
 
824
    /* Return error status */
825
    status =  HAL_ERROR;
826
  }
827
 
828
  /* Release Lock */
829
  __HAL_UNLOCK(hi2c);
830
  return status;
831
}
832
 
833
/**
834
  * @brief  Unregister an I2C Callback
835
  *         I2C callback is redirected to the weak predefined callback
836
  * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
837
  *                the configuration information for the specified I2C.
838
  * @param  CallbackID ID of the callback to be unregistered
839
  *         This parameter can be one of the following values:
840
  *         This parameter can be one of the following values:
841
  *          @arg @ref HAL_I2C_MASTER_TX_COMPLETE_CB_ID Master Tx Transfer completed callback ID
842
  *          @arg @ref HAL_I2C_MASTER_RX_COMPLETE_CB_ID Master Rx Transfer completed callback ID
843
  *          @arg @ref HAL_I2C_SLAVE_TX_COMPLETE_CB_ID Slave Tx Transfer completed callback ID
844
  *          @arg @ref HAL_I2C_SLAVE_RX_COMPLETE_CB_ID Slave Rx Transfer completed callback ID
845
  *          @arg @ref HAL_I2C_LISTEN_COMPLETE_CB_ID Listen Complete callback ID
846
  *          @arg @ref HAL_I2C_MEM_TX_COMPLETE_CB_ID Memory Tx Transfer callback ID
847
  *          @arg @ref HAL_I2C_MEM_RX_COMPLETE_CB_ID Memory Rx Transfer completed callback ID
848
  *          @arg @ref HAL_I2C_ERROR_CB_ID Error callback ID
849
  *          @arg @ref HAL_I2C_ABORT_CB_ID Abort callback ID
850
  *          @arg @ref HAL_I2C_MSPINIT_CB_ID MspInit callback ID
851
  *          @arg @ref HAL_I2C_MSPDEINIT_CB_ID MspDeInit callback ID
852
  * @retval HAL status
853
  */
854
HAL_StatusTypeDef HAL_I2C_UnRegisterCallback(I2C_HandleTypeDef *hi2c, HAL_I2C_CallbackIDTypeDef CallbackID)
855
{
856
  HAL_StatusTypeDef status = HAL_OK;
857
 
858
  /* Process locked */
859
  __HAL_LOCK(hi2c);
860
 
861
  if (HAL_I2C_STATE_READY == hi2c->State)
862
  {
863
    switch (CallbackID)
864
    {
865
      case HAL_I2C_MASTER_TX_COMPLETE_CB_ID :
866
        hi2c->MasterTxCpltCallback = HAL_I2C_MasterTxCpltCallback; /* Legacy weak MasterTxCpltCallback */
867
        break;
868
 
869
      case HAL_I2C_MASTER_RX_COMPLETE_CB_ID :
870
        hi2c->MasterRxCpltCallback = HAL_I2C_MasterRxCpltCallback; /* Legacy weak MasterRxCpltCallback */
871
        break;
872
 
873
      case HAL_I2C_SLAVE_TX_COMPLETE_CB_ID :
874
        hi2c->SlaveTxCpltCallback = HAL_I2C_SlaveTxCpltCallback;   /* Legacy weak SlaveTxCpltCallback  */
875
        break;
876
 
877
      case HAL_I2C_SLAVE_RX_COMPLETE_CB_ID :
878
        hi2c->SlaveRxCpltCallback = HAL_I2C_SlaveRxCpltCallback;   /* Legacy weak SlaveRxCpltCallback  */
879
        break;
880
 
881
      case HAL_I2C_LISTEN_COMPLETE_CB_ID :
882
        hi2c->ListenCpltCallback = HAL_I2C_ListenCpltCallback;     /* Legacy weak ListenCpltCallback   */
883
        break;
884
 
885
      case HAL_I2C_MEM_TX_COMPLETE_CB_ID :
886
        hi2c->MemTxCpltCallback = HAL_I2C_MemTxCpltCallback;       /* Legacy weak MemTxCpltCallback    */
887
        break;
888
 
889
      case HAL_I2C_MEM_RX_COMPLETE_CB_ID :
890
        hi2c->MemRxCpltCallback = HAL_I2C_MemRxCpltCallback;       /* Legacy weak MemRxCpltCallback    */
891
        break;
892
 
893
      case HAL_I2C_ERROR_CB_ID :
894
        hi2c->ErrorCallback = HAL_I2C_ErrorCallback;               /* Legacy weak ErrorCallback        */
895
        break;
896
 
897
      case HAL_I2C_ABORT_CB_ID :
898
        hi2c->AbortCpltCallback = HAL_I2C_AbortCpltCallback;       /* Legacy weak AbortCpltCallback    */
899
        break;
900
 
901
      case HAL_I2C_MSPINIT_CB_ID :
902
        hi2c->MspInitCallback = HAL_I2C_MspInit;                   /* Legacy weak MspInit              */
903
        break;
904
 
905
      case HAL_I2C_MSPDEINIT_CB_ID :
906
        hi2c->MspDeInitCallback = HAL_I2C_MspDeInit;               /* Legacy weak MspDeInit            */
907
        break;
908
 
909
      default :
910
        /* Update the error code */
911
        hi2c->ErrorCode |= HAL_I2C_ERROR_INVALID_CALLBACK;
912
 
913
        /* Return error status */
914
        status =  HAL_ERROR;
915
        break;
916
    }
917
  }
918
  else if (HAL_I2C_STATE_RESET == hi2c->State)
919
  {
920
    switch (CallbackID)
921
    {
922
      case HAL_I2C_MSPINIT_CB_ID :
923
        hi2c->MspInitCallback = HAL_I2C_MspInit;                   /* Legacy weak MspInit              */
924
        break;
925
 
926
      case HAL_I2C_MSPDEINIT_CB_ID :
927
        hi2c->MspDeInitCallback = HAL_I2C_MspDeInit;               /* Legacy weak MspDeInit            */
928
        break;
929
 
930
      default :
931
        /* Update the error code */
932
        hi2c->ErrorCode |= HAL_I2C_ERROR_INVALID_CALLBACK;
933
 
934
        /* Return error status */
935
        status =  HAL_ERROR;
936
        break;
937
    }
938
  }
939
  else
940
  {
941
    /* Update the error code */
942
    hi2c->ErrorCode |= HAL_I2C_ERROR_INVALID_CALLBACK;
943
 
944
    /* Return error status */
945
    status =  HAL_ERROR;
946
  }
947
 
948
  /* Release Lock */
949
  __HAL_UNLOCK(hi2c);
950
  return status;
951
}
952
 
953
/**
954
  * @brief  Register the Slave Address Match I2C Callback
955
  *         To be used instead of the weak HAL_I2C_AddrCallback() predefined callback
956
  * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
957
  *                the configuration information for the specified I2C.
958
  * @param  pCallback pointer to the Address Match Callback function
959
  * @retval HAL status
960
  */
961
HAL_StatusTypeDef HAL_I2C_RegisterAddrCallback(I2C_HandleTypeDef *hi2c, pI2C_AddrCallbackTypeDef pCallback)
962
{
963
  HAL_StatusTypeDef status = HAL_OK;
964
 
965
  if (pCallback == NULL)
966
  {
967
    /* Update the error code */
968
    hi2c->ErrorCode |= HAL_I2C_ERROR_INVALID_CALLBACK;
969
 
970
    return HAL_ERROR;
971
  }
972
  /* Process locked */
973
  __HAL_LOCK(hi2c);
974
 
975
  if (HAL_I2C_STATE_READY == hi2c->State)
976
  {
977
    hi2c->AddrCallback = pCallback;
978
  }
979
  else
980
  {
981
    /* Update the error code */
982
    hi2c->ErrorCode |= HAL_I2C_ERROR_INVALID_CALLBACK;
983
 
984
    /* Return error status */
985
    status =  HAL_ERROR;
986
  }
987
 
988
  /* Release Lock */
989
  __HAL_UNLOCK(hi2c);
990
  return status;
991
}
992
 
993
/**
994
  * @brief  UnRegister the Slave Address Match I2C Callback
995
  *         Info Ready I2C Callback is redirected to the weak HAL_I2C_AddrCallback() predefined callback
996
  * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
997
  *                the configuration information for the specified I2C.
998
  * @retval HAL status
999
  */
1000
HAL_StatusTypeDef HAL_I2C_UnRegisterAddrCallback(I2C_HandleTypeDef *hi2c)
1001
{
1002
  HAL_StatusTypeDef status = HAL_OK;
1003
 
1004
  /* Process locked */
1005
  __HAL_LOCK(hi2c);
1006
 
1007
  if (HAL_I2C_STATE_READY == hi2c->State)
1008
  {
1009
    hi2c->AddrCallback = HAL_I2C_AddrCallback; /* Legacy weak AddrCallback  */
1010
  }
1011
  else
1012
  {
1013
    /* Update the error code */
1014
    hi2c->ErrorCode |= HAL_I2C_ERROR_INVALID_CALLBACK;
1015
 
1016
    /* Return error status */
1017
    status =  HAL_ERROR;
1018
  }
1019
 
1020
  /* Release Lock */
1021
  __HAL_UNLOCK(hi2c);
1022
  return status;
1023
}
1024
 
1025
#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */
1026
 
1027
/**
1028
  * @}
1029
  */
1030
 
1031
/** @defgroup I2C_Exported_Functions_Group2 Input and Output operation functions
6 mjames 1032
  *  @brief   Data transfers functions
1033
  *
2 mjames 1034
@verbatim
1035
 ===============================================================================
1036
                      ##### IO operation functions #####
1037
 ===============================================================================
1038
    [..]
1039
    This subsection provides a set of functions allowing to manage the I2C data
1040
    transfers.
1041
 
1042
    (#) There are two modes of transfer:
1043
       (++) Blocking mode : The communication is performed in the polling mode.
1044
            The status of all data processing is returned by the same function
1045
            after finishing transfer.
1046
       (++) No-Blocking mode : The communication is performed using Interrupts
1047
            or DMA. These functions return the status of the transfer startup.
1048
            The end of the data processing will be indicated through the
1049
            dedicated I2C IRQ when using Interrupt mode or the DMA IRQ when
1050
            using DMA mode.
1051
 
1052
    (#) Blocking mode functions are :
1053
        (++) HAL_I2C_Master_Transmit()
1054
        (++) HAL_I2C_Master_Receive()
1055
        (++) HAL_I2C_Slave_Transmit()
1056
        (++) HAL_I2C_Slave_Receive()
1057
        (++) HAL_I2C_Mem_Write()
1058
        (++) HAL_I2C_Mem_Read()
1059
        (++) HAL_I2C_IsDeviceReady()
1060
 
1061
    (#) No-Blocking mode functions with Interrupt are :
1062
        (++) HAL_I2C_Master_Transmit_IT()
1063
        (++) HAL_I2C_Master_Receive_IT()
1064
        (++) HAL_I2C_Slave_Transmit_IT()
1065
        (++) HAL_I2C_Slave_Receive_IT()
1066
        (++) HAL_I2C_Mem_Write_IT()
1067
        (++) HAL_I2C_Mem_Read_IT()
1068
        (++) HAL_I2C_Master_Seq_Transmit_IT()
1069
        (++) HAL_I2C_Master_Seq_Receive_IT()
1070
        (++) HAL_I2C_Slave_Seq_Transmit_IT()
1071
        (++) HAL_I2C_Slave_Seq_Receive_IT()
1072
        (++) HAL_I2C_EnableListen_IT()
1073
        (++) HAL_I2C_DisableListen_IT()
1074
        (++) HAL_I2C_Master_Abort_IT()
1075
 
1076
    (#) No-Blocking mode functions with DMA are :
1077
        (++) HAL_I2C_Master_Transmit_DMA()
1078
        (++) HAL_I2C_Master_Receive_DMA()
1079
        (++) HAL_I2C_Slave_Transmit_DMA()
1080
        (++) HAL_I2C_Slave_Receive_DMA()
1081
        (++) HAL_I2C_Mem_Write_DMA()
1082
        (++) HAL_I2C_Mem_Read_DMA()
1083
        (++) HAL_I2C_Master_Seq_Transmit_DMA()
1084
        (++) HAL_I2C_Master_Seq_Receive_DMA()
1085
        (++) HAL_I2C_Slave_Seq_Transmit_DMA()
1086
        (++) HAL_I2C_Slave_Seq_Receive_DMA()
1087
 
1088
    (#) A set of Transfer Complete Callbacks are provided in non Blocking mode:
1089
        (++) HAL_I2C_MasterTxCpltCallback()
1090
        (++) HAL_I2C_MasterRxCpltCallback()
1091
        (++) HAL_I2C_SlaveTxCpltCallback()
1092
        (++) HAL_I2C_SlaveRxCpltCallback()
1093
        (++) HAL_I2C_MemTxCpltCallback()
1094
        (++) HAL_I2C_MemRxCpltCallback()
1095
        (++) HAL_I2C_AddrCallback()
1096
        (++) HAL_I2C_ListenCpltCallback()
1097
        (++) HAL_I2C_ErrorCallback()
1098
        (++) HAL_I2C_AbortCpltCallback()
1099
 
1100
@endverbatim
1101
  * @{
1102
  */
1103
 
1104
/**
1105
  * @brief  Transmits in master mode an amount of data in blocking mode.
1106
  * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
1107
  *                the configuration information for the specified I2C.
1108
  * @param  DevAddress Target device address: The device 7 bits address value
1109
  *         in datasheet must be shifted to the left before calling the interface
1110
  * @param  pData Pointer to data buffer
1111
  * @param  Size Amount of data to be sent
1112
  * @param  Timeout Timeout duration
1113
  * @retval HAL status
1114
  */
6 mjames 1115
HAL_StatusTypeDef HAL_I2C_Master_Transmit(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData,
1116
                                          uint16_t Size, uint32_t Timeout)
2 mjames 1117
{
1118
  uint32_t tickstart;
1119
 
1120
  if (hi2c->State == HAL_I2C_STATE_READY)
1121
  {
1122
    /* Process Locked */
1123
    __HAL_LOCK(hi2c);
1124
 
1125
    /* Init tickstart for timeout management*/
1126
    tickstart = HAL_GetTick();
1127
 
1128
    if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY, tickstart) != HAL_OK)
1129
    {
1130
      return HAL_ERROR;
1131
    }
1132
 
1133
    hi2c->State     = HAL_I2C_STATE_BUSY_TX;
1134
    hi2c->Mode      = HAL_I2C_MODE_MASTER;
1135
    hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
1136
 
1137
    /* Prepare transfer parameters */
1138
    hi2c->pBuffPtr  = pData;
1139
    hi2c->XferCount = Size;
1140
    hi2c->XferISR   = NULL;
1141
 
1142
    /* Send Slave Address */
1143
    /* Set NBYTES to write and reload if hi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */
1144
    if (hi2c->XferCount > MAX_NBYTE_SIZE)
1145
    {
1146
      hi2c->XferSize = MAX_NBYTE_SIZE;
6 mjames 1147
      I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, I2C_RELOAD_MODE,
1148
                         I2C_GENERATE_START_WRITE);
2 mjames 1149
    }
1150
    else
1151
    {
1152
      hi2c->XferSize = hi2c->XferCount;
6 mjames 1153
      I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, I2C_AUTOEND_MODE,
1154
                         I2C_GENERATE_START_WRITE);
2 mjames 1155
    }
1156
 
1157
    while (hi2c->XferCount > 0U)
1158
    {
1159
      /* Wait until TXIS flag is set */
1160
      if (I2C_WaitOnTXISFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK)
1161
      {
1162
        return HAL_ERROR;
1163
      }
1164
      /* Write data to TXDR */
1165
      hi2c->Instance->TXDR = *hi2c->pBuffPtr;
1166
 
1167
      /* Increment Buffer pointer */
1168
      hi2c->pBuffPtr++;
1169
 
1170
      hi2c->XferCount--;
1171
      hi2c->XferSize--;
1172
 
1173
      if ((hi2c->XferCount != 0U) && (hi2c->XferSize == 0U))
1174
      {
1175
        /* Wait until TCR flag is set */
1176
        if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_TCR, RESET, Timeout, tickstart) != HAL_OK)
1177
        {
1178
          return HAL_ERROR;
1179
        }
1180
 
1181
        if (hi2c->XferCount > MAX_NBYTE_SIZE)
1182
        {
1183
          hi2c->XferSize = MAX_NBYTE_SIZE;
6 mjames 1184
          I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, I2C_RELOAD_MODE,
1185
                             I2C_NO_STARTSTOP);
2 mjames 1186
        }
1187
        else
1188
        {
1189
          hi2c->XferSize = hi2c->XferCount;
6 mjames 1190
          I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, I2C_AUTOEND_MODE,
1191
                             I2C_NO_STARTSTOP);
2 mjames 1192
        }
1193
      }
1194
    }
1195
 
1196
    /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */
1197
    /* Wait until STOPF flag is set */
1198
    if (I2C_WaitOnSTOPFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK)
1199
    {
1200
      return HAL_ERROR;
1201
    }
1202
 
1203
    /* Clear STOP Flag */
1204
    __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF);
1205
 
1206
    /* Clear Configuration Register 2 */
1207
    I2C_RESET_CR2(hi2c);
1208
 
1209
    hi2c->State = HAL_I2C_STATE_READY;
1210
    hi2c->Mode  = HAL_I2C_MODE_NONE;
1211
 
1212
    /* Process Unlocked */
1213
    __HAL_UNLOCK(hi2c);
1214
 
1215
    return HAL_OK;
1216
  }
1217
  else
1218
  {
1219
    return HAL_BUSY;
1220
  }
1221
}
1222
 
1223
/**
1224
  * @brief  Receives in master mode an amount of data in blocking mode.
1225
  * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
1226
  *                the configuration information for the specified I2C.
1227
  * @param  DevAddress Target device address: The device 7 bits address value
1228
  *         in datasheet must be shifted to the left before calling the interface
1229
  * @param  pData Pointer to data buffer
1230
  * @param  Size Amount of data to be sent
1231
  * @param  Timeout Timeout duration
1232
  * @retval HAL status
1233
  */
6 mjames 1234
HAL_StatusTypeDef HAL_I2C_Master_Receive(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData,
1235
                                         uint16_t Size, uint32_t Timeout)
2 mjames 1236
{
1237
  uint32_t tickstart;
1238
 
1239
  if (hi2c->State == HAL_I2C_STATE_READY)
1240
  {
1241
    /* Process Locked */
1242
    __HAL_LOCK(hi2c);
1243
 
1244
    /* Init tickstart for timeout management*/
1245
    tickstart = HAL_GetTick();
1246
 
1247
    if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY, tickstart) != HAL_OK)
1248
    {
1249
      return HAL_ERROR;
1250
    }
1251
 
1252
    hi2c->State     = HAL_I2C_STATE_BUSY_RX;
1253
    hi2c->Mode      = HAL_I2C_MODE_MASTER;
1254
    hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
1255
 
1256
    /* Prepare transfer parameters */
1257
    hi2c->pBuffPtr  = pData;
1258
    hi2c->XferCount = Size;
1259
    hi2c->XferISR   = NULL;
1260
 
1261
    /* Send Slave Address */
1262
    /* Set NBYTES to write and reload if hi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */
1263
    if (hi2c->XferCount > MAX_NBYTE_SIZE)
1264
    {
1265
      hi2c->XferSize = MAX_NBYTE_SIZE;
6 mjames 1266
      I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, I2C_RELOAD_MODE,
1267
                         I2C_GENERATE_START_READ);
2 mjames 1268
    }
1269
    else
1270
    {
1271
      hi2c->XferSize = hi2c->XferCount;
6 mjames 1272
      I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, I2C_AUTOEND_MODE,
1273
                         I2C_GENERATE_START_READ);
2 mjames 1274
    }
1275
 
1276
    while (hi2c->XferCount > 0U)
1277
    {
1278
      /* Wait until RXNE flag is set */
1279
      if (I2C_WaitOnRXNEFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK)
1280
      {
1281
        return HAL_ERROR;
1282
      }
1283
 
1284
      /* Read data from RXDR */
1285
      *hi2c->pBuffPtr = (uint8_t)hi2c->Instance->RXDR;
1286
 
1287
      /* Increment Buffer pointer */
1288
      hi2c->pBuffPtr++;
1289
 
1290
      hi2c->XferSize--;
1291
      hi2c->XferCount--;
1292
 
1293
      if ((hi2c->XferCount != 0U) && (hi2c->XferSize == 0U))
1294
      {
1295
        /* Wait until TCR flag is set */
1296
        if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_TCR, RESET, Timeout, tickstart) != HAL_OK)
1297
        {
1298
          return HAL_ERROR;
1299
        }
1300
 
1301
        if (hi2c->XferCount > MAX_NBYTE_SIZE)
1302
        {
1303
          hi2c->XferSize = MAX_NBYTE_SIZE;
6 mjames 1304
          I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, I2C_RELOAD_MODE,
1305
                             I2C_NO_STARTSTOP);
2 mjames 1306
        }
1307
        else
1308
        {
1309
          hi2c->XferSize = hi2c->XferCount;
6 mjames 1310
          I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, I2C_AUTOEND_MODE,
1311
                             I2C_NO_STARTSTOP);
2 mjames 1312
        }
1313
      }
1314
    }
1315
 
1316
    /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */
1317
    /* Wait until STOPF flag is set */
1318
    if (I2C_WaitOnSTOPFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK)
1319
    {
1320
      return HAL_ERROR;
1321
    }
1322
 
1323
    /* Clear STOP Flag */
1324
    __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF);
1325
 
1326
    /* Clear Configuration Register 2 */
1327
    I2C_RESET_CR2(hi2c);
1328
 
1329
    hi2c->State = HAL_I2C_STATE_READY;
1330
    hi2c->Mode  = HAL_I2C_MODE_NONE;
1331
 
1332
    /* Process Unlocked */
1333
    __HAL_UNLOCK(hi2c);
1334
 
1335
    return HAL_OK;
1336
  }
1337
  else
1338
  {
1339
    return HAL_BUSY;
1340
  }
1341
}
1342
 
1343
/**
1344
  * @brief  Transmits in slave mode an amount of data in blocking mode.
1345
  * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
1346
  *                the configuration information for the specified I2C.
1347
  * @param  pData Pointer to data buffer
1348
  * @param  Size Amount of data to be sent
1349
  * @param  Timeout Timeout duration
1350
  * @retval HAL status
1351
  */
6 mjames 1352
HAL_StatusTypeDef HAL_I2C_Slave_Transmit(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size,
1353
                                         uint32_t Timeout)
2 mjames 1354
{
1355
  uint32_t tickstart;
1356
 
1357
  if (hi2c->State == HAL_I2C_STATE_READY)
1358
  {
1359
    if ((pData == NULL) || (Size == 0U))
1360
    {
1361
      hi2c->ErrorCode = HAL_I2C_ERROR_INVALID_PARAM;
1362
      return  HAL_ERROR;
1363
    }
1364
    /* Process Locked */
1365
    __HAL_LOCK(hi2c);
1366
 
1367
    /* Init tickstart for timeout management*/
1368
    tickstart = HAL_GetTick();
1369
 
1370
    hi2c->State     = HAL_I2C_STATE_BUSY_TX;
1371
    hi2c->Mode      = HAL_I2C_MODE_SLAVE;
1372
    hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
1373
 
1374
    /* Prepare transfer parameters */
1375
    hi2c->pBuffPtr  = pData;
1376
    hi2c->XferCount = Size;
1377
    hi2c->XferISR   = NULL;
1378
 
1379
    /* Enable Address Acknowledge */
1380
    hi2c->Instance->CR2 &= ~I2C_CR2_NACK;
1381
 
1382
    /* Wait until ADDR flag is set */
1383
    if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_ADDR, RESET, Timeout, tickstart) != HAL_OK)
1384
    {
1385
      /* Disable Address Acknowledge */
1386
      hi2c->Instance->CR2 |= I2C_CR2_NACK;
1387
      return HAL_ERROR;
1388
    }
1389
 
1390
    /* Clear ADDR flag */
1391
    __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_ADDR);
1392
 
1393
    /* If 10bit addressing mode is selected */
1394
    if (hi2c->Init.AddressingMode == I2C_ADDRESSINGMODE_10BIT)
1395
    {
1396
      /* Wait until ADDR flag is set */
1397
      if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_ADDR, RESET, Timeout, tickstart) != HAL_OK)
1398
      {
1399
        /* Disable Address Acknowledge */
1400
        hi2c->Instance->CR2 |= I2C_CR2_NACK;
1401
        return HAL_ERROR;
1402
      }
1403
 
1404
      /* Clear ADDR flag */
1405
      __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_ADDR);
1406
    }
1407
 
1408
    /* Wait until DIR flag is set Transmitter mode */
1409
    if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_DIR, RESET, Timeout, tickstart) != HAL_OK)
1410
    {
1411
      /* Disable Address Acknowledge */
1412
      hi2c->Instance->CR2 |= I2C_CR2_NACK;
1413
      return HAL_ERROR;
1414
    }
1415
 
1416
    while (hi2c->XferCount > 0U)
1417
    {
1418
      /* Wait until TXIS flag is set */
1419
      if (I2C_WaitOnTXISFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK)
1420
      {
1421
        /* Disable Address Acknowledge */
1422
        hi2c->Instance->CR2 |= I2C_CR2_NACK;
1423
        return HAL_ERROR;
1424
      }
1425
 
1426
      /* Write data to TXDR */
1427
      hi2c->Instance->TXDR = *hi2c->pBuffPtr;
1428
 
1429
      /* Increment Buffer pointer */
1430
      hi2c->pBuffPtr++;
1431
 
1432
      hi2c->XferCount--;
1433
    }
1434
 
1435
    /* Wait until STOP flag is set */
1436
    if (I2C_WaitOnSTOPFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK)
1437
    {
1438
      /* Disable Address Acknowledge */
1439
      hi2c->Instance->CR2 |= I2C_CR2_NACK;
1440
 
1441
      if (hi2c->ErrorCode == HAL_I2C_ERROR_AF)
1442
      {
1443
        /* Normal use case for Transmitter mode */
1444
        /* A NACK is generated to confirm the end of transfer */
1445
        hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
1446
      }
1447
      else
1448
      {
1449
        return HAL_ERROR;
1450
      }
1451
    }
1452
 
1453
    /* Clear STOP flag */
1454
    __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF);
1455
 
1456
    /* Wait until BUSY flag is reset */
1457
    if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, Timeout, tickstart) != HAL_OK)
1458
    {
1459
      /* Disable Address Acknowledge */
1460
      hi2c->Instance->CR2 |= I2C_CR2_NACK;
1461
      return HAL_ERROR;
1462
    }
1463
 
1464
    /* Disable Address Acknowledge */
1465
    hi2c->Instance->CR2 |= I2C_CR2_NACK;
1466
 
1467
    hi2c->State = HAL_I2C_STATE_READY;
1468
    hi2c->Mode  = HAL_I2C_MODE_NONE;
1469
 
1470
    /* Process Unlocked */
1471
    __HAL_UNLOCK(hi2c);
1472
 
1473
    return HAL_OK;
1474
  }
1475
  else
1476
  {
1477
    return HAL_BUSY;
1478
  }
1479
}
1480
 
1481
/**
1482
  * @brief  Receive in slave mode an amount of data in blocking mode
1483
  * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
1484
  *                the configuration information for the specified I2C.
1485
  * @param  pData Pointer to data buffer
1486
  * @param  Size Amount of data to be sent
1487
  * @param  Timeout Timeout duration
1488
  * @retval HAL status
1489
  */
6 mjames 1490
HAL_StatusTypeDef HAL_I2C_Slave_Receive(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size,
1491
                                        uint32_t Timeout)
2 mjames 1492
{
1493
  uint32_t tickstart;
1494
 
1495
  if (hi2c->State == HAL_I2C_STATE_READY)
1496
  {
1497
    if ((pData == NULL) || (Size == 0U))
1498
    {
1499
      hi2c->ErrorCode = HAL_I2C_ERROR_INVALID_PARAM;
1500
      return  HAL_ERROR;
1501
    }
1502
    /* Process Locked */
1503
    __HAL_LOCK(hi2c);
1504
 
1505
    /* Init tickstart for timeout management*/
1506
    tickstart = HAL_GetTick();
1507
 
1508
    hi2c->State     = HAL_I2C_STATE_BUSY_RX;
1509
    hi2c->Mode      = HAL_I2C_MODE_SLAVE;
1510
    hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
1511
 
1512
    /* Prepare transfer parameters */
1513
    hi2c->pBuffPtr  = pData;
1514
    hi2c->XferCount = Size;
1515
    hi2c->XferISR   = NULL;
1516
 
1517
    /* Enable Address Acknowledge */
1518
    hi2c->Instance->CR2 &= ~I2C_CR2_NACK;
1519
 
1520
    /* Wait until ADDR flag is set */
1521
    if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_ADDR, RESET, Timeout, tickstart) != HAL_OK)
1522
    {
1523
      /* Disable Address Acknowledge */
1524
      hi2c->Instance->CR2 |= I2C_CR2_NACK;
1525
      return HAL_ERROR;
1526
    }
1527
 
1528
    /* Clear ADDR flag */
1529
    __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_ADDR);
1530
 
1531
    /* Wait until DIR flag is reset Receiver mode */
1532
    if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_DIR, SET, Timeout, tickstart) != HAL_OK)
1533
    {
1534
      /* Disable Address Acknowledge */
1535
      hi2c->Instance->CR2 |= I2C_CR2_NACK;
1536
      return HAL_ERROR;
1537
    }
1538
 
1539
    while (hi2c->XferCount > 0U)
1540
    {
1541
      /* Wait until RXNE flag is set */
1542
      if (I2C_WaitOnRXNEFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK)
1543
      {
1544
        /* Disable Address Acknowledge */
1545
        hi2c->Instance->CR2 |= I2C_CR2_NACK;
1546
 
1547
        /* Store Last receive data if any */
1548
        if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_RXNE) == SET)
1549
        {
1550
          /* Read data from RXDR */
1551
          *hi2c->pBuffPtr = (uint8_t)hi2c->Instance->RXDR;
1552
 
1553
          /* Increment Buffer pointer */
1554
          hi2c->pBuffPtr++;
1555
 
1556
          hi2c->XferCount--;
1557
        }
1558
 
1559
        return HAL_ERROR;
1560
      }
1561
 
1562
      /* Read data from RXDR */
1563
      *hi2c->pBuffPtr = (uint8_t)hi2c->Instance->RXDR;
1564
 
1565
      /* Increment Buffer pointer */
1566
      hi2c->pBuffPtr++;
1567
 
1568
      hi2c->XferCount--;
1569
    }
1570
 
1571
    /* Wait until STOP flag is set */
1572
    if (I2C_WaitOnSTOPFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK)
1573
    {
1574
      /* Disable Address Acknowledge */
1575
      hi2c->Instance->CR2 |= I2C_CR2_NACK;
1576
      return HAL_ERROR;
1577
    }
1578
 
1579
    /* Clear STOP flag */
1580
    __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF);
1581
 
1582
    /* Wait until BUSY flag is reset */
1583
    if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, Timeout, tickstart) != HAL_OK)
1584
    {
1585
      /* Disable Address Acknowledge */
1586
      hi2c->Instance->CR2 |= I2C_CR2_NACK;
1587
      return HAL_ERROR;
1588
    }
1589
 
1590
    /* Disable Address Acknowledge */
1591
    hi2c->Instance->CR2 |= I2C_CR2_NACK;
1592
 
1593
    hi2c->State = HAL_I2C_STATE_READY;
1594
    hi2c->Mode  = HAL_I2C_MODE_NONE;
1595
 
1596
    /* Process Unlocked */
1597
    __HAL_UNLOCK(hi2c);
1598
 
1599
    return HAL_OK;
1600
  }
1601
  else
1602
  {
1603
    return HAL_BUSY;
1604
  }
1605
}
1606
 
1607
/**
1608
  * @brief  Transmit in master mode an amount of data in non-blocking mode with Interrupt
1609
  * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
1610
  *                the configuration information for the specified I2C.
1611
  * @param  DevAddress Target device address: The device 7 bits address value
1612
  *         in datasheet must be shifted to the left before calling the interface
1613
  * @param  pData Pointer to data buffer
1614
  * @param  Size Amount of data to be sent
1615
  * @retval HAL status
1616
  */
6 mjames 1617
HAL_StatusTypeDef HAL_I2C_Master_Transmit_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData,
1618
                                             uint16_t Size)
2 mjames 1619
{
1620
  uint32_t xfermode;
1621
 
1622
  if (hi2c->State == HAL_I2C_STATE_READY)
1623
  {
1624
    if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) == SET)
1625
    {
1626
      return HAL_BUSY;
1627
    }
1628
 
1629
    /* Process Locked */
1630
    __HAL_LOCK(hi2c);
1631
 
1632
    hi2c->State       = HAL_I2C_STATE_BUSY_TX;
1633
    hi2c->Mode        = HAL_I2C_MODE_MASTER;
1634
    hi2c->ErrorCode   = HAL_I2C_ERROR_NONE;
1635
 
1636
    /* Prepare transfer parameters */
1637
    hi2c->pBuffPtr    = pData;
1638
    hi2c->XferCount   = Size;
1639
    hi2c->XferOptions = I2C_NO_OPTION_FRAME;
1640
    hi2c->XferISR     = I2C_Master_ISR_IT;
1641
 
1642
    if (hi2c->XferCount > MAX_NBYTE_SIZE)
1643
    {
1644
      hi2c->XferSize = MAX_NBYTE_SIZE;
1645
      xfermode = I2C_RELOAD_MODE;
1646
    }
1647
    else
1648
    {
1649
      hi2c->XferSize = hi2c->XferCount;
1650
      xfermode = I2C_AUTOEND_MODE;
1651
    }
1652
 
1653
    /* Send Slave Address */
1654
    /* Set NBYTES to write and reload if hi2c->XferCount > MAX_NBYTE_SIZE */
1655
    I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, xfermode, I2C_GENERATE_START_WRITE);
1656
 
1657
    /* Process Unlocked */
1658
    __HAL_UNLOCK(hi2c);
1659
 
1660
    /* Note : The I2C interrupts must be enabled after unlocking current process
1661
              to avoid the risk of I2C interrupt handle execution before current
1662
              process unlock */
1663
 
1664
    /* Enable ERR, TC, STOP, NACK, TXI interrupt */
1665
    /* possible to enable all of these */
6 mjames 1666
    /* I2C_IT_ERRI | I2C_IT_TCI | I2C_IT_STOPI | I2C_IT_NACKI |
1667
      I2C_IT_ADDRI | I2C_IT_RXI | I2C_IT_TXI */
2 mjames 1668
    I2C_Enable_IRQ(hi2c, I2C_XFER_TX_IT);
1669
 
1670
    return HAL_OK;
1671
  }
1672
  else
1673
  {
1674
    return HAL_BUSY;
1675
  }
1676
}
1677
 
1678
/**
1679
  * @brief  Receive in master mode an amount of data in non-blocking mode with Interrupt
1680
  * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
1681
  *                the configuration information for the specified I2C.
1682
  * @param  DevAddress Target device address: The device 7 bits address value
1683
  *         in datasheet must be shifted to the left before calling the interface
1684
  * @param  pData Pointer to data buffer
1685
  * @param  Size Amount of data to be sent
1686
  * @retval HAL status
1687
  */
6 mjames 1688
HAL_StatusTypeDef HAL_I2C_Master_Receive_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData,
1689
                                            uint16_t Size)
2 mjames 1690
{
1691
  uint32_t xfermode;
1692
 
1693
  if (hi2c->State == HAL_I2C_STATE_READY)
1694
  {
1695
    if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) == SET)
1696
    {
1697
      return HAL_BUSY;
1698
    }
1699
 
1700
    /* Process Locked */
1701
    __HAL_LOCK(hi2c);
1702
 
1703
    hi2c->State       = HAL_I2C_STATE_BUSY_RX;
1704
    hi2c->Mode        = HAL_I2C_MODE_MASTER;
1705
    hi2c->ErrorCode   = HAL_I2C_ERROR_NONE;
1706
 
1707
    /* Prepare transfer parameters */
1708
    hi2c->pBuffPtr    = pData;
1709
    hi2c->XferCount   = Size;
1710
    hi2c->XferOptions = I2C_NO_OPTION_FRAME;
1711
    hi2c->XferISR     = I2C_Master_ISR_IT;
1712
 
1713
    if (hi2c->XferCount > MAX_NBYTE_SIZE)
1714
    {
1715
      hi2c->XferSize = MAX_NBYTE_SIZE;
1716
      xfermode = I2C_RELOAD_MODE;
1717
    }
1718
    else
1719
    {
1720
      hi2c->XferSize = hi2c->XferCount;
1721
      xfermode = I2C_AUTOEND_MODE;
1722
    }
1723
 
1724
    /* Send Slave Address */
1725
    /* Set NBYTES to write and reload if hi2c->XferCount > MAX_NBYTE_SIZE */
1726
    I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, xfermode, I2C_GENERATE_START_READ);
1727
 
1728
    /* Process Unlocked */
1729
    __HAL_UNLOCK(hi2c);
1730
 
1731
    /* Note : The I2C interrupts must be enabled after unlocking current process
1732
              to avoid the risk of I2C interrupt handle execution before current
1733
              process unlock */
1734
 
1735
    /* Enable ERR, TC, STOP, NACK, RXI interrupt */
1736
    /* possible to enable all of these */
6 mjames 1737
    /* I2C_IT_ERRI | I2C_IT_TCI | I2C_IT_STOPI | I2C_IT_NACKI |
1738
      I2C_IT_ADDRI | I2C_IT_RXI | I2C_IT_TXI */
2 mjames 1739
    I2C_Enable_IRQ(hi2c, I2C_XFER_RX_IT);
1740
 
1741
    return HAL_OK;
1742
  }
1743
  else
1744
  {
1745
    return HAL_BUSY;
1746
  }
1747
}
1748
 
1749
/**
1750
  * @brief  Transmit in slave mode an amount of data in non-blocking mode with Interrupt
1751
  * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
1752
  *                the configuration information for the specified I2C.
1753
  * @param  pData Pointer to data buffer
1754
  * @param  Size Amount of data to be sent
1755
  * @retval HAL status
1756
  */
1757
HAL_StatusTypeDef HAL_I2C_Slave_Transmit_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size)
1758
{
1759
  if (hi2c->State == HAL_I2C_STATE_READY)
1760
  {
1761
    /* Process Locked */
1762
    __HAL_LOCK(hi2c);
1763
 
1764
    hi2c->State       = HAL_I2C_STATE_BUSY_TX;
1765
    hi2c->Mode        = HAL_I2C_MODE_SLAVE;
1766
    hi2c->ErrorCode   = HAL_I2C_ERROR_NONE;
1767
 
1768
    /* Enable Address Acknowledge */
1769
    hi2c->Instance->CR2 &= ~I2C_CR2_NACK;
1770
 
1771
    /* Prepare transfer parameters */
1772
    hi2c->pBuffPtr    = pData;
1773
    hi2c->XferCount   = Size;
1774
    hi2c->XferSize    = hi2c->XferCount;
1775
    hi2c->XferOptions = I2C_NO_OPTION_FRAME;
1776
    hi2c->XferISR     = I2C_Slave_ISR_IT;
1777
 
1778
    /* Process Unlocked */
1779
    __HAL_UNLOCK(hi2c);
1780
 
1781
    /* Note : The I2C interrupts must be enabled after unlocking current process
1782
              to avoid the risk of I2C interrupt handle execution before current
1783
              process unlock */
1784
 
1785
    /* Enable ERR, TC, STOP, NACK, TXI interrupt */
1786
    /* possible to enable all of these */
6 mjames 1787
    /* I2C_IT_ERRI | I2C_IT_TCI | I2C_IT_STOPI | I2C_IT_NACKI |
1788
      I2C_IT_ADDRI | I2C_IT_RXI | I2C_IT_TXI */
2 mjames 1789
    I2C_Enable_IRQ(hi2c, I2C_XFER_TX_IT | I2C_XFER_LISTEN_IT);
1790
 
1791
    return HAL_OK;
1792
  }
1793
  else
1794
  {
1795
    return HAL_BUSY;
1796
  }
1797
}
1798
 
1799
/**
1800
  * @brief  Receive in slave mode an amount of data in non-blocking mode with Interrupt
1801
  * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
1802
  *                the configuration information for the specified I2C.
1803
  * @param  pData Pointer to data buffer
1804
  * @param  Size Amount of data to be sent
1805
  * @retval HAL status
1806
  */
1807
HAL_StatusTypeDef HAL_I2C_Slave_Receive_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size)
1808
{
1809
  if (hi2c->State == HAL_I2C_STATE_READY)
1810
  {
1811
    /* Process Locked */
1812
    __HAL_LOCK(hi2c);
1813
 
1814
    hi2c->State       = HAL_I2C_STATE_BUSY_RX;
1815
    hi2c->Mode        = HAL_I2C_MODE_SLAVE;
1816
    hi2c->ErrorCode   = HAL_I2C_ERROR_NONE;
1817
 
1818
    /* Enable Address Acknowledge */
1819
    hi2c->Instance->CR2 &= ~I2C_CR2_NACK;
1820
 
1821
    /* Prepare transfer parameters */
1822
    hi2c->pBuffPtr    = pData;
1823
    hi2c->XferCount   = Size;
1824
    hi2c->XferSize    = hi2c->XferCount;
1825
    hi2c->XferOptions = I2C_NO_OPTION_FRAME;
1826
    hi2c->XferISR     = I2C_Slave_ISR_IT;
1827
 
1828
    /* Process Unlocked */
1829
    __HAL_UNLOCK(hi2c);
1830
 
1831
    /* Note : The I2C interrupts must be enabled after unlocking current process
1832
              to avoid the risk of I2C interrupt handle execution before current
1833
              process unlock */
1834
 
1835
    /* Enable ERR, TC, STOP, NACK, RXI interrupt */
1836
    /* possible to enable all of these */
6 mjames 1837
    /* I2C_IT_ERRI | I2C_IT_TCI | I2C_IT_STOPI | I2C_IT_NACKI |
1838
      I2C_IT_ADDRI | I2C_IT_RXI | I2C_IT_TXI */
2 mjames 1839
    I2C_Enable_IRQ(hi2c, I2C_XFER_RX_IT | I2C_XFER_LISTEN_IT);
1840
 
1841
    return HAL_OK;
1842
  }
1843
  else
1844
  {
1845
    return HAL_BUSY;
1846
  }
1847
}
1848
 
1849
/**
1850
  * @brief  Transmit in master mode an amount of data in non-blocking mode with DMA
1851
  * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
1852
  *                the configuration information for the specified I2C.
1853
  * @param  DevAddress Target device address: The device 7 bits address value
1854
  *         in datasheet must be shifted to the left before calling the interface
1855
  * @param  pData Pointer to data buffer
1856
  * @param  Size Amount of data to be sent
1857
  * @retval HAL status
1858
  */
6 mjames 1859
HAL_StatusTypeDef HAL_I2C_Master_Transmit_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData,
1860
                                              uint16_t Size)
2 mjames 1861
{
1862
  uint32_t xfermode;
1863
  HAL_StatusTypeDef dmaxferstatus;
1864
 
1865
  if (hi2c->State == HAL_I2C_STATE_READY)
1866
  {
1867
    if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) == SET)
1868
    {
1869
      return HAL_BUSY;
1870
    }
1871
 
1872
    /* Process Locked */
1873
    __HAL_LOCK(hi2c);
1874
 
1875
    hi2c->State       = HAL_I2C_STATE_BUSY_TX;
1876
    hi2c->Mode        = HAL_I2C_MODE_MASTER;
1877
    hi2c->ErrorCode   = HAL_I2C_ERROR_NONE;
1878
 
1879
    /* Prepare transfer parameters */
1880
    hi2c->pBuffPtr    = pData;
1881
    hi2c->XferCount   = Size;
1882
    hi2c->XferOptions = I2C_NO_OPTION_FRAME;
1883
    hi2c->XferISR     = I2C_Master_ISR_DMA;
1884
 
1885
    if (hi2c->XferCount > MAX_NBYTE_SIZE)
1886
    {
1887
      hi2c->XferSize = MAX_NBYTE_SIZE;
1888
      xfermode = I2C_RELOAD_MODE;
1889
    }
1890
    else
1891
    {
1892
      hi2c->XferSize = hi2c->XferCount;
1893
      xfermode = I2C_AUTOEND_MODE;
1894
    }
1895
 
1896
    if (hi2c->XferSize > 0U)
1897
    {
1898
      if (hi2c->hdmatx != NULL)
1899
      {
1900
        /* Set the I2C DMA transfer complete callback */
1901
        hi2c->hdmatx->XferCpltCallback = I2C_DMAMasterTransmitCplt;
1902
 
1903
        /* Set the DMA error callback */
1904
        hi2c->hdmatx->XferErrorCallback = I2C_DMAError;
1905
 
1906
        /* Set the unused DMA callbacks to NULL */
1907
        hi2c->hdmatx->XferHalfCpltCallback = NULL;
1908
        hi2c->hdmatx->XferAbortCallback = NULL;
1909
 
1910
        /* Enable the DMA channel */
6 mjames 1911
        dmaxferstatus = HAL_DMA_Start_IT(hi2c->hdmatx, (uint32_t)pData, (uint32_t)&hi2c->Instance->TXDR,
1912
                                         hi2c->XferSize);
2 mjames 1913
      }
1914
      else
1915
      {
1916
        /* Update I2C state */
1917
        hi2c->State     = HAL_I2C_STATE_READY;
1918
        hi2c->Mode      = HAL_I2C_MODE_NONE;
1919
 
1920
        /* Update I2C error code */
1921
        hi2c->ErrorCode |= HAL_I2C_ERROR_DMA_PARAM;
1922
 
1923
        /* Process Unlocked */
1924
        __HAL_UNLOCK(hi2c);
1925
 
1926
        return HAL_ERROR;
1927
      }
1928
 
1929
      if (dmaxferstatus == HAL_OK)
1930
      {
1931
        /* Send Slave Address */
1932
        /* Set NBYTES to write and reload if hi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */
1933
        I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, xfermode, I2C_GENERATE_START_WRITE);
1934
 
1935
        /* Update XferCount value */
1936
        hi2c->XferCount -= hi2c->XferSize;
1937
 
1938
        /* Process Unlocked */
1939
        __HAL_UNLOCK(hi2c);
1940
 
1941
        /* Note : The I2C interrupts must be enabled after unlocking current process
1942
                  to avoid the risk of I2C interrupt handle execution before current
1943
                  process unlock */
1944
        /* Enable ERR and NACK interrupts */
1945
        I2C_Enable_IRQ(hi2c, I2C_XFER_ERROR_IT);
1946
 
1947
        /* Enable DMA Request */
1948
        hi2c->Instance->CR1 |= I2C_CR1_TXDMAEN;
1949
      }
1950
      else
1951
      {
1952
        /* Update I2C state */
1953
        hi2c->State     = HAL_I2C_STATE_READY;
1954
        hi2c->Mode      = HAL_I2C_MODE_NONE;
1955
 
1956
        /* Update I2C error code */
1957
        hi2c->ErrorCode |= HAL_I2C_ERROR_DMA;
1958
 
1959
        /* Process Unlocked */
1960
        __HAL_UNLOCK(hi2c);
1961
 
1962
        return HAL_ERROR;
1963
      }
1964
    }
1965
    else
1966
    {
1967
      /* Update Transfer ISR function pointer */
1968
      hi2c->XferISR = I2C_Master_ISR_IT;
1969
 
1970
      /* Send Slave Address */
1971
      /* Set NBYTES to write and generate START condition */
6 mjames 1972
      I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, I2C_AUTOEND_MODE,
1973
                         I2C_GENERATE_START_WRITE);
2 mjames 1974
 
1975
      /* Process Unlocked */
1976
      __HAL_UNLOCK(hi2c);
1977
 
1978
      /* Note : The I2C interrupts must be enabled after unlocking current process
1979
                to avoid the risk of I2C interrupt handle execution before current
1980
                process unlock */
1981
      /* Enable ERR, TC, STOP, NACK, TXI interrupt */
1982
      /* possible to enable all of these */
6 mjames 1983
      /* I2C_IT_ERRI | I2C_IT_TCI | I2C_IT_STOPI | I2C_IT_NACKI |
1984
        I2C_IT_ADDRI | I2C_IT_RXI | I2C_IT_TXI */
2 mjames 1985
      I2C_Enable_IRQ(hi2c, I2C_XFER_TX_IT);
1986
    }
1987
 
1988
    return HAL_OK;
1989
  }
1990
  else
1991
  {
1992
    return HAL_BUSY;
1993
  }
1994
}
1995
 
1996
/**
1997
  * @brief  Receive in master mode an amount of data in non-blocking mode with DMA
1998
  * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
1999
  *                the configuration information for the specified I2C.
2000
  * @param  DevAddress Target device address: The device 7 bits address value
2001
  *         in datasheet must be shifted to the left before calling the interface
2002
  * @param  pData Pointer to data buffer
2003
  * @param  Size Amount of data to be sent
2004
  * @retval HAL status
2005
  */
6 mjames 2006
HAL_StatusTypeDef HAL_I2C_Master_Receive_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData,
2007
                                             uint16_t Size)
2 mjames 2008
{
2009
  uint32_t xfermode;
2010
  HAL_StatusTypeDef dmaxferstatus;
2011
 
2012
  if (hi2c->State == HAL_I2C_STATE_READY)
2013
  {
2014
    if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) == SET)
2015
    {
2016
      return HAL_BUSY;
2017
    }
2018
 
2019
    /* Process Locked */
2020
    __HAL_LOCK(hi2c);
2021
 
2022
    hi2c->State       = HAL_I2C_STATE_BUSY_RX;
2023
    hi2c->Mode        = HAL_I2C_MODE_MASTER;
2024
    hi2c->ErrorCode   = HAL_I2C_ERROR_NONE;
2025
 
2026
    /* Prepare transfer parameters */
2027
    hi2c->pBuffPtr    = pData;
2028
    hi2c->XferCount   = Size;
2029
    hi2c->XferOptions = I2C_NO_OPTION_FRAME;
2030
    hi2c->XferISR     = I2C_Master_ISR_DMA;
2031
 
2032
    if (hi2c->XferCount > MAX_NBYTE_SIZE)
2033
    {
2034
      hi2c->XferSize = MAX_NBYTE_SIZE;
2035
      xfermode = I2C_RELOAD_MODE;
2036
    }
2037
    else
2038
    {
2039
      hi2c->XferSize = hi2c->XferCount;
2040
      xfermode = I2C_AUTOEND_MODE;
2041
    }
2042
 
2043
    if (hi2c->XferSize > 0U)
2044
    {
2045
      if (hi2c->hdmarx != NULL)
2046
      {
2047
        /* Set the I2C DMA transfer complete callback */
2048
        hi2c->hdmarx->XferCpltCallback = I2C_DMAMasterReceiveCplt;
2049
 
2050
        /* Set the DMA error callback */
2051
        hi2c->hdmarx->XferErrorCallback = I2C_DMAError;
2052
 
2053
        /* Set the unused DMA callbacks to NULL */
2054
        hi2c->hdmarx->XferHalfCpltCallback = NULL;
2055
        hi2c->hdmarx->XferAbortCallback = NULL;
2056
 
2057
        /* Enable the DMA channel */
6 mjames 2058
        dmaxferstatus = HAL_DMA_Start_IT(hi2c->hdmarx, (uint32_t)&hi2c->Instance->RXDR, (uint32_t)pData,
2059
                                         hi2c->XferSize);
2 mjames 2060
      }
2061
      else
2062
      {
2063
        /* Update I2C state */
2064
        hi2c->State     = HAL_I2C_STATE_READY;
2065
        hi2c->Mode      = HAL_I2C_MODE_NONE;
2066
 
2067
        /* Update I2C error code */
2068
        hi2c->ErrorCode |= HAL_I2C_ERROR_DMA_PARAM;
2069
 
2070
        /* Process Unlocked */
2071
        __HAL_UNLOCK(hi2c);
2072
 
2073
        return HAL_ERROR;
2074
      }
2075
 
2076
      if (dmaxferstatus == HAL_OK)
2077
      {
2078
        /* Send Slave Address */
2079
        /* Set NBYTES to read and reload if hi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */
2080
        I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, xfermode, I2C_GENERATE_START_READ);
2081
 
2082
        /* Update XferCount value */
2083
        hi2c->XferCount -= hi2c->XferSize;
2084
 
2085
        /* Process Unlocked */
2086
        __HAL_UNLOCK(hi2c);
2087
 
2088
        /* Note : The I2C interrupts must be enabled after unlocking current process
2089
                  to avoid the risk of I2C interrupt handle execution before current
2090
                  process unlock */
2091
        /* Enable ERR and NACK interrupts */
2092
        I2C_Enable_IRQ(hi2c, I2C_XFER_ERROR_IT);
2093
 
2094
        /* Enable DMA Request */
2095
        hi2c->Instance->CR1 |= I2C_CR1_RXDMAEN;
2096
      }
2097
      else
2098
      {
2099
        /* Update I2C state */
2100
        hi2c->State     = HAL_I2C_STATE_READY;
2101
        hi2c->Mode      = HAL_I2C_MODE_NONE;
2102
 
2103
        /* Update I2C error code */
2104
        hi2c->ErrorCode |= HAL_I2C_ERROR_DMA;
2105
 
2106
        /* Process Unlocked */
2107
        __HAL_UNLOCK(hi2c);
2108
 
2109
        return HAL_ERROR;
2110
      }
2111
    }
2112
    else
2113
    {
2114
      /* Update Transfer ISR function pointer */
2115
      hi2c->XferISR = I2C_Master_ISR_IT;
2116
 
2117
      /* Send Slave Address */
2118
      /* Set NBYTES to read and generate START condition */
6 mjames 2119
      I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, I2C_AUTOEND_MODE,
2120
                         I2C_GENERATE_START_READ);
2 mjames 2121
 
2122
      /* Process Unlocked */
2123
      __HAL_UNLOCK(hi2c);
2124
 
2125
      /* Note : The I2C interrupts must be enabled after unlocking current process
2126
                to avoid the risk of I2C interrupt handle execution before current
2127
                process unlock */
2128
      /* Enable ERR, TC, STOP, NACK, TXI interrupt */
2129
      /* possible to enable all of these */
6 mjames 2130
      /* I2C_IT_ERRI | I2C_IT_TCI | I2C_IT_STOPI | I2C_IT_NACKI |
2131
        I2C_IT_ADDRI | I2C_IT_RXI | I2C_IT_TXI */
2 mjames 2132
      I2C_Enable_IRQ(hi2c, I2C_XFER_TX_IT);
2133
    }
2134
 
2135
    return HAL_OK;
2136
  }
2137
  else
2138
  {
2139
    return HAL_BUSY;
2140
  }
2141
}
2142
 
2143
/**
2144
  * @brief  Transmit in slave mode an amount of data in non-blocking mode with DMA
2145
  * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
2146
  *                the configuration information for the specified I2C.
2147
  * @param  pData Pointer to data buffer
2148
  * @param  Size Amount of data to be sent
2149
  * @retval HAL status
2150
  */
2151
HAL_StatusTypeDef HAL_I2C_Slave_Transmit_DMA(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size)
2152
{
2153
  HAL_StatusTypeDef dmaxferstatus;
2154
 
2155
  if (hi2c->State == HAL_I2C_STATE_READY)
2156
  {
2157
    if ((pData == NULL) || (Size == 0U))
2158
    {
2159
      hi2c->ErrorCode = HAL_I2C_ERROR_INVALID_PARAM;
2160
      return  HAL_ERROR;
2161
    }
2162
    /* Process Locked */
2163
    __HAL_LOCK(hi2c);
2164
 
2165
    hi2c->State       = HAL_I2C_STATE_BUSY_TX;
2166
    hi2c->Mode        = HAL_I2C_MODE_SLAVE;
2167
    hi2c->ErrorCode   = HAL_I2C_ERROR_NONE;
2168
 
2169
    /* Prepare transfer parameters */
2170
    hi2c->pBuffPtr    = pData;
2171
    hi2c->XferCount   = Size;
2172
    hi2c->XferSize    = hi2c->XferCount;
2173
    hi2c->XferOptions = I2C_NO_OPTION_FRAME;
2174
    hi2c->XferISR     = I2C_Slave_ISR_DMA;
2175
 
2176
    if (hi2c->hdmatx != NULL)
2177
    {
2178
      /* Set the I2C DMA transfer complete callback */
2179
      hi2c->hdmatx->XferCpltCallback = I2C_DMASlaveTransmitCplt;
2180
 
2181
      /* Set the DMA error callback */
2182
      hi2c->hdmatx->XferErrorCallback = I2C_DMAError;
2183
 
2184
      /* Set the unused DMA callbacks to NULL */
2185
      hi2c->hdmatx->XferHalfCpltCallback = NULL;
2186
      hi2c->hdmatx->XferAbortCallback = NULL;
2187
 
2188
      /* Enable the DMA channel */
6 mjames 2189
      dmaxferstatus = HAL_DMA_Start_IT(hi2c->hdmatx, (uint32_t)pData, (uint32_t)&hi2c->Instance->TXDR,
2190
                                       hi2c->XferSize);
2 mjames 2191
    }
2192
    else
2193
    {
2194
      /* Update I2C state */
2195
      hi2c->State     = HAL_I2C_STATE_LISTEN;
2196
      hi2c->Mode      = HAL_I2C_MODE_NONE;
2197
 
2198
      /* Update I2C error code */
2199
      hi2c->ErrorCode |= HAL_I2C_ERROR_DMA_PARAM;
2200
 
2201
      /* Process Unlocked */
2202
      __HAL_UNLOCK(hi2c);
2203
 
2204
      return HAL_ERROR;
2205
    }
2206
 
2207
    if (dmaxferstatus == HAL_OK)
2208
    {
2209
      /* Enable Address Acknowledge */
2210
      hi2c->Instance->CR2 &= ~I2C_CR2_NACK;
2211
 
2212
      /* Process Unlocked */
2213
      __HAL_UNLOCK(hi2c);
2214
 
2215
      /* Note : The I2C interrupts must be enabled after unlocking current process
2216
                to avoid the risk of I2C interrupt handle execution before current
2217
                process unlock */
2218
      /* Enable ERR, STOP, NACK, ADDR interrupts */
2219
      I2C_Enable_IRQ(hi2c, I2C_XFER_LISTEN_IT);
2220
 
2221
      /* Enable DMA Request */
2222
      hi2c->Instance->CR1 |= I2C_CR1_TXDMAEN;
2223
    }
2224
    else
2225
    {
2226
      /* Update I2C state */
2227
      hi2c->State     = HAL_I2C_STATE_LISTEN;
2228
      hi2c->Mode      = HAL_I2C_MODE_NONE;
2229
 
2230
      /* Update I2C error code */
2231
      hi2c->ErrorCode |= HAL_I2C_ERROR_DMA;
2232
 
2233
      /* Process Unlocked */
2234
      __HAL_UNLOCK(hi2c);
2235
 
2236
      return HAL_ERROR;
2237
    }
2238
 
2239
    return HAL_OK;
2240
  }
2241
  else
2242
  {
2243
    return HAL_BUSY;
2244
  }
2245
}
2246
 
2247
/**
2248
  * @brief  Receive in slave mode an amount of data in non-blocking mode with DMA
2249
  * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
2250
  *                the configuration information for the specified I2C.
2251
  * @param  pData Pointer to data buffer
2252
  * @param  Size Amount of data to be sent
2253
  * @retval HAL status
2254
  */
2255
HAL_StatusTypeDef HAL_I2C_Slave_Receive_DMA(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size)
2256
{
2257
  HAL_StatusTypeDef dmaxferstatus;
2258
 
2259
  if (hi2c->State == HAL_I2C_STATE_READY)
2260
  {
2261
    if ((pData == NULL) || (Size == 0U))
2262
    {
2263
      hi2c->ErrorCode = HAL_I2C_ERROR_INVALID_PARAM;
2264
      return  HAL_ERROR;
2265
    }
2266
    /* Process Locked */
2267
    __HAL_LOCK(hi2c);
2268
 
2269
    hi2c->State       = HAL_I2C_STATE_BUSY_RX;
2270
    hi2c->Mode        = HAL_I2C_MODE_SLAVE;
2271
    hi2c->ErrorCode   = HAL_I2C_ERROR_NONE;
2272
 
2273
    /* Prepare transfer parameters */
2274
    hi2c->pBuffPtr    = pData;
2275
    hi2c->XferCount   = Size;
2276
    hi2c->XferSize    = hi2c->XferCount;
2277
    hi2c->XferOptions = I2C_NO_OPTION_FRAME;
2278
    hi2c->XferISR     = I2C_Slave_ISR_DMA;
2279
 
2280
    if (hi2c->hdmarx != NULL)
2281
    {
2282
      /* Set the I2C DMA transfer complete callback */
2283
      hi2c->hdmarx->XferCpltCallback = I2C_DMASlaveReceiveCplt;
2284
 
2285
      /* Set the DMA error callback */
2286
      hi2c->hdmarx->XferErrorCallback = I2C_DMAError;
2287
 
2288
      /* Set the unused DMA callbacks to NULL */
2289
      hi2c->hdmarx->XferHalfCpltCallback = NULL;
2290
      hi2c->hdmarx->XferAbortCallback = NULL;
2291
 
2292
      /* Enable the DMA channel */
6 mjames 2293
      dmaxferstatus = HAL_DMA_Start_IT(hi2c->hdmarx, (uint32_t)&hi2c->Instance->RXDR, (uint32_t)pData,
2294
                                       hi2c->XferSize);
2 mjames 2295
    }
2296
    else
2297
    {
2298
      /* Update I2C state */
2299
      hi2c->State     = HAL_I2C_STATE_LISTEN;
2300
      hi2c->Mode      = HAL_I2C_MODE_NONE;
2301
 
2302
      /* Update I2C error code */
2303
      hi2c->ErrorCode |= HAL_I2C_ERROR_DMA_PARAM;
2304
 
2305
      /* Process Unlocked */
2306
      __HAL_UNLOCK(hi2c);
2307
 
2308
      return HAL_ERROR;
2309
    }
2310
 
2311
    if (dmaxferstatus == HAL_OK)
2312
    {
2313
      /* Enable Address Acknowledge */
2314
      hi2c->Instance->CR2 &= ~I2C_CR2_NACK;
2315
 
2316
      /* Process Unlocked */
2317
      __HAL_UNLOCK(hi2c);
2318
 
2319
      /* Note : The I2C interrupts must be enabled after unlocking current process
2320
                to avoid the risk of I2C interrupt handle execution before current
2321
                process unlock */
2322
      /* Enable ERR, STOP, NACK, ADDR interrupts */
2323
      I2C_Enable_IRQ(hi2c, I2C_XFER_LISTEN_IT);
2324
 
2325
      /* Enable DMA Request */
2326
      hi2c->Instance->CR1 |= I2C_CR1_RXDMAEN;
2327
    }
2328
    else
2329
    {
2330
      /* Update I2C state */
2331
      hi2c->State     = HAL_I2C_STATE_LISTEN;
2332
      hi2c->Mode      = HAL_I2C_MODE_NONE;
2333
 
2334
      /* Update I2C error code */
2335
      hi2c->ErrorCode |= HAL_I2C_ERROR_DMA;
2336
 
2337
      /* Process Unlocked */
2338
      __HAL_UNLOCK(hi2c);
2339
 
2340
      return HAL_ERROR;
2341
    }
2342
 
2343
    return HAL_OK;
2344
  }
2345
  else
2346
  {
2347
    return HAL_BUSY;
2348
  }
2349
}
2350
/**
2351
  * @brief  Write an amount of data in blocking mode to a specific memory address
2352
  * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
2353
  *                the configuration information for the specified I2C.
2354
  * @param  DevAddress Target device address: The device 7 bits address value
2355
  *         in datasheet must be shifted to the left before calling the interface
2356
  * @param  MemAddress Internal memory address
2357
  * @param  MemAddSize Size of internal memory address
2358
  * @param  pData Pointer to data buffer
2359
  * @param  Size Amount of data to be sent
2360
  * @param  Timeout Timeout duration
2361
  * @retval HAL status
2362
  */
6 mjames 2363
HAL_StatusTypeDef HAL_I2C_Mem_Write(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress,
2364
                                    uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout)
2 mjames 2365
{
2366
  uint32_t tickstart;
2367
 
2368
  /* Check the parameters */
2369
  assert_param(IS_I2C_MEMADD_SIZE(MemAddSize));
2370
 
2371
  if (hi2c->State == HAL_I2C_STATE_READY)
2372
  {
2373
    if ((pData == NULL) || (Size == 0U))
2374
    {
2375
      hi2c->ErrorCode = HAL_I2C_ERROR_INVALID_PARAM;
2376
      return  HAL_ERROR;
2377
    }
2378
 
2379
    /* Process Locked */
2380
    __HAL_LOCK(hi2c);
2381
 
2382
    /* Init tickstart for timeout management*/
2383
    tickstart = HAL_GetTick();
2384
 
2385
    if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY, tickstart) != HAL_OK)
2386
    {
2387
      return HAL_ERROR;
2388
    }
2389
 
2390
    hi2c->State     = HAL_I2C_STATE_BUSY_TX;
2391
    hi2c->Mode      = HAL_I2C_MODE_MEM;
2392
    hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
2393
 
2394
    /* Prepare transfer parameters */
2395
    hi2c->pBuffPtr  = pData;
2396
    hi2c->XferCount = Size;
2397
    hi2c->XferISR   = NULL;
2398
 
2399
    /* Send Slave Address and Memory Address */
2400
    if (I2C_RequestMemoryWrite(hi2c, DevAddress, MemAddress, MemAddSize, Timeout, tickstart) != HAL_OK)
2401
    {
2402
      /* Process Unlocked */
2403
      __HAL_UNLOCK(hi2c);
2404
      return HAL_ERROR;
2405
    }
2406
 
2407
    /* Set NBYTES to write and reload if hi2c->XferCount > MAX_NBYTE_SIZE */
2408
    if (hi2c->XferCount > MAX_NBYTE_SIZE)
2409
    {
2410
      hi2c->XferSize = MAX_NBYTE_SIZE;
2411
      I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, I2C_RELOAD_MODE, I2C_NO_STARTSTOP);
2412
    }
2413
    else
2414
    {
2415
      hi2c->XferSize = hi2c->XferCount;
2416
      I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, I2C_AUTOEND_MODE, I2C_NO_STARTSTOP);
2417
    }
2418
 
2419
    do
2420
    {
2421
      /* Wait until TXIS flag is set */
2422
      if (I2C_WaitOnTXISFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK)
2423
      {
2424
        return HAL_ERROR;
2425
      }
2426
 
2427
      /* Write data to TXDR */
2428
      hi2c->Instance->TXDR = *hi2c->pBuffPtr;
2429
 
2430
      /* Increment Buffer pointer */
2431
      hi2c->pBuffPtr++;
2432
 
2433
      hi2c->XferCount--;
2434
      hi2c->XferSize--;
2435
 
2436
      if ((hi2c->XferCount != 0U) && (hi2c->XferSize == 0U))
2437
      {
2438
        /* Wait until TCR flag is set */
2439
        if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_TCR, RESET, Timeout, tickstart) != HAL_OK)
2440
        {
2441
          return HAL_ERROR;
2442
        }
2443
 
2444
        if (hi2c->XferCount > MAX_NBYTE_SIZE)
2445
        {
2446
          hi2c->XferSize = MAX_NBYTE_SIZE;
6 mjames 2447
          I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, I2C_RELOAD_MODE,
2448
                             I2C_NO_STARTSTOP);
2 mjames 2449
        }
2450
        else
2451
        {
2452
          hi2c->XferSize = hi2c->XferCount;
6 mjames 2453
          I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, I2C_AUTOEND_MODE,
2454
                             I2C_NO_STARTSTOP);
2 mjames 2455
        }
2456
      }
2457
 
6 mjames 2458
    } while (hi2c->XferCount > 0U);
2 mjames 2459
 
2460
    /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */
2461
    /* Wait until STOPF flag is reset */
2462
    if (I2C_WaitOnSTOPFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK)
2463
    {
2464
      return HAL_ERROR;
2465
    }
2466
 
2467
    /* Clear STOP Flag */
2468
    __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF);
2469
 
2470
    /* Clear Configuration Register 2 */
2471
    I2C_RESET_CR2(hi2c);
2472
 
2473
    hi2c->State = HAL_I2C_STATE_READY;
2474
    hi2c->Mode  = HAL_I2C_MODE_NONE;
2475
 
2476
    /* Process Unlocked */
2477
    __HAL_UNLOCK(hi2c);
2478
 
2479
    return HAL_OK;
2480
  }
2481
  else
2482
  {
2483
    return HAL_BUSY;
2484
  }
2485
}
2486
 
2487
/**
2488
  * @brief  Read an amount of data in blocking mode from a specific memory address
2489
  * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
2490
  *                the configuration information for the specified I2C.
2491
  * @param  DevAddress Target device address: The device 7 bits address value
2492
  *         in datasheet must be shifted to the left before calling the interface
2493
  * @param  MemAddress Internal memory address
2494
  * @param  MemAddSize Size of internal memory address
2495
  * @param  pData Pointer to data buffer
2496
  * @param  Size Amount of data to be sent
2497
  * @param  Timeout Timeout duration
2498
  * @retval HAL status
2499
  */
6 mjames 2500
HAL_StatusTypeDef HAL_I2C_Mem_Read(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress,
2501
                                   uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout)
2 mjames 2502
{
2503
  uint32_t tickstart;
2504
 
2505
  /* Check the parameters */
2506
  assert_param(IS_I2C_MEMADD_SIZE(MemAddSize));
2507
 
2508
  if (hi2c->State == HAL_I2C_STATE_READY)
2509
  {
2510
    if ((pData == NULL) || (Size == 0U))
2511
    {
2512
      hi2c->ErrorCode = HAL_I2C_ERROR_INVALID_PARAM;
2513
      return  HAL_ERROR;
2514
    }
2515
 
2516
    /* Process Locked */
2517
    __HAL_LOCK(hi2c);
2518
 
2519
    /* Init tickstart for timeout management*/
2520
    tickstart = HAL_GetTick();
2521
 
2522
    if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY, tickstart) != HAL_OK)
2523
    {
2524
      return HAL_ERROR;
2525
    }
2526
 
2527
    hi2c->State     = HAL_I2C_STATE_BUSY_RX;
2528
    hi2c->Mode      = HAL_I2C_MODE_MEM;
2529
    hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
2530
 
2531
    /* Prepare transfer parameters */
2532
    hi2c->pBuffPtr  = pData;
2533
    hi2c->XferCount = Size;
2534
    hi2c->XferISR   = NULL;
2535
 
2536
    /* Send Slave Address and Memory Address */
2537
    if (I2C_RequestMemoryRead(hi2c, DevAddress, MemAddress, MemAddSize, Timeout, tickstart) != HAL_OK)
2538
    {
2539
      /* Process Unlocked */
2540
      __HAL_UNLOCK(hi2c);
2541
      return HAL_ERROR;
2542
    }
2543
 
2544
    /* Send Slave Address */
2545
    /* Set NBYTES to write and reload if hi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */
2546
    if (hi2c->XferCount > MAX_NBYTE_SIZE)
2547
    {
2548
      hi2c->XferSize = MAX_NBYTE_SIZE;
6 mjames 2549
      I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, I2C_RELOAD_MODE,
2550
                         I2C_GENERATE_START_READ);
2 mjames 2551
    }
2552
    else
2553
    {
2554
      hi2c->XferSize = hi2c->XferCount;
6 mjames 2555
      I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, I2C_AUTOEND_MODE,
2556
                         I2C_GENERATE_START_READ);
2 mjames 2557
    }
2558
 
2559
    do
2560
    {
2561
      /* Wait until RXNE flag is set */
2562
      if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_RXNE, RESET, Timeout, tickstart) != HAL_OK)
2563
      {
2564
        return HAL_ERROR;
2565
      }
2566
 
2567
      /* Read data from RXDR */
2568
      *hi2c->pBuffPtr = (uint8_t)hi2c->Instance->RXDR;
2569
 
2570
      /* Increment Buffer pointer */
2571
      hi2c->pBuffPtr++;
2572
 
2573
      hi2c->XferSize--;
2574
      hi2c->XferCount--;
2575
 
2576
      if ((hi2c->XferCount != 0U) && (hi2c->XferSize == 0U))
2577
      {
2578
        /* Wait until TCR flag is set */
2579
        if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_TCR, RESET, Timeout, tickstart) != HAL_OK)
2580
        {
2581
          return HAL_ERROR;
2582
        }
2583
 
2584
        if (hi2c->XferCount > MAX_NBYTE_SIZE)
2585
        {
2586
          hi2c->XferSize = MAX_NBYTE_SIZE;
6 mjames 2587
          I2C_TransferConfig(hi2c, DevAddress, (uint8_t) hi2c->XferSize, I2C_RELOAD_MODE,
2588
                             I2C_NO_STARTSTOP);
2 mjames 2589
        }
2590
        else
2591
        {
2592
          hi2c->XferSize = hi2c->XferCount;
6 mjames 2593
          I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, I2C_AUTOEND_MODE,
2594
                             I2C_NO_STARTSTOP);
2 mjames 2595
        }
2596
      }
6 mjames 2597
    } while (hi2c->XferCount > 0U);
2 mjames 2598
 
2599
    /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */
2600
    /* Wait until STOPF flag is reset */
2601
    if (I2C_WaitOnSTOPFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK)
2602
    {
2603
      return HAL_ERROR;
2604
    }
2605
 
2606
    /* Clear STOP Flag */
2607
    __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF);
2608
 
2609
    /* Clear Configuration Register 2 */
2610
    I2C_RESET_CR2(hi2c);
2611
 
2612
    hi2c->State = HAL_I2C_STATE_READY;
2613
    hi2c->Mode  = HAL_I2C_MODE_NONE;
2614
 
2615
    /* Process Unlocked */
2616
    __HAL_UNLOCK(hi2c);
2617
 
2618
    return HAL_OK;
2619
  }
2620
  else
2621
  {
2622
    return HAL_BUSY;
2623
  }
2624
}
2625
/**
2626
  * @brief  Write an amount of data in non-blocking mode with Interrupt to a specific memory address
2627
  * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
2628
  *                the configuration information for the specified I2C.
2629
  * @param  DevAddress Target device address: The device 7 bits address value
2630
  *         in datasheet must be shifted to the left before calling the interface
2631
  * @param  MemAddress Internal memory address
2632
  * @param  MemAddSize Size of internal memory address
2633
  * @param  pData Pointer to data buffer
2634
  * @param  Size Amount of data to be sent
2635
  * @retval HAL status
2636
  */
6 mjames 2637
HAL_StatusTypeDef HAL_I2C_Mem_Write_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress,
2638
                                       uint16_t MemAddSize, uint8_t *pData, uint16_t Size)
2 mjames 2639
{
2640
  uint32_t tickstart;
2641
  uint32_t xfermode;
2642
 
2643
  /* Check the parameters */
2644
  assert_param(IS_I2C_MEMADD_SIZE(MemAddSize));
2645
 
2646
  if (hi2c->State == HAL_I2C_STATE_READY)
2647
  {
2648
    if ((pData == NULL) || (Size == 0U))
2649
    {
2650
      hi2c->ErrorCode = HAL_I2C_ERROR_INVALID_PARAM;
2651
      return  HAL_ERROR;
2652
    }
2653
 
2654
    if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) == SET)
2655
    {
2656
      return HAL_BUSY;
2657
    }
2658
 
2659
    /* Process Locked */
2660
    __HAL_LOCK(hi2c);
2661
 
2662
    /* Init tickstart for timeout management*/
2663
    tickstart = HAL_GetTick();
2664
 
2665
    hi2c->State       = HAL_I2C_STATE_BUSY_TX;
2666
    hi2c->Mode        = HAL_I2C_MODE_MEM;
2667
    hi2c->ErrorCode   = HAL_I2C_ERROR_NONE;
2668
 
2669
    /* Prepare transfer parameters */
2670
    hi2c->pBuffPtr    = pData;
2671
    hi2c->XferCount   = Size;
2672
    hi2c->XferOptions = I2C_NO_OPTION_FRAME;
2673
    hi2c->XferISR     = I2C_Master_ISR_IT;
2674
 
2675
    if (hi2c->XferCount > MAX_NBYTE_SIZE)
2676
    {
2677
      hi2c->XferSize = MAX_NBYTE_SIZE;
2678
      xfermode = I2C_RELOAD_MODE;
2679
    }
2680
    else
2681
    {
2682
      hi2c->XferSize = hi2c->XferCount;
2683
      xfermode = I2C_AUTOEND_MODE;
2684
    }
2685
 
2686
    /* Send Slave Address and Memory Address */
6 mjames 2687
    if (I2C_RequestMemoryWrite(hi2c, DevAddress, MemAddress, MemAddSize, I2C_TIMEOUT_FLAG, tickstart)
2688
        != HAL_OK)
2 mjames 2689
    {
2690
      /* Process Unlocked */
2691
      __HAL_UNLOCK(hi2c);
2692
      return HAL_ERROR;
2693
    }
2694
 
2695
    /* Set NBYTES to write and reload if hi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */
2696
    I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, xfermode, I2C_NO_STARTSTOP);
2697
 
2698
    /* Process Unlocked */
2699
    __HAL_UNLOCK(hi2c);
2700
 
2701
    /* Note : The I2C interrupts must be enabled after unlocking current process
2702
              to avoid the risk of I2C interrupt handle execution before current
2703
              process unlock */
2704
 
2705
    /* Enable ERR, TC, STOP, NACK, TXI interrupt */
2706
    /* possible to enable all of these */
6 mjames 2707
    /* I2C_IT_ERRI | I2C_IT_TCI | I2C_IT_STOPI | I2C_IT_NACKI |
2708
      I2C_IT_ADDRI | I2C_IT_RXI | I2C_IT_TXI */
2 mjames 2709
    I2C_Enable_IRQ(hi2c, I2C_XFER_TX_IT);
2710
 
2711
    return HAL_OK;
2712
  }
2713
  else
2714
  {
2715
    return HAL_BUSY;
2716
  }
2717
}
2718
 
2719
/**
2720
  * @brief  Read an amount of data in non-blocking mode with Interrupt from a specific memory address
2721
  * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
2722
  *                the configuration information for the specified I2C.
2723
  * @param  DevAddress Target device address: The device 7 bits address value
2724
  *         in datasheet must be shifted to the left before calling the interface
2725
  * @param  MemAddress Internal memory address
2726
  * @param  MemAddSize Size of internal memory address
2727
  * @param  pData Pointer to data buffer
2728
  * @param  Size Amount of data to be sent
2729
  * @retval HAL status
2730
  */
6 mjames 2731
HAL_StatusTypeDef HAL_I2C_Mem_Read_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress,
2732
                                      uint16_t MemAddSize, uint8_t *pData, uint16_t Size)
2 mjames 2733
{
2734
  uint32_t tickstart;
2735
  uint32_t xfermode;
2736
 
2737
  /* Check the parameters */
2738
  assert_param(IS_I2C_MEMADD_SIZE(MemAddSize));
2739
 
2740
  if (hi2c->State == HAL_I2C_STATE_READY)
2741
  {
2742
    if ((pData == NULL) || (Size == 0U))
2743
    {
2744
      hi2c->ErrorCode = HAL_I2C_ERROR_INVALID_PARAM;
2745
      return  HAL_ERROR;
2746
    }
2747
 
2748
    if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) == SET)
2749
    {
2750
      return HAL_BUSY;
2751
    }
2752
 
2753
    /* Process Locked */
2754
    __HAL_LOCK(hi2c);
2755
 
2756
    /* Init tickstart for timeout management*/
2757
    tickstart = HAL_GetTick();
2758
 
2759
    hi2c->State       = HAL_I2C_STATE_BUSY_RX;
2760
    hi2c->Mode        = HAL_I2C_MODE_MEM;
2761
    hi2c->ErrorCode   = HAL_I2C_ERROR_NONE;
2762
 
2763
    /* Prepare transfer parameters */
2764
    hi2c->pBuffPtr    = pData;
2765
    hi2c->XferCount   = Size;
2766
    hi2c->XferOptions = I2C_NO_OPTION_FRAME;
2767
    hi2c->XferISR     = I2C_Master_ISR_IT;
2768
 
2769
    if (hi2c->XferCount > MAX_NBYTE_SIZE)
2770
    {
2771
      hi2c->XferSize = MAX_NBYTE_SIZE;
2772
      xfermode = I2C_RELOAD_MODE;
2773
    }
2774
    else
2775
    {
2776
      hi2c->XferSize = hi2c->XferCount;
2777
      xfermode = I2C_AUTOEND_MODE;
2778
    }
2779
 
2780
    /* Send Slave Address and Memory Address */
2781
    if (I2C_RequestMemoryRead(hi2c, DevAddress, MemAddress, MemAddSize, I2C_TIMEOUT_FLAG, tickstart) != HAL_OK)
2782
    {
2783
      /* Process Unlocked */
2784
      __HAL_UNLOCK(hi2c);
2785
      return HAL_ERROR;
2786
    }
2787
 
2788
    /* Set NBYTES to write and reload if hi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */
2789
    I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, xfermode, I2C_GENERATE_START_READ);
2790
 
2791
    /* Process Unlocked */
2792
    __HAL_UNLOCK(hi2c);
2793
 
2794
    /* Note : The I2C interrupts must be enabled after unlocking current process
2795
              to avoid the risk of I2C interrupt handle execution before current
2796
              process unlock */
2797
 
2798
    /* Enable ERR, TC, STOP, NACK, RXI interrupt */
2799
    /* possible to enable all of these */
6 mjames 2800
    /* I2C_IT_ERRI | I2C_IT_TCI | I2C_IT_STOPI | I2C_IT_NACKI |
2801
      I2C_IT_ADDRI | I2C_IT_RXI | I2C_IT_TXI */
2 mjames 2802
    I2C_Enable_IRQ(hi2c, I2C_XFER_RX_IT);
2803
 
2804
    return HAL_OK;
2805
  }
2806
  else
2807
  {
2808
    return HAL_BUSY;
2809
  }
2810
}
2811
/**
2812
  * @brief  Write an amount of data in non-blocking mode with DMA to a specific memory address
2813
  * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
2814
  *                the configuration information for the specified I2C.
2815
  * @param  DevAddress Target device address: The device 7 bits address value
2816
  *         in datasheet must be shifted to the left before calling the interface
2817
  * @param  MemAddress Internal memory address
2818
  * @param  MemAddSize Size of internal memory address
2819
  * @param  pData Pointer to data buffer
2820
  * @param  Size Amount of data to be sent
2821
  * @retval HAL status
2822
  */
6 mjames 2823
HAL_StatusTypeDef HAL_I2C_Mem_Write_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress,
2824
                                        uint16_t MemAddSize, uint8_t *pData, uint16_t Size)
2 mjames 2825
{
2826
  uint32_t tickstart;
2827
  uint32_t xfermode;
2828
  HAL_StatusTypeDef dmaxferstatus;
2829
 
2830
  /* Check the parameters */
2831
  assert_param(IS_I2C_MEMADD_SIZE(MemAddSize));
2832
 
2833
  if (hi2c->State == HAL_I2C_STATE_READY)
2834
  {
2835
    if ((pData == NULL) || (Size == 0U))
2836
    {
2837
      hi2c->ErrorCode = HAL_I2C_ERROR_INVALID_PARAM;
2838
      return  HAL_ERROR;
2839
    }
2840
 
2841
    if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) == SET)
2842
    {
2843
      return HAL_BUSY;
2844
    }
2845
 
2846
    /* Process Locked */
2847
    __HAL_LOCK(hi2c);
2848
 
2849
    /* Init tickstart for timeout management*/
2850
    tickstart = HAL_GetTick();
2851
 
2852
    hi2c->State       = HAL_I2C_STATE_BUSY_TX;
2853
    hi2c->Mode        = HAL_I2C_MODE_MEM;
2854
    hi2c->ErrorCode   = HAL_I2C_ERROR_NONE;
2855
 
2856
    /* Prepare transfer parameters */
2857
    hi2c->pBuffPtr    = pData;
2858
    hi2c->XferCount   = Size;
2859
    hi2c->XferOptions = I2C_NO_OPTION_FRAME;
2860
    hi2c->XferISR     = I2C_Master_ISR_DMA;
2861
 
2862
    if (hi2c->XferCount > MAX_NBYTE_SIZE)
2863
    {
2864
      hi2c->XferSize = MAX_NBYTE_SIZE;
2865
      xfermode = I2C_RELOAD_MODE;
2866
    }
2867
    else
2868
    {
2869
      hi2c->XferSize = hi2c->XferCount;
2870
      xfermode = I2C_AUTOEND_MODE;
2871
    }
2872
 
2873
    /* Send Slave Address and Memory Address */
6 mjames 2874
    if (I2C_RequestMemoryWrite(hi2c, DevAddress, MemAddress, MemAddSize, I2C_TIMEOUT_FLAG, tickstart)
2875
        != HAL_OK)
2 mjames 2876
    {
2877
      /* Process Unlocked */
2878
      __HAL_UNLOCK(hi2c);
2879
      return HAL_ERROR;
2880
    }
2881
 
2882
 
2883
    if (hi2c->hdmatx != NULL)
2884
    {
2885
      /* Set the I2C DMA transfer complete callback */
2886
      hi2c->hdmatx->XferCpltCallback = I2C_DMAMasterTransmitCplt;
2887
 
2888
      /* Set the DMA error callback */
2889
      hi2c->hdmatx->XferErrorCallback = I2C_DMAError;
2890
 
2891
      /* Set the unused DMA callbacks to NULL */
2892
      hi2c->hdmatx->XferHalfCpltCallback = NULL;
2893
      hi2c->hdmatx->XferAbortCallback = NULL;
2894
 
2895
      /* Enable the DMA channel */
6 mjames 2896
      dmaxferstatus = HAL_DMA_Start_IT(hi2c->hdmatx, (uint32_t)pData, (uint32_t)&hi2c->Instance->TXDR,
2897
                                       hi2c->XferSize);
2 mjames 2898
    }
2899
    else
2900
    {
2901
      /* Update I2C state */
2902
      hi2c->State     = HAL_I2C_STATE_READY;
2903
      hi2c->Mode      = HAL_I2C_MODE_NONE;
2904
 
2905
      /* Update I2C error code */
2906
      hi2c->ErrorCode |= HAL_I2C_ERROR_DMA_PARAM;
2907
 
2908
      /* Process Unlocked */
2909
      __HAL_UNLOCK(hi2c);
2910
 
2911
      return HAL_ERROR;
2912
    }
2913
 
2914
    if (dmaxferstatus == HAL_OK)
2915
    {
2916
      /* Send Slave Address */
2917
      /* Set NBYTES to write and reload if hi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */
2918
      I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, xfermode, I2C_NO_STARTSTOP);
2919
 
2920
      /* Update XferCount value */
2921
      hi2c->XferCount -= hi2c->XferSize;
2922
 
2923
      /* Process Unlocked */
2924
      __HAL_UNLOCK(hi2c);
2925
 
2926
      /* Note : The I2C interrupts must be enabled after unlocking current process
2927
                to avoid the risk of I2C interrupt handle execution before current
2928
                process unlock */
2929
      /* Enable ERR and NACK interrupts */
2930
      I2C_Enable_IRQ(hi2c, I2C_XFER_ERROR_IT);
2931
 
2932
      /* Enable DMA Request */
2933
      hi2c->Instance->CR1 |= I2C_CR1_TXDMAEN;
2934
    }
2935
    else
2936
    {
2937
      /* Update I2C state */
2938
      hi2c->State     = HAL_I2C_STATE_READY;
2939
      hi2c->Mode      = HAL_I2C_MODE_NONE;
2940
 
2941
      /* Update I2C error code */
2942
      hi2c->ErrorCode |= HAL_I2C_ERROR_DMA;
2943
 
2944
      /* Process Unlocked */
2945
      __HAL_UNLOCK(hi2c);
2946
 
2947
      return HAL_ERROR;
2948
    }
2949
 
2950
    return HAL_OK;
2951
  }
2952
  else
2953
  {
2954
    return HAL_BUSY;
2955
  }
2956
}
2957
 
2958
/**
2959
  * @brief  Reads an amount of data in non-blocking mode with DMA from a specific memory address.
2960
  * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
2961
  *                the configuration information for the specified I2C.
2962
  * @param  DevAddress Target device address: The device 7 bits address value
2963
  *         in datasheet must be shifted to the left before calling the interface
2964
  * @param  MemAddress Internal memory address
2965
  * @param  MemAddSize Size of internal memory address
2966
  * @param  pData Pointer to data buffer
2967
  * @param  Size Amount of data to be read
2968
  * @retval HAL status
2969
  */
6 mjames 2970
HAL_StatusTypeDef HAL_I2C_Mem_Read_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress,
2971
                                       uint16_t MemAddSize, uint8_t *pData, uint16_t Size)
2 mjames 2972
{
2973
  uint32_t tickstart;
2974
  uint32_t xfermode;
2975
  HAL_StatusTypeDef dmaxferstatus;
2976
 
2977
  /* Check the parameters */
2978
  assert_param(IS_I2C_MEMADD_SIZE(MemAddSize));
2979
 
2980
  if (hi2c->State == HAL_I2C_STATE_READY)
2981
  {
2982
    if ((pData == NULL) || (Size == 0U))
2983
    {
2984
      hi2c->ErrorCode = HAL_I2C_ERROR_INVALID_PARAM;
2985
      return  HAL_ERROR;
2986
    }
2987
 
2988
    if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) == SET)
2989
    {
2990
      return HAL_BUSY;
2991
    }
2992
 
2993
    /* Process Locked */
2994
    __HAL_LOCK(hi2c);
2995
 
2996
    /* Init tickstart for timeout management*/
2997
    tickstart = HAL_GetTick();
2998
 
2999
    hi2c->State       = HAL_I2C_STATE_BUSY_RX;
3000
    hi2c->Mode        = HAL_I2C_MODE_MEM;
3001
    hi2c->ErrorCode   = HAL_I2C_ERROR_NONE;
3002
 
3003
    /* Prepare transfer parameters */
3004
    hi2c->pBuffPtr    = pData;
3005
    hi2c->XferCount   = Size;
3006
    hi2c->XferOptions = I2C_NO_OPTION_FRAME;
3007
    hi2c->XferISR     = I2C_Master_ISR_DMA;
3008
 
3009
    if (hi2c->XferCount > MAX_NBYTE_SIZE)
3010
    {
3011
      hi2c->XferSize = MAX_NBYTE_SIZE;
3012
      xfermode = I2C_RELOAD_MODE;
3013
    }
3014
    else
3015
    {
3016
      hi2c->XferSize = hi2c->XferCount;
3017
      xfermode = I2C_AUTOEND_MODE;
3018
    }
3019
 
3020
    /* Send Slave Address and Memory Address */
3021
    if (I2C_RequestMemoryRead(hi2c, DevAddress, MemAddress, MemAddSize, I2C_TIMEOUT_FLAG, tickstart) != HAL_OK)
3022
    {
3023
      /* Process Unlocked */
3024
      __HAL_UNLOCK(hi2c);
3025
      return HAL_ERROR;
3026
    }
3027
 
3028
    if (hi2c->hdmarx != NULL)
3029
    {
3030
      /* Set the I2C DMA transfer complete callback */
3031
      hi2c->hdmarx->XferCpltCallback = I2C_DMAMasterReceiveCplt;
3032
 
3033
      /* Set the DMA error callback */
3034
      hi2c->hdmarx->XferErrorCallback = I2C_DMAError;
3035
 
3036
      /* Set the unused DMA callbacks to NULL */
3037
      hi2c->hdmarx->XferHalfCpltCallback = NULL;
3038
      hi2c->hdmarx->XferAbortCallback = NULL;
3039
 
3040
      /* Enable the DMA channel */
6 mjames 3041
      dmaxferstatus = HAL_DMA_Start_IT(hi2c->hdmarx, (uint32_t)&hi2c->Instance->RXDR, (uint32_t)pData,
3042
                                       hi2c->XferSize);
2 mjames 3043
    }
3044
    else
3045
    {
3046
      /* Update I2C state */
3047
      hi2c->State     = HAL_I2C_STATE_READY;
3048
      hi2c->Mode      = HAL_I2C_MODE_NONE;
3049
 
3050
      /* Update I2C error code */
3051
      hi2c->ErrorCode |= HAL_I2C_ERROR_DMA_PARAM;
3052
 
3053
      /* Process Unlocked */
3054
      __HAL_UNLOCK(hi2c);
3055
 
3056
      return HAL_ERROR;
3057
    }
3058
 
3059
    if (dmaxferstatus == HAL_OK)
3060
    {
3061
      /* Set NBYTES to write and reload if hi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */
3062
      I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, xfermode, I2C_GENERATE_START_READ);
3063
 
3064
      /* Update XferCount value */
3065
      hi2c->XferCount -= hi2c->XferSize;
3066
 
3067
      /* Process Unlocked */
3068
      __HAL_UNLOCK(hi2c);
3069
 
3070
      /* Note : The I2C interrupts must be enabled after unlocking current process
3071
                to avoid the risk of I2C interrupt handle execution before current
3072
                process unlock */
3073
      /* Enable ERR and NACK interrupts */
3074
      I2C_Enable_IRQ(hi2c, I2C_XFER_ERROR_IT);
3075
 
3076
      /* Enable DMA Request */
3077
      hi2c->Instance->CR1 |= I2C_CR1_RXDMAEN;
3078
    }
3079
    else
3080
    {
3081
      /* Update I2C state */
3082
      hi2c->State     = HAL_I2C_STATE_READY;
3083
      hi2c->Mode      = HAL_I2C_MODE_NONE;
3084
 
3085
      /* Update I2C error code */
3086
      hi2c->ErrorCode |= HAL_I2C_ERROR_DMA;
3087
 
3088
      /* Process Unlocked */
3089
      __HAL_UNLOCK(hi2c);
3090
 
3091
      return HAL_ERROR;
3092
    }
3093
 
3094
    return HAL_OK;
3095
  }
3096
  else
3097
  {
3098
    return HAL_BUSY;
3099
  }
3100
}
3101
 
3102
/**
3103
  * @brief  Checks if target device is ready for communication.
3104
  * @note   This function is used with Memory devices
3105
  * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
3106
  *                the configuration information for the specified I2C.
3107
  * @param  DevAddress Target device address: The device 7 bits address value
3108
  *         in datasheet must be shifted to the left before calling the interface
3109
  * @param  Trials Number of trials
3110
  * @param  Timeout Timeout duration
3111
  * @retval HAL status
3112
  */
6 mjames 3113
HAL_StatusTypeDef HAL_I2C_IsDeviceReady(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint32_t Trials,
3114
                                        uint32_t Timeout)
2 mjames 3115
{
3116
  uint32_t tickstart;
3117
 
3118
  __IO uint32_t I2C_Trials = 0UL;
3119
 
3120
  FlagStatus tmp1;
3121
  FlagStatus tmp2;
3122
 
3123
  if (hi2c->State == HAL_I2C_STATE_READY)
3124
  {
3125
    if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) == SET)
3126
    {
3127
      return HAL_BUSY;
3128
    }
3129
 
3130
    /* Process Locked */
3131
    __HAL_LOCK(hi2c);
3132
 
3133
    hi2c->State = HAL_I2C_STATE_BUSY;
3134
    hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
3135
 
3136
    do
3137
    {
3138
      /* Generate Start */
3139
      hi2c->Instance->CR2 = I2C_GENERATE_START(hi2c->Init.AddressingMode, DevAddress);
3140
 
3141
      /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */
3142
      /* Wait until STOPF flag is set or a NACK flag is set*/
3143
      tickstart = HAL_GetTick();
3144
 
3145
      tmp1 = __HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_STOPF);
3146
      tmp2 = __HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_AF);
3147
 
3148
      while ((tmp1 == RESET) && (tmp2 == RESET))
3149
      {
3150
        if (Timeout != HAL_MAX_DELAY)
3151
        {
3152
          if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
3153
          {
3154
            /* Update I2C state */
3155
            hi2c->State = HAL_I2C_STATE_READY;
3156
 
3157
            /* Update I2C error code */
3158
            hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT;
3159
 
3160
            /* Process Unlocked */
3161
            __HAL_UNLOCK(hi2c);
3162
 
3163
            return HAL_ERROR;
3164
          }
3165
        }
3166
 
3167
        tmp1 = __HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_STOPF);
3168
        tmp2 = __HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_AF);
3169
      }
3170
 
3171
      /* Check if the NACKF flag has not been set */
3172
      if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_AF) == RESET)
3173
      {
3174
        /* Wait until STOPF flag is reset */
3175
        if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_STOPF, RESET, Timeout, tickstart) != HAL_OK)
3176
        {
3177
          return HAL_ERROR;
3178
        }
3179
 
3180
        /* Clear STOP Flag */
3181
        __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF);
3182
 
3183
        /* Device is ready */
3184
        hi2c->State = HAL_I2C_STATE_READY;
3185
 
3186
        /* Process Unlocked */
3187
        __HAL_UNLOCK(hi2c);
3188
 
3189
        return HAL_OK;
3190
      }
3191
      else
3192
      {
3193
        /* Wait until STOPF flag is reset */
3194
        if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_STOPF, RESET, Timeout, tickstart) != HAL_OK)
3195
        {
3196
          return HAL_ERROR;
3197
        }
3198
 
3199
        /* Clear NACK Flag */
3200
        __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF);
3201
 
3202
        /* Clear STOP Flag, auto generated with autoend*/
3203
        __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF);
3204
      }
3205
 
3206
      /* Check if the maximum allowed number of trials has been reached */
3207
      if (I2C_Trials == Trials)
3208
      {
3209
        /* Generate Stop */
3210
        hi2c->Instance->CR2 |= I2C_CR2_STOP;
3211
 
3212
        /* Wait until STOPF flag is reset */
3213
        if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_STOPF, RESET, Timeout, tickstart) != HAL_OK)
3214
        {
3215
          return HAL_ERROR;
3216
        }
3217
 
3218
        /* Clear STOP Flag */
3219
        __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF);
3220
      }
3221
 
3222
      /* Increment Trials */
3223
      I2C_Trials++;
6 mjames 3224
    } while (I2C_Trials < Trials);
2 mjames 3225
 
3226
    /* Update I2C state */
3227
    hi2c->State = HAL_I2C_STATE_READY;
3228
 
3229
    /* Update I2C error code */
3230
    hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT;
3231
 
3232
    /* Process Unlocked */
3233
    __HAL_UNLOCK(hi2c);
3234
 
3235
    return HAL_ERROR;
3236
  }
3237
  else
3238
  {
3239
    return HAL_BUSY;
3240
  }
3241
}
3242
 
3243
/**
3244
  * @brief  Sequential transmit in master I2C mode an amount of data in non-blocking mode with Interrupt.
3245
  * @note   This interface allow to manage repeated start condition when a direction change during transfer
3246
  * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
3247
  *                the configuration information for the specified I2C.
3248
  * @param  DevAddress Target device address: The device 7 bits address value
3249
  *         in datasheet must be shifted to the left before calling the interface
3250
  * @param  pData Pointer to data buffer
3251
  * @param  Size Amount of data to be sent
3252
  * @param  XferOptions Options of Transfer, value of @ref I2C_XFEROPTIONS
3253
  * @retval HAL status
3254
  */
6 mjames 3255
HAL_StatusTypeDef HAL_I2C_Master_Seq_Transmit_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData,
3256
                                                 uint16_t Size, uint32_t XferOptions)
2 mjames 3257
{
3258
  uint32_t xfermode;
3259
  uint32_t xferrequest = I2C_GENERATE_START_WRITE;
3260
 
3261
  /* Check the parameters */
3262
  assert_param(IS_I2C_TRANSFER_OPTIONS_REQUEST(XferOptions));
3263
 
3264
  if (hi2c->State == HAL_I2C_STATE_READY)
3265
  {
3266
    /* Process Locked */
3267
    __HAL_LOCK(hi2c);
3268
 
3269
    hi2c->State     = HAL_I2C_STATE_BUSY_TX;
3270
    hi2c->Mode      = HAL_I2C_MODE_MASTER;
3271
    hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
3272
 
3273
    /* Prepare transfer parameters */
3274
    hi2c->pBuffPtr    = pData;
3275
    hi2c->XferCount   = Size;
3276
    hi2c->XferOptions = XferOptions;
3277
    hi2c->XferISR     = I2C_Master_ISR_IT;
3278
 
3279
    /* If hi2c->XferCount > MAX_NBYTE_SIZE, use reload mode */
3280
    if (hi2c->XferCount > MAX_NBYTE_SIZE)
3281
    {
3282
      hi2c->XferSize = MAX_NBYTE_SIZE;
3283
      xfermode = I2C_RELOAD_MODE;
3284
    }
3285
    else
3286
    {
3287
      hi2c->XferSize = hi2c->XferCount;
3288
      xfermode = hi2c->XferOptions;
3289
    }
3290
 
6 mjames 3291
    /* If transfer direction not change and there is no request to start another frame,
3292
       do not generate Restart Condition */
2 mjames 3293
    /* Mean Previous state is same as current state */
6 mjames 3294
    if ((hi2c->PreviousState == I2C_STATE_MASTER_BUSY_TX) && \
3295
        (IS_I2C_TRANSFER_OTHER_OPTIONS_REQUEST(XferOptions) == 0))
2 mjames 3296
    {
3297
      xferrequest = I2C_NO_STARTSTOP;
3298
    }
3299
    else
3300
    {
3301
      /* Convert OTHER_xxx XferOptions if any */
3302
      I2C_ConvertOtherXferOptions(hi2c);
3303
 
3304
      /* Update xfermode accordingly if no reload is necessary */
6 mjames 3305
      if (hi2c->XferCount <= MAX_NBYTE_SIZE)
2 mjames 3306
      {
3307
        xfermode = hi2c->XferOptions;
3308
      }
3309
    }
3310
 
3311
    /* Send Slave Address and set NBYTES to write */
3312
    I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, xfermode, xferrequest);
3313
 
3314
    /* Process Unlocked */
3315
    __HAL_UNLOCK(hi2c);
3316
 
3317
    /* Note : The I2C interrupts must be enabled after unlocking current process
3318
              to avoid the risk of I2C interrupt handle execution before current
3319
              process unlock */
3320
    I2C_Enable_IRQ(hi2c, I2C_XFER_TX_IT);
3321
 
3322
    return HAL_OK;
3323
  }
3324
  else
3325
  {
3326
    return HAL_BUSY;
3327
  }
3328
}
3329
 
3330
/**
3331
  * @brief  Sequential transmit in master I2C mode an amount of data in non-blocking mode with DMA.
3332
  * @note   This interface allow to manage repeated start condition when a direction change during transfer
3333
  * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
3334
  *                the configuration information for the specified I2C.
3335
  * @param  DevAddress Target device address: The device 7 bits address value
3336
  *         in datasheet must be shifted to the left before calling the interface
3337
  * @param  pData Pointer to data buffer
3338
  * @param  Size Amount of data to be sent
3339
  * @param  XferOptions Options of Transfer, value of @ref I2C_XFEROPTIONS
3340
  * @retval HAL status
3341
  */
6 mjames 3342
HAL_StatusTypeDef HAL_I2C_Master_Seq_Transmit_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData,
3343
                                                  uint16_t Size, uint32_t XferOptions)
2 mjames 3344
{
3345
  uint32_t xfermode;
3346
  uint32_t xferrequest = I2C_GENERATE_START_WRITE;
3347
  HAL_StatusTypeDef dmaxferstatus;
3348
 
3349
  /* Check the parameters */
3350
  assert_param(IS_I2C_TRANSFER_OPTIONS_REQUEST(XferOptions));
3351
 
3352
  if (hi2c->State == HAL_I2C_STATE_READY)
3353
  {
3354
    /* Process Locked */
3355
    __HAL_LOCK(hi2c);
3356
 
3357
    hi2c->State     = HAL_I2C_STATE_BUSY_TX;
3358
    hi2c->Mode      = HAL_I2C_MODE_MASTER;
3359
    hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
3360
 
3361
    /* Prepare transfer parameters */
3362
    hi2c->pBuffPtr    = pData;
3363
    hi2c->XferCount   = Size;
3364
    hi2c->XferOptions = XferOptions;
3365
    hi2c->XferISR     = I2C_Master_ISR_DMA;
3366
 
3367
    /* If hi2c->XferCount > MAX_NBYTE_SIZE, use reload mode */
3368
    if (hi2c->XferCount > MAX_NBYTE_SIZE)
3369
    {
3370
      hi2c->XferSize = MAX_NBYTE_SIZE;
3371
      xfermode = I2C_RELOAD_MODE;
3372
    }
3373
    else
3374
    {
3375
      hi2c->XferSize = hi2c->XferCount;
3376
      xfermode = hi2c->XferOptions;
3377
    }
3378
 
6 mjames 3379
    /* If transfer direction not change and there is no request to start another frame,
3380
       do not generate Restart Condition */
2 mjames 3381
    /* Mean Previous state is same as current state */
6 mjames 3382
    if ((hi2c->PreviousState == I2C_STATE_MASTER_BUSY_TX) && \
3383
        (IS_I2C_TRANSFER_OTHER_OPTIONS_REQUEST(XferOptions) == 0))
2 mjames 3384
    {
3385
      xferrequest = I2C_NO_STARTSTOP;
3386
    }
3387
    else
3388
    {
3389
      /* Convert OTHER_xxx XferOptions if any */
3390
      I2C_ConvertOtherXferOptions(hi2c);
3391
 
3392
      /* Update xfermode accordingly if no reload is necessary */
6 mjames 3393
      if (hi2c->XferCount <= MAX_NBYTE_SIZE)
2 mjames 3394
      {
3395
        xfermode = hi2c->XferOptions;
3396
      }
3397
    }
3398
 
3399
    if (hi2c->XferSize > 0U)
3400
    {
3401
      if (hi2c->hdmatx != NULL)
3402
      {
3403
        /* Set the I2C DMA transfer complete callback */
3404
        hi2c->hdmatx->XferCpltCallback = I2C_DMAMasterTransmitCplt;
3405
 
3406
        /* Set the DMA error callback */
3407
        hi2c->hdmatx->XferErrorCallback = I2C_DMAError;
3408
 
3409
        /* Set the unused DMA callbacks to NULL */
3410
        hi2c->hdmatx->XferHalfCpltCallback = NULL;
3411
        hi2c->hdmatx->XferAbortCallback = NULL;
3412
 
3413
        /* Enable the DMA channel */
6 mjames 3414
        dmaxferstatus = HAL_DMA_Start_IT(hi2c->hdmatx, (uint32_t)pData, (uint32_t)&hi2c->Instance->TXDR,
3415
                                         hi2c->XferSize);
2 mjames 3416
      }
3417
      else
3418
      {
3419
        /* Update I2C state */
3420
        hi2c->State     = HAL_I2C_STATE_READY;
3421
        hi2c->Mode      = HAL_I2C_MODE_NONE;
3422
 
3423
        /* Update I2C error code */
3424
        hi2c->ErrorCode |= HAL_I2C_ERROR_DMA_PARAM;
3425
 
3426
        /* Process Unlocked */
3427
        __HAL_UNLOCK(hi2c);
3428
 
3429
        return HAL_ERROR;
3430
      }
3431
 
3432
      if (dmaxferstatus == HAL_OK)
3433
      {
3434
        /* Send Slave Address and set NBYTES to write */
3435
        I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, xfermode, xferrequest);
3436
 
3437
        /* Update XferCount value */
3438
        hi2c->XferCount -= hi2c->XferSize;
3439
 
3440
        /* Process Unlocked */
3441
        __HAL_UNLOCK(hi2c);
3442
 
3443
        /* Note : The I2C interrupts must be enabled after unlocking current process
3444
                  to avoid the risk of I2C interrupt handle execution before current
3445
                  process unlock */
3446
        /* Enable ERR and NACK interrupts */
3447
        I2C_Enable_IRQ(hi2c, I2C_XFER_ERROR_IT);
3448
 
3449
        /* Enable DMA Request */
3450
        hi2c->Instance->CR1 |= I2C_CR1_TXDMAEN;
3451
      }
3452
      else
3453
      {
3454
        /* Update I2C state */
3455
        hi2c->State     = HAL_I2C_STATE_READY;
3456
        hi2c->Mode      = HAL_I2C_MODE_NONE;
3457
 
3458
        /* Update I2C error code */
3459
        hi2c->ErrorCode |= HAL_I2C_ERROR_DMA;
3460
 
3461
        /* Process Unlocked */
3462
        __HAL_UNLOCK(hi2c);
3463
 
3464
        return HAL_ERROR;
3465
      }
3466
    }
3467
    else
3468
    {
3469
      /* Update Transfer ISR function pointer */
3470
      hi2c->XferISR = I2C_Master_ISR_IT;
3471
 
3472
      /* Send Slave Address */
3473
      /* Set NBYTES to write and generate START condition */
6 mjames 3474
      I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, I2C_AUTOEND_MODE,
3475
                         I2C_GENERATE_START_WRITE);
2 mjames 3476
 
3477
      /* Process Unlocked */
3478
      __HAL_UNLOCK(hi2c);
3479
 
3480
      /* Note : The I2C interrupts must be enabled after unlocking current process
3481
                to avoid the risk of I2C interrupt handle execution before current
3482
                process unlock */
3483
      /* Enable ERR, TC, STOP, NACK, TXI interrupt */
3484
      /* possible to enable all of these */
6 mjames 3485
      /* I2C_IT_ERRI | I2C_IT_TCI | I2C_IT_STOPI | I2C_IT_NACKI |
3486
        I2C_IT_ADDRI | I2C_IT_RXI | I2C_IT_TXI */
2 mjames 3487
      I2C_Enable_IRQ(hi2c, I2C_XFER_TX_IT);
3488
    }
3489
 
3490
    return HAL_OK;
3491
  }
3492
  else
3493
  {
3494
    return HAL_BUSY;
3495
  }
3496
}
3497
 
3498
/**
3499
  * @brief  Sequential receive in master I2C mode an amount of data in non-blocking mode with Interrupt
3500
  * @note   This interface allow to manage repeated start condition when a direction change during transfer
3501
  * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
3502
  *                the configuration information for the specified I2C.
3503
  * @param  DevAddress Target device address: The device 7 bits address value
3504
  *         in datasheet must be shifted to the left before calling the interface
3505
  * @param  pData Pointer to data buffer
3506
  * @param  Size Amount of data to be sent
3507
  * @param  XferOptions Options of Transfer, value of @ref I2C_XFEROPTIONS
3508
  * @retval HAL status
3509
  */
6 mjames 3510
HAL_StatusTypeDef HAL_I2C_Master_Seq_Receive_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData,
3511
                                                uint16_t Size, uint32_t XferOptions)
2 mjames 3512
{
3513
  uint32_t xfermode;
3514
  uint32_t xferrequest = I2C_GENERATE_START_READ;
3515
 
3516
  /* Check the parameters */
3517
  assert_param(IS_I2C_TRANSFER_OPTIONS_REQUEST(XferOptions));
3518
 
3519
  if (hi2c->State == HAL_I2C_STATE_READY)
3520
  {
3521
    /* Process Locked */
3522
    __HAL_LOCK(hi2c);
3523
 
3524
    hi2c->State     = HAL_I2C_STATE_BUSY_RX;
3525
    hi2c->Mode      = HAL_I2C_MODE_MASTER;
3526
    hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
3527
 
3528
    /* Prepare transfer parameters */
3529
    hi2c->pBuffPtr    = pData;
3530
    hi2c->XferCount   = Size;
3531
    hi2c->XferOptions = XferOptions;
3532
    hi2c->XferISR     = I2C_Master_ISR_IT;
3533
 
3534
    /* If hi2c->XferCount > MAX_NBYTE_SIZE, use reload mode */
3535
    if (hi2c->XferCount > MAX_NBYTE_SIZE)
3536
    {
3537
      hi2c->XferSize = MAX_NBYTE_SIZE;
3538
      xfermode = I2C_RELOAD_MODE;
3539
    }
3540
    else
3541
    {
3542
      hi2c->XferSize = hi2c->XferCount;
3543
      xfermode = hi2c->XferOptions;
3544
    }
3545
 
6 mjames 3546
    /* If transfer direction not change and there is no request to start another frame,
3547
       do not generate Restart Condition */
2 mjames 3548
    /* Mean Previous state is same as current state */
6 mjames 3549
    if ((hi2c->PreviousState == I2C_STATE_MASTER_BUSY_RX) && \
3550
        (IS_I2C_TRANSFER_OTHER_OPTIONS_REQUEST(XferOptions) == 0))
2 mjames 3551
    {
3552
      xferrequest = I2C_NO_STARTSTOP;
3553
    }
3554
    else
3555
    {
3556
      /* Convert OTHER_xxx XferOptions if any */
3557
      I2C_ConvertOtherXferOptions(hi2c);
3558
 
3559
      /* Update xfermode accordingly if no reload is necessary */
6 mjames 3560
      if (hi2c->XferCount <= MAX_NBYTE_SIZE)
2 mjames 3561
      {
3562
        xfermode = hi2c->XferOptions;
3563
      }
3564
    }
3565
 
3566
    /* Send Slave Address and set NBYTES to read */
3567
    I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, xfermode, xferrequest);
3568
 
3569
    /* Process Unlocked */
3570
    __HAL_UNLOCK(hi2c);
3571
 
3572
    /* Note : The I2C interrupts must be enabled after unlocking current process
3573
              to avoid the risk of I2C interrupt handle execution before current
3574
              process unlock */
3575
    I2C_Enable_IRQ(hi2c, I2C_XFER_RX_IT);
3576
 
3577
    return HAL_OK;
3578
  }
3579
  else
3580
  {
3581
    return HAL_BUSY;
3582
  }
3583
}
3584
 
3585
/**
3586
  * @brief  Sequential receive in master I2C mode an amount of data in non-blocking mode with DMA
3587
  * @note   This interface allow to manage repeated start condition when a direction change during transfer
3588
  * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
3589
  *                the configuration information for the specified I2C.
3590
  * @param  DevAddress Target device address: The device 7 bits address value
3591
  *         in datasheet must be shifted to the left before calling the interface
3592
  * @param  pData Pointer to data buffer
3593
  * @param  Size Amount of data to be sent
3594
  * @param  XferOptions Options of Transfer, value of @ref I2C_XFEROPTIONS
3595
  * @retval HAL status
3596
  */
6 mjames 3597
HAL_StatusTypeDef HAL_I2C_Master_Seq_Receive_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData,
3598
                                                 uint16_t Size, uint32_t XferOptions)
2 mjames 3599
{
3600
  uint32_t xfermode;
3601
  uint32_t xferrequest = I2C_GENERATE_START_READ;
3602
  HAL_StatusTypeDef dmaxferstatus;
3603
 
3604
  /* Check the parameters */
3605
  assert_param(IS_I2C_TRANSFER_OPTIONS_REQUEST(XferOptions));
3606
 
3607
  if (hi2c->State == HAL_I2C_STATE_READY)
3608
  {
3609
    /* Process Locked */
3610
    __HAL_LOCK(hi2c);
3611
 
3612
    hi2c->State     = HAL_I2C_STATE_BUSY_RX;
3613
    hi2c->Mode      = HAL_I2C_MODE_MASTER;
3614
    hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
3615
 
3616
    /* Prepare transfer parameters */
3617
    hi2c->pBuffPtr    = pData;
3618
    hi2c->XferCount   = Size;
3619
    hi2c->XferOptions = XferOptions;
3620
    hi2c->XferISR     = I2C_Master_ISR_DMA;
3621
 
3622
    /* If hi2c->XferCount > MAX_NBYTE_SIZE, use reload mode */
3623
    if (hi2c->XferCount > MAX_NBYTE_SIZE)
3624
    {
3625
      hi2c->XferSize = MAX_NBYTE_SIZE;
3626
      xfermode = I2C_RELOAD_MODE;
3627
    }
3628
    else
3629
    {
3630
      hi2c->XferSize = hi2c->XferCount;
3631
      xfermode = hi2c->XferOptions;
3632
    }
3633
 
6 mjames 3634
    /* If transfer direction not change and there is no request to start another frame,
3635
       do not generate Restart Condition */
2 mjames 3636
    /* Mean Previous state is same as current state */
6 mjames 3637
    if ((hi2c->PreviousState == I2C_STATE_MASTER_BUSY_RX) && \
3638
        (IS_I2C_TRANSFER_OTHER_OPTIONS_REQUEST(XferOptions) == 0))
2 mjames 3639
    {
3640
      xferrequest = I2C_NO_STARTSTOP;
3641
    }
3642
    else
3643
    {
3644
      /* Convert OTHER_xxx XferOptions if any */
3645
      I2C_ConvertOtherXferOptions(hi2c);
3646
 
3647
      /* Update xfermode accordingly if no reload is necessary */
6 mjames 3648
      if (hi2c->XferCount <= MAX_NBYTE_SIZE)
2 mjames 3649
      {
3650
        xfermode = hi2c->XferOptions;
3651
      }
3652
    }
3653
 
3654
    if (hi2c->XferSize > 0U)
3655
    {
3656
      if (hi2c->hdmarx != NULL)
3657
      {
3658
        /* Set the I2C DMA transfer complete callback */
3659
        hi2c->hdmarx->XferCpltCallback = I2C_DMAMasterReceiveCplt;
3660
 
3661
        /* Set the DMA error callback */
3662
        hi2c->hdmarx->XferErrorCallback = I2C_DMAError;
3663
 
3664
        /* Set the unused DMA callbacks to NULL */
3665
        hi2c->hdmarx->XferHalfCpltCallback = NULL;
3666
        hi2c->hdmarx->XferAbortCallback = NULL;
3667
 
3668
        /* Enable the DMA channel */
6 mjames 3669
        dmaxferstatus = HAL_DMA_Start_IT(hi2c->hdmarx, (uint32_t)&hi2c->Instance->RXDR, (uint32_t)pData,
3670
                                         hi2c->XferSize);
2 mjames 3671
      }
3672
      else
3673
      {
3674
        /* Update I2C state */
3675
        hi2c->State     = HAL_I2C_STATE_READY;
3676
        hi2c->Mode      = HAL_I2C_MODE_NONE;
3677
 
3678
        /* Update I2C error code */
3679
        hi2c->ErrorCode |= HAL_I2C_ERROR_DMA_PARAM;
3680
 
3681
        /* Process Unlocked */
3682
        __HAL_UNLOCK(hi2c);
3683
 
3684
        return HAL_ERROR;
3685
      }
3686
 
3687
      if (dmaxferstatus == HAL_OK)
3688
      {
3689
        /* Send Slave Address and set NBYTES to read */
3690
        I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, xfermode, xferrequest);
3691
 
3692
        /* Update XferCount value */
3693
        hi2c->XferCount -= hi2c->XferSize;
3694
 
3695
        /* Process Unlocked */
3696
        __HAL_UNLOCK(hi2c);
3697
 
3698
        /* Note : The I2C interrupts must be enabled after unlocking current process
3699
                  to avoid the risk of I2C interrupt handle execution before current
3700
                  process unlock */
3701
        /* Enable ERR and NACK interrupts */
3702
        I2C_Enable_IRQ(hi2c, I2C_XFER_ERROR_IT);
3703
 
3704
        /* Enable DMA Request */
3705
        hi2c->Instance->CR1 |= I2C_CR1_RXDMAEN;
3706
      }
3707
      else
3708
      {
3709
        /* Update I2C state */
3710
        hi2c->State     = HAL_I2C_STATE_READY;
3711
        hi2c->Mode      = HAL_I2C_MODE_NONE;
3712
 
3713
        /* Update I2C error code */
3714
        hi2c->ErrorCode |= HAL_I2C_ERROR_DMA;
3715
 
3716
        /* Process Unlocked */
3717
        __HAL_UNLOCK(hi2c);
3718
 
3719
        return HAL_ERROR;
3720
      }
3721
    }
3722
    else
3723
    {
3724
      /* Update Transfer ISR function pointer */
3725
      hi2c->XferISR = I2C_Master_ISR_IT;
3726
 
3727
      /* Send Slave Address */
3728
      /* Set NBYTES to read and generate START condition */
6 mjames 3729
      I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, I2C_AUTOEND_MODE,
3730
                         I2C_GENERATE_START_READ);
2 mjames 3731
 
3732
      /* Process Unlocked */
3733
      __HAL_UNLOCK(hi2c);
3734
 
3735
      /* Note : The I2C interrupts must be enabled after unlocking current process
3736
                to avoid the risk of I2C interrupt handle execution before current
3737
                process unlock */
3738
      /* Enable ERR, TC, STOP, NACK, TXI interrupt */
3739
      /* possible to enable all of these */
6 mjames 3740
      /* I2C_IT_ERRI | I2C_IT_TCI | I2C_IT_STOPI | I2C_IT_NACKI |
3741
        I2C_IT_ADDRI | I2C_IT_RXI | I2C_IT_TXI */
2 mjames 3742
      I2C_Enable_IRQ(hi2c, I2C_XFER_TX_IT);
3743
    }
3744
 
3745
    return HAL_OK;
3746
  }
3747
  else
3748
  {
3749
    return HAL_BUSY;
3750
  }
3751
}
3752
 
3753
/**
3754
  * @brief  Sequential transmit in slave/device I2C mode an amount of data in non-blocking mode with Interrupt
3755
  * @note   This interface allow to manage repeated start condition when a direction change during transfer
3756
  * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
3757
  *                the configuration information for the specified I2C.
3758
  * @param  pData Pointer to data buffer
3759
  * @param  Size Amount of data to be sent
3760
  * @param  XferOptions Options of Transfer, value of @ref I2C_XFEROPTIONS
3761
  * @retval HAL status
3762
  */
6 mjames 3763
HAL_StatusTypeDef HAL_I2C_Slave_Seq_Transmit_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size,
3764
                                                uint32_t XferOptions)
2 mjames 3765
{
3766
  /* Check the parameters */
3767
  assert_param(IS_I2C_TRANSFER_OPTIONS_REQUEST(XferOptions));
3768
 
3769
  if (((uint32_t)hi2c->State & (uint32_t)HAL_I2C_STATE_LISTEN) == (uint32_t)HAL_I2C_STATE_LISTEN)
3770
  {
3771
    if ((pData == NULL) || (Size == 0U))
3772
    {
3773
      hi2c->ErrorCode = HAL_I2C_ERROR_INVALID_PARAM;
3774
      return  HAL_ERROR;
3775
    }
3776
 
3777
    /* Disable Interrupts, to prevent preemption during treatment in case of multicall */
3778
    I2C_Disable_IRQ(hi2c, I2C_XFER_LISTEN_IT | I2C_XFER_TX_IT);
3779
 
3780
    /* Process Locked */
3781
    __HAL_LOCK(hi2c);
3782
 
3783
    /* I2C cannot manage full duplex exchange so disable previous IT enabled if any */
3784
    /* and then toggle the HAL slave RX state to TX state */
3785
    if (hi2c->State == HAL_I2C_STATE_BUSY_RX_LISTEN)
3786
    {
3787
      /* Disable associated Interrupts */
3788
      I2C_Disable_IRQ(hi2c, I2C_XFER_RX_IT);
3789
 
3790
      /* Abort DMA Xfer if any */
3791
      if ((hi2c->Instance->CR1 & I2C_CR1_RXDMAEN) == I2C_CR1_RXDMAEN)
3792
      {
3793
        hi2c->Instance->CR1 &= ~I2C_CR1_RXDMAEN;
3794
 
3795
        if (hi2c->hdmarx != NULL)
3796
        {
3797
          /* Set the I2C DMA Abort callback :
3798
           will lead to call HAL_I2C_ErrorCallback() at end of DMA abort procedure */
3799
          hi2c->hdmarx->XferAbortCallback = I2C_DMAAbort;
3800
 
3801
          /* Abort DMA RX */
3802
          if (HAL_DMA_Abort_IT(hi2c->hdmarx) != HAL_OK)
3803
          {
3804
            /* Call Directly XferAbortCallback function in case of error */
3805
            hi2c->hdmarx->XferAbortCallback(hi2c->hdmarx);
3806
          }
3807
        }
3808
      }
3809
    }
3810
 
3811
    hi2c->State     = HAL_I2C_STATE_BUSY_TX_LISTEN;
3812
    hi2c->Mode      = HAL_I2C_MODE_SLAVE;
3813
    hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
3814
 
3815
    /* Enable Address Acknowledge */
3816
    hi2c->Instance->CR2 &= ~I2C_CR2_NACK;
3817
 
3818
    /* Prepare transfer parameters */
3819
    hi2c->pBuffPtr    = pData;
3820
    hi2c->XferCount   = Size;
3821
    hi2c->XferSize    = hi2c->XferCount;
3822
    hi2c->XferOptions = XferOptions;
3823
    hi2c->XferISR     = I2C_Slave_ISR_IT;
3824
 
3825
    if (I2C_GET_DIR(hi2c) == I2C_DIRECTION_RECEIVE)
3826
    {
3827
      /* Clear ADDR flag after prepare the transfer parameters */
3828
      /* This action will generate an acknowledge to the Master */
3829
      __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_ADDR);
3830
    }
3831
 
3832
    /* Process Unlocked */
3833
    __HAL_UNLOCK(hi2c);
3834
 
3835
    /* Note : The I2C interrupts must be enabled after unlocking current process
3836
    to avoid the risk of I2C interrupt handle execution before current
3837
    process unlock */
3838
    /* REnable ADDR interrupt */
3839
    I2C_Enable_IRQ(hi2c, I2C_XFER_TX_IT | I2C_XFER_LISTEN_IT);
3840
 
3841
    return HAL_OK;
3842
  }
3843
  else
3844
  {
3845
    return HAL_ERROR;
3846
  }
3847
}
3848
 
3849
/**
3850
  * @brief  Sequential transmit in slave/device I2C mode an amount of data in non-blocking mode with DMA
3851
  * @note   This interface allow to manage repeated start condition when a direction change during transfer
3852
  * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
3853
  *                the configuration information for the specified I2C.
3854
  * @param  pData Pointer to data buffer
3855
  * @param  Size Amount of data to be sent
3856
  * @param  XferOptions Options of Transfer, value of @ref I2C_XFEROPTIONS
3857
  * @retval HAL status
3858
  */
6 mjames 3859
HAL_StatusTypeDef HAL_I2C_Slave_Seq_Transmit_DMA(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size,
3860
                                                 uint32_t XferOptions)
2 mjames 3861
{
3862
  HAL_StatusTypeDef dmaxferstatus;
3863
 
3864
  /* Check the parameters */
3865
  assert_param(IS_I2C_TRANSFER_OPTIONS_REQUEST(XferOptions));
3866
 
3867
  if (((uint32_t)hi2c->State & (uint32_t)HAL_I2C_STATE_LISTEN) == (uint32_t)HAL_I2C_STATE_LISTEN)
3868
  {
3869
    if ((pData == NULL) || (Size == 0U))
3870
    {
3871
      hi2c->ErrorCode = HAL_I2C_ERROR_INVALID_PARAM;
3872
      return  HAL_ERROR;
3873
    }
3874
 
3875
    /* Process Locked */
3876
    __HAL_LOCK(hi2c);
3877
 
3878
    /* Disable Interrupts, to prevent preemption during treatment in case of multicall */
3879
    I2C_Disable_IRQ(hi2c, I2C_XFER_LISTEN_IT | I2C_XFER_TX_IT);
3880
 
3881
    /* I2C cannot manage full duplex exchange so disable previous IT enabled if any */
3882
    /* and then toggle the HAL slave RX state to TX state */
3883
    if (hi2c->State == HAL_I2C_STATE_BUSY_RX_LISTEN)
3884
    {
3885
      /* Disable associated Interrupts */
3886
      I2C_Disable_IRQ(hi2c, I2C_XFER_RX_IT);
3887
 
3888
      if ((hi2c->Instance->CR1 & I2C_CR1_RXDMAEN) == I2C_CR1_RXDMAEN)
3889
      {
3890
        /* Abort DMA Xfer if any */
3891
        if (hi2c->hdmarx != NULL)
3892
        {
3893
          hi2c->Instance->CR1 &= ~I2C_CR1_RXDMAEN;
3894
 
3895
          /* Set the I2C DMA Abort callback :
3896
           will lead to call HAL_I2C_ErrorCallback() at end of DMA abort procedure */
3897
          hi2c->hdmarx->XferAbortCallback = I2C_DMAAbort;
3898
 
3899
          /* Abort DMA RX */
3900
          if (HAL_DMA_Abort_IT(hi2c->hdmarx) != HAL_OK)
3901
          {
3902
            /* Call Directly XferAbortCallback function in case of error */
3903
            hi2c->hdmarx->XferAbortCallback(hi2c->hdmarx);
3904
          }
3905
        }
3906
      }
3907
    }
3908
    else if (hi2c->State == HAL_I2C_STATE_BUSY_TX_LISTEN)
3909
    {
3910
      if ((hi2c->Instance->CR1 & I2C_CR1_TXDMAEN) == I2C_CR1_TXDMAEN)
3911
      {
3912
        hi2c->Instance->CR1 &= ~I2C_CR1_TXDMAEN;
3913
 
3914
        /* Abort DMA Xfer if any */
3915
        if (hi2c->hdmatx != NULL)
3916
        {
3917
          /* Set the I2C DMA Abort callback :
3918
           will lead to call HAL_I2C_ErrorCallback() at end of DMA abort procedure */
3919
          hi2c->hdmatx->XferAbortCallback = I2C_DMAAbort;
3920
 
3921
          /* Abort DMA TX */
3922
          if (HAL_DMA_Abort_IT(hi2c->hdmatx) != HAL_OK)
3923
          {
3924
            /* Call Directly XferAbortCallback function in case of error */
3925
            hi2c->hdmatx->XferAbortCallback(hi2c->hdmatx);
3926
          }
3927
        }
3928
      }
3929
    }
3930
    else
3931
    {
3932
      /* Nothing to do */
3933
    }
3934
 
3935
    hi2c->State     = HAL_I2C_STATE_BUSY_TX_LISTEN;
3936
    hi2c->Mode      = HAL_I2C_MODE_SLAVE;
3937
    hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
3938
 
3939
    /* Enable Address Acknowledge */
3940
    hi2c->Instance->CR2 &= ~I2C_CR2_NACK;
3941
 
3942
    /* Prepare transfer parameters */
3943
    hi2c->pBuffPtr    = pData;
3944
    hi2c->XferCount   = Size;
3945
    hi2c->XferSize    = hi2c->XferCount;
3946
    hi2c->XferOptions = XferOptions;
3947
    hi2c->XferISR     = I2C_Slave_ISR_DMA;
3948
 
3949
    if (hi2c->hdmatx != NULL)
3950
    {
3951
      /* Set the I2C DMA transfer complete callback */
3952
      hi2c->hdmatx->XferCpltCallback = I2C_DMASlaveTransmitCplt;
3953
 
3954
      /* Set the DMA error callback */
3955
      hi2c->hdmatx->XferErrorCallback = I2C_DMAError;
3956
 
3957
      /* Set the unused DMA callbacks to NULL */
3958
      hi2c->hdmatx->XferHalfCpltCallback = NULL;
3959
      hi2c->hdmatx->XferAbortCallback = NULL;
3960
 
3961
      /* Enable the DMA channel */
6 mjames 3962
      dmaxferstatus = HAL_DMA_Start_IT(hi2c->hdmatx, (uint32_t)pData, (uint32_t)&hi2c->Instance->TXDR,
3963
                                       hi2c->XferSize);
2 mjames 3964
    }
3965
    else
3966
    {
3967
      /* Update I2C state */
3968
      hi2c->State     = HAL_I2C_STATE_LISTEN;
3969
      hi2c->Mode      = HAL_I2C_MODE_NONE;
3970
 
3971
      /* Update I2C error code */
3972
      hi2c->ErrorCode |= HAL_I2C_ERROR_DMA_PARAM;
3973
 
3974
      /* Process Unlocked */
3975
      __HAL_UNLOCK(hi2c);
3976
 
3977
      return HAL_ERROR;
3978
    }
3979
 
3980
    if (dmaxferstatus == HAL_OK)
3981
    {
3982
      /* Update XferCount value */
3983
      hi2c->XferCount -= hi2c->XferSize;
3984
 
3985
      /* Reset XferSize */
3986
      hi2c->XferSize = 0;
3987
    }
3988
    else
3989
    {
3990
      /* Update I2C state */
3991
      hi2c->State     = HAL_I2C_STATE_LISTEN;
3992
      hi2c->Mode      = HAL_I2C_MODE_NONE;
3993
 
3994
      /* Update I2C error code */
3995
      hi2c->ErrorCode |= HAL_I2C_ERROR_DMA;
3996
 
3997
      /* Process Unlocked */
3998
      __HAL_UNLOCK(hi2c);
3999
 
4000
      return HAL_ERROR;
4001
    }
4002
 
4003
    if (I2C_GET_DIR(hi2c) == I2C_DIRECTION_RECEIVE)
4004
    {
4005
      /* Clear ADDR flag after prepare the transfer parameters */
4006
      /* This action will generate an acknowledge to the Master */
4007
      __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_ADDR);
4008
    }
4009
 
4010
    /* Process Unlocked */
4011
    __HAL_UNLOCK(hi2c);
4012
 
4013
    /* Note : The I2C interrupts must be enabled after unlocking current process
4014
    to avoid the risk of I2C interrupt handle execution before current
4015
    process unlock */
4016
    /* Enable ERR, STOP, NACK, ADDR interrupts */
4017
    I2C_Enable_IRQ(hi2c, I2C_XFER_LISTEN_IT);
4018
 
4019
    /* Enable DMA Request */
4020
    hi2c->Instance->CR1 |= I2C_CR1_TXDMAEN;
4021
 
4022
    return HAL_OK;
4023
  }
4024
  else
4025
  {
4026
    return HAL_ERROR;
4027
  }
4028
}
4029
 
4030
/**
4031
  * @brief  Sequential receive in slave/device I2C mode an amount of data in non-blocking mode with Interrupt
4032
  * @note   This interface allow to manage repeated start condition when a direction change during transfer
4033
  * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
4034
  *                the configuration information for the specified I2C.
4035
  * @param  pData Pointer to data buffer
4036
  * @param  Size Amount of data to be sent
4037
  * @param  XferOptions Options of Transfer, value of @ref I2C_XFEROPTIONS
4038
  * @retval HAL status
4039
  */
6 mjames 4040
HAL_StatusTypeDef HAL_I2C_Slave_Seq_Receive_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size,
4041
                                               uint32_t XferOptions)
2 mjames 4042
{
4043
  /* Check the parameters */
4044
  assert_param(IS_I2C_TRANSFER_OPTIONS_REQUEST(XferOptions));
4045
 
4046
  if (((uint32_t)hi2c->State & (uint32_t)HAL_I2C_STATE_LISTEN) == (uint32_t)HAL_I2C_STATE_LISTEN)
4047
  {
4048
    if ((pData == NULL) || (Size == 0U))
4049
    {
4050
      hi2c->ErrorCode = HAL_I2C_ERROR_INVALID_PARAM;
4051
      return  HAL_ERROR;
4052
    }
4053
 
4054
    /* Disable Interrupts, to prevent preemption during treatment in case of multicall */
4055
    I2C_Disable_IRQ(hi2c, I2C_XFER_LISTEN_IT | I2C_XFER_RX_IT);
4056
 
4057
    /* Process Locked */
4058
    __HAL_LOCK(hi2c);
4059
 
4060
    /* I2C cannot manage full duplex exchange so disable previous IT enabled if any */
4061
    /* and then toggle the HAL slave TX state to RX state */
4062
    if (hi2c->State == HAL_I2C_STATE_BUSY_TX_LISTEN)
4063
    {
4064
      /* Disable associated Interrupts */
4065
      I2C_Disable_IRQ(hi2c, I2C_XFER_TX_IT);
4066
 
4067
      if ((hi2c->Instance->CR1 & I2C_CR1_TXDMAEN) == I2C_CR1_TXDMAEN)
4068
      {
4069
        hi2c->Instance->CR1 &= ~I2C_CR1_TXDMAEN;
4070
 
4071
        /* Abort DMA Xfer if any */
4072
        if (hi2c->hdmatx != NULL)
4073
        {
4074
          /* Set the I2C DMA Abort callback :
4075
           will lead to call HAL_I2C_ErrorCallback() at end of DMA abort procedure */
4076
          hi2c->hdmatx->XferAbortCallback = I2C_DMAAbort;
4077
 
4078
          /* Abort DMA TX */
4079
          if (HAL_DMA_Abort_IT(hi2c->hdmatx) != HAL_OK)
4080
          {
4081
            /* Call Directly XferAbortCallback function in case of error */
4082
            hi2c->hdmatx->XferAbortCallback(hi2c->hdmatx);
4083
          }
4084
        }
4085
      }
4086
    }
4087
 
4088
    hi2c->State     = HAL_I2C_STATE_BUSY_RX_LISTEN;
4089
    hi2c->Mode      = HAL_I2C_MODE_SLAVE;
4090
    hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
4091
 
4092
    /* Enable Address Acknowledge */
4093
    hi2c->Instance->CR2 &= ~I2C_CR2_NACK;
4094
 
4095
    /* Prepare transfer parameters */
4096
    hi2c->pBuffPtr    = pData;
4097
    hi2c->XferCount   = Size;
4098
    hi2c->XferSize    = hi2c->XferCount;
4099
    hi2c->XferOptions = XferOptions;
4100
    hi2c->XferISR     = I2C_Slave_ISR_IT;
4101
 
4102
    if (I2C_GET_DIR(hi2c) == I2C_DIRECTION_TRANSMIT)
4103
    {
4104
      /* Clear ADDR flag after prepare the transfer parameters */
4105
      /* This action will generate an acknowledge to the Master */
4106
      __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_ADDR);
4107
    }
4108
 
4109
    /* Process Unlocked */
4110
    __HAL_UNLOCK(hi2c);
4111
 
4112
    /* Note : The I2C interrupts must be enabled after unlocking current process
4113
    to avoid the risk of I2C interrupt handle execution before current
4114
    process unlock */
4115
    /* REnable ADDR interrupt */
4116
    I2C_Enable_IRQ(hi2c, I2C_XFER_RX_IT | I2C_XFER_LISTEN_IT);
4117
 
4118
    return HAL_OK;
4119
  }
4120
  else
4121
  {
4122
    return HAL_ERROR;
4123
  }
4124
}
4125
 
4126
/**
4127
  * @brief  Sequential receive in slave/device I2C mode an amount of data in non-blocking mode with DMA
4128
  * @note   This interface allow to manage repeated start condition when a direction change during transfer
4129
  * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
4130
  *                the configuration information for the specified I2C.
4131
  * @param  pData Pointer to data buffer
4132
  * @param  Size Amount of data to be sent
4133
  * @param  XferOptions Options of Transfer, value of @ref I2C_XFEROPTIONS
4134
  * @retval HAL status
4135
  */
6 mjames 4136
HAL_StatusTypeDef HAL_I2C_Slave_Seq_Receive_DMA(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size,
4137
                                                uint32_t XferOptions)
2 mjames 4138
{
4139
  HAL_StatusTypeDef dmaxferstatus;
4140
 
4141
  /* Check the parameters */
4142
  assert_param(IS_I2C_TRANSFER_OPTIONS_REQUEST(XferOptions));
4143
 
4144
  if (((uint32_t)hi2c->State & (uint32_t)HAL_I2C_STATE_LISTEN) == (uint32_t)HAL_I2C_STATE_LISTEN)
4145
  {
4146
    if ((pData == NULL) || (Size == 0U))
4147
    {
4148
      hi2c->ErrorCode = HAL_I2C_ERROR_INVALID_PARAM;
4149
      return  HAL_ERROR;
4150
    }
4151
 
4152
    /* Disable Interrupts, to prevent preemption during treatment in case of multicall */
4153
    I2C_Disable_IRQ(hi2c, I2C_XFER_LISTEN_IT | I2C_XFER_RX_IT);
4154
 
4155
    /* Process Locked */
4156
    __HAL_LOCK(hi2c);
4157
 
4158
    /* I2C cannot manage full duplex exchange so disable previous IT enabled if any */
4159
    /* and then toggle the HAL slave TX state to RX state */
4160
    if (hi2c->State == HAL_I2C_STATE_BUSY_TX_LISTEN)
4161
    {
4162
      /* Disable associated Interrupts */
4163
      I2C_Disable_IRQ(hi2c, I2C_XFER_TX_IT);
4164
 
4165
      if ((hi2c->Instance->CR1 & I2C_CR1_TXDMAEN) == I2C_CR1_TXDMAEN)
4166
      {
4167
        /* Abort DMA Xfer if any */
4168
        if (hi2c->hdmatx != NULL)
4169
        {
4170
          hi2c->Instance->CR1 &= ~I2C_CR1_TXDMAEN;
4171
 
4172
          /* Set the I2C DMA Abort callback :
4173
           will lead to call HAL_I2C_ErrorCallback() at end of DMA abort procedure */
4174
          hi2c->hdmatx->XferAbortCallback = I2C_DMAAbort;
4175
 
4176
          /* Abort DMA TX */
4177
          if (HAL_DMA_Abort_IT(hi2c->hdmatx) != HAL_OK)
4178
          {
4179
            /* Call Directly XferAbortCallback function in case of error */
4180
            hi2c->hdmatx->XferAbortCallback(hi2c->hdmatx);
4181
          }
4182
        }
4183
      }
4184
    }
4185
    else if (hi2c->State == HAL_I2C_STATE_BUSY_RX_LISTEN)
4186
    {
4187
      if ((hi2c->Instance->CR1 & I2C_CR1_RXDMAEN) == I2C_CR1_RXDMAEN)
4188
      {
4189
        hi2c->Instance->CR1 &= ~I2C_CR1_RXDMAEN;
4190
 
4191
        /* Abort DMA Xfer if any */
4192
        if (hi2c->hdmarx != NULL)
4193
        {
4194
          /* Set the I2C DMA Abort callback :
4195
           will lead to call HAL_I2C_ErrorCallback() at end of DMA abort procedure */
4196
          hi2c->hdmarx->XferAbortCallback = I2C_DMAAbort;
4197
 
4198
          /* Abort DMA RX */
4199
          if (HAL_DMA_Abort_IT(hi2c->hdmarx) != HAL_OK)
4200
          {
4201
            /* Call Directly XferAbortCallback function in case of error */
4202
            hi2c->hdmarx->XferAbortCallback(hi2c->hdmarx);
4203
          }
4204
        }
4205
      }
4206
    }
4207
    else
4208
    {
4209
      /* Nothing to do */
4210
    }
4211
 
4212
    hi2c->State     = HAL_I2C_STATE_BUSY_RX_LISTEN;
4213
    hi2c->Mode      = HAL_I2C_MODE_SLAVE;
4214
    hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
4215
 
4216
    /* Enable Address Acknowledge */
4217
    hi2c->Instance->CR2 &= ~I2C_CR2_NACK;
4218
 
4219
    /* Prepare transfer parameters */
4220
    hi2c->pBuffPtr    = pData;
4221
    hi2c->XferCount   = Size;
4222
    hi2c->XferSize    = hi2c->XferCount;
4223
    hi2c->XferOptions = XferOptions;
4224
    hi2c->XferISR     = I2C_Slave_ISR_DMA;
4225
 
4226
    if (hi2c->hdmarx != NULL)
4227
    {
4228
      /* Set the I2C DMA transfer complete callback */
4229
      hi2c->hdmarx->XferCpltCallback = I2C_DMASlaveReceiveCplt;
4230
 
4231
      /* Set the DMA error callback */
4232
      hi2c->hdmarx->XferErrorCallback = I2C_DMAError;
4233
 
4234
      /* Set the unused DMA callbacks to NULL */
4235
      hi2c->hdmarx->XferHalfCpltCallback = NULL;
4236
      hi2c->hdmarx->XferAbortCallback = NULL;
4237
 
4238
      /* Enable the DMA channel */
6 mjames 4239
      dmaxferstatus = HAL_DMA_Start_IT(hi2c->hdmarx, (uint32_t)&hi2c->Instance->RXDR,
4240
                                       (uint32_t)pData, hi2c->XferSize);
2 mjames 4241
    }
4242
    else
4243
    {
4244
      /* Update I2C state */
4245
      hi2c->State     = HAL_I2C_STATE_LISTEN;
4246
      hi2c->Mode      = HAL_I2C_MODE_NONE;
4247
 
4248
      /* Update I2C error code */
4249
      hi2c->ErrorCode |= HAL_I2C_ERROR_DMA_PARAM;
4250
 
4251
      /* Process Unlocked */
4252
      __HAL_UNLOCK(hi2c);
4253
 
4254
      return HAL_ERROR;
4255
    }
4256
 
4257
    if (dmaxferstatus == HAL_OK)
4258
    {
4259
      /* Update XferCount value */
4260
      hi2c->XferCount -= hi2c->XferSize;
4261
 
4262
      /* Reset XferSize */
4263
      hi2c->XferSize = 0;
4264
    }
4265
    else
4266
    {
4267
      /* Update I2C state */
4268
      hi2c->State     = HAL_I2C_STATE_LISTEN;
4269
      hi2c->Mode      = HAL_I2C_MODE_NONE;
4270
 
4271
      /* Update I2C error code */
4272
      hi2c->ErrorCode |= HAL_I2C_ERROR_DMA;
4273
 
4274
      /* Process Unlocked */
4275
      __HAL_UNLOCK(hi2c);
4276
 
4277
      return HAL_ERROR;
4278
    }
4279
 
4280
    if (I2C_GET_DIR(hi2c) == I2C_DIRECTION_TRANSMIT)
4281
    {
4282
      /* Clear ADDR flag after prepare the transfer parameters */
4283
      /* This action will generate an acknowledge to the Master */
4284
      __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_ADDR);
4285
    }
4286
 
4287
    /* Process Unlocked */
4288
    __HAL_UNLOCK(hi2c);
4289
 
4290
    /* Note : The I2C interrupts must be enabled after unlocking current process
4291
    to avoid the risk of I2C interrupt handle execution before current
4292
    process unlock */
4293
    /* REnable ADDR interrupt */
4294
    I2C_Enable_IRQ(hi2c, I2C_XFER_RX_IT | I2C_XFER_LISTEN_IT);
4295
 
4296
    /* Enable DMA Request */
4297
    hi2c->Instance->CR1 |= I2C_CR1_RXDMAEN;
4298
 
4299
    return HAL_OK;
4300
  }
4301
  else
4302
  {
4303
    return HAL_ERROR;
4304
  }
4305
}
4306
 
4307
/**
4308
  * @brief  Enable the Address listen mode with Interrupt.
4309
  * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
4310
  *                the configuration information for the specified I2C.
4311
  * @retval HAL status
4312
  */
4313
HAL_StatusTypeDef HAL_I2C_EnableListen_IT(I2C_HandleTypeDef *hi2c)
4314
{
4315
  if (hi2c->State == HAL_I2C_STATE_READY)
4316
  {
4317
    hi2c->State = HAL_I2C_STATE_LISTEN;
4318
    hi2c->XferISR = I2C_Slave_ISR_IT;
4319
 
4320
    /* Enable the Address Match interrupt */
4321
    I2C_Enable_IRQ(hi2c, I2C_XFER_LISTEN_IT);
4322
 
4323
    return HAL_OK;
4324
  }
4325
  else
4326
  {
4327
    return HAL_BUSY;
4328
  }
4329
}
4330
 
4331
/**
4332
  * @brief  Disable the Address listen mode with Interrupt.
4333
  * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
4334
  *                the configuration information for the specified I2C
4335
  * @retval HAL status
4336
  */
4337
HAL_StatusTypeDef HAL_I2C_DisableListen_IT(I2C_HandleTypeDef *hi2c)
4338
{
4339
  /* Declaration of tmp to prevent undefined behavior of volatile usage */
4340
  uint32_t tmp;
4341
 
4342
  /* Disable Address listen mode only if a transfer is not ongoing */
4343
  if (hi2c->State == HAL_I2C_STATE_LISTEN)
4344
  {
4345
    tmp = (uint32_t)(hi2c->State) & I2C_STATE_MSK;
4346
    hi2c->PreviousState = tmp | (uint32_t)(hi2c->Mode);
4347
    hi2c->State = HAL_I2C_STATE_READY;
4348
    hi2c->Mode = HAL_I2C_MODE_NONE;
4349
    hi2c->XferISR = NULL;
4350
 
4351
    /* Disable the Address Match interrupt */
4352
    I2C_Disable_IRQ(hi2c, I2C_XFER_LISTEN_IT);
4353
 
4354
    return HAL_OK;
4355
  }
4356
  else
4357
  {
4358
    return HAL_BUSY;
4359
  }
4360
}
4361
 
4362
/**
4363
  * @brief  Abort a master I2C IT or DMA process communication with Interrupt.
4364
  * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
4365
  *                the configuration information for the specified I2C.
4366
  * @param  DevAddress Target device address: The device 7 bits address value
4367
  *         in datasheet must be shifted to the left before calling the interface
4368
  * @retval HAL status
4369
  */
4370
HAL_StatusTypeDef HAL_I2C_Master_Abort_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress)
4371
{
4372
  if (hi2c->Mode == HAL_I2C_MODE_MASTER)
4373
  {
4374
    /* Process Locked */
4375
    __HAL_LOCK(hi2c);
4376
 
6 mjames 4377
    /* Disable Interrupts and Store Previous state */
4378
    if (hi2c->State == HAL_I2C_STATE_BUSY_TX)
4379
    {
4380
      I2C_Disable_IRQ(hi2c, I2C_XFER_TX_IT);
4381
      hi2c->PreviousState = I2C_STATE_MASTER_BUSY_TX;
4382
    }
4383
    else if (hi2c->State == HAL_I2C_STATE_BUSY_RX)
4384
    {
4385
      I2C_Disable_IRQ(hi2c, I2C_XFER_RX_IT);
4386
      hi2c->PreviousState = I2C_STATE_MASTER_BUSY_RX;
4387
    }
4388
    else
4389
    {
4390
      /* Do nothing */
4391
    }
2 mjames 4392
 
4393
    /* Set State at HAL_I2C_STATE_ABORT */
4394
    hi2c->State = HAL_I2C_STATE_ABORT;
4395
 
4396
    /* Set NBYTES to 1 to generate a dummy read on I2C peripheral */
4397
    /* Set AUTOEND mode, this will generate a NACK then STOP condition to abort the current transfer */
4398
    I2C_TransferConfig(hi2c, DevAddress, 1, I2C_AUTOEND_MODE, I2C_GENERATE_STOP);
4399
 
4400
    /* Process Unlocked */
4401
    __HAL_UNLOCK(hi2c);
4402
 
4403
    /* Note : The I2C interrupts must be enabled after unlocking current process
4404
              to avoid the risk of I2C interrupt handle execution before current
4405
              process unlock */
4406
    I2C_Enable_IRQ(hi2c, I2C_XFER_CPLT_IT);
4407
 
4408
    return HAL_OK;
4409
  }
4410
  else
4411
  {
4412
    /* Wrong usage of abort function */
4413
    /* This function should be used only in case of abort monitored by master device */
4414
    return HAL_ERROR;
4415
  }
4416
}
4417
 
4418
/**
4419
  * @}
4420
  */
4421
 
4422
/** @defgroup I2C_IRQ_Handler_and_Callbacks IRQ Handler and Callbacks
6 mjames 4423
  * @{
4424
  */
2 mjames 4425
 
4426
/**
4427
  * @brief  This function handles I2C event interrupt request.
4428
  * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
4429
  *                the configuration information for the specified I2C.
4430
  * @retval None
4431
  */
4432
void HAL_I2C_EV_IRQHandler(I2C_HandleTypeDef *hi2c)
4433
{
4434
  /* Get current IT Flags and IT sources value */
4435
  uint32_t itflags   = READ_REG(hi2c->Instance->ISR);
4436
  uint32_t itsources = READ_REG(hi2c->Instance->CR1);
4437
 
4438
  /* I2C events treatment -------------------------------------*/
4439
  if (hi2c->XferISR != NULL)
4440
  {
4441
    hi2c->XferISR(hi2c, itflags, itsources);
4442
  }
4443
}
4444
 
4445
/**
4446
  * @brief  This function handles I2C error interrupt request.
4447
  * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
4448
  *                the configuration information for the specified I2C.
4449
  * @retval None
4450
  */
4451
void HAL_I2C_ER_IRQHandler(I2C_HandleTypeDef *hi2c)
4452
{
4453
  uint32_t itflags   = READ_REG(hi2c->Instance->ISR);
4454
  uint32_t itsources = READ_REG(hi2c->Instance->CR1);
4455
  uint32_t tmperror;
4456
 
4457
  /* I2C Bus error interrupt occurred ------------------------------------*/
6 mjames 4458
  if ((I2C_CHECK_FLAG(itflags, I2C_FLAG_BERR) != RESET) && \
4459
      (I2C_CHECK_IT_SOURCE(itsources, I2C_IT_ERRI) != RESET))
2 mjames 4460
  {
4461
    hi2c->ErrorCode |= HAL_I2C_ERROR_BERR;
4462
 
4463
    /* Clear BERR flag */
4464
    __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_BERR);
4465
  }
4466
 
4467
  /* I2C Over-Run/Under-Run interrupt occurred ----------------------------------------*/
6 mjames 4468
  if ((I2C_CHECK_FLAG(itflags, I2C_FLAG_OVR) != RESET) && \
4469
      (I2C_CHECK_IT_SOURCE(itsources, I2C_IT_ERRI) != RESET))
2 mjames 4470
  {
4471
    hi2c->ErrorCode |= HAL_I2C_ERROR_OVR;
4472
 
4473
    /* Clear OVR flag */
4474
    __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_OVR);
4475
  }
4476
 
4477
  /* I2C Arbitration Loss error interrupt occurred -------------------------------------*/
6 mjames 4478
  if ((I2C_CHECK_FLAG(itflags, I2C_FLAG_ARLO) != RESET) && \
4479
      (I2C_CHECK_IT_SOURCE(itsources, I2C_IT_ERRI) != RESET))
2 mjames 4480
  {
4481
    hi2c->ErrorCode |= HAL_I2C_ERROR_ARLO;
4482
 
4483
    /* Clear ARLO flag */
4484
    __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_ARLO);
4485
  }
4486
 
4487
  /* Store current volatile hi2c->ErrorCode, misra rule */
4488
  tmperror = hi2c->ErrorCode;
4489
 
4490
  /* Call the Error Callback in case of Error detected */
4491
  if ((tmperror & (HAL_I2C_ERROR_BERR | HAL_I2C_ERROR_OVR | HAL_I2C_ERROR_ARLO)) !=  HAL_I2C_ERROR_NONE)
4492
  {
4493
    I2C_ITError(hi2c, tmperror);
4494
  }
4495
}
4496
 
4497
/**
4498
  * @brief  Master Tx Transfer completed callback.
4499
  * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
4500
  *                the configuration information for the specified I2C.
4501
  * @retval None
4502
  */
4503
__weak void HAL_I2C_MasterTxCpltCallback(I2C_HandleTypeDef *hi2c)
4504
{
4505
  /* Prevent unused argument(s) compilation warning */
4506
  UNUSED(hi2c);
4507
 
4508
  /* NOTE : This function should not be modified, when the callback is needed,
4509
            the HAL_I2C_MasterTxCpltCallback could be implemented in the user file
4510
   */
4511
}
4512
 
4513
/**
4514
  * @brief  Master Rx Transfer completed callback.
4515
  * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
4516
  *                the configuration information for the specified I2C.
4517
  * @retval None
4518
  */
4519
__weak void HAL_I2C_MasterRxCpltCallback(I2C_HandleTypeDef *hi2c)
4520
{
4521
  /* Prevent unused argument(s) compilation warning */
4522
  UNUSED(hi2c);
4523
 
4524
  /* NOTE : This function should not be modified, when the callback is needed,
4525
            the HAL_I2C_MasterRxCpltCallback could be implemented in the user file
4526
   */
4527
}
4528
 
4529
/** @brief  Slave Tx Transfer completed callback.
4530
  * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
4531
  *                the configuration information for the specified I2C.
4532
  * @retval None
4533
  */
4534
__weak void HAL_I2C_SlaveTxCpltCallback(I2C_HandleTypeDef *hi2c)
4535
{
4536
  /* Prevent unused argument(s) compilation warning */
4537
  UNUSED(hi2c);
4538
 
4539
  /* NOTE : This function should not be modified, when the callback is needed,
4540
            the HAL_I2C_SlaveTxCpltCallback could be implemented in the user file
4541
   */
4542
}
4543
 
4544
/**
4545
  * @brief  Slave Rx Transfer completed callback.
4546
  * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
4547
  *                the configuration information for the specified I2C.
4548
  * @retval None
4549
  */
4550
__weak void HAL_I2C_SlaveRxCpltCallback(I2C_HandleTypeDef *hi2c)
4551
{
4552
  /* Prevent unused argument(s) compilation warning */
4553
  UNUSED(hi2c);
4554
 
4555
  /* NOTE : This function should not be modified, when the callback is needed,
4556
            the HAL_I2C_SlaveRxCpltCallback could be implemented in the user file
4557
   */
4558
}
4559
 
4560
/**
4561
  * @brief  Slave Address Match callback.
4562
  * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
4563
  *                the configuration information for the specified I2C.
4564
  * @param  TransferDirection Master request Transfer Direction (Write/Read), value of @ref I2C_XFERDIRECTION
4565
  * @param  AddrMatchCode Address Match Code
4566
  * @retval None
4567
  */
4568
__weak void HAL_I2C_AddrCallback(I2C_HandleTypeDef *hi2c, uint8_t TransferDirection, uint16_t AddrMatchCode)
4569
{
4570
  /* Prevent unused argument(s) compilation warning */
4571
  UNUSED(hi2c);
4572
  UNUSED(TransferDirection);
4573
  UNUSED(AddrMatchCode);
4574
 
4575
  /* NOTE : This function should not be modified, when the callback is needed,
4576
            the HAL_I2C_AddrCallback() could be implemented in the user file
4577
   */
4578
}
4579
 
4580
/**
4581
  * @brief  Listen Complete callback.
4582
  * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
4583
  *                the configuration information for the specified I2C.
4584
  * @retval None
4585
  */
4586
__weak void HAL_I2C_ListenCpltCallback(I2C_HandleTypeDef *hi2c)
4587
{
4588
  /* Prevent unused argument(s) compilation warning */
4589
  UNUSED(hi2c);
4590
 
4591
  /* NOTE : This function should not be modified, when the callback is needed,
4592
            the HAL_I2C_ListenCpltCallback() could be implemented in the user file
4593
   */
4594
}
4595
 
4596
/**
4597
  * @brief  Memory Tx Transfer completed callback.
4598
  * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
4599
  *                the configuration information for the specified I2C.
4600
  * @retval None
4601
  */
4602
__weak void HAL_I2C_MemTxCpltCallback(I2C_HandleTypeDef *hi2c)
4603
{
4604
  /* Prevent unused argument(s) compilation warning */
4605
  UNUSED(hi2c);
4606
 
4607
  /* NOTE : This function should not be modified, when the callback is needed,
4608
            the HAL_I2C_MemTxCpltCallback could be implemented in the user file
4609
   */
4610
}
4611
 
4612
/**
4613
  * @brief  Memory Rx Transfer completed callback.
4614
  * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
4615
  *                the configuration information for the specified I2C.
4616
  * @retval None
4617
  */
4618
__weak void HAL_I2C_MemRxCpltCallback(I2C_HandleTypeDef *hi2c)
4619
{
4620
  /* Prevent unused argument(s) compilation warning */
4621
  UNUSED(hi2c);
4622
 
4623
  /* NOTE : This function should not be modified, when the callback is needed,
4624
            the HAL_I2C_MemRxCpltCallback could be implemented in the user file
4625
   */
4626
}
4627
 
4628
/**
4629
  * @brief  I2C error callback.
4630
  * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
4631
  *                the configuration information for the specified I2C.
4632
  * @retval None
4633
  */
4634
__weak void HAL_I2C_ErrorCallback(I2C_HandleTypeDef *hi2c)
4635
{
4636
  /* Prevent unused argument(s) compilation warning */
4637
  UNUSED(hi2c);
4638
 
4639
  /* NOTE : This function should not be modified, when the callback is needed,
4640
            the HAL_I2C_ErrorCallback could be implemented in the user file
4641
   */
4642
}
4643
 
4644
/**
4645
  * @brief  I2C abort callback.
4646
  * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
4647
  *                the configuration information for the specified I2C.
4648
  * @retval None
4649
  */
4650
__weak void HAL_I2C_AbortCpltCallback(I2C_HandleTypeDef *hi2c)
4651
{
4652
  /* Prevent unused argument(s) compilation warning */
4653
  UNUSED(hi2c);
4654
 
4655
  /* NOTE : This function should not be modified, when the callback is needed,
4656
            the HAL_I2C_AbortCpltCallback could be implemented in the user file
4657
   */
4658
}
4659
 
4660
/**
4661
  * @}
4662
  */
4663
 
4664
/** @defgroup I2C_Exported_Functions_Group3 Peripheral State, Mode and Error functions
6 mjames 4665
  *  @brief   Peripheral State, Mode and Error functions
4666
  *
2 mjames 4667
@verbatim
4668
 ===============================================================================
4669
            ##### Peripheral State, Mode and Error functions #####
4670
 ===============================================================================
4671
    [..]
4672
    This subsection permit to get in run-time the status of the peripheral
4673
    and the data flow.
4674
 
4675
@endverbatim
4676
  * @{
4677
  */
4678
 
4679
/**
4680
  * @brief  Return the I2C handle state.
4681
  * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
4682
  *                the configuration information for the specified I2C.
4683
  * @retval HAL state
4684
  */
4685
HAL_I2C_StateTypeDef HAL_I2C_GetState(I2C_HandleTypeDef *hi2c)
4686
{
4687
  /* Return I2C handle state */
4688
  return hi2c->State;
4689
}
4690
 
4691
/**
4692
  * @brief  Returns the I2C Master, Slave, Memory or no mode.
4693
  * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
4694
  *         the configuration information for I2C module
4695
  * @retval HAL mode
4696
  */
4697
HAL_I2C_ModeTypeDef HAL_I2C_GetMode(I2C_HandleTypeDef *hi2c)
4698
{
4699
  return hi2c->Mode;
4700
}
4701
 
4702
/**
6 mjames 4703
  * @brief  Return the I2C error code.
2 mjames 4704
  * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
4705
  *              the configuration information for the specified I2C.
6 mjames 4706
  * @retval I2C Error Code
4707
  */
2 mjames 4708
uint32_t HAL_I2C_GetError(I2C_HandleTypeDef *hi2c)
4709
{
4710
  return hi2c->ErrorCode;
4711
}
4712
 
4713
/**
4714
  * @}
4715
  */
4716
 
4717
/**
4718
  * @}
4719
  */
4720
 
4721
/** @addtogroup I2C_Private_Functions
4722
  * @{
4723
  */
4724
 
4725
/**
4726
  * @brief  Interrupt Sub-Routine which handle the Interrupt Flags Master Mode with Interrupt.
4727
  * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
4728
  *                the configuration information for the specified I2C.
4729
  * @param  ITFlags Interrupt flags to handle.
4730
  * @param  ITSources Interrupt sources enabled.
4731
  * @retval HAL status
4732
  */
6 mjames 4733
static HAL_StatusTypeDef I2C_Master_ISR_IT(struct __I2C_HandleTypeDef *hi2c, uint32_t ITFlags,
4734
                                           uint32_t ITSources)
2 mjames 4735
{
4736
  uint16_t devaddress;
4737
  uint32_t tmpITFlags = ITFlags;
4738
 
4739
  /* Process Locked */
4740
  __HAL_LOCK(hi2c);
4741
 
6 mjames 4742
  if ((I2C_CHECK_FLAG(tmpITFlags, I2C_FLAG_AF) != RESET) && \
4743
      (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_NACKI) != RESET))
2 mjames 4744
  {
4745
    /* Clear NACK Flag */
4746
    __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF);
4747
 
4748
    /* Set corresponding Error Code */
4749
    /* No need to generate STOP, it is automatically done */
4750
    /* Error callback will be send during stop flag treatment */
4751
    hi2c->ErrorCode |= HAL_I2C_ERROR_AF;
4752
 
4753
    /* Flush TX register */
4754
    I2C_Flush_TXDR(hi2c);
4755
  }
6 mjames 4756
  else if ((I2C_CHECK_FLAG(tmpITFlags, I2C_FLAG_RXNE) != RESET) && \
4757
           (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_RXI) != RESET))
2 mjames 4758
  {
4759
    /* Remove RXNE flag on temporary variable as read done */
4760
    tmpITFlags &= ~I2C_FLAG_RXNE;
4761
 
4762
    /* Read data from RXDR */
4763
    *hi2c->pBuffPtr = (uint8_t)hi2c->Instance->RXDR;
4764
 
4765
    /* Increment Buffer pointer */
4766
    hi2c->pBuffPtr++;
4767
 
4768
    hi2c->XferSize--;
4769
    hi2c->XferCount--;
4770
  }
6 mjames 4771
  else if ((I2C_CHECK_FLAG(tmpITFlags, I2C_FLAG_TXIS) != RESET) && \
4772
           (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_TXI) != RESET))
2 mjames 4773
  {
4774
    /* Write data to TXDR */
4775
    hi2c->Instance->TXDR = *hi2c->pBuffPtr;
4776
 
4777
    /* Increment Buffer pointer */
4778
    hi2c->pBuffPtr++;
4779
 
4780
    hi2c->XferSize--;
4781
    hi2c->XferCount--;
4782
  }
6 mjames 4783
  else if ((I2C_CHECK_FLAG(tmpITFlags, I2C_FLAG_TCR) != RESET) && \
4784
           (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_TCI) != RESET))
2 mjames 4785
  {
4786
    if ((hi2c->XferCount != 0U) && (hi2c->XferSize == 0U))
4787
    {
4788
      devaddress = (uint16_t)(hi2c->Instance->CR2 & I2C_CR2_SADD);
4789
 
4790
      if (hi2c->XferCount > MAX_NBYTE_SIZE)
4791
      {
4792
        hi2c->XferSize = MAX_NBYTE_SIZE;
4793
        I2C_TransferConfig(hi2c, devaddress, (uint8_t)hi2c->XferSize, I2C_RELOAD_MODE, I2C_NO_STARTSTOP);
4794
      }
4795
      else
4796
      {
4797
        hi2c->XferSize = hi2c->XferCount;
4798
        if (hi2c->XferOptions != I2C_NO_OPTION_FRAME)
4799
        {
6 mjames 4800
          I2C_TransferConfig(hi2c, devaddress, (uint8_t)hi2c->XferSize,
4801
                             hi2c->XferOptions, I2C_NO_STARTSTOP);
2 mjames 4802
        }
4803
        else
4804
        {
6 mjames 4805
          I2C_TransferConfig(hi2c, devaddress, (uint8_t)hi2c->XferSize,
4806
                             I2C_AUTOEND_MODE, I2C_NO_STARTSTOP);
2 mjames 4807
        }
4808
      }
4809
    }
4810
    else
4811
    {
4812
      /* Call TxCpltCallback() if no stop mode is set */
4813
      if (I2C_GET_STOP_MODE(hi2c) != I2C_AUTOEND_MODE)
4814
      {
4815
        /* Call I2C Master Sequential complete process */
4816
        I2C_ITMasterSeqCplt(hi2c);
4817
      }
4818
      else
4819
      {
4820
        /* Wrong size Status regarding TCR flag event */
4821
        /* Call the corresponding callback to inform upper layer of End of Transfer */
4822
        I2C_ITError(hi2c, HAL_I2C_ERROR_SIZE);
4823
      }
4824
    }
4825
  }
6 mjames 4826
  else if ((I2C_CHECK_FLAG(tmpITFlags, I2C_FLAG_TC) != RESET) && \
4827
           (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_TCI) != RESET))
2 mjames 4828
  {
4829
    if (hi2c->XferCount == 0U)
4830
    {
4831
      if (I2C_GET_STOP_MODE(hi2c) != I2C_AUTOEND_MODE)
4832
      {
4833
        /* Generate a stop condition in case of no transfer option */
4834
        if (hi2c->XferOptions == I2C_NO_OPTION_FRAME)
4835
        {
4836
          /* Generate Stop */
4837
          hi2c->Instance->CR2 |= I2C_CR2_STOP;
4838
        }
4839
        else
4840
        {
4841
          /* Call I2C Master Sequential complete process */
4842
          I2C_ITMasterSeqCplt(hi2c);
4843
        }
4844
      }
4845
    }
4846
    else
4847
    {
4848
      /* Wrong size Status regarding TC flag event */
4849
      /* Call the corresponding callback to inform upper layer of End of Transfer */
4850
      I2C_ITError(hi2c, HAL_I2C_ERROR_SIZE);
4851
    }
4852
  }
4853
  else
4854
  {
4855
    /* Nothing to do */
4856
  }
4857
 
6 mjames 4858
  if ((I2C_CHECK_FLAG(tmpITFlags, I2C_FLAG_STOPF) != RESET) && \
4859
      (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_STOPI) != RESET))
2 mjames 4860
  {
4861
    /* Call I2C Master complete process */
4862
    I2C_ITMasterCplt(hi2c, tmpITFlags);
4863
  }
4864
 
4865
  /* Process Unlocked */
4866
  __HAL_UNLOCK(hi2c);
4867
 
4868
  return HAL_OK;
4869
}
4870
 
4871
/**
4872
  * @brief  Interrupt Sub-Routine which handle the Interrupt Flags Slave Mode with Interrupt.
4873
  * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
4874
  *                the configuration information for the specified I2C.
4875
  * @param  ITFlags Interrupt flags to handle.
4876
  * @param  ITSources Interrupt sources enabled.
4877
  * @retval HAL status
4878
  */
6 mjames 4879
static HAL_StatusTypeDef I2C_Slave_ISR_IT(struct __I2C_HandleTypeDef *hi2c, uint32_t ITFlags,
4880
                                          uint32_t ITSources)
2 mjames 4881
{
4882
  uint32_t tmpoptions = hi2c->XferOptions;
4883
  uint32_t tmpITFlags = ITFlags;
4884
 
4885
  /* Process locked */
4886
  __HAL_LOCK(hi2c);
4887
 
4888
  /* Check if STOPF is set */
6 mjames 4889
  if ((I2C_CHECK_FLAG(tmpITFlags, I2C_FLAG_STOPF) != RESET) && \
4890
      (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_STOPI) != RESET))
2 mjames 4891
  {
4892
    /* Call I2C Slave complete process */
4893
    I2C_ITSlaveCplt(hi2c, tmpITFlags);
4894
  }
4895
 
6 mjames 4896
  if ((I2C_CHECK_FLAG(tmpITFlags, I2C_FLAG_AF) != RESET) && \
4897
      (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_NACKI) != RESET))
2 mjames 4898
  {
4899
    /* Check that I2C transfer finished */
4900
    /* if yes, normal use case, a NACK is sent by the MASTER when Transfer is finished */
4901
    /* Mean XferCount == 0*/
4902
    /* So clear Flag NACKF only */
4903
    if (hi2c->XferCount == 0U)
4904
    {
6 mjames 4905
      if ((hi2c->State == HAL_I2C_STATE_LISTEN) && (tmpoptions == I2C_FIRST_AND_LAST_FRAME))
4906
        /* Same action must be done for (tmpoptions == I2C_LAST_FRAME) which removed for
4907
           Warning[Pa134]: left and right operands are identical */
2 mjames 4908
      {
4909
        /* Call I2C Listen complete process */
4910
        I2C_ITListenCplt(hi2c, tmpITFlags);
4911
      }
4912
      else if ((hi2c->State == HAL_I2C_STATE_BUSY_TX_LISTEN) && (tmpoptions != I2C_NO_OPTION_FRAME))
4913
      {
4914
        /* Clear NACK Flag */
4915
        __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF);
4916
 
4917
        /* Flush TX register */
4918
        I2C_Flush_TXDR(hi2c);
4919
 
4920
        /* Last Byte is Transmitted */
4921
        /* Call I2C Slave Sequential complete process */
4922
        I2C_ITSlaveSeqCplt(hi2c);
4923
      }
4924
      else
4925
      {
4926
        /* Clear NACK Flag */
4927
        __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF);
4928
      }
4929
    }
4930
    else
4931
    {
4932
      /* if no, error use case, a Non-Acknowledge of last Data is generated by the MASTER*/
4933
      /* Clear NACK Flag */
4934
      __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF);
4935
 
4936
      /* Set ErrorCode corresponding to a Non-Acknowledge */
4937
      hi2c->ErrorCode |= HAL_I2C_ERROR_AF;
4938
 
4939
      if ((tmpoptions == I2C_FIRST_FRAME) || (tmpoptions == I2C_NEXT_FRAME))
4940
      {
4941
        /* Call the corresponding callback to inform upper layer of End of Transfer */
4942
        I2C_ITError(hi2c, hi2c->ErrorCode);
4943
      }
4944
    }
4945
  }
6 mjames 4946
  else if ((I2C_CHECK_FLAG(tmpITFlags, I2C_FLAG_RXNE) != RESET) && \
4947
           (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_RXI) != RESET))
2 mjames 4948
  {
4949
    if (hi2c->XferCount > 0U)
4950
    {
4951
      /* Read data from RXDR */
4952
      *hi2c->pBuffPtr = (uint8_t)hi2c->Instance->RXDR;
4953
 
4954
      /* Increment Buffer pointer */
4955
      hi2c->pBuffPtr++;
4956
 
4957
      hi2c->XferSize--;
4958
      hi2c->XferCount--;
4959
    }
4960
 
4961
    if ((hi2c->XferCount == 0U) && \
4962
        (tmpoptions != I2C_NO_OPTION_FRAME))
4963
    {
4964
      /* Call I2C Slave Sequential complete process */
4965
      I2C_ITSlaveSeqCplt(hi2c);
4966
    }
4967
  }
6 mjames 4968
  else if ((I2C_CHECK_FLAG(tmpITFlags, I2C_FLAG_ADDR) != RESET) && \
4969
           (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_ADDRI) != RESET))
2 mjames 4970
  {
4971
    I2C_ITAddrCplt(hi2c, tmpITFlags);
4972
  }
6 mjames 4973
  else if ((I2C_CHECK_FLAG(tmpITFlags, I2C_FLAG_TXIS) != RESET) && \
4974
           (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_TXI) != RESET))
2 mjames 4975
  {
4976
    /* Write data to TXDR only if XferCount not reach "0" */
4977
    /* A TXIS flag can be set, during STOP treatment      */
6 mjames 4978
    /* Check if all Data have already been sent */
2 mjames 4979
    /* If it is the case, this last write in TXDR is not sent, correspond to a dummy TXIS event */
4980
    if (hi2c->XferCount > 0U)
4981
    {
4982
      /* Write data to TXDR */
4983
      hi2c->Instance->TXDR = *hi2c->pBuffPtr;
4984
 
4985
      /* Increment Buffer pointer */
4986
      hi2c->pBuffPtr++;
4987
 
4988
      hi2c->XferCount--;
4989
      hi2c->XferSize--;
4990
    }
4991
    else
4992
    {
4993
      if ((tmpoptions == I2C_NEXT_FRAME) || (tmpoptions == I2C_FIRST_FRAME))
4994
      {
4995
        /* Last Byte is Transmitted */
4996
        /* Call I2C Slave Sequential complete process */
4997
        I2C_ITSlaveSeqCplt(hi2c);
4998
      }
4999
    }
5000
  }
5001
  else
5002
  {
5003
    /* Nothing to do */
5004
  }
5005
 
5006
  /* Process Unlocked */
5007
  __HAL_UNLOCK(hi2c);
5008
 
5009
  return HAL_OK;
5010
}
5011
 
5012
/**
5013
  * @brief  Interrupt Sub-Routine which handle the Interrupt Flags Master Mode with DMA.
5014
  * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
5015
  *                the configuration information for the specified I2C.
5016
  * @param  ITFlags Interrupt flags to handle.
5017
  * @param  ITSources Interrupt sources enabled.
5018
  * @retval HAL status
5019
  */
6 mjames 5020
static HAL_StatusTypeDef I2C_Master_ISR_DMA(struct __I2C_HandleTypeDef *hi2c, uint32_t ITFlags,
5021
                                            uint32_t ITSources)
2 mjames 5022
{
5023
  uint16_t devaddress;
5024
  uint32_t xfermode;
5025
 
5026
  /* Process Locked */
5027
  __HAL_LOCK(hi2c);
5028
 
6 mjames 5029
  if ((I2C_CHECK_FLAG(ITFlags, I2C_FLAG_AF) != RESET) && \
5030
      (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_NACKI) != RESET))
2 mjames 5031
  {
5032
    /* Clear NACK Flag */
5033
    __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF);
5034
 
5035
    /* Set corresponding Error Code */
5036
    hi2c->ErrorCode |= HAL_I2C_ERROR_AF;
5037
 
5038
    /* No need to generate STOP, it is automatically done */
5039
    /* But enable STOP interrupt, to treat it */
5040
    /* Error callback will be send during stop flag treatment */
5041
    I2C_Enable_IRQ(hi2c, I2C_XFER_CPLT_IT);
5042
 
5043
    /* Flush TX register */
5044
    I2C_Flush_TXDR(hi2c);
5045
  }
6 mjames 5046
  else if ((I2C_CHECK_FLAG(ITFlags, I2C_FLAG_TCR) != RESET) && \
5047
           (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_TCI) != RESET))
2 mjames 5048
  {
5049
    /* Disable TC interrupt */
5050
    __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_TCI);
5051
 
5052
    if (hi2c->XferCount != 0U)
5053
    {
5054
      /* Recover Slave address */
5055
      devaddress = (uint16_t)(hi2c->Instance->CR2 & I2C_CR2_SADD);
5056
 
5057
      /* Prepare the new XferSize to transfer */
5058
      if (hi2c->XferCount > MAX_NBYTE_SIZE)
5059
      {
5060
        hi2c->XferSize = MAX_NBYTE_SIZE;
5061
        xfermode = I2C_RELOAD_MODE;
5062
      }
5063
      else
5064
      {
5065
        hi2c->XferSize = hi2c->XferCount;
5066
        if (hi2c->XferOptions != I2C_NO_OPTION_FRAME)
5067
        {
5068
          xfermode = hi2c->XferOptions;
5069
        }
5070
        else
5071
        {
5072
          xfermode = I2C_AUTOEND_MODE;
5073
        }
5074
      }
5075
 
5076
      /* Set the new XferSize in Nbytes register */
5077
      I2C_TransferConfig(hi2c, devaddress, (uint8_t)hi2c->XferSize, xfermode, I2C_NO_STARTSTOP);
5078
 
5079
      /* Update XferCount value */
5080
      hi2c->XferCount -= hi2c->XferSize;
5081
 
5082
      /* Enable DMA Request */
5083
      if (hi2c->State == HAL_I2C_STATE_BUSY_RX)
5084
      {
5085
        hi2c->Instance->CR1 |= I2C_CR1_RXDMAEN;
5086
      }
5087
      else
5088
      {
5089
        hi2c->Instance->CR1 |= I2C_CR1_TXDMAEN;
5090
      }
5091
    }
5092
    else
5093
    {
5094
      /* Call TxCpltCallback() if no stop mode is set */
5095
      if (I2C_GET_STOP_MODE(hi2c) != I2C_AUTOEND_MODE)
5096
      {
5097
        /* Call I2C Master Sequential complete process */
5098
        I2C_ITMasterSeqCplt(hi2c);
5099
      }
5100
      else
5101
      {
5102
        /* Wrong size Status regarding TCR flag event */
5103
        /* Call the corresponding callback to inform upper layer of End of Transfer */
5104
        I2C_ITError(hi2c, HAL_I2C_ERROR_SIZE);
5105
      }
5106
    }
5107
  }
6 mjames 5108
  else if ((I2C_CHECK_FLAG(ITFlags, I2C_FLAG_TC) != RESET) && \
5109
           (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_TCI) != RESET))
2 mjames 5110
  {
5111
    if (hi2c->XferCount == 0U)
5112
    {
5113
      if (I2C_GET_STOP_MODE(hi2c) != I2C_AUTOEND_MODE)
5114
      {
5115
        /* Generate a stop condition in case of no transfer option */
5116
        if (hi2c->XferOptions == I2C_NO_OPTION_FRAME)
5117
        {
5118
          /* Generate Stop */
5119
          hi2c->Instance->CR2 |= I2C_CR2_STOP;
5120
        }
5121
        else
5122
        {
5123
          /* Call I2C Master Sequential complete process */
5124
          I2C_ITMasterSeqCplt(hi2c);
5125
        }
5126
      }
5127
    }
5128
    else
5129
    {
5130
      /* Wrong size Status regarding TC flag event */
5131
      /* Call the corresponding callback to inform upper layer of End of Transfer */
5132
      I2C_ITError(hi2c, HAL_I2C_ERROR_SIZE);
5133
    }
5134
  }
6 mjames 5135
  else if ((I2C_CHECK_FLAG(ITFlags, I2C_FLAG_STOPF) != RESET) && \
5136
           (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_STOPI) != RESET))
2 mjames 5137
  {
5138
    /* Call I2C Master complete process */
5139
    I2C_ITMasterCplt(hi2c, ITFlags);
5140
  }
5141
  else
5142
  {
5143
    /* Nothing to do */
5144
  }
5145
 
5146
  /* Process Unlocked */
5147
  __HAL_UNLOCK(hi2c);
5148
 
5149
  return HAL_OK;
5150
}
5151
 
5152
/**
5153
  * @brief  Interrupt Sub-Routine which handle the Interrupt Flags Slave Mode with DMA.
5154
  * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
5155
  *                the configuration information for the specified I2C.
5156
  * @param  ITFlags Interrupt flags to handle.
5157
  * @param  ITSources Interrupt sources enabled.
5158
  * @retval HAL status
5159
  */
6 mjames 5160
static HAL_StatusTypeDef I2C_Slave_ISR_DMA(struct __I2C_HandleTypeDef *hi2c, uint32_t ITFlags,
5161
                                           uint32_t ITSources)
2 mjames 5162
{
5163
  uint32_t tmpoptions = hi2c->XferOptions;
5164
  uint32_t treatdmanack = 0U;
6 mjames 5165
  HAL_I2C_StateTypeDef tmpstate;
2 mjames 5166
 
5167
  /* Process locked */
5168
  __HAL_LOCK(hi2c);
5169
 
5170
  /* Check if STOPF is set */
6 mjames 5171
  if ((I2C_CHECK_FLAG(ITFlags, I2C_FLAG_STOPF) != RESET) && \
5172
      (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_STOPI) != RESET))
2 mjames 5173
  {
5174
    /* Call I2C Slave complete process */
5175
    I2C_ITSlaveCplt(hi2c, ITFlags);
5176
  }
5177
 
6 mjames 5178
  if ((I2C_CHECK_FLAG(ITFlags, I2C_FLAG_AF) != RESET) && \
5179
      (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_NACKI) != RESET))
2 mjames 5180
  {
5181
    /* Check that I2C transfer finished */
5182
    /* if yes, normal use case, a NACK is sent by the MASTER when Transfer is finished */
5183
    /* Mean XferCount == 0 */
5184
    /* So clear Flag NACKF only */
5185
    if ((I2C_CHECK_IT_SOURCE(ITSources, I2C_CR1_TXDMAEN) != RESET) ||
5186
        (I2C_CHECK_IT_SOURCE(ITSources, I2C_CR1_RXDMAEN) != RESET))
5187
    {
5188
      /* Split check of hdmarx, for MISRA compliance */
5189
      if (hi2c->hdmarx != NULL)
5190
      {
5191
        if (I2C_CHECK_IT_SOURCE(ITSources, I2C_CR1_RXDMAEN) != RESET)
5192
        {
5193
          if (__HAL_DMA_GET_COUNTER(hi2c->hdmarx) == 0U)
5194
          {
5195
            treatdmanack = 1U;
5196
          }
5197
        }
5198
      }
5199
 
5200
      /* Split check of hdmatx, for MISRA compliance  */
5201
      if (hi2c->hdmatx != NULL)
5202
      {
5203
        if (I2C_CHECK_IT_SOURCE(ITSources, I2C_CR1_TXDMAEN) != RESET)
5204
        {
5205
          if (__HAL_DMA_GET_COUNTER(hi2c->hdmatx) == 0U)
5206
          {
5207
            treatdmanack = 1U;
5208
          }
5209
        }
5210
      }
5211
 
5212
      if (treatdmanack == 1U)
5213
      {
6 mjames 5214
        if ((hi2c->State == HAL_I2C_STATE_LISTEN) && (tmpoptions == I2C_FIRST_AND_LAST_FRAME))
5215
          /* Same action must be done for (tmpoptions == I2C_LAST_FRAME) which removed for
5216
             Warning[Pa134]: left and right operands are identical */
2 mjames 5217
        {
5218
          /* Call I2C Listen complete process */
5219
          I2C_ITListenCplt(hi2c, ITFlags);
5220
        }
5221
        else if ((hi2c->State == HAL_I2C_STATE_BUSY_TX_LISTEN) && (tmpoptions != I2C_NO_OPTION_FRAME))
5222
        {
5223
          /* Clear NACK Flag */
5224
          __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF);
5225
 
5226
          /* Flush TX register */
5227
          I2C_Flush_TXDR(hi2c);
5228
 
5229
          /* Last Byte is Transmitted */
5230
          /* Call I2C Slave Sequential complete process */
5231
          I2C_ITSlaveSeqCplt(hi2c);
5232
        }
5233
        else
5234
        {
5235
          /* Clear NACK Flag */
5236
          __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF);
5237
        }
5238
      }
5239
      else
5240
      {
5241
        /* if no, error use case, a Non-Acknowledge of last Data is generated by the MASTER*/
5242
        /* Clear NACK Flag */
5243
        __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF);
5244
 
5245
        /* Set ErrorCode corresponding to a Non-Acknowledge */
5246
        hi2c->ErrorCode |= HAL_I2C_ERROR_AF;
5247
 
6 mjames 5248
        /* Store current hi2c->State, solve MISRA2012-Rule-13.5 */
5249
        tmpstate = hi2c->State;
5250
 
2 mjames 5251
        if ((tmpoptions == I2C_FIRST_FRAME) || (tmpoptions == I2C_NEXT_FRAME))
5252
        {
6 mjames 5253
          if ((tmpstate == HAL_I2C_STATE_BUSY_TX) || (tmpstate == HAL_I2C_STATE_BUSY_TX_LISTEN))
5254
          {
5255
            hi2c->PreviousState = I2C_STATE_SLAVE_BUSY_TX;
5256
          }
5257
          else if ((tmpstate == HAL_I2C_STATE_BUSY_RX) || (tmpstate == HAL_I2C_STATE_BUSY_RX_LISTEN))
5258
          {
5259
            hi2c->PreviousState = I2C_STATE_SLAVE_BUSY_RX;
5260
          }
5261
          else
5262
          {
5263
            /* Do nothing */
5264
          }
5265
 
2 mjames 5266
          /* Call the corresponding callback to inform upper layer of End of Transfer */
5267
          I2C_ITError(hi2c, hi2c->ErrorCode);
5268
        }
5269
      }
5270
    }
5271
    else
5272
    {
5273
      /* Only Clear NACK Flag, no DMA treatment is pending */
5274
      __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF);
5275
    }
5276
  }
6 mjames 5277
  else if ((I2C_CHECK_FLAG(ITFlags, I2C_FLAG_ADDR) != RESET) && \
5278
           (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_ADDRI) != RESET))
2 mjames 5279
  {
5280
    I2C_ITAddrCplt(hi2c, ITFlags);
5281
  }
5282
  else
5283
  {
5284
    /* Nothing to do */
5285
  }
5286
 
5287
  /* Process Unlocked */
5288
  __HAL_UNLOCK(hi2c);
5289
 
5290
  return HAL_OK;
5291
}
5292
 
5293
/**
5294
  * @brief  Master sends target device address followed by internal memory address for write request.
5295
  * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
5296
  *                the configuration information for the specified I2C.
5297
  * @param  DevAddress Target device address: The device 7 bits address value
5298
  *         in datasheet must be shifted to the left before calling the interface
5299
  * @param  MemAddress Internal memory address
5300
  * @param  MemAddSize Size of internal memory address
5301
  * @param  Timeout Timeout duration
5302
  * @param  Tickstart Tick start value
5303
  * @retval HAL status
5304
  */
6 mjames 5305
static HAL_StatusTypeDef I2C_RequestMemoryWrite(I2C_HandleTypeDef *hi2c, uint16_t DevAddress,
5306
                                                uint16_t MemAddress, uint16_t MemAddSize, uint32_t Timeout,
5307
                                                uint32_t Tickstart)
2 mjames 5308
{
5309
  I2C_TransferConfig(hi2c, DevAddress, (uint8_t)MemAddSize, I2C_RELOAD_MODE, I2C_GENERATE_START_WRITE);
5310
 
5311
  /* Wait until TXIS flag is set */
5312
  if (I2C_WaitOnTXISFlagUntilTimeout(hi2c, Timeout, Tickstart) != HAL_OK)
5313
  {
5314
    return HAL_ERROR;
5315
  }
5316
 
5317
  /* If Memory address size is 8Bit */
5318
  if (MemAddSize == I2C_MEMADD_SIZE_8BIT)
5319
  {
5320
    /* Send Memory Address */
5321
    hi2c->Instance->TXDR = I2C_MEM_ADD_LSB(MemAddress);
5322
  }
5323
  /* If Memory address size is 16Bit */
5324
  else
5325
  {
5326
    /* Send MSB of Memory Address */
5327
    hi2c->Instance->TXDR = I2C_MEM_ADD_MSB(MemAddress);
5328
 
5329
    /* Wait until TXIS flag is set */
5330
    if (I2C_WaitOnTXISFlagUntilTimeout(hi2c, Timeout, Tickstart) != HAL_OK)
5331
    {
5332
      return HAL_ERROR;
5333
    }
5334
 
5335
    /* Send LSB of Memory Address */
5336
    hi2c->Instance->TXDR = I2C_MEM_ADD_LSB(MemAddress);
5337
  }
5338
 
5339
  /* Wait until TCR flag is set */
5340
  if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_TCR, RESET, Timeout, Tickstart) != HAL_OK)
5341
  {
5342
    return HAL_ERROR;
5343
  }
5344
 
5345
  return HAL_OK;
5346
}
5347
 
5348
/**
5349
  * @brief  Master sends target device address followed by internal memory address for read request.
5350
  * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
5351
  *                the configuration information for the specified I2C.
5352
  * @param  DevAddress Target device address: The device 7 bits address value
5353
  *         in datasheet must be shifted to the left before calling the interface
5354
  * @param  MemAddress Internal memory address
5355
  * @param  MemAddSize Size of internal memory address
5356
  * @param  Timeout Timeout duration
5357
  * @param  Tickstart Tick start value
5358
  * @retval HAL status
5359
  */
6 mjames 5360
static HAL_StatusTypeDef I2C_RequestMemoryRead(I2C_HandleTypeDef *hi2c, uint16_t DevAddress,
5361
                                               uint16_t MemAddress, uint16_t MemAddSize, uint32_t Timeout,
5362
                                               uint32_t Tickstart)
2 mjames 5363
{
5364
  I2C_TransferConfig(hi2c, DevAddress, (uint8_t)MemAddSize, I2C_SOFTEND_MODE, I2C_GENERATE_START_WRITE);
5365
 
5366
  /* Wait until TXIS flag is set */
5367
  if (I2C_WaitOnTXISFlagUntilTimeout(hi2c, Timeout, Tickstart) != HAL_OK)
5368
  {
5369
    return HAL_ERROR;
5370
  }
5371
 
5372
  /* If Memory address size is 8Bit */
5373
  if (MemAddSize == I2C_MEMADD_SIZE_8BIT)
5374
  {
5375
    /* Send Memory Address */
5376
    hi2c->Instance->TXDR = I2C_MEM_ADD_LSB(MemAddress);
5377
  }
5378
  /* If Memory address size is 16Bit */
5379
  else
5380
  {
5381
    /* Send MSB of Memory Address */
5382
    hi2c->Instance->TXDR = I2C_MEM_ADD_MSB(MemAddress);
5383
 
5384
    /* Wait until TXIS flag is set */
5385
    if (I2C_WaitOnTXISFlagUntilTimeout(hi2c, Timeout, Tickstart) != HAL_OK)
5386
    {
5387
      return HAL_ERROR;
5388
    }
5389
 
5390
    /* Send LSB of Memory Address */
5391
    hi2c->Instance->TXDR = I2C_MEM_ADD_LSB(MemAddress);
5392
  }
5393
 
5394
  /* Wait until TC flag is set */
5395
  if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_TC, RESET, Timeout, Tickstart) != HAL_OK)
5396
  {
5397
    return HAL_ERROR;
5398
  }
5399
 
5400
  return HAL_OK;
5401
}
5402
 
5403
/**
5404
  * @brief  I2C Address complete process callback.
5405
  * @param  hi2c I2C handle.
5406
  * @param  ITFlags Interrupt flags to handle.
5407
  * @retval None
5408
  */
5409
static void I2C_ITAddrCplt(I2C_HandleTypeDef *hi2c, uint32_t ITFlags)
5410
{
5411
  uint8_t transferdirection;
5412
  uint16_t slaveaddrcode;
5413
  uint16_t ownadd1code;
5414
  uint16_t ownadd2code;
5415
 
5416
  /* Prevent unused argument(s) compilation warning */
5417
  UNUSED(ITFlags);
5418
 
5419
  /* In case of Listen state, need to inform upper layer of address match code event */
5420
  if (((uint32_t)hi2c->State & (uint32_t)HAL_I2C_STATE_LISTEN) == (uint32_t)HAL_I2C_STATE_LISTEN)
5421
  {
5422
    transferdirection = I2C_GET_DIR(hi2c);
5423
    slaveaddrcode     = I2C_GET_ADDR_MATCH(hi2c);
5424
    ownadd1code       = I2C_GET_OWN_ADDRESS1(hi2c);
5425
    ownadd2code       = I2C_GET_OWN_ADDRESS2(hi2c);
5426
 
5427
    /* If 10bits addressing mode is selected */
5428
    if (hi2c->Init.AddressingMode == I2C_ADDRESSINGMODE_10BIT)
5429
    {
6 mjames 5430
      if ((slaveaddrcode & SLAVE_ADDR_MSK) == ((ownadd1code >> SLAVE_ADDR_SHIFT) & SLAVE_ADDR_MSK))
2 mjames 5431
      {
5432
        slaveaddrcode = ownadd1code;
5433
        hi2c->AddrEventCount++;
5434
        if (hi2c->AddrEventCount == 2U)
5435
        {
5436
          /* Reset Address Event counter */
5437
          hi2c->AddrEventCount = 0U;
5438
 
5439
          /* Clear ADDR flag */
5440
          __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_ADDR);
5441
 
5442
          /* Process Unlocked */
5443
          __HAL_UNLOCK(hi2c);
5444
 
5445
          /* Call Slave Addr callback */
5446
#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1)
5447
          hi2c->AddrCallback(hi2c, transferdirection, slaveaddrcode);
5448
#else
5449
          HAL_I2C_AddrCallback(hi2c, transferdirection, slaveaddrcode);
5450
#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */
5451
        }
5452
      }
5453
      else
5454
      {
5455
        slaveaddrcode = ownadd2code;
5456
 
5457
        /* Disable ADDR Interrupts */
5458
        I2C_Disable_IRQ(hi2c, I2C_XFER_LISTEN_IT);
5459
 
5460
        /* Process Unlocked */
5461
        __HAL_UNLOCK(hi2c);
5462
 
5463
        /* Call Slave Addr callback */
5464
#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1)
5465
        hi2c->AddrCallback(hi2c, transferdirection, slaveaddrcode);
5466
#else
5467
        HAL_I2C_AddrCallback(hi2c, transferdirection, slaveaddrcode);
5468
#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */
5469
      }
5470
    }
5471
    /* else 7 bits addressing mode is selected */
5472
    else
5473
    {
5474
      /* Disable ADDR Interrupts */
5475
      I2C_Disable_IRQ(hi2c, I2C_XFER_LISTEN_IT);
5476
 
5477
      /* Process Unlocked */
5478
      __HAL_UNLOCK(hi2c);
5479
 
5480
      /* Call Slave Addr callback */
5481
#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1)
5482
      hi2c->AddrCallback(hi2c, transferdirection, slaveaddrcode);
5483
#else
5484
      HAL_I2C_AddrCallback(hi2c, transferdirection, slaveaddrcode);
5485
#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */
5486
    }
5487
  }
5488
  /* Else clear address flag only */
5489
  else
5490
  {
5491
    /* Clear ADDR flag */
5492
    __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_ADDR);
5493
 
5494
    /* Process Unlocked */
5495
    __HAL_UNLOCK(hi2c);
5496
  }
5497
}
5498
 
5499
/**
5500
  * @brief  I2C Master sequential complete process.
5501
  * @param  hi2c I2C handle.
5502
  * @retval None
5503
  */
5504
static void I2C_ITMasterSeqCplt(I2C_HandleTypeDef *hi2c)
5505
{
5506
  /* Reset I2C handle mode */
5507
  hi2c->Mode = HAL_I2C_MODE_NONE;
5508
 
5509
  /* No Generate Stop, to permit restart mode */
5510
  /* The stop will be done at the end of transfer, when I2C_AUTOEND_MODE enable */
5511
  if (hi2c->State == HAL_I2C_STATE_BUSY_TX)
5512
  {
5513
    hi2c->State         = HAL_I2C_STATE_READY;
5514
    hi2c->PreviousState = I2C_STATE_MASTER_BUSY_TX;
5515
    hi2c->XferISR       = NULL;
5516
 
5517
    /* Disable Interrupts */
5518
    I2C_Disable_IRQ(hi2c, I2C_XFER_TX_IT);
5519
 
5520
    /* Process Unlocked */
5521
    __HAL_UNLOCK(hi2c);
5522
 
5523
    /* Call the corresponding callback to inform upper layer of End of Transfer */
5524
#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1)
5525
    hi2c->MasterTxCpltCallback(hi2c);
5526
#else
5527
    HAL_I2C_MasterTxCpltCallback(hi2c);
5528
#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */
5529
  }
5530
  /* hi2c->State == HAL_I2C_STATE_BUSY_RX */
5531
  else
5532
  {
5533
    hi2c->State         = HAL_I2C_STATE_READY;
5534
    hi2c->PreviousState = I2C_STATE_MASTER_BUSY_RX;
5535
    hi2c->XferISR       = NULL;
5536
 
5537
    /* Disable Interrupts */
5538
    I2C_Disable_IRQ(hi2c, I2C_XFER_RX_IT);
5539
 
5540
    /* Process Unlocked */
5541
    __HAL_UNLOCK(hi2c);
5542
 
5543
    /* Call the corresponding callback to inform upper layer of End of Transfer */
5544
#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1)
5545
    hi2c->MasterRxCpltCallback(hi2c);
5546
#else
5547
    HAL_I2C_MasterRxCpltCallback(hi2c);
5548
#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */
5549
  }
5550
}
5551
 
5552
/**
5553
  * @brief  I2C Slave sequential complete process.
5554
  * @param  hi2c I2C handle.
5555
  * @retval None
5556
  */
5557
static void I2C_ITSlaveSeqCplt(I2C_HandleTypeDef *hi2c)
5558
{
6 mjames 5559
  uint32_t tmpcr1value = READ_REG(hi2c->Instance->CR1);
5560
 
2 mjames 5561
  /* Reset I2C handle mode */
5562
  hi2c->Mode = HAL_I2C_MODE_NONE;
5563
 
6 mjames 5564
  /* If a DMA is ongoing, Update handle size context */
5565
  if (I2C_CHECK_IT_SOURCE(tmpcr1value, I2C_CR1_TXDMAEN) != RESET)
5566
  {
5567
    /* Disable DMA Request */
5568
    hi2c->Instance->CR1 &= ~I2C_CR1_TXDMAEN;
5569
  }
5570
  else if (I2C_CHECK_IT_SOURCE(tmpcr1value, I2C_CR1_RXDMAEN) != RESET)
5571
  {
5572
    /* Disable DMA Request */
5573
    hi2c->Instance->CR1 &= ~I2C_CR1_RXDMAEN;
5574
  }
5575
  else
5576
  {
5577
    /* Do nothing */
5578
  }
5579
 
2 mjames 5580
  if (hi2c->State == HAL_I2C_STATE_BUSY_TX_LISTEN)
5581
  {
5582
    /* Remove HAL_I2C_STATE_SLAVE_BUSY_TX, keep only HAL_I2C_STATE_LISTEN */
5583
    hi2c->State         = HAL_I2C_STATE_LISTEN;
5584
    hi2c->PreviousState = I2C_STATE_SLAVE_BUSY_TX;
5585
 
5586
    /* Disable Interrupts */
5587
    I2C_Disable_IRQ(hi2c, I2C_XFER_TX_IT);
5588
 
5589
    /* Process Unlocked */
5590
    __HAL_UNLOCK(hi2c);
5591
 
5592
    /* Call the corresponding callback to inform upper layer of End of Transfer */
5593
#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1)
5594
    hi2c->SlaveTxCpltCallback(hi2c);
5595
#else
5596
    HAL_I2C_SlaveTxCpltCallback(hi2c);
5597
#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */
5598
  }
5599
 
5600
  else if (hi2c->State == HAL_I2C_STATE_BUSY_RX_LISTEN)
5601
  {
5602
    /* Remove HAL_I2C_STATE_SLAVE_BUSY_RX, keep only HAL_I2C_STATE_LISTEN */
5603
    hi2c->State         = HAL_I2C_STATE_LISTEN;
5604
    hi2c->PreviousState = I2C_STATE_SLAVE_BUSY_RX;
5605
 
5606
    /* Disable Interrupts */
5607
    I2C_Disable_IRQ(hi2c, I2C_XFER_RX_IT);
5608
 
5609
    /* Process Unlocked */
5610
    __HAL_UNLOCK(hi2c);
5611
 
5612
    /* Call the corresponding callback to inform upper layer of End of Transfer */
5613
#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1)
5614
    hi2c->SlaveRxCpltCallback(hi2c);
5615
#else
5616
    HAL_I2C_SlaveRxCpltCallback(hi2c);
5617
#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */
5618
  }
5619
  else
5620
  {
5621
    /* Nothing to do */
5622
  }
5623
}
5624
 
5625
/**
5626
  * @brief  I2C Master complete process.
5627
  * @param  hi2c I2C handle.
5628
  * @param  ITFlags Interrupt flags to handle.
5629
  * @retval None
5630
  */
5631
static void I2C_ITMasterCplt(I2C_HandleTypeDef *hi2c, uint32_t ITFlags)
5632
{
5633
  uint32_t tmperror;
6 mjames 5634
  uint32_t tmpITFlags = ITFlags;
5635
  __IO uint32_t tmpreg;
2 mjames 5636
 
5637
  /* Clear STOP Flag */
5638
  __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF);
5639
 
6 mjames 5640
  /* Disable Interrupts and Store Previous state */
5641
  if (hi2c->State == HAL_I2C_STATE_BUSY_TX)
5642
  {
5643
    I2C_Disable_IRQ(hi2c, I2C_XFER_TX_IT);
5644
    hi2c->PreviousState = I2C_STATE_MASTER_BUSY_TX;
5645
  }
5646
  else if (hi2c->State == HAL_I2C_STATE_BUSY_RX)
5647
  {
5648
    I2C_Disable_IRQ(hi2c, I2C_XFER_RX_IT);
5649
    hi2c->PreviousState = I2C_STATE_MASTER_BUSY_RX;
5650
  }
5651
  else
5652
  {
5653
    /* Do nothing */
5654
  }
5655
 
2 mjames 5656
  /* Clear Configuration Register 2 */
5657
  I2C_RESET_CR2(hi2c);
5658
 
5659
  /* Reset handle parameters */
5660
  hi2c->XferISR       = NULL;
5661
  hi2c->XferOptions   = I2C_NO_OPTION_FRAME;
5662
 
6 mjames 5663
  if (I2C_CHECK_FLAG(tmpITFlags, I2C_FLAG_AF) != RESET)
2 mjames 5664
  {
5665
    /* Clear NACK Flag */
5666
    __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF);
5667
 
5668
    /* Set acknowledge error code */
5669
    hi2c->ErrorCode |= HAL_I2C_ERROR_AF;
5670
  }
5671
 
6 mjames 5672
  /* Fetch Last receive data if any */
5673
  if ((hi2c->State == HAL_I2C_STATE_ABORT) && (I2C_CHECK_FLAG(tmpITFlags, I2C_FLAG_RXNE) != RESET))
5674
  {
5675
    /* Read data from RXDR */
5676
    tmpreg = (uint8_t)hi2c->Instance->RXDR;
5677
    UNUSED(tmpreg);
5678
  }
5679
 
2 mjames 5680
  /* Flush TX register */
5681
  I2C_Flush_TXDR(hi2c);
5682
 
5683
  /* Store current volatile hi2c->ErrorCode, misra rule */
5684
  tmperror = hi2c->ErrorCode;
5685
 
5686
  /* Call the corresponding callback to inform upper layer of End of Transfer */
5687
  if ((hi2c->State == HAL_I2C_STATE_ABORT) || (tmperror != HAL_I2C_ERROR_NONE))
5688
  {
5689
    /* Call the corresponding callback to inform upper layer of End of Transfer */
5690
    I2C_ITError(hi2c, hi2c->ErrorCode);
5691
  }
5692
  /* hi2c->State == HAL_I2C_STATE_BUSY_TX */
5693
  else if (hi2c->State == HAL_I2C_STATE_BUSY_TX)
5694
  {
5695
    hi2c->State = HAL_I2C_STATE_READY;
6 mjames 5696
    hi2c->PreviousState = I2C_STATE_NONE;
2 mjames 5697
 
5698
    if (hi2c->Mode == HAL_I2C_MODE_MEM)
5699
    {
5700
      hi2c->Mode = HAL_I2C_MODE_NONE;
5701
 
5702
      /* Process Unlocked */
5703
      __HAL_UNLOCK(hi2c);
5704
 
5705
      /* Call the corresponding callback to inform upper layer of End of Transfer */
5706
#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1)
5707
      hi2c->MemTxCpltCallback(hi2c);
5708
#else
5709
      HAL_I2C_MemTxCpltCallback(hi2c);
5710
#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */
5711
    }
5712
    else
5713
    {
5714
      hi2c->Mode = HAL_I2C_MODE_NONE;
5715
 
5716
      /* Process Unlocked */
5717
      __HAL_UNLOCK(hi2c);
5718
 
5719
      /* Call the corresponding callback to inform upper layer of End of Transfer */
5720
#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1)
5721
      hi2c->MasterTxCpltCallback(hi2c);
5722
#else
5723
      HAL_I2C_MasterTxCpltCallback(hi2c);
5724
#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */
5725
    }
5726
  }
5727
  /* hi2c->State == HAL_I2C_STATE_BUSY_RX */
5728
  else if (hi2c->State == HAL_I2C_STATE_BUSY_RX)
5729
  {
5730
    hi2c->State = HAL_I2C_STATE_READY;
6 mjames 5731
    hi2c->PreviousState = I2C_STATE_NONE;
2 mjames 5732
 
5733
    if (hi2c->Mode == HAL_I2C_MODE_MEM)
5734
    {
5735
      hi2c->Mode = HAL_I2C_MODE_NONE;
5736
 
5737
      /* Process Unlocked */
5738
      __HAL_UNLOCK(hi2c);
5739
 
5740
      /* Call the corresponding callback to inform upper layer of End of Transfer */
5741
#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1)
5742
      hi2c->MemRxCpltCallback(hi2c);
5743
#else
5744
      HAL_I2C_MemRxCpltCallback(hi2c);
5745
#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */
5746
    }
5747
    else
5748
    {
5749
      hi2c->Mode = HAL_I2C_MODE_NONE;
5750
 
5751
      /* Process Unlocked */
5752
      __HAL_UNLOCK(hi2c);
5753
 
5754
      /* Call the corresponding callback to inform upper layer of End of Transfer */
5755
#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1)
5756
      hi2c->MasterRxCpltCallback(hi2c);
5757
#else
5758
      HAL_I2C_MasterRxCpltCallback(hi2c);
5759
#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */
5760
    }
5761
  }
5762
  else
5763
  {
5764
    /* Nothing to do */
5765
  }
5766
}
5767
 
5768
/**
5769
  * @brief  I2C Slave complete process.
5770
  * @param  hi2c I2C handle.
5771
  * @param  ITFlags Interrupt flags to handle.
5772
  * @retval None
5773
  */
5774
static void I2C_ITSlaveCplt(I2C_HandleTypeDef *hi2c, uint32_t ITFlags)
5775
{
5776
  uint32_t tmpcr1value = READ_REG(hi2c->Instance->CR1);
5777
  uint32_t tmpITFlags = ITFlags;
6 mjames 5778
  HAL_I2C_StateTypeDef tmpstate = hi2c->State;
2 mjames 5779
 
5780
  /* Clear STOP Flag */
5781
  __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF);
5782
 
6 mjames 5783
  /* Disable Interrupts and Store Previous state */
5784
  if ((tmpstate == HAL_I2C_STATE_BUSY_TX) || (tmpstate == HAL_I2C_STATE_BUSY_TX_LISTEN))
5785
  {
5786
    I2C_Disable_IRQ(hi2c, I2C_XFER_LISTEN_IT | I2C_XFER_TX_IT);
5787
    hi2c->PreviousState = I2C_STATE_SLAVE_BUSY_TX;
5788
  }
5789
  else if ((tmpstate == HAL_I2C_STATE_BUSY_RX) || (tmpstate == HAL_I2C_STATE_BUSY_RX_LISTEN))
5790
  {
5791
    I2C_Disable_IRQ(hi2c, I2C_XFER_LISTEN_IT | I2C_XFER_RX_IT);
5792
    hi2c->PreviousState = I2C_STATE_SLAVE_BUSY_RX;
5793
  }
5794
  else
5795
  {
5796
    /* Do nothing */
5797
  }
2 mjames 5798
 
5799
  /* Disable Address Acknowledge */
5800
  hi2c->Instance->CR2 |= I2C_CR2_NACK;
5801
 
5802
  /* Clear Configuration Register 2 */
5803
  I2C_RESET_CR2(hi2c);
5804
 
5805
  /* Flush TX register */
5806
  I2C_Flush_TXDR(hi2c);
5807
 
5808
  /* If a DMA is ongoing, Update handle size context */
5809
  if (I2C_CHECK_IT_SOURCE(tmpcr1value, I2C_CR1_TXDMAEN) != RESET)
5810
  {
6 mjames 5811
    /* Disable DMA Request */
5812
    hi2c->Instance->CR1 &= ~I2C_CR1_TXDMAEN;
5813
 
2 mjames 5814
    if (hi2c->hdmatx != NULL)
5815
    {
5816
      hi2c->XferCount = (uint16_t)__HAL_DMA_GET_COUNTER(hi2c->hdmatx);
5817
    }
5818
  }
5819
  else if (I2C_CHECK_IT_SOURCE(tmpcr1value, I2C_CR1_RXDMAEN) != RESET)
5820
  {
6 mjames 5821
    /* Disable DMA Request */
5822
    hi2c->Instance->CR1 &= ~I2C_CR1_RXDMAEN;
5823
 
2 mjames 5824
    if (hi2c->hdmarx != NULL)
5825
    {
5826
      hi2c->XferCount = (uint16_t)__HAL_DMA_GET_COUNTER(hi2c->hdmarx);
5827
    }
5828
  }
5829
  else
5830
  {
5831
    /* Do nothing */
5832
  }
5833
 
5834
  /* Store Last receive data if any */
5835
  if (I2C_CHECK_FLAG(tmpITFlags, I2C_FLAG_RXNE) != RESET)
5836
  {
5837
    /* Remove RXNE flag on temporary variable as read done */
5838
    tmpITFlags &= ~I2C_FLAG_RXNE;
5839
 
5840
    /* Read data from RXDR */
5841
    *hi2c->pBuffPtr = (uint8_t)hi2c->Instance->RXDR;
5842
 
5843
    /* Increment Buffer pointer */
5844
    hi2c->pBuffPtr++;
5845
 
5846
    if ((hi2c->XferSize > 0U))
5847
    {
5848
      hi2c->XferSize--;
5849
      hi2c->XferCount--;
5850
    }
5851
  }
5852
 
5853
  /* All data are not transferred, so set error code accordingly */
5854
  if (hi2c->XferCount != 0U)
5855
  {
5856
    /* Set ErrorCode corresponding to a Non-Acknowledge */
5857
    hi2c->ErrorCode |= HAL_I2C_ERROR_AF;
5858
  }
5859
 
5860
  hi2c->Mode = HAL_I2C_MODE_NONE;
5861
  hi2c->XferISR = NULL;
5862
 
5863
  if (hi2c->ErrorCode != HAL_I2C_ERROR_NONE)
5864
  {
5865
    /* Call the corresponding callback to inform upper layer of End of Transfer */
5866
    I2C_ITError(hi2c, hi2c->ErrorCode);
5867
 
5868
    /* Call the Listen Complete callback, to inform upper layer of the end of Listen usecase */
5869
    if (hi2c->State == HAL_I2C_STATE_LISTEN)
5870
    {
5871
      /* Call I2C Listen complete process */
5872
      I2C_ITListenCplt(hi2c, tmpITFlags);
5873
    }
5874
  }
5875
  else if (hi2c->XferOptions != I2C_NO_OPTION_FRAME)
5876
  {
6 mjames 5877
    /* Call the Sequential Complete callback, to inform upper layer of the end of Transfer */
2 mjames 5878
    I2C_ITSlaveSeqCplt(hi2c);
5879
 
5880
    hi2c->XferOptions = I2C_NO_OPTION_FRAME;
5881
    hi2c->State = HAL_I2C_STATE_READY;
6 mjames 5882
    hi2c->PreviousState = I2C_STATE_NONE;
2 mjames 5883
 
5884
    /* Process Unlocked */
5885
    __HAL_UNLOCK(hi2c);
5886
 
5887
    /* Call the Listen Complete callback, to inform upper layer of the end of Listen usecase */
5888
#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1)
5889
    hi2c->ListenCpltCallback(hi2c);
5890
#else
5891
    HAL_I2C_ListenCpltCallback(hi2c);
5892
#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */
5893
  }
5894
  /* Call the corresponding callback to inform upper layer of End of Transfer */
5895
  else if (hi2c->State == HAL_I2C_STATE_BUSY_RX)
5896
  {
5897
    hi2c->State = HAL_I2C_STATE_READY;
6 mjames 5898
    hi2c->PreviousState = I2C_STATE_NONE;
2 mjames 5899
 
5900
    /* Process Unlocked */
5901
    __HAL_UNLOCK(hi2c);
5902
 
5903
    /* Call the corresponding callback to inform upper layer of End of Transfer */
5904
#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1)
5905
    hi2c->SlaveRxCpltCallback(hi2c);
5906
#else
5907
    HAL_I2C_SlaveRxCpltCallback(hi2c);
5908
#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */
5909
  }
5910
  else
5911
  {
5912
    hi2c->State = HAL_I2C_STATE_READY;
6 mjames 5913
    hi2c->PreviousState = I2C_STATE_NONE;
2 mjames 5914
 
5915
    /* Process Unlocked */
5916
    __HAL_UNLOCK(hi2c);
5917
 
5918
    /* Call the corresponding callback to inform upper layer of End of Transfer */
5919
#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1)
5920
    hi2c->SlaveTxCpltCallback(hi2c);
5921
#else
5922
    HAL_I2C_SlaveTxCpltCallback(hi2c);
5923
#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */
5924
  }
5925
}
5926
 
5927
/**
5928
  * @brief  I2C Listen complete process.
5929
  * @param  hi2c I2C handle.
5930
  * @param  ITFlags Interrupt flags to handle.
5931
  * @retval None
5932
  */
5933
static void I2C_ITListenCplt(I2C_HandleTypeDef *hi2c, uint32_t ITFlags)
5934
{
5935
  /* Reset handle parameters */
5936
  hi2c->XferOptions = I2C_NO_OPTION_FRAME;
5937
  hi2c->PreviousState = I2C_STATE_NONE;
5938
  hi2c->State = HAL_I2C_STATE_READY;
5939
  hi2c->Mode = HAL_I2C_MODE_NONE;
5940
  hi2c->XferISR = NULL;
5941
 
5942
  /* Store Last receive data if any */
5943
  if (I2C_CHECK_FLAG(ITFlags, I2C_FLAG_RXNE) != RESET)
5944
  {
5945
    /* Read data from RXDR */
5946
    *hi2c->pBuffPtr = (uint8_t)hi2c->Instance->RXDR;
5947
 
5948
    /* Increment Buffer pointer */
5949
    hi2c->pBuffPtr++;
5950
 
5951
    if ((hi2c->XferSize > 0U))
5952
    {
5953
      hi2c->XferSize--;
5954
      hi2c->XferCount--;
5955
 
5956
      /* Set ErrorCode corresponding to a Non-Acknowledge */
5957
      hi2c->ErrorCode |= HAL_I2C_ERROR_AF;
5958
    }
5959
  }
5960
 
5961
  /* Disable all Interrupts*/
5962
  I2C_Disable_IRQ(hi2c, I2C_XFER_LISTEN_IT | I2C_XFER_RX_IT | I2C_XFER_TX_IT);
5963
 
5964
  /* Clear NACK Flag */
5965
  __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF);
5966
 
5967
  /* Process Unlocked */
5968
  __HAL_UNLOCK(hi2c);
5969
 
5970
  /* Call the Listen Complete callback, to inform upper layer of the end of Listen usecase */
5971
#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1)
5972
  hi2c->ListenCpltCallback(hi2c);
5973
#else
5974
  HAL_I2C_ListenCpltCallback(hi2c);
5975
#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */
5976
}
5977
 
5978
/**
5979
  * @brief  I2C interrupts error process.
5980
  * @param  hi2c I2C handle.
5981
  * @param  ErrorCode Error code to handle.
5982
  * @retval None
5983
  */
5984
static void I2C_ITError(I2C_HandleTypeDef *hi2c, uint32_t ErrorCode)
5985
{
5986
  HAL_I2C_StateTypeDef tmpstate = hi2c->State;
6 mjames 5987
  uint32_t tmppreviousstate;
2 mjames 5988
 
5989
  /* Reset handle parameters */
5990
  hi2c->Mode          = HAL_I2C_MODE_NONE;
5991
  hi2c->XferOptions   = I2C_NO_OPTION_FRAME;
5992
  hi2c->XferCount     = 0U;
5993
 
5994
  /* Set new error code */
5995
  hi2c->ErrorCode |= ErrorCode;
5996
 
5997
  /* Disable Interrupts */
5998
  if ((tmpstate == HAL_I2C_STATE_LISTEN)         ||
5999
      (tmpstate == HAL_I2C_STATE_BUSY_TX_LISTEN) ||
6000
      (tmpstate == HAL_I2C_STATE_BUSY_RX_LISTEN))
6001
  {
6002
    /* Disable all interrupts, except interrupts related to LISTEN state */
6003
    I2C_Disable_IRQ(hi2c, I2C_XFER_RX_IT | I2C_XFER_TX_IT);
6004
 
6005
    /* keep HAL_I2C_STATE_LISTEN if set */
6006
    hi2c->State         = HAL_I2C_STATE_LISTEN;
6007
    hi2c->XferISR       = I2C_Slave_ISR_IT;
6008
  }
6009
  else
6010
  {
6011
    /* Disable all interrupts */
6012
    I2C_Disable_IRQ(hi2c, I2C_XFER_LISTEN_IT | I2C_XFER_RX_IT | I2C_XFER_TX_IT);
6013
 
6 mjames 6014
    /* If state is an abort treatment on going, don't change state */
2 mjames 6015
    /* This change will be do later */
6016
    if (hi2c->State != HAL_I2C_STATE_ABORT)
6017
    {
6018
      /* Set HAL_I2C_STATE_READY */
6019
      hi2c->State         = HAL_I2C_STATE_READY;
6020
    }
6021
    hi2c->XferISR       = NULL;
6022
  }
6023
 
6024
  /* Abort DMA TX transfer if any */
6 mjames 6025
  tmppreviousstate = hi2c->PreviousState;
6026
  if ((hi2c->hdmatx != NULL) && ((tmppreviousstate == I2C_STATE_MASTER_BUSY_TX) || \
6027
                                 (tmppreviousstate == I2C_STATE_SLAVE_BUSY_TX)))
2 mjames 6028
  {
6 mjames 6029
    if ((hi2c->Instance->CR1 & I2C_CR1_TXDMAEN) == I2C_CR1_TXDMAEN)
6030
    {
6031
      hi2c->Instance->CR1 &= ~I2C_CR1_TXDMAEN;
6032
    }
2 mjames 6033
 
6 mjames 6034
    if (HAL_DMA_GetState(hi2c->hdmatx) != HAL_DMA_STATE_READY)
2 mjames 6035
    {
6036
      /* Set the I2C DMA Abort callback :
6037
       will lead to call HAL_I2C_ErrorCallback() at end of DMA abort procedure */
6038
      hi2c->hdmatx->XferAbortCallback = I2C_DMAAbort;
6039
 
6040
      /* Process Unlocked */
6041
      __HAL_UNLOCK(hi2c);
6042
 
6043
      /* Abort DMA TX */
6044
      if (HAL_DMA_Abort_IT(hi2c->hdmatx) != HAL_OK)
6045
      {
6046
        /* Call Directly XferAbortCallback function in case of error */
6047
        hi2c->hdmatx->XferAbortCallback(hi2c->hdmatx);
6048
      }
6049
    }
6 mjames 6050
    else
6051
    {
6052
      I2C_TreatErrorCallback(hi2c);
6053
    }
2 mjames 6054
  }
6055
  /* Abort DMA RX transfer if any */
6 mjames 6056
  else if ((hi2c->hdmarx != NULL) && ((tmppreviousstate == I2C_STATE_MASTER_BUSY_RX) || \
6057
                                      (tmppreviousstate == I2C_STATE_SLAVE_BUSY_RX)))
2 mjames 6058
  {
6 mjames 6059
    if ((hi2c->Instance->CR1 & I2C_CR1_RXDMAEN) == I2C_CR1_RXDMAEN)
6060
    {
6061
      hi2c->Instance->CR1 &= ~I2C_CR1_RXDMAEN;
6062
    }
2 mjames 6063
 
6 mjames 6064
    if (HAL_DMA_GetState(hi2c->hdmarx) != HAL_DMA_STATE_READY)
2 mjames 6065
    {
6066
      /* Set the I2C DMA Abort callback :
6067
        will lead to call HAL_I2C_ErrorCallback() at end of DMA abort procedure */
6068
      hi2c->hdmarx->XferAbortCallback = I2C_DMAAbort;
6069
 
6070
      /* Process Unlocked */
6071
      __HAL_UNLOCK(hi2c);
6072
 
6073
      /* Abort DMA RX */
6074
      if (HAL_DMA_Abort_IT(hi2c->hdmarx) != HAL_OK)
6075
      {
6076
        /* Call Directly hi2c->hdmarx->XferAbortCallback function in case of error */
6077
        hi2c->hdmarx->XferAbortCallback(hi2c->hdmarx);
6078
      }
6079
    }
6 mjames 6080
    else
6081
    {
6082
      I2C_TreatErrorCallback(hi2c);
6083
    }
2 mjames 6084
  }
6 mjames 6085
  else
2 mjames 6086
  {
6 mjames 6087
    I2C_TreatErrorCallback(hi2c);
6088
  }
6089
}
6090
 
6091
/**
6092
  * @brief  I2C Error callback treatment.
6093
  * @param  hi2c I2C handle.
6094
  * @retval None
6095
  */
6096
static void I2C_TreatErrorCallback(I2C_HandleTypeDef *hi2c)
6097
{
6098
  if (hi2c->State == HAL_I2C_STATE_ABORT)
6099
  {
2 mjames 6100
    hi2c->State = HAL_I2C_STATE_READY;
6 mjames 6101
    hi2c->PreviousState = I2C_STATE_NONE;
2 mjames 6102
 
6103
    /* Process Unlocked */
6104
    __HAL_UNLOCK(hi2c);
6105
 
6106
    /* Call the corresponding callback to inform upper layer of End of Transfer */
6107
#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1)
6108
    hi2c->AbortCpltCallback(hi2c);
6109
#else
6110
    HAL_I2C_AbortCpltCallback(hi2c);
6111
#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */
6112
  }
6113
  else
6114
  {
6 mjames 6115
    hi2c->PreviousState = I2C_STATE_NONE;
6116
 
2 mjames 6117
    /* Process Unlocked */
6118
    __HAL_UNLOCK(hi2c);
6119
 
6120
    /* Call the corresponding callback to inform upper layer of End of Transfer */
6121
#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1)
6122
    hi2c->ErrorCallback(hi2c);
6123
#else
6124
    HAL_I2C_ErrorCallback(hi2c);
6125
#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */
6126
  }
6127
}
6128
 
6129
/**
6130
  * @brief  I2C Tx data register flush process.
6131
  * @param  hi2c I2C handle.
6132
  * @retval None
6133
  */
6134
static void I2C_Flush_TXDR(I2C_HandleTypeDef *hi2c)
6135
{
6136
  /* If a pending TXIS flag is set */
6137
  /* Write a dummy data in TXDR to clear it */
6138
  if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_TXIS) != RESET)
6139
  {
6140
    hi2c->Instance->TXDR = 0x00U;
6141
  }
6142
 
6143
  /* Flush TX register if not empty */
6144
  if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_TXE) == RESET)
6145
  {
6146
    __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_TXE);
6147
  }
6148
}
6149
 
6150
/**
6151
  * @brief  DMA I2C master transmit process complete callback.
6152
  * @param  hdma DMA handle
6153
  * @retval None
6154
  */
6155
static void I2C_DMAMasterTransmitCplt(DMA_HandleTypeDef *hdma)
6156
{
6 mjames 6157
  /* Derogation MISRAC2012-Rule-11.5 */
6158
  I2C_HandleTypeDef *hi2c = (I2C_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent);
2 mjames 6159
 
6160
  /* Disable DMA Request */
6161
  hi2c->Instance->CR1 &= ~I2C_CR1_TXDMAEN;
6162
 
6163
  /* If last transfer, enable STOP interrupt */
6164
  if (hi2c->XferCount == 0U)
6165
  {
6166
    /* Enable STOP interrupt */
6167
    I2C_Enable_IRQ(hi2c, I2C_XFER_CPLT_IT);
6168
  }
6169
  /* else prepare a new DMA transfer and enable TCReload interrupt */
6170
  else
6171
  {
6172
    /* Update Buffer pointer */
6173
    hi2c->pBuffPtr += hi2c->XferSize;
6174
 
6175
    /* Set the XferSize to transfer */
6176
    if (hi2c->XferCount > MAX_NBYTE_SIZE)
6177
    {
6178
      hi2c->XferSize = MAX_NBYTE_SIZE;
6179
    }
6180
    else
6181
    {
6182
      hi2c->XferSize = hi2c->XferCount;
6183
    }
6184
 
6185
    /* Enable the DMA channel */
6 mjames 6186
    if (HAL_DMA_Start_IT(hi2c->hdmatx, (uint32_t)hi2c->pBuffPtr, (uint32_t)&hi2c->Instance->TXDR,
6187
                         hi2c->XferSize) != HAL_OK)
2 mjames 6188
    {
6189
      /* Call the corresponding callback to inform upper layer of End of Transfer */
6190
      I2C_ITError(hi2c, HAL_I2C_ERROR_DMA);
6191
    }
6192
    else
6193
    {
6194
      /* Enable TC interrupts */
6195
      I2C_Enable_IRQ(hi2c, I2C_XFER_RELOAD_IT);
6196
    }
6197
  }
6198
}
6199
 
6200
/**
6201
  * @brief  DMA I2C slave transmit process complete callback.
6202
  * @param  hdma DMA handle
6203
  * @retval None
6204
  */
6205
static void I2C_DMASlaveTransmitCplt(DMA_HandleTypeDef *hdma)
6206
{
6 mjames 6207
  /* Derogation MISRAC2012-Rule-11.5 */
6208
  I2C_HandleTypeDef *hi2c = (I2C_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent);
2 mjames 6209
  uint32_t tmpoptions = hi2c->XferOptions;
6210
 
6211
  if ((tmpoptions == I2C_NEXT_FRAME) || (tmpoptions == I2C_FIRST_FRAME))
6212
  {
6213
    /* Disable DMA Request */
6214
    hi2c->Instance->CR1 &= ~I2C_CR1_TXDMAEN;
6215
 
6216
    /* Last Byte is Transmitted */
6217
    /* Call I2C Slave Sequential complete process */
6218
    I2C_ITSlaveSeqCplt(hi2c);
6219
  }
6220
  else
6221
  {
6222
    /* No specific action, Master fully manage the generation of STOP condition */
6223
    /* Mean that this generation can arrive at any time, at the end or during DMA process */
6224
    /* So STOP condition should be manage through Interrupt treatment */
6225
  }
6226
}
6227
 
6228
/**
6229
  * @brief DMA I2C master receive process complete callback.
6230
  * @param  hdma DMA handle
6231
  * @retval None
6232
  */
6233
static void I2C_DMAMasterReceiveCplt(DMA_HandleTypeDef *hdma)
6234
{
6 mjames 6235
  /* Derogation MISRAC2012-Rule-11.5 */
6236
  I2C_HandleTypeDef *hi2c = (I2C_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent);
2 mjames 6237
 
6238
  /* Disable DMA Request */
6239
  hi2c->Instance->CR1 &= ~I2C_CR1_RXDMAEN;
6240
 
6241
  /* If last transfer, enable STOP interrupt */
6242
  if (hi2c->XferCount == 0U)
6243
  {
6244
    /* Enable STOP interrupt */
6245
    I2C_Enable_IRQ(hi2c, I2C_XFER_CPLT_IT);
6246
  }
6247
  /* else prepare a new DMA transfer and enable TCReload interrupt */
6248
  else
6249
  {
6250
    /* Update Buffer pointer */
6251
    hi2c->pBuffPtr += hi2c->XferSize;
6252
 
6253
    /* Set the XferSize to transfer */
6254
    if (hi2c->XferCount > MAX_NBYTE_SIZE)
6255
    {
6256
      hi2c->XferSize = MAX_NBYTE_SIZE;
6257
    }
6258
    else
6259
    {
6260
      hi2c->XferSize = hi2c->XferCount;
6261
    }
6262
 
6263
    /* Enable the DMA channel */
6 mjames 6264
    if (HAL_DMA_Start_IT(hi2c->hdmarx, (uint32_t)&hi2c->Instance->RXDR, (uint32_t)hi2c->pBuffPtr,
6265
                         hi2c->XferSize) != HAL_OK)
2 mjames 6266
    {
6267
      /* Call the corresponding callback to inform upper layer of End of Transfer */
6268
      I2C_ITError(hi2c, HAL_I2C_ERROR_DMA);
6269
    }
6270
    else
6271
    {
6272
      /* Enable TC interrupts */
6273
      I2C_Enable_IRQ(hi2c, I2C_XFER_RELOAD_IT);
6274
    }
6275
  }
6276
}
6277
 
6278
/**
6279
  * @brief  DMA I2C slave receive process complete callback.
6280
  * @param  hdma DMA handle
6281
  * @retval None
6282
  */
6283
static void I2C_DMASlaveReceiveCplt(DMA_HandleTypeDef *hdma)
6284
{
6 mjames 6285
  /* Derogation MISRAC2012-Rule-11.5 */
6286
  I2C_HandleTypeDef *hi2c = (I2C_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent);
2 mjames 6287
  uint32_t tmpoptions = hi2c->XferOptions;
6288
 
6289
  if ((__HAL_DMA_GET_COUNTER(hi2c->hdmarx) == 0U) && \
6290
      (tmpoptions != I2C_NO_OPTION_FRAME))
6291
  {
6292
    /* Disable DMA Request */
6293
    hi2c->Instance->CR1 &= ~I2C_CR1_RXDMAEN;
6294
 
6295
    /* Call I2C Slave Sequential complete process */
6296
    I2C_ITSlaveSeqCplt(hi2c);
6297
  }
6298
  else
6299
  {
6300
    /* No specific action, Master fully manage the generation of STOP condition */
6301
    /* Mean that this generation can arrive at any time, at the end or during DMA process */
6302
    /* So STOP condition should be manage through Interrupt treatment */
6303
  }
6304
}
6305
 
6306
/**
6307
  * @brief  DMA I2C communication error callback.
6308
  * @param hdma DMA handle
6309
  * @retval None
6310
  */
6311
static void I2C_DMAError(DMA_HandleTypeDef *hdma)
6312
{
6 mjames 6313
  /* Derogation MISRAC2012-Rule-11.5 */
6314
  I2C_HandleTypeDef *hi2c = (I2C_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent);
2 mjames 6315
 
6316
  /* Disable Acknowledge */
6317
  hi2c->Instance->CR2 |= I2C_CR2_NACK;
6318
 
6319
  /* Call the corresponding callback to inform upper layer of End of Transfer */
6320
  I2C_ITError(hi2c, HAL_I2C_ERROR_DMA);
6321
}
6322
 
6323
/**
6324
  * @brief DMA I2C communication abort callback
6325
  *        (To be called at end of DMA Abort procedure).
6326
  * @param hdma DMA handle.
6327
  * @retval None
6328
  */
6329
static void I2C_DMAAbort(DMA_HandleTypeDef *hdma)
6330
{
6 mjames 6331
  /* Derogation MISRAC2012-Rule-11.5 */
6332
  I2C_HandleTypeDef *hi2c = (I2C_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent);
2 mjames 6333
 
6334
  /* Reset AbortCpltCallback */
6 mjames 6335
  if (hi2c->hdmatx != NULL)
2 mjames 6336
  {
6 mjames 6337
    hi2c->hdmatx->XferAbortCallback = NULL;
2 mjames 6338
  }
6 mjames 6339
  if (hi2c->hdmarx != NULL)
2 mjames 6340
  {
6 mjames 6341
    hi2c->hdmarx->XferAbortCallback = NULL;
2 mjames 6342
  }
6 mjames 6343
 
6344
  I2C_TreatErrorCallback(hi2c);
2 mjames 6345
}
6346
 
6347
/**
6348
  * @brief  This function handles I2C Communication Timeout.
6349
  * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
6350
  *                the configuration information for the specified I2C.
6351
  * @param  Flag Specifies the I2C flag to check.
6352
  * @param  Status The new Flag status (SET or RESET).
6353
  * @param  Timeout Timeout duration
6354
  * @param  Tickstart Tick start value
6355
  * @retval HAL status
6356
  */
6 mjames 6357
static HAL_StatusTypeDef I2C_WaitOnFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Flag, FlagStatus Status,
6358
                                                    uint32_t Timeout, uint32_t Tickstart)
2 mjames 6359
{
6360
  while (__HAL_I2C_GET_FLAG(hi2c, Flag) == Status)
6361
  {
6362
    /* Check for the Timeout */
6363
    if (Timeout != HAL_MAX_DELAY)
6364
    {
6365
      if (((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U))
6366
      {
6367
        hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT;
6368
        hi2c->State = HAL_I2C_STATE_READY;
6369
        hi2c->Mode = HAL_I2C_MODE_NONE;
6370
 
6371
        /* Process Unlocked */
6372
        __HAL_UNLOCK(hi2c);
6373
        return HAL_ERROR;
6374
      }
6375
    }
6376
  }
6377
  return HAL_OK;
6378
}
6379
 
6380
/**
6381
  * @brief  This function handles I2C Communication Timeout for specific usage of TXIS flag.
6382
  * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
6383
  *                the configuration information for the specified I2C.
6384
  * @param  Timeout Timeout duration
6385
  * @param  Tickstart Tick start value
6386
  * @retval HAL status
6387
  */
6 mjames 6388
static HAL_StatusTypeDef I2C_WaitOnTXISFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Timeout,
6389
                                                        uint32_t Tickstart)
2 mjames 6390
{
6391
  while (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_TXIS) == RESET)
6392
  {
6393
    /* Check if a NACK is detected */
6394
    if (I2C_IsAcknowledgeFailed(hi2c, Timeout, Tickstart) != HAL_OK)
6395
    {
6396
      return HAL_ERROR;
6397
    }
6398
 
6399
    /* Check for the Timeout */
6400
    if (Timeout != HAL_MAX_DELAY)
6401
    {
6402
      if (((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U))
6403
      {
6404
        hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT;
6405
        hi2c->State = HAL_I2C_STATE_READY;
6406
        hi2c->Mode = HAL_I2C_MODE_NONE;
6407
 
6408
        /* Process Unlocked */
6409
        __HAL_UNLOCK(hi2c);
6410
 
6411
        return HAL_ERROR;
6412
      }
6413
    }
6414
  }
6415
  return HAL_OK;
6416
}
6417
 
6418
/**
6419
  * @brief  This function handles I2C Communication Timeout for specific usage of STOP flag.
6420
  * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
6421
  *                the configuration information for the specified I2C.
6422
  * @param  Timeout Timeout duration
6423
  * @param  Tickstart Tick start value
6424
  * @retval HAL status
6425
  */
6 mjames 6426
static HAL_StatusTypeDef I2C_WaitOnSTOPFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Timeout,
6427
                                                        uint32_t Tickstart)
2 mjames 6428
{
6429
  while (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_STOPF) == RESET)
6430
  {
6431
    /* Check if a NACK is detected */
6432
    if (I2C_IsAcknowledgeFailed(hi2c, Timeout, Tickstart) != HAL_OK)
6433
    {
6434
      return HAL_ERROR;
6435
    }
6436
 
6437
    /* Check for the Timeout */
6438
    if (((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U))
6439
    {
6440
      hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT;
6441
      hi2c->State = HAL_I2C_STATE_READY;
6442
      hi2c->Mode = HAL_I2C_MODE_NONE;
6443
 
6444
      /* Process Unlocked */
6445
      __HAL_UNLOCK(hi2c);
6446
 
6447
      return HAL_ERROR;
6448
    }
6449
  }
6450
  return HAL_OK;
6451
}
6452
 
6453
/**
6454
  * @brief  This function handles I2C Communication Timeout for specific usage of RXNE flag.
6455
  * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
6456
  *                the configuration information for the specified I2C.
6457
  * @param  Timeout Timeout duration
6458
  * @param  Tickstart Tick start value
6459
  * @retval HAL status
6460
  */
6 mjames 6461
static HAL_StatusTypeDef I2C_WaitOnRXNEFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Timeout,
6462
                                                        uint32_t Tickstart)
2 mjames 6463
{
6464
  while (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_RXNE) == RESET)
6465
  {
6466
    /* Check if a NACK is detected */
6467
    if (I2C_IsAcknowledgeFailed(hi2c, Timeout, Tickstart) != HAL_OK)
6468
    {
6469
      return HAL_ERROR;
6470
    }
6471
 
6472
    /* Check if a STOPF is detected */
6473
    if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_STOPF) == SET)
6474
    {
6475
      /* Check if an RXNE is pending */
6476
      /* Store Last receive data if any */
6477
      if ((__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_RXNE) == SET) && (hi2c->XferSize > 0U))
6478
      {
6479
        /* Return HAL_OK */
6480
        /* The Reading of data from RXDR will be done in caller function */
6481
        return HAL_OK;
6482
      }
6483
      else
6484
      {
6485
        /* Clear STOP Flag */
6486
        __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF);
6487
 
6488
        /* Clear Configuration Register 2 */
6489
        I2C_RESET_CR2(hi2c);
6490
 
6491
        hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
6492
        hi2c->State = HAL_I2C_STATE_READY;
6493
        hi2c->Mode = HAL_I2C_MODE_NONE;
6494
 
6495
        /* Process Unlocked */
6496
        __HAL_UNLOCK(hi2c);
6497
 
6498
        return HAL_ERROR;
6499
      }
6500
    }
6501
 
6502
    /* Check for the Timeout */
6503
    if (((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U))
6504
    {
6505
      hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT;
6506
      hi2c->State = HAL_I2C_STATE_READY;
6507
 
6508
      /* Process Unlocked */
6509
      __HAL_UNLOCK(hi2c);
6510
 
6511
      return HAL_ERROR;
6512
    }
6513
  }
6514
  return HAL_OK;
6515
}
6516
 
6517
/**
6518
  * @brief  This function handles Acknowledge failed detection during an I2C Communication.
6519
  * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
6520
  *                the configuration information for the specified I2C.
6521
  * @param  Timeout Timeout duration
6522
  * @param  Tickstart Tick start value
6523
  * @retval HAL status
6524
  */
6525
static HAL_StatusTypeDef I2C_IsAcknowledgeFailed(I2C_HandleTypeDef *hi2c, uint32_t Timeout, uint32_t Tickstart)
6526
{
6527
  if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_AF) == SET)
6528
  {
6 mjames 6529
    /* In case of Soft End condition, generate the STOP condition */
6530
    if (I2C_GET_STOP_MODE(hi2c) != I2C_AUTOEND_MODE)
6531
    {
6532
      /* Generate Stop */
6533
      hi2c->Instance->CR2 |= I2C_CR2_STOP;
6534
    }
2 mjames 6535
    /* Wait until STOP Flag is reset */
6536
    /* AutoEnd should be initiate after AF */
6537
    while (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_STOPF) == RESET)
6538
    {
6539
      /* Check for the Timeout */
6540
      if (Timeout != HAL_MAX_DELAY)
6541
      {
6542
        if (((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U))
6543
        {
6544
          hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT;
6545
          hi2c->State = HAL_I2C_STATE_READY;
6546
          hi2c->Mode = HAL_I2C_MODE_NONE;
6547
 
6548
          /* Process Unlocked */
6549
          __HAL_UNLOCK(hi2c);
6550
 
6551
          return HAL_ERROR;
6552
        }
6553
      }
6554
    }
6555
 
6556
    /* Clear NACKF Flag */
6557
    __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF);
6558
 
6559
    /* Clear STOP Flag */
6560
    __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF);
6561
 
6562
    /* Flush TX register */
6563
    I2C_Flush_TXDR(hi2c);
6564
 
6565
    /* Clear Configuration Register 2 */
6566
    I2C_RESET_CR2(hi2c);
6567
 
6568
    hi2c->ErrorCode |= HAL_I2C_ERROR_AF;
6569
    hi2c->State = HAL_I2C_STATE_READY;
6570
    hi2c->Mode = HAL_I2C_MODE_NONE;
6571
 
6572
    /* Process Unlocked */
6573
    __HAL_UNLOCK(hi2c);
6574
 
6575
    return HAL_ERROR;
6576
  }
6577
  return HAL_OK;
6578
}
6579
 
6580
/**
6581
  * @brief  Handles I2Cx communication when starting transfer or during transfer (TC or TCR flag are set).
6582
  * @param  hi2c I2C handle.
6583
  * @param  DevAddress Specifies the slave address to be programmed.
6584
  * @param  Size Specifies the number of bytes to be programmed.
6585
  *   This parameter must be a value between 0 and 255.
6586
  * @param  Mode New state of the I2C START condition generation.
6587
  *   This parameter can be one of the following values:
6588
  *     @arg @ref I2C_RELOAD_MODE Enable Reload mode .
6589
  *     @arg @ref I2C_AUTOEND_MODE Enable Automatic end mode.
6590
  *     @arg @ref I2C_SOFTEND_MODE Enable Software end mode.
6591
  * @param  Request New state of the I2C START condition generation.
6592
  *   This parameter can be one of the following values:
6593
  *     @arg @ref I2C_NO_STARTSTOP Don't Generate stop and start condition.
6594
  *     @arg @ref I2C_GENERATE_STOP Generate stop condition (Size should be set to 0).
6595
  *     @arg @ref I2C_GENERATE_START_READ Generate Restart for read request.
6596
  *     @arg @ref I2C_GENERATE_START_WRITE Generate Restart for write request.
6597
  * @retval None
6598
  */
6 mjames 6599
static void I2C_TransferConfig(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t Size, uint32_t Mode,
6600
                               uint32_t Request)
2 mjames 6601
{
6602
  /* Check the parameters */
6603
  assert_param(IS_I2C_ALL_INSTANCE(hi2c->Instance));
6604
  assert_param(IS_TRANSFER_MODE(Mode));
6605
  assert_param(IS_TRANSFER_REQUEST(Request));
6606
 
6607
  /* update CR2 register */
6 mjames 6608
  MODIFY_REG(hi2c->Instance->CR2,
6609
             ((I2C_CR2_SADD | I2C_CR2_NBYTES | I2C_CR2_RELOAD | I2C_CR2_AUTOEND | \
6610
               (I2C_CR2_RD_WRN & (uint32_t)(Request >> (31U - I2C_CR2_RD_WRN_Pos))) | \
6611
               I2C_CR2_START | I2C_CR2_STOP)), \
6612
             (uint32_t)(((uint32_t)DevAddress & I2C_CR2_SADD) | \
6613
                        (((uint32_t)Size << I2C_CR2_NBYTES_Pos) & I2C_CR2_NBYTES) | \
6614
                        (uint32_t)Mode | (uint32_t)Request));
2 mjames 6615
}
6616
 
6617
/**
6618
  * @brief  Manage the enabling of Interrupts.
6619
  * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
6620
  *                the configuration information for the specified I2C.
6621
  * @param  InterruptRequest Value of @ref I2C_Interrupt_configuration_definition.
6622
  * @retval None
6623
  */
6624
static void I2C_Enable_IRQ(I2C_HandleTypeDef *hi2c, uint16_t InterruptRequest)
6625
{
6626
  uint32_t tmpisr = 0U;
6627
 
6628
  if ((hi2c->XferISR == I2C_Master_ISR_DMA) || \
6629
      (hi2c->XferISR == I2C_Slave_ISR_DMA))
6630
  {
6631
    if ((InterruptRequest & I2C_XFER_LISTEN_IT) == I2C_XFER_LISTEN_IT)
6632
    {
6633
      /* Enable ERR, STOP, NACK and ADDR interrupts */
6634
      tmpisr |= I2C_IT_ADDRI | I2C_IT_STOPI | I2C_IT_NACKI | I2C_IT_ERRI;
6635
    }
6636
 
6 mjames 6637
    if (InterruptRequest == I2C_XFER_ERROR_IT)
2 mjames 6638
    {
6639
      /* Enable ERR and NACK interrupts */
6640
      tmpisr |= I2C_IT_ERRI | I2C_IT_NACKI;
6641
    }
6642
 
6 mjames 6643
    if (InterruptRequest == I2C_XFER_CPLT_IT)
2 mjames 6644
    {
6645
      /* Enable STOP interrupts */
6 mjames 6646
      tmpisr |= (I2C_IT_STOPI | I2C_IT_TCI);
2 mjames 6647
    }
6648
 
6 mjames 6649
    if (InterruptRequest == I2C_XFER_RELOAD_IT)
2 mjames 6650
    {
6651
      /* Enable TC interrupts */
6652
      tmpisr |= I2C_IT_TCI;
6653
    }
6654
  }
6655
  else
6656
  {
6657
    if ((InterruptRequest & I2C_XFER_LISTEN_IT) == I2C_XFER_LISTEN_IT)
6658
    {
6659
      /* Enable ERR, STOP, NACK, and ADDR interrupts */
6660
      tmpisr |= I2C_IT_ADDRI | I2C_IT_STOPI | I2C_IT_NACKI | I2C_IT_ERRI;
6661
    }
6662
 
6663
    if ((InterruptRequest & I2C_XFER_TX_IT) == I2C_XFER_TX_IT)
6664
    {
6665
      /* Enable ERR, TC, STOP, NACK and RXI interrupts */
6666
      tmpisr |= I2C_IT_ERRI | I2C_IT_TCI | I2C_IT_STOPI | I2C_IT_NACKI | I2C_IT_TXI;
6667
    }
6668
 
6669
    if ((InterruptRequest & I2C_XFER_RX_IT) == I2C_XFER_RX_IT)
6670
    {
6671
      /* Enable ERR, TC, STOP, NACK and TXI interrupts */
6672
      tmpisr |= I2C_IT_ERRI | I2C_IT_TCI | I2C_IT_STOPI | I2C_IT_NACKI | I2C_IT_RXI;
6673
    }
6674
 
6 mjames 6675
    if (InterruptRequest == I2C_XFER_CPLT_IT)
2 mjames 6676
    {
6677
      /* Enable STOP interrupts */
6678
      tmpisr |= I2C_IT_STOPI;
6679
    }
6680
  }
6681
 
6682
  /* Enable interrupts only at the end */
6683
  /* to avoid the risk of I2C interrupt handle execution before */
6684
  /* all interrupts requested done */
6685
  __HAL_I2C_ENABLE_IT(hi2c, tmpisr);
6686
}
6687
 
6688
/**
6689
  * @brief  Manage the disabling of Interrupts.
6690
  * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
6691
  *                the configuration information for the specified I2C.
6692
  * @param  InterruptRequest Value of @ref I2C_Interrupt_configuration_definition.
6693
  * @retval None
6694
  */
6695
static void I2C_Disable_IRQ(I2C_HandleTypeDef *hi2c, uint16_t InterruptRequest)
6696
{
6697
  uint32_t tmpisr = 0U;
6698
 
6699
  if ((InterruptRequest & I2C_XFER_TX_IT) == I2C_XFER_TX_IT)
6700
  {
6701
    /* Disable TC and TXI interrupts */
6702
    tmpisr |= I2C_IT_TCI | I2C_IT_TXI;
6703
 
6704
    if (((uint32_t)hi2c->State & (uint32_t)HAL_I2C_STATE_LISTEN) != (uint32_t)HAL_I2C_STATE_LISTEN)
6705
    {
6706
      /* Disable NACK and STOP interrupts */
6707
      tmpisr |= I2C_IT_STOPI | I2C_IT_NACKI | I2C_IT_ERRI;
6708
    }
6709
  }
6710
 
6711
  if ((InterruptRequest & I2C_XFER_RX_IT) == I2C_XFER_RX_IT)
6712
  {
6713
    /* Disable TC and RXI interrupts */
6714
    tmpisr |= I2C_IT_TCI | I2C_IT_RXI;
6715
 
6716
    if (((uint32_t)hi2c->State & (uint32_t)HAL_I2C_STATE_LISTEN) != (uint32_t)HAL_I2C_STATE_LISTEN)
6717
    {
6718
      /* Disable NACK and STOP interrupts */
6719
      tmpisr |= I2C_IT_STOPI | I2C_IT_NACKI | I2C_IT_ERRI;
6720
    }
6721
  }
6722
 
6723
  if ((InterruptRequest & I2C_XFER_LISTEN_IT) == I2C_XFER_LISTEN_IT)
6724
  {
6725
    /* Disable ADDR, NACK and STOP interrupts */
6726
    tmpisr |= I2C_IT_ADDRI | I2C_IT_STOPI | I2C_IT_NACKI | I2C_IT_ERRI;
6727
  }
6728
 
6 mjames 6729
  if (InterruptRequest == I2C_XFER_ERROR_IT)
2 mjames 6730
  {
6731
    /* Enable ERR and NACK interrupts */
6732
    tmpisr |= I2C_IT_ERRI | I2C_IT_NACKI;
6733
  }
6734
 
6 mjames 6735
  if (InterruptRequest == I2C_XFER_CPLT_IT)
2 mjames 6736
  {
6737
    /* Enable STOP interrupts */
6738
    tmpisr |= I2C_IT_STOPI;
6739
  }
6740
 
6 mjames 6741
  if (InterruptRequest == I2C_XFER_RELOAD_IT)
2 mjames 6742
  {
6743
    /* Enable TC interrupts */
6744
    tmpisr |= I2C_IT_TCI;
6745
  }
6746
 
6747
  /* Disable interrupts only at the end */
6748
  /* to avoid a breaking situation like at "t" time */
6749
  /* all disable interrupts request are not done */
6750
  __HAL_I2C_DISABLE_IT(hi2c, tmpisr);
6751
}
6752
 
6753
/**
6 mjames 6754
  * @brief  Convert I2Cx OTHER_xxx XferOptions to functional XferOptions.
2 mjames 6755
  * @param  hi2c I2C handle.
6756
  * @retval None
6757
  */
6758
static void I2C_ConvertOtherXferOptions(I2C_HandleTypeDef *hi2c)
6759
{
6760
  /* if user set XferOptions to I2C_OTHER_FRAME            */
6761
  /* it request implicitly to generate a restart condition */
6762
  /* set XferOptions to I2C_FIRST_FRAME                    */
6763
  if (hi2c->XferOptions == I2C_OTHER_FRAME)
6764
  {
6765
    hi2c->XferOptions = I2C_FIRST_FRAME;
6766
  }
6767
  /* else if user set XferOptions to I2C_OTHER_AND_LAST_FRAME */
6768
  /* it request implicitly to generate a restart condition    */
6769
  /* then generate a stop condition at the end of transfer    */
6770
  /* set XferOptions to I2C_FIRST_AND_LAST_FRAME              */
6771
  else if (hi2c->XferOptions == I2C_OTHER_AND_LAST_FRAME)
6772
  {
6773
    hi2c->XferOptions = I2C_FIRST_AND_LAST_FRAME;
6774
  }
6775
  else
6776
  {
6777
    /* Nothing to do */
6778
  }
6779
}
6780
 
6781
/**
6782
  * @}
6783
  */
6784
 
6785
#endif /* HAL_I2C_MODULE_ENABLED */
6786
/**
6787
  * @}
6788
  */
6789
 
6790
/**
6791
  * @}
6792
  */
6793
 
6794
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/