Some minor Logitech serial mouse bug fixes and implemented the auto baud rate mode.

This commit is contained in:
OBattler
2023-05-02 21:53:42 +02:00
parent 18f96d2823
commit f16f7a2464

View File

@@ -37,7 +37,9 @@ enum {
PHASE_DIAGNOSTIC,
PHASE_FORMAT_AND_REVISION,
PHASE_COPYRIGHT_STRING,
PHASE_BUTTONS
PHASE_BUTTONS,
PHASE_ACK,
PHASE_BAUD_RATE
};
enum {
@@ -63,7 +65,8 @@ typedef struct {
int command_pos, command_phase,
report_pos, report_phase,
command_enabled, report_enabled;
double transmit_period, report_period;
double transmit_period, report_period,
auto_period;
pc_timer_t command_timer, report_timer;
serial_t *serial;
@@ -191,9 +194,9 @@ sermouse_data_msystems(mouse_t *dev, int x, int y, int b)
static uint8_t
sermouse_data_3bp(mouse_t *dev, int x, int y, int b)
{
dev->data[0] |= (b & 0x01) ? 0x00 : 0x04; /* left button */
dev->data[0] |= (b & 0x04) ? 0x00 : 0x02; /* middle button */
dev->data[0] |= (b & 0x02) ? 0x00 : 0x01; /* right button */
dev->data[0] |= (b & 0x01) ? 0x04 : 0x00; /* left button */
dev->data[0] |= (b & 0x04) ? 0x02 : 0x00; /* middle button */
dev->data[0] |= (b & 0x02) ? 0x01 : 0x00; /* right button */
dev->data[1] = x;
dev->data[2] = -y;
@@ -211,7 +214,7 @@ sermouse_data_mmseries(mouse_t *dev, int x, int y, int b)
dev->data[0] = 0x80;
if (x >= 0)
dev->data[0] |= 0x10;
if (y < 0)
if (y >= 0)
dev->data[0] |= 0x08;
dev->data[0] |= (b & 0x01) ? 0x04 : 0x00; /* left button */
dev->data[0] |= (b & 0x04) ? 0x02 : 0x00; /* middle button */
@@ -481,6 +484,15 @@ sermouse_command_timer(void *priv)
sermouse_report_timer((void *) dev);
}
break;
case PHASE_ACK:
serial_write_fifo(dev->serial, 0x06);
/* FALLTHROUGH */
case PHASE_BAUD_RATE:
sermouse_command_phase_idle(dev);
sermouse_timer_on(dev, dev->report_period, 1);
dev->report_phase = REPORT_PHASE_PREPARE;
sermouse_report_timer((void *) dev);
break;
case PHASE_DATA:
serial_write_fifo(dev->serial, dev->data[dev->command_pos]);
sermouse_command_pos_check(dev, dev->data_len);
@@ -587,6 +599,15 @@ ltsermouse_set_report_period(mouse_t *dev, int rps)
dev->report_phase = REPORT_PHASE_PREPARE;
}
static void
ltsermouse_switch_baud_rate(mouse_t *dev, int phase)
{
dev->command_pos = 0;
dev->command_phase = phase;
timer_stop(&dev->command_timer);
sermouse_timer_on(dev, 10000.0, 0);
}
static void
ltsermouse_write(struct serial_s *serial, void *priv, uint8_t data)
{
@@ -617,11 +638,18 @@ ltsermouse_write(struct serial_s *serial, void *priv, uint8_t data)
dev->transmit_period = sermouse_transmit_period(dev, 9600, -1);
break;
}
ltsermouse_switch_baud_rate(dev, PHASE_BAUD_RATE);
break;
}
else
switch (data) {
case 0x20:
sermouse_timer_on(dev, 0.0, 1);
dev->transmit_period = dev->auto_period;
ltsermouse_switch_baud_rate(dev, PHASE_ACK);
break;
case 0x2A:
sermouse_timer_on(dev, 0.0, 1);
dev->want_data = data;
dev->data_len = 1;
break;
@@ -699,6 +727,14 @@ ltsermouse_write(struct serial_s *serial, void *priv, uint8_t data)
}
}
static void
ltsermouse_transmit_period(serial_t *serial, void *priv, double transmit_period)
{
mouse_t *dev = (mouse_t *) priv;
dev->auto_period = transmit_period;
}
static void
sermouse_speed_changed(void *priv)
{
@@ -775,6 +811,7 @@ sermouse_init(const device_t *info)
}
dev->transmit_period = sermouse_transmit_period(dev, 1200, -1);
dev->auto_period = dev->transmit_period;
/* Default: Continuous reporting = no delay between reports. */
dev->report_phase = REPORT_PHASE_PREPARE;
@@ -787,7 +824,7 @@ sermouse_init(const device_t *info)
/* Attach a serial port to the mouse. */
if (info->local)
dev->serial = serial_attach(dev->port, sermouse_callback, ltsermouse_write, dev);
dev->serial = serial_attach_ex(dev->port, sermouse_callback, ltsermouse_write, ltsermouse_transmit_period, NULL, dev);
else
dev->serial = serial_attach(dev->port, sermouse_callback, NULL, dev);