1 /**
2   ******************************************************************************
3   * @file    stm32f4xx_spdifrx.c
4   * @author  MCD Application Team
5   * @version V1.5.1
6   * @date    22-May-2015
7   * @brief   This file provides firmware functions to manage the following
8   *          functionalities of the Serial Audio Interface (SPDIFRX):
9   *           + Initialization and Configuration
10   *           + Data transfers functions
11   *           + DMA transfers management
12   *           + Interrupts and flags management
13   ******************************************************************************
14   * @attention
15   *
16   * <h2><center>&copy; COPYRIGHT 2015 STMicroelectronics</center></h2>
17   *
18   * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
19   * You may not use this file except in compliance with the License.
20   * You may obtain a copy of the License at:
21   *
22   *        http://www.st.com/software_license_agreement_liberty_v2
23   *
24   * Unless required by applicable law or agreed to in writing, software
25   * distributed under the License is distributed on an "AS IS" BASIS,
26   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
27   * See the License for the specific language governing permissions and
28   * limitations under the License.
29   *
30   ******************************************************************************
31   */
32 
33 /* Includes ------------------------------------------------------------------*/
34 #include "stm32f4xx_spdifrx.h"
35 #include "stm32f4xx_rcc.h"
36 
37 /** @addtogroup STM32F4xx_StdPeriph_Driver
38   * @{
39   */
40 
41 /** @defgroup SPDIFRX
42   * @brief SPDIFRX driver modules
43   * @{
44   */
45 
46 #if defined(STM32F446xx)
47 /* Private typedef -----------------------------------------------------------*/
48 /* Private define ------------------------------------------------------------*/
49 #define CR_CLEAR_MASK 0x000000FE7
50 /* Private macro -------------------------------------------------------------*/
51 /* Private variables ---------------------------------------------------------*/
52 /* Private function prototypes -----------------------------------------------*/
53 /* Private functions ---------------------------------------------------------*/
54 
55 /** @defgroup SPDIFRX_Private_Functions
56   * @{
57   */
58 
59 /** @defgroup SPDIFRX_Group1 Initialization and Configuration functions
60   *  @brief   Initialization and Configuration functions
61   *
62 @verbatim
63  ===============================================================================
64             ##### Initialization and Configuration functions #####
65  ===============================================================================
66   [..]
67   This section provides a set of functions allowing to initialize the SPDIFRX Audio
68 
69   Block Mode, Audio Protocol, Data size, Synchronization between audio block,
70   Master clock Divider, FIFO threshold, Frame configuration, slot configuration,
71   Tristate mode, Companding mode and Mute mode.
72   [..]
73   The SPDIFRX_Init(), SPDIFRX_FrameInit() and SPDIFRX_SlotInit() functions follows the SPDIFRX Block
74   configuration procedures for Master mode and Slave mode (details for these procedures
75   are available in reference manual(RMxxxx).
76 
77 @endverbatim
78   * @{
79   */
80 
81 /**
82   * @brief  Deinitialize the SPDIFRXx peripheral registers to their default reset values.
83   * @param  void
84   * @retval None
85   */
SPDIFRX_DeInit(void)86 void SPDIFRX_DeInit(void)
87 {
88   /* Enable SPDIFRX reset state */
89   RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPDIFRX, ENABLE);
90   /* Release SPDIFRX from reset state */
91   RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPDIFRX, DISABLE);
92 }
93 
94 /**
95   * @brief  Initializes the SPDIFRX  peripheral according to the specified
96   *         parameters in the SPDIFRX_InitStruct.
97   *
98   * @note   SPDIFRX clock is generated from a specific output of the PLLSPDIFRX or a specific
99   *         output of the PLLI2S or from an alternate function bypassing the PLL I2S.
100   *
101   * @param  SPDIFRX_InitStruct: pointer to a SPDIFRX_InitTypeDef structure that
102   *         contains the configuration information for the specified SPDIFRX Block peripheral.
103   * @retval None
104   */
SPDIFRX_Init(SPDIFRX_InitTypeDef * SPDIFRX_InitStruct)105 void SPDIFRX_Init(SPDIFRX_InitTypeDef* SPDIFRX_InitStruct)
106 {
107   uint32_t tmpreg = 0;
108 
109   /* Check the SPDIFRX parameters */
110   assert_param(IS_STEREO_MODE(SPDIFRX_InitStruct->SPDIFRX_StereoMode));
111   assert_param(IS_SPDIFRX_INPUT_SELECT(SPDIFRX_InitStruct->SPDIFRX_InputSelection));
112   assert_param(IS_SPDIFRX_MAX_RETRIES(SPDIFRX_InitStruct->SPDIFRX_Retries));
113   assert_param(IS_SPDIFRX_WAIT_FOR_ACTIVITY(SPDIFRX_InitStruct->SPDIFRX_WaitForActivity));
114   assert_param(IS_SPDIFRX_CHANNEL(SPDIFRX_InitStruct->SPDIFRX_ChannelSelection));
115   assert_param(IS_SPDIFRX_DATA_FORMAT(SPDIFRX_InitStruct->SPDIFRX_DataFormat));
116 
117   /* SPDIFRX CR Configuration */
118   /* Get the SPDIFRX CR value */
119   tmpreg = SPDIFRX->CR;
120   /* Clear INSEL, WFA, NBTR, CHSEL, DRFMT and RXSTEO bits */
121   tmpreg &= CR_CLEAR_MASK;
122   /* Configure SPDIFRX: Input selection, Maximum allowed re-tries during synchronization phase,
123   wait for activity, Channel Selection, Data samples format and stereo/mono mode */
124   /* Set INSEL bits according to SPDIFRX_InputSelection value   */
125   /* Set WFA   bit  according to SPDIFRX_WaitForActivity value  */
126   /* Set NBTR  bit  according to SPDIFRX_Retries value          */
127   /* Set CHSEL bit  according to SPDIFRX_ChannelSelection value */
128   /* Set DRFMT bits according to SPDIFRX_DataFormat value       */
129   /* Set RXSTEO bit according to SPDIFRX_StereoMode value       */
130 
131   tmpreg |= (uint32_t)(SPDIFRX_InitStruct->SPDIFRX_InputSelection   | SPDIFRX_InitStruct->SPDIFRX_WaitForActivity   |
132                        SPDIFRX_InitStruct->SPDIFRX_Retries          | SPDIFRX_InitStruct->SPDIFRX_ChannelSelection  |
133                        SPDIFRX_InitStruct->SPDIFRX_DataFormat       | SPDIFRX_InitStruct->SPDIFRX_StereoMode
134                        );
135 
136   /* Write to SPDIFRX CR */
137   SPDIFRX->CR = tmpreg;
138 }
139 
140 /**
141   * @brief  Fills each SPDIFRX_InitStruct member with its default value.
142   * @param  SPDIFRX_InitStruct: pointer to a SPDIFRX_InitTypeDef structure which will
143   *         be initialized.
144   * @retval None
145   */
SPDIFRX_StructInit(SPDIFRX_InitTypeDef * SPDIFRX_InitStruct)146 void SPDIFRX_StructInit(SPDIFRX_InitTypeDef* SPDIFRX_InitStruct)
147 {
148   /* Reset SPDIFRX init structure parameters values */
149   /* Initialize the PDIF_InputSelection member */
150   SPDIFRX_InitStruct->SPDIFRX_InputSelection = SPDIFRX_Input_IN0;
151   /* Initialize the SPDIFRX_WaitForActivity member */
152   SPDIFRX_InitStruct->SPDIFRX_WaitForActivity = SPDIFRX_WaitForActivity_On;
153   /* Initialize the SPDIFRX_Retries member */
154   SPDIFRX_InitStruct->SPDIFRX_Retries = SPDIFRX_16MAX_RETRIES;
155   /* Initialize the SPDIFRX_ChannelSelection member */
156   SPDIFRX_InitStruct->SPDIFRX_ChannelSelection = SPDIFRX_Select_Channel_A;
157   /* Initialize the SPDIFRX_DataFormat member */
158   SPDIFRX_InitStruct->SPDIFRX_DataFormat = SPDIFRX_MSB_DataFormat;
159   /* Initialize the SPDIFRX_StereoMode member */
160   SPDIFRX_InitStruct->SPDIFRX_StereoMode = SPDIFRX_StereoMode_Enabled;
161 }
162 
163 /**
164   * @brief  Enables or disables the SPDIFRX frame x bit.
165   * @param  NewState: new state of the selected SPDIFRX frame bit.
166   *          This parameter can be: ENABLE or DISABLE.
167   * @retval None
168   */
SPDIFRX_SetPreambleTypeBit(FunctionalState NewState)169 void SPDIFRX_SetPreambleTypeBit(FunctionalState NewState)
170 {
171   /* Check the parameters */
172   assert_param(IS_FUNCTIONAL_STATE(NewState));
173 
174   if (NewState != DISABLE)
175   {
176     /* Enable the selected SPDIFRX frame bit */
177     SPDIFRX->CR |= SPDIFRX_CR_PTMSK;
178   }
179   else
180   {
181     /* Disable the selected SPDIFRX frame bit */
182     SPDIFRX->CR &= ~(SPDIFRX_CR_PTMSK);
183   }
184 }
185 
186 /**
187   * @brief  Enables or disables the SPDIFRX frame x bit.
188   * @param  NewState: new state of the selected SPDIFRX frame bit.
189   *          This parameter can be: ENABLE or DISABLE.
190   * @retval None
191   */
SPDIFRX_SetUserDataChannelStatusBits(FunctionalState NewState)192 void SPDIFRX_SetUserDataChannelStatusBits(FunctionalState NewState)
193 {
194   /* Check the parameters */
195   assert_param(IS_FUNCTIONAL_STATE(NewState));
196 
197   if (NewState != DISABLE)
198   {
199     /* Enable the selected SPDIFRX frame bit */
200     SPDIFRX->CR |= SPDIFRX_CR_CUMSK;
201   }
202   else
203   {
204     /* Disable the selected SPDIFRX frame bit */
205     SPDIFRX->CR &= ~(SPDIFRX_CR_CUMSK);
206   }
207 }
208 
209 /**
210   * @brief  Enables or disables the SPDIFRX frame x bit.
211   * @param  NewState: new state of the selected SPDIFRX frame bit.
212   *          This parameter can be: ENABLE or DISABLE.
213   * @retval None
214   */
SPDIFRX_SetValidityBit(FunctionalState NewState)215 void SPDIFRX_SetValidityBit(FunctionalState NewState)
216 {
217   /* Check the parameters */
218   assert_param(IS_FUNCTIONAL_STATE(NewState));
219 
220   if (NewState != DISABLE)
221   {
222     /* Enable the selected SPDIFRX frame bit */
223     SPDIFRX->CR |= SPDIFRX_CR_VMSK;
224   }
225   else
226   {
227     /* Disable the selected SPDIFRX frame bit */
228     SPDIFRX->CR &= ~(SPDIFRX_CR_VMSK);
229   }
230 }
231 
232 /**
233   * @brief  Enables or disables the SPDIFRX frame x bit.
234   * @param  NewState: new state of the selected SPDIFRX frame bit.
235   *          This parameter can be: ENABLE or DISABLE.
236   * @retval None
237   */
SPDIFRX_SetParityBit(FunctionalState NewState)238 void SPDIFRX_SetParityBit(FunctionalState NewState)
239 {
240   /* Check the parameters */
241   assert_param(IS_FUNCTIONAL_STATE(NewState));
242 
243   if (NewState != DISABLE)
244   {
245     /* Enable the selected SPDIFRX frame bit */
246     SPDIFRX->CR |= SPDIFRX_CR_PMSK;
247   }
248   else
249   {
250     /* Disable the selected SPDIFRX frame bit */
251     SPDIFRX->CR &= ~(SPDIFRX_CR_PMSK);
252   }
253 }
254 
255 /**
256   * @brief  Enables or disables the SPDIFRX DMA interface (RX).
257   * @param  NewState: new state of the selected SPDIFRX DMA transfer request.
258   *          This parameter can be: ENABLE or DISABLE.
259   * @retval None
260   */
SPDIFRX_RxDMACmd(FunctionalState NewState)261 void SPDIFRX_RxDMACmd(FunctionalState NewState)
262 {
263   /* Check the parameters */
264   assert_param(IS_FUNCTIONAL_STATE(NewState));
265 
266   if (NewState != DISABLE)
267   {
268     /* Enable the selected SPDIFRX DMA requests */
269     SPDIFRX->CR |= SPDIFRX_CR_RXDMAEN;
270   }
271   else
272   {
273     /* Disable the selected SPDIFRX DMA requests */
274     SPDIFRX->CR &= ~(SPDIFRX_CR_RXDMAEN);
275   }
276 }
277 
278 /**
279   * @brief  Enables or disables the SPDIFRX DMA interface (Control Buffer).
280   * @param  NewState: new state of the selected SPDIFRX DMA transfer request.
281   *          This parameter can be: ENABLE or DISABLE.
282   * @retval None
283   */
SPDIFRX_CbDMACmd(FunctionalState NewState)284 void SPDIFRX_CbDMACmd(FunctionalState NewState)
285 {
286   /* Check the parameters */
287   assert_param(IS_FUNCTIONAL_STATE(NewState));
288 
289   if (NewState != DISABLE)
290   {
291     /* Enable the selected SPDIFRX DMA requests */
292     SPDIFRX->CR |= SPDIFRX_CR_CBDMAEN;
293   }
294   else
295   {
296     /* Disable the selected SPDIFRX DMA requests */
297     SPDIFRX->CR &= ~(SPDIFRX_CR_CBDMAEN);
298   }
299 }
300 
301 /**
302   * @brief  Enables or disables the SPDIFRX peripheral.
303   * @param  SPDIFRX_State: specifies the SPDIFRX peripheral state.
304   *          This parameter can be one of the following values:
305   *            @arg SPDIFRX_STATE_IDLE : Disable SPDIFRX-RX (STATE_IDLE)
306   *            @arg SPDIFRX_STATE_SYNC : Enable SPDIFRX-RX Synchronization only
307   *            @arg SPDIFRX_STATE_RCV  : Enable SPDIFRX Receiver
308   * @retval None
309   */
SPDIFRX_Cmd(uint32_t SPDIFRX_State)310 void SPDIFRX_Cmd(uint32_t SPDIFRX_State)
311 {
312   /* Check the parameters */
313   assert_param(IS_SPDIFRX_STATE(SPDIFRX_State));
314 
315   /* Clear SPDIFRXEN bits */
316     SPDIFRX->CR &= ~(SPDIFRX_CR_SPDIFEN);
317   /* Set new SPDIFRXEN value */
318     SPDIFRX->CR |= SPDIFRX_State;
319 }
320 
321 /**
322   * @brief  Enables or disables the specified SPDIFRX Block interrupts.
323   * @param  SPDIFRX_IT: specifies the SPDIFRX interrupt source to be enabled or disabled.
324   *          This parameter can be one of the following values:
325   *            @arg SPDIFRX_IT_RXNE:  RXNE interrupt enable
326   *            @arg SPDIFRX_IT_CSRNE: Control Buffer Ready Interrupt Enable
327   *            @arg SPDIFRX_IT_PERRIE: Parity error interrupt enable
328   *            @arg SPDIFRX_IT_OVRIE:  Overrun error Interrupt Enable
329   *            @arg SPDIFRX_IT_SBLKIE: Synchronization Block Detected Interrupt Enable
330   *            @arg SPDIFRX_IT_SYNCDIE: Synchronization Done
331   *            @arg SPDIFRX_IT_IFEIE: Serial Interface Error Interrupt Enable
332   * @param  NewState: new state of the specified SPDIFRX interrupt.
333   *          This parameter can be: ENABLE or DISABLE.
334   * @retval None
335   */
SPDIFRX_ITConfig(uint32_t SPDIFRX_IT,FunctionalState NewState)336 void SPDIFRX_ITConfig(uint32_t SPDIFRX_IT, FunctionalState NewState)
337 {
338   /* Check the parameters */
339   assert_param(IS_FUNCTIONAL_STATE(NewState));
340   assert_param(IS_SPDIFRX_CONFIG_IT(SPDIFRX_IT));
341 
342   if (NewState != DISABLE)
343   {
344     /* Enable the selected SPDIFRX interrupt */
345     SPDIFRX->IMR |= SPDIFRX_IT;
346   }
347   else
348   {
349     /* Disable the selected SPDIFRX interrupt */
350     SPDIFRX->IMR &= ~(SPDIFRX_IT);
351   }
352 }
353 
354 /**
355   * @brief  Checks whether the specified SPDIFRX flag is set or not.
356   * @param  SPDIFRX_FLAG: specifies the SPDIFRX flag to check.
357   *          This parameter can be one of the following values:
358   *            @arg SPDIFRX_FLAG_RXNE: Read data register not empty flag.
359   *            @arg SPDIFRX_FLAG_CSRNE: The Control Buffer register is not empty flag.
360   *            @arg SPDIFRX_FLAG_PERR: Parity error flag.
361   *            @arg SPDIFRX_FLAG_OVR: Overrun error flag.
362   *            @arg SPDIFRX_FLAG_SBD: Synchronization Block Detected flag.
363   *            @arg SPDIFRX_FLAG_SYNCD: Synchronization Done flag.
364   *            @arg SPDIFRX_FLAG_FERR: Framing error flag.
365   *            @arg SPDIFRX_FLAG_SERR: Synchronization error flag.
366   *            @arg SPDIFRX_FLAG_TERR: Time-out error flag.
367   * @retval The new state of SPDIFRX_FLAG (SET or RESET).
368   */
SPDIFRX_GetFlagStatus(uint32_t SPDIFRX_FLAG)369 FlagStatus SPDIFRX_GetFlagStatus(uint32_t SPDIFRX_FLAG)
370 {
371   FlagStatus bitstatus = RESET;
372 
373   /* Check the parameters */
374   assert_param(IS_SPDIFRX_FLAG(SPDIFRX_FLAG));
375 
376   /* Check the status of the specified SPDIFRX flag */
377   if ((SPDIFRX->SR & SPDIFRX_FLAG) != (uint32_t)RESET)
378   {
379     /* SPDIFRX_FLAG is set */
380     bitstatus = SET;
381   }
382   else
383   {
384     /* SPDIFRX_FLAG is reset */
385     bitstatus = RESET;
386   }
387   /* Return the SPDIFRX_FLAG status */
388   return  bitstatus;
389 }
390 
391 /**
392   * @brief  Clears the specified SPDIFRX flag.
393   * @param  SPDIFRX_FLAG: specifies the SPDIFRX flag to check.
394   *          This parameter can be one of the following values:
395   *            @arg SPDIFRX_FLAG_PERR: Parity error flag.
396   *            @arg SPDIFRX_FLAG_OVR: Overrun error flag.
397   *            @arg SPDIFRX_FLAG_SBD: Synchronization Block Detected flag.
398   *            @arg SPDIFRX_FLAG_SYNCD: Synchronization Done flag.
399   *
400   * @retval None
401   */
SPDIFRX_ClearFlag(uint32_t SPDIFRX_FLAG)402 void SPDIFRX_ClearFlag(uint32_t SPDIFRX_FLAG)
403 {
404   /* Check the parameters */
405   assert_param(IS_SPDIFRX_CLEAR_FLAG(SPDIFRX_FLAG));
406 
407   /* Clear the selected SPDIFRX Block flag */
408   SPDIFRX->IFCR |= SPDIFRX_FLAG;
409 }
410 
411 /**
412   * @brief  Checks whether the specified SPDIFRX interrupt has occurred or not.
413   * @param  SPDIFRX_IT: specifies the SPDIFRX interrupt source to be enabled or disabled.
414   *          This parameter can be one of the following values:
415   *            @arg SPDIFRX_IT_RXNE:  RXNE interrupt enable
416   *            @arg SPDIFRX_IT_CSRNE: Control Buffer Ready Interrupt Enable
417   *            @arg SPDIFRX_IT_PERRIE: Parity error interrupt enable
418   *            @arg SPDIFRX_IT_OVRIE:  Overrun error Interrupt Enable
419   *            @arg SPDIFRX_IT_SBLKIE: Synchronization Block Detected Interrupt Enable
420   *            @arg SPDIFRX_IT_SYNCDIE: Synchronization Done
421   *            @arg SPDIFRX_IT_IFEIE: Serial Interface Error Interrupt Enable
422   * @retval The new state of SPDIFRX_IT (SET or RESET).
423   */
SPDIFRX_GetITStatus(uint32_t SPDIFRX_IT)424 ITStatus SPDIFRX_GetITStatus(uint32_t SPDIFRX_IT)
425 {
426   ITStatus bitstatus = RESET;
427   uint32_t  enablestatus = 0;
428 
429   /* Check the parameters */
430   assert_param(IS_SPDIFRX_CONFIG_IT(SPDIFRX_IT));
431 
432   /* Get the SPDIFRX_IT enable bit status */
433   enablestatus = (SPDIFRX->IMR & SPDIFRX_IT) ;
434 
435   /* Check the status of the specified SPDIFRX interrupt */
436   if (((SPDIFRX->SR & SPDIFRX_IT) != (uint32_t)RESET) && (enablestatus != (uint32_t)RESET))
437   {
438     /* SPDIFRX_IT is set */
439     bitstatus = SET;
440   }
441   else
442   {
443     /* SPDIFRX_IT is reset */
444     bitstatus = RESET;
445   }
446   /* Return the SPDIFRX_IT status */
447   return bitstatus;
448 }
449 
450 /**
451   * @brief  Clears the SPDIFRX interrupt pending bit.
452   * @param  SAI_IT: specifies the SPDIFRX interrupt pending bit to clear.
453   *          This parameter can be one of the following values:
454   *            @arg SPDIFRX_IT_MUTEDET: MUTE detection interrupt.
455   *            @arg SPDIFRX_IT_OVRUDR: overrun/underrun interrupt.
456   *            @arg SPDIFRX_IT_WCKCFG: wrong clock configuration interrupt.
457   *            @arg SPDIFRX_IT_CNRDY: codec not ready interrupt.
458   *            @arg SPDIFRX_IT_AFSDET: anticipated frame synchronization detection interrupt.
459   *            @arg SPDIFRX_IT_LFSDET: late frame synchronization detection interrupt.
460   *
461   * @note    FREQ (FIFO Request) flag is cleared :
462   *          - When the audio block is transmitter and the FIFO is full or the FIFO
463   *            has one data (one buffer mode) depending the bit FTH in the
464   *            SPDIFRX_xCR2 register.
465   *          - When the audio block is receiver and the FIFO is not empty
466   *
467   * @retval None
468   */
SPDIFRX_ClearITPendingBit(uint32_t SPDIFRX_IT)469 void SPDIFRX_ClearITPendingBit(uint32_t SPDIFRX_IT)
470 {
471   /* Check the parameters */
472   assert_param(IS_SPDIFRX_CLEAR_FLAG(SPDIFRX_IT));
473 
474   /* Clear the selected SPDIFRX interrupt pending bit */
475   SPDIFRX->IFCR |= SPDIFRX_IT;
476 }
477 
478 /**
479   * @}
480   */
481 
482 /**
483   * @}
484   */
485 
486 #endif /* STM32F446xx */
487 /**
488   * @}
489   */
490 
491 /**
492   * @}
493   */
494 
495 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
496