stm32l4xx_hal_swpmi.c 45 KB

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