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

1267 lines
40 KiB

  1. /**
  2. ******************************************************************************
  3. * @file stm32h7xx_hal_spdifrx.c
  4. * @author MCD Application Team
  5. * @version V1.2.0
  6. * @date 29-December-2017
  7. * @brief This file provides firmware functions to manage the following
  8. * functionalities of the SPDIFRX audio interface:
  9. * + Initialization and Configuration
  10. * + Data transfers functions
  11. * + DMA transfers management
  12. * + Interrupts and flags management
  13. @verbatim
  14. ===============================================================================
  15. ##### How to use this driver #####
  16. ===============================================================================
  17. [..]
  18. The SPDIFRX HAL driver can be used as follow:
  19. (#) Declare SPDIFRX_HandleTypeDef handle structure.
  20. (#) Initialize the SPDIFRX low level resources by implement the HAL_SPDIFRX_MspInit() API:
  21. (##) Enable the SPDIFRX interface clock.
  22. (##) SPDIFRX pins configuration:
  23. (+++) Enable the clock for the SPDIFRX GPIOs.
  24. (+++) Configure these SPDIFRX pins as alternate function pull-up.
  25. (##) NVIC configuration if you need to use interrupt process (HAL_SPDIFRX_ReceiveControlFlow_IT() and HAL_SPDIFRX_ReceiveDataFlow_IT() API's).
  26. (+++) Configure the SPDIFRX interrupt priority.
  27. (+++) Enable the NVIC SPDIFRX IRQ handle.
  28. (##) DMA Configuration if you need to use DMA process (HAL_SPDIFRX_ReceiveDataFlow_DMA() and HAL_SPDIFRX_ReceiveControlFlow_DMA() API's).
  29. (+++) Declare a DMA handle structure for the reception of the Data Flow channel.
  30. (+++) Declare a DMA handle structure for the reception of the Control Flow channel.
  31. (+++) Enable the DMAx interface clock.
  32. (+++) Configure the declared DMA handle structure CtrlRx/DataRx with the required parameters.
  33. (+++) Configure the DMA Channel.
  34. (+++) Associate the initialized DMA handle to the SPDIFRX DMA CtrlRx/DataRx handle.
  35. (+++) Configure the priority and enable the NVIC for the transfer complete interrupt on the
  36. DMA CtrlRx/DataRx channel.
  37. (#) Program the input selection, re-tries number, wait for activity, channel status selection, data format, stereo mode and masking of user bits
  38. using HAL_SPDIFRX_Init() function.
  39. -@- The specific SPDIFRX interrupts (RXNE/CSRNE and Error Interrupts) will be managed using the macros
  40. __SPDIFRX_ENABLE_IT() and __SPDIFRX_DISABLE_IT() inside the receive process.
  41. -@- Make sure that ck_spdif clock is configured.
  42. (#) Three operation modes are available within this driver :
  43. *** Polling mode for reception operation (for debug purpose) ***
  44. ================================================================
  45. [..]
  46. (+) Receive data flow in blocking mode using HAL_SPDIFRX_ReceiveDataFlow()
  47. (+) Receive control flow of data in blocking mode using HAL_SPDIFRX_ReceiveControlFlow()
  48. *** Interrupt mode for reception operation ***
  49. =========================================
  50. [..]
  51. (+) Receive an amount of data (Data Flow) in non blocking mode using HAL_SPDIFRX_ReceiveDataFlow_IT()
  52. (+) Receive an amount of data (Control Flow) in non blocking mode using HAL_SPDIFRX_ReceiveControlFlow_IT()
  53. (+) At reception end of half transfer HAL_SPDIFRX_RxHalfCpltCallback is executed and user can
  54. add his own code by customization of function pointer HAL_SPDIFRX_RxHalfCpltCallback
  55. (+) At reception end of transfer HAL_SPDIFRX_RxCpltCallback is executed and user can
  56. add his own code by customization of function pointer HAL_SPDIFRX_RxCpltCallback
  57. (+) In case of transfer Error, HAL_SPDIFRX_ErrorCallback() function is executed and user can
  58. add his own code by customization of function pointer HAL_SPDIFRX_ErrorCallback
  59. *** DMA mode for reception operation ***
  60. ========================================
  61. [..]
  62. (+) Receive an amount of data (Data Flow) in non blocking mode (DMA) using HAL_SPDIFRX_ReceiveDataFlow_DMA()
  63. (+) Receive an amount of data (Control Flow) in non blocking mode (DMA) using HAL_SPDIFRX_ReceiveControlFlow_DMA()
  64. (+) At reception end of half transfer HAL_SPDIFRX_RxHalfCpltCallback is executed and user can
  65. add his own code by customization of function pointer HAL_SPDIFRX_RxHalfCpltCallback
  66. (+) At reception end of transfer HAL_SPDIFRX_RxCpltCallback is executed and user can
  67. add his own code by customization of function pointer HAL_SPDIFRX_RxCpltCallback
  68. (+) In case of transfer Error, HAL_SPDIFRX_ErrorCallback() function is executed and user can
  69. add his own code by customization of function pointer HAL_SPDIFRX_ErrorCallback
  70. (+) Stop the DMA Transfer using HAL_SPDIFRX_DMAStop()
  71. *** SPDIFRX HAL driver macros list ***
  72. =============================================
  73. [..]
  74. Below the list of most used macros in USART HAL driver.
  75. (+) __HAL_SPDIFRX_IDLE: Disable the specified SPDIFRX peripheral (IDEL State)
  76. (+) __HAL_SPDIFRX_SYNC: Enable the synchronization state of the specified SPDIFRX peripheral (SYNC State)
  77. (+) __HAL_SPDIFRX_RCV: Enable the receive state of the specified SPDIFRX peripheral (RCV State)
  78. (+) __HAL_SPDIFRX_ENABLE_IT : Enable the specified SPDIFRX interrupts
  79. (+) __HAL_SPDIFRX_DISABLE_IT : Disable the specified SPDIFRX interrupts
  80. (+) __HAL_SPDIFRX_GET_FLAG: Check whether the specified SPDIFRX flag is set or not.
  81. [..]
  82. (@) You can refer to the SPDIFRX HAL driver header file for more useful macros
  83. @endverbatim
  84. ******************************************************************************
  85. * @attention
  86. *
  87. * <h2><center>&copy; COPYRIGHT(c) 2017 STMicroelectronics</center></h2>
  88. *
  89. * Redistribution and use in source and binary forms, with or without modification,
  90. * are permitted provided that the following conditions are met:
  91. * 1. Redistributions of source code must retain the above copyright notice,
  92. * this list of conditions and the following disclaimer.
  93. * 2. Redistributions in binary form must reproduce the above copyright notice,
  94. * this list of conditions and the following disclaimer in the documentation
  95. * and/or other materials provided with the distribution.
  96. * 3. Neither the name of STMicroelectronics nor the names of its contributors
  97. * may be used to endorse or promote products derived from this software
  98. * without specific prior written permission.
  99. *
  100. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  101. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  102. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  103. * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  104. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  105. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  106. * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  107. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  108. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  109. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  110. *
  111. ******************************************************************************
  112. */
  113. /* Includes ------------------------------------------------------------------*/
  114. #include "stm32h7xx_hal.h"
  115. /** @addtogroup STM32H7xx_HAL_Driver
  116. * @{
  117. */
  118. #if defined (SPDIFRX)
  119. /** @defgroup SPDIFRX SPDIFRX
  120. * @brief SPDIFRX HAL module driver
  121. * @{
  122. */
  123. #ifdef HAL_SPDIFRX_MODULE_ENABLED
  124. /* Private typedef -----------------------------------------------------------*/
  125. /* Private define ------------------------------------------------------------*/
  126. #define SPDIFRX_TIMEOUT_VALUE 0xFFFFU
  127. /* Private macro -------------------------------------------------------------*/
  128. /* Private variables ---------------------------------------------------------*/
  129. /* Private function prototypes -----------------------------------------------*/
  130. /** @addtogroup SPDIFRX_Private_Functions
  131. * @{
  132. */
  133. static void SPDIFRX_DMARxCplt(DMA_HandleTypeDef *hdma);
  134. static void SPDIFRX_DMARxHalfCplt(DMA_HandleTypeDef *hdma);
  135. static void SPDIFRX_DMACxCplt(DMA_HandleTypeDef *hdma);
  136. static void SPDIFRX_DMACxHalfCplt(DMA_HandleTypeDef *hdma);
  137. static void SPDIFRX_DMAError(DMA_HandleTypeDef *hdma);
  138. static void SPDIFRX_ReceiveControlFlow_IT(SPDIFRX_HandleTypeDef *hspdif);
  139. static void SPDIFRX_ReceiveDataFlow_IT(SPDIFRX_HandleTypeDef *hspdif);
  140. static HAL_StatusTypeDef SPDIFRX_WaitOnFlagUntilTimeout(SPDIFRX_HandleTypeDef *hspdif, uint32_t Flag, FlagStatus Status, uint32_t Timeout, uint32_t tickstart);
  141. /**
  142. * @}
  143. */
  144. /* Exported functions ---------------------------------------------------------*/
  145. /** @defgroup SPDIFRX_Exported_Functions SPDIFRX Exported Functions
  146. * @{
  147. */
  148. /** @defgroup SPDIFRX_Exported_Functions_Group1 Initialization and de-initialization functions
  149. * @brief Initialization and Configuration functions
  150. *
  151. @verbatim
  152. ===============================================================================
  153. ##### Initialization and de-initialization functions #####
  154. ===============================================================================
  155. [..] This subsection provides a set of functions allowing to initialize and
  156. de-initialize the SPDIFRX peripheral:
  157. (+) User must Implement HAL_SPDIFRX_MspInit() function in which he configures
  158. all related peripherals resources (CLOCK, GPIO, DMA, IT and NVIC ).
  159. (+) Call the function HAL_SPDIFRX_Init() to configure the SPDIFRX peripheral with
  160. the selected configuration:
  161. (++) Input Selection (IN0, IN1,...)
  162. (++) Maximum allowed re-tries during synchronization phase
  163. (++) Wait for activity on SPDIF selected input
  164. (++) Channel status selection (from channel A or B)
  165. (++) Data format (LSB, MSB, ...)
  166. (++) Stereo mode
  167. (++) User bits masking (PT,C,U,V,...)
  168. (+) Call the function HAL_SPDIFRX_DeInit() to restore the default configuration
  169. of the selected SPDIFRXx peripheral.
  170. @endverbatim
  171. * @{
  172. */
  173. /**
  174. * @brief Initializes the SPDIFRX according to the specified parameters
  175. * in the SPDIFRX_InitTypeDef and create the associated handle.
  176. * @param hspdif: SPDIFRX handle
  177. * @retval HAL status
  178. */
  179. HAL_StatusTypeDef HAL_SPDIFRX_Init(SPDIFRX_HandleTypeDef *hspdif)
  180. {
  181. uint32_t tmpreg = 0;
  182. /* Check the SPDIFRX handle allocation */
  183. if(hspdif == NULL)
  184. {
  185. return HAL_ERROR;
  186. }
  187. /* Check the SPDIFRX parameters */
  188. assert_param(IS_STEREO_MODE(hspdif->Init.StereoMode));
  189. assert_param(IS_SPDIFRX_INPUT_SELECT(hspdif->Init.InputSelection));
  190. assert_param(IS_SPDIFRX_MAX_RETRIES(hspdif->Init.Retries));
  191. assert_param(IS_SPDIFRX_WAIT_FOR_ACTIVITY(hspdif->Init.WaitForActivity));
  192. assert_param(IS_SPDIFRX_CHANNEL(hspdif->Init.ChannelSelection));
  193. assert_param(IS_SPDIFRX_DATA_FORMAT(hspdif->Init.DataFormat));
  194. assert_param(IS_PREAMBLE_TYPE_MASK(hspdif->Init.PreambleTypeMask));
  195. assert_param(IS_CHANNEL_STATUS_MASK(hspdif->Init.ChannelStatusMask));
  196. assert_param(IS_VALIDITY_MASK(hspdif->Init.ValidityBitMask));
  197. assert_param(IS_PARITY_ERROR_MASK(hspdif->Init.ParityErrorMask));
  198. assert_param(IS_SYMBOL_CLOCK_GEN(hspdif->Init.SymbolClockGen));
  199. assert_param(IS_SYMBOL_CLOCK_GEN(hspdif->Init.BackupSymbolClockGen));
  200. if(hspdif->State == HAL_SPDIFRX_STATE_RESET)
  201. {
  202. /* Allocate lock resource and initialize it */
  203. hspdif->Lock = HAL_UNLOCKED;
  204. /* Init the low level hardware : GPIO, CLOCK, CORTEX...etc */
  205. HAL_SPDIFRX_MspInit(hspdif);
  206. }
  207. /* SPDIFRX peripheral state is BUSY*/
  208. hspdif->State = HAL_SPDIFRX_STATE_BUSY;
  209. /* Disable SPDIFRX interface (IDLE State) */
  210. __HAL_SPDIFRX_IDLE(hspdif);
  211. /* Reset the old SPDIFRX CR configuration */
  212. tmpreg = hspdif->Instance->CR;
  213. tmpreg &= ~((uint16_t) SPDIFRX_CR_RXSTEO | SPDIFRX_CR_DRFMT | SPDIFRX_CR_PMSK |
  214. SPDIFRX_CR_VMSK | SPDIFRX_CR_CUMSK | SPDIFRX_CR_PTMSK |
  215. SPDIFRX_CR_CHSEL | SPDIFRX_CR_NBTR | SPDIFRX_CR_WFA |
  216. SPDIFRX_CR_CKSEN | SPDIFRX_CR_CKSBKPEN |
  217. SPDIFRX_CR_INSEL);
  218. /* Sets the new configuration of the SPDIFRX peripheral */
  219. tmpreg |= ((uint16_t) hspdif->Init.StereoMode |
  220. hspdif->Init.InputSelection |
  221. hspdif->Init.Retries |
  222. hspdif->Init.WaitForActivity |
  223. hspdif->Init.ChannelSelection |
  224. hspdif->Init.DataFormat |
  225. hspdif->Init.PreambleTypeMask |
  226. hspdif->Init.ChannelStatusMask |
  227. hspdif->Init.ValidityBitMask |
  228. hspdif->Init.SymbolClockGen |
  229. hspdif->Init.BackupSymbolClockGen |
  230. hspdif->Init.ParityErrorMask
  231. );
  232. hspdif->Instance->CR = tmpreg;
  233. hspdif->ErrorCode = HAL_SPDIFRX_ERROR_NONE;
  234. /* SPDIFRX peripheral state is READY*/
  235. hspdif->State = HAL_SPDIFRX_STATE_READY;
  236. return HAL_OK;
  237. }
  238. /**
  239. * @brief DeInitializes the SPDIFRX peripheral
  240. * @param hspdif: SPDIFRX handle
  241. * @retval HAL status
  242. */
  243. HAL_StatusTypeDef HAL_SPDIFRX_DeInit(SPDIFRX_HandleTypeDef *hspdif)
  244. {
  245. /* Check the SPDIFRX handle allocation */
  246. if(hspdif == NULL)
  247. {
  248. return HAL_ERROR;
  249. }
  250. /* Check the parameters */
  251. assert_param(IS_SPDIFRX_ALL_INSTANCE(hspdif->Instance));
  252. hspdif->State = HAL_SPDIFRX_STATE_BUSY;
  253. /* Disable SPDIFRX interface (IDLE state) */
  254. __HAL_SPDIFRX_IDLE(hspdif);
  255. /* DeInit the low level hardware: GPIO, CLOCK, NVIC... */
  256. HAL_SPDIFRX_MspDeInit(hspdif);
  257. hspdif->ErrorCode = HAL_SPDIFRX_ERROR_NONE;
  258. /* SPDIFRX peripheral state is RESET*/
  259. hspdif->State = HAL_SPDIFRX_STATE_RESET;
  260. /* Release Lock */
  261. __HAL_UNLOCK(hspdif);
  262. return HAL_OK;
  263. }
  264. /**
  265. * @brief SPDIFRX MSP Init
  266. * @param hspdif: SPDIFRX handle
  267. * @retval None
  268. */
  269. __weak void HAL_SPDIFRX_MspInit(SPDIFRX_HandleTypeDef *hspdif)
  270. {
  271. /* Prevent unused argument(s) compilation warning */
  272. UNUSED(hspdif);
  273. /* NOTE : This function Should not be modified, when the callback is needed,
  274. the HAL_SPDIFRX_MspInit could be implemented in the user file
  275. */
  276. }
  277. /**
  278. * @brief SPDIFRX MSP DeInit
  279. * @param hspdif: SPDIFRX handle
  280. * @retval None
  281. */
  282. __weak void HAL_SPDIFRX_MspDeInit(SPDIFRX_HandleTypeDef *hspdif)
  283. {
  284. /* Prevent unused argument(s) compilation warning */
  285. UNUSED(hspdif);
  286. /* NOTE : This function Should not be modified, when the callback is needed,
  287. the HAL_SPDIFRX_MspDeInit could be implemented in the user file
  288. */
  289. }
  290. /**
  291. * @brief Sets the SPDIFRX dtat format according to the specified parameters
  292. * in the SPDIFRX_InitTypeDef.
  293. * @param hspdif: SPDIFRX handle
  294. * @param sDataFormat: SPDIFRX data format
  295. * @retval HAL status
  296. */
  297. HAL_StatusTypeDef HAL_SPDIFRX_SetDataFormat(SPDIFRX_HandleTypeDef *hspdif, SPDIFRX_SetDataFormatTypeDef sDataFormat)
  298. {
  299. uint32_t tmpreg = 0;
  300. /* Check the SPDIFRX handle allocation */
  301. if(hspdif == NULL)
  302. {
  303. return HAL_ERROR;
  304. }
  305. /* Check the SPDIFRX parameters */
  306. assert_param(IS_STEREO_MODE(sDataFormat.StereoMode));
  307. assert_param(IS_SPDIFRX_DATA_FORMAT(sDataFormat.DataFormat));
  308. assert_param(IS_PREAMBLE_TYPE_MASK(sDataFormat.PreambleTypeMask));
  309. assert_param(IS_CHANNEL_STATUS_MASK(sDataFormat.ChannelStatusMask));
  310. assert_param(IS_VALIDITY_MASK(sDataFormat.ValidityBitMask));
  311. assert_param(IS_PARITY_ERROR_MASK(sDataFormat.ParityErrorMask));
  312. /* Reset the old SPDIFRX CR configuration */
  313. tmpreg = hspdif->Instance->CR;
  314. if(((tmpreg & SPDIFRX_STATE_RCV) == SPDIFRX_STATE_RCV) &&
  315. (((tmpreg & SPDIFRX_CR_DRFMT) != sDataFormat.DataFormat) ||
  316. ((tmpreg & SPDIFRX_CR_RXSTEO) != sDataFormat.StereoMode)))
  317. {
  318. return HAL_ERROR;
  319. }
  320. tmpreg &= ~((uint16_t) SPDIFRX_CR_RXSTEO | SPDIFRX_CR_DRFMT | SPDIFRX_CR_PMSK |
  321. SPDIFRX_CR_VMSK | SPDIFRX_CR_CUMSK | SPDIFRX_CR_PTMSK);
  322. /* Sets the new configuration of the SPDIFRX peripheral */
  323. tmpreg |= ((uint16_t) sDataFormat.StereoMode |
  324. sDataFormat.DataFormat |
  325. sDataFormat.PreambleTypeMask |
  326. sDataFormat.ChannelStatusMask |
  327. sDataFormat.ValidityBitMask |
  328. sDataFormat.ParityErrorMask);
  329. hspdif->Instance->CR = tmpreg;
  330. return HAL_OK;
  331. }
  332. /**
  333. * @}
  334. */
  335. /** @defgroup SPDIFRX_Exported_Functions_Group2 IO operation functions
  336. * @brief Data transfers functions
  337. *
  338. @verbatim
  339. ===============================================================================
  340. ##### IO operation functions #####
  341. ===============================================================================
  342. [..]
  343. This subsection provides a set of functions allowing to manage the SPDIFRX data
  344. transfers.
  345. (#) There is two mode of transfer:
  346. (++) Blocking mode : The communication is performed in the polling mode.
  347. The status of all data processing is returned by the same function
  348. after finishing transfer.
  349. (++) No-Blocking mode : The communication is performed using Interrupts
  350. or DMA. These functions return the status of the transfer start-up.
  351. The end of the data processing will be indicated through the
  352. dedicated SPDIFRX IRQ when using Interrupt mode or the DMA IRQ when
  353. using DMA mode.
  354. (#) Blocking mode functions are :
  355. (++) HAL_SPDIFRX_ReceiveDataFlow()
  356. (++) HAL_SPDIFRX_ReceiveControlFlow()
  357. (+@) Do not use blocking mode to receive both control and data flow at the same time.
  358. (#) No-Blocking mode functions with Interrupt are :
  359. (++) HAL_SPDIFRX_ReceiveControlFlow_IT()
  360. (++) HAL_SPDIFRX_ReceiveDataFlow_IT()
  361. (#) No-Blocking mode functions with DMA are :
  362. (++) HAL_SPDIFRX_ReceiveControlFlow_DMA()
  363. (++) HAL_SPDIFRX_ReceiveDataFlow_DMA()
  364. (#) A set of Transfer Complete Callbacks are provided in No_Blocking mode:
  365. (++) HAL_SPDIFRX_RxCpltCallback()
  366. (++) HAL_SPDIFRX_ErrorCallback()
  367. @endverbatim
  368. * @{
  369. */
  370. /**
  371. * @brief Receives an amount of data (Data Flow) in blocking mode.
  372. * @param hspdif: pointer to SPDIFRX_HandleTypeDef structure that contains
  373. * the configuration information for SPDIFRX module.
  374. * @param pData: Pointer to data buffer
  375. * @param Size: Amount of data to be received
  376. * @param Timeout: Timeout duration
  377. * @retval HAL status
  378. */
  379. HAL_StatusTypeDef HAL_SPDIFRX_ReceiveDataFlow(SPDIFRX_HandleTypeDef *hspdif, uint32_t *pData, uint16_t Size, uint32_t Timeout)
  380. {
  381. uint32_t tickstart = 0U;
  382. if((pData == NULL ) || (Size == 0U))
  383. {
  384. return HAL_ERROR;
  385. }
  386. if(hspdif->State == HAL_SPDIFRX_STATE_READY)
  387. {
  388. /* Process Locked */
  389. __HAL_LOCK(hspdif);
  390. hspdif->State = HAL_SPDIFRX_STATE_BUSY;
  391. /* Start synchronisation */
  392. __HAL_SPDIFRX_SYNC(hspdif);
  393. /* Get tick */
  394. tickstart = HAL_GetTick();
  395. /* Wait until SYNCD flag is set */
  396. if(SPDIFRX_WaitOnFlagUntilTimeout(hspdif, SPDIFRX_FLAG_SYNCD, RESET, Timeout, tickstart) != HAL_OK)
  397. {
  398. return HAL_TIMEOUT;
  399. }
  400. /* Start reception */
  401. __HAL_SPDIFRX_RCV(hspdif);
  402. /* Receive data flow */
  403. while(Size > 0U)
  404. {
  405. /* Get tick */
  406. tickstart = HAL_GetTick();
  407. /* Wait until RXNE flag is set */
  408. if(SPDIFRX_WaitOnFlagUntilTimeout(hspdif, SPDIFRX_FLAG_RXNE, RESET, Timeout, tickstart) != HAL_OK)
  409. {
  410. return HAL_TIMEOUT;
  411. }
  412. (*pData++) = hspdif->Instance->DR;
  413. Size--;
  414. }
  415. /* SPDIFRX ready */
  416. hspdif->State = HAL_SPDIFRX_STATE_READY;
  417. /* Process Unlocked */
  418. __HAL_UNLOCK(hspdif);
  419. return HAL_OK;
  420. }
  421. else
  422. {
  423. return HAL_BUSY;
  424. }
  425. }
  426. /**
  427. * @brief Receives an amount of data (Control Flow) in blocking mode.
  428. * @param hspdif: pointer to a SPDIFRX_HandleTypeDef structure that contains
  429. * the configuration information for SPDIFRX module.
  430. * @param pData: Pointer to data buffer
  431. * @param Size: Amount of data to be received
  432. * @param Timeout: Timeout duration
  433. * @retval HAL status
  434. */
  435. HAL_StatusTypeDef HAL_SPDIFRX_ReceiveControlFlow(SPDIFRX_HandleTypeDef *hspdif, uint32_t *pData, uint16_t Size, uint32_t Timeout)
  436. {
  437. uint32_t tickstart = 0U;
  438. if((pData == NULL ) || (Size == 0U))
  439. {
  440. return HAL_ERROR;
  441. }
  442. if(hspdif->State == HAL_SPDIFRX_STATE_READY)
  443. {
  444. /* Process Locked */
  445. __HAL_LOCK(hspdif);
  446. hspdif->State = HAL_SPDIFRX_STATE_BUSY;
  447. /* Start synchronization */
  448. __HAL_SPDIFRX_SYNC(hspdif);
  449. /* Get tick */
  450. tickstart = HAL_GetTick();
  451. /* Wait until SYNCD flag is set */
  452. if(SPDIFRX_WaitOnFlagUntilTimeout(hspdif, SPDIFRX_FLAG_SYNCD, RESET, Timeout, tickstart) != HAL_OK)
  453. {
  454. return HAL_TIMEOUT;
  455. }
  456. /* Start reception */
  457. __HAL_SPDIFRX_RCV(hspdif);
  458. /* Receive control flow */
  459. while(Size > 0U)
  460. {
  461. /* Get tick */
  462. tickstart = HAL_GetTick();
  463. /* Wait until CSRNE flag is set */
  464. if(SPDIFRX_WaitOnFlagUntilTimeout(hspdif, SPDIFRX_FLAG_CSRNE, RESET, Timeout, tickstart) != HAL_OK)
  465. {
  466. return HAL_TIMEOUT;
  467. }
  468. (*pData++) = hspdif->Instance->CSR;
  469. Size--;
  470. }
  471. /* SPDIFRX ready */
  472. hspdif->State = HAL_SPDIFRX_STATE_READY;
  473. /* Process Unlocked */
  474. __HAL_UNLOCK(hspdif);
  475. return HAL_OK;
  476. }
  477. else
  478. {
  479. return HAL_BUSY;
  480. }
  481. }
  482. /**
  483. * @brief Receive an amount of data (Data Flow) in non-blocking mode with Interrupt
  484. * @param hspdif: SPDIFRX handle
  485. * @param pData: a 32-bit pointer to the Receive data buffer.
  486. * @param Size: number of data sample to be received .
  487. * @retval HAL status
  488. */
  489. HAL_StatusTypeDef HAL_SPDIFRX_ReceiveDataFlow_IT(SPDIFRX_HandleTypeDef *hspdif, uint32_t *pData, uint16_t Size)
  490. {
  491. uint32_t tickstart = 0U;
  492. if((hspdif->State == HAL_SPDIFRX_STATE_READY) || (hspdif->State == HAL_SPDIFRX_STATE_BUSY_CX))
  493. {
  494. if((pData == NULL) || (Size == 0U))
  495. {
  496. return HAL_ERROR;
  497. }
  498. /* Process Locked */
  499. __HAL_LOCK(hspdif);
  500. hspdif->pRxBuffPtr = pData;
  501. hspdif->RxXferSize = Size;
  502. hspdif->RxXferCount = Size;
  503. hspdif->ErrorCode = HAL_SPDIFRX_ERROR_NONE;
  504. /* Check if a receive process is ongoing or not */
  505. hspdif->State = HAL_SPDIFRX_STATE_BUSY_RX;
  506. /* Enable the SPDIFRX PE Error Interrupt */
  507. __HAL_SPDIFRX_ENABLE_IT(hspdif, SPDIFRX_IT_PERRIE);
  508. /* Enable the SPDIFRX OVR Error Interrupt */
  509. __HAL_SPDIFRX_ENABLE_IT(hspdif, SPDIFRX_IT_OVRIE);
  510. /* Process Unlocked */
  511. __HAL_UNLOCK(hspdif);
  512. /* Enable the SPDIFRX RXNE interrupt */
  513. __HAL_SPDIFRX_ENABLE_IT(hspdif, SPDIFRX_IT_RXNE);
  514. if (((SPDIFRX->CR & SPDIFRX_CR_SPDIFEN) != SPDIFRX_STATE_SYNC) || ((SPDIFRX->CR & SPDIFRX_CR_SPDIFEN) != 0x00U))
  515. {
  516. /* Start synchronization */
  517. __HAL_SPDIFRX_SYNC(hspdif);
  518. /* Get tick */
  519. tickstart = HAL_GetTick();
  520. /* Wait until SYNCD flag is set */
  521. if(SPDIFRX_WaitOnFlagUntilTimeout(hspdif, SPDIFRX_FLAG_SYNCD, RESET, SPDIFRX_TIMEOUT_VALUE, tickstart) != HAL_OK)
  522. {
  523. return HAL_TIMEOUT;
  524. }
  525. /* Start reception */
  526. __HAL_SPDIFRX_RCV(hspdif);
  527. }
  528. return HAL_OK;
  529. }
  530. else
  531. {
  532. return HAL_BUSY;
  533. }
  534. }
  535. /**
  536. * @brief Receive an amount of data (Control Flow) with Interrupt
  537. * @param hspdif: SPDIFRX handle
  538. * @param pData: a 32-bit pointer to the Receive data buffer.
  539. * @param Size: number of data sample (Control Flow) to be received :
  540. * @retval HAL status
  541. */
  542. HAL_StatusTypeDef HAL_SPDIFRX_ReceiveControlFlow_IT(SPDIFRX_HandleTypeDef *hspdif, uint32_t *pData, uint16_t Size)
  543. {
  544. uint32_t tickstart = 0U;
  545. if((hspdif->State == HAL_SPDIFRX_STATE_READY) || (hspdif->State == HAL_SPDIFRX_STATE_BUSY_RX))
  546. {
  547. if((pData == NULL ) || (Size == 0U))
  548. {
  549. return HAL_ERROR;
  550. }
  551. /* Process Locked */
  552. __HAL_LOCK(hspdif);
  553. hspdif->pCsBuffPtr = pData;
  554. hspdif->CsXferSize = Size;
  555. hspdif->CsXferCount = Size;
  556. hspdif->ErrorCode = HAL_SPDIFRX_ERROR_NONE;
  557. /* Check if a receive process is ongoing or not */
  558. hspdif->State = HAL_SPDIFRX_STATE_BUSY_CX;
  559. /* Enable the SPDIFRX PE Error Interrupt */
  560. __HAL_SPDIFRX_ENABLE_IT(hspdif, SPDIFRX_IT_PERRIE);
  561. /* Enable the SPDIFRX OVR Error Interrupt */
  562. __HAL_SPDIFRX_ENABLE_IT(hspdif, SPDIFRX_IT_OVRIE);
  563. /* Process Unlocked */
  564. __HAL_UNLOCK(hspdif);
  565. /* Enable the SPDIFRX CSRNE interrupt */
  566. __HAL_SPDIFRX_ENABLE_IT(hspdif, SPDIFRX_IT_CSRNE);
  567. if (((SPDIFRX->CR & SPDIFRX_CR_SPDIFEN) != SPDIFRX_STATE_SYNC) || ((SPDIFRX->CR & SPDIFRX_CR_SPDIFEN) != 0x00U))
  568. {
  569. /* Start synchronization */
  570. __HAL_SPDIFRX_SYNC(hspdif);
  571. /* Get tick */
  572. tickstart = HAL_GetTick();
  573. /* Wait until SYNCD flag is set */
  574. if(SPDIFRX_WaitOnFlagUntilTimeout(hspdif, SPDIFRX_FLAG_SYNCD, RESET, SPDIFRX_TIMEOUT_VALUE, tickstart) != HAL_OK)
  575. {
  576. return HAL_TIMEOUT;
  577. }
  578. /* Start reception */
  579. __HAL_SPDIFRX_RCV(hspdif);
  580. }
  581. return HAL_OK;
  582. }
  583. else
  584. {
  585. return HAL_BUSY;
  586. }
  587. }
  588. /**
  589. * @brief Receive an amount of data (Data Flow) mode with DMA
  590. * @param hspdif: SPDIFRX handle
  591. * @param pData: a 32-bit pointer to the Receive data buffer.
  592. * @param Size: number of data sample to be received :
  593. * @retval HAL status
  594. */
  595. HAL_StatusTypeDef HAL_SPDIFRX_ReceiveDataFlow_DMA(SPDIFRX_HandleTypeDef *hspdif, uint32_t *pData, uint16_t Size)
  596. {
  597. uint32_t tickstart = 0U;
  598. if((pData == NULL) || (Size == 0U))
  599. {
  600. return HAL_ERROR;
  601. }
  602. if((hspdif->State == HAL_SPDIFRX_STATE_READY) || (hspdif->State == HAL_SPDIFRX_STATE_BUSY_CX))
  603. {
  604. hspdif->pRxBuffPtr = pData;
  605. hspdif->RxXferSize = Size;
  606. hspdif->RxXferCount = Size;
  607. /* Process Locked */
  608. __HAL_LOCK(hspdif);
  609. hspdif->ErrorCode = HAL_SPDIFRX_ERROR_NONE;
  610. hspdif->State = HAL_SPDIFRX_STATE_BUSY_RX;
  611. /* Set the SPDIFRX Rx DMA Half transfer complete callback */
  612. hspdif->hdmaDrRx->XferHalfCpltCallback = SPDIFRX_DMARxHalfCplt;
  613. /* Set the SPDIFRX Rx DMA transfer complete callback */
  614. hspdif->hdmaDrRx->XferCpltCallback = SPDIFRX_DMARxCplt;
  615. /* Set the DMA error callback */
  616. hspdif->hdmaDrRx->XferErrorCallback = SPDIFRX_DMAError;
  617. /* Enable the DMA request */
  618. HAL_DMA_Start_IT(hspdif->hdmaDrRx, (uint32_t)&hspdif->Instance->DR, (uint32_t)hspdif->pRxBuffPtr, Size);
  619. /* Enable RXDMAEN bit in SPDIFRX CR register for data flow reception*/
  620. hspdif->Instance->CR |= SPDIFRX_CR_RXDMAEN;
  621. if (((SPDIFRX->CR & SPDIFRX_CR_SPDIFEN) != SPDIFRX_STATE_SYNC) || ((SPDIFRX->CR & SPDIFRX_CR_SPDIFEN) != 0x00U))
  622. {
  623. /* Start synchronization */
  624. __HAL_SPDIFRX_SYNC(hspdif);
  625. /* Get tick */
  626. tickstart = HAL_GetTick();
  627. /* Wait until SYNCD flag is set */
  628. if(SPDIFRX_WaitOnFlagUntilTimeout(hspdif, SPDIFRX_FLAG_SYNCD, RESET, SPDIFRX_TIMEOUT_VALUE, tickstart) != HAL_OK)
  629. {
  630. return HAL_TIMEOUT;
  631. }
  632. /* Start reception */
  633. __HAL_SPDIFRX_RCV(hspdif);
  634. }
  635. /* Process Unlocked */
  636. __HAL_UNLOCK(hspdif);
  637. return HAL_OK;
  638. }
  639. else
  640. {
  641. return HAL_BUSY;
  642. }
  643. }
  644. /**
  645. * @brief Receive an amount of data (Control Flow) with DMA
  646. * @param hspdif: SPDIFRX handle
  647. * @param pData: a 32-bit pointer to the Receive data buffer.
  648. * @param Size: number of data (Control Flow) sample to be received :
  649. * @retval HAL status
  650. */
  651. HAL_StatusTypeDef HAL_SPDIFRX_ReceiveControlFlow_DMA(SPDIFRX_HandleTypeDef *hspdif, uint32_t *pData, uint16_t Size)
  652. {
  653. uint32_t tickstart = 0U;
  654. if((pData == NULL) || (Size == 0U))
  655. {
  656. return HAL_ERROR;
  657. }
  658. if((hspdif->State == HAL_SPDIFRX_STATE_READY) || (hspdif->State == HAL_SPDIFRX_STATE_BUSY_RX))
  659. {
  660. hspdif->pCsBuffPtr = pData;
  661. hspdif->CsXferSize = Size;
  662. hspdif->CsXferCount = Size;
  663. /* Process Locked */
  664. __HAL_LOCK(hspdif);
  665. hspdif->ErrorCode = HAL_SPDIFRX_ERROR_NONE;
  666. hspdif->State = HAL_SPDIFRX_STATE_BUSY_CX;
  667. /* Set the SPDIFRX Rx DMA Half transfer complete callback */
  668. hspdif->hdmaCsRx->XferHalfCpltCallback = SPDIFRX_DMACxHalfCplt;
  669. /* Set the SPDIFRX Rx DMA transfer complete callback */
  670. hspdif->hdmaCsRx->XferCpltCallback = SPDIFRX_DMACxCplt;
  671. /* Set the DMA error callback */
  672. hspdif->hdmaCsRx->XferErrorCallback = SPDIFRX_DMAError;
  673. /* Enable the DMA request */
  674. HAL_DMA_Start_IT(hspdif->hdmaCsRx, (uint32_t)&hspdif->Instance->CSR, (uint32_t)hspdif->pCsBuffPtr, Size);
  675. /* Enable CBDMAEN bit in SPDIFRX CR register for control flow reception*/
  676. hspdif->Instance->CR |= SPDIFRX_CR_CBDMAEN;
  677. if (((SPDIFRX->CR & SPDIFRX_CR_SPDIFEN) != SPDIFRX_STATE_SYNC) || ((SPDIFRX->CR & SPDIFRX_CR_SPDIFEN) != 0x00U))
  678. {
  679. /* Start synchronization */
  680. __HAL_SPDIFRX_SYNC(hspdif);
  681. /* Get tick */
  682. tickstart = HAL_GetTick();
  683. /* Wait until SYNCD flag is set */
  684. if(SPDIFRX_WaitOnFlagUntilTimeout(hspdif, SPDIFRX_FLAG_SYNCD, RESET, SPDIFRX_TIMEOUT_VALUE, tickstart) != HAL_OK)
  685. {
  686. return HAL_TIMEOUT;
  687. }
  688. /* Start reception */
  689. __HAL_SPDIFRX_RCV(hspdif);
  690. }
  691. /* Process Unlocked */
  692. __HAL_UNLOCK(hspdif);
  693. return HAL_OK;
  694. }
  695. else
  696. {
  697. return HAL_BUSY;
  698. }
  699. }
  700. /**
  701. * @brief stop the audio stream receive from the Media.
  702. * @param hspdif: SPDIFRX handle
  703. * @retval None
  704. */
  705. HAL_StatusTypeDef HAL_SPDIFRX_DMAStop(SPDIFRX_HandleTypeDef *hspdif)
  706. {
  707. /* Process Locked */
  708. __HAL_LOCK(hspdif);
  709. /* Disable the SPDIFRX DMA requests */
  710. hspdif->Instance->CR &= (uint16_t)(~SPDIFRX_CR_RXDMAEN);
  711. hspdif->Instance->CR &= (uint16_t)(~SPDIFRX_CR_CBDMAEN);
  712. /* Disable the SPDIFRX DMA channel */
  713. __HAL_DMA_DISABLE(hspdif->hdmaDrRx);
  714. __HAL_DMA_DISABLE(hspdif->hdmaCsRx);
  715. /* Disable SPDIFRX peripheral */
  716. __HAL_SPDIFRX_IDLE(hspdif);
  717. hspdif->State = HAL_SPDIFRX_STATE_READY;
  718. /* Process Unlocked */
  719. __HAL_UNLOCK(hspdif);
  720. return HAL_OK;
  721. }
  722. /**
  723. * @brief This function handles SPDIFRX interrupt request.
  724. * @param hspdif: SPDIFRX handle
  725. * @retval HAL status
  726. */
  727. void HAL_SPDIFRX_IRQHandler(SPDIFRX_HandleTypeDef *hspdif)
  728. {
  729. /* SPDIFRX in mode Data Flow Reception ------------------------------------------------*/
  730. if((__HAL_SPDIFRX_GET_FLAG(hspdif, SPDIFRX_FLAG_RXNE) != RESET) && (__HAL_SPDIFRX_GET_IT_SOURCE(hspdif, SPDIFRX_IT_RXNE) != RESET))
  731. {
  732. __HAL_SPDIFRX_CLEAR_IT(hspdif, SPDIFRX_IT_RXNE);
  733. SPDIFRX_ReceiveDataFlow_IT(hspdif);
  734. }
  735. /* SPDIFRX in mode Control Flow Reception ------------------------------------------------*/
  736. if((__HAL_SPDIFRX_GET_FLAG(hspdif, SPDIFRX_FLAG_CSRNE) != RESET) && (__HAL_SPDIFRX_GET_IT_SOURCE(hspdif, SPDIFRX_IT_CSRNE) != RESET))
  737. {
  738. __HAL_SPDIFRX_CLEAR_IT(hspdif, SPDIFRX_IT_CSRNE);
  739. SPDIFRX_ReceiveControlFlow_IT(hspdif);
  740. }
  741. /* SPDIFRX Overrun error interrupt occurred ---------------------------------*/
  742. if((__HAL_SPDIFRX_GET_FLAG(hspdif, SPDIFRX_FLAG_OVR) != RESET) && (__HAL_SPDIFRX_GET_IT_SOURCE(hspdif, SPDIFRX_IT_OVRIE) != RESET))
  743. {
  744. __HAL_SPDIFRX_CLEAR_IT(hspdif, SPDIFRX_FLAG_OVR);
  745. /* Change the SPDIFRX error code */
  746. hspdif->ErrorCode |= HAL_SPDIFRX_ERROR_OVR;
  747. /* the transfer is not stopped */
  748. HAL_SPDIFRX_ErrorCallback(hspdif);
  749. }
  750. /* SPDIFRX Parity error interrupt occurred ---------------------------------*/
  751. if((__HAL_SPDIFRX_GET_FLAG(hspdif, SPDIFRX_FLAG_PERR) != RESET) && (__HAL_SPDIFRX_GET_IT_SOURCE(hspdif, SPDIFRX_IT_PERRIE) != RESET))
  752. {
  753. __HAL_SPDIFRX_CLEAR_IT(hspdif, SPDIFRX_FLAG_PERR);
  754. /* Change the SPDIFRX error code */
  755. hspdif->ErrorCode |= HAL_SPDIFRX_ERROR_PE;
  756. /* the transfer is not stopped */
  757. HAL_SPDIFRX_ErrorCallback(hspdif);
  758. }
  759. }
  760. /**
  761. * @brief Rx Transfer (Data flow) half completed callbacks
  762. * @param hspdif: SPDIFRX handle
  763. * @retval None
  764. */
  765. __weak void HAL_SPDIFRX_RxHalfCpltCallback(SPDIFRX_HandleTypeDef *hspdif)
  766. {
  767. /* Prevent unused argument(s) compilation warning */
  768. UNUSED(hspdif);
  769. /* NOTE : This function Should not be modified, when the callback is needed,
  770. the HAL_SPDIFRX_RxCpltCallback could be implemented in the user file
  771. */
  772. }
  773. /**
  774. * @brief Rx Transfer (Data flow) completed callbacks
  775. * @param hspdif: SPDIFRX handle
  776. * @retval None
  777. */
  778. __weak void HAL_SPDIFRX_RxCpltCallback(SPDIFRX_HandleTypeDef *hspdif)
  779. {
  780. /* Prevent unused argument(s) compilation warning */
  781. UNUSED(hspdif);
  782. /* NOTE : This function Should not be modified, when the callback is needed,
  783. the HAL_SPDIFRX_RxCpltCallback could be implemented in the user file
  784. */
  785. }
  786. /**
  787. * @brief Rx (Control flow) Transfer half completed callbacks
  788. * @param hspdif: SPDIFRX handle
  789. * @retval None
  790. */
  791. __weak void HAL_SPDIFRX_CxHalfCpltCallback(SPDIFRX_HandleTypeDef *hspdif)
  792. {
  793. /* Prevent unused argument(s) compilation warning */
  794. UNUSED(hspdif);
  795. /* NOTE : This function Should not be modified, when the callback is needed,
  796. the HAL_SPDIFRX_RxCpltCallback could be implemented in the user file
  797. */
  798. }
  799. /**
  800. * @brief Rx Transfer (Control flow) completed callbacks
  801. * @param hspdif: SPDIFRX handle
  802. * @retval None
  803. */
  804. __weak void HAL_SPDIFRX_CxCpltCallback(SPDIFRX_HandleTypeDef *hspdif)
  805. {
  806. /* Prevent unused argument(s) compilation warning */
  807. UNUSED(hspdif);
  808. /* NOTE : This function Should not be modified, when the callback is needed,
  809. the HAL_SPDIFRX_RxCpltCallback could be implemented in the user file
  810. */
  811. }
  812. /**
  813. * @brief SPDIFRX error callbacks
  814. * @param hspdif: SPDIFRX handle
  815. * @retval None
  816. */
  817. __weak void HAL_SPDIFRX_ErrorCallback(SPDIFRX_HandleTypeDef *hspdif)
  818. {
  819. /* Prevent unused argument(s) compilation warning */
  820. UNUSED(hspdif);
  821. /* NOTE : This function Should not be modified, when the callback is needed,
  822. the HAL_SPDIFRX_ErrorCallback could be implemented in the user file
  823. */
  824. }
  825. /**
  826. * @}
  827. */
  828. /** @defgroup SPDIFRX_Exported_Functions_Group3 Peripheral State and Errors functions
  829. * @brief Peripheral State functions
  830. *
  831. @verbatim
  832. ===============================================================================
  833. ##### Peripheral State and Errors functions #####
  834. ===============================================================================
  835. [..]
  836. This subsection permit to get in run-time the status of the peripheral
  837. and the data flow.
  838. @endverbatim
  839. * @{
  840. */
  841. /**
  842. * @brief Return the SPDIFRX state
  843. * @param hspdif : SPDIFRX handle
  844. * @retval HAL state
  845. */
  846. HAL_SPDIFRX_StateTypeDef HAL_SPDIFRX_GetState(SPDIFRX_HandleTypeDef *hspdif)
  847. {
  848. return hspdif->State;
  849. }
  850. /**
  851. * @brief Return the SPDIFRX error code
  852. * @param hspdif : SPDIFRX handle
  853. * @retval SPDIFRX Error Code
  854. */
  855. uint32_t HAL_SPDIFRX_GetError(SPDIFRX_HandleTypeDef *hspdif)
  856. {
  857. return hspdif->ErrorCode;
  858. }
  859. /**
  860. * @}
  861. */
  862. /**
  863. * @brief DMA SPDIFRX receive process (Data flow) complete callback
  864. * @param hdma : DMA handle
  865. * @retval None
  866. */
  867. static void SPDIFRX_DMARxCplt(DMA_HandleTypeDef *hdma)
  868. {
  869. SPDIFRX_HandleTypeDef* hspdif = ( SPDIFRX_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
  870. /* Disable Rx DMA Request */
  871. if(hdma->Init.Mode != DMA_CIRCULAR)
  872. {
  873. hspdif->Instance->CR &= (uint16_t)(~SPDIFRX_CR_RXDMAEN);
  874. hspdif->RxXferCount = 0;
  875. hspdif->State = HAL_SPDIFRX_STATE_READY;
  876. }
  877. HAL_SPDIFRX_RxCpltCallback(hspdif);
  878. }
  879. /**
  880. * @brief DMA SPDIFRX receive process (Data flow) half complete callback
  881. * @param hdma : DMA handle
  882. * @retval None
  883. */
  884. static void SPDIFRX_DMARxHalfCplt(DMA_HandleTypeDef *hdma)
  885. {
  886. SPDIFRX_HandleTypeDef* hspdif = (SPDIFRX_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
  887. HAL_SPDIFRX_RxHalfCpltCallback(hspdif);
  888. }
  889. /**
  890. * @brief DMA SPDIFRX receive process (Control flow) complete callback
  891. * @param hdma : DMA handle
  892. * @retval None
  893. */
  894. static void SPDIFRX_DMACxCplt(DMA_HandleTypeDef *hdma)
  895. {
  896. SPDIFRX_HandleTypeDef* hspdif = ( SPDIFRX_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
  897. /* Disable Cb DMA Request */
  898. hspdif->Instance->CR &= (uint16_t)(~SPDIFRX_CR_CBDMAEN);
  899. hspdif->CsXferCount = 0;
  900. hspdif->State = HAL_SPDIFRX_STATE_READY;
  901. HAL_SPDIFRX_CxCpltCallback(hspdif);
  902. }
  903. /**
  904. * @brief DMA SPDIFRX receive process (Control flow) half complete callback
  905. * @param hdma : DMA handle
  906. * @retval None
  907. */
  908. static void SPDIFRX_DMACxHalfCplt(DMA_HandleTypeDef *hdma)
  909. {
  910. SPDIFRX_HandleTypeDef* hspdif = (SPDIFRX_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
  911. HAL_SPDIFRX_CxHalfCpltCallback(hspdif);
  912. }
  913. /**
  914. * @brief DMA SPDIFRX communication error callback
  915. * @param hdma : DMA handle
  916. * @retval None
  917. */
  918. static void SPDIFRX_DMAError(DMA_HandleTypeDef *hdma)
  919. {
  920. SPDIFRX_HandleTypeDef* hspdif = ( SPDIFRX_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
  921. /* Disable Rx and Cb DMA Request */
  922. hspdif->Instance->CR &= (uint16_t)(~(SPDIFRX_CR_RXDMAEN | SPDIFRX_CR_CBDMAEN));
  923. hspdif->RxXferCount = 0;
  924. hspdif->State= HAL_SPDIFRX_STATE_READY;
  925. /* Set the error code and execute error callback*/
  926. hspdif->ErrorCode |= HAL_SPDIFRX_ERROR_DMA;
  927. HAL_SPDIFRX_ErrorCallback(hspdif);
  928. }
  929. /**
  930. * @brief Receive an amount of data (Data Flow) with Interrupt
  931. * @param hspdif: SPDIFRX handle
  932. * @retval None
  933. */
  934. static void SPDIFRX_ReceiveDataFlow_IT(SPDIFRX_HandleTypeDef *hspdif)
  935. {
  936. /* Receive data */
  937. (*hspdif->pRxBuffPtr++) = hspdif->Instance->DR;
  938. hspdif->RxXferCount--;
  939. if(hspdif->RxXferCount == 0)
  940. {
  941. /* Disable RXNE/PE and OVR interrupts */
  942. __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_OVRIE | SPDIFRX_IT_PERRIE | SPDIFRX_IT_RXNE);
  943. hspdif->State = HAL_SPDIFRX_STATE_READY;
  944. /* Process Unlocked */
  945. __HAL_UNLOCK(hspdif);
  946. HAL_SPDIFRX_RxCpltCallback(hspdif);
  947. }
  948. }
  949. /**
  950. * @brief Receive an amount of data (Control Flow) with Interrupt
  951. * @param hspdif: SPDIFRX handle
  952. * @retval None
  953. */
  954. static void SPDIFRX_ReceiveControlFlow_IT(SPDIFRX_HandleTypeDef *hspdif)
  955. {
  956. /* Receive data */
  957. (*hspdif->pCsBuffPtr++) = hspdif->Instance->CSR;
  958. hspdif->CsXferCount--;
  959. if(hspdif->CsXferCount == 0)
  960. {
  961. /* Disable CSRNE interrupt */
  962. __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_CSRNE);
  963. hspdif->State = HAL_SPDIFRX_STATE_READY;
  964. /* Process Unlocked */
  965. __HAL_UNLOCK(hspdif);
  966. HAL_SPDIFRX_CxCpltCallback(hspdif);
  967. }
  968. }
  969. /**
  970. * @brief This function handles SPDIFRX Communication Timeout.
  971. * @param hspdif: SPDIFRX handle
  972. * @param Flag: Flag checked
  973. * @param Status: Value of the flag expected
  974. * @param Timeout: Duration of the timeout
  975. * @param tickstart: Tick start value
  976. * @retval HAL status
  977. */
  978. static HAL_StatusTypeDef SPDIFRX_WaitOnFlagUntilTimeout(SPDIFRX_HandleTypeDef *hspdif, uint32_t Flag, FlagStatus Status, uint32_t Timeout, uint32_t tickstart)
  979. {
  980. /* Wait until flag is set */
  981. if(Status == RESET)
  982. {
  983. while(__HAL_SPDIFRX_GET_FLAG(hspdif, Flag) == RESET)
  984. {
  985. /* Check for the Timeout */
  986. if(Timeout != HAL_MAX_DELAY)
  987. {
  988. if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout))
  989. {
  990. /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt process */
  991. __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_RXNE);
  992. __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_CSRNE);
  993. __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_PERRIE);
  994. __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_OVRIE);
  995. __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_SBLKIE);
  996. __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_SYNCDIE);
  997. __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_IFEIE);
  998. hspdif->State= HAL_SPDIFRX_STATE_READY;
  999. /* Process Unlocked */
  1000. __HAL_UNLOCK(hspdif);
  1001. return HAL_TIMEOUT;
  1002. }
  1003. }
  1004. }
  1005. }
  1006. else
  1007. {
  1008. while(__HAL_SPDIFRX_GET_FLAG(hspdif, Flag) != RESET)
  1009. {
  1010. /* Check for the Timeout */
  1011. if(Timeout != HAL_MAX_DELAY)
  1012. {
  1013. if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout))
  1014. {
  1015. /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt process */
  1016. __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_RXNE);
  1017. __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_CSRNE);
  1018. __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_PERRIE);
  1019. __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_OVRIE);
  1020. __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_SBLKIE);
  1021. __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_SYNCDIE);
  1022. __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_IFEIE);
  1023. hspdif->State= HAL_SPDIFRX_STATE_READY;
  1024. /* Process Unlocked */
  1025. __HAL_UNLOCK(hspdif);
  1026. return HAL_TIMEOUT;
  1027. }
  1028. }
  1029. }
  1030. }
  1031. return HAL_OK;
  1032. }
  1033. /**
  1034. * @}
  1035. */
  1036. #endif /* SPDIFRX */
  1037. #endif /* HAL_SPDIFRX_MODULE_ENABLED */
  1038. /**
  1039. * @}
  1040. */
  1041. /**
  1042. * @}
  1043. */
  1044. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/