forked from mfulz_github/qmk_firmware
Updated all host mode demos and projects to use the EVENT_USB_Host_DeviceEnumerationComplete() event callback for device configuration instead of manual host state machine manipulations in the main application task.
Added new USB_Host_ConfigurationNumber global variable to indicate the selected configuration in an attached device. Renamed global state variables that are specific to a certain USB mode to clearly indicate which mode the variable relates to, by changing the USB_* prefix to USB_Device_* or USB_Host_*. Removed the HOST_STATE_WaitForDeviceRemoval and HOST_STATE_Suspended host state machine states, as these are no longer required. Altered the USB_Host_SetDeviceConfiguration() function to update the new USB_Host_ConfigurationNumber global as required. Moved out the Host mode standard request convenience/helper functions from the architecture specific Host driver files to the architecture agnostic HostStandardReq.c driver file.
This commit is contained in:
parent
bcb627e1a1
commit
137ce280c1
|
@ -74,7 +74,43 @@ void EVENT_USB_Host_DeviceUnattached(void)
|
|||
* 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)
|
||||
{
|
||||
printf("Error Retrieving Configuration Descriptor.\r\n");
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
if (HID_Host_ConfigurePipes(&Mouse_HID_Host_Interface,
|
||||
ConfigDescriptorSize, ConfigDescriptorData) != HID_ENUMERROR_NoError)
|
||||
{
|
||||
printf("Attached Device Not a Valid Mouse.\r\n");
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
if (USB_Host_SetDeviceConfiguration(1) != HOST_SENDCONTROL_Successful)
|
||||
{
|
||||
printf("Error Setting Device Configuration.\r\n");
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
if (HID_Host_SetBootProtocol(&Mouse_HID_Host_Interface) != HOST_SENDCONTROL_Successful)
|
||||
{
|
||||
printf("Could not Set Boot Protocol Mode.\r\n");
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
printf("Mouse Enumerated.\r\n");
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_READY);
|
||||
}
|
||||
|
||||
|
@ -104,84 +140,38 @@ void EVENT_USB_Host_DeviceEnumerationFailed(const uint8_t ErrorCode,
|
|||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
}
|
||||
|
||||
/** Host state machine task. This task handles the enumeration and control of USB Mice while in USB Host mode,
|
||||
/** Host USB management task. This task handles the control of USB Mice while in USB Host mode,
|
||||
* setting up the appropriate data pipes and processing reports from the attached device.
|
||||
*/
|
||||
void MouseHostTask(void)
|
||||
void MouseHost_Task(void)
|
||||
{
|
||||
switch (USB_HostState)
|
||||
if (USB_HostState != HOST_STATE_Configured)
|
||||
return;
|
||||
|
||||
if (HID_Host_IsReportReceived(&Mouse_HID_Host_Interface))
|
||||
{
|
||||
case HOST_STATE_Addressed:
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
|
||||
uint8_t LEDMask = LEDS_NO_LEDS;
|
||||
|
||||
uint16_t ConfigDescriptorSize;
|
||||
uint8_t ConfigDescriptorData[512];
|
||||
USB_MouseReport_Data_t MouseReport;
|
||||
HID_Host_ReceiveReport(&Mouse_HID_Host_Interface, &MouseReport);
|
||||
|
||||
if (USB_Host_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData,
|
||||
sizeof(ConfigDescriptorData)) != HOST_GETCONFIG_Successful)
|
||||
{
|
||||
printf("Error Retrieving Configuration Descriptor.\r\n");
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
printf_P(PSTR("dX:%2d dY:%2d Button:%d\r\n"), MouseReport.X,
|
||||
MouseReport.Y,
|
||||
MouseReport.Button);
|
||||
if (MouseReport.X > 0)
|
||||
LEDMask |= LEDS_LED1;
|
||||
else if (MouseReport.X < 0)
|
||||
LEDMask |= LEDS_LED2;
|
||||
|
||||
if (HID_Host_ConfigurePipes(&Mouse_HID_Host_Interface,
|
||||
ConfigDescriptorSize, ConfigDescriptorData) != HID_ENUMERROR_NoError)
|
||||
{
|
||||
printf("Attached Device Not a Valid Mouse.\r\n");
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
if (MouseReport.Y > 0)
|
||||
LEDMask |= LEDS_LED3;
|
||||
else if (MouseReport.Y < 0)
|
||||
LEDMask |= LEDS_LED4;
|
||||
|
||||
if (USB_Host_SetDeviceConfiguration(1) != HOST_SENDCONTROL_Successful)
|
||||
{
|
||||
printf("Error Setting Device Configuration.\r\n");
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
if (MouseReport.Button)
|
||||
LEDMask = LEDS_ALL_LEDS;
|
||||
|
||||
if (HID_Host_SetBootProtocol(&Mouse_HID_Host_Interface) != HOST_SENDCONTROL_Successful)
|
||||
{
|
||||
printf("Could not Set Boot Protocol Mode.\r\n");
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
printf("Mouse Enumerated.\r\n");
|
||||
USB_HostState = HOST_STATE_Configured;
|
||||
break;
|
||||
case HOST_STATE_Configured:
|
||||
if (HID_Host_IsReportReceived(&Mouse_HID_Host_Interface))
|
||||
{
|
||||
uint8_t LEDMask = LEDS_NO_LEDS;
|
||||
|
||||
USB_MouseReport_Data_t MouseReport;
|
||||
HID_Host_ReceiveReport(&Mouse_HID_Host_Interface, &MouseReport);
|
||||
|
||||
printf_P(PSTR("dX:%2d dY:%2d Button:%d\r\n"), MouseReport.X,
|
||||
MouseReport.Y,
|
||||
MouseReport.Button);
|
||||
if (MouseReport.X > 0)
|
||||
LEDMask |= LEDS_LED1;
|
||||
else if (MouseReport.X < 0)
|
||||
LEDMask |= LEDS_LED2;
|
||||
|
||||
if (MouseReport.Y > 0)
|
||||
LEDMask |= LEDS_LED3;
|
||||
else if (MouseReport.Y < 0)
|
||||
LEDMask |= LEDS_LED4;
|
||||
|
||||
if (MouseReport.Button)
|
||||
LEDMask = LEDS_ALL_LEDS;
|
||||
|
||||
LEDs_SetAllLEDs(LEDMask);
|
||||
}
|
||||
|
||||
break;
|
||||
LEDs_SetAllLEDs(LEDMask);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -43,7 +43,7 @@
|
|||
extern USB_ClassInfo_HID_Host_t Mouse_HID_Host_Interface;
|
||||
|
||||
/* Function Prototypes: */
|
||||
void MouseHostTask(void);
|
||||
void MouseHost_Task(void);
|
||||
|
||||
void EVENT_USB_Host_HostError(const uint8_t ErrorCode);
|
||||
void EVENT_USB_Host_DeviceAttached(void);
|
||||
|
|
|
@ -53,7 +53,7 @@ int main(void)
|
|||
/* Determine which USB mode we are currently in */
|
||||
if (USB_CurrentMode == USB_MODE_Host)
|
||||
{
|
||||
MouseHostTask();
|
||||
MouseHost_Task();
|
||||
HID_Host_USBTask(&Mouse_HID_Host_Interface);
|
||||
}
|
||||
else
|
||||
|
|
|
@ -63,81 +63,6 @@ int main(void)
|
|||
|
||||
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(&Microphone_Audio_Interface,
|
||||
ConfigDescriptorSize, ConfigDescriptorData) != AUDIO_ENUMERROR_NoError)
|
||||
{
|
||||
puts_P(PSTR("Attached Device Not a Valid Audio Input 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(&Microphone_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(&Microphone_Audio_Interface, Microphone_Audio_Interface.Config.DataINPipeNumber,
|
||||
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
|
||||
|
||||
/* Set speaker as output */
|
||||
DDRC |= (1 << 6);
|
||||
|
||||
/* PWM speaker timer initialization */
|
||||
TCCR3A = ((1 << WGM30) | (1 << COM3A1) | (1 << COM3A0)); // Set on match, clear on TOP
|
||||
TCCR3B = ((1 << WGM32) | (1 << CS30)); // Fast 8-Bit PWM, F_CPU 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(&Microphone_Audio_Interface);
|
||||
USB_USBTask();
|
||||
}
|
||||
|
@ -217,6 +142,65 @@ void EVENT_USB_Host_DeviceUnattached(void)
|
|||
*/
|
||||
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(&Microphone_Audio_Interface,
|
||||
ConfigDescriptorSize, ConfigDescriptorData) != AUDIO_ENUMERROR_NoError)
|
||||
{
|
||||
puts_P(PSTR("Attached Device Not a Valid Audio Input 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(&Microphone_Audio_Interface, true) != HOST_SENDCONTROL_Successful)
|
||||
{
|
||||
puts_P(PSTR("Error Enabling Audio Stream.\r\n"));
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
USB_Audio_SampleFreq_t SampleRate = AUDIO_SAMPLE_FREQ(48000);
|
||||
if (Audio_Host_GetSetEndpointProperty(&Microphone_Audio_Interface, Microphone_Audio_Interface.Config.DataINPipeNumber,
|
||||
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);
|
||||
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
|
||||
|
||||
/* Set speaker as output */
|
||||
DDRC |= (1 << 6);
|
||||
|
||||
/* PWM speaker timer initialization */
|
||||
TCCR3A = ((1 << WGM30) | (1 << COM3A1) | (1 << COM3A0)); // Set on match, clear on TOP
|
||||
TCCR3B = ((1 << WGM32) | (1 << CS30)); // Fast 8-Bit PWM, F_CPU speed
|
||||
|
||||
puts_P(PSTR("Audio Device Enumerated.\r\n"));
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_READY);
|
||||
}
|
||||
|
||||
|
|
|
@ -63,74 +63,6 @@ int main(void)
|
|||
|
||||
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();
|
||||
}
|
||||
|
@ -218,6 +150,58 @@ void EVENT_USB_Host_DeviceUnattached(void)
|
|||
*/
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
@ -74,97 +74,7 @@ int main(void)
|
|||
|
||||
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 (HID_Host_ConfigurePipes(&Joystick_HID_Interface,
|
||||
ConfigDescriptorSize, ConfigDescriptorData) != HID_ENUMERROR_NoError)
|
||||
{
|
||||
puts_P(PSTR("Attached Device Not a Valid Joystick.\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 (HID_Host_SetReportProtocol(&Joystick_HID_Interface) != 0)
|
||||
{
|
||||
puts_P(PSTR("Error Setting Report Protocol Mode or Not a Valid Joystick.\r\n"));
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
puts_P(PSTR("Joystick Enumerated.\r\n"));
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_READY);
|
||||
USB_HostState = HOST_STATE_Configured;
|
||||
break;
|
||||
case HOST_STATE_Configured:
|
||||
if (HID_Host_IsReportReceived(&Joystick_HID_Interface))
|
||||
{
|
||||
uint8_t JoystickReport[Joystick_HID_Interface.State.LargestReportSize];
|
||||
HID_Host_ReceiveReport(&Joystick_HID_Interface, &JoystickReport);
|
||||
|
||||
uint8_t LEDMask = LEDS_NO_LEDS;
|
||||
|
||||
for (uint8_t ReportNumber = 0; ReportNumber < HIDReportInfo.TotalReportItems; ReportNumber++)
|
||||
{
|
||||
HID_ReportItem_t* ReportItem = &HIDReportInfo.ReportItems[ReportNumber];
|
||||
|
||||
/* Update the report item value if it is contained within the current report */
|
||||
if (!(USB_GetHIDReportItemInfo(JoystickReport, ReportItem)))
|
||||
continue;
|
||||
|
||||
/* Determine what report item is being tested, process updated value as needed */
|
||||
if ((ReportItem->Attributes.Usage.Page == USAGE_PAGE_BUTTON) &&
|
||||
(ReportItem->ItemType == HID_REPORT_ITEM_In))
|
||||
{
|
||||
if (ReportItem->Value)
|
||||
LEDMask = LEDS_ALL_LEDS;
|
||||
}
|
||||
else if ((ReportItem->Attributes.Usage.Page == USAGE_PAGE_GENERIC_DCTRL) &&
|
||||
((ReportItem->Attributes.Usage.Usage == USAGE_X) ||
|
||||
(ReportItem->Attributes.Usage.Usage == USAGE_Y)) &&
|
||||
(ReportItem->ItemType == HID_REPORT_ITEM_In))
|
||||
{
|
||||
int16_t DeltaMovement = HID_ALIGN_DATA(ReportItem, int16_t);
|
||||
|
||||
if (DeltaMovement)
|
||||
{
|
||||
if (ReportItem->Attributes.Usage.Usage == USAGE_X)
|
||||
LEDMask |= ((DeltaMovement > 0) ? LEDS_LED1 : LEDS_LED2);
|
||||
else
|
||||
LEDMask |= ((DeltaMovement > 0) ? LEDS_LED3 : LEDS_LED4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LEDs_SetAllLEDs(LEDMask);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
JoystickHost_Task();
|
||||
|
||||
HID_Host_USBTask(&Joystick_HID_Interface);
|
||||
USB_USBTask();
|
||||
|
@ -190,6 +100,57 @@ void SetupHardware(void)
|
|||
Serial_CreateStream(NULL);
|
||||
}
|
||||
|
||||
/** Task to manage an enumerated USB joystick once connected, to display movement
|
||||
* data as it is received.
|
||||
*/
|
||||
void JoystickHost_Task(void)
|
||||
{
|
||||
if (USB_HostState != HOST_STATE_Configured)
|
||||
return;
|
||||
|
||||
if (HID_Host_IsReportReceived(&Joystick_HID_Interface))
|
||||
{
|
||||
uint8_t JoystickReport[Joystick_HID_Interface.State.LargestReportSize];
|
||||
HID_Host_ReceiveReport(&Joystick_HID_Interface, &JoystickReport);
|
||||
|
||||
uint8_t LEDMask = LEDS_NO_LEDS;
|
||||
|
||||
for (uint8_t ReportNumber = 0; ReportNumber < HIDReportInfo.TotalReportItems; ReportNumber++)
|
||||
{
|
||||
HID_ReportItem_t* ReportItem = &HIDReportInfo.ReportItems[ReportNumber];
|
||||
|
||||
/* Update the report item value if it is contained within the current report */
|
||||
if (!(USB_GetHIDReportItemInfo(JoystickReport, ReportItem)))
|
||||
continue;
|
||||
|
||||
/* Determine what report item is being tested, process updated value as needed */
|
||||
if ((ReportItem->Attributes.Usage.Page == USAGE_PAGE_BUTTON) &&
|
||||
(ReportItem->ItemType == HID_REPORT_ITEM_In))
|
||||
{
|
||||
if (ReportItem->Value)
|
||||
LEDMask = LEDS_ALL_LEDS;
|
||||
}
|
||||
else if ((ReportItem->Attributes.Usage.Page == USAGE_PAGE_GENERIC_DCTRL) &&
|
||||
((ReportItem->Attributes.Usage.Usage == USAGE_X) ||
|
||||
(ReportItem->Attributes.Usage.Usage == USAGE_Y)) &&
|
||||
(ReportItem->ItemType == HID_REPORT_ITEM_In))
|
||||
{
|
||||
int16_t DeltaMovement = HID_ALIGN_DATA(ReportItem, int16_t);
|
||||
|
||||
if (DeltaMovement)
|
||||
{
|
||||
if (ReportItem->Attributes.Usage.Usage == USAGE_X)
|
||||
LEDMask |= ((DeltaMovement > 0) ? LEDS_LED1 : LEDS_LED2);
|
||||
else
|
||||
LEDMask |= ((DeltaMovement > 0) ? LEDS_LED3 : LEDS_LED4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LEDs_SetAllLEDs(LEDMask);
|
||||
}
|
||||
}
|
||||
|
||||
/** Event handler for the USB_DeviceAttached event. This indicates that a device has been attached to the host, and
|
||||
* starts the library USB task to begin the enumeration and USB management process.
|
||||
*/
|
||||
|
@ -213,6 +174,42 @@ void EVENT_USB_Host_DeviceUnattached(void)
|
|||
*/
|
||||
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 (HID_Host_ConfigurePipes(&Joystick_HID_Interface,
|
||||
ConfigDescriptorSize, ConfigDescriptorData) != HID_ENUMERROR_NoError)
|
||||
{
|
||||
puts_P(PSTR("Attached Device Not a Valid Joystick.\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 (HID_Host_SetReportProtocol(&Joystick_HID_Interface) != 0)
|
||||
{
|
||||
puts_P(PSTR("Error Setting Report Protocol Mode or Not a Valid Joystick.\r\n"));
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
puts_P(PSTR("Joystick Enumerated.\r\n"));
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_READY);
|
||||
}
|
||||
|
||||
|
|
|
@ -80,6 +80,7 @@
|
|||
|
||||
/* Function Prototypes: */
|
||||
void SetupHardware(void);
|
||||
void JoystickHost_Task(void);
|
||||
|
||||
void EVENT_USB_Host_HostError(const uint8_t ErrorCode);
|
||||
void EVENT_USB_Host_DeviceAttached(void);
|
||||
|
|
|
@ -69,98 +69,7 @@ int main(void)
|
|||
|
||||
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 (HID_Host_ConfigurePipes(&Keyboard_HID_Interface,
|
||||
ConfigDescriptorSize, ConfigDescriptorData) != HID_ENUMERROR_NoError)
|
||||
{
|
||||
puts_P(PSTR("Attached Device Not a Valid Keyboard.\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 (HID_Host_SetBootProtocol(&Keyboard_HID_Interface) != 0)
|
||||
{
|
||||
puts_P(PSTR("Could not Set Boot Protocol Mode.\r\n"));
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
puts_P(PSTR("Keyboard Enumerated.\r\n"));
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_READY);
|
||||
USB_HostState = HOST_STATE_Configured;
|
||||
break;
|
||||
case HOST_STATE_Configured:
|
||||
if (HID_Host_IsReportReceived(&Keyboard_HID_Interface))
|
||||
{
|
||||
USB_KeyboardReport_Data_t KeyboardReport;
|
||||
HID_Host_ReceiveReport(&Keyboard_HID_Interface, &KeyboardReport);
|
||||
|
||||
LEDs_ChangeLEDs(LEDS_LED1, (KeyboardReport.Modifier) ? LEDS_LED1 : 0);
|
||||
|
||||
uint8_t KeyCode = KeyboardReport.KeyCode[0];
|
||||
|
||||
if (KeyCode)
|
||||
{
|
||||
char PressedKey = 0;
|
||||
|
||||
LEDs_ToggleLEDs(LEDS_LED2);
|
||||
|
||||
/* Retrieve pressed key character if alphanumeric */
|
||||
if ((KeyCode >= HID_KEYBOARD_SC_A) && (KeyCode <= HID_KEYBOARD_SC_Z))
|
||||
{
|
||||
PressedKey = (KeyCode - HID_KEYBOARD_SC_A) + 'A';
|
||||
}
|
||||
else if ((KeyCode >= HID_KEYBOARD_SC_1_AND_EXCLAMATION) &
|
||||
(KeyCode < HID_KEYBOARD_SC_0_AND_CLOSING_PARENTHESIS))
|
||||
{
|
||||
PressedKey = (KeyCode - HID_KEYBOARD_SC_1_AND_EXCLAMATION) + '1';
|
||||
}
|
||||
else if (KeyCode == HID_KEYBOARD_SC_0_AND_CLOSING_PARENTHESIS)
|
||||
{
|
||||
PressedKey = '0';
|
||||
}
|
||||
else if (KeyCode == HID_KEYBOARD_SC_SPACE)
|
||||
{
|
||||
PressedKey = ' ';
|
||||
}
|
||||
else if (KeyCode == HID_KEYBOARD_SC_ENTER)
|
||||
{
|
||||
PressedKey = '\n';
|
||||
}
|
||||
|
||||
if (PressedKey)
|
||||
putchar(PressedKey);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
KeyboardHost_Task();
|
||||
|
||||
HID_Host_USBTask(&Keyboard_HID_Interface);
|
||||
USB_USBTask();
|
||||
|
@ -186,6 +95,58 @@ void SetupHardware(void)
|
|||
Serial_CreateStream(NULL);
|
||||
}
|
||||
|
||||
/** Task to manage an enumerated USB keyboard once connected, to display key state
|
||||
* data as it is received.
|
||||
*/
|
||||
void KeyboardHost_Task(void)
|
||||
{
|
||||
if (USB_HostState != HOST_STATE_Configured)
|
||||
return;
|
||||
|
||||
if (HID_Host_IsReportReceived(&Keyboard_HID_Interface))
|
||||
{
|
||||
USB_KeyboardReport_Data_t KeyboardReport;
|
||||
HID_Host_ReceiveReport(&Keyboard_HID_Interface, &KeyboardReport);
|
||||
|
||||
LEDs_ChangeLEDs(LEDS_LED1, (KeyboardReport.Modifier) ? LEDS_LED1 : 0);
|
||||
|
||||
uint8_t KeyCode = KeyboardReport.KeyCode[0];
|
||||
|
||||
if (KeyCode)
|
||||
{
|
||||
char PressedKey = 0;
|
||||
|
||||
LEDs_ToggleLEDs(LEDS_LED2);
|
||||
|
||||
/* Retrieve pressed key character if alphanumeric */
|
||||
if ((KeyCode >= HID_KEYBOARD_SC_A) && (KeyCode <= HID_KEYBOARD_SC_Z))
|
||||
{
|
||||
PressedKey = (KeyCode - HID_KEYBOARD_SC_A) + 'A';
|
||||
}
|
||||
else if ((KeyCode >= HID_KEYBOARD_SC_1_AND_EXCLAMATION) &
|
||||
(KeyCode < HID_KEYBOARD_SC_0_AND_CLOSING_PARENTHESIS))
|
||||
{
|
||||
PressedKey = (KeyCode - HID_KEYBOARD_SC_1_AND_EXCLAMATION) + '1';
|
||||
}
|
||||
else if (KeyCode == HID_KEYBOARD_SC_0_AND_CLOSING_PARENTHESIS)
|
||||
{
|
||||
PressedKey = '0';
|
||||
}
|
||||
else if (KeyCode == HID_KEYBOARD_SC_SPACE)
|
||||
{
|
||||
PressedKey = ' ';
|
||||
}
|
||||
else if (KeyCode == HID_KEYBOARD_SC_ENTER)
|
||||
{
|
||||
PressedKey = '\n';
|
||||
}
|
||||
|
||||
if (PressedKey)
|
||||
putchar(PressedKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Event handler for the USB_DeviceAttached event. This indicates that a device has been attached to the host, and
|
||||
* starts the library USB task to begin the enumeration and USB management process.
|
||||
*/
|
||||
|
@ -209,6 +170,42 @@ void EVENT_USB_Host_DeviceUnattached(void)
|
|||
*/
|
||||
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 (HID_Host_ConfigurePipes(&Keyboard_HID_Interface,
|
||||
ConfigDescriptorSize, ConfigDescriptorData) != HID_ENUMERROR_NoError)
|
||||
{
|
||||
puts_P(PSTR("Attached Device Not a Valid Keyboard.\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 (HID_Host_SetBootProtocol(&Keyboard_HID_Interface) != 0)
|
||||
{
|
||||
puts_P(PSTR("Could not Set Boot Protocol Mode.\r\n"));
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
puts_P(PSTR("Keyboard Enumerated.\r\n"));
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_READY);
|
||||
}
|
||||
|
||||
|
|
|
@ -65,6 +65,7 @@
|
|||
|
||||
/* Function Prototypes: */
|
||||
void SetupHardware(void);
|
||||
void KeyboardHost_Task(void);
|
||||
|
||||
void EVENT_USB_Host_HostError(const uint8_t ErrorCode);
|
||||
void EVENT_USB_Host_DeviceAttached(void);
|
||||
|
|
|
@ -74,119 +74,7 @@ int main(void)
|
|||
|
||||
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 (HID_Host_ConfigurePipes(&Keyboard_HID_Interface,
|
||||
ConfigDescriptorSize, ConfigDescriptorData) != HID_ENUMERROR_NoError)
|
||||
{
|
||||
puts_P(PSTR("Attached Device Not a Valid Keyboard.\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 (HID_Host_SetReportProtocol(&Keyboard_HID_Interface) != 0)
|
||||
{
|
||||
puts_P(PSTR("Error Setting Report Protocol Mode or Not a Valid Keyboard.\r\n"));
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
puts_P(PSTR("Keyboard Enumerated.\r\n"));
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_READY);
|
||||
USB_HostState = HOST_STATE_Configured;
|
||||
break;
|
||||
case HOST_STATE_Configured:
|
||||
if (HID_Host_IsReportReceived(&Keyboard_HID_Interface))
|
||||
{
|
||||
uint8_t KeyboardReport[Keyboard_HID_Interface.State.LargestReportSize];
|
||||
HID_Host_ReceiveReport(&Keyboard_HID_Interface, &KeyboardReport);
|
||||
|
||||
for (uint8_t ReportNumber = 0; ReportNumber < HIDReportInfo.TotalReportItems; ReportNumber++)
|
||||
{
|
||||
HID_ReportItem_t* ReportItem = &HIDReportInfo.ReportItems[ReportNumber];
|
||||
|
||||
/* Update the report item value if it is contained within the current report */
|
||||
if (!(USB_GetHIDReportItemInfo(KeyboardReport, ReportItem)))
|
||||
continue;
|
||||
|
||||
/* Determine what report item is being tested, process updated value as needed */
|
||||
if ((ReportItem->Attributes.Usage.Page == USAGE_PAGE_KEYBOARD) &&
|
||||
(ReportItem->Attributes.BitSize == 8) &&
|
||||
(ReportItem->Attributes.Logical.Maximum > 1) &&
|
||||
(ReportItem->ItemType == HID_REPORT_ITEM_In))
|
||||
{
|
||||
/* Key code is an unsigned char in length, cast to the appropriate type */
|
||||
uint8_t KeyCode = (uint8_t)ReportItem->Value;
|
||||
|
||||
/* If scan-code is non-zero, a key is being pressed */
|
||||
if (KeyCode)
|
||||
{
|
||||
/* Toggle status LED to indicate keypress */
|
||||
LEDs_ToggleLEDs(LEDS_LED2);
|
||||
|
||||
char PressedKey = 0;
|
||||
|
||||
/* Convert scan-code to printable character if alphanumeric */
|
||||
if ((KeyCode >= HID_KEYBOARD_SC_A) && (KeyCode <= HID_KEYBOARD_SC_Z))
|
||||
{
|
||||
PressedKey = (KeyCode - HID_KEYBOARD_SC_A) + 'A';
|
||||
}
|
||||
else if ((KeyCode >= HID_KEYBOARD_SC_1_AND_EXCLAMATION) &
|
||||
(KeyCode < HID_KEYBOARD_SC_0_AND_CLOSING_PARENTHESIS))
|
||||
{
|
||||
PressedKey = (KeyCode - HID_KEYBOARD_SC_1_AND_EXCLAMATION) + '1';
|
||||
}
|
||||
else if (KeyCode == HID_KEYBOARD_SC_0_AND_CLOSING_PARENTHESIS)
|
||||
{
|
||||
PressedKey = '0';
|
||||
}
|
||||
else if (KeyCode == HID_KEYBOARD_SC_SPACE)
|
||||
{
|
||||
PressedKey = ' ';
|
||||
}
|
||||
else if (KeyCode == HID_KEYBOARD_SC_ENTER)
|
||||
{
|
||||
PressedKey = '\n';
|
||||
}
|
||||
|
||||
/* Print the pressed key character out through the serial port if valid */
|
||||
if (PressedKey)
|
||||
putchar(PressedKey);
|
||||
}
|
||||
|
||||
/* Once a scan-code is found, stop scanning through the report items */
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
KeyboardHost_Task();
|
||||
|
||||
HID_Host_USBTask(&Keyboard_HID_Interface);
|
||||
USB_USBTask();
|
||||
|
@ -212,6 +100,79 @@ void SetupHardware(void)
|
|||
Serial_CreateStream(NULL);
|
||||
}
|
||||
|
||||
/** Task to manage an enumerated USB keyboard once connected, to display key state
|
||||
* data as it is received.
|
||||
*/
|
||||
void KeyboardHost_Task(void)
|
||||
{
|
||||
if (USB_HostState != HOST_STATE_Configured)
|
||||
return;
|
||||
|
||||
if (HID_Host_IsReportReceived(&Keyboard_HID_Interface))
|
||||
{
|
||||
uint8_t KeyboardReport[Keyboard_HID_Interface.State.LargestReportSize];
|
||||
HID_Host_ReceiveReport(&Keyboard_HID_Interface, &KeyboardReport);
|
||||
|
||||
for (uint8_t ReportNumber = 0; ReportNumber < HIDReportInfo.TotalReportItems; ReportNumber++)
|
||||
{
|
||||
HID_ReportItem_t* ReportItem = &HIDReportInfo.ReportItems[ReportNumber];
|
||||
|
||||
/* Update the report item value if it is contained within the current report */
|
||||
if (!(USB_GetHIDReportItemInfo(KeyboardReport, ReportItem)))
|
||||
continue;
|
||||
|
||||
/* Determine what report item is being tested, process updated value as needed */
|
||||
if ((ReportItem->Attributes.Usage.Page == USAGE_PAGE_KEYBOARD) &&
|
||||
(ReportItem->Attributes.BitSize == 8) &&
|
||||
(ReportItem->Attributes.Logical.Maximum > 1) &&
|
||||
(ReportItem->ItemType == HID_REPORT_ITEM_In))
|
||||
{
|
||||
/* Key code is an unsigned char in length, cast to the appropriate type */
|
||||
uint8_t KeyCode = (uint8_t)ReportItem->Value;
|
||||
|
||||
/* If scan-code is non-zero, a key is being pressed */
|
||||
if (KeyCode)
|
||||
{
|
||||
/* Toggle status LED to indicate keypress */
|
||||
LEDs_ToggleLEDs(LEDS_LED2);
|
||||
|
||||
char PressedKey = 0;
|
||||
|
||||
/* Convert scan-code to printable character if alphanumeric */
|
||||
if ((KeyCode >= HID_KEYBOARD_SC_A) && (KeyCode <= HID_KEYBOARD_SC_Z))
|
||||
{
|
||||
PressedKey = (KeyCode - HID_KEYBOARD_SC_A) + 'A';
|
||||
}
|
||||
else if ((KeyCode >= HID_KEYBOARD_SC_1_AND_EXCLAMATION) &
|
||||
(KeyCode < HID_KEYBOARD_SC_0_AND_CLOSING_PARENTHESIS))
|
||||
{
|
||||
PressedKey = (KeyCode - HID_KEYBOARD_SC_1_AND_EXCLAMATION) + '1';
|
||||
}
|
||||
else if (KeyCode == HID_KEYBOARD_SC_0_AND_CLOSING_PARENTHESIS)
|
||||
{
|
||||
PressedKey = '0';
|
||||
}
|
||||
else if (KeyCode == HID_KEYBOARD_SC_SPACE)
|
||||
{
|
||||
PressedKey = ' ';
|
||||
}
|
||||
else if (KeyCode == HID_KEYBOARD_SC_ENTER)
|
||||
{
|
||||
PressedKey = '\n';
|
||||
}
|
||||
|
||||
/* Print the pressed key character out through the serial port if valid */
|
||||
if (PressedKey)
|
||||
putchar(PressedKey);
|
||||
}
|
||||
|
||||
/* Once a scan-code is found, stop scanning through the report items */
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Event handler for the USB_DeviceAttached event. This indicates that a device has been attached to the host, and
|
||||
* starts the library USB task to begin the enumeration and USB management process.
|
||||
*/
|
||||
|
@ -235,6 +196,42 @@ void EVENT_USB_Host_DeviceUnattached(void)
|
|||
*/
|
||||
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 (HID_Host_ConfigurePipes(&Keyboard_HID_Interface,
|
||||
ConfigDescriptorSize, ConfigDescriptorData) != HID_ENUMERROR_NoError)
|
||||
{
|
||||
puts_P(PSTR("Attached Device Not a Valid Keyboard.\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 (HID_Host_SetReportProtocol(&Keyboard_HID_Interface) != 0)
|
||||
{
|
||||
puts_P(PSTR("Error Setting Report Protocol Mode or Not a Valid Keyboard.\r\n"));
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
puts_P(PSTR("Keyboard Enumerated.\r\n"));
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_READY);
|
||||
}
|
||||
|
||||
|
|
|
@ -68,6 +68,7 @@
|
|||
|
||||
/* Function Prototypes: */
|
||||
void SetupHardware(void);
|
||||
void KeyboardHost_Task(void);
|
||||
|
||||
void EVENT_USB_Host_HostError(const uint8_t ErrorCode);
|
||||
void EVENT_USB_Host_DeviceAttached(void);
|
||||
|
|
|
@ -67,63 +67,7 @@ int main(void)
|
|||
|
||||
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 (MIDI_Host_ConfigurePipes(&Keyboard_MIDI_Interface,
|
||||
ConfigDescriptorSize, ConfigDescriptorData) != MIDI_ENUMERROR_NoError)
|
||||
{
|
||||
puts_P(PSTR("Attached Device Not a Valid MIDI Class 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;
|
||||
}
|
||||
|
||||
puts_P(PSTR("MIDI Device Enumerated.\r\n"));
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_READY);
|
||||
USB_HostState = HOST_STATE_Configured;
|
||||
break;
|
||||
case HOST_STATE_Configured:
|
||||
CheckJoystickMovement();
|
||||
|
||||
MIDI_EventPacket_t MIDIEvent;
|
||||
while (MIDI_Host_ReceiveEventPacket(&Keyboard_MIDI_Interface, &MIDIEvent))
|
||||
{
|
||||
bool NoteOnEvent = ((MIDIEvent.Command & 0x0F) == (MIDI_COMMAND_NOTE_ON >> 4));
|
||||
bool NoteOffEvent = ((MIDIEvent.Command & 0x0F) == (MIDI_COMMAND_NOTE_OFF >> 4));
|
||||
|
||||
if (NoteOnEvent || NoteOffEvent)
|
||||
{
|
||||
printf_P(PSTR("MIDI Note %s - Channel %d, Pitch %d, Velocity %d\r\n"), NoteOnEvent ? "On" : "Off",
|
||||
((MIDIEvent.Data1 & 0x0F) + 1),
|
||||
MIDIEvent.Data2, MIDIEvent.Data3);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
JoystickHost_Task();
|
||||
|
||||
MIDI_Host_USBTask(&Keyboard_MIDI_Interface);
|
||||
USB_USBTask();
|
||||
|
@ -151,6 +95,35 @@ void SetupHardware(void)
|
|||
Serial_CreateStream(NULL);
|
||||
}
|
||||
|
||||
/** Task to manage an enumerated USB MIDI device once connected, to display received
|
||||
* note events from the host and send note changes in response to tbe board's joystick.
|
||||
*/
|
||||
void JoystickHost_Task(void)
|
||||
{
|
||||
if (USB_HostState != HOST_STATE_Configured)
|
||||
return;
|
||||
|
||||
MIDI_EventPacket_t MIDIEvent;
|
||||
while (MIDI_Host_ReceiveEventPacket(&Keyboard_MIDI_Interface, &MIDIEvent))
|
||||
{
|
||||
bool NoteOnEvent = ((MIDIEvent.Command & 0x0F) == (MIDI_COMMAND_NOTE_ON >> 4));
|
||||
bool NoteOffEvent = ((MIDIEvent.Command & 0x0F) == (MIDI_COMMAND_NOTE_OFF >> 4));
|
||||
|
||||
/* Display note events from the host */
|
||||
if (NoteOnEvent || NoteOffEvent)
|
||||
{
|
||||
printf_P(PSTR("MIDI Note %s - Channel %d, Pitch %d, Velocity %d\r\n"), NoteOnEvent ? "On" : "Off",
|
||||
((MIDIEvent.Data1 & 0x0F) + 1),
|
||||
MIDIEvent.Data2, MIDIEvent.Data3);
|
||||
}
|
||||
}
|
||||
|
||||
CheckJoystickMovement();
|
||||
}
|
||||
|
||||
/** Checks for movement of the board's joystick, and sends corresponding MIDI note on/off
|
||||
* messages to the host.
|
||||
*/
|
||||
void CheckJoystickMovement(void)
|
||||
{
|
||||
static uint8_t PrevJoystickStatus;
|
||||
|
@ -170,26 +143,22 @@ void CheckJoystickMovement(void)
|
|||
MIDICommand = ((JoystickStatus & JOY_LEFT)? MIDI_COMMAND_NOTE_ON : MIDI_COMMAND_NOTE_OFF);
|
||||
MIDIPitch = 0x3C;
|
||||
}
|
||||
|
||||
if (JoystickChanges & JOY_UP)
|
||||
else if (JoystickChanges & JOY_UP)
|
||||
{
|
||||
MIDICommand = ((JoystickStatus & JOY_UP)? MIDI_COMMAND_NOTE_ON : MIDI_COMMAND_NOTE_OFF);
|
||||
MIDIPitch = 0x3D;
|
||||
}
|
||||
|
||||
if (JoystickChanges & JOY_RIGHT)
|
||||
else if (JoystickChanges & JOY_RIGHT)
|
||||
{
|
||||
MIDICommand = ((JoystickStatus & JOY_RIGHT)? MIDI_COMMAND_NOTE_ON : MIDI_COMMAND_NOTE_OFF);
|
||||
MIDIPitch = 0x3E;
|
||||
}
|
||||
|
||||
if (JoystickChanges & JOY_DOWN)
|
||||
else if (JoystickChanges & JOY_DOWN)
|
||||
{
|
||||
MIDICommand = ((JoystickStatus & JOY_DOWN)? MIDI_COMMAND_NOTE_ON : MIDI_COMMAND_NOTE_OFF);
|
||||
MIDIPitch = 0x3F;
|
||||
}
|
||||
|
||||
if (JoystickChanges & JOY_PRESS)
|
||||
else if (JoystickChanges & JOY_PRESS)
|
||||
{
|
||||
MIDICommand = ((JoystickStatus & JOY_PRESS)? MIDI_COMMAND_NOTE_ON : MIDI_COMMAND_NOTE_OFF);
|
||||
MIDIPitch = 0x3B;
|
||||
|
@ -237,6 +206,35 @@ void EVENT_USB_Host_DeviceUnattached(void)
|
|||
*/
|
||||
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 (MIDI_Host_ConfigurePipes(&Keyboard_MIDI_Interface,
|
||||
ConfigDescriptorSize, ConfigDescriptorData) != MIDI_ENUMERROR_NoError)
|
||||
{
|
||||
puts_P(PSTR("Attached Device Not a Valid MIDI Class 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;
|
||||
}
|
||||
|
||||
puts_P(PSTR("MIDI Device Enumerated.\r\n"));
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_READY);
|
||||
}
|
||||
|
||||
|
|
|
@ -68,6 +68,7 @@
|
|||
/* Function Prototypes: */
|
||||
void SetupHardware(void);
|
||||
void CheckJoystickMovement(void);
|
||||
void JoystickHost_Task(void);
|
||||
|
||||
void EVENT_USB_Host_HostError(const uint8_t ErrorCode);
|
||||
void EVENT_USB_Host_DeviceAttached(void);
|
||||
|
|
|
@ -67,166 +67,8 @@ int main(void)
|
|||
|
||||
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 (MS_Host_ConfigurePipes(&FlashDisk_MS_Interface,
|
||||
ConfigDescriptorSize, ConfigDescriptorData) != MS_ENUMERROR_NoError)
|
||||
{
|
||||
puts_P(PSTR("Attached Device Not a Valid Mass Storage 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;
|
||||
}
|
||||
|
||||
puts_P(PSTR("Mass Storage Device Enumerated.\r\n"));
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_READY);
|
||||
USB_HostState = HOST_STATE_Configured;
|
||||
break;
|
||||
case HOST_STATE_Configured:
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_BUSY);
|
||||
|
||||
uint8_t MaxLUNIndex;
|
||||
if (MS_Host_GetMaxLUN(&FlashDisk_MS_Interface, &MaxLUNIndex))
|
||||
{
|
||||
puts_P(PSTR("Error retrieving max LUN index.\r\n"));
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
printf_P(PSTR("Total LUNs: %d - Using first LUN in device.\r\n"), (MaxLUNIndex + 1));
|
||||
|
||||
if (MS_Host_ResetMSInterface(&FlashDisk_MS_Interface))
|
||||
{
|
||||
puts_P(PSTR("Error resetting Mass Storage interface.\r\n"));
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
SCSI_Request_Sense_Response_t SenseData;
|
||||
if (MS_Host_RequestSense(&FlashDisk_MS_Interface, 0, &SenseData) != 0)
|
||||
{
|
||||
puts_P(PSTR("Error retrieving device sense.\r\n"));
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
if (MS_Host_PreventAllowMediumRemoval(&FlashDisk_MS_Interface, 0, true))
|
||||
{
|
||||
puts_P(PSTR("Error setting Prevent Device Removal bit.\r\n"));
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
SCSI_Inquiry_Response_t InquiryData;
|
||||
if (MS_Host_GetInquiryData(&FlashDisk_MS_Interface, 0, &InquiryData))
|
||||
{
|
||||
puts_P(PSTR("Error retrieving device Inquiry data.\r\n"));
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
printf_P(PSTR("Vendor \"%.8s\", Product \"%.16s\"\r\n"), InquiryData.VendorID, InquiryData.ProductID);
|
||||
|
||||
puts_P(PSTR("Waiting until ready...\r\n"));
|
||||
|
||||
for (;;)
|
||||
{
|
||||
uint8_t ErrorCode = MS_Host_TestUnitReady(&FlashDisk_MS_Interface, 0);
|
||||
|
||||
if (!(ErrorCode))
|
||||
break;
|
||||
|
||||
/* Check if an error other than a logical command error (device busy) received */
|
||||
if (ErrorCode != MS_ERROR_LOGICAL_CMD_FAILED)
|
||||
{
|
||||
puts_P(PSTR("Error waiting for device to be ready.\r\n"));
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
puts_P(PSTR("Retrieving Capacity...\r\n"));
|
||||
|
||||
SCSI_Capacity_t DiskCapacity;
|
||||
if (MS_Host_ReadDeviceCapacity(&FlashDisk_MS_Interface, 0, &DiskCapacity))
|
||||
{
|
||||
puts_P(PSTR("Error retrieving device capacity.\r\n"));
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
printf_P(PSTR("%lu blocks of %lu bytes.\r\n"), DiskCapacity.Blocks, DiskCapacity.BlockSize);
|
||||
|
||||
uint8_t BlockBuffer[DiskCapacity.BlockSize];
|
||||
|
||||
if (MS_Host_ReadDeviceBlocks(&FlashDisk_MS_Interface, 0, 0x00000000, 1, DiskCapacity.BlockSize, BlockBuffer))
|
||||
{
|
||||
puts_P(PSTR("Error reading device block.\r\n"));
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
puts_P(PSTR("\r\nContents of first block:\r\n"));
|
||||
|
||||
for (uint16_t Chunk = 0; Chunk < (DiskCapacity.BlockSize >> 4); Chunk++)
|
||||
{
|
||||
uint8_t* ChunkPtr = &BlockBuffer[Chunk << 4];
|
||||
|
||||
/* Print out the 16 bytes of the chunk in HEX format */
|
||||
for (uint8_t ByteOffset = 0; ByteOffset < (1 << 4); ByteOffset++)
|
||||
{
|
||||
char CurrByte = *(ChunkPtr + ByteOffset);
|
||||
printf_P(PSTR("%.2X "), CurrByte);
|
||||
}
|
||||
|
||||
printf_P(PSTR(" "));
|
||||
|
||||
/* Print out the 16 bytes of the chunk in ASCII format */
|
||||
for (uint8_t ByteOffset = 0; ByteOffset < (1 << 4); ByteOffset++)
|
||||
{
|
||||
char CurrByte = *(ChunkPtr + ByteOffset);
|
||||
putchar(isprint(CurrByte) ? CurrByte : '.');
|
||||
}
|
||||
|
||||
printf_P(PSTR("\r\n"));
|
||||
}
|
||||
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_READY);
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
MassStorageHost_Task();
|
||||
|
||||
MS_Host_USBTask(&FlashDisk_MS_Interface);
|
||||
USB_USBTask();
|
||||
}
|
||||
|
@ -251,6 +93,87 @@ void SetupHardware(void)
|
|||
Serial_CreateStream(NULL);
|
||||
}
|
||||
|
||||
/** Task to manage an enumerated USB Mass Storage device once connected, to print out
|
||||
* data from the device.
|
||||
*/
|
||||
void MassStorageHost_Task(void)
|
||||
{
|
||||
if (USB_HostState != HOST_STATE_Configured)
|
||||
return;
|
||||
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_BUSY);
|
||||
|
||||
puts_P(PSTR("Waiting until ready...\r\n"));
|
||||
|
||||
for (;;)
|
||||
{
|
||||
uint8_t ErrorCode = MS_Host_TestUnitReady(&FlashDisk_MS_Interface, 0);
|
||||
|
||||
if (!(ErrorCode))
|
||||
break;
|
||||
|
||||
/* Check if an error other than a logical command error (device busy) received */
|
||||
if (ErrorCode != MS_ERROR_LOGICAL_CMD_FAILED)
|
||||
{
|
||||
puts_P(PSTR("Error waiting for device to be ready.\r\n"));
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
USB_Host_SetDeviceConfiguration(0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
puts_P(PSTR("Retrieving Capacity...\r\n"));
|
||||
|
||||
SCSI_Capacity_t DiskCapacity;
|
||||
if (MS_Host_ReadDeviceCapacity(&FlashDisk_MS_Interface, 0, &DiskCapacity))
|
||||
{
|
||||
puts_P(PSTR("Error retrieving device capacity.\r\n"));
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
USB_Host_SetDeviceConfiguration(0);
|
||||
return;
|
||||
}
|
||||
|
||||
printf_P(PSTR("%lu blocks of %lu bytes.\r\n"), DiskCapacity.Blocks, DiskCapacity.BlockSize);
|
||||
|
||||
uint8_t BlockBuffer[DiskCapacity.BlockSize];
|
||||
|
||||
if (MS_Host_ReadDeviceBlocks(&FlashDisk_MS_Interface, 0, 0x00000000, 1, DiskCapacity.BlockSize, BlockBuffer))
|
||||
{
|
||||
puts_P(PSTR("Error reading device block.\r\n"));
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
USB_Host_SetDeviceConfiguration(0);
|
||||
return;
|
||||
}
|
||||
|
||||
puts_P(PSTR("\r\nContents of first block:\r\n"));
|
||||
|
||||
for (uint16_t Chunk = 0; Chunk < (DiskCapacity.BlockSize >> 4); Chunk++)
|
||||
{
|
||||
uint8_t* ChunkPtr = &BlockBuffer[Chunk << 4];
|
||||
|
||||
/* Print out the 16 bytes of the chunk in HEX format */
|
||||
for (uint8_t ByteOffset = 0; ByteOffset < (1 << 4); ByteOffset++)
|
||||
{
|
||||
char CurrByte = *(ChunkPtr + ByteOffset);
|
||||
printf_P(PSTR("%.2X "), CurrByte);
|
||||
}
|
||||
|
||||
printf_P(PSTR(" "));
|
||||
|
||||
/* Print out the 16 bytes of the chunk in ASCII format */
|
||||
for (uint8_t ByteOffset = 0; ByteOffset < (1 << 4); ByteOffset++)
|
||||
{
|
||||
char CurrByte = *(ChunkPtr + ByteOffset);
|
||||
putchar(isprint(CurrByte) ? CurrByte : '.');
|
||||
}
|
||||
|
||||
printf_P(PSTR("\r\n"));
|
||||
}
|
||||
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_READY);
|
||||
USB_Host_SetDeviceConfiguration(0);
|
||||
}
|
||||
|
||||
/** Event handler for the USB_DeviceAttached event. This indicates that a device has been attached to the host, and
|
||||
* starts the library USB task to begin the enumeration and USB management process.
|
||||
*/
|
||||
|
@ -274,6 +197,82 @@ void EVENT_USB_Host_DeviceUnattached(void)
|
|||
*/
|
||||
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 (MS_Host_ConfigurePipes(&FlashDisk_MS_Interface,
|
||||
ConfigDescriptorSize, ConfigDescriptorData) != MS_ENUMERROR_NoError)
|
||||
{
|
||||
puts_P(PSTR("Attached Device Not a Valid Mass Storage 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;
|
||||
}
|
||||
|
||||
uint8_t MaxLUNIndex;
|
||||
if (MS_Host_GetMaxLUN(&FlashDisk_MS_Interface, &MaxLUNIndex))
|
||||
{
|
||||
puts_P(PSTR("Error retrieving max LUN index.\r\n"));
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
USB_Host_SetDeviceConfiguration(0);
|
||||
return;
|
||||
}
|
||||
|
||||
printf_P(PSTR("Total LUNs: %d - Using first LUN in device.\r\n"), (MaxLUNIndex + 1));
|
||||
|
||||
if (MS_Host_ResetMSInterface(&FlashDisk_MS_Interface))
|
||||
{
|
||||
puts_P(PSTR("Error resetting Mass Storage interface.\r\n"));
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
USB_Host_SetDeviceConfiguration(0);
|
||||
return;
|
||||
}
|
||||
|
||||
SCSI_Request_Sense_Response_t SenseData;
|
||||
if (MS_Host_RequestSense(&FlashDisk_MS_Interface, 0, &SenseData) != 0)
|
||||
{
|
||||
puts_P(PSTR("Error retrieving device sense.\r\n"));
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
USB_Host_SetDeviceConfiguration(0);
|
||||
return;
|
||||
}
|
||||
|
||||
if (MS_Host_PreventAllowMediumRemoval(&FlashDisk_MS_Interface, 0, true))
|
||||
{
|
||||
puts_P(PSTR("Error setting Prevent Device Removal bit.\r\n"));
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
USB_Host_SetDeviceConfiguration(0);
|
||||
return;
|
||||
}
|
||||
|
||||
SCSI_Inquiry_Response_t InquiryData;
|
||||
if (MS_Host_GetInquiryData(&FlashDisk_MS_Interface, 0, &InquiryData))
|
||||
{
|
||||
puts_P(PSTR("Error retrieving device Inquiry data.\r\n"));
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
USB_Host_SetDeviceConfiguration(0);
|
||||
return;
|
||||
}
|
||||
|
||||
printf_P(PSTR("Vendor \"%.8s\", Product \"%.16s\"\r\n"), InquiryData.VendorID, InquiryData.ProductID);
|
||||
|
||||
puts_P(PSTR("Mass Storage Device Enumerated.\r\n"));
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_READY);
|
||||
}
|
||||
|
||||
|
|
|
@ -69,7 +69,8 @@
|
|||
|
||||
/* Function Prototypes: */
|
||||
void SetupHardware(void);
|
||||
|
||||
void MassStorageHost_Task(void);
|
||||
|
||||
void EVENT_USB_Host_HostError(const uint8_t ErrorCode);
|
||||
void EVENT_USB_Host_DeviceAttached(void);
|
||||
void EVENT_USB_Host_DeviceUnattached(void);
|
||||
|
|
|
@ -69,81 +69,7 @@ int main(void)
|
|||
|
||||
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 (HID_Host_ConfigurePipes(&Mouse_HID_Interface,
|
||||
ConfigDescriptorSize, ConfigDescriptorData) != HID_ENUMERROR_NoError)
|
||||
{
|
||||
puts_P(PSTR("Attached Device Not a Valid Mouse.\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 (HID_Host_SetBootProtocol(&Mouse_HID_Interface) != 0)
|
||||
{
|
||||
puts_P(PSTR("Could not Set Boot Protocol Mode.\r\n"));
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
puts_P(PSTR("Mouse Enumerated.\r\n"));
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_READY);
|
||||
USB_HostState = HOST_STATE_Configured;
|
||||
break;
|
||||
case HOST_STATE_Configured:
|
||||
if (HID_Host_IsReportReceived(&Mouse_HID_Interface))
|
||||
{
|
||||
uint8_t LEDMask = LEDS_NO_LEDS;
|
||||
|
||||
USB_MouseReport_Data_t MouseReport;
|
||||
HID_Host_ReceiveReport(&Mouse_HID_Interface, &MouseReport);
|
||||
|
||||
printf_P(PSTR("dX:%2d dY:%2d Button:%d\r\n"), MouseReport.X,
|
||||
MouseReport.Y,
|
||||
MouseReport.Button);
|
||||
if (MouseReport.X > 0)
|
||||
LEDMask |= LEDS_LED1;
|
||||
else if (MouseReport.X < 0)
|
||||
LEDMask |= LEDS_LED2;
|
||||
|
||||
if (MouseReport.Y > 0)
|
||||
LEDMask |= LEDS_LED3;
|
||||
else if (MouseReport.Y < 0)
|
||||
LEDMask |= LEDS_LED4;
|
||||
|
||||
if (MouseReport.Button)
|
||||
LEDMask = LEDS_ALL_LEDS;
|
||||
|
||||
LEDs_SetAllLEDs(LEDMask);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
MouseHost_Task();
|
||||
|
||||
HID_Host_USBTask(&Mouse_HID_Interface);
|
||||
USB_USBTask();
|
||||
|
@ -169,6 +95,41 @@ void SetupHardware(void)
|
|||
Serial_CreateStream(NULL);
|
||||
}
|
||||
|
||||
/** Task to manage an enumerated USB mouse once connected, to display movement
|
||||
* data as it is received.
|
||||
*/
|
||||
void MouseHost_Task(void)
|
||||
{
|
||||
if (USB_HostState != HOST_STATE_Configured)
|
||||
return;
|
||||
|
||||
if (HID_Host_IsReportReceived(&Mouse_HID_Interface))
|
||||
{
|
||||
uint8_t LEDMask = LEDS_NO_LEDS;
|
||||
|
||||
USB_MouseReport_Data_t MouseReport;
|
||||
HID_Host_ReceiveReport(&Mouse_HID_Interface, &MouseReport);
|
||||
|
||||
printf_P(PSTR("dX:%2d dY:%2d Button:%d\r\n"), MouseReport.X,
|
||||
MouseReport.Y,
|
||||
MouseReport.Button);
|
||||
if (MouseReport.X > 0)
|
||||
LEDMask |= LEDS_LED1;
|
||||
else if (MouseReport.X < 0)
|
||||
LEDMask |= LEDS_LED2;
|
||||
|
||||
if (MouseReport.Y > 0)
|
||||
LEDMask |= LEDS_LED3;
|
||||
else if (MouseReport.Y < 0)
|
||||
LEDMask |= LEDS_LED4;
|
||||
|
||||
if (MouseReport.Button)
|
||||
LEDMask = LEDS_ALL_LEDS;
|
||||
|
||||
LEDs_SetAllLEDs(LEDMask);
|
||||
}
|
||||
}
|
||||
|
||||
/** Event handler for the USB_DeviceAttached event. This indicates that a device has been attached to the host, and
|
||||
* starts the library USB task to begin the enumeration and USB management process.
|
||||
*/
|
||||
|
@ -192,6 +153,42 @@ void EVENT_USB_Host_DeviceUnattached(void)
|
|||
*/
|
||||
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 (HID_Host_ConfigurePipes(&Mouse_HID_Interface,
|
||||
ConfigDescriptorSize, ConfigDescriptorData) != HID_ENUMERROR_NoError)
|
||||
{
|
||||
puts_P(PSTR("Attached Device Not a Valid Mouse.\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 (HID_Host_SetBootProtocol(&Mouse_HID_Interface) != 0)
|
||||
{
|
||||
puts_P(PSTR("Could not Set Boot Protocol Mode.\r\n"));
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
puts_P(PSTR("Mouse Enumerated.\r\n"));
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_READY);
|
||||
}
|
||||
|
||||
|
|
|
@ -65,6 +65,7 @@
|
|||
|
||||
/* Function Prototypes: */
|
||||
void SetupHardware(void);
|
||||
void MouseHost_Task(void);
|
||||
|
||||
void EVENT_USB_Host_HostError(const uint8_t ErrorCode);
|
||||
void EVENT_USB_Host_DeviceAttached(void);
|
||||
|
|
|
@ -74,106 +74,7 @@ int main(void)
|
|||
|
||||
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 (HID_Host_ConfigurePipes(&Mouse_HID_Interface,
|
||||
ConfigDescriptorSize, ConfigDescriptorData) != HID_ENUMERROR_NoError)
|
||||
{
|
||||
puts_P(PSTR("Attached Device Not a Valid Mouse.\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 (HID_Host_SetReportProtocol(&Mouse_HID_Interface) != 0)
|
||||
{
|
||||
puts_P(PSTR("Error Setting Report Protocol Mode or Not a Valid Mouse.\r\n"));
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
puts_P(PSTR("Mouse Enumerated.\r\n"));
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_READY);
|
||||
USB_HostState = HOST_STATE_Configured;
|
||||
break;
|
||||
case HOST_STATE_Configured:
|
||||
if (HID_Host_IsReportReceived(&Mouse_HID_Interface))
|
||||
{
|
||||
uint8_t MouseReport[Mouse_HID_Interface.State.LargestReportSize];
|
||||
HID_Host_ReceiveReport(&Mouse_HID_Interface, &MouseReport);
|
||||
|
||||
uint8_t LEDMask = LEDS_NO_LEDS;
|
||||
|
||||
for (uint8_t ReportNumber = 0; ReportNumber < HIDReportInfo.TotalReportItems; ReportNumber++)
|
||||
{
|
||||
HID_ReportItem_t* ReportItem = &HIDReportInfo.ReportItems[ReportNumber];
|
||||
|
||||
/* Update the report item value if it is contained within the current report */
|
||||
if (!(USB_GetHIDReportItemInfo(MouseReport, ReportItem)))
|
||||
continue;
|
||||
|
||||
/* Determine what report item is being tested, process updated value as needed */
|
||||
if ((ReportItem->Attributes.Usage.Page == USAGE_PAGE_BUTTON) &&
|
||||
(ReportItem->ItemType == HID_REPORT_ITEM_In))
|
||||
{
|
||||
if (ReportItem->Value)
|
||||
LEDMask = LEDS_ALL_LEDS;
|
||||
}
|
||||
else if ((ReportItem->Attributes.Usage.Page == USAGE_PAGE_GENERIC_DCTRL) &&
|
||||
(ReportItem->Attributes.Usage.Usage == USAGE_SCROLL_WHEEL) &&
|
||||
(ReportItem->ItemType == HID_REPORT_ITEM_In))
|
||||
{
|
||||
int16_t WheelDelta = HID_ALIGN_DATA(ReportItem, int16_t);
|
||||
|
||||
if (WheelDelta)
|
||||
LEDMask = (LEDS_LED1 | LEDS_LED2 | ((WheelDelta > 0) ? LEDS_LED3 : LEDS_LED4));
|
||||
}
|
||||
else if ((ReportItem->Attributes.Usage.Page == USAGE_PAGE_GENERIC_DCTRL) &&
|
||||
((ReportItem->Attributes.Usage.Usage == USAGE_X) ||
|
||||
(ReportItem->Attributes.Usage.Usage == USAGE_Y)) &&
|
||||
(ReportItem->ItemType == HID_REPORT_ITEM_In))
|
||||
{
|
||||
int16_t DeltaMovement = HID_ALIGN_DATA(ReportItem, int16_t);
|
||||
|
||||
if (DeltaMovement)
|
||||
{
|
||||
if (ReportItem->Attributes.Usage.Usage == USAGE_X)
|
||||
LEDMask |= ((DeltaMovement > 0) ? LEDS_LED1 : LEDS_LED2);
|
||||
else
|
||||
LEDMask |= ((DeltaMovement > 0) ? LEDS_LED3 : LEDS_LED4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LEDs_SetAllLEDs(LEDMask);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
MouseHost_Task();
|
||||
|
||||
HID_Host_USBTask(&Mouse_HID_Interface);
|
||||
USB_USBTask();
|
||||
|
@ -199,6 +100,66 @@ void SetupHardware(void)
|
|||
Serial_CreateStream(NULL);
|
||||
}
|
||||
|
||||
/** Task to manage an enumerated USB mouse once connected, to display movement
|
||||
* data as it is received.
|
||||
*/
|
||||
void MouseHost_Task(void)
|
||||
{
|
||||
if (USB_HostState != HOST_STATE_Configured)
|
||||
return;
|
||||
|
||||
if (HID_Host_IsReportReceived(&Mouse_HID_Interface))
|
||||
{
|
||||
uint8_t MouseReport[Mouse_HID_Interface.State.LargestReportSize];
|
||||
HID_Host_ReceiveReport(&Mouse_HID_Interface, &MouseReport);
|
||||
|
||||
uint8_t LEDMask = LEDS_NO_LEDS;
|
||||
|
||||
for (uint8_t ReportNumber = 0; ReportNumber < HIDReportInfo.TotalReportItems; ReportNumber++)
|
||||
{
|
||||
HID_ReportItem_t* ReportItem = &HIDReportInfo.ReportItems[ReportNumber];
|
||||
|
||||
/* Update the report item value if it is contained within the current report */
|
||||
if (!(USB_GetHIDReportItemInfo(MouseReport, ReportItem)))
|
||||
continue;
|
||||
|
||||
/* Determine what report item is being tested, process updated value as needed */
|
||||
if ((ReportItem->Attributes.Usage.Page == USAGE_PAGE_BUTTON) &&
|
||||
(ReportItem->ItemType == HID_REPORT_ITEM_In))
|
||||
{
|
||||
if (ReportItem->Value)
|
||||
LEDMask = LEDS_ALL_LEDS;
|
||||
}
|
||||
else if ((ReportItem->Attributes.Usage.Page == USAGE_PAGE_GENERIC_DCTRL) &&
|
||||
(ReportItem->Attributes.Usage.Usage == USAGE_SCROLL_WHEEL) &&
|
||||
(ReportItem->ItemType == HID_REPORT_ITEM_In))
|
||||
{
|
||||
int16_t WheelDelta = HID_ALIGN_DATA(ReportItem, int16_t);
|
||||
|
||||
if (WheelDelta)
|
||||
LEDMask = (LEDS_LED1 | LEDS_LED2 | ((WheelDelta > 0) ? LEDS_LED3 : LEDS_LED4));
|
||||
}
|
||||
else if ((ReportItem->Attributes.Usage.Page == USAGE_PAGE_GENERIC_DCTRL) &&
|
||||
((ReportItem->Attributes.Usage.Usage == USAGE_X) ||
|
||||
(ReportItem->Attributes.Usage.Usage == USAGE_Y)) &&
|
||||
(ReportItem->ItemType == HID_REPORT_ITEM_In))
|
||||
{
|
||||
int16_t DeltaMovement = HID_ALIGN_DATA(ReportItem, int16_t);
|
||||
|
||||
if (DeltaMovement)
|
||||
{
|
||||
if (ReportItem->Attributes.Usage.Usage == USAGE_X)
|
||||
LEDMask |= ((DeltaMovement > 0) ? LEDS_LED1 : LEDS_LED2);
|
||||
else
|
||||
LEDMask |= ((DeltaMovement > 0) ? LEDS_LED3 : LEDS_LED4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LEDs_SetAllLEDs(LEDMask);
|
||||
}
|
||||
}
|
||||
|
||||
/** Event handler for the USB_DeviceAttached event. This indicates that a device has been attached to the host, and
|
||||
* starts the library USB task to begin the enumeration and USB management process.
|
||||
*/
|
||||
|
@ -222,6 +183,42 @@ void EVENT_USB_Host_DeviceUnattached(void)
|
|||
*/
|
||||
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 (HID_Host_ConfigurePipes(&Mouse_HID_Interface,
|
||||
ConfigDescriptorSize, ConfigDescriptorData) != HID_ENUMERROR_NoError)
|
||||
{
|
||||
puts_P(PSTR("Attached Device Not a Valid Mouse.\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 (HID_Host_SetReportProtocol(&Mouse_HID_Interface) != 0)
|
||||
{
|
||||
puts_P(PSTR("Error Setting Report Protocol Mode or Not a Valid Mouse.\r\n"));
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
puts_P(PSTR("Mouse Enumerated.\r\n"));
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_READY);
|
||||
}
|
||||
|
||||
|
|
|
@ -83,6 +83,7 @@
|
|||
|
||||
/* Function Prototypes: */
|
||||
void SetupHardware(void);
|
||||
void MouseHost_Task(void);
|
||||
|
||||
void EVENT_USB_Host_HostError(const uint8_t ErrorCode);
|
||||
void EVENT_USB_Host_DeviceAttached(void);
|
||||
|
|
|
@ -67,88 +67,7 @@ int main(void)
|
|||
|
||||
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 (PRNT_Host_ConfigurePipes(&Printer_PRNT_Interface,
|
||||
ConfigDescriptorSize, ConfigDescriptorData) != PRNT_ENUMERROR_NoError)
|
||||
{
|
||||
puts_P(PSTR("Attached Device Not a Valid Printer Class 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 (PRNT_Host_SetBidirectionalMode(&Printer_PRNT_Interface) != HOST_SENDCONTROL_Successful)
|
||||
{
|
||||
puts_P(PSTR("Error Setting Bidirectional Mode.\r\n"));
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
puts_P(PSTR("Printer Device Enumerated.\r\n"));
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_READY);
|
||||
USB_HostState = HOST_STATE_Configured;
|
||||
break;
|
||||
case HOST_STATE_Configured:
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_BUSY);
|
||||
|
||||
puts_P(PSTR("Retrieving Device ID...\r\n"));
|
||||
|
||||
char DeviceIDString[300];
|
||||
if (PRNT_Host_GetDeviceID(&Printer_PRNT_Interface, DeviceIDString,
|
||||
sizeof(DeviceIDString)) != HOST_SENDCONTROL_Successful)
|
||||
{
|
||||
puts_P(PSTR("Error Getting Device ID.\r\n"));
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
printf_P(PSTR("Device ID: %s.\r\n"), DeviceIDString);
|
||||
|
||||
char TestPageData[] = "\033%-12345X\033E" "LUFA PCL Test Page" "\033E\033%-12345X";
|
||||
uint16_t TestPageLength = strlen(TestPageData);
|
||||
|
||||
printf_P(PSTR("Sending Test Page (%d bytes)...\r\n"), TestPageLength);
|
||||
|
||||
if (PRNT_Host_SendData(&Printer_PRNT_Interface, &TestPageData, TestPageLength) != PIPE_RWSTREAM_NoError)
|
||||
{
|
||||
puts_P(PSTR("Error Sending Page Data.\r\n"));
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
puts_P(PSTR("Test Page Sent.\r\n"));
|
||||
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_READY);
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
PrinterHost_Task();
|
||||
|
||||
PRNT_Host_USBTask(&Printer_PRNT_Interface);
|
||||
USB_USBTask();
|
||||
|
@ -174,6 +93,49 @@ void SetupHardware(void)
|
|||
Serial_CreateStream(NULL);
|
||||
}
|
||||
|
||||
/** Task to manage an enumerated USB printer once connected, to display device
|
||||
* information and print a test PCL page.
|
||||
*/
|
||||
void PrinterHost_Task(void)
|
||||
{
|
||||
if (USB_HostState != HOST_STATE_Configured)
|
||||
return;
|
||||
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_BUSY);
|
||||
|
||||
puts_P(PSTR("Retrieving Device ID...\r\n"));
|
||||
|
||||
char DeviceIDString[300];
|
||||
if (PRNT_Host_GetDeviceID(&Printer_PRNT_Interface, DeviceIDString,
|
||||
sizeof(DeviceIDString)) != HOST_SENDCONTROL_Successful)
|
||||
{
|
||||
puts_P(PSTR("Error Getting Device ID.\r\n"));
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
USB_Host_SetDeviceConfiguration(0);
|
||||
return;
|
||||
}
|
||||
|
||||
printf_P(PSTR("Device ID: %s.\r\n"), DeviceIDString);
|
||||
|
||||
char TestPageData[] = "\033%-12345X\033E" "LUFA PCL Test Page" "\033E\033%-12345X";
|
||||
uint16_t TestPageLength = strlen(TestPageData);
|
||||
|
||||
printf_P(PSTR("Sending Test Page (%d bytes)...\r\n"), TestPageLength);
|
||||
|
||||
if (PRNT_Host_SendData(&Printer_PRNT_Interface, &TestPageData, TestPageLength) != PIPE_RWSTREAM_NoError)
|
||||
{
|
||||
puts_P(PSTR("Error Sending Page Data.\r\n"));
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
USB_Host_SetDeviceConfiguration(0);
|
||||
return;
|
||||
}
|
||||
|
||||
puts_P(PSTR("Test Page Sent.\r\n"));
|
||||
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_READY);
|
||||
USB_Host_SetDeviceConfiguration(0);
|
||||
}
|
||||
|
||||
/** Event handler for the USB_DeviceAttached event. This indicates that a device has been attached to the host, and
|
||||
* starts the library USB task to begin the enumeration and USB management process.
|
||||
*/
|
||||
|
@ -197,6 +159,43 @@ void EVENT_USB_Host_DeviceUnattached(void)
|
|||
*/
|
||||
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 (PRNT_Host_ConfigurePipes(&Printer_PRNT_Interface,
|
||||
ConfigDescriptorSize, ConfigDescriptorData) != PRNT_ENUMERROR_NoError)
|
||||
{
|
||||
puts_P(PSTR("Attached Device Not a Valid Printer Class 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 (PRNT_Host_SetBidirectionalMode(&Printer_PRNT_Interface) != HOST_SENDCONTROL_Successful)
|
||||
{
|
||||
puts_P(PSTR("Error Setting Bidirectional Mode.\r\n"));
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
USB_Host_SetDeviceConfiguration(0);
|
||||
return;
|
||||
}
|
||||
|
||||
puts_P(PSTR("Printer Device Enumerated.\r\n"));
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_READY);
|
||||
}
|
||||
|
||||
|
|
|
@ -68,6 +68,7 @@
|
|||
|
||||
/* Function Prototypes: */
|
||||
void SetupHardware(void);
|
||||
void PrinterHost_Task(void);
|
||||
|
||||
void EVENT_USB_Host_HostError(const uint8_t ErrorCode);
|
||||
void EVENT_USB_Host_DeviceAttached(void);
|
||||
|
|
|
@ -75,93 +75,21 @@ int main(void)
|
|||
|
||||
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 (RNDIS_Host_ConfigurePipes(&Ethernet_RNDIS_Interface,
|
||||
ConfigDescriptorSize, ConfigDescriptorData) != RNDIS_ENUMERROR_NoError)
|
||||
{
|
||||
puts_P(PSTR("Attached Device Not a Valid RNDIS Class 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 (RNDIS_Host_InitializeDevice(&Ethernet_RNDIS_Interface) != HOST_SENDCONTROL_Successful)
|
||||
{
|
||||
puts_P(PSTR("Error Initializing Device.\r\n"));
|
||||
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
printf_P(PSTR("Device Max Transfer Size: %lu bytes.\r\n"), Ethernet_RNDIS_Interface.State.DeviceMaxPacketSize);
|
||||
|
||||
uint32_t PacketFilter = (REMOTE_NDIS_PACKET_DIRECTED | REMOTE_NDIS_PACKET_BROADCAST | REMOTE_NDIS_PACKET_ALL_MULTICAST);
|
||||
if (RNDIS_Host_SetRNDISProperty(&Ethernet_RNDIS_Interface, OID_GEN_CURRENT_PACKET_FILTER,
|
||||
&PacketFilter, sizeof(PacketFilter)) != HOST_SENDCONTROL_Successful)
|
||||
{
|
||||
puts_P(PSTR("Error Setting Device Packet Filter.\r\n"));
|
||||
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
uint32_t VendorID;
|
||||
if (RNDIS_Host_QueryRNDISProperty(&Ethernet_RNDIS_Interface, OID_GEN_VENDOR_ID,
|
||||
&VendorID, sizeof(VendorID)) != HOST_SENDCONTROL_Successful)
|
||||
{
|
||||
puts_P(PSTR("Error Getting Vendor ID.\r\n"));
|
||||
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
printf_P(PSTR("Device Vendor ID: 0x%08lX\r\n"), VendorID);
|
||||
|
||||
puts_P(PSTR("RNDIS Device Enumerated.\r\n"));
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_READY);
|
||||
USB_HostState = HOST_STATE_Configured;
|
||||
break;
|
||||
case HOST_STATE_Configured:
|
||||
PrintIncomingPackets();
|
||||
|
||||
break;
|
||||
}
|
||||
RNDISHost_Task();
|
||||
|
||||
RNDIS_Host_USBTask(&Ethernet_RNDIS_Interface);
|
||||
USB_USBTask();
|
||||
}
|
||||
}
|
||||
|
||||
/** Prints incoming packets from the attached RNDIS device to the serial port. */
|
||||
void PrintIncomingPackets(void)
|
||||
/** Task to manage an enumerated USB RNDIS device once connected, to display device
|
||||
* received data packets.
|
||||
*/
|
||||
void RNDISHost_Task(void)
|
||||
{
|
||||
if (USB_HostState != HOST_STATE_Configured)
|
||||
return;
|
||||
|
||||
if (RNDIS_Host_IsPacketReceived(&Ethernet_RNDIS_Interface))
|
||||
{
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_BUSY);
|
||||
|
@ -222,6 +150,70 @@ void EVENT_USB_Host_DeviceUnattached(void)
|
|||
*/
|
||||
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 (RNDIS_Host_ConfigurePipes(&Ethernet_RNDIS_Interface,
|
||||
ConfigDescriptorSize, ConfigDescriptorData) != RNDIS_ENUMERROR_NoError)
|
||||
{
|
||||
puts_P(PSTR("Attached Device Not a Valid RNDIS Class 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 (RNDIS_Host_InitializeDevice(&Ethernet_RNDIS_Interface) != HOST_SENDCONTROL_Successful)
|
||||
{
|
||||
puts_P(PSTR("Error Initializing Device.\r\n"));
|
||||
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
USB_Host_SetDeviceConfiguration(0);
|
||||
return;
|
||||
}
|
||||
|
||||
printf_P(PSTR("Device Max Transfer Size: %lu bytes.\r\n"), Ethernet_RNDIS_Interface.State.DeviceMaxPacketSize);
|
||||
|
||||
uint32_t PacketFilter = (REMOTE_NDIS_PACKET_DIRECTED | REMOTE_NDIS_PACKET_BROADCAST | REMOTE_NDIS_PACKET_ALL_MULTICAST);
|
||||
if (RNDIS_Host_SetRNDISProperty(&Ethernet_RNDIS_Interface, OID_GEN_CURRENT_PACKET_FILTER,
|
||||
&PacketFilter, sizeof(PacketFilter)) != HOST_SENDCONTROL_Successful)
|
||||
{
|
||||
puts_P(PSTR("Error Setting Device Packet Filter.\r\n"));
|
||||
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
USB_Host_SetDeviceConfiguration(0);
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t VendorID;
|
||||
if (RNDIS_Host_QueryRNDISProperty(&Ethernet_RNDIS_Interface, OID_GEN_VENDOR_ID,
|
||||
&VendorID, sizeof(VendorID)) != HOST_SENDCONTROL_Successful)
|
||||
{
|
||||
puts_P(PSTR("Error Getting Vendor ID.\r\n"));
|
||||
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
USB_Host_SetDeviceConfiguration(0);
|
||||
return;
|
||||
}
|
||||
|
||||
printf_P(PSTR("Device Vendor ID: 0x%08lX\r\n"), VendorID);
|
||||
|
||||
puts_P(PSTR("RNDIS Device Enumerated.\r\n"));
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_READY);
|
||||
}
|
||||
|
||||
|
|
|
@ -68,7 +68,7 @@
|
|||
|
||||
/* Function Prototypes: */
|
||||
void SetupHardware(void);
|
||||
void PrintIncomingPackets(void);
|
||||
void RNDISHost_Task(void);
|
||||
|
||||
void EVENT_USB_Host_HostError(const uint8_t ErrorCode);
|
||||
void EVENT_USB_Host_DeviceAttached(void);
|
||||
|
|
|
@ -70,80 +70,8 @@ int main(void)
|
|||
|
||||
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 (SI_Host_ConfigurePipes(&DigitalCamera_SI_Interface,
|
||||
ConfigDescriptorSize, ConfigDescriptorData) != SI_ENUMERROR_NoError)
|
||||
{
|
||||
puts_P(PSTR("Attached Device Not a Valid Still Image Class 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;
|
||||
}
|
||||
|
||||
puts_P(PSTR("Still Image Device Enumerated.\r\n"));
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_READY);
|
||||
USB_HostState = HOST_STATE_Configured;
|
||||
break;
|
||||
case HOST_STATE_Configured:
|
||||
puts_P(PSTR("Opening Session...\r\n"));
|
||||
|
||||
if (SI_Host_OpenSession(&DigitalCamera_SI_Interface) != PIPE_RWSTREAM_NoError)
|
||||
{
|
||||
puts_P(PSTR("Could not open PIMA session.\r\n"));
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
puts_P(PSTR("Turning off Device...\r\n"));
|
||||
|
||||
SI_Host_SendCommand(&DigitalCamera_SI_Interface, 0x1013, 0, NULL);
|
||||
if (SI_Host_ReceiveResponse(&DigitalCamera_SI_Interface))
|
||||
{
|
||||
puts_P(PSTR("Could not turn off device.\r\n"));
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
puts_P(PSTR("Device Off.\r\n"));
|
||||
|
||||
puts_P(PSTR("Closing Session...\r\n"));
|
||||
|
||||
if (SI_Host_CloseSession(&DigitalCamera_SI_Interface) != PIPE_RWSTREAM_NoError)
|
||||
{
|
||||
puts_P(PSTR("Could not close PIMA session.\r\n"));
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_READY);
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
StillImageHost_Task();
|
||||
|
||||
SI_Host_USBTask(&DigitalCamera_SI_Interface);
|
||||
USB_USBTask();
|
||||
}
|
||||
|
@ -168,6 +96,48 @@ void SetupHardware(void)
|
|||
Serial_CreateStream(NULL);
|
||||
}
|
||||
|
||||
/** Task to manage an enumerated USB Still Image device once connected, to manage a
|
||||
* new PIMA session in order to send commands to the attached device.
|
||||
*/
|
||||
void StillImageHost_Task(void)
|
||||
{
|
||||
if (USB_HostState != HOST_STATE_Configured)
|
||||
return;
|
||||
|
||||
puts_P(PSTR("Opening Session...\r\n"));
|
||||
|
||||
if (SI_Host_OpenSession(&DigitalCamera_SI_Interface) != PIPE_RWSTREAM_NoError)
|
||||
{
|
||||
puts_P(PSTR("Could not open PIMA session.\r\n"));
|
||||
USB_Host_SetDeviceConfiguration(0);
|
||||
return;
|
||||
}
|
||||
|
||||
puts_P(PSTR("Turning off Device...\r\n"));
|
||||
|
||||
SI_Host_SendCommand(&DigitalCamera_SI_Interface, 0x1013, 0, NULL);
|
||||
if (SI_Host_ReceiveResponse(&DigitalCamera_SI_Interface))
|
||||
{
|
||||
puts_P(PSTR("Could not turn off device.\r\n"));
|
||||
USB_Host_SetDeviceConfiguration(0);
|
||||
return;
|
||||
}
|
||||
|
||||
puts_P(PSTR("Device Off.\r\n"));
|
||||
|
||||
puts_P(PSTR("Closing Session...\r\n"));
|
||||
|
||||
if (SI_Host_CloseSession(&DigitalCamera_SI_Interface) != PIPE_RWSTREAM_NoError)
|
||||
{
|
||||
puts_P(PSTR("Could not close PIMA session.\r\n"));
|
||||
USB_Host_SetDeviceConfiguration(0);
|
||||
return;
|
||||
}
|
||||
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_READY);
|
||||
USB_Host_SetDeviceConfiguration(0);
|
||||
}
|
||||
|
||||
/** Event handler for the USB_DeviceAttached event. This indicates that a device has been attached to the host, and
|
||||
* starts the library USB task to begin the enumeration and USB management process.
|
||||
*/
|
||||
|
@ -191,6 +161,35 @@ void EVENT_USB_Host_DeviceUnattached(void)
|
|||
*/
|
||||
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 (SI_Host_ConfigurePipes(&DigitalCamera_SI_Interface,
|
||||
ConfigDescriptorSize, ConfigDescriptorData) != SI_ENUMERROR_NoError)
|
||||
{
|
||||
puts_P(PSTR("Attached Device Not a Valid Still Image Class 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;
|
||||
}
|
||||
|
||||
puts_P(PSTR("Still Image Device Enumerated.\r\n"));
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_READY);
|
||||
}
|
||||
|
||||
|
|
|
@ -65,6 +65,7 @@
|
|||
|
||||
/* Function Prototypes: */
|
||||
void SetupHardware(void);
|
||||
void StillImageHost_Task(void);
|
||||
|
||||
void EVENT_USB_Host_HostError(const uint8_t ErrorCode);
|
||||
void EVENT_USB_Host_DeviceAttached(void);
|
||||
|
|
|
@ -70,55 +70,7 @@ int main(void)
|
|||
|
||||
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 (CDC_Host_ConfigurePipes(&VirtualSerial_CDC_Interface,
|
||||
ConfigDescriptorSize, ConfigDescriptorData) != CDC_ENUMERROR_NoError)
|
||||
{
|
||||
puts_P(PSTR("Attached Device Not a Valid CDC Class 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;
|
||||
}
|
||||
|
||||
puts_P(PSTR("CDC Device Enumerated.\r\n"));
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_READY);
|
||||
USB_HostState = HOST_STATE_Configured;
|
||||
break;
|
||||
case HOST_STATE_Configured:
|
||||
if (CDC_Host_BytesReceived(&VirtualSerial_CDC_Interface))
|
||||
{
|
||||
/* Echo received bytes from the attached device through the USART */
|
||||
int16_t ReceivedByte = CDC_Host_ReceiveByte(&VirtualSerial_CDC_Interface);
|
||||
if (!(ReceivedByte < 0))
|
||||
putchar(ReceivedByte);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
CDCHost_Task();
|
||||
|
||||
CDC_Host_USBTask(&VirtualSerial_CDC_Interface);
|
||||
USB_USBTask();
|
||||
|
@ -144,6 +96,23 @@ void SetupHardware(void)
|
|||
Serial_CreateStream(NULL);
|
||||
}
|
||||
|
||||
/** Task to manage an enumerated USB CDC device once connected, to print received data
|
||||
* from the device to the serial port.
|
||||
*/
|
||||
void CDCHost_Task(void)
|
||||
{
|
||||
if (USB_HostState != HOST_STATE_Configured)
|
||||
return;
|
||||
|
||||
if (CDC_Host_BytesReceived(&VirtualSerial_CDC_Interface))
|
||||
{
|
||||
/* Echo received bytes from the attached device through the USART */
|
||||
int16_t ReceivedByte = CDC_Host_ReceiveByte(&VirtualSerial_CDC_Interface);
|
||||
if (!(ReceivedByte < 0))
|
||||
putchar(ReceivedByte);
|
||||
}
|
||||
}
|
||||
|
||||
/** Event handler for the USB_DeviceAttached event. This indicates that a device has been attached to the host, and
|
||||
* starts the library USB task to begin the enumeration and USB management process.
|
||||
*/
|
||||
|
@ -167,6 +136,35 @@ void EVENT_USB_Host_DeviceUnattached(void)
|
|||
*/
|
||||
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 (CDC_Host_ConfigurePipes(&VirtualSerial_CDC_Interface,
|
||||
ConfigDescriptorSize, ConfigDescriptorData) != CDC_ENUMERROR_NoError)
|
||||
{
|
||||
puts_P(PSTR("Attached Device Not a Valid CDC Class 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;
|
||||
}
|
||||
|
||||
puts_P(PSTR("CDC Device Enumerated.\r\n"));
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_READY);
|
||||
}
|
||||
|
||||
|
|
|
@ -65,6 +65,7 @@
|
|||
|
||||
/* Function Prototypes: */
|
||||
void SetupHardware(void);
|
||||
void CDCHost_Task(void);
|
||||
|
||||
void EVENT_USB_Host_HostError(const uint8_t ErrorCode);
|
||||
void EVENT_USB_Host_DeviceAttached(void);
|
||||
|
|
|
@ -50,7 +50,7 @@ int main(void)
|
|||
|
||||
for (;;)
|
||||
{
|
||||
Android_Host_Task();
|
||||
AndroidHost_Task();
|
||||
USB_USBTask();
|
||||
}
|
||||
}
|
||||
|
@ -74,6 +74,53 @@ void SetupHardware(void)
|
|||
Serial_CreateStream(NULL);
|
||||
}
|
||||
|
||||
/** Task to set the configuration of the attached device after it has been enumerated. */
|
||||
void AndroidHost_Task(void)
|
||||
{
|
||||
if (USB_HostState != HOST_STATE_Configured)
|
||||
return;
|
||||
|
||||
/* Select the data IN pipe */
|
||||
Pipe_SelectPipe(ANDROID_DATA_IN_PIPE);
|
||||
Pipe_Unfreeze();
|
||||
|
||||
/* Check to see if a packet has been received */
|
||||
if (Pipe_IsINReceived())
|
||||
{
|
||||
/* Re-freeze IN pipe after the packet has been received */
|
||||
Pipe_Freeze();
|
||||
|
||||
/* Check if data is in the pipe */
|
||||
if (Pipe_IsReadWriteAllowed())
|
||||
{
|
||||
uint8_t NextReceivedByte = Pipe_BytesInPipe();
|
||||
uint8_t LEDMask = LEDS_NO_LEDS;
|
||||
|
||||
if (NextReceivedByte & 0x01)
|
||||
LEDMask |= LEDS_LED1;
|
||||
|
||||
if (NextReceivedByte & 0x02)
|
||||
LEDMask |= LEDS_LED2;
|
||||
|
||||
if (NextReceivedByte & 0x04)
|
||||
LEDMask |= LEDS_LED3;
|
||||
|
||||
if (NextReceivedByte & 0x08)
|
||||
LEDMask |= LEDS_LED4;
|
||||
|
||||
LEDs_SetAllLEDs(LEDMask);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Clear the pipe after all data in the packet has been read, ready for the next packet */
|
||||
Pipe_ClearIN();
|
||||
}
|
||||
}
|
||||
|
||||
/* Re-freeze IN pipe after use */
|
||||
Pipe_Freeze();
|
||||
}
|
||||
|
||||
/** Event handler for the USB_DeviceAttached event. This indicates that a device has been attached to the host, and
|
||||
* starts the library USB task to begin the enumeration and USB management process.
|
||||
*/
|
||||
|
@ -97,6 +144,92 @@ void EVENT_USB_Host_DeviceUnattached(void)
|
|||
*/
|
||||
void EVENT_USB_Host_DeviceEnumerationComplete(void)
|
||||
{
|
||||
puts_P(PSTR("Getting Device Data.\r\n"));
|
||||
|
||||
/* Get and process the configuration descriptor data */
|
||||
uint8_t ErrorCode = ProcessDeviceDescriptor();
|
||||
|
||||
bool RequiresModeSwitch = (ErrorCode == NonAccessoryModeAndroidDevice);
|
||||
|
||||
/* Error out if the device is not an Android device or an error occurred */
|
||||
if ((ErrorCode != AccessoryModeAndroidDevice) && !(RequiresModeSwitch))
|
||||
{
|
||||
if (ErrorCode == DevControlError)
|
||||
puts_P(PSTR(ESC_FG_RED "Control Error (Get Device).\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;
|
||||
}
|
||||
|
||||
printf_P(PSTR("Android Device Detected - %sAccessory mode.\r\n"), (RequiresModeSwitch ? "Non-" : ""));
|
||||
|
||||
/* Check if a valid Android device was attached, but it is not current in Accessory mode */
|
||||
if (RequiresModeSwitch)
|
||||
{
|
||||
uint16_t AndroidProtocol;
|
||||
|
||||
/* Fetch the version of the Android Accessory Protocol supported by the device */
|
||||
if ((ErrorCode = Android_GetAccessoryProtocol(&AndroidProtocol)) != HOST_SENDCONTROL_Successful)
|
||||
{
|
||||
printf_P(PSTR(ESC_FG_RED "Control Error (Get Protocol).\r\n"
|
||||
" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
|
||||
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Validate the returned protocol version */
|
||||
if (AndroidProtocol != ANDROID_PROTOCOL_Accessory)
|
||||
{
|
||||
puts_P(PSTR(ESC_FG_RED "Accessory Mode Not Supported."));
|
||||
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Send the device strings and start the Android Accessory Mode */
|
||||
Android_SendString(ANDROID_STRING_Manufacturer, "Dean Camera");
|
||||
Android_SendString(ANDROID_STRING_Model, "LUFA Android Demo");
|
||||
Android_SendString(ANDROID_STRING_Description, "LUFA Android Demo");
|
||||
Android_SendString(ANDROID_STRING_Version, "1.0");
|
||||
Android_SendString(ANDROID_STRING_URI, "http://www.lufa-lib.org");
|
||||
Android_SendString(ANDROID_STRING_Serial, "0000000012345678");
|
||||
|
||||
Android_StartAccessoryMode();
|
||||
return;
|
||||
}
|
||||
|
||||
puts_P(PSTR("Getting Config Data.\r\n"));
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
puts_P(PSTR("Accessory Mode Android Enumerated.\r\n"));
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_READY);
|
||||
}
|
||||
|
||||
|
@ -126,166 +259,3 @@ void EVENT_USB_Host_DeviceEnumerationFailed(const uint8_t ErrorCode,
|
|||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
}
|
||||
|
||||
/** Task to set the configuration of the attached device after it has been enumerated. */
|
||||
void Android_Host_Task(void)
|
||||
{
|
||||
uint8_t ErrorCode;
|
||||
|
||||
switch (USB_HostState)
|
||||
{
|
||||
case HOST_STATE_Addressed:
|
||||
puts_P(PSTR("Getting Device Data.\r\n"));
|
||||
|
||||
/* Get and process the configuration descriptor data */
|
||||
ErrorCode = ProcessDeviceDescriptor();
|
||||
|
||||
bool RequiresModeSwitch = (ErrorCode == NonAccessoryModeAndroidDevice);
|
||||
|
||||
/* Error out if the device is not an Android device or an error occurred */
|
||||
if ((ErrorCode != AccessoryModeAndroidDevice) && !(RequiresModeSwitch))
|
||||
{
|
||||
if (ErrorCode == DevControlError)
|
||||
puts_P(PSTR(ESC_FG_RED "Control Error (Get Device).\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);
|
||||
|
||||
/* Indicate error via status LEDs */
|
||||
LEDs_SetAllLEDs(LEDS_LED1);
|
||||
|
||||
/* Wait until USB device disconnected */
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
printf_P(PSTR("Android Device Detected - %sAccessory mode.\r\n"), (RequiresModeSwitch ? "Non-" : ""));
|
||||
|
||||
/* 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);
|
||||
|
||||
/* Indicate error via status LEDs */
|
||||
LEDs_SetAllLEDs(LEDS_LED1);
|
||||
|
||||
/* Wait until USB device disconnected */
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Check if a valid Android device was attached, but it is not current in Accessory mode */
|
||||
if (RequiresModeSwitch)
|
||||
{
|
||||
uint16_t AndroidProtocol;
|
||||
|
||||
/* Fetch the version of the Android Accessory Protocol supported by the device */
|
||||
if ((ErrorCode = Android_GetAccessoryProtocol(&AndroidProtocol)) != HOST_SENDCONTROL_Successful)
|
||||
{
|
||||
printf_P(PSTR(ESC_FG_RED "Control Error (Get Protocol).\r\n"
|
||||
" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
|
||||
|
||||
/* Indicate error via status LEDs */
|
||||
LEDs_SetAllLEDs(LEDS_LED1);
|
||||
|
||||
/* Wait until USB device disconnected */
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Validate the returned protocol version */
|
||||
if (AndroidProtocol != ANDROID_PROTOCOL_Accessory)
|
||||
{
|
||||
puts_P(PSTR(ESC_FG_RED "Accessory Mode Not Supported."));
|
||||
|
||||
/* Indicate error via status LEDs */
|
||||
LEDs_SetAllLEDs(LEDS_LED1);
|
||||
|
||||
/* Wait until USB device disconnected */
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Send the device strings and start the Android Accessory Mode */
|
||||
Android_SendString(ANDROID_STRING_Manufacturer, "Dean Camera");
|
||||
Android_SendString(ANDROID_STRING_Model, "LUFA Android Demo");
|
||||
Android_SendString(ANDROID_STRING_Description, "LUFA Android Demo");
|
||||
Android_SendString(ANDROID_STRING_Version, "1.0");
|
||||
Android_SendString(ANDROID_STRING_URI, "http://www.lufa-lib.org");
|
||||
Android_SendString(ANDROID_STRING_Serial, "0000000012345678");
|
||||
Android_StartAccessoryMode();
|
||||
|
||||
/* Wait until USB device disconnected */
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
puts_P(PSTR("Getting Config Data.\r\n"));
|
||||
|
||||
/* 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);
|
||||
|
||||
/* Indicate error via status LEDs */
|
||||
LEDs_SetAllLEDs(LEDS_LED1);
|
||||
|
||||
/* Wait until USB device disconnected */
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
puts_P(PSTR("Accessory Mode Android Enumerated.\r\n"));
|
||||
|
||||
USB_HostState = HOST_STATE_Configured;
|
||||
break;
|
||||
case HOST_STATE_Configured:
|
||||
/* Select the data IN pipe */
|
||||
Pipe_SelectPipe(ANDROID_DATA_IN_PIPE);
|
||||
Pipe_Unfreeze();
|
||||
|
||||
/* Check to see if a packet has been received */
|
||||
if (Pipe_IsINReceived())
|
||||
{
|
||||
/* Re-freeze IN pipe after the packet has been received */
|
||||
Pipe_Freeze();
|
||||
|
||||
/* Check if data is in the pipe */
|
||||
if (Pipe_IsReadWriteAllowed())
|
||||
{
|
||||
uint8_t NextReceivedByte = Pipe_BytesInPipe();
|
||||
uint8_t LEDMask = LEDS_NO_LEDS;
|
||||
|
||||
if (NextReceivedByte & 0x01)
|
||||
LEDMask |= LEDS_LED1;
|
||||
|
||||
if (NextReceivedByte & 0x02)
|
||||
LEDMask |= LEDS_LED2;
|
||||
|
||||
if (NextReceivedByte & 0x04)
|
||||
LEDMask |= LEDS_LED3;
|
||||
|
||||
if (NextReceivedByte & 0x08)
|
||||
LEDMask |= LEDS_LED4;
|
||||
|
||||
LEDs_SetAllLEDs(LEDMask);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Clear the pipe after all data in the packet has been read, ready for the next packet */
|
||||
Pipe_ClearIN();
|
||||
}
|
||||
}
|
||||
|
||||
/* Re-freeze IN pipe after use */
|
||||
Pipe_Freeze();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -70,6 +70,10 @@
|
|||
/** LED mask for the library LED driver, to indicate that the USB interface is busy. */
|
||||
#define LEDMASK_USB_BUSY LEDS_LED2
|
||||
|
||||
/* Function Prototypes: */
|
||||
void SetupHardware(void);
|
||||
void AndroidHost_Task(void);
|
||||
|
||||
/* Event Handlers: */
|
||||
void EVENT_USB_Host_DeviceAttached(void);
|
||||
void EVENT_USB_Host_DeviceUnattached(void);
|
||||
|
@ -78,9 +82,5 @@
|
|||
void EVENT_USB_Host_DeviceEnumerationFailed(const uint8_t ErrorCode,
|
||||
const uint8_t SubErrorCode);
|
||||
|
||||
/* Function Prototypes: */
|
||||
void Android_Host_Task(void);
|
||||
void SetupHardware(void);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -60,7 +60,6 @@ int main(void)
|
|||
{
|
||||
RFCOMM_ServiceChannels(SerialChannel_ACL);
|
||||
|
||||
Bluetooth_Host_Task();
|
||||
Bluetooth_Stack_USBTask();
|
||||
USB_USBTask();
|
||||
}
|
||||
|
@ -108,6 +107,55 @@ void EVENT_USB_Host_DeviceUnattached(void)
|
|||
*/
|
||||
void EVENT_USB_Host_DeviceEnumerationComplete(void)
|
||||
{
|
||||
puts_P(PSTR("Getting Device Data.\r\n"));
|
||||
|
||||
uint8_t ErrorCode;
|
||||
|
||||
/* Get and process the configuration descriptor data */
|
||||
if ((ErrorCode = ProcessDeviceDescriptor()) != SuccessfulDeviceRead)
|
||||
{
|
||||
if (ErrorCode == DevControlError)
|
||||
puts_P(PSTR(ESC_FG_RED "Control Error (Get Device).\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;
|
||||
}
|
||||
|
||||
puts_P(PSTR("Getting Config Data.\r\n"));
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
puts_P(PSTR("Bluetooth Dongle Enumerated.\r\n"));
|
||||
|
||||
/* Initialize the Bluetooth stack */
|
||||
Bluetooth_Stack_Init();
|
||||
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_READY);
|
||||
}
|
||||
|
||||
|
@ -137,77 +185,3 @@ void EVENT_USB_Host_DeviceEnumerationFailed(const uint8_t ErrorCode,
|
|||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
}
|
||||
|
||||
/** Task to set the configuration of the attached device after it has been enumerated. */
|
||||
void Bluetooth_Host_Task(void)
|
||||
{
|
||||
uint8_t ErrorCode;
|
||||
|
||||
switch (USB_HostState)
|
||||
{
|
||||
case HOST_STATE_Addressed:
|
||||
puts_P(PSTR("Getting Device Data.\r\n"));
|
||||
|
||||
/* Get and process the configuration descriptor data */
|
||||
if ((ErrorCode = ProcessDeviceDescriptor()) != SuccessfulDeviceRead)
|
||||
{
|
||||
if (ErrorCode == DevControlError)
|
||||
puts_P(PSTR(ESC_FG_RED "Control Error (Get Device).\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);
|
||||
|
||||
/* Indicate error via status LEDs */
|
||||
LEDs_SetAllLEDs(LEDS_LED1);
|
||||
|
||||
/* Wait until USB device disconnected */
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
puts_P(PSTR("Bluetooth Dongle Detected.\r\n"));
|
||||
|
||||
/* 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);
|
||||
|
||||
/* Indicate error via status LEDs */
|
||||
LEDs_SetAllLEDs(LEDS_LED1);
|
||||
|
||||
/* Wait until USB device disconnected */
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
puts_P(PSTR("Getting Config Data.\r\n"));
|
||||
|
||||
/* 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);
|
||||
|
||||
/* Indicate error via status LEDs */
|
||||
LEDs_SetAllLEDs(LEDS_LED1);
|
||||
|
||||
/* Wait until USB device disconnected */
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
puts_P(PSTR("Bluetooth Dongle Enumerated.\r\n"));
|
||||
|
||||
/* Initialize the Bluetooth stack */
|
||||
Bluetooth_Stack_Init();
|
||||
|
||||
USB_HostState = HOST_STATE_Configured;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -80,7 +80,6 @@
|
|||
const uint8_t SubErrorCode);
|
||||
|
||||
/* Function Prototypes: */
|
||||
void Bluetooth_Host_Task(void);
|
||||
void SetupHardware(void);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -50,7 +50,6 @@ int main(void)
|
|||
|
||||
for (;;)
|
||||
{
|
||||
Audio_Task();
|
||||
USB_USBTask();
|
||||
}
|
||||
}
|
||||
|
@ -97,6 +96,81 @@ void EVENT_USB_Host_DeviceUnattached(void)
|
|||
*/
|
||||
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
|
||||
|
||||
/* Set speaker as output */
|
||||
DDRC |= (1 << 6);
|
||||
|
||||
/* PWM speaker timer initialization */
|
||||
TCCR3A = ((1 << WGM30) | (1 << COM3A1) | (1 << COM3A0)); // Set on match, clear on TOP
|
||||
TCCR3B = ((1 << WGM32) | (1 << CS30)); // Fast 8-Bit PWM, F_CPU speed
|
||||
|
||||
puts_P(PSTR("Microphone Enumerated.\r\n"));
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_READY);
|
||||
}
|
||||
|
||||
|
@ -126,109 +200,6 @@ void EVENT_USB_Host_DeviceEnumerationFailed(const uint8_t ErrorCode,
|
|||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
}
|
||||
|
||||
void Audio_Task(void)
|
||||
{
|
||||
uint8_t ErrorCode;
|
||||
|
||||
switch (USB_HostState)
|
||||
{
|
||||
case HOST_STATE_Addressed:
|
||||
puts_P(PSTR("Getting Config Data.\r\n"));
|
||||
|
||||
/* 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);
|
||||
|
||||
/* Indicate error status */
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
|
||||
/* Wait until USB device disconnected */
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
/* 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);
|
||||
|
||||
/* Indicate error status */
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
|
||||
/* Wait until USB device disconnected */
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
/* Indicate error status */
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
|
||||
/* Wait until USB device disconnected */
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
/* Indicate error status */
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
|
||||
/* Wait until USB device disconnected */
|
||||
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
|
||||
|
||||
/* Set speaker as output */
|
||||
DDRC |= (1 << 6);
|
||||
|
||||
/* PWM speaker timer initialization */
|
||||
TCCR3A = ((1 << WGM30) | (1 << COM3A1) | (1 << COM3A0)); // Set on match, clear on TOP
|
||||
TCCR3B = ((1 << WGM32) | (1 << CS30)); // Fast 8-Bit PWM, F_CPU speed
|
||||
|
||||
puts_P(PSTR("Microphone Enumerated.\r\n"));
|
||||
|
||||
USB_HostState = HOST_STATE_Configured;
|
||||
break;
|
||||
case HOST_STATE_Configured:
|
||||
/* Do nothing - audio stream is handled by the timer interrupt routine */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/** ISR to handle the reloading of the PWM timer with the next sample. */
|
||||
ISR(TIMER0_COMPA_vect, ISR_BLOCK)
|
||||
{
|
||||
|
|
|
@ -66,7 +66,6 @@
|
|||
#define LEDMASK_USB_ERROR (LEDS_LED1 | LEDS_LED3)
|
||||
|
||||
/* Function Prototypes: */
|
||||
void Audio_Task(void);
|
||||
void SetupHardware(void);
|
||||
|
||||
void EVENT_USB_Host_HostError(const uint8_t ErrorCode);
|
||||
|
|
|
@ -50,7 +50,6 @@ int main(void)
|
|||
|
||||
for (;;)
|
||||
{
|
||||
Audio_Task();
|
||||
USB_USBTask();
|
||||
}
|
||||
}
|
||||
|
@ -100,6 +99,73 @@ void EVENT_USB_Host_DeviceUnattached(void)
|
|||
*/
|
||||
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);
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -129,102 +195,6 @@ void EVENT_USB_Host_DeviceEnumerationFailed(const uint8_t ErrorCode,
|
|||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
}
|
||||
|
||||
void Audio_Task(void)
|
||||
{
|
||||
uint8_t ErrorCode;
|
||||
|
||||
switch (USB_HostState)
|
||||
{
|
||||
case HOST_STATE_Addressed:
|
||||
puts_P(PSTR("Getting Config Data.\r\n"));
|
||||
|
||||
/* 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);
|
||||
|
||||
/* Indicate error status */
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
|
||||
/* Wait until USB device disconnected */
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
/* 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);
|
||||
|
||||
/* Indicate error status */
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
|
||||
/* Wait until USB device disconnected */
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
/* Indicate error status */
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
|
||||
/* Wait until USB device disconnected */
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
/* Indicate error status */
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
|
||||
/* Wait until USB device disconnected */
|
||||
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("Speaker Enumerated.\r\n"));
|
||||
|
||||
USB_HostState = HOST_STATE_Configured;
|
||||
break;
|
||||
case HOST_STATE_Configured:
|
||||
/* Do nothing - audio stream is handled by the timer interrupt routine */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/** ISR to handle the reloading of the endpoint with the next sample. */
|
||||
ISR(TIMER0_COMPA_vect, ISR_BLOCK)
|
||||
{
|
||||
|
|
|
@ -80,7 +80,6 @@
|
|||
#define LEDMASK_USB_ERROR (LEDS_LED1 | LEDS_LED3)
|
||||
|
||||
/* Function Prototypes: */
|
||||
void Audio_Task(void);
|
||||
void SetupHardware(void);
|
||||
|
||||
void EVENT_USB_Host_HostError(const uint8_t ErrorCode);
|
||||
|
|
|
@ -50,7 +50,8 @@ int main(void)
|
|||
|
||||
for (;;)
|
||||
{
|
||||
HID_Host_Task();
|
||||
ReadNextReport();
|
||||
|
||||
USB_USBTask();
|
||||
}
|
||||
}
|
||||
|
@ -97,6 +98,35 @@ void EVENT_USB_Host_DeviceUnattached(void)
|
|||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
puts_P(PSTR("HID Device Enumerated.\r\n"));
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_READY);
|
||||
}
|
||||
|
||||
|
@ -131,6 +161,9 @@ void EVENT_USB_Host_DeviceEnumerationFailed(const uint8_t ErrorCode,
|
|||
*/
|
||||
void ReadNextReport(void)
|
||||
{
|
||||
if (USB_HostState != HOST_STATE_Configured)
|
||||
return;
|
||||
|
||||
/* Select and unfreeze HID data IN pipe */
|
||||
Pipe_SelectPipe(HID_DATA_IN_PIPE);
|
||||
Pipe_Unfreeze();
|
||||
|
@ -178,6 +211,9 @@ void WriteNextReport(uint8_t* ReportOUTData,
|
|||
const uint8_t ReportType,
|
||||
uint16_t ReportLength)
|
||||
{
|
||||
if (USB_HostState != HOST_STATE_Configured)
|
||||
return;
|
||||
|
||||
/* Select the HID data OUT pipe */
|
||||
Pipe_SelectPipe(HID_DATA_OUT_PIPE);
|
||||
|
||||
|
@ -229,59 +265,3 @@ void WriteNextReport(uint8_t* ReportOUTData,
|
|||
}
|
||||
}
|
||||
|
||||
/** Task to set the configuration of the attached device after it has been enumerated, and to read and process
|
||||
* HID reports from the device and to send reports if desired.
|
||||
*/
|
||||
void HID_Host_Task(void)
|
||||
{
|
||||
uint8_t ErrorCode;
|
||||
|
||||
/* Switch to determine what user-application handled host state the host state machine is in */
|
||||
switch (USB_HostState)
|
||||
{
|
||||
case HOST_STATE_Addressed:
|
||||
puts_P(PSTR("Getting Config Data.\r\n"));
|
||||
|
||||
/* 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);
|
||||
|
||||
/* Indicate error status */
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
|
||||
/* Wait until USB device disconnected */
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
/* 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);
|
||||
|
||||
/* Indicate error status */
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
|
||||
/* Wait until USB device disconnected */
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
puts_P(PSTR("HID Device Enumerated.\r\n"));
|
||||
|
||||
USB_HostState = HOST_STATE_Configured;
|
||||
break;
|
||||
case HOST_STATE_Configured:
|
||||
ReadNextReport();
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -76,8 +76,12 @@
|
|||
|
||||
/* Function Prototypes: */
|
||||
void SetupHardware(void);
|
||||
void HID_Host_Task(void);
|
||||
|
||||
void ReadNextReport(void);
|
||||
void WriteNextReport(uint8_t* ReportOUTData,
|
||||
const uint8_t ReportIndex,
|
||||
const uint8_t ReportType,
|
||||
uint16_t ReportLength);
|
||||
|
||||
void EVENT_USB_Host_HostError(const uint8_t ErrorCode);
|
||||
void EVENT_USB_Host_DeviceAttached(void);
|
||||
void EVENT_USB_Host_DeviceUnattached(void);
|
||||
|
@ -85,11 +89,5 @@
|
|||
const uint8_t SubErrorCode);
|
||||
void EVENT_USB_Host_DeviceEnumerationComplete(void);
|
||||
|
||||
void ReadNextReport(void);
|
||||
void WriteNextReport(uint8_t* ReportOUTData,
|
||||
const uint8_t ReportIndex,
|
||||
const uint8_t ReportType,
|
||||
uint16_t ReportLength);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -50,7 +50,8 @@ int main(void)
|
|||
|
||||
for (;;)
|
||||
{
|
||||
Joystick_HID_Task();
|
||||
JoystickHost_Task();
|
||||
|
||||
USB_USBTask();
|
||||
}
|
||||
}
|
||||
|
@ -97,6 +98,52 @@ void EVENT_USB_Host_DeviceUnattached(void)
|
|||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
printf_P(PSTR("Processing HID Report (Size %d Bytes).\r\n"), HIDReportSize);
|
||||
|
||||
/* Get and process the device's first HID report descriptor */
|
||||
if ((ErrorCode = GetHIDReportData()) != ParseSuccessful)
|
||||
{
|
||||
puts_P(PSTR(ESC_FG_RED "Report Parse Error.\r\n"));
|
||||
|
||||
if (!(HIDReportInfo.TotalReportItems))
|
||||
puts_P(PSTR("Not a valid Joystick." ESC_FG_WHITE));
|
||||
else
|
||||
printf_P(PSTR(" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
|
||||
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
USB_Host_SetDeviceConfiguration(0);
|
||||
return;
|
||||
}
|
||||
|
||||
puts_P(PSTR("Joystick Enumerated.\r\n"));
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_READY);
|
||||
}
|
||||
|
||||
|
@ -125,104 +172,40 @@ void EVENT_USB_Host_DeviceEnumerationFailed(const uint8_t ErrorCode, const uint8
|
|||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
}
|
||||
|
||||
/** Task to set the configuration of the attached device after it has been enumerated, and to read and process
|
||||
* the HID report descriptor and HID reports from the device and display the results onto the board LEDs.
|
||||
/** Task to read and process the HID report descriptor and HID reports from the device
|
||||
* and display the results onto the board LEDs.
|
||||
*/
|
||||
void Joystick_HID_Task(void)
|
||||
void JoystickHost_Task(void)
|
||||
{
|
||||
uint8_t ErrorCode;
|
||||
if (USB_HostState != HOST_STATE_Configured)
|
||||
return;
|
||||
|
||||
/* Select and unfreeze joystick data pipe */
|
||||
Pipe_SelectPipe(JOYSTICK_DATA_IN_PIPE);
|
||||
Pipe_Unfreeze();
|
||||
|
||||
/* Switch to determine what user-application handled host state the host state machine is in */
|
||||
switch (USB_HostState)
|
||||
/* Check to see if a packet has been received */
|
||||
if (Pipe_IsINReceived())
|
||||
{
|
||||
case HOST_STATE_Addressed:
|
||||
puts_P(PSTR("Getting Config Data.\r\n"));
|
||||
/* Check if data has been received from the attached joystick */
|
||||
if (Pipe_IsReadWriteAllowed())
|
||||
{
|
||||
/* Create buffer big enough for the report */
|
||||
uint8_t JoystickReport[Pipe_BytesInPipe()];
|
||||
|
||||
/* 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"));
|
||||
/* Load in the joystick report */
|
||||
Pipe_Read_Stream_LE(JoystickReport, Pipe_BytesInPipe(), NULL);
|
||||
|
||||
printf_P(PSTR(" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
|
||||
/* Process the read in joystick report from the device */
|
||||
ProcessJoystickReport(JoystickReport);
|
||||
}
|
||||
|
||||
/* Indicate error via status LEDs */
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
|
||||
/* Wait until USB device disconnected */
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
/* 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);
|
||||
|
||||
/* Indicate error via status LEDs */
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
|
||||
/* Wait until USB device disconnected */
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
printf_P(PSTR("Processing HID Report (Size %d Bytes).\r\n"), HIDReportSize);
|
||||
|
||||
/* Get and process the device's first HID report descriptor */
|
||||
if ((ErrorCode = GetHIDReportData()) != ParseSuccessful)
|
||||
{
|
||||
puts_P(PSTR(ESC_FG_RED "Report Parse Error.\r\n"));
|
||||
|
||||
if (!(HIDReportInfo.TotalReportItems))
|
||||
puts_P(PSTR("Not a valid Joystick." ESC_FG_WHITE));
|
||||
else
|
||||
printf_P(PSTR(" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
|
||||
|
||||
/* Indicate error via status LEDs */
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
|
||||
/* Wait until USB device disconnected */
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
puts_P(PSTR("Joystick Enumerated.\r\n"));
|
||||
|
||||
USB_HostState = HOST_STATE_Configured;
|
||||
break;
|
||||
case HOST_STATE_Configured:
|
||||
/* Select and unfreeze joystick data pipe */
|
||||
Pipe_SelectPipe(JOYSTICK_DATA_IN_PIPE);
|
||||
Pipe_Unfreeze();
|
||||
|
||||
/* Check to see if a packet has been received */
|
||||
if (Pipe_IsINReceived())
|
||||
{
|
||||
/* Check if data has been received from the attached joystick */
|
||||
if (Pipe_IsReadWriteAllowed())
|
||||
{
|
||||
/* Create buffer big enough for the report */
|
||||
uint8_t JoystickReport[Pipe_BytesInPipe()];
|
||||
|
||||
/* Load in the joystick report */
|
||||
Pipe_Read_Stream_LE(JoystickReport, Pipe_BytesInPipe(), NULL);
|
||||
|
||||
/* Process the read in joystick report from the device */
|
||||
ProcessJoystickReport(JoystickReport);
|
||||
}
|
||||
|
||||
/* Clear the IN endpoint, ready for next data packet */
|
||||
Pipe_ClearIN();
|
||||
}
|
||||
|
||||
/* Freeze joystick data pipe */
|
||||
Pipe_Freeze();
|
||||
break;
|
||||
/* Clear the IN endpoint, ready for next data packet */
|
||||
Pipe_ClearIN();
|
||||
}
|
||||
|
||||
/* Freeze joystick data pipe */
|
||||
Pipe_Freeze();
|
||||
}
|
||||
|
||||
/** Processes a read HID report from an attached joystick, extracting out elements via the HID parser results
|
||||
|
|
|
@ -67,8 +67,8 @@
|
|||
#define LEDMASK_USB_ERROR (LEDS_LED1 | LEDS_LED3)
|
||||
|
||||
/* Function Prototypes: */
|
||||
void Joystick_HID_Task(void);
|
||||
void SetupHardware(void);
|
||||
void JoystickHost_Task(void);
|
||||
|
||||
void EVENT_USB_Host_HostError(const uint8_t ErrorCode);
|
||||
void EVENT_USB_Host_DeviceAttached(void);
|
||||
|
|
|
@ -50,7 +50,8 @@ int main(void)
|
|||
|
||||
for (;;)
|
||||
{
|
||||
Keyboard_HID_Task();
|
||||
KeyboardHost_Task();
|
||||
|
||||
USB_USBTask();
|
||||
}
|
||||
}
|
||||
|
@ -97,6 +98,59 @@ void EVENT_USB_Host_DeviceUnattached(void)
|
|||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
/* HID class request to set the keyboard protocol to the Boot Protocol */
|
||||
USB_ControlRequest = (USB_Request_Header_t)
|
||||
{
|
||||
.bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE),
|
||||
.bRequest = HID_REQ_SetProtocol,
|
||||
.wValue = 0,
|
||||
.wIndex = 0,
|
||||
.wLength = 0,
|
||||
};
|
||||
|
||||
/* Select the control pipe for the request transfer */
|
||||
Pipe_SelectPipe(PIPE_CONTROLPIPE);
|
||||
|
||||
/* Send the request, display error and wait for device detach if request fails */
|
||||
if ((ErrorCode = USB_Host_SendControlRequest(NULL)) != HOST_SENDCONTROL_Successful)
|
||||
{
|
||||
printf_P(PSTR(ESC_FG_RED "Control Error (Set Protocol).\r\n"
|
||||
" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
|
||||
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
USB_Host_SetDeviceConfiguration(0);
|
||||
return;
|
||||
}
|
||||
|
||||
puts_P(PSTR("Keyboard Enumerated.\r\n"));
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_READY);
|
||||
}
|
||||
|
||||
|
@ -126,12 +180,13 @@ void EVENT_USB_Host_DeviceEnumerationFailed(const uint8_t ErrorCode,
|
|||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
}
|
||||
|
||||
/** Reads in and processes the next report from the attached device, displaying the report
|
||||
/** Task to read in and processes the next report from the attached device, displaying the report
|
||||
* contents on the board LEDs and via the serial port.
|
||||
*/
|
||||
void ReadNextReport(void)
|
||||
void KeyboardHost_Task(void)
|
||||
{
|
||||
USB_KeyboardReport_Data_t KeyboardReport;
|
||||
if (USB_HostState != HOST_STATE_Configured)
|
||||
return;
|
||||
|
||||
/* Select keyboard data pipe */
|
||||
Pipe_SelectPipe(KEYBOARD_DATA_IN_PIPE);
|
||||
|
@ -151,6 +206,8 @@ void ReadNextReport(void)
|
|||
/* Ensure pipe contains data before trying to read from it */
|
||||
if (Pipe_IsReadWriteAllowed())
|
||||
{
|
||||
USB_KeyboardReport_Data_t KeyboardReport;
|
||||
|
||||
/* Read in keyboard report data */
|
||||
Pipe_Read_Stream_LE(&KeyboardReport, sizeof(KeyboardReport), NULL);
|
||||
|
||||
|
@ -203,86 +260,3 @@ void ReadNextReport(void)
|
|||
Pipe_Freeze();
|
||||
}
|
||||
|
||||
/** Task to set the configuration of the attached device after it has been enumerated, and to read and process
|
||||
* HID reports from the device and display the results onto the board LEDs.
|
||||
*/
|
||||
void Keyboard_HID_Task(void)
|
||||
{
|
||||
uint8_t ErrorCode;
|
||||
|
||||
switch (USB_HostState)
|
||||
{
|
||||
case HOST_STATE_Addressed:
|
||||
puts_P(PSTR("Getting Config Data.\r\n"));
|
||||
|
||||
/* 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);
|
||||
|
||||
/* Indicate error status */
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
|
||||
/* Wait until USB device disconnected */
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
/* 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);
|
||||
|
||||
/* Indicate error status */
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
|
||||
/* Wait until USB device disconnected */
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
/* HID class request to set the keyboard protocol to the Boot Protocol */
|
||||
USB_ControlRequest = (USB_Request_Header_t)
|
||||
{
|
||||
.bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE),
|
||||
.bRequest = HID_REQ_SetProtocol,
|
||||
.wValue = 0,
|
||||
.wIndex = 0,
|
||||
.wLength = 0,
|
||||
};
|
||||
|
||||
/* Select the control pipe for the request transfer */
|
||||
Pipe_SelectPipe(PIPE_CONTROLPIPE);
|
||||
|
||||
/* Send the request, display error and wait for device detach if request fails */
|
||||
if ((ErrorCode = USB_Host_SendControlRequest(NULL)) != HOST_SENDCONTROL_Successful)
|
||||
{
|
||||
printf_P(PSTR(ESC_FG_RED "Control Error (Set Protocol).\r\n"
|
||||
" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
|
||||
|
||||
/* Indicate error status */
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
|
||||
/* Wait until USB device disconnected */
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
puts_P(PSTR("Keyboard Enumerated.\r\n"));
|
||||
|
||||
USB_HostState = HOST_STATE_Configured;
|
||||
break;
|
||||
case HOST_STATE_Configured:
|
||||
/* If a report has been received, read and process it */
|
||||
ReadNextReport();
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -66,8 +66,8 @@
|
|||
#define LEDMASK_USB_ERROR (LEDS_LED1 | LEDS_LED3)
|
||||
|
||||
/* Function Prototypes: */
|
||||
void Keyboard_HID_Task(void);
|
||||
void SetupHardware(void);
|
||||
void KeyboardHost_Task(void);
|
||||
|
||||
void EVENT_USB_Host_HostError(const uint8_t ErrorCode);
|
||||
void EVENT_USB_Host_DeviceAttached(void);
|
||||
|
@ -76,7 +76,5 @@
|
|||
const uint8_t SubErrorCode);
|
||||
void EVENT_USB_Host_DeviceEnumerationComplete(void);
|
||||
|
||||
void ReadNextReport(void);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -50,7 +50,8 @@ int main(void)
|
|||
|
||||
for (;;)
|
||||
{
|
||||
Keyboard_HID_Task();
|
||||
KeyboardHost_Task();
|
||||
|
||||
USB_USBTask();
|
||||
}
|
||||
}
|
||||
|
@ -97,6 +98,53 @@ void EVENT_USB_Host_DeviceUnattached(void)
|
|||
*/
|
||||
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)
|
||||
|
||||
{
|
||||
puts_P(PSTR(ESC_FG_RED "Control Error (Set Configuration).\r\n"));
|
||||
printf_P(PSTR(" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
|
||||
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
printf_P(PSTR("Processing HID Report (Size %d Bytes).\r\n"), HIDReportSize);
|
||||
|
||||
/* Get and process the device's first HID report descriptor */
|
||||
if ((ErrorCode = GetHIDReportData()) != ParseSuccessful)
|
||||
{
|
||||
puts_P(PSTR(ESC_FG_RED "Report Parse Error.\r\n"));
|
||||
|
||||
if (!(HIDReportInfo.TotalReportItems))
|
||||
puts_P(PSTR("Not a valid Keyboard." ESC_FG_WHITE));
|
||||
else
|
||||
printf_P(PSTR(" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
|
||||
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
USB_Host_SetDeviceConfiguration(0);
|
||||
return;
|
||||
}
|
||||
|
||||
puts_P(PSTR("Keyboard Enumerated.\r\n"));
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_READY);
|
||||
}
|
||||
|
||||
|
@ -126,104 +174,40 @@ void EVENT_USB_Host_DeviceEnumerationFailed(const uint8_t ErrorCode,
|
|||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
}
|
||||
|
||||
/** Task to set the configuration of the attached device after it has been enumerated, and to read and process
|
||||
* the HID report descriptor and HID reports from the device and display the results onto the board LEDs.
|
||||
/** Task to read in and processes the next report from the attached device, displaying the report
|
||||
* contents on the board LEDs and via the serial port.
|
||||
*/
|
||||
void Keyboard_HID_Task(void)
|
||||
void KeyboardHost_Task(void)
|
||||
{
|
||||
uint8_t ErrorCode;
|
||||
if (USB_HostState != HOST_STATE_Configured)
|
||||
return;
|
||||
|
||||
/* Select and unfreeze keyboard data pipe */
|
||||
Pipe_SelectPipe(KEYBOARD_DATA_IN_PIPE);
|
||||
Pipe_Unfreeze();
|
||||
|
||||
switch (USB_HostState)
|
||||
/* Check to see if a packet has been received */
|
||||
if (Pipe_IsINReceived())
|
||||
{
|
||||
case HOST_STATE_Addressed:
|
||||
puts_P(PSTR("Getting Config Data.\r\n"));
|
||||
/* Check if data has been received from the attached keyboard */
|
||||
if (Pipe_IsReadWriteAllowed())
|
||||
{
|
||||
/* Create buffer big enough for the report */
|
||||
uint8_t KeyboardReport[Pipe_BytesInPipe()];
|
||||
|
||||
/* 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"));
|
||||
/* Load in the keyboard report */
|
||||
Pipe_Read_Stream_LE(KeyboardReport, Pipe_BytesInPipe(), NULL);
|
||||
|
||||
printf_P(PSTR(" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
|
||||
/* Process the read in keyboard report from the device */
|
||||
ProcessKeyboardReport(KeyboardReport);
|
||||
}
|
||||
|
||||
/* Indicate error via status LEDs */
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
|
||||
/* Wait until USB device disconnected */
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Set the device configuration to the first configuration (rarely do devices use multiple configurations) */
|
||||
if ((ErrorCode = USB_Host_SetDeviceConfiguration(1)) != HOST_SENDCONTROL_Successful)
|
||||
|
||||
{
|
||||
puts_P(PSTR(ESC_FG_RED "Control Error (Set Configuration).\r\n"));
|
||||
printf_P(PSTR(" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
|
||||
|
||||
/* Indicate error via status LEDs */
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
|
||||
/* Wait until USB device disconnected */
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
printf_P(PSTR("Processing HID Report (Size %d Bytes).\r\n"), HIDReportSize);
|
||||
|
||||
/* Get and process the device's first HID report descriptor */
|
||||
if ((ErrorCode = GetHIDReportData()) != ParseSuccessful)
|
||||
{
|
||||
puts_P(PSTR(ESC_FG_RED "Report Parse Error.\r\n"));
|
||||
|
||||
if (!(HIDReportInfo.TotalReportItems))
|
||||
puts_P(PSTR("Not a valid Keyboard." ESC_FG_WHITE));
|
||||
else
|
||||
printf_P(PSTR(" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
|
||||
|
||||
/* Indicate error via status LEDs */
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
|
||||
/* Wait until USB device disconnected */
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
puts_P(PSTR("Keyboard Enumerated.\r\n"));
|
||||
|
||||
USB_HostState = HOST_STATE_Configured;
|
||||
break;
|
||||
case HOST_STATE_Configured:
|
||||
/* Select and unfreeze keyboard data pipe */
|
||||
Pipe_SelectPipe(KEYBOARD_DATA_IN_PIPE);
|
||||
Pipe_Unfreeze();
|
||||
|
||||
/* Check to see if a packet has been received */
|
||||
if (Pipe_IsINReceived())
|
||||
{
|
||||
/* Check if data has been received from the attached keyboard */
|
||||
if (Pipe_IsReadWriteAllowed())
|
||||
{
|
||||
/* Create buffer big enough for the report */
|
||||
uint8_t KeyboardReport[Pipe_BytesInPipe()];
|
||||
|
||||
/* Load in the keyboard report */
|
||||
Pipe_Read_Stream_LE(KeyboardReport, Pipe_BytesInPipe(), NULL);
|
||||
|
||||
/* Process the read in keyboard report from the device */
|
||||
ProcessKeyboardReport(KeyboardReport);
|
||||
}
|
||||
|
||||
/* Clear the IN endpoint, ready for next data packet */
|
||||
Pipe_ClearIN();
|
||||
}
|
||||
|
||||
/* Freeze keyboard data pipe */
|
||||
Pipe_Freeze();
|
||||
break;
|
||||
/* Clear the IN endpoint, ready for next data packet */
|
||||
Pipe_ClearIN();
|
||||
}
|
||||
|
||||
/* Freeze keyboard data pipe */
|
||||
Pipe_Freeze();
|
||||
}
|
||||
|
||||
/** Processes a read HID report from an attached keyboard, extracting out elements via the HID parser results
|
||||
|
|
|
@ -62,8 +62,8 @@
|
|||
#define LEDMASK_USB_ERROR (LEDS_LED1 | LEDS_LED3)
|
||||
|
||||
/* Function Prototypes: */
|
||||
void Keyboard_HID_Task(void);
|
||||
void SetupHardware(void);
|
||||
void KeyboardHost_Task(void);
|
||||
|
||||
void EVENT_USB_Host_HostError(const uint8_t ErrorCode);
|
||||
void EVENT_USB_Host_DeviceAttached(void);
|
||||
|
|
|
@ -50,7 +50,8 @@ int main(void)
|
|||
|
||||
for (;;)
|
||||
{
|
||||
MIDI_Host_Task();
|
||||
MIDIHost_Task();
|
||||
|
||||
USB_USBTask();
|
||||
}
|
||||
}
|
||||
|
@ -99,6 +100,35 @@ void EVENT_USB_Host_DeviceUnattached(void)
|
|||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
puts_P(PSTR("MIDI Device Enumerated.\r\n"));
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_READY);
|
||||
}
|
||||
|
||||
|
@ -128,147 +158,102 @@ void EVENT_USB_Host_DeviceEnumerationFailed(const uint8_t ErrorCode,
|
|||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
}
|
||||
|
||||
/** Task to set the configuration of the attached device after it has been enumerated, and to read in
|
||||
* note on/off messages from the attached MIDI device and print it to the serial port. When the board
|
||||
* joystick or buttons are pressed, note on/off messages are sent to the attached device.
|
||||
/** Task to read in note on/off messages from the attached MIDI device and print it to the serial port.
|
||||
* When the board joystick or buttons are pressed, note on/off messages are sent to the attached device.
|
||||
*/
|
||||
void MIDI_Host_Task(void)
|
||||
void MIDIHost_Task(void)
|
||||
{
|
||||
uint8_t ErrorCode;
|
||||
if (USB_HostState != HOST_STATE_Configured)
|
||||
return;
|
||||
|
||||
Pipe_SelectPipe(MIDI_DATA_IN_PIPE);
|
||||
|
||||
switch (USB_HostState)
|
||||
if (Pipe_IsINReceived())
|
||||
{
|
||||
case HOST_STATE_Addressed:
|
||||
puts_P(PSTR("Getting Config Data.\r\n"));
|
||||
MIDI_EventPacket_t MIDIEvent;
|
||||
|
||||
/* 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"));
|
||||
Pipe_Read_Stream_LE(&MIDIEvent, sizeof(MIDIEvent), NULL);
|
||||
|
||||
printf_P(PSTR(" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
|
||||
if (!(Pipe_BytesInPipe()))
|
||||
Pipe_ClearIN();
|
||||
|
||||
/* Indicate error via status LEDs */
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
bool NoteOnEvent = ((MIDIEvent.Command & 0x0F) == (MIDI_COMMAND_NOTE_ON >> 4));
|
||||
bool NoteOffEvent = ((MIDIEvent.Command & 0x0F) == (MIDI_COMMAND_NOTE_OFF >> 4));
|
||||
|
||||
/* Wait until USB device disconnected */
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
if (NoteOnEvent || NoteOffEvent)
|
||||
{
|
||||
printf_P(PSTR("MIDI Note %s - Channel %d, Pitch %d, Velocity %d\r\n"), NoteOnEvent ? "On" : "Off",
|
||||
((MIDIEvent.Data1 & 0x0F) + 1),
|
||||
MIDIEvent.Data2, MIDIEvent.Data3);
|
||||
}
|
||||
}
|
||||
|
||||
/* 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);
|
||||
Pipe_SelectPipe(MIDI_DATA_OUT_PIPE);
|
||||
|
||||
/* Indicate error via status LEDs */
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
if (Pipe_IsOUTReady())
|
||||
{
|
||||
uint8_t MIDICommand = 0;
|
||||
uint8_t MIDIPitch;
|
||||
|
||||
/* Wait until USB device disconnected */
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
static uint8_t PrevJoystickStatus;
|
||||
uint8_t JoystickStatus = Joystick_GetStatus();
|
||||
uint8_t JoystickChanges = (JoystickStatus ^ PrevJoystickStatus);
|
||||
|
||||
puts_P(PSTR("MIDI Device Enumerated.\r\n"));
|
||||
/* Get board button status - if pressed use channel 10 (percussion), otherwise use channel 1 */
|
||||
uint8_t Channel = ((Buttons_GetStatus() & BUTTONS_BUTTON1) ? MIDI_CHANNEL(10) : MIDI_CHANNEL(1));
|
||||
|
||||
USB_HostState = HOST_STATE_Configured;
|
||||
break;
|
||||
case HOST_STATE_Configured:
|
||||
Pipe_SelectPipe(MIDI_DATA_IN_PIPE);
|
||||
if (JoystickChanges & JOY_LEFT)
|
||||
{
|
||||
MIDICommand = ((JoystickStatus & JOY_LEFT)? MIDI_COMMAND_NOTE_ON : MIDI_COMMAND_NOTE_OFF);
|
||||
MIDIPitch = 0x3C;
|
||||
}
|
||||
|
||||
if (Pipe_IsINReceived())
|
||||
{
|
||||
MIDI_EventPacket_t MIDIEvent;
|
||||
if (JoystickChanges & JOY_UP)
|
||||
{
|
||||
MIDICommand = ((JoystickStatus & JOY_UP)? MIDI_COMMAND_NOTE_ON : MIDI_COMMAND_NOTE_OFF);
|
||||
MIDIPitch = 0x3D;
|
||||
}
|
||||
|
||||
Pipe_Read_Stream_LE(&MIDIEvent, sizeof(MIDIEvent), NULL);
|
||||
if (JoystickChanges & JOY_RIGHT)
|
||||
{
|
||||
MIDICommand = ((JoystickStatus & JOY_RIGHT)? MIDI_COMMAND_NOTE_ON : MIDI_COMMAND_NOTE_OFF);
|
||||
MIDIPitch = 0x3E;
|
||||
}
|
||||
|
||||
if (!(Pipe_BytesInPipe()))
|
||||
Pipe_ClearIN();
|
||||
if (JoystickChanges & JOY_DOWN)
|
||||
{
|
||||
MIDICommand = ((JoystickStatus & JOY_DOWN)? MIDI_COMMAND_NOTE_ON : MIDI_COMMAND_NOTE_OFF);
|
||||
MIDIPitch = 0x3F;
|
||||
}
|
||||
|
||||
bool NoteOnEvent = ((MIDIEvent.Command & 0x0F) == (MIDI_COMMAND_NOTE_ON >> 4));
|
||||
bool NoteOffEvent = ((MIDIEvent.Command & 0x0F) == (MIDI_COMMAND_NOTE_OFF >> 4));
|
||||
if (JoystickChanges & JOY_PRESS)
|
||||
{
|
||||
MIDICommand = ((JoystickStatus & JOY_PRESS)? MIDI_COMMAND_NOTE_ON : MIDI_COMMAND_NOTE_OFF);
|
||||
MIDIPitch = 0x3B;
|
||||
}
|
||||
|
||||
if (NoteOnEvent || NoteOffEvent)
|
||||
/* Check if a MIDI command is to be sent */
|
||||
if (MIDICommand)
|
||||
{
|
||||
MIDI_EventPacket_t MIDIEvent = (MIDI_EventPacket_t)
|
||||
{
|
||||
printf_P(PSTR("MIDI Note %s - Channel %d, Pitch %d, Velocity %d\r\n"), NoteOnEvent ? "On" : "Off",
|
||||
((MIDIEvent.Data1 & 0x0F) + 1),
|
||||
MIDIEvent.Data2, MIDIEvent.Data3);
|
||||
}
|
||||
}
|
||||
.CableNumber = 0,
|
||||
.Command = (MIDICommand >> 4),
|
||||
|
||||
Pipe_SelectPipe(MIDI_DATA_OUT_PIPE);
|
||||
.Data1 = MIDICommand | Channel,
|
||||
.Data2 = MIDIPitch,
|
||||
.Data3 = MIDI_STANDARD_VELOCITY,
|
||||
};
|
||||
|
||||
if (Pipe_IsOUTReady())
|
||||
{
|
||||
uint8_t MIDICommand = 0;
|
||||
uint8_t MIDIPitch;
|
||||
/* Write the MIDI event packet to the pipe */
|
||||
Pipe_Write_Stream_LE(&MIDIEvent, sizeof(MIDIEvent), NULL);
|
||||
|
||||
static uint8_t PrevJoystickStatus;
|
||||
uint8_t JoystickStatus = Joystick_GetStatus();
|
||||
uint8_t JoystickChanges = (JoystickStatus ^ PrevJoystickStatus);
|
||||
/* Send the data in the pipe to the device */
|
||||
Pipe_ClearOUT();
|
||||
}
|
||||
|
||||
/* Get board button status - if pressed use channel 10 (percussion), otherwise use channel 1 */
|
||||
uint8_t Channel = ((Buttons_GetStatus() & BUTTONS_BUTTON1) ? MIDI_CHANNEL(10) : MIDI_CHANNEL(1));
|
||||
|
||||
if (JoystickChanges & JOY_LEFT)
|
||||
{
|
||||
MIDICommand = ((JoystickStatus & JOY_LEFT)? MIDI_COMMAND_NOTE_ON : MIDI_COMMAND_NOTE_OFF);
|
||||
MIDIPitch = 0x3C;
|
||||
}
|
||||
|
||||
if (JoystickChanges & JOY_UP)
|
||||
{
|
||||
MIDICommand = ((JoystickStatus & JOY_UP)? MIDI_COMMAND_NOTE_ON : MIDI_COMMAND_NOTE_OFF);
|
||||
MIDIPitch = 0x3D;
|
||||
}
|
||||
|
||||
if (JoystickChanges & JOY_RIGHT)
|
||||
{
|
||||
MIDICommand = ((JoystickStatus & JOY_RIGHT)? MIDI_COMMAND_NOTE_ON : MIDI_COMMAND_NOTE_OFF);
|
||||
MIDIPitch = 0x3E;
|
||||
}
|
||||
|
||||
if (JoystickChanges & JOY_DOWN)
|
||||
{
|
||||
MIDICommand = ((JoystickStatus & JOY_DOWN)? MIDI_COMMAND_NOTE_ON : MIDI_COMMAND_NOTE_OFF);
|
||||
MIDIPitch = 0x3F;
|
||||
}
|
||||
|
||||
if (JoystickChanges & JOY_PRESS)
|
||||
{
|
||||
MIDICommand = ((JoystickStatus & JOY_PRESS)? MIDI_COMMAND_NOTE_ON : MIDI_COMMAND_NOTE_OFF);
|
||||
MIDIPitch = 0x3B;
|
||||
}
|
||||
|
||||
/* Check if a MIDI command is to be sent */
|
||||
if (MIDICommand)
|
||||
{
|
||||
MIDI_EventPacket_t MIDIEvent = (MIDI_EventPacket_t)
|
||||
{
|
||||
.CableNumber = 0,
|
||||
.Command = (MIDICommand >> 4),
|
||||
|
||||
.Data1 = MIDICommand | Channel,
|
||||
.Data2 = MIDIPitch,
|
||||
.Data3 = MIDI_STANDARD_VELOCITY,
|
||||
};
|
||||
|
||||
/* Write the MIDI event packet to the pipe */
|
||||
Pipe_Write_Stream_LE(&MIDIEvent, sizeof(MIDIEvent), NULL);
|
||||
|
||||
/* Send the data in the pipe to the device */
|
||||
Pipe_ClearOUT();
|
||||
}
|
||||
|
||||
/* Save previous joystick value for next joystick change detection */
|
||||
PrevJoystickStatus = JoystickStatus;
|
||||
}
|
||||
|
||||
break;
|
||||
/* Save previous joystick value for next joystick change detection */
|
||||
PrevJoystickStatus = JoystickStatus;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -69,7 +69,7 @@
|
|||
|
||||
/* Function Prototypes: */
|
||||
void SetupHardware(void);
|
||||
void MIDI_Host_Task(void);
|
||||
void MIDIHost_Task(void);
|
||||
|
||||
void EVENT_USB_Host_HostError(const uint8_t ErrorCode);
|
||||
void EVENT_USB_Host_DeviceAttached(void);
|
||||
|
|
|
@ -54,7 +54,8 @@ int main(void)
|
|||
|
||||
for (;;)
|
||||
{
|
||||
MassStorage_Task();
|
||||
MassStorageHost_Task();
|
||||
|
||||
USB_USBTask();
|
||||
}
|
||||
}
|
||||
|
@ -102,6 +103,35 @@ void EVENT_USB_Host_DeviceUnattached(void)
|
|||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
puts_P(PSTR("Mass Storage Disk Enumerated.\r\n"));
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_READY);
|
||||
}
|
||||
|
||||
|
@ -134,240 +164,181 @@ void EVENT_USB_Host_DeviceEnumerationFailed(const uint8_t ErrorCode,
|
|||
/** Task to set the configuration of the attached device after it has been enumerated, and to read in blocks from
|
||||
* the device and print them to the serial port.
|
||||
*/
|
||||
void MassStorage_Task(void)
|
||||
void MassStorageHost_Task(void)
|
||||
{
|
||||
if (USB_HostState != HOST_STATE_Configured)
|
||||
return;
|
||||
|
||||
/* Indicate device busy via the status LEDs */
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_BUSY);
|
||||
|
||||
uint8_t ErrorCode;
|
||||
|
||||
switch (USB_HostState)
|
||||
/* Send the request, display error and wait for device detach if request fails */
|
||||
if ((ErrorCode = MassStore_GetMaxLUN(&MassStore_MaxLUNIndex)) != HOST_SENDCONTROL_Successful)
|
||||
{
|
||||
case HOST_STATE_Addressed:
|
||||
puts_P(PSTR("Getting Config Data.\r\n"));
|
||||
|
||||
/* 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);
|
||||
|
||||
/* Indicate error via status LEDs */
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
|
||||
/* Wait until USB device disconnected */
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
/* 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);
|
||||
|
||||
/* Indicate error via status LEDs */
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
|
||||
/* Wait until USB device disconnected */
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
puts_P(PSTR("Mass Storage Disk Enumerated.\r\n"));
|
||||
|
||||
USB_HostState = HOST_STATE_Configured;
|
||||
break;
|
||||
case HOST_STATE_Configured:
|
||||
/* Indicate device busy via the status LEDs */
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_BUSY);
|
||||
|
||||
/* Send the request, display error and wait for device detach if request fails */
|
||||
if ((ErrorCode = MassStore_GetMaxLUN(&MassStore_MaxLUNIndex)) != HOST_SENDCONTROL_Successful)
|
||||
{
|
||||
ShowDiskReadError(PSTR("Get Max LUN"), ErrorCode);
|
||||
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Print number of LUNs detected in the attached device */
|
||||
printf_P(PSTR("Total LUNs: %d - Using first LUN in device.\r\n"), (MassStore_MaxLUNIndex + 1));
|
||||
|
||||
/* Reset the Mass Storage device interface, ready for use */
|
||||
if ((ErrorCode = MassStore_MassStorageReset()) != HOST_SENDCONTROL_Successful)
|
||||
{
|
||||
ShowDiskReadError(PSTR("Mass Storage Reset"), ErrorCode);
|
||||
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Get sense data from the device - many devices will not accept any other commands until the sense data
|
||||
* is read - both on start-up and after a failed command */
|
||||
SCSI_Request_Sense_Response_t SenseData;
|
||||
if ((ErrorCode = MassStore_RequestSense(0, &SenseData)) != 0)
|
||||
{
|
||||
ShowDiskReadError(PSTR("Request Sense"), ErrorCode);
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Set the prevent removal flag for the device, allowing it to be accessed */
|
||||
if ((ErrorCode = MassStore_PreventAllowMediumRemoval(0, true)) != 0)
|
||||
{
|
||||
ShowDiskReadError(PSTR("Prevent/Allow Medium Removal"), ErrorCode);
|
||||
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Get inquiry data from the device */
|
||||
SCSI_Inquiry_Response_t InquiryData;
|
||||
if ((ErrorCode = MassStore_Inquiry(0, &InquiryData)) != 0)
|
||||
{
|
||||
ShowDiskReadError(PSTR("Inquiry"), ErrorCode);
|
||||
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Print vendor and product names of attached device */
|
||||
printf_P(PSTR("Vendor \"%.8s\", Product \"%.16s\"\r\n"), InquiryData.VendorID, InquiryData.ProductID);
|
||||
|
||||
/* Wait until disk ready */
|
||||
puts_P(PSTR("Waiting until ready.."));
|
||||
|
||||
for (;;)
|
||||
{
|
||||
Serial_SendByte('.');
|
||||
|
||||
/* Abort if device removed */
|
||||
if (USB_HostState == HOST_STATE_Unattached)
|
||||
break;
|
||||
|
||||
/* Check to see if the attached device is ready for new commands */
|
||||
ErrorCode = MassStore_TestUnitReady(0);
|
||||
|
||||
/* If attached device is ready, abort the loop */
|
||||
if (!(ErrorCode))
|
||||
break;
|
||||
|
||||
/* If an error other than a logical command failure (indicating device busy) returned, abort */
|
||||
if (ErrorCode != MASS_STORE_SCSI_COMMAND_FAILED)
|
||||
{
|
||||
ShowDiskReadError(PSTR("Test Unit Ready"), ErrorCode);
|
||||
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
puts_P(PSTR("\r\nRetrieving Capacity... "));
|
||||
|
||||
/* Create new structure for the disk's capacity in blocks and block size */
|
||||
SCSI_Capacity_t DiskCapacity;
|
||||
|
||||
/* Retrieve disk capacity */
|
||||
if ((ErrorCode = MassStore_ReadCapacity(0, &DiskCapacity)) != 0)
|
||||
{
|
||||
ShowDiskReadError(PSTR("Read Capacity"), ErrorCode);
|
||||
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Display the disk capacity in blocks * block size bytes */
|
||||
printf_P(PSTR("%lu blocks of %lu bytes.\r\n"), DiskCapacity.Blocks, DiskCapacity.BlockSize);
|
||||
|
||||
/* Create a new buffer capable of holding a single block from the device */
|
||||
uint8_t BlockBuffer[DiskCapacity.BlockSize];
|
||||
|
||||
/* Read in the first 512 byte block from the device */
|
||||
if ((ErrorCode = MassStore_ReadDeviceBlock(0, 0x00000000, 1, DiskCapacity.BlockSize, BlockBuffer)) != 0)
|
||||
{
|
||||
ShowDiskReadError(PSTR("Read Device Block"), ErrorCode);
|
||||
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
puts_P(PSTR("\r\nContents of first block:\r\n"));
|
||||
|
||||
/* Print out the first block in both HEX and ASCII, 16 bytes per line */
|
||||
for (uint16_t Chunk = 0; Chunk < (DiskCapacity.BlockSize >> 4); Chunk++)
|
||||
{
|
||||
/* Pointer to the start of the current 16-byte chunk in the read block of data */
|
||||
uint8_t* ChunkPtr = &BlockBuffer[Chunk << 4];
|
||||
|
||||
/* Print out the 16 bytes of the chunk in HEX format */
|
||||
for (uint8_t ByteOffset = 0; ByteOffset < (1 << 4); ByteOffset++)
|
||||
{
|
||||
char CurrByte = *(ChunkPtr + ByteOffset);
|
||||
|
||||
printf_P(PSTR("%.2X "), CurrByte);
|
||||
}
|
||||
|
||||
puts_P(PSTR(" "));
|
||||
|
||||
/* Print out the 16 bytes of the chunk in ASCII format */
|
||||
for (uint8_t ByteOffset = 0; ByteOffset < (1 << 4); ByteOffset++)
|
||||
{
|
||||
char CurrByte = *(ChunkPtr + ByteOffset);
|
||||
|
||||
putchar(isprint(CurrByte) ? CurrByte : '.');
|
||||
}
|
||||
|
||||
puts_P(PSTR("\r\n"));
|
||||
}
|
||||
|
||||
puts_P(PSTR("\r\n\r\nPress board button to read entire ASCII contents of disk...\r\n\r\n"));
|
||||
|
||||
/* Wait for the board button to be pressed */
|
||||
while (!(Buttons_GetStatus() & BUTTONS_BUTTON1))
|
||||
{
|
||||
/* Abort if device removed */
|
||||
if (USB_HostState == HOST_STATE_Unattached)
|
||||
break;
|
||||
}
|
||||
|
||||
/* Abort if device removed */
|
||||
if (USB_HostState == HOST_STATE_Unattached)
|
||||
break;
|
||||
|
||||
/* Print out the entire disk contents in ASCII format */
|
||||
for (uint32_t CurrBlockAddress = 0; CurrBlockAddress < DiskCapacity.Blocks; CurrBlockAddress++)
|
||||
{
|
||||
/* Read in the next block of data from the device */
|
||||
if ((ErrorCode = MassStore_ReadDeviceBlock(0, CurrBlockAddress, 1, DiskCapacity.BlockSize, BlockBuffer)) != 0)
|
||||
{
|
||||
ShowDiskReadError(PSTR("Read Device Block"), ErrorCode);
|
||||
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Send the ASCII data in the read in block to the serial port */
|
||||
for (uint16_t Byte = 0; Byte < DiskCapacity.BlockSize; Byte++)
|
||||
{
|
||||
char CurrByte = BlockBuffer[Byte];
|
||||
|
||||
putchar(isprint(CurrByte) ? CurrByte : '.');
|
||||
}
|
||||
|
||||
/* Abort if device removed */
|
||||
if (USB_HostState == HOST_STATE_Unattached)
|
||||
break;
|
||||
}
|
||||
|
||||
/* Indicate device no longer busy */
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_READY);
|
||||
|
||||
/* Wait until USB device disconnected */
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
ShowDiskReadError(PSTR("Get Max LUN"), ErrorCode);
|
||||
USB_Host_SetDeviceConfiguration(0);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Print number of LUNs detected in the attached device */
|
||||
printf_P(PSTR("Total LUNs: %d - Using first LUN in device.\r\n"), (MassStore_MaxLUNIndex + 1));
|
||||
|
||||
/* Reset the Mass Storage device interface, ready for use */
|
||||
if ((ErrorCode = MassStore_MassStorageReset()) != HOST_SENDCONTROL_Successful)
|
||||
{
|
||||
ShowDiskReadError(PSTR("Mass Storage Reset"), ErrorCode);
|
||||
USB_Host_SetDeviceConfiguration(0);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Get sense data from the device - many devices will not accept any other commands until the sense data
|
||||
* is read - both on start-up and after a failed command */
|
||||
SCSI_Request_Sense_Response_t SenseData;
|
||||
if ((ErrorCode = MassStore_RequestSense(0, &SenseData)) != 0)
|
||||
{
|
||||
ShowDiskReadError(PSTR("Request Sense"), ErrorCode);
|
||||
USB_Host_SetDeviceConfiguration(0);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Set the prevent removal flag for the device, allowing it to be accessed */
|
||||
if ((ErrorCode = MassStore_PreventAllowMediumRemoval(0, true)) != 0)
|
||||
{
|
||||
ShowDiskReadError(PSTR("Prevent/Allow Medium Removal"), ErrorCode);
|
||||
USB_Host_SetDeviceConfiguration(0);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Get inquiry data from the device */
|
||||
SCSI_Inquiry_Response_t InquiryData;
|
||||
if ((ErrorCode = MassStore_Inquiry(0, &InquiryData)) != 0)
|
||||
{
|
||||
ShowDiskReadError(PSTR("Inquiry"), ErrorCode);
|
||||
USB_Host_SetDeviceConfiguration(0);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Print vendor and product names of attached device */
|
||||
printf_P(PSTR("Vendor \"%.8s\", Product \"%.16s\"\r\n"), InquiryData.VendorID, InquiryData.ProductID);
|
||||
|
||||
/* Wait until disk ready */
|
||||
puts_P(PSTR("Waiting until ready.."));
|
||||
|
||||
for (;;)
|
||||
{
|
||||
Serial_SendByte('.');
|
||||
|
||||
/* Abort if device removed */
|
||||
if (USB_HostState == HOST_STATE_Unattached)
|
||||
break;
|
||||
|
||||
/* Check to see if the attached device is ready for new commands */
|
||||
ErrorCode = MassStore_TestUnitReady(0);
|
||||
|
||||
/* If attached device is ready, abort the loop */
|
||||
if (!(ErrorCode))
|
||||
break;
|
||||
|
||||
/* If an error other than a logical command failure (indicating device busy) returned, abort */
|
||||
if (ErrorCode != MASS_STORE_SCSI_COMMAND_FAILED)
|
||||
{
|
||||
ShowDiskReadError(PSTR("Test Unit Ready"), ErrorCode);
|
||||
USB_Host_SetDeviceConfiguration(0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
puts_P(PSTR("\r\nRetrieving Capacity... "));
|
||||
|
||||
/* Create new structure for the disk's capacity in blocks and block size */
|
||||
SCSI_Capacity_t DiskCapacity;
|
||||
|
||||
/* Retrieve disk capacity */
|
||||
if ((ErrorCode = MassStore_ReadCapacity(0, &DiskCapacity)) != 0)
|
||||
{
|
||||
ShowDiskReadError(PSTR("Read Capacity"), ErrorCode);
|
||||
USB_Host_SetDeviceConfiguration(0);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Display the disk capacity in blocks * block size bytes */
|
||||
printf_P(PSTR("%lu blocks of %lu bytes.\r\n"), DiskCapacity.Blocks, DiskCapacity.BlockSize);
|
||||
|
||||
/* Create a new buffer capable of holding a single block from the device */
|
||||
uint8_t BlockBuffer[DiskCapacity.BlockSize];
|
||||
|
||||
/* Read in the first 512 byte block from the device */
|
||||
if ((ErrorCode = MassStore_ReadDeviceBlock(0, 0x00000000, 1, DiskCapacity.BlockSize, BlockBuffer)) != 0)
|
||||
{
|
||||
ShowDiskReadError(PSTR("Read Device Block"), ErrorCode);
|
||||
USB_Host_SetDeviceConfiguration(0);
|
||||
return;
|
||||
}
|
||||
|
||||
puts_P(PSTR("\r\nContents of first block:\r\n"));
|
||||
|
||||
/* Print out the first block in both HEX and ASCII, 16 bytes per line */
|
||||
for (uint16_t Chunk = 0; Chunk < (DiskCapacity.BlockSize >> 4); Chunk++)
|
||||
{
|
||||
/* Pointer to the start of the current 16-byte chunk in the read block of data */
|
||||
uint8_t* ChunkPtr = &BlockBuffer[Chunk << 4];
|
||||
|
||||
/* Print out the 16 bytes of the chunk in HEX format */
|
||||
for (uint8_t ByteOffset = 0; ByteOffset < (1 << 4); ByteOffset++)
|
||||
{
|
||||
char CurrByte = *(ChunkPtr + ByteOffset);
|
||||
|
||||
printf_P(PSTR("%.2X "), CurrByte);
|
||||
}
|
||||
|
||||
puts_P(PSTR(" "));
|
||||
|
||||
/* Print out the 16 bytes of the chunk in ASCII format */
|
||||
for (uint8_t ByteOffset = 0; ByteOffset < (1 << 4); ByteOffset++)
|
||||
{
|
||||
char CurrByte = *(ChunkPtr + ByteOffset);
|
||||
|
||||
putchar(isprint(CurrByte) ? CurrByte : '.');
|
||||
}
|
||||
|
||||
puts_P(PSTR("\r\n"));
|
||||
}
|
||||
|
||||
puts_P(PSTR("\r\n\r\nPress board button to read entire ASCII contents of disk...\r\n\r\n"));
|
||||
|
||||
/* Wait for the board button to be pressed */
|
||||
while (!(Buttons_GetStatus() & BUTTONS_BUTTON1))
|
||||
{
|
||||
/* Abort if device removed */
|
||||
if (USB_HostState == HOST_STATE_Unattached)
|
||||
return;
|
||||
}
|
||||
|
||||
/* Print out the entire disk contents in ASCII format */
|
||||
for (uint32_t CurrBlockAddress = 0; CurrBlockAddress < DiskCapacity.Blocks; CurrBlockAddress++)
|
||||
{
|
||||
/* Read in the next block of data from the device */
|
||||
if ((ErrorCode = MassStore_ReadDeviceBlock(0, CurrBlockAddress, 1, DiskCapacity.BlockSize, BlockBuffer)) != 0)
|
||||
{
|
||||
ShowDiskReadError(PSTR("Read Device Block"), ErrorCode);
|
||||
USB_Host_SetDeviceConfiguration(0);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Send the ASCII data in the read in block to the serial port */
|
||||
for (uint16_t Byte = 0; Byte < DiskCapacity.BlockSize; Byte++)
|
||||
{
|
||||
char CurrByte = BlockBuffer[Byte];
|
||||
|
||||
putchar(isprint(CurrByte) ? CurrByte : '.');
|
||||
}
|
||||
}
|
||||
|
||||
/* Indicate device no longer busy */
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_READY);
|
||||
USB_Host_SetDeviceConfiguration(0);
|
||||
}
|
||||
|
||||
/** Indicates that a communication error has occurred with the attached Mass Storage Device,
|
||||
|
|
|
@ -74,8 +74,8 @@
|
|||
#define LEDMASK_USB_BUSY LEDS_LED2
|
||||
|
||||
/* Function Prototypes: */
|
||||
void MassStorage_Task(void);
|
||||
void SetupHardware(void);
|
||||
void MassStorageHost_Task(void);
|
||||
|
||||
void EVENT_USB_Host_HostError(const uint8_t ErrorCode);
|
||||
void EVENT_USB_Host_DeviceAttached(void);
|
||||
|
|
|
@ -50,7 +50,8 @@ int main(void)
|
|||
|
||||
for (;;)
|
||||
{
|
||||
Mouse_HID_Task();
|
||||
MouseHost_Task();
|
||||
|
||||
USB_USBTask();
|
||||
}
|
||||
}
|
||||
|
@ -97,6 +98,59 @@ void EVENT_USB_Host_DeviceUnattached(void)
|
|||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
/* HID class request to set the mouse protocol to the Boot Protocol */
|
||||
USB_ControlRequest = (USB_Request_Header_t)
|
||||
{
|
||||
.bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE),
|
||||
.bRequest = HID_REQ_SetProtocol,
|
||||
.wValue = 0,
|
||||
.wIndex = 0,
|
||||
.wLength = 0,
|
||||
};
|
||||
|
||||
/* Select the control pipe for the request transfer */
|
||||
Pipe_SelectPipe(PIPE_CONTROLPIPE);
|
||||
|
||||
/* Send the request, display error and wait for device detach if request fails */
|
||||
if ((ErrorCode = USB_Host_SendControlRequest(NULL)) != HOST_SENDCONTROL_Successful)
|
||||
{
|
||||
printf_P(PSTR(ESC_FG_RED "Control Error (Set Protocol).\r\n"
|
||||
" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
|
||||
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
USB_Host_SetDeviceConfiguration(0);
|
||||
return;
|
||||
}
|
||||
|
||||
puts_P(PSTR("Mouse Enumerated.\r\n"));
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_READY);
|
||||
}
|
||||
|
||||
|
@ -129,8 +183,11 @@ void EVENT_USB_Host_DeviceEnumerationFailed(const uint8_t ErrorCode,
|
|||
/** Reads in and processes the next report from the attached device, displaying the report
|
||||
* contents on the board LEDs and via the serial port.
|
||||
*/
|
||||
void ReadNextReport(void)
|
||||
void MouseHost_Task(void)
|
||||
{
|
||||
if (USB_HostState != HOST_STATE_Configured)
|
||||
return;
|
||||
|
||||
USB_MouseReport_Data_t MouseReport;
|
||||
uint8_t LEDMask = LEDS_NO_LEDS;
|
||||
|
||||
|
@ -189,87 +246,3 @@ void ReadNextReport(void)
|
|||
Pipe_Freeze();
|
||||
}
|
||||
|
||||
/** Task to set the configuration of the attached device after it has been enumerated, and to read and process
|
||||
* HID reports from the device and display the results onto the board LEDs.
|
||||
*/
|
||||
void Mouse_HID_Task(void)
|
||||
{
|
||||
uint8_t ErrorCode;
|
||||
|
||||
/* Switch to determine what user-application handled host state the host state machine is in */
|
||||
switch (USB_HostState)
|
||||
{
|
||||
case HOST_STATE_Addressed:
|
||||
puts_P(PSTR("Getting Config Data.\r\n"));
|
||||
|
||||
/* 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);
|
||||
|
||||
/* Indicate error status */
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
|
||||
/* Wait until USB device disconnected */
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
/* 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);
|
||||
|
||||
/* Indicate error status */
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
|
||||
/* Wait until USB device disconnected */
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
/* HID class request to set the mouse protocol to the Boot Protocol */
|
||||
USB_ControlRequest = (USB_Request_Header_t)
|
||||
{
|
||||
.bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE),
|
||||
.bRequest = HID_REQ_SetProtocol,
|
||||
.wValue = 0,
|
||||
.wIndex = 0,
|
||||
.wLength = 0,
|
||||
};
|
||||
|
||||
/* Select the control pipe for the request transfer */
|
||||
Pipe_SelectPipe(PIPE_CONTROLPIPE);
|
||||
|
||||
/* Send the request, display error and wait for device detach if request fails */
|
||||
if ((ErrorCode = USB_Host_SendControlRequest(NULL)) != HOST_SENDCONTROL_Successful)
|
||||
{
|
||||
printf_P(PSTR(ESC_FG_RED "Control Error (Set Protocol).\r\n"
|
||||
" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
|
||||
|
||||
/* Indicate error status */
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
|
||||
/* Wait until USB device disconnected */
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
puts_P(PSTR("Mouse Enumerated.\r\n"));
|
||||
|
||||
USB_HostState = HOST_STATE_Configured;
|
||||
break;
|
||||
case HOST_STATE_Configured:
|
||||
/* If a report has been received, read and process it */
|
||||
ReadNextReport();
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -66,8 +66,8 @@
|
|||
#define LEDMASK_USB_ERROR (LEDS_LED1 | LEDS_LED3)
|
||||
|
||||
/* Function Prototypes: */
|
||||
void Mouse_HID_Task(void);
|
||||
void SetupHardware(void);
|
||||
void MouseHost_Task(void);
|
||||
|
||||
void EVENT_USB_Host_HostError(const uint8_t ErrorCode);
|
||||
void EVENT_USB_Host_DeviceAttached(void);
|
||||
|
|
|
@ -50,7 +50,8 @@ int main(void)
|
|||
|
||||
for (;;)
|
||||
{
|
||||
Mouse_HID_Task();
|
||||
MouseHost_Task();
|
||||
|
||||
USB_USBTask();
|
||||
}
|
||||
}
|
||||
|
@ -97,6 +98,52 @@ void EVENT_USB_Host_DeviceUnattached(void)
|
|||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
printf_P(PSTR("Processing HID Report (Size %d Bytes).\r\n"), HIDReportSize);
|
||||
|
||||
/* Get and process the device's first HID report descriptor */
|
||||
if ((ErrorCode = GetHIDReportData()) != ParseSuccessful)
|
||||
{
|
||||
puts_P(PSTR(ESC_FG_RED "Report Parse Error.\r\n"));
|
||||
|
||||
if (!(HIDReportInfo.TotalReportItems))
|
||||
puts_P(PSTR("Not a valid Mouse." ESC_FG_WHITE));
|
||||
else
|
||||
printf_P(PSTR(" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
|
||||
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
USB_Host_SetDeviceConfiguration(0);
|
||||
return;
|
||||
}
|
||||
|
||||
puts_P(PSTR("Mouse Enumerated.\r\n"));
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_READY);
|
||||
}
|
||||
|
||||
|
@ -126,104 +173,40 @@ void EVENT_USB_Host_DeviceEnumerationFailed(const uint8_t ErrorCode,
|
|||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
}
|
||||
|
||||
/** Task to set the configuration of the attached device after it has been enumerated, and to read and process
|
||||
* the HID report descriptor and HID reports from the device and display the results onto the board LEDs.
|
||||
/** Task to read and process the HID report descriptor and HID reports from the device and display the
|
||||
* results onto the board LEDs.
|
||||
*/
|
||||
void Mouse_HID_Task(void)
|
||||
void MouseHost_Task(void)
|
||||
{
|
||||
uint8_t ErrorCode;
|
||||
if (USB_HostState != HOST_STATE_Configured)
|
||||
return;
|
||||
|
||||
/* Switch to determine what user-application handled host state the host state machine is in */
|
||||
switch (USB_HostState)
|
||||
/* Select and unfreeze mouse data pipe */
|
||||
Pipe_SelectPipe(MOUSE_DATA_IN_PIPE);
|
||||
Pipe_Unfreeze();
|
||||
|
||||
/* Check to see if a packet has been received */
|
||||
if (Pipe_IsINReceived())
|
||||
{
|
||||
case HOST_STATE_Addressed:
|
||||
puts_P(PSTR("Getting Config Data.\r\n"));
|
||||
/* Check if data has been received from the attached mouse */
|
||||
if (Pipe_IsReadWriteAllowed())
|
||||
{
|
||||
/* Create buffer big enough for the report */
|
||||
uint8_t MouseReport[Pipe_BytesInPipe()];
|
||||
|
||||
/* 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"));
|
||||
/* Load in the mouse report */
|
||||
Pipe_Read_Stream_LE(MouseReport, Pipe_BytesInPipe(), NULL);
|
||||
|
||||
printf_P(PSTR(" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
|
||||
/* Process the read in mouse report from the device */
|
||||
ProcessMouseReport(MouseReport);
|
||||
}
|
||||
|
||||
/* Indicate error via status LEDs */
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
|
||||
/* Wait until USB device disconnected */
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
/* 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);
|
||||
|
||||
/* Indicate error via status LEDs */
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
|
||||
/* Wait until USB device disconnected */
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
printf_P(PSTR("Processing HID Report (Size %d Bytes).\r\n"), HIDReportSize);
|
||||
|
||||
/* Get and process the device's first HID report descriptor */
|
||||
if ((ErrorCode = GetHIDReportData()) != ParseSuccessful)
|
||||
{
|
||||
puts_P(PSTR(ESC_FG_RED "Report Parse Error.\r\n"));
|
||||
|
||||
if (!(HIDReportInfo.TotalReportItems))
|
||||
puts_P(PSTR("Not a valid Mouse." ESC_FG_WHITE));
|
||||
else
|
||||
printf_P(PSTR(" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
|
||||
|
||||
/* Indicate error via status LEDs */
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
|
||||
/* Wait until USB device disconnected */
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
puts_P(PSTR("Mouse Enumerated.\r\n"));
|
||||
|
||||
USB_HostState = HOST_STATE_Configured;
|
||||
break;
|
||||
case HOST_STATE_Configured:
|
||||
/* Select and unfreeze mouse data pipe */
|
||||
Pipe_SelectPipe(MOUSE_DATA_IN_PIPE);
|
||||
Pipe_Unfreeze();
|
||||
|
||||
/* Check to see if a packet has been received */
|
||||
if (Pipe_IsINReceived())
|
||||
{
|
||||
/* Check if data has been received from the attached mouse */
|
||||
if (Pipe_IsReadWriteAllowed())
|
||||
{
|
||||
/* Create buffer big enough for the report */
|
||||
uint8_t MouseReport[Pipe_BytesInPipe()];
|
||||
|
||||
/* Load in the mouse report */
|
||||
Pipe_Read_Stream_LE(MouseReport, Pipe_BytesInPipe(), NULL);
|
||||
|
||||
/* Process the read in mouse report from the device */
|
||||
ProcessMouseReport(MouseReport);
|
||||
}
|
||||
|
||||
/* Clear the IN endpoint, ready for next data packet */
|
||||
Pipe_ClearIN();
|
||||
}
|
||||
|
||||
/* Freeze mouse data pipe */
|
||||
Pipe_Freeze();
|
||||
break;
|
||||
/* Clear the IN endpoint, ready for next data packet */
|
||||
Pipe_ClearIN();
|
||||
}
|
||||
|
||||
/* Freeze mouse data pipe */
|
||||
Pipe_Freeze();
|
||||
}
|
||||
|
||||
/** Processes a read HID report from an attached mouse, extracting out elements via the HID parser results
|
||||
|
|
|
@ -67,8 +67,8 @@
|
|||
#define LEDMASK_USB_ERROR (LEDS_LED1 | LEDS_LED3)
|
||||
|
||||
/* Function Prototypes: */
|
||||
void Mouse_HID_Task(void);
|
||||
void SetupHardware(void);
|
||||
void MouseHost_Task(void);
|
||||
|
||||
void EVENT_USB_Host_HostError(const uint8_t ErrorCode);
|
||||
void EVENT_USB_Host_DeviceAttached(void);
|
||||
|
|
|
@ -50,7 +50,8 @@ int main(void)
|
|||
|
||||
for (;;)
|
||||
{
|
||||
USB_Printer_Host();
|
||||
PrinterHost_Task();
|
||||
|
||||
USB_USBTask();
|
||||
}
|
||||
}
|
||||
|
@ -97,6 +98,65 @@ void EVENT_USB_Host_DeviceUnattached(void)
|
|||
*/
|
||||
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"), 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;
|
||||
}
|
||||
|
||||
/* Some printers use alternate settings to determine the communication protocol used - if so, send a SetInterface
|
||||
* request to switch to the interface alternate setting with the Bidirectional protocol */
|
||||
if (PrinterAltSetting)
|
||||
{
|
||||
if ((ErrorCode = USB_Host_SetInterfaceAltSetting(PrinterInterfaceNumber, PrinterAltSetting)) != HOST_SENDCONTROL_Successful)
|
||||
{
|
||||
printf_P(PSTR(ESC_FG_RED "Control Error (Set Interface).\r\n"
|
||||
" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
|
||||
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
USB_Host_SetDeviceConfiguration(0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
puts_P(PSTR("Retrieving Device ID...\r\n"));
|
||||
|
||||
char DeviceIDString[300];
|
||||
if ((ErrorCode = Printer_GetDeviceID(DeviceIDString, sizeof(DeviceIDString))) != HOST_SENDCONTROL_Successful)
|
||||
{
|
||||
printf_P(PSTR(ESC_FG_RED "Control Error (Get Device ID).\r\n"
|
||||
" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
|
||||
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
USB_Host_SetDeviceConfiguration(0);
|
||||
return;
|
||||
}
|
||||
|
||||
printf_P(PSTR("Printer Device ID: %s\r\n"), DeviceIDString);
|
||||
|
||||
puts_P(PSTR("Printer Enumerated.\r\n"));
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_READY);
|
||||
}
|
||||
|
||||
|
@ -126,122 +186,39 @@ void EVENT_USB_Host_DeviceEnumerationFailed(const uint8_t ErrorCode,
|
|||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
}
|
||||
|
||||
/** Task to set the configuration of the attached device after it has been enumerated, and to send some test page
|
||||
* data to the attached printer.
|
||||
/** Task to manage an enumerated USB printer once connected, to display device
|
||||
* information and print a test PCL page.
|
||||
*/
|
||||
void USB_Printer_Host(void)
|
||||
void PrinterHost_Task(void)
|
||||
{
|
||||
if (USB_HostState != HOST_STATE_Configured)
|
||||
return;
|
||||
|
||||
uint8_t ErrorCode;
|
||||
|
||||
switch (USB_HostState)
|
||||
/* Indicate device busy via the status LEDs */
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_BUSY);
|
||||
|
||||
char TestPageData[] = "\033%-12345X\033E" "LUFA PCL Test Page" "\033E\033%-12345X";
|
||||
uint16_t TestPageLength = strlen(TestPageData);
|
||||
|
||||
printf_P(PSTR("Sending Test Page (%d bytes)...\r\n"), TestPageLength);
|
||||
|
||||
/* Send the test page to the attached printer */
|
||||
if ((ErrorCode = Printer_SendData(&TestPageData, TestPageLength)) != PIPE_RWSTREAM_NoError)
|
||||
{
|
||||
case HOST_STATE_Addressed:
|
||||
puts_P(PSTR("Getting Config Data.\r\n"));
|
||||
printf_P(PSTR(ESC_FG_RED "Error Sending Test Page.\r\n"
|
||||
" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
|
||||
|
||||
/* Select the control pipe for the request transfer */
|
||||
Pipe_SelectPipe(PIPE_CONTROLPIPE);
|
||||
|
||||
/* 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"), ErrorCode);
|
||||
|
||||
/* Indicate error via status LEDs */
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
|
||||
/* Wait until USB device disconnected */
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
/* 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);
|
||||
|
||||
/* Indicate error via status LEDs */
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
|
||||
/* Wait until USB device disconnected */
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Some printers use alternate settings to determine the communication protocol used - if so, send a SetInterface
|
||||
* request to switch to the interface alternate setting with the Bidirectional protocol */
|
||||
if (PrinterAltSetting)
|
||||
{
|
||||
if ((ErrorCode = USB_Host_SetInterfaceAltSetting(PrinterInterfaceNumber, PrinterAltSetting)) != HOST_SENDCONTROL_Successful)
|
||||
{
|
||||
printf_P(PSTR(ESC_FG_RED "Control Error (Set Interface).\r\n"
|
||||
" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
|
||||
|
||||
/* Indicate error via status LEDs */
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
|
||||
/* Wait until USB device disconnected */
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
puts_P(PSTR("Retrieving Device ID...\r\n"));
|
||||
|
||||
char DeviceIDString[300];
|
||||
if ((ErrorCode = Printer_GetDeviceID(DeviceIDString, sizeof(DeviceIDString))) != HOST_SENDCONTROL_Successful)
|
||||
{
|
||||
printf_P(PSTR(ESC_FG_RED "Control Error (Get Device ID).\r\n"
|
||||
" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
|
||||
|
||||
/* Indicate error via status LEDs */
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
|
||||
/* Wait until USB device disconnected */
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
printf_P(PSTR("Printer Device ID: %s\r\n"), DeviceIDString);
|
||||
|
||||
puts_P(PSTR("Printer Enumerated.\r\n"));
|
||||
|
||||
USB_HostState = HOST_STATE_Configured;
|
||||
break;
|
||||
case HOST_STATE_Configured:
|
||||
/* Indicate device busy via the status LEDs */
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_BUSY);
|
||||
|
||||
char TestPageData[] = "\033%-12345X\033E" "LUFA PCL Test Page" "\033E\033%-12345X";
|
||||
uint16_t TestPageLength = strlen(TestPageData);
|
||||
|
||||
printf_P(PSTR("Sending Test Page (%d bytes)...\r\n"), TestPageLength);
|
||||
|
||||
if ((ErrorCode = Printer_SendData(&TestPageData, TestPageLength)) != PIPE_RWSTREAM_NoError)
|
||||
{
|
||||
printf_P(PSTR(ESC_FG_RED "Error Sending Test Page.\r\n"
|
||||
" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
|
||||
|
||||
/* Indicate error via status LEDs */
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
|
||||
/* Wait until USB device disconnected */
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
puts_P(PSTR("Test Page Sent.\r\n"));
|
||||
|
||||
/* Indicate device no longer busy */
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_READY);
|
||||
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
USB_Host_SetDeviceConfiguration(0);
|
||||
return;
|
||||
}
|
||||
|
||||
puts_P(PSTR("Test Page Sent.\r\n"));
|
||||
|
||||
/* Indicate device no longer busy */
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_READY);
|
||||
USB_Host_SetDeviceConfiguration(0);
|
||||
}
|
||||
|
||||
|
|
|
@ -74,16 +74,15 @@
|
|||
extern uint8_t PrinterInterfaceNumber;
|
||||
|
||||
/* Function Prototypes: */
|
||||
void SetupHardware(void);
|
||||
void PrinterHost_Task(void);
|
||||
|
||||
void EVENT_USB_Host_DeviceAttached(void);
|
||||
void EVENT_USB_Host_DeviceUnattached(void);
|
||||
void EVENT_USB_Host_DeviceEnumerationComplete(void);
|
||||
void EVENT_USB_Host_HostError(const uint8_t ErrorCode);
|
||||
void EVENT_USB_Host_DeviceEnumerationFailed(const uint8_t ErrorCode,
|
||||
const uint8_t SubErrorCode);
|
||||
|
||||
void SetupHardware(void);
|
||||
|
||||
void USB_Printer_Host(void);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -50,7 +50,8 @@ int main(void)
|
|||
|
||||
for (;;)
|
||||
{
|
||||
RNDIS_Host_Task();
|
||||
RNDISHost_Task();
|
||||
|
||||
USB_USBTask();
|
||||
}
|
||||
}
|
||||
|
@ -97,6 +98,75 @@ void EVENT_USB_Host_DeviceUnattached(void)
|
|||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
uint16_t DeviceMaxPacketSize;
|
||||
if ((ErrorCode = RNDIS_InitializeDevice(1024, &DeviceMaxPacketSize)) != HOST_SENDCONTROL_Successful)
|
||||
{
|
||||
printf_P(PSTR(ESC_FG_RED "Error Initializing Device.\r\n"
|
||||
" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
|
||||
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
USB_Host_SetDeviceConfiguration(0);
|
||||
return;
|
||||
}
|
||||
|
||||
printf_P(PSTR("Device Max Transfer Size: %lu bytes.\r\n"), DeviceMaxPacketSize);
|
||||
|
||||
/* We set the default filter to only receive packets we would be interested in */
|
||||
uint32_t PacketFilter = (REMOTE_NDIS_PACKET_DIRECTED | REMOTE_NDIS_PACKET_BROADCAST | REMOTE_NDIS_PACKET_ALL_MULTICAST);
|
||||
if ((ErrorCode = RNDIS_SetRNDISProperty(OID_GEN_CURRENT_PACKET_FILTER,
|
||||
&PacketFilter, sizeof(PacketFilter))) != HOST_SENDCONTROL_Successful)
|
||||
{
|
||||
printf_P(PSTR(ESC_FG_RED "Error Setting Device Packet Filter.\r\n"
|
||||
" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
|
||||
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
USB_Host_SetDeviceConfiguration(0);
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t VendorID;
|
||||
if ((ErrorCode = RNDIS_QueryRNDISProperty(OID_GEN_VENDOR_ID,
|
||||
&VendorID, sizeof(VendorID))) != HOST_SENDCONTROL_Successful)
|
||||
{
|
||||
printf_P(PSTR(ESC_FG_RED "Error Getting Vendor ID.\r\n"
|
||||
" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
|
||||
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
USB_Host_SetDeviceConfiguration(0);
|
||||
return;
|
||||
}
|
||||
|
||||
printf_P(PSTR("Device Vendor ID: 0x%08lX\r\n"), VendorID);
|
||||
|
||||
puts_P(PSTR("RNDIS Device Enumerated.\r\n"));
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_READY);
|
||||
}
|
||||
|
||||
|
@ -126,8 +196,13 @@ void EVENT_USB_Host_DeviceEnumerationFailed(const uint8_t ErrorCode,
|
|||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
}
|
||||
|
||||
void PrintIncomingPackets(void)
|
||||
/** Task to read in data received from the attached RNDIS device and print it to the serial port.
|
||||
*/
|
||||
void RNDISHost_Task(void)
|
||||
{
|
||||
if (USB_HostState != HOST_STATE_Configured)
|
||||
return;
|
||||
|
||||
uint8_t ErrorCode;
|
||||
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_BUSY);
|
||||
|
@ -136,7 +211,7 @@ void PrintIncomingPackets(void)
|
|||
if ((ErrorCode = RNDIS_GetPacketLength(&PacketLength)) != HOST_SENDCONTROL_Successful)
|
||||
{
|
||||
printf_P(PSTR(ESC_FG_RED "Packet Reception Error.\r\n"
|
||||
" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
|
||||
" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -170,107 +245,3 @@ void PrintIncomingPackets(void)
|
|||
LEDs_SetAllLEDs(LEDMASK_USB_READY);
|
||||
}
|
||||
|
||||
/** Task to set the configuration of the attached device after it has been enumerated, and to read in
|
||||
* data received from the attached RNDIS device and print it to the serial port.
|
||||
*/
|
||||
void RNDIS_Host_Task(void)
|
||||
{
|
||||
uint8_t ErrorCode;
|
||||
|
||||
switch (USB_HostState)
|
||||
{
|
||||
case HOST_STATE_Addressed:
|
||||
puts_P(PSTR("Getting Config Data.\r\n"));
|
||||
|
||||
/* 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);
|
||||
|
||||
/* Indicate error via status LEDs */
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
|
||||
/* Wait until USB device disconnected */
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
/* 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);
|
||||
|
||||
/* Indicate error via status LEDs */
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
|
||||
/* Wait until USB device disconnected */
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
uint16_t DeviceMaxPacketSize;
|
||||
if ((ErrorCode = RNDIS_InitializeDevice(1024, &DeviceMaxPacketSize)) != HOST_SENDCONTROL_Successful)
|
||||
{
|
||||
printf_P(PSTR(ESC_FG_RED "Error Initializing Device.\r\n"
|
||||
" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
|
||||
|
||||
/* Indicate error via status LEDs */
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
|
||||
/* Wait until USB device disconnected */
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
printf_P(PSTR("Device Max Transfer Size: %lu bytes.\r\n"), DeviceMaxPacketSize);
|
||||
|
||||
/* We set the default filter to only receive packets we would be interested in */
|
||||
uint32_t PacketFilter = (REMOTE_NDIS_PACKET_DIRECTED | REMOTE_NDIS_PACKET_BROADCAST | REMOTE_NDIS_PACKET_ALL_MULTICAST);
|
||||
if ((ErrorCode = RNDIS_SetRNDISProperty(OID_GEN_CURRENT_PACKET_FILTER,
|
||||
&PacketFilter, sizeof(PacketFilter))) != HOST_SENDCONTROL_Successful)
|
||||
{
|
||||
printf_P(PSTR(ESC_FG_RED "Error Setting Device Packet Filter.\r\n"
|
||||
" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
|
||||
|
||||
/* Indicate error via status LEDs */
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
|
||||
/* Wait until USB device disconnected */
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
uint32_t VendorID;
|
||||
if ((ErrorCode = RNDIS_QueryRNDISProperty(OID_GEN_VENDOR_ID,
|
||||
&VendorID, sizeof(VendorID))) != HOST_SENDCONTROL_Successful)
|
||||
{
|
||||
printf_P(PSTR(ESC_FG_RED "Error Getting Vendor ID.\r\n"
|
||||
" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
|
||||
|
||||
/* Indicate error via status LEDs */
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
|
||||
/* Wait until USB device disconnected */
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
printf_P(PSTR("Device Vendor ID: 0x%08lX\r\n"), VendorID);
|
||||
|
||||
puts_P(PSTR("RNDIS Device Enumerated.\r\n"));
|
||||
|
||||
USB_HostState = HOST_STATE_Configured;
|
||||
break;
|
||||
case HOST_STATE_Configured:
|
||||
PrintIncomingPackets();
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -72,8 +72,7 @@
|
|||
|
||||
/* Function Prototypes: */
|
||||
void SetupHardware(void);
|
||||
void PrintIncomingPackets(void);
|
||||
void RNDIS_Host_Task(void);
|
||||
void RNDISHost_Task(void);
|
||||
|
||||
void EVENT_USB_Host_HostError(const uint8_t ErrorCode);
|
||||
void EVENT_USB_Host_DeviceAttached(void);
|
||||
|
|
|
@ -50,7 +50,8 @@ int main(void)
|
|||
|
||||
for (;;)
|
||||
{
|
||||
StillImage_Task();
|
||||
StillImageHost_Task();
|
||||
|
||||
USB_USBTask();
|
||||
}
|
||||
}
|
||||
|
@ -98,6 +99,35 @@ void EVENT_USB_Host_DeviceUnattached(void)
|
|||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
puts_P(PSTR("Still Image Device Enumerated.\r\n"));
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_READY);
|
||||
}
|
||||
|
||||
|
@ -127,214 +157,166 @@ void EVENT_USB_Host_DeviceEnumerationFailed(const uint8_t ErrorCode,
|
|||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
}
|
||||
|
||||
/** Task to set the configuration of the attached device after it has been enumerated, and to print device information
|
||||
* through the serial port.
|
||||
/** Task to print device information through the serial port, and open/close a test PIMA session with the
|
||||
* attached Still Image device.
|
||||
*/
|
||||
void StillImage_Task(void)
|
||||
void StillImageHost_Task(void)
|
||||
{
|
||||
if (USB_HostState != HOST_STATE_Configured)
|
||||
return;
|
||||
|
||||
uint8_t ErrorCode;
|
||||
|
||||
switch (USB_HostState)
|
||||
/* Indicate device busy via the status LEDs */
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_BUSY);
|
||||
|
||||
puts_P(PSTR("Retrieving Device Info...\r\n"));
|
||||
|
||||
PIMA_SendBlock = (PIMA_Container_t)
|
||||
{
|
||||
.DataLength = PIMA_COMMAND_SIZE(0),
|
||||
.Type = PIMA_CONTAINER_CommandBlock,
|
||||
.Code = PIMA_OPERATION_GETDEVICEINFO,
|
||||
.TransactionID = 0x00000000,
|
||||
.Params = {},
|
||||
};
|
||||
|
||||
/* Send the GETDEVICEINFO block */
|
||||
SImage_SendBlockHeader();
|
||||
|
||||
/* Receive the response data block */
|
||||
if ((ErrorCode = SImage_ReceiveBlockHeader()) != PIPE_RWSTREAM_NoError)
|
||||
{
|
||||
case HOST_STATE_Addressed:
|
||||
puts_P(PSTR("Getting Config Data.\r\n"));
|
||||
|
||||
/* 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);
|
||||
|
||||
/* Indicate error via status LEDs */
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
|
||||
/* Wait until USB device disconnected */
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
/* 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);
|
||||
|
||||
/* Indicate error via status LEDs */
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
|
||||
/* Wait until USB device disconnected */
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
puts_P(PSTR("Still Image Device Enumerated.\r\n"));
|
||||
USB_HostState = HOST_STATE_Configured;
|
||||
break;
|
||||
case HOST_STATE_Configured:
|
||||
/* Indicate device busy via the status LEDs */
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_BUSY);
|
||||
|
||||
puts_P(PSTR("Retrieving Device Info...\r\n"));
|
||||
|
||||
PIMA_SendBlock = (PIMA_Container_t)
|
||||
{
|
||||
.DataLength = PIMA_COMMAND_SIZE(0),
|
||||
.Type = PIMA_CONTAINER_CommandBlock,
|
||||
.Code = PIMA_OPERATION_GETDEVICEINFO,
|
||||
.TransactionID = 0x00000000,
|
||||
.Params = {},
|
||||
};
|
||||
|
||||
/* Send the GETDEVICEINFO block */
|
||||
SImage_SendBlockHeader();
|
||||
|
||||
/* Receive the response data block */
|
||||
if ((ErrorCode = SImage_ReceiveBlockHeader()) != PIPE_RWSTREAM_NoError)
|
||||
{
|
||||
ShowCommandError(ErrorCode, false);
|
||||
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Calculate the size of the returned device info data structure */
|
||||
uint16_t DeviceInfoSize = (PIMA_ReceivedBlock.DataLength - PIMA_COMMAND_SIZE(0));
|
||||
|
||||
/* Create a buffer large enough to hold the entire device info */
|
||||
uint8_t DeviceInfo[DeviceInfoSize];
|
||||
|
||||
/* Read in the data block data (containing device info) */
|
||||
SImage_ReadData(DeviceInfo, DeviceInfoSize);
|
||||
|
||||
/* Once all the data has been read, the pipe must be cleared before the response can be sent */
|
||||
Pipe_ClearIN();
|
||||
|
||||
/* Create a pointer for walking through the info dataset */
|
||||
uint8_t* DeviceInfoPos = DeviceInfo;
|
||||
|
||||
/* Skip over the data before the unicode device information strings */
|
||||
DeviceInfoPos += 8; // Skip to VendorExtensionDesc String
|
||||
DeviceInfoPos += (1 + UNICODE_STRING_LENGTH(*DeviceInfoPos)); // Skip over VendorExtensionDesc String
|
||||
DeviceInfoPos += 2; // Skip over FunctionalMode
|
||||
DeviceInfoPos += (4 + (*(uint32_t*)DeviceInfoPos << 1)); // Skip over Supported Operations Array
|
||||
DeviceInfoPos += (4 + (*(uint32_t*)DeviceInfoPos << 1)); // Skip over Supported Events Array
|
||||
DeviceInfoPos += (4 + (*(uint32_t*)DeviceInfoPos << 1)); // Skip over Supported Device Properties Array
|
||||
DeviceInfoPos += (4 + (*(uint32_t*)DeviceInfoPos << 1)); // Skip over Capture Formats Array
|
||||
DeviceInfoPos += (4 + (*(uint32_t*)DeviceInfoPos << 1)); // Skip over Image Formats Array
|
||||
|
||||
/* Extract and convert the Manufacturer Unicode string to ASCII and print it through the USART */
|
||||
char Manufacturer[*DeviceInfoPos];
|
||||
UnicodeToASCII(DeviceInfoPos, Manufacturer);
|
||||
printf_P(PSTR(" Manufacturer: %s\r\n"), Manufacturer);
|
||||
|
||||
DeviceInfoPos += 1 + UNICODE_STRING_LENGTH(*DeviceInfoPos); // Skip over Manufacturer String
|
||||
|
||||
/* Extract and convert the Model Unicode string to ASCII and print it through the USART */
|
||||
char Model[*DeviceInfoPos];
|
||||
UnicodeToASCII(DeviceInfoPos, Model);
|
||||
printf_P(PSTR(" Model: %s\r\n"), Model);
|
||||
|
||||
DeviceInfoPos += 1 + UNICODE_STRING_LENGTH(*DeviceInfoPos); // Skip over Model String
|
||||
|
||||
/* Extract and convert the Device Version Unicode string to ASCII and print it through the USART */
|
||||
char DeviceVersion[*DeviceInfoPos];
|
||||
UnicodeToASCII(DeviceInfoPos, DeviceVersion);
|
||||
printf_P(PSTR(" Device Version: %s\r\n"), DeviceVersion);
|
||||
|
||||
/* Receive the final response block from the device */
|
||||
if ((ErrorCode = SImage_ReceiveBlockHeader()) != PIPE_RWSTREAM_NoError)
|
||||
{
|
||||
ShowCommandError(ErrorCode, false);
|
||||
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Verify that the command completed successfully */
|
||||
if ((PIMA_ReceivedBlock.Type != PIMA_CONTAINER_ResponseBlock) || (PIMA_ReceivedBlock.Code != PIMA_RESPONSE_OK))
|
||||
{
|
||||
ShowCommandError(PIMA_ReceivedBlock.Code, true);
|
||||
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
puts_P(PSTR("Opening Session...\r\n"));
|
||||
|
||||
PIMA_SendBlock = (PIMA_Container_t)
|
||||
{
|
||||
.DataLength = PIMA_COMMAND_SIZE(1),
|
||||
.Type = PIMA_CONTAINER_CommandBlock,
|
||||
.Code = PIMA_OPERATION_OPENSESSION,
|
||||
.TransactionID = 0x00000000,
|
||||
.Params = {0x00000001},
|
||||
};
|
||||
|
||||
/* Send the OPENSESSION block, open a session with an ID of 0x0001 */
|
||||
SImage_SendBlockHeader();
|
||||
|
||||
/* Receive the response block from the device */
|
||||
if ((ErrorCode = SImage_ReceiveBlockHeader()) != PIPE_RWSTREAM_NoError)
|
||||
{
|
||||
ShowCommandError(ErrorCode, false);
|
||||
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Verify that the command completed successfully */
|
||||
if ((PIMA_ReceivedBlock.Type != PIMA_CONTAINER_ResponseBlock) || (PIMA_ReceivedBlock.Code != PIMA_RESPONSE_OK))
|
||||
{
|
||||
ShowCommandError(PIMA_ReceivedBlock.Code, true);
|
||||
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
puts_P(PSTR("Closing Session...\r\n"));
|
||||
|
||||
PIMA_SendBlock = (PIMA_Container_t)
|
||||
{
|
||||
.DataLength = PIMA_COMMAND_SIZE(1),
|
||||
.Type = PIMA_CONTAINER_CommandBlock,
|
||||
.Code = PIMA_OPERATION_CLOSESESSION,
|
||||
.TransactionID = 0x00000001,
|
||||
.Params = {0x00000001},
|
||||
};
|
||||
|
||||
/* Send the CLOSESESSION block, close the session with an ID of 0x0001 */
|
||||
SImage_SendBlockHeader();
|
||||
|
||||
/* Receive the response block from the device */
|
||||
if ((ErrorCode = SImage_ReceiveBlockHeader()) != PIPE_RWSTREAM_NoError)
|
||||
{
|
||||
ShowCommandError(ErrorCode, false);
|
||||
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Verify that the command completed successfully */
|
||||
if ((PIMA_ReceivedBlock.Type != PIMA_CONTAINER_ResponseBlock) || (PIMA_ReceivedBlock.Code != PIMA_RESPONSE_OK))
|
||||
{
|
||||
ShowCommandError(PIMA_ReceivedBlock.Code, true);
|
||||
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
puts_P(PSTR("Done.\r\n"));
|
||||
|
||||
/* Indicate device no longer busy */
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_READY);
|
||||
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
ShowCommandError(ErrorCode, false);
|
||||
USB_Host_SetDeviceConfiguration(0);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Calculate the size of the returned device info data structure */
|
||||
uint16_t DeviceInfoSize = (PIMA_ReceivedBlock.DataLength - PIMA_COMMAND_SIZE(0));
|
||||
|
||||
/* Create a buffer large enough to hold the entire device info */
|
||||
uint8_t DeviceInfo[DeviceInfoSize];
|
||||
|
||||
/* Read in the data block data (containing device info) */
|
||||
SImage_ReadData(DeviceInfo, DeviceInfoSize);
|
||||
|
||||
/* Once all the data has been read, the pipe must be cleared before the response can be sent */
|
||||
Pipe_ClearIN();
|
||||
|
||||
/* Create a pointer for walking through the info dataset */
|
||||
uint8_t* DeviceInfoPos = DeviceInfo;
|
||||
|
||||
/* Skip over the data before the unicode device information strings */
|
||||
DeviceInfoPos += 8; // Skip to VendorExtensionDesc String
|
||||
DeviceInfoPos += (1 + UNICODE_STRING_LENGTH(*DeviceInfoPos)); // Skip over VendorExtensionDesc String
|
||||
DeviceInfoPos += 2; // Skip over FunctionalMode
|
||||
DeviceInfoPos += (4 + (*(uint32_t*)DeviceInfoPos << 1)); // Skip over Supported Operations Array
|
||||
DeviceInfoPos += (4 + (*(uint32_t*)DeviceInfoPos << 1)); // Skip over Supported Events Array
|
||||
DeviceInfoPos += (4 + (*(uint32_t*)DeviceInfoPos << 1)); // Skip over Supported Device Properties Array
|
||||
DeviceInfoPos += (4 + (*(uint32_t*)DeviceInfoPos << 1)); // Skip over Capture Formats Array
|
||||
DeviceInfoPos += (4 + (*(uint32_t*)DeviceInfoPos << 1)); // Skip over Image Formats Array
|
||||
|
||||
/* Extract and convert the Manufacturer Unicode string to ASCII and print it through the USART */
|
||||
char Manufacturer[*DeviceInfoPos];
|
||||
UnicodeToASCII(DeviceInfoPos, Manufacturer);
|
||||
printf_P(PSTR(" Manufacturer: %s\r\n"), Manufacturer);
|
||||
|
||||
DeviceInfoPos += 1 + UNICODE_STRING_LENGTH(*DeviceInfoPos); // Skip over Manufacturer String
|
||||
|
||||
/* Extract and convert the Model Unicode string to ASCII and print it through the USART */
|
||||
char Model[*DeviceInfoPos];
|
||||
UnicodeToASCII(DeviceInfoPos, Model);
|
||||
printf_P(PSTR(" Model: %s\r\n"), Model);
|
||||
|
||||
DeviceInfoPos += 1 + UNICODE_STRING_LENGTH(*DeviceInfoPos); // Skip over Model String
|
||||
|
||||
/* Extract and convert the Device Version Unicode string to ASCII and print it through the USART */
|
||||
char DeviceVersion[*DeviceInfoPos];
|
||||
UnicodeToASCII(DeviceInfoPos, DeviceVersion);
|
||||
printf_P(PSTR(" Device Version: %s\r\n"), DeviceVersion);
|
||||
|
||||
/* Receive the final response block from the device */
|
||||
if ((ErrorCode = SImage_ReceiveBlockHeader()) != PIPE_RWSTREAM_NoError)
|
||||
{
|
||||
ShowCommandError(ErrorCode, false);
|
||||
USB_Host_SetDeviceConfiguration(0);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Verify that the command completed successfully */
|
||||
if ((PIMA_ReceivedBlock.Type != PIMA_CONTAINER_ResponseBlock) || (PIMA_ReceivedBlock.Code != PIMA_RESPONSE_OK))
|
||||
{
|
||||
ShowCommandError(PIMA_ReceivedBlock.Code, true);
|
||||
USB_Host_SetDeviceConfiguration(0);
|
||||
return;
|
||||
}
|
||||
|
||||
puts_P(PSTR("Opening Session...\r\n"));
|
||||
|
||||
PIMA_SendBlock = (PIMA_Container_t)
|
||||
{
|
||||
.DataLength = PIMA_COMMAND_SIZE(1),
|
||||
.Type = PIMA_CONTAINER_CommandBlock,
|
||||
.Code = PIMA_OPERATION_OPENSESSION,
|
||||
.TransactionID = 0x00000000,
|
||||
.Params = {0x00000001},
|
||||
};
|
||||
|
||||
/* Send the OPENSESSION block, open a session with an ID of 0x0001 */
|
||||
SImage_SendBlockHeader();
|
||||
|
||||
/* Receive the response block from the device */
|
||||
if ((ErrorCode = SImage_ReceiveBlockHeader()) != PIPE_RWSTREAM_NoError)
|
||||
{
|
||||
ShowCommandError(ErrorCode, false);
|
||||
USB_Host_SetDeviceConfiguration(0);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Verify that the command completed successfully */
|
||||
if ((PIMA_ReceivedBlock.Type != PIMA_CONTAINER_ResponseBlock) || (PIMA_ReceivedBlock.Code != PIMA_RESPONSE_OK))
|
||||
{
|
||||
ShowCommandError(PIMA_ReceivedBlock.Code, true);
|
||||
USB_Host_SetDeviceConfiguration(0);
|
||||
return;
|
||||
}
|
||||
|
||||
puts_P(PSTR("Closing Session...\r\n"));
|
||||
|
||||
PIMA_SendBlock = (PIMA_Container_t)
|
||||
{
|
||||
.DataLength = PIMA_COMMAND_SIZE(1),
|
||||
.Type = PIMA_CONTAINER_CommandBlock,
|
||||
.Code = PIMA_OPERATION_CLOSESESSION,
|
||||
.TransactionID = 0x00000001,
|
||||
.Params = {0x00000001},
|
||||
};
|
||||
|
||||
/* Send the CLOSESESSION block, close the session with an ID of 0x0001 */
|
||||
SImage_SendBlockHeader();
|
||||
|
||||
/* Receive the response block from the device */
|
||||
if ((ErrorCode = SImage_ReceiveBlockHeader()) != PIPE_RWSTREAM_NoError)
|
||||
{
|
||||
ShowCommandError(ErrorCode, false);
|
||||
USB_Host_SetDeviceConfiguration(0);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Verify that the command completed successfully */
|
||||
if ((PIMA_ReceivedBlock.Type != PIMA_CONTAINER_ResponseBlock) || (PIMA_ReceivedBlock.Code != PIMA_RESPONSE_OK))
|
||||
{
|
||||
ShowCommandError(PIMA_ReceivedBlock.Code, true);
|
||||
USB_Host_SetDeviceConfiguration(0);
|
||||
return;
|
||||
}
|
||||
|
||||
puts_P(PSTR("Done.\r\n"));
|
||||
|
||||
/* Indicate device no longer busy */
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_READY);
|
||||
USB_Host_SetDeviceConfiguration(0);
|
||||
}
|
||||
|
||||
/** Function to convert a given Unicode encoded string to ASCII. This function will only work correctly on Unicode
|
||||
|
|
|
@ -69,8 +69,8 @@
|
|||
#define LEDMASK_USB_BUSY LEDS_LED2
|
||||
|
||||
/* Function Prototypes: */
|
||||
void StillImage_Task(void);
|
||||
void SetupHardware(void);
|
||||
void StillImageHost_Task(void);
|
||||
|
||||
void EVENT_USB_Host_HostError(const uint8_t ErrorCode);
|
||||
void EVENT_USB_Host_DeviceAttached(void);
|
||||
|
|
|
@ -50,7 +50,8 @@ int main(void)
|
|||
|
||||
for (;;)
|
||||
{
|
||||
CDC_Host_Task();
|
||||
CDCHost_Task();
|
||||
|
||||
USB_USBTask();
|
||||
}
|
||||
}
|
||||
|
@ -97,6 +98,35 @@ void EVENT_USB_Host_DeviceUnattached(void)
|
|||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
puts_P(PSTR("CDC Device Enumerated.\r\n"));
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_READY);
|
||||
}
|
||||
|
||||
|
@ -126,102 +156,57 @@ void EVENT_USB_Host_DeviceEnumerationFailed(const uint8_t ErrorCode,
|
|||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
}
|
||||
|
||||
/** Task to set the configuration of the attached device after it has been enumerated, and to read in
|
||||
* data received from the attached CDC device and print it to the serial port.
|
||||
/** Task to read in data received from the attached CDC device and print it to the serial port.
|
||||
*/
|
||||
void CDC_Host_Task(void)
|
||||
void CDCHost_Task(void)
|
||||
{
|
||||
uint8_t ErrorCode;
|
||||
if (USB_HostState != HOST_STATE_Configured)
|
||||
return;
|
||||
|
||||
switch (USB_HostState)
|
||||
/* Select the data IN pipe */
|
||||
Pipe_SelectPipe(CDC_DATA_IN_PIPE);
|
||||
Pipe_Unfreeze();
|
||||
|
||||
/* Check to see if a packet has been received */
|
||||
if (Pipe_IsINReceived())
|
||||
{
|
||||
case HOST_STATE_Addressed:
|
||||
puts_P(PSTR("Getting Config Data.\r\n"));
|
||||
/* Re-freeze IN pipe after the packet has been received */
|
||||
Pipe_Freeze();
|
||||
|
||||
/* 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"));
|
||||
/* Check if data is in the pipe */
|
||||
if (Pipe_IsReadWriteAllowed())
|
||||
{
|
||||
/* Get the length of the pipe data, and create a new buffer to hold it */
|
||||
uint16_t BufferLength = Pipe_BytesInPipe();
|
||||
uint8_t Buffer[BufferLength];
|
||||
|
||||
printf_P(PSTR(" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
|
||||
/* Read in the pipe data to the temporary buffer */
|
||||
Pipe_Read_Stream_LE(Buffer, BufferLength, NULL);
|
||||
|
||||
/* Indicate error via status LEDs */
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
/* Print out the buffer contents to the USART */
|
||||
for (uint16_t BufferByte = 0; BufferByte < BufferLength; BufferByte++)
|
||||
putchar(Buffer[BufferByte]);
|
||||
}
|
||||
|
||||
/* Wait until USB device disconnected */
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
/* 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);
|
||||
|
||||
/* Indicate error via status LEDs */
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
|
||||
/* Wait until USB device disconnected */
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
puts_P(PSTR("CDC Device Enumerated.\r\n"));
|
||||
|
||||
USB_HostState = HOST_STATE_Configured;
|
||||
break;
|
||||
case HOST_STATE_Configured:
|
||||
/* Select the data IN pipe */
|
||||
Pipe_SelectPipe(CDC_DATA_IN_PIPE);
|
||||
Pipe_Unfreeze();
|
||||
|
||||
/* Check to see if a packet has been received */
|
||||
if (Pipe_IsINReceived())
|
||||
{
|
||||
/* Re-freeze IN pipe after the packet has been received */
|
||||
Pipe_Freeze();
|
||||
|
||||
/* Check if data is in the pipe */
|
||||
if (Pipe_IsReadWriteAllowed())
|
||||
{
|
||||
/* Get the length of the pipe data, and create a new buffer to hold it */
|
||||
uint16_t BufferLength = Pipe_BytesInPipe();
|
||||
uint8_t Buffer[BufferLength];
|
||||
|
||||
/* Read in the pipe data to the temporary buffer */
|
||||
Pipe_Read_Stream_LE(Buffer, BufferLength, NULL);
|
||||
|
||||
/* Print out the buffer contents to the USART */
|
||||
for (uint16_t BufferByte = 0; BufferByte < BufferLength; BufferByte++)
|
||||
putchar(Buffer[BufferByte]);
|
||||
}
|
||||
|
||||
/* Clear the pipe after it is read, ready for the next packet */
|
||||
Pipe_ClearIN();
|
||||
}
|
||||
|
||||
/* Re-freeze IN pipe after use */
|
||||
Pipe_Freeze();
|
||||
|
||||
/* Select and unfreeze the notification pipe */
|
||||
Pipe_SelectPipe(CDC_NOTIFICATION_PIPE);
|
||||
Pipe_Unfreeze();
|
||||
|
||||
/* Check if a packet has been received */
|
||||
if (Pipe_IsINReceived())
|
||||
{
|
||||
/* Discard the unused event notification */
|
||||
Pipe_ClearIN();
|
||||
}
|
||||
|
||||
/* Freeze notification IN pipe after use */
|
||||
Pipe_Freeze();
|
||||
|
||||
break;
|
||||
/* Clear the pipe after it is read, ready for the next packet */
|
||||
Pipe_ClearIN();
|
||||
}
|
||||
|
||||
/* Re-freeze IN pipe after use */
|
||||
Pipe_Freeze();
|
||||
|
||||
/* Select and unfreeze the notification pipe */
|
||||
Pipe_SelectPipe(CDC_NOTIFICATION_PIPE);
|
||||
Pipe_Unfreeze();
|
||||
|
||||
/* Check if a packet has been received */
|
||||
if (Pipe_IsINReceived())
|
||||
{
|
||||
/* Discard the unused event notification */
|
||||
Pipe_ClearIN();
|
||||
}
|
||||
|
||||
/* Freeze notification IN pipe after use */
|
||||
Pipe_Freeze();
|
||||
}
|
||||
|
||||
|
|
|
@ -67,7 +67,7 @@
|
|||
|
||||
/* Function Prototypes: */
|
||||
void SetupHardware(void);
|
||||
void CDC_Host_Task(void);
|
||||
void CDCHost_Task(void);
|
||||
|
||||
void EVENT_USB_Host_HostError(const uint8_t ErrorCode);
|
||||
void EVENT_USB_Host_DeviceAttached(void);
|
||||
|
|
|
@ -132,8 +132,8 @@
|
|||
* \note This macro should only be used if the device has indicated to the host that it
|
||||
* supports the Remote Wakeup feature in the device descriptors, and should only be
|
||||
* issued if the host is currently allowing remote wakeup events from the device (i.e.,
|
||||
* the \ref USB_RemoteWakeupEnabled flag is set). When the \c NO_DEVICE_REMOTE_WAKEUP compile
|
||||
* time option is used, this macro is unavailable.
|
||||
* the \ref USB_Device_RemoteWakeupEnabled flag is set). When the \c NO_DEVICE_REMOTE_WAKEUP
|
||||
* compile time option is used, this macro is unavailable.
|
||||
* \n\n
|
||||
*
|
||||
* \note The USB clock must be running for this function to operate. If the stack is initialized with
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
#include "../Endpoint.h"
|
||||
|
||||
#if !defined(FIXED_CONTROL_ENDPOINT_SIZE)
|
||||
uint8_t USB_ControlEndpointSize = ENDPOINT_CONTROLEP_DEFAULT_SIZE;
|
||||
uint8_t USB_Device_ControlEndpointSize = ENDPOINT_CONTROLEP_DEFAULT_SIZE;
|
||||
#endif
|
||||
|
||||
bool Endpoint_ConfigureEndpoint_Prv(const uint8_t Number,
|
||||
|
|
|
@ -846,9 +846,9 @@
|
|||
* changed in value.
|
||||
*/
|
||||
#if (!defined(FIXED_CONTROL_ENDPOINT_SIZE) || defined(__DOXYGEN__))
|
||||
extern uint8_t USB_ControlEndpointSize;
|
||||
extern uint8_t USB_Device_ControlEndpointSize;
|
||||
#else
|
||||
#define USB_ControlEndpointSize FIXED_CONTROL_ENDPOINT_SIZE
|
||||
#define USB_Device_ControlEndpointSize FIXED_CONTROL_ENDPOINT_SIZE
|
||||
#endif
|
||||
|
||||
/* Function Prototypes: */
|
||||
|
|
|
@ -137,7 +137,7 @@ void USB_Host_ProcessNextHostState(void)
|
|||
break;
|
||||
}
|
||||
|
||||
USB_ControlPipeSize = DataBuffer[offsetof(USB_Descriptor_Device_t, Endpoint0Size)];
|
||||
USB_Host_ControlPipeSize = DataBuffer[offsetof(USB_Descriptor_Device_t, Endpoint0Size)];
|
||||
|
||||
USB_Host_ResetDevice();
|
||||
|
||||
|
@ -146,7 +146,7 @@ void USB_Host_ProcessNextHostState(void)
|
|||
case HOST_STATE_Default_PostReset:
|
||||
Pipe_ConfigurePipe(PIPE_CONTROLPIPE, EP_TYPE_CONTROL,
|
||||
PIPE_TOKEN_SETUP, ENDPOINT_CONTROLEP,
|
||||
USB_ControlPipeSize, PIPE_BANK_SINGLE);
|
||||
USB_Host_ControlPipeSize, PIPE_BANK_SINGLE);
|
||||
|
||||
if (!(Pipe_IsConfigured()))
|
||||
{
|
||||
|
@ -175,8 +175,9 @@ void USB_Host_ProcessNextHostState(void)
|
|||
case HOST_STATE_Default_PostAddressSet:
|
||||
USB_Host_SetDeviceAddress(USB_HOST_DEVICEADDRESS);
|
||||
|
||||
EVENT_USB_Host_DeviceEnumerationComplete();
|
||||
USB_HostState = HOST_STATE_Addressed;
|
||||
|
||||
EVENT_USB_Host_DeviceEnumerationComplete();
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -253,6 +254,8 @@ static void USB_Host_ResetDevice(void)
|
|||
USB_Host_ResetBus();
|
||||
while (!(USB_Host_IsBusResetComplete()));
|
||||
USB_Host_ResumeBus();
|
||||
|
||||
USB_Host_ConfigurationNumber = 0;
|
||||
|
||||
bool HSOFIEnabled = USB_INT_IsEnabled(USB_INT_HSOFI);
|
||||
|
||||
|
@ -285,88 +288,5 @@ static void USB_Host_ResetDevice(void)
|
|||
USB_INT_Enable(USB_INT_DDISCI);
|
||||
}
|
||||
|
||||
uint8_t USB_Host_SetDeviceConfiguration(const uint8_t ConfigNumber)
|
||||
{
|
||||
USB_ControlRequest = (USB_Request_Header_t)
|
||||
{
|
||||
.bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_DEVICE),
|
||||
.bRequest = REQ_SetConfiguration,
|
||||
.wValue = ConfigNumber,
|
||||
.wIndex = 0,
|
||||
.wLength = 0,
|
||||
};
|
||||
|
||||
Pipe_SelectPipe(PIPE_CONTROLPIPE);
|
||||
|
||||
return USB_Host_SendControlRequest(NULL);
|
||||
}
|
||||
|
||||
uint8_t USB_Host_GetDeviceDescriptor(void* const DeviceDescriptorPtr)
|
||||
{
|
||||
USB_ControlRequest = (USB_Request_Header_t)
|
||||
{
|
||||
.bmRequestType = (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE),
|
||||
.bRequest = REQ_GetDescriptor,
|
||||
.wValue = (DTYPE_Device << 8),
|
||||
.wIndex = 0,
|
||||
.wLength = sizeof(USB_Descriptor_Device_t),
|
||||
};
|
||||
|
||||
Pipe_SelectPipe(PIPE_CONTROLPIPE);
|
||||
|
||||
return USB_Host_SendControlRequest(DeviceDescriptorPtr);
|
||||
}
|
||||
|
||||
uint8_t USB_Host_GetDeviceStringDescriptor(const uint8_t Index,
|
||||
void* const Buffer,
|
||||
const uint8_t BufferLength)
|
||||
{
|
||||
USB_ControlRequest = (USB_Request_Header_t)
|
||||
{
|
||||
.bmRequestType = (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE),
|
||||
.bRequest = REQ_GetDescriptor,
|
||||
.wValue = (DTYPE_String << 8) | Index,
|
||||
.wIndex = 0,
|
||||
.wLength = BufferLength,
|
||||
};
|
||||
|
||||
Pipe_SelectPipe(PIPE_CONTROLPIPE);
|
||||
|
||||
return USB_Host_SendControlRequest(Buffer);
|
||||
}
|
||||
|
||||
uint8_t USB_Host_ClearPipeStall(const uint8_t EndpointNum)
|
||||
{
|
||||
USB_ControlRequest = (USB_Request_Header_t)
|
||||
{
|
||||
.bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_ENDPOINT),
|
||||
.bRequest = REQ_ClearFeature,
|
||||
.wValue = FEATURE_SEL_EndpointHalt,
|
||||
.wIndex = EndpointNum,
|
||||
.wLength = 0,
|
||||
};
|
||||
|
||||
Pipe_SelectPipe(PIPE_CONTROLPIPE);
|
||||
|
||||
return USB_Host_SendControlRequest(NULL);
|
||||
}
|
||||
|
||||
uint8_t USB_Host_SetInterfaceAltSetting(const uint8_t InterfaceIndex,
|
||||
const uint8_t AltSetting)
|
||||
{
|
||||
USB_ControlRequest = (USB_Request_Header_t)
|
||||
{
|
||||
.bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_INTERFACE),
|
||||
.bRequest = REQ_SetInterface,
|
||||
.wValue = AltSetting,
|
||||
.wIndex = InterfaceIndex,
|
||||
.wLength = 0,
|
||||
};
|
||||
|
||||
Pipe_SelectPipe(PIPE_CONTROLPIPE);
|
||||
|
||||
return USB_Host_SendControlRequest(NULL);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -207,6 +207,9 @@
|
|||
/** Suspends the USB bus, preventing any communications from occurring between the host and attached
|
||||
* device until the bus has been resumed. This stops the transmission of the 1MS Start Of Frame
|
||||
* messages to the device.
|
||||
*
|
||||
* \note While the USB bus is suspended, all USB interrupt sources are also disabled; this means that
|
||||
* some events (such as device disconnections) will not fire until the bus is resumed.
|
||||
*/
|
||||
static inline void USB_Host_SuspendBus(void) ATTR_ALWAYS_INLINE;
|
||||
static inline void USB_Host_SuspendBus(void)
|
||||
|
@ -276,73 +279,6 @@
|
|||
return ((UHCON & (1 << RESUME)) ? false : true);
|
||||
}
|
||||
|
||||
/* Function Prototypes: */
|
||||
/** Convenience function. This routine sends a SET CONFIGURATION standard request to the attached
|
||||
* device, with the given configuration index. This can be used to easily set the device
|
||||
* configuration without creating and sending the request manually.
|
||||
*
|
||||
* \note After this routine returns, the control pipe will be selected.
|
||||
*
|
||||
* \param[in] ConfigNumber Configuration index to send to the device.
|
||||
*
|
||||
* \return A value from the \ref USB_Host_SendControlErrorCodes_t enum to indicate the result.
|
||||
*/
|
||||
uint8_t USB_Host_SetDeviceConfiguration(const uint8_t ConfigNumber);
|
||||
|
||||
/** Convenience function. This routine sends a GET DESCRIPTOR standard request to the attached
|
||||
* device, requesting the device descriptor. This can be used to easily retrieve information
|
||||
* about the device such as its VID, PID and power requirements.
|
||||
*
|
||||
* \note After this routine returns, the control pipe will be selected.
|
||||
*
|
||||
* \param[out] DeviceDescriptorPtr Pointer to the destination device descriptor structure where
|
||||
* the read data is to be stored.
|
||||
*
|
||||
* \return A value from the \ref USB_Host_SendControlErrorCodes_t enum to indicate the result.
|
||||
*/
|
||||
uint8_t USB_Host_GetDeviceDescriptor(void* const DeviceDescriptorPtr);
|
||||
|
||||
/** Convenience function. This routine sends a GET DESCRIPTOR standard request to the attached
|
||||
* device, requesting the string descriptor of the specified index. This can be used to easily
|
||||
* retrieve string descriptors from the device by index, after the index is obtained from the
|
||||
* Device or Configuration descriptors.
|
||||
*
|
||||
* \note After this routine returns, the control pipe will be selected.
|
||||
*
|
||||
* \param[in] Index Index of the string index to retrieve.
|
||||
* \param[out] Buffer Pointer to the destination buffer where the retrieved string descriptor is
|
||||
* to be stored.
|
||||
* \param[in] BufferLength Maximum size of the string descriptor which can be stored into the buffer.
|
||||
*
|
||||
* \return A value from the \ref USB_Host_SendControlErrorCodes_t enum to indicate the result.
|
||||
*/
|
||||
uint8_t USB_Host_GetDeviceStringDescriptor(const uint8_t Index,
|
||||
void* const Buffer,
|
||||
const uint8_t BufferLength);
|
||||
|
||||
/** Clears a stall condition on the given pipe, via a CLEAR FEATURE standard request to the attached device.
|
||||
*
|
||||
* \note After this routine returns, the control pipe will be selected.
|
||||
*
|
||||
* \param[in] EndpointIndex Index of the endpoint to clear, including the endpoint's direction.
|
||||
*
|
||||
* \return A value from the \ref USB_Host_SendControlErrorCodes_t enum to indicate the result.
|
||||
*/
|
||||
uint8_t USB_Host_ClearPipeStall(const uint8_t EndpointIndex);
|
||||
|
||||
/** Selects a given alternative setting for the specified interface, via a SET INTERFACE standard request to
|
||||
* the attached device.
|
||||
*
|
||||
* \note After this routine returns, the control pipe will be selected.
|
||||
*
|
||||
* \param[in] InterfaceIndex Index of the interface whose alternative setting is to be altered.
|
||||
* \param[in] AltSetting Index of the interface's alternative setting which is to be selected.
|
||||
*
|
||||
* \return A value from the \ref USB_Host_SendControlErrorCodes_t enum to indicate the result.
|
||||
*/
|
||||
uint8_t USB_Host_SetInterfaceAltSetting(const uint8_t InterfaceIndex,
|
||||
const uint8_t AltSetting);
|
||||
|
||||
/* Private Interface - For use in library only: */
|
||||
#if !defined(__DOXYGEN__)
|
||||
/* Macros: */
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
|
||||
#include "../Pipe.h"
|
||||
|
||||
uint8_t USB_ControlPipeSize = PIPE_CONTROLPIPE_DEFAULT_SIZE;
|
||||
uint8_t USB_Host_ControlPipeSize = PIPE_CONTROLPIPE_DEFAULT_SIZE;
|
||||
|
||||
bool Pipe_ConfigurePipe(const uint8_t Number,
|
||||
const uint8_t Type,
|
||||
|
|
|
@ -804,7 +804,7 @@
|
|||
* \note This variable should be treated as read-only in the user application, and never manually
|
||||
* changed in value.
|
||||
*/
|
||||
extern uint8_t USB_ControlPipeSize;
|
||||
extern uint8_t USB_Host_ControlPipeSize;
|
||||
|
||||
/* Function Prototypes: */
|
||||
/** Configures the specified pipe number with the given pipe type, token, target endpoint number in the
|
||||
|
|
|
@ -58,7 +58,7 @@ uint8_t TEMPLATE_FUNC_NAME (const void* const Buffer,
|
|||
{
|
||||
uint16_t BytesInEndpoint = Endpoint_BytesInEndpoint();
|
||||
|
||||
while (Length && (BytesInEndpoint < USB_ControlEndpointSize))
|
||||
while (Length && (BytesInEndpoint < USB_Device_ControlEndpointSize))
|
||||
{
|
||||
TEMPLATE_TRANSFER_BYTE(DataStream);
|
||||
TEMPLATE_BUFFER_MOVE(DataStream, 1);
|
||||
|
@ -66,7 +66,7 @@ uint8_t TEMPLATE_FUNC_NAME (const void* const Buffer,
|
|||
BytesInEndpoint++;
|
||||
}
|
||||
|
||||
LastPacketFull = (BytesInEndpoint == USB_ControlEndpointSize);
|
||||
LastPacketFull = (BytesInEndpoint == USB_Device_ControlEndpointSize);
|
||||
Endpoint_ClearIN();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -178,15 +178,15 @@ void USB_ResetInterface(void)
|
|||
#if defined(USB_CAN_BE_DEVICE)
|
||||
static void USB_Init_Device(void)
|
||||
{
|
||||
USB_DeviceState = DEVICE_STATE_Unattached;
|
||||
USB_ConfigurationNumber = 0;
|
||||
USB_DeviceState = DEVICE_STATE_Unattached;
|
||||
USB_Device_ConfigurationNumber = 0;
|
||||
|
||||
#if !defined(NO_DEVICE_REMOTE_WAKEUP)
|
||||
USB_RemoteWakeupEnabled = false;
|
||||
USB_Device_RemoteWakeupEnabled = false;
|
||||
#endif
|
||||
|
||||
#if !defined(NO_DEVICE_SELF_POWER)
|
||||
USB_CurrentlySelfPowered = false;
|
||||
USB_Device_CurrentlySelfPowered = false;
|
||||
#endif
|
||||
|
||||
#if !defined(FIXED_CONTROL_ENDPOINT_SIZE)
|
||||
|
@ -199,21 +199,21 @@ static void USB_Init_Device(void)
|
|||
if (CALLBACK_USB_GetDescriptor((DTYPE_Device << 8), 0, (void*)&DeviceDescriptorPtr, &DescriptorAddressSpace) != NO_DESCRIPTOR)
|
||||
{
|
||||
if (DescriptorAddressSpace == MEMSPACE_FLASH)
|
||||
USB_ControlEndpointSize = pgm_read_byte(&DeviceDescriptorPtr->Endpoint0Size);
|
||||
USB_Device_ControlEndpointSize = pgm_read_byte(&DeviceDescriptorPtr->Endpoint0Size);
|
||||
else if (DescriptorAddressSpace == MEMSPACE_EEPROM)
|
||||
USB_ControlEndpointSize = eeprom_read_byte(&DeviceDescriptorPtr->Endpoint0Size);
|
||||
USB_Device_ControlEndpointSize = eeprom_read_byte(&DeviceDescriptorPtr->Endpoint0Size);
|
||||
else
|
||||
USB_ControlEndpointSize = DeviceDescriptorPtr->Endpoint0Size;
|
||||
USB_Device_ControlEndpointSize = DeviceDescriptorPtr->Endpoint0Size;
|
||||
}
|
||||
#else
|
||||
if (CALLBACK_USB_GetDescriptor((DTYPE_Device << 8), 0, (void*)&DeviceDescriptorPtr) != NO_DESCRIPTOR)
|
||||
{
|
||||
#if defined(USE_RAM_DESCRIPTORS)
|
||||
USB_ControlEndpointSize = DeviceDescriptorPtr->Endpoint0Size;
|
||||
USB_Device_ControlEndpointSize = DeviceDescriptorPtr->Endpoint0Size;
|
||||
#elif defined(USE_EEPROM_DESCRIPTORS)
|
||||
USB_ControlEndpointSize = eeprom_read_byte(&DeviceDescriptorPtr->Endpoint0Size);
|
||||
USB_Device_ControlEndpointSize = eeprom_read_byte(&DeviceDescriptorPtr->Endpoint0Size);
|
||||
#else
|
||||
USB_ControlEndpointSize = pgm_read_byte(&DeviceDescriptorPtr->Endpoint0Size);
|
||||
USB_Device_ControlEndpointSize = pgm_read_byte(&DeviceDescriptorPtr->Endpoint0Size);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
@ -229,7 +229,7 @@ static void USB_Init_Device(void)
|
|||
#endif
|
||||
|
||||
Endpoint_ConfigureEndpoint(ENDPOINT_CONTROLEP, EP_TYPE_CONTROL,
|
||||
ENDPOINT_DIR_OUT, USB_ControlEndpointSize,
|
||||
ENDPOINT_DIR_OUT, USB_Device_ControlEndpointSize,
|
||||
ENDPOINT_BANK_SINGLE);
|
||||
|
||||
USB_INT_Clear(USB_INT_SUSPI);
|
||||
|
@ -243,8 +243,9 @@ static void USB_Init_Device(void)
|
|||
#if defined(USB_CAN_BE_HOST)
|
||||
static void USB_Init_Host(void)
|
||||
{
|
||||
USB_HostState = HOST_STATE_Unattached;
|
||||
USB_ControlPipeSize = PIPE_CONTROLPIPE_DEFAULT_SIZE;
|
||||
USB_HostState = HOST_STATE_Unattached;
|
||||
USB_Host_ConfigurationNumber = 0;
|
||||
USB_Host_ControlPipeSize = PIPE_CONTROLPIPE_DEFAULT_SIZE;
|
||||
|
||||
USB_Host_HostMode_On();
|
||||
|
||||
|
@ -254,7 +255,7 @@ static void USB_Init_Host(void)
|
|||
|
||||
USB_INT_Enable(USB_INT_SRPI);
|
||||
USB_INT_Enable(USB_INT_BCERRI);
|
||||
|
||||
|
||||
USB_Attach();
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -144,7 +144,7 @@ ISR(USB_GEN_vect, ISR_BLOCK)
|
|||
USB_INT_Disable(USB_INT_WAKEUPI);
|
||||
USB_INT_Enable(USB_INT_SUSPI);
|
||||
|
||||
if (USB_ConfigurationNumber)
|
||||
if (USB_Device_ConfigurationNumber)
|
||||
USB_DeviceState = DEVICE_STATE_Configured;
|
||||
else
|
||||
USB_DeviceState = (USB_Device_IsAddressSet()) ? DEVICE_STATE_Configured : DEVICE_STATE_Powered;
|
||||
|
@ -160,15 +160,15 @@ ISR(USB_GEN_vect, ISR_BLOCK)
|
|||
{
|
||||
USB_INT_Clear(USB_INT_EORSTI);
|
||||
|
||||
USB_DeviceState = DEVICE_STATE_Default;
|
||||
USB_ConfigurationNumber = 0;
|
||||
USB_DeviceState = DEVICE_STATE_Default;
|
||||
USB_Device_ConfigurationNumber = 0;
|
||||
|
||||
USB_INT_Clear(USB_INT_SUSPI);
|
||||
USB_INT_Disable(USB_INT_SUSPI);
|
||||
USB_INT_Enable(USB_INT_WAKEUPI);
|
||||
|
||||
Endpoint_ConfigureEndpoint(ENDPOINT_CONTROLEP, EP_TYPE_CONTROL,
|
||||
ENDPOINT_DIR_OUT, USB_ControlEndpointSize,
|
||||
ENDPOINT_DIR_OUT, USB_Device_ControlEndpointSize,
|
||||
ENDPOINT_BANK_SINGLE);
|
||||
|
||||
#if defined(INTERRUPT_CONTROL_ENDPOINT)
|
||||
|
|
|
@ -36,14 +36,14 @@
|
|||
#define __INCLUDE_FROM_DEVICESTDREQ_C
|
||||
#include "DeviceStandardReq.h"
|
||||
|
||||
uint8_t USB_ConfigurationNumber;
|
||||
uint8_t USB_Device_ConfigurationNumber;
|
||||
|
||||
#if !defined(NO_DEVICE_SELF_POWER)
|
||||
bool USB_CurrentlySelfPowered;
|
||||
bool USB_Device_CurrentlySelfPowered;
|
||||
#endif
|
||||
|
||||
#if !defined(NO_DEVICE_REMOTE_WAKEUP)
|
||||
bool USB_RemoteWakeupEnabled;
|
||||
bool USB_Device_RemoteWakeupEnabled;
|
||||
#endif
|
||||
|
||||
void USB_Device_ProcessControlRequest(void)
|
||||
|
@ -184,11 +184,11 @@ static void USB_Device_SetConfiguration(void)
|
|||
|
||||
Endpoint_ClearSETUP();
|
||||
|
||||
USB_ConfigurationNumber = (uint8_t)USB_ControlRequest.wValue;
|
||||
USB_Device_ConfigurationNumber = (uint8_t)USB_ControlRequest.wValue;
|
||||
|
||||
Endpoint_ClearStatusStage();
|
||||
|
||||
if (USB_ConfigurationNumber)
|
||||
if (USB_Device_ConfigurationNumber)
|
||||
USB_DeviceState = DEVICE_STATE_Configured;
|
||||
else
|
||||
USB_DeviceState = (USB_Device_IsAddressSet()) ? DEVICE_STATE_Configured : DEVICE_STATE_Powered;
|
||||
|
@ -200,7 +200,7 @@ static void USB_Device_GetConfiguration(void)
|
|||
{
|
||||
Endpoint_ClearSETUP();
|
||||
|
||||
Endpoint_Write_8(USB_ConfigurationNumber);
|
||||
Endpoint_Write_8(USB_Device_ConfigurationNumber);
|
||||
Endpoint_ClearIN();
|
||||
|
||||
Endpoint_ClearStatusStage();
|
||||
|
@ -285,12 +285,12 @@ static void USB_Device_GetStatus(void)
|
|||
#if !defined(NO_DEVICE_SELF_POWER) || !defined(NO_DEVICE_REMOTE_WAKEUP)
|
||||
case (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE):
|
||||
#if !defined(NO_DEVICE_SELF_POWER)
|
||||
if (USB_CurrentlySelfPowered)
|
||||
if (USB_Device_CurrentlySelfPowered)
|
||||
CurrentStatus |= FEATURE_SELFPOWERED_ENABLED;
|
||||
#endif
|
||||
|
||||
#if !defined(NO_DEVICE_REMOTE_WAKEUP)
|
||||
if (USB_RemoteWakeupEnabled)
|
||||
if (USB_Device_RemoteWakeupEnabled)
|
||||
CurrentStatus |= FEATURE_REMOTE_WAKEUP_ENABLED;
|
||||
#endif
|
||||
break;
|
||||
|
@ -324,7 +324,7 @@ static void USB_Device_ClearSetFeature(void)
|
|||
#if !defined(NO_DEVICE_REMOTE_WAKEUP)
|
||||
case REQREC_DEVICE:
|
||||
if ((uint8_t)USB_ControlRequest.wValue == FEATURE_SEL_DeviceRemoteWakeup)
|
||||
USB_RemoteWakeupEnabled = (USB_ControlRequest.bRequest == REQ_SetFeature);
|
||||
USB_Device_RemoteWakeupEnabled = (USB_ControlRequest.bRequest == REQ_SetFeature);
|
||||
else
|
||||
return;
|
||||
|
||||
|
|
|
@ -91,7 +91,7 @@
|
|||
*
|
||||
* \ingroup Group_Device
|
||||
*/
|
||||
extern uint8_t USB_ConfigurationNumber;
|
||||
extern uint8_t USB_Device_ConfigurationNumber;
|
||||
|
||||
#if !defined(NO_DEVICE_REMOTE_WAKEUP)
|
||||
/** Indicates if the host is currently allowing the device to issue remote wakeup events. If this
|
||||
|
@ -108,7 +108,7 @@
|
|||
*
|
||||
* \ingroup Group_Device
|
||||
*/
|
||||
extern bool USB_RemoteWakeupEnabled;
|
||||
extern bool USB_Device_RemoteWakeupEnabled;
|
||||
#endif
|
||||
|
||||
#if !defined(NO_DEVICE_SELF_POWER)
|
||||
|
@ -118,7 +118,7 @@
|
|||
*
|
||||
* \ingroup Group_Device
|
||||
*/
|
||||
extern bool USB_CurrentlySelfPowered;
|
||||
extern bool USB_Device_CurrentlySelfPowered;
|
||||
#endif
|
||||
|
||||
/* Private Interface - For use in library only: */
|
||||
|
|
|
@ -249,7 +249,7 @@
|
|||
* This event is time-critical; exceeding OS-specific delays within this event handler (typically of around
|
||||
* one second) will prevent the device from enumerating correctly.
|
||||
*
|
||||
* This event fires after the value of \ref USB_ConfigurationNumber has been changed.
|
||||
* This event fires after the value of \ref USB_Device_ConfigurationNumber has been changed.
|
||||
*
|
||||
* \note This event does not exist if the \c USB_HOST_ONLY token is supplied to the compiler (see
|
||||
* \ref Group_USBManagement documentation).
|
||||
|
|
|
@ -65,8 +65,7 @@
|
|||
|
||||
/* Public Interface - May be used in end-application: */
|
||||
/* Enums: */
|
||||
/** Enum for the various states of the USB Host state machine. Only some states are
|
||||
* implemented in the LUFA library - other states are left to the user to implement.
|
||||
/** Enum for the various states of the USB Host state machine.
|
||||
*
|
||||
* For information on each possible USB host state, refer to the USB 2.0 specification.
|
||||
* Several of the USB host states are broken up further into multiple smaller sub-states,
|
||||
|
@ -76,94 +75,49 @@
|
|||
*/
|
||||
enum USB_Host_States_t
|
||||
{
|
||||
HOST_STATE_WaitForDeviceRemoval = 0, /**< Internally implemented by the library. This state can be
|
||||
* used by the library to wait until the attached device is
|
||||
* removed by the user - useful for when an error occurs or
|
||||
* further communication with the device is not needed. This
|
||||
* allows for other code to run while the state machine is
|
||||
* effectively disabled.
|
||||
HOST_STATE_WaitForDevice = 0, /**< This state indicates that the stack is waiting for an interval
|
||||
* to elapse before continuing with the next step of the device
|
||||
* enumeration process.
|
||||
*/
|
||||
HOST_STATE_WaitForDevice = 1, /**< Internally implemented by the library. This state indicates
|
||||
* that the stack is waiting for an interval to elapse before
|
||||
* continuing with the next step of the device enumeration
|
||||
HOST_STATE_Unattached = 1, /**< This state indicates that the host state machine is waiting for
|
||||
* a device to be attached so that it can start the enumeration process.
|
||||
*/
|
||||
HOST_STATE_Powered = 2, /**< This state indicates that a device has been attached, and the
|
||||
* library's internals are being configured to begin the enumeration
|
||||
* process.
|
||||
*
|
||||
* \note Do not manually change to this state in the user code.
|
||||
*/
|
||||
HOST_STATE_Unattached = 2, /**< Internally implemented by the library. This state indicates
|
||||
* that the host state machine is waiting for a device to be
|
||||
* attached so that it can start the enumeration process.
|
||||
*
|
||||
* \note Do not manually change to this state in the user code.
|
||||
HOST_STATE_Powered_WaitForDeviceSettle = 3, /**< This state indicates that the stack is waiting for the initial
|
||||
* settling period to elapse before beginning the enumeration process.
|
||||
*/
|
||||
HOST_STATE_Powered = 3, /**< Internally implemented by the library. This state indicates
|
||||
* that a device has been attached, and the library's internals
|
||||
* are being configured to begin the enumeration process.
|
||||
*
|
||||
* \note Do not manually change to this state in the user code.
|
||||
HOST_STATE_Powered_WaitForConnect = 4, /**< This state indicates that the stack is waiting for a connection event
|
||||
* from the USB controller to indicate a valid USB device has been attached
|
||||
* to the bus and is ready to be enumerated.
|
||||
*/
|
||||
HOST_STATE_Powered_WaitForDeviceSettle = 4, /**< Internally implemented by the library. This state indicates
|
||||
* that the stack is waiting for the initial settling period to
|
||||
* elapse before beginning the enumeration process.
|
||||
*
|
||||
* \note Do not manually change to this state in the user code.
|
||||
HOST_STATE_Powered_DoReset = 5, /**< This state indicates that a valid USB device has been attached, and that
|
||||
* it will now be reset to ensure it is ready for enumeration.
|
||||
*/
|
||||
HOST_STATE_Powered_WaitForConnect = 5, /**< Internally implemented by the library. This state indicates
|
||||
* that the stack is waiting for a connection event from the USB
|
||||
* controller to indicate a valid USB device has been attached to
|
||||
* the bus and is ready to be enumerated.
|
||||
*
|
||||
* \note Do not manually change to this state in the user code.
|
||||
HOST_STATE_Powered_ConfigPipe = 6, /**< This state indicates that the attached device is currently powered and
|
||||
* reset, and that the control pipe is now being configured by the stack.
|
||||
*/
|
||||
HOST_STATE_Powered_DoReset = 6, /**< Internally implemented by the library. This state indicates
|
||||
* that a valid USB device has been attached, and that it is
|
||||
* will now be reset to ensure it is ready for enumeration.
|
||||
*
|
||||
* \note Do not manually change to this state in the user code.
|
||||
*/
|
||||
HOST_STATE_Powered_ConfigPipe = 7, /**< Internally implemented by the library. This state indicates
|
||||
* that the attached device is currently powered and reset, and
|
||||
* that the control pipe is now being configured by the stack.
|
||||
*
|
||||
* \note Do not manually change to this state in the user code.
|
||||
*/
|
||||
HOST_STATE_Default = 8, /**< Internally implemented by the library. This state indicates
|
||||
* that the stack is currently retrieving the control endpoint's
|
||||
* size from the device, so that the control pipe can be altered
|
||||
HOST_STATE_Default = 7, /**< This state indicates that the stack is currently retrieving the control
|
||||
* endpoint's size from the device, so that the control pipe can be altered
|
||||
* to match.
|
||||
*
|
||||
* \note Do not manually change to this state in the user code.
|
||||
*/
|
||||
HOST_STATE_Default_PostReset = 9, /**< Internally implemented by the library. This state indicates that
|
||||
* the control pipe is being reconfigured to match the retrieved
|
||||
* control endpoint size from the device, and the device's USB bus
|
||||
* address is being set.
|
||||
*
|
||||
* \note Do not manually change to this state in the user code.
|
||||
HOST_STATE_Default_PostReset = 8, /**< This state indicates that the control pipe is being reconfigured to match
|
||||
* the retrieved control endpoint size from the device, and the device's USB
|
||||
* bus address is being set.
|
||||
*/
|
||||
HOST_STATE_Default_PostAddressSet = 10, /**< Internally implemented by the library. This state indicates that
|
||||
* the device's address has now been set, and the stack is has now
|
||||
* completed the device enumeration process. This state causes the
|
||||
* stack to change the current USB device address to that set for
|
||||
* the connected device, before progressing to the user-implemented
|
||||
* \ref HOST_STATE_Addressed state for further communications.
|
||||
*
|
||||
* \note Do not manually change to this state in the user code.
|
||||
HOST_STATE_Default_PostAddressSet = 9, /**< This state indicates that the device's address has now been set, and the
|
||||
* stack is has now completed the device enumeration process. This state causes
|
||||
* the stack to change the current USB device address to that set for the
|
||||
* connected device, before progressing to the \ref HOST_STATE_Addressed state
|
||||
* ready for use in the user application.
|
||||
*/
|
||||
HOST_STATE_Addressed = 11, /**< May be implemented by the user project. This state should
|
||||
* set the device configuration before progressing to the
|
||||
* \ref HOST_STATE_Configured state. Other processing (such as the
|
||||
* retrieval and processing of the device descriptor) should also
|
||||
* be placed in this state.
|
||||
HOST_STATE_Addressed = 10, /**< Indicates that the device has been enumerated and addressed, and is now waiting
|
||||
* for the user application to configure the device ready for use.
|
||||
*/
|
||||
HOST_STATE_Configured = 12, /**< May be implemented by the user project. This state should implement the
|
||||
* actual work performed on the attached device and changed to the
|
||||
* \ref HOST_STATE_Suspended or \ref HOST_STATE_WaitForDeviceRemoval states as needed.
|
||||
*/
|
||||
HOST_STATE_Suspended = 15, /**< May be implemented by the user project. This state should be maintained
|
||||
* while the bus is suspended, and changed to either the \ref HOST_STATE_Configured
|
||||
* (after resuming the bus with the USB_Host_ResumeBus() macro) or the
|
||||
* \ref HOST_STATE_WaitForDeviceRemoval states as needed.
|
||||
HOST_STATE_Configured = 11, /**< Indicates that the device has been configured into a valid device configuration,
|
||||
* ready for general use by the user application.
|
||||
*/
|
||||
};
|
||||
|
||||
|
|
|
@ -36,6 +36,8 @@
|
|||
#define __INCLUDE_FROM_HOSTSTDREQ_C
|
||||
#include "HostStandardReq.h"
|
||||
|
||||
uint8_t USB_Host_ConfigurationNumber;
|
||||
|
||||
uint8_t USB_Host_SendControlRequest(void* const BufferPtr)
|
||||
{
|
||||
uint8_t* DataStream = (uint8_t*)BufferPtr;
|
||||
|
@ -119,7 +121,7 @@ uint8_t USB_Host_SendControlRequest(void* const BufferPtr)
|
|||
if ((ReturnStatus = USB_Host_WaitForIOS(USB_HOST_WAITFOR_OutReady)) != HOST_SENDCONTROL_Successful)
|
||||
goto End_Of_Control_Send;
|
||||
|
||||
while (DataLen && (Pipe_BytesInPipe() < USB_ControlPipeSize))
|
||||
while (DataLen && (Pipe_BytesInPipe() < USB_Host_ControlPipeSize))
|
||||
{
|
||||
Pipe_Write_8(*(DataStream++));
|
||||
DataLen--;
|
||||
|
@ -178,5 +180,96 @@ static uint8_t USB_Host_WaitForIOS(const uint8_t WaitType)
|
|||
return HOST_SENDCONTROL_Successful;
|
||||
}
|
||||
|
||||
uint8_t USB_Host_SetDeviceConfiguration(const uint8_t ConfigNumber)
|
||||
{
|
||||
uint8_t ErrorCode;
|
||||
|
||||
USB_ControlRequest = (USB_Request_Header_t)
|
||||
{
|
||||
.bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_DEVICE),
|
||||
.bRequest = REQ_SetConfiguration,
|
||||
.wValue = ConfigNumber,
|
||||
.wIndex = 0,
|
||||
.wLength = 0,
|
||||
};
|
||||
|
||||
Pipe_SelectPipe(PIPE_CONTROLPIPE);
|
||||
|
||||
if ((ErrorCode = USB_Host_SendControlRequest(NULL)) == HOST_SENDCONTROL_Successful)
|
||||
{
|
||||
USB_Host_ConfigurationNumber = ConfigNumber;
|
||||
USB_HostState = (ConfigNumber) ? HOST_STATE_Configured : HOST_STATE_Addressed;
|
||||
}
|
||||
|
||||
return ErrorCode;
|
||||
}
|
||||
|
||||
uint8_t USB_Host_GetDeviceDescriptor(void* const DeviceDescriptorPtr)
|
||||
{
|
||||
USB_ControlRequest = (USB_Request_Header_t)
|
||||
{
|
||||
.bmRequestType = (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE),
|
||||
.bRequest = REQ_GetDescriptor,
|
||||
.wValue = (DTYPE_Device << 8),
|
||||
.wIndex = 0,
|
||||
.wLength = sizeof(USB_Descriptor_Device_t),
|
||||
};
|
||||
|
||||
Pipe_SelectPipe(PIPE_CONTROLPIPE);
|
||||
|
||||
return USB_Host_SendControlRequest(DeviceDescriptorPtr);
|
||||
}
|
||||
|
||||
uint8_t USB_Host_GetDeviceStringDescriptor(const uint8_t Index,
|
||||
void* const Buffer,
|
||||
const uint8_t BufferLength)
|
||||
{
|
||||
USB_ControlRequest = (USB_Request_Header_t)
|
||||
{
|
||||
.bmRequestType = (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE),
|
||||
.bRequest = REQ_GetDescriptor,
|
||||
.wValue = (DTYPE_String << 8) | Index,
|
||||
.wIndex = 0,
|
||||
.wLength = BufferLength,
|
||||
};
|
||||
|
||||
Pipe_SelectPipe(PIPE_CONTROLPIPE);
|
||||
|
||||
return USB_Host_SendControlRequest(Buffer);
|
||||
}
|
||||
|
||||
uint8_t USB_Host_ClearPipeStall(const uint8_t EndpointNum)
|
||||
{
|
||||
USB_ControlRequest = (USB_Request_Header_t)
|
||||
{
|
||||
.bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_ENDPOINT),
|
||||
.bRequest = REQ_ClearFeature,
|
||||
.wValue = FEATURE_SEL_EndpointHalt,
|
||||
.wIndex = EndpointNum,
|
||||
.wLength = 0,
|
||||
};
|
||||
|
||||
Pipe_SelectPipe(PIPE_CONTROLPIPE);
|
||||
|
||||
return USB_Host_SendControlRequest(NULL);
|
||||
}
|
||||
|
||||
uint8_t USB_Host_SetInterfaceAltSetting(const uint8_t InterfaceIndex,
|
||||
const uint8_t AltSetting)
|
||||
{
|
||||
USB_ControlRequest = (USB_Request_Header_t)
|
||||
{
|
||||
.bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_INTERFACE),
|
||||
.bRequest = REQ_SetInterface,
|
||||
.wValue = AltSetting,
|
||||
.wIndex = InterfaceIndex,
|
||||
.wLength = 0,
|
||||
};
|
||||
|
||||
Pipe_SelectPipe(PIPE_CONTROLPIPE);
|
||||
|
||||
return USB_Host_SendControlRequest(NULL);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -77,6 +77,19 @@
|
|||
HOST_SENDCONTROL_SoftwareTimeOut = 4, /**< The request or data transfer timed out. */
|
||||
};
|
||||
|
||||
/* Global Variables: */
|
||||
/** Indicates the currently set configuration number of the attached device. This indicates the currently
|
||||
* selected configuration value if one has been set sucessfully, or 0 if no configuration has been selected.
|
||||
*
|
||||
* To set a device configuration, call the \ref USB_Host_SetDeviceConfiguration() function.
|
||||
*
|
||||
* \note This variable should be treated as read-only in the user application, and never manually
|
||||
* changed in value.
|
||||
*
|
||||
* \ingroup Group_Host
|
||||
*/
|
||||
extern uint8_t USB_Host_ConfigurationNumber;
|
||||
|
||||
/* Function Prototypes: */
|
||||
/** Sends the request stored in the \ref USB_ControlRequest global structure to the attached device,
|
||||
* and transfers the data stored in the buffer to the device, or from the device to the buffer
|
||||
|
@ -91,6 +104,85 @@
|
|||
*/
|
||||
uint8_t USB_Host_SendControlRequest(void* const BufferPtr);
|
||||
|
||||
/** Convenience function. This routine sends a SET CONFIGURATION standard request to the attached
|
||||
* device, with the given configuration index. This can be used to easily set the device
|
||||
* configuration without creating and sending the request manually.
|
||||
*
|
||||
* This routine will automatically update the \ref USB_HostState and \ref USB_Host_ConfigurationNumber
|
||||
* state variables according to the given function parameters and the result of the request.
|
||||
*
|
||||
* \note After this routine returns, the control pipe will be selected.
|
||||
*
|
||||
* \ingroup Group_PipeControlReq
|
||||
*
|
||||
* \param[in] ConfigNumber Configuration index to send to the device.
|
||||
*
|
||||
* \return A value from the \ref USB_Host_SendControlErrorCodes_t enum to indicate the result.
|
||||
*/
|
||||
uint8_t USB_Host_SetDeviceConfiguration(const uint8_t ConfigNumber);
|
||||
|
||||
/** Convenience function. This routine sends a GET DESCRIPTOR standard request to the attached
|
||||
* device, requesting the device descriptor. This can be used to easily retrieve information
|
||||
* about the device such as its VID, PID and power requirements.
|
||||
*
|
||||
* \note After this routine returns, the control pipe will be selected.
|
||||
*
|
||||
* \ingroup Group_PipeControlReq
|
||||
*
|
||||
* \param[out] DeviceDescriptorPtr Pointer to the destination device descriptor structure where
|
||||
* the read data is to be stored.
|
||||
*
|
||||
* \return A value from the \ref USB_Host_SendControlErrorCodes_t enum to indicate the result.
|
||||
*/
|
||||
uint8_t USB_Host_GetDeviceDescriptor(void* const DeviceDescriptorPtr);
|
||||
|
||||
/** Convenience function. This routine sends a GET DESCRIPTOR standard request to the attached
|
||||
* device, requesting the string descriptor of the specified index. This can be used to easily
|
||||
* retrieve string descriptors from the device by index, after the index is obtained from the
|
||||
* Device or Configuration descriptors.
|
||||
*
|
||||
* \note After this routine returns, the control pipe will be selected.
|
||||
*
|
||||
* \ingroup Group_PipeControlReq
|
||||
*
|
||||
* \param[in] Index Index of the string index to retrieve.
|
||||
* \param[out] Buffer Pointer to the destination buffer where the retrieved string descriptor is
|
||||
* to be stored.
|
||||
* \param[in] BufferLength Maximum size of the string descriptor which can be stored into the buffer.
|
||||
*
|
||||
* \return A value from the \ref USB_Host_SendControlErrorCodes_t enum to indicate the result.
|
||||
*/
|
||||
uint8_t USB_Host_GetDeviceStringDescriptor(const uint8_t Index,
|
||||
void* const Buffer,
|
||||
const uint8_t BufferLength);
|
||||
|
||||
/** Clears a stall condition on the given pipe, via a CLEAR FEATURE standard request to the attached device.
|
||||
*
|
||||
* \note After this routine returns, the control pipe will be selected.
|
||||
*
|
||||
* \ingroup Group_PipeControlReq
|
||||
*
|
||||
* \param[in] EndpointIndex Index of the endpoint to clear, including the endpoint's direction.
|
||||
*
|
||||
* \return A value from the \ref USB_Host_SendControlErrorCodes_t enum to indicate the result.
|
||||
*/
|
||||
uint8_t USB_Host_ClearPipeStall(const uint8_t EndpointIndex);
|
||||
|
||||
/** Selects a given alternative setting for the specified interface, via a SET INTERFACE standard request to
|
||||
* the attached device.
|
||||
*
|
||||
* \note After this routine returns, the control pipe will be selected.
|
||||
*
|
||||
* \ingroup Group_PipeControlReq
|
||||
*
|
||||
* \param[in] InterfaceIndex Index of the interface whose alternative setting is to be altered.
|
||||
* \param[in] AltSetting Index of the interface's alternative setting which is to be selected.
|
||||
*
|
||||
* \return A value from the \ref USB_Host_SendControlErrorCodes_t enum to indicate the result.
|
||||
*/
|
||||
uint8_t USB_Host_SetInterfaceAltSetting(const uint8_t InterfaceIndex,
|
||||
const uint8_t AltSetting);
|
||||
|
||||
/* Private Interface - For use in library only: */
|
||||
#if !defined(__DOXYGEN__)
|
||||
/* Enums: */
|
||||
|
|
|
@ -122,8 +122,8 @@
|
|||
* \note This macro should only be used if the device has indicated to the host that it
|
||||
* supports the Remote Wakeup feature in the device descriptors, and should only be
|
||||
* issued if the host is currently allowing remote wakeup events from the device (i.e.,
|
||||
* the \ref USB_RemoteWakeupEnabled flag is set). When the \c NO_DEVICE_REMOTE_WAKEUP compile
|
||||
* time option is used, this macro is unavailable.
|
||||
* the \ref USB_Device_RemoteWakeupEnabled flag is set). When the \c NO_DEVICE_REMOTE_WAKEUP
|
||||
* compile time option is used, this macro is unavailable.
|
||||
* \n\n
|
||||
*
|
||||
* \note The USB clock must be running for this function to operate. If the stack is initialized with
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
#include "../Endpoint.h"
|
||||
|
||||
#if !defined(FIXED_CONTROL_ENDPOINT_SIZE)
|
||||
uint8_t USB_ControlEndpointSize = ENDPOINT_CONTROLEP_DEFAULT_SIZE;
|
||||
uint8_t USB_Device_ControlEndpointSize = ENDPOINT_CONTROLEP_DEFAULT_SIZE;
|
||||
#endif
|
||||
|
||||
volatile uint32_t USB_SelectedEndpoint = ENDPOINT_CONTROLEP;
|
||||
|
|
|
@ -830,9 +830,9 @@
|
|||
* changed in value.
|
||||
*/
|
||||
#if (!defined(FIXED_CONTROL_ENDPOINT_SIZE) || defined(__DOXYGEN__))
|
||||
extern uint8_t USB_ControlEndpointSize;
|
||||
extern uint8_t USB_Device_ControlEndpointSize;
|
||||
#else
|
||||
#define USB_ControlEndpointSize FIXED_CONTROL_ENDPOINT_SIZE
|
||||
#define USB_Device_ControlEndpointSize FIXED_CONTROL_ENDPOINT_SIZE
|
||||
#endif
|
||||
|
||||
/* Function Prototypes: */
|
||||
|
|
|
@ -137,7 +137,7 @@ void USB_Host_ProcessNextHostState(void)
|
|||
break;
|
||||
}
|
||||
|
||||
USB_ControlPipeSize = DataBuffer[offsetof(USB_Descriptor_Device_t, Endpoint0Size)];
|
||||
USB_Host_ControlPipeSize = DataBuffer[offsetof(USB_Descriptor_Device_t, Endpoint0Size)];
|
||||
|
||||
USB_Host_ResetDevice();
|
||||
|
||||
|
@ -146,7 +146,7 @@ void USB_Host_ProcessNextHostState(void)
|
|||
case HOST_STATE_Default_PostReset:
|
||||
Pipe_ConfigurePipe(PIPE_CONTROLPIPE, EP_TYPE_CONTROL,
|
||||
PIPE_TOKEN_SETUP, ENDPOINT_CONTROLEP,
|
||||
USB_ControlPipeSize, PIPE_BANK_SINGLE);
|
||||
USB_Host_ControlPipeSize, PIPE_BANK_SINGLE);
|
||||
|
||||
if (!(Pipe_IsConfigured()))
|
||||
{
|
||||
|
@ -175,8 +175,9 @@ void USB_Host_ProcessNextHostState(void)
|
|||
case HOST_STATE_Default_PostAddressSet:
|
||||
USB_Host_SetDeviceAddress(USB_HOST_DEVICEADDRESS);
|
||||
|
||||
EVENT_USB_Host_DeviceEnumerationComplete();
|
||||
USB_HostState = HOST_STATE_Addressed;
|
||||
|
||||
EVENT_USB_Host_DeviceEnumerationComplete();
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -253,6 +254,8 @@ static void USB_Host_ResetDevice(void)
|
|||
USB_Host_ResetBus();
|
||||
while (!(USB_Host_IsBusResetComplete()));
|
||||
USB_Host_ResumeBus();
|
||||
|
||||
USB_Host_ConfigurationNumber = 0;
|
||||
|
||||
bool HSOFIEnabled = USB_INT_IsEnabled(USB_INT_HSOFI);
|
||||
|
||||
|
@ -285,88 +288,5 @@ static void USB_Host_ResetDevice(void)
|
|||
USB_INT_Enable(USB_INT_DDISCI);
|
||||
}
|
||||
|
||||
uint8_t USB_Host_SetDeviceConfiguration(const uint8_t ConfigNumber)
|
||||
{
|
||||
USB_ControlRequest = (USB_Request_Header_t)
|
||||
{
|
||||
.bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_DEVICE),
|
||||
.bRequest = REQ_SetConfiguration,
|
||||
.wValue = ConfigNumber,
|
||||
.wIndex = 0,
|
||||
.wLength = 0,
|
||||
};
|
||||
|
||||
Pipe_SelectPipe(PIPE_CONTROLPIPE);
|
||||
|
||||
return USB_Host_SendControlRequest(NULL);
|
||||
}
|
||||
|
||||
uint8_t USB_Host_GetDeviceDescriptor(void* const DeviceDescriptorPtr)
|
||||
{
|
||||
USB_ControlRequest = (USB_Request_Header_t)
|
||||
{
|
||||
.bmRequestType = (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE),
|
||||
.bRequest = REQ_GetDescriptor,
|
||||
.wValue = (DTYPE_Device << 8),
|
||||
.wIndex = 0,
|
||||
.wLength = sizeof(USB_Descriptor_Device_t),
|
||||
};
|
||||
|
||||
Pipe_SelectPipe(PIPE_CONTROLPIPE);
|
||||
|
||||
return USB_Host_SendControlRequest(DeviceDescriptorPtr);
|
||||
}
|
||||
|
||||
uint8_t USB_Host_GetDeviceStringDescriptor(const uint8_t Index,
|
||||
void* const Buffer,
|
||||
const uint8_t BufferLength)
|
||||
{
|
||||
USB_ControlRequest = (USB_Request_Header_t)
|
||||
{
|
||||
.bmRequestType = (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE),
|
||||
.bRequest = REQ_GetDescriptor,
|
||||
.wValue = (DTYPE_String << 8) | Index,
|
||||
.wIndex = 0,
|
||||
.wLength = BufferLength,
|
||||
};
|
||||
|
||||
Pipe_SelectPipe(PIPE_CONTROLPIPE);
|
||||
|
||||
return USB_Host_SendControlRequest(Buffer);
|
||||
}
|
||||
|
||||
uint8_t USB_Host_ClearPipeStall(const uint8_t EndpointNum)
|
||||
{
|
||||
USB_ControlRequest = (USB_Request_Header_t)
|
||||
{
|
||||
.bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_ENDPOINT),
|
||||
.bRequest = REQ_ClearFeature,
|
||||
.wValue = FEATURE_SEL_EndpointHalt,
|
||||
.wIndex = EndpointNum,
|
||||
.wLength = 0,
|
||||
};
|
||||
|
||||
Pipe_SelectPipe(PIPE_CONTROLPIPE);
|
||||
|
||||
return USB_Host_SendControlRequest(NULL);
|
||||
}
|
||||
|
||||
uint8_t USB_Host_SetInterfaceAltSetting(const uint8_t InterfaceIndex,
|
||||
const uint8_t AltSetting)
|
||||
{
|
||||
USB_ControlRequest = (USB_Request_Header_t)
|
||||
{
|
||||
.bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_INTERFACE),
|
||||
.bRequest = REQ_SetInterface,
|
||||
.wValue = AltSetting,
|
||||
.wIndex = InterfaceIndex,
|
||||
.wLength = 0,
|
||||
};
|
||||
|
||||
Pipe_SelectPipe(PIPE_CONTROLPIPE);
|
||||
|
||||
return USB_Host_SendControlRequest(NULL);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -208,6 +208,9 @@
|
|||
/** Suspends the USB bus, preventing any communications from occurring between the host and attached
|
||||
* device until the bus has been resumed. This stops the transmission of the 1MS Start Of Frame
|
||||
* messages to the device.
|
||||
*
|
||||
* \note While the USB bus is suspended, all USB interrupt sources are also disabled; this means that
|
||||
* some events (such as device disconnections) will not fire until the bus is resumed.
|
||||
*/
|
||||
static inline void USB_Host_SuspendBus(void) ATTR_ALWAYS_INLINE;
|
||||
static inline void USB_Host_SuspendBus(void)
|
||||
|
@ -277,73 +280,6 @@
|
|||
return AVR32_USBB.UHCON.resume;
|
||||
}
|
||||
|
||||
/* Function Prototypes: */
|
||||
/** Convenience function. This routine sends a SET CONFIGURATION standard request to the attached
|
||||
* device, with the given configuration index. This can be used to easily set the device
|
||||
* configuration without creating and sending the request manually.
|
||||
*
|
||||
* \note After this routine returns, the control pipe will be selected.
|
||||
*
|
||||
* \param[in] ConfigNumber Configuration index to send to the device.
|
||||
*
|
||||
* \return A value from the \ref USB_Host_SendControlErrorCodes_t enum to indicate the result.
|
||||
*/
|
||||
uint8_t USB_Host_SetDeviceConfiguration(const uint8_t ConfigNumber);
|
||||
|
||||
/** Convenience function. This routine sends a GET DESCRIPTOR standard request to the attached
|
||||
* device, requesting the device descriptor. This can be used to easily retrieve information
|
||||
* about the device such as its VID, PID and power requirements.
|
||||
*
|
||||
* \note After this routine returns, the control pipe will be selected.
|
||||
*
|
||||
* \param[out] DeviceDescriptorPtr Pointer to the destination device descriptor structure where
|
||||
* the read data is to be stored.
|
||||
*
|
||||
* \return A value from the \ref USB_Host_SendControlErrorCodes_t enum to indicate the result.
|
||||
*/
|
||||
uint8_t USB_Host_GetDeviceDescriptor(void* const DeviceDescriptorPtr);
|
||||
|
||||
/** Convenience function. This routine sends a GET DESCRIPTOR standard request to the attached
|
||||
* device, requesting the string descriptor of the specified index. This can be used to easily
|
||||
* retrieve string descriptors from the device by index, after the index is obtained from the
|
||||
* Device or Configuration descriptors.
|
||||
*
|
||||
* \note After this routine returns, the control pipe will be selected.
|
||||
*
|
||||
* \param[in] Index Index of the string index to retrieve.
|
||||
* \param[out] Buffer Pointer to the destination buffer where the retrieved string descriptor is
|
||||
* to be stored.
|
||||
* \param[in] BufferLength Maximum size of the string descriptor which can be stored into the buffer.
|
||||
*
|
||||
* \return A value from the \ref USB_Host_SendControlErrorCodes_t enum to indicate the result.
|
||||
*/
|
||||
uint8_t USB_Host_GetDeviceStringDescriptor(const uint8_t Index,
|
||||
void* const Buffer,
|
||||
const uint8_t BufferLength);
|
||||
|
||||
/** Clears a stall condition on the given pipe, via a CLEAR FEATURE standard request to the attached device.
|
||||
*
|
||||
* \note After this routine returns, the control pipe will be selected.
|
||||
*
|
||||
* \param[in] EndpointIndex Index of the endpoint to clear, including the endpoint's direction.
|
||||
*
|
||||
* \return A value from the \ref USB_Host_SendControlErrorCodes_t enum to indicate the result.
|
||||
*/
|
||||
uint8_t USB_Host_ClearPipeStall(const uint8_t EndpointIndex);
|
||||
|
||||
/** Selects a given alternative setting for the specified interface, via a SET INTERFACE standard request to
|
||||
* the attached device.
|
||||
*
|
||||
* \note After this routine returns, the control pipe will be selected.
|
||||
*
|
||||
* \param[in] InterfaceIndex Index of the interface whose alternative setting is to be altered.
|
||||
* \param[in] AltSetting Index of the interface's alternative setting which is to be selected.
|
||||
*
|
||||
* \return A value from the \ref USB_Host_SendControlErrorCodes_t enum to indicate the result.
|
||||
*/
|
||||
uint8_t USB_Host_SetInterfaceAltSetting(const uint8_t InterfaceIndex,
|
||||
const uint8_t AltSetting);
|
||||
|
||||
/* Private Interface - For use in library only: */
|
||||
#if !defined(__DOXYGEN__)
|
||||
/* Macros: */
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
|
||||
#include "../Pipe.h"
|
||||
|
||||
uint8_t USB_ControlPipeSize = PIPE_CONTROLPIPE_DEFAULT_SIZE;
|
||||
uint8_t USB_Host_ControlPipeSize = PIPE_CONTROLPIPE_DEFAULT_SIZE;
|
||||
|
||||
volatile uint32_t USB_SelectedPipe = PIPE_CONTROLPIPE;
|
||||
volatile uint8_t* USB_PipeFIFOPos[PIPE_TOTAL_PIPES];
|
||||
|
|
|
@ -804,7 +804,7 @@
|
|||
* \note This variable should be treated as read-only in the user application, and never manually
|
||||
* changed in value.
|
||||
*/
|
||||
extern uint8_t USB_ControlPipeSize;
|
||||
extern uint8_t USB_Host_ControlPipeSize;
|
||||
|
||||
/* Function Prototypes: */
|
||||
/** Configures the specified pipe number with the given pipe type, token, target endpoint number in the
|
||||
|
|
|
@ -58,7 +58,7 @@ uint8_t TEMPLATE_FUNC_NAME (const void* const Buffer,
|
|||
{
|
||||
uint16_t BytesInEndpoint = Endpoint_BytesInEndpoint();
|
||||
|
||||
while (Length && (BytesInEndpoint < USB_ControlEndpointSize))
|
||||
while (Length && (BytesInEndpoint < USB_Device_ControlEndpointSize))
|
||||
{
|
||||
TEMPLATE_TRANSFER_BYTE(DataStream);
|
||||
TEMPLATE_BUFFER_MOVE(DataStream, 1);
|
||||
|
@ -66,7 +66,7 @@ uint8_t TEMPLATE_FUNC_NAME (const void* const Buffer,
|
|||
BytesInEndpoint++;
|
||||
}
|
||||
|
||||
LastPacketFull = (BytesInEndpoint == USB_ControlEndpointSize);
|
||||
LastPacketFull = (BytesInEndpoint == USB_Device_ControlEndpointSize);
|
||||
Endpoint_ClearIN();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -147,22 +147,22 @@ void USB_ResetInterface(void)
|
|||
#if defined(USB_CAN_BE_DEVICE)
|
||||
static void USB_Init_Device(void)
|
||||
{
|
||||
USB_DeviceState = DEVICE_STATE_Unattached;
|
||||
USB_ConfigurationNumber = 0;
|
||||
USB_DeviceState = DEVICE_STATE_Unattached;
|
||||
USB_Device_ConfigurationNumber = 0;
|
||||
|
||||
#if !defined(NO_DEVICE_REMOTE_WAKEUP)
|
||||
USB_RemoteWakeupEnabled = false;
|
||||
USB_Device_RemoteWakeupEnabled = false;
|
||||
#endif
|
||||
|
||||
#if !defined(NO_DEVICE_SELF_POWER)
|
||||
USB_CurrentlySelfPowered = false;
|
||||
USB_Device_CurrentlySelfPowered = false;
|
||||
#endif
|
||||
|
||||
#if !defined(FIXED_CONTROL_ENDPOINT_SIZE)
|
||||
USB_Descriptor_Device_t* DeviceDescriptorPtr;
|
||||
|
||||
if (CALLBACK_USB_GetDescriptor((DTYPE_Device << 8), 0, (void*)&DeviceDescriptorPtr) != NO_DESCRIPTOR)
|
||||
USB_ControlEndpointSize = DeviceDescriptorPtr->Endpoint0Size;
|
||||
USB_Device_ControlEndpointSize = DeviceDescriptorPtr->Endpoint0Size;
|
||||
#endif
|
||||
|
||||
if (USB_Options & USB_DEVICE_OPT_LOWSPEED)
|
||||
|
@ -173,7 +173,7 @@ static void USB_Init_Device(void)
|
|||
USB_INT_Enable(USB_INT_VBUSTI);
|
||||
|
||||
Endpoint_ConfigureEndpoint(ENDPOINT_CONTROLEP, EP_TYPE_CONTROL,
|
||||
ENDPOINT_DIR_OUT, USB_ControlEndpointSize,
|
||||
ENDPOINT_DIR_OUT, USB_Device_ControlEndpointSize,
|
||||
ENDPOINT_BANK_SINGLE);
|
||||
|
||||
USB_INT_Clear(USB_INT_SUSPI);
|
||||
|
@ -187,8 +187,9 @@ static void USB_Init_Device(void)
|
|||
#if defined(USB_CAN_BE_HOST)
|
||||
static void USB_Init_Host(void)
|
||||
{
|
||||
USB_HostState = HOST_STATE_Unattached;
|
||||
USB_ControlPipeSize = PIPE_CONTROLPIPE_DEFAULT_SIZE;
|
||||
USB_HostState = HOST_STATE_Unattached;
|
||||
USB_Host_ConfigurationNumber = 0;
|
||||
USB_Host_ControlPipeSize = PIPE_CONTROLPIPE_DEFAULT_SIZE;
|
||||
|
||||
USB_Host_HostMode_On();
|
||||
|
||||
|
|
|
@ -97,7 +97,7 @@ ISR(USB_GEN_vect)
|
|||
USB_INT_Disable(USB_INT_WAKEUPI);
|
||||
USB_INT_Enable(USB_INT_SUSPI);
|
||||
|
||||
if (USB_ConfigurationNumber)
|
||||
if (USB_Device_ConfigurationNumber)
|
||||
USB_DeviceState = DEVICE_STATE_Configured;
|
||||
else
|
||||
USB_DeviceState = (USB_Device_IsAddressSet()) ? DEVICE_STATE_Configured : DEVICE_STATE_Powered;
|
||||
|
@ -109,8 +109,8 @@ ISR(USB_GEN_vect)
|
|||
{
|
||||
USB_INT_Clear(USB_INT_EORSTI);
|
||||
|
||||
USB_DeviceState = DEVICE_STATE_Default;
|
||||
USB_ConfigurationNumber = 0;
|
||||
USB_DeviceState = DEVICE_STATE_Default;
|
||||
USB_Device_ConfigurationNumber = 0;
|
||||
|
||||
USB_INT_Clear(USB_INT_SUSPI);
|
||||
USB_INT_Disable(USB_INT_SUSPI);
|
||||
|
@ -118,7 +118,7 @@ ISR(USB_GEN_vect)
|
|||
|
||||
USB_Device_SetDeviceAddress(0);
|
||||
Endpoint_ConfigureEndpoint(ENDPOINT_CONTROLEP, EP_TYPE_CONTROL,
|
||||
ENDPOINT_DIR_OUT, USB_ControlEndpointSize,
|
||||
ENDPOINT_DIR_OUT, USB_Device_ControlEndpointSize,
|
||||
ENDPOINT_BANK_SINGLE);
|
||||
|
||||
EVENT_USB_Device_Reset();
|
||||
|
|
|
@ -93,9 +93,8 @@
|
|||
/** Indicates the current host state machine state. When in host mode, this indicates the state
|
||||
* via one of the values of the \ref USB_Host_States_t enum values.
|
||||
*
|
||||
* This value may be altered by the user application to implement the \ref HOST_STATE_Addressed,
|
||||
* \ref HOST_STATE_Configured and \ref HOST_STATE_Suspended states which are not implemented by
|
||||
* the library internally.
|
||||
* This value should not be altered by the user application as it is handled automatically by the
|
||||
* library.
|
||||
*
|
||||
* To reduce program size and speed up checks of this global on the AVR8 architecture, it can be
|
||||
* placed into one of the AVR's \c GPIOR hardware registers instead of RAM by defining the
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
* - Added board hardware driver support for the EVK1100 board
|
||||
* - Added board hardware driver support for the EVK1104 board
|
||||
* - Added new HID_Host_SetIdlePeriod() function to the HID Host Class driver
|
||||
* - Added new USB_Host_ConfigurationNumber global variable to indicate the selected configuration in an attached device
|
||||
* - Library Applications:
|
||||
* - Added RNDIS device mode to the Webserver project
|
||||
* - Added new incomplete AndroidAccessoryHost Host LowLevel demo
|
||||
|
@ -41,8 +42,14 @@
|
|||
* continuous sample rates
|
||||
* - Pipe_BoundEndpointNumber() has been renamed to Pipe_GetBoundEndpointAddress(), and now returns the correct endpoint direction
|
||||
* as part of the endpoint address
|
||||
* - Renamed global state variables that are specific to a certain USB mode to clearly indicate which mode the variable relates to,
|
||||
* by changing the USB_* prefix to USB_Device_* or USB_Host_*
|
||||
* - Removed the HOST_STATE_WaitForDeviceRemoval and HOST_STATE_Suspended host state machine states, as these are no longer required
|
||||
* - Altered the USB_Host_SetDeviceConfiguration() function to update the new USB_Host_ConfigurationNumber global as required
|
||||
* - Library Applications:
|
||||
* - Modified the Low Level and Class Driver AudioInput and AudioOutput demos to support multiple audio sample rates
|
||||
* - Updated all host mode demos and projects to use the EVENT_USB_Host_DeviceEnumerationComplete() event callback for device configuration
|
||||
* instead of manual host state machine manipulations in the main application task
|
||||
*
|
||||
* <b>Fixed:</b>
|
||||
* - Core:
|
||||
|
|
|
@ -179,8 +179,8 @@
|
|||
*
|
||||
* <b>NO_DEVICE_SELF_POWER</b> - (\ref Group_Device) - <i>All Architectures</i> \n
|
||||
* USB devices may be bus powered, self powered, or a combination of both. When a device can be both bus powered and self powered, the host may
|
||||
* query the device to determine the current power source, via \ref USB_CurrentlySelfPowered. For solely bus powered devices, this global and the
|
||||
* code required to manage it may be disabled by passing this token to the library via the -D switch.
|
||||
* query the device to determine the current power source, via \ref USB_Device_CurrentlySelfPowered. For solely bus powered devices, this global
|
||||
* and the code required to manage it may be disabled by passing this token to the library via the -D switch.
|
||||
*
|
||||
*
|
||||
* \section Sec_SummaryUSBHostTokens USB Host Mode Driver Related Tokens
|
||||
|
|
|
@ -24,7 +24,8 @@
|
|||
* -# Abstract out Mass Storage byte send/receive to prevent low level API use in projects
|
||||
* -# Consider switch from endpoint numbers to full endpoint addresses to ease future architecture expansion
|
||||
* -# Fix HID report parser usage support for array types
|
||||
* -# Remove need for direct user Host State Machine interaction in the Host mode applications
|
||||
* -# Mass Storage Host demo incompatibilities with some devices
|
||||
* -# Add additional standard request helper functions to host mode
|
||||
* - Documentation/Support
|
||||
* -# Add detailed overviews of how each demo works
|
||||
* -# Add board overviews
|
||||
|
|
|
@ -20,6 +20,19 @@
|
|||
* - The device mode Audio class driver now requires a new user application callback, \ref CALLBACK_Audio_Device_GetSetEndpointProperty().
|
||||
* Existing applications must implement this new callback, however if multiple sample rates or pitch control is not used,
|
||||
* this function may be hard-coded to always return false for previous behaviour to be retained.
|
||||
* - The \c USB_ConfigurationNumber, \c USB_RemoteWakeupEnabled and \c USB_CurrentlySelfPowered globals have been renamed to
|
||||
* \ref USB_Device_ConfigurationNumber, \ref USB_Device_RemoteWakeupEnabled and \ref USB_Device_CurrentlySelfPowered to clearly indicate
|
||||
* the USB mode they relate to. Existing applications using these variables should rename all references to the previous names.
|
||||
*
|
||||
* <b>Host Mode</b>
|
||||
* - The USB_Host_SetDeviceConfiguration() function now automatically sets the USB Host state machine to the \ref HOST_STATE_Configured
|
||||
* state if a non-zero configuration is set sucessfully, or the \ref HOST_STATE_Addressed if a zero-index configuration is specified. Existing
|
||||
* applications should no longer manually alter the \ref USB_HostState global, and should instead call this function to configure and
|
||||
* unconfigure an attached device.
|
||||
* - The \c HOST_STATE_WaitForDeviceRemoval and \c HOST_STATE_Suspended host state machine states have been removed; these are replaced by
|
||||
* unconfiguring the attached device via a call to \ref USB_Host_SetDeviceConfiguration() and a test of \ref USB_Host_IsBusSuspended() instead.
|
||||
* - It is highly recommended that the EVENT_USB_Host_DeviceEnumerationComplete() event callback now be used for initial device configuration,
|
||||
* rather than a switch on the USB host state machine state for readability.
|
||||
*
|
||||
* \section Sec_Migration110528 Migrating from 101122 to 110528
|
||||
* <b>Non-USB Library Components</b>
|
||||
|
|
|
@ -74,68 +74,30 @@ int main(void)
|
|||
|
||||
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 (HID_Host_ConfigurePipes(&Device_HID_Interface,
|
||||
ConfigDescriptorSize, ConfigDescriptorData) != HID_ENUMERROR_NoError)
|
||||
{
|
||||
puts_P(PSTR("Attached Device Not a Valid HID 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 (HID_Host_SetReportProtocol(&Device_HID_Interface) != 0)
|
||||
{
|
||||
puts_P(PSTR("Error Setting Report Protocol Mode.\r\n"));
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
puts_P(PSTR("HID Device Enumerated.\r\n"));
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_READY);
|
||||
USB_HostState = HOST_STATE_Configured;
|
||||
break;
|
||||
case HOST_STATE_Configured:
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_BUSY);
|
||||
|
||||
OutputReportSizes();
|
||||
OutputParsedReportItems();
|
||||
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_READY);
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
RetrieveDeviceData();
|
||||
|
||||
HID_Host_USBTask(&Device_HID_Interface);
|
||||
USB_USBTask();
|
||||
}
|
||||
}
|
||||
|
||||
/** Task to retrieve the HID device information from an attached device, and output
|
||||
* the relevant data to the serial port for analysis.
|
||||
*/
|
||||
void RetrieveDeviceData(void)
|
||||
{
|
||||
if (USB_CurrentMode != USB_MODE_Host)
|
||||
return;
|
||||
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_BUSY);
|
||||
|
||||
OutputReportSizes();
|
||||
OutputParsedReportItems();
|
||||
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_READY);
|
||||
USB_Host_SetDeviceConfiguration(0);
|
||||
}
|
||||
|
||||
/** Prints a summary of the device's HID report sizes from the HID parser output to the serial port
|
||||
* for display to the user.
|
||||
*/
|
||||
|
@ -276,6 +238,43 @@ void EVENT_USB_Host_DeviceUnattached(void)
|
|||
*/
|
||||
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 (HID_Host_ConfigurePipes(&Device_HID_Interface,
|
||||
ConfigDescriptorSize, ConfigDescriptorData) != HID_ENUMERROR_NoError)
|
||||
{
|
||||
puts_P(PSTR("Attached Device Not a Valid HID 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 (HID_Host_SetReportProtocol(&Device_HID_Interface) != 0)
|
||||
{
|
||||
puts_P(PSTR("Error Setting Report Protocol Mode.\r\n"));
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
USB_Host_SetDeviceConfiguration(0);
|
||||
return;
|
||||
}
|
||||
|
||||
puts_P(PSTR("HID Device Enumerated.\r\n"));
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_READY);
|
||||
}
|
||||
|
||||
|
|
|
@ -69,6 +69,7 @@
|
|||
|
||||
/* Function Prototypes: */
|
||||
void SetupHardware(void);
|
||||
void RetrieveDeviceData(void);
|
||||
void OutputReportSizes(void);
|
||||
void OutputParsedReportItems(void);
|
||||
void OutputCollectionPath(const HID_CollectionPath_t* const CollectionPath);
|
||||
|
|
|
@ -103,8 +103,8 @@ int main(void)
|
|||
for (;;)
|
||||
{
|
||||
Read_Joystick_Status();
|
||||
|
||||
HID_Host_Task();
|
||||
DiscardNextReport();
|
||||
|
||||
USB_USBTask();
|
||||
}
|
||||
}
|
||||
|
@ -198,6 +198,22 @@ void EVENT_USB_Host_DeviceUnattached(void)
|
|||
*/
|
||||
void EVENT_USB_Host_DeviceEnumerationComplete(void)
|
||||
{
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
|
||||
|
||||
/* Get and process the configuration descriptor data */
|
||||
if (ProcessConfigurationDescriptor() != SuccessfulConfigRead)
|
||||
{
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Set the device configuration to the first configuration (rarely do devices use multiple configurations) */
|
||||
if (USB_Host_SetDeviceConfiguration(1) != HOST_SENDCONTROL_Successful)
|
||||
{
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_READY);
|
||||
}
|
||||
|
||||
|
@ -222,6 +238,9 @@ void EVENT_USB_Host_DeviceEnumerationFailed(const uint8_t ErrorCode,
|
|||
/** Reads in and discards the next report from the attached device. */
|
||||
void DiscardNextReport(void)
|
||||
{
|
||||
if (USB_HostState != HOST_STATE_Configured)
|
||||
return;
|
||||
|
||||
/* Select and unfreeze HID data IN pipe */
|
||||
Pipe_SelectPipe(HID_DATA_IN_PIPE);
|
||||
Pipe_Unfreeze();
|
||||
|
@ -250,6 +269,9 @@ void DiscardNextReport(void)
|
|||
void WriteNextReport(uint8_t* const ReportOUTData,
|
||||
const uint16_t ReportLength)
|
||||
{
|
||||
if (USB_HostState != HOST_STATE_Configured)
|
||||
return;
|
||||
|
||||
/* Select and unfreeze HID data OUT pipe */
|
||||
Pipe_SelectPipe(HID_DATA_OUT_PIPE);
|
||||
|
||||
|
@ -297,45 +319,3 @@ void WriteNextReport(uint8_t* const ReportOUTData,
|
|||
}
|
||||
}
|
||||
|
||||
/** Task to set the configuration of the attached device after it has been enumerated, and to read and process
|
||||
* HID reports from the device and to send reports if desired.
|
||||
*/
|
||||
void HID_Host_Task(void)
|
||||
{
|
||||
uint8_t ErrorCode;
|
||||
|
||||
/* Switch to determine what user-application handled host state the host state machine is in */
|
||||
switch (USB_HostState)
|
||||
{
|
||||
case HOST_STATE_Addressed:
|
||||
/* Get and process the configuration descriptor data */
|
||||
if ((ErrorCode = ProcessConfigurationDescriptor()) != SuccessfulConfigRead)
|
||||
{
|
||||
/* Indicate error status */
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
|
||||
/* Wait until USB device disconnected */
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Set the device configuration to the first configuration (rarely do devices use multiple configurations) */
|
||||
if ((ErrorCode = USB_Host_SetDeviceConfiguration(1)) != HOST_SENDCONTROL_Successful)
|
||||
{
|
||||
/* Indicate error status */
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
|
||||
/* Wait until USB device disconnected */
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
USB_HostState = HOST_STATE_Configured;
|
||||
break;
|
||||
case HOST_STATE_Configured:
|
||||
DiscardNextReport();
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -77,8 +77,6 @@
|
|||
const uint16_t ReportSize);
|
||||
void Send_Command(const uint8_t* const Command);
|
||||
|
||||
void HID_Host_Task(void);
|
||||
|
||||
void EVENT_USB_Host_HostError(const uint8_t ErrorCode);
|
||||
void EVENT_USB_Host_DeviceAttached(void);
|
||||
void EVENT_USB_Host_DeviceUnattached(void);
|
||||
|
|
|
@ -113,7 +113,7 @@ void uIPManagement_Init(void)
|
|||
*/
|
||||
void uIPManagement_ManageNetwork(void)
|
||||
{
|
||||
if (((USB_CurrentMode == USB_MODE_Host) && (USB_HostState == HOST_STATE_Configured)) ||
|
||||
if (((USB_CurrentMode == USB_MODE_Host) && (USB_HostState == HOST_STATE_Configured)) ||
|
||||
((USB_CurrentMode == USB_MODE_Device) && (USB_DeviceState == DEVICE_STATE_Configured)))
|
||||
{
|
||||
uIPManagement_ProcessIncomingPacket();
|
||||
|
|
|
@ -66,73 +66,8 @@ void USBHostMode_USBTask(void)
|
|||
if (USB_CurrentMode != USB_MODE_Host)
|
||||
return;
|
||||
|
||||
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)
|
||||
{
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
if (RNDIS_Host_ConfigurePipes(&Ethernet_RNDIS_Interface_Host,
|
||||
ConfigDescriptorSize, ConfigDescriptorData) != RNDIS_ENUMERROR_NoError)
|
||||
{
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
if (USB_Host_SetDeviceConfiguration(1) != HOST_SENDCONTROL_Successful)
|
||||
{
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
if (RNDIS_Host_InitializeDevice(&Ethernet_RNDIS_Interface_Host) != HOST_SENDCONTROL_Successful)
|
||||
{
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
uint32_t PacketFilter = (REMOTE_NDIS_PACKET_DIRECTED | REMOTE_NDIS_PACKET_BROADCAST);
|
||||
if (RNDIS_Host_SetRNDISProperty(&Ethernet_RNDIS_Interface_Host, OID_GEN_CURRENT_PACKET_FILTER,
|
||||
&PacketFilter, sizeof(PacketFilter)) != HOST_SENDCONTROL_Successful)
|
||||
{
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
if (RNDIS_Host_QueryRNDISProperty(&Ethernet_RNDIS_Interface_Host, OID_802_3_CURRENT_ADDRESS,
|
||||
&MACAddress, sizeof(MACAddress)) != HOST_SENDCONTROL_Successful)
|
||||
{
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Initialize uIP stack */
|
||||
uIPManagement_Init();
|
||||
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_READY);
|
||||
USB_HostState = HOST_STATE_Configured;
|
||||
break;
|
||||
case HOST_STATE_Configured:
|
||||
uIPManagement_ManageNetwork();
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
uIPManagement_ManageNetwork();
|
||||
|
||||
RNDIS_Host_USBTask(&Ethernet_RNDIS_Interface_Host);
|
||||
}
|
||||
|
||||
|
@ -157,6 +92,55 @@ void EVENT_USB_Host_DeviceUnattached(void)
|
|||
*/
|
||||
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)
|
||||
{
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
if (RNDIS_Host_ConfigurePipes(&Ethernet_RNDIS_Interface_Host,
|
||||
ConfigDescriptorSize, ConfigDescriptorData) != RNDIS_ENUMERROR_NoError)
|
||||
{
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
if (USB_Host_SetDeviceConfiguration(1) != HOST_SENDCONTROL_Successful)
|
||||
{
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
if (RNDIS_Host_InitializeDevice(&Ethernet_RNDIS_Interface_Host) != HOST_SENDCONTROL_Successful)
|
||||
{
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t PacketFilter = (REMOTE_NDIS_PACKET_DIRECTED | REMOTE_NDIS_PACKET_BROADCAST);
|
||||
if (RNDIS_Host_SetRNDISProperty(&Ethernet_RNDIS_Interface_Host, OID_GEN_CURRENT_PACKET_FILTER,
|
||||
&PacketFilter, sizeof(PacketFilter)) != HOST_SENDCONTROL_Successful)
|
||||
{
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
if (RNDIS_Host_QueryRNDISProperty(&Ethernet_RNDIS_Interface_Host, OID_802_3_CURRENT_ADDRESS,
|
||||
&MACAddress, sizeof(MACAddress)) != HOST_SENDCONTROL_Successful)
|
||||
{
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Initialize uIP stack */
|
||||
uIPManagement_Init();
|
||||
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_READY);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue