#define LOG_MODULE "ezusb-iidx-fpga" #include "ezusb-iidx/fpga.h" #include #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; }