У меня аналогичная проблема. При работе с I2S как мастер, а кодека как слейв после воспроизведения сэмпла иногда включаются шумы.
Вот инициализация шин:
// configure I2S port
SPI_I2S_DeInit(CODEC_I2S);
I2S_InitType.I2S_AudioFreq = I2S_AudioFreq_22k;
I2S_InitType.I2S_MCLKOutput = I2S_MCLKOutput_Enable;
//I2S_InitType.I2S_MCLKOutput = I2S_MCLKOutput_Disable;
I2S_InitType.I2S_DataFormat = I2S_DataFormat_16b;
I2S_InitType.I2S_Mode = I2S_Mode_MasterTx;
//I2S_InitType.I2S_Mode = I2S_Mode_SlaveTx;
I2S_InitType.I2S_Standard = I2S_Standard_Phillips;
I2S_InitType.I2S_CPOL = I2S_CPOL_Low;
I2S_Init(CODEC_I2S, &I2S_InitType);
I2S_Cmd(CODEC_I2S, ENABLE);
// configure I2C port
I2C_DeInit(CODEC_I2C);
I2C_InitType.I2C_ClockSpeed = 100000;
I2C_InitType.I2C_Mode = I2C_Mode_I2C;
I2C_InitType.I2C_OwnAddress1 = CORE_I2C_ADDRESS;
I2C_InitType.I2C_Ack = I2C_Ack_Enable;
I2C_InitType.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
I2C_InitType.I2C_DutyCycle = I2C_DutyCycle_2;
Вот конфигурация кодека:
void codec_ctrl_init()
{
uint32_t delaycount;
uint8_t CodecCommandBuffer[3];
uint8_t regValue = 0xFF;
GPIO_SetBits(GPIOD, CODEC_RESET_PIN);
delaycount = 1000000;
while (delaycount > 0)
{
delaycount--;
}
//keep codec OFF
CodecCommandBuffer[0] = CODEC_MAP_PLAYBACK_CTRL1;
CodecCommandBuffer[1] = 0x01;
send_codec_ctrl(CodecCommandBuffer, 2);
//begin initialization sequence (p. 32)
CodecCommandBuffer[0] = 0x00;
CodecCommandBuffer[1] = 0x99;
send_codec_ctrl(CodecCommandBuffer, 2);
CodecCommandBuffer[0] = 0x47;
CodecCommandBuffer[1] = 0x80;
send_codec_ctrl(CodecCommandBuffer, 2);
regValue = read_codec_register(0x32);
CodecCommandBuffer[0] = 0x32;
CodecCommandBuffer[1] = regValue | 0x80;
send_codec_ctrl(CodecCommandBuffer, 2);
regValue = read_codec_register(0x32);
CodecCommandBuffer[0] = 0x32;
CodecCommandBuffer[1] = regValue & (~0x80);
send_codec_ctrl(CodecCommandBuffer, 2);
CodecCommandBuffer[0] = 0x00;
CodecCommandBuffer[1] = 0x00;
send_codec_ctrl(CodecCommandBuffer, 2);
//end of initialization sequence
CodecCommandBuffer[0] = CODEC_MAP_PWR_CTRL2;
CodecCommandBuffer[1] = AUTO;
send_codec_ctrl(CodecCommandBuffer, 2);
CodecCommandBuffer[0] = CODEC_MAP_PLAYBACK_CTRL1;
CodecCommandBuffer[1] = 0x70;
send_codec_ctrl(CodecCommandBuffer, 2);
CodecCommandBuffer[0] = CODEC_MAP_CLK_CTRL;
CodecCommandBuffer[1] = 0x81; //auto detect clock
//CodecCommandBuffer[1] = 0x60; //speed 1:1
send_codec_ctrl(CodecCommandBuffer, 2);
CodecCommandBuffer[0] = CODEC_MAP_IF_CTRL1;
//CodecCommandBuffer[1] = CODEC_STD;
CodecCommandBuffer[1] = 0x07;
//CodecCommandBuffer[1] = 0x84; //Master
send_codec_ctrl(CodecCommandBuffer, 2);
CodecCommandBuffer[0] = CODEC_MAP_PWR_CTRL1;
CodecCommandBuffer[1] = 0x9E;
send_codec_ctrl(CodecCommandBuffer, 2);
}
Сами данные я отправляю через ДМА I2S (SPI3)
Я пытался повторить Ваш опыт установив кодек в мастер и дергая MCLK таймером. Пока безрезультатно.
Расскажите пожалуйста подробнее про настройку I2S, MCLK и таймера. Как вы добились частоты 12.2880 MHz?
У меня частота проца 84 МГц и если перскаллер установить в 0, а период поставить на 3, у меня зависает инициализация таймера