Урок 48
Часть 2
USB DEVICE AUDIO
В прошлой части нашего урока мы создали и настроили проект в Cube MX, создали каркас приложения, добавили все макросы и глобальные переменные, которые в процессе написания кода нам потребуются. Также мы начали писать некоторые функции аудио-библиотеки.
В файле audioplay.c напишем функции задержки в микросекундах. Данной функцией мы пользуемся часто
//—————————————————————
__STATIC_INLINE void DelayMicro(__IO uint32_t micros)
{
micros *=(SystemCoreClock / 1000000) / 5;
while (micros—);
}
//—————————————————————
void Error(void)
В функциях AudioOut_Init и cs43l22_Init заменим функции задержек HAL_Delay на функции DelayMicro, так как с функциями задержек HAL у меня происходили зависания и не работала отладка
DelayMicro(5000);
HAL_GPIO_WritePin(AUDIO_RESET_GPIO, AUDIO_RESET_PIN, GPIO_PIN_SET);
DelayMicro(5000);
Отключим оптимизацию для лучшей отладки
Скомпилируем код и проверим, считан ли у нас идентификатор аудио ЦАП и тот ли именно он считан. Проверим мы это с помощью отладки. Установим точку останова, запустим отладку, дойдём до точки останова, а затем идем шагами. Если всё нормально считано, то попадём в отмеченное на рисунке место
Дальше вставим ещё строку в инициализацию
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);
Тем самым мы в ЦАПе включаем автоопределение скорости, также делитель на 2
Добавим в файле audioplay.c в функцию cs43l22_Stop ещё один входной аргумент
//——————————————————
uint32_t cs43l22_Stop(uint16_t DeviceAddr, uint32_t CodecPdwnMode)
{
Исправим функцию AudioPlay_Stop
uint8_t AudioPlay_Stop(uint32_t Option)
{
uint8_t ret = AUDIO_OK;
/* Call Audio Codec Stop function */
if(cs43l22_Stop(AUDIO_I2C_ADDRESS, Option) != 0)
{
ret = AUDIO_ERROR;
}
if(ret == AUDIO_OK)
{
if(Option == CODEC_PDWN_HW)
{
/* Wait at least 100us */
DelayMicro(2000);
}
/* Stop DMA transfer of PCM samples towards the serial audio interface */
if (HAL_I2S_DMAStop(&hi2s3)!= HAL_OK)
{
ret = AUDIO_ERROR;
}
}
/* Return AUDIO_OK when all operations are correctly done */
return ret;
}
//——————————————————
В файл audioplay.h добавим прототип данной функции
uint8_t AudioOut_Init(uint16_t OutputDevice, uint8_t Volume, uint32_t AudioFreq);
uint8_t AudioPlay_Stop(uint32_t Option);
Вызовем данную функцию в файле usbd_audio_if.c в определенном обработчике
static int8_t AUDIO_DeInit_FS(uint32_t options)
{
/* USER CODE BEGIN 1 */
AudioPlay_Stop(CODEC_PDWN_SW);
return (USBD_OK);
/* USER CODE END 1 */
}
Теперь в файле audioplay.c изменим вызов функции cs43l22_Play
uint32_t cs43l22_Play(uint16_t DeviceAddr, uint16_t* pBuffer, uint16_t Size)
{
Вставим две функции следующего содержания
//——————————————————
uint8_t AudioPlay_Play(uint16_t* pBuffer, uint32_t Size)
{
uint8_t ret = AUDIO_OK;
if(cs43l22_Play(AUDIO_I2C_ADDRESS, pBuffer, Size) != 0)
{
Error();
ret = AUDIO_ERROR;
}
if(ret == AUDIO_OK)
{
if (HAL_I2S_Transmit_DMA(&hi2s3, (uint16_t*) pBuffer, DMA_MAX(Size / AUDIODATA_SIZE))!= HAL_OK)
{
Error();
ret = AUDIO_ERROR;
}
}
return ret;
}
//——————————————————
void AudioPlay_ChangeBuffer(uint16_t *pData, uint16_t Size)
{
HAL_I2S_Transmit_DMA(&hi2s3, (uint16_t*) pData, Size);
}
//——————————————————
Ну здесь всё стандартно, я думаю и объяснять нечего.
Вставим прототипы функций в файл audioplay.h
uint8_t AudioPlay_Stop(uint32_t Option);
uint8_t AudioPlay_Play(uint16_t* pBuffer, uint32_t Size);
void AudioPlay_ChangeBuffer(uint16_t *pData, uint16_t Size);
В файле usbd_audio_if.c в обработчике вставим вызовы функций
static int8_t AUDIO_AudioCmd_FS (uint8_t* pbuf, uint32_t size, uint8_t cmd)
{
/* USER CODE BEGIN 2 */
switch(cmd)
{
case AUDIO_CMD_START:
AudioPlay_Play((uint16_t *)pbuf, size);
break;
case AUDIO_CMD_PLAY:
AudioPlay_ChangeBuffer((uint16_t *)pbuf, size);
break;
}
return (USBD_OK);
/* USER CODE END 2 */
}
В следующей части нашего урока мы мы закончим изучение данной темы и услышим работу написанной нашими руками звуковой карты.
Предыдущая часть Программирование МК STM32 Следующая часть
Техническая документация на Аудио ЦАП CS43L22
Купить отладочную плату можно здесь STM32F4-DISCOVERY
Смотреть ВИДЕОУРОК
Добавить комментарий