STM32F746G-DISCO 보드에서 USB Device모드를 사용하여 Audio Device Class를 테스트해 보았습니다.
Audio Device Class가 어떤 것인가 하면 이어폰/스피커/헤드폰의 연결이 USB로 되어 있어서 PC의 USB 단자에 꽂으면 오디오를 들을 수 있는 제품이 있습니다. 이러한 오디오 입/출력 기능을 STM32F746G-DISCO 보드를 사용하여 구현할 수 있으며, 이때 사용되는 것이 USB의 Audio Class를 사용하면 가능합니다.
STM32F746G-DISCO 보드의 펌웨어에서 제공되는 AUDIO_Standalone 예제를 참고하여 테스트되었습니다.
(예제 위치 : STM32Cube_FW_F7_V1.16.1/Projects/STM32756G_EVAL/Applications/USB_Device/CDC_Standalone)
STM32CubeIDE에서 새 프로젝트를 생성합니다.
핀 초기화 후 RCC/NVIC/SYS/USART1/SAI2(SAI A)/USB_OTG_FS/USB_DEVICE를 설정하였습니다.
USB_OTG_FS는 Device모드로 설정하였고 Class는 Audio Device Class로 설정하였습니다.
테스트하면서 이상한 점이 하나 있는데 Audio Device Class의 Device Descriptor 설정 시 기본 PID가 22336으로 설정이 되는데 이 PID로는 윈도우 PC에서 장치를 인식하지 못합니다. 예제에 적혀있는 0x5730(22320) 값을 사용해야만 윈도우 PC에서 정상적인 장치로 인식되어졌습니다.
Audio를 위해서는 SAI2가 사용되는데 아래 회로도에 맞춰서 핀 설정을 하였으며 SAI2 -> SAI_A의 모드는 Master with Master Clock Out으로 설정하였습니다.
코드를 생성 후 USB_DEVICE/App/usbd_audio_if.c 을 예제 파일을 참고하여 수정합니다.
static int8_t AUDIO_Init_FS(uint32_t AudioFreq, uint32_t Volume, uint32_t options)
{
/* USER CODE BEGIN 0 */
if(BSP_AUDIO_OUT_Init(OUTPUT_DEVICE_AUTO, Volume, AudioFreq) == AUDIO_OK)
printf("[Info] BSP_AUDIO initailized.\r\n");
else
printf("[Error] BSP_AUDIO failed to initailized. @line:%d\r\n", __LINE__);
/* Update the Audio frame slot configuration to match the PCM standard instead of TDM */
BSP_AUDIO_OUT_SetAudioFrameSlot(CODEC_AUDIOFRAME_SLOT_02);
return (USBD_OK);
/* USER CODE END 0 */
}
/**
* @brief De-Initializes the AUDIO media low layer
* @param options: Reserved for future use
* @retval USBD_OK if all operations are OK else USBD_FAIL
*/
static int8_t AUDIO_DeInit_FS(uint32_t options)
{
/* USER CODE BEGIN 1 */
BSP_AUDIO_OUT_Stop(CODEC_PDWN_SW);
return (USBD_OK);
/* USER CODE END 1 */
}
/**
* @brief Handles AUDIO command.
* @param pbuf: Pointer to buffer of data to be sent
* @param size: Number of data to be sent (in bytes)
* @param cmd: Command opcode
* @retval USBD_OK if all operations are OK else USBD_FAIL
*/
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:
BSP_AUDIO_OUT_Play((uint16_t *)pbuf, 2*size);
break;
case AUDIO_CMD_PLAY:
BSP_AUDIO_OUT_ChangeBuffer((uint16_t *)pbuf, 2*size);
break;
}
UNUSED(pbuf);
UNUSED(size);
UNUSED(cmd);
return (USBD_OK);
/* USER CODE END 2 */
}
/**
* @brief Controls AUDIO Volume.
* @param vol: volume level (0..100)
* @retval USBD_OK if all operations are OK else USBD_FAIL
*/
static int8_t AUDIO_VolumeCtl_FS(uint8_t vol)
{
/* USER CODE BEGIN 3 */
BSP_AUDIO_OUT_SetVolume(vol);
return (USBD_OK);
/* USER CODE END 3 */
}
/**
* @brief Controls AUDIO Mute.
* @param cmd: command opcode
* @retval USBD_OK if all operations are OK else USBD_FAIL
*/
static int8_t AUDIO_MuteCtl_FS(uint8_t cmd)
{
/* USER CODE BEGIN 4 */
BSP_AUDIO_OUT_SetMute(cmd);
return (USBD_OK);
/* USER CODE END 4 */
}
/**
* @brief AUDIO_PeriodicT_FS
* @param cmd: Command opcode
* @retval USBD_OK if all operations are OK else USBD_FAIL
*/
static int8_t AUDIO_PeriodicTC_FS(uint8_t *pbuf, uint32_t size, uint8_t cmd)
{
/* USER CODE BEGIN 5 */
UNUSED(pbuf);
UNUSED(size);
UNUSED(cmd);
return (USBD_OK);
/* USER CODE END 5 */
}
/**
* @brief Gets AUDIO State.
* @retval USBD_OK if all operations are OK else USBD_FAIL
*/
static int8_t AUDIO_GetState_FS(void)
{
/* USER CODE BEGIN 6 */
return (USBD_OK);
/* USER CODE END 6 */
}
/**
* @brief Manages the DMA full transfer complete event.
* @retval None
*/
void TransferComplete_CallBack_FS(void)
{
/* USER CODE BEGIN 7 */
USBD_AUDIO_Sync(&hUsbDeviceFS, AUDIO_OFFSET_FULL);
/* USER CODE END 7 */
}
/**
* @brief Manages the DMA Half transfer complete event.
* @retval None
*/
void HalfTransfer_CallBack_FS(void)
{
/* USER CODE BEGIN 8 */
USBD_AUDIO_Sync(&hUsbDeviceFS, AUDIO_OFFSET_HALF);
/* USER CODE END 8 */
}
Core/Src/stm32f7xx_it.c에 아래 내용을 추가합니다.
extern SAI_HandleTypeDef haudio_out_sai;
void DMA2_Stream4_IRQHandler(void)
{
HAL_DMA_IRQHandler(haudio_out_sai.hdmatx);
}
예제용 파일을 참고하여 코드를 추가 및 변경하여 적용시킵니다.
적용이 다 되었으면 빌드를 한 후 보드에 다운로드를 합니다.
스피커를 보드에 연결한 후 Micro USB 케이블을 CN13(USB_FS) 커넥터에 꽂습니다.
그러면 아래 그림처럼 '사운드, 비디오 및 게임 컨트롤러'에 'STM32 Audio Class' 장치가 추가됩니다.
윈도우 PC에서 비디오/음악 파일을 재생을 하면 PC의 Audio 출력이 USB를 거쳐 STM32F746G-DISCO 보드의 스피커로 출력됩니다.
(유튜브에 동영상을 업로드하니 음악 관련 저작권 문제가 있다고 나오네요. 한 10초 분량의 가요를 녹화했는데 정확한 곡명과 가수를 찾아서 저작권 문제가 있다고 알려줍니다. 그래서 다시 무료 음악을 다운로드 받아 재녹화를 해서 업로드하였습니다.)
'Hardware > STM32' 카테고리의 다른 글
[STM32F746G-DISCO] USB DFU 사용하기 (Device Mode) (0) | 2024.07.17 |
---|---|
[STM32F746G-DISCO] Flash 사용하기 (0) | 2024.07.17 |
[STM32F746G-DISCO] USB CDC로 사용하기 (Device Mode) (0) | 2024.07.16 |
[STM32F746G-DISCO] USB MSC로 사용하기 (Device Mode) (0) | 2024.07.16 |
[STM32F746G-DISCO] USB 키보드로 사용하기 (Device Mode) (0) | 2024.07.15 |
댓글