/** Event handler for the USB_DeviceEnumerationComplete event. This indicates that a device has been successfully * enumerated by the host and is now ready to be used by the application. */ void EVENT_USB_Host_DeviceEnumerationComplete(void) { LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING); uint16_t ConfigDescriptorSize; uint8_t ConfigDescriptorData[512]; if (USB_Host_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData, sizeof(ConfigDescriptorData)) != HOST_GETCONFIG_Successful) { puts_P(PSTR("Error Retrieving Configuration Descriptor.\r\n")); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); return; } if (Audio_Host_ConfigurePipes(&Speaker_Audio_Interface, ConfigDescriptorSize, ConfigDescriptorData) != AUDIO_ENUMERROR_NoError) { puts_P(PSTR("Attached Device Not a Valid Audio Output Device.\r\n")); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); return; } if (USB_Host_SetDeviceConfiguration(1) != HOST_SENDCONTROL_Successful) { puts_P(PSTR("Error Setting Device Configuration.\r\n")); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); return; } if (Audio_Host_StartStopStreaming(&Speaker_Audio_Interface, true) != HOST_SENDCONTROL_Successful) { puts_P(PSTR("Error Enabling Audio Stream.\r\n")); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); USB_Host_SetDeviceConfiguration(0); return; } USB_Audio_SampleFreq_t SampleRate = AUDIO_SAMPLE_FREQ(48000); if (Audio_Host_GetSetEndpointProperty(&Speaker_Audio_Interface, Speaker_Audio_Interface.Config.DataOUTPipeNumber, AUDIO_REQ_SetCurrent, AUDIO_EPCONTROL_SamplingFreq, sizeof(SampleRate), &SampleRate) != HOST_SENDCONTROL_Successful) { puts_P(PSTR("Error Setting Audio Sampling Frequency.\r\n")); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); USB_Host_SetDeviceConfiguration(0); return; } /* Sample reload timer initialization */ TIMSK0 = (1 << OCIE0A); OCR0A = ((F_CPU / 8 / 48000) - 1); TCCR0A = (1 << WGM01); // CTC mode TCCR0B = (1 << CS01); // Fcpu/8 speed puts_P(PSTR("Audio Device Enumerated.\r\n")); LEDs_SetAllLEDs(LEDMASK_USB_READY); }
.Type = DTYPE_CSInterface }, .Subtype = AUDIO_DSUBTYPE_CSInterface_FormatType, .FormatType = 0x01, .Channels = 0x01, .SubFrameSize = 0x02, .BitResolution = 16, .TotalDiscreteSampleRates = (sizeof(ConfigurationDescriptor.Audio_AudioFormatSampleRates) / sizeof(USB_Audio_SampleFreq_t)), }, .Audio_AudioFormatSampleRates = { AUDIO_SAMPLE_FREQ(8000), AUDIO_SAMPLE_FREQ(11025), AUDIO_SAMPLE_FREQ(22050), AUDIO_SAMPLE_FREQ(44100), AUDIO_SAMPLE_FREQ(48000), }, .Audio_StreamEndpoint = { .Endpoint = { .Header = {.Size = sizeof(USB_Audio_Descriptor_StreamEndpoint_Std_t), .Type = DTYPE_Endpoint}, .EndpointAddress = (ENDPOINT_DESCRIPTOR_DIR_IN | AUDIO_STREAM_EPNUM), .Attributes = (EP_TYPE_ISOCHRONOUS | ENDPOINT_ATTR_SYNC | ENDPOINT_USAGE_DATA), .EndpointSize = AUDIO_STREAM_EPSIZE,
/** Main program entry point. This routine configures the hardware required by the application, then * enters a loop to run the application tasks in sequence. */ int main(void) { SetupHardware(); puts_P(PSTR(ESC_FG_CYAN "Audio Output Host Demo running.\r\n" ESC_FG_WHITE)); LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY); sei(); for (;;) { switch (USB_HostState) { case HOST_STATE_Addressed: LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING); uint16_t ConfigDescriptorSize; uint8_t ConfigDescriptorData[512]; if (USB_Host_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData, sizeof(ConfigDescriptorData)) != HOST_GETCONFIG_Successful) { puts_P(PSTR("Error Retrieving Configuration Descriptor.\r\n")); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); USB_HostState = HOST_STATE_WaitForDeviceRemoval; break; } if (Audio_Host_ConfigurePipes(&Speaker_Audio_Interface, ConfigDescriptorSize, ConfigDescriptorData) != AUDIO_ENUMERROR_NoError) { puts_P(PSTR("Attached Device Not a Valid Audio Output Device.\r\n")); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); USB_HostState = HOST_STATE_WaitForDeviceRemoval; break; } if (USB_Host_SetDeviceConfiguration(1) != HOST_SENDCONTROL_Successful) { puts_P(PSTR("Error Setting Device Configuration.\r\n")); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); USB_HostState = HOST_STATE_WaitForDeviceRemoval; break; } if (Audio_Host_StartStopStreaming(&Speaker_Audio_Interface, true) != HOST_SENDCONTROL_Successful) { puts_P(PSTR("Error Enabling Audio Stream.\r\n")); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); USB_HostState = HOST_STATE_WaitForDeviceRemoval; break; } USB_Audio_SampleFreq_t SampleRate = AUDIO_SAMPLE_FREQ(48000); if (Audio_Host_GetSetEndpointProperty(&Speaker_Audio_Interface, Speaker_Audio_Interface.Config.DataOUTPipeNumber, AUDIO_REQ_SetCurrent, AUDIO_EPCONTROL_SamplingFreq, sizeof(SampleRate), &SampleRate) != HOST_SENDCONTROL_Successful) { puts_P(PSTR("Error Setting Audio Sampling Frequency.\r\n")); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); USB_HostState = HOST_STATE_WaitForDeviceRemoval; break; } /* Sample reload timer initialization */ TIMSK0 = (1 << OCIE0A); OCR0A = ((F_CPU / 8 / 48000) - 1); TCCR0A = (1 << WGM01); // CTC mode TCCR0B = (1 << CS01); // Fcpu/8 speed puts_P(PSTR("Audio Device Enumerated.\r\n")); LEDs_SetAllLEDs(LEDMASK_USB_READY); USB_HostState = HOST_STATE_Configured; break; case HOST_STATE_Configured: /* Do nothing - audio stream is handled by the timer interrupt routine */ break; } Audio_Host_USBTask(&Speaker_Audio_Interface); USB_USBTask(); } }
.AudioFormat = 0x0001 }, .Audio_AudioFormat = { .Header = {.Size = sizeof(USB_Audio_Descriptor_Format_t), .Type = DTYPE_CSInterface}, .Subtype = AUDIO_DSUBTYPE_CSInterface_FormatType, .FormatType = 0x01, .Channels = 0x01, .SubFrameSize = 0x02, .BitResolution = 16, .SampleFrequencyType = AUDIO_TOTAL_SAMPLE_RATES, .SampleFrequencies = {AUDIO_SAMPLE_FREQ(AUDIO_SAMPLE_FREQUENCY)} }, .Audio_StreamEndpoint = { .Endpoint = { .Header = {.Size = sizeof(USB_Audio_Descriptor_StreamEndpoint_Std_t), .Type = DTYPE_Endpoint}, .EndpointAddress = (ENDPOINT_DESCRIPTOR_DIR_IN | AUDIO_STREAM_EPNUM), .Attributes = (EP_TYPE_ISOCHRONOUS | ENDPOINT_ATTR_SYNC | ENDPOINT_USAGE_DATA), .EndpointSize = AUDIO_STREAM_EPSIZE, .PollingIntervalMS = 0x01 }, .Refresh = 0,
/** Event handler for the USB_DeviceEnumerationComplete event. This indicates that a device has been successfully * enumerated by the host and is now ready to be used by the application. */ void EVENT_USB_Host_DeviceEnumerationComplete(void) { puts_P(PSTR("Getting Config Data.\r\n")); uint8_t ErrorCode; /* Get and process the configuration descriptor data */ if ((ErrorCode = ProcessConfigurationDescriptor()) != SuccessfulConfigRead) { if (ErrorCode == ControlError) puts_P(PSTR(ESC_FG_RED "Control Error (Get Configuration).\r\n")); else puts_P(PSTR(ESC_FG_RED "Invalid Device.\r\n")); printf_P(PSTR(" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); return; } /* Set the device configuration to the first configuration (rarely do devices use multiple configurations) */ if ((ErrorCode = USB_Host_SetDeviceConfiguration(1)) != HOST_SENDCONTROL_Successful) { printf_P(PSTR(ESC_FG_RED "Control Error (Set Configuration).\r\n" " -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); return; } if ((ErrorCode = USB_Host_SetInterfaceAltSetting(StreamingInterfaceIndex, StreamingInterfaceAltSetting)) != HOST_SENDCONTROL_Successful) { printf_P(PSTR(ESC_FG_RED "Could not set alternative streaming interface setting.\r\n" " -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); USB_Host_SetDeviceConfiguration(0); return; } USB_ControlRequest = (USB_Request_Header_t) { .bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_ENDPOINT), .bRequest = AUDIO_REQ_SetCurrent, .wValue = (AUDIO_EPCONTROL_SamplingFreq << 8), .wIndex = StreamingEndpointAddress, .wLength = sizeof(USB_Audio_SampleFreq_t), }; USB_Audio_SampleFreq_t SampleRate = AUDIO_SAMPLE_FREQ(48000); /* Select the control pipe for the request transfer */ Pipe_SelectPipe(PIPE_CONTROLPIPE); /* Set the sample rate on the streaming interface endpoint */ if ((ErrorCode = USB_Host_SendControlRequest(&SampleRate)) != HOST_SENDCONTROL_Successful) { LEDs_SetAllLEDs(LEDMASK_USB_ERROR); USB_Host_SetDeviceConfiguration(0); return; } /* Sample reload timer initialization */ TIMSK0 = (1 << OCIE0A); OCR0A = ((F_CPU / 8 / 48000) - 1); TCCR0A = (1 << WGM01); // CTC mode TCCR0B = (1 << CS01); // Fcpu/8 speed puts_P(PSTR("Speaker Enumerated.\r\n")); LEDs_SetAllLEDs(LEDMASK_USB_READY); } /** Event handler for the USB_HostError event. This indicates that a hardware error occurred while in host mode. */ void EVENT_USB_Host_HostError(const uint8_t ErrorCode) { USB_Disable(); printf_P(PSTR(ESC_FG_RED "Host Mode Error\r\n" " -- Error Code %d\r\n" ESC_FG_WHITE), ErrorCode); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); for(;;); }
0x01, /* bTerminalLink */ 0x01, /* bDelay */ 0x01, /* wFormatTag AUDIO_FORMAT_PCM 0x0001*/ 0x00, /* 07 byte*/ /* USB Speaker Audio Type III Format Interface Descriptor */ 0x0B, /* bLength */ AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ AUDIO_STREAMING_FORMAT_TYPE, /* bDescriptorSubtype */ AUDIO_FORMAT_TYPE_III, /* bFormatType */ 0x02, /* bNrChannels */ 0x02, /* bSubFrameSize : 2 Bytes per frame (16bits) */ 16, /* bBitResolution (16-bits per sample) */ 0x01, /* bSamFreqType only one frequency supported */ AUDIO_SAMPLE_FREQ(USBD_AUDIO_FREQ), /* Audio sampling frequency coded on 3 bytes */ /* 11 byte*/ /* Endpoint 1 - Standard Descriptor */ AUDIO_STANDARD_ENDPOINT_DESC_SIZE, /* bLength */ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType */ AUDIO_OUT_EP, /* bEndpointAddress 1 out endpoint*/ USBD_EP_TYPE_ISOC, /* bmAttributes */ AUDIO_PACKET_SZE(USBD_AUDIO_FREQ), /* wMaxPacketSize in Bytes (Freq(Samples)*2(Stereo)*2(HalfWord)) */ 0x01, /* bInterval */ 0x00, /* bRefresh */ 0x00, /* bSynchAddress */ /* 09 byte*/ /* Endpoint - Audio Streaming Descriptor*/ AUDIO_STREAMING_ENDPOINT_DESC_SIZE, /* bLength */