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