AnsweredAssumed Answered

USB Audio Graceful Shutdown/Restart

Question asked by dmann on Jun 6, 2011
Latest reply on Jun 13, 2011 by CraigG

Hello,

 

I am working on a system that makes use of both the USB audio (device mode) and USB FSS(host mode). I am having issues with shutting down a working USB audio session and then re-enabling it. Given the usb audio initialization code below, what is the recommended way to shut down the usb audio device, given that it may need to be re-enabled at the users request?

 

 

void init_usbAudio(void)
{
    /* Initialize the circular buffer structure */
    InitializeCircBuf();
                                     
    /* Initialize system services */
    adi_ssl_Init();

    /* Open a DCB queue for Audio Callbacks */
    adi_dcb_Open(
                    14,
                    &DCBMgrQueue1[ADI_DCB_QUEUE_SIZE],
                    (ADI_DCB_ENTRY_SIZE)*10,
                    &Result,
                    &adi_dcb_QueueHandle
                    );
    
       /* Initialize USB Core      */
    adi_usb_CoreInit((void*)&Result);

    /* Open the Controller driver */
    adi_dev_Open(    adi_dev_ManagerHandle,                     /* DevMgr handle */
                            &ADI_USBDRC_Entrypoint,                    /* pdd entry point */
                            0,                                      /* device instance */
                            (void*)1,                                /* client handle callback identifier */
                            &PeripheralDevHandle,                    /* device handle */
                            ADI_DEV_DIRECTION_BIDIRECTIONAL,        /* data direction for this device */
                            NULL,                                    /* handle to DmaMgr for this device */
                            NULL,                                    /* handle to deferred callback service */
                            ClientCallback);                        /* callback function */

    /* Open the Audio Class driver */
    adi_dev_Open(    adi_dev_ManagerHandle,                    /* DevMgr handle */
                            &ADI_USB_Device_AudioClass_Entrypoint,  /* pdd entry point */
                            0,                                        /* device instance */
                            (void*)0x1,                                /* client handle callback identifier */
                            &adi_DevHandle,                            /* DevMgr handle for this device */
                            ADI_DEV_DIRECTION_BIDIRECTIONAL,        /* data direction for this device */
                            adi_dma_ManagerHandle,                    /* handle to DmaMgr for this device */
                            adi_dcb_QueueHandle,                    /* handle to deferred callback service */
                            ClientCallback);                        /* client's callback function */

    /* Initialize the Audio Codec */
    adi_codec_Init( 
                                &OutboundData0[0], 
                                AUDIO_CODEC_DAC_BUFFER_SIZE, 
                                &InboundData0[0], 
                                AUDIO_CODEC_ADC_BUFFER_SIZE,
                                adi_dcb_QueueHandle, 
                                AudioCodecCallback
                           );
    
    /* Give the controller handle to the Audio class driver */
    adi_dev_Control(adi_DevHandle,
                             ADI_USB_CMD_CLASS_SET_CONTROLLER_HANDLE,
                             (void*)PeripheralDevHandle);
 
    /* Do not include Mic in mixer */
    adi_dev_Control(adi_DevHandle,
                             ADI_USB_AUDIO_CMD_MIC_IN_ADC_MIXER,
                             (void*)FALSE);
 
    /* Do not include Mic record control */
    adi_dev_Control(adi_DevHandle,
                             ADI_USB_AUDIO_CMD_ENABLE_MIC_RECORD_CTL,
                             (void*)FALSE);
 
    /* Use 32 bit subframe to allow 24 or 16 bit audio playback */
    adi_dev_Control(adi_DevHandle,
                             ADI_USB_AUDIO_CMD_SET_32BIT_PBK_RESOLUTION,
                             (void*)FALSE); 
    
     /* Configure the Audio class driver */
    Result = adi_dev_Control(adi_DevHandle,
                             ADI_USB_CMD_CLASS_CONFIGURE,
                             (void*)0);

    /* Set the Vendor ID */
    Result = adi_dev_Control(adi_DevHandle,
                             ADI_USB_AUDIO_CMD_SET_VID,
                             (void*)USB_VID_TEST); 
    /* Set the Product ID */                                         
    Result = adi_dev_Control(adi_DevHandle,
                             ADI_USB_AUDIO_CMD_SET_PID,
                             (void*)USB_PID_BF527KIT_AUDIO_CLASS);
        
    /* Set the Product String */
    Result = adi_dev_Control(adi_DevHandle,
                             ADI_USB_AUDIO_CMD_SET_PRODUCT_STRING,
                             USB_PRODUCT_STRING); 
    /* Set data flow  */
    Result = adi_dev_Control(adi_DevHandle,
                             ADI_DEV_CMD_SET_DATAFLOW_METHOD,
                             (void*)ADI_DEV_MODE_CHAINED);

     /* Enable data flow */
    Result = adi_dev_Control(adi_DevHandle,
                             ADI_DEV_CMD_SET_DATAFLOW,
                             (void*)TRUE);
            
    /****************** Send Codec out working Buffer to Audio class driver **********************/
    
    /* Clear the codec output buffer */
    for(i = 0; i < AUDIO_OUTPUT_BUFFER_SIZE; i++)
    {
        OutboundData0[i] = 0;
    }

    /* Clear the silence buffer*/
    for(i = 0; i < AUDIO_CODEC_DAC_BUFFER_SIZE; i++)
    {
        SilenceBuffer[i] = 0;
    }
   
    for(i = 0; i < NUM_DAC_BUFFERS; i++)
    {
           /* Outbound 1D buffers */
        UsbOutboundBuffer[i].Data                = (void *)&OutboundData0[i * AUDIO_CODEC_DAC_BUFFER_SIZE];
        UsbOutboundBuffer[i].ElementCount        = AUDIO_CODEC_DAC_BUFFER_SIZE/DMA_BUS_WIDTH_IN_BYTES;
        UsbOutboundBuffer[i].ElementWidth        = DMA_BUS_WIDTH_IN_BYTES;
        UsbOutboundBuffer[i].CallbackParameter   = &UsbOutboundBuffer[i];   /* enable callback on completion of this buffer */
        UsbOutboundBuffer[i].ProcessedFlag       = FALSE;
        UsbOutboundBuffer[i].pNext               = NULL;
        
        /* Mark playback buffer number */
        UsbOutboundBuffer[i].pAdditionalInfo     = (void *)i;
    
        adi_dev_Read(adi_DevHandle,
                    ADI_DEV_1D,
                    (ADI_DEV_BUFFER *)&UsbOutboundBuffer[i]);
    }                                
                
    /****************** USB Buffer preparation **********************/
     /* Configure the USB buffer */
       usbBuffer.Data = &USB_Buffer;
      usbBuffer.ElementCount = PBK_PKT_SIZE;
       usbBuffer.ElementWidth = 1;
       usbBuffer.ProcessedFlag = FALSE;
       usbBuffer.ProcessedElementCount = 0;
       usbBuffer.CallbackParameter = &usbBuffer;
       usbBuffer.pNext = NULL;

    /****************************************************************/
    /* Enable the Audio class driver */
    adi_dev_Control(PeripheralDevHandle,
                             ADI_USB_CMD_ENABLE_USB,
                            (void*)0);
}    

I've tried simply closing the drivers, via a shutdown function, but this doesn't seem to work.

 

 

void shutdown_usbAudio(void)
{
    u32 Result;
    /* Enable the Audio class driver */
    //Result = adi_dev_Control(PeripheralDevHandle,
    //                         ADI_USB_CMD_DISABLE_USB,
    //                        (void*)0);
    //if (Result != ADI_INT_RESULT_SUCCESS)
    //        failure();

    
    adi_dev_Close(adi_DevHandle);
    adi_dev_Close(PeripheralDevHandle);    
    adi_dcb_Close(adi_dcb_QueueHandle);
}

Outcomes