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.
 
 
 

1950 lines
59 KiB

  1. /**
  2. ******************************************************************************
  3. * @file stm32h7xx_hal_swpmi.c
  4. * @author MCD Application Team
  5. * @brief SWPMI HAL module driver.
  6. * This file provides firmware functions to manage the following
  7. * functionalities of the Single Wire Protocol Master Interface (SWPMI).
  8. * + Initialization and Configuration
  9. * + Data transfers functions
  10. * + DMA transfers management
  11. * + Interrupts and flags management
  12. @verbatim
  13. ===============================================================================
  14. ##### How to use this driver #####
  15. ===============================================================================
  16. [..]
  17. The SWPMI HAL driver can be used as follows:
  18. (#) Declare a SWPMI_HandleTypeDef handle structure (eg. SWPMI_HandleTypeDef hswpmi).
  19. (#) Initialize the SWPMI low level resources by implementing the HAL_SWPMI_MspInit() API:
  20. (##) Enable the SWPMIx interface clock with __HAL_RCC_SWPMIx_CLK_ENABLE().
  21. (##) SWPMI IO configuration:
  22. (+++) Enable the clock for the SWPMI GPIO.
  23. (+++) Configure these SWPMI pins as alternate function pull-up.
  24. (##) NVIC configuration if you need to use interrupt process (HAL_SWPMI_Transmit_IT()
  25. and HAL_SWPMI_Receive_IT() APIs):
  26. (+++) Configure the SWPMIx interrupt priority with HAL_NVIC_SetPriority().
  27. (+++) Enable the NVIC SWPMI IRQ handle with HAL_NVIC_EnableIRQ().
  28. (##) DMA Configuration if you need to use DMA process (HAL_SWPMI_Transmit_DMA()
  29. and HAL_SWPMI_Receive_DMA() APIs):
  30. (+++) Declare a DMA handle structure for the Tx/Rx streams.
  31. (+++) Enable the DMAx interface clock.
  32. (+++) Configure the declared DMA handle structure with the required
  33. Tx/Rx parameters.
  34. (+++) Configure the DMA Tx/Rx streams and requests.
  35. (+++) Associate the initialized DMA handle to the SWPMI DMA Tx/Rx handle.
  36. (+++) Configure the priority and enable the NVIC for the transfer complete
  37. interrupt on the DMA Tx/Rx streams.
  38. (#) Program the Bite Rate, Tx Buffering mode, Rx Buffering mode in the Init structure.
  39. (#) Enable the SWPMI peripheral by calling the HAL_SWPMI_Init() function.
  40. [..]
  41. Three operation modes are available within this driver :
  42. *** Polling mode IO operation ***
  43. =================================
  44. [..]
  45. (+) Send an amount of data in blocking mode using HAL_SWPMI_Transmit()
  46. (+) Receive an amount of data in blocking mode using HAL_SWPMI_Receive()
  47. *** Interrupt mode IO operation ***
  48. ===================================
  49. [..]
  50. (+) Send an amount of data in non-blocking mode using HAL_SWPMI_Transmit_IT()
  51. (+) At transmission end of transfer HAL_SWPMI_TxCpltCallback() is executed and user can
  52. add his own code by customization of function pointer HAL_SWPMI_TxCpltCallback()
  53. (+) Receive an amount of data in non-blocking mode using HAL_SWPMI_Receive_IT()
  54. (+) At reception end of transfer HAL_SWPMI_RxCpltCallback() is executed and user can
  55. add his own code by customization of function pointer HAL_SWPMI_RxCpltCallback()
  56. (+) In case of flag error, HAL_SWPMI_ErrorCallback() function is executed and user can
  57. add his own code by customization of function pointer HAL_SWPMI_ErrorCallback()
  58. *** DMA mode IO operation ***
  59. =============================
  60. [..]
  61. (+) Send an amount of data in non-blocking mode (DMA) using HAL_SWPMI_Transmit_DMA()
  62. (+) At transmission end of transfer HAL_SWPMI_TxCpltCallback() is executed and user can
  63. add his own code by customization of function pointer HAL_SWPMI_TxCpltCallback()
  64. (+) Receive an amount of data in non-blocking mode (DMA) using HAL_SWPMI_Receive_DMA()
  65. (+) At reception end of transfer HAL_SWPMI_RxCpltCallback() is executed and user can
  66. add his own code by customization of function pointer HAL_SWPMI_RxCpltCallback()
  67. (+) In case of flag error, HAL_SWPMI_ErrorCallback() function is executed and user can
  68. add his own code by customization of function pointer HAL_SWPMI_ErrorCallback()
  69. (+) Stop the DMA Transfer using HAL_SWPMI_DMAStop()
  70. *** SWPMI HAL driver additional function list ***
  71. ===============================================
  72. [..]
  73. Below the list the others API available SWPMI HAL driver :
  74. (+) HAL_SWPMI_EnableLoopback(): Enable the loopback mode for test purpose only
  75. (+) HAL_SWPMI_DisableLoopback(): Disable the loopback mode
  76. *** SWPMI HAL driver macros list ***
  77. ==================================
  78. [..]
  79. Below the list of most used macros in SWPMI HAL driver :
  80. (+) __HAL_SWPMI_ENABLE(): Enable the SWPMI peripheral
  81. (+) __HAL_SWPMI_DISABLE(): Disable the SWPMI peripheral
  82. (+) __HAL_SWPMI_TRANSCEIVER_ENABLE(): Enable the SWPMI peripheral transceiver
  83. (+) __HAL_SWPMI_TRANSCEIVER_DISABLE(): Disable the SWPMI peripheral transceiver
  84. (+) __HAL_SWPMI_ENABLE_IT(): Enable the specified SWPMI interrupts
  85. (+) __HAL_SWPMI_DISABLE_IT(): Disable the specified SWPMI interrupts
  86. (+) __HAL_SWPMI_GET_IT_SOURCE(): Check if the specified SWPMI interrupt source is
  87. enabled or disabled
  88. (+) __HAL_SWPMI_GET_FLAG(): Check whether the specified SWPMI flag is set or not
  89. *** Callback registration ***
  90. =============================
  91. [..]
  92. The compilation define USE_HAL_SWPMI_REGISTER_CALLBACKS when set to 1
  93. allows the user to configure dynamically the driver callbacks.
  94. [..]
  95. Use function HAL_SWPMI_RegisterCallback() to register a user callback. It allows
  96. to register the following callbacks:
  97. (+) RxCpltCallback : SWPMI receive complete.
  98. (+) RxHalfCpltCallback : SWPMI receive half complete.
  99. (+) TxCpltCallback : SWPMI transmit complete.
  100. (+) TxHalfCpltCallback : SWPMI transmit half complete.
  101. (+) ErrorCallback : SWPMI error.
  102. (+) MspInitCallback : SWPMI MspInit.
  103. (+) MspDeInitCallback : SWPMI MspDeInit.
  104. [..]
  105. This function takes as parameters the HAL peripheral handle, the callback ID
  106. and a pointer to the user callback function.
  107. [..]
  108. Use function HAL_SWPMI_UnRegisterCallback() to reset a callback to the default
  109. weak (surcharged) function.
  110. HAL_SWPMI_UnRegisterCallback() takes as parameters the HAL peripheral handle,
  111. and the callback ID.
  112. This function allows to reset following callbacks:
  113. (+) RxCpltCallback : SWPMI receive complete.
  114. (+) RxHalfCpltCallback : SWPMI receive half complete.
  115. (+) TxCpltCallback : SWPMI transmit complete.
  116. (+) TxHalfCpltCallback : SWPMI transmit half complete.
  117. (+) ErrorCallback : SWPMI error.
  118. (+) MspInitCallback : SWPMI MspInit.
  119. (+) MspDeInitCallback : SWPMI MspDeInit.
  120. [..]
  121. By default, after the HAL_SWPMI_Init and if the state is HAL_SWPMI_STATE_RESET
  122. all callbacks are reset to the corresponding legacy weak (surcharged) functions:
  123. examples HAL_SWPMI_RxCpltCallback(), HAL_SWPMI_ErrorCallback().
  124. Exception done for MspInit and MspDeInit callbacks that are respectively
  125. reset to the legacy weak (surcharged) functions in the HAL_SWPMI_Init
  126. and HAL_SWPMI_DeInit only when these callbacks are null (not registered beforehand).
  127. If not, MspInit or MspDeInit are not null, the HAL_SWPMI_Init and HAL_SWPMI_DeInit
  128. keep and use the user MspInit/MspDeInit callbacks (registered beforehand).
  129. [..]
  130. Callbacks can be registered/unregistered in READY state only.
  131. Exception done for MspInit/MspDeInit callbacks that can be registered/unregistered
  132. in READY or RESET state, thus registered (user) MspInit/DeInit callbacks can be used
  133. during the Init/DeInit.
  134. In that case first register the MspInit/MspDeInit user callbacks
  135. using HAL_SWPMI_RegisterCallback before calling @ref HAL_SWPMI_DeInit
  136. or HAL_SWPMI_Init function.
  137. [..]
  138. When the compilation define USE_HAL_SWPMI_REGISTER_CALLBACKS is set to 0 or
  139. not defined, the callback registering feature is not available
  140. and weak (surcharged) callbacks are used.
  141. @endverbatim
  142. ******************************************************************************
  143. * @attention
  144. *
  145. * <h2><center>&copy; Copyright (c) 2017 STMicroelectronics.
  146. * All rights reserved.</center></h2>
  147. *
  148. * This software component is licensed by ST under BSD 3-Clause license,
  149. * the "License"; You may not use this file except in compliance with the
  150. * License. You may obtain a copy of the License at:
  151. * opensource.org/licenses/BSD-3-Clause
  152. *
  153. ******************************************************************************
  154. */
  155. /* Includes ------------------------------------------------------------------*/
  156. #include "stm32h7xx_hal.h"
  157. /** @addtogroup STM32H7xx_HAL_Driver
  158. * @{
  159. */
  160. /** @defgroup SWPMI SWPMI
  161. * @brief HAL SWPMI module driver
  162. * @{
  163. */
  164. #ifdef HAL_SWPMI_MODULE_ENABLED
  165. /* Private typedef -----------------------------------------------------------*/
  166. /* Private define ------------------------------------------------------------*/
  167. /* Private constants ---------------------------------------------------------*/
  168. /** @addtogroup SWPMI_Private_Constants SWPMI Private Constants
  169. * @{
  170. */
  171. #define SWPMI_TIMEOUT_VALUE 22000U /* End of transmission timeout */
  172. #define SWPMI_TRANSCEIVER_RDY_TIMEOUT_VALUE 2000U /* Transceiver ready timeout */
  173. /**
  174. * @}
  175. */
  176. /* Private macros ------------------------------------------------------------*/
  177. /* Private variables ---------------------------------------------------------*/
  178. /* Private function prototypes -----------------------------------------------*/
  179. static void SWPMI_DMATransmitCplt(DMA_HandleTypeDef *hdma);
  180. static void SWPMI_DMATxHalfCplt(DMA_HandleTypeDef *hdma);
  181. static void SWPMI_DMAReceiveCplt(DMA_HandleTypeDef *hdma);
  182. static void SWPMI_DMARxHalfCplt(DMA_HandleTypeDef *hdma);
  183. static void SWPMI_DMAError(DMA_HandleTypeDef *hdma);
  184. static void SWPMI_DMAAbortOnError(DMA_HandleTypeDef *hdma);
  185. static void SWPMI_Transmit_IT(SWPMI_HandleTypeDef *hswpmi);
  186. static void SWPMI_EndTransmit_IT(SWPMI_HandleTypeDef *hswpmi);
  187. static void SWPMI_Receive_IT(SWPMI_HandleTypeDef *hswpmi);
  188. static void SWPMI_EndReceive_IT(SWPMI_HandleTypeDef *hswpmi);
  189. static void SWPMI_EndTransmitReceive_IT(SWPMI_HandleTypeDef *hswpmi);
  190. static HAL_StatusTypeDef SWPMI_WaitOnFlagSetUntilTimeout(SWPMI_HandleTypeDef *hswpmi, uint32_t Flag, uint32_t Tickstart, uint32_t Timeout);
  191. /* Exported functions --------------------------------------------------------*/
  192. /** @defgroup SWPMI_Exported_Functions SWPMI Exported Functions
  193. * @{
  194. */
  195. /** @defgroup SWPMI_Exported_Group1 Initialization/de-initialization methods
  196. * @brief Initialization and Configuration functions
  197. *
  198. @verbatim
  199. ===============================================================================
  200. ##### Initialization and Configuration functions #####
  201. ===============================================================================
  202. [..] This section provides functions allowing to:
  203. (+) Initialize and configure the SWPMI peripheral.
  204. (+) De-initialize the SWPMI peripheral.
  205. @endverbatim
  206. * @{
  207. */
  208. /**
  209. * @brief Initialize the SWPMI peripheral according to the specified parameters in the SWPMI_InitTypeDef.
  210. * @param hswpmi SWPMI handle
  211. * @retval HAL status
  212. */
  213. HAL_StatusTypeDef HAL_SWPMI_Init(SWPMI_HandleTypeDef *hswpmi)
  214. {
  215. HAL_StatusTypeDef status = HAL_OK;
  216. uint32_t tickstart = HAL_GetTick();
  217. /* Check the SWPMI handle allocation */
  218. if(hswpmi == NULL)
  219. {
  220. status = HAL_ERROR;
  221. }
  222. else
  223. {
  224. /* Check the parameters */
  225. assert_param(IS_SWPMI_VOLTAGE_CLASS(hswpmi->Init.VoltageClass));
  226. assert_param(IS_SWPMI_BITRATE_VALUE(hswpmi->Init.BitRate));
  227. assert_param(IS_SWPMI_TX_BUFFERING_MODE(hswpmi->Init.TxBufferingMode));
  228. assert_param(IS_SWPMI_RX_BUFFERING_MODE(hswpmi->Init.RxBufferingMode));
  229. if(hswpmi->State == HAL_SWPMI_STATE_RESET)
  230. {
  231. /* Allocate lock resource and initialize it */
  232. hswpmi->Lock = HAL_UNLOCKED;
  233. #if (USE_HAL_SWPMI_REGISTER_CALLBACKS == 1)
  234. /* Reset callback pointers to the weak predefined callbacks */
  235. hswpmi->RxCpltCallback = HAL_SWPMI_RxCpltCallback;
  236. hswpmi->RxHalfCpltCallback = HAL_SWPMI_RxHalfCpltCallback;
  237. hswpmi->TxCpltCallback = HAL_SWPMI_TxCpltCallback;
  238. hswpmi->TxHalfCpltCallback = HAL_SWPMI_TxHalfCpltCallback;
  239. hswpmi->ErrorCallback = HAL_SWPMI_ErrorCallback;
  240. /* Init the low level hardware : GPIO, CLOCK, NVIC and DMA */
  241. if(hswpmi->MspInitCallback == NULL)
  242. {
  243. hswpmi->MspInitCallback = HAL_SWPMI_MspInit;
  244. }
  245. hswpmi->MspInitCallback(hswpmi);
  246. #else
  247. /* Init the low level hardware : GPIO, CLOCK, NVIC and DMA */
  248. HAL_SWPMI_MspInit(hswpmi);
  249. #endif
  250. }
  251. hswpmi->State = HAL_SWPMI_STATE_BUSY;
  252. /* Disable SWPMI interface */
  253. CLEAR_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT);
  254. /* Clear all SWPMI interface flags */
  255. WRITE_REG(hswpmi->Instance->ICR, 0x099F);
  256. /* Apply Voltage class selection */
  257. MODIFY_REG(hswpmi->Instance->OR, SWPMI_OR_CLASS, hswpmi->Init.VoltageClass);
  258. /* Configure the BRR register (Bitrate) */
  259. WRITE_REG(hswpmi->Instance->BRR, hswpmi->Init.BitRate);
  260. /* Apply SWPMI CR configuration */
  261. MODIFY_REG(hswpmi->Instance->CR, \
  262. SWPMI_CR_RXDMA | SWPMI_CR_TXDMA | SWPMI_CR_RXMODE | SWPMI_CR_TXMODE, \
  263. hswpmi->Init.TxBufferingMode | hswpmi->Init.RxBufferingMode);
  264. /* Enable the SWPMI transceiver */
  265. SET_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPEN);
  266. /* Wait on RDYF flag to activate SWPMI */
  267. if(SWPMI_WaitOnFlagSetUntilTimeout(hswpmi, SWPMI_FLAG_RDYF, tickstart, SWPMI_TRANSCEIVER_RDY_TIMEOUT_VALUE) != HAL_OK)
  268. {
  269. status = HAL_TIMEOUT;
  270. }
  271. if(status == HAL_OK)
  272. {
  273. hswpmi->ErrorCode = HAL_SWPMI_ERROR_NONE;
  274. hswpmi->State = HAL_SWPMI_STATE_READY;
  275. /* Enable SWPMI peripheral */
  276. SET_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT);
  277. }
  278. else
  279. {
  280. hswpmi->ErrorCode = HAL_SWPMI_ERROR_TRANSCEIVER_NOT_READY;
  281. hswpmi->State = HAL_SWPMI_STATE_ERROR;
  282. }
  283. }
  284. return status;
  285. }
  286. /**
  287. * @brief De-initialize the SWPMI peripheral.
  288. * @param hswpmi SWPMI handle
  289. * @retval HAL status
  290. */
  291. HAL_StatusTypeDef HAL_SWPMI_DeInit(SWPMI_HandleTypeDef *hswpmi)
  292. {
  293. HAL_StatusTypeDef status = HAL_OK;
  294. /* Check the SWPMI handle allocation */
  295. if(hswpmi == NULL)
  296. {
  297. status = HAL_ERROR;
  298. }
  299. else
  300. {
  301. /* Check the parameters */
  302. assert_param(IS_SWPMI_INSTANCE(hswpmi->Instance));
  303. hswpmi->State = HAL_SWPMI_STATE_BUSY;
  304. /* Disable SWPMI interface */
  305. CLEAR_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT);
  306. /* Disable Loopback mode */
  307. CLEAR_BIT(hswpmi->Instance->CR, SWPMI_CR_LPBK);
  308. /* Disable SWPMI transceiver */
  309. CLEAR_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPEN);
  310. /* DeInit the low level hardware: GPIO, CLOCK, NVIC and DMA */
  311. #if (USE_HAL_SWPMI_REGISTER_CALLBACKS == 1)
  312. if(hswpmi->MspDeInitCallback == NULL)
  313. {
  314. hswpmi->MspDeInitCallback = HAL_SWPMI_MspDeInit;
  315. }
  316. hswpmi->MspDeInitCallback(hswpmi);
  317. #else
  318. HAL_SWPMI_MspDeInit(hswpmi);
  319. #endif
  320. hswpmi->ErrorCode = HAL_SWPMI_ERROR_NONE;
  321. hswpmi->State = HAL_SWPMI_STATE_RESET;
  322. /* Release Lock */
  323. __HAL_UNLOCK(hswpmi);
  324. }
  325. return status;
  326. }
  327. /**
  328. * @brief Initialize the SWPMI MSP.
  329. * @param hswpmi SWPMI handle
  330. * @retval None
  331. */
  332. __weak void HAL_SWPMI_MspInit(SWPMI_HandleTypeDef *hswpmi)
  333. {
  334. /* Prevent unused argument(s) compilation warning */
  335. UNUSED(hswpmi);
  336. /* NOTE : This function should not be modified, when the callback is needed,
  337. the HAL_SWPMI_MspInit can be implemented in the user file
  338. */
  339. }
  340. /**
  341. * @brief DeInitialize the SWPMI MSP.
  342. * @param hswpmi SWPMI handle
  343. * @retval None
  344. */
  345. __weak void HAL_SWPMI_MspDeInit(SWPMI_HandleTypeDef *hswpmi)
  346. {
  347. /* Prevent unused argument(s) compilation warning */
  348. UNUSED(hswpmi);
  349. /* NOTE : This function should not be modified, when the callback is needed,
  350. the HAL_SWPMI_MspDeInit can be implemented in the user file
  351. */
  352. }
  353. #if (USE_HAL_SWPMI_REGISTER_CALLBACKS == 1)
  354. /**
  355. * @brief Register a user SWPMI callback
  356. * to be used instead of the weak predefined callback.
  357. * @param hswpmi SWPMI handle.
  358. * @param CallbackID ID of the callback to be registered.
  359. * This parameter can be one of the following values:
  360. * @arg @ref HAL_SWPMI_RX_COMPLETE_CB_ID receive complete callback ID.
  361. * @arg @ref HAL_SWPMI_RX_HALFCOMPLETE_CB_ID receive half complete callback ID.
  362. * @arg @ref HAL_SWPMI_TX_COMPLETE_CB_ID transmit complete callback ID.
  363. * @arg @ref HAL_SWPMI_TX_HALFCOMPLETE_CB_ID transmit half complete callback ID.
  364. * @arg @ref HAL_SWPMI_ERROR_CB_ID error callback ID.
  365. * @arg @ref HAL_SWPMI_MSPINIT_CB_ID MSP init callback ID.
  366. * @arg @ref HAL_SWPMI_MSPDEINIT_CB_ID MSP de-init callback ID.
  367. * @param pCallback pointer to the callback function.
  368. * @retval HAL status.
  369. */
  370. HAL_StatusTypeDef HAL_SWPMI_RegisterCallback(SWPMI_HandleTypeDef *hswpmi,
  371. HAL_SWPMI_CallbackIDTypeDef CallbackID,
  372. pSWPMI_CallbackTypeDef pCallback)
  373. {
  374. HAL_StatusTypeDef status = HAL_OK;
  375. if(pCallback == NULL)
  376. {
  377. /* update the error code */
  378. hswpmi->ErrorCode |= HAL_SWPMI_ERROR_INVALID_CALLBACK;
  379. /* update return status */
  380. status = HAL_ERROR;
  381. }
  382. else
  383. {
  384. if(hswpmi->State == HAL_SWPMI_STATE_READY)
  385. {
  386. switch (CallbackID)
  387. {
  388. case HAL_SWPMI_RX_COMPLETE_CB_ID :
  389. hswpmi->RxCpltCallback = pCallback;
  390. break;
  391. case HAL_SWPMI_RX_HALFCOMPLETE_CB_ID :
  392. hswpmi->RxHalfCpltCallback = pCallback;
  393. break;
  394. case HAL_SWPMI_TX_COMPLETE_CB_ID :
  395. hswpmi->TxCpltCallback = pCallback;
  396. break;
  397. case HAL_SWPMI_TX_HALFCOMPLETE_CB_ID :
  398. hswpmi->TxHalfCpltCallback = pCallback;
  399. break;
  400. case HAL_SWPMI_ERROR_CB_ID :
  401. hswpmi->ErrorCallback = pCallback;
  402. break;
  403. case HAL_SWPMI_MSPINIT_CB_ID :
  404. hswpmi->MspInitCallback = pCallback;
  405. break;
  406. case HAL_SWPMI_MSPDEINIT_CB_ID :
  407. hswpmi->MspDeInitCallback = pCallback;
  408. break;
  409. default :
  410. /* update the error code */
  411. hswpmi->ErrorCode |= HAL_SWPMI_ERROR_INVALID_CALLBACK;
  412. /* update return status */
  413. status = HAL_ERROR;
  414. break;
  415. }
  416. }
  417. else if(hswpmi->State == HAL_SWPMI_STATE_RESET)
  418. {
  419. switch (CallbackID)
  420. {
  421. case HAL_SWPMI_MSPINIT_CB_ID :
  422. hswpmi->MspInitCallback = pCallback;
  423. break;
  424. case HAL_SWPMI_MSPDEINIT_CB_ID :
  425. hswpmi->MspDeInitCallback = pCallback;
  426. break;
  427. default :
  428. /* update the error code */
  429. hswpmi->ErrorCode |= HAL_SWPMI_ERROR_INVALID_CALLBACK;
  430. /* update return status */
  431. status = HAL_ERROR;
  432. break;
  433. }
  434. }
  435. else
  436. {
  437. /* update the error code */
  438. hswpmi->ErrorCode |= HAL_SWPMI_ERROR_INVALID_CALLBACK;
  439. /* update return status */
  440. status = HAL_ERROR;
  441. }
  442. }
  443. return status;
  444. }
  445. /**
  446. * @brief Unregister a user SWPMI callback.
  447. * SWPMI callback is redirected to the weak predefined callback.
  448. * @param hswpmi SWPMI handle.
  449. * @param CallbackID ID of the callback to be unregistered.
  450. * This parameter can be one of the following values:
  451. * @arg @ref HAL_SWPMI_RX_COMPLETE_CB_ID receive complete callback ID.
  452. * @arg @ref HAL_SWPMI_RX_HALFCOMPLETE_CB_ID receive half complete callback ID.
  453. * @arg @ref HAL_SWPMI_TX_COMPLETE_CB_ID transmit complete callback ID.
  454. * @arg @ref HAL_SWPMI_TX_HALFCOMPLETE_CB_ID transmit half complete callback ID.
  455. * @arg @ref HAL_SWPMI_ERROR_CB_ID error callback ID.
  456. * @arg @ref HAL_SWPMI_MSPINIT_CB_ID MSP init callback ID.
  457. * @arg @ref HAL_SWPMI_MSPDEINIT_CB_ID MSP de-init callback ID.
  458. * @retval HAL status.
  459. */
  460. HAL_StatusTypeDef HAL_SWPMI_UnRegisterCallback(SWPMI_HandleTypeDef *hswpmi,
  461. HAL_SWPMI_CallbackIDTypeDef CallbackID)
  462. {
  463. HAL_StatusTypeDef status = HAL_OK;
  464. if(hswpmi->State == HAL_SWPMI_STATE_READY)
  465. {
  466. switch (CallbackID)
  467. {
  468. case HAL_SWPMI_RX_COMPLETE_CB_ID :
  469. hswpmi->RxCpltCallback = HAL_SWPMI_RxCpltCallback;
  470. break;
  471. case HAL_SWPMI_RX_HALFCOMPLETE_CB_ID :
  472. hswpmi->RxHalfCpltCallback = HAL_SWPMI_RxHalfCpltCallback;
  473. break;
  474. case HAL_SWPMI_TX_COMPLETE_CB_ID :
  475. hswpmi->TxCpltCallback = HAL_SWPMI_TxCpltCallback;
  476. break;
  477. case HAL_SWPMI_TX_HALFCOMPLETE_CB_ID :
  478. hswpmi->TxHalfCpltCallback = HAL_SWPMI_TxHalfCpltCallback;
  479. break;
  480. case HAL_SWPMI_ERROR_CB_ID :
  481. hswpmi->ErrorCallback = HAL_SWPMI_ErrorCallback;
  482. break;
  483. case HAL_SWPMI_MSPINIT_CB_ID :
  484. hswpmi->MspInitCallback = HAL_SWPMI_MspInit;
  485. break;
  486. case HAL_SWPMI_MSPDEINIT_CB_ID :
  487. hswpmi->MspDeInitCallback = HAL_SWPMI_MspDeInit;
  488. break;
  489. default :
  490. /* update the error code */
  491. hswpmi->ErrorCode |= HAL_SWPMI_ERROR_INVALID_CALLBACK;
  492. /* update return status */
  493. status = HAL_ERROR;
  494. break;
  495. }
  496. }
  497. else if(hswpmi->State == HAL_SWPMI_STATE_RESET)
  498. {
  499. switch (CallbackID)
  500. {
  501. case HAL_SWPMI_MSPINIT_CB_ID :
  502. hswpmi->MspInitCallback = HAL_SWPMI_MspInit;
  503. break;
  504. case HAL_SWPMI_MSPDEINIT_CB_ID :
  505. hswpmi->MspDeInitCallback = HAL_SWPMI_MspDeInit;
  506. break;
  507. default :
  508. /* update the error code */
  509. hswpmi->ErrorCode |= HAL_SWPMI_ERROR_INVALID_CALLBACK;
  510. /* update return status */
  511. status = HAL_ERROR;
  512. break;
  513. }
  514. }
  515. else
  516. {
  517. /* update the error code */
  518. hswpmi->ErrorCode |= HAL_SWPMI_ERROR_INVALID_CALLBACK;
  519. /* update return status */
  520. status = HAL_ERROR;
  521. }
  522. return status;
  523. }
  524. #endif /* USE_HAL_SWPMI_REGISTER_CALLBACKS */
  525. /**
  526. * @}
  527. */
  528. /** @defgroup SWPMI_Exported_Group2 IO operation methods
  529. * @brief SWPMI Transmit/Receive functions
  530. *
  531. @verbatim
  532. ===============================================================================
  533. ##### IO operation methods #####
  534. ===============================================================================
  535. [..]
  536. This subsection provides a set of functions allowing to manage the SWPMI
  537. data transfers.
  538. (#) There are two modes of transfer:
  539. (++) Blocking mode: The communication is performed in polling mode.
  540. The HAL status of all data processing is returned by the same function
  541. after finishing transfer.
  542. (++) Non-Blocking mode: The communication is performed using Interrupts
  543. or DMA. The end of the data processing will be indicated through the
  544. dedicated SWPMI Interrupt handler (HAL_SWPMI_IRQHandler()) when using Interrupt mode or
  545. the selected DMA stream interrupt handler when using DMA mode.
  546. The HAL_SWPMI_TxCpltCallback(), HAL_SWPMI_RxCpltCallback() user callbacks
  547. will be executed respectively at the end of the transmit or receive process.
  548. The HAL_SWPMI_ErrorCallback() user callback will be executed when a communication error is detected.
  549. (#) Blocking mode API's are:
  550. (++) HAL_SWPMI_Transmit()
  551. (++) HAL_SWPMI_Receive()
  552. (#) Non-Blocking mode API's with Interrupt are:
  553. (++) HAL_SWPMI_Transmit_IT()
  554. (++) HAL_SWPMI_Receive_IT()
  555. (++) HAL_SWPMI_IRQHandler()
  556. (#) Non-Blocking mode API's with DMA are:
  557. (++) HAL_SWPMI_Transmit_DMA()
  558. (++) HAL_SWPMI_Receive_DMA()
  559. (++) HAL_SWPMI_DMAPause()
  560. (++) HAL_SWPMI_DMAResume()
  561. (++) HAL_SWPMI_DMAStop()
  562. (#) A set of Transfer Complete Callbacks are provided in Non-Blocking mode:
  563. (++) HAL_SWPMI_TxHalfCpltCallback()
  564. (++) HAL_SWPMI_TxCpltCallback()
  565. (++) HAL_SWPMI_RxHalfCpltCallback()
  566. (++) HAL_SWPMI_RxCpltCallback()
  567. (++) HAL_SWPMI_ErrorCallback()
  568. (#) The capability to launch the above IO operations in loopback mode for
  569. user application verification:
  570. (++) HAL_SWPMI_EnableLoopback()
  571. (++) HAL_SWPMI_DisableLoopback()
  572. @endverbatim
  573. * @{
  574. */
  575. /**
  576. * @brief Transmit an amount of data in blocking mode.
  577. * @param hswpmi pointer to a SWPMI_HandleTypeDef structure that contains
  578. * the configuration information for SWPMI module.
  579. * @param pData Pointer to data buffer
  580. * @param Size Amount of data to be sent
  581. * @param Timeout Timeout duration
  582. * @retval HAL status
  583. */
  584. HAL_StatusTypeDef HAL_SWPMI_Transmit(SWPMI_HandleTypeDef *hswpmi, uint32_t* pData, uint16_t Size, uint32_t Timeout)
  585. {
  586. uint32_t tickstart = HAL_GetTick();
  587. HAL_StatusTypeDef status = HAL_OK;
  588. HAL_SWPMI_StateTypeDef tmp_state;
  589. uint32_t *ptmp_data;
  590. uint32_t tmp_size;
  591. if((pData == NULL ) || (Size == 0U))
  592. {
  593. status = HAL_ERROR;
  594. }
  595. else
  596. {
  597. /* Process Locked */
  598. __HAL_LOCK(hswpmi);
  599. tmp_state = hswpmi->State;
  600. if((tmp_state == HAL_SWPMI_STATE_READY) || (tmp_state == HAL_SWPMI_STATE_BUSY_RX))
  601. {
  602. /* Check if a non-blocking receive process is ongoing or not */
  603. if(tmp_state == HAL_SWPMI_STATE_READY)
  604. {
  605. hswpmi->State = HAL_SWPMI_STATE_BUSY_TX;
  606. /* Disable any transmitter interrupts */
  607. __HAL_SWPMI_DISABLE_IT(hswpmi, SWPMI_IT_TCIE | SWPMI_IT_TIE | SWPMI_IT_TXUNRIE | SWPMI_IT_TXBEIE);
  608. /* Disable any transmitter flags */
  609. __HAL_SWPMI_CLEAR_FLAG(hswpmi, SWPMI_FLAG_TXBEF | SWPMI_FLAG_TXUNRF | SWPMI_FLAG_TCF);
  610. /* Enable SWPMI peripheral if not */
  611. SET_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT);
  612. }
  613. else
  614. {
  615. hswpmi->State = HAL_SWPMI_STATE_BUSY_TX_RX;
  616. }
  617. ptmp_data = pData;
  618. tmp_size = Size;
  619. do
  620. {
  621. /* Wait the TXE to write data */
  622. if(HAL_IS_BIT_SET(hswpmi->Instance->ISR, SWPMI_FLAG_TXE))
  623. {
  624. hswpmi->Instance->TDR = *ptmp_data;
  625. ptmp_data++;
  626. tmp_size--;
  627. }
  628. else
  629. {
  630. /* Check for the Timeout */
  631. if(Timeout != HAL_MAX_DELAY)
  632. {
  633. if(((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
  634. {
  635. status = HAL_TIMEOUT;
  636. break;
  637. }
  638. }
  639. }
  640. } while(tmp_size != 0U);
  641. /* Wait on TXBEF flag to be able to start a second transfer */
  642. if(SWPMI_WaitOnFlagSetUntilTimeout(hswpmi, SWPMI_FLAG_TXBEF, tickstart, Timeout) != HAL_OK)
  643. {
  644. /* Timeout occurred */
  645. hswpmi->ErrorCode |= HAL_SWPMI_ERROR_TXBEF_TIMEOUT;
  646. status = HAL_TIMEOUT;
  647. }
  648. if(status == HAL_OK)
  649. {
  650. /* Check if a non-blocking receive Process is ongoing or not */
  651. if(hswpmi->State == HAL_SWPMI_STATE_BUSY_TX_RX)
  652. {
  653. hswpmi->State = HAL_SWPMI_STATE_BUSY_RX;
  654. }
  655. else
  656. {
  657. hswpmi->State = HAL_SWPMI_STATE_READY;
  658. }
  659. }
  660. }
  661. else
  662. {
  663. status = HAL_BUSY;
  664. }
  665. }
  666. if((status != HAL_OK) && (status != HAL_BUSY))
  667. {
  668. hswpmi->State = HAL_SWPMI_STATE_READY;
  669. }
  670. /* Process Unlocked */
  671. __HAL_UNLOCK(hswpmi);
  672. return status;
  673. }
  674. /**
  675. * @brief Receive an amount of data in blocking mode.
  676. * @param hswpmi pointer to a SWPMI_HandleTypeDef structure that contains
  677. * the configuration information for SWPMI module.
  678. * @param pData Pointer to data buffer
  679. * @param Size Amount of data to be received
  680. * @param Timeout Timeout duration
  681. * @retval HAL status
  682. */
  683. HAL_StatusTypeDef HAL_SWPMI_Receive(SWPMI_HandleTypeDef *hswpmi, uint32_t *pData, uint16_t Size, uint32_t Timeout)
  684. {
  685. uint32_t tickstart = HAL_GetTick();
  686. HAL_StatusTypeDef status = HAL_OK;
  687. HAL_SWPMI_StateTypeDef tmp_state;
  688. uint32_t *ptmp_data;
  689. uint32_t tmp_size;
  690. if((pData == NULL ) || (Size == 0U))
  691. {
  692. status = HAL_ERROR;
  693. }
  694. else
  695. {
  696. /* Process Locked */
  697. __HAL_LOCK(hswpmi);
  698. tmp_state = hswpmi->State;
  699. if((tmp_state == HAL_SWPMI_STATE_READY) || (tmp_state == HAL_SWPMI_STATE_BUSY_TX))
  700. {
  701. /* Check if a non-blocking transmit process is ongoing or not */
  702. if(tmp_state == HAL_SWPMI_STATE_READY)
  703. {
  704. hswpmi->State = HAL_SWPMI_STATE_BUSY_RX;
  705. /* Disable any receiver interrupts */
  706. CLEAR_BIT(hswpmi->Instance->IER, SWPMI_IT_SRIE | SWPMI_IT_RIE | SWPMI_IT_RXBERIE | SWPMI_IT_RXOVRIE | SWPMI_IT_RXBFIE);
  707. /* Enable SWPMI peripheral if not */
  708. SET_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT);
  709. }
  710. else
  711. {
  712. hswpmi->State = HAL_SWPMI_STATE_BUSY_TX_RX;
  713. }
  714. ptmp_data = pData;
  715. tmp_size = Size;
  716. do
  717. {
  718. /* Wait the RXNE to read data */
  719. if(HAL_IS_BIT_SET(hswpmi->Instance->ISR, SWPMI_FLAG_RXNE))
  720. {
  721. *ptmp_data = hswpmi->Instance->RDR;
  722. ptmp_data++;
  723. tmp_size--;
  724. }
  725. else
  726. {
  727. /* Check for the Timeout */
  728. if(Timeout != HAL_MAX_DELAY)
  729. {
  730. if(((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
  731. {
  732. status = HAL_TIMEOUT;
  733. break;
  734. }
  735. }
  736. }
  737. } while(tmp_size != 0U);
  738. if(status == HAL_OK)
  739. {
  740. if(HAL_IS_BIT_SET(hswpmi->Instance->ISR, SWPMI_FLAG_RXBFF))
  741. {
  742. /* Clear RXBFF at end of reception */
  743. WRITE_REG(hswpmi->Instance->ICR, SWPMI_FLAG_RXBFF);
  744. }
  745. /* Check if a non-blocking transmit Process is ongoing or not */
  746. if(hswpmi->State == HAL_SWPMI_STATE_BUSY_TX_RX)
  747. {
  748. hswpmi->State = HAL_SWPMI_STATE_BUSY_TX;
  749. }
  750. else
  751. {
  752. hswpmi->State = HAL_SWPMI_STATE_READY;
  753. }
  754. }
  755. }
  756. else
  757. {
  758. status = HAL_BUSY;
  759. }
  760. }
  761. if((status != HAL_OK) && (status != HAL_BUSY))
  762. {
  763. hswpmi->State = HAL_SWPMI_STATE_READY;
  764. }
  765. /* Process Unlocked */
  766. __HAL_UNLOCK(hswpmi);
  767. return status;
  768. }
  769. /**
  770. * @brief Transmit an amount of data in non-blocking mode with interrupt.
  771. * @param hswpmi pointer to a SWPMI_HandleTypeDef structure that contains
  772. * the configuration information for SWPMI module.
  773. * @param pData Pointer to data buffer
  774. * @param Size Amount of data to be sent
  775. * @retval HAL status
  776. */
  777. HAL_StatusTypeDef HAL_SWPMI_Transmit_IT(SWPMI_HandleTypeDef *hswpmi, uint32_t *pData, uint16_t Size)
  778. {
  779. HAL_StatusTypeDef status = HAL_OK;
  780. HAL_SWPMI_StateTypeDef tmp_state;
  781. if((pData == NULL ) || (Size == 0U))
  782. {
  783. status = HAL_ERROR;
  784. }
  785. else
  786. {
  787. /* Process Locked */
  788. __HAL_LOCK(hswpmi);
  789. tmp_state = hswpmi->State;
  790. if((tmp_state == HAL_SWPMI_STATE_READY) || (tmp_state == HAL_SWPMI_STATE_BUSY_RX))
  791. {
  792. /* Update handle */
  793. hswpmi->pTxBuffPtr = pData;
  794. hswpmi->TxXferSize = Size;
  795. hswpmi->TxXferCount = Size;
  796. hswpmi->ErrorCode = HAL_SWPMI_ERROR_NONE;
  797. /* Check if a receive process is ongoing or not */
  798. if(tmp_state == HAL_SWPMI_STATE_READY)
  799. {
  800. hswpmi->State = HAL_SWPMI_STATE_BUSY_TX;
  801. /* Enable SWPMI peripheral if not */
  802. SET_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT);
  803. }
  804. else
  805. {
  806. hswpmi->State = HAL_SWPMI_STATE_BUSY_TX_RX;
  807. }
  808. /* Enable the SWPMI transmit underrun error */
  809. __HAL_SWPMI_ENABLE_IT(hswpmi, SWPMI_IT_TXUNRIE);
  810. /* Process Unlocked */
  811. __HAL_UNLOCK(hswpmi);
  812. /* Enable the SWPMI interrupts: */
  813. /* - Transmit data register empty */
  814. /* - Transmit buffer empty */
  815. /* - Transmit/Reception completion */
  816. __HAL_SWPMI_ENABLE_IT(hswpmi, SWPMI_IT_TIE | SWPMI_IT_TXBEIE | SWPMI_IT_TCIE);
  817. }
  818. else
  819. {
  820. status = HAL_BUSY;
  821. /* Process Unlocked */
  822. __HAL_UNLOCK(hswpmi);
  823. }
  824. }
  825. return status;
  826. }
  827. /**
  828. * @brief Receive an amount of data in non-blocking mode with interrupt.
  829. * @param hswpmi SWPMI handle
  830. * @param pData Pointer to data buffer
  831. * @param Size Amount of data to be received
  832. * @retval HAL status
  833. */
  834. HAL_StatusTypeDef HAL_SWPMI_Receive_IT(SWPMI_HandleTypeDef *hswpmi, uint32_t *pData, uint16_t Size)
  835. {
  836. HAL_StatusTypeDef status = HAL_OK;
  837. HAL_SWPMI_StateTypeDef tmp_state;
  838. if((pData == NULL ) || (Size == 0U))
  839. {
  840. status = HAL_ERROR;
  841. }
  842. else
  843. {
  844. /* Process Locked */
  845. __HAL_LOCK(hswpmi);
  846. tmp_state = hswpmi->State;
  847. if((tmp_state == HAL_SWPMI_STATE_READY) || (tmp_state == HAL_SWPMI_STATE_BUSY_TX))
  848. {
  849. /* Update handle */
  850. hswpmi->pRxBuffPtr = pData;
  851. hswpmi->RxXferSize = Size;
  852. hswpmi->RxXferCount = Size;
  853. hswpmi->ErrorCode = HAL_SWPMI_ERROR_NONE;
  854. /* Check if a transmit process is ongoing or not */
  855. if(tmp_state == HAL_SWPMI_STATE_READY)
  856. {
  857. hswpmi->State = HAL_SWPMI_STATE_BUSY_RX;
  858. /* Enable SWPMI peripheral if not */
  859. SET_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT);
  860. }
  861. else
  862. {
  863. hswpmi->State = HAL_SWPMI_STATE_BUSY_TX_RX;
  864. }
  865. /* Process Unlocked */
  866. __HAL_UNLOCK(hswpmi);
  867. /* Enable the SWPMI slave resume */
  868. /* Enable the SWPMI Data Register not empty Interrupt, receive CRC Error, receive overrun and RxBuf Interrupt */
  869. /* Enable the SWPMI Transmit/Reception completion */
  870. __HAL_SWPMI_ENABLE_IT(hswpmi, SWPMI_IT_RIE | SWPMI_IT_RXBERIE | SWPMI_IT_RXOVRIE | SWPMI_IT_RXBFIE);
  871. }
  872. else
  873. {
  874. status = HAL_BUSY;
  875. /* Process Unlocked */
  876. __HAL_UNLOCK(hswpmi);
  877. }
  878. }
  879. return status;
  880. }
  881. /**
  882. * @brief Transmit an amount of data in non-blocking mode with DMA interrupt.
  883. * @param hswpmi SWPMI handle
  884. * @param pData Pointer to data buffer
  885. * @param Size Amount of data to be sent
  886. * @retval HAL status
  887. */
  888. HAL_StatusTypeDef HAL_SWPMI_Transmit_DMA(SWPMI_HandleTypeDef *hswpmi, uint32_t *pData, uint16_t Size)
  889. {
  890. HAL_StatusTypeDef status = HAL_OK;
  891. HAL_SWPMI_StateTypeDef tmp_state;
  892. if((pData == NULL ) || (Size == 0U))
  893. {
  894. status = HAL_ERROR;
  895. }
  896. else
  897. {
  898. /* Process Locked */
  899. __HAL_LOCK(hswpmi);
  900. tmp_state = hswpmi->State;
  901. if((tmp_state == HAL_SWPMI_STATE_READY) || (tmp_state == HAL_SWPMI_STATE_BUSY_RX))
  902. {
  903. /* Update handle */
  904. hswpmi->pTxBuffPtr = pData;
  905. hswpmi->TxXferSize = Size;
  906. hswpmi->TxXferCount = Size;
  907. hswpmi->ErrorCode = HAL_SWPMI_ERROR_NONE;
  908. /* Check if a receive process is ongoing or not */
  909. if(tmp_state == HAL_SWPMI_STATE_READY)
  910. {
  911. hswpmi->State = HAL_SWPMI_STATE_BUSY_TX;
  912. /* Enable SWPMI peripheral if not */
  913. SET_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT);
  914. }
  915. else
  916. {
  917. hswpmi->State = HAL_SWPMI_STATE_BUSY_TX_RX;
  918. }
  919. /* Set the SWPMI DMA transfer complete callback */
  920. hswpmi->hdmatx->XferCpltCallback = SWPMI_DMATransmitCplt;
  921. /* Set the SWPMI DMA Half transfer complete callback */
  922. hswpmi->hdmatx->XferHalfCpltCallback = SWPMI_DMATxHalfCplt;
  923. /* Set the DMA error callback */
  924. hswpmi->hdmatx->XferErrorCallback = SWPMI_DMAError;
  925. /* Enable the SWPMI transmit DMA stream */
  926. if(HAL_DMA_Start_IT(hswpmi->hdmatx, (uint32_t)hswpmi->pTxBuffPtr, (uint32_t)&hswpmi->Instance->TDR, Size) != HAL_OK)
  927. {
  928. hswpmi->State = tmp_state; /* Back to previous state */
  929. hswpmi->ErrorCode = HAL_SWPMI_ERROR_DMA;
  930. status = HAL_ERROR;
  931. /* Process Unlocked */
  932. __HAL_UNLOCK(hswpmi);
  933. }
  934. else
  935. {
  936. /* Process Unlocked */
  937. __HAL_UNLOCK(hswpmi);
  938. /* Enable the SWPMI transmit underrun error */
  939. __HAL_SWPMI_ENABLE_IT(hswpmi, SWPMI_IT_TXUNRIE);
  940. /* Enable the DMA transfer for transmit request by setting the TXDMA bit
  941. in the SWPMI CR register */
  942. SET_BIT(hswpmi->Instance->CR, SWPMI_CR_TXDMA);
  943. }
  944. }
  945. else
  946. {
  947. status = HAL_BUSY;
  948. /* Process Unlocked */
  949. __HAL_UNLOCK(hswpmi);
  950. }
  951. }
  952. return status;
  953. }
  954. /**
  955. * @brief Receive an amount of data in non-blocking mode with DMA interrupt.
  956. * @param hswpmi SWPMI handle
  957. * @param pData Pointer to data buffer
  958. * @param Size Amount of data to be received
  959. * @retval HAL status
  960. */
  961. HAL_StatusTypeDef HAL_SWPMI_Receive_DMA(SWPMI_HandleTypeDef *hswpmi, uint32_t *pData, uint16_t Size)
  962. {
  963. HAL_StatusTypeDef status = HAL_OK;
  964. HAL_SWPMI_StateTypeDef tmp_state;
  965. if((pData == NULL ) || (Size == 0U))
  966. {
  967. status = HAL_ERROR;
  968. }
  969. else
  970. {
  971. /* Process Locked */
  972. __HAL_LOCK(hswpmi);
  973. tmp_state = hswpmi->State;
  974. if((tmp_state == HAL_SWPMI_STATE_READY) || (tmp_state == HAL_SWPMI_STATE_BUSY_TX))
  975. {
  976. /* Update handle */
  977. hswpmi->pRxBuffPtr = pData;
  978. hswpmi->RxXferSize = Size;
  979. hswpmi->ErrorCode = HAL_SWPMI_ERROR_NONE;
  980. /* Check if a transmit process is ongoing or not */
  981. if(tmp_state == HAL_SWPMI_STATE_READY)
  982. {
  983. hswpmi->State = HAL_SWPMI_STATE_BUSY_RX;
  984. /* Enable SWPMI peripheral if not */
  985. SET_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT);
  986. }
  987. else
  988. {
  989. hswpmi->State = HAL_SWPMI_STATE_BUSY_TX_RX;
  990. }
  991. /* Set the SWPMI DMA transfer complete callback */
  992. hswpmi->hdmarx->XferCpltCallback = SWPMI_DMAReceiveCplt;
  993. /* Set the SWPMI DMA Half transfer complete callback */
  994. hswpmi->hdmarx->XferHalfCpltCallback = SWPMI_DMARxHalfCplt;
  995. /* Set the DMA error callback */
  996. hswpmi->hdmarx->XferErrorCallback = SWPMI_DMAError;
  997. /* Enable the DMA request */
  998. if(HAL_DMA_Start_IT(hswpmi->hdmarx, (uint32_t)&hswpmi->Instance->RDR, (uint32_t)hswpmi->pRxBuffPtr, Size) != HAL_OK)
  999. {
  1000. hswpmi->State = tmp_state; /* Back to previous state */
  1001. hswpmi->ErrorCode = HAL_SWPMI_ERROR_DMA;
  1002. status = HAL_ERROR;
  1003. /* Process Unlocked */
  1004. __HAL_UNLOCK(hswpmi);
  1005. }
  1006. else
  1007. {
  1008. /* Process Unlocked */
  1009. __HAL_UNLOCK(hswpmi);
  1010. /* Enable the SWPMI receive CRC Error and receive overrun interrupts */
  1011. __HAL_SWPMI_ENABLE_IT(hswpmi, SWPMI_IT_RXBERIE | SWPMI_IT_RXOVRIE);
  1012. /* Enable the DMA transfer for the receiver request by setting the RXDMA bit
  1013. in the SWPMI CR register */
  1014. SET_BIT(hswpmi->Instance->CR, SWPMI_CR_RXDMA);
  1015. }
  1016. }
  1017. else
  1018. {
  1019. status = HAL_BUSY;
  1020. /* Process Unlocked */
  1021. __HAL_UNLOCK(hswpmi);
  1022. }
  1023. }
  1024. return status;
  1025. }
  1026. /**
  1027. * @brief Stop all DMA transfers.
  1028. * @param hswpmi SWPMI handle
  1029. * @retval HAL status
  1030. */
  1031. HAL_StatusTypeDef HAL_SWPMI_DMAStop(SWPMI_HandleTypeDef *hswpmi)
  1032. {
  1033. HAL_StatusTypeDef status = HAL_OK;
  1034. /* Process Locked */
  1035. __HAL_LOCK(hswpmi);
  1036. /* Disable the SWPMI Tx/Rx DMA requests */
  1037. CLEAR_BIT(hswpmi->Instance->CR, (SWPMI_CR_TXDMA | SWPMI_CR_RXDMA));
  1038. /* Abort the SWPMI DMA tx stream */
  1039. if(hswpmi->hdmatx != NULL)
  1040. {
  1041. if(HAL_DMA_Abort(hswpmi->hdmatx) != HAL_OK)
  1042. {
  1043. hswpmi->ErrorCode |= HAL_SWPMI_ERROR_DMA;
  1044. status = HAL_ERROR;
  1045. }
  1046. }
  1047. /* Abort the SWPMI DMA rx stream */
  1048. if(hswpmi->hdmarx != NULL)
  1049. {
  1050. if(HAL_DMA_Abort(hswpmi->hdmarx) != HAL_OK)
  1051. {
  1052. hswpmi->ErrorCode |= HAL_SWPMI_ERROR_DMA;
  1053. status = HAL_ERROR;
  1054. }
  1055. }
  1056. /* Disable SWPMI interface */
  1057. CLEAR_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT);
  1058. hswpmi->State = HAL_SWPMI_STATE_READY;
  1059. /* Process Unlocked */
  1060. __HAL_UNLOCK(hswpmi);
  1061. return status;
  1062. }
  1063. /**
  1064. * @brief Enable the Loopback mode.
  1065. * @param hswpmi SWPMI handle
  1066. * @note Loopback mode is to be used only for test purposes
  1067. * @retval HAL_OK / HAL_BUSY
  1068. */
  1069. HAL_StatusTypeDef HAL_SWPMI_EnableLoopback(SWPMI_HandleTypeDef *hswpmi)
  1070. {
  1071. HAL_StatusTypeDef status = HAL_OK;
  1072. /* Process Locked */
  1073. __HAL_LOCK(hswpmi);
  1074. /* Make sure the SWPMI interface is not enabled to set the loopback mode */
  1075. CLEAR_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT);
  1076. /* Set Loopback */
  1077. SET_BIT(hswpmi->Instance->CR, SWPMI_CR_LPBK);
  1078. /* Enable SWPMI interface in loopback mode */
  1079. SET_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT);
  1080. /* Process Unlocked */
  1081. __HAL_UNLOCK(hswpmi);
  1082. return status;
  1083. }
  1084. /**
  1085. * @brief Disable the Loopback mode.
  1086. * @param hswpmi SWPMI handle
  1087. * @note Loopback mode is to be used only for test purposes
  1088. * @retval HAL_OK / HAL_BUSY
  1089. */
  1090. HAL_StatusTypeDef HAL_SWPMI_DisableLoopback(SWPMI_HandleTypeDef *hswpmi)
  1091. {
  1092. HAL_StatusTypeDef status = HAL_OK;
  1093. /* Process Locked */
  1094. __HAL_LOCK(hswpmi);
  1095. /* Make sure the SWPMI interface is not enabled to reset the loopback mode */
  1096. CLEAR_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT);
  1097. /* Reset Loopback */
  1098. CLEAR_BIT(hswpmi->Instance->CR, SWPMI_CR_LPBK);
  1099. /* Re-enable SWPMI interface in normal mode */
  1100. SET_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT);
  1101. /* Process Unlocked */
  1102. __HAL_UNLOCK(hswpmi);
  1103. return status;
  1104. }
  1105. /**
  1106. * @}
  1107. */
  1108. /** @defgroup SWPMI_Exported_Group3 SWPMI IRQ handler and callbacks
  1109. * @brief SWPMI IRQ handler.
  1110. *
  1111. @verbatim
  1112. ==============================================================================
  1113. ##### SWPMI IRQ handler and callbacks #####
  1114. ==============================================================================
  1115. [..] This section provides SWPMI IRQ handler and callback functions called within
  1116. the IRQ handler.
  1117. @endverbatim
  1118. * @{
  1119. */
  1120. /**
  1121. * @brief Handle SWPMI interrupt request.
  1122. * @param hswpmi SWPMI handle
  1123. * @retval None
  1124. */
  1125. void HAL_SWPMI_IRQHandler(SWPMI_HandleTypeDef *hswpmi)
  1126. {
  1127. uint32_t regisr = READ_REG(hswpmi->Instance->ISR);
  1128. uint32_t regier = READ_REG(hswpmi->Instance->IER);
  1129. uint32_t errcode = HAL_SWPMI_ERROR_NONE;
  1130. /* SWPMI CRC error interrupt occurred --------------------------------------*/
  1131. if(((regisr & SWPMI_FLAG_RXBERF) != 0U) && ((regier & SWPMI_IT_RXBERIE) != 0U))
  1132. {
  1133. /* Disable Receive CRC interrupt */
  1134. CLEAR_BIT(hswpmi->Instance->IER, SWPMI_IT_RXBERIE | SWPMI_IT_RXBFIE);
  1135. /* Clear Receive CRC and Receive buffer full flag */
  1136. WRITE_REG(hswpmi->Instance->ICR, SWPMI_FLAG_RXBERF | SWPMI_FLAG_RXBFF);
  1137. errcode |= HAL_SWPMI_ERROR_CRC;
  1138. }
  1139. /* SWPMI Over-Run interrupt occurred -----------------------------------------*/
  1140. if(((regisr & SWPMI_FLAG_RXOVRF) != 0U) && ((regier & SWPMI_IT_RXOVRIE) != 0U))
  1141. {
  1142. /* Disable Receive overrun interrupt */
  1143. CLEAR_BIT(hswpmi->Instance->IER, SWPMI_IT_RXOVRIE);
  1144. /* Clear Receive overrun flag */
  1145. WRITE_REG(hswpmi->Instance->ICR, SWPMI_FLAG_RXOVRF);
  1146. errcode |= HAL_SWPMI_ERROR_OVR;
  1147. }
  1148. /* SWPMI Under-Run interrupt occurred -----------------------------------------*/
  1149. if(((regisr & SWPMI_FLAG_TXUNRF) != 0U) && ((regier & SWPMI_IT_TXUNRIE) != 0U))
  1150. {
  1151. /* Disable Transmit under run interrupt */
  1152. CLEAR_BIT(hswpmi->Instance->IER, SWPMI_IT_TXUNRIE);
  1153. /* Clear Transmit under run flag */
  1154. WRITE_REG(hswpmi->Instance->ICR, SWPMI_FLAG_TXUNRF);
  1155. errcode |= HAL_SWPMI_ERROR_UDR;
  1156. }
  1157. /* Call SWPMI Error Call back function if needed --------------------------*/
  1158. if(errcode != HAL_SWPMI_ERROR_NONE)
  1159. {
  1160. hswpmi->ErrorCode |= errcode;
  1161. if((errcode & HAL_SWPMI_ERROR_UDR) != 0U)
  1162. {
  1163. /* Check TXDMA transfer to abort */
  1164. if(HAL_IS_BIT_SET(hswpmi->Instance->CR, SWPMI_CR_TXDMA))
  1165. {
  1166. /* Disable DMA TX at SWPMI level */
  1167. CLEAR_BIT(hswpmi->Instance->CR, SWPMI_CR_TXDMA);
  1168. /* Abort the USART DMA Tx stream */
  1169. if(hswpmi->hdmatx != NULL)
  1170. {
  1171. /* Set the SWPMI Tx DMA Abort callback :
  1172. will lead to call HAL_SWPMI_ErrorCallback() at end of DMA abort procedure */
  1173. hswpmi->hdmatx->XferAbortCallback = SWPMI_DMAAbortOnError;
  1174. /* Abort DMA TX */
  1175. if(HAL_DMA_Abort_IT(hswpmi->hdmatx) != HAL_OK)
  1176. {
  1177. /* Call Directly hswpmi->hdmatx->XferAbortCallback function in case of error */
  1178. hswpmi->hdmatx->XferAbortCallback(hswpmi->hdmatx);
  1179. }
  1180. }
  1181. else
  1182. {
  1183. /* Set the SWPMI state ready to be able to start again the process */
  1184. hswpmi->State = HAL_SWPMI_STATE_READY;
  1185. #if (USE_HAL_SWPMI_REGISTER_CALLBACKS == 1)
  1186. hswpmi->ErrorCallback(hswpmi);
  1187. #else
  1188. HAL_SWPMI_ErrorCallback(hswpmi);
  1189. #endif
  1190. }
  1191. }
  1192. else
  1193. {
  1194. /* Set the SWPMI state ready to be able to start again the process */
  1195. hswpmi->State = HAL_SWPMI_STATE_READY;
  1196. #if (USE_HAL_SWPMI_REGISTER_CALLBACKS == 1)
  1197. hswpmi->ErrorCallback(hswpmi);
  1198. #else
  1199. HAL_SWPMI_ErrorCallback(hswpmi);
  1200. #endif
  1201. }
  1202. }
  1203. else
  1204. {
  1205. /* Check RXDMA transfer to abort */
  1206. if(HAL_IS_BIT_SET(hswpmi->Instance->CR, SWPMI_CR_RXDMA))
  1207. {
  1208. /* Disable DMA RX at SWPMI level */
  1209. CLEAR_BIT(hswpmi->Instance->CR, SWPMI_CR_RXDMA);
  1210. /* Abort the USART DMA Rx stream */
  1211. if(hswpmi->hdmarx != NULL)
  1212. {
  1213. /* Set the SWPMI Rx DMA Abort callback :
  1214. will lead to call HAL_SWPMI_ErrorCallback() at end of DMA abort procedure */
  1215. hswpmi->hdmarx->XferAbortCallback = SWPMI_DMAAbortOnError;
  1216. /* Abort DMA RX */
  1217. if(HAL_DMA_Abort_IT(hswpmi->hdmarx) != HAL_OK)
  1218. {
  1219. /* Call Directly hswpmi->hdmarx->XferAbortCallback function in case of error */
  1220. hswpmi->hdmarx->XferAbortCallback(hswpmi->hdmarx);
  1221. }
  1222. }
  1223. else
  1224. {
  1225. /* Set the SWPMI state ready to be able to start again the process */
  1226. hswpmi->State = HAL_SWPMI_STATE_READY;
  1227. #if (USE_HAL_SWPMI_REGISTER_CALLBACKS == 1)
  1228. hswpmi->ErrorCallback(hswpmi);
  1229. #else
  1230. HAL_SWPMI_ErrorCallback(hswpmi);
  1231. #endif
  1232. }
  1233. }
  1234. else
  1235. {
  1236. /* Set the SWPMI state ready to be able to start again the process */
  1237. hswpmi->State = HAL_SWPMI_STATE_READY;
  1238. #if (USE_HAL_SWPMI_REGISTER_CALLBACKS == 1)
  1239. hswpmi->ErrorCallback(hswpmi);
  1240. #else
  1241. HAL_SWPMI_ErrorCallback(hswpmi);
  1242. #endif
  1243. }
  1244. }
  1245. }
  1246. /* SWPMI in mode Receiver ---------------------------------------------------*/
  1247. if(((regisr & SWPMI_FLAG_RXNE) != 0U) && ((regier & SWPMI_IT_RIE) != 0U))
  1248. {
  1249. SWPMI_Receive_IT(hswpmi);
  1250. }
  1251. /* SWPMI in mode Transmitter ------------------------------------------------*/
  1252. if(((regisr & SWPMI_FLAG_TXE) != 0U) && ((regier & SWPMI_IT_TIE) != 0U))
  1253. {
  1254. SWPMI_Transmit_IT(hswpmi);
  1255. }
  1256. /* SWPMI in mode Transmitter (Transmit buffer empty) ------------------------*/
  1257. if(((regisr & SWPMI_FLAG_TXBEF) != 0U) && ((regier & SWPMI_IT_TXBEIE) != 0U))
  1258. {
  1259. SWPMI_EndTransmit_IT(hswpmi);
  1260. }
  1261. /* SWPMI in mode Receiver (Receive buffer full) -----------------------------*/
  1262. if(((regisr & SWPMI_FLAG_RXBFF) != 0U) && ((regier & SWPMI_IT_RXBFIE) != 0U))
  1263. {
  1264. SWPMI_EndReceive_IT(hswpmi);
  1265. }
  1266. /* Both Transmission and reception complete ---------------------------------*/
  1267. if(((regisr & SWPMI_FLAG_TCF) != 0U) && ((regier & SWPMI_IT_TCIE) != 0U))
  1268. {
  1269. SWPMI_EndTransmitReceive_IT(hswpmi);
  1270. }
  1271. }
  1272. /**
  1273. * @brief Tx Transfer completed callback.
  1274. * @param hswpmi SWPMI handle
  1275. * @retval None
  1276. */
  1277. __weak void HAL_SWPMI_TxCpltCallback(SWPMI_HandleTypeDef *hswpmi)
  1278. {
  1279. /* Prevent unused argument(s) compilation warning */
  1280. UNUSED(hswpmi);
  1281. /* NOTE : This function should not be modified, when the callback is needed,
  1282. the HAL_SWPMI_TxCpltCallback is to be implemented in the user file
  1283. */
  1284. }
  1285. /**
  1286. * @brief Tx Half Transfer completed callback.
  1287. * @param hswpmi SWPMI handle
  1288. * @retval None
  1289. */
  1290. __weak void HAL_SWPMI_TxHalfCpltCallback(SWPMI_HandleTypeDef *hswpmi)
  1291. {
  1292. /* Prevent unused argument(s) compilation warning */
  1293. UNUSED(hswpmi);
  1294. /* NOTE: This function should not be modified, when the callback is needed,
  1295. the HAL_SWPMI_TxHalfCpltCallback is to be implemented in the user file
  1296. */
  1297. }
  1298. /**
  1299. * @brief Rx Transfer completed callback.
  1300. * @param hswpmi SWPMI handle
  1301. * @retval None
  1302. */
  1303. __weak void HAL_SWPMI_RxCpltCallback(SWPMI_HandleTypeDef *hswpmi)
  1304. {
  1305. /* Prevent unused argument(s) compilation warning */
  1306. UNUSED(hswpmi);
  1307. /* NOTE : This function should not be modified, when the callback is needed,
  1308. the HAL_SWPMI_RxCpltCallback is to be implemented in the user file
  1309. */
  1310. }
  1311. /**
  1312. * @brief Rx Half Transfer completed callback.
  1313. * @param hswpmi SWPMI handle
  1314. * @retval None
  1315. */
  1316. __weak void HAL_SWPMI_RxHalfCpltCallback(SWPMI_HandleTypeDef *hswpmi)
  1317. {
  1318. /* Prevent unused argument(s) compilation warning */
  1319. UNUSED(hswpmi);
  1320. /* NOTE: This function should not be modified, when the callback is needed,
  1321. the HAL_SWPMI_RxHalfCpltCallback is to be implemented in the user file
  1322. */
  1323. }
  1324. /**
  1325. * @brief SWPMI error callback.
  1326. * @param hswpmi SWPMI handle
  1327. * @retval None
  1328. */
  1329. __weak void HAL_SWPMI_ErrorCallback(SWPMI_HandleTypeDef *hswpmi)
  1330. {
  1331. /* Prevent unused argument(s) compilation warning */
  1332. UNUSED(hswpmi);
  1333. /* NOTE : This function should not be modified, when the callback is needed,
  1334. the HAL_SWPMI_ErrorCallback is to be implemented in the user file
  1335. */
  1336. }
  1337. /**
  1338. * @}
  1339. */
  1340. /** @defgroup SWPMI_Exported_Group4 Peripheral Control methods
  1341. * @brief SWPMI control functions
  1342. *
  1343. @verbatim
  1344. ===============================================================================
  1345. ##### Peripheral Control methods #####
  1346. ===============================================================================
  1347. [..]
  1348. This subsection provides a set of functions allowing to control the SWPMI.
  1349. (+) HAL_SWPMI_GetState() API is helpful to check in run-time the state of the SWPMI peripheral
  1350. (+) HAL_SWPMI_GetError() API is helpful to check in run-time the error state of the SWPMI peripheral
  1351. @endverbatim
  1352. * @{
  1353. */
  1354. /**
  1355. * @brief Return the SWPMI handle state.
  1356. * @param hswpmi SWPMI handle
  1357. * @retval HAL state
  1358. */
  1359. HAL_SWPMI_StateTypeDef HAL_SWPMI_GetState(SWPMI_HandleTypeDef *hswpmi)
  1360. {
  1361. /* Return SWPMI handle state */
  1362. return hswpmi->State;
  1363. }
  1364. /**
  1365. * @brief Return the SWPMI error code.
  1366. * @param hswpmi : pointer to a SWPMI_HandleTypeDef structure that contains
  1367. * the configuration information for the specified SWPMI.
  1368. * @retval SWPMI Error Code
  1369. */
  1370. uint32_t HAL_SWPMI_GetError(SWPMI_HandleTypeDef *hswpmi)
  1371. {
  1372. return hswpmi->ErrorCode;
  1373. }
  1374. /**
  1375. * @}
  1376. */
  1377. /**
  1378. * @}
  1379. */
  1380. /* Private functions ---------------------------------------------------------*/
  1381. /** @defgroup SWPMI_Private_Functions SWPMI Private Functions
  1382. * @{
  1383. */
  1384. /**
  1385. * @brief Transmit an amount of data in interrupt mode.
  1386. * @note Function called under interruption only, once interruptions have been enabled by HAL_SWPMI_Transmit_IT()
  1387. * @param hswpmi SWPMI handle
  1388. * @retval None
  1389. */
  1390. static void SWPMI_Transmit_IT(SWPMI_HandleTypeDef *hswpmi)
  1391. {
  1392. HAL_SWPMI_StateTypeDef tmp_state = hswpmi->State;
  1393. if ((tmp_state == HAL_SWPMI_STATE_BUSY_TX) || (tmp_state == HAL_SWPMI_STATE_BUSY_TX_RX))
  1394. {
  1395. if(hswpmi->TxXferCount == 0U)
  1396. {
  1397. /* Disable the SWPMI TXE and Underrun Interrupts */
  1398. CLEAR_BIT(hswpmi->Instance->IER, (SWPMI_IT_TIE | SWPMI_IT_TXUNRIE));
  1399. }
  1400. else
  1401. {
  1402. hswpmi->Instance->TDR = (uint32_t)*hswpmi->pTxBuffPtr;
  1403. hswpmi->pTxBuffPtr++;
  1404. hswpmi->TxXferCount--;
  1405. }
  1406. }
  1407. else
  1408. {
  1409. /* nothing to do */
  1410. }
  1411. }
  1412. /**
  1413. * @brief Wraps up transmission in non-blocking mode.
  1414. * @param hswpmi SWPMI handle
  1415. * @retval None
  1416. */
  1417. static void SWPMI_EndTransmit_IT(SWPMI_HandleTypeDef *hswpmi)
  1418. {
  1419. /* Clear the SWPMI Transmit buffer empty Flag */
  1420. WRITE_REG(hswpmi->Instance->ICR, SWPMI_FLAG_TXBEF);
  1421. /* Disable the all SWPMI Transmit Interrupts */
  1422. CLEAR_BIT(hswpmi->Instance->IER, SWPMI_IT_TIE | SWPMI_IT_TXUNRIE | SWPMI_IT_TXBEIE);
  1423. /* Check if a receive Process is ongoing or not */
  1424. if(hswpmi->State == HAL_SWPMI_STATE_BUSY_TX_RX)
  1425. {
  1426. hswpmi->State = HAL_SWPMI_STATE_BUSY_RX;
  1427. }
  1428. else
  1429. {
  1430. hswpmi->State = HAL_SWPMI_STATE_READY;
  1431. }
  1432. #if (USE_HAL_SWPMI_REGISTER_CALLBACKS == 1)
  1433. hswpmi->TxCpltCallback(hswpmi);
  1434. #else
  1435. HAL_SWPMI_TxCpltCallback(hswpmi);
  1436. #endif
  1437. }
  1438. /**
  1439. * @brief Receive an amount of data in interrupt mode.
  1440. * @note Function called under interruption only, once interruptions have been enabled by HAL_SWPMI_Receive_IT()
  1441. * @param hswpmi SWPMI handle
  1442. * @retval None
  1443. */
  1444. static void SWPMI_Receive_IT(SWPMI_HandleTypeDef *hswpmi)
  1445. {
  1446. HAL_SWPMI_StateTypeDef tmp_state = hswpmi->State;
  1447. if((tmp_state == HAL_SWPMI_STATE_BUSY_RX) || (tmp_state == HAL_SWPMI_STATE_BUSY_TX_RX))
  1448. {
  1449. *hswpmi->pRxBuffPtr = (uint32_t)(hswpmi->Instance->RDR);
  1450. hswpmi->pRxBuffPtr++;
  1451. --hswpmi->RxXferCount;
  1452. if(hswpmi->RxXferCount == 0U)
  1453. {
  1454. /* Wait for RXBFF flag to update state */
  1455. #if (USE_HAL_SWPMI_REGISTER_CALLBACKS == 1)
  1456. hswpmi->RxCpltCallback(hswpmi);
  1457. #else
  1458. HAL_SWPMI_RxCpltCallback(hswpmi);
  1459. #endif
  1460. }
  1461. }
  1462. else
  1463. {
  1464. /* nothing to do */
  1465. }
  1466. }
  1467. /**
  1468. * @brief Wraps up reception in non-blocking mode.
  1469. * @param hswpmi SWPMI handle
  1470. * @retval None
  1471. */
  1472. static void SWPMI_EndReceive_IT(SWPMI_HandleTypeDef *hswpmi)
  1473. {
  1474. /* Clear the SWPMI Receive buffer full Flag */
  1475. WRITE_REG(hswpmi->Instance->ICR, SWPMI_FLAG_RXBFF);
  1476. /* Disable the all SWPMI Receive Interrupts */
  1477. CLEAR_BIT(hswpmi->Instance->IER, SWPMI_IT_RIE | SWPMI_IT_RXBERIE | SWPMI_IT_RXOVRIE | SWPMI_IT_RXBFIE);
  1478. /* Check if a transmit Process is ongoing or not */
  1479. if(hswpmi->State == HAL_SWPMI_STATE_BUSY_TX_RX)
  1480. {
  1481. hswpmi->State = HAL_SWPMI_STATE_BUSY_TX;
  1482. }
  1483. else
  1484. {
  1485. hswpmi->State = HAL_SWPMI_STATE_READY;
  1486. }
  1487. }
  1488. /**
  1489. * @brief Wraps up transmission and reception in non-blocking mode.
  1490. * @param hswpmi SWPMI handle
  1491. * @retval None
  1492. */
  1493. static void SWPMI_EndTransmitReceive_IT(SWPMI_HandleTypeDef *hswpmi)
  1494. {
  1495. /* Clear the SWPMI Transmission Complete Flag */
  1496. WRITE_REG(hswpmi->Instance->ICR, SWPMI_FLAG_TCF);
  1497. /* Disable the SWPMI Transmission Complete Interrupt */
  1498. CLEAR_BIT(hswpmi->Instance->IER, SWPMI_IT_TCIE);
  1499. /* Check if a receive Process is ongoing or not */
  1500. if(hswpmi->State == HAL_SWPMI_STATE_BUSY_TX_RX)
  1501. {
  1502. hswpmi->State = HAL_SWPMI_STATE_BUSY_RX;
  1503. }
  1504. else if(hswpmi->State == HAL_SWPMI_STATE_BUSY_TX)
  1505. {
  1506. hswpmi->State = HAL_SWPMI_STATE_READY;
  1507. }
  1508. else
  1509. {
  1510. /* nothing to do */
  1511. }
  1512. }
  1513. /**
  1514. * @brief DMA SWPMI transmit process complete callback.
  1515. * @param hdma DMA handle
  1516. * @retval None
  1517. */
  1518. static void SWPMI_DMATransmitCplt(DMA_HandleTypeDef *hdma)
  1519. {
  1520. SWPMI_HandleTypeDef* hswpmi = ( SWPMI_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
  1521. uint32_t tickstart;
  1522. /* DMA Normal mode*/
  1523. if(((((DMA_Stream_TypeDef *)hdma->Instance)->CR) & DMA_SxCR_CIRC) == 0U)
  1524. {
  1525. hswpmi->TxXferCount = 0U;
  1526. /* Disable the DMA transfer for transmit request by setting the TXDMA bit
  1527. in the SWPMI CR register */
  1528. CLEAR_BIT(hswpmi->Instance->CR, SWPMI_CR_TXDMA);
  1529. /* Init tickstart for timeout managment*/
  1530. tickstart = HAL_GetTick();
  1531. /* Wait the TXBEF */
  1532. if(SWPMI_WaitOnFlagSetUntilTimeout(hswpmi, SWPMI_FLAG_TXBEF, tickstart, SWPMI_TIMEOUT_VALUE) != HAL_OK)
  1533. {
  1534. /* Timeout occurred */
  1535. hswpmi->ErrorCode |= HAL_SWPMI_ERROR_TXBEF_TIMEOUT;
  1536. #if (USE_HAL_SWPMI_REGISTER_CALLBACKS == 1)
  1537. hswpmi->ErrorCallback(hswpmi);
  1538. #else
  1539. HAL_SWPMI_ErrorCallback(hswpmi);
  1540. #endif
  1541. }
  1542. else
  1543. {
  1544. /* No Timeout */
  1545. /* Check if a receive process is ongoing or not */
  1546. if(hswpmi->State == HAL_SWPMI_STATE_BUSY_TX_RX)
  1547. {
  1548. hswpmi->State = HAL_SWPMI_STATE_BUSY_RX;
  1549. }
  1550. else
  1551. {
  1552. hswpmi->State = HAL_SWPMI_STATE_READY;
  1553. }
  1554. #if (USE_HAL_SWPMI_REGISTER_CALLBACKS == 1)
  1555. hswpmi->TxCpltCallback(hswpmi);
  1556. #else
  1557. HAL_SWPMI_TxCpltCallback(hswpmi);
  1558. #endif
  1559. }
  1560. }
  1561. /* DMA Circular mode */
  1562. else
  1563. {
  1564. #if (USE_HAL_SWPMI_REGISTER_CALLBACKS == 1)
  1565. hswpmi->TxCpltCallback(hswpmi);
  1566. #else
  1567. HAL_SWPMI_TxCpltCallback(hswpmi);
  1568. #endif
  1569. }
  1570. }
  1571. /**
  1572. * @brief DMA SWPMI transmit process half complete callback.
  1573. * @param hdma DMA handle
  1574. * @retval None
  1575. */
  1576. static void SWPMI_DMATxHalfCplt(DMA_HandleTypeDef *hdma)
  1577. {
  1578. SWPMI_HandleTypeDef* hswpmi = (SWPMI_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
  1579. #if (USE_HAL_SWPMI_REGISTER_CALLBACKS == 1)
  1580. hswpmi->TxHalfCpltCallback(hswpmi);
  1581. #else
  1582. HAL_SWPMI_TxHalfCpltCallback(hswpmi);
  1583. #endif
  1584. }
  1585. /**
  1586. * @brief DMA SWPMI receive process complete callback.
  1587. * @param hdma DMA handle
  1588. * @retval None
  1589. */
  1590. static void SWPMI_DMAReceiveCplt(DMA_HandleTypeDef *hdma)
  1591. {
  1592. SWPMI_HandleTypeDef* hswpmi = ( SWPMI_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
  1593. /* DMA Normal mode*/
  1594. if(((((DMA_Stream_TypeDef *)hdma->Instance)->CR) & DMA_SxCR_CIRC) == 0U)
  1595. {
  1596. hswpmi->RxXferCount = 0U;
  1597. /* Disable the DMA transfer for the receiver request by setting the RXDMA bit
  1598. in the SWPMI CR register */
  1599. CLEAR_BIT(hswpmi->Instance->CR, SWPMI_CR_RXDMA);
  1600. /* Check if a transmit Process is ongoing or not */
  1601. if(hswpmi->State == HAL_SWPMI_STATE_BUSY_TX_RX)
  1602. {
  1603. hswpmi->State = HAL_SWPMI_STATE_BUSY_TX;
  1604. }
  1605. else
  1606. {
  1607. hswpmi->State = HAL_SWPMI_STATE_READY;
  1608. }
  1609. }
  1610. #if (USE_HAL_SWPMI_REGISTER_CALLBACKS == 1)
  1611. hswpmi->RxCpltCallback(hswpmi);
  1612. #else
  1613. HAL_SWPMI_RxCpltCallback(hswpmi);
  1614. #endif
  1615. }
  1616. /**
  1617. * @brief DMA SWPMI receive process half complete callback.
  1618. * @param hdma DMA handle
  1619. * @retval None
  1620. */
  1621. static void SWPMI_DMARxHalfCplt(DMA_HandleTypeDef *hdma)
  1622. {
  1623. SWPMI_HandleTypeDef* hswpmi = (SWPMI_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
  1624. #if (USE_HAL_SWPMI_REGISTER_CALLBACKS == 1)
  1625. hswpmi->RxHalfCpltCallback(hswpmi);
  1626. #else
  1627. HAL_SWPMI_RxHalfCpltCallback(hswpmi);
  1628. #endif
  1629. }
  1630. /**
  1631. * @brief DMA SWPMI communication error callback.
  1632. * @param hdma DMA handle
  1633. * @retval None
  1634. */
  1635. static void SWPMI_DMAError(DMA_HandleTypeDef *hdma)
  1636. {
  1637. SWPMI_HandleTypeDef* hswpmi = ( SWPMI_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
  1638. /* Update handle */
  1639. hswpmi->RxXferCount = 0U;
  1640. hswpmi->TxXferCount = 0U;
  1641. hswpmi->State= HAL_SWPMI_STATE_READY;
  1642. hswpmi->ErrorCode |= HAL_SWPMI_ERROR_DMA;
  1643. #if (USE_HAL_SWPMI_REGISTER_CALLBACKS == 1)
  1644. hswpmi->ErrorCallback(hswpmi);
  1645. #else
  1646. HAL_SWPMI_ErrorCallback(hswpmi);
  1647. #endif
  1648. }
  1649. /**
  1650. * @brief DMA SWPMI communication abort callback.
  1651. * @param hdma DMA handle
  1652. * @retval None
  1653. */
  1654. static void SWPMI_DMAAbortOnError(DMA_HandleTypeDef *hdma)
  1655. {
  1656. SWPMI_HandleTypeDef* hswpmi = ( SWPMI_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
  1657. /* Update handle */
  1658. hswpmi->RxXferCount = 0U;
  1659. hswpmi->TxXferCount = 0U;
  1660. hswpmi->State= HAL_SWPMI_STATE_READY;
  1661. #if (USE_HAL_SWPMI_REGISTER_CALLBACKS == 1)
  1662. hswpmi->ErrorCallback(hswpmi);
  1663. #else
  1664. HAL_SWPMI_ErrorCallback(hswpmi);
  1665. #endif
  1666. }
  1667. /**
  1668. * @brief Handle SWPMI Communication Timeout.
  1669. * @param hswpmi SWPMI handle
  1670. * @param Flag: specifies the SWPMI flag to check.
  1671. * @param Tickstart Tick start value
  1672. * @param Timeout timeout duration.
  1673. * @retval HAL status
  1674. */
  1675. static HAL_StatusTypeDef SWPMI_WaitOnFlagSetUntilTimeout(SWPMI_HandleTypeDef *hswpmi, uint32_t Flag, uint32_t Tickstart, uint32_t Timeout)
  1676. {
  1677. HAL_StatusTypeDef status = HAL_OK;
  1678. /* Wait until flag is set */
  1679. while(!(HAL_IS_BIT_SET(hswpmi->Instance->ISR, Flag)))
  1680. {
  1681. /* Check for the Timeout */
  1682. if ((((HAL_GetTick() - Tickstart) > Timeout) && (Timeout != HAL_MAX_DELAY)) || (Timeout == 0U))
  1683. {
  1684. /* Set the SWPMI state ready to be able to start again the process */
  1685. hswpmi->State = HAL_SWPMI_STATE_READY;
  1686. status = HAL_TIMEOUT;
  1687. break;
  1688. }
  1689. }
  1690. return status;
  1691. }
  1692. /**
  1693. * @}
  1694. */
  1695. #endif /* HAL_SWPMI_MODULE_ENABLED */
  1696. /**
  1697. * @}
  1698. */
  1699. /**
  1700. * @}
  1701. */
  1702. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/