diff --git a/src/device/mouse_microtouch_touchscreen.c b/src/device/mouse_microtouch_touchscreen.c index b05e82054..2f5333121 100644 --- a/src/device/mouse_microtouch_touchscreen.c +++ b/src/device/mouse_microtouch_touchscreen.c @@ -19,9 +19,10 @@ /* TODO: - Properly implement GP/SP commands (formats are not documented at all, like anywhere; no dumps yet). + - Decouple serial packet generation from mouse poll rate. - Dynamic baud rate selection from software following this. - Add additional SMT2/3 formats as we currently only support Tablet, Hex and Dec. - - Add additional SMT2/3 modes as we currently hardcode Mode Stream + Mode Status. + - Add additional SMT2/3 modes as we currently hardcode Mode Stream. */ #include #include @@ -56,9 +57,10 @@ const char* mtouch_identity[] = { typedef struct mouse_microtouch_t { double baud_rate; int b; - char cmd[512]; + char cmd[256]; int cmd_pos; - int format; + uint8_t format; + bool mode_status; uint8_t id, cal_cntr, pen_mode; bool soh; bool in_reset; @@ -82,7 +84,7 @@ void microtouch_reset_complete(void *priv) { mouse_microtouch_t *mtouch = (mouse_microtouch_t *) priv; - + mtouch->in_reset = false; mt_fifo8_puts(&mtouch->resp, "0"); } @@ -91,7 +93,7 @@ void microtouch_calibrate_timer(void *priv) { mouse_microtouch_t *mtouch = (mouse_microtouch_t *) priv; - + if (!fifo8_num_used(&mtouch->resp)) { mtouch->cal_cntr--; mt_fifo8_puts(&mtouch->resp, "1"); @@ -101,87 +103,105 @@ microtouch_calibrate_timer(void *priv) void microtouch_process_commands(mouse_microtouch_t *mtouch) { - int i = 0; int fifo_used = fifo8_num_used(&mtouch->resp); mtouch->cmd[strcspn(mtouch->cmd, "\r")] = '\0'; mtouch->cmd_pos = 0; - for (i = 0; i < strlen(mtouch->cmd); i++) { - mtouch->cmd[i] = toupper(mtouch->cmd[i]); + if (mtouch->cmd[0] == 'A' && (mtouch->cmd[1] == 'D' || mtouch->cmd[1] == 'E')) { /* Autobaud Enable/Disable */ + mt_fifo8_puts(&mtouch->resp, "0"); } - if (mtouch->cmd[0] == 'Z') { /* Null */ + if (mtouch->cmd[0] == 'C' && (mtouch->cmd[1] == 'N' || mtouch->cmd[1] == 'X')) { /* Calibrate New/Extended */ + mt_fifo8_puts(&mtouch->resp, "0"); + mtouch->cal_cntr = 2; + } + if (mtouch->cmd[0] == 'F' && mtouch->cmd[1] == 'D') { /* Format Decimal */ + mouse_set_sample_rate(106); + mtouch->format = FORMAT_DEC; + mt_fifo8_puts(&mtouch->resp, "0"); + } + if (mtouch->cmd[0] == 'F' && mtouch->cmd[1] == 'N') { /* Filter Number */ mt_fifo8_puts(&mtouch->resp, "0"); } if (mtouch->cmd[0] == 'F' && mtouch->cmd[1] == 'O') { /* Finger Only */ mtouch->pen_mode = 1; mt_fifo8_puts(&mtouch->resp, "0"); } - if (mtouch->cmd[0] == 'U' && mtouch->cmd[1] == 'T') { /* Unit Type */ - mt_fifo8_puts(&mtouch->resp, "TP****00"); - } - if (mtouch->cmd[0] == 'O' && mtouch->cmd[1] == 'I') { /* Output Identity */ - mt_fifo8_puts(&mtouch->resp, mtouch_identity[mtouch->id]); - } - if (mtouch->cmd[0] == 'F' && mtouch->cmd[1] == 'D') { /* Format Decimal */ - mtouch->format = FORMAT_DEC; - mt_fifo8_puts(&mtouch->resp, "0"); - } if (mtouch->cmd[0] == 'F' && mtouch->cmd[1] == 'H') { /* Format Hexadecimal */ + mouse_set_sample_rate(106); mtouch->format = FORMAT_HEX; mt_fifo8_puts(&mtouch->resp, "0"); } + if (mtouch->cmd[0] == 'F' && mtouch->cmd[1] == 'Q') { /* ?? */ + mt_fifo8_puts(&mtouch->resp, "0"); + } if (mtouch->cmd[0] == 'F' && mtouch->cmd[1] == 'R') { /* Format Raw */ + mouse_set_sample_rate(106); mtouch->format = FORMAT_RAW; mtouch->cal_cntr = 0; mt_fifo8_puts(&mtouch->resp, "0"); } if (mtouch->cmd[0] == 'F' && mtouch->cmd[1] == 'T') { /* Format Tablet */ + mouse_set_sample_rate(192); mtouch->format = FORMAT_TABLET; mt_fifo8_puts(&mtouch->resp, "0"); } - if (mtouch->cmd[0] == 'M' && mtouch->cmd[1] == 'S') { /* Mode Stream */ - mt_fifo8_puts(&mtouch->resp, "0"); - } - if (mtouch->cmd[0] == 'R') { /* Reset */ - mtouch->in_reset = true; - mtouch->cal_cntr = 0; - mtouch->pen_mode = 3; - - if (mtouch->id < 2) - mtouch->format = FORMAT_DEC; - else - mtouch->format = FORMAT_TABLET; - - timer_on_auto(&mtouch->reset_timer, 500. * 1000.); - } - if (mtouch->cmd[0] == 'A' && (mtouch->cmd[1] == 'D' || mtouch->cmd[1] == 'E')) { /* Autobaud Enable/Disable */ - mt_fifo8_puts(&mtouch->resp, "0"); - } - if (mtouch->cmd[0] == 'N' && mtouch->cmd[1] == 'M') { /* ?? */ - mt_fifo8_puts(&mtouch->resp, "1"); - } - if (mtouch->cmd[0] == 'F' && mtouch->cmd[1] == 'Q') { /* ?? */ - mt_fifo8_puts(&mtouch->resp, "1"); - } if (mtouch->cmd[0] == 'G' && mtouch->cmd[1] == 'F') { /* ?? */ - mt_fifo8_puts(&mtouch->resp, "1"); - } - if (mtouch->cmd[0] == 'P') { - if (mtouch->cmd[1] == 'F') mtouch->pen_mode = 3; /* Pen or Finger */ - else if (mtouch->cmd[1] == 'O') mtouch->pen_mode = 2; /* Pen Only */ - mt_fifo8_puts(&mtouch->resp, "0");; - } - if (mtouch->cmd[0] == 'C' && (mtouch->cmd[1] == 'N' || mtouch->cmd[1] == 'X')) { /* Calibrate New/Extended */ mt_fifo8_puts(&mtouch->resp, "0"); - mtouch->cal_cntr = 2; } if (mtouch->cmd[0] == 'G' && mtouch->cmd[1] == 'P' && mtouch->cmd[2] == '1') { /* Get Parameter Block 1 */ mt_fifo8_puts(&mtouch->resp, "A"); fifo8_push_all(&mtouch->resp, (uint8_t *) "0000000000000000000000000\r", sizeof("0000000000000000000000000\r") - 1); mt_fifo8_puts(&mtouch->resp, "0"); } + if (mtouch->cmd[0] == 'M' && mtouch->cmd[1] == 'P') { /* ?? */ + mt_fifo8_puts(&mtouch->resp, "0"); + } + if (mtouch->cmd[0] == 'M' && mtouch->cmd[1] == 'S') { /* Mode Stream */ + mt_fifo8_puts(&mtouch->resp, "0"); + } + if (mtouch->cmd[0] == 'M' && mtouch->cmd[1] == 'T') { /* Mode Status */ + mtouch->mode_status = true; + mt_fifo8_puts(&mtouch->resp, "0"); + } + if (mtouch->cmd[0] == 'N' && mtouch->cmd[1] == 'M') { /* ?? */ + mt_fifo8_puts(&mtouch->resp, "0"); + } + if (mtouch->cmd[0] == 'O' && mtouch->cmd[1] == 'I') { /* Output Identity */ + mt_fifo8_puts(&mtouch->resp, mtouch_identity[mtouch->id]); + } + if (mtouch->cmd[0] == 'P') { + if (mtouch->cmd[1] == 'F') mtouch->pen_mode = 3; /* Pen or Finger */ + else if (mtouch->cmd[1] == 'O') mtouch->pen_mode = 2; /* Pen Only */ + mt_fifo8_puts(&mtouch->resp, "0"); /* Also 'PL' Parameter Lock */ + } + if (mtouch->cmd[0] == 'Q' && mtouch->cmd[1] == 'P') { /* ?? */ + mt_fifo8_puts(&mtouch->resp, "0"); + } + if (mtouch->cmd[0] == 'R') { /* Reset */ + mtouch->in_reset = true; + mtouch->cal_cntr = 0; + mtouch->pen_mode = 3; + mtouch->mode_status = false; + + if (mtouch->id < 2) { + mouse_set_sample_rate(106); + mtouch->format = FORMAT_DEC; + } + else { + mouse_set_sample_rate(192); + mtouch->format = FORMAT_TABLET; + } + + timer_on_auto(&mtouch->reset_timer, 500. * 1000.); + } if (mtouch->cmd[0] == 'S' && mtouch->cmd[1] == 'P' && mtouch->cmd[2] == '1') { /* Set Parameter Block 1 */ mt_fifo8_puts(&mtouch->resp, "A"); } + if (mtouch->cmd[0] == 'U' && mtouch->cmd[1] == 'T') { /* Unit Type */ + mt_fifo8_puts(&mtouch->resp, "TP****00"); + } + if (mtouch->cmd[0] == 'Z') { /* Null */ + mt_fifo8_puts(&mtouch->resp, "0"); + } if (fifo8_num_used(&mtouch->resp) != fifo_used || mtouch->in_reset) { pclog("Command handled: %s\n", mtouch->cmd); } else { @@ -210,7 +230,7 @@ mtouch_write_to_host(void *priv) } no_write_to_machine: - timer_on_auto(&dev->host_to_serial_timer, (1000000.0 / (double) 9600.0) * (double) (1 + 8 + 1)); + timer_on_auto(&dev->host_to_serial_timer, (1000000.0 / (double) dev->baud_rate) * (double) (1 + 8 + 1)); } void @@ -235,7 +255,7 @@ mtouch_poll(void *priv) { mouse_microtouch_t *dev = (mouse_microtouch_t *) priv; - if (fifo8_num_free(&dev->resp) <= 10 || dev->format == FORMAT_RAW) { + if (fifo8_num_free(&dev->resp) <= 256 - 10 || dev->format == FORMAT_RAW) { return 0; } @@ -243,7 +263,7 @@ mtouch_poll(void *priv) double abs_x; double abs_y; int b = mouse_get_buttons_ex(); - + mouse_get_abs_coords(&abs_x, &abs_y); if (abs_x >= 1.0) @@ -256,12 +276,13 @@ mtouch_poll(void *priv) abs_y = 0.0; if (enable_overscan) { int index = mouse_tablet_in_proximity - 1; - if (mouse_tablet_in_proximity == -1) + if (mouse_tablet_in_proximity == -1) { mouse_tablet_in_proximity = 0; - + } + abs_x *= monitors[index].mon_unscaled_size_x - 1; abs_y *= monitors[index].mon_efscrnsz_y - 1; - + if (abs_x <= (monitors[index].mon_overscan_x / 2.)) { abs_x = (monitors[index].mon_overscan_x / 2.); } @@ -291,16 +312,23 @@ mtouch_poll(void *priv) abs_y_int = 999 - (abs_y * 999); char buffer[10]; - if (b) { - if (!dev->b) { /* Touchdown */ - snprintf(buffer, sizeof(buffer), "\x19%03d,%03d\r", abs_x_int, abs_y_int); - } else { /* Touch Continuation */ - snprintf(buffer, sizeof(buffer), "\x1c%03d,%03d\r", abs_x_int, abs_y_int); + if (!dev->mode_status) { + if (b) { // Touch + snprintf(buffer, sizeof(buffer), "\x1%03d,%03d\r", abs_x_int, abs_y_int); + fifo8_push_all(&dev->resp, (uint8_t *)buffer, strlen(buffer)); } - } else if (dev->b) { /* Liftoff */ - snprintf(buffer, sizeof(buffer), "\x18%03d,%03d\r", abs_x_int, abs_y_int); + } else { + if (b) { + if (!dev->b) { /* Touchdown Status */ + snprintf(buffer, sizeof(buffer), "\x19%03d,%03d\r", abs_x_int, abs_y_int); + } else { /* Touch Continuation Status */ + snprintf(buffer, sizeof(buffer), "\x1c%03d,%03d\r", abs_x_int, abs_y_int); + } + } else if (dev->b) { /* Liftoff Status */ + snprintf(buffer, sizeof(buffer), "\x18%03d,%03d\r", abs_x_int, abs_y_int); + } + fifo8_push_all(&dev->resp, (uint8_t *)buffer, strlen(buffer)); } - fifo8_push_all(&dev->resp, (uint8_t *)buffer, strlen(buffer)); } else if (dev->format == FORMAT_HEX) { @@ -308,16 +336,23 @@ mtouch_poll(void *priv) abs_y_int = 1023 - (abs_y * 1023); char buffer[10]; - if (b) { - if (!dev->b) { /* Touchdown */ - snprintf(buffer, sizeof(buffer), "\x19%03X,%03X\r", abs_x_int, abs_y_int); - } else { /* Touch Continuation */ - snprintf(buffer, sizeof(buffer), "\x1c%03X,%03X\r", abs_x_int, abs_y_int); + if (!dev->mode_status) { + if (b) { // Touch + snprintf(buffer, sizeof(buffer), "\x1%03X,%03X\r", abs_x_int, abs_y_int); + fifo8_push_all(&dev->resp, (uint8_t *)buffer, strlen(buffer)); } - } else if (dev->b) { /* Liftoff */ - snprintf(buffer, sizeof(buffer), "\x18%03X,%03X\r", abs_x_int, abs_y_int); + } else { + if (b) { + if (!dev->b) { /* Touchdown Status */ + snprintf(buffer, sizeof(buffer), "\x19%03X,%03X\r", abs_x_int, abs_y_int); + } else { /* Touch Continuation Status */ + snprintf(buffer, sizeof(buffer), "\x1c%03X,%03X\r", abs_x_int, abs_y_int); + } + } else if (dev->b) { /* Liftoff Status */ + snprintf(buffer, sizeof(buffer), "\x18%03X,%03X\r", abs_x_int, abs_y_int); + } + fifo8_push_all(&dev->resp, (uint8_t *)buffer, strlen(buffer)); } - fifo8_push_all(&dev->resp, (uint8_t *)buffer, strlen(buffer)); } else if (dev->format == FORMAT_TABLET) { @@ -353,27 +388,36 @@ void * mtouch_init(const device_t *info) { mouse_microtouch_t *dev = calloc(1, sizeof(mouse_microtouch_t)); - + dev->serial = serial_attach(device_get_config_int("port"), NULL, mtouch_write, dev); dev->baud_rate = device_get_config_int("baudrate"); - fifo8_create(&dev->resp, 512); + serial_set_cts(dev->serial, 1); + serial_set_dsr(dev->serial, 1); + serial_set_dcd(dev->serial, 1); + + fifo8_create(&dev->resp, 256); timer_add(&dev->host_to_serial_timer, mtouch_write_to_host, dev, 0); timer_add(&dev->reset_timer, microtouch_reset_complete, dev, 0); timer_on_auto(&dev->host_to_serial_timer, (1000000. / dev->baud_rate) * 10); dev->id = device_get_config_int("identity"); - dev->pen_mode = 3; + dev->pen_mode = 3; + dev->mode_status = false; - if (dev->id < 2) /* legacy controllers */ + if (dev->id < 2) { /* legacy controllers */ dev->format = FORMAT_DEC; - else + mouse_set_sample_rate(106); + } + else { dev->format = FORMAT_TABLET; - + mouse_set_sample_rate(192); + } + mouse_input_mode = device_get_config_int("crosshair") + 1; mouse_set_buttons(2); mouse_set_poll_ex(mtouch_poll_global); - + mtouch_inst = dev; - + return dev; } @@ -386,7 +430,7 @@ mtouch_close(void *priv) /* Detach serial port from the mouse. */ if (dev && dev->serial && dev->serial->sd) memset(dev->serial->sd, 0, sizeof(serial_device_t)); - + free(dev); mtouch_inst = NULL; }