stm32l4xx_hal_swpmi.c 59 KB

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