• Main Page
  • Related Pages
  • Data Structures
  • Files
  • File List
  • Globals

audio_spe.c

Go to the documentation of this file.
00001 /****************** COPYRIGHT (C) 2007-2010 RAISONANCE S.A.S. *****************/
00012 /******************************************************************************/
00013 
00014 /* Includes ------------------------------------------------------------------*/
00015 #include "circle.h"
00016 
00018 
00019 /* Private typedef -----------------------------------------------------------*/
00020 
00021 /* Private define ------------------------------------------------------------*/
00022 #define STw5094A_ADDR_WR   0xE2      /* addr for WRITE access*/
00023 #define STw5094A_ADDR_RD   0xE3      /* addr for READ access*/
00024 
00025 #define STw5094A_I2C_SPEED 100000
00026 
00027 /* Maximum Timeout values for flags and events waiting loops. These timeouts are
00028    not based on accurate values, they just guarantee that the application will
00029    not remain stuck if the I2C communication is corrupted.
00030    You may modify these timeout values depending on CPU frequency and application
00031    conditions (interrupts routines ...). */
00032 #define STw5094A_I2C_FLAG_TIMEOUT         ((uint32_t)0x1000)
00033 #define STw5094A_I2C_LONG_TIMEOUT         ((uint32_t)(10 * STw5094A_I2C_FLAG_TIMEOUT))
00034 
00035 #define NB_REG 22
00036 #define CONTROL_REGISTER_1 1
00037 #define CONTROL_REGISTER_2 2
00038 #define CONTROL_REGISTER_3 3
00039 #define CONTROL_REGISTER_4 4
00040 #define CONTROL_REGISTER_5 5
00041 #define CONTROL_REGISTER_6 6
00042 #define CONTROL_REGISTER_7 7
00043 #define CONTROL_REGISTER_8 8
00044 #define CONTROL_REGISTER_9 9
00045 #define CONTROL_REGISTER_10 10
00046 #define CONTROL_REGISTER_11 11
00047 #define CONTROL_REGISTER_12 12
00048 #define CONTROL_REGISTER_13 13
00049 #define CONTROL_REGISTER_14 14
00050 #define CONTROL_REGISTER_15 15
00051 #define CONTROL_REGISTER_16 16
00052 #define CONTROL_REGISTER_17 17
00053 #define CONTROL_REGISTER_18 18
00054 #define CONTROL_REGISTER_19 19
00055 #define CONTROL_REGISTER_20 20
00056 #define CONTROL_REGISTER_21 21
00057 
00058 #define LOCAL_BUFFER_SIZE 1024          //size of the local buffer in 16 bits words
00059 
00060 /* Private variables ---------------------------------------------------------*/
00061 volatile u8 AUDIO_CODEC_CRs[22];
00062 volatile s8   flagWrite_AUDIO_CODEC_CRs   = -1;
00063 s8   AUDIO_Volume                         = 0;           // number of 2 dB steps for attenuation volume
00064 bool AUDIO_SpeakerOn                      = 1;           // loudspeaker active or not
00065 bool AUDIO_SpeakerOnOld                   = 0;           // flag for change detection
00066 bool AUDIO_Mute                           = 0;           // sound (loudspeaker+headphones) active or not
00067 
00068 const sound_type*  Audio_buffer;
00069 vs32 Audio_buffer_index = 0;
00070 volatile u16 Audio_buffer_size = 0;
00071 volatile s16 Audio_buffer_local[LOCAL_BUFFER_SIZE];       // working buffer for MONO mode management
00072 s32 Audio_buffer_local_size = LOCAL_BUFFER_SIZE;
00073 AUDIO_PlaybackBuffer_Status bufferstatus_local;
00074 volatile AUDIO_PlaybackBuffer_Status  audio_buffer_fill = LOW_EMPTY | HIGH_EMPTY ;
00075 
00076 voice_type*  Voice_buffer;
00077 volatile u16 Voice_buffer_index = 0;
00078 volatile u16 Voice_buffer_size = 0;
00079 volatile AUDIO_RecordBuffer_Status  voice_record_buffer_fill = EMPTY;
00080 
00081 AUDIO_DeviceMode_enum AUDIO_DeviceMode = AUDIO_MODE;
00082 AUDIO_Playback_status_enum AUDIO_Playback_status = NO_SOUND;
00083 AUDIO_Recording_status_enum AUDIO_Recording_status = NO_RECORD;
00084 AUDIO_Length_enum AUDIO_Length = LG_8_BITS;
00085 AUDIO_Frequency_enum AUDIO_Frequency = FRQ_16KHZ;
00086 AUDIO_Format_enum AUDIO_Format = MONO;
00087 
00088 /* Setting of the prescaler depends on the PLL frequency..*/
00089 #ifdef STM32F10X_CL
00090 // Array for clocks configuration = 48 KHz, 44KHz, 22 KHz, 16 KHz, 8KHz
00091 const u32 I2S_PreDiv2[5] = { RCC_PREDIV2_Div6, RCC_PREDIV2_Div11, RCC_PREDIV2_Div11,  RCC_PREDIV2_Div4, RCC_PREDIV2_Div12 };
00092 const u32 I2S_Pll3Mul[5] = { RCC_PLL3Mul_20, RCC_PLL3Mul_20, RCC_PLL3Mul_10, RCC_PLL3Mul_20, RCC_PLL3Mul_20 };
00093 const u16 I2S_PrescalerVal[5] = { 32,  18,  18, 144, 96 };
00094 #else
00095 // Array for I2S divider configuration = 18MHz, 24MHz, 36MHz, 48MHz, 72MHz
00096 const u16 I2S_PrescalerVal[5] = { 0x111,  0x117, 0x123, 0x02F, 0x146 };
00097 #endif
00098 
00099 /* Private function prototypes -----------------------------------------------*/
00100 void AUDIO_Init_I2C();
00101 void AUDIO_Init_audio_mode( AUDIO_DeviceMode_enum mode, AUDIO_Length_enum length, AUDIO_Frequency_enum frequency, AUDIO_Format_enum format );
00102 void AUDIO_Init_voice_mode( AUDIO_DeviceMode_enum mode );
00103 s32  AUDIO_I2C_ReadMultByte( u8 ReadAddr, u8 NumByteToRead, u8* pBuffer );
00104 void AUDIO_I2C_WriteMultByte( u8 WriteAddr, u8 NumByteToWrite, u8* pBuffer );
00105 
00106 
00107 /* Private functions ---------------------------------------------------------*/
00108 
00109 /*******************************************************************************
00110 *
00111 *                                AUDIO_DeviceSoftwareReset
00112 *
00113 *******************************************************************************/
00119 /******************************************************************************/
00120 void AUDIO_DeviceSoftwareReset( void )
00121 {
00122     u8 reset_value = 0x2;
00123     AUDIO_I2C_WriteMultByte( CONTROL_REGISTER_21, 1, &reset_value );
00124 }
00125 
00126 
00127 /*******************************************************************************
00128 *
00129 *                                AUDIO_UpdateRegisters
00130 *
00131 *******************************************************************************/
00140 /******************************************************************************/
00141 void AUDIO_UpdateRegisters( void )
00142 {
00143     if ( ( flagWrite_AUDIO_CODEC_CRs > -1 ) && ( flagWrite_AUDIO_CODEC_CRs < 22 ) )
00144     {
00145         /* Write of the register passed in the flag parameter */
00146         AUDIO_I2C_WriteMultByte( flagWrite_AUDIO_CODEC_CRs, 1, ( u8* ) &AUDIO_CODEC_CRs[flagWrite_AUDIO_CODEC_CRs] );
00147     }
00148     else
00149     {
00150         if ( flagWrite_AUDIO_CODEC_CRs >= 22 )
00151         {
00152             /* Write all the 22 registers*/
00153             AUDIO_I2C_WriteMultByte( CONTROL_REGISTER_0, 22, ( u8* ) AUDIO_CODEC_CRs );
00154         }
00155     }
00156     flagWrite_AUDIO_CODEC_CRs = -1;
00157 }
00158 
00159 /*******************************************************************************
00160 *
00161 *                                AUDIO_SetClocks
00162 *
00163 *******************************************************************************/
00171 /******************************************************************************/
00172 #ifdef STM32F10X_CL
00173 void AUDIO_SetClocks( AUDIO_Frequency_enum frequency )
00174 {
00175     // First stops the clock before configuration change
00176 
00177     /* Select internal clock as system clock source */
00178     RCC_SYSCLKConfig( RCC_SYSCLKSource_HSI );
00179 
00180     /* Disable PLL */
00181     RCC_PLLCmd( DISABLE );
00182     RCC_PLL3Cmd( DISABLE );
00183     RCC_PLL2Cmd( DISABLE );
00184 
00185     // Change the configuration accoding to IS2S spec (see Reference manual)
00186     RCC_PREDIV2Config( I2S_PreDiv2[frequency] );
00187     RCC_PLL3Config( I2S_Pll3Mul[frequency] );
00188 
00189     // Set the prescaler values for the I2S (audio codec) according to the PLLs
00190     *( u16* )AUDIO_I2SPR = I2S_PrescalerVal[frequency];
00191 
00192     // Restart PLL2
00193     RCC_PLL2Cmd( ENABLE );
00194     /* Wait till PLL2 is ready */
00195     while ( ( RCC->CR & RCC_CR_PLL2RDY ) == 0 )
00196     {
00197     }
00198 
00199     /* Enable PLL */
00200     RCC_PLLCmd( ENABLE );
00201     /* Wait till PLL is ready */
00202     while ( ( RCC->CR & RCC_CR_PLLRDY ) == 0 )
00203     {
00204     }
00205 
00206     /* Select PLL as system clock source */
00207     RCC_SYSCLKConfig( RCC_SYSCLKSource_PLLCLK );
00208     /* Wait till PLL is used as system clock source */
00209     while ( ( RCC->CFGR & ( uint32_t )RCC_CFGR_SWS ) != ( uint32_t )0x08 )
00210     {
00211     }
00212 
00213     // Restart PLL3
00214     RCC_PLL3Cmd( ENABLE );
00215     /* Wait till PLL3 is ready */
00216     while ( ( RCC->CR & RCC_CR_PLL3RDY ) == 0 )
00217     {
00218     }
00219 
00220 }
00221 #endif
00222 
00223 /* Public functions for CircleOS ---------------------------------------------*/
00224 
00225 /*******************************************************************************
00226 *
00227 *                                AUDIO_Init
00228 *
00229 *******************************************************************************/
00238 /******************************************************************************/
00239 void AUDIO_Init( void )
00240 {
00241 
00242     /* Enable clocks */
00243     RCC_APB1PeriphClockCmd( RCC_APB1Periph_I2C2, ENABLE );
00244 
00245     RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB |
00246                             RCC_APB2Periph_AFIO, ENABLE );
00247 
00248     /* Set the default values*/
00249     if ( fFirstStartup == FALSE )
00250     {
00251         AUDIO_Volume = ( ( UTIL_ReadBackupRegister( BKP_SYS2 ) ) & BKPMASK_S2_VOLUME ) >> 8 ;
00252 
00253         /* Restore the configuration    */
00254         AUDIO_SpeakerOn = ( ( UTIL_ReadBackupRegister( BKP_SYS2 ) ) & BKPMASK_S2_SPEAKER ) ? 1 : 0;
00255         AUDIO_SpeakerOnOld = AUDIO_SpeakerOn;
00256         AUDIO_SPEAKER_OnOff( AUDIO_SpeakerOn );
00257         AUDIO_Mute = ( ( UTIL_ReadBackupRegister( BKP_SYS2 ) ) & BKPMASK_S2_MUTE ) ? 1 : 0;
00258         AUDIO_BuzzerOn = ( ( UTIL_ReadBackupRegister( BKP_SYS2 ) ) & BKPMASK_S2_BUZZER ) ? 1 : 0;
00259 
00260     }
00261     else
00262     {
00263         AUDIO_SpeakerOn =  1;
00264         AUDIO_SpeakerOnOld = 1;
00265         AUDIO_Mute = FALSE;
00266         AUDIO_Volume = AUDIO_MIN_ATTENUATION;
00267         AUDIO_BuzzerOn = TRUE;
00268     }
00269 
00270     /* Init I2C */
00271     AUDIO_Init_I2C();
00272 
00273     /*--STEP 1 : device software reset*/
00274     AUDIO_DeviceSoftwareReset();
00275 
00276     /*--STEP 2 : read CR0 to CR21 to get default config*/
00277     AUDIO_I2C_ReadMultByte( CONTROL_REGISTER_0, 22, ( u8* ) AUDIO_CODEC_CRs );
00278 
00279     /* Init the default audio mode for playing 8 bits / 16 kHz audio sounds*/
00280 //    AUDIO_Init_audio_mode(AUDIO_MODE, LG_8_BITS, FRQ_16KHZ, MONO);
00281     AUDIO_Init_voice_mode( VOICE_MODE );    // YRT20100324 : electrical pb on power on
00282     // if Loud Speaker driver ON
00283 
00284     // Write register now to power on the codec and his drivers
00285     AUDIO_UpdateRegisters();
00286 
00287     // Wait for power stabilization
00288     Delayms( 2000 );
00289 
00290     // Generate the 12 MHz clock for codec
00291     GPIO_InitTypeDef  GPIO_InitStructure;
00292     GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_8;
00293     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
00294     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
00295     GPIO_Init( GPIOA, &GPIO_InitStructure );
00296     RCC_MCOConfig( RCC_MCO_HSE );
00297 }
00298 
00299 /*******************************************************************************
00300 *
00301 *                                AUDIO_Handler
00302 *
00303 *******************************************************************************/
00311 /******************************************************************************/
00312 void AUDIO_Handler( void )
00313 {
00314     // Update codec registers, if requested
00315     AUDIO_UpdateRegisters();
00316 
00317     /* Apply configuration change, if necessary*/
00318     if ( AUDIO_SpeakerOn != AUDIO_SpeakerOnOld )
00319     {
00320         AUDIO_SPEAKER_OnOff( AUDIO_SpeakerOn );
00321         AUDIO_SpeakerOnOld = AUDIO_SpeakerOn;
00322 
00323         /* Update the default system toolbar*/
00324         TOOLBAR_SetDefaultToolbar();
00325     }
00326 
00327     return;
00328 }
00329 
00330 /*******************************************************************************
00331 *
00332 *                                AUDIO_I2S_GPIO_Init
00333 *
00334 *******************************************************************************/
00342 /******************************************************************************/
00343 void AUDIO_I2S_GPIO_Init(void)
00344 {
00345     GPIO_InitTypeDef GPIO_InitStructure;
00346 
00347     /* GPIO configuration for I2S2 port*/
00348     RCC_PERIPH_GPIO_CLOCK_CMD( GPIO_I2S_WS_PERIPH, ENABLE );
00349     RCC_PERIPH_GPIO_CLOCK_CMD( GPIO_I2S_SCK_PERIPH, ENABLE );
00350     RCC_PERIPH_GPIO_CLOCK_CMD( GPIO_I2S_SD_PERIPH, ENABLE );
00351 
00352     /* Configure I2S pins: SD, SCK and WS */
00353     GPIO_InitStructure.GPIO_Pin   = GPIO_I2S_WS_PIN;
00354     GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF_PP;
00355     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
00356     GPIO_Init( GPIOx_I2S_WS_PORT, &GPIO_InitStructure );
00357 
00358     GPIO_InitStructure.GPIO_Pin   = GPIO_I2S_SCK_PIN;
00359     GPIO_Init( GPIOx_I2S_SCK_PORT, &GPIO_InitStructure );
00360 
00361     GPIO_InitStructure.GPIO_Pin   = GPIO_I2S_SD_PIN;
00362     GPIO_Init( GPIOx_I2S_SD_PORT, &GPIO_InitStructure );
00363 
00364 }
00365 
00366 /*******************************************************************************
00367 *
00368 *                                AUDIO_CODEC_Init_I2C
00369 *
00370 ********************************************************************************/
00377 /********************************************************************************/
00378 void AUDIO_Init_I2C( void )
00379 {
00380 
00381     s32 i;
00382     GPIO_InitTypeDef  GPIO_InitStructure;
00383     I2C_InitTypeDef  I2C_InitStructure;
00384 
00385     /* GPIO configuration ---------- */
00386     RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB, ENABLE );
00387 
00388     /* Configure GPIO pins: SCL and SDA for I2C2 */
00389     GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_10 | GPIO_Pin_11;
00390     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
00391     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
00392     GPIO_Init( GPIOB, &GPIO_InitStructure );
00393 
00394     /* I2C configuration ----------- */
00395     I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
00396     I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
00397     I2C_InitStructure.I2C_OwnAddress1 = 0xC0;
00398     I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
00399     I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
00400     I2C_InitStructure.I2C_ClockSpeed = STw5094A_I2C_SPEED;
00401 
00402     /* I2C Peripheral Enable */
00403     I2C_Cmd( I2C2, ENABLE );
00404 
00405     /* Apply I2C configuration after enabling it */
00406     I2C_Init( I2C2, &I2C_InitStructure );
00407 
00408 }
00409 
00410 
00411 /*******************************************************************************
00412 *
00413 *                             AUDIO_Init_audio_mode
00414 *
00415 *******************************************************************************/
00433 /******************************************************************************/
00434 void AUDIO_Init_audio_mode( AUDIO_DeviceMode_enum mode, AUDIO_Length_enum length, AUDIO_Frequency_enum frequency, AUDIO_Format_enum format )
00435 {
00436     s32 i = 0;
00437     DMA_InitTypeDef    DMA_InitStructure;
00438     GPIO_InitTypeDef GPIO_InitStructure;
00439     I2S_InitTypeDef I2S_InitStructure;
00440     NVIC_InitTypeDef NVIC_InitStructure;
00441 
00442 
00443     /* The MONO mode uses working buffer to dupplicate datas on the two channels*/
00444     /* and switch buffer half by half => uses DMA in circular mode*/
00445     /*KJ   if (format == MONO)*/
00446     /*KJ       mode = AUDIO_CIRCULAR_MODE;*/
00447 
00448     RCC_APB1PeriphClockCmd( RCC_APBxPeriph_AUDIO_I2S, ENABLE );
00449     I2S_Cmd( AUDIO_I2S, DISABLE );
00450 
00451     /* Enable audio interface of STw5094a : set the proper config -------------*/
00452 
00453     /* MCLK or AUXCLK = 512 kHz; Voice Data Fs is 8 kHz ; Linear code ; B1 and B2 consecutive ; 8 bits time-slot*/
00454     AUDIO_CODEC_CRs[0]  = 0x00;
00455 
00456     /* Delayed data timing; CR2A connected to RX path ; TX path connected to DX; */
00457     /* PCM I/F enabled ; B1 channel selected; Normal operation*/
00458     AUDIO_CODEC_CRs[1]  = 0x14;
00459 
00460     /* Microphone inout "MIC1" Selected; MBIAS enable; Voice PreAmplifier gain = 22.5 dB*/
00461     AUDIO_CODEC_CRs[4]  = 0x6f;
00462 
00463     /* Voice Codec Receive High Pass filter enabled ; Sidetone gain = -19.5 dB (voice -> HP)*/
00464     AUDIO_CODEC_CRs[5]  = 0x17;
00465 
00466     /* !MUT + PLS (LoudSpeaker) + PHL/PHR (Headphone)+ SE + !RTE (tone)*/
00467     AUDIO_CODEC_CRs[6]  = ( AUDIO_SpeakerOn ? 0x10 : 0 ) + 0x0c + 0x02 ;
00468 
00469     /* MUT*/
00470     if ( AUDIO_Mute == TRUE )
00471     {
00472         AUDIO_CODEC_CRs[6] |= 0x20;
00473     }
00474     else
00475     {
00476         AUDIO_CODEC_CRs[6] &= 0xDF;
00477     }
00478 
00479     s32 hp_setting = ( AUDIO_Volume + 2 ) * 2;
00480     if ( hp_setting > 0x14 )
00481         hp_setting = 0x14;
00482 
00483     /* Apply new volume to codec */
00484     AUDIO_CODEC_CRs[7] = AUDIO_Volume;      /* loudspeaker gain ( +6 / -24 dB)*/
00485     AUDIO_CODEC_CRs[8] = hp_setting ;       /* left HeadPhones gain  ( +0 / -40 dB)*/
00486     AUDIO_CODEC_CRs[9] = hp_setting ;       /* right HeadPhones gain ( +0 / -40 dB)*/
00487 
00488     /* Tone generator :  F1 selected, tone gain = -24db, square*/
00489     AUDIO_CODEC_CRs[12] = 0x84;
00490 
00491     /* Tone generator : F1/F2 frequency = 445 Hz*/
00492     AUDIO_CODEC_CRs[13] = 89;
00493     AUDIO_CODEC_CRs[14] = 89;
00494 
00495     AUDIO_CODEC_CRs[16] = 0x08; /*KJ20090320 - Changed from 0x00 to 0x08 for Non-Delayed data.*/
00496 
00497     /* Headphone common driver = 1.35V + enable */
00498 #ifdef STM32F10X_CL
00499     AUDIO_CODEC_CRs[18] = 0x61;     /* AMCK between 14 and 19 MHz*/
00500 #else
00501     AUDIO_CODEC_CRs[18] = 0x60;     /* AMCK between 9 and et 14 MHz*/
00502 #endif
00503 
00504     /* Audio mode + power ON + AMCK clock for tone only*/
00505     AUDIO_CODEC_CRs[21] = 0x61;
00506 
00507     flagWrite_AUDIO_CODEC_CRs = 22;
00508 
00509 
00510     /* Init I2S communication to send data on Audio interface -----------------*/
00511 
00512     /* Enable the DMA1 Channel 5 Interrupt */
00513     NVIC_InitStructure.NVIC_IRQChannel = AUDIO_DMA_TX_Channelx_IRQn;
00514     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
00515     NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
00516     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
00517     NVIC_Init( &NVIC_InitStructure );
00518 
00519     /* DMA1 Channel4 configuration ----------------------------------------------*/
00520     RCC_AHBPeriphClockCmd( RCC_AHBPeriph_AUDIO_DMA, ENABLE );
00521     DMA_DeInit( AUDIO_DMA_TX );
00522     DMA_InitStructure.DMA_PeripheralBaseAddr = ( u32 )&AUDIO_I2S->DR;
00523     DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
00524     DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
00525     DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
00526     DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
00527     DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
00528     if ( ( mode == AUDIO_CIRCULAR_MODE ) || format == MONO ) /*/ Changed KJ 27May-09*/
00529         DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
00530     else
00531         DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
00532     DMA_InitStructure.DMA_Priority = DMA_Priority_High;
00533     DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
00534     DMA_Init( AUDIO_DMA_TX, &DMA_InitStructure );
00535 
00536     DMA_ITConfig( AUDIO_DMA_TX, DMA_IT_TC | DMA_IT_HT, ENABLE );
00537 
00538     /* GPIO configuration for I2S port*/
00539     AUDIO_I2S_GPIO_Init();
00540 
00541     /*-- Configure I2S --*/
00542     /* I2S peripheral configuration*/
00543     I2S_InitStructure.I2S_Standard   = I2S_Standard_MSB;
00544 
00545     /* I2S audio samples length - Only support 8 and 16 bit - sound quality isn't anyway better out...*/
00546     I2S_InitStructure.I2S_DataFormat = I2S_DataFormat_16b;
00547     I2S_InitStructure.I2S_MCLKOutput = I2S_MCLKOutput_Disable;
00548 
00549     /* IS2S audio samples frequency*/
00550     switch ( frequency ) /*/ KJ20090320 - Changed Selection of FRQ*/
00551     {
00552     case FRQ_8KHZ : I2S_InitStructure.I2S_AudioFreq  = I2S_AudioFreq_8k;
00553         break;
00554     case FRQ_16KHZ : I2S_InitStructure.I2S_AudioFreq  = I2S_AudioFreq_16k;
00555         break;
00556     case FRQ_22KHZ : I2S_InitStructure.I2S_AudioFreq  = I2S_AudioFreq_22k;
00557         break;
00558     case FRQ_44KHZ : I2S_InitStructure.I2S_AudioFreq  = I2S_AudioFreq_44k;
00559         break;
00560     case FRQ_48KHZ : I2S_InitStructure.I2S_AudioFreq  = I2S_AudioFreq_48k;
00561         break;
00562     default:         I2S_InitStructure.I2S_AudioFreq  = I2S_AudioFreq_8k;
00563     }
00564 
00565     I2S_InitStructure.I2S_CPOL       = I2S_CPOL_Low;
00566     I2S_InitStructure.I2S_Mode       = I2S_Mode_MasterTx;
00567 
00568     /* Set the I2S prescaler value according to the PLL value*/
00569 //    UTIL_SetPll( UTIL_GetPll() );  YRT091208 The prescaler is already calculated in the I2S_Init function
00570 
00571     I2S_Init( AUDIO_I2S, &I2S_InitStructure );
00572 
00573 #ifdef STM32F10X_CL
00574     /* Set the I2S prescaler value according to the PLL value*/
00575     AUDIO_SetClocks( frequency );
00576 #endif
00577 
00578     Audio_buffer_index = 0;
00579     AUDIO_Playback_status = NO_SOUND;
00580 
00581     /* Memorize new audio format values*/
00582     AUDIO_Length = length;
00583     AUDIO_Frequency = frequency;
00584     AUDIO_Format = format;
00585 
00586     /*Buffers are supposed to be empty here*/
00587     audio_buffer_fill = LOW_EMPTY | HIGH_EMPTY ;
00588 
00589     /* Enable the I2S2*/
00590     I2S_Cmd( AUDIO_I2S, ENABLE );
00591 
00592     /* Audio mode ready*/
00593 }
00594 
00595 /*******************************************************************************
00596 *
00597 *                             AUDIO_Init_voice_mode
00598 *
00599 *******************************************************************************/
00613 /******************************************************************************/
00614 void AUDIO_Init_voice_mode( AUDIO_DeviceMode_enum mode )
00615 {
00616     s32 i = 0;
00617     GPIO_InitTypeDef GPIO_InitStructure;
00618     I2S_InitTypeDef I2S_InitStructure;
00619     NVIC_InitTypeDef NVIC_InitStructure;
00620     DMA_InitTypeDef    DMA_InitStructure;
00621 
00622     RCC_APB1PeriphClockCmd( RCC_APBxPeriph_AUDIO_I2S , ENABLE );
00623     I2S_Cmd( AUDIO_I2S, DISABLE );
00624 
00625     /* Enable audio interface of STw5094a : set the proper config -------------*/
00626 
00627     /* MCLK or AUXCLK = 512 kHz; Voice Data Fs is 16 kHz ; Linear code ; B1 and B2 consecutive ; 8 bits time-slot*/
00628     AUDIO_CODEC_CRs[0]  = 0x20; /*/0x20 16khz / 0x00 8Khz*/
00629 
00630     /* Delayed data timing; CR2A connected to RX path ; TX path connected to DX; */
00631     /* PCM I/F enabled ; B1 channel selected; Normal operation*/
00632     AUDIO_CODEC_CRs[1]  = 0x14;
00633 
00634     /* Microphone inout "MIC1" Selected; MBIAS enable; Voice PreAmplifier gain = 22.5 dB*/
00635     AUDIO_CODEC_CRs[4]  = 0x6f;
00636 
00637     /* Voice Codec Receive High Pass filter enabled (HPB); Codec internal sidetone enabled (SI)*/
00638     /* Sidetone gain = -15.5 dB (voice -> HP)*/
00639     AUDIO_CODEC_CRs[5]  = 0x13;
00640 
00641     /* !PLS (LoudSpeaker) + !PHL/PHR (Headphone)+ !SE + !RTE (tone)*/
00642     AUDIO_CODEC_CRs[6]  = 0; /*record, no sound  (AUDIO_SpeakerOn?0x10:0) + 0x0c; */
00643 
00644     /* MUT*/
00645     if ( AUDIO_Mute == TRUE )
00646     {
00647         AUDIO_CODEC_CRs[6] |= 0x20;
00648     }
00649     else
00650     {
00651         AUDIO_CODEC_CRs[6] &= 0xDF;
00652     }
00653 
00654     /* Apply volume to codec */
00655     s32 hp_setting = ( AUDIO_Volume + 2 ) * 2;
00656     if ( hp_setting > 0x14 )
00657         hp_setting = 0x14;
00658 
00659     /* Apply new volume to codec */
00660     AUDIO_CODEC_CRs[7] = AUDIO_Volume;      /* loudspeaker gain ( +6 / -24 dB)*/
00661     AUDIO_CODEC_CRs[8] = hp_setting ;       /* left HeadPhones gain  ( +0 / -40 dB)*/
00662     AUDIO_CODEC_CRs[9] = hp_setting ;       /* right HeadPhones gain ( +0 / -40 dB)*/
00663 
00664     /* Tone generator :  F1 and F2 muted, tone gain = 0 db, square, no output*/
00665     AUDIO_CODEC_CRs[12] = 0x00;
00666 
00667     /* Tone generator : F1/F2 frequency = 445 Hz*/
00668     AUDIO_CODEC_CRs[13]  = AUDIO_CODEC_CRs[14]  = 0x0;
00669 
00670     /* Headphone common driver = 1.35V + enable / AMCK between 9 et 14 MHz*/
00671     AUDIO_CODEC_CRs[18] = 0x60;
00672 
00673     /* Voice mode + power ON + AUXCLK clock for tone only*/
00674     AUDIO_CODEC_CRs[21] = 0x01;
00675 
00676     flagWrite_AUDIO_CODEC_CRs = 22;
00677 
00678     /* Init I2S communication to send data on Audio interface -----------------*/
00679 
00680     /* Enable the DMA1 Channel 4 Interrupt */
00681     NVIC_InitStructure.NVIC_IRQChannel = AUDIO_DMA_RX_Channelx_IRQn;
00682     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
00683     NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
00684     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
00685     NVIC_Init( &NVIC_InitStructure );
00686 
00687     /* DMA1 Channel4 configuration ----------------------------------------------*/
00688     RCC_AHBPeriphClockCmd( RCC_AHBPeriph_AUDIO_DMA, ENABLE );
00689     DMA_DeInit( AUDIO_DMA_RX );
00690     DMA_InitStructure.DMA_PeripheralBaseAddr = ( u32 )&AUDIO_I2S->DR;
00691     DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
00692     DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
00693     DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
00694     DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
00695     DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
00696     if ( mode == VOICE_CIRCULAR_MODE )
00697         DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
00698     else
00699         DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
00700     DMA_InitStructure.DMA_Priority = DMA_Priority_High;
00701     DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
00702     DMA_Init( AUDIO_DMA_RX, &DMA_InitStructure );
00703 
00704     DMA_ITConfig( AUDIO_DMA_RX, DMA_IT_TC | DMA_IT_HT, ENABLE );
00705 
00706     /* GPIO configuration for I2S port*/
00707     AUDIO_I2S_GPIO_Init();
00708 
00709     /*-- Configure I2S --*/
00710     /* I2S peripheral configuration, set PCM standard*/
00711     I2S_InitStructure.I2S_Standard = I2S_Standard_PCMShort;
00712 
00713     /* I2S audio samples length*/
00714     I2S_InitStructure.I2S_DataFormat = I2S_DataFormat_16bextended; /* We only support this mode..*/
00715 
00716     I2S_InitStructure.I2S_MCLKOutput = I2S_MCLKOutput_Disable;
00717 
00718     /* IS2S audio samples frequency*/
00719     I2S_InitStructure.I2S_AudioFreq  = I2S_AudioFreq_16k; /* We only support 16bit due to MCLK 1CH x 32Bit x 16Khz = 512KhzMCLK*/
00720     I2S_InitStructure.I2S_CPOL       = I2S_CPOL_Low;
00721     I2S_InitStructure.I2S_Mode       = I2S_Mode_MasterRx;
00722     I2S_Init( AUDIO_I2S, &I2S_InitStructure );
00723 
00724     /* Set the I2S prescaler value according to the PLL value*/
00725 #ifdef STM32F10X_CL
00726     /* Set the clocks according to the sample frequency required */
00727     UTIL_SetPll( SPEED_VERY_HIGH );
00728     AUDIO_SetClocks( FRQ_16KHZ );
00729 #else
00730     UTIL_SetPll( UTIL_GetPll() );
00731 #endif
00732 
00733     Voice_buffer_index = 0;
00734     AUDIO_Recording_status = NO_RECORD;
00735 
00736     /* Memorize new audio format values*/
00737     AUDIO_Length = LG_16_BITS;
00738     AUDIO_Frequency = FRQ_16KHZ;
00739     AUDIO_Format = MONO;
00740 
00741     /* Enable the I2S2*/
00742     I2S_Cmd( AUDIO_I2S, ENABLE );
00743 
00744     /* Voice mode ready*/
00745 }
00746 
00747 
00748 /*******************************************************************************
00749 *
00750 *                                AUDIO_Shutdown
00751 *
00752 *******************************************************************************/
00760 /******************************************************************************/
00761 void AUDIO_Shutdown( void )
00762 {
00763     /* Stop IT SPI*/
00764     I2S_Cmd( AUDIO_I2S, DISABLE );
00765 
00766     /* Reset and power down the codec*/
00767     AUDIO_DeviceSoftwareReset();
00768 
00769     /* Stop I2C*/
00770     I2C_Cmd( I2C2, DISABLE );
00771 }
00772 
00773 /*******************************************************************************
00774 *
00775 *                                AUDIO_Welcome_Msg
00776 *
00777 ********************************************************************************/
00783 /********************************************************************************/
00784 const u8 welcome_16K_8 [] =
00785 {
00786 #include "welcome_stm32_16k_8b.h"
00787 };
00788 
00789 void AUDIO_Welcome_Msg( void )
00790 {
00791     AUDIO_SetMode( AUDIO_MODE, LG_8_BITS, FRQ_16KHZ, MONO );
00792     AUDIO_Play( ( sound_type* )welcome_16K_8, sizeof welcome_16K_8 );
00793 }
00794 
00795 /*******************************************************************************
00796 *
00797 *                            AUDIO_I2C_Read_Register
00798 *
00799 *******************************************************************************/
00810 /******************************************************************************/
00811 u8 AUDIO_I2C_Read_Register( u8 register_to_read )
00812 {
00813     u8 val = 0;
00814     AUDIO_I2C_ReadMultByte( register_to_read, 1, &val );
00815     return val;
00816 }
00817 
00818 /*******************************************************************************
00819 *
00820 *                           AUDIO_I2C_WriteRegister
00821 *
00822 *******************************************************************************/
00834 /******************************************************************************/
00835 void AUDIO_I2C_WriteRegister( u8 register_to_write, u8 data_to_write )
00836 {
00837     AUDIO_I2C_WriteMultByte( register_to_write, 1, &data_to_write );
00838 }
00839 
00840 /*******************************************************************************
00841 *
00842 *                            AUDIO_I2C_WriteMultByte
00843 *
00844 *******************************************************************************/
00859 /******************************************************************************/
00860 void AUDIO_I2C_WriteMultByte( u8 WriteAddr, u8 NumByteToWrite, u8* pBuffer )
00861 {
00862     s32 i;
00863     vu32 dr_temp ;
00864     u32 TimeOut;
00865 
00866     /* Send START condition */
00867     I2C_GenerateSTART( I2C2, ENABLE );
00868 
00869     /* Test on EV5 and clear it */
00870     TimeOut = STw5094A_I2C_LONG_TIMEOUT;
00871     while ( !I2C_CheckEvent( I2C2, I2C_EVENT_MASTER_MODE_SELECT ) )
00872     {
00873         if ( I2C2->SR1 & I2C_FLAG_RXNE )
00874             dr_temp = I2C2->DR;
00875 
00876         if ( ( TimeOut-- ) == 0 )
00877             return;
00878     }
00879 
00880     /* Send STw5094A address for write */
00881     I2C_Send7bitAddress( I2C2, STw5094A_ADDR_WR, I2C_Direction_Transmitter );
00882 
00883     /* Test on EV6 and clear it */
00884     TimeOut = STw5094A_I2C_LONG_TIMEOUT;
00885     while ( !I2C_CheckEvent( I2C2, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED ) )
00886     {
00887         if ( ( TimeOut-- ) == 0 )
00888             return;
00889     }
00890 
00891     /* Send the STw5094A's internal address to write to */
00892     I2C_SendData( I2C2, WriteAddr );
00893 
00894 
00895     /* Test on EV8 and clear it */
00896     TimeOut = STw5094A_I2C_LONG_TIMEOUT;
00897     while ( !I2C_CheckEvent( I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED ) )
00898     {
00899         if ( ( TimeOut-- ) == 0 )
00900             return;
00901     }
00902 
00903     while ( NumByteToWrite ) /* uses the STw5094A's addr. register auto-increment feature*/
00904     {
00905         /* Send the byte to be written */
00906         I2C_SendData( I2C2, * pBuffer );
00907 
00908         /* Test on EV8 and clear it */
00909         TimeOut = STw5094A_I2C_LONG_TIMEOUT;
00910         while ( !I2C_CheckEvent( I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED ) )
00911         {
00912             if ( ( TimeOut-- ) == 0 )
00913                 return;
00914         }
00915 
00916         if ( NumByteToWrite == 1 )
00917             { I2C_GenerateSTOP( I2C2, ENABLE ); } /* STOP */
00918 
00919         pBuffer++;
00920         NumByteToWrite--;
00921     }
00922     for ( i = 0 ; i < 500 ; i++ )    { ; }
00923 }
00924 
00925 /*******************************************************************************
00926 *
00927 *                            AUDIO_I2C_ReadMultByte
00928 *
00929 *******************************************************************************/
00945 /******************************************************************************/
00946 s32 AUDIO_I2C_ReadMultByte( u8 ReadAddr, u8 NumByteToRead, u8* pBuffer )
00947 {
00948     s32 i;
00949     vu32 dr_temp ;
00950     u32 TimeOut;
00951 
00952     /* Send START condition */
00953     I2C_GenerateSTART( I2C2, ENABLE );
00954 
00955     /* Test on EV5 and clear it */
00956     TimeOut = STw5094A_I2C_LONG_TIMEOUT;
00957     while ( !I2C_CheckEvent( I2C2, I2C_EVENT_MASTER_MODE_SELECT ) )
00958     {
00959         if ( I2C2->SR1 & I2C_FLAG_RXNE )
00960             dr_temp = I2C2->DR;
00961 
00962         if ( ( TimeOut-- ) == 0 )
00963             return;
00964     }
00965 
00966     /* Send STw5094A address for write */
00967     I2C_Send7bitAddress( I2C2, STw5094A_ADDR_WR, I2C_Direction_Transmitter );
00968 
00969 
00970     /* Test on EV6 and clear it */
00971     TimeOut = STw5094A_I2C_LONG_TIMEOUT;
00972     while ( !I2C_CheckEvent( I2C2, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED ) )
00973     {
00974         if ( ( TimeOut-- ) == 0 )
00975             return;
00976     }
00977 
00978     /* Clear EV6 by setting again the PE bit */
00979     I2C_Cmd( I2C2, ENABLE );
00980 
00981     /* Send the STw5094A's internal address to write to */
00982     I2C_SendData( I2C2, ReadAddr );
00983 
00984     /* Test on EV8 and clear it */
00985     TimeOut = STw5094A_I2C_LONG_TIMEOUT;
00986     while ( !I2C_CheckEvent( I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED ) )
00987     {
00988         if ( ( TimeOut-- ) == 0 )
00989             return;
00990     }
00991 
00992     /* Send START condition a second time */
00993     I2C_GenerateSTART( I2C2, ENABLE );
00994 
00995     /* Test on EV5 and clear it */
00996     TimeOut = STw5094A_I2C_LONG_TIMEOUT;
00997     while ( !I2C_CheckEvent( I2C2, I2C_EVENT_MASTER_MODE_SELECT ) )
00998     {
00999         if ( ( TimeOut-- ) == 0 )
01000             return;
01001     }
01002 
01003     /* Send STw5094A address for read */
01004     I2C_Send7bitAddress( I2C2, STw5094A_ADDR_RD, I2C_Direction_Receiver );
01005 
01006     /* Test on EV6 and clear it */
01007     TimeOut = STw5094A_I2C_LONG_TIMEOUT;
01008     while ( !I2C_CheckEvent( I2C2, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED ) )
01009     {
01010         if ( ( TimeOut-- ) == 0 )
01011             return;
01012     }
01013 
01014     /* While there is data to be read */
01015     while ( NumByteToRead )
01016     {
01017         if ( NumByteToRead == 1 )
01018         {
01019             /* Disable Acknowledgement */
01020             I2C_AcknowledgeConfig( I2C2, DISABLE );
01021 
01022             /* Send STOP Condition */
01023             I2C_GenerateSTOP( I2C2, ENABLE );
01024         }
01025 
01026         /* Test on EV7 and clear it */
01027         TimeOut = STw5094A_I2C_LONG_TIMEOUT;
01028         if ( I2C_CheckEvent( I2C2, I2C_EVENT_MASTER_BYTE_RECEIVED ) )
01029         {
01030             /* Read a byte from the codec */
01031             *pBuffer = I2C_ReceiveData( I2C2 );
01032 
01033             /* Point to the next location where the byte read will be saved */
01034             pBuffer++;
01035 
01036             /* Decrement the read bytes counter */
01037             NumByteToRead--;
01038         }
01039         else
01040         {
01041             if ( ( TimeOut-- ) == 0 )
01042                 return;
01043         }
01044 
01045     }
01046 
01047     /* Enable Acknowledgement to be ready for another reception */
01048     I2C_AcknowledgeConfig( I2C2, ENABLE );
01049 
01050     for ( i = 0 ; i < 500 ; i++ )    { ; }
01051 }
01052 
01053 
01054 /*******************************************************************************
01055 *
01056 *                            AUDIO_BUZZER_SetToneFrequency
01057 *
01058 *******************************************************************************/
01068 /******************************************************************************/
01069 void AUDIO_BUZZER_SetToneFrequency( u16 freq )
01070 {
01071     u16 valreg;
01072 
01073     if ( freq < 250 )
01074         valreg = ( 256 * freq ) / 1000;
01075     else
01076     {
01077         if ( freq < 750 )
01078             valreg = ( ( 128 * freq ) / 1000 ) + 32;
01079         else
01080         {
01081             if ( freq < 1750 )
01082                 valreg = ( ( 64 * freq ) / 1000 ) + 80;
01083             else
01084             {
01085                 if ( freq < 3720 )
01086                     valreg = ( ( 32 * freq ) / 1000 ) + 136;
01087                 else
01088                     valreg = 255;
01089             }
01090         }
01091     }
01092 
01093     /* Set frequency to */
01094     AUDIO_CODEC_CRs[13] = valreg;
01095     AUDIO_CODEC_CRs[14] = valreg;
01096 
01097     /* Update register (to be done by the tim2 irq)*/
01098     SET_FLAG_WRITE_CODEC_CRS( 13 );
01099 }
01100 
01101 /*******************************************************************************
01102 *
01103 *                            AUDIO_BUZZER_OnOff
01104 *
01105 *******************************************************************************/
01116 /******************************************************************************/
01117 void AUDIO_BUZZER_OnOff( ON_OFF_enum mode )
01118 {
01119     if ( mode != OFF )
01120         AUDIO_CODEC_CRs[6] |= 0x01;
01121     else
01122         AUDIO_CODEC_CRs[6] &= 0xFE;
01123 
01124     /* Update register (to be done by the tim2 irq)*/
01125     SET_FLAG_WRITE_CODEC_CRS( 6 );
01126 }
01127 
01128 /*******************************************************************************
01129 *
01130 *                            AUDIO_Set_Volume
01131 *
01132 *******************************************************************************/
01137 /******************************************************************************/
01138 void AUDIO_Set_Volume( void )
01139 {
01140     s32 hp_setting = ( AUDIO_Volume + 2 ) * 2;
01141     if ( hp_setting > 0x14 )
01142         hp_setting = 0x14;
01143 
01144     /* Apply new volume to codec */
01145     AUDIO_CODEC_CRs[7] = AUDIO_Volume;      /* loudspeaker gain ( +6 / -24 dB)*/
01146     AUDIO_CODEC_CRs[8] = hp_setting ;       /* left HeadPhones gain  ( +0 / -40 dB)*/
01147     AUDIO_CODEC_CRs[9] = hp_setting ;       /* right HeadPhones gain ( +0 / -40 dB)*/
01148 
01149     /* Update all registers (to be done by the tim2 irq)*/
01150     SET_FLAG_WRITE_CODEC_CRS( 22 );
01151 }
01152 
01153 /*******************************************************************************
01154 *
01155 *                                AUDIO_Cpy_Mono
01156 *
01157 ********************************************************************************/
01163 /********************************************************************************/
01164 void AUDIO_Cpy_Mono( void )
01165 {
01166     volatile u16 i;
01167     s16  temp;
01168 
01169     /* Stop if end of original buffer */
01170     if ( Audio_buffer_index >= Audio_buffer_size )
01171     {
01172         if ( AUDIO_DeviceMode == AUDIO_MODE ) /* KJ 27may-2009*/
01173             AUDIO_Playback_Stop();
01174     }
01175 
01176     /* End of the first half working buffer*/
01177     if ( bufferstatus_local & LOW_EMPTY )
01178     {
01179         if ( AUDIO_Length == LG_16_BITS )
01180         {
01181             for ( i = 0 ; i < ( ( Audio_buffer_local_size / 4 ) - 1 ) ; i = i + 2 )
01182             {
01183                 temp = *( s16* )( Audio_buffer + Audio_buffer_index );
01184                 Audio_buffer_local[i + 1] = Audio_buffer_local[i] = temp;
01185                 Audio_buffer_index += 2; /* 16 bit*/
01186             }
01187         }
01188         else
01189         {
01190             for ( i = 0; i < ( ( Audio_buffer_local_size / 4 ) - 1 ); i = i + 2 )
01191             {
01192                 temp = ( ( s16 )( ( *( Audio_buffer + Audio_buffer_index ) ^ 0x80 ) ) ) << 8;
01193                 Audio_buffer_local[i + 1] = Audio_buffer_local[i] = temp;
01194                 Audio_buffer_index++; /* 8 bit      */
01195             }
01196         }
01197         bufferstatus_local &= ~LOW_EMPTY;
01198     }
01199 
01200     /* End of the second half working buffer*/
01201     if ( bufferstatus_local & HIGH_EMPTY )
01202     {
01203         if ( AUDIO_Length == LG_16_BITS )
01204         {
01205             for ( i = ( Audio_buffer_local_size / 4 ) ; i < ( Audio_buffer_local_size / 2 ); i = i + 2 )
01206             {
01207                 temp = *( s16* )( Audio_buffer + Audio_buffer_index );
01208                 Audio_buffer_local[i + 1] = Audio_buffer_local[i] = temp;
01209                 Audio_buffer_index += 2; /* 16 bit*/
01210             }
01211         }
01212         else
01213         {
01214             for ( i = ( Audio_buffer_local_size / 4 ); i < ( ( Audio_buffer_local_size ) / 2 ) - 1; i = i + 2 )
01215             {
01216                 temp = ( ( s16 )( ( *( Audio_buffer + Audio_buffer_index ) ^ 0x80 ) ) ) << 8;
01217                 Audio_buffer_local[i + 1] = Audio_buffer_local[i] = temp;
01218                 Audio_buffer_index++; /* 8 bit      */
01219             }
01220         }
01221         bufferstatus_local &= ~HIGH_EMPTY;
01222     }
01223 
01224     if ( Audio_buffer_index == ( Audio_buffer_size / 2 ) )
01225     {
01226         audio_buffer_fill |= LOW_EMPTY;
01227         if ( audio_buffer_fill & HIGH_EMPTY )
01228         {
01229             if ( AUDIO_DeviceMode == AUDIO_MODE ) /* KJ 27may-2009*/
01230                 AUDIO_Playback_Stop();
01231         }
01232     }
01233     if ( Audio_buffer_index >= Audio_buffer_size )
01234     {
01235         audio_buffer_fill |= HIGH_EMPTY;
01236         Audio_buffer_index = 0;
01237         if ( audio_buffer_fill & LOW_EMPTY )
01238         {
01239             if ( AUDIO_DeviceMode == AUDIO_MODE ) /* KJ 27may-2009*/
01240                 AUDIO_Playback_Stop();
01241         }
01242     }
01243 }
01244 
01246 
01247 /* Public functions ----------------------------------------------------------*/
01248 
01249 
01250 /*******************************************************************************
01251 *
01252 *                                AUDIO_SetMode
01253 *
01254 ********************************************************************************/
01267 /********************************************************************************/
01268 void AUDIO_SetMode( AUDIO_DeviceMode_enum mode,
01269                     AUDIO_Length_enum length,
01270                     AUDIO_Frequency_enum frequency,
01271                     AUDIO_Format_enum format )
01272 {
01273     if ( ( mode == VOICE_MODE ) || ( mode == VOICE_CIRCULAR_MODE ) )
01274         AUDIO_Init_voice_mode( mode );
01275     else
01276         AUDIO_Init_audio_mode( mode, length, frequency, format );
01277 
01278     AUDIO_DeviceMode = mode;
01279 }
01280 
01281 
01282 /*******************************************************************************
01283 *
01284 *                                AUDIO_GetMode
01285 *
01286 ********************************************************************************/
01296 /********************************************************************************/
01297 AUDIO_DeviceMode_enum AUDIO_GetMode( void )
01298 {
01299     return AUDIO_DeviceMode;
01300 }
01301 
01302 /*******************************************************************************
01303 *
01304 *                                AUDIO_Play
01305 *
01306 ********************************************************************************/
01318 /********************************************************************************/
01319 void AUDIO_Play( const sound_type* buffer, s32 size )
01320 {
01321     audio_buffer_fill =  LOW_EMPTY | HIGH_EMPTY;
01322     bufferstatus_local =  LOW_EMPTY | HIGH_EMPTY;
01323 
01324     if ( AUDIO_Format == STEREO )
01325     {
01326         /* Uses the original buffer*/
01327         AUDIO_DMA_TX->CMAR = ( u32 )buffer;         // Set the buffer
01328         AUDIO_DMA_TX->CNDTR = size;                 /* Set the size */
01329     }
01330     else
01331     {
01332         /* Uses the local buffer*/
01333         if ( AUDIO_Length == LG_16_BITS )
01334             size *= 2;
01335         Audio_buffer = ( sound_type* ) buffer;       /* Copy the pointer to real databuffer/source*/
01336         Audio_buffer_index = 0;                      /* Copy the pointer to real databuffer/source*/
01337         Audio_buffer_size = size;                    /* Size to the real databuffer/source*/
01338         AUDIO_Cpy_Mono();
01339         AUDIO_DMA_TX->CMAR = ( u32 )Audio_buffer_local;        /* Set the buffer*/
01340         AUDIO_DMA_TX->CNDTR = ( ( Audio_buffer_local_size ) / 2 ); /* Set the size*/
01341     }
01342 
01343     DMA_Cmd( AUDIO_DMA_TX, ENABLE );                 /* Enable DMA Channel for Audio*/
01344     SPI_I2S_DMACmd( AUDIO_I2S, SPI_I2S_DMAReq_Tx, ENABLE ); /* Enable I2S DMA REQ.*/
01345     AUDIO_Playback_status = IS_PLAYING;
01346 }
01347 
01348 /*******************************************************************************
01349 *
01350 *                                AUDIO_Playback_Stop
01351 *
01352 ********************************************************************************/
01358 /********************************************************************************/
01359 void AUDIO_Playback_Stop( void )
01360 {
01361     vs32 i;
01362 
01363     DMA_Cmd( AUDIO_DMA_TX, DISABLE );                  /* Disable DMA Channel for Audio*/
01364     SPI_I2S_DMACmd( AUDIO_I2S, SPI_I2S_DMAReq_Tx, DISABLE ); /* Disable I2S DMA REQ.*/
01365 
01366     AUDIO_Playback_status = NO_SOUND;
01367 
01368     /* Shutdwon codec in order to avoid non expected voices*/
01369     AUDIO_WriteRegister( 21, 0x60 );
01370     for ( i = 0; i < 10000 ; i++ ) {;}
01371 
01372     /* Wake up codec*/
01373     AUDIO_WriteRegister( 21, 0x61 );
01374 
01375 }
01376 
01377 
01378 /*******************************************************************************
01379 *
01380 *                                AUDIO_Record
01381 *
01382 ********************************************************************************/
01390 /********************************************************************************/
01391 void AUDIO_Record( sound_type* buffer, s32 size )
01392 {
01393     /* Initialize the recording buffer*/
01394     Voice_buffer = ( voice_type* ) buffer;
01395     Voice_buffer_size = size;
01396     Voice_buffer_index = 0;
01397     voice_record_buffer_fill = EMPTY;
01398 
01399     /* Inform that actual data tranfer is processed in the interrupt handler*/
01400     AUDIO_Recording_status = IS_RECORDING;
01401     AUDIO_DMA_RX->CMAR = ( u32 )buffer;                 /* Set the buffer*/
01402     AUDIO_DMA_RX->CNDTR = size;                         /* Set the size*/
01403     DMA_Cmd( AUDIO_DMA_RX, ENABLE );                    /* Enable DMA Channel for Audio*/
01404     SPI_I2S_DMACmd( AUDIO_I2S, SPI_I2S_DMAReq_Rx, ENABLE );   /* Enable I2S DMA REQ.*/
01405 }
01406 
01407 /*******************************************************************************
01408 *
01409 *                                AUDIO_Record_Stop
01410 *
01411 ********************************************************************************/
01417 /********************************************************************************/
01418 void AUDIO_Record_Stop( void )
01419 {
01420     DMA_Cmd( AUDIO_DMA_RX, DISABLE );                  /* Disable DMA Channel for Audio */
01421     SPI_I2S_DMACmd( AUDIO_I2S, SPI_I2S_DMAReq_Rx, DISABLE ); /* Disable I2S DMA REQ.*/
01422     AUDIO_Recording_status = NO_RECORD;
01423 }
01424 
01425 /*******************************************************************************
01426 *
01427 *                            AUDIO_Playback_GetStatus
01428 *
01429 *******************************************************************************/
01437 /******************************************************************************/
01438 AUDIO_Playback_status_enum AUDIO_Playback_GetStatus( void )
01439 {
01440     return AUDIO_Playback_status;
01441 }
01442 
01443 /*******************************************************************************
01444 *
01445 *                            AUDIO_PlaybackBuffer_GetStatus
01446 *
01447 *******************************************************************************/
01458 /******************************************************************************/
01459 AUDIO_PlaybackBuffer_Status AUDIO_PlaybackBuffer_GetStatus( AUDIO_PlaybackBuffer_Status value )
01460 {
01461     if ( value )
01462         audio_buffer_fill &= ~value;
01463     return audio_buffer_fill;
01464 }
01465 
01466 /*******************************************************************************
01467 *
01468 *                            AUDIO_Record_Buffer_GetStatus
01469 *
01470 *******************************************************************************/
01481 /******************************************************************************/
01482 AUDIO_RecordBuffer_Status AUDIO_RecordBuffer_GetStatus( AUDIO_RecordBuffer_Status value )
01483 {
01484     if ( value )
01485         voice_record_buffer_fill &= ~value;
01486     return voice_record_buffer_fill;
01487 }
01488 
01489 /*******************************************************************************
01490 *
01491 *                            AUDIO_Recording_GetStatus
01492 *
01493 *******************************************************************************/
01501 /******************************************************************************/
01502 AUDIO_Recording_status_enum AUDIO_Recording_GetStatus( void )
01503 {
01504     return AUDIO_Recording_status;
01505 }
01506 
01507 /*******************************************************************************
01508 *
01509 *                            AUDIO_SPEAKER_OnOff
01510 *
01511 *******************************************************************************/
01521 /******************************************************************************/
01522 void AUDIO_SPEAKER_OnOff( ON_OFF_enum mode )
01523 {
01524     if ( mode != OFF )
01525     {
01526         AUDIO_CODEC_CRs[6] |= 0x10;
01527         AUDIO_SpeakerOn = 1;
01528     }
01529     else
01530     {
01531         AUDIO_CODEC_CRs[6] &= 0xEF;
01532         AUDIO_SpeakerOn = 0;
01533     }
01534 
01535     /* Update register */
01536     SET_FLAG_WRITE_CODEC_CRS( 6 );
01537 }
01538 
01539 /*******************************************************************************
01540 *
01541 *                            AUDIO_MUTE_OnOff
01542 *
01543 *******************************************************************************/
01552 /******************************************************************************/
01553 void AUDIO_MUTE_OnOff( ON_OFF_enum mode )
01554 {
01555     if ( mode != OFF )
01556     {
01557         AUDIO_CODEC_CRs[6] |= 0x20;
01558         AUDIO_Mute = TRUE;
01559     }
01560     else
01561     {
01562         AUDIO_CODEC_CRs[6] &= 0xDF;
01563         AUDIO_Mute = FALSE;
01564     }
01565 
01566     /* Updates register*/
01567     SET_FLAG_WRITE_CODEC_CRS( 6 );
01568 }
01569 
01570 /*******************************************************************************
01571 *
01572 *                            AUDIO_isMute
01573 *
01574 *******************************************************************************/
01583 /******************************************************************************/
01584 bool AUDIO_IsMute( void )
01585 {
01586     return ( AUDIO_Mute == 1 );
01587 }
01588 
01589 /*******************************************************************************
01590 *
01591 *                            AUDIO_Inc_Volume
01592 *
01593 *******************************************************************************/
01600 /******************************************************************************/
01601 void AUDIO_Inc_Volume( u8 dB )
01602 {
01603     /* 2 dB step minimum*/
01604     if ( dB <= 1 )
01605         dB = 2;
01606 
01607     /* Decrement the internal attenuation value*/
01608     AUDIO_Volume -= dB / 2;
01609     if ( AUDIO_Volume < AUDIO_MIN_ATTENUATION )
01610         AUDIO_Volume = AUDIO_MIN_ATTENUATION;
01611 
01612     /* Apply new volume to codec */
01613     AUDIO_Set_Volume( );
01614 }
01615 
01616 /*******************************************************************************
01617 *
01618 *                            AUDIO_Dec_Volume
01619 *
01620 *******************************************************************************/
01627 /******************************************************************************/
01628 void AUDIO_Dec_Volume( u8 dB )
01629 {
01630     /* 2 dB step minimum*/
01631     if ( dB <= 1 )
01632         dB = 2;
01633 
01634     /* Increment the internal attenuation value*/
01635     AUDIO_Volume += ( dB / 2 );
01636     if ( AUDIO_Volume > 15 )
01637         AUDIO_Volume = 15;
01638 
01639     /* Apply new volume to codec */
01640     AUDIO_Set_Volume( );
01641 }
01642 
01643 /*******************************************************************************
01644 *
01645 *                            AUDIO_ReadRegister
01646 *
01647 *******************************************************************************/
01658 /******************************************************************************/
01659 u8 AUDIO_ReadRegister( u8 register_to_read )
01660 {
01661     u8 val = 0;
01662     if ( register_to_read < 22 )
01663     {
01664         /* Get the new register value*/
01665         AUDIO_I2C_ReadMultByte( register_to_read, 1, &val );
01666         /* Update the local register table*/
01667         AUDIO_CODEC_CRs[register_to_read] = val;
01668     }
01669     return val;
01670 }
01671 
01672 /*******************************************************************************
01673 *
01674 *                           AUDIO_WriteRegister
01675 *
01676 *******************************************************************************/
01689 /******************************************************************************/
01690 void AUDIO_WriteRegister( u8 register_to_write, u8 data_to_write )
01691 {
01692     if ( register_to_write < 22 )
01693     {
01694         /* Update the local register table*/
01695         AUDIO_CODEC_CRs[register_to_write] = data_to_write;
01696         /* Launch write register*/
01697         SET_FLAG_WRITE_CODEC_CRS( register_to_write );
01698     }
01699 }
01700 
01701 /*******************************************************************************
01702 *
01703 *                            AUDIO_SetLocalBufferSize
01704 *
01705 *******************************************************************************/
01714 /******************************************************************************/
01715 void AUDIO_SetLocalBufferSize( s32 size )
01716 {
01717 
01718     /* Convert in 16 bits words size*/
01719     size /= 2;
01720 
01721     if ( size < 128 )
01722         size = 128;
01723 
01724     if ( size > LOCAL_BUFFER_SIZE )
01725         size = LOCAL_BUFFER_SIZE;
01726 
01727     Audio_buffer_local_size = size;
01728 }