/** 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); USB_Descriptor_Device_t DeviceDescriptor; if (USB_Host_GetDeviceDescriptor(&DeviceDescriptor) != HOST_SENDCONTROL_Successful) { puts_P(PSTR("Error Retrieving Device Descriptor.\r\n")); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); return; } bool NeedModeSwitch; if (!(AOA_Host_ValidateAccessoryDevice(&AndroidDevice_AOA_Interface, &DeviceDescriptor, &NeedModeSwitch))) { puts_P(PSTR("Not an Android device.\r\n")); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); return; } if (NeedModeSwitch) { puts_P(PSTR("Not in Accessory mode, switching...\r\n")); AOA_Host_StartAccessoryMode(&AndroidDevice_AOA_Interface); return; } uint16_t ConfigDescriptorSize; uint8_t ConfigDescriptorData[512]; if (USB_Host_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData, sizeof(ConfigDescriptorData)) != HOST_GETCONFIG_Successful) { puts_P(PSTR("Error Retrieving Configuration Descriptor.\r\n")); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); return; } if (AOA_Host_ConfigurePipes(&AndroidDevice_AOA_Interface, ConfigDescriptorSize, ConfigDescriptorData) != AOA_ENUMERROR_NoError) { puts_P(PSTR("Attached Device Not a Valid Android Accessory Class Device.\r\n")); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); return; } if (USB_Host_SetDeviceConfiguration(1) != HOST_SENDCONTROL_Successful) { puts_P(PSTR("Error Setting Device Configuration.\r\n")); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); return; } puts_P(PSTR("Android 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) { LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING); uint16_t ConfigDescriptorSize; uint8_t ConfigDescriptorData[512]; if (USB_Host_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData, sizeof(ConfigDescriptorData)) != HOST_GETCONFIG_Successful) { LEDs_SetAllLEDs(LEDMASK_USB_ERROR); return; } if (RNDIS_Host_ConfigurePipes(&Ethernet_RNDIS_Interface_Host, ConfigDescriptorSize, ConfigDescriptorData) != RNDIS_ENUMERROR_NoError) { LEDs_SetAllLEDs(LEDMASK_USB_ERROR); return; } if (USB_Host_SetDeviceConfiguration(1) != HOST_SENDCONTROL_Successful) { LEDs_SetAllLEDs(LEDMASK_USB_ERROR); return; } if (RNDIS_Host_InitializeDevice(&Ethernet_RNDIS_Interface_Host) != HOST_SENDCONTROL_Successful) { LEDs_SetAllLEDs(LEDMASK_USB_ERROR); USB_Host_SetDeviceConfiguration(0); return; } uint32_t PacketFilter = (REMOTE_NDIS_PACKET_DIRECTED | REMOTE_NDIS_PACKET_BROADCAST); if (RNDIS_Host_SetRNDISProperty(&Ethernet_RNDIS_Interface_Host, OID_GEN_CURRENT_PACKET_FILTER, &PacketFilter, sizeof(PacketFilter)) != HOST_SENDCONTROL_Successful) { LEDs_SetAllLEDs(LEDMASK_USB_ERROR); USB_Host_SetDeviceConfiguration(0); return; } if (RNDIS_Host_QueryRNDISProperty(&Ethernet_RNDIS_Interface_Host, OID_802_3_CURRENT_ADDRESS, &MACAddress, sizeof(MACAddress)) != HOST_SENDCONTROL_Successful) { LEDs_SetAllLEDs(LEDMASK_USB_ERROR); USB_Host_SetDeviceConfiguration(0); return; } /* Initialize uIP stack */ uIPManagement_Init(); LEDs_SetAllLEDs(LEDMASK_USB_READY); }
/** Reads and processes an attached device's descriptors, to determine compatibility and pipe configurations. This * routine will read in the entire configuration descriptor, and configure the hosts pipes to correctly communicate * with compatible devices. * * This routine searches for a HID interface descriptor containing at least one Interrupt type IN endpoint and HID descriptor. * * \return An error code from the \ref MouseHostWithParser_GetConfigDescriptorDataCodes_t enum. */ uint8_t ProcessConfigurationDescriptor(void) { uint8_t ConfigDescriptorData[512]; void* CurrConfigLocation = ConfigDescriptorData; uint16_t CurrConfigBytesRem; /* Retrieve the entire configuration descriptor into the allocated buffer */ switch (USB_Host_GetDeviceConfigDescriptor(1, &CurrConfigBytesRem, ConfigDescriptorData, sizeof(ConfigDescriptorData))) { case HOST_GETCONFIG_Successful: break; case HOST_GETCONFIG_InvalidData: return InvalidConfigDataReturned; case HOST_GETCONFIG_BuffOverflow: return DescriptorTooLarge; default: return ControlError; } /* Get the mouse interface from the configuration descriptor */ if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation, DComp_NextMouseInterface) != DESCRIPTOR_SEARCH_COMP_Found) { /* Descriptor not found, error out */ return NoHIDInterfaceFound; } /* Get the mouse interface's HID descriptor */ if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation, DComp_NextHID) != DESCRIPTOR_SEARCH_COMP_Found) { /* Descriptor not found, error out */ return NoHIDDescriptorFound; } /* Save the HID report size for later use */ HIDReportSize = DESCRIPTOR_CAST(CurrConfigLocation, USB_Descriptor_HID_t).HIDReportLength; /* Get the mouse interface's data endpoint descriptor */ if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation, DComp_NextMouseInterfaceDataEndpoint) != DESCRIPTOR_SEARCH_COMP_Found) { /* Descriptor not found, error out */ return NoEndpointFound; } /* Retrieve the endpoint address from the endpoint descriptor */ USB_Descriptor_Endpoint_t* EndpointData = DESCRIPTOR_PCAST(CurrConfigLocation, USB_Descriptor_Endpoint_t); /* Configure the mouse data pipe */ Pipe_ConfigurePipe(MOUSE_DATAPIPE, EP_TYPE_INTERRUPT, PIPE_TOKEN_IN, EndpointData->EndpointAddress, EndpointData->EndpointSize, PIPE_BANK_SINGLE); /* Valid data found, return success */ return SuccessfulConfigRead; }
/** 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(const uint8_t corenum) { uint16_t ConfigDescriptorSize; uint8_t ConfigDescriptorData[512]; uint8_t *pCfgDesc; uint8_t i; uint8_t err_code; /* Read Configuration descriptor */ if (USB_Host_GetDeviceConfigDescriptor(corenum, 1, &ConfigDescriptorSize, ConfigDescriptorData, sizeof(ConfigDescriptorData)) != HOST_GETCONFIG_Successful) { DEBUGOUT("Error Retrieving Configuration Descriptor.\r\n"); return; } serialInfCount = 0; pCfgDesc = ConfigDescriptorData; /* Parse configuration descriptor to find CDC interfaces, note that the pointer to the configuration data is changed each time the function is called */ while((err_code = CDC_Host_FindConfigInterface(&Serial_Interface[serialInfCount], &ConfigDescriptorSize, (void **)&pCfgDesc)) == CDC_ENUMERROR_NoError) { serialInfCount++; if(serialInfCount >= MAX_SERIAL_INTERFACES) { DEBUGOUT("Reached Max Serial Interface of %d\r\n", MAX_SERIAL_INTERFACES); break; } } if(err_code == CDC_ENUMERROR_PipeConfigurationFailed) { DEBUGOUT("Error in Configuring Pipe.\r\n"); return; } /* No CDC interface was found */ if(serialInfCount == 0) { DEBUGOUT("Attached Device Not a Valid CDC Device.\r\n"); return; } if (USB_Host_SetDeviceConfiguration(Serial_Interface[0].Config.PortNumber, 1) != HOST_SENDCONTROL_Successful) { DEBUGOUT("Error Setting Device Configuration.\r\n"); return; } /* Set line coding for each interface */ for (i = 0; i < serialInfCount; i++) { Serial_Interface[i].State.LineEncoding.BaudRateBPS = 115200; Serial_Interface[i].State.LineEncoding.CharFormat = 0; Serial_Interface[i].State.LineEncoding.ParityType = 0; Serial_Interface[i].State.LineEncoding.DataBits = 8; CDC_Host_SetLineEncoding(&Serial_Interface[i]); } DEBUGOUT("Serial Device Enumerated.\r\n"); }
void EVENT_USB_Host_DeviceEnumerationComplete(void) { LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING); uint16_t ConfigDescriptorSize; uint8_t ConfigDescriptorData[512]; if (USB_Host_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData, sizeof(ConfigDescriptorData)) != HOST_GETCONFIG_Successful) { LEDs_SetAllLEDs(LEDMASK_USB_ERROR); return; } if (MS_Host_ConfigurePipes(&DiskHost_MS_Interface, ConfigDescriptorSize, ConfigDescriptorData) != MS_ENUMERROR_NoError) { LEDs_SetAllLEDs(LEDMASK_USB_ERROR); return; } if (USB_Host_SetDeviceConfiguration(1) != HOST_SENDCONTROL_Successful) { LEDs_SetAllLEDs(LEDMASK_USB_ERROR); return; } uint8_t MaxLUNIndex; if (MS_Host_GetMaxLUN(&DiskHost_MS_Interface, &MaxLUNIndex)) { LEDs_SetAllLEDs(LEDMASK_USB_ERROR); return; } if (MS_Host_ResetMSInterface(&DiskHost_MS_Interface)) { LEDs_SetAllLEDs(LEDMASK_USB_ERROR); return; } SCSI_Request_Sense_Response_t SenseData; if (MS_Host_RequestSense(&DiskHost_MS_Interface, 0, &SenseData) != 0) { LEDs_SetAllLEDs(LEDMASK_USB_ERROR); return; } pf_mount(&DiskFATState); 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) { uint16_t ConfigDescriptorSize; uint8_t ConfigDescriptorData[512]; if (USB_Host_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData, sizeof(ConfigDescriptorData)) != HOST_GETCONFIG_Successful) { return; } if (USB_Host_SetDeviceConfiguration(1) != HOST_SENDCONTROL_Successful) { return; } }
/** Event handler for the USB_DeviceEnumerationComplete event. This indicates that a device has been successfully * enumerated by the host and is now ready to be used by the application. */ void EVENT_USB_Host_DeviceEnumerationComplete(void) { LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING); uint16_t ConfigDescriptorSize; uint8_t ConfigDescriptorData[512]; if (USB_Host_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData, sizeof(ConfigDescriptorData)) != HOST_GETCONFIG_Successful) { puts_P(PSTR("Error Retrieving Configuration Descriptor.\r\n")); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); return; } if (CDC_Host_ConfigurePipes(&VirtualSerial_CDC_Interface, ConfigDescriptorSize, ConfigDescriptorData) != CDC_ENUMERROR_NoError) { puts_P(PSTR("Attached Device Not a Valid CDC Class Device.\r\n")); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); return; } if (USB_Host_SetDeviceConfiguration(1) != HOST_SENDCONTROL_Successful) { puts_P(PSTR("Error Setting Device Configuration.\r\n")); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); return; } VirtualSerial_CDC_Interface.State.LineEncoding.BaudRateBPS = 9600; VirtualSerial_CDC_Interface.State.LineEncoding.CharFormat = CDC_LINEENCODING_OneStopBit; VirtualSerial_CDC_Interface.State.LineEncoding.ParityType = CDC_PARITY_None; VirtualSerial_CDC_Interface.State.LineEncoding.DataBits = 8; if (CDC_Host_SetLineEncoding(&VirtualSerial_CDC_Interface)) { puts_P(PSTR("Error Setting Device Line Encoding.\r\n")); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); return; } puts_P(PSTR("CDC 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) { USB_Descriptor_Device_t DeviceDescriptor; uint16_t ConfigDescriptorSize; uint8_t ConfigDescriptorData[512]; printf(PSTR("\r\n* Configuring *")); if (USB_Host_GetDeviceDescriptor(&DeviceDescriptor) != HOST_SENDCONTROL_Successful) { printf(PSTR("\r\nERR: Dev Desc")); //RGB_SetColour(RGB_ALIAS_Error); //return; } if (USB_Host_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData, sizeof(ConfigDescriptorData)) != HOST_GETCONFIG_Successful) { printf(PSTR("\r\nERR: Config Desc")); // RGB_SetColour(RGB_ALIAS_Error); // return; } BluetoothAdapter_ConfigurePipes(&DeviceDescriptor, ConfigDescriptorSize, ConfigDescriptorData); if (USB_Host_SetDeviceConfiguration(1) != HOST_SENDCONTROL_Successful) { printf(PSTR("\r\nERR: Set Config")); // RGB_SetColour(RGB_ALIAS_Error); return; } if (!(BluetoothAdapter_PostConfiguration())) { printf(PSTR("\r\nERR: Post Config")); // RGB_SetColour(RGB_ALIAS_Error); return; } printf(PSTR("\r\n* System Ready *\n")); // RGB_SetColour(RGB_ALIAS_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(const uint8_t corenum) { LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING); uint16_t ConfigDescriptorSize; uint8_t ConfigDescriptorData[512]; if (USB_Host_GetDeviceConfigDescriptor(corenum, 1, &ConfigDescriptorSize, ConfigDescriptorData, sizeof(ConfigDescriptorData)) != HOST_GETCONFIG_Successful) { puts_P(PSTR("Error Retrieving Configuration Descriptor.\r\n")); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); return; } Keyboard_Host_HID_Interface.Config.PortNumber = corenum; if (HID_Host_ConfigurePipes(&Keyboard_Host_HID_Interface, ConfigDescriptorSize, ConfigDescriptorData) != HID_ENUMERROR_NoError) { puts_P(PSTR("Attached Device Not a Valid Keyboard.\r\n")); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); return; } if (USB_Host_SetDeviceConfiguration(corenum, 1) != HOST_SENDCONTROL_Successful) { puts_P(PSTR("Error Setting Device Configuration.\r\n")); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); return; } if (HID_Host_SetBootProtocol(&Keyboard_Host_HID_Interface) != 0) { puts_P(PSTR("Could not Set Boot Protocol Mode.\r\n")); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); USB_Host_SetDeviceConfiguration(corenum, 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); uint16_t ConfigDescriptorSize; uint8_t ConfigDescriptorData[512]; if (USB_Host_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData, sizeof(ConfigDescriptorData)) != HOST_GETCONFIG_Successful) { puts_P(PSTR("Error Retrieving Configuration Descriptor.\r\n")); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); return; } if (HID_Host_ConfigurePipes(&Joystick_HID_Interface, ConfigDescriptorSize, ConfigDescriptorData) != HID_ENUMERROR_NoError) { puts_P(PSTR("Attached Device Not a Valid Joystick.\r\n")); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); return; } if (USB_Host_SetDeviceConfiguration(1) != HOST_SENDCONTROL_Successful) { puts_P(PSTR("Error Setting Device Configuration.\r\n")); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); return; } if (HID_Host_SetReportProtocol(&Joystick_HID_Interface) != 0) { puts_P(PSTR("Error Setting Report Protocol Mode or Not a Valid Joystick.\r\n")); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); USB_Host_SetDeviceConfiguration(0); return; } puts_P(PSTR("Joystick 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); uint16_t ConfigDescriptorSize; uint8_t ConfigDescriptorData[512]; if (USB_Host_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData, sizeof(ConfigDescriptorData)) != HOST_GETCONFIG_Successful) { puts_P(PSTR("Error Retrieving Configuration Descriptor.\r\n")); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); return; } if (PRNT_Host_ConfigurePipes(&Printer_PRNT_Interface, ConfigDescriptorSize, ConfigDescriptorData) != PRNT_ENUMERROR_NoError) { puts_P(PSTR("Attached Device Not a Valid Printer Class Device.\r\n")); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); return; } if (USB_Host_SetDeviceConfiguration(1) != HOST_SENDCONTROL_Successful) { puts_P(PSTR("Error Setting Device Configuration.\r\n")); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); return; } if (PRNT_Host_SetBidirectionalMode(&Printer_PRNT_Interface) != HOST_SENDCONTROL_Successful) { puts_P(PSTR("Error Setting Bidirectional Mode.\r\n")); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); USB_Host_SetDeviceConfiguration(0); return; } puts_P(PSTR("Printer Device Enumerated.\r\n")); LEDs_SetAllLEDs(LEDMASK_USB_READY); }
/** Event handler for the USB_DeviceEnumerationComplete event. This indicates that a device has been successfully * enumerated by the host and is now ready to be used by the application. */ void EVENT_USB_Host_DeviceEnumerationComplete(void) { LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING); uint16_t ConfigDescriptorSize; uint8_t ConfigDescriptorData[512]; if (USB_Host_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData, sizeof(ConfigDescriptorData)) != HOST_GETCONFIG_Successful) { printf("Error Retrieving Configuration Descriptor.\r\n"); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); return; } if (HID_Host_ConfigurePipes(&Mouse_HID_Host_Interface, ConfigDescriptorSize, ConfigDescriptorData) != HID_ENUMERROR_NoError) { printf("Attached Device Not a Valid Mouse.\r\n"); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); return; } if (USB_Host_SetDeviceConfiguration(1) != HOST_SENDCONTROL_Successful) { printf("Error Setting Device Configuration.\r\n"); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); return; } if (HID_Host_SetBootProtocol(&Mouse_HID_Host_Interface) != HOST_SENDCONTROL_Successful) { printf("Could not Set Boot Protocol Mode.\r\n"); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); return; } printf("Mouse Enumerated.\r\n"); LEDs_SetAllLEDs(LEDMASK_USB_READY); }
/** Reads and processes an attached device's descriptors, to determine compatibility and pipe configurations. This * routine will read in the entire configuration descriptor, and configure the hosts pipes to correctly communicate * with compatible devices. * * This routine searches for a HID interface descriptor containing at least one Interrupt type IN endpoint and HID descriptor. * * \return An error code from the \ref MouseHostWithParser_GetConfigDescriptorDataCodes_t enum. */ uint8_t ProcessConfigurationDescriptor(void) { uint8_t ConfigDescriptorData[512]; void* CurrConfigLocation = ConfigDescriptorData; uint16_t CurrConfigBytesRem; USB_Descriptor_Interface_t* HIDInterface = NULL; USB_HID_Descriptor_HID_t* HIDDescriptor = NULL; USB_Descriptor_Endpoint_t* DataINEndpoint = NULL; /* Retrieve the entire configuration descriptor into the allocated buffer */ switch (USB_Host_GetDeviceConfigDescriptor(1, &CurrConfigBytesRem, ConfigDescriptorData, sizeof(ConfigDescriptorData))) { case HOST_GETCONFIG_Successful: break; case HOST_GETCONFIG_InvalidData: return InvalidConfigDataReturned; case HOST_GETCONFIG_BuffOverflow: return DescriptorTooLarge; default: return ControlError; } while (!(DataINEndpoint)) { /* See if we've found a likely compatible interface, and if there is an endpoint within that interface */ if (!(HIDInterface) || USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation, DComp_NextMouseInterfaceDataEndpoint) != DESCRIPTOR_SEARCH_COMP_Found) { /* Get the next HID interface from the configuration descriptor */ if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation, DComp_NextMouseInterface) != DESCRIPTOR_SEARCH_COMP_Found) { /* Descriptor not found, error out */ return NoCompatibleInterfaceFound; } /* Save the interface in case we need to refer back to it later */ HIDInterface = DESCRIPTOR_PCAST(CurrConfigLocation, USB_Descriptor_Interface_t); /* Get the HID descriptor from the configuration descriptor */ if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation, DComp_NextHID) != DESCRIPTOR_SEARCH_COMP_Found) { /* Descriptor not found, error out */ return NoCompatibleInterfaceFound; } /* Save the HID descriptor for later use */ HIDDescriptor = DESCRIPTOR_PCAST(CurrConfigLocation, USB_HID_Descriptor_HID_t); /* Skip the remainder of the loop as we have not found an endpoint yet */ continue; } /* Retrieve the endpoint address from the endpoint descriptor */ USB_Descriptor_Endpoint_t* EndpointData = DESCRIPTOR_PCAST(CurrConfigLocation, USB_Descriptor_Endpoint_t); /* If the endpoint is a IN type endpoint */ if (EndpointData->EndpointAddress & ENDPOINT_DESCRIPTOR_DIR_IN) DataINEndpoint = EndpointData; } /* Configure the HID data IN pipe */ Pipe_ConfigurePipe(MOUSE_DATA_IN_PIPE, EP_TYPE_INTERRUPT, PIPE_TOKEN_IN, DataINEndpoint->EndpointAddress, DataINEndpoint->EndpointSize, PIPE_BANK_SINGLE); Pipe_SetInterruptPeriod(DataINEndpoint->PollingIntervalMS); /* Get the HID report size from the HID report descriptor */ HIDReportSize = HIDDescriptor->HIDReportLength; /* Valid data found, return success */ return SuccessfulConfigRead; }
/** 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(const uint8_t corenum) { uint16_t ConfigDescriptorSize; uint8_t ConfigDescriptorData[512]; if (USB_Host_GetDeviceConfigDescriptor(corenum, 1, &ConfigDescriptorSize, ConfigDescriptorData, sizeof(ConfigDescriptorData)) != HOST_GETCONFIG_Successful) { DEBUGOUT("Error Retrieving Configuration Descriptor.\r\n"); return; } FlashDisk_MS_Interface.Config.PortNumber = corenum; if (MS_Host_ConfigurePipes(&FlashDisk_MS_Interface, ConfigDescriptorSize, ConfigDescriptorData) != MS_ENUMERROR_NoError) { DEBUGOUT("Attached Device Not a Valid Mass Storage Device.\r\n"); return; } if (USB_Host_SetDeviceConfiguration(FlashDisk_MS_Interface.Config.PortNumber, 1) != HOST_SENDCONTROL_Successful) { DEBUGOUT("Error Setting Device Configuration.\r\n"); return; } uint8_t MaxLUNIndex; if (MS_Host_GetMaxLUN(&FlashDisk_MS_Interface, &MaxLUNIndex)) { DEBUGOUT("Error retrieving max LUN index.\r\n"); USB_Host_SetDeviceConfiguration(FlashDisk_MS_Interface.Config.PortNumber, 0); return; } DEBUGOUT(("Total LUNs: %d - Using first LUN in device.\r\n"), (MaxLUNIndex + 1)); if (MS_Host_ResetMSInterface(&FlashDisk_MS_Interface)) { DEBUGOUT("Error resetting Mass Storage interface.\r\n"); USB_Host_SetDeviceConfiguration(FlashDisk_MS_Interface.Config.PortNumber, 0); return; } SCSI_Request_Sense_Response_t SenseData; if (MS_Host_RequestSense(&FlashDisk_MS_Interface, 0, &SenseData) != 0) { DEBUGOUT("Error retrieving device sense.\r\n"); USB_Host_SetDeviceConfiguration(FlashDisk_MS_Interface.Config.PortNumber, 0); return; } // if (MS_Host_PreventAllowMediumRemoval(&FlashDisk_MS_Interface, 0, true)) { // DEBUGOUT("Error setting Prevent Device Removal bit.\r\n"); // USB_Host_SetDeviceConfiguration(FlashDisk_MS_Interface.Config.PortNumber, 0); // return; // } SCSI_Inquiry_Response_t InquiryData; if (MS_Host_GetInquiryData(&FlashDisk_MS_Interface, 0, &InquiryData)) { DEBUGOUT("Error retrieving device Inquiry data.\r\n"); USB_Host_SetDeviceConfiguration(FlashDisk_MS_Interface.Config.PortNumber, 0); return; } /* DEBUGOUT("Vendor \"%.8s\", Product \"%.16s\"\r\n", InquiryData.VendorID, InquiryData.ProductID); */ DEBUGOUT("Mass Storage Device Enumerated.\r\n"); }
/** Reads and processes an attached device's descriptors, to determine compatibility and pipe configurations. This * routine will read in the entire configuration descriptor, and configure the hosts pipes to correctly communicate * with compatible devices. * * This routine searches for a MSD interface descriptor containing bulk IN and OUT data endpoints. * * \return An error code from the \ref MassStorageHost_GetConfigDescriptorDataCodes_t enum. */ uint8_t ProcessConfigurationDescriptor(void) { uint8_t ConfigDescriptorData[512]; void* CurrConfigLocation = ConfigDescriptorData; uint16_t CurrConfigBytesRem; uint8_t FoundEndpoints = 0; /* Retrieve the entire configuration descriptor into the allocated buffer */ switch (USB_Host_GetDeviceConfigDescriptor(1, &CurrConfigBytesRem, ConfigDescriptorData, sizeof(ConfigDescriptorData))) { case HOST_GETCONFIG_Successful: break; case HOST_GETCONFIG_InvalidData: return InvalidConfigDataReturned; case HOST_GETCONFIG_BuffOverflow: return DescriptorTooLarge; default: return ControlError; } /* Get the mass storage interface from the configuration descriptor */ if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation, DComp_NextMSInterface) != DESCRIPTOR_SEARCH_COMP_Found) { /* Descriptor not found, error out */ return NoInterfaceFound; } /* Get the IN and OUT data endpoints for the mass storage interface */ while (FoundEndpoints != ((1 << MASS_STORE_DATA_IN_PIPE) | (1 << MASS_STORE_DATA_OUT_PIPE))) { /* Fetch the next bulk endpoint from the current mass storage interface */ if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation, DComp_NextMSInterfaceBulkDataEndpoint) != DESCRIPTOR_SEARCH_COMP_Found) { /* Descriptor not found, error out */ return NoEndpointFound; } USB_Descriptor_Endpoint_t* EndpointData = DESCRIPTOR_PCAST(CurrConfigLocation, USB_Descriptor_Endpoint_t); /* Check if the endpoint is a bulk IN or bulk OUT endpoint, set appropriate globals */ if (EndpointData->EndpointAddress & ENDPOINT_DESCRIPTOR_DIR_IN) { /* Configure the data IN pipe */ Pipe_ConfigurePipe(MASS_STORE_DATA_IN_PIPE, EP_TYPE_BULK, PIPE_TOKEN_IN, EndpointData->EndpointAddress, EndpointData->EndpointSize, PIPE_BANK_DOUBLE); /* Set the flag indicating that the data IN pipe has been found */ FoundEndpoints |= (1 << MASS_STORE_DATA_IN_PIPE); } else { /* Configure the data OUT pipe */ Pipe_ConfigurePipe(MASS_STORE_DATA_OUT_PIPE, EP_TYPE_BULK, PIPE_TOKEN_OUT, EndpointData->EndpointAddress, EndpointData->EndpointSize, PIPE_BANK_DOUBLE); /* Set the flag indicating that the data OUT pipe has been found */ FoundEndpoints |= (1 << MASS_STORE_DATA_OUT_PIPE); } } /* Valid data found, return success */ return SuccessfulConfigRead; }
/** Event handler for the USB_DeviceEnumerationComplete event. This indicates that a device has been successfully * enumerated by the host and is now ready to be used by the application. */ void EVENT_USB_Host_DeviceEnumerationComplete(void) { LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING); uint16_t ConfigDescriptorSize; uint8_t ConfigDescriptorData[512]; if (USB_Host_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData, sizeof(ConfigDescriptorData)) != HOST_GETCONFIG_Successful) { puts_P(PSTR("Error Retrieving Configuration Descriptor.\r\n")); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); return; } if (RNDIS_Host_ConfigurePipes(&Ethernet_RNDIS_Interface, ConfigDescriptorSize, ConfigDescriptorData) != RNDIS_ENUMERROR_NoError) { puts_P(PSTR("Attached Device Not a Valid RNDIS Class Device.\r\n")); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); return; } if (USB_Host_SetDeviceConfiguration(1) != HOST_SENDCONTROL_Successful) { puts_P(PSTR("Error Setting Device Configuration.\r\n")); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); return; } if (RNDIS_Host_InitializeDevice(&Ethernet_RNDIS_Interface) != HOST_SENDCONTROL_Successful) { puts_P(PSTR("Error Initializing Device.\r\n")); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); USB_Host_SetDeviceConfiguration(0); return; } printf_P(PSTR("Device Max Transfer Size: %lu bytes.\r\n"), Ethernet_RNDIS_Interface.State.DeviceMaxPacketSize); uint32_t PacketFilter = (REMOTE_NDIS_PACKET_DIRECTED | REMOTE_NDIS_PACKET_BROADCAST | REMOTE_NDIS_PACKET_ALL_MULTICAST); if (RNDIS_Host_SetRNDISProperty(&Ethernet_RNDIS_Interface, OID_GEN_CURRENT_PACKET_FILTER, &PacketFilter, sizeof(PacketFilter)) != HOST_SENDCONTROL_Successful) { puts_P(PSTR("Error Setting Device Packet Filter.\r\n")); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); USB_Host_SetDeviceConfiguration(0); return; } uint32_t VendorID; if (RNDIS_Host_QueryRNDISProperty(&Ethernet_RNDIS_Interface, OID_GEN_VENDOR_ID, &VendorID, sizeof(VendorID)) != HOST_SENDCONTROL_Successful) { puts_P(PSTR("Error Getting Vendor ID.\r\n")); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); USB_Host_SetDeviceConfiguration(0); return; } printf_P(PSTR("Device Vendor ID: 0x%08lX\r\n"), VendorID); puts_P(PSTR("RNDIS Device Enumerated.\r\n")); LEDs_SetAllLEDs(LEDMASK_USB_READY); }
/** Reads and processes an attached device's descriptors, to determine compatibility and pipe configurations. This * routine will read in the entire configuration descriptor, and configure the hosts pipes to correctly communicate * with compatible devices. * * This routine searches for a Streaming Audio interface descriptor containing a valid Isochronous audio endpoint. * * \return An error code from the \ref AudioHost_GetConfigDescriptorDataCodes_t enum. */ uint8_t ProcessConfigurationDescriptor(void) { uint8_t ConfigDescriptorData[512]; void* CurrConfigLocation = ConfigDescriptorData; uint16_t CurrConfigBytesRem; USB_Descriptor_Interface_t* AudioControlInterface = NULL; USB_Descriptor_Interface_t* AudioStreamingInterface = NULL; USB_Descriptor_Endpoint_t* DataOUTEndpoint = NULL; /* Retrieve the entire configuration descriptor into the allocated buffer */ switch (USB_Host_GetDeviceConfigDescriptor(1, &CurrConfigBytesRem, ConfigDescriptorData, sizeof(ConfigDescriptorData))) { case HOST_GETCONFIG_Successful: break; case HOST_GETCONFIG_InvalidData: return InvalidConfigDataReturned; case HOST_GETCONFIG_BuffOverflow: return DescriptorTooLarge; default: return ControlError; } while (!(DataOUTEndpoint)) { /* See if we've found a likely compatible interface, and if there is an endpoint within that interface */ if (!(AudioControlInterface) || USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation, DComp_NextAudioInterfaceDataEndpoint) != DESCRIPTOR_SEARCH_COMP_Found) { /* Check if we haven't found an Audio Control interface yet, or if we have run out of related Audio Streaming interfaces */ if (!(AudioControlInterface) || USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation, DComp_NextAudioStreamInterface) != DESCRIPTOR_SEARCH_COMP_Found) { /* Find a new Audio Control interface if the current one doesn't contain a compatible streaming interface */ if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation, DComp_NextAudioControlInterface) != DESCRIPTOR_SEARCH_COMP_Found) { /* Descriptor not found, error out */ return NoCompatibleInterfaceFound; } /* Save the interface in case we need to refer back to it later */ AudioControlInterface = DESCRIPTOR_PCAST(CurrConfigLocation, USB_Descriptor_Interface_t); /* Find the next Audio Streaming interface within that Audio Control interface */ if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation, DComp_NextAudioStreamInterface) != DESCRIPTOR_SEARCH_COMP_Found) { /* Descriptor not found, error out */ return NoCompatibleInterfaceFound; } } /* Save the interface in case we need to refer back to it later */ AudioStreamingInterface = DESCRIPTOR_PCAST(CurrConfigLocation, USB_Descriptor_Interface_t); /* Skip the remainder of the loop as we have not found an endpoint yet */ continue; } /* Retrieve the endpoint address from the endpoint descriptor */ USB_Descriptor_Endpoint_t* EndpointData = DESCRIPTOR_PCAST(CurrConfigLocation, USB_Descriptor_Endpoint_t); /* Save the endpoint if it is an OUT type endpoint */ if ((EndpointData->EndpointAddress & ENDPOINT_DIR_MASK) == ENDPOINT_DIR_OUT) DataOUTEndpoint = EndpointData; } StreamingInterfaceIndex = AudioStreamingInterface->InterfaceNumber; StreamingInterfaceAltSetting = AudioStreamingInterface->AlternateSetting; StreamingEndpointAddress = DataOUTEndpoint->EndpointAddress; /* Configure the Audio data OUT pipe */ Pipe_ConfigurePipe(AUDIO_DATA_OUT_PIPE, EP_TYPE_ISOCHRONOUS, DataOUTEndpoint->EndpointAddress, DataOUTEndpoint->EndpointSize, 2); /* Valid data found, return success */ return SuccessfulConfigRead; }
/** Reads and processes an attached device's descriptors, to determine compatibility and pipe configurations. This * routine will read in the entire configuration descriptor, and configure the hosts pipes to correctly communicate * with compatible devices. * * This routine searches for a HID interface descriptor containing at least one Interrupt type IN endpoint. * * \return An error code from the \ref GenericHIDHost_GetConfigDescriptorDataCodes_t enum. */ uint8_t ProcessConfigurationDescriptor(void) { uint8_t ConfigDescriptorData[512]; void* CurrConfigLocation = ConfigDescriptorData; uint16_t CurrConfigBytesRem; USB_Descriptor_Interface_t* HIDInterface = NULL; USB_Descriptor_Endpoint_t* DataINEndpoint = NULL; USB_Descriptor_Endpoint_t* DataOUTEndpoint = NULL; /* Retrieve the entire configuration descriptor into the allocated buffer */ switch (USB_Host_GetDeviceConfigDescriptor(1, &CurrConfigBytesRem, ConfigDescriptorData, sizeof(ConfigDescriptorData))) { case HOST_GETCONFIG_Successful: break; case HOST_GETCONFIG_InvalidData: return InvalidConfigDataReturned; case HOST_GETCONFIG_BuffOverflow: return DescriptorTooLarge; default: return ControlError; } while (!(DataINEndpoint) || !(DataOUTEndpoint)) { /* See if we've found a likely compatible interface, and if there is an endpoint within that interface */ if (!(HIDInterface) || USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation, DComp_NextHIDInterfaceDataEndpoint) != DESCRIPTOR_SEARCH_COMP_Found) { /* Not all HID devices have an OUT endpoint - if we've reached the end of the HID descriptor * but only found the mandatory IN endpoint, it's safe to continue with the device enumeration */ if (DataINEndpoint) break; /* Get the next HID interface from the configuration descriptor */ if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation, DComp_NextHIDInterface) != DESCRIPTOR_SEARCH_COMP_Found) { /* Descriptor not found, error out */ return NoCompatibleInterfaceFound; } /* Save the interface in case we need to refer back to it later */ HIDInterface = DESCRIPTOR_PCAST(CurrConfigLocation, USB_Descriptor_Interface_t); /* Clear any found endpoints */ DataOUTEndpoint = NULL; /* Skip the remainder of the loop as we have not found an endpoint yet */ continue; } /* Retrieve the endpoint address from the endpoint descriptor */ USB_Descriptor_Endpoint_t* EndpointData = DESCRIPTOR_PCAST(CurrConfigLocation, USB_Descriptor_Endpoint_t); /* If the endpoint is a IN type endpoint */ if ((EndpointData->EndpointAddress & ENDPOINT_DIR_MASK) == ENDPOINT_DIR_IN) DataINEndpoint = EndpointData; else DataOUTEndpoint = EndpointData; } /* Configure the HID data IN pipe */ Pipe_ConfigurePipe(HID_DATA_IN_PIPE, EP_TYPE_INTERRUPT, PIPE_TOKEN_IN, DataINEndpoint->EndpointAddress, DataINEndpoint->EndpointSize, PIPE_BANK_SINGLE); Pipe_SetInterruptPeriod(DataINEndpoint->PollingIntervalMS); /* Check if the HID interface contained an optional OUT data endpoint */ if (DataOUTEndpoint) { /* Configure the HID data OUT pipe */ Pipe_ConfigurePipe(HID_DATA_OUT_PIPE, EP_TYPE_INTERRUPT, PIPE_TOKEN_OUT, DataOUTEndpoint->EndpointAddress, DataOUTEndpoint->EndpointSize, PIPE_BANK_SINGLE); } /* Valid data found, return success */ return SuccessfulConfigRead; }
/** USB host mode management task. This function manages the RNDIS Host class driver and uIP stack when the device is * initialized in USB host mode. */ void USBHostMode_USBTask(void) { if (USB_CurrentMode != USB_MODE_Host) return; switch (USB_HostState) { case HOST_STATE_Addressed: LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING); uint16_t ConfigDescriptorSize; uint8_t ConfigDescriptorData[512]; if (USB_Host_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData, sizeof(ConfigDescriptorData)) != HOST_GETCONFIG_Successful) { LEDs_SetAllLEDs(LEDMASK_USB_ERROR); USB_HostState = HOST_STATE_WaitForDeviceRemoval; break; } if (RNDIS_Host_ConfigurePipes(&Ethernet_RNDIS_Interface, ConfigDescriptorSize, ConfigDescriptorData) != RNDIS_ENUMERROR_NoError) { LEDs_SetAllLEDs(LEDMASK_USB_ERROR); USB_HostState = HOST_STATE_WaitForDeviceRemoval; break; } if (USB_Host_SetDeviceConfiguration(1) != HOST_SENDCONTROL_Successful) { LEDs_SetAllLEDs(LEDMASK_USB_ERROR); USB_HostState = HOST_STATE_WaitForDeviceRemoval; break; } if (RNDIS_Host_InitializeDevice(&Ethernet_RNDIS_Interface) != HOST_SENDCONTROL_Successful) { LEDs_SetAllLEDs(LEDMASK_USB_ERROR); USB_HostState = HOST_STATE_WaitForDeviceRemoval; break; } uint32_t PacketFilter = (REMOTE_NDIS_PACKET_DIRECTED | REMOTE_NDIS_PACKET_BROADCAST); if (RNDIS_Host_SetRNDISProperty(&Ethernet_RNDIS_Interface, OID_GEN_CURRENT_PACKET_FILTER, &PacketFilter, sizeof(PacketFilter)) != HOST_SENDCONTROL_Successful) { LEDs_SetAllLEDs(LEDMASK_USB_ERROR); USB_HostState = HOST_STATE_WaitForDeviceRemoval; break; } if (RNDIS_Host_QueryRNDISProperty(&Ethernet_RNDIS_Interface, OID_802_3_CURRENT_ADDRESS, &MACAddress, sizeof(MACAddress)) != HOST_SENDCONTROL_Successful) { LEDs_SetAllLEDs(LEDMASK_USB_ERROR); USB_HostState = HOST_STATE_WaitForDeviceRemoval; break; } /* Initialize uIP stack */ uIPManagement_Init(); LEDs_SetAllLEDs(LEDMASK_USB_READY); USB_HostState = HOST_STATE_Configured; break; case HOST_STATE_Configured: uIPManagement_ManageNetwork(); break; } RNDIS_Host_USBTask(&Ethernet_RNDIS_Interface); }
/** Main program entry point. This routine configures the hardware required by the application, then * enters a loop to run the application tasks in sequence. */ int main(void) { SetupHardware(); puts_P(PSTR(ESC_FG_CYAN "Still Image Host Demo running.\r\n" ESC_FG_WHITE)); LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY); for (;;) { switch (USB_HostState) { case HOST_STATE_Addressed: LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING); uint16_t ConfigDescriptorSize; uint8_t ConfigDescriptorData[512]; if (USB_Host_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData, sizeof(ConfigDescriptorData)) != HOST_GETCONFIG_Successful) { printf("Error Retrieving Configuration Descriptor.\r\n"); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); USB_HostState = HOST_STATE_WaitForDeviceRemoval; break; } if (SImage_Host_ConfigurePipes(&DigitalCamera_SI_Interface, ConfigDescriptorSize, ConfigDescriptorData) != SI_ENUMERROR_NoError) { printf("Attached Device Not a Valid CDC Class Device.\r\n"); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); USB_HostState = HOST_STATE_WaitForDeviceRemoval; break; } if (USB_Host_SetDeviceConfiguration(1) != HOST_SENDCONTROL_Successful) { printf("Error Setting Device Configuration.\r\n"); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); USB_HostState = HOST_STATE_WaitForDeviceRemoval; break; } printf("Still Image Device Enumerated.\r\n"); USB_HostState = HOST_STATE_Configured; break; case HOST_STATE_Configured: printf("Opening Session...\r\n"); if (SImage_Host_OpenSession(&DigitalCamera_SI_Interface) != PIPE_RWSTREAM_NoError) { printf("Could not open PIMA session.\r\n"); USB_HostState = HOST_STATE_WaitForDeviceRemoval; break; } printf("Turning off Device...\r\n"); SImage_Host_SendCommand(&DigitalCamera_SI_Interface, 0x1013, 0, NULL); if (SImage_Host_ReceiveResponse(&DigitalCamera_SI_Interface)) { printf("Could not turn off device.\r\n"); USB_HostState = HOST_STATE_WaitForDeviceRemoval; break; } printf("Device Off.\r\n"); printf("Closing Session...\r\n"); if (SImage_Host_CloseSession(&DigitalCamera_SI_Interface) != PIPE_RWSTREAM_NoError) { printf("Could not close PIMA session.\r\n"); USB_HostState = HOST_STATE_WaitForDeviceRemoval; break; } LEDs_SetAllLEDs(LEDMASK_USB_READY); USB_HostState = HOST_STATE_WaitForDeviceRemoval; break; } SImage_Host_USBTask(&DigitalCamera_SI_Interface); USB_USBTask(); } }
/** Main program entry point. This routine configures the hardware required by the application, then * enters a loop to run the application tasks in sequence. */ int main(void) { SetupHardware(); puts_P(PSTR(ESC_FG_CYAN "Audio Output Host Demo running.\r\n" ESC_FG_WHITE)); LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY); sei(); for (;;) { switch (USB_HostState) { case HOST_STATE_Addressed: LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING); uint16_t ConfigDescriptorSize; uint8_t ConfigDescriptorData[512]; if (USB_Host_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData, sizeof(ConfigDescriptorData)) != HOST_GETCONFIG_Successful) { puts_P(PSTR("Error Retrieving Configuration Descriptor.\r\n")); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); USB_HostState = HOST_STATE_WaitForDeviceRemoval; break; } if (Audio_Host_ConfigurePipes(&Speaker_Audio_Interface, ConfigDescriptorSize, ConfigDescriptorData) != AUDIO_ENUMERROR_NoError) { puts_P(PSTR("Attached Device Not a Valid Audio Output Device.\r\n")); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); USB_HostState = HOST_STATE_WaitForDeviceRemoval; break; } if (USB_Host_SetDeviceConfiguration(1) != HOST_SENDCONTROL_Successful) { puts_P(PSTR("Error Setting Device Configuration.\r\n")); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); USB_HostState = HOST_STATE_WaitForDeviceRemoval; break; } if (Audio_Host_StartStopStreaming(&Speaker_Audio_Interface, true) != HOST_SENDCONTROL_Successful) { puts_P(PSTR("Error Enabling Audio Stream.\r\n")); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); USB_HostState = HOST_STATE_WaitForDeviceRemoval; break; } USB_Audio_SampleFreq_t SampleRate = AUDIO_SAMPLE_FREQ(48000); if (Audio_Host_GetSetEndpointProperty(&Speaker_Audio_Interface, Speaker_Audio_Interface.Config.DataOUTPipeNumber, AUDIO_REQ_SetCurrent, AUDIO_EPCONTROL_SamplingFreq, sizeof(SampleRate), &SampleRate) != HOST_SENDCONTROL_Successful) { puts_P(PSTR("Error Setting Audio Sampling Frequency.\r\n")); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); USB_HostState = HOST_STATE_WaitForDeviceRemoval; break; } /* Sample reload timer initialization */ TIMSK0 = (1 << OCIE0A); OCR0A = ((F_CPU / 8 / 48000) - 1); TCCR0A = (1 << WGM01); // CTC mode TCCR0B = (1 << CS01); // Fcpu/8 speed puts_P(PSTR("Audio Device Enumerated.\r\n")); LEDs_SetAllLEDs(LEDMASK_USB_READY); USB_HostState = HOST_STATE_Configured; break; case HOST_STATE_Configured: /* Do nothing - audio stream is handled by the timer interrupt routine */ break; } Audio_Host_USBTask(&Speaker_Audio_Interface); USB_USBTask(); } }
/** Main program entry point. This routine configures the hardware required by the application, then * enters a loop to run the application tasks in sequence. */ int main(void) { SetupHardware(); puts_P(PSTR(ESC_FG_CYAN "Printer Host Demo running.\r\n" ESC_FG_WHITE)); LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY); sei(); for (;;) { switch (USB_HostState) { case HOST_STATE_Addressed: LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING); uint16_t ConfigDescriptorSize; uint8_t ConfigDescriptorData[512]; if (USB_Host_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData, sizeof(ConfigDescriptorData)) != HOST_GETCONFIG_Successful) { puts_P(PSTR("Error Retrieving Configuration Descriptor.\r\n")); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); USB_HostState = HOST_STATE_WaitForDeviceRemoval; break; } if (PRNT_Host_ConfigurePipes(&Printer_PRNT_Interface, ConfigDescriptorSize, ConfigDescriptorData) != PRNT_ENUMERROR_NoError) { puts_P(PSTR("Attached Device Not a Valid Printer Class Device.\r\n")); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); USB_HostState = HOST_STATE_WaitForDeviceRemoval; break; } if (USB_Host_SetDeviceConfiguration(1) != HOST_SENDCONTROL_Successful) { puts_P(PSTR("Error Setting Device Configuration.\r\n")); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); USB_HostState = HOST_STATE_WaitForDeviceRemoval; break; } if (PRNT_Host_SetBidirectionalMode(&Printer_PRNT_Interface) != HOST_SENDCONTROL_Successful) { puts_P(PSTR("Error Setting Bidirectional Mode.\r\n")); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); USB_HostState = HOST_STATE_WaitForDeviceRemoval; break; } puts_P(PSTR("Printer Device Enumerated.\r\n")); LEDs_SetAllLEDs(LEDMASK_USB_READY); USB_HostState = HOST_STATE_Configured; break; case HOST_STATE_Configured: LEDs_SetAllLEDs(LEDMASK_USB_BUSY); puts_P(PSTR("Retrieving Device ID...\r\n")); char DeviceIDString[300]; if (PRNT_Host_GetDeviceID(&Printer_PRNT_Interface, DeviceIDString, sizeof(DeviceIDString)) != HOST_SENDCONTROL_Successful) { puts_P(PSTR("Error Getting Device ID.\r\n")); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); USB_HostState = HOST_STATE_WaitForDeviceRemoval; break; } printf_P(PSTR("Device ID: %s.\r\n"), DeviceIDString); char TestPageData[] = "\033%-12345X\033E" "LUFA PCL Test Page" "\033E\033%-12345X"; uint16_t TestPageLength = strlen(TestPageData); printf_P(PSTR("Sending Test Page (%d bytes)...\r\n"), TestPageLength); if (PRNT_Host_SendData(&Printer_PRNT_Interface, &TestPageData, TestPageLength) != PIPE_RWSTREAM_NoError) { puts_P(PSTR("Error Sending Page Data.\r\n")); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); USB_HostState = HOST_STATE_WaitForDeviceRemoval; break; } puts_P(PSTR("Test Page Sent.\r\n")); LEDs_SetAllLEDs(LEDMASK_USB_READY); USB_HostState = HOST_STATE_WaitForDeviceRemoval; break; } PRNT_Host_USBTask(&Printer_PRNT_Interface); USB_USBTask(); } }
/** Main program entry point. This routine configures the hardware required by the application, then * enters a loop to run the application tasks in sequence. */ int main(void) { SetupHardware(); puts_P(PSTR(ESC_FG_CYAN "Keyboard Host Demo running.\r\n" ESC_FG_WHITE)); LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY); sei(); for (;;) { switch (USB_HostState) { case HOST_STATE_Addressed: LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING); uint16_t ConfigDescriptorSize; uint8_t ConfigDescriptorData[512]; if (USB_Host_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData, sizeof(ConfigDescriptorData)) != HOST_GETCONFIG_Successful) { puts_P(PSTR("Error Retrieving Configuration Descriptor.\r\n")); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); USB_HostState = HOST_STATE_WaitForDeviceRemoval; break; } if (HID_Host_ConfigurePipes(&Keyboard_HID_Interface, ConfigDescriptorSize, ConfigDescriptorData) != HID_ENUMERROR_NoError) { puts_P(PSTR("Attached Device Not a Valid Keyboard.\r\n")); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); USB_HostState = HOST_STATE_WaitForDeviceRemoval; break; } if (USB_Host_SetDeviceConfiguration(1) != HOST_SENDCONTROL_Successful) { puts_P(PSTR("Error Setting Device Configuration.\r\n")); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); USB_HostState = HOST_STATE_WaitForDeviceRemoval; break; } if (HID_Host_SetReportProtocol(&Keyboard_HID_Interface) != 0) { puts_P(PSTR("Error Setting Report Protocol Mode or Not a Valid Keyboard.\r\n")); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); USB_HostState = HOST_STATE_WaitForDeviceRemoval; break; } puts_P(PSTR("Keyboard Enumerated.\r\n")); LEDs_SetAllLEDs(LEDMASK_USB_READY); USB_HostState = HOST_STATE_Configured; break; case HOST_STATE_Configured: if (HID_Host_IsReportReceived(&Keyboard_HID_Interface)) { uint8_t KeyboardReport[Keyboard_HID_Interface.State.LargestReportSize]; HID_Host_ReceiveReport(&Keyboard_HID_Interface, &KeyboardReport); for (uint8_t ReportNumber = 0; ReportNumber < HIDReportInfo.TotalReportItems; ReportNumber++) { HID_ReportItem_t* ReportItem = &HIDReportInfo.ReportItems[ReportNumber]; /* Update the report item value if it is contained within the current report */ if (!(USB_GetHIDReportItemInfo(KeyboardReport, ReportItem))) continue; /* Determine what report item is being tested, process updated value as needed */ if ((ReportItem->Attributes.Usage.Page == USAGE_PAGE_KEYBOARD) && (ReportItem->Attributes.BitSize == 8) && (ReportItem->Attributes.Logical.Maximum > 1) && (ReportItem->ItemType == REPORT_ITEM_TYPE_In)) { /* Key code is an unsigned char in length, cast to the appropriate type */ uint8_t KeyCode = (uint8_t)ReportItem->Value; /* If scan-code is non-zero, a key is being pressed */ if (KeyCode) { /* Toggle status LED to indicate keypress */ LEDs_ToggleLEDs(LEDS_LED2); char PressedKey = 0; /* Convert scan-code to printable character if alphanumeric */ if ((KeyCode >= 0x04) && (KeyCode <= 0x1D)) PressedKey = (KeyCode - 0x04) + 'A'; else if ((KeyCode >= 0x1E) && (KeyCode <= 0x27)) PressedKey = (KeyCode - 0x1E) + '0'; else if (KeyCode == 0x2C) PressedKey = ' '; else if (KeyCode == 0x28) PressedKey = '\n'; /* Print the pressed key character out through the serial port if valid */ if (PressedKey) putchar(PressedKey); } /* Once a scan-code is found, stop scanning through the report items */ break; } } } break; } HID_Host_USBTask(&Keyboard_HID_Interface); USB_USBTask(); } }
/** Reads and processes an attached device's descriptors, to determine compatibility and pipe configurations. This * routine will read in the entire configuration descriptor, and configure the hosts pipes to correctly communicate * with compatible devices. * * This routine searches for a MSD interface descriptor containing bulk IN and OUT data endpoints. * * \return An error code from the \ref MassStorageHost_GetConfigDescriptorDataCodes_t enum. */ uint8_t ProcessConfigurationDescriptor(void) { uint8_t ConfigDescriptorData[512]; void* CurrConfigLocation = ConfigDescriptorData; uint16_t CurrConfigBytesRem; USB_Descriptor_Interface_t* MSInterface = NULL; USB_Descriptor_Endpoint_t* DataINEndpoint = NULL; USB_Descriptor_Endpoint_t* DataOUTEndpoint = NULL; /* Retrieve the entire configuration descriptor into the allocated buffer */ switch (USB_Host_GetDeviceConfigDescriptor(1, &CurrConfigBytesRem, ConfigDescriptorData, sizeof(ConfigDescriptorData))) { case HOST_GETCONFIG_Successful: break; case HOST_GETCONFIG_InvalidData: return InvalidConfigDataReturned; case HOST_GETCONFIG_BuffOverflow: return DescriptorTooLarge; default: return ControlError; } while (!(DataINEndpoint) || !(DataOUTEndpoint)) { /* See if we've found a likely compatible interface, and if there is an endpoint within that interface */ if (!(MSInterface) || USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation, DComp_NextMSInterfaceBulkDataEndpoint) != DESCRIPTOR_SEARCH_COMP_Found) { /* Get the next Mass Storage interface from the configuration descriptor */ if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation, DComp_NextMSInterface) != DESCRIPTOR_SEARCH_COMP_Found) { /* Descriptor not found, error out */ return NoCompatibleInterfaceFound; } /* Save the interface in case we need to refer back to it later */ MSInterface = DESCRIPTOR_PCAST(CurrConfigLocation, USB_Descriptor_Interface_t); /* Clear any found endpoints */ DataINEndpoint = NULL; DataOUTEndpoint = NULL; /* Skip the remainder of the loop as we have not found an endpoint yet */ continue; } /* Retrieve the endpoint address from the endpoint descriptor */ USB_Descriptor_Endpoint_t* EndpointData = DESCRIPTOR_PCAST(CurrConfigLocation, USB_Descriptor_Endpoint_t); /* If the endpoint is a IN type endpoint */ if (EndpointData->EndpointAddress & ENDPOINT_DESCRIPTOR_DIR_IN) DataINEndpoint = EndpointData; else DataOUTEndpoint = EndpointData; } /* Configure the Mass Storage data IN pipe */ Pipe_ConfigurePipe(MASS_STORE_DATA_IN_PIPE, EP_TYPE_BULK, PIPE_TOKEN_IN, DataINEndpoint->EndpointAddress, DataINEndpoint->EndpointSize, PIPE_BANK_SINGLE); /* Configure the Mass Storage data OUT pipe */ Pipe_ConfigurePipe(MASS_STORE_DATA_OUT_PIPE, EP_TYPE_BULK, PIPE_TOKEN_OUT, DataOUTEndpoint->EndpointAddress, DataOUTEndpoint->EndpointSize, PIPE_BANK_SINGLE); /* Valid data found, return success */ return SuccessfulConfigRead; }
/** Reads and processes an attached device's descriptors, to determine compatibility and pipe configurations. This * routine will read in the entire configuration descriptor, and configure the hosts pipes to correctly communicate * with compatible devices. * * This routine searches for a BT interface descriptor containing bulk IN and OUT data endpoints. * * \return An error code from the \ref BluetoothHost_GetConfigDescriptorDataCodes_t enum. */ uint8_t ProcessConfigurationDescriptor(void) { uint8_t ConfigDescriptorData[512]; void* CurrConfigLocation = ConfigDescriptorData; uint16_t CurrConfigBytesRem; USB_Descriptor_Endpoint_t* DataINEndpoint = NULL; USB_Descriptor_Endpoint_t* DataOUTEndpoint = NULL; USB_Descriptor_Endpoint_t* EventsEndpoint = NULL; /* Retrieve the entire configuration descriptor into the allocated buffer */ switch (USB_Host_GetDeviceConfigDescriptor(1, &CurrConfigBytesRem, ConfigDescriptorData, sizeof(ConfigDescriptorData))) { case HOST_GETCONFIG_Successful: break; case HOST_GETCONFIG_InvalidData: return InvalidConfigDataReturned; case HOST_GETCONFIG_BuffOverflow: return DescriptorTooLarge; default: return DevControlError; } /* The Bluetooth USB transport addendum mandates that the data (not streaming voice) endpoints be in the first interface descriptor (interface 0) */ USB_GetNextDescriptorOfType(&CurrConfigBytesRem, &CurrConfigLocation, DTYPE_Interface); /* Ensure that an interface was found, and the end of the descriptor was not reached */ if (!(CurrConfigBytesRem)) return NoCompatibleInterfaceFound; while (!(DataINEndpoint) || !(DataOUTEndpoint)) { /* Get the next Bluetooth interface's data endpoint descriptor */ if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation, DComp_NextInterfaceBluetoothDataEndpoint) != DESCRIPTOR_SEARCH_COMP_Found) { /* Data endpoints not found within the first bluetooth device interface, error out */ return NoCompatibleInterfaceFound; } /* Retrieve the endpoint address from the endpoint descriptor */ USB_Descriptor_Endpoint_t* EndpointData = DESCRIPTOR_PCAST(CurrConfigLocation, USB_Descriptor_Endpoint_t); /* If the endpoint is a IN type endpoint */ if ((EndpointData->EndpointAddress & ENDPOINT_DIR_MASK) == ENDPOINT_DIR_IN) { /* Check if the found endpoint is a interrupt or bulk type descriptor */ if ((EndpointData->Attributes & EP_TYPE_MASK) == EP_TYPE_INTERRUPT) EventsEndpoint = EndpointData; else DataINEndpoint = EndpointData; } else { DataOUTEndpoint = EndpointData; } } /* Configure the Bluetooth data IN pipe */ Pipe_ConfigurePipe(BLUETOOTH_DATA_IN_PIPE, EP_TYPE_BULK, PIPE_TOKEN_IN, DataINEndpoint->EndpointAddress, DataINEndpoint->EndpointSize, PIPE_BANK_SINGLE); /* Configure the Bluetooth data OUT pipe */ Pipe_ConfigurePipe(BLUETOOTH_DATA_OUT_PIPE, EP_TYPE_BULK, PIPE_TOKEN_OUT, DataOUTEndpoint->EndpointAddress, DataOUTEndpoint->EndpointSize, PIPE_BANK_SINGLE); /* Configure the Bluetooth events pipe */ Pipe_ConfigurePipe(BLUETOOTH_EVENTS_PIPE, EP_TYPE_INTERRUPT, PIPE_TOKEN_IN, EventsEndpoint->EndpointAddress, EventsEndpoint->EndpointSize, PIPE_BANK_SINGLE); Pipe_SetInterruptPeriod(EventsEndpoint->PollingIntervalMS); /* Valid data found, return success */ return SuccessfulConfigRead; }
/** Main program entry point. This routine configures the hardware required by the application, then * enters a loop to run the application tasks in sequence. */ int main(void) { SetupHardware(); puts_P(PSTR(ESC_FG_CYAN "RNDIS Host Demo running.\r\n" ESC_FG_WHITE)); LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY); sei(); for (;;) { switch (USB_HostState) { case HOST_STATE_Addressed: LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING); uint16_t ConfigDescriptorSize; uint8_t ConfigDescriptorData[512]; if (USB_Host_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData, sizeof(ConfigDescriptorData)) != HOST_GETCONFIG_Successful) { puts_P(PSTR("Error Retrieving Configuration Descriptor.\r\n")); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); USB_HostState = HOST_STATE_WaitForDeviceRemoval; break; } if (RNDIS_Host_ConfigurePipes(&Ethernet_RNDIS_Interface, ConfigDescriptorSize, ConfigDescriptorData) != RNDIS_ENUMERROR_NoError) { puts_P(PSTR("Attached Device Not a Valid RNDIS Class Device.\r\n")); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); USB_HostState = HOST_STATE_WaitForDeviceRemoval; break; } if (USB_Host_SetDeviceConfiguration(1) != HOST_SENDCONTROL_Successful) { puts_P(PSTR("Error Setting Device Configuration.\r\n")); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); USB_HostState = HOST_STATE_WaitForDeviceRemoval; break; } if (RNDIS_Host_InitializeDevice(&Ethernet_RNDIS_Interface) != HOST_SENDCONTROL_Successful) { puts_P(PSTR("Error Initializing Device.\r\n")); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); USB_HostState = HOST_STATE_WaitForDeviceRemoval; break; } printf_P(PSTR("Device Max Transfer Size: %lu bytes.\r\n"), Ethernet_RNDIS_Interface.State.DeviceMaxPacketSize); uint32_t PacketFilter = (REMOTE_NDIS_PACKET_DIRECTED | REMOTE_NDIS_PACKET_BROADCAST | REMOTE_NDIS_PACKET_ALL_MULTICAST); if (RNDIS_Host_SetRNDISProperty(&Ethernet_RNDIS_Interface, OID_GEN_CURRENT_PACKET_FILTER, &PacketFilter, sizeof(PacketFilter)) != HOST_SENDCONTROL_Successful) { puts_P(PSTR("Error Setting Device Packet Filter.\r\n")); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); USB_HostState = HOST_STATE_WaitForDeviceRemoval; break; } uint32_t VendorID; if (RNDIS_Host_QueryRNDISProperty(&Ethernet_RNDIS_Interface, OID_GEN_VENDOR_ID, &VendorID, sizeof(VendorID)) != HOST_SENDCONTROL_Successful) { puts_P(PSTR("Error Getting Vendor ID.\r\n")); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); USB_HostState = HOST_STATE_WaitForDeviceRemoval; break; } printf_P(PSTR("Device Vendor ID: 0x%08lX\r\n"), VendorID); puts_P(PSTR("RNDIS Device Enumerated.\r\n")); LEDs_SetAllLEDs(LEDMASK_USB_READY); USB_HostState = HOST_STATE_Configured; break; case HOST_STATE_Configured: PrintIncomingPackets(); break; } RNDIS_Host_USBTask(&Ethernet_RNDIS_Interface); USB_USBTask(); } }
/** Main program entry point. This routine configures the hardware required by the application, then * enters a loop to run the application tasks in sequence. */ int main(void) { SetupHardware(); puts_P(PSTR(ESC_FG_CYAN "Mouse Host Demo running.\r\n" ESC_FG_WHITE)); sei(); LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY); for (;;) { switch (USB_HostState) { case HOST_STATE_Addressed: LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING); uint16_t ConfigDescriptorSize; uint8_t ConfigDescriptorData[512]; if (USB_Host_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData, sizeof(ConfigDescriptorData)) != HOST_GETCONFIG_Successful) { puts_P(PSTR("Error Retrieving Configuration Descriptor.\r\n")); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); USB_HostState = HOST_STATE_WaitForDeviceRemoval; break; } if (HID_Host_ConfigurePipes(&Mouse_HID_Interface, ConfigDescriptorSize, ConfigDescriptorData) != HID_ENUMERROR_NoError) { puts_P(PSTR("Attached Device Not a Valid Mouse.\r\n")); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); USB_HostState = HOST_STATE_WaitForDeviceRemoval; break; } if (USB_Host_SetDeviceConfiguration(1) != HOST_SENDCONTROL_Successful) { puts_P(PSTR("Error Setting Device Configuration.\r\n")); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); USB_HostState = HOST_STATE_WaitForDeviceRemoval; break; } if (HID_Host_SetReportProtocol(&Mouse_HID_Interface) != 0) { puts_P(PSTR("Error Setting Report Protocol Mode or Not a Valid Mouse.\r\n")); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); USB_HostState = HOST_STATE_WaitForDeviceRemoval; break; } puts_P(PSTR("Mouse Enumerated.\r\n")); LEDs_SetAllLEDs(LEDMASK_USB_READY); USB_HostState = HOST_STATE_Configured; break; case HOST_STATE_Configured: if (HID_Host_IsReportReceived(&Mouse_HID_Interface)) { uint8_t MouseReport[Mouse_HID_Interface.State.LargestReportSize]; HID_Host_ReceiveReport(&Mouse_HID_Interface, &MouseReport); uint8_t LEDMask = LEDS_NO_LEDS; for (uint8_t ReportNumber = 0; ReportNumber < HIDReportInfo.TotalReportItems; ReportNumber++) { HID_ReportItem_t* ReportItem = &HIDReportInfo.ReportItems[ReportNumber]; /* Update the report item value if it is contained within the current report */ if (!(USB_GetHIDReportItemInfo(MouseReport, ReportItem))) continue; /* Determine what report item is being tested, process updated value as needed */ if ((ReportItem->Attributes.Usage.Page == USAGE_PAGE_BUTTON) && (ReportItem->ItemType == REPORT_ITEM_TYPE_In)) { if (ReportItem->Value) LEDMask = LEDS_ALL_LEDS; } else if ((ReportItem->Attributes.Usage.Page == USAGE_PAGE_GENERIC_DCTRL) && (ReportItem->Attributes.Usage.Usage == USAGE_SCROLL_WHEEL) && (ReportItem->ItemType == REPORT_ITEM_TYPE_In)) { int16_t WheelDelta = HID_ALIGN_DATA(ReportItem, int16_t); if (WheelDelta) LEDMask = (LEDS_LED1 | LEDS_LED2 | ((WheelDelta > 0) ? LEDS_LED3 : LEDS_LED4)); } else if ((ReportItem->Attributes.Usage.Page == USAGE_PAGE_GENERIC_DCTRL) && ((ReportItem->Attributes.Usage.Usage == USAGE_X) || (ReportItem->Attributes.Usage.Usage == USAGE_Y)) && (ReportItem->ItemType == REPORT_ITEM_TYPE_In)) { int16_t DeltaMovement = HID_ALIGN_DATA(ReportItem, int16_t); if (ReportItem->Attributes.Usage.Usage == USAGE_X) { if (DeltaMovement) LEDMask |= ((DeltaMovement > 0) ? LEDS_LED1 : LEDS_LED2); } else { if (DeltaMovement) LEDMask |= ((DeltaMovement > 0) ? LEDS_LED3 : LEDS_LED4); } } } LEDs_SetAllLEDs(LEDMask); } break; } HID_Host_USBTask(&Mouse_HID_Interface); USB_USBTask(); } }
/** Reads and processes an attached device's descriptors, to determine compatibility and pipe configurations. This * routine will read in the entire configuration descriptor, and configure the hosts pipes to correctly communicate * with compatible devices. * * This routine searches for a CDC interface descriptor containing bulk data IN and OUT endpoints, and an interrupt event endpoint. * * \return An error code from the \ref CDCHost_GetConfigDescriptorDataCodes_t enum. */ uint8_t ProcessConfigurationDescriptor(void) { uint8_t ConfigDescriptorData[512]; void* CurrConfigLocation = ConfigDescriptorData; uint16_t CurrConfigBytesRem; USB_Descriptor_Interface_t* CDCControlInterface = NULL; USB_Descriptor_Endpoint_t* DataINEndpoint = NULL; USB_Descriptor_Endpoint_t* DataOUTEndpoint = NULL; USB_Descriptor_Endpoint_t* NotificationEndpoint = NULL; /* Retrieve the entire configuration descriptor into the allocated buffer */ switch (USB_Host_GetDeviceConfigDescriptor(1, &CurrConfigBytesRem, ConfigDescriptorData, sizeof(ConfigDescriptorData))) { case HOST_GETCONFIG_Successful: break; case HOST_GETCONFIG_InvalidData: return InvalidConfigDataReturned; case HOST_GETCONFIG_BuffOverflow: return DescriptorTooLarge; default: return ControlError; } while (!(DataINEndpoint) || !(DataOUTEndpoint) || !(NotificationEndpoint)) { /* See if we've found a likely compatible interface, and if there is an endpoint within that interface */ if (!(CDCControlInterface) || USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation, DComp_NextCDCDataInterfaceEndpoint) != DESCRIPTOR_SEARCH_COMP_Found) { /* Check if we have already found the control interface's notification endpoint or not */ if (NotificationEndpoint) { /* Get the next CDC data interface from the configuration descriptor */ if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation, DComp_NextCDCDataInterface) != DESCRIPTOR_SEARCH_COMP_Found) { /* Descriptor not found, error out */ return NoCompatibleInterfaceFound; } /* Clear any found endpoints */ DataINEndpoint = NULL; DataOUTEndpoint = NULL; } else { /* Get the next CDC control interface from the configuration descriptor */ if (USB_GetNextDescriptorComp(&CurrConfigBytesRem, &CurrConfigLocation, DComp_NextCDCControlInterface) != DESCRIPTOR_SEARCH_COMP_Found) { /* Descriptor not found, error out */ return NoCompatibleInterfaceFound; } /* Save the interface in case we need to refer back to it later */ CDCControlInterface = DESCRIPTOR_PCAST(CurrConfigLocation, USB_Descriptor_Interface_t); /* Clear any found endpoints */ NotificationEndpoint = NULL; } /* Skip the remainder of the loop as we have not found an endpoint yet */ continue; } /* Retrieve the endpoint address from the endpoint descriptor */ USB_Descriptor_Endpoint_t* EndpointData = DESCRIPTOR_PCAST(CurrConfigLocation, USB_Descriptor_Endpoint_t); /* If the endpoint is a IN type endpoint */ if ((EndpointData->EndpointAddress & ENDPOINT_DIR_MASK) == ENDPOINT_DIR_IN) { /* Check if the found endpoint is a interrupt or bulk type descriptor */ if ((EndpointData->Attributes & EP_TYPE_MASK) == EP_TYPE_INTERRUPT) NotificationEndpoint = EndpointData; else DataINEndpoint = EndpointData; } else { DataOUTEndpoint = EndpointData; } } /* Configure the CDC data IN pipe */ Pipe_ConfigurePipe(CDC_DATA_IN_PIPE, EP_TYPE_BULK, DataINEndpoint->EndpointAddress, DataINEndpoint->EndpointSize, 1); /* Configure the CDC data OUT pipe */ Pipe_ConfigurePipe(CDC_DATA_OUT_PIPE, EP_TYPE_BULK, DataOUTEndpoint->EndpointAddress, DataOUTEndpoint->EndpointSize, 1); /* Configure the CDC notification pipe */ Pipe_ConfigurePipe(CDC_NOTIFICATION_PIPE, EP_TYPE_INTERRUPT, NotificationEndpoint->EndpointAddress, NotificationEndpoint->EndpointSize, 1); Pipe_SetInterruptPeriod(NotificationEndpoint->PollingIntervalMS); /* Valid data found, return success */ return SuccessfulConfigRead; }
/** Main program entry point. This routine configures the hardware required by the application, then * enters a loop to run the application tasks in sequence. */ int main(void) { SetupHardware(); puts_P(PSTR(ESC_FG_CYAN "Keyboard Host Demo running.\r\n" ESC_FG_WHITE)); LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY); sei(); for (;;) { switch (USB_HostState) { case HOST_STATE_Addressed: LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING); uint16_t ConfigDescriptorSize; uint8_t ConfigDescriptorData[512]; if (USB_Host_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData, sizeof(ConfigDescriptorData)) != HOST_GETCONFIG_Successful) { puts_P(PSTR("Error Retrieving Configuration Descriptor.\r\n")); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); USB_HostState = HOST_STATE_WaitForDeviceRemoval; break; } if (HID_Host_ConfigurePipes(&Keyboard_HID_Interface, ConfigDescriptorSize, ConfigDescriptorData) != HID_ENUMERROR_NoError) { puts_P(PSTR("Attached Device Not a Valid Keyboard.\r\n")); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); USB_HostState = HOST_STATE_WaitForDeviceRemoval; break; } if (USB_Host_SetDeviceConfiguration(1) != HOST_SENDCONTROL_Successful) { puts_P(PSTR("Error Setting Device Configuration.\r\n")); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); USB_HostState = HOST_STATE_WaitForDeviceRemoval; break; } if (HID_Host_SetBootProtocol(&Keyboard_HID_Interface) != 0) { puts_P(PSTR("Could not Set Boot Protocol Mode.\r\n")); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); USB_HostState = HOST_STATE_WaitForDeviceRemoval; break; } puts_P(PSTR("Keyboard Enumerated.\r\n")); LEDs_SetAllLEDs(LEDMASK_USB_READY); USB_HostState = HOST_STATE_Configured; break; case HOST_STATE_Configured: if (HID_Host_IsReportReceived(&Keyboard_HID_Interface)) { USB_KeyboardReport_Data_t KeyboardReport; HID_Host_ReceiveReport(&Keyboard_HID_Interface, &KeyboardReport); LEDs_ChangeLEDs(LEDS_LED1, (KeyboardReport.Modifier) ? LEDS_LED1 : 0); uint8_t KeyCode = KeyboardReport.KeyCode[0]; if (KeyCode) { char PressedKey = 0; LEDs_ToggleLEDs(LEDS_LED2); /* Retrieve pressed key character if alphanumeric */ if ((KeyCode >= HID_KEYBOARD_SC_A) && (KeyCode <= HID_KEYBOARD_SC_Z)) { PressedKey = (KeyCode - HID_KEYBOARD_SC_A) + 'A'; } else if ((KeyCode >= HID_KEYBOARD_SC_1_AND_EXCLAMATION) & (KeyCode <= HID_KEYBOARD_SC_0_AND_CLOSING_PARENTHESIS)) { PressedKey = (KeyCode - HID_KEYBOARD_SC_1_AND_EXCLAMATION) + '0'; } else if (KeyCode == HID_KEYBOARD_SC_SPACE) { PressedKey = ' '; } else if (KeyCode == HID_KEYBOARD_SC_ENTER) { PressedKey = '\n'; } if (PressedKey) putchar(PressedKey); } } break; } HID_Host_USBTask(&Keyboard_HID_Interface); USB_USBTask(); } }
/** Main program entry point. This routine configures the hardware required by the application, then * enters a loop to run the application tasks in sequence. */ int main(void) { SetupHardware(); puts_P(PSTR(ESC_FG_CYAN "HID Device Report Viewer Running.\r\n" ESC_FG_WHITE)); LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY); sei(); for (;;) { switch (USB_HostState) { case HOST_STATE_Addressed: LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING); uint16_t ConfigDescriptorSize; uint8_t ConfigDescriptorData[512]; if (USB_Host_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData, sizeof(ConfigDescriptorData)) != HOST_GETCONFIG_Successful) { puts_P(PSTR("Error Retrieving Configuration Descriptor.\r\n")); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); USB_HostState = HOST_STATE_WaitForDeviceRemoval; break; } if (HID_Host_ConfigurePipes(&Device_HID_Interface, ConfigDescriptorSize, ConfigDescriptorData) != HID_ENUMERROR_NoError) { puts_P(PSTR("Attached Device Not a Valid HID Device.\r\n")); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); USB_HostState = HOST_STATE_WaitForDeviceRemoval; break; } if (USB_Host_SetDeviceConfiguration(1) != HOST_SENDCONTROL_Successful) { puts_P(PSTR("Error Setting Device Configuration.\r\n")); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); USB_HostState = HOST_STATE_WaitForDeviceRemoval; break; } if (HID_Host_SetReportProtocol(&Device_HID_Interface) != 0) { puts_P(PSTR("Error Setting Report Protocol Mode.\r\n")); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); USB_HostState = HOST_STATE_WaitForDeviceRemoval; break; } puts_P(PSTR("HID Device Enumerated.\r\n")); LEDs_SetAllLEDs(LEDMASK_USB_READY); USB_HostState = HOST_STATE_Configured; break; case HOST_STATE_Configured: LEDs_SetAllLEDs(LEDMASK_USB_BUSY); OutputReportSizes(); OutputParsedReportItems(); LEDs_SetAllLEDs(LEDMASK_USB_READY); USB_HostState = HOST_STATE_WaitForDeviceRemoval; break; } HID_Host_USBTask(&Device_HID_Interface); USB_USBTask(); } }