static void usb_request_error(void) { usb_stall_endpoint(ep_index(0, DIR_TX)); usb_stall_endpoint(ep_index(0, DIR_RX)); }
static void usb_handle_standard_request(const usb_setup_t& setup) { switch(setup.bRequest) { case USB_SET_ADDRESS: { const uint8_t new_address = setup.wValue_L; UDADDR = new_address; usb_clear_in(); usb_wait_for_in_ready(); UDADDR |= _BV(ADDEN); } break; case USB_GET_DESCRIPTOR: { const uint8_t descriptor_index = setup.wValue_L; const uint8_t descriptor_type = setup.wValue_H; uint16_t length = (setup.wLength_H << 8) | setup.wLength_L; const uint8_t* descriptor = 0; uint8_t descriptor_length = 0; switch( descriptor_type ) { case USB_DESCRIPTOR_TYPE_DEVICE: if( descriptor_index == 0 ) { descriptor = device_descriptor; descriptor_length = sizeof(device_descriptor); } break; case USB_DESCRIPTOR_TYPE_CONFIGURATION: if( descriptor_index == 0 ) { descriptor = configuration_descriptor; descriptor_length = sizeof(configuration_descriptor); } break; case USB_DESCRIPTOR_TYPE_STRING: if( descriptor_index < string_descriptors_count ) { descriptor = string_descriptors[descriptor_index]; descriptor_length = descriptor[0]; } break; default: break; } if( descriptor ) { usb_write_descriptor(descriptor, descriptor_length, length); usb_clear_in(); usb_wait_for_status_out(); usb_clear_out(); } else { usb_stall_endpoint(); } } break; case USB_GET_CONFIGURATION: { UEDATX = usb_configuration; usb_clear_in(); usb_wait_for_status_out(); usb_clear_out(); } break; case USB_SET_CONFIGURATION: { const uint8_t new_configuration = setup.wValue_L; if( new_configuration > 1 ) { usb_stall_endpoint(); } else { if( new_configuration == 0 ) { // No configuration, go to ADDRESS state. UDADDR = 0; } usb_configuration = new_configuration; usb_clear_in(); usb_wait_for_in_ready(); } } break; //case USB_SET_DESCRIPTOR: //case USB_GET_STATUS: //case USB_CLEAR_FEATURE: //case USB_SET_FEATURE: //case USB_GET_INTERFACE: //case USB_SET_INTERFACE: //case USB_SYNCH_FRAME: default: usb_stall_endpoint(); break; } }