forked from Hay1tsme/segatools
IO device shows as connected, no auto read tho
This commit is contained in:
parent
5bfd5ae850
commit
0d3e93ce82
@ -28,9 +28,17 @@ static HRESULT touch1_handle_irp_locked(struct irp *irp);
|
|||||||
static HRESULT touch_req_dispatch(const struct touch_req *req);
|
static HRESULT touch_req_dispatch(const struct touch_req *req);
|
||||||
|
|
||||||
static HRESULT touch_frame_decode(struct touch_req *dest, struct iobuf *iobuf, int side);
|
static HRESULT touch_frame_decode(struct touch_req *dest, struct iobuf *iobuf, int side);
|
||||||
|
static HRESULT touch_frame_encode(struct iobuf *dest, const void *ptr, size_t nbytes);
|
||||||
|
static uint8_t calc_checksum(const void *ptr, size_t nbytes);
|
||||||
|
|
||||||
static HRESULT touch_handle_get_rev_date(const struct touch_req *req);
|
static HRESULT touch_handle_get_rev_date(const struct touch_req *req);
|
||||||
static HRESULT touch_handle_startup(const struct touch_req *req);
|
static HRESULT touch_handle_startup(const struct touch_req *req);
|
||||||
|
static HRESULT touch_handle_get_rev_date_detail(const struct touch_req *req);
|
||||||
|
static HRESULT touch_handle_mystery1(const struct touch_req *req);
|
||||||
|
static HRESULT touch_handle_mystery2(const struct touch_req *req);
|
||||||
|
static HRESULT touch_handle_start_auto_scan(const struct touch_req *req);
|
||||||
|
|
||||||
|
uint8_t input_frame_count = 0x7b;
|
||||||
|
|
||||||
static CRITICAL_SECTION touch0_lock;
|
static CRITICAL_SECTION touch0_lock;
|
||||||
static struct uart touch0_uart;
|
static struct uart touch0_uart;
|
||||||
@ -43,9 +51,9 @@ static uint8_t touch1_written_bytes[520];
|
|||||||
static uint8_t touch1_readable_bytes[520];
|
static uint8_t touch1_readable_bytes[520];
|
||||||
|
|
||||||
HRESULT touch_hook_init(const struct touch_config *cfg)
|
HRESULT touch_hook_init(const struct touch_config *cfg)
|
||||||
{
|
{
|
||||||
assert(cfg != NULL);
|
assert(cfg != NULL);
|
||||||
assert(mercury_dll.touch_init != NULL);
|
assert(mercury_dll.touch_init != NULL);
|
||||||
|
|
||||||
// not sure why this always returns false...
|
// not sure why this always returns false...
|
||||||
/*if (!cfg->enable) {
|
/*if (!cfg->enable) {
|
||||||
@ -82,7 +90,7 @@ static HRESULT touch_handle_irp(struct irp *irp)
|
|||||||
hr = touch0_handle_irp_locked(irp);
|
hr = touch0_handle_irp_locked(irp);
|
||||||
LeaveCriticalSection(&touch0_lock);
|
LeaveCriticalSection(&touch0_lock);
|
||||||
}
|
}
|
||||||
else if (uart_match_irp(&touch1_uart, irp)) {
|
else if (uart_match_irp(&touch1_uart, irp)) {
|
||||||
EnterCriticalSection(&touch1_lock);
|
EnterCriticalSection(&touch1_lock);
|
||||||
hr = touch1_handle_irp_locked(irp);
|
hr = touch1_handle_irp_locked(irp);
|
||||||
LeaveCriticalSection(&touch1_lock);
|
LeaveCriticalSection(&touch1_lock);
|
||||||
@ -117,7 +125,7 @@ static HRESULT touch0_handle_irp_locked(struct irp *irp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
#if 1
|
#if 0
|
||||||
dprintf("TX0 Buffer:\n");
|
dprintf("TX0 Buffer:\n");
|
||||||
dump_iobuf(&touch0_uart.written);
|
dump_iobuf(&touch0_uart.written);
|
||||||
#endif
|
#endif
|
||||||
@ -164,7 +172,7 @@ static HRESULT touch1_handle_irp_locked(struct irp *irp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
#if 1
|
#if 0
|
||||||
dprintf("TX1 Buffer:\n");
|
dprintf("TX1 Buffer:\n");
|
||||||
dump_iobuf(&touch1_uart.written);
|
dump_iobuf(&touch1_uart.written);
|
||||||
#endif
|
#endif
|
||||||
@ -196,37 +204,191 @@ static HRESULT touch_req_dispatch(const struct touch_req *req)
|
|||||||
return touch_handle_get_rev_date(req);
|
return touch_handle_get_rev_date(req);
|
||||||
case CMD_STARTUP:
|
case CMD_STARTUP:
|
||||||
return touch_handle_startup(req);
|
return touch_handle_startup(req);
|
||||||
|
case CMD_GET_REV_DATE_DETAIL:
|
||||||
|
return touch_handle_get_rev_date_detail(req);
|
||||||
|
case CMD_MYSTERY1:
|
||||||
|
return touch_handle_mystery1(req);
|
||||||
|
case CMD_MYSTERY2:
|
||||||
|
return touch_handle_mystery2(req);
|
||||||
|
case CMD_START_AUTO_SCAN:
|
||||||
|
return touch_handle_start_auto_scan(req);
|
||||||
|
case CMD_BEGIN_WRITE:
|
||||||
|
dprintf("Wacca touch: Begin write for side %d\n", req->side);
|
||||||
|
return S_OK;
|
||||||
|
case CMD_NEXT_WRITE:
|
||||||
|
dprintf("Wacca touch: continue write for side %d\n", req->side);
|
||||||
|
return S_OK;
|
||||||
default:
|
default:
|
||||||
dprintf("Wacca touch: Unhandled command %02x\n", req->cmd);
|
dprintf("Wacca touch: Unhandled command %02x\n", req->cmd);
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT touch_handle_get_rev_date(const struct touch_req *req)
|
static HRESULT touch_handle_get_rev_date(const struct touch_req *req)
|
||||||
{
|
{
|
||||||
|
struct touch_resp_get_rev_date resp;
|
||||||
|
HRESULT hr;
|
||||||
|
uint8_t rev[6] = { 0x31, 0x39, 0x30, 0x35, 0x32, 0x33 };
|
||||||
|
|
||||||
dprintf("Wacca Touch%d: Get board rev date\n", req->side);
|
dprintf("Wacca Touch%d: Get board rev date\n", req->side);
|
||||||
|
|
||||||
|
resp.cmd = 0xa0;
|
||||||
|
memcpy(resp.data, rev, sizeof(rev));
|
||||||
|
//resp.data = rev;
|
||||||
|
|
||||||
if (req->side == 0) {
|
if (req->side == 0) {
|
||||||
// TODO: a0 31 39 30 35 32 33 2c
|
hr = touch_frame_encode(&touch0_uart.readable, &resp, sizeof(resp));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// TODO: see above
|
hr = touch_frame_encode(&touch1_uart.readable, &resp, sizeof(resp));
|
||||||
}
|
}
|
||||||
return S_OK;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* TODO: Very ugly please make better before upstreaming */
|
||||||
static HRESULT touch_handle_startup(const struct touch_req *req)
|
static HRESULT touch_handle_startup(const struct touch_req *req)
|
||||||
{
|
{
|
||||||
|
struct touch_resp_startup resp;
|
||||||
|
HRESULT hr;
|
||||||
|
uint8_t *rev;
|
||||||
|
|
||||||
dprintf("Wacca Touch%d: Startup\n", req->side);
|
dprintf("Wacca Touch%d: Startup\n", req->side);
|
||||||
if (req->side == 0) {
|
|
||||||
// TODO: 20 20 20 20 30 20 20 20 20 30 20 20 20 20 31 20 20 20 20 32 20 20 20 20 33 20 20 20 20 34 20 20 20 20 35 20 20 20 31 35 20 20 20 31 35 20 20 20 31 35 20 20 20 31 35 20 20 20 31 35 20 20 20 31 35 20 20 20 31 31 20 20 20 31 31 20 20 20 31 31 0d
|
switch (req->data[2]) {
|
||||||
|
case 0x30:
|
||||||
|
rev = (uint8_t[80]) { 0x20, 0x20, 0x20, 0x20, 0x30, 0x20, 0x20, 0x20, 0x20, 0x30, 0x20,
|
||||||
|
0x20, 0x20, 0x20, 0x31, 0x20, 0x20, 0x20, 0x20, 0x32, 0x20, 0x20, 0x20, 0x20,
|
||||||
|
0x33, 0x20, 0x20, 0x20, 0x20, 0x34, 0x20, 0x20, 0x20, 0x20, 0x35, 0x20, 0x20,
|
||||||
|
0x20, 0x31, 0x35, 0x20, 0x20, 0x20, 0x31, 0x35, 0x20, 0x20, 0x20, 0x31, 0x35,
|
||||||
|
0x20, 0x20, 0x20, 0x31, 0x35, 0x20, 0x20, 0x20, 0x31, 0x35, 0x20, 0x20, 0x20,
|
||||||
|
0x31, 0x35, 0x20, 0x20, 0x20, 0x31, 0x31, 0x20, 0x20, 0x20, 0x31, 0x31, 0x20,
|
||||||
|
0x20, 0x20, 0x31, 0x31 };
|
||||||
|
break;
|
||||||
|
case 0x31:
|
||||||
|
rev = (uint8_t[80]) { 0x20, 0x20, 0x20, 0x31, 0x31, 0x20, 0x20, 0x20, 0x31, 0x31, 0x20,
|
||||||
|
0x20, 0x20, 0x31, 0x31, 0x20, 0x20, 0x31, 0x32, 0x38, 0x20, 0x20, 0x31, 0x30,
|
||||||
|
0x33, 0x20, 0x20, 0x31, 0x30, 0x33, 0x20, 0x20, 0x31, 0x31, 0x35, 0x20, 0x20,
|
||||||
|
0x31, 0x33, 0x38, 0x20, 0x20, 0x31, 0x32, 0x37, 0x20, 0x20, 0x31, 0x30, 0x33,
|
||||||
|
0x20, 0x20, 0x31, 0x30, 0x35, 0x20, 0x20, 0x31, 0x31, 0x31, 0x20, 0x20, 0x31,
|
||||||
|
0x32, 0x36, 0x20, 0x20, 0x31, 0x31, 0x33, 0x20, 0x20, 0x20, 0x39, 0x35, 0x20,
|
||||||
|
0x20, 0x31, 0x30, 0x30 };
|
||||||
|
break;
|
||||||
|
case 0x33:
|
||||||
|
rev = (uint8_t[80]) { 0x20, 0x20, 0x31, 0x30, 0x31, 0x20, 0x20, 0x31, 0x31, 0x35, 0x20,
|
||||||
|
0x20, 0x20, 0x39, 0x38, 0x20, 0x20, 0x20, 0x38, 0x36, 0x20, 0x20, 0x20, 0x37,
|
||||||
|
0x36, 0x20, 0x20, 0x20, 0x36, 0x37, 0x20, 0x20, 0x20, 0x36, 0x38, 0x20, 0x20,
|
||||||
|
0x20, 0x34, 0x38, 0x20, 0x20, 0x31, 0x31, 0x37, 0x20, 0x20, 0x20, 0x20, 0x30,
|
||||||
|
0x20, 0x20, 0x20, 0x38, 0x32, 0x20, 0x20, 0x31, 0x35, 0x34, 0x20, 0x20, 0x20,
|
||||||
|
0x20, 0x30, 0x20, 0x20, 0x20, 0x20, 0x36, 0x20, 0x20, 0x20, 0x33, 0x35, 0x20,
|
||||||
|
0x20, 0x20, 0x20, 0x34 };
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
dprintf("Wacca touch: BAD STARTUP REQUEST %2hx\n", req->data[2]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(resp.data, rev, 80 * sizeof(uint8_t));
|
||||||
|
|
||||||
|
if (req->side == 0) {
|
||||||
|
hr = touch_frame_encode(&touch0_uart.readable, &resp, sizeof(resp));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// TODO: see above
|
hr = touch_frame_encode(&touch1_uart.readable, &resp, sizeof(resp));
|
||||||
}
|
}
|
||||||
return S_OK;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static HRESULT touch_handle_get_rev_date_detail(const struct touch_req *req)
|
||||||
|
{
|
||||||
|
struct touch_resp_get_rev_date_detail resp;
|
||||||
|
HRESULT hr;
|
||||||
|
uint8_t rev[43] = { 0x31, 0x39, 0x30, 0x35, 0x32, 0x33, 0x52, 0x31,
|
||||||
|
0x39, 0x30, 0x35, 0x31, 0x34, 0x31, 0x39, 0x30, 0x35, 0x31, 0x34, 0x31,
|
||||||
|
0x39, 0x30, 0x35, 0x31, 0x34, 0x31, 0x39, 0x30, 0x35, 0x31, 0x34, 0x31,
|
||||||
|
0x39, 0x30, 0x35, 0x31, 0x34, 0x31, 0x39, 0x30, 0x35, 0x31, 0x34 };
|
||||||
|
|
||||||
|
dprintf("Wacca Touch%d: get rev date detail\n", req->side);
|
||||||
|
|
||||||
|
resp.cmd = 0xa8;
|
||||||
|
memcpy(resp.data, rev, sizeof(rev));
|
||||||
|
|
||||||
|
if (req->side == 0) {
|
||||||
|
hr = touch_frame_encode(&touch0_uart.readable, &resp, sizeof(resp));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
hr = touch_frame_encode(&touch1_uart.readable, &resp, sizeof(resp));
|
||||||
|
}
|
||||||
|
return hr;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT touch_handle_mystery1(const struct touch_req *req)
|
||||||
|
{
|
||||||
|
struct touch_resp_mystery1 resp;
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
|
dprintf("Wacca Touch%d: mystery command 1\n", req->side);
|
||||||
|
|
||||||
|
resp.cmd = 0xa2;
|
||||||
|
resp.data = 0x3f;
|
||||||
|
|
||||||
|
if (req->side == 0) {
|
||||||
|
hr = touch_frame_encode(&touch0_uart.readable, &resp, sizeof(resp));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
hr = touch_frame_encode(&touch1_uart.readable, &resp, sizeof(resp));
|
||||||
|
}
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT touch_handle_mystery2(const struct touch_req *req)
|
||||||
|
{
|
||||||
|
struct touch_resp_mystery2 resp;
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
|
dprintf("Wacca Touch%d: mystery command 2\n", req->side);
|
||||||
|
|
||||||
|
resp.cmd = 0x94;
|
||||||
|
resp.data = 0;
|
||||||
|
|
||||||
|
if (req->side == 0) {
|
||||||
|
hr = touch_frame_encode(&touch0_uart.readable, &resp, sizeof(resp));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
hr = touch_frame_encode(&touch1_uart.readable, &resp, sizeof(resp));
|
||||||
|
}
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT touch_handle_start_auto_scan(const struct touch_req *req)
|
||||||
|
{
|
||||||
|
struct touch_resp_start_auto resp;
|
||||||
|
HRESULT hr;
|
||||||
|
uint8_t data1[24] = { 0 };
|
||||||
|
uint8_t data2[9] = { 0x0d, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00 };
|
||||||
|
|
||||||
|
dprintf("Wacca Touch%d: Start Auto\n", req->side);
|
||||||
|
|
||||||
|
resp.cmd = 0x9c;
|
||||||
|
resp.data = 0;
|
||||||
|
resp.checksum = 0x49;
|
||||||
|
|
||||||
|
resp.frame.cmd= 0x81;
|
||||||
|
resp.frame.count = input_frame_count++;
|
||||||
|
memcpy(resp.frame.data1, data1, sizeof(data1));
|
||||||
|
memcpy(resp.frame.data2, data2, sizeof(data2));
|
||||||
|
resp.frame.checksum = calc_checksum(&resp.frame, sizeof(resp.frame));
|
||||||
|
|
||||||
|
if (req->side == 0) {
|
||||||
|
hr = touch_frame_encode(&touch0_uart.readable, &resp, sizeof(resp));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
hr = touch_frame_encode(&touch1_uart.readable, &resp, sizeof(resp));
|
||||||
|
}
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Decodes the response into a struct that's easier to work with. */
|
||||||
static HRESULT touch_frame_decode(struct touch_req *dest, struct iobuf *iobuf, int side)
|
static HRESULT touch_frame_decode(struct touch_req *dest, struct iobuf *iobuf, int side)
|
||||||
{
|
{
|
||||||
dest->side = side;
|
dest->side = side;
|
||||||
@ -243,3 +405,39 @@ static HRESULT touch_frame_decode(struct touch_req *dest, struct iobuf *iobuf, i
|
|||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Encode and send the response.
|
||||||
|
* The last byte of every response is a checksum.
|
||||||
|
* This checksum is calculated by bitwise XORing
|
||||||
|
* every byte in the response, then dropping the MSB.
|
||||||
|
* Thanks the CrazyRedMachine for figuring that out!!
|
||||||
|
*/
|
||||||
|
static HRESULT touch_frame_encode(struct iobuf *dest, const void *ptr, size_t nbytes)
|
||||||
|
{
|
||||||
|
const uint8_t *src;
|
||||||
|
uint8_t checksum = 0;
|
||||||
|
|
||||||
|
src = ptr;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < nbytes; i++) {
|
||||||
|
dest->bytes[dest->pos++] = src[i];
|
||||||
|
checksum = checksum^(src[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
dest->bytes[dest->pos++] = checksum&0x7f;
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint8_t calc_checksum(const void *ptr, size_t nbytes)
|
||||||
|
{
|
||||||
|
const uint8_t *src;
|
||||||
|
uint8_t checksum = 0;
|
||||||
|
|
||||||
|
src = ptr;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < nbytes; i++) {
|
||||||
|
checksum = checksum^(src[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return checksum&0x7f;
|
||||||
|
}
|
||||||
|
@ -12,20 +12,60 @@ enum touch_cmd {
|
|||||||
CMD_GET_REV_DATE = 0xa0,
|
CMD_GET_REV_DATE = 0xa0,
|
||||||
CMD_STARTUP = 0x72,
|
CMD_STARTUP = 0x72,
|
||||||
CMD_GET_REV_DATE_DETAIL = 0xa8,
|
CMD_GET_REV_DATE_DETAIL = 0xa8,
|
||||||
CMD_UNKNOWN1 = 0xa2,
|
CMD_MYSTERY1 = 0xa2,
|
||||||
CMD_UNKNOWN2 = 0x94,
|
CMD_MYSTERY2 = 0x94,
|
||||||
CMD_START_AUTO = 0xc9
|
CMD_START_AUTO_SCAN = 0xc9,
|
||||||
|
CMD_BEGIN_WRITE = 0x77,
|
||||||
|
CMD_NEXT_WRITE = 0x20
|
||||||
};
|
};
|
||||||
|
|
||||||
struct touch_req {
|
struct touch_req {
|
||||||
int side;
|
uint8_t side; // COM3 or COM4
|
||||||
int cmd; // First byte is the command byte
|
uint8_t cmd; // First byte is the command byte
|
||||||
int data[256]; // rest of the data goes here
|
uint8_t data[256]; // rest of the data goes here
|
||||||
int data_length; // Size of the data including command byte
|
uint8_t data_length; // Size of the data including command byte
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// The checksum is only calculated when we're about to send it so
|
||||||
|
// it's not part of any of these structs. Just note that the last
|
||||||
|
// byte of every response is a checksum
|
||||||
struct touch_input_frame {
|
struct touch_input_frame {
|
||||||
int data[36];
|
uint8_t cmd;
|
||||||
|
uint8_t data1[24];
|
||||||
|
uint8_t data2[9];
|
||||||
|
uint8_t count;
|
||||||
|
uint8_t checksum;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct touch_resp_get_rev_date {
|
||||||
|
uint8_t cmd;
|
||||||
|
uint8_t data[6];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct touch_resp_startup {
|
||||||
|
uint8_t data[80];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct touch_resp_get_rev_date_detail {
|
||||||
|
uint8_t cmd;
|
||||||
|
uint8_t data[43];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct touch_resp_mystery1 {
|
||||||
|
uint8_t cmd;
|
||||||
|
uint8_t data;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct touch_resp_mystery2 {
|
||||||
|
uint8_t cmd;
|
||||||
|
uint8_t data;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct touch_resp_start_auto {
|
||||||
|
uint8_t cmd;
|
||||||
|
uint8_t data;
|
||||||
|
uint8_t checksum;
|
||||||
|
struct touch_input_frame frame;
|
||||||
};
|
};
|
||||||
|
|
||||||
HRESULT touch_hook_init(const struct touch_config *cfg);
|
HRESULT touch_hook_init(const struct touch_config *cfg);
|
||||||
|
Loading…
Reference in New Issue
Block a user