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; | |||