Subversion Repositories LedShow

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

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