Skip to main content
Visitor II
July 5, 2020
Question

USB Audio Class losing 50% of my data

  • July 5, 2020
  • 0 replies
  • 799 views

0693W000001sASMQA2.pngHi, I am trying to get a robust isochronous transfer of audio from my STM32F072CB using the audio device class. My code is based on the code generated by STM32CubeMX for a speaker but I have changed the descriptor in order to make it an audio input. Basically all I have changed is usbd_audio.c and usbd_audio.h. I am sending 120 bytes on each DataIn interrupt (which I have confirmed occurs every millisecond) but when I record from this source, I only get 50% of the data and if I look at the USB trace using WireShark I can see that all my packets have errors and every second packet has no data! I have managed to find a few examples such as the X-CUBE-MEMSMIC1 example and as far as I can tell I am doing the same thing they are. Any help to get a reliable audio data transfer much appreciated!

static uint8_t USBD_AUDIO_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum)
{
	HAL_GPIO_TogglePin(LED2_GPIO_Port, LED2_Pin);
	//TODO: Check alternate setting
	USBD_LL_Transmit(pdev, AUDIO_IN_EP, FAKEDATA, AUDIO_IN_PACKET);
 return USBD_OK;
}
static uint8_t USBD_AUDIO_SOF(USBD_HandleTypeDef *pdev)
{
	HAL_GPIO_TogglePin(LED1_GPIO_Port, LED1_Pin);
 return USBD_OK;
}
static uint8_t USBD_AUDIO_Setup(USBD_HandleTypeDef *pdev,
 USBD_SetupReqTypedef *req)
{
 USBD_AUDIO_HandleTypeDef *haudio;
 uint16_t len;
 uint8_t *pbuf;
 uint16_t status_info = 0U;
 uint8_t ret = USBD_OK;
 
 haudio = (USBD_AUDIO_HandleTypeDef *)pdev->pClassData;
 
 switch (req->bmRequest & USB_REQ_TYPE_MASK)
 {
 case USB_REQ_TYPE_CLASS :
 switch (req->bRequest)
 {
 case AUDIO_REQ_GET_CUR:
 AUDIO_REQ_GetCurrent(pdev, req);
 break;
 
 case AUDIO_REQ_SET_CUR:
 AUDIO_REQ_SetCurrent(pdev, req);
 break;
 
 default:
 USBD_CtlError(pdev, req);
 ret = USBD_FAIL;
 break;
 }
 break;
 
 case USB_REQ_TYPE_STANDARD:
 switch (req->bRequest)
 {
 case USB_REQ_GET_STATUS:
 if (pdev->dev_state == USBD_STATE_CONFIGURED)
 {
 USBD_CtlSendData(pdev, (uint8_t *)(void *)&status_info, 2U);
 }
 else
 {
 USBD_CtlError(pdev, req);
 ret = USBD_FAIL;
 }
 break;
 
 case USB_REQ_GET_DESCRIPTOR:
 if ((req->wValue >> 8) == AUDIO_DESCRIPTOR_TYPE)
 {
 pbuf = USBD_AUDIO_CfgDesc + 18;
 len = MIN(USB_AUDIO_DESC_SIZ, req->wLength);
 
 USBD_CtlSendData(pdev, pbuf, len);
 }
 break;
 
 case USB_REQ_GET_INTERFACE :
 if (pdev->dev_state == USBD_STATE_CONFIGURED)
 {
 USBD_CtlSendData(pdev, (uint8_t *)(void *)&haudio->alt_setting, 1U);
 }
 else
 {
 USBD_CtlError(pdev, req);
 ret = USBD_FAIL;
 }
 break;
 
 case USB_REQ_SET_INTERFACE :
 if (pdev->dev_state == USBD_STATE_CONFIGURED)
 {
 if ((uint8_t)(req->wValue) <= USBD_MAX_NUM_INTERFACES)
 {
 haudio->alt_setting = (uint8_t)(req->wValue);
 if ((uint8_t)(req->wValue) == 1)
 {
 	 // Must send dummy packet to begin data in packets (not sure why?)
 	 USBD_LL_Transmit(pdev, AUDIO_IN_EP, FAKEDATA, 0);
 }
 }
 else
 {
 /* Call the error management function (command will be nacked */
 USBD_CtlError(pdev, req);
 ret = USBD_FAIL;
 }
 }
 else
 {
 USBD_CtlError(pdev, req);
 ret = USBD_FAIL;
 }
 break;
 
 default:
 USBD_CtlError(pdev, req);
 ret = USBD_FAIL;
 break;
 }
 break;
 default:
 USBD_CtlError(pdev, req);
 ret = USBD_FAIL;
 break;
 }
 
 return ret;
}
static uint8_t USBD_AUDIO_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
{
 
	for(uint8_t i = 0; i < AUDIO_IN_PACKET; i+=2)
	{
		FAKEDATA[i+1] = i;
		FAKEDATA[i] = 0;
	}
 
 USBD_AUDIO_HandleTypeDef *haudio;
 
 /* Open EP OUT */
 USBD_LL_OpenEP(pdev, AUDIO_IN_EP, USBD_EP_TYPE_ISOC, AUDIO_IN_PACKET);
 pdev->ep_in[AUDIO_IN_EP & 0xFU].is_used = 1U;
 
 /* Allocate Audio structure */
 pdev->pClassData = USBD_malloc(sizeof(USBD_AUDIO_HandleTypeDef));
 
 if (pdev->pClassData == NULL)
 {
 return USBD_FAIL;
 }
 else
 {
 haudio = (USBD_AUDIO_HandleTypeDef *) pdev->pClassData;
 haudio->alt_setting = 0U;
 haudio->offset = AUDIO_OFFSET_UNKNOWN;
 haudio->wr_ptr = 0U;
 haudio->rd_ptr = 0U;
 haudio->rd_enable = 0U;
 
 /* Initialize the Audio output Hardware layer */
 if (((USBD_AUDIO_ItfTypeDef *)pdev->pUserData)->Init(USBD_AUDIO_FREQ,
 AUDIO_DEFAULT_VOLUME,
 0U) != 0)
 {
 return USBD_FAIL;
 }
 }
 
 return USBD_OK;
}

    This topic has been closed for replies.