1
0
mirror of https://github.com/mist-devel/mist-firmware.git synced 2026-05-06 00:04:39 +00:00

HID: more complete HAT switch handling

This commit is contained in:
Gyorgy Szombathelyi
2021-09-06 17:43:03 +02:00
parent 93a1220285
commit 3c892c72e7
3 changed files with 29 additions and 9 deletions

View File

@@ -814,26 +814,31 @@ static void usb_process_iface (usb_hid_iface_info_t *iface,
uint8_t hat = collect_bits(p, conf->joystick_mouse.hat.offset,
conf->joystick_mouse.hat.size, 0);
// we don't want more than 4 bits
uint8_t size = conf->joystick_mouse.hat.size;
while(size-- > 4)
hat >>= 1;
// iprintf("HAT = %d\n", hat);
// TODO: Deal with 3 bit (4 direction/no diagonal) hats
static const uint8_t hat2x[] = { 127,255,255,255,127, 0, 0, 0 };
static const uint8_t hat2y[] = { 0, 0,127,255,255,255,127, 0 };
if(hat&8) {
uint16_t units = conf->joystick_mouse.hat.logical.max - conf->joystick_mouse.hat.logical.min;
if(hat > conf->joystick_mouse.hat.logical.max || hat < conf->joystick_mouse.hat.logical.min || !units) {
// hat is idle - don't override analog
/*
if (a[0] > JOYSTICK_AXIS_TRIGGER_MIN) || a[0] < JOYSTICK_AXIS_TRIGGER_MAX) a[0] = JOYSTICK_AXIS_MID;
if (a[1] > JOYSTICK_AXIS_TRIGGER_MIN) || a[1] < JOYSTICK_AXIS_TRIGGER_MAX) a[1] = JOYSTICK_AXIS_MID;
*/
} else {
uint8_t x_val = hat2x[hat];
uint8_t y_val = hat2y[hat];
uint16_t degrees = (hat - conf->joystick_mouse.hat.logical.min) *
(conf->joystick_mouse.hat.physical.max - conf->joystick_mouse.hat.physical.min) / units;
//iprintf("hat logical min=%d max=%d, physical min=%d max=%d degrees=%d\n",
// conf->joystick_mouse.hat.logical.min,
// conf->joystick_mouse.hat.logical.max,
// conf->joystick_mouse.hat.physical.min,
// conf->joystick_mouse.hat.physical.max,
// degrees);
uint8_t idx = (degrees/45) & 0x07;
uint8_t x_val = hat2x[idx];
uint8_t y_val = hat2y[idx];
// cancel out with X analog axis if it pushes on the opposite direction
if(x_val < JOYSTICK_AXIS_TRIGGER_MIN) {
// hat pointing left, compensate if analog is pointing right

View File

@@ -87,6 +87,7 @@ bool parse_report_descriptor(uint8_t *rep, uint16_t rep_size, hid_report_t *conf
uint8_t report_size, report_count;
uint16_t bit_count = 0, usage_count = 0;
uint16_t logical_minimum=0, logical_maximum=0;
uint16_t physical_minimum=0, physical_maximum=0;
// mask used to check of all required components have been found, so
// that e.g. both axes and the button of a joystick are ready to be used
@@ -211,6 +212,10 @@ bool parse_report_descriptor(uint8_t *rep, uint16_t rep_size, hid_report_t *conf
if(conf->type == REPORT_TYPE_JOYSTICK) {
conf->joystick_mouse.hat.offset = cnt;
conf->joystick_mouse.hat.size = report_size;
conf->joystick_mouse.hat.logical.min = logical_minimum;
conf->joystick_mouse.hat.logical.max = logical_maximum;
conf->joystick_mouse.hat.physical.min = physical_minimum;
conf->joystick_mouse.hat.physical.max = physical_maximum;
}
}
@@ -328,10 +333,12 @@ bool parse_report_descriptor(uint8_t *rep, uint16_t rep_size, hid_report_t *conf
case 3:
hidp_extreme_debugf("PHYSICAL_MINIMUM(%d/%d)", value, (int16_t)value);
physical_minimum = value;
break;
case 4:
hidp_extreme_debugf("PHYSICAL_MAXIMUM(%d)", value);
physical_maximum = value;
break;
case 5:

View File

@@ -35,6 +35,14 @@ typedef struct {
struct {
uint16_t offset;
uint8_t size;
struct {
uint16_t min;
uint16_t max;
} logical;
struct {
uint16_t min;
uint16_t max;
} physical;
} hat; // 1 hat (joystick only)
uint8_t button_count;