You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

2813 regels
101 KiB

  1. /**
  2. ******************************************************************************
  3. * @file stm32f4xx_hal_fmpsmbus.c
  4. * @author MCD Application Team
  5. * @brief FMPSMBUS HAL module driver.
  6. * This file provides firmware functions to manage the following
  7. * functionalities of the System Management Bus (SMBus) peripheral,
  8. * based on I2C principles of operation :
  9. * + Initialization and de-initialization functions
  10. * + IO operation functions
  11. * + Peripheral State and Errors functions
  12. *
  13. ******************************************************************************
  14. * @attention
  15. *
  16. * Copyright (c) 2016 STMicroelectronics.
  17. * All rights reserved.
  18. *
  19. * This software is licensed under terms that can be found in the LICENSE file
  20. * in the root directory of this software component.
  21. * If no LICENSE file comes with this software, it is provided AS-IS.
  22. *
  23. ******************************************************************************
  24. @verbatim
  25. ==============================================================================
  26. ##### How to use this driver #####
  27. ==============================================================================
  28. [..]
  29. The FMPSMBUS HAL driver can be used as follows:
  30. (#) Declare a FMPSMBUS_HandleTypeDef handle structure, for example:
  31. FMPSMBUS_HandleTypeDef hfmpsmbus;
  32. (#)Initialize the FMPSMBUS low level resources by implementing the HAL_FMPSMBUS_MspInit() API:
  33. (##) Enable the FMPSMBUSx interface clock
  34. (##) FMPSMBUS pins configuration
  35. (+++) Enable the clock for the FMPSMBUS GPIOs
  36. (+++) Configure FMPSMBUS pins as alternate function open-drain
  37. (##) NVIC configuration if you need to use interrupt process
  38. (+++) Configure the FMPSMBUSx interrupt priority
  39. (+++) Enable the NVIC FMPSMBUS IRQ Channel
  40. (#) Configure the Communication Clock Timing, Bus Timeout, Own Address1, Master Addressing mode,
  41. Dual Addressing mode, Own Address2, Own Address2 Mask, General call, Nostretch mode,
  42. Peripheral mode and Packet Error Check mode in the hfmpsmbus Init structure.
  43. (#) Initialize the FMPSMBUS registers by calling the HAL_FMPSMBUS_Init() API:
  44. (++) These API's configures also the low level Hardware GPIO, CLOCK, CORTEX...etc)
  45. by calling the customized HAL_FMPSMBUS_MspInit(&hfmpsmbus) API.
  46. (#) To check if target device is ready for communication, use the function HAL_FMPSMBUS_IsDeviceReady()
  47. (#) For FMPSMBUS IO operations, only one mode of operations is available within this driver
  48. *** Interrupt mode IO operation ***
  49. ===================================
  50. [..]
  51. (+) Transmit in master/host FMPSMBUS mode an amount of data in non-blocking mode
  52. using HAL_FMPSMBUS_Master_Transmit_IT()
  53. (++) At transmission end of transfer HAL_FMPSMBUS_MasterTxCpltCallback() is executed and users can
  54. add their own code by customization of function pointer HAL_FMPSMBUS_MasterTxCpltCallback()
  55. (+) Receive in master/host FMPSMBUS mode an amount of data in non-blocking mode
  56. using HAL_FMPSMBUS_Master_Receive_IT()
  57. (++) At reception end of transfer HAL_FMPSMBUS_MasterRxCpltCallback() is executed and users can
  58. add their own code by customization of function pointer HAL_FMPSMBUS_MasterRxCpltCallback()
  59. (+) Abort a master/host FMPSMBUS process communication with Interrupt using HAL_FMPSMBUS_Master_Abort_IT()
  60. (++) The associated previous transfer callback is called at the end of abort process
  61. (++) mean HAL_FMPSMBUS_MasterTxCpltCallback() in case of previous state was master transmit
  62. (++) mean HAL_FMPSMBUS_MasterRxCpltCallback() in case of previous state was master receive
  63. (+) Enable/disable the Address listen mode in slave/device or host/slave FMPSMBUS mode
  64. using HAL_FMPSMBUS_EnableListen_IT() HAL_FMPSMBUS_DisableListen_IT()
  65. (++) When address slave/device FMPSMBUS match, HAL_FMPSMBUS_AddrCallback() is executed and users can
  66. add their own code to check the Address Match Code and the transmission direction
  67. request by master/host (Write/Read).
  68. (++) At Listen mode end HAL_FMPSMBUS_ListenCpltCallback() is executed and users can
  69. add their own code by customization of function pointer HAL_FMPSMBUS_ListenCpltCallback()
  70. (+) Transmit in slave/device FMPSMBUS mode an amount of data in non-blocking mode
  71. using HAL_FMPSMBUS_Slave_Transmit_IT()
  72. (++) At transmission end of transfer HAL_FMPSMBUS_SlaveTxCpltCallback() is executed and users can
  73. add their own code by customization of function pointer HAL_FMPSMBUS_SlaveTxCpltCallback()
  74. (+) Receive in slave/device FMPSMBUS mode an amount of data in non-blocking mode
  75. using HAL_FMPSMBUS_Slave_Receive_IT()
  76. (++) At reception end of transfer HAL_FMPSMBUS_SlaveRxCpltCallback() is executed and users can
  77. add their own code by customization of function pointer HAL_FMPSMBUS_SlaveRxCpltCallback()
  78. (+) Enable/Disable the FMPSMBUS alert mode using
  79. HAL_FMPSMBUS_EnableAlert_IT() or HAL_FMPSMBUS_DisableAlert_IT()
  80. (++) When FMPSMBUS Alert is generated HAL_FMPSMBUS_ErrorCallback() is executed and users can
  81. add their own code by customization of function pointer HAL_FMPSMBUS_ErrorCallback()
  82. to check the Alert Error Code using function HAL_FMPSMBUS_GetError()
  83. (+) Get HAL state machine or error values using HAL_FMPSMBUS_GetState() or HAL_FMPSMBUS_GetError()
  84. (+) In case of transfer Error, HAL_FMPSMBUS_ErrorCallback() function is executed and users can
  85. add their own code by customization of function pointer HAL_FMPSMBUS_ErrorCallback()
  86. to check the Error Code using function HAL_FMPSMBUS_GetError()
  87. *** FMPSMBUS HAL driver macros list ***
  88. ==================================
  89. [..]
  90. Below the list of most used macros in FMPSMBUS HAL driver.
  91. (+) __HAL_FMPSMBUS_ENABLE: Enable the FMPSMBUS peripheral
  92. (+) __HAL_FMPSMBUS_DISABLE: Disable the FMPSMBUS peripheral
  93. (+) __HAL_FMPSMBUS_GET_FLAG: Check whether the specified FMPSMBUS flag is set or not
  94. (+) __HAL_FMPSMBUS_CLEAR_FLAG: Clear the specified FMPSMBUS pending flag
  95. (+) __HAL_FMPSMBUS_ENABLE_IT: Enable the specified FMPSMBUS interrupt
  96. (+) __HAL_FMPSMBUS_DISABLE_IT: Disable the specified FMPSMBUS interrupt
  97. *** Callback registration ***
  98. =============================================
  99. [..]
  100. The compilation flag USE_HAL_FMPSMBUS_REGISTER_CALLBACKS when set to 1
  101. allows the user to configure dynamically the driver callbacks.
  102. Use Functions HAL_FMPSMBUS_RegisterCallback() or HAL_FMPSMBUS_RegisterAddrCallback()
  103. to register an interrupt callback.
  104. [..]
  105. Function HAL_FMPSMBUS_RegisterCallback() allows to register following callbacks:
  106. (+) MasterTxCpltCallback : callback for Master transmission end of transfer.
  107. (+) MasterRxCpltCallback : callback for Master reception end of transfer.
  108. (+) SlaveTxCpltCallback : callback for Slave transmission end of transfer.
  109. (+) SlaveRxCpltCallback : callback for Slave reception end of transfer.
  110. (+) ListenCpltCallback : callback for end of listen mode.
  111. (+) ErrorCallback : callback for error detection.
  112. (+) MspInitCallback : callback for Msp Init.
  113. (+) MspDeInitCallback : callback for Msp DeInit.
  114. This function takes as parameters the HAL peripheral handle, the Callback ID
  115. and a pointer to the user callback function.
  116. [..]
  117. For specific callback AddrCallback use dedicated register callbacks : HAL_FMPSMBUS_RegisterAddrCallback.
  118. [..]
  119. Use function HAL_FMPSMBUS_UnRegisterCallback to reset a callback to the default
  120. weak function.
  121. HAL_FMPSMBUS_UnRegisterCallback takes as parameters the HAL peripheral handle,
  122. and the Callback ID.
  123. This function allows to reset following callbacks:
  124. (+) MasterTxCpltCallback : callback for Master transmission end of transfer.
  125. (+) MasterRxCpltCallback : callback for Master reception end of transfer.
  126. (+) SlaveTxCpltCallback : callback for Slave transmission end of transfer.
  127. (+) SlaveRxCpltCallback : callback for Slave reception end of transfer.
  128. (+) ListenCpltCallback : callback for end of listen mode.
  129. (+) ErrorCallback : callback for error detection.
  130. (+) MspInitCallback : callback for Msp Init.
  131. (+) MspDeInitCallback : callback for Msp DeInit.
  132. [..]
  133. For callback AddrCallback use dedicated register callbacks : HAL_FMPSMBUS_UnRegisterAddrCallback.
  134. [..]
  135. By default, after the HAL_FMPSMBUS_Init() and when the state is HAL_FMPI2C_STATE_RESET
  136. all callbacks are set to the corresponding weak functions:
  137. examples HAL_FMPSMBUS_MasterTxCpltCallback(), HAL_FMPSMBUS_MasterRxCpltCallback().
  138. Exception done for MspInit and MspDeInit functions that are
  139. reset to the legacy weak functions in the HAL_FMPSMBUS_Init()/ HAL_FMPSMBUS_DeInit() only when
  140. these callbacks are null (not registered beforehand).
  141. If MspInit or MspDeInit are not null, the HAL_FMPSMBUS_Init()/ HAL_FMPSMBUS_DeInit()
  142. keep and use the user MspInit/MspDeInit callbacks (registered beforehand) whatever the state.
  143. [..]
  144. Callbacks can be registered/unregistered in HAL_FMPI2C_STATE_READY state only.
  145. Exception done MspInit/MspDeInit functions that can be registered/unregistered
  146. in HAL_FMPI2C_STATE_READY or HAL_FMPI2C_STATE_RESET state,
  147. thus registered (user) MspInit/DeInit callbacks can be used during the Init/DeInit.
  148. Then, the user first registers the MspInit/MspDeInit user callbacks
  149. using HAL_FMPSMBUS_RegisterCallback() before calling HAL_FMPSMBUS_DeInit()
  150. or HAL_FMPSMBUS_Init() function.
  151. [..]
  152. When the compilation flag USE_HAL_FMPSMBUS_REGISTER_CALLBACKS is set to 0 or
  153. not defined, the callback registration feature is not available and all callbacks
  154. are set to the corresponding weak functions.
  155. [..]
  156. (@) You can refer to the FMPSMBUS HAL driver header file for more useful macros
  157. @endverbatim
  158. */
  159. /* Includes ------------------------------------------------------------------*/
  160. #include "stm32f4xx_hal.h"
  161. /** @addtogroup STM32F4xx_HAL_Driver
  162. * @{
  163. */
  164. /** @defgroup FMPSMBUS FMPSMBUS
  165. * @brief FMPSMBUS HAL module driver
  166. * @{
  167. */
  168. #ifdef HAL_FMPSMBUS_MODULE_ENABLED
  169. #if defined(FMPI2C_CR1_PE)
  170. /* Private typedef -----------------------------------------------------------*/
  171. /* Private constants ---------------------------------------------------------*/
  172. /** @defgroup FMPSMBUS_Private_Define FMPSMBUS Private Constants
  173. * @{
  174. */
  175. #define TIMING_CLEAR_MASK (0xF0FFFFFFUL) /*!< FMPSMBUS TIMING clear register Mask */
  176. #define HAL_TIMEOUT_ADDR (10000U) /*!< 10 s */
  177. #define HAL_TIMEOUT_BUSY (25U) /*!< 25 ms */
  178. #define HAL_TIMEOUT_DIR (25U) /*!< 25 ms */
  179. #define HAL_TIMEOUT_RXNE (25U) /*!< 25 ms */
  180. #define HAL_TIMEOUT_STOPF (25U) /*!< 25 ms */
  181. #define HAL_TIMEOUT_TC (25U) /*!< 25 ms */
  182. #define HAL_TIMEOUT_TCR (25U) /*!< 25 ms */
  183. #define HAL_TIMEOUT_TXIS (25U) /*!< 25 ms */
  184. #define MAX_NBYTE_SIZE 255U
  185. /**
  186. * @}
  187. */
  188. /* Private macro -------------------------------------------------------------*/
  189. /* Private variables ---------------------------------------------------------*/
  190. /* Private function prototypes -----------------------------------------------*/
  191. /** @addtogroup FMPSMBUS_Private_Functions FMPSMBUS Private Functions
  192. * @{
  193. */
  194. /* Private functions to handle flags during polling transfer */
  195. static HAL_StatusTypeDef FMPSMBUS_WaitOnFlagUntilTimeout(FMPSMBUS_HandleTypeDef *hfmpsmbus, uint32_t Flag,
  196. FlagStatus Status, uint32_t Timeout);
  197. /* Private functions for FMPSMBUS transfer IRQ handler */
  198. static HAL_StatusTypeDef FMPSMBUS_Master_ISR(FMPSMBUS_HandleTypeDef *hfmpsmbus, uint32_t StatusFlags);
  199. static HAL_StatusTypeDef FMPSMBUS_Slave_ISR(FMPSMBUS_HandleTypeDef *hfmpsmbus, uint32_t StatusFlags);
  200. static void FMPSMBUS_ITErrorHandler(FMPSMBUS_HandleTypeDef *hfmpsmbus);
  201. /* Private functions to centralize the enable/disable of Interrupts */
  202. static void FMPSMBUS_Enable_IRQ(FMPSMBUS_HandleTypeDef *hfmpsmbus, uint32_t InterruptRequest);
  203. static void FMPSMBUS_Disable_IRQ(FMPSMBUS_HandleTypeDef *hfmpsmbus, uint32_t InterruptRequest);
  204. /* Private function to flush TXDR register */
  205. static void FMPSMBUS_Flush_TXDR(FMPSMBUS_HandleTypeDef *hfmpsmbus);
  206. /* Private function to handle start, restart or stop a transfer */
  207. static void FMPSMBUS_TransferConfig(FMPSMBUS_HandleTypeDef *hfmpsmbus, uint16_t DevAddress, uint8_t Size,
  208. uint32_t Mode, uint32_t Request);
  209. /* Private function to Convert Specific options */
  210. static void FMPSMBUS_ConvertOtherXferOptions(FMPSMBUS_HandleTypeDef *hfmpsmbus);
  211. /**
  212. * @}
  213. */
  214. /* Exported functions --------------------------------------------------------*/
  215. /** @defgroup FMPSMBUS_Exported_Functions FMPSMBUS Exported Functions
  216. * @{
  217. */
  218. /** @defgroup FMPSMBUS_Exported_Functions_Group1 Initialization and de-initialization functions
  219. * @brief Initialization and Configuration functions
  220. *
  221. @verbatim
  222. ===============================================================================
  223. ##### Initialization and de-initialization functions #####
  224. ===============================================================================
  225. [..] This subsection provides a set of functions allowing to initialize and
  226. deinitialize the FMPSMBUSx peripheral:
  227. (+) User must Implement HAL_FMPSMBUS_MspInit() function in which he configures
  228. all related peripherals resources (CLOCK, GPIO, IT and NVIC ).
  229. (+) Call the function HAL_FMPSMBUS_Init() to configure the selected device with
  230. the selected configuration:
  231. (++) Clock Timing
  232. (++) Bus Timeout
  233. (++) Analog Filer mode
  234. (++) Own Address 1
  235. (++) Addressing mode (Master, Slave)
  236. (++) Dual Addressing mode
  237. (++) Own Address 2
  238. (++) Own Address 2 Mask
  239. (++) General call mode
  240. (++) Nostretch mode
  241. (++) Packet Error Check mode
  242. (++) Peripheral mode
  243. (+) Call the function HAL_FMPSMBUS_DeInit() to restore the default configuration
  244. of the selected FMPSMBUSx peripheral.
  245. (+) Enable/Disable Analog/Digital filters with HAL_FMPSMBUS_ConfigAnalogFilter() and
  246. HAL_FMPSMBUS_ConfigDigitalFilter().
  247. @endverbatim
  248. * @{
  249. */
  250. /**
  251. * @brief Initialize the FMPSMBUS according to the specified parameters
  252. * in the FMPSMBUS_InitTypeDef and initialize the associated handle.
  253. * @param hfmpsmbus Pointer to a FMPSMBUS_HandleTypeDef structure that contains
  254. * the configuration information for the specified FMPSMBUS.
  255. * @retval HAL status
  256. */
  257. HAL_StatusTypeDef HAL_FMPSMBUS_Init(FMPSMBUS_HandleTypeDef *hfmpsmbus)
  258. {
  259. /* Check the FMPSMBUS handle allocation */
  260. if (hfmpsmbus == NULL)
  261. {
  262. return HAL_ERROR;
  263. }
  264. /* Check the parameters */
  265. assert_param(IS_FMPSMBUS_ALL_INSTANCE(hfmpsmbus->Instance));
  266. assert_param(IS_FMPSMBUS_ANALOG_FILTER(hfmpsmbus->Init.AnalogFilter));
  267. assert_param(IS_FMPSMBUS_OWN_ADDRESS1(hfmpsmbus->Init.OwnAddress1));
  268. assert_param(IS_FMPSMBUS_ADDRESSING_MODE(hfmpsmbus->Init.AddressingMode));
  269. assert_param(IS_FMPSMBUS_DUAL_ADDRESS(hfmpsmbus->Init.DualAddressMode));
  270. assert_param(IS_FMPSMBUS_OWN_ADDRESS2(hfmpsmbus->Init.OwnAddress2));
  271. assert_param(IS_FMPSMBUS_OWN_ADDRESS2_MASK(hfmpsmbus->Init.OwnAddress2Masks));
  272. assert_param(IS_FMPSMBUS_GENERAL_CALL(hfmpsmbus->Init.GeneralCallMode));
  273. assert_param(IS_FMPSMBUS_NO_STRETCH(hfmpsmbus->Init.NoStretchMode));
  274. assert_param(IS_FMPSMBUS_PEC(hfmpsmbus->Init.PacketErrorCheckMode));
  275. assert_param(IS_FMPSMBUS_PERIPHERAL_MODE(hfmpsmbus->Init.PeripheralMode));
  276. if (hfmpsmbus->State == HAL_FMPSMBUS_STATE_RESET)
  277. {
  278. /* Allocate lock resource and initialize it */
  279. hfmpsmbus->Lock = HAL_UNLOCKED;
  280. #if (USE_HAL_FMPSMBUS_REGISTER_CALLBACKS == 1)
  281. hfmpsmbus->MasterTxCpltCallback = HAL_FMPSMBUS_MasterTxCpltCallback; /* Legacy weak MasterTxCpltCallback */
  282. hfmpsmbus->MasterRxCpltCallback = HAL_FMPSMBUS_MasterRxCpltCallback; /* Legacy weak MasterRxCpltCallback */
  283. hfmpsmbus->SlaveTxCpltCallback = HAL_FMPSMBUS_SlaveTxCpltCallback; /* Legacy weak SlaveTxCpltCallback */
  284. hfmpsmbus->SlaveRxCpltCallback = HAL_FMPSMBUS_SlaveRxCpltCallback; /* Legacy weak SlaveRxCpltCallback */
  285. hfmpsmbus->ListenCpltCallback = HAL_FMPSMBUS_ListenCpltCallback; /* Legacy weak ListenCpltCallback */
  286. hfmpsmbus->ErrorCallback = HAL_FMPSMBUS_ErrorCallback; /* Legacy weak ErrorCallback */
  287. hfmpsmbus->AddrCallback = HAL_FMPSMBUS_AddrCallback; /* Legacy weak AddrCallback */
  288. if (hfmpsmbus->MspInitCallback == NULL)
  289. {
  290. hfmpsmbus->MspInitCallback = HAL_FMPSMBUS_MspInit; /* Legacy weak MspInit */
  291. }
  292. /* Init the low level hardware : GPIO, CLOCK, CORTEX...etc */
  293. hfmpsmbus->MspInitCallback(hfmpsmbus);
  294. #else
  295. /* Init the low level hardware : GPIO, CLOCK, NVIC */
  296. HAL_FMPSMBUS_MspInit(hfmpsmbus);
  297. #endif /* USE_HAL_FMPSMBUS_REGISTER_CALLBACKS */
  298. }
  299. hfmpsmbus->State = HAL_FMPSMBUS_STATE_BUSY;
  300. /* Disable the selected FMPSMBUS peripheral */
  301. __HAL_FMPSMBUS_DISABLE(hfmpsmbus);
  302. /*---------------------------- FMPSMBUSx TIMINGR Configuration ------------------------*/
  303. /* Configure FMPSMBUSx: Frequency range */
  304. hfmpsmbus->Instance->TIMINGR = hfmpsmbus->Init.Timing & TIMING_CLEAR_MASK;
  305. /*---------------------------- FMPSMBUSx TIMEOUTR Configuration ------------------------*/
  306. /* Configure FMPSMBUSx: Bus Timeout */
  307. hfmpsmbus->Instance->TIMEOUTR &= ~FMPI2C_TIMEOUTR_TIMOUTEN;
  308. hfmpsmbus->Instance->TIMEOUTR &= ~FMPI2C_TIMEOUTR_TEXTEN;
  309. hfmpsmbus->Instance->TIMEOUTR = hfmpsmbus->Init.SMBusTimeout;
  310. /*---------------------------- FMPSMBUSx OAR1 Configuration -----------------------*/
  311. /* Configure FMPSMBUSx: Own Address1 and ack own address1 mode */
  312. hfmpsmbus->Instance->OAR1 &= ~FMPI2C_OAR1_OA1EN;
  313. if (hfmpsmbus->Init.OwnAddress1 != 0UL)
  314. {
  315. if (hfmpsmbus->Init.AddressingMode == FMPSMBUS_ADDRESSINGMODE_7BIT)
  316. {
  317. hfmpsmbus->Instance->OAR1 = (FMPI2C_OAR1_OA1EN | hfmpsmbus->Init.OwnAddress1);
  318. }
  319. else /* FMPSMBUS_ADDRESSINGMODE_10BIT */
  320. {
  321. hfmpsmbus->Instance->OAR1 = (FMPI2C_OAR1_OA1EN | FMPI2C_OAR1_OA1MODE | hfmpsmbus->Init.OwnAddress1);
  322. }
  323. }
  324. /*---------------------------- FMPSMBUSx CR2 Configuration ------------------------*/
  325. /* Configure FMPSMBUSx: Addressing Master mode */
  326. if (hfmpsmbus->Init.AddressingMode == FMPSMBUS_ADDRESSINGMODE_10BIT)
  327. {
  328. hfmpsmbus->Instance->CR2 = (FMPI2C_CR2_ADD10);
  329. }
  330. /* Enable the AUTOEND by default, and enable NACK (should be disable only during Slave process) */
  331. /* AUTOEND and NACK bit will be manage during Transfer process */
  332. hfmpsmbus->Instance->CR2 |= (FMPI2C_CR2_AUTOEND | FMPI2C_CR2_NACK);
  333. /*---------------------------- FMPSMBUSx OAR2 Configuration -----------------------*/
  334. /* Configure FMPSMBUSx: Dual mode and Own Address2 */
  335. hfmpsmbus->Instance->OAR2 = (hfmpsmbus->Init.DualAddressMode | hfmpsmbus->Init.OwnAddress2 | \
  336. (hfmpsmbus->Init.OwnAddress2Masks << 8U));
  337. /*---------------------------- FMPSMBUSx CR1 Configuration ------------------------*/
  338. /* Configure FMPSMBUSx: Generalcall and NoStretch mode */
  339. hfmpsmbus->Instance->CR1 = (hfmpsmbus->Init.GeneralCallMode | hfmpsmbus->Init.NoStretchMode | \
  340. hfmpsmbus->Init.PacketErrorCheckMode | hfmpsmbus->Init.PeripheralMode | \
  341. hfmpsmbus->Init.AnalogFilter);
  342. /* Enable Slave Byte Control only in case of Packet Error Check is enabled
  343. and FMPSMBUS Peripheral is set in Slave mode */
  344. if ((hfmpsmbus->Init.PacketErrorCheckMode == FMPSMBUS_PEC_ENABLE) && \
  345. ((hfmpsmbus->Init.PeripheralMode == FMPSMBUS_PERIPHERAL_MODE_FMPSMBUS_SLAVE) || \
  346. (hfmpsmbus->Init.PeripheralMode == FMPSMBUS_PERIPHERAL_MODE_FMPSMBUS_SLAVE_ARP)))
  347. {
  348. hfmpsmbus->Instance->CR1 |= FMPI2C_CR1_SBC;
  349. }
  350. /* Enable the selected FMPSMBUS peripheral */
  351. __HAL_FMPSMBUS_ENABLE(hfmpsmbus);
  352. hfmpsmbus->ErrorCode = HAL_FMPSMBUS_ERROR_NONE;
  353. hfmpsmbus->PreviousState = HAL_FMPSMBUS_STATE_READY;
  354. hfmpsmbus->State = HAL_FMPSMBUS_STATE_READY;
  355. return HAL_OK;
  356. }
  357. /**
  358. * @brief DeInitialize the FMPSMBUS peripheral.
  359. * @param hfmpsmbus Pointer to a FMPSMBUS_HandleTypeDef structure that contains
  360. * the configuration information for the specified FMPSMBUS.
  361. * @retval HAL status
  362. */
  363. HAL_StatusTypeDef HAL_FMPSMBUS_DeInit(FMPSMBUS_HandleTypeDef *hfmpsmbus)
  364. {
  365. /* Check the FMPSMBUS handle allocation */
  366. if (hfmpsmbus == NULL)
  367. {
  368. return HAL_ERROR;
  369. }
  370. /* Check the parameters */
  371. assert_param(IS_FMPSMBUS_ALL_INSTANCE(hfmpsmbus->Instance));
  372. hfmpsmbus->State = HAL_FMPSMBUS_STATE_BUSY;
  373. /* Disable the FMPSMBUS Peripheral Clock */
  374. __HAL_FMPSMBUS_DISABLE(hfmpsmbus);
  375. #if (USE_HAL_FMPSMBUS_REGISTER_CALLBACKS == 1)
  376. if (hfmpsmbus->MspDeInitCallback == NULL)
  377. {
  378. hfmpsmbus->MspDeInitCallback = HAL_FMPSMBUS_MspDeInit; /* Legacy weak MspDeInit */
  379. }
  380. /* DeInit the low level hardware: GPIO, CLOCK, NVIC */
  381. hfmpsmbus->MspDeInitCallback(hfmpsmbus);
  382. #else
  383. /* DeInit the low level hardware: GPIO, CLOCK, NVIC */
  384. HAL_FMPSMBUS_MspDeInit(hfmpsmbus);
  385. #endif /* USE_HAL_FMPSMBUS_REGISTER_CALLBACKS */
  386. hfmpsmbus->ErrorCode = HAL_FMPSMBUS_ERROR_NONE;
  387. hfmpsmbus->PreviousState = HAL_FMPSMBUS_STATE_RESET;
  388. hfmpsmbus->State = HAL_FMPSMBUS_STATE_RESET;
  389. /* Release Lock */
  390. __HAL_UNLOCK(hfmpsmbus);
  391. return HAL_OK;
  392. }
  393. /**
  394. * @brief Initialize the FMPSMBUS MSP.
  395. * @param hfmpsmbus Pointer to a FMPSMBUS_HandleTypeDef structure that contains
  396. * the configuration information for the specified FMPSMBUS.
  397. * @retval None
  398. */
  399. __weak void HAL_FMPSMBUS_MspInit(FMPSMBUS_HandleTypeDef *hfmpsmbus)
  400. {
  401. /* Prevent unused argument(s) compilation warning */
  402. UNUSED(hfmpsmbus);
  403. /* NOTE : This function should not be modified, when the callback is needed,
  404. the HAL_FMPSMBUS_MspInit could be implemented in the user file
  405. */
  406. }
  407. /**
  408. * @brief DeInitialize the FMPSMBUS MSP.
  409. * @param hfmpsmbus Pointer to a FMPSMBUS_HandleTypeDef structure that contains
  410. * the configuration information for the specified FMPSMBUS.
  411. * @retval None
  412. */
  413. __weak void HAL_FMPSMBUS_MspDeInit(FMPSMBUS_HandleTypeDef *hfmpsmbus)
  414. {
  415. /* Prevent unused argument(s) compilation warning */
  416. UNUSED(hfmpsmbus);
  417. /* NOTE : This function should not be modified, when the callback is needed,
  418. the HAL_FMPSMBUS_MspDeInit could be implemented in the user file
  419. */
  420. }
  421. /**
  422. * @brief Configure Analog noise filter.
  423. * @param hfmpsmbus Pointer to a FMPSMBUS_HandleTypeDef structure that contains
  424. * the configuration information for the specified FMPSMBUS.
  425. * @param AnalogFilter This parameter can be one of the following values:
  426. * @arg @ref FMPSMBUS_ANALOGFILTER_ENABLE
  427. * @arg @ref FMPSMBUS_ANALOGFILTER_DISABLE
  428. * @retval HAL status
  429. */
  430. HAL_StatusTypeDef HAL_FMPSMBUS_ConfigAnalogFilter(FMPSMBUS_HandleTypeDef *hfmpsmbus, uint32_t AnalogFilter)
  431. {
  432. /* Check the parameters */
  433. assert_param(IS_FMPSMBUS_ALL_INSTANCE(hfmpsmbus->Instance));
  434. assert_param(IS_FMPSMBUS_ANALOG_FILTER(AnalogFilter));
  435. if (hfmpsmbus->State == HAL_FMPSMBUS_STATE_READY)
  436. {
  437. /* Process Locked */
  438. __HAL_LOCK(hfmpsmbus);
  439. hfmpsmbus->State = HAL_FMPSMBUS_STATE_BUSY;
  440. /* Disable the selected FMPSMBUS peripheral */
  441. __HAL_FMPSMBUS_DISABLE(hfmpsmbus);
  442. /* Reset ANOFF bit */
  443. hfmpsmbus->Instance->CR1 &= ~(FMPI2C_CR1_ANFOFF);
  444. /* Set analog filter bit*/
  445. hfmpsmbus->Instance->CR1 |= AnalogFilter;
  446. __HAL_FMPSMBUS_ENABLE(hfmpsmbus);
  447. hfmpsmbus->State = HAL_FMPSMBUS_STATE_READY;
  448. /* Process Unlocked */
  449. __HAL_UNLOCK(hfmpsmbus);
  450. return HAL_OK;
  451. }
  452. else
  453. {
  454. return HAL_BUSY;
  455. }
  456. }
  457. /**
  458. * @brief Configure Digital noise filter.
  459. * @param hfmpsmbus Pointer to a FMPSMBUS_HandleTypeDef structure that contains
  460. * the configuration information for the specified FMPSMBUS.
  461. * @param DigitalFilter Coefficient of digital noise filter between Min_Data=0x00 and Max_Data=0x0F.
  462. * @retval HAL status
  463. */
  464. HAL_StatusTypeDef HAL_FMPSMBUS_ConfigDigitalFilter(FMPSMBUS_HandleTypeDef *hfmpsmbus, uint32_t DigitalFilter)
  465. {
  466. uint32_t tmpreg;
  467. /* Check the parameters */
  468. assert_param(IS_FMPSMBUS_ALL_INSTANCE(hfmpsmbus->Instance));
  469. assert_param(IS_FMPSMBUS_DIGITAL_FILTER(DigitalFilter));
  470. if (hfmpsmbus->State == HAL_FMPSMBUS_STATE_READY)
  471. {
  472. /* Process Locked */
  473. __HAL_LOCK(hfmpsmbus);
  474. hfmpsmbus->State = HAL_FMPSMBUS_STATE_BUSY;
  475. /* Disable the selected FMPSMBUS peripheral */
  476. __HAL_FMPSMBUS_DISABLE(hfmpsmbus);
  477. /* Get the old register value */
  478. tmpreg = hfmpsmbus->Instance->CR1;
  479. /* Reset FMPI2C DNF bits [11:8] */
  480. tmpreg &= ~(FMPI2C_CR1_DNF);
  481. /* Set FMPI2Cx DNF coefficient */
  482. tmpreg |= DigitalFilter << FMPI2C_CR1_DNF_Pos;
  483. /* Store the new register value */
  484. hfmpsmbus->Instance->CR1 = tmpreg;
  485. __HAL_FMPSMBUS_ENABLE(hfmpsmbus);
  486. hfmpsmbus->State = HAL_FMPSMBUS_STATE_READY;
  487. /* Process Unlocked */
  488. __HAL_UNLOCK(hfmpsmbus);
  489. return HAL_OK;
  490. }
  491. else
  492. {
  493. return HAL_BUSY;
  494. }
  495. }
  496. #if (USE_HAL_FMPSMBUS_REGISTER_CALLBACKS == 1)
  497. /**
  498. * @brief Register a User FMPSMBUS Callback
  499. * To be used instead of the weak predefined callback
  500. * @note The HAL_FMPSMBUS_RegisterCallback() may be called before HAL_FMPSMBUS_Init() in
  501. * HAL_FMPSMBUS_STATE_RESET to register callbacks for HAL_FMPSMBUS_MSPINIT_CB_ID and
  502. * HAL_FMPSMBUS_MSPDEINIT_CB_ID.
  503. * @param hfmpsmbus Pointer to a FMPSMBUS_HandleTypeDef structure that contains
  504. * the configuration information for the specified FMPSMBUS.
  505. * @param CallbackID ID of the callback to be registered
  506. * This parameter can be one of the following values:
  507. * @arg @ref HAL_FMPSMBUS_MASTER_TX_COMPLETE_CB_ID Master Tx Transfer completed callback ID
  508. * @arg @ref HAL_FMPSMBUS_MASTER_RX_COMPLETE_CB_ID Master Rx Transfer completed callback ID
  509. * @arg @ref HAL_FMPSMBUS_SLAVE_TX_COMPLETE_CB_ID Slave Tx Transfer completed callback ID
  510. * @arg @ref HAL_FMPSMBUS_SLAVE_RX_COMPLETE_CB_ID Slave Rx Transfer completed callback ID
  511. * @arg @ref HAL_FMPSMBUS_LISTEN_COMPLETE_CB_ID Listen Complete callback ID
  512. * @arg @ref HAL_FMPSMBUS_ERROR_CB_ID Error callback ID
  513. * @arg @ref HAL_FMPSMBUS_MSPINIT_CB_ID MspInit callback ID
  514. * @arg @ref HAL_FMPSMBUS_MSPDEINIT_CB_ID MspDeInit callback ID
  515. * @param pCallback pointer to the Callback function
  516. * @retval HAL status
  517. */
  518. HAL_StatusTypeDef HAL_FMPSMBUS_RegisterCallback(FMPSMBUS_HandleTypeDef *hfmpsmbus,
  519. HAL_FMPSMBUS_CallbackIDTypeDef CallbackID,
  520. pFMPSMBUS_CallbackTypeDef pCallback)
  521. {
  522. HAL_StatusTypeDef status = HAL_OK;
  523. if (pCallback == NULL)
  524. {
  525. /* Update the error code */
  526. hfmpsmbus->ErrorCode |= HAL_FMPSMBUS_ERROR_INVALID_CALLBACK;
  527. return HAL_ERROR;
  528. }
  529. if (HAL_FMPSMBUS_STATE_READY == hfmpsmbus->State)
  530. {
  531. switch (CallbackID)
  532. {
  533. case HAL_FMPSMBUS_MASTER_TX_COMPLETE_CB_ID :
  534. hfmpsmbus->MasterTxCpltCallback = pCallback;
  535. break;
  536. case HAL_FMPSMBUS_MASTER_RX_COMPLETE_CB_ID :
  537. hfmpsmbus->MasterRxCpltCallback = pCallback;
  538. break;
  539. case HAL_FMPSMBUS_SLAVE_TX_COMPLETE_CB_ID :
  540. hfmpsmbus->SlaveTxCpltCallback = pCallback;
  541. break;
  542. case HAL_FMPSMBUS_SLAVE_RX_COMPLETE_CB_ID :
  543. hfmpsmbus->SlaveRxCpltCallback = pCallback;
  544. break;
  545. case HAL_FMPSMBUS_LISTEN_COMPLETE_CB_ID :
  546. hfmpsmbus->ListenCpltCallback = pCallback;
  547. break;
  548. case HAL_FMPSMBUS_ERROR_CB_ID :
  549. hfmpsmbus->ErrorCallback = pCallback;
  550. break;
  551. case HAL_FMPSMBUS_MSPINIT_CB_ID :
  552. hfmpsmbus->MspInitCallback = pCallback;
  553. break;
  554. case HAL_FMPSMBUS_MSPDEINIT_CB_ID :
  555. hfmpsmbus->MspDeInitCallback = pCallback;
  556. break;
  557. default :
  558. /* Update the error code */
  559. hfmpsmbus->ErrorCode |= HAL_FMPSMBUS_ERROR_INVALID_CALLBACK;
  560. /* Return error status */
  561. status = HAL_ERROR;
  562. break;
  563. }
  564. }
  565. else if (HAL_FMPSMBUS_STATE_RESET == hfmpsmbus->State)
  566. {
  567. switch (CallbackID)
  568. {
  569. case HAL_FMPSMBUS_MSPINIT_CB_ID :
  570. hfmpsmbus->MspInitCallback = pCallback;
  571. break;
  572. case HAL_FMPSMBUS_MSPDEINIT_CB_ID :
  573. hfmpsmbus->MspDeInitCallback = pCallback;
  574. break;
  575. default :
  576. /* Update the error code */
  577. hfmpsmbus->ErrorCode |= HAL_FMPSMBUS_ERROR_INVALID_CALLBACK;
  578. /* Return error status */
  579. status = HAL_ERROR;
  580. break;
  581. }
  582. }
  583. else
  584. {
  585. /* Update the error code */
  586. hfmpsmbus->ErrorCode |= HAL_FMPSMBUS_ERROR_INVALID_CALLBACK;
  587. /* Return error status */
  588. status = HAL_ERROR;
  589. }
  590. return status;
  591. }
  592. /**
  593. * @brief Unregister an FMPSMBUS Callback
  594. * FMPSMBUS callback is redirected to the weak predefined callback
  595. * @note The HAL_FMPSMBUS_UnRegisterCallback() may be called before HAL_FMPSMBUS_Init() in
  596. * HAL_FMPSMBUS_STATE_RESET to un-register callbacks for HAL_FMPSMBUS_MSPINIT_CB_ID and
  597. * HAL_FMPSMBUS_MSPDEINIT_CB_ID
  598. * @param hfmpsmbus Pointer to a FMPSMBUS_HandleTypeDef structure that contains
  599. * the configuration information for the specified FMPSMBUS.
  600. * @param CallbackID ID of the callback to be unregistered
  601. * This parameter can be one of the following values:
  602. * This parameter can be one of the following values:
  603. * @arg @ref HAL_FMPSMBUS_MASTER_TX_COMPLETE_CB_ID Master Tx Transfer completed callback ID
  604. * @arg @ref HAL_FMPSMBUS_MASTER_RX_COMPLETE_CB_ID Master Rx Transfer completed callback ID
  605. * @arg @ref HAL_FMPSMBUS_SLAVE_TX_COMPLETE_CB_ID Slave Tx Transfer completed callback ID
  606. * @arg @ref HAL_FMPSMBUS_SLAVE_RX_COMPLETE_CB_ID Slave Rx Transfer completed callback ID
  607. * @arg @ref HAL_FMPSMBUS_LISTEN_COMPLETE_CB_ID Listen Complete callback ID
  608. * @arg @ref HAL_FMPSMBUS_ERROR_CB_ID Error callback ID
  609. * @arg @ref HAL_FMPSMBUS_MSPINIT_CB_ID MspInit callback ID
  610. * @arg @ref HAL_FMPSMBUS_MSPDEINIT_CB_ID MspDeInit callback ID
  611. * @retval HAL status
  612. */
  613. HAL_StatusTypeDef HAL_FMPSMBUS_UnRegisterCallback(FMPSMBUS_HandleTypeDef *hfmpsmbus,
  614. HAL_FMPSMBUS_CallbackIDTypeDef CallbackID)
  615. {
  616. HAL_StatusTypeDef status = HAL_OK;
  617. if (HAL_FMPSMBUS_STATE_READY == hfmpsmbus->State)
  618. {
  619. switch (CallbackID)
  620. {
  621. case HAL_FMPSMBUS_MASTER_TX_COMPLETE_CB_ID :
  622. hfmpsmbus->MasterTxCpltCallback = HAL_FMPSMBUS_MasterTxCpltCallback; /* Legacy weak MasterTxCpltCallback */
  623. break;
  624. case HAL_FMPSMBUS_MASTER_RX_COMPLETE_CB_ID :
  625. hfmpsmbus->MasterRxCpltCallback = HAL_FMPSMBUS_MasterRxCpltCallback; /* Legacy weak MasterRxCpltCallback */
  626. break;
  627. case HAL_FMPSMBUS_SLAVE_TX_COMPLETE_CB_ID :
  628. hfmpsmbus->SlaveTxCpltCallback = HAL_FMPSMBUS_SlaveTxCpltCallback; /* Legacy weak SlaveTxCpltCallback */
  629. break;
  630. case HAL_FMPSMBUS_SLAVE_RX_COMPLETE_CB_ID :
  631. hfmpsmbus->SlaveRxCpltCallback = HAL_FMPSMBUS_SlaveRxCpltCallback; /* Legacy weak SlaveRxCpltCallback */
  632. break;
  633. case HAL_FMPSMBUS_LISTEN_COMPLETE_CB_ID :
  634. hfmpsmbus->ListenCpltCallback = HAL_FMPSMBUS_ListenCpltCallback; /* Legacy weak ListenCpltCallback */
  635. break;
  636. case HAL_FMPSMBUS_ERROR_CB_ID :
  637. hfmpsmbus->ErrorCallback = HAL_FMPSMBUS_ErrorCallback; /* Legacy weak ErrorCallback */
  638. break;
  639. case HAL_FMPSMBUS_MSPINIT_CB_ID :
  640. hfmpsmbus->MspInitCallback = HAL_FMPSMBUS_MspInit; /* Legacy weak MspInit */
  641. break;
  642. case HAL_FMPSMBUS_MSPDEINIT_CB_ID :
  643. hfmpsmbus->MspDeInitCallback = HAL_FMPSMBUS_MspDeInit; /* Legacy weak MspDeInit */
  644. break;
  645. default :
  646. /* Update the error code */
  647. hfmpsmbus->ErrorCode |= HAL_FMPSMBUS_ERROR_INVALID_CALLBACK;
  648. /* Return error status */
  649. status = HAL_ERROR;
  650. break;
  651. }
  652. }
  653. else if (HAL_FMPSMBUS_STATE_RESET == hfmpsmbus->State)
  654. {
  655. switch (CallbackID)
  656. {
  657. case HAL_FMPSMBUS_MSPINIT_CB_ID :
  658. hfmpsmbus->MspInitCallback = HAL_FMPSMBUS_MspInit; /* Legacy weak MspInit */
  659. break;
  660. case HAL_FMPSMBUS_MSPDEINIT_CB_ID :
  661. hfmpsmbus->MspDeInitCallback = HAL_FMPSMBUS_MspDeInit; /* Legacy weak MspDeInit */
  662. break;
  663. default :
  664. /* Update the error code */
  665. hfmpsmbus->ErrorCode |= HAL_FMPSMBUS_ERROR_INVALID_CALLBACK;
  666. /* Return error status */
  667. status = HAL_ERROR;
  668. break;
  669. }
  670. }
  671. else
  672. {
  673. /* Update the error code */
  674. hfmpsmbus->ErrorCode |= HAL_FMPSMBUS_ERROR_INVALID_CALLBACK;
  675. /* Return error status */
  676. status = HAL_ERROR;
  677. }
  678. return status;
  679. }
  680. /**
  681. * @brief Register the Slave Address Match FMPSMBUS Callback
  682. * To be used instead of the weak HAL_FMPSMBUS_AddrCallback() predefined callback
  683. * @param hfmpsmbus Pointer to a FMPSMBUS_HandleTypeDef structure that contains
  684. * the configuration information for the specified FMPSMBUS.
  685. * @param pCallback pointer to the Address Match Callback function
  686. * @retval HAL status
  687. */
  688. HAL_StatusTypeDef HAL_FMPSMBUS_RegisterAddrCallback(FMPSMBUS_HandleTypeDef *hfmpsmbus,
  689. pFMPSMBUS_AddrCallbackTypeDef pCallback)
  690. {
  691. HAL_StatusTypeDef status = HAL_OK;
  692. if (pCallback == NULL)
  693. {
  694. /* Update the error code */
  695. hfmpsmbus->ErrorCode |= HAL_FMPSMBUS_ERROR_INVALID_CALLBACK;
  696. return HAL_ERROR;
  697. }
  698. if (HAL_FMPSMBUS_STATE_READY == hfmpsmbus->State)
  699. {
  700. hfmpsmbus->AddrCallback = pCallback;
  701. }
  702. else
  703. {
  704. /* Update the error code */
  705. hfmpsmbus->ErrorCode |= HAL_FMPSMBUS_ERROR_INVALID_CALLBACK;
  706. /* Return error status */
  707. status = HAL_ERROR;
  708. }
  709. return status;
  710. }
  711. /**
  712. * @brief UnRegister the Slave Address Match FMPSMBUS Callback
  713. * Info Ready FMPSMBUS Callback is redirected to the weak HAL_FMPSMBUS_AddrCallback() predefined callback
  714. * @param hfmpsmbus Pointer to a FMPSMBUS_HandleTypeDef structure that contains
  715. * the configuration information for the specified FMPSMBUS.
  716. * @retval HAL status
  717. */
  718. HAL_StatusTypeDef HAL_FMPSMBUS_UnRegisterAddrCallback(FMPSMBUS_HandleTypeDef *hfmpsmbus)
  719. {
  720. HAL_StatusTypeDef status = HAL_OK;
  721. if (HAL_FMPSMBUS_STATE_READY == hfmpsmbus->State)
  722. {
  723. hfmpsmbus->AddrCallback = HAL_FMPSMBUS_AddrCallback; /* Legacy weak AddrCallback */
  724. }
  725. else
  726. {
  727. /* Update the error code */
  728. hfmpsmbus->ErrorCode |= HAL_FMPSMBUS_ERROR_INVALID_CALLBACK;
  729. /* Return error status */
  730. status = HAL_ERROR;
  731. }
  732. return status;
  733. }
  734. #endif /* USE_HAL_FMPSMBUS_REGISTER_CALLBACKS */
  735. /**
  736. * @}
  737. */
  738. /** @defgroup FMPSMBUS_Exported_Functions_Group2 Input and Output operation functions
  739. * @brief Data transfers functions
  740. *
  741. @verbatim
  742. ===============================================================================
  743. ##### IO operation functions #####
  744. ===============================================================================
  745. [..]
  746. This subsection provides a set of functions allowing to manage the FMPSMBUS data
  747. transfers.
  748. (#) Blocking mode function to check if device is ready for usage is :
  749. (++) HAL_FMPSMBUS_IsDeviceReady()
  750. (#) There is only one mode of transfer:
  751. (++) Non-Blocking mode : The communication is performed using Interrupts.
  752. These functions return the status of the transfer startup.
  753. The end of the data processing will be indicated through the
  754. dedicated FMPSMBUS IRQ when using Interrupt mode.
  755. (#) Non-Blocking mode functions with Interrupt are :
  756. (++) HAL_FMPSMBUS_Master_Transmit_IT()
  757. (++) HAL_FMPSMBUS_Master_Receive_IT()
  758. (++) HAL_FMPSMBUS_Slave_Transmit_IT()
  759. (++) HAL_FMPSMBUS_Slave_Receive_IT()
  760. (++) HAL_FMPSMBUS_EnableListen_IT() or alias HAL_FMPSMBUS_EnableListen_IT()
  761. (++) HAL_FMPSMBUS_DisableListen_IT()
  762. (++) HAL_FMPSMBUS_EnableAlert_IT()
  763. (++) HAL_FMPSMBUS_DisableAlert_IT()
  764. (#) A set of Transfer Complete Callbacks are provided in non-Blocking mode:
  765. (++) HAL_FMPSMBUS_MasterTxCpltCallback()
  766. (++) HAL_FMPSMBUS_MasterRxCpltCallback()
  767. (++) HAL_FMPSMBUS_SlaveTxCpltCallback()
  768. (++) HAL_FMPSMBUS_SlaveRxCpltCallback()
  769. (++) HAL_FMPSMBUS_AddrCallback()
  770. (++) HAL_FMPSMBUS_ListenCpltCallback()
  771. (++) HAL_FMPSMBUS_ErrorCallback()
  772. @endverbatim
  773. * @{
  774. */
  775. /**
  776. * @brief Transmit in master/host FMPSMBUS mode an amount of data in non-blocking mode with Interrupt.
  777. * @param hfmpsmbus Pointer to a FMPSMBUS_HandleTypeDef structure that contains
  778. * the configuration information for the specified FMPSMBUS.
  779. * @param DevAddress Target device address: The device 7 bits address value
  780. * in datasheet must be shifted to the left before calling the interface
  781. * @param pData Pointer to data buffer
  782. * @param Size Amount of data to be sent
  783. * @param XferOptions Options of Transfer, value of @ref FMPSMBUS_XferOptions_definition
  784. * @retval HAL status
  785. */
  786. HAL_StatusTypeDef HAL_FMPSMBUS_Master_Transmit_IT(FMPSMBUS_HandleTypeDef *hfmpsmbus, uint16_t DevAddress,
  787. uint8_t *pData, uint16_t Size, uint32_t XferOptions)
  788. {
  789. uint32_t tmp;
  790. uint32_t sizetoxfer;
  791. /* Check the parameters */
  792. assert_param(IS_FMPSMBUS_TRANSFER_OPTIONS_REQUEST(XferOptions));
  793. if (hfmpsmbus->State == HAL_FMPSMBUS_STATE_READY)
  794. {
  795. /* Process Locked */
  796. __HAL_LOCK(hfmpsmbus);
  797. hfmpsmbus->State = HAL_FMPSMBUS_STATE_MASTER_BUSY_TX;
  798. hfmpsmbus->ErrorCode = HAL_FMPSMBUS_ERROR_NONE;
  799. /* Prepare transfer parameters */
  800. hfmpsmbus->pBuffPtr = pData;
  801. hfmpsmbus->XferCount = Size;
  802. hfmpsmbus->XferOptions = XferOptions;
  803. /* In case of Quick command, remove autoend mode */
  804. /* Manage the stop generation by software */
  805. if (hfmpsmbus->pBuffPtr == NULL)
  806. {
  807. hfmpsmbus->XferOptions &= ~FMPSMBUS_AUTOEND_MODE;
  808. }
  809. if (Size > MAX_NBYTE_SIZE)
  810. {
  811. hfmpsmbus->XferSize = MAX_NBYTE_SIZE;
  812. }
  813. else
  814. {
  815. hfmpsmbus->XferSize = Size;
  816. }
  817. sizetoxfer = hfmpsmbus->XferSize;
  818. if ((sizetoxfer > 0U) && ((XferOptions == FMPSMBUS_FIRST_FRAME) ||
  819. (XferOptions == FMPSMBUS_FIRST_AND_LAST_FRAME_NO_PEC) ||
  820. (XferOptions == FMPSMBUS_FIRST_FRAME_WITH_PEC) ||
  821. (XferOptions == FMPSMBUS_FIRST_AND_LAST_FRAME_WITH_PEC)))
  822. {
  823. if (hfmpsmbus->pBuffPtr != NULL)
  824. {
  825. /* Preload TX register */
  826. /* Write data to TXDR */
  827. hfmpsmbus->Instance->TXDR = *hfmpsmbus->pBuffPtr;
  828. /* Increment Buffer pointer */
  829. hfmpsmbus->pBuffPtr++;
  830. hfmpsmbus->XferCount--;
  831. hfmpsmbus->XferSize--;
  832. }
  833. else
  834. {
  835. return HAL_ERROR;
  836. }
  837. }
  838. /* Send Slave Address */
  839. /* Set NBYTES to write and reload if size > MAX_NBYTE_SIZE and generate RESTART */
  840. if ((sizetoxfer < hfmpsmbus->XferCount) && (sizetoxfer == MAX_NBYTE_SIZE))
  841. {
  842. FMPSMBUS_TransferConfig(hfmpsmbus, DevAddress, (uint8_t)sizetoxfer,
  843. FMPSMBUS_RELOAD_MODE | (hfmpsmbus->XferOptions & FMPSMBUS_SENDPEC_MODE),
  844. FMPSMBUS_GENERATE_START_WRITE);
  845. }
  846. else
  847. {
  848. /* If transfer direction not change, do not generate Restart Condition */
  849. /* Mean Previous state is same as current state */
  850. /* Store current volatile XferOptions, misra rule */
  851. tmp = hfmpsmbus->XferOptions;
  852. if ((hfmpsmbus->PreviousState == HAL_FMPSMBUS_STATE_MASTER_BUSY_TX) && \
  853. (IS_FMPSMBUS_TRANSFER_OTHER_OPTIONS_REQUEST(tmp) == 0))
  854. {
  855. FMPSMBUS_TransferConfig(hfmpsmbus, DevAddress, (uint8_t)sizetoxfer, hfmpsmbus->XferOptions,
  856. FMPSMBUS_NO_STARTSTOP);
  857. }
  858. /* Else transfer direction change, so generate Restart with new transfer direction */
  859. else
  860. {
  861. /* Convert OTHER_xxx XferOptions if any */
  862. FMPSMBUS_ConvertOtherXferOptions(hfmpsmbus);
  863. /* Handle Transfer */
  864. FMPSMBUS_TransferConfig(hfmpsmbus, DevAddress, (uint8_t)sizetoxfer,
  865. hfmpsmbus->XferOptions,
  866. FMPSMBUS_GENERATE_START_WRITE);
  867. }
  868. /* If PEC mode is enable, size to transmit manage by SW part should be Size-1 byte, corresponding to PEC byte */
  869. /* PEC byte is automatically sent by HW block, no need to manage it in Transmit process */
  870. if (FMPSMBUS_GET_PEC_MODE(hfmpsmbus) != 0UL)
  871. {
  872. if (hfmpsmbus->XferSize > 0U)
  873. {
  874. hfmpsmbus->XferSize--;
  875. hfmpsmbus->XferCount--;
  876. }
  877. else
  878. {
  879. return HAL_ERROR;
  880. }
  881. }
  882. }
  883. /* Process Unlocked */
  884. __HAL_UNLOCK(hfmpsmbus);
  885. /* Note : The FMPSMBUS interrupts must be enabled after unlocking current process
  886. to avoid the risk of FMPSMBUS interrupt handle execution before current
  887. process unlock */
  888. FMPSMBUS_Enable_IRQ(hfmpsmbus, FMPSMBUS_IT_TX);
  889. return HAL_OK;
  890. }
  891. else
  892. {
  893. return HAL_BUSY;
  894. }
  895. }
  896. /**
  897. * @brief Receive in master/host FMPSMBUS mode an amount of data in non-blocking mode with Interrupt.
  898. * @param hfmpsmbus Pointer to a FMPSMBUS_HandleTypeDef structure that contains
  899. * the configuration information for the specified FMPSMBUS.
  900. * @param DevAddress Target device address: The device 7 bits address value
  901. * in datasheet must be shifted to the left before calling the interface
  902. * @param pData Pointer to data buffer
  903. * @param Size Amount of data to be sent
  904. * @param XferOptions Options of Transfer, value of @ref FMPSMBUS_XferOptions_definition
  905. * @retval HAL status
  906. */
  907. HAL_StatusTypeDef HAL_FMPSMBUS_Master_Receive_IT(FMPSMBUS_HandleTypeDef *hfmpsmbus, uint16_t DevAddress, uint8_t *pData,
  908. uint16_t Size, uint32_t XferOptions)
  909. {
  910. uint32_t tmp;
  911. /* Check the parameters */
  912. assert_param(IS_FMPSMBUS_TRANSFER_OPTIONS_REQUEST(XferOptions));
  913. if (hfmpsmbus->State == HAL_FMPSMBUS_STATE_READY)
  914. {
  915. /* Process Locked */
  916. __HAL_LOCK(hfmpsmbus);
  917. hfmpsmbus->State = HAL_FMPSMBUS_STATE_MASTER_BUSY_RX;
  918. hfmpsmbus->ErrorCode = HAL_FMPSMBUS_ERROR_NONE;
  919. /* Prepare transfer parameters */
  920. hfmpsmbus->pBuffPtr = pData;
  921. hfmpsmbus->XferCount = Size;
  922. hfmpsmbus->XferOptions = XferOptions;
  923. /* In case of Quick command, remove autoend mode */
  924. /* Manage the stop generation by software */
  925. if (hfmpsmbus->pBuffPtr == NULL)
  926. {
  927. hfmpsmbus->XferOptions &= ~FMPSMBUS_AUTOEND_MODE;
  928. }
  929. if (Size > MAX_NBYTE_SIZE)
  930. {
  931. hfmpsmbus->XferSize = MAX_NBYTE_SIZE;
  932. }
  933. else
  934. {
  935. hfmpsmbus->XferSize = Size;
  936. }
  937. /* Send Slave Address */
  938. /* Set NBYTES to write and reload if size > MAX_NBYTE_SIZE and generate RESTART */
  939. if ((hfmpsmbus->XferSize < hfmpsmbus->XferCount) && (hfmpsmbus->XferSize == MAX_NBYTE_SIZE))
  940. {
  941. FMPSMBUS_TransferConfig(hfmpsmbus, DevAddress, (uint8_t)hfmpsmbus->XferSize,
  942. FMPSMBUS_RELOAD_MODE | (hfmpsmbus->XferOptions & FMPSMBUS_SENDPEC_MODE),
  943. FMPSMBUS_GENERATE_START_READ);
  944. }
  945. else
  946. {
  947. /* If transfer direction not change, do not generate Restart Condition */
  948. /* Mean Previous state is same as current state */
  949. /* Store current volatile XferOptions, Misra rule */
  950. tmp = hfmpsmbus->XferOptions;
  951. if ((hfmpsmbus->PreviousState == HAL_FMPSMBUS_STATE_MASTER_BUSY_RX) && \
  952. (IS_FMPSMBUS_TRANSFER_OTHER_OPTIONS_REQUEST(tmp) == 0))
  953. {
  954. FMPSMBUS_TransferConfig(hfmpsmbus, DevAddress, (uint8_t)hfmpsmbus->XferSize, hfmpsmbus->XferOptions,
  955. FMPSMBUS_NO_STARTSTOP);
  956. }
  957. /* Else transfer direction change, so generate Restart with new transfer direction */
  958. else
  959. {
  960. /* Convert OTHER_xxx XferOptions if any */
  961. FMPSMBUS_ConvertOtherXferOptions(hfmpsmbus);
  962. /* Handle Transfer */
  963. FMPSMBUS_TransferConfig(hfmpsmbus, DevAddress, (uint8_t)hfmpsmbus->XferSize,
  964. hfmpsmbus->XferOptions,
  965. FMPSMBUS_GENERATE_START_READ);
  966. }
  967. }
  968. /* Process Unlocked */
  969. __HAL_UNLOCK(hfmpsmbus);
  970. /* Note : The FMPSMBUS interrupts must be enabled after unlocking current process
  971. to avoid the risk of FMPSMBUS interrupt handle execution before current
  972. process unlock */
  973. FMPSMBUS_Enable_IRQ(hfmpsmbus, FMPSMBUS_IT_RX);
  974. return HAL_OK;
  975. }
  976. else
  977. {
  978. return HAL_BUSY;
  979. }
  980. }
  981. /**
  982. * @brief Abort a master/host FMPSMBUS process communication with Interrupt.
  983. * @note This abort can be called only if state is ready
  984. * @param hfmpsmbus Pointer to a FMPSMBUS_HandleTypeDef structure that contains
  985. * the configuration information for the specified FMPSMBUS.
  986. * @param DevAddress Target device address: The device 7 bits address value
  987. * in datasheet must be shifted to the left before calling the interface
  988. * @retval HAL status
  989. */
  990. HAL_StatusTypeDef HAL_FMPSMBUS_Master_Abort_IT(FMPSMBUS_HandleTypeDef *hfmpsmbus, uint16_t DevAddress)
  991. {
  992. if (hfmpsmbus->State == HAL_FMPSMBUS_STATE_READY)
  993. {
  994. /* Process Locked */
  995. __HAL_LOCK(hfmpsmbus);
  996. /* Keep the same state as previous */
  997. /* to perform as well the call of the corresponding end of transfer callback */
  998. if (hfmpsmbus->PreviousState == HAL_FMPSMBUS_STATE_MASTER_BUSY_TX)
  999. {
  1000. hfmpsmbus->State = HAL_FMPSMBUS_STATE_MASTER_BUSY_TX;
  1001. }
  1002. else if (hfmpsmbus->PreviousState == HAL_FMPSMBUS_STATE_MASTER_BUSY_RX)
  1003. {
  1004. hfmpsmbus->State = HAL_FMPSMBUS_STATE_MASTER_BUSY_RX;
  1005. }
  1006. else
  1007. {
  1008. /* Wrong usage of abort function */
  1009. /* This function should be used only in case of abort monitored by master device */
  1010. return HAL_ERROR;
  1011. }
  1012. hfmpsmbus->ErrorCode = HAL_FMPSMBUS_ERROR_NONE;
  1013. /* Set NBYTES to 1 to generate a dummy read on FMPSMBUS peripheral */
  1014. /* Set AUTOEND mode, this will generate a NACK then STOP condition to abort the current transfer */
  1015. FMPSMBUS_TransferConfig(hfmpsmbus, DevAddress, 1, FMPSMBUS_AUTOEND_MODE, FMPSMBUS_NO_STARTSTOP);
  1016. /* Process Unlocked */
  1017. __HAL_UNLOCK(hfmpsmbus);
  1018. /* Note : The FMPSMBUS interrupts must be enabled after unlocking current process
  1019. to avoid the risk of FMPSMBUS interrupt handle execution before current
  1020. process unlock */
  1021. if (hfmpsmbus->State == HAL_FMPSMBUS_STATE_MASTER_BUSY_TX)
  1022. {
  1023. FMPSMBUS_Enable_IRQ(hfmpsmbus, FMPSMBUS_IT_TX);
  1024. }
  1025. else if (hfmpsmbus->State == HAL_FMPSMBUS_STATE_MASTER_BUSY_RX)
  1026. {
  1027. FMPSMBUS_Enable_IRQ(hfmpsmbus, FMPSMBUS_IT_RX);
  1028. }
  1029. else
  1030. {
  1031. /* Nothing to do */
  1032. }
  1033. return HAL_OK;
  1034. }
  1035. else
  1036. {
  1037. return HAL_BUSY;
  1038. }
  1039. }
  1040. /**
  1041. * @brief Transmit in slave/device FMPSMBUS mode an amount of data in non-blocking mode with Interrupt.
  1042. * @param hfmpsmbus Pointer to a FMPSMBUS_HandleTypeDef structure that contains
  1043. * the configuration information for the specified FMPSMBUS.
  1044. * @param pData Pointer to data buffer
  1045. * @param Size Amount of data to be sent
  1046. * @param XferOptions Options of Transfer, value of @ref FMPSMBUS_XferOptions_definition
  1047. * @retval HAL status
  1048. */
  1049. HAL_StatusTypeDef HAL_FMPSMBUS_Slave_Transmit_IT(FMPSMBUS_HandleTypeDef *hfmpsmbus, uint8_t *pData, uint16_t Size,
  1050. uint32_t XferOptions)
  1051. {
  1052. /* Check the parameters */
  1053. assert_param(IS_FMPSMBUS_TRANSFER_OPTIONS_REQUEST(XferOptions));
  1054. if ((hfmpsmbus->State & HAL_FMPSMBUS_STATE_LISTEN) == HAL_FMPSMBUS_STATE_LISTEN)
  1055. {
  1056. if ((pData == NULL) || (Size == 0UL))
  1057. {
  1058. hfmpsmbus->ErrorCode = HAL_FMPSMBUS_ERROR_INVALID_PARAM;
  1059. return HAL_ERROR;
  1060. }
  1061. /* Disable Interrupts, to prevent preemption during treatment in case of multicall */
  1062. FMPSMBUS_Disable_IRQ(hfmpsmbus, FMPSMBUS_IT_ADDR | FMPSMBUS_IT_TX);
  1063. /* Process Locked */
  1064. __HAL_LOCK(hfmpsmbus);
  1065. hfmpsmbus->State = (HAL_FMPSMBUS_STATE_SLAVE_BUSY_TX | HAL_FMPSMBUS_STATE_LISTEN);
  1066. hfmpsmbus->ErrorCode = HAL_FMPSMBUS_ERROR_NONE;
  1067. /* Set SBC bit to manage Acknowledge at each bit */
  1068. hfmpsmbus->Instance->CR1 |= FMPI2C_CR1_SBC;
  1069. /* Enable Address Acknowledge */
  1070. hfmpsmbus->Instance->CR2 &= ~FMPI2C_CR2_NACK;
  1071. /* Prepare transfer parameters */
  1072. hfmpsmbus->pBuffPtr = pData;
  1073. hfmpsmbus->XferCount = Size;
  1074. hfmpsmbus->XferOptions = XferOptions;
  1075. /* Convert OTHER_xxx XferOptions if any */
  1076. FMPSMBUS_ConvertOtherXferOptions(hfmpsmbus);
  1077. if (Size > MAX_NBYTE_SIZE)
  1078. {
  1079. hfmpsmbus->XferSize = MAX_NBYTE_SIZE;
  1080. }
  1081. else
  1082. {
  1083. hfmpsmbus->XferSize = Size;
  1084. }
  1085. /* Set NBYTES to write and reload if size > MAX_NBYTE_SIZE and generate RESTART */
  1086. if ((hfmpsmbus->XferSize < hfmpsmbus->XferCount) && (hfmpsmbus->XferSize == MAX_NBYTE_SIZE))
  1087. {
  1088. FMPSMBUS_TransferConfig(hfmpsmbus, 0, (uint8_t)hfmpsmbus->XferSize,
  1089. FMPSMBUS_RELOAD_MODE | (hfmpsmbus->XferOptions & FMPSMBUS_SENDPEC_MODE),
  1090. FMPSMBUS_NO_STARTSTOP);
  1091. }
  1092. else
  1093. {
  1094. /* Set NBYTE to transmit */
  1095. FMPSMBUS_TransferConfig(hfmpsmbus, 0, (uint8_t)hfmpsmbus->XferSize, hfmpsmbus->XferOptions,
  1096. FMPSMBUS_NO_STARTSTOP);
  1097. /* If PEC mode is enable, size to transmit should be Size-1 byte, corresponding to PEC byte */
  1098. /* PEC byte is automatically sent by HW block, no need to manage it in Transmit process */
  1099. if (FMPSMBUS_GET_PEC_MODE(hfmpsmbus) != 0UL)
  1100. {
  1101. hfmpsmbus->XferSize--;
  1102. hfmpsmbus->XferCount--;
  1103. }
  1104. }
  1105. /* Clear ADDR flag after prepare the transfer parameters */
  1106. /* This action will generate an acknowledge to the HOST */
  1107. __HAL_FMPSMBUS_CLEAR_FLAG(hfmpsmbus, FMPSMBUS_FLAG_ADDR);
  1108. /* Process Unlocked */
  1109. __HAL_UNLOCK(hfmpsmbus);
  1110. /* Note : The FMPSMBUS interrupts must be enabled after unlocking current process
  1111. to avoid the risk of FMPSMBUS interrupt handle execution before current
  1112. process unlock */
  1113. /* REnable ADDR interrupt */
  1114. FMPSMBUS_Enable_IRQ(hfmpsmbus, FMPSMBUS_IT_TX | FMPSMBUS_IT_ADDR);
  1115. return HAL_OK;
  1116. }
  1117. else
  1118. {
  1119. return HAL_BUSY;
  1120. }
  1121. }
  1122. /**
  1123. * @brief Receive in slave/device FMPSMBUS mode an amount of data in non-blocking mode with Interrupt.
  1124. * @param hfmpsmbus Pointer to a FMPSMBUS_HandleTypeDef structure that contains
  1125. * the configuration information for the specified FMPSMBUS.
  1126. * @param pData Pointer to data buffer
  1127. * @param Size Amount of data to be sent
  1128. * @param XferOptions Options of Transfer, value of @ref FMPSMBUS_XferOptions_definition
  1129. * @retval HAL status
  1130. */
  1131. HAL_StatusTypeDef HAL_FMPSMBUS_Slave_Receive_IT(FMPSMBUS_HandleTypeDef *hfmpsmbus, uint8_t *pData, uint16_t Size,
  1132. uint32_t XferOptions)
  1133. {
  1134. /* Check the parameters */
  1135. assert_param(IS_FMPSMBUS_TRANSFER_OPTIONS_REQUEST(XferOptions));
  1136. if ((hfmpsmbus->State & HAL_FMPSMBUS_STATE_LISTEN) == HAL_FMPSMBUS_STATE_LISTEN)
  1137. {
  1138. if ((pData == NULL) || (Size == 0UL))
  1139. {
  1140. hfmpsmbus->ErrorCode = HAL_FMPSMBUS_ERROR_INVALID_PARAM;
  1141. return HAL_ERROR;
  1142. }
  1143. /* Disable Interrupts, to prevent preemption during treatment in case of multicall */
  1144. FMPSMBUS_Disable_IRQ(hfmpsmbus, FMPSMBUS_IT_ADDR | FMPSMBUS_IT_RX);
  1145. /* Process Locked */
  1146. __HAL_LOCK(hfmpsmbus);
  1147. hfmpsmbus->State = (HAL_FMPSMBUS_STATE_SLAVE_BUSY_RX | HAL_FMPSMBUS_STATE_LISTEN);
  1148. hfmpsmbus->ErrorCode = HAL_FMPSMBUS_ERROR_NONE;
  1149. /* Set SBC bit to manage Acknowledge at each bit */
  1150. hfmpsmbus->Instance->CR1 |= FMPI2C_CR1_SBC;
  1151. /* Enable Address Acknowledge */
  1152. hfmpsmbus->Instance->CR2 &= ~FMPI2C_CR2_NACK;
  1153. /* Prepare transfer parameters */
  1154. hfmpsmbus->pBuffPtr = pData;
  1155. hfmpsmbus->XferSize = Size;
  1156. hfmpsmbus->XferCount = Size;
  1157. hfmpsmbus->XferOptions = XferOptions;
  1158. /* Convert OTHER_xxx XferOptions if any */
  1159. FMPSMBUS_ConvertOtherXferOptions(hfmpsmbus);
  1160. /* Set NBYTE to receive */
  1161. /* If XferSize equal "1", or XferSize equal "2" with PEC requested (mean 1 data byte + 1 PEC byte */
  1162. /* no need to set RELOAD bit mode, a ACK will be automatically generated in that case */
  1163. /* else need to set RELOAD bit mode to generate an automatic ACK at each byte Received */
  1164. /* This RELOAD bit will be reset for last BYTE to be receive in FMPSMBUS_Slave_ISR */
  1165. if (((FMPSMBUS_GET_PEC_MODE(hfmpsmbus) != 0UL) && (hfmpsmbus->XferSize == 2U)) || (hfmpsmbus->XferSize == 1U))
  1166. {
  1167. FMPSMBUS_TransferConfig(hfmpsmbus, 0, (uint8_t)hfmpsmbus->XferSize, hfmpsmbus->XferOptions,
  1168. FMPSMBUS_NO_STARTSTOP);
  1169. }
  1170. else
  1171. {
  1172. FMPSMBUS_TransferConfig(hfmpsmbus, 0, 1, hfmpsmbus->XferOptions | FMPSMBUS_RELOAD_MODE, FMPSMBUS_NO_STARTSTOP);
  1173. }
  1174. /* Clear ADDR flag after prepare the transfer parameters */
  1175. /* This action will generate an acknowledge to the HOST */
  1176. __HAL_FMPSMBUS_CLEAR_FLAG(hfmpsmbus, FMPSMBUS_FLAG_ADDR);
  1177. /* Process Unlocked */
  1178. __HAL_UNLOCK(hfmpsmbus);
  1179. /* Note : The FMPSMBUS interrupts must be enabled after unlocking current process
  1180. to avoid the risk of FMPSMBUS interrupt handle execution before current
  1181. process unlock */
  1182. /* REnable ADDR interrupt */
  1183. FMPSMBUS_Enable_IRQ(hfmpsmbus, FMPSMBUS_IT_RX | FMPSMBUS_IT_ADDR);
  1184. return HAL_OK;
  1185. }
  1186. else
  1187. {
  1188. return HAL_BUSY;
  1189. }
  1190. }
  1191. /**
  1192. * @brief Enable the Address listen mode with Interrupt.
  1193. * @param hfmpsmbus Pointer to a FMPSMBUS_HandleTypeDef structure that contains
  1194. * the configuration information for the specified FMPSMBUS.
  1195. * @retval HAL status
  1196. */
  1197. HAL_StatusTypeDef HAL_FMPSMBUS_EnableListen_IT(FMPSMBUS_HandleTypeDef *hfmpsmbus)
  1198. {
  1199. hfmpsmbus->State = HAL_FMPSMBUS_STATE_LISTEN;
  1200. /* Enable the Address Match interrupt */
  1201. FMPSMBUS_Enable_IRQ(hfmpsmbus, FMPSMBUS_IT_ADDR);
  1202. return HAL_OK;
  1203. }
  1204. /**
  1205. * @brief Disable the Address listen mode with Interrupt.
  1206. * @param hfmpsmbus Pointer to a FMPSMBUS_HandleTypeDef structure that contains
  1207. * the configuration information for the specified FMPSMBUS.
  1208. * @retval HAL status
  1209. */
  1210. HAL_StatusTypeDef HAL_FMPSMBUS_DisableListen_IT(FMPSMBUS_HandleTypeDef *hfmpsmbus)
  1211. {
  1212. /* Disable Address listen mode only if a transfer is not ongoing */
  1213. if (hfmpsmbus->State == HAL_FMPSMBUS_STATE_LISTEN)
  1214. {
  1215. hfmpsmbus->State = HAL_FMPSMBUS_STATE_READY;
  1216. /* Disable the Address Match interrupt */
  1217. FMPSMBUS_Disable_IRQ(hfmpsmbus, FMPSMBUS_IT_ADDR);
  1218. return HAL_OK;
  1219. }
  1220. else
  1221. {
  1222. return HAL_BUSY;
  1223. }
  1224. }
  1225. /**
  1226. * @brief Enable the FMPSMBUS alert mode with Interrupt.
  1227. * @param hfmpsmbus Pointer to a FMPSMBUS_HandleTypeDef structure that contains
  1228. * the configuration information for the specified FMPSMBUSx peripheral.
  1229. * @retval HAL status
  1230. */
  1231. HAL_StatusTypeDef HAL_FMPSMBUS_EnableAlert_IT(FMPSMBUS_HandleTypeDef *hfmpsmbus)
  1232. {
  1233. /* Enable SMBus alert */
  1234. hfmpsmbus->Instance->CR1 |= FMPI2C_CR1_ALERTEN;
  1235. /* Clear ALERT flag */
  1236. __HAL_FMPSMBUS_CLEAR_FLAG(hfmpsmbus, FMPSMBUS_FLAG_ALERT);
  1237. /* Enable Alert Interrupt */
  1238. FMPSMBUS_Enable_IRQ(hfmpsmbus, FMPSMBUS_IT_ALERT);
  1239. return HAL_OK;
  1240. }
  1241. /**
  1242. * @brief Disable the FMPSMBUS alert mode with Interrupt.
  1243. * @param hfmpsmbus Pointer to a FMPSMBUS_HandleTypeDef structure that contains
  1244. * the configuration information for the specified FMPSMBUSx peripheral.
  1245. * @retval HAL status
  1246. */
  1247. HAL_StatusTypeDef HAL_FMPSMBUS_DisableAlert_IT(FMPSMBUS_HandleTypeDef *hfmpsmbus)
  1248. {
  1249. /* Enable SMBus alert */
  1250. hfmpsmbus->Instance->CR1 &= ~FMPI2C_CR1_ALERTEN;
  1251. /* Disable Alert Interrupt */
  1252. FMPSMBUS_Disable_IRQ(hfmpsmbus, FMPSMBUS_IT_ALERT);
  1253. return HAL_OK;
  1254. }
  1255. /**
  1256. * @brief Check if target device is ready for communication.
  1257. * @param hfmpsmbus Pointer to a FMPSMBUS_HandleTypeDef structure that contains
  1258. * the configuration information for the specified FMPSMBUS.
  1259. * @param DevAddress Target device address: The device 7 bits address value
  1260. * in datasheet must be shifted to the left before calling the interface
  1261. * @param Trials Number of trials
  1262. * @param Timeout Timeout duration
  1263. * @retval HAL status
  1264. */
  1265. HAL_StatusTypeDef HAL_FMPSMBUS_IsDeviceReady(FMPSMBUS_HandleTypeDef *hfmpsmbus, uint16_t DevAddress, uint32_t Trials,
  1266. uint32_t Timeout)
  1267. {
  1268. uint32_t tickstart;
  1269. __IO uint32_t FMPSMBUS_Trials = 0UL;
  1270. FlagStatus tmp1;
  1271. FlagStatus tmp2;
  1272. if (hfmpsmbus->State == HAL_FMPSMBUS_STATE_READY)
  1273. {
  1274. if (__HAL_FMPSMBUS_GET_FLAG(hfmpsmbus, FMPSMBUS_FLAG_BUSY) != RESET)
  1275. {
  1276. return HAL_BUSY;
  1277. }
  1278. /* Process Locked */
  1279. __HAL_LOCK(hfmpsmbus);
  1280. hfmpsmbus->State = HAL_FMPSMBUS_STATE_BUSY;
  1281. hfmpsmbus->ErrorCode = HAL_FMPSMBUS_ERROR_NONE;
  1282. do
  1283. {
  1284. /* Generate Start */
  1285. hfmpsmbus->Instance->CR2 = FMPSMBUS_GENERATE_START(hfmpsmbus->Init.AddressingMode, DevAddress);
  1286. /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */
  1287. /* Wait until STOPF flag is set or a NACK flag is set*/
  1288. tickstart = HAL_GetTick();
  1289. tmp1 = __HAL_FMPSMBUS_GET_FLAG(hfmpsmbus, FMPSMBUS_FLAG_STOPF);
  1290. tmp2 = __HAL_FMPSMBUS_GET_FLAG(hfmpsmbus, FMPSMBUS_FLAG_AF);
  1291. while ((tmp1 == RESET) && (tmp2 == RESET))
  1292. {
  1293. if (Timeout != HAL_MAX_DELAY)
  1294. {
  1295. if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0UL))
  1296. {
  1297. /* Device is ready */
  1298. hfmpsmbus->State = HAL_FMPSMBUS_STATE_READY;
  1299. /* Update FMPSMBUS error code */
  1300. hfmpsmbus->ErrorCode |= HAL_FMPSMBUS_ERROR_HALTIMEOUT;
  1301. /* Process Unlocked */
  1302. __HAL_UNLOCK(hfmpsmbus);
  1303. return HAL_ERROR;
  1304. }
  1305. }
  1306. tmp1 = __HAL_FMPSMBUS_GET_FLAG(hfmpsmbus, FMPSMBUS_FLAG_STOPF);
  1307. tmp2 = __HAL_FMPSMBUS_GET_FLAG(hfmpsmbus, FMPSMBUS_FLAG_AF);
  1308. }
  1309. /* Check if the NACKF flag has not been set */
  1310. if (__HAL_FMPSMBUS_GET_FLAG(hfmpsmbus, FMPSMBUS_FLAG_AF) == RESET)
  1311. {
  1312. /* Wait until STOPF flag is reset */
  1313. if (FMPSMBUS_WaitOnFlagUntilTimeout(hfmpsmbus, FMPSMBUS_FLAG_STOPF, RESET, Timeout) != HAL_OK)
  1314. {
  1315. return HAL_ERROR;
  1316. }
  1317. /* Clear STOP Flag */
  1318. __HAL_FMPSMBUS_CLEAR_FLAG(hfmpsmbus, FMPSMBUS_FLAG_STOPF);
  1319. /* Device is ready */
  1320. hfmpsmbus->State = HAL_FMPSMBUS_STATE_READY;
  1321. /* Process Unlocked */
  1322. __HAL_UNLOCK(hfmpsmbus);
  1323. return HAL_OK;
  1324. }
  1325. else
  1326. {
  1327. /* Wait until STOPF flag is reset */
  1328. if (FMPSMBUS_WaitOnFlagUntilTimeout(hfmpsmbus, FMPSMBUS_FLAG_STOPF, RESET, Timeout) != HAL_OK)
  1329. {
  1330. return HAL_ERROR;
  1331. }
  1332. /* Clear NACK Flag */
  1333. __HAL_FMPSMBUS_CLEAR_FLAG(hfmpsmbus, FMPSMBUS_FLAG_AF);
  1334. /* Clear STOP Flag, auto generated with autoend*/
  1335. __HAL_FMPSMBUS_CLEAR_FLAG(hfmpsmbus, FMPSMBUS_FLAG_STOPF);
  1336. }
  1337. /* Check if the maximum allowed number of trials has been reached */
  1338. if (FMPSMBUS_Trials == Trials)
  1339. {
  1340. /* Generate Stop */
  1341. hfmpsmbus->Instance->CR2 |= FMPI2C_CR2_STOP;
  1342. /* Wait until STOPF flag is reset */
  1343. if (FMPSMBUS_WaitOnFlagUntilTimeout(hfmpsmbus, FMPSMBUS_FLAG_STOPF, RESET, Timeout) != HAL_OK)
  1344. {
  1345. return HAL_ERROR;
  1346. }
  1347. /* Clear STOP Flag */
  1348. __HAL_FMPSMBUS_CLEAR_FLAG(hfmpsmbus, FMPSMBUS_FLAG_STOPF);
  1349. }
  1350. /* Increment Trials */
  1351. FMPSMBUS_Trials++;
  1352. } while (FMPSMBUS_Trials < Trials);
  1353. hfmpsmbus->State = HAL_FMPSMBUS_STATE_READY;
  1354. /* Update FMPSMBUS error code */
  1355. hfmpsmbus->ErrorCode |= HAL_FMPSMBUS_ERROR_HALTIMEOUT;
  1356. /* Process Unlocked */
  1357. __HAL_UNLOCK(hfmpsmbus);
  1358. return HAL_ERROR;
  1359. }
  1360. else
  1361. {
  1362. return HAL_BUSY;
  1363. }
  1364. }
  1365. /**
  1366. * @}
  1367. */
  1368. /** @defgroup FMPSMBUS_IRQ_Handler_and_Callbacks IRQ Handler and Callbacks
  1369. * @{
  1370. */
  1371. /**
  1372. * @brief Handle FMPSMBUS event interrupt request.
  1373. * @param hfmpsmbus Pointer to a FMPSMBUS_HandleTypeDef structure that contains
  1374. * the configuration information for the specified FMPSMBUS.
  1375. * @retval None
  1376. */
  1377. void HAL_FMPSMBUS_EV_IRQHandler(FMPSMBUS_HandleTypeDef *hfmpsmbus)
  1378. {
  1379. /* Use a local variable to store the current ISR flags */
  1380. /* This action will avoid a wrong treatment due to ISR flags change during interrupt handler */
  1381. uint32_t tmpisrvalue = READ_REG(hfmpsmbus->Instance->ISR);
  1382. uint32_t tmpcr1value = READ_REG(hfmpsmbus->Instance->CR1);
  1383. /* FMPSMBUS in mode Transmitter ---------------------------------------------------*/
  1384. if ((FMPSMBUS_CHECK_IT_SOURCE(tmpcr1value, (FMPSMBUS_IT_TCI | FMPSMBUS_IT_STOPI |
  1385. FMPSMBUS_IT_NACKI | FMPSMBUS_IT_TXI)) != RESET) &&
  1386. ((FMPSMBUS_CHECK_FLAG(tmpisrvalue, FMPSMBUS_FLAG_TXIS) != RESET) ||
  1387. (FMPSMBUS_CHECK_FLAG(tmpisrvalue, FMPSMBUS_FLAG_TCR) != RESET) ||
  1388. (FMPSMBUS_CHECK_FLAG(tmpisrvalue, FMPSMBUS_FLAG_TC) != RESET) ||
  1389. (FMPSMBUS_CHECK_FLAG(tmpisrvalue, FMPSMBUS_FLAG_STOPF) != RESET) ||
  1390. (FMPSMBUS_CHECK_FLAG(tmpisrvalue, FMPSMBUS_FLAG_AF) != RESET)))
  1391. {
  1392. /* Slave mode selected */
  1393. if ((hfmpsmbus->State & HAL_FMPSMBUS_STATE_SLAVE_BUSY_TX) == HAL_FMPSMBUS_STATE_SLAVE_BUSY_TX)
  1394. {
  1395. (void)FMPSMBUS_Slave_ISR(hfmpsmbus, tmpisrvalue);
  1396. }
  1397. /* Master mode selected */
  1398. else if ((hfmpsmbus->State & HAL_FMPSMBUS_STATE_MASTER_BUSY_TX) == HAL_FMPSMBUS_STATE_MASTER_BUSY_TX)
  1399. {
  1400. (void)FMPSMBUS_Master_ISR(hfmpsmbus, tmpisrvalue);
  1401. }
  1402. else
  1403. {
  1404. /* Nothing to do */
  1405. }
  1406. }
  1407. /* FMPSMBUS in mode Receiver ----------------------------------------------------*/
  1408. if ((FMPSMBUS_CHECK_IT_SOURCE(tmpcr1value, (FMPSMBUS_IT_TCI | FMPSMBUS_IT_STOPI |
  1409. FMPSMBUS_IT_NACKI | FMPSMBUS_IT_RXI)) != RESET) &&
  1410. ((FMPSMBUS_CHECK_FLAG(tmpisrvalue, FMPSMBUS_FLAG_RXNE) != RESET) ||
  1411. (FMPSMBUS_CHECK_FLAG(tmpisrvalue, FMPSMBUS_FLAG_TCR) != RESET) ||
  1412. (FMPSMBUS_CHECK_FLAG(tmpisrvalue, FMPSMBUS_FLAG_TC) != RESET) ||
  1413. (FMPSMBUS_CHECK_FLAG(tmpisrvalue, FMPSMBUS_FLAG_STOPF) != RESET) ||
  1414. (FMPSMBUS_CHECK_FLAG(tmpisrvalue, FMPSMBUS_FLAG_AF) != RESET)))
  1415. {
  1416. /* Slave mode selected */
  1417. if ((hfmpsmbus->State & HAL_FMPSMBUS_STATE_SLAVE_BUSY_RX) == HAL_FMPSMBUS_STATE_SLAVE_BUSY_RX)
  1418. {
  1419. (void)FMPSMBUS_Slave_ISR(hfmpsmbus, tmpisrvalue);
  1420. }
  1421. /* Master mode selected */
  1422. else if ((hfmpsmbus->State & HAL_FMPSMBUS_STATE_MASTER_BUSY_RX) == HAL_FMPSMBUS_STATE_MASTER_BUSY_RX)
  1423. {
  1424. (void)FMPSMBUS_Master_ISR(hfmpsmbus, tmpisrvalue);
  1425. }
  1426. else
  1427. {
  1428. /* Nothing to do */
  1429. }
  1430. }
  1431. /* FMPSMBUS in mode Listener Only --------------------------------------------------*/
  1432. if (((FMPSMBUS_CHECK_IT_SOURCE(tmpcr1value, FMPSMBUS_IT_ADDRI) != RESET) ||
  1433. (FMPSMBUS_CHECK_IT_SOURCE(tmpcr1value, FMPSMBUS_IT_STOPI) != RESET) ||
  1434. (FMPSMBUS_CHECK_IT_SOURCE(tmpcr1value, FMPSMBUS_IT_NACKI) != RESET)) &&
  1435. ((FMPSMBUS_CHECK_FLAG(tmpisrvalue, FMPSMBUS_FLAG_ADDR) != RESET) ||
  1436. (FMPSMBUS_CHECK_FLAG(tmpisrvalue, FMPSMBUS_FLAG_STOPF) != RESET) ||
  1437. (FMPSMBUS_CHECK_FLAG(tmpisrvalue, FMPSMBUS_FLAG_AF) != RESET)))
  1438. {
  1439. if ((hfmpsmbus->State & HAL_FMPSMBUS_STATE_LISTEN) == HAL_FMPSMBUS_STATE_LISTEN)
  1440. {
  1441. (void)FMPSMBUS_Slave_ISR(hfmpsmbus, tmpisrvalue);
  1442. }
  1443. }
  1444. }
  1445. /**
  1446. * @brief Handle FMPSMBUS error interrupt request.
  1447. * @param hfmpsmbus Pointer to a FMPSMBUS_HandleTypeDef structure that contains
  1448. * the configuration information for the specified FMPSMBUS.
  1449. * @retval None
  1450. */
  1451. void HAL_FMPSMBUS_ER_IRQHandler(FMPSMBUS_HandleTypeDef *hfmpsmbus)
  1452. {
  1453. FMPSMBUS_ITErrorHandler(hfmpsmbus);
  1454. }
  1455. /**
  1456. * @brief Master Tx Transfer completed callback.
  1457. * @param hfmpsmbus Pointer to a FMPSMBUS_HandleTypeDef structure that contains
  1458. * the configuration information for the specified FMPSMBUS.
  1459. * @retval None
  1460. */
  1461. __weak void HAL_FMPSMBUS_MasterTxCpltCallback(FMPSMBUS_HandleTypeDef *hfmpsmbus)
  1462. {
  1463. /* Prevent unused argument(s) compilation warning */
  1464. UNUSED(hfmpsmbus);
  1465. /* NOTE : This function should not be modified, when the callback is needed,
  1466. the HAL_FMPSMBUS_MasterTxCpltCallback() could be implemented in the user file
  1467. */
  1468. }
  1469. /**
  1470. * @brief Master Rx Transfer completed callback.
  1471. * @param hfmpsmbus Pointer to a FMPSMBUS_HandleTypeDef structure that contains
  1472. * the configuration information for the specified FMPSMBUS.
  1473. * @retval None
  1474. */
  1475. __weak void HAL_FMPSMBUS_MasterRxCpltCallback(FMPSMBUS_HandleTypeDef *hfmpsmbus)
  1476. {
  1477. /* Prevent unused argument(s) compilation warning */
  1478. UNUSED(hfmpsmbus);
  1479. /* NOTE : This function should not be modified, when the callback is needed,
  1480. the HAL_FMPSMBUS_MasterRxCpltCallback() could be implemented in the user file
  1481. */
  1482. }
  1483. /** @brief Slave Tx Transfer completed callback.
  1484. * @param hfmpsmbus Pointer to a FMPSMBUS_HandleTypeDef structure that contains
  1485. * the configuration information for the specified FMPSMBUS.
  1486. * @retval None
  1487. */
  1488. __weak void HAL_FMPSMBUS_SlaveTxCpltCallback(FMPSMBUS_HandleTypeDef *hfmpsmbus)
  1489. {
  1490. /* Prevent unused argument(s) compilation warning */
  1491. UNUSED(hfmpsmbus);
  1492. /* NOTE : This function should not be modified, when the callback is needed,
  1493. the HAL_FMPSMBUS_SlaveTxCpltCallback() could be implemented in the user file
  1494. */
  1495. }
  1496. /**
  1497. * @brief Slave Rx Transfer completed callback.
  1498. * @param hfmpsmbus Pointer to a FMPSMBUS_HandleTypeDef structure that contains
  1499. * the configuration information for the specified FMPSMBUS.
  1500. * @retval None
  1501. */
  1502. __weak void HAL_FMPSMBUS_SlaveRxCpltCallback(FMPSMBUS_HandleTypeDef *hfmpsmbus)
  1503. {
  1504. /* Prevent unused argument(s) compilation warning */
  1505. UNUSED(hfmpsmbus);
  1506. /* NOTE : This function should not be modified, when the callback is needed,
  1507. the HAL_FMPSMBUS_SlaveRxCpltCallback() could be implemented in the user file
  1508. */
  1509. }
  1510. /**
  1511. * @brief Slave Address Match callback.
  1512. * @param hfmpsmbus Pointer to a FMPSMBUS_HandleTypeDef structure that contains
  1513. * the configuration information for the specified FMPSMBUS.
  1514. * @param TransferDirection Master request Transfer Direction (Write/Read)
  1515. * @param AddrMatchCode Address Match Code
  1516. * @retval None
  1517. */
  1518. __weak void HAL_FMPSMBUS_AddrCallback(FMPSMBUS_HandleTypeDef *hfmpsmbus, uint8_t TransferDirection,
  1519. uint16_t AddrMatchCode)
  1520. {
  1521. /* Prevent unused argument(s) compilation warning */
  1522. UNUSED(hfmpsmbus);
  1523. UNUSED(TransferDirection);
  1524. UNUSED(AddrMatchCode);
  1525. /* NOTE : This function should not be modified, when the callback is needed,
  1526. the HAL_FMPSMBUS_AddrCallback() could be implemented in the user file
  1527. */
  1528. }
  1529. /**
  1530. * @brief Listen Complete callback.
  1531. * @param hfmpsmbus Pointer to a FMPSMBUS_HandleTypeDef structure that contains
  1532. * the configuration information for the specified FMPSMBUS.
  1533. * @retval None
  1534. */
  1535. __weak void HAL_FMPSMBUS_ListenCpltCallback(FMPSMBUS_HandleTypeDef *hfmpsmbus)
  1536. {
  1537. /* Prevent unused argument(s) compilation warning */
  1538. UNUSED(hfmpsmbus);
  1539. /* NOTE : This function should not be modified, when the callback is needed,
  1540. the HAL_FMPSMBUS_ListenCpltCallback() could be implemented in the user file
  1541. */
  1542. }
  1543. /**
  1544. * @brief FMPSMBUS error callback.
  1545. * @param hfmpsmbus Pointer to a FMPSMBUS_HandleTypeDef structure that contains
  1546. * the configuration information for the specified FMPSMBUS.
  1547. * @retval None
  1548. */
  1549. __weak void HAL_FMPSMBUS_ErrorCallback(FMPSMBUS_HandleTypeDef *hfmpsmbus)
  1550. {
  1551. /* Prevent unused argument(s) compilation warning */
  1552. UNUSED(hfmpsmbus);
  1553. /* NOTE : This function should not be modified, when the callback is needed,
  1554. the HAL_FMPSMBUS_ErrorCallback() could be implemented in the user file
  1555. */
  1556. }
  1557. /**
  1558. * @}
  1559. */
  1560. /** @defgroup FMPSMBUS_Exported_Functions_Group3 Peripheral State and Errors functions
  1561. * @brief Peripheral State and Errors functions
  1562. *
  1563. @verbatim
  1564. ===============================================================================
  1565. ##### Peripheral State and Errors functions #####
  1566. ===============================================================================
  1567. [..]
  1568. This subsection permits to get in run-time the status of the peripheral
  1569. and the data flow.
  1570. @endverbatim
  1571. * @{
  1572. */
  1573. /**
  1574. * @brief Return the FMPSMBUS handle state.
  1575. * @param hfmpsmbus Pointer to a FMPSMBUS_HandleTypeDef structure that contains
  1576. * the configuration information for the specified FMPSMBUS.
  1577. * @retval HAL state
  1578. */
  1579. uint32_t HAL_FMPSMBUS_GetState(const FMPSMBUS_HandleTypeDef *hfmpsmbus)
  1580. {
  1581. /* Return FMPSMBUS handle state */
  1582. return hfmpsmbus->State;
  1583. }
  1584. /**
  1585. * @brief Return the FMPSMBUS error code.
  1586. * @param hfmpsmbus Pointer to a FMPSMBUS_HandleTypeDef structure that contains
  1587. * the configuration information for the specified FMPSMBUS.
  1588. * @retval FMPSMBUS Error Code
  1589. */
  1590. uint32_t HAL_FMPSMBUS_GetError(const FMPSMBUS_HandleTypeDef *hfmpsmbus)
  1591. {
  1592. return hfmpsmbus->ErrorCode;
  1593. }
  1594. /**
  1595. * @}
  1596. */
  1597. /**
  1598. * @}
  1599. */
  1600. /** @addtogroup FMPSMBUS_Private_Functions FMPSMBUS Private Functions
  1601. * @brief Data transfers Private functions
  1602. * @{
  1603. */
  1604. /**
  1605. * @brief Interrupt Sub-Routine which handle the Interrupt Flags Master Mode.
  1606. * @param hfmpsmbus Pointer to a FMPSMBUS_HandleTypeDef structure that contains
  1607. * the configuration information for the specified FMPSMBUS.
  1608. * @param StatusFlags Value of Interrupt Flags.
  1609. * @retval HAL status
  1610. */
  1611. static HAL_StatusTypeDef FMPSMBUS_Master_ISR(FMPSMBUS_HandleTypeDef *hfmpsmbus, uint32_t StatusFlags)
  1612. {
  1613. uint16_t DevAddress;
  1614. /* Process Locked */
  1615. __HAL_LOCK(hfmpsmbus);
  1616. if (FMPSMBUS_CHECK_FLAG(StatusFlags, FMPSMBUS_FLAG_AF) != RESET)
  1617. {
  1618. /* Clear NACK Flag */
  1619. __HAL_FMPSMBUS_CLEAR_FLAG(hfmpsmbus, FMPSMBUS_FLAG_AF);
  1620. /* Set corresponding Error Code */
  1621. /* No need to generate STOP, it is automatically done */
  1622. hfmpsmbus->ErrorCode |= HAL_FMPSMBUS_ERROR_ACKF;
  1623. /* Flush TX register */
  1624. FMPSMBUS_Flush_TXDR(hfmpsmbus);
  1625. /* Process Unlocked */
  1626. __HAL_UNLOCK(hfmpsmbus);
  1627. /* Call the Error callback to inform upper layer */
  1628. #if (USE_HAL_FMPSMBUS_REGISTER_CALLBACKS == 1)
  1629. hfmpsmbus->ErrorCallback(hfmpsmbus);
  1630. #else
  1631. HAL_FMPSMBUS_ErrorCallback(hfmpsmbus);
  1632. #endif /* USE_HAL_FMPSMBUS_REGISTER_CALLBACKS */
  1633. }
  1634. else if (FMPSMBUS_CHECK_FLAG(StatusFlags, FMPSMBUS_FLAG_STOPF) != RESET)
  1635. {
  1636. /* Check and treat errors if errors occurs during STOP process */
  1637. FMPSMBUS_ITErrorHandler(hfmpsmbus);
  1638. /* Call the corresponding callback to inform upper layer of End of Transfer */
  1639. if (hfmpsmbus->State == HAL_FMPSMBUS_STATE_MASTER_BUSY_TX)
  1640. {
  1641. /* Disable Interrupt */
  1642. FMPSMBUS_Disable_IRQ(hfmpsmbus, FMPSMBUS_IT_TX);
  1643. /* Clear STOP Flag */
  1644. __HAL_FMPSMBUS_CLEAR_FLAG(hfmpsmbus, FMPSMBUS_FLAG_STOPF);
  1645. /* Clear Configuration Register 2 */
  1646. FMPSMBUS_RESET_CR2(hfmpsmbus);
  1647. /* Flush remaining data in Fifo register in case of error occurs before TXEmpty */
  1648. /* Disable the selected FMPSMBUS peripheral */
  1649. __HAL_FMPSMBUS_DISABLE(hfmpsmbus);
  1650. hfmpsmbus->PreviousState = HAL_FMPSMBUS_STATE_READY;
  1651. hfmpsmbus->State = HAL_FMPSMBUS_STATE_READY;
  1652. /* Process Unlocked */
  1653. __HAL_UNLOCK(hfmpsmbus);
  1654. /* Re-enable the selected FMPSMBUS peripheral */
  1655. __HAL_FMPSMBUS_ENABLE(hfmpsmbus);
  1656. /* Call the corresponding callback to inform upper layer of End of Transfer */
  1657. #if (USE_HAL_FMPSMBUS_REGISTER_CALLBACKS == 1)
  1658. hfmpsmbus->MasterTxCpltCallback(hfmpsmbus);
  1659. #else
  1660. HAL_FMPSMBUS_MasterTxCpltCallback(hfmpsmbus);
  1661. #endif /* USE_HAL_FMPSMBUS_REGISTER_CALLBACKS */
  1662. }
  1663. else if (hfmpsmbus->State == HAL_FMPSMBUS_STATE_MASTER_BUSY_RX)
  1664. {
  1665. /* Store Last receive data if any */
  1666. if (FMPSMBUS_CHECK_FLAG(StatusFlags, FMPSMBUS_FLAG_RXNE) != RESET)
  1667. {
  1668. /* Read data from RXDR */
  1669. *hfmpsmbus->pBuffPtr = (uint8_t)(hfmpsmbus->Instance->RXDR);
  1670. /* Increment Buffer pointer */
  1671. hfmpsmbus->pBuffPtr++;
  1672. if ((hfmpsmbus->XferSize > 0U))
  1673. {
  1674. hfmpsmbus->XferSize--;
  1675. hfmpsmbus->XferCount--;
  1676. }
  1677. }
  1678. /* Disable Interrupt */
  1679. FMPSMBUS_Disable_IRQ(hfmpsmbus, FMPSMBUS_IT_RX);
  1680. /* Clear STOP Flag */
  1681. __HAL_FMPSMBUS_CLEAR_FLAG(hfmpsmbus, FMPSMBUS_FLAG_STOPF);
  1682. /* Clear Configuration Register 2 */
  1683. FMPSMBUS_RESET_CR2(hfmpsmbus);
  1684. hfmpsmbus->PreviousState = HAL_FMPSMBUS_STATE_READY;
  1685. hfmpsmbus->State = HAL_FMPSMBUS_STATE_READY;
  1686. /* Process Unlocked */
  1687. __HAL_UNLOCK(hfmpsmbus);
  1688. /* Call the corresponding callback to inform upper layer of End of Transfer */
  1689. #if (USE_HAL_FMPSMBUS_REGISTER_CALLBACKS == 1)
  1690. hfmpsmbus->MasterRxCpltCallback(hfmpsmbus);
  1691. #else
  1692. HAL_FMPSMBUS_MasterRxCpltCallback(hfmpsmbus);
  1693. #endif /* USE_HAL_FMPSMBUS_REGISTER_CALLBACKS */
  1694. }
  1695. else
  1696. {
  1697. /* Nothing to do */
  1698. }
  1699. }
  1700. else if (FMPSMBUS_CHECK_FLAG(StatusFlags, FMPSMBUS_FLAG_RXNE) != RESET)
  1701. {
  1702. /* Read data from RXDR */
  1703. *hfmpsmbus->pBuffPtr = (uint8_t)(hfmpsmbus->Instance->RXDR);
  1704. /* Increment Buffer pointer */
  1705. hfmpsmbus->pBuffPtr++;
  1706. /* Increment Size counter */
  1707. hfmpsmbus->XferSize--;
  1708. hfmpsmbus->XferCount--;
  1709. }
  1710. else if (FMPSMBUS_CHECK_FLAG(StatusFlags, FMPSMBUS_FLAG_TXIS) != RESET)
  1711. {
  1712. /* Write data to TXDR */
  1713. hfmpsmbus->Instance->TXDR = *hfmpsmbus->pBuffPtr;
  1714. /* Increment Buffer pointer */
  1715. hfmpsmbus->pBuffPtr++;
  1716. /* Increment Size counter */
  1717. hfmpsmbus->XferSize--;
  1718. hfmpsmbus->XferCount--;
  1719. }
  1720. else if (FMPSMBUS_CHECK_FLAG(StatusFlags, FMPSMBUS_FLAG_TCR) != RESET)
  1721. {
  1722. if ((hfmpsmbus->XferCount != 0U) && (hfmpsmbus->XferSize == 0U))
  1723. {
  1724. DevAddress = (uint16_t)(hfmpsmbus->Instance->CR2 & FMPI2C_CR2_SADD);
  1725. if (hfmpsmbus->XferCount > MAX_NBYTE_SIZE)
  1726. {
  1727. FMPSMBUS_TransferConfig(hfmpsmbus, DevAddress, MAX_NBYTE_SIZE,
  1728. (FMPSMBUS_RELOAD_MODE | (hfmpsmbus->XferOptions & FMPSMBUS_SENDPEC_MODE)),
  1729. FMPSMBUS_NO_STARTSTOP);
  1730. hfmpsmbus->XferSize = MAX_NBYTE_SIZE;
  1731. }
  1732. else
  1733. {
  1734. hfmpsmbus->XferSize = hfmpsmbus->XferCount;
  1735. FMPSMBUS_TransferConfig(hfmpsmbus, DevAddress, (uint8_t)hfmpsmbus->XferSize, hfmpsmbus->XferOptions,
  1736. FMPSMBUS_NO_STARTSTOP);
  1737. /* If PEC mode is enable, size to transmit should be Size-1 byte, corresponding to PEC byte */
  1738. /* PEC byte is automatically sent by HW block, no need to manage it in Transmit process */
  1739. if (FMPSMBUS_GET_PEC_MODE(hfmpsmbus) != 0UL)
  1740. {
  1741. hfmpsmbus->XferSize--;
  1742. hfmpsmbus->XferCount--;
  1743. }
  1744. }
  1745. }
  1746. else if ((hfmpsmbus->XferCount == 0U) && (hfmpsmbus->XferSize == 0U))
  1747. {
  1748. /* Call TxCpltCallback() if no stop mode is set */
  1749. if (FMPSMBUS_GET_STOP_MODE(hfmpsmbus) != FMPSMBUS_AUTOEND_MODE)
  1750. {
  1751. /* Call the corresponding callback to inform upper layer of End of Transfer */
  1752. if (hfmpsmbus->State == HAL_FMPSMBUS_STATE_MASTER_BUSY_TX)
  1753. {
  1754. /* Disable Interrupt */
  1755. FMPSMBUS_Disable_IRQ(hfmpsmbus, FMPSMBUS_IT_TX);
  1756. hfmpsmbus->PreviousState = hfmpsmbus->State;
  1757. hfmpsmbus->State = HAL_FMPSMBUS_STATE_READY;
  1758. /* Process Unlocked */
  1759. __HAL_UNLOCK(hfmpsmbus);
  1760. /* Call the corresponding callback to inform upper layer of End of Transfer */
  1761. #if (USE_HAL_FMPSMBUS_REGISTER_CALLBACKS == 1)
  1762. hfmpsmbus->MasterTxCpltCallback(hfmpsmbus);
  1763. #else
  1764. HAL_FMPSMBUS_MasterTxCpltCallback(hfmpsmbus);
  1765. #endif /* USE_HAL_FMPSMBUS_REGISTER_CALLBACKS */
  1766. }
  1767. else if (hfmpsmbus->State == HAL_FMPSMBUS_STATE_MASTER_BUSY_RX)
  1768. {
  1769. FMPSMBUS_Disable_IRQ(hfmpsmbus, FMPSMBUS_IT_RX);
  1770. hfmpsmbus->PreviousState = hfmpsmbus->State;
  1771. hfmpsmbus->State = HAL_FMPSMBUS_STATE_READY;
  1772. /* Process Unlocked */
  1773. __HAL_UNLOCK(hfmpsmbus);
  1774. /* Call the corresponding callback to inform upper layer of End of Transfer */
  1775. #if (USE_HAL_FMPSMBUS_REGISTER_CALLBACKS == 1)
  1776. hfmpsmbus->MasterRxCpltCallback(hfmpsmbus);
  1777. #else
  1778. HAL_FMPSMBUS_MasterRxCpltCallback(hfmpsmbus);
  1779. #endif /* USE_HAL_FMPSMBUS_REGISTER_CALLBACKS */
  1780. }
  1781. else
  1782. {
  1783. /* Nothing to do */
  1784. }
  1785. }
  1786. }
  1787. else
  1788. {
  1789. /* Nothing to do */
  1790. }
  1791. }
  1792. else if (FMPSMBUS_CHECK_FLAG(StatusFlags, FMPSMBUS_FLAG_TC) != RESET)
  1793. {
  1794. if (hfmpsmbus->XferCount == 0U)
  1795. {
  1796. /* Specific use case for Quick command */
  1797. if (hfmpsmbus->pBuffPtr == NULL)
  1798. {
  1799. /* Generate a Stop command */
  1800. hfmpsmbus->Instance->CR2 |= FMPI2C_CR2_STOP;
  1801. }
  1802. /* Call TxCpltCallback() if no stop mode is set */
  1803. else if (FMPSMBUS_GET_STOP_MODE(hfmpsmbus) != FMPSMBUS_AUTOEND_MODE)
  1804. {
  1805. /* No Generate Stop, to permit restart mode */
  1806. /* The stop will be done at the end of transfer, when FMPSMBUS_AUTOEND_MODE enable */
  1807. /* Call the corresponding callback to inform upper layer of End of Transfer */
  1808. if (hfmpsmbus->State == HAL_FMPSMBUS_STATE_MASTER_BUSY_TX)
  1809. {
  1810. /* Disable Interrupt */
  1811. FMPSMBUS_Disable_IRQ(hfmpsmbus, FMPSMBUS_IT_TX);
  1812. hfmpsmbus->PreviousState = hfmpsmbus->State;
  1813. hfmpsmbus->State = HAL_FMPSMBUS_STATE_READY;
  1814. /* Process Unlocked */
  1815. __HAL_UNLOCK(hfmpsmbus);
  1816. /* Call the corresponding callback to inform upper layer of End of Transfer */
  1817. #if (USE_HAL_FMPSMBUS_REGISTER_CALLBACKS == 1)
  1818. hfmpsmbus->MasterTxCpltCallback(hfmpsmbus);
  1819. #else
  1820. HAL_FMPSMBUS_MasterTxCpltCallback(hfmpsmbus);
  1821. #endif /* USE_HAL_FMPSMBUS_REGISTER_CALLBACKS */
  1822. }
  1823. else if (hfmpsmbus->State == HAL_FMPSMBUS_STATE_MASTER_BUSY_RX)
  1824. {
  1825. FMPSMBUS_Disable_IRQ(hfmpsmbus, FMPSMBUS_IT_RX);
  1826. hfmpsmbus->PreviousState = hfmpsmbus->State;
  1827. hfmpsmbus->State = HAL_FMPSMBUS_STATE_READY;
  1828. /* Process Unlocked */
  1829. __HAL_UNLOCK(hfmpsmbus);
  1830. /* Call the corresponding callback to inform upper layer of End of Transfer */
  1831. #if (USE_HAL_FMPSMBUS_REGISTER_CALLBACKS == 1)
  1832. hfmpsmbus->MasterRxCpltCallback(hfmpsmbus);
  1833. #else
  1834. HAL_FMPSMBUS_MasterRxCpltCallback(hfmpsmbus);
  1835. #endif /* USE_HAL_FMPSMBUS_REGISTER_CALLBACKS */
  1836. }
  1837. else
  1838. {
  1839. /* Nothing to do */
  1840. }
  1841. }
  1842. else
  1843. {
  1844. /* Nothing to do */
  1845. }
  1846. }
  1847. }
  1848. else
  1849. {
  1850. /* Nothing to do */
  1851. }
  1852. /* Process Unlocked */
  1853. __HAL_UNLOCK(hfmpsmbus);
  1854. return HAL_OK;
  1855. }
  1856. /**
  1857. * @brief Interrupt Sub-Routine which handle the Interrupt Flags Slave Mode.
  1858. * @param hfmpsmbus Pointer to a FMPSMBUS_HandleTypeDef structure that contains
  1859. * the configuration information for the specified FMPSMBUS.
  1860. * @param StatusFlags Value of Interrupt Flags.
  1861. * @retval HAL status
  1862. */
  1863. static HAL_StatusTypeDef FMPSMBUS_Slave_ISR(FMPSMBUS_HandleTypeDef *hfmpsmbus, uint32_t StatusFlags)
  1864. {
  1865. uint8_t TransferDirection;
  1866. uint16_t SlaveAddrCode;
  1867. /* Process Locked */
  1868. __HAL_LOCK(hfmpsmbus);
  1869. if (FMPSMBUS_CHECK_FLAG(StatusFlags, FMPSMBUS_FLAG_AF) != RESET)
  1870. {
  1871. /* Check that FMPSMBUS transfer finished */
  1872. /* if yes, normal usecase, a NACK is sent by the HOST when Transfer is finished */
  1873. /* Mean XferCount == 0*/
  1874. /* So clear Flag NACKF only */
  1875. if (hfmpsmbus->XferCount == 0U)
  1876. {
  1877. /* Clear NACK Flag */
  1878. __HAL_FMPSMBUS_CLEAR_FLAG(hfmpsmbus, FMPSMBUS_FLAG_AF);
  1879. /* Flush TX register */
  1880. FMPSMBUS_Flush_TXDR(hfmpsmbus);
  1881. /* Process Unlocked */
  1882. __HAL_UNLOCK(hfmpsmbus);
  1883. }
  1884. else
  1885. {
  1886. /* if no, error usecase, a Non-Acknowledge of last Data is generated by the HOST*/
  1887. /* Clear NACK Flag */
  1888. __HAL_FMPSMBUS_CLEAR_FLAG(hfmpsmbus, FMPSMBUS_FLAG_AF);
  1889. /* Set HAL State to "Idle" State, mean to LISTEN state */
  1890. /* So reset Slave Busy state */
  1891. hfmpsmbus->PreviousState = hfmpsmbus->State;
  1892. hfmpsmbus->State &= ~((uint32_t)HAL_FMPSMBUS_STATE_SLAVE_BUSY_TX);
  1893. hfmpsmbus->State &= ~((uint32_t)HAL_FMPSMBUS_STATE_SLAVE_BUSY_RX);
  1894. /* Disable RX/TX Interrupts, keep only ADDR Interrupt */
  1895. FMPSMBUS_Disable_IRQ(hfmpsmbus, FMPSMBUS_IT_RX | FMPSMBUS_IT_TX);
  1896. /* Set ErrorCode corresponding to a Non-Acknowledge */
  1897. hfmpsmbus->ErrorCode |= HAL_FMPSMBUS_ERROR_ACKF;
  1898. /* Flush TX register */
  1899. FMPSMBUS_Flush_TXDR(hfmpsmbus);
  1900. /* Process Unlocked */
  1901. __HAL_UNLOCK(hfmpsmbus);
  1902. /* Call the Error callback to inform upper layer */
  1903. #if (USE_HAL_FMPSMBUS_REGISTER_CALLBACKS == 1)
  1904. hfmpsmbus->ErrorCallback(hfmpsmbus);
  1905. #else
  1906. HAL_FMPSMBUS_ErrorCallback(hfmpsmbus);
  1907. #endif /* USE_HAL_FMPSMBUS_REGISTER_CALLBACKS */
  1908. }
  1909. }
  1910. else if (FMPSMBUS_CHECK_FLAG(StatusFlags, FMPSMBUS_FLAG_ADDR) != RESET)
  1911. {
  1912. TransferDirection = (uint8_t)(FMPSMBUS_GET_DIR(hfmpsmbus));
  1913. SlaveAddrCode = (uint16_t)(FMPSMBUS_GET_ADDR_MATCH(hfmpsmbus));
  1914. /* Disable ADDR interrupt to prevent multiple ADDRInterrupt*/
  1915. /* Other ADDRInterrupt will be treat in next Listen usecase */
  1916. __HAL_FMPSMBUS_DISABLE_IT(hfmpsmbus, FMPSMBUS_IT_ADDRI);
  1917. /* Process Unlocked */
  1918. __HAL_UNLOCK(hfmpsmbus);
  1919. /* Call Slave Addr callback */
  1920. #if (USE_HAL_FMPSMBUS_REGISTER_CALLBACKS == 1)
  1921. hfmpsmbus->AddrCallback(hfmpsmbus, TransferDirection, SlaveAddrCode);
  1922. #else
  1923. HAL_FMPSMBUS_AddrCallback(hfmpsmbus, TransferDirection, SlaveAddrCode);
  1924. #endif /* USE_HAL_FMPSMBUS_REGISTER_CALLBACKS */
  1925. }
  1926. else if ((FMPSMBUS_CHECK_FLAG(StatusFlags, FMPSMBUS_FLAG_RXNE) != RESET) ||
  1927. (FMPSMBUS_CHECK_FLAG(StatusFlags, FMPSMBUS_FLAG_TCR) != RESET))
  1928. {
  1929. if ((hfmpsmbus->State & HAL_FMPSMBUS_STATE_SLAVE_BUSY_RX) == HAL_FMPSMBUS_STATE_SLAVE_BUSY_RX)
  1930. {
  1931. /* Read data from RXDR */
  1932. *hfmpsmbus->pBuffPtr = (uint8_t)(hfmpsmbus->Instance->RXDR);
  1933. /* Increment Buffer pointer */
  1934. hfmpsmbus->pBuffPtr++;
  1935. hfmpsmbus->XferSize--;
  1936. hfmpsmbus->XferCount--;
  1937. if (hfmpsmbus->XferCount == 1U)
  1938. {
  1939. /* Receive last Byte, can be PEC byte in case of PEC BYTE enabled */
  1940. /* or only the last Byte of Transfer */
  1941. /* So reset the RELOAD bit mode */
  1942. hfmpsmbus->XferOptions &= ~FMPSMBUS_RELOAD_MODE;
  1943. FMPSMBUS_TransferConfig(hfmpsmbus, 0, 1, hfmpsmbus->XferOptions, FMPSMBUS_NO_STARTSTOP);
  1944. }
  1945. else if (hfmpsmbus->XferCount == 0U)
  1946. {
  1947. /* Last Byte is received, disable Interrupt */
  1948. FMPSMBUS_Disable_IRQ(hfmpsmbus, FMPSMBUS_IT_RX);
  1949. /* Remove HAL_FMPSMBUS_STATE_SLAVE_BUSY_RX, keep only HAL_FMPSMBUS_STATE_LISTEN */
  1950. hfmpsmbus->PreviousState = hfmpsmbus->State;
  1951. hfmpsmbus->State &= ~((uint32_t)HAL_FMPSMBUS_STATE_SLAVE_BUSY_RX);
  1952. /* Process Unlocked */
  1953. __HAL_UNLOCK(hfmpsmbus);
  1954. /* Call the corresponding callback to inform upper layer of End of Transfer */
  1955. #if (USE_HAL_FMPSMBUS_REGISTER_CALLBACKS == 1)
  1956. hfmpsmbus->SlaveRxCpltCallback(hfmpsmbus);
  1957. #else
  1958. HAL_FMPSMBUS_SlaveRxCpltCallback(hfmpsmbus);
  1959. #endif /* USE_HAL_FMPSMBUS_REGISTER_CALLBACKS */
  1960. }
  1961. else
  1962. {
  1963. /* Set Reload for next Bytes */
  1964. FMPSMBUS_TransferConfig(hfmpsmbus, 0, 1,
  1965. FMPSMBUS_RELOAD_MODE | (hfmpsmbus->XferOptions & FMPSMBUS_SENDPEC_MODE),
  1966. FMPSMBUS_NO_STARTSTOP);
  1967. /* Ack last Byte Read */
  1968. hfmpsmbus->Instance->CR2 &= ~FMPI2C_CR2_NACK;
  1969. }
  1970. }
  1971. else if ((hfmpsmbus->State & HAL_FMPSMBUS_STATE_SLAVE_BUSY_TX) == HAL_FMPSMBUS_STATE_SLAVE_BUSY_TX)
  1972. {
  1973. if ((hfmpsmbus->XferCount != 0U) && (hfmpsmbus->XferSize == 0U))
  1974. {
  1975. if (hfmpsmbus->XferCount > MAX_NBYTE_SIZE)
  1976. {
  1977. FMPSMBUS_TransferConfig(hfmpsmbus, 0, MAX_NBYTE_SIZE,
  1978. (FMPSMBUS_RELOAD_MODE | (hfmpsmbus->XferOptions & FMPSMBUS_SENDPEC_MODE)),
  1979. FMPSMBUS_NO_STARTSTOP);
  1980. hfmpsmbus->XferSize = MAX_NBYTE_SIZE;
  1981. }
  1982. else
  1983. {
  1984. hfmpsmbus->XferSize = hfmpsmbus->XferCount;
  1985. FMPSMBUS_TransferConfig(hfmpsmbus, 0, (uint8_t)hfmpsmbus->XferSize, hfmpsmbus->XferOptions,
  1986. FMPSMBUS_NO_STARTSTOP);
  1987. /* If PEC mode is enable, size to transmit should be Size-1 byte, corresponding to PEC byte */
  1988. /* PEC byte is automatically sent by HW block, no need to manage it in Transmit process */
  1989. if (FMPSMBUS_GET_PEC_MODE(hfmpsmbus) != 0UL)
  1990. {
  1991. hfmpsmbus->XferSize--;
  1992. hfmpsmbus->XferCount--;
  1993. }
  1994. }
  1995. }
  1996. }
  1997. else
  1998. {
  1999. /* Nothing to do */
  2000. }
  2001. }
  2002. else if (FMPSMBUS_CHECK_FLAG(StatusFlags, FMPSMBUS_FLAG_TXIS) != RESET)
  2003. {
  2004. /* Write data to TXDR only if XferCount not reach "0" */
  2005. /* A TXIS flag can be set, during STOP treatment */
  2006. /* Check if all Data have already been sent */
  2007. /* If it is the case, this last write in TXDR is not sent, correspond to a dummy TXIS event */
  2008. if (hfmpsmbus->XferCount > 0U)
  2009. {
  2010. /* Write data to TXDR */
  2011. hfmpsmbus->Instance->TXDR = *hfmpsmbus->pBuffPtr;
  2012. /* Increment Buffer pointer */
  2013. hfmpsmbus->pBuffPtr++;
  2014. hfmpsmbus->XferCount--;
  2015. hfmpsmbus->XferSize--;
  2016. }
  2017. if (hfmpsmbus->XferCount == 0U)
  2018. {
  2019. /* Last Byte is Transmitted */
  2020. /* Remove HAL_FMPSMBUS_STATE_SLAVE_BUSY_TX, keep only HAL_FMPSMBUS_STATE_LISTEN */
  2021. FMPSMBUS_Disable_IRQ(hfmpsmbus, FMPSMBUS_IT_TX);
  2022. hfmpsmbus->PreviousState = hfmpsmbus->State;
  2023. hfmpsmbus->State &= ~((uint32_t)HAL_FMPSMBUS_STATE_SLAVE_BUSY_TX);
  2024. /* Process Unlocked */
  2025. __HAL_UNLOCK(hfmpsmbus);
  2026. /* Call the corresponding callback to inform upper layer of End of Transfer */
  2027. #if (USE_HAL_FMPSMBUS_REGISTER_CALLBACKS == 1)
  2028. hfmpsmbus->SlaveTxCpltCallback(hfmpsmbus);
  2029. #else
  2030. HAL_FMPSMBUS_SlaveTxCpltCallback(hfmpsmbus);
  2031. #endif /* USE_HAL_FMPSMBUS_REGISTER_CALLBACKS */
  2032. }
  2033. }
  2034. else
  2035. {
  2036. /* Nothing to do */
  2037. }
  2038. /* Check if STOPF is set */
  2039. if (FMPSMBUS_CHECK_FLAG(StatusFlags, FMPSMBUS_FLAG_STOPF) != RESET)
  2040. {
  2041. if ((hfmpsmbus->State & HAL_FMPSMBUS_STATE_LISTEN) == HAL_FMPSMBUS_STATE_LISTEN)
  2042. {
  2043. /* Store Last receive data if any */
  2044. if (__HAL_FMPSMBUS_GET_FLAG(hfmpsmbus, FMPSMBUS_FLAG_RXNE) != RESET)
  2045. {
  2046. /* Read data from RXDR */
  2047. *hfmpsmbus->pBuffPtr = (uint8_t)(hfmpsmbus->Instance->RXDR);
  2048. /* Increment Buffer pointer */
  2049. hfmpsmbus->pBuffPtr++;
  2050. if ((hfmpsmbus->XferSize > 0U))
  2051. {
  2052. hfmpsmbus->XferSize--;
  2053. hfmpsmbus->XferCount--;
  2054. }
  2055. }
  2056. /* Disable RX and TX Interrupts */
  2057. FMPSMBUS_Disable_IRQ(hfmpsmbus, FMPSMBUS_IT_RX | FMPSMBUS_IT_TX);
  2058. /* Disable ADDR Interrupt */
  2059. FMPSMBUS_Disable_IRQ(hfmpsmbus, FMPSMBUS_IT_ADDR);
  2060. /* Disable Address Acknowledge */
  2061. hfmpsmbus->Instance->CR2 |= FMPI2C_CR2_NACK;
  2062. /* Clear Configuration Register 2 */
  2063. FMPSMBUS_RESET_CR2(hfmpsmbus);
  2064. /* Clear STOP Flag */
  2065. __HAL_FMPSMBUS_CLEAR_FLAG(hfmpsmbus, FMPSMBUS_FLAG_STOPF);
  2066. /* Clear ADDR flag */
  2067. __HAL_FMPSMBUS_CLEAR_FLAG(hfmpsmbus, FMPSMBUS_FLAG_ADDR);
  2068. hfmpsmbus->XferOptions = 0;
  2069. hfmpsmbus->PreviousState = hfmpsmbus->State;
  2070. hfmpsmbus->State = HAL_FMPSMBUS_STATE_READY;
  2071. /* Process Unlocked */
  2072. __HAL_UNLOCK(hfmpsmbus);
  2073. /* Call the Listen Complete callback, to inform upper layer of the end of Listen usecase */
  2074. #if (USE_HAL_FMPSMBUS_REGISTER_CALLBACKS == 1)
  2075. hfmpsmbus->ListenCpltCallback(hfmpsmbus);
  2076. #else
  2077. HAL_FMPSMBUS_ListenCpltCallback(hfmpsmbus);
  2078. #endif /* USE_HAL_FMPSMBUS_REGISTER_CALLBACKS */
  2079. }
  2080. }
  2081. /* Process Unlocked */
  2082. __HAL_UNLOCK(hfmpsmbus);
  2083. return HAL_OK;
  2084. }
  2085. /**
  2086. * @brief Manage the enabling of Interrupts.
  2087. * @param hfmpsmbus Pointer to a FMPSMBUS_HandleTypeDef structure that contains
  2088. * the configuration information for the specified FMPSMBUS.
  2089. * @param InterruptRequest Value of @ref FMPSMBUS_Interrupt_configuration_definition.
  2090. * @retval HAL status
  2091. */
  2092. static void FMPSMBUS_Enable_IRQ(FMPSMBUS_HandleTypeDef *hfmpsmbus, uint32_t InterruptRequest)
  2093. {
  2094. uint32_t tmpisr = 0UL;
  2095. if ((InterruptRequest & FMPSMBUS_IT_ALERT) == FMPSMBUS_IT_ALERT)
  2096. {
  2097. /* Enable ERR interrupt */
  2098. tmpisr |= FMPSMBUS_IT_ERRI;
  2099. }
  2100. if ((InterruptRequest & FMPSMBUS_IT_ADDR) == FMPSMBUS_IT_ADDR)
  2101. {
  2102. /* Enable ADDR, STOP interrupt */
  2103. tmpisr |= FMPSMBUS_IT_ADDRI | FMPSMBUS_IT_STOPI | FMPSMBUS_IT_NACKI | FMPSMBUS_IT_ERRI;
  2104. }
  2105. if ((InterruptRequest & FMPSMBUS_IT_TX) == FMPSMBUS_IT_TX)
  2106. {
  2107. /* Enable ERR, TC, STOP, NACK, RXI interrupt */
  2108. tmpisr |= FMPSMBUS_IT_ERRI | FMPSMBUS_IT_TCI | FMPSMBUS_IT_STOPI | FMPSMBUS_IT_NACKI | FMPSMBUS_IT_TXI;
  2109. }
  2110. if ((InterruptRequest & FMPSMBUS_IT_RX) == FMPSMBUS_IT_RX)
  2111. {
  2112. /* Enable ERR, TC, STOP, NACK, TXI interrupt */
  2113. tmpisr |= FMPSMBUS_IT_ERRI | FMPSMBUS_IT_TCI | FMPSMBUS_IT_STOPI | FMPSMBUS_IT_NACKI | FMPSMBUS_IT_RXI;
  2114. }
  2115. /* Enable interrupts only at the end */
  2116. /* to avoid the risk of FMPSMBUS interrupt handle execution before */
  2117. /* all interrupts requested done */
  2118. __HAL_FMPSMBUS_ENABLE_IT(hfmpsmbus, tmpisr);
  2119. }
  2120. /**
  2121. * @brief Manage the disabling of Interrupts.
  2122. * @param hfmpsmbus Pointer to a FMPSMBUS_HandleTypeDef structure that contains
  2123. * the configuration information for the specified FMPSMBUS.
  2124. * @param InterruptRequest Value of @ref FMPSMBUS_Interrupt_configuration_definition.
  2125. * @retval HAL status
  2126. */
  2127. static void FMPSMBUS_Disable_IRQ(FMPSMBUS_HandleTypeDef *hfmpsmbus, uint32_t InterruptRequest)
  2128. {
  2129. uint32_t tmpisr = 0UL;
  2130. uint32_t tmpstate = hfmpsmbus->State;
  2131. if ((tmpstate == HAL_FMPSMBUS_STATE_READY) && ((InterruptRequest & FMPSMBUS_IT_ALERT) == FMPSMBUS_IT_ALERT))
  2132. {
  2133. /* Disable ERR interrupt */
  2134. tmpisr |= FMPSMBUS_IT_ERRI;
  2135. }
  2136. if ((InterruptRequest & FMPSMBUS_IT_TX) == FMPSMBUS_IT_TX)
  2137. {
  2138. /* Disable TC, STOP, NACK and TXI interrupt */
  2139. tmpisr |= FMPSMBUS_IT_TCI | FMPSMBUS_IT_TXI;
  2140. if ((FMPSMBUS_GET_ALERT_ENABLED(hfmpsmbus) == 0UL)
  2141. && ((tmpstate & HAL_FMPSMBUS_STATE_LISTEN) != HAL_FMPSMBUS_STATE_LISTEN))
  2142. {
  2143. /* Disable ERR interrupt */
  2144. tmpisr |= FMPSMBUS_IT_ERRI;
  2145. }
  2146. if ((tmpstate & HAL_FMPSMBUS_STATE_LISTEN) != HAL_FMPSMBUS_STATE_LISTEN)
  2147. {
  2148. /* Disable STOP and NACK interrupt */
  2149. tmpisr |= FMPSMBUS_IT_STOPI | FMPSMBUS_IT_NACKI;
  2150. }
  2151. }
  2152. if ((InterruptRequest & FMPSMBUS_IT_RX) == FMPSMBUS_IT_RX)
  2153. {
  2154. /* Disable TC, STOP, NACK and RXI interrupt */
  2155. tmpisr |= FMPSMBUS_IT_TCI | FMPSMBUS_IT_RXI;
  2156. if ((FMPSMBUS_GET_ALERT_ENABLED(hfmpsmbus) == 0UL)
  2157. && ((tmpstate & HAL_FMPSMBUS_STATE_LISTEN) != HAL_FMPSMBUS_STATE_LISTEN))
  2158. {
  2159. /* Disable ERR interrupt */
  2160. tmpisr |= FMPSMBUS_IT_ERRI;
  2161. }
  2162. if ((tmpstate & HAL_FMPSMBUS_STATE_LISTEN) != HAL_FMPSMBUS_STATE_LISTEN)
  2163. {
  2164. /* Disable STOP and NACK interrupt */
  2165. tmpisr |= FMPSMBUS_IT_STOPI | FMPSMBUS_IT_NACKI;
  2166. }
  2167. }
  2168. if ((InterruptRequest & FMPSMBUS_IT_ADDR) == FMPSMBUS_IT_ADDR)
  2169. {
  2170. /* Disable ADDR, STOP and NACK interrupt */
  2171. tmpisr |= FMPSMBUS_IT_ADDRI | FMPSMBUS_IT_STOPI | FMPSMBUS_IT_NACKI;
  2172. if (FMPSMBUS_GET_ALERT_ENABLED(hfmpsmbus) == 0UL)
  2173. {
  2174. /* Disable ERR interrupt */
  2175. tmpisr |= FMPSMBUS_IT_ERRI;
  2176. }
  2177. }
  2178. /* Disable interrupts only at the end */
  2179. /* to avoid a breaking situation like at "t" time */
  2180. /* all disable interrupts request are not done */
  2181. __HAL_FMPSMBUS_DISABLE_IT(hfmpsmbus, tmpisr);
  2182. }
  2183. /**
  2184. * @brief FMPSMBUS interrupts error handler.
  2185. * @param hfmpsmbus FMPSMBUS handle.
  2186. * @retval None
  2187. */
  2188. static void FMPSMBUS_ITErrorHandler(FMPSMBUS_HandleTypeDef *hfmpsmbus)
  2189. {
  2190. uint32_t itflags = READ_REG(hfmpsmbus->Instance->ISR);
  2191. uint32_t itsources = READ_REG(hfmpsmbus->Instance->CR1);
  2192. uint32_t tmpstate;
  2193. uint32_t tmperror;
  2194. /* FMPSMBUS Bus error interrupt occurred ------------------------------------*/
  2195. if (((itflags & FMPSMBUS_FLAG_BERR) == FMPSMBUS_FLAG_BERR) && \
  2196. ((itsources & FMPSMBUS_IT_ERRI) == FMPSMBUS_IT_ERRI))
  2197. {
  2198. hfmpsmbus->ErrorCode |= HAL_FMPSMBUS_ERROR_BERR;
  2199. /* Clear BERR flag */
  2200. __HAL_FMPSMBUS_CLEAR_FLAG(hfmpsmbus, FMPSMBUS_FLAG_BERR);
  2201. }
  2202. /* FMPSMBUS Over-Run/Under-Run interrupt occurred ----------------------------------------*/
  2203. if (((itflags & FMPSMBUS_FLAG_OVR) == FMPSMBUS_FLAG_OVR) && \
  2204. ((itsources & FMPSMBUS_IT_ERRI) == FMPSMBUS_IT_ERRI))
  2205. {
  2206. hfmpsmbus->ErrorCode |= HAL_FMPSMBUS_ERROR_OVR;
  2207. /* Clear OVR flag */
  2208. __HAL_FMPSMBUS_CLEAR_FLAG(hfmpsmbus, FMPSMBUS_FLAG_OVR);
  2209. }
  2210. /* FMPSMBUS Arbitration Loss error interrupt occurred ------------------------------------*/
  2211. if (((itflags & FMPSMBUS_FLAG_ARLO) == FMPSMBUS_FLAG_ARLO) && \
  2212. ((itsources & FMPSMBUS_IT_ERRI) == FMPSMBUS_IT_ERRI))
  2213. {
  2214. hfmpsmbus->ErrorCode |= HAL_FMPSMBUS_ERROR_ARLO;
  2215. /* Clear ARLO flag */
  2216. __HAL_FMPSMBUS_CLEAR_FLAG(hfmpsmbus, FMPSMBUS_FLAG_ARLO);
  2217. }
  2218. /* FMPSMBUS Timeout error interrupt occurred ---------------------------------------------*/
  2219. if (((itflags & FMPSMBUS_FLAG_TIMEOUT) == FMPSMBUS_FLAG_TIMEOUT) && \
  2220. ((itsources & FMPSMBUS_IT_ERRI) == FMPSMBUS_IT_ERRI))
  2221. {
  2222. hfmpsmbus->ErrorCode |= HAL_FMPSMBUS_ERROR_BUSTIMEOUT;
  2223. /* Clear TIMEOUT flag */
  2224. __HAL_FMPSMBUS_CLEAR_FLAG(hfmpsmbus, FMPSMBUS_FLAG_TIMEOUT);
  2225. }
  2226. /* FMPSMBUS Alert error interrupt occurred -----------------------------------------------*/
  2227. if (((itflags & FMPSMBUS_FLAG_ALERT) == FMPSMBUS_FLAG_ALERT) && \
  2228. ((itsources & FMPSMBUS_IT_ERRI) == FMPSMBUS_IT_ERRI))
  2229. {
  2230. hfmpsmbus->ErrorCode |= HAL_FMPSMBUS_ERROR_ALERT;
  2231. /* Clear ALERT flag */
  2232. __HAL_FMPSMBUS_CLEAR_FLAG(hfmpsmbus, FMPSMBUS_FLAG_ALERT);
  2233. }
  2234. /* FMPSMBUS Packet Error Check error interrupt occurred ----------------------------------*/
  2235. if (((itflags & FMPSMBUS_FLAG_PECERR) == FMPSMBUS_FLAG_PECERR) && \
  2236. ((itsources & FMPSMBUS_IT_ERRI) == FMPSMBUS_IT_ERRI))
  2237. {
  2238. hfmpsmbus->ErrorCode |= HAL_FMPSMBUS_ERROR_PECERR;
  2239. /* Clear PEC error flag */
  2240. __HAL_FMPSMBUS_CLEAR_FLAG(hfmpsmbus, FMPSMBUS_FLAG_PECERR);
  2241. }
  2242. if (hfmpsmbus->ErrorCode != HAL_FMPSMBUS_ERROR_NONE)
  2243. {
  2244. /* Flush TX register */
  2245. FMPSMBUS_Flush_TXDR(hfmpsmbus);
  2246. }
  2247. /* Store current volatile hfmpsmbus->ErrorCode, misra rule */
  2248. tmperror = hfmpsmbus->ErrorCode;
  2249. /* Call the Error Callback in case of Error detected */
  2250. if ((tmperror != HAL_FMPSMBUS_ERROR_NONE) && (tmperror != HAL_FMPSMBUS_ERROR_ACKF))
  2251. {
  2252. /* Do not Reset the HAL state in case of ALERT error */
  2253. if ((tmperror & HAL_FMPSMBUS_ERROR_ALERT) != HAL_FMPSMBUS_ERROR_ALERT)
  2254. {
  2255. /* Store current volatile hfmpsmbus->State, misra rule */
  2256. tmpstate = hfmpsmbus->State;
  2257. if (((tmpstate & HAL_FMPSMBUS_STATE_SLAVE_BUSY_TX) == HAL_FMPSMBUS_STATE_SLAVE_BUSY_TX)
  2258. || ((tmpstate & HAL_FMPSMBUS_STATE_SLAVE_BUSY_RX) == HAL_FMPSMBUS_STATE_SLAVE_BUSY_RX))
  2259. {
  2260. /* Reset only HAL_FMPSMBUS_STATE_SLAVE_BUSY_XX */
  2261. /* keep HAL_FMPSMBUS_STATE_LISTEN if set */
  2262. hfmpsmbus->PreviousState = HAL_FMPSMBUS_STATE_READY;
  2263. hfmpsmbus->State = HAL_FMPSMBUS_STATE_LISTEN;
  2264. }
  2265. }
  2266. /* Call the Error callback to inform upper layer */
  2267. #if (USE_HAL_FMPSMBUS_REGISTER_CALLBACKS == 1)
  2268. hfmpsmbus->ErrorCallback(hfmpsmbus);
  2269. #else
  2270. HAL_FMPSMBUS_ErrorCallback(hfmpsmbus);
  2271. #endif /* USE_HAL_FMPSMBUS_REGISTER_CALLBACKS */
  2272. }
  2273. }
  2274. /**
  2275. * @brief Handle FMPSMBUS Communication Timeout.
  2276. * @param hfmpsmbus Pointer to a FMPSMBUS_HandleTypeDef structure that contains
  2277. * the configuration information for the specified FMPSMBUS.
  2278. * @param Flag Specifies the FMPSMBUS flag to check.
  2279. * @param Status The new Flag status (SET or RESET).
  2280. * @param Timeout Timeout duration
  2281. * @retval HAL status
  2282. */
  2283. static HAL_StatusTypeDef FMPSMBUS_WaitOnFlagUntilTimeout(FMPSMBUS_HandleTypeDef *hfmpsmbus, uint32_t Flag,
  2284. FlagStatus Status, uint32_t Timeout)
  2285. {
  2286. uint32_t tickstart = HAL_GetTick();
  2287. /* Wait until flag is set */
  2288. while ((FlagStatus)(__HAL_FMPSMBUS_GET_FLAG(hfmpsmbus, Flag)) == Status)
  2289. {
  2290. /* Check for the Timeout */
  2291. if (Timeout != HAL_MAX_DELAY)
  2292. {
  2293. if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0UL))
  2294. {
  2295. hfmpsmbus->PreviousState = hfmpsmbus->State;
  2296. hfmpsmbus->State = HAL_FMPSMBUS_STATE_READY;
  2297. /* Update FMPSMBUS error code */
  2298. hfmpsmbus->ErrorCode |= HAL_FMPSMBUS_ERROR_HALTIMEOUT;
  2299. /* Process Unlocked */
  2300. __HAL_UNLOCK(hfmpsmbus);
  2301. return HAL_ERROR;
  2302. }
  2303. }
  2304. }
  2305. return HAL_OK;
  2306. }
  2307. /**
  2308. * @brief FMPSMBUS Tx data register flush process.
  2309. * @param hfmpsmbus FMPSMBUS handle.
  2310. * @retval None
  2311. */
  2312. static void FMPSMBUS_Flush_TXDR(FMPSMBUS_HandleTypeDef *hfmpsmbus)
  2313. {
  2314. /* If a pending TXIS flag is set */
  2315. /* Write a dummy data in TXDR to clear it */
  2316. if (__HAL_FMPSMBUS_GET_FLAG(hfmpsmbus, FMPSMBUS_FLAG_TXIS) != RESET)
  2317. {
  2318. hfmpsmbus->Instance->TXDR = 0x00U;
  2319. }
  2320. /* Flush TX register if not empty */
  2321. if (__HAL_FMPSMBUS_GET_FLAG(hfmpsmbus, FMPSMBUS_FLAG_TXE) == RESET)
  2322. {
  2323. __HAL_FMPSMBUS_CLEAR_FLAG(hfmpsmbus, FMPSMBUS_FLAG_TXE);
  2324. }
  2325. }
  2326. /**
  2327. * @brief Handle FMPSMBUSx communication when starting transfer or during transfer (TC or TCR flag are set).
  2328. * @param hfmpsmbus FMPSMBUS handle.
  2329. * @param DevAddress specifies the slave address to be programmed.
  2330. * @param Size specifies the number of bytes to be programmed.
  2331. * This parameter must be a value between 0 and 255.
  2332. * @param Mode New state of the FMPSMBUS START condition generation.
  2333. * This parameter can be one or a combination of the following values:
  2334. * @arg @ref FMPSMBUS_RELOAD_MODE Enable Reload mode.
  2335. * @arg @ref FMPSMBUS_AUTOEND_MODE Enable Automatic end mode.
  2336. * @arg @ref FMPSMBUS_SOFTEND_MODE Enable Software end mode and Reload mode.
  2337. * @arg @ref FMPSMBUS_SENDPEC_MODE Enable Packet Error Calculation mode.
  2338. * @param Request New state of the FMPSMBUS START condition generation.
  2339. * This parameter can be one of the following values:
  2340. * @arg @ref FMPSMBUS_NO_STARTSTOP Don't Generate stop and start condition.
  2341. * @arg @ref FMPSMBUS_GENERATE_STOP Generate stop condition (Size should be set to 0).
  2342. * @arg @ref FMPSMBUS_GENERATE_START_READ Generate Restart for read request.
  2343. * @arg @ref FMPSMBUS_GENERATE_START_WRITE Generate Restart for write request.
  2344. * @retval None
  2345. */
  2346. static void FMPSMBUS_TransferConfig(FMPSMBUS_HandleTypeDef *hfmpsmbus, uint16_t DevAddress, uint8_t Size,
  2347. uint32_t Mode, uint32_t Request)
  2348. {
  2349. /* Check the parameters */
  2350. assert_param(IS_FMPSMBUS_ALL_INSTANCE(hfmpsmbus->Instance));
  2351. assert_param(IS_FMPSMBUS_TRANSFER_MODE(Mode));
  2352. assert_param(IS_FMPSMBUS_TRANSFER_REQUEST(Request));
  2353. /* update CR2 register */
  2354. MODIFY_REG(hfmpsmbus->Instance->CR2,
  2355. ((FMPI2C_CR2_SADD | FMPI2C_CR2_NBYTES | FMPI2C_CR2_RELOAD | FMPI2C_CR2_AUTOEND | \
  2356. (FMPI2C_CR2_RD_WRN & (uint32_t)(Request >> (31UL - FMPI2C_CR2_RD_WRN_Pos))) | \
  2357. FMPI2C_CR2_START | FMPI2C_CR2_STOP | FMPI2C_CR2_PECBYTE)), \
  2358. (uint32_t)(((uint32_t)DevAddress & FMPI2C_CR2_SADD) | \
  2359. (((uint32_t)Size << FMPI2C_CR2_NBYTES_Pos) & FMPI2C_CR2_NBYTES) | \
  2360. (uint32_t)Mode | (uint32_t)Request));
  2361. }
  2362. /**
  2363. * @brief Convert FMPSMBUSx OTHER_xxx XferOptions to functional XferOptions.
  2364. * @param hfmpsmbus FMPSMBUS handle.
  2365. * @retval None
  2366. */
  2367. static void FMPSMBUS_ConvertOtherXferOptions(FMPSMBUS_HandleTypeDef *hfmpsmbus)
  2368. {
  2369. /* if user set XferOptions to FMPSMBUS_OTHER_FRAME_NO_PEC */
  2370. /* it request implicitly to generate a restart condition */
  2371. /* set XferOptions to FMPSMBUS_FIRST_FRAME */
  2372. if (hfmpsmbus->XferOptions == FMPSMBUS_OTHER_FRAME_NO_PEC)
  2373. {
  2374. hfmpsmbus->XferOptions = FMPSMBUS_FIRST_FRAME;
  2375. }
  2376. /* else if user set XferOptions to FMPSMBUS_OTHER_FRAME_WITH_PEC */
  2377. /* it request implicitly to generate a restart condition */
  2378. /* set XferOptions to FMPSMBUS_FIRST_FRAME | FMPSMBUS_SENDPEC_MODE */
  2379. else if (hfmpsmbus->XferOptions == FMPSMBUS_OTHER_FRAME_WITH_PEC)
  2380. {
  2381. hfmpsmbus->XferOptions = FMPSMBUS_FIRST_FRAME | FMPSMBUS_SENDPEC_MODE;
  2382. }
  2383. /* else if user set XferOptions to FMPSMBUS_OTHER_AND_LAST_FRAME_NO_PEC */
  2384. /* it request implicitly to generate a restart condition */
  2385. /* then generate a stop condition at the end of transfer */
  2386. /* set XferOptions to FMPSMBUS_FIRST_AND_LAST_FRAME_NO_PEC */
  2387. else if (hfmpsmbus->XferOptions == FMPSMBUS_OTHER_AND_LAST_FRAME_NO_PEC)
  2388. {
  2389. hfmpsmbus->XferOptions = FMPSMBUS_FIRST_AND_LAST_FRAME_NO_PEC;
  2390. }
  2391. /* else if user set XferOptions to FMPSMBUS_OTHER_AND_LAST_FRAME_WITH_PEC */
  2392. /* it request implicitly to generate a restart condition */
  2393. /* then generate a stop condition at the end of transfer */
  2394. /* set XferOptions to FMPSMBUS_FIRST_AND_LAST_FRAME_WITH_PEC */
  2395. else if (hfmpsmbus->XferOptions == FMPSMBUS_OTHER_AND_LAST_FRAME_WITH_PEC)
  2396. {
  2397. hfmpsmbus->XferOptions = FMPSMBUS_FIRST_AND_LAST_FRAME_WITH_PEC;
  2398. }
  2399. else
  2400. {
  2401. /* Nothing to do */
  2402. }
  2403. }
  2404. /**
  2405. * @}
  2406. */
  2407. #endif /* FMPI2C_CR1_PE */
  2408. #endif /* HAL_FMPSMBUS_MODULE_ENABLED */
  2409. /**
  2410. * @}
  2411. */
  2412. /**
  2413. * @}
  2414. */