Updated all host mode demos and projects to use the EVENT_USB_Host_DeviceEnumerationComplete() event callback for device configuration instead of manual host state machine manipulations in the main application task.
Added new USB_Host_ConfigurationNumber global variable to indicate the selected configuration in an attached device. Renamed global state variables that are specific to a certain USB mode to clearly indicate which mode the variable relates to, by changing the USB_* prefix to USB_Device_* or USB_Host_*. Removed the HOST_STATE_WaitForDeviceRemoval and HOST_STATE_Suspended host state machine states, as these are no longer required. Altered the USB_Host_SetDeviceConfiguration() function to update the new USB_Host_ConfigurationNumber global as required. Moved out the Host mode standard request convenience/helper functions from the architecture specific Host driver files to the architecture agnostic HostStandardReq.c driver file.
This commit is contained in:
parent
bcb627e1a1
commit
137ce280c1
96 changed files with 3053 additions and 3656 deletions
|
|
@ -50,7 +50,6 @@ int main(void)
|
|||
|
||||
for (;;)
|
||||
{
|
||||
Audio_Task();
|
||||
USB_USBTask();
|
||||
}
|
||||
}
|
||||
|
|
@ -97,6 +96,81 @@ void EVENT_USB_Host_DeviceUnattached(void)
|
|||
*/
|
||||
void EVENT_USB_Host_DeviceEnumerationComplete(void)
|
||||
{
|
||||
puts_P(PSTR("Getting Config Data.\r\n"));
|
||||
|
||||
uint8_t ErrorCode;
|
||||
|
||||
/* Get and process the configuration descriptor data */
|
||||
if ((ErrorCode = ProcessConfigurationDescriptor()) != SuccessfulConfigRead)
|
||||
{
|
||||
if (ErrorCode == ControlError)
|
||||
puts_P(PSTR(ESC_FG_RED "Control Error (Get Configuration).\r\n"));
|
||||
else
|
||||
puts_P(PSTR(ESC_FG_RED "Invalid Device.\r\n"));
|
||||
|
||||
printf_P(PSTR(" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
|
||||
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Set the device configuration to the first configuration (rarely do devices use multiple configurations) */
|
||||
if ((ErrorCode = USB_Host_SetDeviceConfiguration(1)) != HOST_SENDCONTROL_Successful)
|
||||
{
|
||||
printf_P(PSTR(ESC_FG_RED "Control Error (Set Configuration).\r\n"
|
||||
" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
|
||||
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
if ((ErrorCode = USB_Host_SetInterfaceAltSetting(StreamingInterfaceIndex,
|
||||
StreamingInterfaceAltSetting)) != HOST_SENDCONTROL_Successful)
|
||||
{
|
||||
printf_P(PSTR(ESC_FG_RED "Could not set alternative streaming interface setting.\r\n"
|
||||
" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
|
||||
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
USB_Host_SetDeviceConfiguration(0);
|
||||
return;
|
||||
}
|
||||
|
||||
USB_ControlRequest = (USB_Request_Header_t)
|
||||
{
|
||||
.bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_ENDPOINT),
|
||||
.bRequest = AUDIO_REQ_SetCurrent,
|
||||
.wValue = (AUDIO_EPCONTROL_SamplingFreq << 8),
|
||||
.wIndex = StreamingEndpointAddress,
|
||||
.wLength = sizeof(USB_Audio_SampleFreq_t),
|
||||
};
|
||||
|
||||
USB_Audio_SampleFreq_t SampleRate = AUDIO_SAMPLE_FREQ(48000);
|
||||
|
||||
/* Select the control pipe for the request transfer */
|
||||
Pipe_SelectPipe(PIPE_CONTROLPIPE);
|
||||
|
||||
/* Set the sample rate on the streaming interface endpoint */
|
||||
if ((ErrorCode = USB_Host_SendControlRequest(&SampleRate)) != HOST_SENDCONTROL_Successful)
|
||||
{
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
USB_Host_SetDeviceConfiguration(0);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Sample reload timer initialization */
|
||||
TIMSK0 = (1 << OCIE0A);
|
||||
OCR0A = ((F_CPU / 8 / 48000) - 1);
|
||||
TCCR0A = (1 << WGM01); // CTC mode
|
||||
TCCR0B = (1 << CS01); // Fcpu/8 speed
|
||||
|
||||
/* Set speaker as output */
|
||||
DDRC |= (1 << 6);
|
||||
|
||||
/* PWM speaker timer initialization */
|
||||
TCCR3A = ((1 << WGM30) | (1 << COM3A1) | (1 << COM3A0)); // Set on match, clear on TOP
|
||||
TCCR3B = ((1 << WGM32) | (1 << CS30)); // Fast 8-Bit PWM, F_CPU speed
|
||||
|
||||
puts_P(PSTR("Microphone Enumerated.\r\n"));
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_READY);
|
||||
}
|
||||
|
||||
|
|
@ -126,109 +200,6 @@ void EVENT_USB_Host_DeviceEnumerationFailed(const uint8_t ErrorCode,
|
|||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
}
|
||||
|
||||
void Audio_Task(void)
|
||||
{
|
||||
uint8_t ErrorCode;
|
||||
|
||||
switch (USB_HostState)
|
||||
{
|
||||
case HOST_STATE_Addressed:
|
||||
puts_P(PSTR("Getting Config Data.\r\n"));
|
||||
|
||||
/* Get and process the configuration descriptor data */
|
||||
if ((ErrorCode = ProcessConfigurationDescriptor()) != SuccessfulConfigRead)
|
||||
{
|
||||
if (ErrorCode == ControlError)
|
||||
puts_P(PSTR(ESC_FG_RED "Control Error (Get Configuration).\r\n"));
|
||||
else
|
||||
puts_P(PSTR(ESC_FG_RED "Invalid Device.\r\n"));
|
||||
|
||||
printf_P(PSTR(" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
|
||||
|
||||
/* Indicate error status */
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
|
||||
/* Wait until USB device disconnected */
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Set the device configuration to the first configuration (rarely do devices use multiple configurations) */
|
||||
if ((ErrorCode = USB_Host_SetDeviceConfiguration(1)) != HOST_SENDCONTROL_Successful)
|
||||
{
|
||||
printf_P(PSTR(ESC_FG_RED "Control Error (Set Configuration).\r\n"
|
||||
" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
|
||||
|
||||
/* Indicate error status */
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
|
||||
/* Wait until USB device disconnected */
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
if ((ErrorCode = USB_Host_SetInterfaceAltSetting(StreamingInterfaceIndex,
|
||||
StreamingInterfaceAltSetting)) != HOST_SENDCONTROL_Successful)
|
||||
{
|
||||
printf_P(PSTR(ESC_FG_RED "Could not set alternative streaming interface setting.\r\n"
|
||||
" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
|
||||
|
||||
/* Indicate error status */
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
|
||||
/* Wait until USB device disconnected */
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
USB_ControlRequest = (USB_Request_Header_t)
|
||||
{
|
||||
.bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_ENDPOINT),
|
||||
.bRequest = AUDIO_REQ_SetCurrent,
|
||||
.wValue = (AUDIO_EPCONTROL_SamplingFreq << 8),
|
||||
.wIndex = StreamingEndpointAddress,
|
||||
.wLength = sizeof(USB_Audio_SampleFreq_t),
|
||||
};
|
||||
|
||||
USB_Audio_SampleFreq_t SampleRate = AUDIO_SAMPLE_FREQ(48000);
|
||||
|
||||
/* Select the control pipe for the request transfer */
|
||||
Pipe_SelectPipe(PIPE_CONTROLPIPE);
|
||||
|
||||
/* Set the sample rate on the streaming interface endpoint */
|
||||
if ((ErrorCode = USB_Host_SendControlRequest(&SampleRate)) != HOST_SENDCONTROL_Successful)
|
||||
{
|
||||
/* Indicate error status */
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
|
||||
/* Wait until USB device disconnected */
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Sample reload timer initialization */
|
||||
TIMSK0 = (1 << OCIE0A);
|
||||
OCR0A = ((F_CPU / 8 / 48000) - 1);
|
||||
TCCR0A = (1 << WGM01); // CTC mode
|
||||
TCCR0B = (1 << CS01); // Fcpu/8 speed
|
||||
|
||||
/* Set speaker as output */
|
||||
DDRC |= (1 << 6);
|
||||
|
||||
/* PWM speaker timer initialization */
|
||||
TCCR3A = ((1 << WGM30) | (1 << COM3A1) | (1 << COM3A0)); // Set on match, clear on TOP
|
||||
TCCR3B = ((1 << WGM32) | (1 << CS30)); // Fast 8-Bit PWM, F_CPU speed
|
||||
|
||||
puts_P(PSTR("Microphone Enumerated.\r\n"));
|
||||
|
||||
USB_HostState = HOST_STATE_Configured;
|
||||
break;
|
||||
case HOST_STATE_Configured:
|
||||
/* Do nothing - audio stream is handled by the timer interrupt routine */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/** ISR to handle the reloading of the PWM timer with the next sample. */
|
||||
ISR(TIMER0_COMPA_vect, ISR_BLOCK)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -66,7 +66,6 @@
|
|||
#define LEDMASK_USB_ERROR (LEDS_LED1 | LEDS_LED3)
|
||||
|
||||
/* Function Prototypes: */
|
||||
void Audio_Task(void);
|
||||
void SetupHardware(void);
|
||||
|
||||
void EVENT_USB_Host_HostError(const uint8_t ErrorCode);
|
||||
|
|
|
|||
|
|
@ -50,7 +50,6 @@ int main(void)
|
|||
|
||||
for (;;)
|
||||
{
|
||||
Audio_Task();
|
||||
USB_USBTask();
|
||||
}
|
||||
}
|
||||
|
|
@ -100,6 +99,73 @@ void EVENT_USB_Host_DeviceUnattached(void)
|
|||
*/
|
||||
void EVENT_USB_Host_DeviceEnumerationComplete(void)
|
||||
{
|
||||
puts_P(PSTR("Getting Config Data.\r\n"));
|
||||
|
||||
uint8_t ErrorCode;
|
||||
|
||||
/* Get and process the configuration descriptor data */
|
||||
if ((ErrorCode = ProcessConfigurationDescriptor()) != SuccessfulConfigRead)
|
||||
{
|
||||
if (ErrorCode == ControlError)
|
||||
puts_P(PSTR(ESC_FG_RED "Control Error (Get Configuration).\r\n"));
|
||||
else
|
||||
puts_P(PSTR(ESC_FG_RED "Invalid Device.\r\n"));
|
||||
|
||||
printf_P(PSTR(" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
|
||||
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Set the device configuration to the first configuration (rarely do devices use multiple configurations) */
|
||||
if ((ErrorCode = USB_Host_SetDeviceConfiguration(1)) != HOST_SENDCONTROL_Successful)
|
||||
{
|
||||
printf_P(PSTR(ESC_FG_RED "Control Error (Set Configuration).\r\n"
|
||||
" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
|
||||
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
if ((ErrorCode = USB_Host_SetInterfaceAltSetting(StreamingInterfaceIndex,
|
||||
StreamingInterfaceAltSetting)) != HOST_SENDCONTROL_Successful)
|
||||
{
|
||||
printf_P(PSTR(ESC_FG_RED "Could not set alternative streaming interface setting.\r\n"
|
||||
" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
|
||||
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
USB_ControlRequest = (USB_Request_Header_t)
|
||||
{
|
||||
.bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_ENDPOINT),
|
||||
.bRequest = AUDIO_REQ_SetCurrent,
|
||||
.wValue = (AUDIO_EPCONTROL_SamplingFreq << 8),
|
||||
.wIndex = StreamingEndpointAddress,
|
||||
.wLength = sizeof(USB_Audio_SampleFreq_t),
|
||||
};
|
||||
|
||||
USB_Audio_SampleFreq_t SampleRate = AUDIO_SAMPLE_FREQ(48000);
|
||||
|
||||
/* Select the control pipe for the request transfer */
|
||||
Pipe_SelectPipe(PIPE_CONTROLPIPE);
|
||||
|
||||
/* Set the sample rate on the streaming interface endpoint */
|
||||
if ((ErrorCode = USB_Host_SendControlRequest(&SampleRate)) != HOST_SENDCONTROL_Successful)
|
||||
{
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
USB_Host_SetDeviceConfiguration(0);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Sample reload timer initialization */
|
||||
TIMSK0 = (1 << OCIE0A);
|
||||
OCR0A = ((F_CPU / 8 / 48000) - 1);
|
||||
TCCR0A = (1 << WGM01); // CTC mode
|
||||
TCCR0B = (1 << CS01); // Fcpu/8 speed
|
||||
|
||||
puts_P(PSTR("Speaker Enumerated.\r\n"));
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_READY);
|
||||
}
|
||||
|
||||
|
|
@ -129,102 +195,6 @@ void EVENT_USB_Host_DeviceEnumerationFailed(const uint8_t ErrorCode,
|
|||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
}
|
||||
|
||||
void Audio_Task(void)
|
||||
{
|
||||
uint8_t ErrorCode;
|
||||
|
||||
switch (USB_HostState)
|
||||
{
|
||||
case HOST_STATE_Addressed:
|
||||
puts_P(PSTR("Getting Config Data.\r\n"));
|
||||
|
||||
/* Get and process the configuration descriptor data */
|
||||
if ((ErrorCode = ProcessConfigurationDescriptor()) != SuccessfulConfigRead)
|
||||
{
|
||||
if (ErrorCode == ControlError)
|
||||
puts_P(PSTR(ESC_FG_RED "Control Error (Get Configuration).\r\n"));
|
||||
else
|
||||
puts_P(PSTR(ESC_FG_RED "Invalid Device.\r\n"));
|
||||
|
||||
printf_P(PSTR(" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
|
||||
|
||||
/* Indicate error status */
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
|
||||
/* Wait until USB device disconnected */
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Set the device configuration to the first configuration (rarely do devices use multiple configurations) */
|
||||
if ((ErrorCode = USB_Host_SetDeviceConfiguration(1)) != HOST_SENDCONTROL_Successful)
|
||||
{
|
||||
printf_P(PSTR(ESC_FG_RED "Control Error (Set Configuration).\r\n"
|
||||
" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
|
||||
|
||||
/* Indicate error status */
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
|
||||
/* Wait until USB device disconnected */
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
if ((ErrorCode = USB_Host_SetInterfaceAltSetting(StreamingInterfaceIndex,
|
||||
StreamingInterfaceAltSetting)) != HOST_SENDCONTROL_Successful)
|
||||
{
|
||||
printf_P(PSTR(ESC_FG_RED "Could not set alternative streaming interface setting.\r\n"
|
||||
" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
|
||||
|
||||
/* Indicate error status */
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
|
||||
/* Wait until USB device disconnected */
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
USB_ControlRequest = (USB_Request_Header_t)
|
||||
{
|
||||
.bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_ENDPOINT),
|
||||
.bRequest = AUDIO_REQ_SetCurrent,
|
||||
.wValue = (AUDIO_EPCONTROL_SamplingFreq << 8),
|
||||
.wIndex = StreamingEndpointAddress,
|
||||
.wLength = sizeof(USB_Audio_SampleFreq_t),
|
||||
};
|
||||
|
||||
USB_Audio_SampleFreq_t SampleRate = AUDIO_SAMPLE_FREQ(48000);
|
||||
|
||||
/* Select the control pipe for the request transfer */
|
||||
Pipe_SelectPipe(PIPE_CONTROLPIPE);
|
||||
|
||||
/* Set the sample rate on the streaming interface endpoint */
|
||||
if ((ErrorCode = USB_Host_SendControlRequest(&SampleRate)) != HOST_SENDCONTROL_Successful)
|
||||
{
|
||||
/* Indicate error status */
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
|
||||
/* Wait until USB device disconnected */
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Sample reload timer initialization */
|
||||
TIMSK0 = (1 << OCIE0A);
|
||||
OCR0A = ((F_CPU / 8 / 48000) - 1);
|
||||
TCCR0A = (1 << WGM01); // CTC mode
|
||||
TCCR0B = (1 << CS01); // Fcpu/8 speed
|
||||
|
||||
puts_P(PSTR("Speaker Enumerated.\r\n"));
|
||||
|
||||
USB_HostState = HOST_STATE_Configured;
|
||||
break;
|
||||
case HOST_STATE_Configured:
|
||||
/* Do nothing - audio stream is handled by the timer interrupt routine */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/** ISR to handle the reloading of the endpoint with the next sample. */
|
||||
ISR(TIMER0_COMPA_vect, ISR_BLOCK)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -80,7 +80,6 @@
|
|||
#define LEDMASK_USB_ERROR (LEDS_LED1 | LEDS_LED3)
|
||||
|
||||
/* Function Prototypes: */
|
||||
void Audio_Task(void);
|
||||
void SetupHardware(void);
|
||||
|
||||
void EVENT_USB_Host_HostError(const uint8_t ErrorCode);
|
||||
|
|
|
|||
|
|
@ -50,7 +50,8 @@ int main(void)
|
|||
|
||||
for (;;)
|
||||
{
|
||||
HID_Host_Task();
|
||||
ReadNextReport();
|
||||
|
||||
USB_USBTask();
|
||||
}
|
||||
}
|
||||
|
|
@ -97,6 +98,35 @@ void EVENT_USB_Host_DeviceUnattached(void)
|
|||
*/
|
||||
void EVENT_USB_Host_DeviceEnumerationComplete(void)
|
||||
{
|
||||
puts_P(PSTR("Getting Config Data.\r\n"));
|
||||
|
||||
uint8_t ErrorCode;
|
||||
|
||||
/* Get and process the configuration descriptor data */
|
||||
if ((ErrorCode = ProcessConfigurationDescriptor()) != SuccessfulConfigRead)
|
||||
{
|
||||
if (ErrorCode == ControlError)
|
||||
puts_P(PSTR(ESC_FG_RED "Control Error (Get Configuration).\r\n"));
|
||||
else
|
||||
puts_P(PSTR(ESC_FG_RED "Invalid Device.\r\n"));
|
||||
|
||||
printf_P(PSTR(" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
|
||||
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Set the device configuration to the first configuration (rarely do devices use multiple configurations) */
|
||||
if ((ErrorCode = USB_Host_SetDeviceConfiguration(1)) != HOST_SENDCONTROL_Successful)
|
||||
{
|
||||
printf_P(PSTR(ESC_FG_RED "Control Error (Set Configuration).\r\n"
|
||||
" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
|
||||
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
puts_P(PSTR("HID Device Enumerated.\r\n"));
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_READY);
|
||||
}
|
||||
|
||||
|
|
@ -131,6 +161,9 @@ void EVENT_USB_Host_DeviceEnumerationFailed(const uint8_t ErrorCode,
|
|||
*/
|
||||
void ReadNextReport(void)
|
||||
{
|
||||
if (USB_HostState != HOST_STATE_Configured)
|
||||
return;
|
||||
|
||||
/* Select and unfreeze HID data IN pipe */
|
||||
Pipe_SelectPipe(HID_DATA_IN_PIPE);
|
||||
Pipe_Unfreeze();
|
||||
|
|
@ -178,6 +211,9 @@ void WriteNextReport(uint8_t* ReportOUTData,
|
|||
const uint8_t ReportType,
|
||||
uint16_t ReportLength)
|
||||
{
|
||||
if (USB_HostState != HOST_STATE_Configured)
|
||||
return;
|
||||
|
||||
/* Select the HID data OUT pipe */
|
||||
Pipe_SelectPipe(HID_DATA_OUT_PIPE);
|
||||
|
||||
|
|
@ -229,59 +265,3 @@ void WriteNextReport(uint8_t* ReportOUTData,
|
|||
}
|
||||
}
|
||||
|
||||
/** Task to set the configuration of the attached device after it has been enumerated, and to read and process
|
||||
* HID reports from the device and to send reports if desired.
|
||||
*/
|
||||
void HID_Host_Task(void)
|
||||
{
|
||||
uint8_t ErrorCode;
|
||||
|
||||
/* Switch to determine what user-application handled host state the host state machine is in */
|
||||
switch (USB_HostState)
|
||||
{
|
||||
case HOST_STATE_Addressed:
|
||||
puts_P(PSTR("Getting Config Data.\r\n"));
|
||||
|
||||
/* Get and process the configuration descriptor data */
|
||||
if ((ErrorCode = ProcessConfigurationDescriptor()) != SuccessfulConfigRead)
|
||||
{
|
||||
if (ErrorCode == ControlError)
|
||||
puts_P(PSTR(ESC_FG_RED "Control Error (Get Configuration).\r\n"));
|
||||
else
|
||||
puts_P(PSTR(ESC_FG_RED "Invalid Device.\r\n"));
|
||||
|
||||
printf_P(PSTR(" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
|
||||
|
||||
/* Indicate error status */
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
|
||||
/* Wait until USB device disconnected */
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Set the device configuration to the first configuration (rarely do devices use multiple configurations) */
|
||||
if ((ErrorCode = USB_Host_SetDeviceConfiguration(1)) != HOST_SENDCONTROL_Successful)
|
||||
{
|
||||
printf_P(PSTR(ESC_FG_RED "Control Error (Set Configuration).\r\n"
|
||||
" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
|
||||
|
||||
/* Indicate error status */
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
|
||||
/* Wait until USB device disconnected */
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
puts_P(PSTR("HID Device Enumerated.\r\n"));
|
||||
|
||||
USB_HostState = HOST_STATE_Configured;
|
||||
break;
|
||||
case HOST_STATE_Configured:
|
||||
ReadNextReport();
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -76,8 +76,12 @@
|
|||
|
||||
/* Function Prototypes: */
|
||||
void SetupHardware(void);
|
||||
void HID_Host_Task(void);
|
||||
|
||||
void ReadNextReport(void);
|
||||
void WriteNextReport(uint8_t* ReportOUTData,
|
||||
const uint8_t ReportIndex,
|
||||
const uint8_t ReportType,
|
||||
uint16_t ReportLength);
|
||||
|
||||
void EVENT_USB_Host_HostError(const uint8_t ErrorCode);
|
||||
void EVENT_USB_Host_DeviceAttached(void);
|
||||
void EVENT_USB_Host_DeviceUnattached(void);
|
||||
|
|
@ -85,11 +89,5 @@
|
|||
const uint8_t SubErrorCode);
|
||||
void EVENT_USB_Host_DeviceEnumerationComplete(void);
|
||||
|
||||
void ReadNextReport(void);
|
||||
void WriteNextReport(uint8_t* ReportOUTData,
|
||||
const uint8_t ReportIndex,
|
||||
const uint8_t ReportType,
|
||||
uint16_t ReportLength);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -50,7 +50,8 @@ int main(void)
|
|||
|
||||
for (;;)
|
||||
{
|
||||
Joystick_HID_Task();
|
||||
JoystickHost_Task();
|
||||
|
||||
USB_USBTask();
|
||||
}
|
||||
}
|
||||
|
|
@ -97,6 +98,52 @@ void EVENT_USB_Host_DeviceUnattached(void)
|
|||
*/
|
||||
void EVENT_USB_Host_DeviceEnumerationComplete(void)
|
||||
{
|
||||
puts_P(PSTR("Getting Config Data.\r\n"));
|
||||
|
||||
uint8_t ErrorCode;
|
||||
|
||||
/* Get and process the configuration descriptor data */
|
||||
if ((ErrorCode = ProcessConfigurationDescriptor()) != SuccessfulConfigRead)
|
||||
{
|
||||
if (ErrorCode == ControlError)
|
||||
puts_P(PSTR(ESC_FG_RED "Control Error (Get Configuration).\r\n"));
|
||||
else
|
||||
puts_P(PSTR(ESC_FG_RED "Invalid Device.\r\n"));
|
||||
|
||||
printf_P(PSTR(" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
|
||||
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Set the device configuration to the first configuration (rarely do devices use multiple configurations) */
|
||||
if ((ErrorCode = USB_Host_SetDeviceConfiguration(1)) != HOST_SENDCONTROL_Successful)
|
||||
{
|
||||
printf_P(PSTR(ESC_FG_RED "Control Error (Set Configuration).\r\n"
|
||||
" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
|
||||
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
printf_P(PSTR("Processing HID Report (Size %d Bytes).\r\n"), HIDReportSize);
|
||||
|
||||
/* Get and process the device's first HID report descriptor */
|
||||
if ((ErrorCode = GetHIDReportData()) != ParseSuccessful)
|
||||
{
|
||||
puts_P(PSTR(ESC_FG_RED "Report Parse Error.\r\n"));
|
||||
|
||||
if (!(HIDReportInfo.TotalReportItems))
|
||||
puts_P(PSTR("Not a valid Joystick." ESC_FG_WHITE));
|
||||
else
|
||||
printf_P(PSTR(" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
|
||||
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
USB_Host_SetDeviceConfiguration(0);
|
||||
return;
|
||||
}
|
||||
|
||||
puts_P(PSTR("Joystick Enumerated.\r\n"));
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_READY);
|
||||
}
|
||||
|
||||
|
|
@ -125,104 +172,40 @@ void EVENT_USB_Host_DeviceEnumerationFailed(const uint8_t ErrorCode, const uint8
|
|||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
}
|
||||
|
||||
/** Task to set the configuration of the attached device after it has been enumerated, and to read and process
|
||||
* the HID report descriptor and HID reports from the device and display the results onto the board LEDs.
|
||||
/** Task to read and process the HID report descriptor and HID reports from the device
|
||||
* and display the results onto the board LEDs.
|
||||
*/
|
||||
void Joystick_HID_Task(void)
|
||||
void JoystickHost_Task(void)
|
||||
{
|
||||
uint8_t ErrorCode;
|
||||
if (USB_HostState != HOST_STATE_Configured)
|
||||
return;
|
||||
|
||||
/* Select and unfreeze joystick data pipe */
|
||||
Pipe_SelectPipe(JOYSTICK_DATA_IN_PIPE);
|
||||
Pipe_Unfreeze();
|
||||
|
||||
/* Switch to determine what user-application handled host state the host state machine is in */
|
||||
switch (USB_HostState)
|
||||
/* Check to see if a packet has been received */
|
||||
if (Pipe_IsINReceived())
|
||||
{
|
||||
case HOST_STATE_Addressed:
|
||||
puts_P(PSTR("Getting Config Data.\r\n"));
|
||||
/* Check if data has been received from the attached joystick */
|
||||
if (Pipe_IsReadWriteAllowed())
|
||||
{
|
||||
/* Create buffer big enough for the report */
|
||||
uint8_t JoystickReport[Pipe_BytesInPipe()];
|
||||
|
||||
/* Get and process the configuration descriptor data */
|
||||
if ((ErrorCode = ProcessConfigurationDescriptor()) != SuccessfulConfigRead)
|
||||
{
|
||||
if (ErrorCode == ControlError)
|
||||
puts_P(PSTR(ESC_FG_RED "Control Error (Get Configuration).\r\n"));
|
||||
else
|
||||
puts_P(PSTR(ESC_FG_RED "Invalid Device.\r\n"));
|
||||
/* Load in the joystick report */
|
||||
Pipe_Read_Stream_LE(JoystickReport, Pipe_BytesInPipe(), NULL);
|
||||
|
||||
printf_P(PSTR(" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
|
||||
/* Process the read in joystick report from the device */
|
||||
ProcessJoystickReport(JoystickReport);
|
||||
}
|
||||
|
||||
/* Indicate error via status LEDs */
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
|
||||
/* Wait until USB device disconnected */
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Set the device configuration to the first configuration (rarely do devices use multiple configurations) */
|
||||
if ((ErrorCode = USB_Host_SetDeviceConfiguration(1)) != HOST_SENDCONTROL_Successful)
|
||||
{
|
||||
printf_P(PSTR(ESC_FG_RED "Control Error (Set Configuration).\r\n"
|
||||
" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
|
||||
|
||||
/* Indicate error via status LEDs */
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
|
||||
/* Wait until USB device disconnected */
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
printf_P(PSTR("Processing HID Report (Size %d Bytes).\r\n"), HIDReportSize);
|
||||
|
||||
/* Get and process the device's first HID report descriptor */
|
||||
if ((ErrorCode = GetHIDReportData()) != ParseSuccessful)
|
||||
{
|
||||
puts_P(PSTR(ESC_FG_RED "Report Parse Error.\r\n"));
|
||||
|
||||
if (!(HIDReportInfo.TotalReportItems))
|
||||
puts_P(PSTR("Not a valid Joystick." ESC_FG_WHITE));
|
||||
else
|
||||
printf_P(PSTR(" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
|
||||
|
||||
/* Indicate error via status LEDs */
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
|
||||
/* Wait until USB device disconnected */
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
puts_P(PSTR("Joystick Enumerated.\r\n"));
|
||||
|
||||
USB_HostState = HOST_STATE_Configured;
|
||||
break;
|
||||
case HOST_STATE_Configured:
|
||||
/* Select and unfreeze joystick data pipe */
|
||||
Pipe_SelectPipe(JOYSTICK_DATA_IN_PIPE);
|
||||
Pipe_Unfreeze();
|
||||
|
||||
/* Check to see if a packet has been received */
|
||||
if (Pipe_IsINReceived())
|
||||
{
|
||||
/* Check if data has been received from the attached joystick */
|
||||
if (Pipe_IsReadWriteAllowed())
|
||||
{
|
||||
/* Create buffer big enough for the report */
|
||||
uint8_t JoystickReport[Pipe_BytesInPipe()];
|
||||
|
||||
/* Load in the joystick report */
|
||||
Pipe_Read_Stream_LE(JoystickReport, Pipe_BytesInPipe(), NULL);
|
||||
|
||||
/* Process the read in joystick report from the device */
|
||||
ProcessJoystickReport(JoystickReport);
|
||||
}
|
||||
|
||||
/* Clear the IN endpoint, ready for next data packet */
|
||||
Pipe_ClearIN();
|
||||
}
|
||||
|
||||
/* Freeze joystick data pipe */
|
||||
Pipe_Freeze();
|
||||
break;
|
||||
/* Clear the IN endpoint, ready for next data packet */
|
||||
Pipe_ClearIN();
|
||||
}
|
||||
|
||||
/* Freeze joystick data pipe */
|
||||
Pipe_Freeze();
|
||||
}
|
||||
|
||||
/** Processes a read HID report from an attached joystick, extracting out elements via the HID parser results
|
||||
|
|
|
|||
|
|
@ -67,8 +67,8 @@
|
|||
#define LEDMASK_USB_ERROR (LEDS_LED1 | LEDS_LED3)
|
||||
|
||||
/* Function Prototypes: */
|
||||
void Joystick_HID_Task(void);
|
||||
void SetupHardware(void);
|
||||
void JoystickHost_Task(void);
|
||||
|
||||
void EVENT_USB_Host_HostError(const uint8_t ErrorCode);
|
||||
void EVENT_USB_Host_DeviceAttached(void);
|
||||
|
|
|
|||
|
|
@ -50,7 +50,8 @@ int main(void)
|
|||
|
||||
for (;;)
|
||||
{
|
||||
Keyboard_HID_Task();
|
||||
KeyboardHost_Task();
|
||||
|
||||
USB_USBTask();
|
||||
}
|
||||
}
|
||||
|
|
@ -97,6 +98,59 @@ void EVENT_USB_Host_DeviceUnattached(void)
|
|||
*/
|
||||
void EVENT_USB_Host_DeviceEnumerationComplete(void)
|
||||
{
|
||||
puts_P(PSTR("Getting Config Data.\r\n"));
|
||||
|
||||
uint8_t ErrorCode;
|
||||
|
||||
/* Get and process the configuration descriptor data */
|
||||
if ((ErrorCode = ProcessConfigurationDescriptor()) != SuccessfulConfigRead)
|
||||
{
|
||||
if (ErrorCode == ControlError)
|
||||
puts_P(PSTR(ESC_FG_RED "Control Error (Get Configuration).\r\n"));
|
||||
else
|
||||
puts_P(PSTR(ESC_FG_RED "Invalid Device.\r\n"));
|
||||
|
||||
printf_P(PSTR(" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
|
||||
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Set the device configuration to the first configuration (rarely do devices use multiple configurations) */
|
||||
if ((ErrorCode = USB_Host_SetDeviceConfiguration(1)) != HOST_SENDCONTROL_Successful)
|
||||
{
|
||||
printf_P(PSTR(ESC_FG_RED "Control Error (Set Configuration).\r\n"
|
||||
" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
|
||||
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
/* HID class request to set the keyboard protocol to the Boot Protocol */
|
||||
USB_ControlRequest = (USB_Request_Header_t)
|
||||
{
|
||||
.bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE),
|
||||
.bRequest = HID_REQ_SetProtocol,
|
||||
.wValue = 0,
|
||||
.wIndex = 0,
|
||||
.wLength = 0,
|
||||
};
|
||||
|
||||
/* Select the control pipe for the request transfer */
|
||||
Pipe_SelectPipe(PIPE_CONTROLPIPE);
|
||||
|
||||
/* Send the request, display error and wait for device detach if request fails */
|
||||
if ((ErrorCode = USB_Host_SendControlRequest(NULL)) != HOST_SENDCONTROL_Successful)
|
||||
{
|
||||
printf_P(PSTR(ESC_FG_RED "Control Error (Set Protocol).\r\n"
|
||||
" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
|
||||
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
USB_Host_SetDeviceConfiguration(0);
|
||||
return;
|
||||
}
|
||||
|
||||
puts_P(PSTR("Keyboard Enumerated.\r\n"));
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_READY);
|
||||
}
|
||||
|
||||
|
|
@ -126,12 +180,13 @@ void EVENT_USB_Host_DeviceEnumerationFailed(const uint8_t ErrorCode,
|
|||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
}
|
||||
|
||||
/** Reads in and processes the next report from the attached device, displaying the report
|
||||
/** Task to read in and processes the next report from the attached device, displaying the report
|
||||
* contents on the board LEDs and via the serial port.
|
||||
*/
|
||||
void ReadNextReport(void)
|
||||
void KeyboardHost_Task(void)
|
||||
{
|
||||
USB_KeyboardReport_Data_t KeyboardReport;
|
||||
if (USB_HostState != HOST_STATE_Configured)
|
||||
return;
|
||||
|
||||
/* Select keyboard data pipe */
|
||||
Pipe_SelectPipe(KEYBOARD_DATA_IN_PIPE);
|
||||
|
|
@ -151,6 +206,8 @@ void ReadNextReport(void)
|
|||
/* Ensure pipe contains data before trying to read from it */
|
||||
if (Pipe_IsReadWriteAllowed())
|
||||
{
|
||||
USB_KeyboardReport_Data_t KeyboardReport;
|
||||
|
||||
/* Read in keyboard report data */
|
||||
Pipe_Read_Stream_LE(&KeyboardReport, sizeof(KeyboardReport), NULL);
|
||||
|
||||
|
|
@ -203,86 +260,3 @@ void ReadNextReport(void)
|
|||
Pipe_Freeze();
|
||||
}
|
||||
|
||||
/** Task to set the configuration of the attached device after it has been enumerated, and to read and process
|
||||
* HID reports from the device and display the results onto the board LEDs.
|
||||
*/
|
||||
void Keyboard_HID_Task(void)
|
||||
{
|
||||
uint8_t ErrorCode;
|
||||
|
||||
switch (USB_HostState)
|
||||
{
|
||||
case HOST_STATE_Addressed:
|
||||
puts_P(PSTR("Getting Config Data.\r\n"));
|
||||
|
||||
/* Get and process the configuration descriptor data */
|
||||
if ((ErrorCode = ProcessConfigurationDescriptor()) != SuccessfulConfigRead)
|
||||
{
|
||||
if (ErrorCode == ControlError)
|
||||
puts_P(PSTR(ESC_FG_RED "Control Error (Get Configuration).\r\n"));
|
||||
else
|
||||
puts_P(PSTR(ESC_FG_RED "Invalid Device.\r\n"));
|
||||
|
||||
printf_P(PSTR(" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
|
||||
|
||||
/* Indicate error status */
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
|
||||
/* Wait until USB device disconnected */
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Set the device configuration to the first configuration (rarely do devices use multiple configurations) */
|
||||
if ((ErrorCode = USB_Host_SetDeviceConfiguration(1)) != HOST_SENDCONTROL_Successful)
|
||||
{
|
||||
printf_P(PSTR(ESC_FG_RED "Control Error (Set Configuration).\r\n"
|
||||
" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
|
||||
|
||||
/* Indicate error status */
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
|
||||
/* Wait until USB device disconnected */
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
/* HID class request to set the keyboard protocol to the Boot Protocol */
|
||||
USB_ControlRequest = (USB_Request_Header_t)
|
||||
{
|
||||
.bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE),
|
||||
.bRequest = HID_REQ_SetProtocol,
|
||||
.wValue = 0,
|
||||
.wIndex = 0,
|
||||
.wLength = 0,
|
||||
};
|
||||
|
||||
/* Select the control pipe for the request transfer */
|
||||
Pipe_SelectPipe(PIPE_CONTROLPIPE);
|
||||
|
||||
/* Send the request, display error and wait for device detach if request fails */
|
||||
if ((ErrorCode = USB_Host_SendControlRequest(NULL)) != HOST_SENDCONTROL_Successful)
|
||||
{
|
||||
printf_P(PSTR(ESC_FG_RED "Control Error (Set Protocol).\r\n"
|
||||
" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
|
||||
|
||||
/* Indicate error status */
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
|
||||
/* Wait until USB device disconnected */
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
puts_P(PSTR("Keyboard Enumerated.\r\n"));
|
||||
|
||||
USB_HostState = HOST_STATE_Configured;
|
||||
break;
|
||||
case HOST_STATE_Configured:
|
||||
/* If a report has been received, read and process it */
|
||||
ReadNextReport();
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -66,8 +66,8 @@
|
|||
#define LEDMASK_USB_ERROR (LEDS_LED1 | LEDS_LED3)
|
||||
|
||||
/* Function Prototypes: */
|
||||
void Keyboard_HID_Task(void);
|
||||
void SetupHardware(void);
|
||||
void KeyboardHost_Task(void);
|
||||
|
||||
void EVENT_USB_Host_HostError(const uint8_t ErrorCode);
|
||||
void EVENT_USB_Host_DeviceAttached(void);
|
||||
|
|
@ -76,7 +76,5 @@
|
|||
const uint8_t SubErrorCode);
|
||||
void EVENT_USB_Host_DeviceEnumerationComplete(void);
|
||||
|
||||
void ReadNextReport(void);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -50,7 +50,8 @@ int main(void)
|
|||
|
||||
for (;;)
|
||||
{
|
||||
Keyboard_HID_Task();
|
||||
KeyboardHost_Task();
|
||||
|
||||
USB_USBTask();
|
||||
}
|
||||
}
|
||||
|
|
@ -97,6 +98,53 @@ void EVENT_USB_Host_DeviceUnattached(void)
|
|||
*/
|
||||
void EVENT_USB_Host_DeviceEnumerationComplete(void)
|
||||
{
|
||||
puts_P(PSTR("Getting Config Data.\r\n"));
|
||||
|
||||
uint8_t ErrorCode;
|
||||
|
||||
/* Get and process the configuration descriptor data */
|
||||
if ((ErrorCode = ProcessConfigurationDescriptor()) != SuccessfulConfigRead)
|
||||
{
|
||||
if (ErrorCode == ControlError)
|
||||
puts_P(PSTR(ESC_FG_RED "Control Error (Get Configuration).\r\n"));
|
||||
else
|
||||
puts_P(PSTR(ESC_FG_RED "Invalid Device.\r\n"));
|
||||
|
||||
printf_P(PSTR(" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
|
||||
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Set the device configuration to the first configuration (rarely do devices use multiple configurations) */
|
||||
if ((ErrorCode = USB_Host_SetDeviceConfiguration(1)) != HOST_SENDCONTROL_Successful)
|
||||
|
||||
{
|
||||
puts_P(PSTR(ESC_FG_RED "Control Error (Set Configuration).\r\n"));
|
||||
printf_P(PSTR(" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
|
||||
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
printf_P(PSTR("Processing HID Report (Size %d Bytes).\r\n"), HIDReportSize);
|
||||
|
||||
/* Get and process the device's first HID report descriptor */
|
||||
if ((ErrorCode = GetHIDReportData()) != ParseSuccessful)
|
||||
{
|
||||
puts_P(PSTR(ESC_FG_RED "Report Parse Error.\r\n"));
|
||||
|
||||
if (!(HIDReportInfo.TotalReportItems))
|
||||
puts_P(PSTR("Not a valid Keyboard." ESC_FG_WHITE));
|
||||
else
|
||||
printf_P(PSTR(" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
|
||||
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
USB_Host_SetDeviceConfiguration(0);
|
||||
return;
|
||||
}
|
||||
|
||||
puts_P(PSTR("Keyboard Enumerated.\r\n"));
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_READY);
|
||||
}
|
||||
|
||||
|
|
@ -126,104 +174,40 @@ void EVENT_USB_Host_DeviceEnumerationFailed(const uint8_t ErrorCode,
|
|||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
}
|
||||
|
||||
/** Task to set the configuration of the attached device after it has been enumerated, and to read and process
|
||||
* the HID report descriptor and HID reports from the device and display the results onto the board LEDs.
|
||||
/** Task to read in and processes the next report from the attached device, displaying the report
|
||||
* contents on the board LEDs and via the serial port.
|
||||
*/
|
||||
void Keyboard_HID_Task(void)
|
||||
void KeyboardHost_Task(void)
|
||||
{
|
||||
uint8_t ErrorCode;
|
||||
if (USB_HostState != HOST_STATE_Configured)
|
||||
return;
|
||||
|
||||
/* Select and unfreeze keyboard data pipe */
|
||||
Pipe_SelectPipe(KEYBOARD_DATA_IN_PIPE);
|
||||
Pipe_Unfreeze();
|
||||
|
||||
switch (USB_HostState)
|
||||
/* Check to see if a packet has been received */
|
||||
if (Pipe_IsINReceived())
|
||||
{
|
||||
case HOST_STATE_Addressed:
|
||||
puts_P(PSTR("Getting Config Data.\r\n"));
|
||||
/* Check if data has been received from the attached keyboard */
|
||||
if (Pipe_IsReadWriteAllowed())
|
||||
{
|
||||
/* Create buffer big enough for the report */
|
||||
uint8_t KeyboardReport[Pipe_BytesInPipe()];
|
||||
|
||||
/* Get and process the configuration descriptor data */
|
||||
if ((ErrorCode = ProcessConfigurationDescriptor()) != SuccessfulConfigRead)
|
||||
{
|
||||
if (ErrorCode == ControlError)
|
||||
puts_P(PSTR(ESC_FG_RED "Control Error (Get Configuration).\r\n"));
|
||||
else
|
||||
puts_P(PSTR(ESC_FG_RED "Invalid Device.\r\n"));
|
||||
/* Load in the keyboard report */
|
||||
Pipe_Read_Stream_LE(KeyboardReport, Pipe_BytesInPipe(), NULL);
|
||||
|
||||
printf_P(PSTR(" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
|
||||
/* Process the read in keyboard report from the device */
|
||||
ProcessKeyboardReport(KeyboardReport);
|
||||
}
|
||||
|
||||
/* Indicate error via status LEDs */
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
|
||||
/* Wait until USB device disconnected */
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Set the device configuration to the first configuration (rarely do devices use multiple configurations) */
|
||||
if ((ErrorCode = USB_Host_SetDeviceConfiguration(1)) != HOST_SENDCONTROL_Successful)
|
||||
|
||||
{
|
||||
puts_P(PSTR(ESC_FG_RED "Control Error (Set Configuration).\r\n"));
|
||||
printf_P(PSTR(" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
|
||||
|
||||
/* Indicate error via status LEDs */
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
|
||||
/* Wait until USB device disconnected */
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
printf_P(PSTR("Processing HID Report (Size %d Bytes).\r\n"), HIDReportSize);
|
||||
|
||||
/* Get and process the device's first HID report descriptor */
|
||||
if ((ErrorCode = GetHIDReportData()) != ParseSuccessful)
|
||||
{
|
||||
puts_P(PSTR(ESC_FG_RED "Report Parse Error.\r\n"));
|
||||
|
||||
if (!(HIDReportInfo.TotalReportItems))
|
||||
puts_P(PSTR("Not a valid Keyboard." ESC_FG_WHITE));
|
||||
else
|
||||
printf_P(PSTR(" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
|
||||
|
||||
/* Indicate error via status LEDs */
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
|
||||
/* Wait until USB device disconnected */
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
puts_P(PSTR("Keyboard Enumerated.\r\n"));
|
||||
|
||||
USB_HostState = HOST_STATE_Configured;
|
||||
break;
|
||||
case HOST_STATE_Configured:
|
||||
/* Select and unfreeze keyboard data pipe */
|
||||
Pipe_SelectPipe(KEYBOARD_DATA_IN_PIPE);
|
||||
Pipe_Unfreeze();
|
||||
|
||||
/* Check to see if a packet has been received */
|
||||
if (Pipe_IsINReceived())
|
||||
{
|
||||
/* Check if data has been received from the attached keyboard */
|
||||
if (Pipe_IsReadWriteAllowed())
|
||||
{
|
||||
/* Create buffer big enough for the report */
|
||||
uint8_t KeyboardReport[Pipe_BytesInPipe()];
|
||||
|
||||
/* Load in the keyboard report */
|
||||
Pipe_Read_Stream_LE(KeyboardReport, Pipe_BytesInPipe(), NULL);
|
||||
|
||||
/* Process the read in keyboard report from the device */
|
||||
ProcessKeyboardReport(KeyboardReport);
|
||||
}
|
||||
|
||||
/* Clear the IN endpoint, ready for next data packet */
|
||||
Pipe_ClearIN();
|
||||
}
|
||||
|
||||
/* Freeze keyboard data pipe */
|
||||
Pipe_Freeze();
|
||||
break;
|
||||
/* Clear the IN endpoint, ready for next data packet */
|
||||
Pipe_ClearIN();
|
||||
}
|
||||
|
||||
/* Freeze keyboard data pipe */
|
||||
Pipe_Freeze();
|
||||
}
|
||||
|
||||
/** Processes a read HID report from an attached keyboard, extracting out elements via the HID parser results
|
||||
|
|
|
|||
|
|
@ -62,8 +62,8 @@
|
|||
#define LEDMASK_USB_ERROR (LEDS_LED1 | LEDS_LED3)
|
||||
|
||||
/* Function Prototypes: */
|
||||
void Keyboard_HID_Task(void);
|
||||
void SetupHardware(void);
|
||||
void KeyboardHost_Task(void);
|
||||
|
||||
void EVENT_USB_Host_HostError(const uint8_t ErrorCode);
|
||||
void EVENT_USB_Host_DeviceAttached(void);
|
||||
|
|
|
|||
|
|
@ -50,7 +50,8 @@ int main(void)
|
|||
|
||||
for (;;)
|
||||
{
|
||||
MIDI_Host_Task();
|
||||
MIDIHost_Task();
|
||||
|
||||
USB_USBTask();
|
||||
}
|
||||
}
|
||||
|
|
@ -99,6 +100,35 @@ void EVENT_USB_Host_DeviceUnattached(void)
|
|||
*/
|
||||
void EVENT_USB_Host_DeviceEnumerationComplete(void)
|
||||
{
|
||||
puts_P(PSTR("Getting Config Data.\r\n"));
|
||||
|
||||
uint8_t ErrorCode;
|
||||
|
||||
/* Get and process the configuration descriptor data */
|
||||
if ((ErrorCode = ProcessConfigurationDescriptor()) != SuccessfulConfigRead)
|
||||
{
|
||||
if (ErrorCode == ControlError)
|
||||
puts_P(PSTR(ESC_FG_RED "Control Error (Get Configuration).\r\n"));
|
||||
else
|
||||
puts_P(PSTR(ESC_FG_RED "Invalid Device.\r\n"));
|
||||
|
||||
printf_P(PSTR(" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
|
||||
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Set the device configuration to the first configuration (rarely do devices use multiple configurations) */
|
||||
if ((ErrorCode = USB_Host_SetDeviceConfiguration(1)) != HOST_SENDCONTROL_Successful)
|
||||
{
|
||||
printf_P(PSTR(ESC_FG_RED "Control Error (Set Configuration).\r\n"
|
||||
" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
|
||||
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
puts_P(PSTR("MIDI Device Enumerated.\r\n"));
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_READY);
|
||||
}
|
||||
|
||||
|
|
@ -128,147 +158,102 @@ void EVENT_USB_Host_DeviceEnumerationFailed(const uint8_t ErrorCode,
|
|||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
}
|
||||
|
||||
/** Task to set the configuration of the attached device after it has been enumerated, and to read in
|
||||
* note on/off messages from the attached MIDI device and print it to the serial port. When the board
|
||||
* joystick or buttons are pressed, note on/off messages are sent to the attached device.
|
||||
/** Task to read in note on/off messages from the attached MIDI device and print it to the serial port.
|
||||
* When the board joystick or buttons are pressed, note on/off messages are sent to the attached device.
|
||||
*/
|
||||
void MIDI_Host_Task(void)
|
||||
void MIDIHost_Task(void)
|
||||
{
|
||||
uint8_t ErrorCode;
|
||||
if (USB_HostState != HOST_STATE_Configured)
|
||||
return;
|
||||
|
||||
Pipe_SelectPipe(MIDI_DATA_IN_PIPE);
|
||||
|
||||
switch (USB_HostState)
|
||||
if (Pipe_IsINReceived())
|
||||
{
|
||||
case HOST_STATE_Addressed:
|
||||
puts_P(PSTR("Getting Config Data.\r\n"));
|
||||
MIDI_EventPacket_t MIDIEvent;
|
||||
|
||||
/* Get and process the configuration descriptor data */
|
||||
if ((ErrorCode = ProcessConfigurationDescriptor()) != SuccessfulConfigRead)
|
||||
{
|
||||
if (ErrorCode == ControlError)
|
||||
puts_P(PSTR(ESC_FG_RED "Control Error (Get Configuration).\r\n"));
|
||||
else
|
||||
puts_P(PSTR(ESC_FG_RED "Invalid Device.\r\n"));
|
||||
Pipe_Read_Stream_LE(&MIDIEvent, sizeof(MIDIEvent), NULL);
|
||||
|
||||
printf_P(PSTR(" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
|
||||
if (!(Pipe_BytesInPipe()))
|
||||
Pipe_ClearIN();
|
||||
|
||||
/* Indicate error via status LEDs */
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
bool NoteOnEvent = ((MIDIEvent.Command & 0x0F) == (MIDI_COMMAND_NOTE_ON >> 4));
|
||||
bool NoteOffEvent = ((MIDIEvent.Command & 0x0F) == (MIDI_COMMAND_NOTE_OFF >> 4));
|
||||
|
||||
/* Wait until USB device disconnected */
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
if (NoteOnEvent || NoteOffEvent)
|
||||
{
|
||||
printf_P(PSTR("MIDI Note %s - Channel %d, Pitch %d, Velocity %d\r\n"), NoteOnEvent ? "On" : "Off",
|
||||
((MIDIEvent.Data1 & 0x0F) + 1),
|
||||
MIDIEvent.Data2, MIDIEvent.Data3);
|
||||
}
|
||||
}
|
||||
|
||||
/* Set the device configuration to the first configuration (rarely do devices use multiple configurations) */
|
||||
if ((ErrorCode = USB_Host_SetDeviceConfiguration(1)) != HOST_SENDCONTROL_Successful)
|
||||
{
|
||||
printf_P(PSTR(ESC_FG_RED "Control Error (Set Configuration).\r\n"
|
||||
" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
|
||||
Pipe_SelectPipe(MIDI_DATA_OUT_PIPE);
|
||||
|
||||
/* Indicate error via status LEDs */
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
if (Pipe_IsOUTReady())
|
||||
{
|
||||
uint8_t MIDICommand = 0;
|
||||
uint8_t MIDIPitch;
|
||||
|
||||
/* Wait until USB device disconnected */
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
static uint8_t PrevJoystickStatus;
|
||||
uint8_t JoystickStatus = Joystick_GetStatus();
|
||||
uint8_t JoystickChanges = (JoystickStatus ^ PrevJoystickStatus);
|
||||
|
||||
puts_P(PSTR("MIDI Device Enumerated.\r\n"));
|
||||
/* Get board button status - if pressed use channel 10 (percussion), otherwise use channel 1 */
|
||||
uint8_t Channel = ((Buttons_GetStatus() & BUTTONS_BUTTON1) ? MIDI_CHANNEL(10) : MIDI_CHANNEL(1));
|
||||
|
||||
USB_HostState = HOST_STATE_Configured;
|
||||
break;
|
||||
case HOST_STATE_Configured:
|
||||
Pipe_SelectPipe(MIDI_DATA_IN_PIPE);
|
||||
if (JoystickChanges & JOY_LEFT)
|
||||
{
|
||||
MIDICommand = ((JoystickStatus & JOY_LEFT)? MIDI_COMMAND_NOTE_ON : MIDI_COMMAND_NOTE_OFF);
|
||||
MIDIPitch = 0x3C;
|
||||
}
|
||||
|
||||
if (Pipe_IsINReceived())
|
||||
{
|
||||
MIDI_EventPacket_t MIDIEvent;
|
||||
if (JoystickChanges & JOY_UP)
|
||||
{
|
||||
MIDICommand = ((JoystickStatus & JOY_UP)? MIDI_COMMAND_NOTE_ON : MIDI_COMMAND_NOTE_OFF);
|
||||
MIDIPitch = 0x3D;
|
||||
}
|
||||
|
||||
Pipe_Read_Stream_LE(&MIDIEvent, sizeof(MIDIEvent), NULL);
|
||||
if (JoystickChanges & JOY_RIGHT)
|
||||
{
|
||||
MIDICommand = ((JoystickStatus & JOY_RIGHT)? MIDI_COMMAND_NOTE_ON : MIDI_COMMAND_NOTE_OFF);
|
||||
MIDIPitch = 0x3E;
|
||||
}
|
||||
|
||||
if (!(Pipe_BytesInPipe()))
|
||||
Pipe_ClearIN();
|
||||
if (JoystickChanges & JOY_DOWN)
|
||||
{
|
||||
MIDICommand = ((JoystickStatus & JOY_DOWN)? MIDI_COMMAND_NOTE_ON : MIDI_COMMAND_NOTE_OFF);
|
||||
MIDIPitch = 0x3F;
|
||||
}
|
||||
|
||||
bool NoteOnEvent = ((MIDIEvent.Command & 0x0F) == (MIDI_COMMAND_NOTE_ON >> 4));
|
||||
bool NoteOffEvent = ((MIDIEvent.Command & 0x0F) == (MIDI_COMMAND_NOTE_OFF >> 4));
|
||||
if (JoystickChanges & JOY_PRESS)
|
||||
{
|
||||
MIDICommand = ((JoystickStatus & JOY_PRESS)? MIDI_COMMAND_NOTE_ON : MIDI_COMMAND_NOTE_OFF);
|
||||
MIDIPitch = 0x3B;
|
||||
}
|
||||
|
||||
if (NoteOnEvent || NoteOffEvent)
|
||||
/* Check if a MIDI command is to be sent */
|
||||
if (MIDICommand)
|
||||
{
|
||||
MIDI_EventPacket_t MIDIEvent = (MIDI_EventPacket_t)
|
||||
{
|
||||
printf_P(PSTR("MIDI Note %s - Channel %d, Pitch %d, Velocity %d\r\n"), NoteOnEvent ? "On" : "Off",
|
||||
((MIDIEvent.Data1 & 0x0F) + 1),
|
||||
MIDIEvent.Data2, MIDIEvent.Data3);
|
||||
}
|
||||
}
|
||||
.CableNumber = 0,
|
||||
.Command = (MIDICommand >> 4),
|
||||
|
||||
Pipe_SelectPipe(MIDI_DATA_OUT_PIPE);
|
||||
.Data1 = MIDICommand | Channel,
|
||||
.Data2 = MIDIPitch,
|
||||
.Data3 = MIDI_STANDARD_VELOCITY,
|
||||
};
|
||||
|
||||
if (Pipe_IsOUTReady())
|
||||
{
|
||||
uint8_t MIDICommand = 0;
|
||||
uint8_t MIDIPitch;
|
||||
/* Write the MIDI event packet to the pipe */
|
||||
Pipe_Write_Stream_LE(&MIDIEvent, sizeof(MIDIEvent), NULL);
|
||||
|
||||
static uint8_t PrevJoystickStatus;
|
||||
uint8_t JoystickStatus = Joystick_GetStatus();
|
||||
uint8_t JoystickChanges = (JoystickStatus ^ PrevJoystickStatus);
|
||||
/* Send the data in the pipe to the device */
|
||||
Pipe_ClearOUT();
|
||||
}
|
||||
|
||||
/* Get board button status - if pressed use channel 10 (percussion), otherwise use channel 1 */
|
||||
uint8_t Channel = ((Buttons_GetStatus() & BUTTONS_BUTTON1) ? MIDI_CHANNEL(10) : MIDI_CHANNEL(1));
|
||||
|
||||
if (JoystickChanges & JOY_LEFT)
|
||||
{
|
||||
MIDICommand = ((JoystickStatus & JOY_LEFT)? MIDI_COMMAND_NOTE_ON : MIDI_COMMAND_NOTE_OFF);
|
||||
MIDIPitch = 0x3C;
|
||||
}
|
||||
|
||||
if (JoystickChanges & JOY_UP)
|
||||
{
|
||||
MIDICommand = ((JoystickStatus & JOY_UP)? MIDI_COMMAND_NOTE_ON : MIDI_COMMAND_NOTE_OFF);
|
||||
MIDIPitch = 0x3D;
|
||||
}
|
||||
|
||||
if (JoystickChanges & JOY_RIGHT)
|
||||
{
|
||||
MIDICommand = ((JoystickStatus & JOY_RIGHT)? MIDI_COMMAND_NOTE_ON : MIDI_COMMAND_NOTE_OFF);
|
||||
MIDIPitch = 0x3E;
|
||||
}
|
||||
|
||||
if (JoystickChanges & JOY_DOWN)
|
||||
{
|
||||
MIDICommand = ((JoystickStatus & JOY_DOWN)? MIDI_COMMAND_NOTE_ON : MIDI_COMMAND_NOTE_OFF);
|
||||
MIDIPitch = 0x3F;
|
||||
}
|
||||
|
||||
if (JoystickChanges & JOY_PRESS)
|
||||
{
|
||||
MIDICommand = ((JoystickStatus & JOY_PRESS)? MIDI_COMMAND_NOTE_ON : MIDI_COMMAND_NOTE_OFF);
|
||||
MIDIPitch = 0x3B;
|
||||
}
|
||||
|
||||
/* Check if a MIDI command is to be sent */
|
||||
if (MIDICommand)
|
||||
{
|
||||
MIDI_EventPacket_t MIDIEvent = (MIDI_EventPacket_t)
|
||||
{
|
||||
.CableNumber = 0,
|
||||
.Command = (MIDICommand >> 4),
|
||||
|
||||
.Data1 = MIDICommand | Channel,
|
||||
.Data2 = MIDIPitch,
|
||||
.Data3 = MIDI_STANDARD_VELOCITY,
|
||||
};
|
||||
|
||||
/* Write the MIDI event packet to the pipe */
|
||||
Pipe_Write_Stream_LE(&MIDIEvent, sizeof(MIDIEvent), NULL);
|
||||
|
||||
/* Send the data in the pipe to the device */
|
||||
Pipe_ClearOUT();
|
||||
}
|
||||
|
||||
/* Save previous joystick value for next joystick change detection */
|
||||
PrevJoystickStatus = JoystickStatus;
|
||||
}
|
||||
|
||||
break;
|
||||
/* Save previous joystick value for next joystick change detection */
|
||||
PrevJoystickStatus = JoystickStatus;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@
|
|||
|
||||
/* Function Prototypes: */
|
||||
void SetupHardware(void);
|
||||
void MIDI_Host_Task(void);
|
||||
void MIDIHost_Task(void);
|
||||
|
||||
void EVENT_USB_Host_HostError(const uint8_t ErrorCode);
|
||||
void EVENT_USB_Host_DeviceAttached(void);
|
||||
|
|
|
|||
|
|
@ -54,7 +54,8 @@ int main(void)
|
|||
|
||||
for (;;)
|
||||
{
|
||||
MassStorage_Task();
|
||||
MassStorageHost_Task();
|
||||
|
||||
USB_USBTask();
|
||||
}
|
||||
}
|
||||
|
|
@ -102,6 +103,35 @@ void EVENT_USB_Host_DeviceUnattached(void)
|
|||
*/
|
||||
void EVENT_USB_Host_DeviceEnumerationComplete(void)
|
||||
{
|
||||
puts_P(PSTR("Getting Config Data.\r\n"));
|
||||
|
||||
uint8_t ErrorCode;
|
||||
|
||||
/* Get and process the configuration descriptor data */
|
||||
if ((ErrorCode = ProcessConfigurationDescriptor()) != SuccessfulConfigRead)
|
||||
{
|
||||
if (ErrorCode == ControlError)
|
||||
puts_P(PSTR(ESC_FG_RED "Control Error (Get Configuration).\r\n"));
|
||||
else
|
||||
puts_P(PSTR(ESC_FG_RED "Invalid Device.\r\n"));
|
||||
|
||||
printf_P(PSTR(" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
|
||||
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Set the device configuration to the first configuration (rarely do devices use multiple configurations) */
|
||||
if ((ErrorCode = USB_Host_SetDeviceConfiguration(1)) != HOST_SENDCONTROL_Successful)
|
||||
{
|
||||
printf_P(PSTR(ESC_FG_RED "Control Error (Set Configuration).\r\n"
|
||||
" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
|
||||
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
puts_P(PSTR("Mass Storage Disk Enumerated.\r\n"));
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_READY);
|
||||
}
|
||||
|
||||
|
|
@ -134,240 +164,181 @@ void EVENT_USB_Host_DeviceEnumerationFailed(const uint8_t ErrorCode,
|
|||
/** Task to set the configuration of the attached device after it has been enumerated, and to read in blocks from
|
||||
* the device and print them to the serial port.
|
||||
*/
|
||||
void MassStorage_Task(void)
|
||||
void MassStorageHost_Task(void)
|
||||
{
|
||||
if (USB_HostState != HOST_STATE_Configured)
|
||||
return;
|
||||
|
||||
/* Indicate device busy via the status LEDs */
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_BUSY);
|
||||
|
||||
uint8_t ErrorCode;
|
||||
|
||||
switch (USB_HostState)
|
||||
/* Send the request, display error and wait for device detach if request fails */
|
||||
if ((ErrorCode = MassStore_GetMaxLUN(&MassStore_MaxLUNIndex)) != HOST_SENDCONTROL_Successful)
|
||||
{
|
||||
case HOST_STATE_Addressed:
|
||||
puts_P(PSTR("Getting Config Data.\r\n"));
|
||||
|
||||
/* Get and process the configuration descriptor data */
|
||||
if ((ErrorCode = ProcessConfigurationDescriptor()) != SuccessfulConfigRead)
|
||||
{
|
||||
if (ErrorCode == ControlError)
|
||||
puts_P(PSTR(ESC_FG_RED "Control Error (Get Configuration).\r\n"));
|
||||
else
|
||||
puts_P(PSTR(ESC_FG_RED "Invalid Device.\r\n"));
|
||||
|
||||
printf_P(PSTR(" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
|
||||
|
||||
/* Indicate error via status LEDs */
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
|
||||
/* Wait until USB device disconnected */
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Set the device configuration to the first configuration (rarely do devices use multiple configurations) */
|
||||
if ((ErrorCode = USB_Host_SetDeviceConfiguration(1)) != HOST_SENDCONTROL_Successful)
|
||||
{
|
||||
printf_P(PSTR(ESC_FG_RED "Control Error (Set Configuration).\r\n"
|
||||
" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
|
||||
|
||||
/* Indicate error via status LEDs */
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
|
||||
/* Wait until USB device disconnected */
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
puts_P(PSTR("Mass Storage Disk Enumerated.\r\n"));
|
||||
|
||||
USB_HostState = HOST_STATE_Configured;
|
||||
break;
|
||||
case HOST_STATE_Configured:
|
||||
/* Indicate device busy via the status LEDs */
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_BUSY);
|
||||
|
||||
/* Send the request, display error and wait for device detach if request fails */
|
||||
if ((ErrorCode = MassStore_GetMaxLUN(&MassStore_MaxLUNIndex)) != HOST_SENDCONTROL_Successful)
|
||||
{
|
||||
ShowDiskReadError(PSTR("Get Max LUN"), ErrorCode);
|
||||
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Print number of LUNs detected in the attached device */
|
||||
printf_P(PSTR("Total LUNs: %d - Using first LUN in device.\r\n"), (MassStore_MaxLUNIndex + 1));
|
||||
|
||||
/* Reset the Mass Storage device interface, ready for use */
|
||||
if ((ErrorCode = MassStore_MassStorageReset()) != HOST_SENDCONTROL_Successful)
|
||||
{
|
||||
ShowDiskReadError(PSTR("Mass Storage Reset"), ErrorCode);
|
||||
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Get sense data from the device - many devices will not accept any other commands until the sense data
|
||||
* is read - both on start-up and after a failed command */
|
||||
SCSI_Request_Sense_Response_t SenseData;
|
||||
if ((ErrorCode = MassStore_RequestSense(0, &SenseData)) != 0)
|
||||
{
|
||||
ShowDiskReadError(PSTR("Request Sense"), ErrorCode);
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Set the prevent removal flag for the device, allowing it to be accessed */
|
||||
if ((ErrorCode = MassStore_PreventAllowMediumRemoval(0, true)) != 0)
|
||||
{
|
||||
ShowDiskReadError(PSTR("Prevent/Allow Medium Removal"), ErrorCode);
|
||||
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Get inquiry data from the device */
|
||||
SCSI_Inquiry_Response_t InquiryData;
|
||||
if ((ErrorCode = MassStore_Inquiry(0, &InquiryData)) != 0)
|
||||
{
|
||||
ShowDiskReadError(PSTR("Inquiry"), ErrorCode);
|
||||
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Print vendor and product names of attached device */
|
||||
printf_P(PSTR("Vendor \"%.8s\", Product \"%.16s\"\r\n"), InquiryData.VendorID, InquiryData.ProductID);
|
||||
|
||||
/* Wait until disk ready */
|
||||
puts_P(PSTR("Waiting until ready.."));
|
||||
|
||||
for (;;)
|
||||
{
|
||||
Serial_SendByte('.');
|
||||
|
||||
/* Abort if device removed */
|
||||
if (USB_HostState == HOST_STATE_Unattached)
|
||||
break;
|
||||
|
||||
/* Check to see if the attached device is ready for new commands */
|
||||
ErrorCode = MassStore_TestUnitReady(0);
|
||||
|
||||
/* If attached device is ready, abort the loop */
|
||||
if (!(ErrorCode))
|
||||
break;
|
||||
|
||||
/* If an error other than a logical command failure (indicating device busy) returned, abort */
|
||||
if (ErrorCode != MASS_STORE_SCSI_COMMAND_FAILED)
|
||||
{
|
||||
ShowDiskReadError(PSTR("Test Unit Ready"), ErrorCode);
|
||||
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
puts_P(PSTR("\r\nRetrieving Capacity... "));
|
||||
|
||||
/* Create new structure for the disk's capacity in blocks and block size */
|
||||
SCSI_Capacity_t DiskCapacity;
|
||||
|
||||
/* Retrieve disk capacity */
|
||||
if ((ErrorCode = MassStore_ReadCapacity(0, &DiskCapacity)) != 0)
|
||||
{
|
||||
ShowDiskReadError(PSTR("Read Capacity"), ErrorCode);
|
||||
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Display the disk capacity in blocks * block size bytes */
|
||||
printf_P(PSTR("%lu blocks of %lu bytes.\r\n"), DiskCapacity.Blocks, DiskCapacity.BlockSize);
|
||||
|
||||
/* Create a new buffer capable of holding a single block from the device */
|
||||
uint8_t BlockBuffer[DiskCapacity.BlockSize];
|
||||
|
||||
/* Read in the first 512 byte block from the device */
|
||||
if ((ErrorCode = MassStore_ReadDeviceBlock(0, 0x00000000, 1, DiskCapacity.BlockSize, BlockBuffer)) != 0)
|
||||
{
|
||||
ShowDiskReadError(PSTR("Read Device Block"), ErrorCode);
|
||||
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
puts_P(PSTR("\r\nContents of first block:\r\n"));
|
||||
|
||||
/* Print out the first block in both HEX and ASCII, 16 bytes per line */
|
||||
for (uint16_t Chunk = 0; Chunk < (DiskCapacity.BlockSize >> 4); Chunk++)
|
||||
{
|
||||
/* Pointer to the start of the current 16-byte chunk in the read block of data */
|
||||
uint8_t* ChunkPtr = &BlockBuffer[Chunk << 4];
|
||||
|
||||
/* Print out the 16 bytes of the chunk in HEX format */
|
||||
for (uint8_t ByteOffset = 0; ByteOffset < (1 << 4); ByteOffset++)
|
||||
{
|
||||
char CurrByte = *(ChunkPtr + ByteOffset);
|
||||
|
||||
printf_P(PSTR("%.2X "), CurrByte);
|
||||
}
|
||||
|
||||
puts_P(PSTR(" "));
|
||||
|
||||
/* Print out the 16 bytes of the chunk in ASCII format */
|
||||
for (uint8_t ByteOffset = 0; ByteOffset < (1 << 4); ByteOffset++)
|
||||
{
|
||||
char CurrByte = *(ChunkPtr + ByteOffset);
|
||||
|
||||
putchar(isprint(CurrByte) ? CurrByte : '.');
|
||||
}
|
||||
|
||||
puts_P(PSTR("\r\n"));
|
||||
}
|
||||
|
||||
puts_P(PSTR("\r\n\r\nPress board button to read entire ASCII contents of disk...\r\n\r\n"));
|
||||
|
||||
/* Wait for the board button to be pressed */
|
||||
while (!(Buttons_GetStatus() & BUTTONS_BUTTON1))
|
||||
{
|
||||
/* Abort if device removed */
|
||||
if (USB_HostState == HOST_STATE_Unattached)
|
||||
break;
|
||||
}
|
||||
|
||||
/* Abort if device removed */
|
||||
if (USB_HostState == HOST_STATE_Unattached)
|
||||
break;
|
||||
|
||||
/* Print out the entire disk contents in ASCII format */
|
||||
for (uint32_t CurrBlockAddress = 0; CurrBlockAddress < DiskCapacity.Blocks; CurrBlockAddress++)
|
||||
{
|
||||
/* Read in the next block of data from the device */
|
||||
if ((ErrorCode = MassStore_ReadDeviceBlock(0, CurrBlockAddress, 1, DiskCapacity.BlockSize, BlockBuffer)) != 0)
|
||||
{
|
||||
ShowDiskReadError(PSTR("Read Device Block"), ErrorCode);
|
||||
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Send the ASCII data in the read in block to the serial port */
|
||||
for (uint16_t Byte = 0; Byte < DiskCapacity.BlockSize; Byte++)
|
||||
{
|
||||
char CurrByte = BlockBuffer[Byte];
|
||||
|
||||
putchar(isprint(CurrByte) ? CurrByte : '.');
|
||||
}
|
||||
|
||||
/* Abort if device removed */
|
||||
if (USB_HostState == HOST_STATE_Unattached)
|
||||
break;
|
||||
}
|
||||
|
||||
/* Indicate device no longer busy */
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_READY);
|
||||
|
||||
/* Wait until USB device disconnected */
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
ShowDiskReadError(PSTR("Get Max LUN"), ErrorCode);
|
||||
USB_Host_SetDeviceConfiguration(0);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Print number of LUNs detected in the attached device */
|
||||
printf_P(PSTR("Total LUNs: %d - Using first LUN in device.\r\n"), (MassStore_MaxLUNIndex + 1));
|
||||
|
||||
/* Reset the Mass Storage device interface, ready for use */
|
||||
if ((ErrorCode = MassStore_MassStorageReset()) != HOST_SENDCONTROL_Successful)
|
||||
{
|
||||
ShowDiskReadError(PSTR("Mass Storage Reset"), ErrorCode);
|
||||
USB_Host_SetDeviceConfiguration(0);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Get sense data from the device - many devices will not accept any other commands until the sense data
|
||||
* is read - both on start-up and after a failed command */
|
||||
SCSI_Request_Sense_Response_t SenseData;
|
||||
if ((ErrorCode = MassStore_RequestSense(0, &SenseData)) != 0)
|
||||
{
|
||||
ShowDiskReadError(PSTR("Request Sense"), ErrorCode);
|
||||
USB_Host_SetDeviceConfiguration(0);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Set the prevent removal flag for the device, allowing it to be accessed */
|
||||
if ((ErrorCode = MassStore_PreventAllowMediumRemoval(0, true)) != 0)
|
||||
{
|
||||
ShowDiskReadError(PSTR("Prevent/Allow Medium Removal"), ErrorCode);
|
||||
USB_Host_SetDeviceConfiguration(0);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Get inquiry data from the device */
|
||||
SCSI_Inquiry_Response_t InquiryData;
|
||||
if ((ErrorCode = MassStore_Inquiry(0, &InquiryData)) != 0)
|
||||
{
|
||||
ShowDiskReadError(PSTR("Inquiry"), ErrorCode);
|
||||
USB_Host_SetDeviceConfiguration(0);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Print vendor and product names of attached device */
|
||||
printf_P(PSTR("Vendor \"%.8s\", Product \"%.16s\"\r\n"), InquiryData.VendorID, InquiryData.ProductID);
|
||||
|
||||
/* Wait until disk ready */
|
||||
puts_P(PSTR("Waiting until ready.."));
|
||||
|
||||
for (;;)
|
||||
{
|
||||
Serial_SendByte('.');
|
||||
|
||||
/* Abort if device removed */
|
||||
if (USB_HostState == HOST_STATE_Unattached)
|
||||
break;
|
||||
|
||||
/* Check to see if the attached device is ready for new commands */
|
||||
ErrorCode = MassStore_TestUnitReady(0);
|
||||
|
||||
/* If attached device is ready, abort the loop */
|
||||
if (!(ErrorCode))
|
||||
break;
|
||||
|
||||
/* If an error other than a logical command failure (indicating device busy) returned, abort */
|
||||
if (ErrorCode != MASS_STORE_SCSI_COMMAND_FAILED)
|
||||
{
|
||||
ShowDiskReadError(PSTR("Test Unit Ready"), ErrorCode);
|
||||
USB_Host_SetDeviceConfiguration(0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
puts_P(PSTR("\r\nRetrieving Capacity... "));
|
||||
|
||||
/* Create new structure for the disk's capacity in blocks and block size */
|
||||
SCSI_Capacity_t DiskCapacity;
|
||||
|
||||
/* Retrieve disk capacity */
|
||||
if ((ErrorCode = MassStore_ReadCapacity(0, &DiskCapacity)) != 0)
|
||||
{
|
||||
ShowDiskReadError(PSTR("Read Capacity"), ErrorCode);
|
||||
USB_Host_SetDeviceConfiguration(0);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Display the disk capacity in blocks * block size bytes */
|
||||
printf_P(PSTR("%lu blocks of %lu bytes.\r\n"), DiskCapacity.Blocks, DiskCapacity.BlockSize);
|
||||
|
||||
/* Create a new buffer capable of holding a single block from the device */
|
||||
uint8_t BlockBuffer[DiskCapacity.BlockSize];
|
||||
|
||||
/* Read in the first 512 byte block from the device */
|
||||
if ((ErrorCode = MassStore_ReadDeviceBlock(0, 0x00000000, 1, DiskCapacity.BlockSize, BlockBuffer)) != 0)
|
||||
{
|
||||
ShowDiskReadError(PSTR("Read Device Block"), ErrorCode);
|
||||
USB_Host_SetDeviceConfiguration(0);
|
||||
return;
|
||||
}
|
||||
|
||||
puts_P(PSTR("\r\nContents of first block:\r\n"));
|
||||
|
||||
/* Print out the first block in both HEX and ASCII, 16 bytes per line */
|
||||
for (uint16_t Chunk = 0; Chunk < (DiskCapacity.BlockSize >> 4); Chunk++)
|
||||
{
|
||||
/* Pointer to the start of the current 16-byte chunk in the read block of data */
|
||||
uint8_t* ChunkPtr = &BlockBuffer[Chunk << 4];
|
||||
|
||||
/* Print out the 16 bytes of the chunk in HEX format */
|
||||
for (uint8_t ByteOffset = 0; ByteOffset < (1 << 4); ByteOffset++)
|
||||
{
|
||||
char CurrByte = *(ChunkPtr + ByteOffset);
|
||||
|
||||
printf_P(PSTR("%.2X "), CurrByte);
|
||||
}
|
||||
|
||||
puts_P(PSTR(" "));
|
||||
|
||||
/* Print out the 16 bytes of the chunk in ASCII format */
|
||||
for (uint8_t ByteOffset = 0; ByteOffset < (1 << 4); ByteOffset++)
|
||||
{
|
||||
char CurrByte = *(ChunkPtr + ByteOffset);
|
||||
|
||||
putchar(isprint(CurrByte) ? CurrByte : '.');
|
||||
}
|
||||
|
||||
puts_P(PSTR("\r\n"));
|
||||
}
|
||||
|
||||
puts_P(PSTR("\r\n\r\nPress board button to read entire ASCII contents of disk...\r\n\r\n"));
|
||||
|
||||
/* Wait for the board button to be pressed */
|
||||
while (!(Buttons_GetStatus() & BUTTONS_BUTTON1))
|
||||
{
|
||||
/* Abort if device removed */
|
||||
if (USB_HostState == HOST_STATE_Unattached)
|
||||
return;
|
||||
}
|
||||
|
||||
/* Print out the entire disk contents in ASCII format */
|
||||
for (uint32_t CurrBlockAddress = 0; CurrBlockAddress < DiskCapacity.Blocks; CurrBlockAddress++)
|
||||
{
|
||||
/* Read in the next block of data from the device */
|
||||
if ((ErrorCode = MassStore_ReadDeviceBlock(0, CurrBlockAddress, 1, DiskCapacity.BlockSize, BlockBuffer)) != 0)
|
||||
{
|
||||
ShowDiskReadError(PSTR("Read Device Block"), ErrorCode);
|
||||
USB_Host_SetDeviceConfiguration(0);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Send the ASCII data in the read in block to the serial port */
|
||||
for (uint16_t Byte = 0; Byte < DiskCapacity.BlockSize; Byte++)
|
||||
{
|
||||
char CurrByte = BlockBuffer[Byte];
|
||||
|
||||
putchar(isprint(CurrByte) ? CurrByte : '.');
|
||||
}
|
||||
}
|
||||
|
||||
/* Indicate device no longer busy */
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_READY);
|
||||
USB_Host_SetDeviceConfiguration(0);
|
||||
}
|
||||
|
||||
/** Indicates that a communication error has occurred with the attached Mass Storage Device,
|
||||
|
|
|
|||
|
|
@ -74,8 +74,8 @@
|
|||
#define LEDMASK_USB_BUSY LEDS_LED2
|
||||
|
||||
/* Function Prototypes: */
|
||||
void MassStorage_Task(void);
|
||||
void SetupHardware(void);
|
||||
void MassStorageHost_Task(void);
|
||||
|
||||
void EVENT_USB_Host_HostError(const uint8_t ErrorCode);
|
||||
void EVENT_USB_Host_DeviceAttached(void);
|
||||
|
|
|
|||
|
|
@ -50,7 +50,8 @@ int main(void)
|
|||
|
||||
for (;;)
|
||||
{
|
||||
Mouse_HID_Task();
|
||||
MouseHost_Task();
|
||||
|
||||
USB_USBTask();
|
||||
}
|
||||
}
|
||||
|
|
@ -97,6 +98,59 @@ void EVENT_USB_Host_DeviceUnattached(void)
|
|||
*/
|
||||
void EVENT_USB_Host_DeviceEnumerationComplete(void)
|
||||
{
|
||||
puts_P(PSTR("Getting Config Data.\r\n"));
|
||||
|
||||
uint8_t ErrorCode;
|
||||
|
||||
/* Get and process the configuration descriptor data */
|
||||
if ((ErrorCode = ProcessConfigurationDescriptor()) != SuccessfulConfigRead)
|
||||
{
|
||||
if (ErrorCode == ControlError)
|
||||
puts_P(PSTR(ESC_FG_RED "Control Error (Get Configuration).\r\n"));
|
||||
else
|
||||
puts_P(PSTR(ESC_FG_RED "Invalid Device.\r\n"));
|
||||
|
||||
printf_P(PSTR(" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
|
||||
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Set the device configuration to the first configuration (rarely do devices use multiple configurations) */
|
||||
if ((ErrorCode = USB_Host_SetDeviceConfiguration(1)) != HOST_SENDCONTROL_Successful)
|
||||
{
|
||||
printf_P(PSTR(ESC_FG_RED "Control Error (Set Configuration).\r\n"
|
||||
" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
|
||||
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
/* HID class request to set the mouse protocol to the Boot Protocol */
|
||||
USB_ControlRequest = (USB_Request_Header_t)
|
||||
{
|
||||
.bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE),
|
||||
.bRequest = HID_REQ_SetProtocol,
|
||||
.wValue = 0,
|
||||
.wIndex = 0,
|
||||
.wLength = 0,
|
||||
};
|
||||
|
||||
/* Select the control pipe for the request transfer */
|
||||
Pipe_SelectPipe(PIPE_CONTROLPIPE);
|
||||
|
||||
/* Send the request, display error and wait for device detach if request fails */
|
||||
if ((ErrorCode = USB_Host_SendControlRequest(NULL)) != HOST_SENDCONTROL_Successful)
|
||||
{
|
||||
printf_P(PSTR(ESC_FG_RED "Control Error (Set Protocol).\r\n"
|
||||
" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
|
||||
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
USB_Host_SetDeviceConfiguration(0);
|
||||
return;
|
||||
}
|
||||
|
||||
puts_P(PSTR("Mouse Enumerated.\r\n"));
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_READY);
|
||||
}
|
||||
|
||||
|
|
@ -129,8 +183,11 @@ void EVENT_USB_Host_DeviceEnumerationFailed(const uint8_t ErrorCode,
|
|||
/** Reads in and processes the next report from the attached device, displaying the report
|
||||
* contents on the board LEDs and via the serial port.
|
||||
*/
|
||||
void ReadNextReport(void)
|
||||
void MouseHost_Task(void)
|
||||
{
|
||||
if (USB_HostState != HOST_STATE_Configured)
|
||||
return;
|
||||
|
||||
USB_MouseReport_Data_t MouseReport;
|
||||
uint8_t LEDMask = LEDS_NO_LEDS;
|
||||
|
||||
|
|
@ -189,87 +246,3 @@ void ReadNextReport(void)
|
|||
Pipe_Freeze();
|
||||
}
|
||||
|
||||
/** Task to set the configuration of the attached device after it has been enumerated, and to read and process
|
||||
* HID reports from the device and display the results onto the board LEDs.
|
||||
*/
|
||||
void Mouse_HID_Task(void)
|
||||
{
|
||||
uint8_t ErrorCode;
|
||||
|
||||
/* Switch to determine what user-application handled host state the host state machine is in */
|
||||
switch (USB_HostState)
|
||||
{
|
||||
case HOST_STATE_Addressed:
|
||||
puts_P(PSTR("Getting Config Data.\r\n"));
|
||||
|
||||
/* Get and process the configuration descriptor data */
|
||||
if ((ErrorCode = ProcessConfigurationDescriptor()) != SuccessfulConfigRead)
|
||||
{
|
||||
if (ErrorCode == ControlError)
|
||||
puts_P(PSTR(ESC_FG_RED "Control Error (Get Configuration).\r\n"));
|
||||
else
|
||||
puts_P(PSTR(ESC_FG_RED "Invalid Device.\r\n"));
|
||||
|
||||
printf_P(PSTR(" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
|
||||
|
||||
/* Indicate error status */
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
|
||||
/* Wait until USB device disconnected */
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Set the device configuration to the first configuration (rarely do devices use multiple configurations) */
|
||||
if ((ErrorCode = USB_Host_SetDeviceConfiguration(1)) != HOST_SENDCONTROL_Successful)
|
||||
{
|
||||
printf_P(PSTR(ESC_FG_RED "Control Error (Set Configuration).\r\n"
|
||||
" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
|
||||
|
||||
/* Indicate error status */
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
|
||||
/* Wait until USB device disconnected */
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
/* HID class request to set the mouse protocol to the Boot Protocol */
|
||||
USB_ControlRequest = (USB_Request_Header_t)
|
||||
{
|
||||
.bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE),
|
||||
.bRequest = HID_REQ_SetProtocol,
|
||||
.wValue = 0,
|
||||
.wIndex = 0,
|
||||
.wLength = 0,
|
||||
};
|
||||
|
||||
/* Select the control pipe for the request transfer */
|
||||
Pipe_SelectPipe(PIPE_CONTROLPIPE);
|
||||
|
||||
/* Send the request, display error and wait for device detach if request fails */
|
||||
if ((ErrorCode = USB_Host_SendControlRequest(NULL)) != HOST_SENDCONTROL_Successful)
|
||||
{
|
||||
printf_P(PSTR(ESC_FG_RED "Control Error (Set Protocol).\r\n"
|
||||
" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
|
||||
|
||||
/* Indicate error status */
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
|
||||
/* Wait until USB device disconnected */
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
puts_P(PSTR("Mouse Enumerated.\r\n"));
|
||||
|
||||
USB_HostState = HOST_STATE_Configured;
|
||||
break;
|
||||
case HOST_STATE_Configured:
|
||||
/* If a report has been received, read and process it */
|
||||
ReadNextReport();
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -66,8 +66,8 @@
|
|||
#define LEDMASK_USB_ERROR (LEDS_LED1 | LEDS_LED3)
|
||||
|
||||
/* Function Prototypes: */
|
||||
void Mouse_HID_Task(void);
|
||||
void SetupHardware(void);
|
||||
void MouseHost_Task(void);
|
||||
|
||||
void EVENT_USB_Host_HostError(const uint8_t ErrorCode);
|
||||
void EVENT_USB_Host_DeviceAttached(void);
|
||||
|
|
|
|||
|
|
@ -50,7 +50,8 @@ int main(void)
|
|||
|
||||
for (;;)
|
||||
{
|
||||
Mouse_HID_Task();
|
||||
MouseHost_Task();
|
||||
|
||||
USB_USBTask();
|
||||
}
|
||||
}
|
||||
|
|
@ -97,6 +98,52 @@ void EVENT_USB_Host_DeviceUnattached(void)
|
|||
*/
|
||||
void EVENT_USB_Host_DeviceEnumerationComplete(void)
|
||||
{
|
||||
puts_P(PSTR("Getting Config Data.\r\n"));
|
||||
|
||||
uint8_t ErrorCode;
|
||||
|
||||
/* Get and process the configuration descriptor data */
|
||||
if ((ErrorCode = ProcessConfigurationDescriptor()) != SuccessfulConfigRead)
|
||||
{
|
||||
if (ErrorCode == ControlError)
|
||||
puts_P(PSTR(ESC_FG_RED "Control Error (Get Configuration).\r\n"));
|
||||
else
|
||||
puts_P(PSTR(ESC_FG_RED "Invalid Device.\r\n"));
|
||||
|
||||
printf_P(PSTR(" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
|
||||
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Set the device configuration to the first configuration (rarely do devices use multiple configurations) */
|
||||
if ((ErrorCode = USB_Host_SetDeviceConfiguration(1)) != HOST_SENDCONTROL_Successful)
|
||||
{
|
||||
printf_P(PSTR(ESC_FG_RED "Control Error (Set Configuration).\r\n"
|
||||
" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
|
||||
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
printf_P(PSTR("Processing HID Report (Size %d Bytes).\r\n"), HIDReportSize);
|
||||
|
||||
/* Get and process the device's first HID report descriptor */
|
||||
if ((ErrorCode = GetHIDReportData()) != ParseSuccessful)
|
||||
{
|
||||
puts_P(PSTR(ESC_FG_RED "Report Parse Error.\r\n"));
|
||||
|
||||
if (!(HIDReportInfo.TotalReportItems))
|
||||
puts_P(PSTR("Not a valid Mouse." ESC_FG_WHITE));
|
||||
else
|
||||
printf_P(PSTR(" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
|
||||
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
USB_Host_SetDeviceConfiguration(0);
|
||||
return;
|
||||
}
|
||||
|
||||
puts_P(PSTR("Mouse Enumerated.\r\n"));
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_READY);
|
||||
}
|
||||
|
||||
|
|
@ -126,104 +173,40 @@ void EVENT_USB_Host_DeviceEnumerationFailed(const uint8_t ErrorCode,
|
|||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
}
|
||||
|
||||
/** Task to set the configuration of the attached device after it has been enumerated, and to read and process
|
||||
* the HID report descriptor and HID reports from the device and display the results onto the board LEDs.
|
||||
/** Task to read and process the HID report descriptor and HID reports from the device and display the
|
||||
* results onto the board LEDs.
|
||||
*/
|
||||
void Mouse_HID_Task(void)
|
||||
void MouseHost_Task(void)
|
||||
{
|
||||
uint8_t ErrorCode;
|
||||
if (USB_HostState != HOST_STATE_Configured)
|
||||
return;
|
||||
|
||||
/* Switch to determine what user-application handled host state the host state machine is in */
|
||||
switch (USB_HostState)
|
||||
/* Select and unfreeze mouse data pipe */
|
||||
Pipe_SelectPipe(MOUSE_DATA_IN_PIPE);
|
||||
Pipe_Unfreeze();
|
||||
|
||||
/* Check to see if a packet has been received */
|
||||
if (Pipe_IsINReceived())
|
||||
{
|
||||
case HOST_STATE_Addressed:
|
||||
puts_P(PSTR("Getting Config Data.\r\n"));
|
||||
/* Check if data has been received from the attached mouse */
|
||||
if (Pipe_IsReadWriteAllowed())
|
||||
{
|
||||
/* Create buffer big enough for the report */
|
||||
uint8_t MouseReport[Pipe_BytesInPipe()];
|
||||
|
||||
/* Get and process the configuration descriptor data */
|
||||
if ((ErrorCode = ProcessConfigurationDescriptor()) != SuccessfulConfigRead)
|
||||
{
|
||||
if (ErrorCode == ControlError)
|
||||
puts_P(PSTR(ESC_FG_RED "Control Error (Get Configuration).\r\n"));
|
||||
else
|
||||
puts_P(PSTR(ESC_FG_RED "Invalid Device.\r\n"));
|
||||
/* Load in the mouse report */
|
||||
Pipe_Read_Stream_LE(MouseReport, Pipe_BytesInPipe(), NULL);
|
||||
|
||||
printf_P(PSTR(" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
|
||||
/* Process the read in mouse report from the device */
|
||||
ProcessMouseReport(MouseReport);
|
||||
}
|
||||
|
||||
/* Indicate error via status LEDs */
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
|
||||
/* Wait until USB device disconnected */
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Set the device configuration to the first configuration (rarely do devices use multiple configurations) */
|
||||
if ((ErrorCode = USB_Host_SetDeviceConfiguration(1)) != HOST_SENDCONTROL_Successful)
|
||||
{
|
||||
printf_P(PSTR(ESC_FG_RED "Control Error (Set Configuration).\r\n"
|
||||
" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
|
||||
|
||||
/* Indicate error via status LEDs */
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
|
||||
/* Wait until USB device disconnected */
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
printf_P(PSTR("Processing HID Report (Size %d Bytes).\r\n"), HIDReportSize);
|
||||
|
||||
/* Get and process the device's first HID report descriptor */
|
||||
if ((ErrorCode = GetHIDReportData()) != ParseSuccessful)
|
||||
{
|
||||
puts_P(PSTR(ESC_FG_RED "Report Parse Error.\r\n"));
|
||||
|
||||
if (!(HIDReportInfo.TotalReportItems))
|
||||
puts_P(PSTR("Not a valid Mouse." ESC_FG_WHITE));
|
||||
else
|
||||
printf_P(PSTR(" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
|
||||
|
||||
/* Indicate error via status LEDs */
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
|
||||
/* Wait until USB device disconnected */
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
puts_P(PSTR("Mouse Enumerated.\r\n"));
|
||||
|
||||
USB_HostState = HOST_STATE_Configured;
|
||||
break;
|
||||
case HOST_STATE_Configured:
|
||||
/* Select and unfreeze mouse data pipe */
|
||||
Pipe_SelectPipe(MOUSE_DATA_IN_PIPE);
|
||||
Pipe_Unfreeze();
|
||||
|
||||
/* Check to see if a packet has been received */
|
||||
if (Pipe_IsINReceived())
|
||||
{
|
||||
/* Check if data has been received from the attached mouse */
|
||||
if (Pipe_IsReadWriteAllowed())
|
||||
{
|
||||
/* Create buffer big enough for the report */
|
||||
uint8_t MouseReport[Pipe_BytesInPipe()];
|
||||
|
||||
/* Load in the mouse report */
|
||||
Pipe_Read_Stream_LE(MouseReport, Pipe_BytesInPipe(), NULL);
|
||||
|
||||
/* Process the read in mouse report from the device */
|
||||
ProcessMouseReport(MouseReport);
|
||||
}
|
||||
|
||||
/* Clear the IN endpoint, ready for next data packet */
|
||||
Pipe_ClearIN();
|
||||
}
|
||||
|
||||
/* Freeze mouse data pipe */
|
||||
Pipe_Freeze();
|
||||
break;
|
||||
/* Clear the IN endpoint, ready for next data packet */
|
||||
Pipe_ClearIN();
|
||||
}
|
||||
|
||||
/* Freeze mouse data pipe */
|
||||
Pipe_Freeze();
|
||||
}
|
||||
|
||||
/** Processes a read HID report from an attached mouse, extracting out elements via the HID parser results
|
||||
|
|
|
|||
|
|
@ -67,8 +67,8 @@
|
|||
#define LEDMASK_USB_ERROR (LEDS_LED1 | LEDS_LED3)
|
||||
|
||||
/* Function Prototypes: */
|
||||
void Mouse_HID_Task(void);
|
||||
void SetupHardware(void);
|
||||
void MouseHost_Task(void);
|
||||
|
||||
void EVENT_USB_Host_HostError(const uint8_t ErrorCode);
|
||||
void EVENT_USB_Host_DeviceAttached(void);
|
||||
|
|
|
|||
|
|
@ -50,7 +50,8 @@ int main(void)
|
|||
|
||||
for (;;)
|
||||
{
|
||||
USB_Printer_Host();
|
||||
PrinterHost_Task();
|
||||
|
||||
USB_USBTask();
|
||||
}
|
||||
}
|
||||
|
|
@ -97,6 +98,65 @@ void EVENT_USB_Host_DeviceUnattached(void)
|
|||
*/
|
||||
void EVENT_USB_Host_DeviceEnumerationComplete(void)
|
||||
{
|
||||
puts_P(PSTR("Getting Config Data.\r\n"));
|
||||
|
||||
uint8_t ErrorCode;
|
||||
|
||||
/* Get and process the configuration descriptor data */
|
||||
if ((ErrorCode = ProcessConfigurationDescriptor()) != SuccessfulConfigRead)
|
||||
{
|
||||
if (ErrorCode == ControlError)
|
||||
puts_P(PSTR(ESC_FG_RED "Control Error (Get Configuration).\r\n"));
|
||||
else
|
||||
puts_P(PSTR(ESC_FG_RED "Invalid Device.\r\n"));
|
||||
|
||||
printf_P(PSTR(" -- Error Code: %d\r\n"), ErrorCode);
|
||||
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Set the device configuration to the first configuration (rarely do devices use multiple configurations) */
|
||||
if ((ErrorCode = USB_Host_SetDeviceConfiguration(1)) != HOST_SENDCONTROL_Successful)
|
||||
{
|
||||
printf_P(PSTR(ESC_FG_RED "Control Error (Set Configuration).\r\n"
|
||||
" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
|
||||
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Some printers use alternate settings to determine the communication protocol used - if so, send a SetInterface
|
||||
* request to switch to the interface alternate setting with the Bidirectional protocol */
|
||||
if (PrinterAltSetting)
|
||||
{
|
||||
if ((ErrorCode = USB_Host_SetInterfaceAltSetting(PrinterInterfaceNumber, PrinterAltSetting)) != HOST_SENDCONTROL_Successful)
|
||||
{
|
||||
printf_P(PSTR(ESC_FG_RED "Control Error (Set Interface).\r\n"
|
||||
" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
|
||||
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
USB_Host_SetDeviceConfiguration(0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
puts_P(PSTR("Retrieving Device ID...\r\n"));
|
||||
|
||||
char DeviceIDString[300];
|
||||
if ((ErrorCode = Printer_GetDeviceID(DeviceIDString, sizeof(DeviceIDString))) != HOST_SENDCONTROL_Successful)
|
||||
{
|
||||
printf_P(PSTR(ESC_FG_RED "Control Error (Get Device ID).\r\n"
|
||||
" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
|
||||
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
USB_Host_SetDeviceConfiguration(0);
|
||||
return;
|
||||
}
|
||||
|
||||
printf_P(PSTR("Printer Device ID: %s\r\n"), DeviceIDString);
|
||||
|
||||
puts_P(PSTR("Printer Enumerated.\r\n"));
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_READY);
|
||||
}
|
||||
|
||||
|
|
@ -126,122 +186,39 @@ void EVENT_USB_Host_DeviceEnumerationFailed(const uint8_t ErrorCode,
|
|||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
}
|
||||
|
||||
/** Task to set the configuration of the attached device after it has been enumerated, and to send some test page
|
||||
* data to the attached printer.
|
||||
/** Task to manage an enumerated USB printer once connected, to display device
|
||||
* information and print a test PCL page.
|
||||
*/
|
||||
void USB_Printer_Host(void)
|
||||
void PrinterHost_Task(void)
|
||||
{
|
||||
if (USB_HostState != HOST_STATE_Configured)
|
||||
return;
|
||||
|
||||
uint8_t ErrorCode;
|
||||
|
||||
switch (USB_HostState)
|
||||
/* Indicate device busy via the status LEDs */
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_BUSY);
|
||||
|
||||
char TestPageData[] = "\033%-12345X\033E" "LUFA PCL Test Page" "\033E\033%-12345X";
|
||||
uint16_t TestPageLength = strlen(TestPageData);
|
||||
|
||||
printf_P(PSTR("Sending Test Page (%d bytes)...\r\n"), TestPageLength);
|
||||
|
||||
/* Send the test page to the attached printer */
|
||||
if ((ErrorCode = Printer_SendData(&TestPageData, TestPageLength)) != PIPE_RWSTREAM_NoError)
|
||||
{
|
||||
case HOST_STATE_Addressed:
|
||||
puts_P(PSTR("Getting Config Data.\r\n"));
|
||||
printf_P(PSTR(ESC_FG_RED "Error Sending Test Page.\r\n"
|
||||
" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
|
||||
|
||||
/* Select the control pipe for the request transfer */
|
||||
Pipe_SelectPipe(PIPE_CONTROLPIPE);
|
||||
|
||||
/* Get and process the configuration descriptor data */
|
||||
if ((ErrorCode = ProcessConfigurationDescriptor()) != SuccessfulConfigRead)
|
||||
{
|
||||
if (ErrorCode == ControlError)
|
||||
puts_P(PSTR(ESC_FG_RED "Control Error (Get Configuration).\r\n"));
|
||||
else
|
||||
puts_P(PSTR(ESC_FG_RED "Invalid Device.\r\n"));
|
||||
|
||||
printf_P(PSTR(" -- Error Code: %d\r\n"), ErrorCode);
|
||||
|
||||
/* Indicate error via status LEDs */
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
|
||||
/* Wait until USB device disconnected */
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Set the device configuration to the first configuration (rarely do devices use multiple configurations) */
|
||||
if ((ErrorCode = USB_Host_SetDeviceConfiguration(1)) != HOST_SENDCONTROL_Successful)
|
||||
{
|
||||
printf_P(PSTR(ESC_FG_RED "Control Error (Set Configuration).\r\n"
|
||||
" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
|
||||
|
||||
/* Indicate error via status LEDs */
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
|
||||
/* Wait until USB device disconnected */
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Some printers use alternate settings to determine the communication protocol used - if so, send a SetInterface
|
||||
* request to switch to the interface alternate setting with the Bidirectional protocol */
|
||||
if (PrinterAltSetting)
|
||||
{
|
||||
if ((ErrorCode = USB_Host_SetInterfaceAltSetting(PrinterInterfaceNumber, PrinterAltSetting)) != HOST_SENDCONTROL_Successful)
|
||||
{
|
||||
printf_P(PSTR(ESC_FG_RED "Control Error (Set Interface).\r\n"
|
||||
" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
|
||||
|
||||
/* Indicate error via status LEDs */
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
|
||||
/* Wait until USB device disconnected */
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
puts_P(PSTR("Retrieving Device ID...\r\n"));
|
||||
|
||||
char DeviceIDString[300];
|
||||
if ((ErrorCode = Printer_GetDeviceID(DeviceIDString, sizeof(DeviceIDString))) != HOST_SENDCONTROL_Successful)
|
||||
{
|
||||
printf_P(PSTR(ESC_FG_RED "Control Error (Get Device ID).\r\n"
|
||||
" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
|
||||
|
||||
/* Indicate error via status LEDs */
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
|
||||
/* Wait until USB device disconnected */
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
printf_P(PSTR("Printer Device ID: %s\r\n"), DeviceIDString);
|
||||
|
||||
puts_P(PSTR("Printer Enumerated.\r\n"));
|
||||
|
||||
USB_HostState = HOST_STATE_Configured;
|
||||
break;
|
||||
case HOST_STATE_Configured:
|
||||
/* Indicate device busy via the status LEDs */
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_BUSY);
|
||||
|
||||
char TestPageData[] = "\033%-12345X\033E" "LUFA PCL Test Page" "\033E\033%-12345X";
|
||||
uint16_t TestPageLength = strlen(TestPageData);
|
||||
|
||||
printf_P(PSTR("Sending Test Page (%d bytes)...\r\n"), TestPageLength);
|
||||
|
||||
if ((ErrorCode = Printer_SendData(&TestPageData, TestPageLength)) != PIPE_RWSTREAM_NoError)
|
||||
{
|
||||
printf_P(PSTR(ESC_FG_RED "Error Sending Test Page.\r\n"
|
||||
" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
|
||||
|
||||
/* Indicate error via status LEDs */
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
|
||||
/* Wait until USB device disconnected */
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
puts_P(PSTR("Test Page Sent.\r\n"));
|
||||
|
||||
/* Indicate device no longer busy */
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_READY);
|
||||
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
USB_Host_SetDeviceConfiguration(0);
|
||||
return;
|
||||
}
|
||||
|
||||
puts_P(PSTR("Test Page Sent.\r\n"));
|
||||
|
||||
/* Indicate device no longer busy */
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_READY);
|
||||
USB_Host_SetDeviceConfiguration(0);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -74,16 +74,15 @@
|
|||
extern uint8_t PrinterInterfaceNumber;
|
||||
|
||||
/* Function Prototypes: */
|
||||
void SetupHardware(void);
|
||||
void PrinterHost_Task(void);
|
||||
|
||||
void EVENT_USB_Host_DeviceAttached(void);
|
||||
void EVENT_USB_Host_DeviceUnattached(void);
|
||||
void EVENT_USB_Host_DeviceEnumerationComplete(void);
|
||||
void EVENT_USB_Host_HostError(const uint8_t ErrorCode);
|
||||
void EVENT_USB_Host_DeviceEnumerationFailed(const uint8_t ErrorCode,
|
||||
const uint8_t SubErrorCode);
|
||||
|
||||
void SetupHardware(void);
|
||||
|
||||
void USB_Printer_Host(void);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -50,7 +50,8 @@ int main(void)
|
|||
|
||||
for (;;)
|
||||
{
|
||||
RNDIS_Host_Task();
|
||||
RNDISHost_Task();
|
||||
|
||||
USB_USBTask();
|
||||
}
|
||||
}
|
||||
|
|
@ -97,6 +98,75 @@ void EVENT_USB_Host_DeviceUnattached(void)
|
|||
*/
|
||||
void EVENT_USB_Host_DeviceEnumerationComplete(void)
|
||||
{
|
||||
puts_P(PSTR("Getting Config Data.\r\n"));
|
||||
|
||||
uint8_t ErrorCode;
|
||||
|
||||
/* Get and process the configuration descriptor data */
|
||||
if ((ErrorCode = ProcessConfigurationDescriptor()) != SuccessfulConfigRead)
|
||||
{
|
||||
if (ErrorCode == ControlError)
|
||||
puts_P(PSTR(ESC_FG_RED "Control Error (Get Configuration).\r\n"));
|
||||
else
|
||||
puts_P(PSTR(ESC_FG_RED "Invalid Device.\r\n"));
|
||||
|
||||
printf_P(PSTR(" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
|
||||
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Set the device configuration to the first configuration (rarely do devices use multiple configurations) */
|
||||
if ((ErrorCode = USB_Host_SetDeviceConfiguration(1)) != HOST_SENDCONTROL_Successful)
|
||||
{
|
||||
printf_P(PSTR(ESC_FG_RED "Control Error (Set Configuration).\r\n"
|
||||
" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
|
||||
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
uint16_t DeviceMaxPacketSize;
|
||||
if ((ErrorCode = RNDIS_InitializeDevice(1024, &DeviceMaxPacketSize)) != HOST_SENDCONTROL_Successful)
|
||||
{
|
||||
printf_P(PSTR(ESC_FG_RED "Error Initializing Device.\r\n"
|
||||
" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
|
||||
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
USB_Host_SetDeviceConfiguration(0);
|
||||
return;
|
||||
}
|
||||
|
||||
printf_P(PSTR("Device Max Transfer Size: %lu bytes.\r\n"), DeviceMaxPacketSize);
|
||||
|
||||
/* We set the default filter to only receive packets we would be interested in */
|
||||
uint32_t PacketFilter = (REMOTE_NDIS_PACKET_DIRECTED | REMOTE_NDIS_PACKET_BROADCAST | REMOTE_NDIS_PACKET_ALL_MULTICAST);
|
||||
if ((ErrorCode = RNDIS_SetRNDISProperty(OID_GEN_CURRENT_PACKET_FILTER,
|
||||
&PacketFilter, sizeof(PacketFilter))) != HOST_SENDCONTROL_Successful)
|
||||
{
|
||||
printf_P(PSTR(ESC_FG_RED "Error Setting Device Packet Filter.\r\n"
|
||||
" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
|
||||
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
USB_Host_SetDeviceConfiguration(0);
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t VendorID;
|
||||
if ((ErrorCode = RNDIS_QueryRNDISProperty(OID_GEN_VENDOR_ID,
|
||||
&VendorID, sizeof(VendorID))) != HOST_SENDCONTROL_Successful)
|
||||
{
|
||||
printf_P(PSTR(ESC_FG_RED "Error Getting Vendor ID.\r\n"
|
||||
" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
|
||||
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
USB_Host_SetDeviceConfiguration(0);
|
||||
return;
|
||||
}
|
||||
|
||||
printf_P(PSTR("Device Vendor ID: 0x%08lX\r\n"), VendorID);
|
||||
|
||||
puts_P(PSTR("RNDIS Device Enumerated.\r\n"));
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_READY);
|
||||
}
|
||||
|
||||
|
|
@ -126,8 +196,13 @@ void EVENT_USB_Host_DeviceEnumerationFailed(const uint8_t ErrorCode,
|
|||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
}
|
||||
|
||||
void PrintIncomingPackets(void)
|
||||
/** Task to read in data received from the attached RNDIS device and print it to the serial port.
|
||||
*/
|
||||
void RNDISHost_Task(void)
|
||||
{
|
||||
if (USB_HostState != HOST_STATE_Configured)
|
||||
return;
|
||||
|
||||
uint8_t ErrorCode;
|
||||
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_BUSY);
|
||||
|
|
@ -136,7 +211,7 @@ void PrintIncomingPackets(void)
|
|||
if ((ErrorCode = RNDIS_GetPacketLength(&PacketLength)) != HOST_SENDCONTROL_Successful)
|
||||
{
|
||||
printf_P(PSTR(ESC_FG_RED "Packet Reception Error.\r\n"
|
||||
" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
|
||||
" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -170,107 +245,3 @@ void PrintIncomingPackets(void)
|
|||
LEDs_SetAllLEDs(LEDMASK_USB_READY);
|
||||
}
|
||||
|
||||
/** Task to set the configuration of the attached device after it has been enumerated, and to read in
|
||||
* data received from the attached RNDIS device and print it to the serial port.
|
||||
*/
|
||||
void RNDIS_Host_Task(void)
|
||||
{
|
||||
uint8_t ErrorCode;
|
||||
|
||||
switch (USB_HostState)
|
||||
{
|
||||
case HOST_STATE_Addressed:
|
||||
puts_P(PSTR("Getting Config Data.\r\n"));
|
||||
|
||||
/* Get and process the configuration descriptor data */
|
||||
if ((ErrorCode = ProcessConfigurationDescriptor()) != SuccessfulConfigRead)
|
||||
{
|
||||
if (ErrorCode == ControlError)
|
||||
puts_P(PSTR(ESC_FG_RED "Control Error (Get Configuration).\r\n"));
|
||||
else
|
||||
puts_P(PSTR(ESC_FG_RED "Invalid Device.\r\n"));
|
||||
|
||||
printf_P(PSTR(" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
|
||||
|
||||
/* Indicate error via status LEDs */
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
|
||||
/* Wait until USB device disconnected */
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Set the device configuration to the first configuration (rarely do devices use multiple configurations) */
|
||||
if ((ErrorCode = USB_Host_SetDeviceConfiguration(1)) != HOST_SENDCONTROL_Successful)
|
||||
{
|
||||
printf_P(PSTR(ESC_FG_RED "Control Error (Set Configuration).\r\n"
|
||||
" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
|
||||
|
||||
/* Indicate error via status LEDs */
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
|
||||
/* Wait until USB device disconnected */
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
uint16_t DeviceMaxPacketSize;
|
||||
if ((ErrorCode = RNDIS_InitializeDevice(1024, &DeviceMaxPacketSize)) != HOST_SENDCONTROL_Successful)
|
||||
{
|
||||
printf_P(PSTR(ESC_FG_RED "Error Initializing Device.\r\n"
|
||||
" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
|
||||
|
||||
/* Indicate error via status LEDs */
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
|
||||
/* Wait until USB device disconnected */
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
printf_P(PSTR("Device Max Transfer Size: %lu bytes.\r\n"), DeviceMaxPacketSize);
|
||||
|
||||
/* We set the default filter to only receive packets we would be interested in */
|
||||
uint32_t PacketFilter = (REMOTE_NDIS_PACKET_DIRECTED | REMOTE_NDIS_PACKET_BROADCAST | REMOTE_NDIS_PACKET_ALL_MULTICAST);
|
||||
if ((ErrorCode = RNDIS_SetRNDISProperty(OID_GEN_CURRENT_PACKET_FILTER,
|
||||
&PacketFilter, sizeof(PacketFilter))) != HOST_SENDCONTROL_Successful)
|
||||
{
|
||||
printf_P(PSTR(ESC_FG_RED "Error Setting Device Packet Filter.\r\n"
|
||||
" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
|
||||
|
||||
/* Indicate error via status LEDs */
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
|
||||
/* Wait until USB device disconnected */
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
uint32_t VendorID;
|
||||
if ((ErrorCode = RNDIS_QueryRNDISProperty(OID_GEN_VENDOR_ID,
|
||||
&VendorID, sizeof(VendorID))) != HOST_SENDCONTROL_Successful)
|
||||
{
|
||||
printf_P(PSTR(ESC_FG_RED "Error Getting Vendor ID.\r\n"
|
||||
" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
|
||||
|
||||
/* Indicate error via status LEDs */
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
|
||||
/* Wait until USB device disconnected */
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
printf_P(PSTR("Device Vendor ID: 0x%08lX\r\n"), VendorID);
|
||||
|
||||
puts_P(PSTR("RNDIS Device Enumerated.\r\n"));
|
||||
|
||||
USB_HostState = HOST_STATE_Configured;
|
||||
break;
|
||||
case HOST_STATE_Configured:
|
||||
PrintIncomingPackets();
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -72,8 +72,7 @@
|
|||
|
||||
/* Function Prototypes: */
|
||||
void SetupHardware(void);
|
||||
void PrintIncomingPackets(void);
|
||||
void RNDIS_Host_Task(void);
|
||||
void RNDISHost_Task(void);
|
||||
|
||||
void EVENT_USB_Host_HostError(const uint8_t ErrorCode);
|
||||
void EVENT_USB_Host_DeviceAttached(void);
|
||||
|
|
|
|||
|
|
@ -50,7 +50,8 @@ int main(void)
|
|||
|
||||
for (;;)
|
||||
{
|
||||
StillImage_Task();
|
||||
StillImageHost_Task();
|
||||
|
||||
USB_USBTask();
|
||||
}
|
||||
}
|
||||
|
|
@ -98,6 +99,35 @@ void EVENT_USB_Host_DeviceUnattached(void)
|
|||
*/
|
||||
void EVENT_USB_Host_DeviceEnumerationComplete(void)
|
||||
{
|
||||
puts_P(PSTR("Getting Config Data.\r\n"));
|
||||
|
||||
uint8_t ErrorCode;
|
||||
|
||||
/* Get and process the configuration descriptor data */
|
||||
if ((ErrorCode = ProcessConfigurationDescriptor()) != SuccessfulConfigRead)
|
||||
{
|
||||
if (ErrorCode == ControlError)
|
||||
puts_P(PSTR(ESC_FG_RED "Control Error (Get Configuration).\r\n"));
|
||||
else
|
||||
puts_P(PSTR(ESC_FG_RED "Invalid Device.\r\n"));
|
||||
|
||||
printf_P(PSTR(" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
|
||||
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Set the device configuration to the first configuration (rarely do devices use multiple configurations) */
|
||||
if ((ErrorCode = USB_Host_SetDeviceConfiguration(1)) != HOST_SENDCONTROL_Successful)
|
||||
{
|
||||
printf_P(PSTR(ESC_FG_RED "Control Error (Set Configuration).\r\n"
|
||||
" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
|
||||
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
puts_P(PSTR("Still Image Device Enumerated.\r\n"));
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_READY);
|
||||
}
|
||||
|
||||
|
|
@ -127,214 +157,166 @@ void EVENT_USB_Host_DeviceEnumerationFailed(const uint8_t ErrorCode,
|
|||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
}
|
||||
|
||||
/** Task to set the configuration of the attached device after it has been enumerated, and to print device information
|
||||
* through the serial port.
|
||||
/** Task to print device information through the serial port, and open/close a test PIMA session with the
|
||||
* attached Still Image device.
|
||||
*/
|
||||
void StillImage_Task(void)
|
||||
void StillImageHost_Task(void)
|
||||
{
|
||||
if (USB_HostState != HOST_STATE_Configured)
|
||||
return;
|
||||
|
||||
uint8_t ErrorCode;
|
||||
|
||||
switch (USB_HostState)
|
||||
/* Indicate device busy via the status LEDs */
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_BUSY);
|
||||
|
||||
puts_P(PSTR("Retrieving Device Info...\r\n"));
|
||||
|
||||
PIMA_SendBlock = (PIMA_Container_t)
|
||||
{
|
||||
.DataLength = PIMA_COMMAND_SIZE(0),
|
||||
.Type = PIMA_CONTAINER_CommandBlock,
|
||||
.Code = PIMA_OPERATION_GETDEVICEINFO,
|
||||
.TransactionID = 0x00000000,
|
||||
.Params = {},
|
||||
};
|
||||
|
||||
/* Send the GETDEVICEINFO block */
|
||||
SImage_SendBlockHeader();
|
||||
|
||||
/* Receive the response data block */
|
||||
if ((ErrorCode = SImage_ReceiveBlockHeader()) != PIPE_RWSTREAM_NoError)
|
||||
{
|
||||
case HOST_STATE_Addressed:
|
||||
puts_P(PSTR("Getting Config Data.\r\n"));
|
||||
|
||||
/* Get and process the configuration descriptor data */
|
||||
if ((ErrorCode = ProcessConfigurationDescriptor()) != SuccessfulConfigRead)
|
||||
{
|
||||
if (ErrorCode == ControlError)
|
||||
puts_P(PSTR(ESC_FG_RED "Control Error (Get Configuration).\r\n"));
|
||||
else
|
||||
puts_P(PSTR(ESC_FG_RED "Invalid Device.\r\n"));
|
||||
|
||||
printf_P(PSTR(" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
|
||||
|
||||
/* Indicate error via status LEDs */
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
|
||||
/* Wait until USB device disconnected */
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Set the device configuration to the first configuration (rarely do devices use multiple configurations) */
|
||||
if ((ErrorCode = USB_Host_SetDeviceConfiguration(1)) != HOST_SENDCONTROL_Successful)
|
||||
{
|
||||
printf_P(PSTR(ESC_FG_RED "Control Error (Set Configuration).\r\n"
|
||||
" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
|
||||
|
||||
/* Indicate error via status LEDs */
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
|
||||
/* Wait until USB device disconnected */
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
puts_P(PSTR("Still Image Device Enumerated.\r\n"));
|
||||
USB_HostState = HOST_STATE_Configured;
|
||||
break;
|
||||
case HOST_STATE_Configured:
|
||||
/* Indicate device busy via the status LEDs */
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_BUSY);
|
||||
|
||||
puts_P(PSTR("Retrieving Device Info...\r\n"));
|
||||
|
||||
PIMA_SendBlock = (PIMA_Container_t)
|
||||
{
|
||||
.DataLength = PIMA_COMMAND_SIZE(0),
|
||||
.Type = PIMA_CONTAINER_CommandBlock,
|
||||
.Code = PIMA_OPERATION_GETDEVICEINFO,
|
||||
.TransactionID = 0x00000000,
|
||||
.Params = {},
|
||||
};
|
||||
|
||||
/* Send the GETDEVICEINFO block */
|
||||
SImage_SendBlockHeader();
|
||||
|
||||
/* Receive the response data block */
|
||||
if ((ErrorCode = SImage_ReceiveBlockHeader()) != PIPE_RWSTREAM_NoError)
|
||||
{
|
||||
ShowCommandError(ErrorCode, false);
|
||||
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Calculate the size of the returned device info data structure */
|
||||
uint16_t DeviceInfoSize = (PIMA_ReceivedBlock.DataLength - PIMA_COMMAND_SIZE(0));
|
||||
|
||||
/* Create a buffer large enough to hold the entire device info */
|
||||
uint8_t DeviceInfo[DeviceInfoSize];
|
||||
|
||||
/* Read in the data block data (containing device info) */
|
||||
SImage_ReadData(DeviceInfo, DeviceInfoSize);
|
||||
|
||||
/* Once all the data has been read, the pipe must be cleared before the response can be sent */
|
||||
Pipe_ClearIN();
|
||||
|
||||
/* Create a pointer for walking through the info dataset */
|
||||
uint8_t* DeviceInfoPos = DeviceInfo;
|
||||
|
||||
/* Skip over the data before the unicode device information strings */
|
||||
DeviceInfoPos += 8; // Skip to VendorExtensionDesc String
|
||||
DeviceInfoPos += (1 + UNICODE_STRING_LENGTH(*DeviceInfoPos)); // Skip over VendorExtensionDesc String
|
||||
DeviceInfoPos += 2; // Skip over FunctionalMode
|
||||
DeviceInfoPos += (4 + (*(uint32_t*)DeviceInfoPos << 1)); // Skip over Supported Operations Array
|
||||
DeviceInfoPos += (4 + (*(uint32_t*)DeviceInfoPos << 1)); // Skip over Supported Events Array
|
||||
DeviceInfoPos += (4 + (*(uint32_t*)DeviceInfoPos << 1)); // Skip over Supported Device Properties Array
|
||||
DeviceInfoPos += (4 + (*(uint32_t*)DeviceInfoPos << 1)); // Skip over Capture Formats Array
|
||||
DeviceInfoPos += (4 + (*(uint32_t*)DeviceInfoPos << 1)); // Skip over Image Formats Array
|
||||
|
||||
/* Extract and convert the Manufacturer Unicode string to ASCII and print it through the USART */
|
||||
char Manufacturer[*DeviceInfoPos];
|
||||
UnicodeToASCII(DeviceInfoPos, Manufacturer);
|
||||
printf_P(PSTR(" Manufacturer: %s\r\n"), Manufacturer);
|
||||
|
||||
DeviceInfoPos += 1 + UNICODE_STRING_LENGTH(*DeviceInfoPos); // Skip over Manufacturer String
|
||||
|
||||
/* Extract and convert the Model Unicode string to ASCII and print it through the USART */
|
||||
char Model[*DeviceInfoPos];
|
||||
UnicodeToASCII(DeviceInfoPos, Model);
|
||||
printf_P(PSTR(" Model: %s\r\n"), Model);
|
||||
|
||||
DeviceInfoPos += 1 + UNICODE_STRING_LENGTH(*DeviceInfoPos); // Skip over Model String
|
||||
|
||||
/* Extract and convert the Device Version Unicode string to ASCII and print it through the USART */
|
||||
char DeviceVersion[*DeviceInfoPos];
|
||||
UnicodeToASCII(DeviceInfoPos, DeviceVersion);
|
||||
printf_P(PSTR(" Device Version: %s\r\n"), DeviceVersion);
|
||||
|
||||
/* Receive the final response block from the device */
|
||||
if ((ErrorCode = SImage_ReceiveBlockHeader()) != PIPE_RWSTREAM_NoError)
|
||||
{
|
||||
ShowCommandError(ErrorCode, false);
|
||||
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Verify that the command completed successfully */
|
||||
if ((PIMA_ReceivedBlock.Type != PIMA_CONTAINER_ResponseBlock) || (PIMA_ReceivedBlock.Code != PIMA_RESPONSE_OK))
|
||||
{
|
||||
ShowCommandError(PIMA_ReceivedBlock.Code, true);
|
||||
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
puts_P(PSTR("Opening Session...\r\n"));
|
||||
|
||||
PIMA_SendBlock = (PIMA_Container_t)
|
||||
{
|
||||
.DataLength = PIMA_COMMAND_SIZE(1),
|
||||
.Type = PIMA_CONTAINER_CommandBlock,
|
||||
.Code = PIMA_OPERATION_OPENSESSION,
|
||||
.TransactionID = 0x00000000,
|
||||
.Params = {0x00000001},
|
||||
};
|
||||
|
||||
/* Send the OPENSESSION block, open a session with an ID of 0x0001 */
|
||||
SImage_SendBlockHeader();
|
||||
|
||||
/* Receive the response block from the device */
|
||||
if ((ErrorCode = SImage_ReceiveBlockHeader()) != PIPE_RWSTREAM_NoError)
|
||||
{
|
||||
ShowCommandError(ErrorCode, false);
|
||||
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Verify that the command completed successfully */
|
||||
if ((PIMA_ReceivedBlock.Type != PIMA_CONTAINER_ResponseBlock) || (PIMA_ReceivedBlock.Code != PIMA_RESPONSE_OK))
|
||||
{
|
||||
ShowCommandError(PIMA_ReceivedBlock.Code, true);
|
||||
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
puts_P(PSTR("Closing Session...\r\n"));
|
||||
|
||||
PIMA_SendBlock = (PIMA_Container_t)
|
||||
{
|
||||
.DataLength = PIMA_COMMAND_SIZE(1),
|
||||
.Type = PIMA_CONTAINER_CommandBlock,
|
||||
.Code = PIMA_OPERATION_CLOSESESSION,
|
||||
.TransactionID = 0x00000001,
|
||||
.Params = {0x00000001},
|
||||
};
|
||||
|
||||
/* Send the CLOSESESSION block, close the session with an ID of 0x0001 */
|
||||
SImage_SendBlockHeader();
|
||||
|
||||
/* Receive the response block from the device */
|
||||
if ((ErrorCode = SImage_ReceiveBlockHeader()) != PIPE_RWSTREAM_NoError)
|
||||
{
|
||||
ShowCommandError(ErrorCode, false);
|
||||
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Verify that the command completed successfully */
|
||||
if ((PIMA_ReceivedBlock.Type != PIMA_CONTAINER_ResponseBlock) || (PIMA_ReceivedBlock.Code != PIMA_RESPONSE_OK))
|
||||
{
|
||||
ShowCommandError(PIMA_ReceivedBlock.Code, true);
|
||||
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
puts_P(PSTR("Done.\r\n"));
|
||||
|
||||
/* Indicate device no longer busy */
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_READY);
|
||||
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
ShowCommandError(ErrorCode, false);
|
||||
USB_Host_SetDeviceConfiguration(0);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Calculate the size of the returned device info data structure */
|
||||
uint16_t DeviceInfoSize = (PIMA_ReceivedBlock.DataLength - PIMA_COMMAND_SIZE(0));
|
||||
|
||||
/* Create a buffer large enough to hold the entire device info */
|
||||
uint8_t DeviceInfo[DeviceInfoSize];
|
||||
|
||||
/* Read in the data block data (containing device info) */
|
||||
SImage_ReadData(DeviceInfo, DeviceInfoSize);
|
||||
|
||||
/* Once all the data has been read, the pipe must be cleared before the response can be sent */
|
||||
Pipe_ClearIN();
|
||||
|
||||
/* Create a pointer for walking through the info dataset */
|
||||
uint8_t* DeviceInfoPos = DeviceInfo;
|
||||
|
||||
/* Skip over the data before the unicode device information strings */
|
||||
DeviceInfoPos += 8; // Skip to VendorExtensionDesc String
|
||||
DeviceInfoPos += (1 + UNICODE_STRING_LENGTH(*DeviceInfoPos)); // Skip over VendorExtensionDesc String
|
||||
DeviceInfoPos += 2; // Skip over FunctionalMode
|
||||
DeviceInfoPos += (4 + (*(uint32_t*)DeviceInfoPos << 1)); // Skip over Supported Operations Array
|
||||
DeviceInfoPos += (4 + (*(uint32_t*)DeviceInfoPos << 1)); // Skip over Supported Events Array
|
||||
DeviceInfoPos += (4 + (*(uint32_t*)DeviceInfoPos << 1)); // Skip over Supported Device Properties Array
|
||||
DeviceInfoPos += (4 + (*(uint32_t*)DeviceInfoPos << 1)); // Skip over Capture Formats Array
|
||||
DeviceInfoPos += (4 + (*(uint32_t*)DeviceInfoPos << 1)); // Skip over Image Formats Array
|
||||
|
||||
/* Extract and convert the Manufacturer Unicode string to ASCII and print it through the USART */
|
||||
char Manufacturer[*DeviceInfoPos];
|
||||
UnicodeToASCII(DeviceInfoPos, Manufacturer);
|
||||
printf_P(PSTR(" Manufacturer: %s\r\n"), Manufacturer);
|
||||
|
||||
DeviceInfoPos += 1 + UNICODE_STRING_LENGTH(*DeviceInfoPos); // Skip over Manufacturer String
|
||||
|
||||
/* Extract and convert the Model Unicode string to ASCII and print it through the USART */
|
||||
char Model[*DeviceInfoPos];
|
||||
UnicodeToASCII(DeviceInfoPos, Model);
|
||||
printf_P(PSTR(" Model: %s\r\n"), Model);
|
||||
|
||||
DeviceInfoPos += 1 + UNICODE_STRING_LENGTH(*DeviceInfoPos); // Skip over Model String
|
||||
|
||||
/* Extract and convert the Device Version Unicode string to ASCII and print it through the USART */
|
||||
char DeviceVersion[*DeviceInfoPos];
|
||||
UnicodeToASCII(DeviceInfoPos, DeviceVersion);
|
||||
printf_P(PSTR(" Device Version: %s\r\n"), DeviceVersion);
|
||||
|
||||
/* Receive the final response block from the device */
|
||||
if ((ErrorCode = SImage_ReceiveBlockHeader()) != PIPE_RWSTREAM_NoError)
|
||||
{
|
||||
ShowCommandError(ErrorCode, false);
|
||||
USB_Host_SetDeviceConfiguration(0);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Verify that the command completed successfully */
|
||||
if ((PIMA_ReceivedBlock.Type != PIMA_CONTAINER_ResponseBlock) || (PIMA_ReceivedBlock.Code != PIMA_RESPONSE_OK))
|
||||
{
|
||||
ShowCommandError(PIMA_ReceivedBlock.Code, true);
|
||||
USB_Host_SetDeviceConfiguration(0);
|
||||
return;
|
||||
}
|
||||
|
||||
puts_P(PSTR("Opening Session...\r\n"));
|
||||
|
||||
PIMA_SendBlock = (PIMA_Container_t)
|
||||
{
|
||||
.DataLength = PIMA_COMMAND_SIZE(1),
|
||||
.Type = PIMA_CONTAINER_CommandBlock,
|
||||
.Code = PIMA_OPERATION_OPENSESSION,
|
||||
.TransactionID = 0x00000000,
|
||||
.Params = {0x00000001},
|
||||
};
|
||||
|
||||
/* Send the OPENSESSION block, open a session with an ID of 0x0001 */
|
||||
SImage_SendBlockHeader();
|
||||
|
||||
/* Receive the response block from the device */
|
||||
if ((ErrorCode = SImage_ReceiveBlockHeader()) != PIPE_RWSTREAM_NoError)
|
||||
{
|
||||
ShowCommandError(ErrorCode, false);
|
||||
USB_Host_SetDeviceConfiguration(0);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Verify that the command completed successfully */
|
||||
if ((PIMA_ReceivedBlock.Type != PIMA_CONTAINER_ResponseBlock) || (PIMA_ReceivedBlock.Code != PIMA_RESPONSE_OK))
|
||||
{
|
||||
ShowCommandError(PIMA_ReceivedBlock.Code, true);
|
||||
USB_Host_SetDeviceConfiguration(0);
|
||||
return;
|
||||
}
|
||||
|
||||
puts_P(PSTR("Closing Session...\r\n"));
|
||||
|
||||
PIMA_SendBlock = (PIMA_Container_t)
|
||||
{
|
||||
.DataLength = PIMA_COMMAND_SIZE(1),
|
||||
.Type = PIMA_CONTAINER_CommandBlock,
|
||||
.Code = PIMA_OPERATION_CLOSESESSION,
|
||||
.TransactionID = 0x00000001,
|
||||
.Params = {0x00000001},
|
||||
};
|
||||
|
||||
/* Send the CLOSESESSION block, close the session with an ID of 0x0001 */
|
||||
SImage_SendBlockHeader();
|
||||
|
||||
/* Receive the response block from the device */
|
||||
if ((ErrorCode = SImage_ReceiveBlockHeader()) != PIPE_RWSTREAM_NoError)
|
||||
{
|
||||
ShowCommandError(ErrorCode, false);
|
||||
USB_Host_SetDeviceConfiguration(0);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Verify that the command completed successfully */
|
||||
if ((PIMA_ReceivedBlock.Type != PIMA_CONTAINER_ResponseBlock) || (PIMA_ReceivedBlock.Code != PIMA_RESPONSE_OK))
|
||||
{
|
||||
ShowCommandError(PIMA_ReceivedBlock.Code, true);
|
||||
USB_Host_SetDeviceConfiguration(0);
|
||||
return;
|
||||
}
|
||||
|
||||
puts_P(PSTR("Done.\r\n"));
|
||||
|
||||
/* Indicate device no longer busy */
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_READY);
|
||||
USB_Host_SetDeviceConfiguration(0);
|
||||
}
|
||||
|
||||
/** Function to convert a given Unicode encoded string to ASCII. This function will only work correctly on Unicode
|
||||
|
|
|
|||
|
|
@ -69,8 +69,8 @@
|
|||
#define LEDMASK_USB_BUSY LEDS_LED2
|
||||
|
||||
/* Function Prototypes: */
|
||||
void StillImage_Task(void);
|
||||
void SetupHardware(void);
|
||||
void StillImageHost_Task(void);
|
||||
|
||||
void EVENT_USB_Host_HostError(const uint8_t ErrorCode);
|
||||
void EVENT_USB_Host_DeviceAttached(void);
|
||||
|
|
|
|||
|
|
@ -50,7 +50,8 @@ int main(void)
|
|||
|
||||
for (;;)
|
||||
{
|
||||
CDC_Host_Task();
|
||||
CDCHost_Task();
|
||||
|
||||
USB_USBTask();
|
||||
}
|
||||
}
|
||||
|
|
@ -97,6 +98,35 @@ void EVENT_USB_Host_DeviceUnattached(void)
|
|||
*/
|
||||
void EVENT_USB_Host_DeviceEnumerationComplete(void)
|
||||
{
|
||||
puts_P(PSTR("Getting Config Data.\r\n"));
|
||||
|
||||
uint8_t ErrorCode;
|
||||
|
||||
/* Get and process the configuration descriptor data */
|
||||
if ((ErrorCode = ProcessConfigurationDescriptor()) != SuccessfulConfigRead)
|
||||
{
|
||||
if (ErrorCode == ControlError)
|
||||
puts_P(PSTR(ESC_FG_RED "Control Error (Get Configuration).\r\n"));
|
||||
else
|
||||
puts_P(PSTR(ESC_FG_RED "Invalid Device.\r\n"));
|
||||
|
||||
printf_P(PSTR(" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
|
||||
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Set the device configuration to the first configuration (rarely do devices use multiple configurations) */
|
||||
if ((ErrorCode = USB_Host_SetDeviceConfiguration(1)) != HOST_SENDCONTROL_Successful)
|
||||
{
|
||||
printf_P(PSTR(ESC_FG_RED "Control Error (Set Configuration).\r\n"
|
||||
" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
|
||||
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
puts_P(PSTR("CDC Device Enumerated.\r\n"));
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_READY);
|
||||
}
|
||||
|
||||
|
|
@ -126,102 +156,57 @@ void EVENT_USB_Host_DeviceEnumerationFailed(const uint8_t ErrorCode,
|
|||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
}
|
||||
|
||||
/** Task to set the configuration of the attached device after it has been enumerated, and to read in
|
||||
* data received from the attached CDC device and print it to the serial port.
|
||||
/** Task to read in data received from the attached CDC device and print it to the serial port.
|
||||
*/
|
||||
void CDC_Host_Task(void)
|
||||
void CDCHost_Task(void)
|
||||
{
|
||||
uint8_t ErrorCode;
|
||||
if (USB_HostState != HOST_STATE_Configured)
|
||||
return;
|
||||
|
||||
switch (USB_HostState)
|
||||
/* Select the data IN pipe */
|
||||
Pipe_SelectPipe(CDC_DATA_IN_PIPE);
|
||||
Pipe_Unfreeze();
|
||||
|
||||
/* Check to see if a packet has been received */
|
||||
if (Pipe_IsINReceived())
|
||||
{
|
||||
case HOST_STATE_Addressed:
|
||||
puts_P(PSTR("Getting Config Data.\r\n"));
|
||||
/* Re-freeze IN pipe after the packet has been received */
|
||||
Pipe_Freeze();
|
||||
|
||||
/* Get and process the configuration descriptor data */
|
||||
if ((ErrorCode = ProcessConfigurationDescriptor()) != SuccessfulConfigRead)
|
||||
{
|
||||
if (ErrorCode == ControlError)
|
||||
puts_P(PSTR(ESC_FG_RED "Control Error (Get Configuration).\r\n"));
|
||||
else
|
||||
puts_P(PSTR(ESC_FG_RED "Invalid Device.\r\n"));
|
||||
/* Check if data is in the pipe */
|
||||
if (Pipe_IsReadWriteAllowed())
|
||||
{
|
||||
/* Get the length of the pipe data, and create a new buffer to hold it */
|
||||
uint16_t BufferLength = Pipe_BytesInPipe();
|
||||
uint8_t Buffer[BufferLength];
|
||||
|
||||
printf_P(PSTR(" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
|
||||
/* Read in the pipe data to the temporary buffer */
|
||||
Pipe_Read_Stream_LE(Buffer, BufferLength, NULL);
|
||||
|
||||
/* Indicate error via status LEDs */
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
/* Print out the buffer contents to the USART */
|
||||
for (uint16_t BufferByte = 0; BufferByte < BufferLength; BufferByte++)
|
||||
putchar(Buffer[BufferByte]);
|
||||
}
|
||||
|
||||
/* Wait until USB device disconnected */
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Set the device configuration to the first configuration (rarely do devices use multiple configurations) */
|
||||
if ((ErrorCode = USB_Host_SetDeviceConfiguration(1)) != HOST_SENDCONTROL_Successful)
|
||||
{
|
||||
printf_P(PSTR(ESC_FG_RED "Control Error (Set Configuration).\r\n"
|
||||
" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode);
|
||||
|
||||
/* Indicate error via status LEDs */
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
|
||||
|
||||
/* Wait until USB device disconnected */
|
||||
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
|
||||
break;
|
||||
}
|
||||
|
||||
puts_P(PSTR("CDC Device Enumerated.\r\n"));
|
||||
|
||||
USB_HostState = HOST_STATE_Configured;
|
||||
break;
|
||||
case HOST_STATE_Configured:
|
||||
/* Select the data IN pipe */
|
||||
Pipe_SelectPipe(CDC_DATA_IN_PIPE);
|
||||
Pipe_Unfreeze();
|
||||
|
||||
/* Check to see if a packet has been received */
|
||||
if (Pipe_IsINReceived())
|
||||
{
|
||||
/* Re-freeze IN pipe after the packet has been received */
|
||||
Pipe_Freeze();
|
||||
|
||||
/* Check if data is in the pipe */
|
||||
if (Pipe_IsReadWriteAllowed())
|
||||
{
|
||||
/* Get the length of the pipe data, and create a new buffer to hold it */
|
||||
uint16_t BufferLength = Pipe_BytesInPipe();
|
||||
uint8_t Buffer[BufferLength];
|
||||
|
||||
/* Read in the pipe data to the temporary buffer */
|
||||
Pipe_Read_Stream_LE(Buffer, BufferLength, NULL);
|
||||
|
||||
/* Print out the buffer contents to the USART */
|
||||
for (uint16_t BufferByte = 0; BufferByte < BufferLength; BufferByte++)
|
||||
putchar(Buffer[BufferByte]);
|
||||
}
|
||||
|
||||
/* Clear the pipe after it is read, ready for the next packet */
|
||||
Pipe_ClearIN();
|
||||
}
|
||||
|
||||
/* Re-freeze IN pipe after use */
|
||||
Pipe_Freeze();
|
||||
|
||||
/* Select and unfreeze the notification pipe */
|
||||
Pipe_SelectPipe(CDC_NOTIFICATION_PIPE);
|
||||
Pipe_Unfreeze();
|
||||
|
||||
/* Check if a packet has been received */
|
||||
if (Pipe_IsINReceived())
|
||||
{
|
||||
/* Discard the unused event notification */
|
||||
Pipe_ClearIN();
|
||||
}
|
||||
|
||||
/* Freeze notification IN pipe after use */
|
||||
Pipe_Freeze();
|
||||
|
||||
break;
|
||||
/* Clear the pipe after it is read, ready for the next packet */
|
||||
Pipe_ClearIN();
|
||||
}
|
||||
|
||||
/* Re-freeze IN pipe after use */
|
||||
Pipe_Freeze();
|
||||
|
||||
/* Select and unfreeze the notification pipe */
|
||||
Pipe_SelectPipe(CDC_NOTIFICATION_PIPE);
|
||||
Pipe_Unfreeze();
|
||||
|
||||
/* Check if a packet has been received */
|
||||
if (Pipe_IsINReceived())
|
||||
{
|
||||
/* Discard the unused event notification */
|
||||
Pipe_ClearIN();
|
||||
}
|
||||
|
||||
/* Freeze notification IN pipe after use */
|
||||
Pipe_Freeze();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@
|
|||
|
||||
/* Function Prototypes: */
|
||||
void SetupHardware(void);
|
||||
void CDC_Host_Task(void);
|
||||
void CDCHost_Task(void);
|
||||
|
||||
void EVENT_USB_Host_HostError(const uint8_t ErrorCode);
|
||||
void EVENT_USB_Host_DeviceAttached(void);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue