Merge branch 'jnosky/master'
[fw/stlink] / exampleF4 / Utilities / STM32F4-Discovery / stm32f4_discovery_audio_codec.c
1 /**
2   ******************************************************************************
3   * @file    stm32f4_discovery_audio_codec.c
4   * @author  MCD Application Team
5   * @version V1.0.0
6   * @date    19-September-2011
7   * @brief   This file includes the low layer driver for CS43L22 Audio Codec
8   *          available on STM32F4-Discovery Kit.  
9   ******************************************************************************
10   * @attention
11   *
12   * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
13   * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
14   * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
15   * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
16   * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
17   * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
18   *
19   * <h2><center>&copy; COPYRIGHT 2011 STMicroelectronics</center></h2>
20   ******************************************************************************  
21   */
22
23 /*==============================================================================================================================
24                                              User NOTES
25 1. How To use this driver:
26 --------------------------
27    - This driver supports STM32F4xx devices on STM32F4-Discovery Kit.
28
29    - Configure the options in file stm32f4_discovery_audio_codec.h in the section CONFIGURATION.
30       Refer to the sections 2 and 3 to have more details on the possible configurations.
31
32    - Call the function EVAL_AUDIO_Init(
33                                     OutputDevice: physical output mode (OUTPUT_DEVICE_SPEAKER, 
34                                                  OUTPUT_DEVICE_HEADPHONE, OUTPUT_DEVICE_AUTO or 
35                                                  OUTPUT_DEVICE_BOTH)
36                                     Volume: initial volume to be set (0 is min (mute), 100 is max (100%)
37                                     AudioFreq: Audio frequency in Hz (8000, 16000, 22500, 32000 ...)
38                                     this parameter is relative to the audio file/stream type.
39                                    )
40       This function configures all the hardware required for the audio application (codec, I2C, I2S, 
41       GPIOs, DMA and interrupt if needed). This function returns 0 if configuration is OK.
42       if the returned value is different from 0 or the function is stuck then the communication with
43       the codec (try to un-plug the power or reset device in this case).
44       + OUTPUT_DEVICE_SPEAKER: only speaker will be set as output for the audio stream.
45       + OUTPUT_DEVICE_HEADPHONE: only headphones will be set as output for the audio stream.
46       + OUTPUT_DEVICE_AUTO: Selection of output device is made through external switch (implemented 
47          into the audio jack on the evaluation board). When the Headphone is connected it is used
48          as output. When the headphone is disconnected from the audio jack, the output is
49          automatically switched to Speaker.
50       + OUTPUT_DEVICE_BOTH: both Speaker and Headphone are used as outputs for the audio stream
51          at the same time.
52
53    - Call the function EVAL_AUDIO_Play(
54                                   pBuffer: pointer to the audio data file address
55                                   Size: size of the buffer to be sent in Bytes
56                                  )
57       to start playing (for the first time) from the audio file/stream.
58
59    - Call the function EVAL_AUDIO_PauseResume(
60                                          Cmd: AUDIO_PAUSE (or 0) to pause playing or AUDIO_RESUME (or 
61                                                any value different from 0) to resume playing.
62                                          )
63        Note. After calling EVAL_AUDIO_PauseResume() function for pause, only EVAL_AUDIO_PauseResume() should be called
64           for resume (it is not allowed to call EVAL_AUDIO_Play() in this case).
65        Note. This function should be called only when the audio file is played or paused (not stopped).
66
67    - For each mode, you may need to implement the relative callback functions into your code.
68       The Callback functions are named EVAL_AUDIO_XXX_CallBack() and only their prototypes are declared in 
69       the stm32f4_discovery_audio_codec.h file. (refer to the example for more details on the callbacks implementations)
70
71    - To Stop playing, to modify the volume level or to mute, use the functions
72        EVAL_AUDIO_Stop(), EVAL_AUDIO_VolumeCtl() and EVAL_AUDIO_Mute().
73
74    - The driver API and the callback functions are at the end of the stm32f4_discovery_audio_codec.h file.
75  
76
77  Driver architecture:
78  --------------------
79  This driver is composed of three main layers:
80    o High Audio Layer: consists of the function API exported in the stm32f4_discovery_audio_codec.h file
81      (EVAL_AUDIO_Init(), EVAL_AUDIO_Play() ...)
82    o Codec Control layer: consists of the functions API controlling the audio codec (CS43L22) and 
83      included as local functions in file stm32f4_discovery_audio_codec.c (Codec_Init(), Codec_Play() ...)
84    o Media Access Layer (MAL): which consists of functions allowing to access the media containing/
85      providing the audio file/stream. These functions are also included as local functions into
86      the stm32f4_discovery_audio_codec.c file (Audio_MAL_Init(), Audio_MAL_Play() ...)
87   Each set of functions (layer) may be implemented independently of the others and customized when 
88   needed.    
89
90 2. Modes description:
91 ---------------------
92      + AUDIO_MAL_MODE_NORMAL : is suitable when the audio file is in a memory location.
93      + AUDIO_MAL_MODE_CIRCULAR: is suitable when the audio data are read either from a 
94         memory location or from a device at real time (double buffer could be used).
95
96 3. DMA interrupts description:
97 ------------------------------
98      + EVAL_AUDIO_IT_TC_ENABLE: Enable this define to use the DMA end of transfer interrupt.
99         then, a callback should be implemented by user to perform specific actions
100         when the DMA has finished the transfer.
101      + EVAL_AUDIO_IT_HT_ENABLE: Enable this define to use the DMA end of half transfer interrupt.
102         then, a callback should be implemented by user to perform specific actions
103         when the DMA has reached the half of the buffer transfer (generally, it is useful 
104         to load the first half of buffer while DMA is loading from the second half).
105      + EVAL_AUDIO_IT_ER_ENABLE: Enable this define to manage the cases of error on DMA transfer.
106
107 4. Known Limitations:
108 ---------------------
109    1- When using the Speaker, if the audio file quality is not high enough, the speaker output
110       may produce high and uncomfortable noise level. To avoid this issue, to use speaker
111       output properly, try to increase audio file sampling rate (typically higher than 48KHz).
112       This operation will lead to larger file size.
113    2- Communication with the audio codec (through I2C) may be corrupted if it is interrupted by some
114       user interrupt routines (in this case, interrupts could be disabled just before the start of 
115       communication then re-enabled when it is over). Note that this communication is only done at
116       the configuration phase (EVAL_AUDIO_Init() or EVAL_AUDIO_Stop()) and when Volume control modification is 
117       performed (EVAL_AUDIO_VolumeCtl() or EVAL_AUDIO_Mute()). When the audio data is played, no communication is 
118       required with the audio codec.
119   3- Parsing of audio file is not implemented (in order to determine audio file properties: Mono/Stereo, Data size, 
120      File size, Audio Frequency, Audio Data header size ...). The configuration is fixed for the given audio file.
121   4- Mono audio streaming is not supported (in order to play mono audio streams, each data should be sent twice 
122      on the I2S or should be duplicated on the source buffer. Or convert the stream in stereo before playing).
123   5- Supports only 16-bit audio data size.
124 ===============================================================================================================================*/
125
126
127 /* Includes ------------------------------------------------------------------*/
128 #include "stm32f4_discovery_audio_codec.h"
129 //ADDED BY ME!!!!!!!!!!!!!!!!!!!!
130 #include "stm32f4xx_conf.h"
131
132 /** @addtogroup Utilities
133   * @{
134   */
135   
136 /** @addtogroup STM32F4_DISCOVERY
137   * @{
138   */
139
140 /** @addtogroup STM32F4_DISCOVERY_AUDIO_CODEC
141   * @brief       This file includes the low layer driver for CS43L22 Audio Codec
142   *              available on STM32F4-Discovery Kit.
143   * @{
144   */ 
145
146 /** @defgroup STM32F4_DISCOVERY_AUDIO_CODEC_Private_Types
147   * @{
148   */ 
149 /**
150   * @}
151   */ 
152   
153 /** @defgroup STM32F4_DISCOVERY_AUDIO_CODEC_Private_Defines
154   * @{
155   */ 
156
157 /* Mask for the bit EN of the I2S CFGR register */
158 #define I2S_ENABLE_MASK                 0x0400
159
160 /* Delay for the Codec to be correctly reset */
161 #define CODEC_RESET_DELAY               0x4FFF
162
163 /* Codec audio Standards */
164 #ifdef I2S_STANDARD_PHILLIPS
165  #define  CODEC_STANDARD                0x04
166  #define I2S_STANDARD                   I2S_Standard_Phillips         
167 #elif defined(I2S_STANDARD_MSB)
168  #define  CODEC_STANDARD                0x00
169  #define I2S_STANDARD                   I2S_Standard_MSB    
170 #elif defined(I2S_STANDARD_LSB)
171  #define  CODEC_STANDARD                0x08
172  #define I2S_STANDARD                   I2S_Standard_LSB    
173 #else 
174  #error "Error: No audio communication standard selected !"
175 #endif /* I2S_STANDARD */
176
177 /* The 7 bits Codec address (sent through I2C interface) */
178 #define CODEC_ADDRESS                   0x94  /* b00100111 */
179 /**
180   * @}
181   */ 
182
183 /** @defgroup STM32F4_DISCOVERY_AUDIO_CODEC_Private_Macros
184   * @{
185   */
186 /**
187   * @}
188   */ 
189   
190 /** @defgroup STM32F4_DISCOVERY_AUDIO_CODEC_Private_Variables
191   * @{
192   */
193 /* This structure is declared global because it is handled by two different functions */
194 static DMA_InitTypeDef DMA_InitStructure; 
195 DMA_InitTypeDef AUDIO_MAL_DMA_InitStructure;
196
197 uint32_t AudioTotalSize = 0xFFFF; /* This variable holds the total size of the audio file */
198 uint32_t AudioRemSize   = 0xFFFF; /* This variable holds the remaining data in audio file */
199 uint16_t *CurrentPos;             /* This variable holds the current position of audio pointer */
200
201 __IO uint32_t  CODECTimeout = CODEC_LONG_TIMEOUT;   
202 __IO uint8_t OutputDev = 0;
203
204
205 __IO uint32_t CurrAudioInterface = AUDIO_INTERFACE_I2S; //AUDIO_INTERFACE_DAC
206 /**
207   * @}
208   */ 
209
210 /** @defgroup STM32F4_DISCOVERY_AUDIO_CODEC_Private_Function_Prototypes
211   * @{
212   */ 
213 /**
214   * @}
215   */ 
216
217 /** @defgroup STM32F4_DISCOVERY_AUDIO_CODEC_Private_Functions
218   * @{
219   */ 
220 static void Audio_MAL_IRQHandler(void);
221 /*-----------------------------------
222                            Audio Codec functions 
223                                     ------------------------------------------*/
224 /* High Layer codec functions */
225 static uint32_t Codec_Init(uint16_t OutputDevice, uint8_t Volume, uint32_t AudioFreq);
226 static uint32_t Codec_DeInit(void);
227 static uint32_t Codec_Play(void);
228 static uint32_t Codec_PauseResume(uint32_t Cmd);
229 static uint32_t Codec_Stop(uint32_t Cmd);
230 static uint32_t Codec_VolumeCtrl(uint8_t Volume);
231 static uint32_t Codec_Mute(uint32_t Cmd);
232 /* Low layer codec functions */
233 static void     Codec_CtrlInterface_Init(void);
234 static void     Codec_CtrlInterface_DeInit(void);
235 static void     Codec_AudioInterface_Init(uint32_t AudioFreq);
236 static void     Codec_AudioInterface_DeInit(void);
237 static void     Codec_Reset(void);
238 static uint32_t Codec_WriteRegister(uint8_t RegisterAddr, uint8_t RegisterValue);
239 static uint32_t Codec_ReadRegister(uint8_t RegisterAddr);
240 static void     Codec_GPIO_Init(void);
241 static void     Codec_GPIO_DeInit(void);
242 static void     Delay(__IO uint32_t nCount);
243 /*----------------------------------------------------------------------------*/
244
245 /*-----------------------------------
246                    MAL (Media Access Layer) functions 
247                                     ------------------------------------------*/
248 /* Peripherals configuration functions */
249 static void     Audio_MAL_Init(void);
250 static void     Audio_MAL_DeInit(void);
251 static void     Audio_MAL_Play(uint32_t Addr, uint32_t Size);
252 static void     Audio_MAL_PauseResume(uint32_t Cmd, uint32_t Addr);
253 static void     Audio_MAL_Stop(void);
254 /*----------------------------------------------------------------------------*/
255
256  /* DMA Stream definitions */
257  uint32_t AUDIO_MAL_DMA_CLOCK    = AUDIO_I2S_DMA_CLOCK;
258  DMA_Stream_TypeDef * AUDIO_MAL_DMA_STREAM   = AUDIO_I2S_DMA_STREAM ;       
259  uint32_t AUDIO_MAL_DMA_DREG     = AUDIO_I2S_DMA_DREG;
260  uint32_t AUDIO_MAL_DMA_CHANNEL  = AUDIO_I2S_DMA_CHANNEL;
261  uint32_t AUDIO_MAL_DMA_IRQ      = AUDIO_I2S_DMA_IRQ  ;
262  uint32_t AUDIO_MAL_DMA_FLAG_TC  = AUDIO_I2S_DMA_FLAG_TC;
263  uint32_t AUDIO_MAL_DMA_FLAG_HT  = AUDIO_I2S_DMA_FLAG_HT;
264  uint32_t AUDIO_MAL_DMA_FLAG_FE  = AUDIO_I2S_DMA_FLAG_FE;
265  uint32_t AUDIO_MAL_DMA_FLAG_TE  = AUDIO_I2S_DMA_FLAG_TE;
266  uint32_t AUDIO_MAL_DMA_FLAG_DME = AUDIO_I2S_DMA_FLAG_DME;
267
268 /**
269   * @brief  Set the current audio interface (I2S or DAC).
270   * @param  Interface: AUDIO_INTERFACE_I2S or AUDIO_INTERFACE_DAC
271   * @retval None
272   */
273 void EVAL_AUDIO_SetAudioInterface(uint32_t Interface)
274 {    
275   CurrAudioInterface = Interface;
276   
277   if (CurrAudioInterface == AUDIO_INTERFACE_I2S)
278   {
279     /* DMA Stream definitions */
280     AUDIO_MAL_DMA_CLOCK    = AUDIO_I2S_DMA_CLOCK;
281     AUDIO_MAL_DMA_STREAM   = AUDIO_I2S_DMA_STREAM;        
282     AUDIO_MAL_DMA_DREG     = AUDIO_I2S_DMA_DREG;
283     AUDIO_MAL_DMA_CHANNEL  = AUDIO_I2S_DMA_CHANNEL;
284     AUDIO_MAL_DMA_IRQ      = AUDIO_I2S_DMA_IRQ  ;
285     AUDIO_MAL_DMA_FLAG_TC  = AUDIO_I2S_DMA_FLAG_TC;
286     AUDIO_MAL_DMA_FLAG_HT  = AUDIO_I2S_DMA_FLAG_HT;
287     AUDIO_MAL_DMA_FLAG_FE  = AUDIO_I2S_DMA_FLAG_FE;
288     AUDIO_MAL_DMA_FLAG_TE  = AUDIO_I2S_DMA_FLAG_TE;
289     AUDIO_MAL_DMA_FLAG_DME = AUDIO_I2S_DMA_FLAG_DME;
290   }
291   else if (Interface == AUDIO_INTERFACE_DAC)
292   {
293     /* DMA Stream definitions */
294     AUDIO_MAL_DMA_CLOCK    = AUDIO_DAC_DMA_CLOCK;
295     AUDIO_MAL_DMA_STREAM   = AUDIO_DAC_DMA_STREAM;        
296     AUDIO_MAL_DMA_DREG     = AUDIO_DAC_DMA_DREG;
297     AUDIO_MAL_DMA_CHANNEL  = AUDIO_DAC_DMA_CHANNEL;
298     AUDIO_MAL_DMA_IRQ      = AUDIO_DAC_DMA_IRQ  ;
299     AUDIO_MAL_DMA_FLAG_TC  = AUDIO_DAC_DMA_FLAG_TC;
300     AUDIO_MAL_DMA_FLAG_HT  = AUDIO_DAC_DMA_FLAG_HT;
301     AUDIO_MAL_DMA_FLAG_FE  = AUDIO_DAC_DMA_FLAG_FE;
302     AUDIO_MAL_DMA_FLAG_TE  = AUDIO_DAC_DMA_FLAG_TE;
303     AUDIO_MAL_DMA_FLAG_DME = AUDIO_DAC_DMA_FLAG_DME;    
304   }
305 }
306
307 /**
308   * @brief  Configure the audio peripherals.
309   * @param  OutputDevice: OUTPUT_DEVICE_SPEAKER, OUTPUT_DEVICE_HEADPHONE,
310   *                       OUTPUT_DEVICE_BOTH or OUTPUT_DEVICE_AUTO .
311   * @param  Volume: Initial volume level (from 0 (Mute) to 100 (Max))
312   * @param  AudioFreq: Audio frequency used to play the audio stream.
313   * @retval 0 if correct communication, else wrong communication
314   */
315 uint32_t EVAL_AUDIO_Init(uint16_t OutputDevice, uint8_t Volume, uint32_t AudioFreq)
316 {    
317   /* Perform low layer Codec initialization */
318   if (Codec_Init(OutputDevice, VOLUME_CONVERT(Volume), AudioFreq) != 0)
319   {
320     return 1;                
321   }
322   else
323   {    
324     /* I2S data transfer preparation:
325     Prepare the Media to be used for the audio transfer from memory to I2S peripheral */
326     Audio_MAL_Init();
327     
328     /* Return 0 when all operations are OK */
329     return 0;
330   }
331 }
332
333 /**
334   * @brief  Deinitializes all the resources used by the codec (those initialized
335   *         by EVAL_AUDIO_Init() function). 
336   * @param  None
337   * @retval 0 if correct communication, else wrong communication
338   */
339 uint32_t EVAL_AUDIO_DeInit(void)
340
341   /* DeInitialize the Media layer */
342   Audio_MAL_DeInit();
343   
344   /* DeInitialize Codec */  
345   Codec_DeInit();  
346   
347   return 0;
348 }
349
350 /**
351   * @brief  Starts playing audio stream from a data buffer for a determined size. 
352   * @param  pBuffer: Pointer to the buffer 
353   * @param  Size: Number of audio data BYTES.
354   * @retval 0 if correct communication, else wrong communication
355   */
356 uint32_t EVAL_AUDIO_Play(uint16_t* pBuffer, uint32_t Size)
357 {
358   /* Set the total number of data to be played (count in half-word) */
359   AudioTotalSize = Size/2;
360
361   /* Call the audio Codec Play function */
362   Codec_Play();
363   
364   /* Update the Media layer and enable it for play */  
365   Audio_MAL_Play((uint32_t)pBuffer, (uint32_t)(DMA_MAX(AudioTotalSize / 2)));
366   
367   /* Update the remaining number of data to be played */
368   AudioRemSize = (Size/2) - DMA_MAX(AudioTotalSize);
369   
370   /* Update the current audio pointer position */
371   CurrentPos = pBuffer + DMA_MAX(AudioTotalSize);
372   
373   return 0;
374 }
375
376 /**
377   * @brief  This function Pauses or Resumes the audio file stream. In case
378   *         of using DMA, the DMA Pause feature is used. In all cases the I2S 
379   *         peripheral is disabled. 
380   * 
381   * @WARNING When calling EVAL_AUDIO_PauseResume() function for pause, only
382   *          this function should be called for resume (use of EVAL_AUDIO_Play() 
383   *          function for resume could lead to unexpected behavior).
384   * 
385   * @param  Cmd: AUDIO_PAUSE (or 0) to pause, AUDIO_RESUME (or any value different
386   *         from 0) to resume. 
387   * @retval 0 if correct communication, else wrong communication
388   */
389 uint32_t EVAL_AUDIO_PauseResume(uint32_t Cmd)
390 {    
391   /* Call the Audio Codec Pause/Resume function */
392   if (Codec_PauseResume(Cmd) != 0)
393   {
394     return 1;
395   }
396   else
397   {
398     /* Call the Media layer pause/resume function */
399     Audio_MAL_PauseResume(Cmd, 0);
400     
401     /* Return 0 if all operations are OK */
402     return 0;
403   }
404 }
405
406 /**
407   * @brief  Stops audio playing and Power down the Audio Codec. 
408   * @param  Option: could be one of the following parameters 
409   *           - CODEC_PDWN_SW: for software power off (by writing registers). 
410   *                            Then no need to reconfigure the Codec after power on.
411   *           - CODEC_PDWN_HW: completely shut down the codec (physically). 
412   *                            Then need to reconfigure the Codec after power on.  
413   * @retval 0 if correct communication, else wrong communication
414   */
415 uint32_t EVAL_AUDIO_Stop(uint32_t Option)
416 {
417   /* Call Audio Codec Stop function */
418   if (Codec_Stop(Option) != 0)
419   {
420     return 1;
421   }
422   else
423   {
424     /* Call Media layer Stop function */
425     Audio_MAL_Stop();
426     
427     /* Update the remaining data number */
428     AudioRemSize = AudioTotalSize;    
429     
430     /* Return 0 when all operations are correctly done */
431     return 0;
432   }
433 }
434
435 /**
436   * @brief  Controls the current audio volume level. 
437   * @param  Volume: Volume level to be set in percentage from 0% to 100% (0 for 
438   *         Mute and 100 for Max volume level).
439   * @retval 0 if correct communication, else wrong communication
440   */
441 uint32_t EVAL_AUDIO_VolumeCtl(uint8_t Volume)
442 {
443   /* Call the codec volume control function with converted volume value */
444   return (Codec_VolumeCtrl(VOLUME_CONVERT(Volume)));
445 }
446
447 /**
448   * @brief  Enables or disables the MUTE mode by software 
449   * @param  Command: could be AUDIO_MUTE_ON to mute sound or AUDIO_MUTE_OFF to 
450   *         unmute the codec and restore previous volume level.
451   * @retval 0 if correct communication, else wrong communication
452   */
453 uint32_t EVAL_AUDIO_Mute(uint32_t Cmd)
454
455   /* Call the Codec Mute function */
456   return (Codec_Mute(Cmd));
457 }
458
459 /**
460   * @brief  This function handles main Media layer interrupt. 
461   * @param  None
462   * @retval 0 if correct communication, else wrong communication
463   */
464 static void Audio_MAL_IRQHandler(void)
465 {    
466 #ifndef AUDIO_MAL_MODE_NORMAL
467   uint16_t *pAddr = (uint16_t *)CurrentPos;
468   uint32_t Size = AudioRemSize;
469 #endif /* AUDIO_MAL_MODE_NORMAL */
470   
471 #ifdef AUDIO_MAL_DMA_IT_TC_EN
472   /* Transfer complete interrupt */
473   if (DMA_GetFlagStatus(AUDIO_MAL_DMA_STREAM, AUDIO_MAL_DMA_FLAG_TC) != RESET)
474   {         
475  #ifdef AUDIO_MAL_MODE_NORMAL
476     /* Check if the end of file has been reached */
477     if (AudioRemSize > 0)
478     {      
479       /* Wait the DMA Stream to be effectively disabled */
480       while (DMA_GetCmdStatus(AUDIO_MAL_DMA_STREAM) != DISABLE)
481       {}
482       
483       /* Clear the Interrupt flag */
484       DMA_ClearFlag(AUDIO_MAL_DMA_STREAM, AUDIO_MAL_DMA_FLAG_TC);  
485       
486       /* Re-Configure the buffer address and size */
487       DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t) CurrentPos;
488       DMA_InitStructure.DMA_BufferSize = (uint32_t) (DMA_MAX(AudioRemSize));
489       
490       /* Configure the DMA Stream with the new parameters */
491       DMA_Init(AUDIO_MAL_DMA_STREAM, &DMA_InitStructure);
492       
493       /* Enable the I2S DMA Stream*/
494       DMA_Cmd(AUDIO_MAL_DMA_STREAM, ENABLE);    
495       
496       /* Update the current pointer position */
497       CurrentPos += DMA_MAX(AudioRemSize);        
498       
499       /* Update the remaining number of data to be played */
500       AudioRemSize -= DMA_MAX(AudioRemSize);    
501     }
502     else
503     {
504       /* Disable the I2S DMA Stream*/
505       DMA_Cmd(AUDIO_MAL_DMA_STREAM, DISABLE);   
506       
507       /* Clear the Interrupt flag */
508       DMA_ClearFlag(AUDIO_MAL_DMA_STREAM, AUDIO_MAL_DMA_FLAG_TC);       
509       
510       /* Manage the remaining file size and new address offset: This function 
511       should be coded by user (its prototype is already declared in stm32f4_discovery_audio_codec.h) */  
512       EVAL_AUDIO_TransferComplete_CallBack((uint32_t)CurrentPos, 0);       
513     }
514     
515  #elif defined(AUDIO_MAL_MODE_CIRCULAR)
516     /* Manage the remaining file size and new address offset: This function 
517        should be coded by user (its prototype is already declared in stm32f4_discovery_audio_codec.h) */  
518     EVAL_AUDIO_TransferComplete_CallBack(pAddr, Size);    
519     
520     /* Clear the Interrupt flag */
521     DMA_ClearFlag(AUDIO_MAL_DMA_STREAM, AUDIO_MAL_DMA_FLAG_TC);
522  #endif /* AUDIO_MAL_MODE_NORMAL */  
523   }
524 #endif /* AUDIO_MAL_DMA_IT_TC_EN */
525
526 #ifdef AUDIO_MAL_DMA_IT_HT_EN  
527   /* Half Transfer complete interrupt */
528   if (DMA_GetFlagStatus(AUDIO_MAL_DMA_STREAM, AUDIO_MAL_DMA_FLAG_HT) != RESET)
529   {
530     /* Manage the remaining file size and new address offset: This function 
531        should be coded by user (its prototype is already declared in stm32f4_discovery_audio_codec.h) */  
532     EVAL_AUDIO_HalfTransfer_CallBack((uint32_t)pAddr, Size);    
533    
534     /* Clear the Interrupt flag */
535     DMA_ClearFlag(AUDIO_MAL_DMA_STREAM, AUDIO_MAL_DMA_FLAG_HT);    
536   }
537 #endif /* AUDIO_MAL_DMA_IT_HT_EN */
538   
539 #ifdef AUDIO_MAL_DMA_IT_TE_EN  
540   /* FIFO Error interrupt */
541   if ((DMA_GetFlagStatus(AUDIO_MAL_DMA_STREAM, AUDIO_MAL_DMA_FLAG_TE) != RESET) || \
542      (DMA_GetFlagStatus(AUDIO_MAL_DMA_STREAM, AUDIO_MAL_DMA_FLAG_FE) != RESET) || \
543      (DMA_GetFlagStatus(AUDIO_MAL_DMA_STREAM, AUDIO_MAL_DMA_FLAG_DME) != RESET))
544     
545   {
546     /* Manage the error generated on DMA FIFO: This function 
547        should be coded by user (its prototype is already declared in stm32f4_discovery_audio_codec.h) */  
548     EVAL_AUDIO_Error_CallBack((uint32_t*)&pAddr);    
549     
550     /* Clear the Interrupt flag */
551     DMA_ClearFlag(AUDIO_MAL_DMA_STREAM, AUDIO_MAL_DMA_FLAG_TE | AUDIO_MAL_DMA_FLAG_FE | \
552                                         AUDIO_MAL_DMA_FLAG_DME);
553   }  
554 #endif /* AUDIO_MAL_DMA_IT_TE_EN */
555 }
556
557 /**
558   * @brief  This function handles main I2S interrupt. 
559   * @param  None
560   * @retval 0 if correct communication, else wrong communication
561   */
562 void Audio_MAL_I2S_IRQHandler(void)
563
564   Audio_MAL_IRQHandler();
565 }
566
567 /**
568   * @brief  This function handles main DAC interrupt. 
569   * @param  None
570   * @retval 0 if correct communication, else wrong communication
571   */
572 void Audio_MAL_DAC_IRQHandler(void)
573
574   Audio_MAL_IRQHandler();
575 }
576
577 /**
578   * @brief  I2S interrupt management
579   * @param  None
580   * @retval None
581   */
582 void Audio_I2S_IRQHandler(void)
583 {
584   /* Check on the I2S TXE flag */  
585   if (SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_TXE) != RESET)
586   { 
587     if (CurrAudioInterface == AUDIO_INTERFACE_DAC)
588     {
589       /* Wirte data to the DAC interface */
590       DAC_SetChannel1Data(DAC_Align_12b_L, EVAL_AUDIO_GetSampleCallBack()); 
591     }
592     
593     /* Send dummy data on I2S to avoid the underrun condition */
594     SPI_I2S_SendData(CODEC_I2S, EVAL_AUDIO_GetSampleCallBack()); 
595   }
596 }
597 /*========================
598
599                 CS43L22 Audio Codec Control Functions
600                                                 ==============================*/
601 /**
602   * @brief  Initializes the audio codec and all related interfaces (control 
603   *         interface: I2C and audio interface: I2S)
604   * @param  OutputDevice: can be OUTPUT_DEVICE_SPEAKER, OUTPUT_DEVICE_HEADPHONE,
605   *                       OUTPUT_DEVICE_BOTH or OUTPUT_DEVICE_AUTO .
606   * @param  Volume: Initial volume level (from 0 (Mute) to 100 (Max))
607   * @param  AudioFreq: Audio frequency used to play the audio stream.
608   * @retval 0 if correct communication, else wrong communication
609   */
610 static uint32_t Codec_Init(uint16_t OutputDevice, uint8_t Volume, uint32_t AudioFreq)
611 {
612   uint32_t counter = 0; 
613
614   /* Configure the Codec related IOs */
615   Codec_GPIO_Init();   
616   
617   /* Reset the Codec Registers */
618   Codec_Reset();
619
620   /* Initialize the Control interface of the Audio Codec */
621   Codec_CtrlInterface_Init();     
622   
623   /* Keep Codec powered OFF */
624   counter += Codec_WriteRegister(0x02, 0x01);  
625       
626   counter += Codec_WriteRegister(0x04, 0xAF); /* SPK always OFF & HP always ON */
627   OutputDev = 0xAF;
628   
629   /* Clock configuration: Auto detection */  
630   counter += Codec_WriteRegister(0x05, 0x81);
631   
632   /* Set the Slave Mode and the audio Standard */  
633   counter += Codec_WriteRegister(0x06, CODEC_STANDARD);
634       
635   /* Set the Master volume */
636   Codec_VolumeCtrl(Volume);
637   
638   if (CurrAudioInterface == AUDIO_INTERFACE_DAC)
639   {
640     /* Enable the PassThrough on AIN1A and AIN1B */
641     counter += Codec_WriteRegister(0x08, 0x01);
642     counter += Codec_WriteRegister(0x09, 0x01);
643     
644     /* Route the analog input to the HP line */
645     counter += Codec_WriteRegister(0x0E, 0xC0);
646     
647     /* Set the Passthough volume */
648     counter += Codec_WriteRegister(0x14, 0x00);
649     counter += Codec_WriteRegister(0x15, 0x00);
650   }
651
652   /* Power on the Codec */
653   counter += Codec_WriteRegister(0x02, 0x9E);  
654   
655   /* Additional configuration for the CODEC. These configurations are done to reduce
656       the time needed for the Codec to power off. If these configurations are removed, 
657       then a long delay should be added between powering off the Codec and switching 
658       off the I2S peripheral MCLK clock (which is the operating clock for Codec).
659       If this delay is not inserted, then the codec will not shut down properly and
660       it results in high noise after shut down. */
661   
662   /* Disable the analog soft ramp */
663   counter += Codec_WriteRegister(0x0A, 0x00);
664   if (CurrAudioInterface != AUDIO_INTERFACE_DAC)
665   {  
666     /* Disable the digital soft ramp */
667     counter += Codec_WriteRegister(0x0E, 0x04);
668   }
669   /* Disable the limiter attack level */
670   counter += Codec_WriteRegister(0x27, 0x00);
671   /* Adjust Bass and Treble levels */
672   counter += Codec_WriteRegister(0x1F, 0x0F);
673   /* Adjust PCM volume level */
674   counter += Codec_WriteRegister(0x1A, 0x0A);
675   counter += Codec_WriteRegister(0x1B, 0x0A);
676
677   /* Configure the I2S peripheral */
678   Codec_AudioInterface_Init(AudioFreq);  
679   
680   /* Return communication control value */
681   return counter;  
682 }
683
684 /**
685   * @brief  Restore the audio codec state to default state and free all used 
686   *         resources.
687   * @param  None
688   * @retval 0 if correct communication, else wrong communication
689   */
690 static uint32_t Codec_DeInit(void)
691 {
692   uint32_t counter = 0; 
693
694   /* Reset the Codec Registers */
695   Codec_Reset();  
696   
697   /* Keep Codec powered OFF */
698   counter += Codec_WriteRegister(0x02, 0x01);    
699   
700   /* Deinitialize all use GPIOs */
701   Codec_GPIO_DeInit();
702
703   /* Disable the Codec control interface */
704   Codec_CtrlInterface_DeInit();
705   
706   /* Deinitialize the Codec audio interface (I2S) */
707   Codec_AudioInterface_DeInit(); 
708   
709   /* Return communication control value */
710   return counter;  
711 }
712
713 /**
714   * @brief  Start the audio Codec play feature.
715   * @note   For this codec no Play options are required.
716   * @param  None
717   * @retval 0 if correct communication, else wrong communication
718   */
719 static uint32_t Codec_Play(void)
720 {
721   /* 
722      No actions required on Codec level for play command
723      */  
724
725   /* Return communication control value */
726   return 0;  
727 }
728
729 /**
730   * @brief  Pauses and resumes playing on the audio codec.
731   * @param  Cmd: AUDIO_PAUSE (or 0) to pause, AUDIO_RESUME (or any value different
732   *         from 0) to resume. 
733   * @retval 0 if correct communication, else wrong communication
734   */
735 static uint32_t Codec_PauseResume(uint32_t Cmd)
736 {
737   uint32_t counter = 0;   
738   
739   /* Pause the audio file playing */
740   if (Cmd == AUDIO_PAUSE)
741   { 
742     /* Mute the output first */
743     counter += Codec_Mute(AUDIO_MUTE_ON);
744
745     /* Put the Codec in Power save mode */    
746     counter += Codec_WriteRegister(0x02, 0x01);    
747   }
748   else /* AUDIO_RESUME */
749   {
750     /* Unmute the output first */
751     counter += Codec_Mute(AUDIO_MUTE_OFF);
752     
753     counter += Codec_WriteRegister(0x04, OutputDev);
754     
755     /* Exit the Power save mode */
756     counter += Codec_WriteRegister(0x02, 0x9E); 
757   }
758
759   return counter;
760 }
761
762 /**
763   * @brief  Stops audio Codec playing. It powers down the codec.
764   * @param  CodecPdwnMode: selects the  power down mode.
765   *          - CODEC_PDWN_SW: only mutes the audio codec. When resuming from this 
766   *                           mode the codec keeps the previous initialization
767   *                           (no need to re-Initialize the codec registers).
768   *          - CODEC_PDWN_HW: Physically power down the codec. When resuming from this
769   *                           mode, the codec is set to default configuration 
770   *                           (user should re-Initialize the codec in order to 
771   *                            play again the audio stream).
772   * @retval 0 if correct communication, else wrong communication
773   */
774 static uint32_t Codec_Stop(uint32_t CodecPdwnMode)
775 {
776   uint32_t counter = 0;   
777
778   /* Mute the output first */
779   Codec_Mute(AUDIO_MUTE_ON);
780   
781   if (CodecPdwnMode == CODEC_PDWN_SW)
782   {    
783     /* Power down the DAC and the speaker (PMDAC and PMSPK bits)*/
784     counter += Codec_WriteRegister(0x02, 0x9F);
785   }
786   else /* CODEC_PDWN_HW */
787   { 
788     /* Power down the DAC components */
789     counter += Codec_WriteRegister(0x02, 0x9F);
790     
791     /* Wait at least 100us */
792     Delay(0xFFF);
793     
794     /* Reset The pin */
795     GPIO_WriteBit(AUDIO_RESET_GPIO, AUDIO_RESET_PIN, Bit_RESET);
796   }
797   
798   return counter;    
799 }
800
801 /**
802   * @brief  Sets higher or lower the codec volume level.
803   * @param  Volume: a byte value from 0 to 255 (refer to codec registers 
804   *         description for more details).
805   * @retval 0 if correct communication, else wrong communication
806   */
807 static uint32_t Codec_VolumeCtrl(uint8_t Volume)
808 {
809   uint32_t counter = 0;
810   
811   if (Volume > 0xE6)
812   {
813     /* Set the Master volume */
814     counter += Codec_WriteRegister(0x20, Volume - 0xE7); 
815     counter += Codec_WriteRegister(0x21, Volume - 0xE7);     
816   }
817   else
818   {
819     /* Set the Master volume */
820     counter += Codec_WriteRegister(0x20, Volume + 0x19); 
821     counter += Codec_WriteRegister(0x21, Volume + 0x19); 
822   }
823
824   return counter;  
825 }
826
827 /**
828   * @brief  Enables or disables the mute feature on the audio codec.
829   * @param  Cmd: AUDIO_MUTE_ON to enable the mute or AUDIO_MUTE_OFF to disable the
830   *             mute mode.
831   * @retval 0 if correct communication, else wrong communication
832   */
833 static uint32_t Codec_Mute(uint32_t Cmd)
834 {
835   uint32_t counter = 0;  
836   
837   /* Set the Mute mode */
838   if (Cmd == AUDIO_MUTE_ON)
839   {
840     counter += Codec_WriteRegister(0x04, 0xFF);
841   }
842   else /* AUDIO_MUTE_OFF Disable the Mute */
843   {
844     counter += Codec_WriteRegister(0x04, OutputDev);
845   }
846   
847   return counter; 
848 }
849
850 /**
851   * @brief  Resets the audio codec. It restores the default configuration of the 
852   *         codec (this function shall be called before initializing the codec).
853   * @note   This function calls an external driver function: The IO Expander driver.
854   * @param  None
855   * @retval None
856   */
857 static void Codec_Reset(void)
858 {
859   /* Power Down the codec */
860   GPIO_WriteBit(AUDIO_RESET_GPIO, AUDIO_RESET_PIN, Bit_RESET);
861
862   /* wait for a delay to insure registers erasing */
863   Delay(CODEC_RESET_DELAY); 
864   
865   /* Power on the codec */
866   GPIO_WriteBit(AUDIO_RESET_GPIO, AUDIO_RESET_PIN, Bit_SET);
867 }
868
869 /**
870   * @brief  Writes a Byte to a given register into the audio codec through the 
871             control interface (I2C)
872   * @param  RegisterAddr: The address (location) of the register to be written.
873   * @param  RegisterValue: the Byte value to be written into destination register.
874   * @retval 0 if correct communication, else wrong communication
875   */
876 static uint32_t Codec_WriteRegister(uint8_t RegisterAddr, uint8_t RegisterValue)
877 {
878   uint32_t result = 0;
879
880   /*!< While the bus is busy */
881   CODECTimeout = CODEC_LONG_TIMEOUT;
882   while(I2C_GetFlagStatus(CODEC_I2C, I2C_FLAG_BUSY))
883   {
884     if((CODECTimeout--) == 0) return Codec_TIMEOUT_UserCallback();
885   }
886   
887   /* Start the config sequence */
888   I2C_GenerateSTART(CODEC_I2C, ENABLE);
889
890   /* Test on EV5 and clear it */
891   CODECTimeout = CODEC_FLAG_TIMEOUT;
892   while (!I2C_CheckEvent(CODEC_I2C, I2C_EVENT_MASTER_MODE_SELECT))
893   {
894     if((CODECTimeout--) == 0) return Codec_TIMEOUT_UserCallback();
895   }
896   
897   /* Transmit the slave address and enable writing operation */
898   I2C_Send7bitAddress(CODEC_I2C, CODEC_ADDRESS, I2C_Direction_Transmitter);
899
900   /* Test on EV6 and clear it */
901   CODECTimeout = CODEC_FLAG_TIMEOUT;
902   while (!I2C_CheckEvent(CODEC_I2C, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
903   {
904     if((CODECTimeout--) == 0) return Codec_TIMEOUT_UserCallback();
905   }
906
907   /* Transmit the first address for write operation */
908   I2C_SendData(CODEC_I2C, RegisterAddr);
909
910   /* Test on EV8 and clear it */
911   CODECTimeout = CODEC_FLAG_TIMEOUT;
912   while (!I2C_CheckEvent(CODEC_I2C, I2C_EVENT_MASTER_BYTE_TRANSMITTING))
913   {
914     if((CODECTimeout--) == 0) return Codec_TIMEOUT_UserCallback();
915   }
916   
917   /* Prepare the register value to be sent */
918   I2C_SendData(CODEC_I2C, RegisterValue);
919   
920   /*!< Wait till all data have been physically transferred on the bus */
921   CODECTimeout = CODEC_LONG_TIMEOUT;
922   while(!I2C_GetFlagStatus(CODEC_I2C, I2C_FLAG_BTF))
923   {
924     if((CODECTimeout--) == 0) Codec_TIMEOUT_UserCallback();
925   }
926   
927   /* End the configuration sequence */
928   I2C_GenerateSTOP(CODEC_I2C, ENABLE);  
929   
930 #ifdef VERIFY_WRITTENDATA
931   /* Verify that the data has been correctly written */  
932   result = (Codec_ReadRegister(RegisterAddr) == RegisterValue)? 0:1;
933 #endif /* VERIFY_WRITTENDATA */
934
935   /* Return the verifying value: 0 (Passed) or 1 (Failed) */
936   return result;  
937 }
938
939 /**
940   * @brief  Reads and returns the value of an audio codec register through the
941   *         control interface (I2C).
942   * @param  RegisterAddr: Address of the register to be read.
943   * @retval Value of the register to be read or dummy value if the communication
944   *         fails.
945   */
946 static uint32_t Codec_ReadRegister(uint8_t RegisterAddr)
947 {
948   uint32_t result = 0;
949
950   /*!< While the bus is busy */
951   CODECTimeout = CODEC_LONG_TIMEOUT;
952   while(I2C_GetFlagStatus(CODEC_I2C, I2C_FLAG_BUSY))
953   {
954     if((CODECTimeout--) == 0) return Codec_TIMEOUT_UserCallback();
955   }
956   
957   /* Start the config sequence */
958   I2C_GenerateSTART(CODEC_I2C, ENABLE);
959
960   /* Test on EV5 and clear it */
961   CODECTimeout = CODEC_FLAG_TIMEOUT;
962   while (!I2C_CheckEvent(CODEC_I2C, I2C_EVENT_MASTER_MODE_SELECT))
963   {
964     if((CODECTimeout--) == 0) return Codec_TIMEOUT_UserCallback();
965   }
966   
967   /* Transmit the slave address and enable writing operation */
968   I2C_Send7bitAddress(CODEC_I2C, CODEC_ADDRESS, I2C_Direction_Transmitter);
969
970   /* Test on EV6 and clear it */
971   CODECTimeout = CODEC_FLAG_TIMEOUT;
972   while (!I2C_CheckEvent(CODEC_I2C, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
973   {
974     if((CODECTimeout--) == 0) return Codec_TIMEOUT_UserCallback();
975   }
976
977   /* Transmit the register address to be read */
978   I2C_SendData(CODEC_I2C, RegisterAddr);
979
980   /* Test on EV8 and clear it */
981   CODECTimeout = CODEC_FLAG_TIMEOUT;
982   while (I2C_GetFlagStatus(CODEC_I2C, I2C_FLAG_BTF) == RESET)
983   {
984     if((CODECTimeout--) == 0) return Codec_TIMEOUT_UserCallback();
985   }
986   
987   /*!< Send START condition a second time */  
988   I2C_GenerateSTART(CODEC_I2C, ENABLE);
989   
990   /*!< Test on EV5 and clear it (cleared by reading SR1 then writing to DR) */
991   CODECTimeout = CODEC_FLAG_TIMEOUT;
992   while(!I2C_CheckEvent(CODEC_I2C, I2C_EVENT_MASTER_MODE_SELECT))
993   {
994     if((CODECTimeout--) == 0) return Codec_TIMEOUT_UserCallback();
995   } 
996   
997   /*!< Send Codec address for read */
998   I2C_Send7bitAddress(CODEC_I2C, CODEC_ADDRESS, I2C_Direction_Receiver);  
999   
1000   /* Wait on ADDR flag to be set (ADDR is still not cleared at this level */
1001   CODECTimeout = CODEC_FLAG_TIMEOUT;
1002   while(I2C_GetFlagStatus(CODEC_I2C, I2C_FLAG_ADDR) == RESET)
1003   {
1004     if((CODECTimeout--) == 0) return Codec_TIMEOUT_UserCallback();
1005   }     
1006   
1007   /*!< Disable Acknowledgment */
1008   I2C_AcknowledgeConfig(CODEC_I2C, DISABLE);   
1009   
1010   /* Clear ADDR register by reading SR1 then SR2 register (SR1 has already been read) */
1011   (void)CODEC_I2C->SR2;
1012   
1013   /*!< Send STOP Condition */
1014   I2C_GenerateSTOP(CODEC_I2C, ENABLE);
1015   
1016   /* Wait for the byte to be received */
1017   CODECTimeout = CODEC_FLAG_TIMEOUT;
1018   while(I2C_GetFlagStatus(CODEC_I2C, I2C_FLAG_RXNE) == RESET)
1019   {
1020     if((CODECTimeout--) == 0) return Codec_TIMEOUT_UserCallback();
1021   }
1022   
1023   /*!< Read the byte received from the Codec */
1024   result = I2C_ReceiveData(CODEC_I2C);
1025   
1026   /* Wait to make sure that STOP flag has been cleared */
1027   CODECTimeout = CODEC_FLAG_TIMEOUT;
1028   while(CODEC_I2C->CR1 & I2C_CR1_STOP)
1029   {
1030     if((CODECTimeout--) == 0) return Codec_TIMEOUT_UserCallback();
1031   }  
1032   
1033   /*!< Re-Enable Acknowledgment to be ready for another reception */
1034   I2C_AcknowledgeConfig(CODEC_I2C, ENABLE);  
1035   
1036   /* Clear AF flag for next communication */
1037   I2C_ClearFlag(CODEC_I2C, I2C_FLAG_AF); 
1038   
1039   /* Return the byte read from Codec */
1040   return result;
1041 }
1042
1043 /**
1044   * @brief  Initializes the Audio Codec control interface (I2C).
1045   * @param  None
1046   * @retval None
1047   */
1048 static void Codec_CtrlInterface_Init(void)
1049 {
1050   I2C_InitTypeDef I2C_InitStructure;
1051   
1052   /* Enable the CODEC_I2C peripheral clock */
1053   RCC_APB1PeriphClockCmd(CODEC_I2C_CLK, ENABLE);
1054   
1055   /* CODEC_I2C peripheral configuration */
1056   I2C_DeInit(CODEC_I2C);
1057   I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
1058   I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
1059   I2C_InitStructure.I2C_OwnAddress1 = 0x33;
1060   I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
1061   I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
1062   I2C_InitStructure.I2C_ClockSpeed = I2C_SPEED;
1063   /* Enable the I2C peripheral */
1064   I2C_Cmd(CODEC_I2C, ENABLE);  
1065   I2C_Init(CODEC_I2C, &I2C_InitStructure);
1066 }
1067
1068 /**
1069   * @brief  Restore the Audio Codec control interface to its default state.
1070   *         This function doesn't de-initialize the I2C because the I2C peripheral
1071   *         may be used by other modules.
1072   * @param  None
1073   * @retval None
1074   */
1075 static void Codec_CtrlInterface_DeInit(void)
1076 {
1077   /* Disable the I2C peripheral */ /* This step is not done here because 
1078      the I2C interface can be used by other modules */
1079   /* I2C_DeInit(CODEC_I2C); */
1080 }
1081
1082 /**
1083   * @brief  Initializes the Audio Codec audio interface (I2S)
1084   * @note   This function assumes that the I2S input clock (through PLL_R in 
1085   *         Devices RevA/Z and through dedicated PLLI2S_R in Devices RevB/Y)
1086   *         is already configured and ready to be used.    
1087   * @param  AudioFreq: Audio frequency to be configured for the I2S peripheral. 
1088   * @retval None
1089   */
1090 static void Codec_AudioInterface_Init(uint32_t AudioFreq)
1091 {
1092   I2S_InitTypeDef I2S_InitStructure;
1093   DAC_InitTypeDef  DAC_InitStructure;
1094
1095   /* Enable the CODEC_I2S peripheral clock */
1096   RCC_APB1PeriphClockCmd(CODEC_I2S_CLK, ENABLE);
1097   
1098   /* CODEC_I2S peripheral configuration */
1099   SPI_I2S_DeInit(CODEC_I2S);
1100   I2S_InitStructure.I2S_AudioFreq = AudioFreq;
1101   I2S_InitStructure.I2S_Standard = I2S_STANDARD;
1102   I2S_InitStructure.I2S_DataFormat = I2S_DataFormat_16b;
1103   I2S_InitStructure.I2S_CPOL = I2S_CPOL_Low;
1104 #ifdef DAC_USE_I2S_DMA
1105   if (CurrAudioInterface == AUDIO_INTERFACE_DAC)
1106   {  
1107     I2S_InitStructure.I2S_Mode = I2S_Mode_MasterRx;
1108   }
1109   else
1110   {
1111 #else
1112    I2S_InitStructure.I2S_Mode = I2S_Mode_MasterTx;
1113 #endif
1114 #ifdef DAC_USE_I2S_DMA
1115   }
1116 #endif /* DAC_USE_I2S_DMA */
1117 #ifdef CODEC_MCLK_ENABLED
1118   I2S_InitStructure.I2S_MCLKOutput = I2S_MCLKOutput_Enable;
1119 #elif defined(CODEC_MCLK_DISABLED)
1120   I2S_InitStructure.I2S_MCLKOutput = I2S_MCLKOutput_Disable;
1121 #else
1122 #error "No selection for the MCLK output has been defined !"
1123 #endif /* CODEC_MCLK_ENABLED */
1124   
1125   /* Initialize the I2S peripheral with the structure above */
1126   I2S_Init(CODEC_I2S, &I2S_InitStructure);
1127
1128
1129   /* Configure the DAC interface */
1130   if (CurrAudioInterface == AUDIO_INTERFACE_DAC)
1131   {    
1132     /* DAC Periph clock enable */
1133     RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE);
1134     
1135     /* DAC channel1 Configuration */
1136     DAC_InitStructure.DAC_Trigger = DAC_Trigger_None;
1137     DAC_InitStructure.DAC_WaveGeneration = DAC_WaveGeneration_None;
1138     DAC_InitStructure.DAC_OutputBuffer = DAC_OutputBuffer_Enable;
1139     DAC_Init(AUDIO_DAC_CHANNEL, &DAC_InitStructure);
1140     
1141     /* Enable DAC Channel1 */
1142     DAC_Cmd(AUDIO_DAC_CHANNEL, ENABLE);  
1143   }
1144   
1145   /* The I2S peripheral will be enabled only in the EVAL_AUDIO_Play() function 
1146        or by user functions if DMA mode not enabled */  
1147 }
1148
1149 /**
1150   * @brief  Restores the Audio Codec audio interface to its default state.
1151   * @param  None
1152   * @retval None
1153   */
1154 static void Codec_AudioInterface_DeInit(void)
1155 {
1156   /* Disable the CODEC_I2S peripheral (in case it hasn't already been disabled) */
1157   I2S_Cmd(CODEC_I2S, DISABLE);
1158   
1159   /* Deinitialize the CODEC_I2S peripheral */
1160   SPI_I2S_DeInit(CODEC_I2S);
1161   
1162   /* Disable the CODEC_I2S peripheral clock */
1163   RCC_APB1PeriphClockCmd(CODEC_I2S_CLK, DISABLE); 
1164 }
1165
1166 /**
1167   * @brief Initializes IOs used by the Audio Codec (on the control and audio 
1168   *        interfaces).
1169   * @param  None
1170   * @retval None
1171   */
1172 static void Codec_GPIO_Init(void)
1173 {
1174   GPIO_InitTypeDef GPIO_InitStructure;
1175   
1176   /* Enable Reset GPIO Clock */
1177   RCC_AHB1PeriphClockCmd(AUDIO_RESET_GPIO_CLK,ENABLE);
1178   
1179   /* Audio reset pin configuration -------------------------------------------------*/
1180   GPIO_InitStructure.GPIO_Pin = AUDIO_RESET_PIN; 
1181   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
1182   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
1183   GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
1184   GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_NOPULL;
1185   GPIO_Init(AUDIO_RESET_GPIO, &GPIO_InitStructure);    
1186   
1187   /* Enable I2S and I2C GPIO clocks */
1188   RCC_AHB1PeriphClockCmd(CODEC_I2C_GPIO_CLOCK | CODEC_I2S_GPIO_CLOCK, ENABLE);
1189
1190   /* CODEC_I2C SCL and SDA pins configuration -------------------------------------*/
1191   GPIO_InitStructure.GPIO_Pin = CODEC_I2C_SCL_PIN | CODEC_I2C_SDA_PIN; 
1192   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
1193   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
1194   GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
1195   GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_NOPULL;
1196   GPIO_Init(CODEC_I2C_GPIO, &GPIO_InitStructure);     
1197   /* Connect pins to I2C peripheral */
1198   GPIO_PinAFConfig(CODEC_I2C_GPIO, CODEC_I2S_SCL_PINSRC, CODEC_I2C_GPIO_AF);  
1199   GPIO_PinAFConfig(CODEC_I2C_GPIO, CODEC_I2S_SDA_PINSRC, CODEC_I2C_GPIO_AF);  
1200
1201   /* CODEC_I2S pins configuration: WS, SCK and SD pins -----------------------------*/
1202   GPIO_InitStructure.GPIO_Pin = CODEC_I2S_SCK_PIN | CODEC_I2S_SD_PIN; 
1203   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
1204   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
1205   GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
1206   GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
1207   GPIO_Init(CODEC_I2S_GPIO, &GPIO_InitStructure);
1208   
1209   /* Connect pins to I2S peripheral  */
1210   GPIO_PinAFConfig(CODEC_I2S_WS_GPIO, CODEC_I2S_WS_PINSRC, CODEC_I2S_GPIO_AF);  
1211   GPIO_PinAFConfig(CODEC_I2S_GPIO, CODEC_I2S_SCK_PINSRC, CODEC_I2S_GPIO_AF);
1212
1213   if (CurrAudioInterface != AUDIO_INTERFACE_DAC) 
1214   {
1215     GPIO_InitStructure.GPIO_Pin = CODEC_I2S_WS_PIN ;
1216     GPIO_Init(CODEC_I2S_WS_GPIO, &GPIO_InitStructure); 
1217     GPIO_PinAFConfig(CODEC_I2S_GPIO, CODEC_I2S_SD_PINSRC, CODEC_I2S_GPIO_AF);
1218   }
1219   else
1220   {
1221     /* GPIOA clock enable (to be used with DAC) */
1222     RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
1223    
1224     /* DAC channel 1 & 2 (DAC_OUT1 = PA.4) configuration */
1225     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
1226     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
1227     GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
1228     GPIO_Init(GPIOA, &GPIO_InitStructure);
1229   }
1230
1231 #ifdef CODEC_MCLK_ENABLED
1232   /* CODEC_I2S pins configuration: MCK pin */
1233   GPIO_InitStructure.GPIO_Pin = CODEC_I2S_MCK_PIN; 
1234   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
1235   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
1236   GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
1237   GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
1238   GPIO_Init(CODEC_I2S_MCK_GPIO, &GPIO_InitStructure);   
1239   /* Connect pins to I2S peripheral  */
1240   GPIO_PinAFConfig(CODEC_I2S_MCK_GPIO, CODEC_I2S_MCK_PINSRC, CODEC_I2S_GPIO_AF); 
1241 #endif /* CODEC_MCLK_ENABLED */ 
1242 }
1243
1244 /**
1245   * @brief  Restores the IOs used by the Audio Codec interface to their default state.
1246   * @param  None
1247   * @retval None
1248   */
1249 static void Codec_GPIO_DeInit(void)
1250 {
1251   GPIO_InitTypeDef GPIO_InitStructure;
1252   
1253   /* Deinitialize all the GPIOs used by the driver */
1254   GPIO_InitStructure.GPIO_Pin =  CODEC_I2S_SCK_PIN | CODEC_I2S_SD_PIN;
1255   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
1256   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
1257   GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
1258   GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_NOPULL;
1259   GPIO_Init(CODEC_I2S_GPIO, &GPIO_InitStructure);  
1260   
1261   GPIO_InitStructure.GPIO_Pin = CODEC_I2S_WS_PIN ;
1262   GPIO_Init(CODEC_I2S_WS_GPIO, &GPIO_InitStructure); 
1263      
1264   /* Disconnect pins from I2S peripheral  */
1265   GPIO_PinAFConfig(CODEC_I2S_WS_GPIO, CODEC_I2S_WS_PINSRC, 0x00);  
1266   GPIO_PinAFConfig(CODEC_I2S_GPIO, CODEC_I2S_SCK_PINSRC, 0x00);
1267   GPIO_PinAFConfig(CODEC_I2S_GPIO, CODEC_I2S_SD_PINSRC, 0x00);  
1268   
1269 #ifdef CODEC_MCLK_ENABLED
1270   /* CODEC_I2S pins deinitialization: MCK pin */
1271   GPIO_InitStructure.GPIO_Pin = CODEC_I2S_MCK_PIN; 
1272   GPIO_Init(CODEC_I2S_MCK_GPIO, &GPIO_InitStructure);   
1273   /* Disconnect pins from I2S peripheral  */
1274   GPIO_PinAFConfig(CODEC_I2S_MCK_GPIO, CODEC_I2S_MCK_PINSRC, CODEC_I2S_GPIO_AF); 
1275 #endif /* CODEC_MCLK_ENABLED */    
1276 }
1277
1278 /**
1279   * @brief  Inserts a delay time (not accurate timing).
1280   * @param  nCount: specifies the delay time length.
1281   * @retval None
1282   */
1283 static void Delay( __IO uint32_t nCount)
1284 {
1285   for (; nCount != 0; nCount--);
1286 }
1287
1288 #ifdef USE_DEFAULT_TIMEOUT_CALLBACK
1289 /**
1290   * @brief  Basic management of the timeout situation.
1291   * @param  None
1292   * @retval None
1293   */
1294 uint32_t Codec_TIMEOUT_UserCallback(void)
1295 {
1296   /* Block communication and all processes */
1297   while (1)
1298   {   
1299   }
1300 }
1301 #endif /* USE_DEFAULT_TIMEOUT_CALLBACK */
1302 /*========================
1303
1304                 Audio MAL Interface Control Functions
1305
1306                                                 ==============================*/
1307
1308 /**
1309   * @brief  Initializes and prepares the Media to perform audio data transfer 
1310   *         from Media to the I2S peripheral.
1311   * @param  None
1312   * @retval None
1313   */
1314 static void Audio_MAL_Init(void)  
1315
1316   
1317 #ifdef I2S_INTERRUPT  
1318   NVIC_InitTypeDef   NVIC_InitStructure;
1319
1320   NVIC_InitStructure.NVIC_IRQChannel = SPI3_IRQn;
1321   NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
1322   NVIC_InitStructure.NVIC_IRQChannelSubPriority =0;
1323   NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
1324   NVIC_Init(&NVIC_InitStructure);
1325   
1326   SPI_I2S_ITConfig(SPI3, SPI_I2S_IT_TXE, ENABLE);
1327
1328   I2S_Cmd(SPI3, ENABLE); 
1329 #else  
1330 #if defined(AUDIO_MAL_DMA_IT_TC_EN) || defined(AUDIO_MAL_DMA_IT_HT_EN) || defined(AUDIO_MAL_DMA_IT_TE_EN)
1331   NVIC_InitTypeDef NVIC_InitStructure;
1332 #endif
1333
1334   if (CurrAudioInterface == AUDIO_INTERFACE_I2S)
1335   {
1336     /* Enable the DMA clock */
1337     RCC_AHB1PeriphClockCmd(AUDIO_MAL_DMA_CLOCK, ENABLE); 
1338     
1339     /* Configure the DMA Stream */
1340     DMA_Cmd(AUDIO_MAL_DMA_STREAM, DISABLE);
1341     DMA_DeInit(AUDIO_MAL_DMA_STREAM);
1342     /* Set the parameters to be configured */
1343     DMA_InitStructure.DMA_Channel = AUDIO_MAL_DMA_CHANNEL;  
1344     DMA_InitStructure.DMA_PeripheralBaseAddr = AUDIO_MAL_DMA_DREG;
1345     DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)0;      /* This field will be configured in play function */
1346     DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral;
1347     DMA_InitStructure.DMA_BufferSize = (uint32_t)0xFFFE;      /* This field will be configured in play function */
1348     DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
1349     DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
1350     DMA_InitStructure.DMA_PeripheralDataSize = AUDIO_MAL_DMA_PERIPH_DATA_SIZE;
1351     DMA_InitStructure.DMA_MemoryDataSize = AUDIO_MAL_DMA_MEM_DATA_SIZE; 
1352 #ifdef AUDIO_MAL_MODE_NORMAL
1353     DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
1354 #elif defined(AUDIO_MAL_MODE_CIRCULAR)
1355     DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
1356 #else
1357 #error "AUDIO_MAL_MODE_NORMAL or AUDIO_MAL_MODE_CIRCULAR should be selected !!"
1358 #endif /* AUDIO_MAL_MODE_NORMAL */  
1359     DMA_InitStructure.DMA_Priority = DMA_Priority_High;
1360     DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Enable;         
1361     DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
1362     DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
1363     DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;  
1364     DMA_Init(AUDIO_MAL_DMA_STREAM, &DMA_InitStructure);  
1365     
1366     /* Enable the selected DMA interrupts (selected in "stm32f4_discovery_eval_audio_codec.h" defines) */
1367 #ifdef AUDIO_MAL_DMA_IT_TC_EN
1368     DMA_ITConfig(AUDIO_MAL_DMA_STREAM, DMA_IT_TC, ENABLE);
1369 #endif /* AUDIO_MAL_DMA_IT_TC_EN */
1370 #ifdef AUDIO_MAL_DMA_IT_HT_EN
1371     DMA_ITConfig(AUDIO_MAL_DMA_STREAM, DMA_IT_HT, ENABLE);
1372 #endif /* AUDIO_MAL_DMA_IT_HT_EN */
1373 #ifdef AUDIO_MAL_DMA_IT_TE_EN
1374     DMA_ITConfig(AUDIO_MAL_DMA_STREAM, DMA_IT_TE | DMA_IT_FE | DMA_IT_DME, ENABLE);
1375 #endif /* AUDIO_MAL_DMA_IT_TE_EN */
1376     
1377 #if defined(AUDIO_MAL_DMA_IT_TC_EN) || defined(AUDIO_MAL_DMA_IT_HT_EN) || defined(AUDIO_MAL_DMA_IT_TE_EN)
1378     /* I2S DMA IRQ Channel configuration */
1379     NVIC_InitStructure.NVIC_IRQChannel = AUDIO_MAL_DMA_IRQ;
1380     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = EVAL_AUDIO_IRQ_PREPRIO;
1381     NVIC_InitStructure.NVIC_IRQChannelSubPriority = EVAL_AUDIO_IRQ_SUBRIO;
1382     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
1383     NVIC_Init(&NVIC_InitStructure);
1384 #endif     
1385   }
1386
1387 #ifdef DAC_USE_I2S_DMA
1388   else
1389   {
1390     /* Enable the DMA clock */
1391     RCC_AHB1PeriphClockCmd(AUDIO_MAL_DMA_CLOCK, ENABLE); 
1392     
1393     /* Configure the DMA Stream */
1394     DMA_Cmd(AUDIO_MAL_DMA_STREAM, DISABLE);
1395     DMA_DeInit(AUDIO_MAL_DMA_STREAM);
1396     /* Set the parameters to be configured */
1397     DMA_InitStructure.DMA_Channel = AUDIO_MAL_DMA_CHANNEL;  
1398     DMA_InitStructure.DMA_PeripheralBaseAddr = AUDIO_MAL_DMA_DREG;
1399     DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)0;      /* This field will be configured in play function */
1400     DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral;
1401     DMA_InitStructure.DMA_BufferSize = (uint32_t)0xFFFE;      /* This field will be configured in play function */
1402     DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
1403     DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
1404     DMA_InitStructure.DMA_PeripheralDataSize = AUDIO_MAL_DMA_PERIPH_DATA_SIZE;
1405     DMA_InitStructure.DMA_MemoryDataSize = AUDIO_MAL_DMA_MEM_DATA_SIZE; 
1406 #ifdef AUDIO_MAL_MODE_NORMAL
1407     DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
1408 #elif defined(AUDIO_MAL_MODE_CIRCULAR)
1409     DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
1410 #else
1411 #error "AUDIO_MAL_MODE_NORMAL or AUDIO_MAL_MODE_CIRCULAR should be selected !!"
1412 #endif /* AUDIO_MAL_MODE_NORMAL */  
1413     DMA_InitStructure.DMA_Priority = DMA_Priority_High;
1414     DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Enable;         
1415     DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
1416     DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
1417     DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;  
1418     DMA_Init(AUDIO_MAL_DMA_STREAM, &DMA_InitStructure);  
1419     
1420     /* Enable the selected DMA interrupts (selected in "stm32f4_discovery_eval_audio_codec.h" defines) */
1421 #ifdef AUDIO_MAL_DMA_IT_TC_EN
1422     DMA_ITConfig(AUDIO_MAL_DMA_STREAM, DMA_IT_TC, ENABLE);
1423 #endif /* AUDIO_MAL_DMA_IT_TC_EN */
1424 #ifdef AUDIO_MAL_DMA_IT_HT_EN
1425     DMA_ITConfig(AUDIO_MAL_DMA_STREAM, DMA_IT_HT, ENABLE);
1426 #endif /* AUDIO_MAL_DMA_IT_HT_EN */
1427 #ifdef AUDIO_MAL_DMA_IT_TE_EN
1428     DMA_ITConfig(AUDIO_MAL_DMA_STREAM, DMA_IT_TE | DMA_IT_FE | DMA_IT_DME, ENABLE);
1429 #endif /* AUDIO_MAL_DMA_IT_TE_EN */
1430     
1431 #if defined(AUDIO_MAL_DMA_IT_TC_EN) || defined(AUDIO_MAL_DMA_IT_HT_EN) || defined(AUDIO_MAL_DMA_IT_TE_EN)
1432     /* I2S DMA IRQ Channel configuration */
1433     NVIC_InitStructure.NVIC_IRQChannel = AUDIO_MAL_DMA_IRQ;
1434     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = EVAL_AUDIO_IRQ_PREPRIO;
1435     NVIC_InitStructure.NVIC_IRQChannelSubPriority = EVAL_AUDIO_IRQ_SUBRIO;
1436     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
1437     NVIC_Init(&NVIC_InitStructure);
1438 #endif 
1439   }
1440 #endif /* DAC_USE_I2S_DMA */
1441   
1442   if (CurrAudioInterface == AUDIO_INTERFACE_I2S)
1443   {
1444     /* Enable the I2S DMA request */
1445     SPI_I2S_DMACmd(CODEC_I2S, SPI_I2S_DMAReq_Tx, ENABLE);  
1446   }
1447   else
1448   {
1449     /* Configure the STM32 DAC to geenrate audio analog signal */
1450     DAC_Config();
1451     
1452 #ifndef DAC_USE_I2S_DMA
1453     /* Enable the I2S interrupt used to write into the DAC register */
1454     SPI_I2S_ITConfig(SPI3, SPI_I2S_IT_TXE, ENABLE);
1455     
1456     /* I2S DMA IRQ Channel configuration */
1457     NVIC_InitStructure.NVIC_IRQChannel = CODEC_I2S_IRQ;
1458     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = EVAL_AUDIO_IRQ_PREPRIO;
1459     NVIC_InitStructure.NVIC_IRQChannelSubPriority = EVAL_AUDIO_IRQ_SUBRIO;
1460     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
1461     NVIC_Init(&NVIC_InitStructure); 
1462 #else
1463     /* Enable the I2S DMA request */
1464     SPI_I2S_DMACmd(CODEC_I2S, SPI_I2S_DMAReq_Rx, ENABLE);   
1465 #endif /* DAC_USE_I2S_DMA */
1466   }
1467 #endif
1468 }
1469
1470 /**
1471   * @brief  Restore default state of the used Media.
1472   * @param  None
1473   * @retval None
1474   */
1475 static void Audio_MAL_DeInit(void)  
1476 {   
1477 #if defined(AUDIO_MAL_DMA_IT_TC_EN) || defined(AUDIO_MAL_DMA_IT_HT_EN) || defined(AUDIO_MAL_DMA_IT_TE_EN)
1478   NVIC_InitTypeDef NVIC_InitStructure;  
1479   
1480   /* Deinitialize the NVIC interrupt for the I2S DMA Stream */
1481   NVIC_InitStructure.NVIC_IRQChannel = AUDIO_MAL_DMA_IRQ;
1482   NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = EVAL_AUDIO_IRQ_PREPRIO;
1483   NVIC_InitStructure.NVIC_IRQChannelSubPriority = EVAL_AUDIO_IRQ_SUBRIO;
1484   NVIC_InitStructure.NVIC_IRQChannelCmd = DISABLE;
1485   NVIC_Init(&NVIC_InitStructure);  
1486 #endif 
1487   
1488   /* Disable the DMA stream before the deinit */
1489   DMA_Cmd(AUDIO_MAL_DMA_STREAM, DISABLE);
1490   
1491   /* Dinitialize the DMA Stream */
1492   DMA_DeInit(AUDIO_MAL_DMA_STREAM);
1493   
1494   /* 
1495      The DMA clock is not disabled, since it can be used by other streams 
1496                                                                           */ 
1497 }
1498
1499 /**
1500   * @brief  Starts playing audio stream from the audio Media.
1501   * @param  None
1502   * @retval None
1503   */
1504 static void Audio_MAL_Play(uint32_t Addr, uint32_t Size)
1505 {         
1506   if (CurrAudioInterface == AUDIO_INTERFACE_I2S)
1507   {
1508     /* Configure the buffer address and size */
1509     DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)Addr;
1510     DMA_InitStructure.DMA_BufferSize = (uint32_t)Size;
1511     
1512     /* Configure the DMA Stream with the new parameters */
1513     DMA_Init(AUDIO_MAL_DMA_STREAM, &DMA_InitStructure);
1514     
1515     /* Enable the I2S DMA Stream*/
1516     DMA_Cmd(AUDIO_MAL_DMA_STREAM, ENABLE);   
1517   }
1518 #ifndef DAC_USE_I2S_DMA
1519   else
1520   {
1521     /* Configure the buffer address and size */
1522     DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)Addr;
1523     DMA_InitStructure.DMA_BufferSize = (uint32_t)Size;
1524     
1525     /* Configure the DMA Stream with the new parameters */
1526     DMA_Init(AUDIO_MAL_DMA_STREAM, &DMA_InitStructure);
1527     
1528     /* Enable the I2S DMA Stream*/
1529     DMA_Cmd(AUDIO_MAL_DMA_STREAM, ENABLE);
1530   }
1531 #endif /* DAC_USE_I2S_DMA */
1532   
1533   /* If the I2S peripheral is still not enabled, enable it */
1534   if ((CODEC_I2S->I2SCFGR & I2S_ENABLE_MASK) == 0)
1535   {
1536     I2S_Cmd(CODEC_I2S, ENABLE);
1537   }
1538 }
1539
1540 /**
1541   * @brief  Pauses or Resumes the audio stream playing from the Media.
1542   * @param  Cmd: AUDIO_PAUSE (or 0) to pause, AUDIO_RESUME (or any value different
1543   *              from 0) to resume. 
1544   * @param  Addr: Address from/at which the audio stream should resume/pause.
1545   * @retval None
1546   */
1547 static void Audio_MAL_PauseResume(uint32_t Cmd, uint32_t Addr)
1548 {
1549   /* Pause the audio file playing */
1550   if (Cmd == AUDIO_PAUSE)
1551   {   
1552     /* Disable the I2S DMA request */
1553     SPI_I2S_DMACmd(CODEC_I2S, SPI_I2S_DMAReq_Tx, DISABLE);
1554
1555     /* Pause the I2S DMA Stream 
1556         Note. For the STM32F4xx devices, the DMA implements a pause feature, 
1557               by disabling the stream, all configuration is preserved and data 
1558               transfer is paused till the next enable of the stream.
1559               This feature is not available on STM32F4xx devices. */
1560     DMA_Cmd(AUDIO_MAL_DMA_STREAM, DISABLE);
1561   }
1562   else /* AUDIO_RESUME */
1563   {
1564     /* Enable the I2S DMA request */
1565     SPI_I2S_DMACmd(CODEC_I2S, SPI_I2S_DMAReq_Tx, ENABLE);
1566   
1567     /* Resume the I2S DMA Stream 
1568         Note. For the STM32F4xx devices, the DMA implements a pause feature, 
1569               by disabling the stream, all configuration is preserved and data 
1570               transfer is paused till the next enable of the stream.
1571               This feature is not available on STM32F4xx devices. */
1572     DMA_Cmd(AUDIO_MAL_DMA_STREAM, ENABLE);
1573     
1574     /* If the I2S peripheral is still not enabled, enable it */
1575     if ((CODEC_I2S->I2SCFGR & I2S_ENABLE_MASK) == 0)
1576     {
1577       I2S_Cmd(CODEC_I2S, ENABLE);
1578     }    
1579   } 
1580 }
1581
1582 /**
1583   * @brief  Stops audio stream playing on the used Media.
1584   * @param  None
1585   * @retval None
1586   */
1587 static void Audio_MAL_Stop(void)
1588 {   
1589   /* Stop the Transfer on the I2S side: Stop and disable the DMA stream */
1590   DMA_Cmd(AUDIO_MAL_DMA_STREAM, DISABLE);
1591
1592   /* Clear all the DMA flags for the next transfer */
1593   DMA_ClearFlag(AUDIO_MAL_DMA_STREAM, AUDIO_MAL_DMA_FLAG_TC |AUDIO_MAL_DMA_FLAG_HT | \
1594                                   AUDIO_MAL_DMA_FLAG_FE | AUDIO_MAL_DMA_FLAG_TE);
1595   
1596   /*  
1597            The I2S DMA requests are not disabled here.
1598                                                             */
1599   
1600   /* In all modes, disable the I2S peripheral */
1601   I2S_Cmd(CODEC_I2S, DISABLE);
1602 }
1603
1604 /**
1605   * @brief  DAC  Channel1 Configuration
1606   * @param  None
1607   * @retval None
1608   */
1609 void DAC_Config(void)
1610 {
1611   DAC_InitTypeDef  DAC_InitStructure;
1612   GPIO_InitTypeDef GPIO_InitStructure;
1613
1614   /* DMA1 clock and GPIOA clock enable (to be used with DAC) */
1615   RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1 | RCC_AHB1Periph_GPIOA, ENABLE);
1616
1617   /* DAC Periph clock enable */
1618   RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE);
1619
1620   /* DAC channel 1 & 2 (DAC_OUT1 = PA.4) configuration */
1621   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
1622   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
1623   GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
1624   GPIO_Init(GPIOA, &GPIO_InitStructure);
1625
1626   /* DAC channel1 Configuration */
1627   DAC_InitStructure.DAC_Trigger = DAC_Trigger_None;
1628   DAC_InitStructure.DAC_WaveGeneration = DAC_WaveGeneration_None;
1629   DAC_InitStructure.DAC_OutputBuffer = DAC_OutputBuffer_Enable;
1630   DAC_Init(AUDIO_DAC_CHANNEL, &DAC_InitStructure);
1631
1632   /* Enable DAC Channel1 */
1633   DAC_Cmd(AUDIO_DAC_CHANNEL, ENABLE);
1634 }
1635 /**
1636   * @}
1637   */
1638
1639 /**
1640   * @}
1641   */
1642
1643 /**
1644   * @}
1645   */
1646
1647 /**
1648   * @}
1649   */
1650
1651 /******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/