stm32l4xx_hal_swpmi.c 47 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548
  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. @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 channels.
  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 channels 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 channels.
  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. @endverbatim
  41. ******************************************************************************
  42. * @attention
  43. *
  44. * <h2><center>&copy; COPYRIGHT(c) 2017 STMicroelectronics</center></h2>
  45. *
  46. * Redistribution and use in source and binary forms, with or without modification,
  47. * are permitted provided that the following conditions are met:
  48. * 1. Redistributions of source code must retain the above copyright notice,
  49. * this list of conditions and the following disclaimer.
  50. * 2. Redistributions in binary form must reproduce the above copyright notice,
  51. * this list of conditions and the following disclaimer in the documentation
  52. * and/or other materials provided with the distribution.
  53. * 3. Neither the name of STMicroelectronics nor the names of its contributors
  54. * may be used to endorse or promote products derived from this software
  55. * without specific prior written permission.
  56. *
  57. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  58. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  59. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  60. * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  61. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  62. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  63. * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  64. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  65. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  66. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  67. *
  68. ******************************************************************************
  69. */
  70. /* Includes ------------------------------------------------------------------*/
  71. #include "stm32l4xx_hal.h"
  72. #if defined(STM32L431xx) || defined(STM32L432xx) || defined(STM32L433xx) || defined(STM32L442xx) || defined(STM32L443xx) || \
  73. defined(STM32L471xx) || defined(STM32L475xx) || defined(STM32L476xx) || defined(STM32L485xx) || defined(STM32L486xx) || \
  74. defined(STM32L496xx) || defined(STM32L4A6xx)
  75. /** @addtogroup STM32L4xx_HAL_Driver
  76. * @{
  77. */
  78. /** @defgroup SWPMI SWPMI
  79. * @brief HAL SWPMI module driver
  80. * @{
  81. */
  82. #ifdef HAL_SWPMI_MODULE_ENABLED
  83. /* Private typedef -----------------------------------------------------------*/
  84. /* Private define ------------------------------------------------------------*/
  85. /* Private constants ---------------------------------------------------------*/
  86. /** @addtogroup SWPMI_Private_Constants SWPMI Private Constants
  87. * @{
  88. */
  89. #define SWPMI_TIMEOUT_VALUE ((uint32_t) 22000)
  90. /**
  91. * @}
  92. */
  93. /* Private macros ------------------------------------------------------------*/
  94. /* Private variables ---------------------------------------------------------*/
  95. /* Private function prototypes -----------------------------------------------*/
  96. static void SWPMI_DMATransmitCplt(DMA_HandleTypeDef *hdma);
  97. static void SWPMI_DMATxHalfCplt(DMA_HandleTypeDef *hdma);
  98. static void SWPMI_DMAReceiveCplt(DMA_HandleTypeDef *hdma);
  99. static void SWPMI_DMARxHalfCplt(DMA_HandleTypeDef *hdma);
  100. static void SWPMI_DMAError(DMA_HandleTypeDef *hdma);
  101. static void SWPMI_DMAAbortOnError(DMA_HandleTypeDef *hdma);
  102. static HAL_StatusTypeDef SWPMI_Transmit_IT(SWPMI_HandleTypeDef *hswpmi);
  103. static HAL_StatusTypeDef SWPMI_EndTransmit_IT(SWPMI_HandleTypeDef *hswpmi);
  104. static HAL_StatusTypeDef SWPMI_Receive_IT(SWPMI_HandleTypeDef *hswpmi);
  105. static HAL_StatusTypeDef SWPMI_EndReceive_IT(SWPMI_HandleTypeDef *hswpmi);
  106. static HAL_StatusTypeDef SWPMI_EndTransmitReceive_IT(SWPMI_HandleTypeDef *hswpmi);
  107. static HAL_StatusTypeDef SWPMI_WaitOnFlagSetUntilTimeout(SWPMI_HandleTypeDef *hswpmi, uint32_t Flag, uint32_t Tickstart, uint32_t Timeout);
  108. /* Exported functions --------------------------------------------------------*/
  109. /** @defgroup SWPMI_Exported_Functions SWPMI Exported Functions
  110. * @{
  111. */
  112. /** @defgroup SWPMI_Exported_Group1 Initialization/de-initialization methods
  113. * @brief Initialization and Configuration functions
  114. *
  115. @verbatim
  116. ===============================================================================
  117. ##### Initialization and Configuration functions #####
  118. ===============================================================================
  119. [..] This section provides functions allowing to:
  120. (+) Initialize and configure the SWPMI peripheral.
  121. (+) De-initialize the SWPMI peripheral.
  122. @endverbatim
  123. * @{
  124. */
  125. /**
  126. * @brief Initialize the SWPMI peripheral according to the specified parameters in the SWPMI_InitTypeDef.
  127. * @param hswpmi: SWPMI handle
  128. * @retval HAL status
  129. */
  130. HAL_StatusTypeDef HAL_SWPMI_Init(SWPMI_HandleTypeDef *hswpmi)
  131. {
  132. HAL_StatusTypeDef status = HAL_OK;
  133. __IO uint32_t wait_loop_index = 0;
  134. /* Check the SWPMI handle allocation */
  135. if(hswpmi == NULL)
  136. {
  137. status = HAL_ERROR;
  138. }
  139. else
  140. {
  141. /* Check the parameters */
  142. assert_param(IS_SWPMI_VOLTAGE_CLASS(hswpmi->Init.VoltageClass));
  143. assert_param(IS_SWPMI_BITRATE_VALUE(hswpmi->Init.BitRate));
  144. assert_param(IS_SWPMI_TX_BUFFERING_MODE(hswpmi->Init.TxBufferingMode));
  145. assert_param(IS_SWPMI_RX_BUFFERING_MODE(hswpmi->Init.RxBufferingMode));
  146. if(hswpmi->State == HAL_SWPMI_STATE_RESET)
  147. {
  148. /* Allocate lock resource and initialize it */
  149. hswpmi->Lock = HAL_UNLOCKED;
  150. /* Init the low level hardware : GPIO, CLOCK, CORTEX */
  151. HAL_SWPMI_MspInit(hswpmi);
  152. }
  153. hswpmi->State = HAL_SWPMI_STATE_BUSY;
  154. /* Disable SWPMI interface */
  155. CLEAR_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT);
  156. /* Clear all SWPMI interface flags */
  157. WRITE_REG(hswpmi->Instance->ICR, 0x019F);
  158. /* Apply Voltage class selection */
  159. MODIFY_REG(hswpmi->Instance->OR, SWPMI_OR_CLASS, hswpmi->Init.VoltageClass);
  160. /* If Voltage class B, apply 300 µs delay */
  161. if(hswpmi->Init.VoltageClass == SWPMI_VOLTAGE_CLASS_B)
  162. {
  163. /* Insure 300 µs wait to insure SWPMI_IO output not higher than 1.8V */
  164. /* Wait loop initialization and execution */
  165. /* Note: Variable divided by 4 to compensate partially CPU processing cycles. */
  166. wait_loop_index = (300 * (SystemCoreClock / (1000000 * 4))) + 150;
  167. while(wait_loop_index != 0)
  168. {
  169. wait_loop_index--;
  170. }
  171. }
  172. /* Configure the BRR register (Bitrate) */
  173. WRITE_REG(hswpmi->Instance->BRR, hswpmi->Init.BitRate);
  174. /* Apply SWPMI CR configuration */
  175. MODIFY_REG(hswpmi->Instance->CR, \
  176. SWPMI_CR_RXDMA | SWPMI_CR_TXDMA | SWPMI_CR_RXMODE | SWPMI_CR_TXMODE, \
  177. hswpmi->Init.TxBufferingMode | hswpmi->Init.RxBufferingMode);
  178. hswpmi->ErrorCode = HAL_SWPMI_ERROR_NONE;
  179. hswpmi->State = HAL_SWPMI_STATE_READY;
  180. /* Enable SWPMI peripheral if not */
  181. SET_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT);
  182. }
  183. return status;
  184. }
  185. /**
  186. * @brief De-initialize the SWPMI peripheral.
  187. * @param hswpmi: SWPMI handle
  188. * @retval HAL status
  189. */
  190. HAL_StatusTypeDef HAL_SWPMI_DeInit(SWPMI_HandleTypeDef *hswpmi)
  191. {
  192. HAL_StatusTypeDef status = HAL_OK;
  193. /* Check the SWPMI handle allocation */
  194. if(hswpmi == NULL)
  195. {
  196. status = HAL_ERROR;
  197. }
  198. else
  199. {
  200. /* Check the parameters */
  201. assert_param(IS_SWPMI_INSTANCE(hswpmi->Instance));
  202. hswpmi->State = HAL_SWPMI_STATE_BUSY;
  203. /* Disable SWPMI interface */
  204. CLEAR_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT);
  205. /* DeInit the low level hardware */
  206. HAL_SWPMI_MspDeInit(hswpmi);
  207. hswpmi->ErrorCode = HAL_SWPMI_ERROR_NONE;
  208. hswpmi->State = HAL_SWPMI_STATE_RESET;
  209. /* Release Lock */
  210. __HAL_UNLOCK(hswpmi);
  211. }
  212. return status;
  213. }
  214. /**
  215. * @brief Initialize the SWPMI MSP.
  216. * @param hswpmi: SWPMI handle
  217. * @retval None
  218. */
  219. __weak void HAL_SWPMI_MspInit(SWPMI_HandleTypeDef *hswpmi)
  220. {
  221. /* Prevent unused argument(s) compilation warning */
  222. UNUSED(hswpmi);
  223. /* NOTE : This function should not be modified, when the callback is needed,
  224. the HAL_SWPMI_MspInit can be implemented in the user file
  225. */
  226. }
  227. /**
  228. * @brief DeInitialize the SWPMI MSP.
  229. * @param hswpmi: SWPMI handle
  230. * @retval None
  231. */
  232. __weak void HAL_SWPMI_MspDeInit(SWPMI_HandleTypeDef *hswpmi)
  233. {
  234. /* Prevent unused argument(s) compilation warning */
  235. UNUSED(hswpmi);
  236. /* NOTE : This function should not be modified, when the callback is needed,
  237. the HAL_SWPMI_MspDeInit can be implemented in the user file
  238. */
  239. }
  240. /**
  241. * @}
  242. */
  243. /** @defgroup SWPMI_Exported_Group2 IO operation methods
  244. * @brief SWPMI Transmit/Receive functions
  245. *
  246. @verbatim
  247. ===============================================================================
  248. ##### IO operation methods #####
  249. ===============================================================================
  250. [..]
  251. This subsection provides a set of functions allowing to manage the SWPMI
  252. data transfers.
  253. (#) There are two modes of transfer:
  254. (++) Blocking mode: The communication is performed in polling mode.
  255. The HAL status of all data processing is returned by the same function
  256. after finishing transfer.
  257. (++) Non-Blocking mode: The communication is performed using Interrupts
  258. or DMA. The end of the data processing will be indicated through the
  259. dedicated SWPMI Interrupt handler (HAL_SWPMI_IRQHandler()) when using Interrupt mode or
  260. the selected DMA channel interrupt handler when using DMA mode.
  261. The HAL_SWPMI_TxCpltCallback(), HAL_SWPMI_RxCpltCallback() user callbacks
  262. will be executed respectively at the end of the transmit or receive process.
  263. The HAL_SWPMI_ErrorCallback() user callback will be executed when a communication error is detected.
  264. (#) Blocking mode API's are:
  265. (++) HAL_SWPMI_Transmit()
  266. (++) HAL_SWPMI_Receive()
  267. (#) Non-Blocking mode API's with Interrupt are:
  268. (++) HAL_SWPMI_Transmit_IT()
  269. (++) HAL_SWPMI_Receive_IT()
  270. (++) HAL_SWPMI_IRQHandler()
  271. (#) Non-Blocking mode API's with DMA are:
  272. (++) HAL_SWPMI_Transmit_DMA()
  273. (++) HAL_SWPMI_Receive_DMA()
  274. (++) HAL_SWPMI_DMAPause()
  275. (++) HAL_SWPMI_DMAResume()
  276. (++) HAL_SWPMI_DMAStop()
  277. (#) A set of Transfer Complete Callbacks are provided in Non-Blocking mode:
  278. (++) HAL_SWPMI_TxHalfCpltCallback()
  279. (++) HAL_SWPMI_TxCpltCallback()
  280. (++) HAL_SWPMI_RxHalfCpltCallback()
  281. (++) HAL_SWPMI_RxCpltCallback()
  282. (++) HAL_SWPMI_ErrorCallback()
  283. (#) The capability to launch the above IO operations in loopback mode for
  284. user application verification:
  285. (++) HAL_SWPMI_EnableLoopback()
  286. (++) HAL_SWPMI_DisableLoopback()
  287. @endverbatim
  288. * @{
  289. */
  290. /**
  291. * @brief Transmit an amount of data in blocking mode.
  292. * @param hswpmi: pointer to a SWPMI_HandleTypeDef structure that contains
  293. * the configuration information for SWPMI module.
  294. * @param pData: Pointer to data buffer
  295. * @param Size: Amount of data to be sent
  296. * @param Timeout: Timeout duration
  297. * @retval HAL status
  298. */
  299. HAL_StatusTypeDef HAL_SWPMI_Transmit(SWPMI_HandleTypeDef *hswpmi, uint32_t* pData, uint16_t Size, uint32_t Timeout)
  300. {
  301. uint32_t tickstart = HAL_GetTick();
  302. HAL_StatusTypeDef status = HAL_OK;
  303. if((pData == NULL ) || (Size == 0))
  304. {
  305. status = HAL_ERROR;
  306. }
  307. else
  308. {
  309. /* Process Locked */
  310. __HAL_LOCK(hswpmi);
  311. if((hswpmi->State == HAL_SWPMI_STATE_READY) || (hswpmi->State == HAL_SWPMI_STATE_BUSY_RX))
  312. {
  313. /* Check if a non-blocking receive process is ongoing or not */
  314. if(hswpmi->State == HAL_SWPMI_STATE_READY)
  315. {
  316. hswpmi->State = HAL_SWPMI_STATE_BUSY_TX;
  317. /* Disable any transmitter interrupts */
  318. __HAL_SWPMI_DISABLE_IT(hswpmi, SWPMI_IT_TCIE | SWPMI_IT_TIE | SWPMI_IT_TXUNRIE | SWPMI_IT_TXBEIE);
  319. /* Disable any transmitter flags */
  320. __HAL_SWPMI_CLEAR_FLAG(hswpmi, SWPMI_FLAG_TXBEF | SWPMI_FLAG_TXUNRF | SWPMI_FLAG_TCF);
  321. /* Enable SWPMI peripheral if not */
  322. SET_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT);
  323. }
  324. else
  325. {
  326. hswpmi->State = HAL_SWPMI_STATE_BUSY_TX_RX;
  327. }
  328. do
  329. {
  330. /* Wait the TXE to write data */
  331. if(HAL_IS_BIT_SET(hswpmi->Instance->ISR, SWPMI_FLAG_TXE))
  332. {
  333. hswpmi->Instance->TDR = (*pData++);
  334. Size--;
  335. }
  336. else
  337. {
  338. /* Check for the Timeout */
  339. if(Timeout != HAL_MAX_DELAY)
  340. {
  341. if((Timeout == 0) || ((HAL_GetTick() - tickstart) > Timeout))
  342. {
  343. status = HAL_TIMEOUT;
  344. break;
  345. }
  346. }
  347. }
  348. } while(Size != 0);
  349. /* Wait on TXBEF flag to be able to start a second transfer */
  350. if(SWPMI_WaitOnFlagSetUntilTimeout(hswpmi, SWPMI_FLAG_TXBEF, tickstart, Timeout) != HAL_OK)
  351. {
  352. status = HAL_TIMEOUT;
  353. }
  354. if(status == HAL_OK)
  355. {
  356. /* Check if a non-blocking receive Process is ongoing or not */
  357. if(hswpmi->State == HAL_SWPMI_STATE_BUSY_TX_RX)
  358. {
  359. hswpmi->State = HAL_SWPMI_STATE_BUSY_RX;
  360. }
  361. else
  362. {
  363. hswpmi->State = HAL_SWPMI_STATE_READY;
  364. }
  365. }
  366. }
  367. else
  368. {
  369. status = HAL_BUSY;
  370. }
  371. }
  372. if((status != HAL_OK) && (status != HAL_BUSY))
  373. {
  374. hswpmi->State = HAL_SWPMI_STATE_READY;
  375. }
  376. /* Process Unlocked */
  377. __HAL_UNLOCK(hswpmi);
  378. return status;
  379. }
  380. /**
  381. * @brief Receive an amount of data in blocking mode.
  382. * @param hswpmi: pointer to a SWPMI_HandleTypeDef structure that contains
  383. * the configuration information for SWPMI module.
  384. * @param pData: Pointer to data buffer
  385. * @param Size: Amount of data to be received
  386. * @param Timeout: Timeout duration
  387. * @retval HAL status
  388. */
  389. HAL_StatusTypeDef HAL_SWPMI_Receive(SWPMI_HandleTypeDef *hswpmi, uint32_t *pData, uint16_t Size, uint32_t Timeout)
  390. {
  391. uint32_t tickstart = HAL_GetTick();
  392. HAL_StatusTypeDef status = HAL_OK;
  393. if((pData == NULL ) || (Size == 0))
  394. {
  395. status = HAL_ERROR;
  396. }
  397. else
  398. {
  399. /* Process Locked */
  400. __HAL_LOCK(hswpmi);
  401. if((hswpmi->State == HAL_SWPMI_STATE_READY) || (hswpmi->State == HAL_SWPMI_STATE_BUSY_TX))
  402. {
  403. /* Check if a non-blocking transmit process is ongoing or not */
  404. if(hswpmi->State == HAL_SWPMI_STATE_READY)
  405. {
  406. hswpmi->State = HAL_SWPMI_STATE_BUSY_RX;
  407. /* Disable any receiver interrupts */
  408. CLEAR_BIT(hswpmi->Instance->IER, SWPMI_IT_SRIE | SWPMI_IT_RIE | SWPMI_IT_RXBERIE | SWPMI_IT_RXOVRIE | SWPMI_IT_RXBFIE);
  409. /* Enable SWPMI peripheral if not */
  410. SET_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT);
  411. }
  412. else
  413. {
  414. hswpmi->State = HAL_SWPMI_STATE_BUSY_TX_RX;
  415. }
  416. do
  417. {
  418. /* Wait the RXNE to read data */
  419. if(HAL_IS_BIT_SET(hswpmi->Instance->ISR, SWPMI_FLAG_RXNE))
  420. {
  421. (*pData++) = hswpmi->Instance->RDR;
  422. Size--;
  423. }
  424. else
  425. {
  426. /* Check for the Timeout */
  427. if(Timeout != HAL_MAX_DELAY)
  428. {
  429. if((Timeout == 0) || ((HAL_GetTick() - tickstart) > Timeout))
  430. {
  431. status = HAL_TIMEOUT;
  432. break;
  433. }
  434. }
  435. }
  436. } while(Size != 0);
  437. if(status == HAL_OK)
  438. {
  439. if(HAL_IS_BIT_SET(hswpmi->Instance->ISR, SWPMI_FLAG_RXBFF))
  440. {
  441. /* Clear RXBFF at end of reception */
  442. WRITE_REG(hswpmi->Instance->ICR, SWPMI_FLAG_RXBFF);
  443. }
  444. /* Check if a non-blocking transmit Process is ongoing or not */
  445. if(hswpmi->State == HAL_SWPMI_STATE_BUSY_TX_RX)
  446. {
  447. hswpmi->State = HAL_SWPMI_STATE_BUSY_TX;
  448. }
  449. else
  450. {
  451. hswpmi->State = HAL_SWPMI_STATE_READY;
  452. }
  453. }
  454. }
  455. else
  456. {
  457. status = HAL_BUSY;
  458. }
  459. }
  460. if((status != HAL_OK) && (status != HAL_BUSY))
  461. {
  462. hswpmi->State = HAL_SWPMI_STATE_READY;
  463. }
  464. /* Process Unlocked */
  465. __HAL_UNLOCK(hswpmi);
  466. return status;
  467. }
  468. /**
  469. * @brief Transmit an amount of data in non-blocking mode with interrupt.
  470. * @param hswpmi: pointer to a SWPMI_HandleTypeDef structure that contains
  471. * the configuration information for SWPMI module.
  472. * @param pData: Pointer to data buffer
  473. * @param Size: Amount of data to be sent
  474. * @retval HAL status
  475. */
  476. HAL_StatusTypeDef HAL_SWPMI_Transmit_IT(SWPMI_HandleTypeDef *hswpmi, uint32_t *pData, uint16_t Size)
  477. {
  478. HAL_StatusTypeDef status = HAL_OK;
  479. if((pData == NULL ) || (Size == 0))
  480. {
  481. status = HAL_ERROR;
  482. }
  483. else
  484. {
  485. /* Process Locked */
  486. __HAL_LOCK(hswpmi);
  487. if((hswpmi->State == HAL_SWPMI_STATE_READY) || (hswpmi->State == HAL_SWPMI_STATE_BUSY_RX))
  488. {
  489. /* Update handle */
  490. hswpmi->pTxBuffPtr = pData;
  491. hswpmi->TxXferSize = Size;
  492. hswpmi->TxXferCount = Size;
  493. hswpmi->ErrorCode = HAL_SWPMI_ERROR_NONE;
  494. /* Check if a receive process is ongoing or not */
  495. if(hswpmi->State == HAL_SWPMI_STATE_READY)
  496. {
  497. hswpmi->State = HAL_SWPMI_STATE_BUSY_TX;
  498. /* Enable SWPMI peripheral if not */
  499. SET_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT);
  500. }
  501. else
  502. {
  503. hswpmi->State = HAL_SWPMI_STATE_BUSY_TX_RX;
  504. }
  505. /* Enable the SWPMI transmit underrun error */
  506. __HAL_SWPMI_ENABLE_IT(hswpmi, SWPMI_IT_TXUNRIE);
  507. /* Process Unlocked */
  508. __HAL_UNLOCK(hswpmi);
  509. /* Enable the SWPMI interrupts: */
  510. /* - Transmit data register empty */
  511. /* - Transmit buffer empty */
  512. /* - Transmit/Reception completion */
  513. __HAL_SWPMI_ENABLE_IT(hswpmi, SWPMI_IT_TIE | SWPMI_IT_TXBEIE | SWPMI_IT_TCIE);
  514. }
  515. else
  516. {
  517. status = HAL_BUSY;
  518. /* Process Unlocked */
  519. __HAL_UNLOCK(hswpmi);
  520. }
  521. }
  522. return status;
  523. }
  524. /**
  525. * @brief Receive an amount of data in non-blocking mode with interrupt.
  526. * @param hswpmi: SWPMI handle
  527. * @param pData: pointer to data buffer
  528. * @param Size: amount of data to be received
  529. * @retval HAL status
  530. */
  531. HAL_StatusTypeDef HAL_SWPMI_Receive_IT(SWPMI_HandleTypeDef *hswpmi, uint32_t *pData, uint16_t Size)
  532. {
  533. HAL_StatusTypeDef status = HAL_OK;
  534. if((pData == NULL ) || (Size == 0))
  535. {
  536. status = HAL_ERROR;
  537. }
  538. else
  539. {
  540. /* Process Locked */
  541. __HAL_LOCK(hswpmi);
  542. if((hswpmi->State == HAL_SWPMI_STATE_READY) || (hswpmi->State == HAL_SWPMI_STATE_BUSY_TX))
  543. {
  544. /* Update handle */
  545. hswpmi->pRxBuffPtr = pData;
  546. hswpmi->RxXferSize = Size;
  547. hswpmi->RxXferCount = Size;
  548. hswpmi->ErrorCode = HAL_SWPMI_ERROR_NONE;
  549. /* Check if a transmit process is ongoing or not */
  550. if(hswpmi->State == HAL_SWPMI_STATE_READY)
  551. {
  552. hswpmi->State = HAL_SWPMI_STATE_BUSY_RX;
  553. /* Enable SWPMI peripheral if not */
  554. SET_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT);
  555. }
  556. else
  557. {
  558. hswpmi->State = HAL_SWPMI_STATE_BUSY_TX_RX;
  559. }
  560. /* Process Unlocked */
  561. __HAL_UNLOCK(hswpmi);
  562. /* Enable the SWPMI slave resume */
  563. /* Enable the SWPMI Data Register not empty Interrupt, receive CRC Error, receive overrun and RxBuf Interrupt */
  564. /* Enable the SWPMI Transmit/Reception completion */
  565. __HAL_SWPMI_ENABLE_IT(hswpmi, SWPMI_IT_RIE | SWPMI_IT_RXBERIE | SWPMI_IT_RXOVRIE | SWPMI_IT_RXBFIE);
  566. }
  567. else
  568. {
  569. status = HAL_BUSY;
  570. /* Process Unlocked */
  571. __HAL_UNLOCK(hswpmi);
  572. }
  573. }
  574. return status;
  575. }
  576. /**
  577. * @brief Transmit an amount of data in non-blocking mode with DMA interrupt.
  578. * @param hswpmi: SWPMI handle
  579. * @param pData: pointer to data buffer
  580. * @param Size: amount of data to be sent
  581. * @retval HAL status
  582. */
  583. HAL_StatusTypeDef HAL_SWPMI_Transmit_DMA(SWPMI_HandleTypeDef *hswpmi, uint32_t *pData, uint16_t Size)
  584. {
  585. HAL_StatusTypeDef status = HAL_OK;
  586. if((pData == NULL ) || (Size == 0))
  587. {
  588. status = HAL_ERROR;
  589. }
  590. else
  591. {
  592. /* Process Locked */
  593. __HAL_LOCK(hswpmi);
  594. if((hswpmi->State == HAL_SWPMI_STATE_READY) || (hswpmi->State == HAL_SWPMI_STATE_BUSY_RX))
  595. {
  596. /* Update handle */
  597. hswpmi->pTxBuffPtr = pData;
  598. hswpmi->TxXferSize = Size;
  599. hswpmi->TxXferCount = Size;
  600. hswpmi->ErrorCode = HAL_SWPMI_ERROR_NONE;
  601. /* Check if a receive process is ongoing or not */
  602. if(hswpmi->State == HAL_SWPMI_STATE_READY)
  603. {
  604. hswpmi->State = HAL_SWPMI_STATE_BUSY_TX;
  605. /* Enable SWPMI peripheral if not */
  606. SET_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT);
  607. }
  608. else
  609. {
  610. hswpmi->State = HAL_SWPMI_STATE_BUSY_TX_RX;
  611. }
  612. /* Set the SWPMI DMA transfer complete callback */
  613. hswpmi->hdmatx->XferCpltCallback = SWPMI_DMATransmitCplt;
  614. /* Set the SWPMI DMA Half transfer complete callback */
  615. hswpmi->hdmatx->XferHalfCpltCallback = SWPMI_DMATxHalfCplt;
  616. /* Set the DMA error callback */
  617. hswpmi->hdmatx->XferErrorCallback = SWPMI_DMAError;
  618. /* Enable the SWPMI transmit DMA Channel */
  619. HAL_DMA_Start_IT(hswpmi->hdmatx, (uint32_t)hswpmi->pTxBuffPtr, (uint32_t)&hswpmi->Instance->TDR, Size);
  620. /* Process Unlocked */
  621. __HAL_UNLOCK(hswpmi);
  622. /* Enable the SWPMI transmit underrun error */
  623. __HAL_SWPMI_ENABLE_IT(hswpmi, SWPMI_IT_TXUNRIE);
  624. /* Enable the DMA transfer for transmit request by setting the TXDMA bit
  625. in the SWPMI CR register */
  626. SET_BIT(hswpmi->Instance->CR, SWPMI_CR_TXDMA);
  627. }
  628. else
  629. {
  630. status = HAL_BUSY;
  631. /* Process Unlocked */
  632. __HAL_UNLOCK(hswpmi);
  633. }
  634. }
  635. return status;
  636. }
  637. /**
  638. * @brief Receive an amount of data in non-blocking mode with DMA interrupt.
  639. * @param hswpmi: SWPMI handle
  640. * @param pData: pointer to data buffer
  641. * @param Size: amount of data to be received
  642. * @retval HAL status
  643. */
  644. HAL_StatusTypeDef HAL_SWPMI_Receive_DMA(SWPMI_HandleTypeDef *hswpmi, uint32_t *pData, uint16_t Size)
  645. {
  646. HAL_StatusTypeDef status = HAL_OK;
  647. if((pData == NULL ) || (Size == 0))
  648. {
  649. status = HAL_ERROR;
  650. }
  651. else
  652. {
  653. /* Process Locked */
  654. __HAL_LOCK(hswpmi);
  655. if((hswpmi->State == HAL_SWPMI_STATE_READY) || (hswpmi->State == HAL_SWPMI_STATE_BUSY_TX))
  656. {
  657. /* Update handle */
  658. hswpmi->pRxBuffPtr = pData;
  659. hswpmi->RxXferSize = Size;
  660. hswpmi->ErrorCode = HAL_SWPMI_ERROR_NONE;
  661. /* Check if a transmit process is ongoing or not */
  662. if(hswpmi->State == HAL_SWPMI_STATE_READY)
  663. {
  664. hswpmi->State = HAL_SWPMI_STATE_BUSY_RX;
  665. /* Enable SWPMI peripheral if not */
  666. SET_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT);
  667. }
  668. else
  669. {
  670. hswpmi->State = HAL_SWPMI_STATE_BUSY_TX_RX;
  671. }
  672. /* Set the SWPMI DMA transfer complete callback */
  673. hswpmi->hdmarx->XferCpltCallback = SWPMI_DMAReceiveCplt;
  674. /* Set the SWPMI DMA Half transfer complete callback */
  675. hswpmi->hdmarx->XferHalfCpltCallback = SWPMI_DMARxHalfCplt;
  676. /* Set the DMA error callback */
  677. hswpmi->hdmarx->XferErrorCallback = SWPMI_DMAError;
  678. /* Enable the DMA request */
  679. HAL_DMA_Start_IT(hswpmi->hdmarx, (uint32_t)&hswpmi->Instance->RDR, (uint32_t)hswpmi->pRxBuffPtr, Size);
  680. /* Process Unlocked */
  681. __HAL_UNLOCK(hswpmi);
  682. /* Enable the SWPMI receive CRC Error and receive overrun interrupts */
  683. __HAL_SWPMI_ENABLE_IT(hswpmi, SWPMI_IT_RXBERIE | SWPMI_IT_RXOVRIE);
  684. /* Enable the DMA transfer for the receiver request by setting the RXDMA bit
  685. in the SWPMI CR register */
  686. SET_BIT(hswpmi->Instance->CR, SWPMI_CR_RXDMA);
  687. }
  688. else
  689. {
  690. status = HAL_BUSY;
  691. /* Process Unlocked */
  692. __HAL_UNLOCK(hswpmi);
  693. }
  694. }
  695. return status;
  696. }
  697. /**
  698. * @brief Stop all DMA transfers.
  699. * @param hswpmi: SWPMI handle
  700. * @retval HAL_OK
  701. */
  702. HAL_StatusTypeDef HAL_SWPMI_DMAStop(SWPMI_HandleTypeDef *hswpmi)
  703. {
  704. /* Process Locked */
  705. __HAL_LOCK(hswpmi);
  706. /* Disable the SWPMI Tx/Rx DMA requests */
  707. CLEAR_BIT(hswpmi->Instance->CR, (SWPMI_CR_TXDMA | SWPMI_CR_RXDMA));
  708. /* Abort the SWPMI DMA tx channel */
  709. if(hswpmi->hdmatx != NULL)
  710. {
  711. HAL_DMA_Abort(hswpmi->hdmatx);
  712. }
  713. /* Abort the SWPMI DMA rx channel */
  714. if(hswpmi->hdmarx != NULL)
  715. {
  716. HAL_DMA_Abort(hswpmi->hdmarx);
  717. }
  718. /* Disable SWPMI interface */
  719. CLEAR_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT);
  720. hswpmi->State = HAL_SWPMI_STATE_READY;
  721. /* Process Unlocked */
  722. __HAL_UNLOCK(hswpmi);
  723. return HAL_OK;
  724. }
  725. /**
  726. * @brief Enable the Loopback mode.
  727. * @param hswpmi: SWPMI handle
  728. * @note Loopback mode is to be used only for test purposes
  729. * @retval HAL_OK / HAL_BUSY
  730. */
  731. HAL_StatusTypeDef HAL_SWPMI_EnableLoopback(SWPMI_HandleTypeDef *hswpmi)
  732. {
  733. HAL_StatusTypeDef status = HAL_OK;
  734. /* Process Locked */
  735. __HAL_LOCK(hswpmi);
  736. /* Check SWPMI not enabled */
  737. if(READ_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT) != RESET)
  738. {
  739. status = HAL_BUSY;
  740. }
  741. else
  742. {
  743. /* Set Loopback */
  744. SET_BIT(hswpmi->Instance->CR, SWPMI_CR_LPBK);
  745. }
  746. /* Process Unlocked */
  747. __HAL_UNLOCK(hswpmi);
  748. return status;
  749. }
  750. /**
  751. * @brief Disable the Loopback mode.
  752. * @param hswpmi: SWPMI handle
  753. * @note Loopback mode is to be used only for test purposes
  754. * @retval HAL_OK / HAL_BUSY
  755. */
  756. HAL_StatusTypeDef HAL_SWPMI_DisableLoopback(SWPMI_HandleTypeDef *hswpmi)
  757. {
  758. HAL_StatusTypeDef status = HAL_OK;
  759. /* Process Locked */
  760. __HAL_LOCK(hswpmi);
  761. /* Check SWPMI not enabled */
  762. if(READ_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT) != RESET)
  763. {
  764. status = HAL_BUSY;
  765. }
  766. else
  767. {
  768. /* Reset Loopback */
  769. CLEAR_BIT(hswpmi->Instance->CR, SWPMI_CR_LPBK);
  770. }
  771. /* Process Unlocked */
  772. __HAL_UNLOCK(hswpmi);
  773. return status;
  774. }
  775. /**
  776. * @}
  777. */
  778. /** @defgroup SWPMI_Exported_Group3 SWPMI IRQ handler and callbacks
  779. * @brief SWPMI IRQ handler.
  780. *
  781. @verbatim
  782. ==============================================================================
  783. ##### SWPMI IRQ handler and callbacks #####
  784. ==============================================================================
  785. [..] This section provides SWPMI IRQ handler and callback functions called within
  786. the IRQ handler.
  787. @endverbatim
  788. * @{
  789. */
  790. /**
  791. * @brief Handle SWPMI interrupt request.
  792. * @param hswpmi: SWPMI handle
  793. * @retval None
  794. */
  795. void HAL_SWPMI_IRQHandler(SWPMI_HandleTypeDef *hswpmi)
  796. {
  797. uint32_t regisr = READ_REG(hswpmi->Instance->ISR);
  798. uint32_t regier = READ_REG(hswpmi->Instance->IER);
  799. uint32_t errcode = HAL_SWPMI_ERROR_NONE;
  800. /* SWPMI CRC error interrupt occurred --------------------------------------*/
  801. if(((regisr & SWPMI_FLAG_RXBERF) != RESET) && ((regier & SWPMI_IT_RXBERIE) != RESET))
  802. {
  803. /* Disable Receive CRC interrupt */
  804. CLEAR_BIT(hswpmi->Instance->IER, SWPMI_IT_RXBERIE | SWPMI_IT_RXBFIE);
  805. /* Clear Receive CRC and Receive buffer full flag */
  806. WRITE_REG(hswpmi->Instance->ICR, SWPMI_FLAG_RXBERF | SWPMI_FLAG_RXBFF);
  807. errcode |= HAL_SWPMI_ERROR_CRC;
  808. }
  809. /* SWPMI Over-Run interrupt occurred -----------------------------------------*/
  810. if(((regisr & SWPMI_FLAG_RXOVRF) != RESET) && ((regier & SWPMI_IT_RXOVRIE) != RESET))
  811. {
  812. /* Disable Receive overrun interrupt */
  813. CLEAR_BIT(hswpmi->Instance->IER, SWPMI_IT_RXOVRIE);
  814. /* Clear Receive overrun flag */
  815. WRITE_REG(hswpmi->Instance->ICR, SWPMI_FLAG_RXOVRF);
  816. errcode |= HAL_SWPMI_ERROR_OVR;
  817. }
  818. /* SWPMI Under-Run interrupt occurred -----------------------------------------*/
  819. if(((regisr & SWPMI_FLAG_TXUNRF) != RESET) && ((regier & SWPMI_IT_TXUNRIE) != RESET))
  820. {
  821. /* Disable Transmit under run interrupt */
  822. CLEAR_BIT(hswpmi->Instance->IER, SWPMI_IT_TXUNRIE);
  823. /* Clear Transmit under run flag */
  824. WRITE_REG(hswpmi->Instance->ICR, SWPMI_FLAG_TXUNRF);
  825. errcode |= HAL_SWPMI_ERROR_UDR;
  826. }
  827. /* Call SWPMI Error Call back function if needed --------------------------*/
  828. if(errcode != HAL_SWPMI_ERROR_NONE)
  829. {
  830. hswpmi->ErrorCode |= errcode;
  831. if((errcode & HAL_SWPMI_ERROR_UDR) != RESET)
  832. {
  833. /* Check TXDMA transfer to abort */
  834. if(HAL_IS_BIT_SET(hswpmi->Instance->CR, SWPMI_CR_TXDMA))
  835. {
  836. /* Disable DMA TX at SWPMI level */
  837. CLEAR_BIT(hswpmi->Instance->CR, SWPMI_CR_TXDMA);
  838. /* Abort the USART DMA Tx channel */
  839. if(hswpmi->hdmatx != NULL)
  840. {
  841. /* Set the SWPMI Tx DMA Abort callback :
  842. will lead to call HAL_SWPMI_ErrorCallback() at end of DMA abort procedure */
  843. hswpmi->hdmatx->XferAbortCallback = SWPMI_DMAAbortOnError;
  844. /* Abort DMA TX */
  845. if(HAL_DMA_Abort_IT(hswpmi->hdmatx) != HAL_OK)
  846. {
  847. /* Call Directly hswpmi->hdmatx->XferAbortCallback function in case of error */
  848. hswpmi->hdmatx->XferAbortCallback(hswpmi->hdmatx);
  849. }
  850. }
  851. else
  852. {
  853. /* Set the SWPMI state ready to be able to start again the process */
  854. hswpmi->State = HAL_SWPMI_STATE_READY;
  855. HAL_SWPMI_ErrorCallback(hswpmi);
  856. }
  857. }
  858. else
  859. {
  860. /* Set the SWPMI state ready to be able to start again the process */
  861. hswpmi->State = HAL_SWPMI_STATE_READY;
  862. HAL_SWPMI_ErrorCallback(hswpmi);
  863. }
  864. }
  865. else
  866. {
  867. /* Check RXDMA transfer to abort */
  868. if(HAL_IS_BIT_SET(hswpmi->Instance->CR, SWPMI_CR_RXDMA))
  869. {
  870. /* Disable DMA RX at SWPMI level */
  871. CLEAR_BIT(hswpmi->Instance->CR, SWPMI_CR_RXDMA);
  872. /* Abort the USART DMA Rx channel */
  873. if(hswpmi->hdmarx != NULL)
  874. {
  875. /* Set the SWPMI Rx DMA Abort callback :
  876. will lead to call HAL_SWPMI_ErrorCallback() at end of DMA abort procedure */
  877. hswpmi->hdmarx->XferAbortCallback = SWPMI_DMAAbortOnError;
  878. /* Abort DMA RX */
  879. if(HAL_DMA_Abort_IT(hswpmi->hdmarx) != HAL_OK)
  880. {
  881. /* Call Directly hswpmi->hdmarx->XferAbortCallback function in case of error */
  882. hswpmi->hdmarx->XferAbortCallback(hswpmi->hdmarx);
  883. }
  884. }
  885. else
  886. {
  887. /* Set the SWPMI state ready to be able to start again the process */
  888. hswpmi->State = HAL_SWPMI_STATE_READY;
  889. HAL_SWPMI_ErrorCallback(hswpmi);
  890. }
  891. }
  892. else
  893. {
  894. /* Set the SWPMI state ready to be able to start again the process */
  895. hswpmi->State = HAL_SWPMI_STATE_READY;
  896. HAL_SWPMI_ErrorCallback(hswpmi);
  897. }
  898. }
  899. }
  900. /* SWPMI in mode Receiver ---------------------------------------------------*/
  901. if(((regisr & SWPMI_FLAG_RXNE) != RESET) && ((regier & SWPMI_IT_RIE) != RESET))
  902. {
  903. SWPMI_Receive_IT(hswpmi);
  904. }
  905. /* SWPMI in mode Transmitter ------------------------------------------------*/
  906. if(((regisr & SWPMI_FLAG_TXE) != RESET) && ((regier & SWPMI_IT_TIE) != RESET))
  907. {
  908. SWPMI_Transmit_IT(hswpmi);
  909. }
  910. /* SWPMI in mode Transmitter (Transmit buffer empty) ------------------------*/
  911. if(((regisr & SWPMI_FLAG_TXBEF) != RESET) && ((regier & SWPMI_IT_TXBEIE) != RESET))
  912. {
  913. SWPMI_EndTransmit_IT(hswpmi);
  914. }
  915. /* SWPMI in mode Receiver (Receive buffer full) -----------------------------*/
  916. if(((regisr & SWPMI_FLAG_RXBFF) != RESET) && ((regier & SWPMI_IT_RXBFIE) != RESET))
  917. {
  918. SWPMI_EndReceive_IT(hswpmi);
  919. }
  920. /* Both Transmission and reception complete ---------------------------------*/
  921. if(((regisr & SWPMI_FLAG_TCF) != RESET) && ((regier & SWPMI_IT_TCIE) != RESET))
  922. {
  923. SWPMI_EndTransmitReceive_IT(hswpmi);
  924. }
  925. }
  926. /**
  927. * @brief Tx Transfer completed callback.
  928. * @param hswpmi: SWPMI handle
  929. * @retval None
  930. */
  931. __weak void HAL_SWPMI_TxCpltCallback(SWPMI_HandleTypeDef *hswpmi)
  932. {
  933. /* Prevent unused argument(s) compilation warning */
  934. UNUSED(hswpmi);
  935. /* NOTE : This function should not be modified, when the callback is needed,
  936. the HAL_SWPMI_TxCpltCallback is to be implemented in the user file
  937. */
  938. }
  939. /**
  940. * @brief Tx Half Transfer completed callback.
  941. * @param hswpmi: SWPMI handle
  942. * @retval None
  943. */
  944. __weak void HAL_SWPMI_TxHalfCpltCallback(SWPMI_HandleTypeDef *hswpmi)
  945. {
  946. /* Prevent unused argument(s) compilation warning */
  947. UNUSED(hswpmi);
  948. /* NOTE: This function should not be modified, when the callback is needed,
  949. the HAL_SWPMI_TxHalfCpltCallback is to be implemented in the user file
  950. */
  951. }
  952. /**
  953. * @brief Rx Transfer completed callback.
  954. * @param hswpmi: SWPMI handle
  955. * @retval None
  956. */
  957. __weak void HAL_SWPMI_RxCpltCallback(SWPMI_HandleTypeDef *hswpmi)
  958. {
  959. /* Prevent unused argument(s) compilation warning */
  960. UNUSED(hswpmi);
  961. /* NOTE : This function should not be modified, when the callback is needed,
  962. the HAL_SWPMI_RxCpltCallback is to be implemented in the user file
  963. */
  964. }
  965. /**
  966. * @brief Rx Half Transfer completed callback.
  967. * @param hswpmi: SWPMI handle
  968. * @retval None
  969. */
  970. __weak void HAL_SWPMI_RxHalfCpltCallback(SWPMI_HandleTypeDef *hswpmi)
  971. {
  972. /* Prevent unused argument(s) compilation warning */
  973. UNUSED(hswpmi);
  974. /* NOTE: This function should not be modified, when the callback is needed,
  975. the HAL_SWPMI_RxHalfCpltCallback is to be implemented in the user file
  976. */
  977. }
  978. /**
  979. * @brief SWPMI error callback.
  980. * @param hswpmi: SWPMI handle
  981. * @retval None
  982. */
  983. __weak void HAL_SWPMI_ErrorCallback(SWPMI_HandleTypeDef *hswpmi)
  984. {
  985. /* Prevent unused argument(s) compilation warning */
  986. UNUSED(hswpmi);
  987. /* NOTE : This function should not be modified, when the callback is needed,
  988. the HAL_SWPMI_ErrorCallback is to be implemented in the user file
  989. */
  990. }
  991. /**
  992. * @}
  993. */
  994. /** @defgroup SWPMI_Exported_Group4 Peripheral Control methods
  995. * @brief SWPMI control functions
  996. *
  997. @verbatim
  998. ===============================================================================
  999. ##### Peripheral Control methods #####
  1000. ===============================================================================
  1001. [..]
  1002. This subsection provides a set of functions allowing to control the SWPMI.
  1003. (+) HAL_SWPMI_GetState() API is helpful to check in run-time the state of the SWPMI peripheral
  1004. (+) HAL_SWPMI_GetError() API is helpful to check in run-time the error state of the SWPMI peripheral
  1005. @endverbatim
  1006. * @{
  1007. */
  1008. /**
  1009. * @brief Return the SWPMI handle state.
  1010. * @param hswpmi: SWPMI handle
  1011. * @retval HAL state
  1012. */
  1013. HAL_SWPMI_StateTypeDef HAL_SWPMI_GetState(SWPMI_HandleTypeDef *hswpmi)
  1014. {
  1015. /* Return SWPMI handle state */
  1016. return hswpmi->State;
  1017. }
  1018. /**
  1019. * @brief Return the SWPMI error code.
  1020. * @param hswpmi : pointer to a SWPMI_HandleTypeDef structure that contains
  1021. * the configuration information for the specified SWPMI.
  1022. * @retval SWPMI Error Code
  1023. */
  1024. uint32_t HAL_SWPMI_GetError(SWPMI_HandleTypeDef *hswpmi)
  1025. {
  1026. return hswpmi->ErrorCode;
  1027. }
  1028. /**
  1029. * @}
  1030. */
  1031. /**
  1032. * @}
  1033. */
  1034. /* Private functions ---------------------------------------------------------*/
  1035. /** @defgroup SWPMI_Private_Functions SWPMI Private Functions
  1036. * @{
  1037. */
  1038. /**
  1039. * @brief Transmit an amount of data in interrupt mode.
  1040. * @note Function called under interruption only, once interruptions have been enabled by HAL_SWPMI_Transmit_IT()
  1041. * @param hswpmi: SWPMI handle
  1042. * @retval HAL status
  1043. */
  1044. static HAL_StatusTypeDef SWPMI_Transmit_IT(SWPMI_HandleTypeDef *hswpmi)
  1045. {
  1046. HAL_StatusTypeDef status = HAL_OK;
  1047. if ((hswpmi->State == HAL_SWPMI_STATE_BUSY_TX) || (hswpmi->State == HAL_SWPMI_STATE_BUSY_TX_RX))
  1048. {
  1049. if(hswpmi->TxXferCount == 0)
  1050. {
  1051. /* Disable the SWPMI TXE and Underrun Interrupts */
  1052. CLEAR_BIT(hswpmi->Instance->IER, (SWPMI_IT_TIE | SWPMI_IT_TXUNRIE));
  1053. }
  1054. else
  1055. {
  1056. hswpmi->Instance->TDR = (uint32_t)(*hswpmi->pTxBuffPtr++);
  1057. hswpmi->TxXferCount--;
  1058. }
  1059. }
  1060. else
  1061. {
  1062. status = HAL_BUSY;
  1063. }
  1064. return status;
  1065. }
  1066. /**
  1067. * @brief Wraps up transmission in non-blocking mode.
  1068. * @param hswpmi: SWPMI handle
  1069. * @retval HAL status
  1070. * @retval HAL status
  1071. */
  1072. static HAL_StatusTypeDef SWPMI_EndTransmit_IT(SWPMI_HandleTypeDef *hswpmi)
  1073. {
  1074. /* Clear the SWPMI Transmit buffer empty Flag */
  1075. WRITE_REG(hswpmi->Instance->ICR, SWPMI_FLAG_TXBEF);
  1076. /* Disable the all SWPMI Transmit Interrupts */
  1077. CLEAR_BIT(hswpmi->Instance->IER, SWPMI_IT_TIE | SWPMI_IT_TXUNRIE | SWPMI_IT_TXBEIE);
  1078. /* Check if a receive Process is ongoing or not */
  1079. if(hswpmi->State == HAL_SWPMI_STATE_BUSY_TX_RX)
  1080. {
  1081. hswpmi->State = HAL_SWPMI_STATE_BUSY_RX;
  1082. }
  1083. else
  1084. {
  1085. hswpmi->State = HAL_SWPMI_STATE_READY;
  1086. }
  1087. HAL_SWPMI_TxCpltCallback(hswpmi);
  1088. return HAL_OK;
  1089. }
  1090. /**
  1091. * @brief Receive an amount of data in interrupt mode.
  1092. * @note Function called under interruption only, once interruptions have been enabled by HAL_SWPMI_Receive_IT()
  1093. * @param hswpmi: SWPMI handle
  1094. * @retval HAL status
  1095. */
  1096. static HAL_StatusTypeDef SWPMI_Receive_IT(SWPMI_HandleTypeDef *hswpmi)
  1097. {
  1098. HAL_StatusTypeDef status = HAL_OK;
  1099. if((hswpmi->State == HAL_SWPMI_STATE_BUSY_RX) || (hswpmi->State == HAL_SWPMI_STATE_BUSY_TX_RX))
  1100. {
  1101. *hswpmi->pRxBuffPtr++ = (uint32_t)(hswpmi->Instance->RDR);
  1102. if(--hswpmi->RxXferCount == 0)
  1103. {
  1104. /* Wait for RXBFF flag to update state */
  1105. HAL_SWPMI_RxCpltCallback(hswpmi);
  1106. }
  1107. }
  1108. else
  1109. {
  1110. status = HAL_BUSY;
  1111. }
  1112. return status;
  1113. }
  1114. /**
  1115. * @brief Wraps up reception in non-blocking mode.
  1116. * @param hswpmi: SWPMI handle
  1117. * @retval HAL status
  1118. * @retval HAL status
  1119. */
  1120. static HAL_StatusTypeDef SWPMI_EndReceive_IT(SWPMI_HandleTypeDef *hswpmi)
  1121. {
  1122. /* Clear the SWPMI Receive buffer full Flag */
  1123. WRITE_REG(hswpmi->Instance->ICR, SWPMI_FLAG_RXBFF);
  1124. /* Disable the all SWPMI Receive Interrupts */
  1125. CLEAR_BIT(hswpmi->Instance->IER, SWPMI_IT_RIE | SWPMI_IT_RXBERIE | SWPMI_IT_RXOVRIE | SWPMI_IT_RXBFIE);
  1126. /* Check if a transmit Process is ongoing or not */
  1127. if(hswpmi->State == HAL_SWPMI_STATE_BUSY_TX_RX)
  1128. {
  1129. hswpmi->State = HAL_SWPMI_STATE_BUSY_TX;
  1130. }
  1131. else
  1132. {
  1133. hswpmi->State = HAL_SWPMI_STATE_READY;
  1134. }
  1135. return HAL_OK;
  1136. }
  1137. /**
  1138. * @brief Wraps up transmission and reception in non-blocking mode.
  1139. * @param hswpmi: SWPMI handle
  1140. * @retval HAL status
  1141. * @retval HAL status
  1142. */
  1143. static HAL_StatusTypeDef SWPMI_EndTransmitReceive_IT(SWPMI_HandleTypeDef *hswpmi)
  1144. {
  1145. /* Clear the SWPMI Transmission Complete Flag */
  1146. WRITE_REG(hswpmi->Instance->ICR, SWPMI_FLAG_TCF);
  1147. /* Disable the SWPMI Transmission Complete Interrupt */
  1148. CLEAR_BIT(hswpmi->Instance->IER, SWPMI_IT_TCIE);
  1149. /* Check if a receive Process is ongoing or not */
  1150. if(hswpmi->State == HAL_SWPMI_STATE_BUSY_TX_RX)
  1151. {
  1152. hswpmi->State = HAL_SWPMI_STATE_BUSY_RX;
  1153. }
  1154. else if(hswpmi->State == HAL_SWPMI_STATE_BUSY_TX)
  1155. {
  1156. hswpmi->State = HAL_SWPMI_STATE_READY;
  1157. }
  1158. return HAL_OK;
  1159. }
  1160. /**
  1161. * @brief DMA SWPMI transmit process complete callback.
  1162. * @param hdma: DMA handle
  1163. * @retval None
  1164. */
  1165. static void SWPMI_DMATransmitCplt(DMA_HandleTypeDef *hdma)
  1166. {
  1167. SWPMI_HandleTypeDef* hswpmi = ( SWPMI_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
  1168. uint32_t tickstart = 0;
  1169. /* DMA Normal mode*/
  1170. if((hdma->Instance->CCR & DMA_CCR_CIRC) != SET)
  1171. {
  1172. hswpmi->TxXferCount = 0;
  1173. /* Disable the DMA transfer for transmit request by setting the TXDMA bit
  1174. in the SWPMI CR register */
  1175. CLEAR_BIT(hswpmi->Instance->CR, SWPMI_CR_TXDMA);
  1176. /* Init tickstart for timeout managment*/
  1177. tickstart = HAL_GetTick();
  1178. /* Wait the TXBEF */
  1179. if(SWPMI_WaitOnFlagSetUntilTimeout(hswpmi, SWPMI_FLAG_TXBEF, tickstart, SWPMI_TIMEOUT_VALUE) != HAL_OK)
  1180. {
  1181. /* Timeout occurred */
  1182. HAL_SWPMI_ErrorCallback(hswpmi);
  1183. }
  1184. else
  1185. {
  1186. /* No Timeout */
  1187. /* Check if a receive process is ongoing or not */
  1188. if(hswpmi->State == HAL_SWPMI_STATE_BUSY_TX_RX)
  1189. {
  1190. hswpmi->State = HAL_SWPMI_STATE_BUSY_RX;
  1191. }
  1192. else
  1193. {
  1194. hswpmi->State = HAL_SWPMI_STATE_READY;
  1195. }
  1196. HAL_SWPMI_TxCpltCallback(hswpmi);
  1197. }
  1198. }
  1199. /* DMA Circular mode */
  1200. else
  1201. {
  1202. HAL_SWPMI_TxCpltCallback(hswpmi);
  1203. }
  1204. }
  1205. /**
  1206. * @brief DMA SWPMI transmit process half complete callback.
  1207. * @param hdma : DMA handle
  1208. * @retval None
  1209. */
  1210. static void SWPMI_DMATxHalfCplt(DMA_HandleTypeDef *hdma)
  1211. {
  1212. SWPMI_HandleTypeDef* hswpmi = (SWPMI_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
  1213. HAL_SWPMI_TxHalfCpltCallback(hswpmi);
  1214. }
  1215. /**
  1216. * @brief DMA SWPMI receive process complete callback.
  1217. * @param hdma: DMA handle
  1218. * @retval None
  1219. */
  1220. static void SWPMI_DMAReceiveCplt(DMA_HandleTypeDef *hdma)
  1221. {
  1222. SWPMI_HandleTypeDef* hswpmi = ( SWPMI_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
  1223. /* DMA Normal mode*/
  1224. if((hdma->Instance->CCR & DMA_CCR_CIRC) == RESET)
  1225. {
  1226. hswpmi->RxXferCount = 0;
  1227. /* Disable the DMA transfer for the receiver request by setting the RXDMA bit
  1228. in the SWPMI CR register */
  1229. CLEAR_BIT(hswpmi->Instance->CR, SWPMI_CR_RXDMA);
  1230. /* Check if a transmit Process is ongoing or not */
  1231. if(hswpmi->State == HAL_SWPMI_STATE_BUSY_TX_RX)
  1232. {
  1233. hswpmi->State = HAL_SWPMI_STATE_BUSY_TX;
  1234. }
  1235. else
  1236. {
  1237. hswpmi->State = HAL_SWPMI_STATE_READY;
  1238. }
  1239. }
  1240. HAL_SWPMI_RxCpltCallback(hswpmi);
  1241. }
  1242. /**
  1243. * @brief DMA SWPMI receive process half complete callback.
  1244. * @param hdma : DMA handle
  1245. * @retval None
  1246. */
  1247. static void SWPMI_DMARxHalfCplt(DMA_HandleTypeDef *hdma)
  1248. {
  1249. SWPMI_HandleTypeDef* hswpmi = (SWPMI_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
  1250. HAL_SWPMI_RxHalfCpltCallback(hswpmi);
  1251. }
  1252. /**
  1253. * @brief DMA SWPMI communication error callback.
  1254. * @param hdma: DMA handle
  1255. * @retval None
  1256. */
  1257. static void SWPMI_DMAError(DMA_HandleTypeDef *hdma)
  1258. {
  1259. SWPMI_HandleTypeDef* hswpmi = ( SWPMI_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
  1260. /* Update handle */
  1261. hswpmi->RxXferCount = 0;
  1262. hswpmi->TxXferCount = 0;
  1263. hswpmi->State= HAL_SWPMI_STATE_READY;
  1264. hswpmi->ErrorCode |= HAL_SWPMI_ERROR_DMA;
  1265. HAL_SWPMI_ErrorCallback(hswpmi);
  1266. }
  1267. /**
  1268. * @brief DMA SWPMI communication abort callback.
  1269. * @param hdma: DMA handle
  1270. * @retval None
  1271. */
  1272. static void SWPMI_DMAAbortOnError(DMA_HandleTypeDef *hdma)
  1273. {
  1274. SWPMI_HandleTypeDef* hswpmi = ( SWPMI_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
  1275. /* Update handle */
  1276. hswpmi->RxXferCount = 0;
  1277. hswpmi->TxXferCount = 0;
  1278. hswpmi->State= HAL_SWPMI_STATE_READY;
  1279. HAL_SWPMI_ErrorCallback(hswpmi);
  1280. }
  1281. /**
  1282. * @brief Handle SWPMI Communication Timeout.
  1283. * @param hswpmi: SWPMI handle
  1284. * @param Flag: specifies the SWPMI flag to check.
  1285. * @param Tickstart Tick start value
  1286. * @param Timeout timeout duration.
  1287. * @retval HAL status
  1288. */
  1289. static HAL_StatusTypeDef SWPMI_WaitOnFlagSetUntilTimeout(SWPMI_HandleTypeDef *hswpmi, uint32_t Flag, uint32_t Tickstart, uint32_t Timeout)
  1290. {
  1291. HAL_StatusTypeDef status = HAL_OK;
  1292. /* Wait until flag is set */
  1293. while(!(HAL_IS_BIT_SET(hswpmi->Instance->ISR, Flag)))
  1294. {
  1295. /* Check for the Timeout */
  1296. if(Timeout != HAL_MAX_DELAY)
  1297. {
  1298. if((Timeout == 0) || ((HAL_GetTick()-Tickstart) > Timeout))
  1299. {
  1300. hswpmi->State = HAL_SWPMI_STATE_READY;
  1301. status = HAL_TIMEOUT;
  1302. break;
  1303. }
  1304. }
  1305. }
  1306. return status;
  1307. }
  1308. /**
  1309. * @}
  1310. */
  1311. #endif /* HAL_SWPMI_MODULE_ENABLED */
  1312. /**
  1313. * @}
  1314. */
  1315. /**
  1316. * @}
  1317. */
  1318. #endif /* STM32L431xx || STM32L432xx || STM32L433xx || STM32L442xx || STM32L443xx || */
  1319. /* STM32L471xx || STM32L475xx || STM32L476xx || STM32L485xx || STM32L486xx || */
  1320. /* STM32L496xx || STM32L4A6xx */
  1321. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/