CircleOS  1
audio_spe.c
Go to the documentation of this file.
1 /****************** COPYRIGHT (C) 2007-2013 KEOLABS S.A.S. ********************/
12 /******************************************************************************/
13 
14 /* Includes ------------------------------------------------------------------*/
15 #include "circle.h"
16 
18 
19 /* Private typedef -----------------------------------------------------------*/
20 
21 /* Private define ------------------------------------------------------------*/
22 #define STw5094A_ADDR_WR 0xE2 /* addr for WRITE access*/
23 #define STw5094A_ADDR_RD 0xE3 /* addr for READ access*/
24 
25 #define STw5094A_I2C_SPEED 100000
26 
27 /* Maximum Timeout values for flags and events waiting loops. These timeouts are
28  not based on accurate values, they just guarantee that the application will
29  not remain stuck if the I2C communication is corrupted.
30  You may modify these timeout values depending on CPU frequency and application
31  conditions (interrupts routines ...). */
32 #define STw5094A_I2C_FLAG_TIMEOUT ((uint32_t)0x1000)
33 #define STw5094A_I2C_LONG_TIMEOUT ((uint32_t)(10 * STw5094A_I2C_FLAG_TIMEOUT))
34 
35 #define NB_REG 22
36 #define CONTROL_REGISTER_1 1
37 #define CONTROL_REGISTER_2 2
38 #define CONTROL_REGISTER_3 3
39 #define CONTROL_REGISTER_4 4
40 #define CONTROL_REGISTER_5 5
41 #define CONTROL_REGISTER_6 6
42 #define CONTROL_REGISTER_7 7
43 #define CONTROL_REGISTER_8 8
44 #define CONTROL_REGISTER_9 9
45 #define CONTROL_REGISTER_10 10
46 #define CONTROL_REGISTER_11 11
47 #define CONTROL_REGISTER_12 12
48 #define CONTROL_REGISTER_13 13
49 #define CONTROL_REGISTER_14 14
50 #define CONTROL_REGISTER_15 15
51 #define CONTROL_REGISTER_16 16
52 #define CONTROL_REGISTER_17 17
53 #define CONTROL_REGISTER_18 18
54 #define CONTROL_REGISTER_19 19
55 #define CONTROL_REGISTER_20 20
56 #define CONTROL_REGISTER_21 21
57 
58 #define LOCAL_BUFFER_SIZE 1024 //size of the local buffer in 16 bits words
59 
60 /* Private variables ---------------------------------------------------------*/
61 volatile u8 AUDIO_CODEC_CRs[22];
62 volatile s8 flagWrite_AUDIO_CODEC_CRs = -1;
63 s8 AUDIO_Volume = 0; // number of 2 dB steps for attenuation volume
64 ON_OFF_enum AUDIO_SpeakerOn = ON; // loudspeaker active or not
65 ON_OFF_enum AUDIO_SpeakerOnOld = OFF; // flag for change detection
66 ON_OFF_enum AUDIO_Mute = OFF; // sound (loudspeaker+headphones) active or not
67 
68 const sound_type* Audio_buffer;
69 volatile u32 Audio_buffer_index = 0;
70 volatile u32 Audio_buffer_size = 0;
71 volatile s16 Audio_buffer_local[LOCAL_BUFFER_SIZE]; // working buffer for MONO mode management
72 s32 Audio_buffer_local_size = LOCAL_BUFFER_SIZE;
73 AUDIO_PlaybackBuffer_Status bufferstatus_local;
74 volatile AUDIO_PlaybackBuffer_Status audio_buffer_fill = LOW_EMPTY | HIGH_EMPTY ;
75 
76 voice_type* Voice_buffer;
77 volatile u32 Voice_buffer_index = 0;
78 volatile u32 Voice_buffer_size = 0;
79 volatile AUDIO_RecordBuffer_Status voice_record_buffer_fill = EMPTY;
80 
81 AUDIO_DeviceMode_enum AUDIO_DeviceMode = AUDIO_MODE;
82 AUDIO_Playback_status_enum AUDIO_Playback_status = NO_SOUND;
83 AUDIO_Recording_status_enum AUDIO_Recording_status = NO_RECORD;
84 AUDIO_Length_enum AUDIO_Length = LG_8_BITS;
85 AUDIO_Frequency_enum AUDIO_Frequency = FRQ_16KHZ;
86 AUDIO_Format_enum AUDIO_Format = MONO;
87 
88 /* Setting of the prescaler depends on the PLL frequency..*/
89 #ifdef STM32F10X_CL
90 // Array for clocks configuration = 48 KHz, 44KHz, 22 KHz, 16 KHz, 8KHz
91 const u32 I2S_PreDiv2[5] = { RCC_PREDIV2_Div6, RCC_PREDIV2_Div11, RCC_PREDIV2_Div11, RCC_PREDIV2_Div4, RCC_PREDIV2_Div12 };
92 const u32 I2S_Pll3Mul[5] = { RCC_PLL3Mul_20, RCC_PLL3Mul_20, RCC_PLL3Mul_10, RCC_PLL3Mul_20, RCC_PLL3Mul_20 };
93 const u16 I2S_PrescalerVal[5] = { 32, 18, 18, 144, 96 };
94 #else
95 // Array for I2S divider configuration = 18MHz, 24MHz, 36MHz, 48MHz, 72MHz
96 const u16 I2S_PrescalerVal[5] = { 0x111, 0x117, 0x123, 0x02F, 0x146 };
97 #endif
98 
99 /* Private function prototypes -----------------------------------------------*/
100 void AUDIO_Init_I2C();
101 void AUDIO_Init_audio_mode( AUDIO_DeviceMode_enum mode, AUDIO_Length_enum length, AUDIO_Frequency_enum frequency, AUDIO_Format_enum format );
102 void AUDIO_Init_voice_mode( AUDIO_DeviceMode_enum mode );
103 s32 AUDIO_I2C_ReadMultByte( u8 ReadAddr, u8 NumByteToRead, u8* pBuffer );
104 s32 AUDIO_I2C_WriteMultByte( u8 WriteAddr, u8 NumByteToWrite, u8* pBuffer );
105 
106 
107 /* Private functions ---------------------------------------------------------*/
108 
109 /*******************************************************************************
110 *
111 * AUDIO_DeviceSoftwareReset
112 *
113 *******************************************************************************/
119 /******************************************************************************/
120 void AUDIO_DeviceSoftwareReset( void )
121 {
122  u8 reset_value = 0x2;
123  AUDIO_I2C_WriteMultByte( CONTROL_REGISTER_21, 1, &reset_value );
124 }
125 
126 
127 /*******************************************************************************
128 *
129 * AUDIO_UpdateRegisters
130 *
131 *******************************************************************************/
140 /******************************************************************************/
141 void AUDIO_UpdateRegisters( void )
142 {
143  if ( ( flagWrite_AUDIO_CODEC_CRs > -1 ) && ( flagWrite_AUDIO_CODEC_CRs < 22 ) )
144  {
145  /* Write of the register passed in the flag parameter */
146  AUDIO_I2C_WriteMultByte( flagWrite_AUDIO_CODEC_CRs, 1, ( u8* ) &AUDIO_CODEC_CRs[flagWrite_AUDIO_CODEC_CRs] );
147  }
148  else
149  {
150  if ( flagWrite_AUDIO_CODEC_CRs >= 22 )
151  {
152  /* Write all the 22 registers*/
153  AUDIO_I2C_WriteMultByte( CONTROL_REGISTER_0, 22, ( u8* ) AUDIO_CODEC_CRs );
154  }
155  }
156  flagWrite_AUDIO_CODEC_CRs = -1;
157 }
158 
159 /*******************************************************************************
160 *
161 * AUDIO_SetClocks
162 *
163 *******************************************************************************/
171 /******************************************************************************/
172 #ifdef STM32F10X_CL
173 void AUDIO_SetClocks( AUDIO_Frequency_enum frequency )
174 {
175  // First stops the clock before configuration change
176 
177  /* Select internal clock as system clock source */
178  RCC_SYSCLKConfig( RCC_SYSCLKSource_HSI );
179 
180  /* Disable PLL */
181  RCC_PLLCmd( DISABLE );
182  RCC_PLL3Cmd( DISABLE );
183  RCC_PLL2Cmd( DISABLE );
184 
185  // Change the configuration accoding to IS2S spec (see Reference manual)
186  RCC_PREDIV2Config( I2S_PreDiv2[frequency] );
187  RCC_PLL3Config( I2S_Pll3Mul[frequency] );
188 
189  // Set the prescaler values for the I2S (audio codec) according to the PLLs
190  *( u16* )AUDIO_I2SPR = I2S_PrescalerVal[frequency];
191 
192  // Restart PLL2
193  RCC_PLL2Cmd( ENABLE );
194  /* Wait till PLL2 is ready */
195  while ( ( RCC->CR & RCC_CR_PLL2RDY ) == 0 )
196  {
197  }
198 
199  /* Enable PLL */
200  RCC_PLLCmd( ENABLE );
201  /* Wait till PLL is ready */
202  while ( ( RCC->CR & RCC_CR_PLLRDY ) == 0 )
203  {
204  }
205 
206  /* Select PLL as system clock source */
207  RCC_SYSCLKConfig( RCC_SYSCLKSource_PLLCLK );
208  /* Wait till PLL is used as system clock source */
209  while ( ( RCC->CFGR & ( uint32_t )RCC_CFGR_SWS ) != ( uint32_t )0x08 )
210  {
211  }
212 
213  // Restart PLL3
214  RCC_PLL3Cmd( ENABLE );
215  /* Wait till PLL3 is ready */
216  while ( ( RCC->CR & RCC_CR_PLL3RDY ) == 0 )
217  {
218  }
219 
220 }
221 #endif
222 
223 /* Public functions for CircleOS ---------------------------------------------*/
224 
225 /*******************************************************************************
226 *
227 * AUDIO_Init
228 *
229 *******************************************************************************/
238 /******************************************************************************/
239 void AUDIO_Init( void )
240 {
241 
242  /* Enable clocks */
243  RCC_APB1PeriphClockCmd( RCC_APB1Periph_I2C2, ENABLE );
244 
245  RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB |
246  RCC_APB2Periph_AFIO, ENABLE );
247 
248  /* Set the default values*/
249  if ( fFirstStartup == FALSE )
250  {
251  AUDIO_Volume = ( ( UTIL_ReadBackupRegister( BKP_SYS5 ) ) & BKPMASK_S5_VOLUME );
252 
253  /* Restore the configuration */
254  AUDIO_SpeakerOn = ( ( UTIL_ReadBackupRegister( BKP_SYS2 ) ) & BKPMASK_S2_SPEAKER ) ? 1 : 0;
255  AUDIO_SpeakerOnOld = AUDIO_SpeakerOn;
256  AUDIO_SPEAKER_OnOff( AUDIO_SpeakerOn );
257  AUDIO_Mute = ( ( UTIL_ReadBackupRegister( BKP_SYS2 ) ) & BKPMASK_S2_MUTE ) ? 1 : 0;
258  AUDIO_BuzzerOn = ( ( UTIL_ReadBackupRegister( BKP_SYS2 ) ) & BKPMASK_S2_BUZZER ) ? 1 : 0;
259 
260  }
261  else
262  {
263  AUDIO_SpeakerOn = 1;
264  AUDIO_SpeakerOnOld = 1;
265  AUDIO_Mute = FALSE;
266  AUDIO_Volume = AUDIO_MIN_ATTENUATION;
267  AUDIO_BuzzerOn = TRUE;
268  }
269 
270  /* Init I2C */
271  AUDIO_Init_I2C();
272 
273  /*--STEP 1 : device software reset*/
274  AUDIO_DeviceSoftwareReset();
275 
276  /*--STEP 2 : read CR0 to CR21 to get default config*/
277  AUDIO_I2C_ReadMultByte( CONTROL_REGISTER_0, 22, ( u8* ) AUDIO_CODEC_CRs );
278 
279  /* Init the default audio mode for playing 8 bits / 16 kHz audio sounds*/
280 // AUDIO_Init_audio_mode(AUDIO_MODE, LG_8_BITS, FRQ_16KHZ, MONO);
281  AUDIO_Init_voice_mode( VOICE_MODE ); // YRT20100324 : electrical pb on power on
282  // if Loud Speaker driver ON
283 
284  // Write register now to power on the codec and his drivers
285  AUDIO_UpdateRegisters();
286 
287  // Wait for power stabilization
288  Delayms( 2000 );
289 
290  // Generate the 12 MHz clock for codec
291  GPIO_InitTypeDef GPIO_InitStructure;
292  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
293  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
294  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
295  GPIO_Init( GPIOA, &GPIO_InitStructure );
296  RCC_MCOConfig( RCC_MCO_HSE );
297 }
298 
299 /*******************************************************************************
300 *
301 * AUDIO_Handler
302 *
303 *******************************************************************************/
311 /******************************************************************************/
312 void AUDIO_Handler( void )
313 {
314  // Update codec registers, if requested
315  AUDIO_UpdateRegisters();
316 
317  /* Apply configuration change, if necessary*/
318  if ( AUDIO_SpeakerOn != AUDIO_SpeakerOnOld )
319  {
320  AUDIO_SPEAKER_OnOff( AUDIO_SpeakerOn );
321  AUDIO_SpeakerOnOld = AUDIO_SpeakerOn;
322 
323  /* Update the default system toolbar*/
325  }
326 
327  return;
328 }
329 
330 /*******************************************************************************
331 *
332 * AUDIO_I2S_GPIO_Init
333 *
334 *******************************************************************************/
342 /******************************************************************************/
343 void AUDIO_I2S_GPIO_Init(void)
344 {
345  GPIO_InitTypeDef GPIO_InitStructure;
346 
347  /* GPIO configuration for I2S2 port*/
348  RCC_PERIPH_GPIO_CLOCK_CMD( GPIO_I2S_WS_PERIPH, ENABLE );
349  RCC_PERIPH_GPIO_CLOCK_CMD( GPIO_I2S_SCK_PERIPH, ENABLE );
350  RCC_PERIPH_GPIO_CLOCK_CMD( GPIO_I2S_SD_PERIPH, ENABLE );
351 
352  /* Configure I2S pins: SD, SCK and WS */
353  GPIO_InitStructure.GPIO_Pin = GPIO_I2S_WS_PIN;
354  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
355  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
356  GPIO_Init( GPIOx_I2S_WS_PORT, &GPIO_InitStructure );
357 
358  GPIO_InitStructure.GPIO_Pin = GPIO_I2S_SCK_PIN;
359  GPIO_Init( GPIOx_I2S_SCK_PORT, &GPIO_InitStructure );
360 
361  GPIO_InitStructure.GPIO_Pin = GPIO_I2S_SD_PIN;
362  GPIO_Init( GPIOx_I2S_SD_PORT, &GPIO_InitStructure );
363 
364 }
365 
366 /*******************************************************************************
367 *
368 * AUDIO_CODEC_Init_I2C
369 *
370 ********************************************************************************/
377 /********************************************************************************/
378 void AUDIO_Init_I2C( void )
379 {
380 
381  GPIO_InitTypeDef GPIO_InitStructure;
382  I2C_InitTypeDef I2C_InitStructure;
383 
384  /* GPIO configuration ---------- */
385  RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB, ENABLE );
386 
387  /* Configure GPIO pins: SCL and SDA for I2C2 */
388  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11;
389  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
390  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
391  GPIO_Init( GPIOB, &GPIO_InitStructure );
392 
393  /* I2C configuration ----------- */
394  I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
395  I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
396  I2C_InitStructure.I2C_OwnAddress1 = 0xC0;
397  I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
398  I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
399  I2C_InitStructure.I2C_ClockSpeed = STw5094A_I2C_SPEED;
400 
401  /* I2C Peripheral Enable */
402  I2C_Cmd( I2C2, ENABLE );
403 
404  /* Apply I2C configuration after enabling it */
405  I2C_Init( I2C2, &I2C_InitStructure );
406 
407 }
408 
409 
410 /*******************************************************************************
411 *
412 * AUDIO_Init_audio_mode
413 *
414 *******************************************************************************/
432 /******************************************************************************/
433 void AUDIO_Init_audio_mode( AUDIO_DeviceMode_enum mode, AUDIO_Length_enum length, AUDIO_Frequency_enum frequency, AUDIO_Format_enum format )
434 {
435  DMA_InitTypeDef DMA_InitStructure;
436  I2S_InitTypeDef I2S_InitStructure;
437  NVIC_InitTypeDef NVIC_InitStructure;
438 
439 
440  /* The MONO mode uses working buffer to dupplicate datas on the two channels*/
441  /* and switch buffer half by half => uses DMA in circular mode*/
442  /*KJ if (format == MONO)*/
443  /*KJ mode = AUDIO_CIRCULAR_MODE;*/
444 
445  RCC_APB1PeriphClockCmd( RCC_APBxPeriph_AUDIO_I2S, ENABLE );
446  I2S_Cmd( AUDIO_I2S, DISABLE );
447 
448  /* Enable audio interface of STw5094a : set the proper config -------------*/
449 
450  /* MCLK or AUXCLK = 512 kHz; Voice Data Fs is 8 kHz ; Linear code ; B1 and B2 consecutive ; 8 bits time-slot*/
451  AUDIO_CODEC_CRs[0] = 0x00;
452 
453  /* Delayed data timing; CR2A connected to RX path ; TX path connected to DX; */
454  /* PCM I/F enabled ; B1 channel selected; Normal operation*/
455  AUDIO_CODEC_CRs[1] = 0x14;
456 
457  /* Microphone inout "MIC1" Selected; MBIAS enable; Voice PreAmplifier gain = 22.5 dB*/
458  AUDIO_CODEC_CRs[4] = 0x6f;
459 
460  /* Voice Codec Receive High Pass filter enabled ; Sidetone gain = -19.5 dB (voice -> HP)*/
461  AUDIO_CODEC_CRs[5] = 0x17;
462 
463  /* !MUT + PLS (LoudSpeaker) + PHL/PHR (Headphone)+ SE + !RTE (tone)*/
464  AUDIO_CODEC_CRs[6] = ( AUDIO_SpeakerOn ? 0x10 : 0 ) + 0x0c + 0x02 ;
465 
466  /* MUT*/
467  if ( AUDIO_Mute == TRUE )
468  {
469  AUDIO_CODEC_CRs[6] |= 0x20;
470  }
471  else
472  {
473  AUDIO_CODEC_CRs[6] &= 0xDF;
474  }
475 
476  s32 hp_setting = ( AUDIO_Volume + 2 ) * 2;
477  if ( hp_setting > 0x14 )
478  hp_setting = 0x14;
479 
480  /* Apply new volume to codec */
481  AUDIO_CODEC_CRs[7] = AUDIO_Volume; /* loudspeaker gain ( +6 / -24 dB)*/
482  AUDIO_CODEC_CRs[8] = hp_setting ; /* left HeadPhones gain ( +0 / -40 dB)*/
483  AUDIO_CODEC_CRs[9] = hp_setting ; /* right HeadPhones gain ( +0 / -40 dB)*/
484 
485  /* Tone generator : F1 selected, tone gain = -24db, square*/
486  AUDIO_CODEC_CRs[12] = 0x84;
487 
488  /* Tone generator : F1/F2 frequency = 445 Hz*/
489  AUDIO_CODEC_CRs[13] = 89;
490  AUDIO_CODEC_CRs[14] = 89;
491 
492  AUDIO_CODEC_CRs[16] = 0x08; /*KJ20090320 - Changed from 0x00 to 0x08 for Non-Delayed data.*/
493 
494  /* Headphone common driver = 1.35V + enable */
495 #ifdef STM32F10X_CL
496  AUDIO_CODEC_CRs[18] = 0x61; /* AMCK between 14 and 19 MHz*/
497 #else
498  AUDIO_CODEC_CRs[18] = 0x60; /* AMCK between 9 and et 14 MHz*/
499 #endif
500 
501  /* Audio mode + power ON + AMCK clock for tone only*/
502  AUDIO_CODEC_CRs[21] = 0x61;
503 
504  flagWrite_AUDIO_CODEC_CRs = 22;
505 
506 
507  /* Init I2S communication to send data on Audio interface -----------------*/
508 
509  /* Enable the DMA1 Channel 5 Interrupt */
510  NVIC_InitStructure.NVIC_IRQChannel = AUDIO_DMA_TX_Channelx_IRQn;
511  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
512  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
513  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
514  NVIC_Init( &NVIC_InitStructure );
515 
516  /* DMA1 Channel4 configuration ----------------------------------------------*/
517  RCC_AHBPeriphClockCmd( RCC_AHBPeriph_AUDIO_DMA, ENABLE );
518  DMA_DeInit( AUDIO_DMA_TX );
519  DMA_InitStructure.DMA_PeripheralBaseAddr = ( u32 )&AUDIO_I2S->DR;
520  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
521  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
522  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
523  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
524  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
525  if ( ( mode == AUDIO_CIRCULAR_MODE ) || format == MONO ) /*/ Changed KJ 27May-09*/
526  DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
527  else
528  DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
529  DMA_InitStructure.DMA_Priority = DMA_Priority_High;
530  DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
531  DMA_Init( AUDIO_DMA_TX, &DMA_InitStructure );
532 
533  DMA_ITConfig( AUDIO_DMA_TX, DMA_IT_TC | DMA_IT_HT, ENABLE );
534 
535  /* GPIO configuration for I2S port*/
536  AUDIO_I2S_GPIO_Init();
537 
538  /*-- Configure I2S --*/
539  /* I2S peripheral configuration*/
540  I2S_InitStructure.I2S_Standard = I2S_Standard_MSB;
541 
542  /* I2S audio samples length - Only support 8 and 16 bit - sound quality isn't anyway better out...*/
543  I2S_InitStructure.I2S_DataFormat = I2S_DataFormat_16b;
544  I2S_InitStructure.I2S_MCLKOutput = I2S_MCLKOutput_Disable;
545 
546  /* IS2S audio samples frequency*/
547  switch ( frequency ) /*/ KJ20090320 - Changed Selection of FRQ*/
548  {
549  case FRQ_8KHZ : I2S_InitStructure.I2S_AudioFreq = I2S_AudioFreq_8k;
550  break;
551  case FRQ_16KHZ : I2S_InitStructure.I2S_AudioFreq = I2S_AudioFreq_16k;
552  break;
553  case FRQ_22KHZ : I2S_InitStructure.I2S_AudioFreq = I2S_AudioFreq_22k;
554  break;
555  case FRQ_44KHZ : I2S_InitStructure.I2S_AudioFreq = I2S_AudioFreq_44k;
556  break;
557  case FRQ_48KHZ : I2S_InitStructure.I2S_AudioFreq = I2S_AudioFreq_48k;
558  break;
559  default: I2S_InitStructure.I2S_AudioFreq = I2S_AudioFreq_8k;
560  }
561 
562  I2S_InitStructure.I2S_CPOL = I2S_CPOL_Low;
563  I2S_InitStructure.I2S_Mode = I2S_Mode_MasterTx;
564 
565  /* Set the I2S prescaler value according to the PLL value*/
566 // UTIL_SetPll( UTIL_GetPll() ); YRT091208 The prescaler is already calculated in the I2S_Init function
567 
568  I2S_Init( AUDIO_I2S, &I2S_InitStructure );
569 
570 #ifdef STM32F10X_CL
571  /* Set the I2S prescaler value according to the PLL value*/
572  AUDIO_SetClocks( frequency );
573 #endif
574 
575  Audio_buffer_index = 0;
576  AUDIO_Playback_status = NO_SOUND;
577 
578  /* Memorize new audio format values*/
579  AUDIO_Length = length;
580  AUDIO_Frequency = frequency;
581  AUDIO_Format = format;
582 
583  /*Buffers are supposed to be empty here*/
584  audio_buffer_fill = LOW_EMPTY | HIGH_EMPTY ;
585 
586  /* Enable the I2S2*/
587  I2S_Cmd( AUDIO_I2S, ENABLE );
588 
589  /* Audio mode ready*/
590 }
591 
592 /*******************************************************************************
593 *
594 * AUDIO_Init_voice_mode
595 *
596 *******************************************************************************/
610 /******************************************************************************/
611 void AUDIO_Init_voice_mode( AUDIO_DeviceMode_enum mode )
612 {
613  I2S_InitTypeDef I2S_InitStructure;
614  NVIC_InitTypeDef NVIC_InitStructure;
615  DMA_InitTypeDef DMA_InitStructure;
616 
617  RCC_APB1PeriphClockCmd( RCC_APBxPeriph_AUDIO_I2S , ENABLE );
618  I2S_Cmd( AUDIO_I2S, DISABLE );
619 
620  /* Enable audio interface of STw5094a : set the proper config -------------*/
621 
622  /* MCLK or AUXCLK = 512 kHz; Voice Data Fs is 16 kHz ; Linear code ; B1 and B2 consecutive ; 8 bits time-slot*/
623  AUDIO_CODEC_CRs[0] = 0x20; /*/0x20 16khz / 0x00 8Khz*/
624 
625  /* Delayed data timing; CR2A connected to RX path ; TX path connected to DX; */
626  /* PCM I/F enabled ; B1 channel selected; Normal operation*/
627  AUDIO_CODEC_CRs[1] = 0x14;
628 
629  /* Microphone inout "MIC1" Selected; MBIAS enable; Voice PreAmplifier gain = 22.5 dB*/
630  AUDIO_CODEC_CRs[4] = 0x6f;
631 
632  /* Voice Codec Receive High Pass filter enabled (HPB); Codec internal sidetone enabled (SI)*/
633  /* Sidetone gain = -15.5 dB (voice -> HP)*/
634  AUDIO_CODEC_CRs[5] = 0x13;
635 
636  /* !PLS (LoudSpeaker) + !PHL/PHR (Headphone)+ !SE + !RTE (tone)*/
637  AUDIO_CODEC_CRs[6] = 0; /*record, no sound (AUDIO_SpeakerOn?0x10:0) + 0x0c; */
638 
639  /* MUT*/
640  if ( AUDIO_Mute == TRUE )
641  {
642  AUDIO_CODEC_CRs[6] |= 0x20;
643  }
644  else
645  {
646  AUDIO_CODEC_CRs[6] &= 0xDF;
647  }
648 
649  /* Apply volume to codec */
650  s32 hp_setting = ( AUDIO_Volume + 2 ) * 2;
651  if ( hp_setting > 0x14 )
652  hp_setting = 0x14;
653 
654  /* Apply new volume to codec */
655  AUDIO_CODEC_CRs[7] = AUDIO_Volume; /* loudspeaker gain ( +6 / -24 dB)*/
656  AUDIO_CODEC_CRs[8] = hp_setting ; /* left HeadPhones gain ( +0 / -40 dB)*/
657  AUDIO_CODEC_CRs[9] = hp_setting ; /* right HeadPhones gain ( +0 / -40 dB)*/
658 
659  /* Tone generator : F1 and F2 muted, tone gain = 0 db, square, no output*/
660  AUDIO_CODEC_CRs[12] = 0x00;
661 
662  /* Tone generator : F1/F2 frequency = 445 Hz*/
663  AUDIO_CODEC_CRs[13] = AUDIO_CODEC_CRs[14] = 0x0;
664 
665  /* Headphone common driver = 1.35V + enable / AMCK between 9 et 14 MHz*/
666  AUDIO_CODEC_CRs[18] = 0x60;
667 
668  /* Voice mode + power ON + AUXCLK clock for tone only*/
669  AUDIO_CODEC_CRs[21] = 0x01;
670 
671  flagWrite_AUDIO_CODEC_CRs = 22;
672 
673  /* Init I2S communication to send data on Audio interface -----------------*/
674 
675  /* Enable the DMA1 Channel 4 Interrupt */
676  NVIC_InitStructure.NVIC_IRQChannel = AUDIO_DMA_RX_Channelx_IRQn;
677  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
678  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
679  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
680  NVIC_Init( &NVIC_InitStructure );
681 
682  /* DMA1 Channel4 configuration ----------------------------------------------*/
683  RCC_AHBPeriphClockCmd( RCC_AHBPeriph_AUDIO_DMA, ENABLE );
684  DMA_DeInit( AUDIO_DMA_RX );
685  DMA_InitStructure.DMA_PeripheralBaseAddr = ( u32 )&AUDIO_I2S->DR;
686  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
687  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
688  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
689  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
690  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
691  if ( mode == VOICE_CIRCULAR_MODE )
692  DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
693  else
694  DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
695  DMA_InitStructure.DMA_Priority = DMA_Priority_High;
696  DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
697  DMA_Init( AUDIO_DMA_RX, &DMA_InitStructure );
698 
699  DMA_ITConfig( AUDIO_DMA_RX, DMA_IT_TC | DMA_IT_HT, ENABLE );
700 
701  /* GPIO configuration for I2S port*/
702  AUDIO_I2S_GPIO_Init();
703 
704  /*-- Configure I2S --*/
705  /* I2S peripheral configuration, set PCM standard*/
706  I2S_InitStructure.I2S_Standard = I2S_Standard_PCMShort;
707 
708  /* I2S audio samples length*/
709  I2S_InitStructure.I2S_DataFormat = I2S_DataFormat_16bextended; /* We only support this mode..*/
710 
711  I2S_InitStructure.I2S_MCLKOutput = I2S_MCLKOutput_Disable;
712 
713  /* IS2S audio samples frequency*/
714  I2S_InitStructure.I2S_AudioFreq = I2S_AudioFreq_16k; /* We only support 16bit due to MCLK 1CH x 32Bit x 16Khz = 512KhzMCLK*/
715  I2S_InitStructure.I2S_CPOL = I2S_CPOL_Low;
716  I2S_InitStructure.I2S_Mode = I2S_Mode_MasterRx;
717  I2S_Init( AUDIO_I2S, &I2S_InitStructure );
718 
719  /* Set the I2S prescaler value according to the PLL value*/
720 #ifdef STM32F10X_CL
721  /* Set the clocks according to the sample frequency required */
723  AUDIO_SetClocks( FRQ_16KHZ );
724 #else
726 #endif
727 
728  Voice_buffer_index = 0;
729  AUDIO_Recording_status = NO_RECORD;
730 
731  /* Memorize new audio format values*/
732  AUDIO_Length = LG_16_BITS;
733  AUDIO_Frequency = FRQ_16KHZ;
734  AUDIO_Format = MONO;
735 
736  /* Enable the I2S2*/
737  I2S_Cmd( AUDIO_I2S, ENABLE );
738 
739  /* Voice mode ready*/
740 }
741 
742 
743 /*******************************************************************************
744 *
745 * AUDIO_Shutdown
746 *
747 *******************************************************************************/
755 /******************************************************************************/
756 void AUDIO_Shutdown( void )
757 {
758  /* Stop IT SPI*/
759  I2S_Cmd( AUDIO_I2S, DISABLE );
760 
761  /* Reset and power down the codec*/
762  AUDIO_DeviceSoftwareReset();
763 
764  /* Stop I2C*/
765  I2C_Cmd( I2C2, DISABLE );
766 }
767 
768 /*******************************************************************************
769 *
770 * AUDIO_Welcome_Msg
771 *
772 ********************************************************************************/
778 /********************************************************************************/
779 const u8 welcome_16K_8 [] =
780 {
781 #include "welcome_stm32_16k_8b.h"
782 };
783 
784 void AUDIO_Welcome_Msg( void )
785 {
787  AUDIO_Play( ( sound_type* )welcome_16K_8, sizeof welcome_16K_8 );
788 }
789 
790 /*******************************************************************************
791 *
792 * AUDIO_I2C_Read_Register
793 *
794 *******************************************************************************/
805 /******************************************************************************/
806 u8 AUDIO_I2C_Read_Register( u8 register_to_read )
807 {
808  u8 val = 0;
809  AUDIO_I2C_ReadMultByte( register_to_read, 1, &val );
810  return val;
811 }
812 
813 /*******************************************************************************
814 *
815 * AUDIO_I2C_WriteRegister
816 *
817 *******************************************************************************/
829 /******************************************************************************/
830 void AUDIO_I2C_WriteRegister( u8 register_to_write, u8 data_to_write )
831 {
832  AUDIO_I2C_WriteMultByte( register_to_write, 1, &data_to_write );
833 }
834 
835 /*******************************************************************************
836 *
837 * AUDIO_I2C_WriteMultByte
838 *
839 *******************************************************************************/
854 /******************************************************************************/
855 s32 AUDIO_I2C_WriteMultByte( u8 WriteAddr, u8 NumByteToWrite, u8* pBuffer )
856 {
857  s32 i;
858  vu32 dr_temp ;
859  u32 TimeOut;
860 
861  /* Send START condition */
862  I2C_GenerateSTART( I2C2, ENABLE );
863 
864  /* Test on EV5 and clear it */
865  TimeOut = STw5094A_I2C_LONG_TIMEOUT;
866  while ( !I2C_CheckEvent( I2C2, I2C_EVENT_MASTER_MODE_SELECT ) )
867  {
868  if ( I2C2->SR1 & I2C_FLAG_RXNE )
869  dr_temp = I2C2->DR;
870 
871  if ( ( TimeOut-- ) == 0 )
872  return -1;
873  }
874 
875  /* Send STw5094A address for write */
876  I2C_Send7bitAddress( I2C2, STw5094A_ADDR_WR, I2C_Direction_Transmitter );
877 
878  /* Test on EV6 and clear it */
879  TimeOut = STw5094A_I2C_LONG_TIMEOUT;
880  while ( !I2C_CheckEvent( I2C2, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED ) )
881  {
882  if ( ( TimeOut-- ) == 0 )
883  return -1;
884  }
885 
886  /* Send the STw5094A's internal address to write to */
887  I2C_SendData( I2C2, WriteAddr );
888 
889 
890  /* Test on EV8 and clear it */
891  TimeOut = STw5094A_I2C_LONG_TIMEOUT;
892  while ( !I2C_CheckEvent( I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED ) )
893  {
894  if ( ( TimeOut-- ) == 0 )
895  return -1;
896  }
897 
898  while ( NumByteToWrite ) /* uses the STw5094A's addr. register auto-increment feature*/
899  {
900  /* Send the byte to be written */
901  I2C_SendData( I2C2, * pBuffer );
902 
903  /* Test on EV8 and clear it */
904  TimeOut = STw5094A_I2C_LONG_TIMEOUT;
905  while ( !I2C_CheckEvent( I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED ) )
906  {
907  if ( ( TimeOut-- ) == 0 )
908  return -1;
909  }
910 
911  if ( NumByteToWrite == 1 )
912  { I2C_GenerateSTOP( I2C2, ENABLE ); } /* STOP */
913 
914  pBuffer++;
915  NumByteToWrite--;
916  }
917  for ( i = 0 ; i < 500 ; i++ ) { ; }
918 
919  return 0;
920 }
921 
922 /*******************************************************************************
923 *
924 * AUDIO_I2C_ReadMultByte
925 *
926 *******************************************************************************/
942 /******************************************************************************/
943 s32 AUDIO_I2C_ReadMultByte( u8 ReadAddr, u8 NumByteToRead, u8* pBuffer )
944 {
945  s32 i;
946  vu32 dr_temp ;
947  u32 TimeOut;
948 
949  /* Send START condition */
950  I2C_GenerateSTART( I2C2, ENABLE );
951 
952  /* Test on EV5 and clear it */
953  TimeOut = STw5094A_I2C_LONG_TIMEOUT;
954  while ( !I2C_CheckEvent( I2C2, I2C_EVENT_MASTER_MODE_SELECT ) )
955  {
956  if ( I2C2->SR1 & I2C_FLAG_RXNE )
957  dr_temp = I2C2->DR;
958 
959  if ( ( TimeOut-- ) == 0 )
960  return -1;
961  }
962 
963  /* Send STw5094A address for write */
964  I2C_Send7bitAddress( I2C2, STw5094A_ADDR_WR, I2C_Direction_Transmitter );
965 
966 
967  /* Test on EV6 and clear it */
968  TimeOut = STw5094A_I2C_LONG_TIMEOUT;
969  while ( !I2C_CheckEvent( I2C2, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED ) )
970  {
971  if ( ( TimeOut-- ) == 0 )
972  return -1;
973  }
974 
975  /* Clear EV6 by setting again the PE bit */
976  I2C_Cmd( I2C2, ENABLE );
977 
978  /* Send the STw5094A's internal address to write to */
979  I2C_SendData( I2C2, ReadAddr );
980 
981  /* Test on EV8 and clear it */
982  TimeOut = STw5094A_I2C_LONG_TIMEOUT;
983  while ( !I2C_CheckEvent( I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED ) )
984  {
985  if ( ( TimeOut-- ) == 0 )
986  return -1;
987  }
988 
989  /* Send START condition a second time */
990  I2C_GenerateSTART( I2C2, ENABLE );
991 
992  /* Test on EV5 and clear it */
993  TimeOut = STw5094A_I2C_LONG_TIMEOUT;
994  while ( !I2C_CheckEvent( I2C2, I2C_EVENT_MASTER_MODE_SELECT ) )
995  {
996  if ( ( TimeOut-- ) == 0 )
997  return -1;
998  }
999 
1000  /* Send STw5094A address for read */
1001  I2C_Send7bitAddress( I2C2, STw5094A_ADDR_RD, I2C_Direction_Receiver );
1002 
1003  /* Test on EV6 and clear it */
1004  TimeOut = STw5094A_I2C_LONG_TIMEOUT;
1005  while ( !I2C_CheckEvent( I2C2, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED ) )
1006  {
1007  if ( ( TimeOut-- ) == 0 )
1008  return -1;
1009  }
1010 
1011  /* While there is data to be read */
1012  while ( NumByteToRead )
1013  {
1014  if ( NumByteToRead == 1 )
1015  {
1016  /* Disable Acknowledgement */
1017  I2C_AcknowledgeConfig( I2C2, DISABLE );
1018 
1019  /* Send STOP Condition */
1020  I2C_GenerateSTOP( I2C2, ENABLE );
1021  }
1022 
1023  /* Test on EV7 and clear it */
1024  TimeOut = STw5094A_I2C_LONG_TIMEOUT;
1025  if ( I2C_CheckEvent( I2C2, I2C_EVENT_MASTER_BYTE_RECEIVED ) )
1026  {
1027  /* Read a byte from the codec */
1028  *pBuffer = I2C_ReceiveData( I2C2 );
1029 
1030  /* Point to the next location where the byte read will be saved */
1031  pBuffer++;
1032 
1033  /* Decrement the read bytes counter */
1034  NumByteToRead--;
1035  }
1036  else
1037  {
1038  if ( ( TimeOut-- ) == 0 )
1039  return -1;
1040  }
1041 
1042  }
1043 
1044  /* Enable Acknowledgement to be ready for another reception */
1045  I2C_AcknowledgeConfig( I2C2, ENABLE );
1046 
1047  for ( i = 0 ; i < 500 ; i++ ) { ; }
1048 
1049  return 0;
1050 }
1051 
1052 
1053 /*******************************************************************************
1054 *
1055 * AUDIO_BUZZER_SetToneFrequency
1056 *
1057 *******************************************************************************/
1067 /******************************************************************************/
1068 void AUDIO_BUZZER_SetToneFrequency( u16 freq )
1069 {
1070  u16 valreg;
1071 
1072  if ( freq < 250 )
1073  valreg = ( 256 * freq ) / 1000;
1074  else
1075  {
1076  if ( freq < 750 )
1077  valreg = ( ( 128 * freq ) / 1000 ) + 32;
1078  else
1079  {
1080  if ( freq < 1750 )
1081  valreg = ( ( 64 * freq ) / 1000 ) + 80;
1082  else
1083  {
1084  if ( freq < 3720 )
1085  valreg = ( ( 32 * freq ) / 1000 ) + 136;
1086  else
1087  valreg = 255;
1088  }
1089  }
1090  }
1091 
1092  /* Set frequency to */
1093  AUDIO_CODEC_CRs[13] = valreg;
1094  AUDIO_CODEC_CRs[14] = valreg;
1095 
1096  /* Update register (to be done by the tim2 irq)*/
1097  SET_FLAG_WRITE_CODEC_CRS( 13 );
1098 }
1099 
1100 /*******************************************************************************
1101 *
1102 * AUDIO_BUZZER_OnOff
1103 *
1104 *******************************************************************************/
1115 /******************************************************************************/
1116 void AUDIO_BUZZER_OnOff( ON_OFF_enum mode )
1117 {
1118  if ( mode != OFF )
1119  AUDIO_CODEC_CRs[6] |= 0x01;
1120  else
1121  AUDIO_CODEC_CRs[6] &= 0xFE;
1122 
1123  /* Update register (to be done by the tim2 irq)*/
1124  SET_FLAG_WRITE_CODEC_CRS( 6 );
1125 }
1126 
1127 /*******************************************************************************
1128 *
1129 * AUDIO_Set_Volume
1130 *
1131 *******************************************************************************/
1136 /******************************************************************************/
1137 void AUDIO_Set_Volume( void )
1138 {
1139  s32 hp_setting = ( AUDIO_Volume + 2 ) * 2;
1140  if ( hp_setting > 0x14 )
1141  hp_setting = 0x14;
1142 
1143  /* Apply new volume to codec */
1144  AUDIO_CODEC_CRs[7] = AUDIO_Volume; /* loudspeaker gain ( +6 / -24 dB)*/
1145  AUDIO_CODEC_CRs[8] = hp_setting ; /* left HeadPhones gain ( +0 / -40 dB)*/
1146  AUDIO_CODEC_CRs[9] = hp_setting ; /* right HeadPhones gain ( +0 / -40 dB)*/
1147 
1148  /* Update all registers (to be done by the tim2 irq)*/
1149  SET_FLAG_WRITE_CODEC_CRS( 22 );
1150 }
1151 
1152 /*******************************************************************************
1153 *
1154 * AUDIO_Cpy_Mono
1155 *
1156 ********************************************************************************/
1162 /********************************************************************************/
1163 void AUDIO_Cpy_Mono( void )
1164 {
1165  volatile u16 i;
1166  s16 temp;
1167 
1168  /* Stop if end of original buffer */
1169  if ( Audio_buffer_index >= Audio_buffer_size )
1170  {
1171  if ( AUDIO_DeviceMode == AUDIO_MODE ) /* KJ 27may-2009*/
1173  }
1174 
1175  /* End of the first half working buffer*/
1176  if ( bufferstatus_local & LOW_EMPTY )
1177  {
1178  if ( AUDIO_Length == LG_16_BITS )
1179  {
1180  for ( i = 0 ; i < ( ( Audio_buffer_local_size / 4 ) - 1 ) ; i = i + 2 )
1181  {
1182  temp = *( s16* )( Audio_buffer + Audio_buffer_index );
1183  Audio_buffer_local[i + 1] = Audio_buffer_local[i] = temp;
1184  Audio_buffer_index += 2; /* 16 bit*/
1185  }
1186  }
1187  else
1188  {
1189  for ( i = 0; i < ( ( Audio_buffer_local_size / 4 ) - 1 ); i = i + 2 )
1190  {
1191  temp = ( ( s16 )( ( *( Audio_buffer + Audio_buffer_index ) ^ 0x80 ) ) ) << 8;
1192  Audio_buffer_local[i + 1] = Audio_buffer_local[i] = temp;
1193  Audio_buffer_index++; /* 8 bit */
1194  }
1195  }
1196  bufferstatus_local &= ~LOW_EMPTY;
1197  }
1198 
1199  /* End of the second half working buffer*/
1200  if ( bufferstatus_local & HIGH_EMPTY )
1201  {
1202  if ( AUDIO_Length == LG_16_BITS )
1203  {
1204  for ( i = ( Audio_buffer_local_size / 4 ) ; i < ( Audio_buffer_local_size / 2 ); i = i + 2 )
1205  {
1206  temp = *( s16* )( Audio_buffer + Audio_buffer_index );
1207  Audio_buffer_local[i + 1] = Audio_buffer_local[i] = temp;
1208  Audio_buffer_index += 2; /* 16 bit*/
1209  }
1210  }
1211  else
1212  {
1213  for ( i = ( Audio_buffer_local_size / 4 ); i < ( ( Audio_buffer_local_size ) / 2 ) - 1; i = i + 2 )
1214  {
1215  temp = ( ( s16 )( ( *( Audio_buffer + Audio_buffer_index ) ^ 0x80 ) ) ) << 8;
1216  Audio_buffer_local[i + 1] = Audio_buffer_local[i] = temp;
1217  Audio_buffer_index++; /* 8 bit */
1218  }
1219  }
1220  bufferstatus_local &= ~HIGH_EMPTY;
1221  }
1222 
1223  if ( Audio_buffer_index == ( Audio_buffer_size / 2 ) )
1224  {
1225  audio_buffer_fill |= LOW_EMPTY;
1226  if ( audio_buffer_fill & HIGH_EMPTY )
1227  {
1228  if ( AUDIO_DeviceMode == AUDIO_MODE ) /* KJ 27may-2009*/
1230  }
1231  }
1232  if ( Audio_buffer_index >= Audio_buffer_size )
1233  {
1234  audio_buffer_fill |= HIGH_EMPTY;
1235  Audio_buffer_index = 0;
1236  if ( audio_buffer_fill & LOW_EMPTY )
1237  {
1238  if ( AUDIO_DeviceMode == AUDIO_MODE ) /* KJ 27may-2009*/
1240  }
1241  }
1242 }
1243 
1245 
1246 /* Public functions ----------------------------------------------------------*/
1247 
1248 
1249 /*******************************************************************************
1250 *
1251 * AUDIO_SetMode
1252 *
1253 ********************************************************************************/
1266 /********************************************************************************/
1268  AUDIO_Length_enum length,
1269  AUDIO_Frequency_enum frequency,
1270  AUDIO_Format_enum format )
1271 {
1272  if ( ( mode == VOICE_MODE ) || ( mode == VOICE_CIRCULAR_MODE ) )
1273  AUDIO_Init_voice_mode( mode );
1274  else
1275  AUDIO_Init_audio_mode( mode, length, frequency, format );
1276 
1277  AUDIO_DeviceMode = mode;
1278 }
1279 
1280 
1281 /*******************************************************************************
1282 *
1283 * AUDIO_GetMode
1284 *
1285 ********************************************************************************/
1295 /********************************************************************************/
1297 {
1298  return AUDIO_DeviceMode;
1299 }
1300 
1301 /*******************************************************************************
1302 *
1303 * AUDIO_Play
1304 *
1305 ********************************************************************************/
1317 /********************************************************************************/
1318 void AUDIO_Play( const sound_type* buffer, s32 size )
1319 {
1320  audio_buffer_fill = LOW_EMPTY | HIGH_EMPTY;
1321  bufferstatus_local = LOW_EMPTY | HIGH_EMPTY;
1322 
1323  if ( AUDIO_Format == STEREO )
1324  {
1325  /* Uses the original buffer*/
1326  AUDIO_DMA_TX->CMAR = ( u32 )buffer; // Set the buffer
1327  AUDIO_DMA_TX->CNDTR = size; /* Set the size */
1328  }
1329  else
1330  {
1331  /* Uses the local buffer*/
1332  if ( AUDIO_Length == LG_16_BITS )
1333  size *= 2;
1334  Audio_buffer = ( sound_type* ) buffer; /* Copy the pointer to real databuffer/source*/
1335  Audio_buffer_index = 0; /* Copy the pointer to real databuffer/source*/
1336  Audio_buffer_size = size; /* Size to the real databuffer/source*/
1337  AUDIO_Cpy_Mono();
1338  AUDIO_DMA_TX->CMAR = ( u32 )Audio_buffer_local; /* Set the buffer*/
1339  AUDIO_DMA_TX->CNDTR = ( ( Audio_buffer_local_size ) / 2 ); /* Set the size*/
1340  }
1341 
1342  DMA_Cmd( AUDIO_DMA_TX, ENABLE ); /* Enable DMA Channel for Audio*/
1343  SPI_I2S_DMACmd( AUDIO_I2S, SPI_I2S_DMAReq_Tx, ENABLE ); /* Enable I2S DMA REQ.*/
1344  AUDIO_Playback_status = IS_PLAYING;
1345 }
1346 
1347 /*******************************************************************************
1348 *
1349 * AUDIO_Playback_Stop
1350 *
1351 ********************************************************************************/
1357 /********************************************************************************/
1359 {
1360  vs32 i;
1361 
1362  DMA_Cmd( AUDIO_DMA_TX, DISABLE ); /* Disable DMA Channel for Audio*/
1363  SPI_I2S_DMACmd( AUDIO_I2S, SPI_I2S_DMAReq_Tx, DISABLE ); /* Disable I2S DMA REQ.*/
1364 
1365  AUDIO_Playback_status = NO_SOUND;
1366 
1367  /* Shutdwon codec in order to avoid non expected voices*/
1368  AUDIO_WriteRegister( 21, 0x60 );
1369  for ( i = 0; i < 10000 ; i++ ) {;}
1370 
1371  /* Wake up codec*/
1372  AUDIO_WriteRegister( 21, 0x61 );
1373 
1374 }
1375 
1376 
1377 /*******************************************************************************
1378 *
1379 * AUDIO_Record
1380 *
1381 ********************************************************************************/
1389 /********************************************************************************/
1390 void AUDIO_Record( sound_type* buffer, s32 size )
1391 {
1392  /* Initialize the recording buffer*/
1393  Voice_buffer = ( voice_type* ) buffer;
1394  Voice_buffer_size = size;
1395  Voice_buffer_index = 0;
1396  voice_record_buffer_fill = EMPTY;
1397 
1398  /* Inform that actual data tranfer is processed in the interrupt handler*/
1399  AUDIO_Recording_status = IS_RECORDING;
1400  AUDIO_DMA_RX->CMAR = ( u32 )buffer; /* Set the buffer*/
1401  AUDIO_DMA_RX->CNDTR = size; /* Set the size*/
1402  DMA_Cmd( AUDIO_DMA_RX, ENABLE ); /* Enable DMA Channel for Audio*/
1403  SPI_I2S_DMACmd( AUDIO_I2S, SPI_I2S_DMAReq_Rx, ENABLE ); /* Enable I2S DMA REQ.*/
1404 }
1405 
1406 /*******************************************************************************
1407 *
1408 * AUDIO_Record_Stop
1409 *
1410 ********************************************************************************/
1416 /********************************************************************************/
1417 void AUDIO_Record_Stop( void )
1418 {
1419  DMA_Cmd( AUDIO_DMA_RX, DISABLE ); /* Disable DMA Channel for Audio */
1420  SPI_I2S_DMACmd( AUDIO_I2S, SPI_I2S_DMAReq_Rx, DISABLE ); /* Disable I2S DMA REQ.*/
1421  AUDIO_Recording_status = NO_RECORD;
1422 }
1423 
1424 /*******************************************************************************
1425 *
1426 * AUDIO_Playback_GetStatus
1427 *
1428 *******************************************************************************/
1436 /******************************************************************************/
1438 {
1439  return AUDIO_Playback_status;
1440 }
1441 
1442 /*******************************************************************************
1443 *
1444 * AUDIO_PlaybackBuffer_GetStatus
1445 *
1446 *******************************************************************************/
1457 /******************************************************************************/
1459 {
1460  if ( value )
1461  audio_buffer_fill &= ~value;
1462  return audio_buffer_fill;
1463 }
1464 
1465 /*******************************************************************************
1466 *
1467 * AUDIO_Record_Buffer_GetStatus
1468 *
1469 *******************************************************************************/
1480 /******************************************************************************/
1482 {
1483  if ( value )
1484  voice_record_buffer_fill &= ~value;
1485  return voice_record_buffer_fill;
1486 }
1487 
1488 /*******************************************************************************
1489 *
1490 * AUDIO_Recording_GetStatus
1491 *
1492 *******************************************************************************/
1500 /******************************************************************************/
1502 {
1503  return AUDIO_Recording_status;
1504 }
1505 
1506 /*******************************************************************************
1507 *
1508 * AUDIO_SPEAKER_OnOff
1509 *
1510 *******************************************************************************/
1520 /******************************************************************************/
1522 {
1523  if ( mode != OFF )
1524  {
1525  AUDIO_CODEC_CRs[6] |= 0x10;
1526  AUDIO_SpeakerOn = 1;
1527  }
1528  else
1529  {
1530  AUDIO_CODEC_CRs[6] &= 0xEF;
1531  AUDIO_SpeakerOn = 0;
1532  }
1533 
1534  /* Update register */
1535  SET_FLAG_WRITE_CODEC_CRS( 6 );
1536 }
1537 
1538 /*******************************************************************************
1539 *
1540 * AUDIO_MUTE_OnOff
1541 *
1542 *******************************************************************************/
1551 /******************************************************************************/
1553 {
1554  if ( mode != OFF )
1555  {
1556  AUDIO_CODEC_CRs[6] |= 0x20;
1557  AUDIO_Mute = TRUE;
1558  }
1559  else
1560  {
1561  AUDIO_CODEC_CRs[6] &= 0xDF;
1562  AUDIO_Mute = FALSE;
1563  }
1564 
1565  /* Updates register*/
1566  SET_FLAG_WRITE_CODEC_CRS( 6 );
1567 }
1568 
1569 /*******************************************************************************
1570 *
1571 * AUDIO_isMute
1572 *
1573 *******************************************************************************/
1582 /******************************************************************************/
1583 bool AUDIO_IsMute( void )
1584 {
1585  return ( AUDIO_Mute == 1 );
1586 }
1587 
1588 /*******************************************************************************
1589 *
1590 * AUDIO_Inc_Volume
1591 *
1592 *******************************************************************************/
1599 /******************************************************************************/
1600 void AUDIO_Inc_Volume( u8 dB )
1601 {
1602  /* 2 dB step minimum*/
1603  if ( dB <= 1 )
1604  dB = 2;
1605 
1606  /* Decrement the internal attenuation value*/
1607  AUDIO_Volume -= dB / 2;
1608  if ( AUDIO_Volume < AUDIO_MIN_ATTENUATION )
1609  AUDIO_Volume = AUDIO_MIN_ATTENUATION;
1610 
1611  /* Apply new volume to codec */
1612  AUDIO_Set_Volume( );
1613 }
1614 
1615 /*******************************************************************************
1616 *
1617 * AUDIO_Dec_Volume
1618 *
1619 *******************************************************************************/
1626 /******************************************************************************/
1627 void AUDIO_Dec_Volume( u8 dB )
1628 {
1629  /* 2 dB step minimum*/
1630  if ( dB <= 1 )
1631  dB = 2;
1632 
1633  /* Increment the internal attenuation value*/
1634  AUDIO_Volume += ( dB / 2 );
1635  if ( AUDIO_Volume > 15 )
1636  AUDIO_Volume = 15;
1637 
1638  /* Apply new volume to codec */
1639  AUDIO_Set_Volume( );
1640 }
1641 
1642 /*******************************************************************************
1643 *
1644 * AUDIO_ReadRegister
1645 *
1646 *******************************************************************************/
1657 /******************************************************************************/
1658 u8 AUDIO_ReadRegister( u8 register_to_read )
1659 {
1660  u8 val = 0;
1661  if ( register_to_read < 22 )
1662  {
1663  /* Get the new register value*/
1664  AUDIO_I2C_ReadMultByte( register_to_read, 1, &val );
1665  /* Update the local register table*/
1666  AUDIO_CODEC_CRs[register_to_read] = val;
1667  }
1668  return val;
1669 }
1670 
1671 /*******************************************************************************
1672 *
1673 * AUDIO_WriteRegister
1674 *
1675 *******************************************************************************/
1688 /******************************************************************************/
1689 void AUDIO_WriteRegister( u8 register_to_write, u8 data_to_write )
1690 {
1691  if ( register_to_write < 22 )
1692  {
1693  /* Update the local register table*/
1694  AUDIO_CODEC_CRs[register_to_write] = data_to_write;
1695  /* Launch write register*/
1696  SET_FLAG_WRITE_CODEC_CRS( register_to_write );
1697  }
1698 }
1699 
1700 /*******************************************************************************
1701 *
1702 * AUDIO_SetLocalBufferSize
1703 *
1704 *******************************************************************************/
1713 /******************************************************************************/
1715 {
1716 
1717  /* Convert in 16 bits words size*/
1718  size /= 2;
1719 
1720  if ( size < 128 )
1721  size = 128;
1722 
1723  if ( size > LOCAL_BUFFER_SIZE )
1724  size = LOCAL_BUFFER_SIZE;
1725 
1726  Audio_buffer_local_size = size;
1727 }