forked from Dniel97/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_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_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 struct uart touch0_uart;
|
||||
@ -117,7 +125,7 @@ static HRESULT touch0_handle_irp_locked(struct irp *irp)
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
#if 1
|
||||
#if 0
|
||||
dprintf("TX0 Buffer:\n");
|
||||
dump_iobuf(&touch0_uart.written);
|
||||
#endif
|
||||
@ -164,7 +172,7 @@ static HRESULT touch1_handle_irp_locked(struct irp *irp)
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
#if 1
|
||||
#if 0
|
||||
dprintf("TX1 Buffer:\n");
|
||||
dump_iobuf(&touch1_uart.written);
|
||||
#endif
|
||||
@ -196,37 +204,191 @@ static HRESULT touch_req_dispatch(const struct touch_req *req)
|
||||
return touch_handle_get_rev_date(req);
|
||||
case CMD_STARTUP:
|
||||
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:
|
||||
dprintf("Wacca touch: Unhandled command %02x\n", req->cmd);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
resp.cmd = 0xa0;
|
||||
memcpy(resp.data, rev, sizeof(rev));
|
||||
//resp.data = rev;
|
||||
|
||||
if (req->side == 0) {
|
||||
// TODO: a0 31 39 30 35 32 33 2c
|
||||
hr = touch_frame_encode(&touch0_uart.readable, &resp, sizeof(resp));
|
||||
}
|
||||
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)
|
||||
{
|
||||
struct touch_resp_startup resp;
|
||||
HRESULT hr;
|
||||
uint8_t *rev;
|
||||
|
||||
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
|
||||
}
|
||||
else {
|
||||
// TODO: see above
|
||||
}
|
||||
return S_OK;
|
||||
|
||||
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 {
|
||||
hr = touch_frame_encode(&touch1_uart.readable, &resp, sizeof(resp));
|
||||
}
|
||||
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)
|
||||
{
|
||||
dest->side = side;
|
||||
@ -243,3 +405,39 @@ static HRESULT touch_frame_decode(struct touch_req *dest, struct iobuf *iobuf, i
|
||||
|
||||
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_STARTUP = 0x72,
|
||||
CMD_GET_REV_DATE_DETAIL = 0xa8,
|
||||
CMD_UNKNOWN1 = 0xa2,
|
||||
CMD_UNKNOWN2 = 0x94,
|
||||
CMD_START_AUTO = 0xc9
|
||||
CMD_MYSTERY1 = 0xa2,
|
||||
CMD_MYSTERY2 = 0x94,
|
||||
CMD_START_AUTO_SCAN = 0xc9,
|
||||
CMD_BEGIN_WRITE = 0x77,
|
||||
CMD_NEXT_WRITE = 0x20
|
||||
};
|
||||
|
||||
struct touch_req {
|
||||
int side;
|
||||
int cmd; // First byte is the command byte
|
||||
int data[256]; // rest of the data goes here
|
||||
int data_length; // Size of the data including command byte
|
||||
uint8_t side; // COM3 or COM4
|
||||
uint8_t cmd; // First byte is the command byte
|
||||
uint8_t data[256]; // rest of the data goes here
|
||||
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 {
|
||||
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);
|
||||
|
Loading…
Reference in New Issue
Block a user