Урок 46
Часть 4
I2S AUDIO
В предыдущей части урока мы продолжили писать инициализацию микросхемы Аудио ЦАП и написали функцию считывания идентификатора данной микросхемы по шине I2C.
Продолжим дальше инициализацию. Для этого в файл audioplay.c напишем ещё одну функцию
//——————————————————
uint32_t cs43l22_Init(uint16_t DeviceAddr, uint16_t OutputDevice, uint8_t Volume, uint32_t AudioFreq)
{
uint32_t counter = 0;
HAL_GPIO_WritePin(AUDIO_RESET_GPIO, AUDIO_RESET_PIN, GPIO_PIN_RESET);
/* Wait for a delay to insure registers erasing */
HAL_Delay(5);
/* Power on the codec */
HAL_GPIO_WritePin(AUDIO_RESET_GPIO, AUDIO_RESET_PIN, GPIO_PIN_SET);
/* Wait for a delay to insure registers erasing */
HAL_Delay(5);
return counter;
}
//——————————————————
Вызовем её в функции AudioOut_Init
if((deviceid & CS43L22_ID_MASK) == CS43L22_ID)
{
ret = AUDIO_OK;
}
if(ret == AUDIO_OK)
{
cs43l22_Init(AUDIO_I2C_ADDRESS, OutputDevice, Volume, AudioFreq);
}
return ret;
Ещё одна функция. Функция записи в регистр микросхемы определённого значения в виде байта
//——————————————————
static uint8_t CODEC_IO_Write(uint8_t Addr, uint8_t Reg, uint8_t Value)
{
HAL_StatusTypeDef status = HAL_OK;
uint32_t result = 0;
status = HAL_I2C_Mem_Write(&hi2c1, Addr, (uint16_t)Reg, I2C_MEMADD_SIZE_8BIT, &Value, 1, 0x1000);
if(status != HAL_OK)
{
Error();
return 1;
}
return result;
}
//——————————————————
Продолжаем писать cs43l22_Init
HAL_Delay(5);
counter += CODEC_IO_Write(DeviceAddr, 0x02, 0x01);
/*Save Output device for mute ON/OFF procedure*/
switch (OutputDevice)
{
case OUTPUT_DEVICE_SPEAKER:
OutputDev = 0xFA;
break;
case OUTPUT_DEVICE_HEADPHONE:
OutputDev = 0xAF;
break;
case OUTPUT_DEVICE_BOTH:
OutputDev = 0xAA;
break;
case OUTPUT_DEVICE_AUTO:
OutputDev = 0x05;
break;
default:
OutputDev = 0x05;
break;
}
counter += CODEC_IO_Write(DeviceAddr, 0x04, OutputDev);
/* Clock configuration: Auto detection */
counter += CODEC_IO_Write(DeviceAddr, 0x05, 0x81);
/* Set the Slave Mode and the audio Standard */
counter += CODEC_IO_Write(DeviceAddr, 0x06, CODEC_STANDARD);
Здесь мы сначала отключили ЦАП (нажмите на картинку для увеличения размера)
Дальше режим работы ЦАП. У нас OUTPUT_DEVICE_AUTO, то есть у нас включатся биты следующие (отмечены синими квадратами) (нажмите на картинку для увеличения размера)
Дальше конфигурируем тактирование ЦАП (нажмите на картинку для увеличения размера)
Расшифровывать все настройки данного регистра не будем, всё написано дальше внизу в даташите. Затем настроим интерфейс:
Данная настройка регистра гласит о следующем:
Serial Port Clocks: Slave (input ONLY)
SCLK Polarity: Not Inverted
DSP Mode: Disabled
DAC Interface Format: I²S, up to 24-bit data
Audio Word Length: 24-bit data
Напишем ещё одну функцию (для установки громкости)
//——————————————————
uint32_t cs43l22_SetVolume(uint16_t DeviceAddr, uint8_t Volume)
{
uint32_t counter = 0;
uint8_t convertedvol = VOLUME_CONVERT(Volume);
if(Volume > 0xE6)
{
/* Set the Master volume */
counter += CODEC_IO_Write(DeviceAddr, 0x20, convertedvol — 0xE7);
counter += CODEC_IO_Write(DeviceAddr, 0x21, convertedvol — 0xE7);
}
else
{
/* Set the Master volume */
counter += CODEC_IO_Write(DeviceAddr, 0x20, convertedvol + 0x19);
counter += CODEC_IO_Write(DeviceAddr, 0x21, convertedvol + 0x19);
}
return counter;
}
//——————————————————
При установке громкости пользуемся следующими регистрами (на каждый канал по регистру) (нажмите на картинку для увеличения размера):
В следующей части нашего занятия мы продолжим и практически закончим писать инициализацию Аудио ЦАП и напишем ещё некоторые немаловажные функции для работы с данной микросхемой.
Предыдущая часть Программирование МК STM32 Следующая часть
Техническая документация на Аудио ЦАП CS43L22
Отладочную плату и дисплей можно приобрести здесь:
Смотреть ВИДЕОУРОК
В последней ф-ции прошу подробно объяснить, что означает и как работает каждая строка:
if(Volume > 0xE6)
{
/* Set the Master volume */
counter += CODEC_IO_Write(DeviceAddr, 0x20, convertedvol — 0xE7);
counter += CODEC_IO_Write(DeviceAddr, 0x21, convertedvol — 0xE7);
}
else
{
/* Set the Master volume */
counter += CODEC_IO_Write(DeviceAddr, 0x20, convertedvol + 0x19);
counter += CODEC_IO_Write(DeviceAddr, 0x21, convertedvol + 0x19);