void CodecController::setup(){ /* Configure the Codec related IOs */ Codec_GPIO_Init(); /* Initialize the Control interface of the Audio Codec */ Codec_CtrlInterface_Init(); /* Reset the Codec Registers */ if(Codec_Reset() != 0) assert_param(false); /* Load default values */ for(int i=0;i<WM8731_NUM_REGS-1;i++) writeRegister(i, wm8731_init_data[i]); // RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); // DEBUG // configureDigitalOutput(GPIOA, GPIO_Pin_6); // DEBUG // configureDigitalOutput(GPIOA, GPIO_Pin_7); // DEBUG // clearPin(GPIOA, GPIO_Pin_6); // DEBUG // clearPin(GPIOA, GPIO_Pin_7); // DEBUG }
/** * @brief Restore the audio codec state to default state and free all used * resources. * @param None. * @retval o if correct communication, else wrong communication */ uint32_t Codec_DeInit(void) { uint32_t counter = 0; /* Reset the Codec Registers */ Codec_Reset(); /* Keep Codec powered OFF */ counter += Codec_WriteRegister(0x02, 0x01); /* Deinitialize all use GPIOs */ Codec_GPIO_DeInit(); /* Disable the Codec control interface */ Codec_CtrlInterface_DeInit(); /* Deinitialize the Codec audio interface (I2S) */ Codec_AudioInterface_DeInit(); /* Return communication control value */ return counter; }
/** * @brief Initializes the audio codec and all related interfaces (control * interface: I2C and audio interface: I2S) * @param OutputDevice: can be OUTPUT_DEVICE_SPEAKER, OUTPUT_DEVICE_HEADPHONE, * OUTPUT_DEVICE_BOTH or OUTPUT_DEVICE_AUTO . * @param Volume: Initial volume level (from 0 (Mute) to 100 (Max)) * @param AudioFreq: Audio frequency used to paly the audio stream. * @retval o if correct communication, else wrong communication */ uint32_t Codec_Init(uint16_t OutputDevice, uint8_t Volume, uint32_t AudioFreq) { uint32_t counter = 0; /* Configure the Codec related IOs */ Codec_GPIO_Init(); /* Reset the Codec Registers */ Codec_Reset(); /* Initialize the Control interface of the Audio Codec */ Codec_CtrlInterface_Init(); /* Keep Codec powered OFF */ counter += Codec_WriteRegister(0x02, 0x01); switch (OutputDevice) { case OUTPUT_DEVICE_SPEAKER: counter += Codec_WriteRegister(0x04, 0xFA); /* SPK always ON & HP always OFF */ OutputDev = 0xFA; break; case OUTPUT_DEVICE_HEADPHONE: counter += Codec_WriteRegister(0x04, 0xAF); /* SPK always OFF & HP always ON */ OutputDev = 0xAF; break; case OUTPUT_DEVICE_BOTH: counter += Codec_WriteRegister(0x04, 0xAA); /* SPK always ON & HP always ON */ OutputDev = 0xAA; break; case OUTPUT_DEVICE_AUTO: counter += Codec_WriteRegister(0x04, 0x05); /* Detect the HP or the SPK automatically */ OutputDev = 0x05; break; default: counter += Codec_WriteRegister(0x04, 0x05); /* Detect the HP or the SPK automatically */ OutputDev = 0x05; break; } /* Clock configuration: Auto detection */ counter += Codec_WriteRegister(0x05, 0x81); /* Set the Slave Mode and the audio Standard */ counter += Codec_WriteRegister(0x06, CODEC_STANDARD); /* Set the Master volume */ Codec_VolumeCtrl(Volume); /* If the Speaker is enabled, set the Mono mode and volume attenuation level */ if (OutputDevice != OUTPUT_DEVICE_HEADPHONE) { /* Set the Speaker Mono mode */ counter += Codec_WriteRegister(0x0F , 0x06); /* Set the Speaker attenuation level */ counter += Codec_WriteRegister(0x24, 0x00); counter += Codec_WriteRegister(0x25, 0x00); } /* Power on the Codec */ counter += Codec_WriteRegister(0x02, 0x9E); /* Additional configuration for the CODEC. These configurations are done to reduce the time needed for the Codec to power off. If these configurations are removed, then a long delay should be added between powering off the Codec and switching off the I2S peripheral MCLK clock (which is the operating clock for Codec). If this delay is not inserted, then the codec will not shut down propoerly and it results in high noise after shut down. */ /* Disable the analog soft ramp */ counter += Codec_WriteRegister(0x0A, 0x00); /* Disable the digital soft ramp */ counter += Codec_WriteRegister(0x0E, 0x04); /* Disable the limiter attack level */ counter += Codec_WriteRegister(0x27, 0x00); /* Adjust Bass and Treble levels */ counter += Codec_WriteRegister(0x1F, 0x0F); /* Adjust PCM volume level */ counter += Codec_WriteRegister(0x1A, 0x0A); counter += Codec_WriteRegister(0x1B, 0x0A); /* Configure the I2S peripheral */ Codec_AudioInterface_Init(AudioFreq); /* Return communication control value */ return counter; }
/** * @brief Initializes the audio codec and all related interfaces (control * interface: I2C and audio interface: I2S) * @param OutputDevice: can be OUTPUT_DEVICE_SPEAKER, OUTPUT_DEVICE_HEADPHONE, * OUTPUT_DEVICE_BOTH or OUTPUT_DEVICE_AUTO . * @param Volume: Initial volume level (from 0 (Mute) to 100 (Max)) * @param AudioFreq: Audio frequency used to play the audio stream. * @retval 0 if correct communication, else wrong communication */ static uint32_t Codec_Init(uint16_t OutputDevice, uint8_t Volume, uint32_t AudioFreq) { uint32_t counter = 0; /* Configure the Codec related IOs */ Codec_GPIO_Init(); /* Reset the Codec Registers */ Codec_Reset(); /* Initialize the Control interface of the Audio Codec */ Codec_CtrlInterface_Init(); /* Keep Codec powered OFF */ counter += Codec_WriteRegister(0x02, 0x01); switch (OutputDevice) { case OUTPUT_DEVICE_SPEAKER: counter += Codec_WriteRegister(0x04, 0xFA); /* SPK always ON & HP always OFF */ OutputDev = 0xFA; break; case OUTPUT_DEVICE_HEADPHONE: counter += Codec_WriteRegister(0x04, 0xAF); /* SPK always OFF & HP always ON */ OutputDev = 0xAF; break; case OUTPUT_DEVICE_BOTH: counter += Codec_WriteRegister(0x04, 0xAA); /* SPK always ON & HP always ON */ OutputDev = 0xAA; break; case OUTPUT_DEVICE_AUTO: counter += Codec_WriteRegister(0x04, 0x05); /* Detect the HP or the SPK automatically */ OutputDev = 0x05; break; default: counter += Codec_WriteRegister(0x04, 0x05); /* Detect the HP or the SPK automatically */ OutputDev = 0x05; break; } /* Clock configuration: Auto detection */ counter += Codec_WriteRegister(0x05, 0x81); /* Set the Slave Mode and the audio Standard */ counter += Codec_WriteRegister(0x06, CODEC_STANDARD); /* Set the Master volume */ Codec_VolumeCtrl(Volume); /* If the Speaker is enabled, set the Mono mode and volume attenuation level */ if (OutputDevice != OUTPUT_DEVICE_HEADPHONE) { /* Set the Speaker Mono mode */ counter += Codec_WriteRegister(0x0F , 0x06); /* Set the Speaker attenuation level */ counter += Codec_WriteRegister(0x24, 0xF0); counter += Codec_WriteRegister(0x25, 0xF0); } /* Power on the Codec */ counter += Codec_WriteRegister(0x02, 0x9E); /* Configure the I2S peripheral */ Codec_AudioInterface_Init(AudioFreq); /* Return communication control value */ return counter; }
/** * @brief Initializes the audio codec and all related interfaces (control * interface: I2C and audio interface: I2S) * @param OutputDevice: can be OUTPUT_DEVICE_SPEAKER, OUTPUT_DEVICE_HEADPHONE, * OUTPUT_DEVICE_BOTH or OUTPUT_DEVICE_AUTO . * @param Volume: Initial volume level (from 0 (Mute) to 100 (Max)) * @param AudioFreq: Audio frequency used to play the audio stream. * @retval 0 if correct communication, else wrong communication */ uint32_t Codec_Init(uint16_t OutputDevice, uint8_t Volume, uint32_t AudioFreq) { uint32_t counter = 0; /* Configure the Codec related IOs */ Codec_GPIO_Init(); /* Reset the Codec Registers */ Codec_Reset(); /* Initialize the Control interface of the Audio Codec */ Codec_CtrlInterface_Init(); /* Keep Codec powered OFF */ counter += Codec_WriteRegister(0x02, 0x01); counter += Codec_WriteRegister(0x04, 0xAF); /* SPK always OFF & HP always ON */ OutputDev = 0xAF; /* Clock configuration: Auto detection */ counter += Codec_WriteRegister(0x05, 0x81); /* Set the Slave Mode and the audio Standard */ counter += Codec_WriteRegister(0x06, CODEC_STANDARD); /* Set the Master volume */ Codec_VolumeCtrl(Volume); if (CurrAudioInterface == AUDIO_INTERFACE_DAC) { /* Enable the PassThrough on AIN1A and AIN1B */ counter += Codec_WriteRegister(0x08, 0x01); counter += Codec_WriteRegister(0x09, 0x01); /* Route the analog input to the HP line */ counter += Codec_WriteRegister(0x0E, 0xC0); /* Set the Passthough volume */ counter += Codec_WriteRegister(0x14, 0x00); counter += Codec_WriteRegister(0x15, 0x00); } /* Power on the Codec */ counter += Codec_WriteRegister(0x02, 0x9E); /* Additional configuration for the CODEC. These configurations are done to reduce the time needed for the Codec to power off. If these configurations are removed, then a long delay should be added between powering off the Codec and switching off the I2S peripheral MCLK clock (which is the operating clock for Codec). If this delay is not inserted, then the codec will not shut down properly and it results in high noise after shut down. */ /* Disable the analog soft ramp */ counter += Codec_WriteRegister(0x0A, 0x00); if (CurrAudioInterface != AUDIO_INTERFACE_DAC) { /* Disable the digital soft ramp */ counter += Codec_WriteRegister(0x0E, 0x04); } /* Disable the limiter attack level */ counter += Codec_WriteRegister(0x27, 0x00); /* Adjust Bass and Treble levels */ counter += Codec_WriteRegister(0x1F, 0x0F); /* Adjust PCM volume level */ counter += Codec_WriteRegister(0x1A, 0x0A); counter += Codec_WriteRegister(0x1B, 0x0A); /* Configure the I2S peripheral */ Codec_AudioInterface_Init(AudioFreq); /* Return communication control value */ return counter; }