finished adding ability for host to put device into bootloader mode by sending a 1-byte command in a HID output report
This commit is contained in:
Binary file not shown.
@@ -26,85 +26,78 @@
|
|||||||
#include "usb.h"
|
#include "usb.h"
|
||||||
#include "usb_device_hid.h"
|
#include "usb_device_hid.h"
|
||||||
#include "padhal.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
|
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
|
||||||
{
|
{
|
||||||
struct
|
uint8_t command;
|
||||||
{
|
} OUTPUT_REPORT;
|
||||||
uint8_t square:1;
|
#pragma pack(pop)
|
||||||
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;
|
|
||||||
|
|
||||||
// USB data must exist within the USB RAM memory space
|
// USB data must exist within the USB RAM memory space
|
||||||
uint8_t joystick_output[64] __at(0x500);
|
OUTPUT_REPORT JoystickOutReport __at(0x500);
|
||||||
INPUT_CONTROLS joystick_input __at(0x600);
|
INPUT_REPORT JoystickInReport __at(0x540);
|
||||||
|
|
||||||
// handle to the last data transmission - allows us to check if it completed
|
// handle to the last data transmission - allows us to check if it completed
|
||||||
USB_VOLATILE USB_HANDLE lastTransmission = 0;
|
USB_VOLATILE USB_HANDLE USBInHandle;
|
||||||
USB_VOLATILE USB_HANDLE lastReceived = 0;
|
USB_VOLATILE USB_HANDLE USBOutHandle;
|
||||||
|
|
||||||
void DANCEPAD_Initialize()
|
void DANCEPAD_Initialize()
|
||||||
{
|
{
|
||||||
lastTransmission = 0;
|
USBInHandle = 0;
|
||||||
|
|
||||||
//enable the HID endpoint
|
//enable the HID endpoint
|
||||||
USBEnableEndpoint(JOYSTICK_EP, USB_IN_ENABLED | USB_OUT_ENABLED | USB_HANDSHAKE_ENABLED | USB_DISALLOW_SETUP);
|
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()
|
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
|
// do not start another transmission if the previous one isn't completed
|
||||||
if(HIDTxHandleBusy(lastTransmission))
|
if(HIDTxHandleBusy(USBInHandle))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/*
|
// buttons are already encoded into a uint8_t so just map that to the button fields in the report data struct
|
||||||
* populate & send a HID report to the host
|
uint8_t pads = PADHAL_GetButtons();
|
||||||
*/
|
JoystickInReport = *(INPUT_REPORT*)&pads;
|
||||||
//Buttons
|
// send the HID input report to the host
|
||||||
joystick_input.val[0] = PADHAL_GetButtons();
|
USBInHandle = HIDTxPacket(JOYSTICK_EP, (uint8_t*)&JoystickInReport, sizeof(JoystickInReport));
|
||||||
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));
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -171,7 +171,7 @@
|
|||||||
#define HID_INT_IN_EP_SIZE 64
|
#define HID_INT_IN_EP_SIZE 64
|
||||||
#define HID_NUM_OF_DSC 1
|
#define HID_NUM_OF_DSC 1
|
||||||
//#define HID_RPT01_SIZE 74
|
//#define HID_RPT01_SIZE 74
|
||||||
#define HID_RPT01_SIZE 54
|
#define HID_RPT01_SIZE 47
|
||||||
|
|
||||||
/** DEFINITIONS ****************************************************/
|
/** DEFINITIONS ****************************************************/
|
||||||
|
|
||||||
|
|||||||
@@ -182,7 +182,7 @@ const uint8_t configDescriptor1[]={
|
|||||||
USB_DESCRIPTOR_INTERFACE, // INTERFACE descriptor type
|
USB_DESCRIPTOR_INTERFACE, // INTERFACE descriptor type
|
||||||
0, // Interface Number
|
0, // Interface Number
|
||||||
0, // Alternate Setting Number
|
0, // Alternate Setting Number
|
||||||
1, // Number of endpoints in this intf
|
2, // Number of endpoints in this intf
|
||||||
HID_INTF, // Class code
|
HID_INTF, // Class code
|
||||||
0, // Subclass code
|
0, // Subclass code
|
||||||
0, // Protocol code
|
0, // Protocol code
|
||||||
@@ -249,66 +249,29 @@ 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)
|
0x09, 0x05, // USAGE (Game Pad)
|
||||||
0xa1, 0x01, // COLLECTION (Application)
|
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)
|
0x15, 0x00, // LOGICAL_MINIMUM (0)
|
||||||
0x25, 0x01, // LOGICAL_MAXIMUM (1)
|
0x25, 0x01, // LOGICAL_MAXIMUM (1)
|
||||||
0x35, 0x00, // PHYSICAL_MINIMUM (0)
|
0x35, 0x00, // PHYSICAL_MINIMUM (0)
|
||||||
0x45, 0x01, // PHYSICAL_MAXIMUM (1)
|
0x45, 0x01, // PHYSICAL_MAXIMUM (1)
|
||||||
0x75, 0x01, // REPORT_SIZE (1)
|
0x75, 0x01, // REPORT_SIZE (1)
|
||||||
0x95, 0x06, // REPORT_COUNT (6)
|
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)
|
0x81, 0x02, // INPUT (Data,Var,Abs)
|
||||||
|
/* Input: 2 bit pad to align data to byte boundary */
|
||||||
0x95, 0x02, // REPORT_COUNT (2)
|
0x95, 0x02, // REPORT_COUNT (2)
|
||||||
0x81, 0x01, // INPUT (Cnst,Ary,Abs)
|
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)
|
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)
|
0x15, 0x00, // LOGICAL_MINIMUM (0)
|
||||||
0x26, 0xff, 0x00, // LOGICAL_MAXIMUM (255)
|
0x26, 0xff, 0x00, // LOGICAL_MAXIMUM (255)
|
||||||
0x75, 0x08, // REPORT_SIZE (8)
|
0x75, 0x08, // REPORT_SIZE (8)
|
||||||
0x95, 0x40, // REPORT_COUNT (1)
|
0x95, 0x01, // REPORT_COUNT (1)
|
||||||
0x91, 0x00, // OUTPUT (Data,Ary,Abs)
|
0x91, 0x00, // OUTPUT (Data,Ary,Abs)
|
||||||
0xc0, // END_COLLECTION
|
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
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
/** EOF usb_descriptors.c ***************************************************/
|
/** EOF usb_descriptors.c ***************************************************/
|
||||||
|
|||||||
Reference in New Issue
Block a user