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