Bemanitools v5.26 release
This commit is contained in:
@@ -0,0 +1,9 @@
|
||||
libs += ezusb-iidx
|
||||
|
||||
libs_ezusb-iidx := \
|
||||
util \
|
||||
|
||||
src_ezusb-iidx := \
|
||||
ezusb-iidx.c \
|
||||
fpga.c \
|
||||
sram.c \
|
||||
@@ -0,0 +1,16 @@
|
||||
#ifndef EZUSB_IIDX_COIN_CMD_H
|
||||
#define EZUSB_IIDX_COIN_CMD_H
|
||||
|
||||
enum ezusb_iidx_coin_command {
|
||||
/* set when "playing" the game */
|
||||
EZUSB_IIDX_COIN_CMD_SET_COIN_MODE_1 = 0x01,
|
||||
/* set when in service menu */
|
||||
EZUSB_IIDX_COIN_CMD_SET_COIN_MODE_2 = 0x02
|
||||
};
|
||||
|
||||
enum ezusb_iidx_coin_command_status {
|
||||
EZUSB_IIDX_COIN_CMD_STATUS_OK = 0x00,
|
||||
EZUSB_IIDX_COIN_CMD_STATUS_FAULT = 0xFE
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,22 @@
|
||||
#ifndef EZUSB_IIDX_EEPROM_CMD_H
|
||||
#define EZUSB_IIDX_EEPROM_CMD_H
|
||||
|
||||
/* commands are the same for v1 and v2 */
|
||||
enum ezusb_iidx_eeprom_command {
|
||||
EZUSB_IIDX_EEPROM_CMD_READ = 0x02,
|
||||
EZUSB_IIDX_EEPROM_CMD_WRITE = 0x03
|
||||
};
|
||||
|
||||
enum ezusb_iidx_eeprom_command_status_v1 {
|
||||
EZUSB_IIDX_EEPROM_CMD_STATUS_V1_READ_OK = 0x01,
|
||||
EZUSB_IIDX_EEPROM_CMD_STATUS_V1_WRITE_OK = 0x02,
|
||||
EZUSB_IIDX_EEPROM_CMD_STATUS_V1_FAULT = 0xFE
|
||||
};
|
||||
|
||||
enum ezusb_iidx_eeprom_command_status_v2 {
|
||||
EZUSB_IIDX_EEPROM_CMD_STATUS_V2_READ_OK = 0x21,
|
||||
EZUSB_IIDX_EEPROM_CMD_STATUS_V2_WRITE_OK = 0x22,
|
||||
EZUSB_IIDX_EEPROM_CMD_STATUS_V2_FAULT = 0xFE
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,271 @@
|
||||
#define LOG_MODULE "ezusb-iidx"
|
||||
|
||||
#include "ezusb-iidx/ezusb-iidx.h"
|
||||
|
||||
#include "ezusb/ezusbsys2.h"
|
||||
|
||||
#include "util/hex.h"
|
||||
#include "util/log.h"
|
||||
#include "util/time.h"
|
||||
|
||||
#include "msg.h"
|
||||
|
||||
//#define DEBUG_DUMP
|
||||
|
||||
/* For debugging */
|
||||
#ifdef DEBUG_DUMP
|
||||
static void ezusb_iidx_log_usb(const char* prefix, uint32_t ctl_code,
|
||||
const BULK_TRANSFER_CONTROL *ctl, uint32_t ctl_size, void* header,
|
||||
uint32_t header_bytes, void* data, uint32_t data_bytes)
|
||||
{
|
||||
char header_str[4096];
|
||||
char data_str[4096];
|
||||
const char* ctl_code_str;
|
||||
|
||||
switch (ctl_code) {
|
||||
case IOCTL_Ezusb_GET_DEVICE_DESCRIPTOR:
|
||||
ctl_code_str = "GET_DEVICE_DESCRIPTOR";
|
||||
break;
|
||||
|
||||
case IOCTL_Ezusb_VENDOR_REQUEST:
|
||||
ctl_code_str = "VENDOR_REQUEST";
|
||||
break;
|
||||
|
||||
case IOCTL_EZUSB_ANCHOR_DOWNLOAD:
|
||||
ctl_code_str = "ANCHOR_DOWNLOAD";
|
||||
break;
|
||||
|
||||
case IOCTL_EZUSB_BULK_READ:
|
||||
if (ctl->pipeNum == EZUSB_IIDX_MSG_PIPE_INTERRUPT_IN) {
|
||||
ctl_code_str = "INT_READ";
|
||||
} else if (ctl->pipeNum == EZUSB_IIDX_MSG_PIPE_BULK_IN) {
|
||||
ctl_code_str = "BULK_READ";
|
||||
} else {
|
||||
ctl_code_str = "INVALID_READ";
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case IOCTL_EZUSB_BULK_WRITE:
|
||||
if (ctl->pipeNum == EZUSB_IIDX_MSG_PIPE_INTERRUPT_OUT) {
|
||||
ctl_code_str = "INT_WRITE";
|
||||
} else if (ctl->pipeNum == EZUSB_IIDX_MSG_PIPE_BULK_OUT) {
|
||||
ctl_code_str = "BULK_WRITE";
|
||||
} else {
|
||||
ctl_code_str = "INVALID_WRITE";
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
ctl_code_str = "UNKNOWN";
|
||||
break;
|
||||
}
|
||||
|
||||
hex_encode_uc(header, header_bytes, header_str, sizeof(header_str));
|
||||
hex_encode_uc(data, data_bytes, data_str, sizeof(data_str));
|
||||
|
||||
log_misc("[EZUSB DUMP %s][%s] header(%d) %s |||| data(%d) %s\n",
|
||||
prefix, ctl_code_str, header_bytes, header_str, data_bytes, data_str);
|
||||
}
|
||||
#endif
|
||||
|
||||
static BOOL ezusb_iidx_device_io_control_wrapper(
|
||||
HANDLE fd, uint32_t code, void *in_bytes, uint32_t in_nbytes,
|
||||
void *out_bytes, uint32_t out_nbytes, DWORD *out_returned,
|
||||
OVERLAPPED *ovl)
|
||||
{
|
||||
BOOL ret;
|
||||
|
||||
#ifdef DEBUG_DUMP
|
||||
ezusb_iidx_log_usb("BEFORE", code, in_bytes, in_nbytes, in_bytes, in_nbytes,
|
||||
out_bytes, out_nbytes);
|
||||
#endif
|
||||
|
||||
ret = DeviceIoControl(fd, code, in_bytes, in_nbytes, out_bytes,
|
||||
out_nbytes, out_returned, ovl);
|
||||
|
||||
#ifdef DEBUG_DUMP
|
||||
ezusb_iidx_log_usb("AFTER", code, in_bytes, in_nbytes, in_bytes, in_nbytes,
|
||||
out_bytes, out_nbytes);
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool ezusb_iidx_ioctl(HANDLE handle, uint32_t code, void* in_bytes,
|
||||
uint32_t in_nbytes, void* out_bytes, uint32_t out_nbytes,
|
||||
uint32_t* out_returned)
|
||||
{
|
||||
return DeviceIoControl(handle, code, in_bytes, in_nbytes, out_bytes,
|
||||
out_nbytes, (LPDWORD) out_returned, NULL);
|
||||
}
|
||||
|
||||
bool ezusb_iidx_interrupt_read(HANDLE handle,
|
||||
struct ezusb_iidx_msg_interrupt_read_packet* packet)
|
||||
{
|
||||
BULK_TRANSFER_CONTROL transfer;
|
||||
DWORD outpkt;
|
||||
|
||||
transfer.pipeNum = EZUSB_IIDX_MSG_PIPE_INTERRUPT_IN;
|
||||
|
||||
return ezusb_iidx_device_io_control_wrapper(
|
||||
handle, IOCTL_EZUSB_BULK_READ, &transfer,
|
||||
sizeof(transfer), packet,
|
||||
sizeof(struct ezusb_iidx_msg_interrupt_read_packet), &outpkt, NULL);
|
||||
}
|
||||
|
||||
bool ezusb_iidx_interrupt_write(HANDLE handle,
|
||||
const struct ezusb_iidx_msg_interrupt_write_packet* packet)
|
||||
{
|
||||
BULK_TRANSFER_CONTROL transfer;
|
||||
DWORD outpkt;
|
||||
|
||||
transfer.pipeNum = EZUSB_IIDX_MSG_PIPE_INTERRUPT_OUT;
|
||||
|
||||
return ezusb_iidx_device_io_control_wrapper(
|
||||
handle, IOCTL_EZUSB_BULK_WRITE, &transfer,
|
||||
sizeof(transfer), (void*) packet,
|
||||
sizeof(struct ezusb_iidx_msg_interrupt_write_packet), &outpkt, NULL);
|
||||
}
|
||||
|
||||
bool ezusb_iidx_bulk_read(HANDLE handle,
|
||||
struct ezusb_iidx_msg_bulk_packet* packet)
|
||||
{
|
||||
BULK_TRANSFER_CONTROL transfer;
|
||||
DWORD outpkt;
|
||||
|
||||
transfer.pipeNum = EZUSB_IIDX_MSG_PIPE_BULK_IN;
|
||||
|
||||
return ezusb_iidx_device_io_control_wrapper(
|
||||
handle, IOCTL_EZUSB_BULK_READ, &transfer,
|
||||
sizeof(transfer), packet,
|
||||
sizeof(struct ezusb_iidx_msg_bulk_packet), &outpkt, NULL);
|
||||
}
|
||||
|
||||
bool ezusb_iidx_bulk_write(HANDLE handle,
|
||||
const struct ezusb_iidx_msg_bulk_packet* packet)
|
||||
{
|
||||
BULK_TRANSFER_CONTROL transfer;
|
||||
DWORD outpkt;
|
||||
|
||||
transfer.pipeNum = EZUSB_IIDX_MSG_PIPE_BULK_OUT;
|
||||
|
||||
return ezusb_iidx_device_io_control_wrapper(
|
||||
handle, IOCTL_EZUSB_BULK_WRITE, &transfer,
|
||||
sizeof(transfer), (void*) packet,
|
||||
sizeof(struct ezusb_iidx_msg_bulk_packet), &outpkt, NULL);
|
||||
}
|
||||
|
||||
bool ezusb_iidx_execute_cmd(HANDLE handle, uint8_t node,
|
||||
uint8_t cmd, uint8_t cmd_detail, uint8_t cmd_detail2,
|
||||
struct ezusb_iidx_msg_interrupt_read_packet* int_read_data)
|
||||
{
|
||||
struct ezusb_iidx_msg_interrupt_write_packet int_write;
|
||||
|
||||
memset(&int_write, 0, sizeof(struct ezusb_iidx_msg_interrupt_write_packet));
|
||||
|
||||
int_write.node = node;
|
||||
int_write.cmd = cmd;
|
||||
int_write.cmd_detail[0] = cmd_detail;
|
||||
int_write.cmd_detail[1] = cmd_detail2;
|
||||
|
||||
log_misc("Execute cmd: %02X %02X %02X %02X",
|
||||
node, cmd, cmd_detail, cmd_detail2);
|
||||
|
||||
if (!ezusb_iidx_interrupt_write(handle, &int_write)) {
|
||||
log_warning("Interrupt write failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
Sleep(10);
|
||||
|
||||
if (!ezusb_iidx_interrupt_read(handle, int_read_data)) {
|
||||
log_warning("Interrupt read failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
log_misc("Cmd result: %02X", int_read_data->status);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
uint8_t ezusb_iidx_execute_cmd_retry(HANDLE handle, uint8_t node,
|
||||
uint8_t cmd, uint8_t cmd_detail, uint8_t cmd_detail2, uint8_t int_reads)
|
||||
{
|
||||
struct ezusb_iidx_msg_interrupt_read_packet int_read;
|
||||
struct ezusb_iidx_msg_interrupt_write_packet int_write;
|
||||
|
||||
memset(&int_write, 0, sizeof(struct ezusb_iidx_msg_interrupt_write_packet));
|
||||
|
||||
int_write.node = node;
|
||||
int_write.cmd = cmd;
|
||||
int_write.cmd_detail[0] = cmd_detail;
|
||||
int_write.cmd_detail[1] = cmd_detail2;
|
||||
|
||||
log_misc("Execute cmd: %02X %02X %02X %02X",
|
||||
node, cmd, cmd_detail, cmd_detail2);
|
||||
|
||||
if (!ezusb_iidx_interrupt_write(handle, &int_write)) {
|
||||
log_warning("Interrupt write failed");
|
||||
return 0xFF;
|
||||
}
|
||||
|
||||
Sleep(10);
|
||||
|
||||
for (uint8_t i = 0; i < int_reads; i++) {
|
||||
if (!ezusb_iidx_interrupt_read(handle, &int_read)) {
|
||||
log_warning("Interrupt read failed");
|
||||
return 0xFF;
|
||||
}
|
||||
}
|
||||
|
||||
log_misc("Cmd result: %02X", int_read.status);
|
||||
|
||||
return int_read.status;
|
||||
}
|
||||
|
||||
bool ezusb_iidx_execute_cmd_timeout(HANDLE handle, uint8_t node,
|
||||
uint8_t cmd, uint8_t cmd_detail, uint8_t cmd_detail2,
|
||||
uint8_t expected_ret_code, uint32_t timeout_ms)
|
||||
{
|
||||
struct ezusb_iidx_msg_interrupt_read_packet int_read;
|
||||
struct ezusb_iidx_msg_interrupt_write_packet int_write;
|
||||
|
||||
memset(&int_write, 0, sizeof(struct ezusb_iidx_msg_interrupt_write_packet));
|
||||
|
||||
int_write.node = node;
|
||||
int_write.cmd = cmd;
|
||||
int_write.cmd_detail[0] = cmd_detail;
|
||||
int_write.cmd_detail[1] = cmd_detail2;
|
||||
|
||||
log_misc("Execute cmd: %02X %02X %02X %02X",
|
||||
node, cmd, cmd_detail, cmd_detail2);
|
||||
|
||||
if (!ezusb_iidx_interrupt_write(handle, &int_write)) {
|
||||
log_warning("Interrupt write failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
Sleep(10);
|
||||
|
||||
uint64_t start = time_get_counter();
|
||||
|
||||
while (time_get_elapsed_ms(time_get_counter() - start) < timeout_ms) {
|
||||
if (!ezusb_iidx_interrupt_read(handle, &int_read)) {
|
||||
log_warning("Interrupt read failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (int_read.status == expected_ret_code) {
|
||||
log_misc("Cmd result: %02X", expected_ret_code);
|
||||
return true;
|
||||
}
|
||||
|
||||
Sleep(10);
|
||||
}
|
||||
|
||||
log_warning("Cmd failed, result: %02X", int_read.status);
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
#ifndef EZUSB_IIDX_H
|
||||
#define EZUSB_IIDX_H
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include "msg.h"
|
||||
|
||||
bool ezusb_iidx_ioctl(HANDLE handle, uint32_t code, void* in_bytes,
|
||||
uint32_t in_nbytes, void* out_bytes, uint32_t out_nbytes,
|
||||
uint32_t* out_returned);
|
||||
|
||||
bool ezusb_iidx_interrupt_read(HANDLE handle,
|
||||
struct ezusb_iidx_msg_interrupt_read_packet* packet);
|
||||
|
||||
bool ezusb_iidx_interrupt_write(HANDLE handle,
|
||||
const struct ezusb_iidx_msg_interrupt_write_packet* packet);
|
||||
|
||||
bool ezusb_iidx_bulk_read(HANDLE handle,
|
||||
struct ezusb_iidx_msg_bulk_packet* packet);
|
||||
|
||||
bool ezusb_iidx_bulk_write(HANDLE handle,
|
||||
const struct ezusb_iidx_msg_bulk_packet* packet);
|
||||
|
||||
bool ezusb_iidx_execute_cmd(HANDLE handle, uint8_t node,
|
||||
uint8_t cmd, uint8_t cmd_detail, uint8_t cmd_detail2,
|
||||
struct ezusb_iidx_msg_interrupt_read_packet* int_read_data);
|
||||
|
||||
uint8_t ezusb_iidx_execute_cmd_retry(HANDLE handle, uint8_t node,
|
||||
uint8_t cmd, uint8_t cmd_detail, uint8_t cmd_detail2, uint8_t int_reads);
|
||||
|
||||
bool ezusb_iidx_execute_cmd_timeout(HANDLE handle, uint8_t node,
|
||||
uint8_t cmd, uint8_t cmd_detail, uint8_t cmd_detail2,
|
||||
uint8_t expected_ret_code, uint32_t timeout_ms);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,37 @@
|
||||
#ifndef EZUSB_IIDX_FPGA_CMD_H
|
||||
#define EZUSB_IIDX_FPGA_CMD_H
|
||||
|
||||
enum ezusb_iidx_fpga_cmd_v1 {
|
||||
EZUSB_IIDX_FPGA_CMD_V1_INIT = 0x01,
|
||||
// TODO rename to reset
|
||||
EZUSB_IIDX_FPGA_CMD_V1_CHECK = 0xFF,
|
||||
// TODO rename to check? -> see firmware
|
||||
EZUSB_IIDX_FPGA_CMD_V1_CHECK_2 = 0x02,
|
||||
EZUSB_IIDX_FPGA_CMD_V1_WRITE = 0x03,
|
||||
EZUSB_IIDX_FPGA_CMD_V1_WRITE_DONE = 0x04
|
||||
};
|
||||
|
||||
enum ezusb_iidx_fpga_cmd_v2 {
|
||||
EZUSB_IIDX_FPGA_CMD_V2_INIT = 0x01,
|
||||
EZUSB_IIDX_FPGA_CMD_V2_CHECK = 0x02,
|
||||
EZUSB_IIDX_FPGA_CMD_V2_WRITE = 0x03,
|
||||
EZUSB_IIDX_FPGA_CMD_V2_WRITE_DONE = 0x04
|
||||
};
|
||||
|
||||
enum ezusb_iidx_fpga_cmd_status_v1 {
|
||||
EZUSB_IIDX_FPGA_CMD_STATUS_V1_OK = 0x00,
|
||||
/* I even checked the firmware and they used the same
|
||||
return code for both, error and ok on some calls...*/
|
||||
EZUSB_IIDX_FPGA_CMD_STATUS_V1_OK_2 = 0xFE,
|
||||
EZUSB_IIDX_FPGA_CMD_STATUS_V1_FAULT = 0xFE,
|
||||
};
|
||||
|
||||
enum ezusb_iidx_fpga_cmd_status_v2 {
|
||||
EZUSB_IIDX_FPGA_CMD_STATUS_V2_NULL = 0x00,
|
||||
EZUSB_IIDX_FPGA_CMD_STATUS_V2_INIT_OK = 0x41,
|
||||
EZUSB_IIDX_FPGA_CMD_STATUS_V2_CHECK_OK = 0x42,
|
||||
EZUSB_IIDX_FPGA_CMD_STATUS_V2_WRITE_OK = 0x43,
|
||||
EZUSB_IIDX_FPGA_CMD_STATUS_V2_FAULT = 0xFE
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,258 @@
|
||||
#define LOG_MODULE "ezusb-iidx-fpga"
|
||||
|
||||
#include "ezusb-iidx/fpga.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "util/log.h"
|
||||
|
||||
#include "ezusb-iidx.h"
|
||||
#include "fpga-cmd.h"
|
||||
|
||||
static bool ezusb_iidx_fpga_write_fw_page(HANDLE handle, uint8_t node,
|
||||
const void* buffer, uint16_t size)
|
||||
{
|
||||
struct ezusb_iidx_msg_bulk_packet packet;
|
||||
|
||||
memset(&packet.payload, 0, 62);
|
||||
|
||||
packet.node = node;
|
||||
packet.page = 0;
|
||||
|
||||
if (size > 62) {
|
||||
size = 62;
|
||||
}
|
||||
|
||||
//log_misc("Writing fpga page, size %d", size);
|
||||
|
||||
memcpy(packet.payload, buffer, size);
|
||||
|
||||
return ezusb_iidx_bulk_write(handle, &packet);
|
||||
}
|
||||
|
||||
static bool ezusb_iidx_fpga_write_fw(HANDLE handle, uint8_t node,
|
||||
const void* buffer, uint16_t size)
|
||||
{
|
||||
uint16_t offset;
|
||||
|
||||
offset = 0;
|
||||
|
||||
log_misc("Writing fw, size %d...", size);
|
||||
|
||||
/* Write in ezusb page sizes */
|
||||
while (offset < size) {
|
||||
if ( !ezusb_iidx_fpga_write_fw_page(handle, node, buffer + offset,
|
||||
size - offset)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
offset += 62;
|
||||
}
|
||||
|
||||
log_misc("Writing fw finished");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool ezusb_iidx_fpga_v1_reset(HANDLE handle)
|
||||
{
|
||||
log_info("[v1] Reset");
|
||||
|
||||
if ( !ezusb_iidx_execute_cmd_timeout(handle, EZUSB_IIDX_MSG_NODE_FPGA_V1,
|
||||
EZUSB_IIDX_FPGA_CMD_V1_INIT, 0x41, 0,
|
||||
EZUSB_IIDX_FPGA_CMD_STATUS_V1_OK_2,
|
||||
10000)) {
|
||||
log_warning("[v1] Reset failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool ezusb_iidx_fpga_v1_write(HANDLE handle, const void* buffer, uint16_t size)
|
||||
{
|
||||
log_info("[v1] Write firmware, size %d", size);
|
||||
|
||||
/* Have a bunch of sleep between each command. If we try to send commands as fast as possible, the
|
||||
hardware fails executing commands and might also crash. */
|
||||
|
||||
if ( !ezusb_iidx_execute_cmd_timeout(handle, EZUSB_IIDX_MSG_NODE_FPGA_V1,
|
||||
EZUSB_IIDX_FPGA_CMD_V1_CHECK, 0x41, 0,
|
||||
EZUSB_IIDX_FPGA_CMD_STATUS_V1_OK,
|
||||
10000)) {
|
||||
log_warning("[v1] Check failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
Sleep(10);
|
||||
|
||||
if ( !ezusb_iidx_execute_cmd_timeout(handle, EZUSB_IIDX_MSG_NODE_FPGA_V1,
|
||||
EZUSB_IIDX_FPGA_CMD_V1_WRITE, size >> 8, size,
|
||||
EZUSB_IIDX_FPGA_CMD_STATUS_V1_OK,
|
||||
10000)) {
|
||||
log_warning("[v1] Write failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
Sleep(10);
|
||||
|
||||
if ( !ezusb_iidx_fpga_write_fw(handle, EZUSB_IIDX_MSG_NODE_FPGA_V1,
|
||||
buffer, size)) {
|
||||
log_warning("[v1] Writing fw failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
Sleep(10);
|
||||
|
||||
if ( !ezusb_iidx_execute_cmd_timeout(handle, EZUSB_IIDX_MSG_NODE_FPGA_V1,
|
||||
EZUSB_IIDX_FPGA_CMD_V1_WRITE_DONE, size >> 8, size,
|
||||
EZUSB_IIDX_FPGA_CMD_STATUS_V1_OK_2,
|
||||
10000)) {
|
||||
log_warning("[v1] Write done failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
Sleep(10);
|
||||
|
||||
if ( !ezusb_iidx_execute_cmd_timeout(handle, EZUSB_IIDX_MSG_NODE_FPGA_V1,
|
||||
EZUSB_IIDX_FPGA_CMD_V1_CHECK, size >> 8, size,
|
||||
EZUSB_IIDX_FPGA_CMD_STATUS_V1_OK,
|
||||
10000)) {
|
||||
log_warning("[v1] Check failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
Sleep(10);
|
||||
|
||||
if ( !ezusb_iidx_execute_cmd_timeout(handle, EZUSB_IIDX_MSG_NODE_FPGA_V1,
|
||||
EZUSB_IIDX_FPGA_CMD_V1_CHECK_2, size >> 8, size,
|
||||
EZUSB_IIDX_FPGA_CMD_STATUS_V1_OK_2,
|
||||
10000)) {
|
||||
log_warning("[v1] Start failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool ezusb_iidx_fpga_v2_reset(HANDLE handle)
|
||||
{
|
||||
log_info("[v2] Reset");
|
||||
|
||||
if ( !ezusb_iidx_execute_cmd_timeout(handle, EZUSB_IIDX_MSG_NODE_FPGA_V2,
|
||||
EZUSB_IIDX_FPGA_CMD_V2_INIT, 1, 0,
|
||||
EZUSB_IIDX_FPGA_CMD_STATUS_V2_INIT_OK,
|
||||
10000)) {
|
||||
log_warning("[v2] Reset failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool ezusb_iidx_fpga_v2_write(HANDLE handle, const void* buffer, uint16_t size)
|
||||
{
|
||||
log_info("[v2] Waiting for fpga ready to write...");
|
||||
|
||||
/* poll until the device reports fpga write ready */
|
||||
while (true) {
|
||||
struct ezusb_iidx_msg_interrupt_read_packet int_read_data;
|
||||
|
||||
if ( !ezusb_iidx_execute_cmd(handle, EZUSB_IIDX_MSG_NODE_FPGA_V2,
|
||||
EZUSB_IIDX_FPGA_CMD_V2_WRITE, size >> 8, size,
|
||||
&int_read_data)) {
|
||||
log_warning("[v2] Write failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (int_read_data.fpga_write_ready == 1) {
|
||||
break;
|
||||
}
|
||||
|
||||
Sleep(10);
|
||||
}
|
||||
|
||||
log_info("[v2] Write firmware, size %d", size);
|
||||
|
||||
if ( !ezusb_iidx_fpga_write_fw(handle, EZUSB_IIDX_MSG_NODE_FPGA_V2,
|
||||
buffer, size)) {
|
||||
log_warning("[v2] Writing fw failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( !ezusb_iidx_execute_cmd_timeout(handle, EZUSB_IIDX_MSG_NODE_FPGA_V2,
|
||||
EZUSB_IIDX_FPGA_CMD_V2_WRITE_DONE, size >> 8, size,
|
||||
EZUSB_IIDX_FPGA_CMD_STATUS_V2_WRITE_OK,
|
||||
10000)) {
|
||||
log_warning("[v2] Write done failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( !ezusb_iidx_execute_cmd_timeout(handle, EZUSB_IIDX_MSG_NODE_FPGA_V2,
|
||||
EZUSB_IIDX_FPGA_CMD_V2_CHECK, size >> 8, size,
|
||||
EZUSB_IIDX_FPGA_CMD_STATUS_V2_CHECK_OK,
|
||||
10000)) {
|
||||
log_warning("[v2] Start failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool ezusb_iidx_fpga_run_prog(HANDLE handle)
|
||||
{
|
||||
/* Run the fpga prog */
|
||||
struct ezusb_iidx_msg_interrupt_write_packet int_write;
|
||||
memset(&int_write, 0, sizeof(struct ezusb_iidx_msg_interrupt_write_packet));
|
||||
|
||||
int_write.fpga_run = 1;
|
||||
|
||||
if (!ezusb_iidx_interrupt_write(handle, &int_write)) {
|
||||
log_warning("Run fpga prog failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ezusb_iidx_fpga_v1_init(HANDLE handle, const void* buffer, uint16_t size)
|
||||
{
|
||||
if (!ezusb_iidx_fpga_v1_reset(handle)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Sleep(10);
|
||||
|
||||
if (!ezusb_iidx_fpga_v1_write(handle, buffer, size)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Sleep(10);
|
||||
|
||||
if (!ezusb_iidx_fpga_run_prog(handle)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ezusb_iidx_fpga_v2_init(HANDLE handle, const void* buffer, uint16_t size)
|
||||
{
|
||||
if (!ezusb_iidx_fpga_v2_reset(handle)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Sleep(10);
|
||||
|
||||
if (!ezusb_iidx_fpga_v2_write(handle, buffer, size)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Sleep(10);
|
||||
|
||||
if (!ezusb_iidx_fpga_run_prog(handle)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
#ifndef EZUSB_IIDX_FPGA_H
|
||||
#define EZUSB_IIDX_FPGA_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <windows.h>
|
||||
|
||||
bool ezusb_iidx_fpga_v1_init(HANDLE handle, const void* buffer, uint16_t size);
|
||||
|
||||
bool ezusb_iidx_fpga_v2_init(HANDLE handle, const void* buffer, uint16_t size);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,108 @@
|
||||
#ifndef EZUSB_IIDX_MSG_H
|
||||
#define EZUSB_IIDX_MSG_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#define EZUSB_PAGESIZE 62
|
||||
|
||||
enum ezusb_iidx_msg_pipe {
|
||||
EZUSB_IIDX_MSG_PIPE_INTERRUPT_OUT = 0,
|
||||
EZUSB_IIDX_MSG_PIPE_INTERRUPT_IN = 1,
|
||||
EZUSB_IIDX_MSG_PIPE_BULK_OUT = 2,
|
||||
EZUSB_IIDX_MSG_PIPE_BULK_IN = 3
|
||||
};
|
||||
|
||||
enum ezusb_iidx_msg_node {
|
||||
EZUSB_IIDX_MSG_NODE_NONE = 0x00,
|
||||
EZUSB_IIDX_MSG_NODE_SECURITY_PLUG = 0x01,
|
||||
EZUSB_IIDX_MSG_NODE_EEPROM = 0x02,
|
||||
EZUSB_IIDX_MSG_NODE_SERIAL = 0x04,
|
||||
EZUSB_IIDX_MSG_NODE_FPGA_V2 = 0x04,
|
||||
EZUSB_IIDX_MSG_NODE_16SEG = 0x05,
|
||||
EZUSB_IIDX_MSG_NODE_COIN = 0x09,
|
||||
EZUSB_IIDX_MSG_NODE_FPGA_V1 = 0x10,
|
||||
EZUSB_IIDX_MSG_NODE_WDT = 0x0C,
|
||||
EZUSB_IIDX_MSG_NODE_SRAM = 0x40,
|
||||
EZUSB_IIDX_MSG_NODE_SECURITY_MEM = 0xFE,
|
||||
};
|
||||
|
||||
struct ezusb_iidx_msg_bulk_packet {
|
||||
uint8_t node;
|
||||
uint8_t page;
|
||||
uint8_t payload[EZUSB_PAGESIZE];
|
||||
};
|
||||
|
||||
struct ezusb_iidx_msg_interrupt_write_packet {
|
||||
uint16_t deck_lights;
|
||||
uint8_t node;
|
||||
uint8_t cmd;
|
||||
uint8_t cmd_detail[2];
|
||||
uint8_t panel_lights;
|
||||
uint8_t unk0;
|
||||
uint8_t top_lamps;
|
||||
uint8_t top_neons;
|
||||
/* Ensure this is always enabled (1) after flashing the fpga prog.
|
||||
Otherwise, all data coming from the fpga is never updated */
|
||||
uint8_t fpga_run;
|
||||
uint8_t unk2;
|
||||
uint8_t unk3;
|
||||
uint8_t unk4;
|
||||
uint8_t unk5;
|
||||
uint8_t unk6;
|
||||
};
|
||||
|
||||
struct ezusb_iidx_msg_interrupt_read_packet {
|
||||
/*
|
||||
Dip switches somewhere here?
|
||||
0: Not used
|
||||
1: Not used
|
||||
2: Not used
|
||||
3: Not used
|
||||
4: Not used
|
||||
5: Not used
|
||||
6: usb mute?
|
||||
7: Not used
|
||||
|
||||
8: P1_1
|
||||
9: P1_2
|
||||
10: P1_3
|
||||
11: P1_4
|
||||
12: P1_5
|
||||
13: P1_6
|
||||
14: P1_7
|
||||
15: P2_1
|
||||
|
||||
16: P2_2
|
||||
17: P2_3
|
||||
18: P2_4
|
||||
19: P2_5
|
||||
20: P2_6
|
||||
21: P2_7
|
||||
22: Coin mech
|
||||
23: Not used
|
||||
24: P1_Start
|
||||
|
||||
25: P2_Start
|
||||
26: VEFX
|
||||
27: Effector
|
||||
28: Test
|
||||
29: Service
|
||||
30: unknown/not used
|
||||
31: coin mode state: this needs to be set according to the currently
|
||||
active coin node (coin mode1 -> 0, coin mode 2 -> 1)
|
||||
*/
|
||||
uint32_t inverted_pad;
|
||||
uint8_t status;
|
||||
uint8_t unk0;
|
||||
uint8_t unk1;
|
||||
uint8_t p2_turntable;
|
||||
uint8_t p1_turntable;
|
||||
uint8_t seq_no;
|
||||
uint8_t fpga2_check_flag_unkn;
|
||||
uint8_t fpga_write_ready;
|
||||
uint8_t serial_io_busy_flag;
|
||||
uint8_t sliders[3];
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,18 @@
|
||||
#ifndef EZUSB_IIDX_SECMEM_CMD_H
|
||||
#define EZUSB_IIDX_SECMEM_CMD_H
|
||||
|
||||
enum ezusb_iidx_secmem_command {
|
||||
EZUSB_IIDX_SECMEM_CMD_WRITE = 0x00,
|
||||
};
|
||||
|
||||
enum ezusb_iidx_secmem_command_status_v1 {
|
||||
EZUSB_IIDX_SECMEM_CMD_STATUS_V1_WRITE_OK = 0x60,
|
||||
EZUSB_IIDX_SECMEM_CMD_STATUS_V1_FAULT = 0xFE,
|
||||
};
|
||||
|
||||
enum ezusb_iidx_secmem_command_status_v2 {
|
||||
EZUSB_IIDX_SECMEM_CMD_STATUS_V2_WRITE_OK = 0x11,
|
||||
EZUSB_IIDX_SECMEM_CMD_STATUS_V2_FAULT = 0xFE,
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,44 @@
|
||||
#ifndef EZUSB_IIDX_SECPLUG_CMD_H
|
||||
#define EZUSB_IIDX_SECPLUG_CMD_H
|
||||
|
||||
enum ezusb_iidx_secplug_dongle_slot {
|
||||
EZUSB_IIDX_SECPLUG_DONGLE_SLOT_BLACK = 0x00,
|
||||
EZUSB_IIDX_SECPLUG_DONGLE_SLOT_WHITE = 0x01,
|
||||
};
|
||||
|
||||
enum ezusb_iidx_secplug_dongle_memory {
|
||||
EZUSB_IIDX_SECPLUG_DONGLE_MEM_ROM = 0x00,
|
||||
EZUSB_IIDX_SECPLUG_DONGLE_MEM_DATA = 0x01
|
||||
};
|
||||
|
||||
enum ezusb_iidx_secplug_command_v1 {
|
||||
EZUSB_IIDX_SECPLUG_CMD_V1_READ_ROM = 0x01,
|
||||
EZUSB_IIDX_SECPLUG_CMD_V1_READ_DATA = 0x02,
|
||||
EZUSB_IIDX_SECPLUG_CMD_V1_SECURITY_CONVERSION = 0x03,
|
||||
EZUSB_IIDX_SECPLUG_CMD_V1_SELECT_BLACK_DONGLE = 0x04,
|
||||
EZUSB_IIDX_SECPLUG_CMD_V1_SELECT_WHITE_DONGLE = 0x05
|
||||
};
|
||||
|
||||
enum ezusb_iidx_secplug_command_status_v1 {
|
||||
EZUSB_IIDX_SECPLUG_CMD_STATUS_V1_OK = 0x00,
|
||||
EZUSB_IIDX_SECPLUG_CMD_STATUS_V1_FAULT = 0xFE
|
||||
};
|
||||
|
||||
enum ezusb_iidx_secplug_command_v2 {
|
||||
EZUSB_IIDX_SECPLUG_CMD_V2_INIT = 0x01,
|
||||
EZUSB_IIDX_SECPLUG_CMD_V2_READ_DATA = 0x02,
|
||||
EZUSB_IIDX_SECPLUG_CMD_V2_READ_ROM = 0x06,
|
||||
EZUSB_IIDX_SECPLUG_CMD_V2_SELECT_WHITE_DONGLE_2 = 0x07,
|
||||
EZUSB_IIDX_SECPLUG_CMD_V2_SELECT_BLACK_DONGLE = 0x08,
|
||||
EZUSB_IIDX_SECPLUG_CMD_V2_SELECT_WHITE_DONGLE = 0x09
|
||||
};
|
||||
|
||||
enum ezusb_iidx_secplug_command_status_v2 {
|
||||
EZUSB_IIDX_SECPLUG_CMD_STATUS_V2_OK = 0x12,
|
||||
EZUSB_IIDX_SECPLUG_CMD_STATUS_V2_DATA_OK = 0x13,
|
||||
EZUSB_IIDX_SECPLUG_CMD_STATUS_V2_ROM_OK = 0x15,
|
||||
EZUSB_IIDX_SECPLUG_CMD_STATUS_V2_SECURITY_SEL_OK = 0x16,
|
||||
EZUSB_IIDX_SECPLUG_CMD_STATUS_V2_FAIL = 0xFE
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,14 @@
|
||||
#ifndef EZUSB_IIDX_SEG16_CMD_H
|
||||
#define EZUSB_IIDX_SEG16_CMD_H
|
||||
|
||||
enum ezusb_iidx_16seg_command {
|
||||
EZUSB_IIDX_16SEG_CMD_WRITE = 0x03,
|
||||
};
|
||||
|
||||
enum ezusb_iidx_16seg_command_status {
|
||||
EZUSB_IIDX_16SEG_CMD_STATUS_OK = 0x00,
|
||||
EZUSB_IIDX_16SEG_CMD_STATUS_FAULT = 0xFE
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,16 @@
|
||||
#ifndef EZUSB_IIDX_SERIAL_CMD_H
|
||||
#define EZUSB_IIDX_SERIAL_CMD_H
|
||||
|
||||
enum ezusb_iidx_serial_command {
|
||||
EZUSB_IIDX_SERIAL_CMD_READ_BUFFER = 0x02,
|
||||
EZUSB_IIDX_SERIAL_CMD_WRITE_BUFFER = 0x03,
|
||||
EZUSB_IIDX_SERIAL_CMD_CLEAR_READ_BUFFER = 0x04,
|
||||
EZUSB_IIDX_SERIAL_CMD_CLEAR_WRITE_BUFFER = 0x05
|
||||
};
|
||||
|
||||
enum ezusb_iidx_serial_command_status {
|
||||
EZUSB_IIDX_SERIAL_CMD_STATUS_OK = 0x00,
|
||||
EZUSB_IIDX_SERIAL_CMD_STATUS_FAULT = 0xFE
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,10 @@
|
||||
#ifndef EZUSB_IIDX_SRAM_CMD_H
|
||||
#define EZUSB_IIDX_SRAM_CMD_H
|
||||
|
||||
enum ezusb_iidx_sram_command {
|
||||
EZUSB_IIDX_SRAM_CMD_WRITE = 0x03,
|
||||
EZUSB_IIDX_SRAM_CMD_READ = 0x02,
|
||||
EZUSB_IIDX_SRAM_CMD_DONE = 0x04
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,116 @@
|
||||
#define LOG_MODULE "ezusb-iidx-sram"
|
||||
|
||||
#include "ezusb-iidx/sram.h"
|
||||
|
||||
#include "util/log.h"
|
||||
|
||||
#include "ezusb-iidx.h"
|
||||
#include "sram-cmd.h"
|
||||
|
||||
static bool ezusb_iidx_sram_write_page(HANDLE handle, uint8_t node,
|
||||
uint8_t page, const void* buffer, uint16_t size)
|
||||
{
|
||||
struct ezusb_iidx_msg_bulk_packet packet;
|
||||
|
||||
memset(&packet.payload, 0, 62);
|
||||
|
||||
packet.node = node;
|
||||
packet.page = page;
|
||||
|
||||
if (size > 62) {
|
||||
size = 62;
|
||||
}
|
||||
|
||||
//log_misc("Writing sram page %d, size %d", page, size);
|
||||
|
||||
memcpy(packet.payload, buffer, size);
|
||||
|
||||
return ezusb_iidx_bulk_write(handle, &packet);
|
||||
}
|
||||
|
||||
static bool ezusb_iidx_sram_read_page(HANDLE handle, uint8_t node)
|
||||
{
|
||||
struct ezusb_iidx_msg_bulk_packet packet;
|
||||
|
||||
memset(&packet, 0, sizeof(struct ezusb_iidx_msg_bulk_packet));
|
||||
|
||||
return ezusb_iidx_bulk_read(handle, &packet);
|
||||
}
|
||||
|
||||
static bool ezusb_iidx_sram_write(HANDLE handle, uint8_t node,
|
||||
const void* buffer, uint16_t size, uint8_t* pages_written)
|
||||
{
|
||||
uint8_t page;
|
||||
uint16_t offset;
|
||||
|
||||
page = 0;
|
||||
offset = 0;
|
||||
*pages_written = 0;
|
||||
|
||||
/* Write in ezusb page sizes */
|
||||
while (offset < size) {
|
||||
if ( !ezusb_iidx_sram_write_page(handle, node, page++,
|
||||
buffer + offset, size - offset)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
offset += 62;
|
||||
|
||||
/* if we are too fast, the downloads might fail */
|
||||
Sleep(10);
|
||||
(*pages_written)++;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool ezusb_iidx_sram_read(HANDLE handle, uint8_t node, uint8_t pages)
|
||||
{
|
||||
for (uint8_t i = 0; i < pages; i++) {
|
||||
if (!ezusb_iidx_sram_read_page(handle, node)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* if we are too fast, this might fail */
|
||||
Sleep(10);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ezusb_iidx_sram_init(HANDLE handle, const void* buffer, uint16_t size)
|
||||
{
|
||||
uint8_t pages_written;
|
||||
struct ezusb_iidx_msg_interrupt_read_packet int_read_data;
|
||||
|
||||
log_info("Init, size %d", size);
|
||||
|
||||
ezusb_iidx_execute_cmd(handle, EZUSB_IIDX_MSG_NODE_SRAM,
|
||||
EZUSB_IIDX_SRAM_CMD_WRITE, 1, 0, &int_read_data);
|
||||
|
||||
log_info("Writing...");
|
||||
|
||||
if ( !ezusb_iidx_sram_write(handle, EZUSB_IIDX_MSG_NODE_SRAM,
|
||||
buffer, size, &pages_written)) {
|
||||
log_warning("Writing sram failed, pages written so far: %d",
|
||||
pages_written);
|
||||
return false;
|
||||
}
|
||||
|
||||
log_info("Data written, pages: %d", pages_written);
|
||||
log_info("Reading back...");
|
||||
|
||||
ezusb_iidx_execute_cmd(handle, EZUSB_IIDX_MSG_NODE_SRAM,
|
||||
EZUSB_IIDX_SRAM_CMD_READ, 1, 0, &int_read_data);
|
||||
|
||||
if (!ezusb_iidx_sram_read(handle, EZUSB_IIDX_MSG_NODE_SRAM,
|
||||
pages_written)) {
|
||||
log_warning("Reading back failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
ezusb_iidx_execute_cmd(handle, EZUSB_IIDX_MSG_NODE_SRAM,
|
||||
EZUSB_IIDX_SRAM_CMD_DONE, 1, 0, &int_read_data);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
#ifndef EZUSB_IIDX_SRAM_H
|
||||
#define EZUSB_IIDX_SRAM_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <windows.h>
|
||||
|
||||
bool ezusb_iidx_sram_init(HANDLE handle, const void* buffer, uint16_t size);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,13 @@
|
||||
#ifndef EZUSB_IIDX_WDT_CMD_H
|
||||
#define EZUSB_IIDX_WDT_CMD_H
|
||||
|
||||
enum ezusb_iidx_wdt_command {
|
||||
EZUSB_IIDX_WDT_CMD_INIT = 0x3C
|
||||
};
|
||||
|
||||
enum ezusb_iidx_wdt_command_status {
|
||||
EZUSB_IIDX_WDT_CMD_STATUS_OK = 0x00,
|
||||
EZUSB_IIDX_WDT_CMD_STATUS_FAULT = 0xFE
|
||||
};
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user