Important bug fix for original version of encorekbd.c Version 1.0 of encorekbd.c has a bug in USB_control_write(). After checking the datavalid bit of the EP_A0_COUNTER register, the data toggle bit needs to be checked, it should be set to 1. There was also a semicolon at the end of the if( EP_A0_MODE.IN_RECEIVED ) statement, which should be removed. Without this check in place, there is sometimes trouble receiving SetReport commands over endpoint 0, which is used to transmit LED codes from the host to the keyboard. Curiously, no problems were encountered with the faulty code unless the device was plugged into a high speed hub on a machine with a USB 2.0 port, running a 2.0 enabled OS. The new version of encorekbd.c will allocate one of the application board's LEDs as a CAPS LOCK LED, to help verify correct receipt of this OUT packet from the host. When multiple keyboards are plugged into a computer system, the host keeps all the LEDs in sync, so toggling the CAPS LOCK key on the host's main keyboard will toggle the LED. Corrected version of the function appears below: =================================================================== void USB_control_write(void) { USB_set_ep0_mode(USB_MODE_ACK_OUT_STATUS_IN); if(!premature_setup) { while( !EP_A0_MODE.OUT_RECEIVED ) { if( EP_A0_MODE.SETUP_RECEIVED ) { premature_setup = 1; return; } } if( !(EP_A0_COUNTER&DATAVALID) ) /* DATAVALID */ goto USB_control_write; if( !(EP_A0_COUNTER&DATATOGGLE) ) /* Check toggle bit */ goto USB_control_write; if( (EP_A0_COUNTER&COUNT_MASK)!=0x03) { USB_send_stall(); data_ok = 0; return; } USB_set_ep0_mode(USB_MODE_NAK_IN_OUT); if( premature_setup ) return; do { if( EP_A0_MODE.OUT_RECEIVED ) goto USB_control_write; if( EP_A0_MODE.IN_RECEIVED ) { data_ok = 1; return; } } while( !EP_A0_MODE.SETUP_RECEIVED ); premature_setup = 1; return; } }