diff --git a/bia_microddr_hid_rpt_desc.hid b/bia_microddr_hid_rpt_desc.hid index 06dd6e0..8272a8e 100644 Binary files a/bia_microddr_hid_rpt_desc.hid and b/bia_microddr_hid_rpt_desc.hid differ diff --git a/firmware/src/dancepad.c b/firmware/src/dancepad.c index 8396e69..d0a6d8a 100644 --- a/firmware/src/dancepad.c +++ b/firmware/src/dancepad.c @@ -26,85 +26,78 @@ #include "usb.h" #include "usb_device_hid.h" #include "padhal.h" +#include "memory.h" -typedef union _INTPUT_CONTROLS_TYPEDEF +// command sent by the host to force us to enter bootloader mode +#define HOST_CMD_JUMP_TO_BOOTLOADER 0xBB + +#define STR(x) #x +#define XSTR(s) STR(s) + +#pragma pack(push, 1) +typedef struct _INPUT_REPORT_TYPEDEF { - struct - { - struct - { - uint8_t square:1; - uint8_t x:1; - uint8_t o:1; - uint8_t triangle:1; - uint8_t L1:1; - uint8_t R1:1; - uint8_t L2:1; - uint8_t R2:1;// - uint8_t select:1; - uint8_t start:1; - uint8_t left_stick:1; - uint8_t right_stick:1; - uint8_t home:1; - uint8_t :3; //filler - } buttons; - struct - { - uint8_t hat_switch:4; - uint8_t :4;//filler - } hat_switch; - struct - { - uint8_t X; - uint8_t Y; - uint8_t Z; - uint8_t Rz; - } analog_stick; - } members; - uint8_t val[7]; -} INPUT_CONTROLS; + uint8_t button_1:1; + uint8_t button_2:1; + uint8_t button_3:1; + uint8_t button_4:1; + uint8_t button_5:1; + uint8_t button_6:1; + uint8_t :2; // pad +} INPUT_REPORT; + +typedef struct _OUTPUT_REPORT_TYPEDEF +{ + uint8_t command; +} OUTPUT_REPORT; +#pragma pack(pop) // USB data must exist within the USB RAM memory space -uint8_t joystick_output[64] __at(0x500); -INPUT_CONTROLS joystick_input __at(0x600); +OUTPUT_REPORT JoystickOutReport __at(0x500); +INPUT_REPORT JoystickInReport __at(0x540); // handle to the last data transmission - allows us to check if it completed -USB_VOLATILE USB_HANDLE lastTransmission = 0; -USB_VOLATILE USB_HANDLE lastReceived = 0; +USB_VOLATILE USB_HANDLE USBInHandle; +USB_VOLATILE USB_HANDLE USBOutHandle; void DANCEPAD_Initialize() { - lastTransmission = 0; + USBInHandle = 0; //enable the HID endpoint USBEnableEndpoint(JOYSTICK_EP, USB_IN_ENABLED | USB_OUT_ENABLED | USB_HANDSHAKE_ENABLED | USB_DISALLOW_SETUP); - lastReceived = HIDRxPacket(JOYSTICK_EP,&(joystick_output[0]),64); + // open a handle to receive a HID output report + USBOutHandle = HIDRxPacket(JOYSTICK_EP, (uint8_t*)&JoystickOutReport, sizeof(JoystickOutReport)); } void DANCEPAD_Tasks() -{ - if (!HIDRxHandleBusy(lastReceived)) +{ + // process any commands received from the host (if any) + if (!HIDRxHandleBusy(USBOutHandle)) { - lastReceived = HIDRxPacket(JOYSTICK_EP,&(joystick_output[0]),64); + switch (JoystickOutReport.command) + { + case HOST_CMD_JUMP_TO_BOOTLOADER: + { + // jump to the bootloader entrypoint immediately + __asm("goto " XSTR(BOOTLOADER_ENTRYPOINT)); + break; + } + default: + break; + } + + // prepare to receive another HID output report + USBOutHandle = HIDRxPacket(JOYSTICK_EP, (uint8_t*)&JoystickOutReport, sizeof(JoystickOutReport)); } // do not start another transmission if the previous one isn't completed - if(HIDTxHandleBusy(lastTransmission)) + if(HIDTxHandleBusy(USBInHandle)) return; - /* - * populate & send a HID report to the host - */ - //Buttons - joystick_input.val[0] = PADHAL_GetButtons(); - joystick_input.val[1] = 0x00; - //Hat switch - joystick_input.val[2] = 0x08; - //Analog sticks - joystick_input.val[3] = 0x80; - joystick_input.val[4] = 0x80; - joystick_input.val[5] = 0x80; - joystick_input.val[6] = 0x80; - //Send the 8 byte packet over USB to the host. - lastTransmission = HIDTxPacket(JOYSTICK_EP, (uint8_t*)&joystick_input, sizeof(joystick_input)); + // buttons are already encoded into a uint8_t so just map that to the button fields in the report data struct + uint8_t pads = PADHAL_GetButtons(); + JoystickInReport = *(INPUT_REPORT*)&pads; + // send the HID input report to the host + USBInHandle = HIDTxPacket(JOYSTICK_EP, (uint8_t*)&JoystickInReport, sizeof(JoystickInReport)); } diff --git a/firmware/src/usb_config.h b/firmware/src/usb_config.h index 5f803d2..dbaf0d3 100644 --- a/firmware/src/usb_config.h +++ b/firmware/src/usb_config.h @@ -171,7 +171,7 @@ #define HID_INT_IN_EP_SIZE 64 #define HID_NUM_OF_DSC 1 //#define HID_RPT01_SIZE 74 -#define HID_RPT01_SIZE 54 +#define HID_RPT01_SIZE 47 /** DEFINITIONS ****************************************************/ diff --git a/firmware/src/usb_descriptors.c b/firmware/src/usb_descriptors.c index 0ab4413..8804101 100644 --- a/firmware/src/usb_descriptors.c +++ b/firmware/src/usb_descriptors.c @@ -182,7 +182,7 @@ const uint8_t configDescriptor1[]={ USB_DESCRIPTOR_INTERFACE, // INTERFACE descriptor type 0, // Interface Number 0, // Alternate Setting Number - 1, // Number of endpoints in this intf + 2, // Number of endpoints in this intf HID_INTF, // Class code 0, // Subclass code 0, // Protocol code @@ -246,69 +246,32 @@ const uint8_t *const USB_SD_Ptr[]= }; const struct{uint8_t report[HID_RPT01_SIZE];}hid_rpt01={{ - 0x05, 0x01, // USAGE_PAGE (Generic Desktop) + 0x05, 0x01, // USAGE_PAGE (Generic Desktop) 0x09, 0x05, // USAGE (Game Pad) 0xa1, 0x01, // COLLECTION (Application) + /* Input: 6 Buttons, 1 bit per button */ + 0x05, 0x09, // USAGE_PAGE (Button) + 0x19, 0x01, // USAGE_MINIMUM (Button 1) + 0x29, 0x06, // USAGE_MAXIMUM (Button 6) 0x15, 0x00, // LOGICAL_MINIMUM (0) 0x25, 0x01, // LOGICAL_MAXIMUM (1) 0x35, 0x00, // PHYSICAL_MINIMUM (0) 0x45, 0x01, // PHYSICAL_MAXIMUM (1) 0x75, 0x01, // REPORT_SIZE (1) 0x95, 0x06, // REPORT_COUNT (6) - 0x05, 0x09, // USAGE_PAGE (Button) - 0x19, 0x01, // USAGE_MINIMUM (Button 1) - 0x29, 0x06, // USAGE_MAXIMUM (Button 6) 0x81, 0x02, // INPUT (Data,Var,Abs) + /* Input: 2 bit pad to align data to byte boundary */ 0x95, 0x02, // REPORT_COUNT (2) 0x81, 0x01, // INPUT (Cnst,Ary,Abs) - 0x06, 0x00, 0xff, // USAGE_PAGE (Vendor Defined Page 1) + /* Output: Single 8-bit byte for control commands from PC */ + 0x06, 0x00, 0xff, // USAGE_PAGE (Generic Desktop) 0x09, 0x01, // USAGE (Vendor Usage 1) - 0xa1, 0x01, // COLLECTION (Application) - 0x19, 0x01, // USAGE_MINIMUM (Vendor Usage 1) - 0x29, 0x40, // USAGE_MAXIMUM (Vendor Usage 2) - 0x15, 0x00, // LOGICAL_MINIMUM (0) - 0x26, 0xff, 0x00, // LOGICAL_MAXIMUM (255) - 0x75, 0x08, // REPORT_SIZE (8) - 0x95, 0x40, // REPORT_COUNT (1) - 0x91, 0x00, // OUTPUT (Data,Ary,Abs) - 0xc0, // END_COLLECTION - 0xc0 // - /*0x05,0x01, //USAGE_PAGE (Generic Desktop) - 0x09,0x05, //USAGE (Game Pad) - 0xA1,0x01, //COLLECTION (Application) - 0x15,0x00, // LOGICAL_MINIMUM(0) - 0x25,0x01, // LOGICAL_MAXIMUM(1) - 0x35,0x00, // PHYSICAL_MINIMUM(0) - 0x45,0x01, // PHYSICAL_MAXIMUM(1) - 0x75,0x01, // REPORT_SIZE(1) - 0x95,0x0D, // REPORT_COUNT(13) - 0x05,0x09, // USAGE_PAGE(Button) - 0x19,0x01, // USAGE_MINIMUM(Button 1) - 0x29,0x0D, // USAGE_MAXIMUM(Button 13) - 0x81,0x02, // INPUT(Data,Var,Abs) - 0x95,0x03, // REPORT_COUNT(3) - 0x81,0x01, // INPUT(Cnst,Ary,Abs) - 0x05,0x01, // USAGE_PAGE(Generic Desktop) - 0x25,0x07, // LOGICAL_MAXIMUM(7) - 0x46,0x3B,0x01, // PHYSICAL_MAXIMUM(315) - 0x75,0x04, // REPORT_SIZE(4) - 0x95,0x01, // REPORT_COUNT(1) - 0x65,0x14, // UNIT(Eng Rot:Angular Pos) - 0x09,0x39, // USAGE(Hat Switch) - 0x81,0x42, // INPUT(Data,Var,Abs,Null) - 0x65,0x00, // UNIT(None) - 0x95,0x01, // REPORT_COUNT(1) - 0x81,0x01, // INPUT(Cnst,Ary,Abs) - 0x26,0xFF,0x00, // LOGICAL_MAXIMUM(255) - 0x46,0xFF,0x00, // PHYSICAL_MAXIMUM(255) - 0x09,0x30, // USAGE(X) - 0x09,0x31, // USAGE(Y) - 0x09,0x32, // USAGE(Z) - 0x09,0x35, // USAGE(Rz) - 0x75,0x08, // REPORT_SIZE(8) - 0x95,0x04, // REPORT_COUNT(4) - 0x81,0x02, // INPUT(Data,Var,Abs) - 0xC0*/ //END_COLLECTION + 0x15, 0x00, // LOGICAL_MINIMUM (0) + 0x26, 0xff, 0x00, // LOGICAL_MAXIMUM (255) + 0x75, 0x08, // REPORT_SIZE (8) + 0x95, 0x01, // REPORT_COUNT (1) + 0x91, 0x00, // OUTPUT (Data,Ary,Abs) + 0xc0 // END_COLLECTION } }; /** EOF usb_descriptors.c ***************************************************/