forked from Dniel97/segatools
LED board improvements and cleanup
This commit is contained in:
parent
d86baab852
commit
8b1d0cfefa
222
board/led15093-cmd.h
Normal file
222
board/led15093-cmd.h
Normal file
@ -0,0 +1,222 @@
|
||||
#pragma once
|
||||
|
||||
#include "board/led15093-frame.h"
|
||||
|
||||
/* Command IDs */
|
||||
|
||||
enum {
|
||||
LED_15093_CMD_RESET = 0x10,
|
||||
LED_15093_CMD_SET_TIMEOUT = 0x11,
|
||||
LED_15093_CMD_UNK1 = 0x12,
|
||||
LED_15093_CMD_SET_DISABLE_RESPONSE = 0x14,
|
||||
LED_15093_CMD_SET_ID = 0x18,
|
||||
LED_15093_CMD_CLEAR_ID = 0x19,
|
||||
LED_15093_CMD_SET_MAX_BRIGHT = 0x3F, // TODO
|
||||
LED_15093_CMD_UPDATE_LED = 0x80,
|
||||
LED_15093_CMD_SET_LED = 0x81,
|
||||
LED_15093_CMD_SET_IMM_LED = 0x82,
|
||||
LED_15093_CMD_SET_FADE_LED = 0x83,
|
||||
LED_15093_CMD_SET_FADE_LEVEL = 0x84,
|
||||
LED_15093_CMD_SET_FADE_SHIFT = 0x85,
|
||||
LED_15093_CMD_SET_AUTO_SHIFT = 0x86,
|
||||
LED_15093_CMD_GET_BOARD_INFO = 0xF0,
|
||||
LED_15093_CMD_GET_BOARD_STATUS = 0xF1,
|
||||
LED_15093_CMD_GET_FW_SUM = 0xF2,
|
||||
LED_15093_CMD_GET_PROTOCOL_VER = 0xF3,
|
||||
LED_15093_CMD_SET_BOOTMODE = 0xFD,
|
||||
LED_15093_CMD_FW_UPDATE = 0xFE,
|
||||
};
|
||||
|
||||
/* Response codes */
|
||||
|
||||
enum {
|
||||
LED_15093_STATUS_OK = 0x01,
|
||||
LED_15093_STATUS_ERR_SUM = 0x02,
|
||||
LED_15093_STATUS_ERR_PARITY = 0x03,
|
||||
LED_15093_STATUS_ERR_FRAMING = 0x04,
|
||||
LED_15093_STATUS_ERR_OVERRUN = 0x05,
|
||||
LED_15093_STATUS_ERR_BUFFER_OVERFLOW = 0x06,
|
||||
};
|
||||
|
||||
enum {
|
||||
LED_15093_REPORT_OK = 0x01,
|
||||
LED_15093_REPORT_WAIT = 0x02,
|
||||
LED_15093_REPORT_ERR1 = 0x03,
|
||||
LED_15093_REPORT_ERR2 = 0x04,
|
||||
};
|
||||
|
||||
/* Status bitmasks */
|
||||
|
||||
enum {
|
||||
LED_15093_STATUS_UART_ERR_SUM = 0x01,
|
||||
LED_15093_STATUS_UART_ERR_PARITY = 0x02,
|
||||
LED_15093_STATUS_UART_ERR_FRAMING = 0x04,
|
||||
LED_15093_STATUS_UART_ERR_OVERRUN = 0x08,
|
||||
LED_15093_STATUS_UART_ERR_BUFFER_OVERFLOW = 0x10,
|
||||
};
|
||||
|
||||
enum {
|
||||
LED_15093_STATUS_BOARD_ERR_WDT = 0x01,
|
||||
LED_15093_STATUS_BOARD_ERR_TIMEOUT = 0x02,
|
||||
LED_15093_STATUS_BOARD_ERR_RESET = 0x04,
|
||||
LED_15093_STATUS_BOARD_ERR_BOR = 0x08,
|
||||
};
|
||||
|
||||
enum {
|
||||
LED_15093_STATUS_CMD_ERR_BUSY = 0x01,
|
||||
LED_15093_STATUS_CMD_ERR_UNKNOWN = 0x02,
|
||||
LED_15093_STATUS_CMD_ERR_PARAM = 0x04,
|
||||
LED_15093_STATUS_CMD_ERR_EXE = 0x08,
|
||||
};
|
||||
|
||||
/* Status types for internal use */
|
||||
|
||||
enum {
|
||||
LED_15093_STATUS_TYPE_BOARD = 1,
|
||||
LED_15093_STATUS_TYPE_UART = 2,
|
||||
LED_15093_STATUS_TYPE_CMD = 3,
|
||||
};
|
||||
|
||||
/* Request data structures */
|
||||
|
||||
struct led15093_req_reset {
|
||||
struct led15093_req_hdr hdr;
|
||||
uint8_t cmd;
|
||||
uint8_t r_type;
|
||||
};
|
||||
|
||||
struct led15093_req_set_timeout {
|
||||
struct led15093_req_hdr hdr;
|
||||
uint8_t cmd;
|
||||
uint8_t count;
|
||||
};
|
||||
|
||||
struct led15093_req_set_disable_response {
|
||||
struct led15093_req_hdr hdr;
|
||||
uint8_t cmd;
|
||||
bool sw;
|
||||
};
|
||||
|
||||
struct led15093_req_set_id {
|
||||
struct led15093_req_hdr hdr;
|
||||
uint8_t cmd;
|
||||
uint8_t id;
|
||||
};
|
||||
|
||||
struct led15093_req_set_led {
|
||||
struct led15093_req_hdr hdr;
|
||||
uint8_t cmd;
|
||||
uint8_t data[198];
|
||||
};
|
||||
|
||||
struct led15093_req_set_fade_level {
|
||||
struct led15093_req_hdr hdr;
|
||||
uint8_t cmd;
|
||||
uint8_t depth;
|
||||
uint8_t cycle;
|
||||
};
|
||||
|
||||
struct led15093_req_set_fade_shift {
|
||||
struct led15093_req_hdr hdr;
|
||||
uint8_t cmd;
|
||||
uint8_t target;
|
||||
};
|
||||
|
||||
struct led15093_req_set_auto_shift {
|
||||
struct led15093_req_hdr hdr;
|
||||
uint8_t cmd;
|
||||
uint8_t count;
|
||||
uint8_t target;
|
||||
};
|
||||
|
||||
struct led15093_req_get_board_status {
|
||||
struct led15093_req_hdr hdr;
|
||||
uint8_t cmd;
|
||||
bool clear;
|
||||
};
|
||||
|
||||
union led15093_req_any {
|
||||
struct led15093_req_hdr hdr;
|
||||
struct led15093_req_reset reset;
|
||||
struct led15093_req_set_timeout set_timeout;
|
||||
struct led15093_req_set_disable_response set_disable_response;
|
||||
struct led15093_req_set_id set_id;
|
||||
struct led15093_req_set_led set_led;
|
||||
struct led15093_req_set_fade_level set_fade_level;
|
||||
struct led15093_req_set_fade_shift set_fade_shift;
|
||||
struct led15093_req_set_auto_shift set_auto_shift;
|
||||
struct led15093_req_get_board_status get_board_status;
|
||||
uint8_t payload[256];
|
||||
};
|
||||
|
||||
/* Response data structures */
|
||||
|
||||
struct led15093_resp_any {
|
||||
struct led15093_resp_hdr hdr;
|
||||
uint8_t status;
|
||||
uint8_t cmd;
|
||||
uint8_t report;
|
||||
uint8_t data[32];
|
||||
};
|
||||
|
||||
struct led15093_resp_timeout {
|
||||
struct led15093_resp_hdr hdr;
|
||||
uint8_t status;
|
||||
uint8_t cmd;
|
||||
uint8_t report;
|
||||
uint8_t count_upper;
|
||||
uint8_t count_lower;
|
||||
};
|
||||
|
||||
struct led15093_resp_fw_sum {
|
||||
struct led15093_resp_hdr hdr;
|
||||
uint8_t status;
|
||||
uint8_t cmd;
|
||||
uint8_t report;
|
||||
uint8_t sum_upper;
|
||||
uint8_t sum_lower;
|
||||
};
|
||||
|
||||
struct led15093_resp_board_info_legacy {
|
||||
struct led15093_resp_hdr hdr;
|
||||
uint8_t status;
|
||||
uint8_t cmd;
|
||||
uint8_t report;
|
||||
char board_num[8];
|
||||
uint8_t lf; // 0x0A (ASCII LF)
|
||||
char chip_num[5];
|
||||
uint8_t endcode; // Always 0xFF
|
||||
uint8_t fw_ver;
|
||||
};
|
||||
|
||||
struct led15093_resp_board_info {
|
||||
struct led15093_resp_hdr hdr;
|
||||
uint8_t status;
|
||||
uint8_t cmd;
|
||||
uint8_t report;
|
||||
char board_num[8];
|
||||
uint8_t lf; // 0x0A (ASCII LF)
|
||||
char chip_num[5];
|
||||
uint8_t endcode; // Always 0xFF
|
||||
uint8_t fw_ver;
|
||||
uint8_t rx_buf;
|
||||
};
|
||||
|
||||
struct led15093_resp_protocol_ver {
|
||||
struct led15093_resp_hdr hdr;
|
||||
uint8_t status;
|
||||
uint8_t cmd;
|
||||
uint8_t report;
|
||||
uint8_t mode;
|
||||
uint8_t major_ver;
|
||||
uint8_t minor_ver;
|
||||
};
|
||||
|
||||
struct led15093_resp_set_auto_shift {
|
||||
struct led15093_resp_hdr hdr;
|
||||
uint8_t status;
|
||||
uint8_t cmd;
|
||||
uint8_t report;
|
||||
uint8_t count;
|
||||
uint8_t target;
|
||||
};
|
@ -5,13 +5,13 @@
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "board/led1509306-frame.h"
|
||||
#include "board/led15093-frame.h"
|
||||
|
||||
#include "hook/iobuf.h"
|
||||
|
||||
static void led1509306_frame_sync(struct iobuf *src);
|
||||
static HRESULT led1509306_frame_accept(const struct iobuf *dest);
|
||||
static HRESULT led1509306_frame_encode_byte(struct iobuf *dest, uint8_t byte);
|
||||
static void led15093_frame_sync(struct iobuf *src);
|
||||
static HRESULT led15093_frame_accept(const struct iobuf *dest);
|
||||
static HRESULT led15093_frame_encode_byte(struct iobuf *dest, uint8_t byte);
|
||||
|
||||
/* Frame structure:
|
||||
|
||||
@ -34,17 +34,17 @@ static HRESULT led1509306_frame_encode_byte(struct iobuf *dest, uint8_t byte);
|
||||
|
||||
0xD0 is an escape byte. Un-escape the subsequent byte by adding 1. */
|
||||
|
||||
static void led1509306_frame_sync(struct iobuf *src)
|
||||
static void led15093_frame_sync(struct iobuf *src)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0 ; i < src->pos && src->bytes[i] != 0xE0 ; i++);
|
||||
for (i = 0 ; i < src->pos && src->bytes[i] != LED_15093_FRAME_SYNC ; i++);
|
||||
|
||||
src->pos -= i;
|
||||
memmove(&src->bytes[0], &src->bytes[i], i);
|
||||
}
|
||||
|
||||
static HRESULT led1509306_frame_accept(const struct iobuf *dest)
|
||||
static HRESULT led15093_frame_accept(const struct iobuf *dest)
|
||||
{
|
||||
uint8_t checksum;
|
||||
size_t i;
|
||||
@ -58,9 +58,9 @@ static HRESULT led1509306_frame_accept(const struct iobuf *dest)
|
||||
for (i = 1 ; i < dest->pos - 1 ; i++) {
|
||||
checksum += dest->bytes[i];
|
||||
}
|
||||
|
||||
//dprintf("LED checksum %02x, expected %02x\n", checksum, dest->bytes[dest->pos - 1]);
|
||||
|
||||
|
||||
// dprintf("LED checksum %02x, expected %02x\n", checksum, dest->bytes[dest->pos - 1]);
|
||||
|
||||
if (checksum != dest->bytes[dest->pos - 1]) {
|
||||
return HRESULT_FROM_WIN32(ERROR_CRC);
|
||||
}
|
||||
@ -68,7 +68,7 @@ static HRESULT led1509306_frame_accept(const struct iobuf *dest)
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT led1509306_frame_decode(struct iobuf *dest, struct iobuf *src)
|
||||
HRESULT led15093_frame_decode(struct iobuf *dest, struct iobuf *src)
|
||||
{
|
||||
uint8_t byte;
|
||||
bool escape;
|
||||
@ -82,7 +82,7 @@ HRESULT led1509306_frame_decode(struct iobuf *dest, struct iobuf *src)
|
||||
assert(src->bytes != NULL || src->nbytes == 0);
|
||||
assert(src->pos <= src->nbytes);
|
||||
|
||||
led1509306_frame_sync(src);
|
||||
led15093_frame_sync(src);
|
||||
|
||||
dest->pos = 0;
|
||||
escape = false;
|
||||
@ -96,9 +96,9 @@ HRESULT led1509306_frame_decode(struct iobuf *dest, struct iobuf *src)
|
||||
hr = HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
|
||||
} else if (i == 0) {
|
||||
dest->bytes[dest->pos++] = byte;
|
||||
} else if (byte == 0xE0) {
|
||||
} else if (byte == LED_15093_FRAME_SYNC) {
|
||||
hr = E_FAIL;
|
||||
} else if (byte == 0xD0) {
|
||||
} else if (byte == LED_15093_FRAME_ESC) {
|
||||
if (escape) {
|
||||
hr = E_FAIL;
|
||||
}
|
||||
@ -114,7 +114,7 @@ HRESULT led1509306_frame_decode(struct iobuf *dest, struct iobuf *src)
|
||||
/* Try to accept the packet we've built up so far */
|
||||
|
||||
if (SUCCEEDED(hr)) {
|
||||
hr = led1509306_frame_accept(dest);
|
||||
hr = led15093_frame_accept(dest);
|
||||
}
|
||||
}
|
||||
|
||||
@ -129,7 +129,7 @@ HRESULT led1509306_frame_decode(struct iobuf *dest, struct iobuf *src)
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT led1509306_frame_encode(
|
||||
HRESULT led15093_frame_encode(
|
||||
struct iobuf *dest,
|
||||
const void *ptr,
|
||||
size_t nbytes)
|
||||
@ -147,22 +147,24 @@ HRESULT led1509306_frame_encode(
|
||||
|
||||
src = ptr;
|
||||
|
||||
assert(nbytes >= 3 && src[0] == 0xE0 && src[3] + 4 == nbytes);
|
||||
assert(nbytes >= 3 &&
|
||||
src[0] == LED_15093_FRAME_SYNC &&
|
||||
src[3] + 4 == nbytes);
|
||||
|
||||
if (dest->pos >= dest->nbytes) {
|
||||
return HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
|
||||
}
|
||||
|
||||
dest->bytes[dest->pos++] = 0xE0;
|
||||
dest->bytes[dest->pos++] = LED_15093_FRAME_SYNC;
|
||||
checksum = 0;
|
||||
// dprintf("%02x ", 0xe0);
|
||||
// dprintf("%02x ", LED_15093_FRAME_SYNC);
|
||||
|
||||
for (i = 1 ; i < nbytes ; i++) {
|
||||
byte = src[i];
|
||||
checksum += byte;
|
||||
// dprintf("%02x ", byte);
|
||||
|
||||
hr = led1509306_frame_encode_byte(dest, byte);
|
||||
hr = led15093_frame_encode_byte(dest, byte);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
return hr;
|
||||
@ -170,17 +172,17 @@ HRESULT led1509306_frame_encode(
|
||||
}
|
||||
// dprintf("%02x \n", checksum);
|
||||
|
||||
return led1509306_frame_encode_byte(dest, checksum);
|
||||
return led15093_frame_encode_byte(dest, checksum);
|
||||
}
|
||||
|
||||
static HRESULT led1509306_frame_encode_byte(struct iobuf *dest, uint8_t byte)
|
||||
static HRESULT led15093_frame_encode_byte(struct iobuf *dest, uint8_t byte)
|
||||
{
|
||||
if (byte == 0xE0 || byte == 0xD0) {
|
||||
if (byte == LED_15093_FRAME_SYNC || byte == LED_15093_FRAME_ESC) {
|
||||
if (dest->pos + 2 > dest->nbytes) {
|
||||
return HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
|
||||
}
|
||||
|
||||
dest->bytes[dest->pos++] = 0xD0;
|
||||
dest->bytes[dest->pos++] = LED_15093_FRAME_ESC;
|
||||
dest->bytes[dest->pos++] = byte - 1;
|
||||
} else {
|
||||
if (dest->pos + 1 > dest->nbytes) {
|
34
board/led15093-frame.h
Normal file
34
board/led15093-frame.h
Normal file
@ -0,0 +1,34 @@
|
||||
#pragma once
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "hook/iobuf.h"
|
||||
|
||||
enum {
|
||||
LED_15093_FRAME_SYNC = 0xE0,
|
||||
LED_15093_FRAME_ESC = 0xD0,
|
||||
};
|
||||
|
||||
struct led15093_req_hdr {
|
||||
uint8_t sync;
|
||||
uint8_t dest_adr;
|
||||
uint8_t src_adr;
|
||||
uint8_t nbytes;
|
||||
};
|
||||
|
||||
struct led15093_resp_hdr {
|
||||
uint8_t sync;
|
||||
uint8_t dest_adr;
|
||||
uint8_t src_adr;
|
||||
uint8_t nbytes;
|
||||
};
|
||||
|
||||
HRESULT led15093_frame_decode(struct iobuf *dest, struct iobuf *src);
|
||||
|
||||
HRESULT led15093_frame_encode(
|
||||
struct iobuf *dest,
|
||||
const void *ptr,
|
||||
size_t nbytes);
|
1112
board/led15093.c
Normal file
1112
board/led15093.c
Normal file
File diff suppressed because it is too large
Load Diff
22
board/led15093.h
Normal file
22
board/led15093.h
Normal file
@ -0,0 +1,22 @@
|
||||
#pragma once
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
struct led15093_config {
|
||||
bool enable;
|
||||
bool high_baudrate;
|
||||
unsigned int port_no[2];
|
||||
char board_number[8];
|
||||
char chip_number[5];
|
||||
char boot_chip_number[5];
|
||||
uint8_t fw_ver;
|
||||
uint16_t fw_sum;
|
||||
};
|
||||
|
||||
HRESULT led15093_hook_init(
|
||||
const struct led15093_config *cfg,
|
||||
unsigned int port_no_0,
|
||||
unsigned int port_no_1);
|
@ -1,45 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "board/led1509306-frame.h"
|
||||
|
||||
enum {
|
||||
LED_15093_06_CMD_RESET = 0x10,
|
||||
LED_15093_06_CMD_SET_TIMEOUT = 0x11,
|
||||
LED_15093_06_CMD_SET_DISABLE_RESPONSE = 0x14,
|
||||
LED_15093_06_CMD_SET_LED = 0x82,
|
||||
LED_15093_06_CMD_SET_LED_COUNT = 0x86,
|
||||
LED_15093_06_CMD_BOARD_INFO = 0xF0,
|
||||
LED_15093_06_CMD_BOARD_STATUS = 0xF1,
|
||||
LED_15093_06_CMD_FW_SUM = 0xF2,
|
||||
LED_15093_06_CMD_PROTOCOL_VER = 0xF3,
|
||||
LED_15093_06_CMD_BOOTLOADER = 0xFD,
|
||||
};
|
||||
|
||||
struct led1509306_req_any {
|
||||
struct led1509306_hdr hdr;
|
||||
uint8_t cmd;
|
||||
uint8_t payload[256];
|
||||
};
|
||||
|
||||
struct led1509306_resp_any {
|
||||
struct led1509306_hdr hdr;
|
||||
uint8_t status;
|
||||
uint8_t cmd;
|
||||
uint8_t report;
|
||||
uint8_t data[32];
|
||||
};
|
||||
|
||||
struct led1509306_resp_board_info {
|
||||
struct led1509306_hdr hdr;
|
||||
uint8_t status;
|
||||
uint8_t cmd;
|
||||
uint8_t report;
|
||||
struct {
|
||||
char board_num[8];
|
||||
uint8_t _0a;
|
||||
char chip_num[5];
|
||||
uint8_t _ff;
|
||||
uint8_t fw_ver;
|
||||
// may be some more data after this that isn't checked
|
||||
} data;
|
||||
};
|
@ -1,26 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "hook/iobuf.h"
|
||||
|
||||
enum {
|
||||
LED_15093_06_FRAME_SYNC = 0xE0,
|
||||
};
|
||||
|
||||
struct led1509306_hdr {
|
||||
uint8_t sync;
|
||||
uint8_t dest_adr;
|
||||
uint8_t src_adr;
|
||||
uint8_t nbytes;
|
||||
};
|
||||
|
||||
HRESULT led1509306_frame_decode(struct iobuf *dest, struct iobuf *src);
|
||||
|
||||
HRESULT led1509306_frame_encode(
|
||||
struct iobuf *dest,
|
||||
const void *ptr,
|
||||
size_t nbytes);
|
@ -20,9 +20,11 @@ board_lib = static_library(
|
||||
'io3.h',
|
||||
'io4.c',
|
||||
'io4.h',
|
||||
'led1509306-cmd.h',
|
||||
'led1509306-frame.c',
|
||||
'led1509306-frame.h',
|
||||
'led15093-cmd.h',
|
||||
'led15093-frame.c',
|
||||
'led15093-frame.h',
|
||||
'led15093.c',
|
||||
'led15093.h',
|
||||
'sg-cmd.c',
|
||||
'sg-cmd.h',
|
||||
'sg-frame.c',
|
||||
|
@ -43,33 +43,65 @@ void slider_config_load(struct slider_config *cfg, const wchar_t *filename)
|
||||
cfg->enable = GetPrivateProfileIntW(L"slider", L"enable", 1, filename);
|
||||
}
|
||||
|
||||
void led1509306_config_load(struct led1509306_config *cfg, const wchar_t *filename)
|
||||
void led15093_config_load(struct led15093_config *cfg, const wchar_t *filename)
|
||||
{
|
||||
assert(cfg != NULL);
|
||||
assert(filename != NULL);
|
||||
|
||||
wchar_t tmpstr[16];
|
||||
|
||||
|
||||
memset(cfg->board_number, ' ', sizeof(cfg->board_number));
|
||||
memset(cfg->chip_number, ' ', sizeof(cfg->chip_number));
|
||||
|
||||
cfg->enable = GetPrivateProfileIntW(L"ledstrip", L"enable", 1, filename);
|
||||
cfg->fw_ver = GetPrivateProfileIntW(L"ledstrip", L"fw_ver", 0x90, filename);
|
||||
cfg->fw_sum = GetPrivateProfileIntW(L"ledstrip", L"fw_sum", 0xadf7, filename);
|
||||
|
||||
GetPrivateProfileStringW(L"ledstrip", L"board_number", L"15093-06", tmpstr, _countof(tmpstr), filename);
|
||||
memset(cfg->boot_chip_number, ' ', sizeof(cfg->boot_chip_number));
|
||||
|
||||
cfg->enable = GetPrivateProfileIntW(L"led15093", L"enable", 1, filename);
|
||||
cfg->port_no[0] = GetPrivateProfileIntW(L"led15093", L"portNo0", 0, filename);
|
||||
cfg->port_no[1] = GetPrivateProfileIntW(L"led15093", L"portNo1", 0, filename);
|
||||
cfg->high_baudrate = GetPrivateProfileIntW(L"led15093", L"highBaudrate", 0, filename);
|
||||
cfg->fw_ver = GetPrivateProfileIntW(L"led15093", L"fwVer", 0x90, filename);
|
||||
cfg->fw_sum = GetPrivateProfileIntW(L"led15093", L"fwSum", 0xadf7, filename);
|
||||
|
||||
GetPrivateProfileStringW(
|
||||
L"led15093",
|
||||
L"boardNumber",
|
||||
L"15093-06",
|
||||
tmpstr,
|
||||
_countof(tmpstr),
|
||||
filename);
|
||||
|
||||
size_t n = wcstombs(cfg->board_number, tmpstr, sizeof(cfg->board_number));
|
||||
for (int i = n; i < sizeof(cfg->board_number); i++)
|
||||
{
|
||||
cfg->board_number[i] = ' ';
|
||||
}
|
||||
|
||||
GetPrivateProfileStringW(L"ledstrip", L"chip_number", L"6710 ", tmpstr, _countof(tmpstr), filename);
|
||||
|
||||
GetPrivateProfileStringW(
|
||||
L"led15093",
|
||||
L"chipNumber",
|
||||
L"6710 ",
|
||||
tmpstr,
|
||||
_countof(tmpstr),
|
||||
filename);
|
||||
|
||||
n = wcstombs(cfg->chip_number, tmpstr, sizeof(cfg->chip_number));
|
||||
for (int i = n; i < sizeof(cfg->chip_number); i++)
|
||||
{
|
||||
cfg->chip_number[i] = ' ';
|
||||
}
|
||||
}
|
||||
|
||||
GetPrivateProfileStringW(
|
||||
L"led15093",
|
||||
L"bootChipNumber",
|
||||
L"6709 ",
|
||||
tmpstr,
|
||||
_countof(tmpstr),
|
||||
filename);
|
||||
|
||||
n = wcstombs(cfg->boot_chip_number, tmpstr, sizeof(cfg->boot_chip_number));
|
||||
for (int i = n; i < sizeof(cfg->boot_chip_number); i++)
|
||||
{
|
||||
cfg->boot_chip_number[i] = ' ';
|
||||
}
|
||||
}
|
||||
|
||||
void chuni_hook_config_load(
|
||||
@ -87,5 +119,5 @@ void chuni_hook_config_load(
|
||||
gfx_config_load(&cfg->gfx, filename);
|
||||
chuni_dll_config_load(&cfg->dll, filename);
|
||||
slider_config_load(&cfg->slider, filename);
|
||||
led1509306_config_load(&cfg->led1509306, filename);
|
||||
led15093_config_load(&cfg->led15093, filename);
|
||||
}
|
||||
|
@ -6,10 +6,10 @@
|
||||
#include "amex/amex.h"
|
||||
|
||||
#include "board/sg-reader.h"
|
||||
#include "board/led15093.h"
|
||||
|
||||
#include "chunihook/chuni-dll.h"
|
||||
#include "chunihook/slider.h"
|
||||
#include "chunihook/led1509306.h"
|
||||
|
||||
#include "gfxhook/gfx.h"
|
||||
|
||||
@ -22,7 +22,7 @@ struct chuni_hook_config {
|
||||
struct gfx_config gfx;
|
||||
struct chuni_dll_config dll;
|
||||
struct slider_config slider;
|
||||
struct led1509306_config led1509306;
|
||||
struct led15093_config led15093;
|
||||
};
|
||||
|
||||
void chuni_dll_config_load(
|
||||
|
@ -9,7 +9,6 @@
|
||||
#include "chunihook/config.h"
|
||||
#include "chunihook/jvs.h"
|
||||
#include "chunihook/slider.h"
|
||||
#include "chunihook/led1509306.h"
|
||||
|
||||
#include "chuniio/chuniio.h"
|
||||
|
||||
@ -97,7 +96,7 @@ static DWORD CALLBACK chuni_pre_startup(void)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
hr = led1509306_hook_init(&chuni_hook_cfg.led1509306);
|
||||
hr = led15093_hook_init(&chuni_hook_cfg.led15093, 10, 11);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
goto fail;
|
||||
|
@ -1,385 +0,0 @@
|
||||
/*
|
||||
SEGA 837-15093-06 LED controller emulator
|
||||
|
||||
Credits:
|
||||
|
||||
somewhatlurker, skogaby
|
||||
*/
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <process.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "board/led1509306-cmd.h"
|
||||
#include "board/led1509306-frame.h"
|
||||
|
||||
#include "chunihook/led1509306.h"
|
||||
|
||||
#include "hook/iobuf.h"
|
||||
#include "hook/iohook.h"
|
||||
|
||||
#include "hooklib/uart.h"
|
||||
|
||||
#include "util/dprintf.h"
|
||||
#include "util/dump.h"
|
||||
|
||||
static HRESULT led1509306_handle_irp(struct irp *irp);
|
||||
static HRESULT led1509306_handle_irp_locked(int board, struct irp *irp);
|
||||
|
||||
static HRESULT led1509306_req_dispatch(int board, const struct led1509306_req_any *req);
|
||||
static HRESULT led1509306_req_reset(int board, const struct led1509306_req_any *req);
|
||||
static HRESULT led1509306_req_get_board_info(int board);
|
||||
static HRESULT led1509306_req_get_fw_sum(int board);
|
||||
static HRESULT led1509306_req_get_protocol_ver(int board);
|
||||
static HRESULT led1509306_req_get_board_status(int board);
|
||||
static HRESULT led1509306_req_set_led(int board, const struct led1509306_req_any *req);
|
||||
static HRESULT led1509306_req_set_disable_response(int board, const struct led1509306_req_any *req);
|
||||
static HRESULT led1509306_req_set_timeout(int board, const struct led1509306_req_any *req);
|
||||
|
||||
static char led1509306_board_num[8];
|
||||
static char led1509306_chip_num[5];
|
||||
static uint8_t led1509306_fw_ver;
|
||||
static uint16_t led1509306_fw_sum;
|
||||
static uint8_t led1509306_board_adr = 2;
|
||||
static uint8_t led1509306_host_adr = 1;
|
||||
|
||||
#define led1509306_nboards 2
|
||||
|
||||
typedef struct {
|
||||
CRITICAL_SECTION lock;
|
||||
struct uart boarduart;
|
||||
uint8_t written_bytes[520];
|
||||
uint8_t readable_bytes[520];
|
||||
bool enable_response;
|
||||
} _led1509306_per_board_vars;
|
||||
|
||||
_led1509306_per_board_vars led1509306_per_board_vars[led1509306_nboards];
|
||||
|
||||
HRESULT led1509306_hook_init(const struct led1509306_config *cfg)
|
||||
{
|
||||
assert(cfg != NULL);
|
||||
|
||||
if (!cfg->enable) {
|
||||
return S_FALSE;
|
||||
}
|
||||
|
||||
memcpy(led1509306_board_num, cfg->board_number, sizeof(led1509306_board_num));
|
||||
memcpy(led1509306_chip_num, cfg->chip_number, sizeof(led1509306_chip_num));
|
||||
led1509306_fw_ver = cfg->fw_ver;
|
||||
led1509306_fw_sum = cfg->fw_sum;
|
||||
|
||||
for (int i = 0; i < led1509306_nboards; i++)
|
||||
{
|
||||
_led1509306_per_board_vars *v = &led1509306_per_board_vars[i];
|
||||
|
||||
InitializeCriticalSection(&v->lock);
|
||||
|
||||
uart_init(&v->boarduart, 10 + i);
|
||||
v->boarduart.written.bytes = v->written_bytes;
|
||||
v->boarduart.written.nbytes = sizeof(v->written_bytes);
|
||||
v->boarduart.readable.bytes = v->readable_bytes;
|
||||
v->boarduart.readable.nbytes = sizeof(v->readable_bytes);
|
||||
|
||||
v->enable_response = true;
|
||||
}
|
||||
|
||||
return iohook_push_handler(led1509306_handle_irp);
|
||||
}
|
||||
|
||||
static HRESULT led1509306_handle_irp(struct irp *irp)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
assert(irp != NULL);
|
||||
|
||||
for (int i = 0; i < led1509306_nboards; i++)
|
||||
{
|
||||
_led1509306_per_board_vars *v = &led1509306_per_board_vars[i];
|
||||
struct uart *boarduart = &v->boarduart;
|
||||
|
||||
if (uart_match_irp(boarduart, irp))
|
||||
{
|
||||
CRITICAL_SECTION lock = v->lock;
|
||||
|
||||
EnterCriticalSection(&lock);
|
||||
hr = led1509306_handle_irp_locked(i, irp);
|
||||
LeaveCriticalSection(&lock);
|
||||
|
||||
return hr;
|
||||
}
|
||||
}
|
||||
|
||||
return iohook_invoke_next(irp);
|
||||
}
|
||||
|
||||
static HRESULT led1509306_handle_irp_locked(int board, struct irp *irp)
|
||||
{
|
||||
struct led1509306_req_any req;
|
||||
struct iobuf req_iobuf;
|
||||
HRESULT hr;
|
||||
|
||||
struct uart *boarduart = &led1509306_per_board_vars[board].boarduart;
|
||||
|
||||
hr = uart_handle_irp(boarduart, irp);
|
||||
|
||||
if (FAILED(hr) || irp->op != IRP_OP_WRITE) {
|
||||
return hr;
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
#if 0
|
||||
dprintf("TX Buffer:\n");
|
||||
dump_iobuf(&boarduart->written);
|
||||
#endif
|
||||
|
||||
req_iobuf.bytes = (byte*)&req;
|
||||
req_iobuf.nbytes = sizeof(req.hdr) + sizeof(req.cmd) + sizeof(req.payload);
|
||||
req_iobuf.pos = 0;
|
||||
|
||||
hr = led1509306_frame_decode(&req_iobuf, &boarduart->written);
|
||||
|
||||
if (hr != S_OK) {
|
||||
if (FAILED(hr)) {
|
||||
dprintf("Chunithm LED Strip: Deframe error: %x\n", (int) hr);
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
#if 0
|
||||
dprintf("Deframe Buffer:\n");
|
||||
dump_iobuf(&req_iobuf);
|
||||
#endif
|
||||
|
||||
hr = led1509306_req_dispatch(board, &req);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
dprintf("Chunithm LED Strip: Processing error: %x\n", (int) hr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static HRESULT led1509306_req_dispatch(int board, const struct led1509306_req_any *req)
|
||||
{
|
||||
switch (req->cmd) {
|
||||
case LED_15093_06_CMD_RESET:
|
||||
return led1509306_req_reset(board, req);
|
||||
|
||||
case LED_15093_06_CMD_BOARD_INFO:
|
||||
return led1509306_req_get_board_info(board);
|
||||
|
||||
case LED_15093_06_CMD_FW_SUM:
|
||||
return led1509306_req_get_fw_sum(board);
|
||||
|
||||
case LED_15093_06_CMD_PROTOCOL_VER:
|
||||
return led1509306_req_get_protocol_ver(board);
|
||||
|
||||
case LED_15093_06_CMD_BOARD_STATUS:
|
||||
return led1509306_req_get_board_status(board);
|
||||
|
||||
case LED_15093_06_CMD_SET_LED:
|
||||
return led1509306_req_set_led(board, req);
|
||||
|
||||
case LED_15093_06_CMD_SET_DISABLE_RESPONSE:
|
||||
return led1509306_req_set_disable_response(board, req);
|
||||
|
||||
case LED_15093_06_CMD_SET_TIMEOUT:
|
||||
return led1509306_req_set_timeout(board, req);
|
||||
|
||||
default:
|
||||
dprintf("Chunithm LED Strip: Unhandled command %02x\n", req->cmd);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
|
||||
static HRESULT led1509306_req_reset(int board, const struct led1509306_req_any *req)
|
||||
{
|
||||
dprintf("Chunithm LED Strip: Reset (board %u, type %02x)\n", board, req->payload[0]);
|
||||
|
||||
if (req->payload[0] != 0xd9)
|
||||
dprintf("Chunithm LED Strip: Warning -- Unknown reset type %02x\n", req->payload[0]);
|
||||
|
||||
led1509306_per_board_vars[board].enable_response = true;
|
||||
|
||||
struct led1509306_resp_any resp;
|
||||
|
||||
memset(&resp, 0, sizeof(resp));
|
||||
resp.hdr.sync = LED_15093_06_FRAME_SYNC;
|
||||
resp.hdr.dest_adr = led1509306_host_adr;
|
||||
resp.hdr.src_adr = led1509306_board_adr;
|
||||
resp.hdr.nbytes = 3;
|
||||
|
||||
resp.status = 1;
|
||||
resp.cmd = LED_15093_06_CMD_RESET;
|
||||
resp.report = 1;
|
||||
|
||||
return led1509306_frame_encode(&led1509306_per_board_vars[board].boarduart.readable, &resp, sizeof(resp.hdr) + resp.hdr.nbytes);
|
||||
}
|
||||
|
||||
static HRESULT led1509306_req_get_board_info(int board)
|
||||
{
|
||||
dprintf("Chunithm LED Strip: Get board info (board %u)\n", board);
|
||||
|
||||
struct led1509306_resp_board_info resp;
|
||||
|
||||
memset(&resp, 0, sizeof(resp));
|
||||
resp.hdr.sync = LED_15093_06_FRAME_SYNC;
|
||||
resp.hdr.dest_adr = led1509306_host_adr;
|
||||
resp.hdr.src_adr = led1509306_board_adr;
|
||||
resp.hdr.nbytes = sizeof(resp.data) + 3;
|
||||
|
||||
resp.status = 1;
|
||||
resp.cmd = LED_15093_06_CMD_BOARD_INFO;
|
||||
resp.report = 1;
|
||||
|
||||
memcpy(resp.data.board_num, led1509306_board_num, sizeof(resp.data.board_num));
|
||||
resp.data._0a = 0x0a;
|
||||
memcpy(resp.data.chip_num, led1509306_chip_num, sizeof(resp.data.chip_num));
|
||||
resp.data._ff = 0xff;
|
||||
resp.data.fw_ver = led1509306_fw_ver;
|
||||
|
||||
return led1509306_frame_encode(&led1509306_per_board_vars[board].boarduart.readable, &resp, sizeof(resp.hdr) + resp.hdr.nbytes);
|
||||
}
|
||||
|
||||
static HRESULT led1509306_req_get_fw_sum(int board)
|
||||
{
|
||||
dprintf("Chunithm LED Strip: Get firmware checksum (board %u)\n", board);
|
||||
|
||||
struct led1509306_resp_any resp;
|
||||
|
||||
memset(&resp, 0, sizeof(resp));
|
||||
resp.hdr.sync = LED_15093_06_FRAME_SYNC;
|
||||
resp.hdr.dest_adr = led1509306_host_adr;
|
||||
resp.hdr.src_adr = led1509306_board_adr;
|
||||
resp.hdr.nbytes = 2 + 3;
|
||||
|
||||
resp.status = 1;
|
||||
resp.cmd = LED_15093_06_CMD_FW_SUM;
|
||||
resp.report = 1;
|
||||
|
||||
resp.data[0] = (led1509306_fw_sum >> 8) & 0xff;
|
||||
resp.data[1] = led1509306_fw_sum & 0xff;
|
||||
|
||||
return led1509306_frame_encode(&led1509306_per_board_vars[board].boarduart.readable, &resp, sizeof(resp.hdr) + resp.hdr.nbytes);
|
||||
}
|
||||
|
||||
static HRESULT led1509306_req_get_protocol_ver(int board)
|
||||
{
|
||||
dprintf("Chunithm LED Strip: Get protocol version (board %u)\n", board);
|
||||
|
||||
struct led1509306_resp_any resp;
|
||||
|
||||
memset(&resp, 0, sizeof(resp));
|
||||
resp.hdr.sync = LED_15093_06_FRAME_SYNC;
|
||||
resp.hdr.dest_adr = led1509306_host_adr;
|
||||
resp.hdr.src_adr = led1509306_board_adr;
|
||||
resp.hdr.nbytes = 3 + 3;
|
||||
|
||||
resp.status = 1;
|
||||
resp.cmd = LED_15093_06_CMD_PROTOCOL_VER;
|
||||
resp.report = 1;
|
||||
|
||||
resp.data[0] = 1;
|
||||
resp.data[1] = 1;
|
||||
resp.data[2] = 4;
|
||||
|
||||
return led1509306_frame_encode(&led1509306_per_board_vars[board].boarduart.readable, &resp, sizeof(resp.hdr) + resp.hdr.nbytes);
|
||||
}
|
||||
|
||||
static HRESULT led1509306_req_get_board_status(int board)
|
||||
{
|
||||
dprintf("Chunithm LED Strip: Get board status (board %u)\n", board);
|
||||
|
||||
struct led1509306_resp_any resp;
|
||||
|
||||
memset(&resp, 0, sizeof(resp));
|
||||
resp.hdr.sync = LED_15093_06_FRAME_SYNC;
|
||||
resp.hdr.dest_adr = led1509306_host_adr;
|
||||
resp.hdr.src_adr = led1509306_board_adr;
|
||||
resp.hdr.nbytes = 4 + 3;
|
||||
|
||||
resp.status = 1;
|
||||
resp.cmd = LED_15093_06_CMD_BOARD_STATUS;
|
||||
resp.report = 1;
|
||||
|
||||
resp.data[0] = 0;
|
||||
resp.data[1] = 0;
|
||||
resp.data[2] = 0;
|
||||
resp.data[3] = 0;
|
||||
|
||||
return led1509306_frame_encode(&led1509306_per_board_vars[board].boarduart.readable, &resp, sizeof(resp.hdr) + resp.hdr.nbytes);
|
||||
}
|
||||
|
||||
static HRESULT led1509306_req_set_led(int board, const struct led1509306_req_any *req)
|
||||
{
|
||||
// dprintf("Chunithm LED Strip: Set LED (board %u)\n", board);
|
||||
|
||||
if (!led1509306_per_board_vars[board].enable_response)
|
||||
return S_OK;
|
||||
|
||||
struct led1509306_resp_any resp;
|
||||
|
||||
memset(&resp, 0, sizeof(resp));
|
||||
resp.hdr.sync = LED_15093_06_FRAME_SYNC;
|
||||
resp.hdr.dest_adr = led1509306_host_adr;
|
||||
resp.hdr.src_adr = led1509306_board_adr;
|
||||
resp.hdr.nbytes = 3;
|
||||
|
||||
resp.status = 1;
|
||||
resp.cmd = LED_15093_06_CMD_SET_LED;
|
||||
resp.report = 1;
|
||||
|
||||
return led1509306_frame_encode(&led1509306_per_board_vars[board].boarduart.readable, &resp, sizeof(resp.hdr) + resp.hdr.nbytes);
|
||||
}
|
||||
|
||||
static HRESULT led1509306_req_set_disable_response(int board, const struct led1509306_req_any *req)
|
||||
{
|
||||
dprintf("Chunithm LED Strip: Disable LED responses (board %u)\n", board);
|
||||
|
||||
led1509306_per_board_vars[board].enable_response = !req->payload[0];
|
||||
|
||||
struct led1509306_resp_any resp;
|
||||
|
||||
memset(&resp, 0, sizeof(resp));
|
||||
resp.hdr.sync = LED_15093_06_FRAME_SYNC;
|
||||
resp.hdr.dest_adr = led1509306_host_adr;
|
||||
resp.hdr.src_adr = led1509306_board_adr;
|
||||
resp.hdr.nbytes = 1 + 3;
|
||||
|
||||
resp.status = 1;
|
||||
resp.cmd = LED_15093_06_CMD_SET_DISABLE_RESPONSE;
|
||||
resp.report = 1;
|
||||
|
||||
resp.data[0] = req->payload[0];
|
||||
|
||||
return led1509306_frame_encode(&led1509306_per_board_vars[board].boarduart.readable, &resp, sizeof(resp.hdr) + resp.hdr.nbytes);
|
||||
}
|
||||
|
||||
static HRESULT led1509306_req_set_timeout(int board, const struct led1509306_req_any *req)
|
||||
{
|
||||
dprintf("Chunithm LED Strip: Set timeout (board %u)\n", board);
|
||||
|
||||
// not actually implemented, but respond correctly anyway
|
||||
|
||||
struct led1509306_resp_any resp;
|
||||
|
||||
memset(&resp, 0, sizeof(resp));
|
||||
resp.hdr.sync = LED_15093_06_FRAME_SYNC;
|
||||
resp.hdr.dest_adr = led1509306_host_adr;
|
||||
resp.hdr.src_adr = led1509306_board_adr;
|
||||
resp.hdr.nbytes = 2 + 3;
|
||||
|
||||
resp.status = 1;
|
||||
resp.cmd = LED_15093_06_CMD_SET_TIMEOUT;
|
||||
resp.report = 1;
|
||||
|
||||
resp.data[0] = req->payload[0];
|
||||
resp.data[1] = req->payload[1];
|
||||
|
||||
return led1509306_frame_encode(&led1509306_per_board_vars[board].boarduart.readable, &resp, sizeof(resp.hdr) + resp.hdr.nbytes);
|
||||
}
|
@ -1,15 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
struct led1509306_config {
|
||||
bool enable;
|
||||
char board_number[8];
|
||||
char chip_number[5];
|
||||
uint8_t fw_ver;
|
||||
uint16_t fw_sum;
|
||||
};
|
||||
|
||||
HRESULT led1509306_hook_init(const struct led1509306_config *cfg);
|
@ -30,7 +30,5 @@ shared_library(
|
||||
'jvs.h',
|
||||
'slider.c',
|
||||
'slider.h',
|
||||
'led1509306.c',
|
||||
'led1509306.h',
|
||||
],
|
||||
)
|
||||
|
@ -71,34 +71,76 @@ void slider_config_load(struct slider_config *cfg, const wchar_t *filename)
|
||||
cfg->enable = GetPrivateProfileIntW(L"slider", L"enable", 1, filename);
|
||||
}
|
||||
|
||||
void led1509306_config_load(struct led1509306_config *cfg, const wchar_t *filename)
|
||||
void led15093_config_load(struct led15093_config *cfg, const wchar_t *filename)
|
||||
{
|
||||
assert(cfg != NULL);
|
||||
assert(filename != NULL);
|
||||
|
||||
wchar_t tmpstr[16];
|
||||
|
||||
bool cvt_port;
|
||||
|
||||
memset(cfg->board_number, ' ', sizeof(cfg->board_number));
|
||||
memset(cfg->chip_number, ' ', sizeof(cfg->chip_number));
|
||||
|
||||
cfg->enable = GetPrivateProfileIntW(L"ledstrip", L"enable", 1, filename);
|
||||
cfg->cvt_port = GetPrivateProfileIntW(L"ledstrip", L"cvt_port", 0, filename);
|
||||
cfg->fw_ver = GetPrivateProfileIntW(L"ledstrip", L"fw_ver", 0x90, filename);
|
||||
cfg->fw_sum = GetPrivateProfileIntW(L"ledstrip", L"fw_sum", 0xadf7, filename);
|
||||
|
||||
GetPrivateProfileStringW(L"ledstrip", L"board_number", L"15093-06", tmpstr, _countof(tmpstr), filename);
|
||||
memset(cfg->boot_chip_number, ' ', sizeof(cfg->boot_chip_number));
|
||||
|
||||
cfg->enable = GetPrivateProfileIntW(L"led15093", L"enable", 1, filename);
|
||||
cvt_port = GetPrivateProfileIntW(L"led15093", L"cvtPort", 0, filename);
|
||||
|
||||
if (!cvt_port) {
|
||||
// SP mode: COM20, COM21
|
||||
cfg->port_no[0] = 20;
|
||||
cfg->port_no[1] = 21;
|
||||
} else {
|
||||
// CVT mode: COM2, COM3
|
||||
cfg->port_no[0] = 2;
|
||||
cfg->port_no[1] = 3;
|
||||
}
|
||||
|
||||
cfg->high_baudrate = GetPrivateProfileIntW(L"led15093", L"highBaudrate", 0, filename);
|
||||
cfg->fw_ver = GetPrivateProfileIntW(L"led15093", L"fwVer", 0x90, filename);
|
||||
cfg->fw_sum = GetPrivateProfileIntW(L"led15093", L"fwSum", 0xadf7, filename);
|
||||
|
||||
GetPrivateProfileStringW(
|
||||
L"led15093",
|
||||
L"boardNumber",
|
||||
L"15093-06",
|
||||
tmpstr,
|
||||
_countof(tmpstr),
|
||||
filename);
|
||||
|
||||
size_t n = wcstombs(cfg->board_number, tmpstr, sizeof(cfg->board_number));
|
||||
for (int i = n; i < sizeof(cfg->board_number); i++)
|
||||
{
|
||||
cfg->board_number[i] = ' ';
|
||||
}
|
||||
|
||||
GetPrivateProfileStringW(L"ledstrip", L"chip_number", L"6710 ", tmpstr, _countof(tmpstr), filename);
|
||||
|
||||
GetPrivateProfileStringW(
|
||||
L"led15093",
|
||||
L"chipNumber",
|
||||
L"6710 ",
|
||||
tmpstr,
|
||||
_countof(tmpstr),
|
||||
filename);
|
||||
|
||||
n = wcstombs(cfg->chip_number, tmpstr, sizeof(cfg->chip_number));
|
||||
for (int i = n; i < sizeof(cfg->chip_number); i++)
|
||||
{
|
||||
cfg->chip_number[i] = ' ';
|
||||
}
|
||||
}
|
||||
|
||||
GetPrivateProfileStringW(
|
||||
L"led15093",
|
||||
L"bootChipNumber",
|
||||
L"6709 ",
|
||||
tmpstr,
|
||||
_countof(tmpstr),
|
||||
filename);
|
||||
|
||||
n = wcstombs(cfg->boot_chip_number, tmpstr, sizeof(cfg->boot_chip_number));
|
||||
for (int i = n; i < sizeof(cfg->boot_chip_number); i++)
|
||||
{
|
||||
cfg->boot_chip_number[i] = ' ';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -118,5 +160,5 @@ void chusan_hook_config_load(
|
||||
gfx_config_load(&cfg->gfx, filename);
|
||||
chuni_dll_config_load(&cfg->dll, filename);
|
||||
slider_config_load(&cfg->slider, filename);
|
||||
led1509306_config_load(&cfg->led1509306, filename);
|
||||
led15093_config_load(&cfg->led15093, filename);
|
||||
}
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include <stddef.h>
|
||||
|
||||
#include "board/config.h"
|
||||
#include "board/led15093.h"
|
||||
|
||||
#include "hooklib/dvd.h"
|
||||
|
||||
@ -12,7 +13,6 @@
|
||||
|
||||
#include "chusanhook/chuni-dll.h"
|
||||
#include "chusanhook/slider.h"
|
||||
#include "chusanhook/led1509306.h"
|
||||
|
||||
struct chusan_hook_config {
|
||||
struct platform_config platform;
|
||||
@ -22,7 +22,7 @@ struct chusan_hook_config {
|
||||
struct gfx_config gfx;
|
||||
struct chuni_dll_config dll;
|
||||
struct slider_config slider;
|
||||
struct led1509306_config led1509306;
|
||||
struct led15093_config led15093;
|
||||
};
|
||||
|
||||
void chuni_dll_config_load(
|
||||
|
@ -11,7 +11,6 @@
|
||||
#include "chusanhook/config.h"
|
||||
#include "chusanhook/io4.h"
|
||||
#include "chusanhook/slider.h"
|
||||
#include "chusanhook/led1509306.h"
|
||||
|
||||
#include "chuniio/chuniio.h"
|
||||
|
||||
@ -100,7 +99,7 @@ static DWORD CALLBACK chusan_pre_startup(void)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
hr = led1509306_hook_init(&chusan_hook_cfg.led1509306);
|
||||
hr = led15093_hook_init(&chusan_hook_cfg.led15093, 20, 21);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
goto fail;
|
||||
|
@ -1,397 +0,0 @@
|
||||
/*
|
||||
SEGA 837-15093-06 LED controller emulator
|
||||
|
||||
Credits:
|
||||
|
||||
somewhatlurker, skogaby
|
||||
*/
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <process.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "board/led1509306-cmd.h"
|
||||
#include "board/led1509306-frame.h"
|
||||
|
||||
#include "chusanhook/led1509306.h"
|
||||
|
||||
#include "hook/iobuf.h"
|
||||
#include "hook/iohook.h"
|
||||
|
||||
#include "hooklib/uart.h"
|
||||
|
||||
#include "util/dprintf.h"
|
||||
#include "util/dump.h"
|
||||
|
||||
static HRESULT led1509306_handle_irp(struct irp *irp);
|
||||
static HRESULT led1509306_handle_irp_locked(int board, struct irp *irp);
|
||||
|
||||
static HRESULT led1509306_req_dispatch(int board, const struct led1509306_req_any *req);
|
||||
static HRESULT led1509306_req_reset(int board, const struct led1509306_req_any *req);
|
||||
static HRESULT led1509306_req_get_board_info(int board);
|
||||
static HRESULT led1509306_req_get_fw_sum(int board);
|
||||
static HRESULT led1509306_req_get_protocol_ver(int board);
|
||||
static HRESULT led1509306_req_get_board_status(int board);
|
||||
static HRESULT led1509306_req_set_led(int board, const struct led1509306_req_any *req);
|
||||
static HRESULT led1509306_req_set_disable_response(int board, const struct led1509306_req_any *req);
|
||||
static HRESULT led1509306_req_set_timeout(int board, const struct led1509306_req_any *req);
|
||||
|
||||
static char led1509306_board_num[8];
|
||||
static char led1509306_chip_num[5];
|
||||
static uint8_t led1509306_fw_ver;
|
||||
static uint16_t led1509306_fw_sum;
|
||||
static uint8_t led1509306_board_adr = 2;
|
||||
static uint8_t led1509306_host_adr = 1;
|
||||
|
||||
#define led1509306_nboards 2
|
||||
|
||||
typedef struct {
|
||||
CRITICAL_SECTION lock;
|
||||
struct uart boarduart;
|
||||
uint8_t written_bytes[520];
|
||||
uint8_t readable_bytes[520];
|
||||
bool enable_response;
|
||||
} _led1509306_per_board_vars;
|
||||
|
||||
_led1509306_per_board_vars led1509306_per_board_vars[led1509306_nboards];
|
||||
|
||||
HRESULT led1509306_hook_init(const struct led1509306_config *cfg)
|
||||
{
|
||||
assert(cfg != NULL);
|
||||
|
||||
if (!cfg->enable) {
|
||||
return S_FALSE;
|
||||
}
|
||||
|
||||
memcpy(led1509306_board_num, cfg->board_number, sizeof(led1509306_board_num));
|
||||
memcpy(led1509306_chip_num, cfg->chip_number, sizeof(led1509306_chip_num));
|
||||
led1509306_fw_ver = cfg->fw_ver;
|
||||
led1509306_fw_sum = cfg->fw_sum;
|
||||
|
||||
int com_ports[2];
|
||||
|
||||
if (!cfg->cvt_port) {
|
||||
// SP mode: COM20, COM21
|
||||
com_ports[0] = 20;
|
||||
com_ports[1] = 21;
|
||||
} else {
|
||||
// CVT mode: COM2, COM3
|
||||
com_ports[0] = 2;
|
||||
com_ports[1] = 3;
|
||||
}
|
||||
|
||||
for (int i = 0; i < led1509306_nboards; i++)
|
||||
{
|
||||
_led1509306_per_board_vars *v = &led1509306_per_board_vars[i];
|
||||
|
||||
InitializeCriticalSection(&v->lock);
|
||||
|
||||
uart_init(&v->boarduart, com_ports[i]);
|
||||
v->boarduart.written.bytes = v->written_bytes;
|
||||
v->boarduart.written.nbytes = sizeof(v->written_bytes);
|
||||
v->boarduart.readable.bytes = v->readable_bytes;
|
||||
v->boarduart.readable.nbytes = sizeof(v->readable_bytes);
|
||||
|
||||
v->enable_response = true;
|
||||
}
|
||||
|
||||
return iohook_push_handler(led1509306_handle_irp);
|
||||
}
|
||||
|
||||
static HRESULT led1509306_handle_irp(struct irp *irp)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
assert(irp != NULL);
|
||||
|
||||
for (int i = 0; i < led1509306_nboards; i++)
|
||||
{
|
||||
_led1509306_per_board_vars *v = &led1509306_per_board_vars[i];
|
||||
struct uart *boarduart = &v->boarduart;
|
||||
|
||||
if (uart_match_irp(boarduart, irp))
|
||||
{
|
||||
CRITICAL_SECTION lock = v->lock;
|
||||
|
||||
EnterCriticalSection(&lock);
|
||||
hr = led1509306_handle_irp_locked(i, irp);
|
||||
LeaveCriticalSection(&lock);
|
||||
|
||||
return hr;
|
||||
}
|
||||
}
|
||||
|
||||
return iohook_invoke_next(irp);
|
||||
}
|
||||
|
||||
static HRESULT led1509306_handle_irp_locked(int board, struct irp *irp)
|
||||
{
|
||||
struct led1509306_req_any req;
|
||||
struct iobuf req_iobuf;
|
||||
HRESULT hr;
|
||||
|
||||
struct uart *boarduart = &led1509306_per_board_vars[board].boarduart;
|
||||
|
||||
hr = uart_handle_irp(boarduart, irp);
|
||||
|
||||
if (FAILED(hr) || irp->op != IRP_OP_WRITE) {
|
||||
return hr;
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
#if 0
|
||||
dprintf("TX Buffer:\n");
|
||||
dump_iobuf(&boarduart->written);
|
||||
#endif
|
||||
|
||||
req_iobuf.bytes = (byte*)&req;
|
||||
req_iobuf.nbytes = sizeof(req.hdr) + sizeof(req.cmd) + sizeof(req.payload);
|
||||
req_iobuf.pos = 0;
|
||||
|
||||
hr = led1509306_frame_decode(&req_iobuf, &boarduart->written);
|
||||
|
||||
if (hr != S_OK) {
|
||||
if (FAILED(hr)) {
|
||||
dprintf("Chunithm LED Strip: Deframe error: %x\n", (int) hr);
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
#if 0
|
||||
dprintf("Deframe Buffer:\n");
|
||||
dump_iobuf(&req_iobuf);
|
||||
#endif
|
||||
|
||||
hr = led1509306_req_dispatch(board, &req);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
dprintf("Chunithm LED Strip: Processing error: %x\n", (int) hr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static HRESULT led1509306_req_dispatch(int board, const struct led1509306_req_any *req)
|
||||
{
|
||||
switch (req->cmd) {
|
||||
case LED_15093_06_CMD_RESET:
|
||||
return led1509306_req_reset(board, req);
|
||||
|
||||
case LED_15093_06_CMD_BOARD_INFO:
|
||||
return led1509306_req_get_board_info(board);
|
||||
|
||||
case LED_15093_06_CMD_FW_SUM:
|
||||
return led1509306_req_get_fw_sum(board);
|
||||
|
||||
case LED_15093_06_CMD_PROTOCOL_VER:
|
||||
return led1509306_req_get_protocol_ver(board);
|
||||
|
||||
case LED_15093_06_CMD_BOARD_STATUS:
|
||||
return led1509306_req_get_board_status(board);
|
||||
|
||||
case LED_15093_06_CMD_SET_LED:
|
||||
return led1509306_req_set_led(board, req);
|
||||
|
||||
case LED_15093_06_CMD_SET_DISABLE_RESPONSE:
|
||||
return led1509306_req_set_disable_response(board, req);
|
||||
|
||||
case LED_15093_06_CMD_SET_TIMEOUT:
|
||||
return led1509306_req_set_timeout(board, req);
|
||||
|
||||
default:
|
||||
dprintf("Chunithm LED Strip: Unhandled command %02x\n", req->cmd);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
|
||||
static HRESULT led1509306_req_reset(int board, const struct led1509306_req_any *req)
|
||||
{
|
||||
dprintf("Chunithm LED Strip: Reset (board %u, type %02x)\n", board, req->payload[0]);
|
||||
|
||||
if (req->payload[0] != 0xd9)
|
||||
dprintf("Chunithm LED Strip: Warning -- Unknown reset type %02x\n", req->payload[0]);
|
||||
|
||||
led1509306_per_board_vars[board].enable_response = true;
|
||||
|
||||
struct led1509306_resp_any resp;
|
||||
|
||||
memset(&resp, 0, sizeof(resp));
|
||||
resp.hdr.sync = LED_15093_06_FRAME_SYNC;
|
||||
resp.hdr.dest_adr = led1509306_host_adr;
|
||||
resp.hdr.src_adr = led1509306_board_adr;
|
||||
resp.hdr.nbytes = 3;
|
||||
|
||||
resp.status = 1;
|
||||
resp.cmd = LED_15093_06_CMD_RESET;
|
||||
resp.report = 1;
|
||||
|
||||
return led1509306_frame_encode(&led1509306_per_board_vars[board].boarduart.readable, &resp, sizeof(resp.hdr) + resp.hdr.nbytes);
|
||||
}
|
||||
|
||||
static HRESULT led1509306_req_get_board_info(int board)
|
||||
{
|
||||
dprintf("Chunithm LED Strip: Get board info (board %u)\n", board);
|
||||
|
||||
struct led1509306_resp_board_info resp;
|
||||
|
||||
memset(&resp, 0, sizeof(resp));
|
||||
resp.hdr.sync = LED_15093_06_FRAME_SYNC;
|
||||
resp.hdr.dest_adr = led1509306_host_adr;
|
||||
resp.hdr.src_adr = led1509306_board_adr;
|
||||
resp.hdr.nbytes = sizeof(resp.data) + 3;
|
||||
|
||||
resp.status = 1;
|
||||
resp.cmd = LED_15093_06_CMD_BOARD_INFO;
|
||||
resp.report = 1;
|
||||
|
||||
memcpy(resp.data.board_num, led1509306_board_num, sizeof(resp.data.board_num));
|
||||
resp.data._0a = 0x0a;
|
||||
memcpy(resp.data.chip_num, led1509306_chip_num, sizeof(resp.data.chip_num));
|
||||
resp.data._ff = 0xff;
|
||||
resp.data.fw_ver = led1509306_fw_ver;
|
||||
|
||||
return led1509306_frame_encode(&led1509306_per_board_vars[board].boarduart.readable, &resp, sizeof(resp.hdr) + resp.hdr.nbytes);
|
||||
}
|
||||
|
||||
static HRESULT led1509306_req_get_fw_sum(int board)
|
||||
{
|
||||
dprintf("Chunithm LED Strip: Get firmware checksum (board %u)\n", board);
|
||||
|
||||
struct led1509306_resp_any resp;
|
||||
|
||||
memset(&resp, 0, sizeof(resp));
|
||||
resp.hdr.sync = LED_15093_06_FRAME_SYNC;
|
||||
resp.hdr.dest_adr = led1509306_host_adr;
|
||||
resp.hdr.src_adr = led1509306_board_adr;
|
||||
resp.hdr.nbytes = 2 + 3;
|
||||
|
||||
resp.status = 1;
|
||||
resp.cmd = LED_15093_06_CMD_FW_SUM;
|
||||
resp.report = 1;
|
||||
|
||||
resp.data[0] = (led1509306_fw_sum >> 8) & 0xff;
|
||||
resp.data[1] = led1509306_fw_sum & 0xff;
|
||||
|
||||
return led1509306_frame_encode(&led1509306_per_board_vars[board].boarduart.readable, &resp, sizeof(resp.hdr) + resp.hdr.nbytes);
|
||||
}
|
||||
|
||||
static HRESULT led1509306_req_get_protocol_ver(int board)
|
||||
{
|
||||
dprintf("Chunithm LED Strip: Get protocol version (board %u)\n", board);
|
||||
|
||||
struct led1509306_resp_any resp;
|
||||
|
||||
memset(&resp, 0, sizeof(resp));
|
||||
resp.hdr.sync = LED_15093_06_FRAME_SYNC;
|
||||
resp.hdr.dest_adr = led1509306_host_adr;
|
||||
resp.hdr.src_adr = led1509306_board_adr;
|
||||
resp.hdr.nbytes = 3 + 3;
|
||||
|
||||
resp.status = 1;
|
||||
resp.cmd = LED_15093_06_CMD_PROTOCOL_VER;
|
||||
resp.report = 1;
|
||||
|
||||
resp.data[0] = 1;
|
||||
resp.data[1] = 1;
|
||||
resp.data[2] = 4;
|
||||
|
||||
return led1509306_frame_encode(&led1509306_per_board_vars[board].boarduart.readable, &resp, sizeof(resp.hdr) + resp.hdr.nbytes);
|
||||
}
|
||||
|
||||
static HRESULT led1509306_req_get_board_status(int board)
|
||||
{
|
||||
dprintf("Chunithm LED Strip: Get board status (board %u)\n", board);
|
||||
|
||||
struct led1509306_resp_any resp;
|
||||
|
||||
memset(&resp, 0, sizeof(resp));
|
||||
resp.hdr.sync = LED_15093_06_FRAME_SYNC;
|
||||
resp.hdr.dest_adr = led1509306_host_adr;
|
||||
resp.hdr.src_adr = led1509306_board_adr;
|
||||
resp.hdr.nbytes = 4 + 3;
|
||||
|
||||
resp.status = 1;
|
||||
resp.cmd = LED_15093_06_CMD_BOARD_STATUS;
|
||||
resp.report = 1;
|
||||
|
||||
resp.data[0] = 0;
|
||||
resp.data[1] = 0;
|
||||
resp.data[2] = 0;
|
||||
resp.data[3] = 0;
|
||||
|
||||
return led1509306_frame_encode(&led1509306_per_board_vars[board].boarduart.readable, &resp, sizeof(resp.hdr) + resp.hdr.nbytes);
|
||||
}
|
||||
|
||||
static HRESULT led1509306_req_set_led(int board, const struct led1509306_req_any *req)
|
||||
{
|
||||
// dprintf("Chunithm LED Strip: Set LED (board %u)\n", board);
|
||||
|
||||
if (!led1509306_per_board_vars[board].enable_response)
|
||||
return S_OK;
|
||||
|
||||
struct led1509306_resp_any resp;
|
||||
|
||||
memset(&resp, 0, sizeof(resp));
|
||||
resp.hdr.sync = LED_15093_06_FRAME_SYNC;
|
||||
resp.hdr.dest_adr = led1509306_host_adr;
|
||||
resp.hdr.src_adr = led1509306_board_adr;
|
||||
resp.hdr.nbytes = 3;
|
||||
|
||||
resp.status = 1;
|
||||
resp.cmd = LED_15093_06_CMD_SET_LED;
|
||||
resp.report = 1;
|
||||
|
||||
return led1509306_frame_encode(&led1509306_per_board_vars[board].boarduart.readable, &resp, sizeof(resp.hdr) + resp.hdr.nbytes);
|
||||
}
|
||||
|
||||
static HRESULT led1509306_req_set_disable_response(int board, const struct led1509306_req_any *req)
|
||||
{
|
||||
dprintf("Chunithm LED Strip: Disable LED responses (board %u)\n", board);
|
||||
|
||||
led1509306_per_board_vars[board].enable_response = !req->payload[0];
|
||||
|
||||
struct led1509306_resp_any resp;
|
||||
|
||||
memset(&resp, 0, sizeof(resp));
|
||||
resp.hdr.sync = LED_15093_06_FRAME_SYNC;
|
||||
resp.hdr.dest_adr = led1509306_host_adr;
|
||||
resp.hdr.src_adr = led1509306_board_adr;
|
||||
resp.hdr.nbytes = 1 + 3;
|
||||
|
||||
resp.status = 1;
|
||||
resp.cmd = LED_15093_06_CMD_SET_DISABLE_RESPONSE;
|
||||
resp.report = 1;
|
||||
|
||||
resp.data[0] = req->payload[0];
|
||||
|
||||
return led1509306_frame_encode(&led1509306_per_board_vars[board].boarduart.readable, &resp, sizeof(resp.hdr) + resp.hdr.nbytes);
|
||||
}
|
||||
|
||||
static HRESULT led1509306_req_set_timeout(int board, const struct led1509306_req_any *req)
|
||||
{
|
||||
dprintf("Chunithm LED Strip: Set timeout (board %u)\n", board);
|
||||
|
||||
// not actually implemented, but respond correctly anyway
|
||||
|
||||
struct led1509306_resp_any resp;
|
||||
|
||||
memset(&resp, 0, sizeof(resp));
|
||||
resp.hdr.sync = LED_15093_06_FRAME_SYNC;
|
||||
resp.hdr.dest_adr = led1509306_host_adr;
|
||||
resp.hdr.src_adr = led1509306_board_adr;
|
||||
resp.hdr.nbytes = 2 + 3;
|
||||
|
||||
resp.status = 1;
|
||||
resp.cmd = LED_15093_06_CMD_SET_TIMEOUT;
|
||||
resp.report = 1;
|
||||
|
||||
resp.data[0] = req->payload[0];
|
||||
resp.data[1] = req->payload[1];
|
||||
|
||||
return led1509306_frame_encode(&led1509306_per_board_vars[board].boarduart.readable, &resp, sizeof(resp.hdr) + resp.hdr.nbytes);
|
||||
}
|
@ -28,7 +28,5 @@ shared_library(
|
||||
'io4.h',
|
||||
'slider.c',
|
||||
'slider.h',
|
||||
'led1509306.c',
|
||||
'led1509306.h',
|
||||
],
|
||||
)
|
||||
|
4
dist/chuni/segatools.ini
vendored
4
dist/chuni/segatools.ini
vendored
@ -38,6 +38,10 @@ monitor=0
|
||||
; Leave empty if you want to use Segatools built-in keyboard input.
|
||||
path=
|
||||
|
||||
[led15093]
|
||||
; 837-15093-06 LED strip emulation setting.
|
||||
enable=1
|
||||
|
||||
[chuniio]
|
||||
; To use a custom Chunithm IO DLL enter its path here.
|
||||
; Leave empty if you want to use Segatools built-in keyboard input.
|
||||
|
39
dist/chusan/segatools.ini
vendored
39
dist/chusan/segatools.ini
vendored
@ -44,7 +44,7 @@ enable=1
|
||||
; LAN Install: If multiple machines are present on the same LAN then set
|
||||
; this to 1 on exactly one machine and set this to 0 on all others.
|
||||
dipsw1=1
|
||||
; Monitor type: 0 = 120FPS, 1 = 60FPS
|
||||
; Monitor type: 0 = 120FPS (SP), 1 = 60FPS (CVT)
|
||||
dipsw2=1
|
||||
; Aime reader hardware type: 0 = SP, 1 = CVT
|
||||
dipsw3=1
|
||||
@ -57,6 +57,18 @@ framed=1
|
||||
; Select the monitor to run the game on. (Fullscreen only, 0 =primary screen)
|
||||
monitor=0
|
||||
|
||||
[led15093]
|
||||
; 837-15093-06 LED strip emulation setting.
|
||||
enable=1
|
||||
; Set to 1 if running game in 60FPS (CVT) mode.
|
||||
cvtPort=0
|
||||
|
||||
[chuniio]
|
||||
; Uncomment this if you have custom chuniio implementation.
|
||||
; x86 chuniio to path32, x64 to path64. Both are necessary.
|
||||
;path32=
|
||||
;path64=
|
||||
|
||||
; -----------------------------------------------------------------------------
|
||||
; Input settings
|
||||
; -----------------------------------------------------------------------------
|
||||
@ -79,18 +91,12 @@ coin=0x33
|
||||
; Set to 0 for enable separate ir control. Deafult is space key.
|
||||
ir=0x20
|
||||
|
||||
[io4]
|
||||
enable=1
|
||||
|
||||
[ledstrip]
|
||||
; Set to 1 if running game in CVT mode.
|
||||
cvt_port=0
|
||||
|
||||
[chuniio]
|
||||
; Uncomment this if you have custom chuniio implementation.
|
||||
; x86 chuniio to path32, x64 to path64. Both are necessary.
|
||||
;path32=
|
||||
;path64=
|
||||
[ir]
|
||||
; Uncomment and complete the following sequence of settings to configure a
|
||||
; custom ir-cappable controller if you have one.
|
||||
;ir6=0x53
|
||||
; ... etc ...
|
||||
;ir1=0x53
|
||||
|
||||
[slider]
|
||||
; Enable slider emulation. If you have real AC slider, set this to 0.
|
||||
@ -116,10 +122,3 @@ cvt_port=0
|
||||
; Enable slider LED serial output. This follows OpeNITHM Serial LED Protocol.
|
||||
; eg. COM5
|
||||
;ledport=
|
||||
|
||||
[ir]
|
||||
; Uncomment and complete the following sequence of settings to configure a
|
||||
; custom ir-cappable controller if you have one.
|
||||
;ir6=0x53
|
||||
; ... etc ...
|
||||
;ir1=0x53
|
8
dist/fgo/segatools.ini
vendored
8
dist/fgo/segatools.ini
vendored
@ -58,10 +58,14 @@ enable=1
|
||||
[ftdi]
|
||||
; FTDI serial to usb adapter emulation for CABINET LED.
|
||||
enable=1
|
||||
; COM port number where the LED board is connected to.
|
||||
portNo=17
|
||||
|
||||
[ledstrip]
|
||||
; 837-15093-06 LED strip emulation setting.
|
||||
[led15093]
|
||||
; 837-15093-06 LED board emulation setting.
|
||||
enable=1
|
||||
; COM port number for the first LED board. Has to be the same as the FTDI port.
|
||||
portNo0=17
|
||||
|
||||
; -----------------------------------------------------------------------------
|
||||
; Input settings
|
||||
|
@ -32,10 +32,10 @@ void ftdi_config_load(struct ftdi_config *cfg, const wchar_t *filename)
|
||||
assert(filename != NULL);
|
||||
|
||||
cfg->enable = GetPrivateProfileIntW(L"ftdi", L"enable", 1, filename);
|
||||
cfg->port_no = GetPrivateProfileIntW(L"ftdi", L"port", 17, filename);
|
||||
cfg->port_no = GetPrivateProfileIntW(L"ftdi", L"portNo", 0, filename);
|
||||
}
|
||||
|
||||
void led1509306_config_load(struct led1509306_config *cfg, const wchar_t *filename)
|
||||
void led15093_config_load(struct led15093_config *cfg, const wchar_t *filename)
|
||||
{
|
||||
assert(cfg != NULL);
|
||||
assert(filename != NULL);
|
||||
@ -44,25 +44,56 @@ void led1509306_config_load(struct led1509306_config *cfg, const wchar_t *filena
|
||||
|
||||
memset(cfg->board_number, ' ', sizeof(cfg->board_number));
|
||||
memset(cfg->chip_number, ' ', sizeof(cfg->chip_number));
|
||||
|
||||
cfg->enable = GetPrivateProfileIntW(L"ledstrip", L"enable", 1, filename);
|
||||
cfg->port_no = GetPrivateProfileIntW(L"ledstrip", L"port", 17, filename);
|
||||
cfg->fw_ver = GetPrivateProfileIntW(L"ledstrip", L"fw_ver", 0xA0, filename);
|
||||
cfg->fw_sum = GetPrivateProfileIntW(L"ledstrip", L"fw_sum", 0xaa53, filename);
|
||||
|
||||
GetPrivateProfileStringW(L"ledstrip", L"board_number", L"15093-06", tmpstr, _countof(tmpstr), filename);
|
||||
memset(cfg->boot_chip_number, ' ', sizeof(cfg->boot_chip_number));
|
||||
|
||||
cfg->enable = GetPrivateProfileIntW(L"led15093", L"enable", 1, filename);
|
||||
cfg->port_no[0] = GetPrivateProfileIntW(L"led15093", L"portNo0", 0, filename);
|
||||
cfg->port_no[1] = GetPrivateProfileIntW(L"led15093", L"portNo1", 0, filename);
|
||||
cfg->high_baudrate = GetPrivateProfileIntW(L"led15093", L"highBaudrate", 0, filename);
|
||||
cfg->fw_ver = GetPrivateProfileIntW(L"led15093", L"fwVer", 0xA0, filename);
|
||||
cfg->fw_sum = GetPrivateProfileIntW(L"led15093", L"fwSum", 0xaa53, filename);
|
||||
|
||||
GetPrivateProfileStringW(
|
||||
L"led15093",
|
||||
L"boardNumber",
|
||||
L"15093-06",
|
||||
tmpstr,
|
||||
_countof(tmpstr),
|
||||
filename);
|
||||
|
||||
size_t n = wcstombs(cfg->board_number, tmpstr, sizeof(cfg->board_number));
|
||||
for (int i = n; i < sizeof(cfg->board_number); i++)
|
||||
{
|
||||
cfg->board_number[i] = ' ';
|
||||
}
|
||||
|
||||
GetPrivateProfileStringW(L"ledstrip", L"chip_number", L"6710A", tmpstr, _countof(tmpstr), filename);
|
||||
|
||||
GetPrivateProfileStringW(
|
||||
L"led15093",
|
||||
L"chipNumber",
|
||||
L"6710A",
|
||||
tmpstr,
|
||||
_countof(tmpstr),
|
||||
filename);
|
||||
|
||||
n = wcstombs(cfg->chip_number, tmpstr, sizeof(cfg->chip_number));
|
||||
for (int i = n; i < sizeof(cfg->chip_number); i++)
|
||||
{
|
||||
cfg->chip_number[i] = ' ';
|
||||
}
|
||||
}
|
||||
|
||||
GetPrivateProfileStringW(
|
||||
L"led15093",
|
||||
L"bootChipNumber",
|
||||
L"6709 ",
|
||||
tmpstr,
|
||||
_countof(tmpstr),
|
||||
filename);
|
||||
|
||||
n = wcstombs(cfg->boot_chip_number, tmpstr, sizeof(cfg->boot_chip_number));
|
||||
for (int i = n; i < sizeof(cfg->boot_chip_number); i++)
|
||||
{
|
||||
cfg->boot_chip_number[i] = ' ';
|
||||
}
|
||||
}
|
||||
|
||||
void fgo_deck_config_load(
|
||||
@ -90,6 +121,6 @@ void fgo_hook_config_load(
|
||||
printer_config_load(&cfg->printer, filename);
|
||||
fgo_deck_config_load(&cfg->deck, filename);
|
||||
ftdi_config_load(&cfg->ftdi, filename);
|
||||
led1509306_config_load(&cfg->led1509306, filename);
|
||||
led15093_config_load(&cfg->led15093, filename);
|
||||
fgo_dll_config_load(&cfg->dll, filename);
|
||||
}
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include <stddef.h>
|
||||
|
||||
#include "board/config.h"
|
||||
#include "board/led15093.h"
|
||||
|
||||
#include "hooklib/dvd.h"
|
||||
#include "hooklib/touch.h"
|
||||
@ -10,7 +11,6 @@
|
||||
|
||||
#include "fgohook/deck.h"
|
||||
#include "fgohook/ftdi.h"
|
||||
#include "fgohook/led1509306.h"
|
||||
#include "fgohook/fgo-dll.h"
|
||||
|
||||
#include "platform/config.h"
|
||||
@ -24,7 +24,7 @@ struct fgo_hook_config {
|
||||
struct printer_config printer;
|
||||
struct deck_config deck;
|
||||
struct ftdi_config ftdi;
|
||||
struct led1509306_config led1509306;
|
||||
struct led15093_config led15093;
|
||||
struct fgo_dll_config dll;
|
||||
};
|
||||
|
||||
|
@ -90,13 +90,13 @@ static DWORD CALLBACK fgo_pre_startup(void)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
hr = ftdi_hook_init(&fgo_hook_cfg.ftdi);
|
||||
hr = ftdi_hook_init(&fgo_hook_cfg.ftdi, 17);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
hr = led1509306_hook_init(&fgo_hook_cfg.led1509306);
|
||||
hr = led15093_hook_init(&fgo_hook_cfg.led15093, 17, 0);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
goto fail;
|
||||
|
@ -121,7 +121,7 @@ static const struct hook_symbol reg_syms[] = {
|
||||
static HANDLE ftdi_fd;
|
||||
static char port_name[8];
|
||||
|
||||
HRESULT ftdi_hook_init(const struct ftdi_config *cfg) {
|
||||
HRESULT ftdi_hook_init(const struct ftdi_config *cfg, unsigned int port_no) {
|
||||
HRESULT hr;
|
||||
|
||||
assert(cfg != NULL);
|
||||
@ -130,6 +130,10 @@ HRESULT ftdi_hook_init(const struct ftdi_config *cfg) {
|
||||
return S_FALSE;
|
||||
}
|
||||
|
||||
if (cfg->port_no != 0) {
|
||||
port_no = cfg->port_no;
|
||||
}
|
||||
|
||||
hook_table_apply(
|
||||
NULL,
|
||||
"setupapi.dll",
|
||||
@ -156,7 +160,7 @@ HRESULT ftdi_hook_init(const struct ftdi_config *cfg) {
|
||||
return hr;
|
||||
}
|
||||
|
||||
sprintf(port_name, "COM%d", cfg->port_no);
|
||||
sprintf(port_name, "COM%d", port_no);
|
||||
|
||||
dprintf("FTDI: Hook enabled.\n");
|
||||
return S_OK;
|
||||
|
@ -18,4 +18,4 @@ DEFINE_GUID(
|
||||
0x11D0,
|
||||
0x9C, 0xE4, 0x08, 0x00, 0x3E, 0x30, 0x1F, 0x73);
|
||||
|
||||
HRESULT ftdi_hook_init(const struct ftdi_config *cfg);
|
||||
HRESULT ftdi_hook_init(const struct ftdi_config *cfg, unsigned int port_no);
|
||||
|
@ -1,387 +0,0 @@
|
||||
/*
|
||||
SEGA 837-15093-06 LED controller emulator
|
||||
|
||||
Credits:
|
||||
|
||||
somewhatlurker, skogaby
|
||||
*/
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <process.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "board/led1509306-cmd.h"
|
||||
#include "board/led1509306-frame.h"
|
||||
|
||||
#include "fgohook/led1509306.h"
|
||||
|
||||
#include "hook/iobuf.h"
|
||||
#include "hook/iohook.h"
|
||||
|
||||
#include "hooklib/uart.h"
|
||||
|
||||
#include "util/dprintf.h"
|
||||
#include "util/dump.h"
|
||||
|
||||
static HRESULT led1509306_handle_irp(struct irp *irp);
|
||||
static HRESULT led1509306_handle_irp_locked(int board, struct irp *irp);
|
||||
|
||||
static HRESULT led1509306_req_dispatch(int board, const struct led1509306_req_any *req);
|
||||
static HRESULT led1509306_req_reset(int board, const struct led1509306_req_any *req);
|
||||
static HRESULT led1509306_req_get_board_info(int board);
|
||||
static HRESULT led1509306_req_get_fw_sum(int board);
|
||||
static HRESULT led1509306_req_get_protocol_ver(int board);
|
||||
static HRESULT led1509306_req_get_board_status(int board);
|
||||
static HRESULT led1509306_req_set_led(int board, const struct led1509306_req_any *req);
|
||||
static HRESULT led1509306_req_set_disable_response(int board, const struct led1509306_req_any *req);
|
||||
static HRESULT led1509306_req_set_timeout(int board, const struct led1509306_req_any *req);
|
||||
|
||||
static char led1509306_board_num[8];
|
||||
static char led1509306_chip_num[5];
|
||||
static uint8_t led1509306_fw_ver;
|
||||
static uint16_t led1509306_fw_sum;
|
||||
static uint8_t led1509306_board_adr = 2;
|
||||
static uint8_t led1509306_host_adr = 1;
|
||||
|
||||
#define led1509306_nboards 2
|
||||
|
||||
typedef struct {
|
||||
CRITICAL_SECTION lock;
|
||||
struct uart boarduart;
|
||||
uint8_t written_bytes[520];
|
||||
uint8_t readable_bytes[520];
|
||||
bool enable_response;
|
||||
} _led1509306_per_board_vars;
|
||||
|
||||
_led1509306_per_board_vars led1509306_per_board_vars[led1509306_nboards];
|
||||
|
||||
HRESULT led1509306_hook_init(const struct led1509306_config *cfg)
|
||||
{
|
||||
assert(cfg != NULL);
|
||||
|
||||
if (!cfg->enable) {
|
||||
return S_FALSE;
|
||||
}
|
||||
|
||||
memcpy(led1509306_board_num, cfg->board_number, sizeof(led1509306_board_num));
|
||||
memcpy(led1509306_chip_num, cfg->chip_number, sizeof(led1509306_chip_num));
|
||||
led1509306_fw_ver = cfg->fw_ver;
|
||||
led1509306_fw_sum = cfg->fw_sum;
|
||||
|
||||
for (int i = 0; i < led1509306_nboards; i++)
|
||||
{
|
||||
_led1509306_per_board_vars *v = &led1509306_per_board_vars[i];
|
||||
|
||||
InitializeCriticalSection(&v->lock);
|
||||
|
||||
uart_init(&v->boarduart, cfg->port_no + i);
|
||||
v->boarduart.written.bytes = v->written_bytes;
|
||||
v->boarduart.written.nbytes = sizeof(v->written_bytes);
|
||||
v->boarduart.readable.bytes = v->readable_bytes;
|
||||
v->boarduart.readable.nbytes = sizeof(v->readable_bytes);
|
||||
|
||||
v->enable_response = true;
|
||||
}
|
||||
|
||||
dprintf("LED Strip: hook enabled.\n");
|
||||
|
||||
return iohook_push_handler(led1509306_handle_irp);
|
||||
}
|
||||
|
||||
static HRESULT led1509306_handle_irp(struct irp *irp)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
assert(irp != NULL);
|
||||
|
||||
for (int i = 0; i < led1509306_nboards; i++)
|
||||
{
|
||||
_led1509306_per_board_vars *v = &led1509306_per_board_vars[i];
|
||||
struct uart *boarduart = &v->boarduart;
|
||||
|
||||
if (uart_match_irp(boarduart, irp))
|
||||
{
|
||||
CRITICAL_SECTION lock = v->lock;
|
||||
|
||||
EnterCriticalSection(&lock);
|
||||
hr = led1509306_handle_irp_locked(i, irp);
|
||||
LeaveCriticalSection(&lock);
|
||||
|
||||
return hr;
|
||||
}
|
||||
}
|
||||
|
||||
return iohook_invoke_next(irp);
|
||||
}
|
||||
|
||||
static HRESULT led1509306_handle_irp_locked(int board, struct irp *irp)
|
||||
{
|
||||
struct led1509306_req_any req;
|
||||
struct iobuf req_iobuf;
|
||||
HRESULT hr;
|
||||
|
||||
struct uart *boarduart = &led1509306_per_board_vars[board].boarduart;
|
||||
|
||||
hr = uart_handle_irp(boarduart, irp);
|
||||
|
||||
if (FAILED(hr) || irp->op != IRP_OP_WRITE) {
|
||||
return hr;
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
#if 0
|
||||
dprintf("TX Buffer:\n");
|
||||
dump_iobuf(&boarduart->written);
|
||||
#endif
|
||||
|
||||
req_iobuf.bytes = (byte*)&req;
|
||||
req_iobuf.nbytes = sizeof(req.hdr) + sizeof(req.cmd) + sizeof(req.payload);
|
||||
req_iobuf.pos = 0;
|
||||
|
||||
hr = led1509306_frame_decode(&req_iobuf, &boarduart->written);
|
||||
|
||||
if (hr != S_OK) {
|
||||
if (FAILED(hr)) {
|
||||
dprintf("LED Strip: Deframe error: %x\n", (int) hr);
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
#if 0
|
||||
dprintf("Deframe Buffer:\n");
|
||||
dump_iobuf(&req_iobuf);
|
||||
#endif
|
||||
|
||||
hr = led1509306_req_dispatch(board, &req);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
dprintf("LED Strip: Processing error: %x\n", (int) hr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static HRESULT led1509306_req_dispatch(int board, const struct led1509306_req_any *req)
|
||||
{
|
||||
switch (req->cmd) {
|
||||
case LED_15093_06_CMD_RESET:
|
||||
return led1509306_req_reset(board, req);
|
||||
|
||||
case LED_15093_06_CMD_BOARD_INFO:
|
||||
return led1509306_req_get_board_info(board);
|
||||
|
||||
case LED_15093_06_CMD_FW_SUM:
|
||||
return led1509306_req_get_fw_sum(board);
|
||||
|
||||
case LED_15093_06_CMD_PROTOCOL_VER:
|
||||
return led1509306_req_get_protocol_ver(board);
|
||||
|
||||
case LED_15093_06_CMD_BOARD_STATUS:
|
||||
return led1509306_req_get_board_status(board);
|
||||
|
||||
case LED_15093_06_CMD_SET_LED:
|
||||
return led1509306_req_set_led(board, req);
|
||||
|
||||
case LED_15093_06_CMD_SET_DISABLE_RESPONSE:
|
||||
return led1509306_req_set_disable_response(board, req);
|
||||
|
||||
case LED_15093_06_CMD_SET_TIMEOUT:
|
||||
return led1509306_req_set_timeout(board, req);
|
||||
|
||||
default:
|
||||
dprintf("LED Strip: Unhandled command %02x\n", req->cmd);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
|
||||
static HRESULT led1509306_req_reset(int board, const struct led1509306_req_any *req)
|
||||
{
|
||||
dprintf("LED Strip: Reset (board %u, type %02x)\n", board, req->payload[0]);
|
||||
|
||||
if (req->payload[0] != 0xd9)
|
||||
dprintf("LED Strip: Warning -- Unknown reset type %02x\n", req->payload[0]);
|
||||
|
||||
led1509306_per_board_vars[board].enable_response = true;
|
||||
|
||||
struct led1509306_resp_any resp;
|
||||
|
||||
memset(&resp, 0, sizeof(resp));
|
||||
resp.hdr.sync = LED_15093_06_FRAME_SYNC;
|
||||
resp.hdr.dest_adr = led1509306_host_adr;
|
||||
resp.hdr.src_adr = led1509306_board_adr;
|
||||
resp.hdr.nbytes = 3;
|
||||
|
||||
resp.status = 1;
|
||||
resp.cmd = LED_15093_06_CMD_RESET;
|
||||
resp.report = 1;
|
||||
|
||||
return led1509306_frame_encode(&led1509306_per_board_vars[board].boarduart.readable, &resp, sizeof(resp.hdr) + resp.hdr.nbytes);
|
||||
}
|
||||
|
||||
static HRESULT led1509306_req_get_board_info(int board)
|
||||
{
|
||||
dprintf("LED Strip: Get board info (board %u)\n", board);
|
||||
|
||||
struct led1509306_resp_board_info resp;
|
||||
|
||||
memset(&resp, 0, sizeof(resp));
|
||||
resp.hdr.sync = LED_15093_06_FRAME_SYNC;
|
||||
resp.hdr.dest_adr = led1509306_host_adr;
|
||||
resp.hdr.src_adr = led1509306_board_adr;
|
||||
resp.hdr.nbytes = sizeof(resp.data) + 3;
|
||||
|
||||
resp.status = 1;
|
||||
resp.cmd = LED_15093_06_CMD_BOARD_INFO;
|
||||
resp.report = 1;
|
||||
|
||||
memcpy(resp.data.board_num, led1509306_board_num, sizeof(resp.data.board_num));
|
||||
resp.data._0a = 0x0a;
|
||||
memcpy(resp.data.chip_num, led1509306_chip_num, sizeof(resp.data.chip_num));
|
||||
resp.data._ff = 0xff;
|
||||
resp.data.fw_ver = led1509306_fw_ver;
|
||||
|
||||
return led1509306_frame_encode(&led1509306_per_board_vars[board].boarduart.readable, &resp, sizeof(resp.hdr) + resp.hdr.nbytes);
|
||||
}
|
||||
|
||||
static HRESULT led1509306_req_get_fw_sum(int board)
|
||||
{
|
||||
dprintf("LED Strip: Get firmware checksum (board %u)\n", board);
|
||||
|
||||
struct led1509306_resp_any resp;
|
||||
|
||||
memset(&resp, 0, sizeof(resp));
|
||||
resp.hdr.sync = LED_15093_06_FRAME_SYNC;
|
||||
resp.hdr.dest_adr = led1509306_host_adr;
|
||||
resp.hdr.src_adr = led1509306_board_adr;
|
||||
resp.hdr.nbytes = 2 + 3;
|
||||
|
||||
resp.status = 1;
|
||||
resp.cmd = LED_15093_06_CMD_FW_SUM;
|
||||
resp.report = 1;
|
||||
|
||||
resp.data[0] = (led1509306_fw_sum >> 8) & 0xff;
|
||||
resp.data[1] = led1509306_fw_sum & 0xff;
|
||||
|
||||
return led1509306_frame_encode(&led1509306_per_board_vars[board].boarduart.readable, &resp, sizeof(resp.hdr) + resp.hdr.nbytes);
|
||||
}
|
||||
|
||||
static HRESULT led1509306_req_get_protocol_ver(int board)
|
||||
{
|
||||
dprintf("LED Strip: Get protocol version (board %u)\n", board);
|
||||
|
||||
struct led1509306_resp_any resp;
|
||||
|
||||
memset(&resp, 0, sizeof(resp));
|
||||
resp.hdr.sync = LED_15093_06_FRAME_SYNC;
|
||||
resp.hdr.dest_adr = led1509306_host_adr;
|
||||
resp.hdr.src_adr = led1509306_board_adr;
|
||||
resp.hdr.nbytes = 3 + 3;
|
||||
|
||||
resp.status = 1;
|
||||
resp.cmd = LED_15093_06_CMD_PROTOCOL_VER;
|
||||
resp.report = 1;
|
||||
|
||||
resp.data[0] = 1;
|
||||
resp.data[1] = 1;
|
||||
resp.data[2] = 4;
|
||||
|
||||
return led1509306_frame_encode(&led1509306_per_board_vars[board].boarduart.readable, &resp, sizeof(resp.hdr) + resp.hdr.nbytes);
|
||||
}
|
||||
|
||||
static HRESULT led1509306_req_get_board_status(int board)
|
||||
{
|
||||
dprintf("LED Strip: Get board status (board %u)\n", board);
|
||||
|
||||
struct led1509306_resp_any resp;
|
||||
|
||||
memset(&resp, 0, sizeof(resp));
|
||||
resp.hdr.sync = LED_15093_06_FRAME_SYNC;
|
||||
resp.hdr.dest_adr = led1509306_host_adr;
|
||||
resp.hdr.src_adr = led1509306_board_adr;
|
||||
resp.hdr.nbytes = 4 + 3;
|
||||
|
||||
resp.status = 1;
|
||||
resp.cmd = LED_15093_06_CMD_BOARD_STATUS;
|
||||
resp.report = 1;
|
||||
|
||||
resp.data[0] = 0;
|
||||
resp.data[1] = 0;
|
||||
resp.data[2] = 0;
|
||||
resp.data[3] = 0;
|
||||
|
||||
return led1509306_frame_encode(&led1509306_per_board_vars[board].boarduart.readable, &resp, sizeof(resp.hdr) + resp.hdr.nbytes);
|
||||
}
|
||||
|
||||
static HRESULT led1509306_req_set_led(int board, const struct led1509306_req_any *req)
|
||||
{
|
||||
// dprintf("LED Strip: Set LED (board %u)\n", board);
|
||||
|
||||
if (!led1509306_per_board_vars[board].enable_response)
|
||||
return S_OK;
|
||||
|
||||
struct led1509306_resp_any resp;
|
||||
|
||||
memset(&resp, 0, sizeof(resp));
|
||||
resp.hdr.sync = LED_15093_06_FRAME_SYNC;
|
||||
resp.hdr.dest_adr = led1509306_host_adr;
|
||||
resp.hdr.src_adr = led1509306_board_adr;
|
||||
resp.hdr.nbytes = 3;
|
||||
|
||||
resp.status = 1;
|
||||
resp.cmd = LED_15093_06_CMD_SET_LED;
|
||||
resp.report = 1;
|
||||
|
||||
return led1509306_frame_encode(&led1509306_per_board_vars[board].boarduart.readable, &resp, sizeof(resp.hdr) + resp.hdr.nbytes);
|
||||
}
|
||||
|
||||
static HRESULT led1509306_req_set_disable_response(int board, const struct led1509306_req_any *req)
|
||||
{
|
||||
dprintf("LED Strip: Disable LED responses (board %u)\n", board);
|
||||
|
||||
led1509306_per_board_vars[board].enable_response = !req->payload[0];
|
||||
|
||||
struct led1509306_resp_any resp;
|
||||
|
||||
memset(&resp, 0, sizeof(resp));
|
||||
resp.hdr.sync = LED_15093_06_FRAME_SYNC;
|
||||
resp.hdr.dest_adr = led1509306_host_adr;
|
||||
resp.hdr.src_adr = led1509306_board_adr;
|
||||
resp.hdr.nbytes = 1 + 3;
|
||||
|
||||
resp.status = 1;
|
||||
resp.cmd = LED_15093_06_CMD_SET_DISABLE_RESPONSE;
|
||||
resp.report = 1;
|
||||
|
||||
resp.data[0] = req->payload[0];
|
||||
|
||||
return led1509306_frame_encode(&led1509306_per_board_vars[board].boarduart.readable, &resp, sizeof(resp.hdr) + resp.hdr.nbytes);
|
||||
}
|
||||
|
||||
static HRESULT led1509306_req_set_timeout(int board, const struct led1509306_req_any *req)
|
||||
{
|
||||
dprintf("LED Strip: Set timeout (board %u)\n", board);
|
||||
|
||||
// not actually implemented, but respond correctly anyway
|
||||
|
||||
struct led1509306_resp_any resp;
|
||||
|
||||
memset(&resp, 0, sizeof(resp));
|
||||
resp.hdr.sync = LED_15093_06_FRAME_SYNC;
|
||||
resp.hdr.dest_adr = led1509306_host_adr;
|
||||
resp.hdr.src_adr = led1509306_board_adr;
|
||||
resp.hdr.nbytes = 2 + 3;
|
||||
|
||||
resp.status = 1;
|
||||
resp.cmd = LED_15093_06_CMD_SET_TIMEOUT;
|
||||
resp.report = 1;
|
||||
|
||||
resp.data[0] = req->payload[0];
|
||||
resp.data[1] = req->payload[1];
|
||||
|
||||
return led1509306_frame_encode(&led1509306_per_board_vars[board].boarduart.readable, &resp, sizeof(resp.hdr) + resp.hdr.nbytes);
|
||||
}
|
@ -1,16 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
struct led1509306_config {
|
||||
bool enable;
|
||||
unsigned int port_no;
|
||||
char board_number[8];
|
||||
char chip_number[5];
|
||||
uint8_t fw_ver;
|
||||
uint16_t fw_sum;
|
||||
};
|
||||
|
||||
HRESULT led1509306_hook_init(const struct led1509306_config *cfg);
|
@ -30,7 +30,5 @@ shared_library(
|
||||
'deck.h',
|
||||
'ftdi.c',
|
||||
'ftdi.h',
|
||||
'led1509306.c',
|
||||
'led1509306.h',
|
||||
],
|
||||
)
|
||||
|
Loading…
Reference in New Issue
Block a user