https://forum.pjrc.com/threads/23681-Many-axis-joystick?p=41943&viewfull=1#post41943main
| #endif | #endif | ||||
| #ifdef JOYSTICK_INTERFACE | #ifdef JOYSTICK_INTERFACE | ||||
| #if JOYSTICK_SIZE == 12 | |||||
| static uint8_t joystick_report_desc[] = { | static uint8_t joystick_report_desc[] = { | ||||
| 0x05, 0x01, // Usage Page (Generic Desktop) | 0x05, 0x01, // Usage Page (Generic Desktop) | ||||
| 0x09, 0x04, // Usage (Joystick) | 0x09, 0x04, // Usage (Joystick) | ||||
| 0x81, 0x02, // Input (variable,absolute) | 0x81, 0x02, // Input (variable,absolute) | ||||
| 0xC0 // End Collection | 0xC0 // End Collection | ||||
| }; | }; | ||||
| #endif | |||||
| #elif JOYSTICK_SIZE == 64 | |||||
| // extreme joystick (to use this, edit JOYSTICK_SIZE to 64 in usb_desc.h) | |||||
| // 128 buttons 16 | |||||
| // 6 axes 12 | |||||
| // 17 sliders 34 | |||||
| // 4 pov 2 | |||||
| static uint8_t joystick_report_desc[] = { | |||||
| 0x05, 0x01, // Usage Page (Generic Desktop) | |||||
| 0x09, 0x04, // Usage (Joystick) | |||||
| 0xA1, 0x01, // Collection (Application) | |||||
| 0x15, 0x00, // Logical Minimum (0) | |||||
| 0x25, 0x01, // Logical Maximum (1) | |||||
| 0x75, 0x01, // Report Size (1) | |||||
| 0x95, 0x80, // Report Count (128) | |||||
| 0x05, 0x09, // Usage Page (Button) | |||||
| 0x19, 0x01, // Usage Minimum (Button #1) | |||||
| 0x29, 0x80, // Usage Maximum (Button #128) | |||||
| 0x81, 0x02, // Input (variable,absolute) | |||||
| 0x05, 0x01, // Usage Page (Generic Desktop) | |||||
| 0x09, 0x01, // Usage (Pointer) | |||||
| 0xA1, 0x00, // Collection () | |||||
| 0x15, 0x00, // Logical Minimum (0) | |||||
| 0x27, 0xFF, 0xFF, 0, 0, // Logical Maximum (65535) | |||||
| 0x75, 0x10, // Report Size (16) | |||||
| 0x95, 23, // Report Count (23) | |||||
| 0x09, 0x30, // Usage (X) | |||||
| 0x09, 0x31, // Usage (Y) | |||||
| 0x09, 0x32, // Usage (Z) | |||||
| 0x09, 0x33, // Usage (Rx) | |||||
| 0x09, 0x34, // Usage (Ry) | |||||
| 0x09, 0x35, // Usage (Rz) | |||||
| 0x09, 0x36, // Usage (Slider) | |||||
| 0x09, 0x36, // Usage (Slider) | |||||
| 0x09, 0x36, // Usage (Slider) | |||||
| 0x09, 0x36, // Usage (Slider) | |||||
| 0x09, 0x36, // Usage (Slider) | |||||
| 0x09, 0x36, // Usage (Slider) | |||||
| 0x09, 0x36, // Usage (Slider) | |||||
| 0x09, 0x36, // Usage (Slider) | |||||
| 0x09, 0x36, // Usage (Slider) | |||||
| 0x09, 0x36, // Usage (Slider) | |||||
| 0x09, 0x36, // Usage (Slider) | |||||
| 0x09, 0x36, // Usage (Slider) | |||||
| 0x09, 0x36, // Usage (Slider) | |||||
| 0x09, 0x36, // Usage (Slider) | |||||
| 0x09, 0x36, // Usage (Slider) | |||||
| 0x09, 0x36, // Usage (Slider) | |||||
| 0x09, 0x36, // Usage (Slider) | |||||
| 0x81, 0x02, // Input (variable,absolute) | |||||
| 0xC0, // End Collection | |||||
| 0x15, 0x00, // Logical Minimum (0) | |||||
| 0x25, 0x07, // Logical Maximum (7) | |||||
| 0x35, 0x00, // Physical Minimum (0) | |||||
| 0x46, 0x3B, 0x01, // Physical Maximum (315) | |||||
| 0x75, 0x04, // Report Size (4) | |||||
| 0x95, 0x04, // Report Count (4) | |||||
| 0x65, 0x14, // Unit (20) | |||||
| 0x05, 0x01, // Usage Page (Generic Desktop) | |||||
| 0x09, 0x39, // Usage (Hat switch) | |||||
| 0x09, 0x39, // Usage (Hat switch) | |||||
| 0x09, 0x39, // Usage (Hat switch) | |||||
| 0x09, 0x39, // Usage (Hat switch) | |||||
| 0x81, 0x42, // Input (variable,absolute,null_state) | |||||
| 0xC0 // End Collection | |||||
| }; | |||||
| #endif // JOYSTICK_SIZE | |||||
| #endif // JOYSTICK_INTERFACE | |||||
| #ifdef MULTITOUCH_INTERFACE | #ifdef MULTITOUCH_INTERFACE | ||||
| // https://forum.pjrc.com/threads/32331-USB-HID-Touchscreen-support-needed | // https://forum.pjrc.com/threads/32331-USB-HID-Touchscreen-support-needed |
| #define MOUSE_INTERVAL 1 | #define MOUSE_INTERVAL 1 | ||||
| #define JOYSTICK_INTERFACE 3 // Joystick | #define JOYSTICK_INTERFACE 3 // Joystick | ||||
| #define JOYSTICK_ENDPOINT 4 | #define JOYSTICK_ENDPOINT 4 | ||||
| #define JOYSTICK_SIZE 16 | |||||
| #define JOYSTICK_SIZE 12 // 12 = normal, 64 = extreme joystick | |||||
| #define JOYSTICK_INTERVAL 2 | #define JOYSTICK_INTERVAL 2 | ||||
| #define ENDPOINT1_CONFIG ENDPOINT_TRANSIMIT_ONLY | #define ENDPOINT1_CONFIG ENDPOINT_TRANSIMIT_ONLY | ||||
| #define ENDPOINT2_CONFIG ENDPOINT_RECEIVE_ONLY | #define ENDPOINT2_CONFIG ENDPOINT_RECEIVE_ONLY | ||||
| #define MOUSE_INTERVAL 2 | #define MOUSE_INTERVAL 2 | ||||
| #define JOYSTICK_INTERFACE 4 // Joystick | #define JOYSTICK_INTERFACE 4 // Joystick | ||||
| #define JOYSTICK_ENDPOINT 6 | #define JOYSTICK_ENDPOINT 6 | ||||
| #define JOYSTICK_SIZE 16 | |||||
| #define JOYSTICK_SIZE 12 // 12 = normal, 64 = extreme joystick | |||||
| #define JOYSTICK_INTERVAL 1 | #define JOYSTICK_INTERVAL 1 | ||||
| #define ENDPOINT1_CONFIG ENDPOINT_TRANSIMIT_ONLY | #define ENDPOINT1_CONFIG ENDPOINT_TRANSIMIT_ONLY | ||||
| #define ENDPOINT2_CONFIG ENDPOINT_TRANSIMIT_ONLY | #define ENDPOINT2_CONFIG ENDPOINT_TRANSIMIT_ONLY | ||||
| #define SEREMU_RX_INTERVAL 2 | #define SEREMU_RX_INTERVAL 2 | ||||
| #define JOYSTICK_INTERFACE 2 // Joystick | #define JOYSTICK_INTERFACE 2 // Joystick | ||||
| #define JOYSTICK_ENDPOINT 5 | #define JOYSTICK_ENDPOINT 5 | ||||
| #define JOYSTICK_SIZE 16 | |||||
| #define JOYSTICK_SIZE 12 // 12 = normal, 64 = extreme joystick | |||||
| #define JOYSTICK_INTERVAL 1 | #define JOYSTICK_INTERVAL 1 | ||||
| #define ENDPOINT1_CONFIG ENDPOINT_TRANSIMIT_ONLY | #define ENDPOINT1_CONFIG ENDPOINT_TRANSIMIT_ONLY | ||||
| #define ENDPOINT2_CONFIG ENDPOINT_RECEIVE_ONLY | #define ENDPOINT2_CONFIG ENDPOINT_RECEIVE_ONLY | ||||
| #define FLIGHTSIM_RX_INTERVAL 1 | #define FLIGHTSIM_RX_INTERVAL 1 | ||||
| #define JOYSTICK_INTERFACE 7 // Joystick | #define JOYSTICK_INTERFACE 7 // Joystick | ||||
| #define JOYSTICK_ENDPOINT 10 | #define JOYSTICK_ENDPOINT 10 | ||||
| #define JOYSTICK_SIZE 16 | |||||
| #define JOYSTICK_SIZE 12 // 12 = normal, 64 = extreme joystick | |||||
| #define JOYSTICK_INTERVAL 1 | #define JOYSTICK_INTERVAL 1 | ||||
| /* | /* | ||||
| #define MTP_INTERFACE 8 // MTP Disk | #define MTP_INTERFACE 8 // MTP Disk |
| #ifdef JOYSTICK_INTERFACE // defined by usb_dev.h -> usb_desc.h | #ifdef JOYSTICK_INTERFACE // defined by usb_dev.h -> usb_desc.h | ||||
| #if F_CPU >= 20000000 | #if F_CPU >= 20000000 | ||||
| uint32_t usb_joystick_data[3]; | |||||
| uint32_t usb_joystick_data[(JOYSTICK_SIZE+3)/4]; | |||||
| // Maximum number of transmit packets to queue so we don't starve other endpoints for memory | // Maximum number of transmit packets to queue so we don't starve other endpoints for memory | ||||
| yield(); | yield(); | ||||
| } | } | ||||
| transmit_previous_timeout = 0; | transmit_previous_timeout = 0; | ||||
| memcpy(tx_packet->buf, usb_joystick_data, 12); | |||||
| tx_packet->len = 12; | |||||
| memcpy(tx_packet->buf, usb_joystick_data, JOYSTICK_SIZE); | |||||
| tx_packet->len = JOYSTICK_SIZE; | |||||
| usb_tx(JOYSTICK_ENDPOINT, tx_packet); | usb_tx(JOYSTICK_ENDPOINT, tx_packet); | ||||
| //serial_print("ok\n"); | //serial_print("ok\n"); | ||||
| return 0; | return 0; |
| extern "C" { | extern "C" { | ||||
| #endif | #endif | ||||
| int usb_joystick_send(void); | int usb_joystick_send(void); | ||||
| extern uint32_t usb_joystick_data[3]; | |||||
| extern uint32_t usb_joystick_data[(JOYSTICK_SIZE+3)/4]; | |||||
| #ifdef __cplusplus | #ifdef __cplusplus | ||||
| } | } | ||||
| #endif | #endif | ||||
| public: | public: | ||||
| void begin(void) { } | void begin(void) { } | ||||
| void end(void) { } | void end(void) { } | ||||
| #if JOYSTICK_SIZE == 12 | |||||
| void button(uint8_t button, bool val) { | void button(uint8_t button, bool val) { | ||||
| if (--button >= 32) return; | if (--button >= 32) return; | ||||
| if (val) usb_joystick_data[0] |= (1 << button); | if (val) usb_joystick_data[0] |= (1 << button); | ||||
| usb_joystick_data[1] = (usb_joystick_data[1] & 0xFFFFFFF0) | val; | usb_joystick_data[1] = (usb_joystick_data[1] & 0xFFFFFFF0) | val; | ||||
| if (!manual_mode) usb_joystick_send(); | if (!manual_mode) usb_joystick_send(); | ||||
| } | } | ||||
| #elif JOYSTICK_SIZE == 64 | |||||
| void button(unsigned int num, bool val) { | |||||
| if (--num >= 128) return; | |||||
| uint32_t *p = usb_joystick_data + (num >> 5); | |||||
| num &= 0x1F; | |||||
| if (val) *p |= (1 << num); | |||||
| else *p &= ~(1 << num); | |||||
| if (!manual_mode) usb_joystick_send(); | |||||
| } | |||||
| void X(unsigned int position) { analog16(0, position); } | |||||
| void Y(unsigned int position) { analog16(1, position); } | |||||
| void Z(unsigned int position) { analog16(2, position); } | |||||
| void Xrotate(unsigned int position) { analog16(3, position); } | |||||
| void Yrotate(unsigned int position) { analog16(4, position); } | |||||
| void Zrotate(unsigned int position) { analog16(5, position); } | |||||
| void slider(unsigned int num, unsigned int position) { | |||||
| if (--num >= 17) return; | |||||
| analog16(num + 6, position); | |||||
| } | |||||
| inline void hat(unsigned int num, int angle) { | |||||
| uint32_t val=15; | |||||
| if (angle > 0 && angle < 23) val = 0; | |||||
| else if (angle < 68) val = 1; | |||||
| else if (angle < 113) val = 2; | |||||
| else if (angle < 158) val = 3; | |||||
| else if (angle < 203) val = 4; | |||||
| else if (angle < 245) val = 5; | |||||
| else if (angle < 293) val = 6; | |||||
| else if (angle < 338) val = 7; | |||||
| else if (angle < 360) val = 0; | |||||
| uint32_t *p = usb_joystick_data; | |||||
| switch(num) { | |||||
| case 1: | |||||
| p[15] = (p[15] & 0xFFF0FFFF) | (val << 16); break; | |||||
| case 2: | |||||
| p[15] = (p[15] & 0xFF0FFFFF) | (val << 20); break; | |||||
| case 3: | |||||
| p[15] = (p[15] & 0xF0FFFFFF) | (val << 24); break; | |||||
| case 4: | |||||
| p[15] = (p[15] & 0x0FFFFFFF) | (val << 28); break; | |||||
| default: | |||||
| return; | |||||
| } | |||||
| if (!manual_mode) usb_joystick_send(); | |||||
| } | |||||
| #endif | |||||
| void useManualSend(bool mode) { | void useManualSend(bool mode) { | ||||
| manual_mode = mode; | manual_mode = mode; | ||||
| } | } | ||||
| } | } | ||||
| private: | private: | ||||
| static uint8_t manual_mode; | static uint8_t manual_mode; | ||||
| #if JOYSTICK_SIZE == 64 | |||||
| void analog16(unsigned int num, unsigned int value) { | |||||
| if (value > 0xFFFF) value = 0xFFFF; | |||||
| uint16_t *p = (uint16_t *)(&usb_joystick_data[4]); | |||||
| p[num] = value; | |||||
| if (!manual_mode) usb_joystick_send(); | |||||
| } | |||||
| #endif | |||||
| }; | }; | ||||
| extern usb_joystick_class Joystick; | extern usb_joystick_class Joystick; | ||||