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:
Dean Camera 2011-07-08 07:25:56 +00:00
parent bcb627e1a1
commit 137ce280c1
96 changed files with 3053 additions and 3656 deletions

View file

@ -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);
}
}

View file

@ -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);

View file

@ -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

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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);

View file

@ -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);
}

View file

@ -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);

View file

@ -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);
}

View file

@ -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);

View file

@ -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);
}

View file

@ -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);

View file

@ -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);
}

View file

@ -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);

View file

@ -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);
}

View file

@ -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);

View file

@ -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);
}

View file

@ -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);

View file

@ -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);
}

View file

@ -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);

View file

@ -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);
}

View file

@ -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);

View file

@ -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);
}

View file

@ -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);

View file

@ -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);
}

View file

@ -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);

View file

@ -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;
}
}

View file

@ -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

View file

@ -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;
}
}

View file

@ -80,7 +80,6 @@
const uint8_t SubErrorCode);
/* Function Prototypes: */
void Bluetooth_Host_Task(void);
void SetupHardware(void);
#endif

View file

@ -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)
{

View file

@ -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);

View file

@ -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)
{

View file

@ -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);

View file

@ -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;
}
}

View file

@ -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

View file

@ -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

View file

@ -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);

View file

@ -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;
}
}

View file

@ -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

View file

@ -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

View file

@ -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);

View file

@ -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;
}
}

View file

@ -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);

View file

@ -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,

View file

@ -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);

View file

@ -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;
}
}

View file

@ -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);

View file

@ -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

View file

@ -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);

View file

@ -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);
}

View file

@ -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

View file

@ -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;
}
}

View file

@ -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);

View file

@ -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

View file

@ -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);

View file

@ -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();
}

View file

@ -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);