https://forum.pjrc.com/threads/23681-Many-axis-joystick?p=41943&viewfull=1#post41943teensy4-core
| @@ -218,6 +218,7 @@ static uint8_t mouse_report_desc[] = { | |||
| #endif | |||
| #ifdef JOYSTICK_INTERFACE | |||
| #if JOYSTICK_SIZE == 12 | |||
| static uint8_t joystick_report_desc[] = { | |||
| 0x05, 0x01, // Usage Page (Generic Desktop) | |||
| 0x09, 0x04, // Usage (Joystick) | |||
| @@ -262,7 +263,73 @@ static uint8_t joystick_report_desc[] = { | |||
| 0x81, 0x02, // Input (variable,absolute) | |||
| 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 | |||
| // https://forum.pjrc.com/threads/32331-USB-HID-Touchscreen-support-needed | |||
| @@ -203,7 +203,7 @@ let me know? http://forum.pjrc.com/forums/4-Suggestions-amp-Bug-Reports | |||
| #define MOUSE_INTERVAL 1 | |||
| #define JOYSTICK_INTERFACE 3 // Joystick | |||
| #define JOYSTICK_ENDPOINT 4 | |||
| #define JOYSTICK_SIZE 16 | |||
| #define JOYSTICK_SIZE 12 // 12 = normal, 64 = extreme joystick | |||
| #define JOYSTICK_INTERVAL 2 | |||
| #define ENDPOINT1_CONFIG ENDPOINT_TRANSIMIT_ONLY | |||
| #define ENDPOINT2_CONFIG ENDPOINT_RECEIVE_ONLY | |||
| @@ -249,7 +249,7 @@ let me know? http://forum.pjrc.com/forums/4-Suggestions-amp-Bug-Reports | |||
| #define MOUSE_INTERVAL 2 | |||
| #define JOYSTICK_INTERFACE 4 // Joystick | |||
| #define JOYSTICK_ENDPOINT 6 | |||
| #define JOYSTICK_SIZE 16 | |||
| #define JOYSTICK_SIZE 12 // 12 = normal, 64 = extreme joystick | |||
| #define JOYSTICK_INTERVAL 1 | |||
| #define ENDPOINT1_CONFIG ENDPOINT_TRANSIMIT_ONLY | |||
| #define ENDPOINT2_CONFIG ENDPOINT_TRANSIMIT_ONLY | |||
| @@ -484,7 +484,7 @@ let me know? http://forum.pjrc.com/forums/4-Suggestions-amp-Bug-Reports | |||
| #define SEREMU_RX_INTERVAL 2 | |||
| #define JOYSTICK_INTERFACE 2 // Joystick | |||
| #define JOYSTICK_ENDPOINT 5 | |||
| #define JOYSTICK_SIZE 16 | |||
| #define JOYSTICK_SIZE 12 // 12 = normal, 64 = extreme joystick | |||
| #define JOYSTICK_INTERVAL 1 | |||
| #define ENDPOINT1_CONFIG ENDPOINT_TRANSIMIT_ONLY | |||
| #define ENDPOINT2_CONFIG ENDPOINT_RECEIVE_ONLY | |||
| @@ -648,7 +648,7 @@ let me know? http://forum.pjrc.com/forums/4-Suggestions-amp-Bug-Reports | |||
| #define FLIGHTSIM_RX_INTERVAL 1 | |||
| #define JOYSTICK_INTERFACE 7 // Joystick | |||
| #define JOYSTICK_ENDPOINT 10 | |||
| #define JOYSTICK_SIZE 16 | |||
| #define JOYSTICK_SIZE 12 // 12 = normal, 64 = extreme joystick | |||
| #define JOYSTICK_INTERVAL 1 | |||
| /* | |||
| #define MTP_INTERFACE 8 // MTP Disk | |||
| @@ -37,7 +37,8 @@ | |||
| #ifdef JOYSTICK_INTERFACE // defined by usb_dev.h -> usb_desc.h | |||
| #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 | |||
| @@ -98,8 +99,8 @@ int usb_joystick_send(void) | |||
| yield(); | |||
| } | |||
| 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); | |||
| //serial_print("ok\n"); | |||
| return 0; | |||
| @@ -42,7 +42,7 @@ | |||
| extern "C" { | |||
| #endif | |||
| int usb_joystick_send(void); | |||
| extern uint32_t usb_joystick_data[3]; | |||
| extern uint32_t usb_joystick_data[(JOYSTICK_SIZE+3)/4]; | |||
| #ifdef __cplusplus | |||
| } | |||
| #endif | |||
| @@ -54,6 +54,7 @@ class usb_joystick_class | |||
| public: | |||
| void begin(void) { } | |||
| void end(void) { } | |||
| #if JOYSTICK_SIZE == 12 | |||
| void button(uint8_t button, bool val) { | |||
| if (--button >= 32) return; | |||
| if (val) usb_joystick_data[0] |= (1 << button); | |||
| @@ -118,6 +119,52 @@ class usb_joystick_class | |||
| usb_joystick_data[1] = (usb_joystick_data[1] & 0xFFFFFFF0) | val; | |||
| 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) { | |||
| manual_mode = mode; | |||
| } | |||
| @@ -126,6 +173,14 @@ class usb_joystick_class | |||
| } | |||
| private: | |||
| 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; | |||