/** Event handler for the USB_DeviceEnumerationComplete event. This indicates that a device has been successfully * enumerated by the host and is now ready to be used by the application. */ void EVENT_USB_Host_DeviceEnumerationComplete(void) { puts_P(PSTR("Getting Config Data.\r\n")); uint8_t ErrorCode; /* Get and process the configuration descriptor data */ if ((ErrorCode = ProcessConfigurationDescriptor()) != SuccessfulConfigRead) { if (ErrorCode == ControlError) puts_P(PSTR(ESC_FG_RED "Control Error (Get Configuration).\r\n")); else puts_P(PSTR(ESC_FG_RED "Invalid Device.\r\n")); printf_P(PSTR(" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); return; } /* Set the device configuration to the first configuration (rarely do devices use multiple configurations) */ if ((ErrorCode = USB_Host_SetDeviceConfiguration(1)) != HOST_SENDCONTROL_Successful) { printf_P(PSTR(ESC_FG_RED "Control Error (Set Configuration).\r\n" " -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); return; } puts_P(PSTR("Still Image Device Enumerated.\r\n")); LEDs_SetAllLEDs(LEDMASK_USB_READY); }
/** Event handler for the USB_DeviceEnumerationComplete event. This indicates that a device has been successfully * enumerated by the host and is now ready to be used by the application. */ void EVENT_USB_Host_DeviceEnumerationComplete(void) { puts_P(PSTR("Getting Config Data.\r\n")); uint8_t ErrorCode; /* Get and process the configuration descriptor data */ if ((ErrorCode = ProcessConfigurationDescriptor()) != SuccessfulConfigRead) { if (ErrorCode == ControlError) puts_P(PSTR(ESC_FG_RED "Control Error (Get Configuration).\r\n")); else puts_P(PSTR(ESC_FG_RED "Invalid Device.\r\n")); printf_P(PSTR(" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); return; } /* Set the device configuration to the first configuration (rarely do devices use multiple configurations) */ if ((ErrorCode = USB_Host_SetDeviceConfiguration(1)) != HOST_SENDCONTROL_Successful) { 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); }
/** Event handler for the USB_DeviceEnumerationComplete event. This indicates that a device has been successfully * enumerated by the host and is now ready to be used by the application. */ void EVENT_USB_Host_DeviceEnumerationComplete(void) { LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING); /* Get and process the configuration descriptor data */ if (ProcessConfigurationDescriptor() != SuccessfulConfigRead) { LEDs_SetAllLEDs(LEDMASK_USB_ERROR); return; } /* Set the device configuration to the first configuration (rarely do devices use multiple configurations) */ if (USB_Host_SetDeviceConfiguration(1) != HOST_SENDCONTROL_Successful) { LEDs_SetAllLEDs(LEDMASK_USB_ERROR); return; } LEDs_SetAllLEDs(LEDMASK_USB_READY); }
// USB Modems make use of a feature called USB mode switching. You can read about it at http://www.draisberghof.de/usb_modeswitch/ // Depending on the modem you will have to define different commands to switch the modem from storage mode to modem mode. // One way to determine the correct command is to run the modem under Windows and use USBMonitor // (http://www.hhdsoftware.com/Downloads/usb-monitor.html) to determine what commands are sent to the modem. // Another method is to look at the code at http://www.draisberghof.de/usb_modeswitch/ to see if the codes for your modem have already been determined. // // This function returns: // true if the modem has been enumerated correctly // false if there is an error, or if we must wait for the modem to disconnect bool ProcessModemUSBStates(void) { uint8_t ErrorCode; Debug_Print("Send configuration command\r\n"); if ((ErrorCode = USB_Host_SetDeviceConfiguration(1)) != HOST_SENDCONTROL_Successful) { Debug_Print("Control error (Set Config)\r\n"); Debug_PrintHex(ErrorCode); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); // Indicate error via status LEDs return false; } Debug_Print("Looking for modem device..."); // Get and process the configuration descriptor data // First time through we expect a non-modem device. Once the device has disconnected and re-attached it should be OK if ((ErrorCode = ProcessConfigurationDescriptor()) != SuccessfulConfigRead) { if (ErrorCode == ControlError) { Debug_Print("Control error (Get Configuration)\r\n"); Debug_PrintHex(ErrorCode); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); // Indicate error via status LEDs return false; } else { Debug_Print("Not a modem device - switching modes\r\n"); USB_Host_SuspendBus(); // This will cause the device to disconnect and reconnect in modem mode return false; // Wait until USB device disconnects } } Debug_Print("Modem device enumerated\r\n"); return true; }
/** Event handler for the USB_DeviceEnumerationComplete event. This indicates that a device has been successfully * enumerated by the host and is now ready to be used by the application. */ void EVENT_USB_Host_DeviceEnumerationComplete(void) { puts_P(PSTR("Getting Device Data.\r\n")); /* Get and process the configuration descriptor data */ uint8_t ErrorCode = ProcessDeviceDescriptor(); bool RequiresModeSwitch = (ErrorCode == NonAccessoryModeAndroidDevice); /* Error out if the device is not an Android device or an error occurred */ if ((ErrorCode != AccessoryModeAndroidDevice) && (ErrorCode != NonAccessoryModeAndroidDevice)) { if (ErrorCode == ControlError) puts_P(PSTR(ESC_FG_RED "Control Error (Get Device).\r\n")); else puts_P(PSTR(ESC_FG_RED "Invalid Device.\r\n")); printf_P(PSTR(" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); return; } printf_P(PSTR("Android Device Detected - %sAccessory mode.\r\n"), (RequiresModeSwitch ? "Non-" : "")); /* Check if a valid Android device was attached, but it is not current in Accessory mode */ if (RequiresModeSwitch) { uint16_t AndroidProtocol; /* Fetch the version of the Android Accessory Protocol supported by the device */ if ((ErrorCode = Android_GetAccessoryProtocol(&AndroidProtocol)) != HOST_SENDCONTROL_Successful) { printf_P(PSTR(ESC_FG_RED "Control Error (Get Protocol).\r\n" " -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); return; } /* Validate the returned protocol version */ if (AndroidProtocol != AOA_PROTOCOL_AccessoryV1) { puts_P(PSTR(ESC_FG_RED "Accessory Mode Not Supported.")); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); return; } /* Send the device strings and start the Android Accessory Mode */ Android_SendString(AOA_STRING_Manufacturer, "Dean Camera"); Android_SendString(AOA_STRING_Model, "LUFA Android Demo"); Android_SendString(AOA_STRING_Description, "LUFA Android Demo"); Android_SendString(AOA_STRING_Version, "1.0"); Android_SendString(AOA_STRING_URI, "http://www.lufa-lib.org"); Android_SendString(AOA_STRING_Serial, "0000000012345678"); Android_StartAccessoryMode(); return; } puts_P(PSTR("Getting Config Data.\r\n")); /* Get and process the configuration descriptor data */ if ((ErrorCode = ProcessConfigurationDescriptor()) != SuccessfulConfigRead) { if (ErrorCode == ControlError) puts_P(PSTR(ESC_FG_RED "Control Error (Get Configuration).\r\n")); else puts_P(PSTR(ESC_FG_RED "Invalid Device.\r\n")); printf_P(PSTR(" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); return; } /* Set the device configuration to the first configuration (rarely do devices use multiple configurations) */ if ((ErrorCode = USB_Host_SetDeviceConfiguration(1)) != HOST_SENDCONTROL_Successful) { printf_P(PSTR(ESC_FG_RED "Control Error (Set Configuration).\r\n" " -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); return; } puts_P(PSTR("Accessory Mode Android Enumerated.\r\n")); LEDs_SetAllLEDs(LEDMASK_USB_READY); }
/** Event handler for the USB_DeviceEnumerationComplete event. This indicates that a device has been successfully * enumerated by the host and is now ready to be used by the application. */ void EVENT_USB_Host_DeviceEnumerationComplete(void) { puts_P(PSTR("Getting Config Data.\r\n")); uint8_t ErrorCode; /* Get and process the configuration descriptor data */ if ((ErrorCode = ProcessConfigurationDescriptor()) != SuccessfulConfigRead) { if (ErrorCode == ControlError) puts_P(PSTR(ESC_FG_RED "Control Error (Get Configuration).\r\n")); else puts_P(PSTR(ESC_FG_RED "Invalid Device.\r\n")); printf_P(PSTR(" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); return; } /* Set the device configuration to the first configuration (rarely do devices use multiple configurations) */ if ((ErrorCode = USB_Host_SetDeviceConfiguration(1)) != HOST_SENDCONTROL_Successful) { printf_P(PSTR(ESC_FG_RED "Control Error (Set Configuration).\r\n" " -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); return; } /* 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); } /** Event handler for the USB_HostError event. This indicates that a hardware error occurred while in host mode. */ void EVENT_USB_Host_HostError(const uint8_t ErrorCode) { USB_Disable(); printf_P(PSTR(ESC_FG_RED "Host Mode Error\r\n" " -- Error Code %d\r\n" ESC_FG_WHITE), ErrorCode); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); for(;;); }
/** Event handler for the USB_DeviceEnumerationComplete event. This indicates that a device has been successfully * enumerated by the host and is now ready to be used by the application. */ void EVENT_USB_Host_DeviceEnumerationComplete(void) { puts_P(PSTR("Getting Config Data.\r\n")); uint8_t ErrorCode; /* Get and process the configuration descriptor data */ if ((ErrorCode = ProcessConfigurationDescriptor()) != SuccessfulConfigRead) { if (ErrorCode == ControlError) puts_P(PSTR(ESC_FG_RED "Control Error (Get Configuration).\r\n")); else puts_P(PSTR(ESC_FG_RED "Invalid Device.\r\n")); printf_P(PSTR(" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); return; } /* Set the device configuration to the first configuration (rarely do devices use multiple configurations) */ if ((ErrorCode = USB_Host_SetDeviceConfiguration(1)) != HOST_SENDCONTROL_Successful) { printf_P(PSTR(ESC_FG_RED "Control Error (Set Configuration).\r\n" " -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); return; } if ((ErrorCode = USB_Host_SetInterfaceAltSetting(StreamingInterfaceIndex, StreamingInterfaceAltSetting)) != HOST_SENDCONTROL_Successful) { printf_P(PSTR(ESC_FG_RED "Could not set alternative streaming interface setting.\r\n" " -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); USB_Host_SetDeviceConfiguration(0); return; } USB_ControlRequest = (USB_Request_Header_t) { .bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_ENDPOINT), .bRequest = AUDIO_REQ_SetCurrent, .wValue = (AUDIO_EPCONTROL_SamplingFreq << 8), .wIndex = StreamingEndpointAddress, .wLength = sizeof(USB_Audio_SampleFreq_t), }; USB_Audio_SampleFreq_t SampleRate = AUDIO_SAMPLE_FREQ(48000); /* Select the control pipe for the request transfer */ Pipe_SelectPipe(PIPE_CONTROLPIPE); /* Set the sample rate on the streaming interface endpoint */ if ((ErrorCode = USB_Host_SendControlRequest(&SampleRate)) != HOST_SENDCONTROL_Successful) { LEDs_SetAllLEDs(LEDMASK_USB_ERROR); USB_Host_SetDeviceConfiguration(0); return; } /* Sample reload timer initialization */ TIMSK0 = (1 << OCIE0A); OCR0A = ((F_CPU / 8 / 48000) - 1); TCCR0A = (1 << WGM01); // CTC mode TCCR0B = (1 << CS01); // Fcpu/8 speed puts_P(PSTR("Speaker Enumerated.\r\n")); LEDs_SetAllLEDs(LEDMASK_USB_READY); } /** Event handler for the USB_HostError event. This indicates that a hardware error occurred while in host mode. */ void EVENT_USB_Host_HostError(const uint8_t ErrorCode) { USB_Disable(); printf_P(PSTR(ESC_FG_RED "Host Mode Error\r\n" " -- Error Code %d\r\n" ESC_FG_WHITE), ErrorCode); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); for(;;); }
/** Event handler for the USB_DeviceEnumerationComplete event. This indicates that a device has been successfully * enumerated by the host and is now ready to be used by the application. */ void EVENT_USB_Host_DeviceEnumerationComplete(void) { puts_P(PSTR("Getting Config Data.\r\n")); uint8_t ErrorCode; /* Get and process the configuration descriptor data */ if ((ErrorCode = ProcessConfigurationDescriptor()) != SuccessfulConfigRead) { if (ErrorCode == ControlError) puts_P(PSTR(ESC_FG_RED "Control Error (Get Configuration).\r\n")); else puts_P(PSTR(ESC_FG_RED "Invalid Device.\r\n")); printf_P(PSTR(" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); return; } /* Set the device configuration to the first configuration (rarely do devices use multiple configurations) */ if ((ErrorCode = USB_Host_SetDeviceConfiguration(1)) != HOST_SENDCONTROL_Successful) { printf_P(PSTR(ESC_FG_RED "Control Error (Set Configuration).\r\n" " -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); return; } CDC_LineEncoding_t LineEncoding = { .BaudRateBPS = 9600, .CharFormat = CDC_LINEENCODING_OneStopBit, .ParityType = CDC_PARITY_None, .DataBits = 8 }; USB_ControlRequest = (USB_Request_Header_t) { .bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE), .bRequest = CDC_REQ_SetLineEncoding, .wValue = 0, .wIndex = 0, .wLength = sizeof(LineEncoding), }; /* Set the Line Encoding of the CDC interface within the device, so that it is ready to accept data */ Pipe_SelectPipe(PIPE_CONTROLPIPE); if (USB_Host_SendControlRequest(&LineEncoding) != HOST_SENDCONTROL_Successful) { printf_P(PSTR(ESC_FG_RED "Control Error (Set Line Encoding).\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); } /** Event handler for the USB_HostError event. This indicates that a hardware error occurred while in host mode. */ void EVENT_USB_Host_HostError(const uint8_t ErrorCode) { USB_Disable(); printf_P(PSTR(ESC_FG_RED "Host Mode Error\r\n" " -- Error Code %d\r\n" ESC_FG_WHITE), ErrorCode); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); for(;;); } /** Event handler for the USB_DeviceEnumerationFailed event. This indicates that a problem occurred while * enumerating an attached USB device. */ void EVENT_USB_Host_DeviceEnumerationFailed(const uint8_t ErrorCode, const uint8_t SubErrorCode) { printf_P(PSTR(ESC_FG_RED "Dev Enum Error\r\n" " -- Error Code %d\r\n" " -- Sub Error Code %d\r\n" " -- In State %d\r\n" ESC_FG_WHITE), ErrorCode, SubErrorCode, USB_HostState); 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. */ void Joystick_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 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; } }
/** 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. */ void USB_Printer_Host(void) { uint8_t ErrorCode; switch (USB_HostState) { case HOST_STATE_Addressed: puts_P(PSTR("Getting Config Data.\r\n")); /* 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) { USB_ControlRequest = (USB_Request_Header_t) { .bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_INTERFACE), .bRequest = REQ_SetInterface, .wValue = PrinterAltSetting, .wIndex = PrinterInterfaceNumber, .wLength = 0, }; if ((ErrorCode = USB_Host_SendControlRequest(NULL)) != 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; } }
/** Task to set the configuration of the attached device after it has been enumerated, and to print device information * through the serial port. */ void StillImage_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; } 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 = CType_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 != CType_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 = CType_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 != CType_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 = CType_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 != CType_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; } } /** Function to convert a given Unicode encoded string to ASCII. This function will only work correctly on Unicode * strings which contain ASCII printable characters only. * * \param[in] UnicodeString Pointer to a Unicode encoded input string * \param[out] Buffer Pointer to a buffer where the converted ASCII string should be stored */ void UnicodeToASCII(uint8_t* UnicodeString, char* Buffer) { /* Get the number of characters in the string, skip to the start of the string data */ uint8_t CharactersRemaining = *(UnicodeString++); /* Loop through the entire unicode string */ while (CharactersRemaining--) { /* Load in the next unicode character (only the lower byte, as only Unicode coded ASCII is supported) */ *(Buffer++) = *UnicodeString; /* Jump to the next unicode character */ UnicodeString += 2; } /* Null terminate the string */ *Buffer = 0; } /** Displays a PIMA command error via the device's serial port. * * \param[in] ErrorCode Error code of the function which failed to complete successfully * \param[in] ResponseCodeError Indicates if the error is due to a command failed indication from the device, or a communication failure */ void ShowCommandError(uint8_t ErrorCode, bool ResponseCodeError) { char* FailureType = ((ResponseCodeError) ? PSTR("Response Code != OK") : PSTR("Transaction Fail")); printf_P(PSTR(ESC_FG_RED "Command Error (%S).\r\n" " -- Error Code %d\r\n" ESC_FG_WHITE), FailureType, ErrorCode); /* Indicate error via status LEDs */ LEDs_SetAllLEDs(LEDMASK_USB_ERROR); }
/** Event handler for the USB_DeviceEnumerationComplete event. This indicates that a device has been successfully * enumerated by the host and is now ready to be used by the application. */ void EVENT_USB_Host_DeviceEnumerationComplete(void) { puts_P(PSTR("Getting Config Data.\r\n")); uint8_t ErrorCode; /* Get and process the configuration descriptor data */ if ((ErrorCode = ProcessConfigurationDescriptor()) != SuccessfulConfigRead) { if (ErrorCode == ControlError) puts_P(PSTR(ESC_FG_RED "Control Error (Get Configuration).\r\n")); else puts_P(PSTR(ESC_FG_RED "Invalid Device.\r\n")); printf_P(PSTR(" -- Error Code: %d\r\n"), 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); }
/** Task to set the configuration of the attached device after it has been enumerated. */ void Android_Host_Task(void) { uint8_t ErrorCode; switch (USB_HostState) { case HOST_STATE_Addressed: puts_P(PSTR("Getting Device Data.\r\n")); /* Get and process the configuration descriptor data */ ErrorCode = ProcessDeviceDescriptor(); /* Save whether the Android device needs to be mode-switched later on */ bool RequiresModeSwitch = (ErrorCode == NonAccessoryModeAndroidDevice); /* Error out if the device is not an Android device or an error occurred */ if ((ErrorCode != AccessoryModeAndroidDevice) && !(RequiresModeSwitch)) { if (ErrorCode == DevControlError) puts_P(PSTR(ESC_FG_RED "Control Error (Get Device).\r\n")); else puts_P(PSTR(ESC_FG_RED "Invalid Device.\r\n")); printf_P(PSTR(" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode); /* Indicate error via status LEDs */ LEDs_SetAllLEDs(LEDS_LED1); /* Wait until USB device disconnected */ USB_HostState = HOST_STATE_WaitForDeviceRemoval; break; } printf_P(PSTR("Android Device Detected - %sAccessory mode.\r\n"), (RequiresModeSwitch ? "Non-" : "")); /* Set the device configuration to the first configuration (rarely do devices use multiple configurations) */ if ((ErrorCode = USB_Host_SetDeviceConfiguration(1)) != HOST_SENDCONTROL_Successful) { printf_P(PSTR(ESC_FG_RED "Control Error (Set Configuration).\r\n" " -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode); /* Indicate error via status LEDs */ LEDs_SetAllLEDs(LEDS_LED1); /* Wait until USB device disconnected */ USB_HostState = HOST_STATE_WaitForDeviceRemoval; break; } /* Check if a valid Android device was attached, but it is not current in Accessory mode */ if (RequiresModeSwitch) { USB_ControlRequest = (USB_Request_Header_t) { .bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_VENDOR | REQREC_DEVICE), .bRequest = ANDROID_Req_StartAccessoryMode, .wValue = 0, .wIndex = 0, .wLength = 0, }; /* Send the control request for the Android device to switch to accessory mode */ Pipe_SelectPipe(PIPE_CONTROLPIPE); USB_Host_SendControlRequest(NULL); /* Wait until USB device disconnected */ USB_HostState = HOST_STATE_WaitForDeviceRemoval; break; } puts_P(PSTR("Getting Config Data.\r\n")); /* Get and process the configuration descriptor data */ if ((ErrorCode = ProcessConfigurationDescriptor()) != SuccessfulConfigRead) { if (ErrorCode == ControlError) puts_P(PSTR(ESC_FG_RED "Control Error (Get Configuration).\r\n")); else puts_P(PSTR(ESC_FG_RED "Invalid Device.\r\n")); printf_P(PSTR(" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode); /* Indicate error via status LEDs */ LEDs_SetAllLEDs(LEDS_LED1); /* Wait until USB device disconnected */ USB_HostState = HOST_STATE_WaitForDeviceRemoval; break; } puts_P(PSTR("Accessory Mode Android Enumerated.\r\n")); USB_HostState = HOST_STATE_Configured; break; case HOST_STATE_Configured: /* Select the data IN pipe */ Pipe_SelectPipe(ANDROID_DATA_IN_PIPE); Pipe_Unfreeze(); /* Check to see if a packet has been received */ if (Pipe_IsINReceived()) { /* Re-freeze IN pipe after the packet has been received */ Pipe_Freeze(); /* Check if data is in the pipe */ if (Pipe_IsReadWriteAllowed()) { uint8_t NextReceivedByte = Pipe_BytesInPipe(); uint8_t LEDMask = LEDS_NO_LEDS; if (NextReceivedByte & 0x01) LEDMask |= LEDS_LED1; if (NextReceivedByte & 0x02) LEDMask |= LEDS_LED2; if (NextReceivedByte & 0x04) LEDMask |= LEDS_LED3; if (NextReceivedByte & 0x08) LEDMask |= LEDS_LED4; LEDs_SetAllLEDs(LEDMask); } else { /* Clear the pipe after all data in the packet has been read, ready for the next packet */ Pipe_ClearIN(); } } /* Re-freeze IN pipe after use */ Pipe_Freeze(); break; } }
/** 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. */ void CDC_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; } puts_P(PSTR("CDC Device Enumerated.\r\n")); USB_HostState = HOST_STATE_Configured; break; case HOST_STATE_Configured: /* Select and the data IN pipe */ Pipe_SelectPipe(CDC_DATAPIPE_IN); 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); /* 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_NOTIFICATIONPIPE); 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; } }
/** 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 = 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; } }
/** Writes a report to the attached device. * * \param[in] ReportOUTData Buffer containing the report to send to the device * \param[in] ReportIndex Index of the report in the device (zero if the device does not use multiple reports) * \param[in] ReportType Type of report to send, either REPORT_TYPE_OUT or REPORT_TYPE_FEATURE * \param[in] ReportLength Length of the report to send */ void WriteNextReport(uint8_t* ReportOUTData, const uint8_t ReportIndex, const uint8_t ReportType, uint16_t ReportLength) { /* Select the HID data OUT pipe */ Pipe_SelectPipe(HID_DATA_OUT_PIPE); /* Not all HID devices have an OUT endpoint (some require OUT reports to be sent over the * control endpoint instead) - check to see if the OUT endpoint has been initialized */ if (Pipe_IsConfigured() && (ReportType == REPORT_TYPE_OUT)) { Pipe_Unfreeze(); /* Ensure pipe is ready to be written to before continuing */ if (!(Pipe_IsOUTReady())) { /* Refreeze the data OUT pipe */ Pipe_Freeze(); return; } /* If the report index is used, send it before the report data */ if (ReportIndex) Pipe_Write_Byte(ReportIndex); /* Write out HID report data */ Pipe_Write_Stream_LE(ReportOUTData, ReportLength); /* Clear the OUT endpoint, send last data packet */ Pipe_ClearOUT(); /* Refreeze the data OUT pipe */ Pipe_Freeze(); } else { /* Class specific request to send a HID report to the device */ USB_ControlRequest = (USB_Request_Header_t) { .bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE), .bRequest = HID_REQ_SetReport, .wValue = ((ReportType << 8) | ReportIndex), .wIndex = 0, .wLength = ReportLength, }; /* Select the control pipe for the request transfer */ Pipe_SelectPipe(PIPE_CONTROLPIPE); /* Send the request to the device */ USB_Host_SendControlRequest(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; } }
/** Task to set the configuration of the attached device after it has been enumerated. */ void Bluetooth_Host_Task(void) { uint8_t ErrorCode; switch (USB_HostState) { case HOST_STATE_Addressed: puts_P(PSTR("Getting Device Data.\r\n")); /* Get and process the configuration descriptor data */ if ((ErrorCode = ProcessDeviceDescriptor()) != SuccessfulDeviceRead) { if (ErrorCode == DevControlError) puts_P(PSTR(ESC_FG_RED "Control Error (Get Device).\r\n")); else puts_P(PSTR(ESC_FG_RED "Invalid Device.\r\n")); printf_P(PSTR(" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode); /* Indicate error via status LEDs */ LEDs_SetAllLEDs(LEDS_LED1); /* Wait until USB device disconnected */ USB_HostState = HOST_STATE_WaitForDeviceRemoval; break; } puts_P(PSTR("Bluetooth Dongle Detected.\r\n")); /* Set the device configuration to the first configuration (rarely do devices use multiple configurations) */ if ((ErrorCode = USB_Host_SetDeviceConfiguration(1)) != HOST_SENDCONTROL_Successful) { printf_P(PSTR(ESC_FG_RED "Control Error (Set Configuration).\r\n" " -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode); /* Indicate error via status LEDs */ LEDs_SetAllLEDs(LEDS_LED1); /* Wait until USB device disconnected */ USB_HostState = HOST_STATE_WaitForDeviceRemoval; break; } puts_P(PSTR("Getting Config Data.\r\n")); /* Get and process the configuration descriptor data */ if ((ErrorCode = ProcessConfigurationDescriptor()) != SuccessfulConfigRead) { if (ErrorCode == ControlError) puts_P(PSTR(ESC_FG_RED "Control Error (Get Configuration).\r\n")); else puts_P(PSTR(ESC_FG_RED "Invalid Device.\r\n")); printf_P(PSTR(" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode); /* Indicate error via status LEDs */ LEDs_SetAllLEDs(LEDS_LED1); /* Wait until USB device disconnected */ USB_HostState = HOST_STATE_WaitForDeviceRemoval; break; } puts_P(PSTR("Bluetooth Dongle Enumerated.\r\n")); /* Initialize the Bluetooth stack */ Bluetooth_Stack_Init(); USB_HostState = HOST_STATE_Configured; break; } }
/** 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; } }
/** Event handler for the USB_DeviceEnumerationComplete event. This indicates that a device has been successfully * enumerated by the host and is now ready to be used by the application. */ void EVENT_USB_Host_DeviceEnumerationComplete(void) { puts_P(PSTR("Getting Config Data.\r\n")); uint8_t ErrorCode; /* Get and process the configuration descriptor data */ if ((ErrorCode = ProcessConfigurationDescriptor()) != SuccessfulConfigRead) { if (ErrorCode == ControlError) puts_P(PSTR(ESC_FG_RED "Control Error (Get Configuration).\r\n")); else puts_P(PSTR(ESC_FG_RED "Invalid Device.\r\n")); printf_P(PSTR(" -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); return; } /* Set the device configuration to the first configuration (rarely do devices use multiple configurations) */ if ((ErrorCode = USB_Host_SetDeviceConfiguration(1)) != HOST_SENDCONTROL_Successful) { printf_P(PSTR(ESC_FG_RED "Control Error (Set Configuration).\r\n" " -- Error Code: %d\r\n" ESC_FG_WHITE), ErrorCode); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); return; } 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); }