mirror of
https://github.com/Polprzewodnikowy/SummerCart64.git
synced 2024-11-22 05:59:15 +01:00
heartbeat + write timeout + 64dd stuff
This commit is contained in:
parent
248feb94e8
commit
0c3213073d
@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
TIMER_ID_USB,
|
||||||
TIMER_ID_WRITEBACK,
|
TIMER_ID_WRITEBACK,
|
||||||
__TIMER_ID_COUNT
|
__TIMER_ID_COUNT
|
||||||
} timer_id_t;
|
} timer_id_t;
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
#include "flash.h"
|
#include "flash.h"
|
||||||
#include "fpga.h"
|
#include "fpga.h"
|
||||||
#include "rtc.h"
|
#include "rtc.h"
|
||||||
|
#include "timer.h"
|
||||||
#include "update.h"
|
#include "update.h"
|
||||||
#include "usb.h"
|
#include "usb.h"
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
@ -19,6 +20,8 @@
|
|||||||
#define RX_FLUSH_ADDRESS (0x07F00000UL)
|
#define RX_FLUSH_ADDRESS (0x07F00000UL)
|
||||||
#define RX_FLUSH_LENGTH (1 * 1024 * 1024)
|
#define RX_FLUSH_LENGTH (1 * 1024 * 1024)
|
||||||
|
|
||||||
|
#define DEBUG_WRITE_TIMEOUT_TICKS (100)
|
||||||
|
|
||||||
|
|
||||||
enum rx_state {
|
enum rx_state {
|
||||||
RX_STATE_IDLE,
|
RX_STATE_IDLE,
|
||||||
@ -49,6 +52,9 @@ struct process {
|
|||||||
uint32_t tx_token;
|
uint32_t tx_token;
|
||||||
bool tx_dma_running;
|
bool tx_dma_running;
|
||||||
|
|
||||||
|
bool flush_response;
|
||||||
|
bool flush_packet;
|
||||||
|
|
||||||
bool response_pending;
|
bool response_pending;
|
||||||
bool response_error;
|
bool response_error;
|
||||||
usb_tx_info_t response_info;
|
usb_tx_info_t response_info;
|
||||||
@ -161,11 +167,16 @@ static void usb_rx_process (void) {
|
|||||||
p.rx_state = RX_STATE_ARGS;
|
p.rx_state = RX_STATE_ARGS;
|
||||||
p.rx_counter = 0;
|
p.rx_counter = 0;
|
||||||
p.rx_dma_running = false;
|
p.rx_dma_running = false;
|
||||||
|
p.flush_response = false;
|
||||||
|
p.flush_packet = false;
|
||||||
p.response_error = false;
|
p.response_error = false;
|
||||||
p.response_info.cmd = p.rx_cmd;
|
p.response_info.cmd = p.rx_cmd;
|
||||||
p.response_info.data_length = 0;
|
p.response_info.data_length = 0;
|
||||||
p.response_info.dma_length = 0;
|
p.response_info.dma_length = 0;
|
||||||
p.response_info.done_callback = NULL;
|
p.response_info.done_callback = NULL;
|
||||||
|
if (p.rx_cmd == 'U') {
|
||||||
|
timer_set(TIMER_ID_USB, DEBUG_WRITE_TIMEOUT_TICKS);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -268,6 +279,7 @@ static void usb_rx_process (void) {
|
|||||||
if (!p.rx_dma_running) {
|
if (!p.rx_dma_running) {
|
||||||
if (usb_validate_address_length(p.rx_args[0], p.rx_args[1], true)) {
|
if (usb_validate_address_length(p.rx_args[0], p.rx_args[1], true)) {
|
||||||
p.rx_state = RX_STATE_FLUSH;
|
p.rx_state = RX_STATE_FLUSH;
|
||||||
|
p.flush_response = true;
|
||||||
} else {
|
} else {
|
||||||
fpga_reg_set(REG_USB_DMA_ADDRESS, p.rx_args[0]);
|
fpga_reg_set(REG_USB_DMA_ADDRESS, p.rx_args[0]);
|
||||||
fpga_reg_set(REG_USB_DMA_LENGTH, p.rx_args[1]);
|
fpga_reg_set(REG_USB_DMA_LENGTH, p.rx_args[1]);
|
||||||
@ -284,7 +296,8 @@ static void usb_rx_process (void) {
|
|||||||
case 'U':
|
case 'U':
|
||||||
if (p.rx_args[1] == 0) {
|
if (p.rx_args[1] == 0) {
|
||||||
p.rx_state = RX_STATE_IDLE;
|
p.rx_state = RX_STATE_IDLE;
|
||||||
} else if ((p.read_length > 0) && usb_dma_ready()) {
|
} else if (usb_dma_ready()) {
|
||||||
|
if (p.read_length > 0) {
|
||||||
uint32_t length = (p.read_length > p.rx_args[1]) ? p.rx_args[1] : p.read_length;
|
uint32_t length = (p.read_length > p.rx_args[1]) ? p.rx_args[1] : p.read_length;
|
||||||
if (!p.rx_dma_running) {
|
if (!p.rx_dma_running) {
|
||||||
fpga_reg_set(REG_USB_DMA_ADDRESS, p.read_address);
|
fpga_reg_set(REG_USB_DMA_ADDRESS, p.read_address);
|
||||||
@ -298,6 +311,11 @@ static void usb_rx_process (void) {
|
|||||||
p.read_length -= length;
|
p.read_length -= length;
|
||||||
p.read_address += length;
|
p.read_address += length;
|
||||||
p.read_ready = true;
|
p.read_ready = true;
|
||||||
|
timer_set(TIMER_ID_USB, DEBUG_WRITE_TIMEOUT_TICKS);
|
||||||
|
}
|
||||||
|
} else if (timer_get(TIMER_ID_USB) == 0) {
|
||||||
|
p.rx_state = RX_STATE_FLUSH;
|
||||||
|
p.flush_packet = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -390,9 +408,19 @@ static void usb_rx_process (void) {
|
|||||||
fpga_reg_set(REG_USB_DMA_SCR, DMA_SCR_DIRECTION | DMA_SCR_START);
|
fpga_reg_set(REG_USB_DMA_SCR, DMA_SCR_DIRECTION | DMA_SCR_START);
|
||||||
p.rx_args[1] -= length;
|
p.rx_args[1] -= length;
|
||||||
} else {
|
} else {
|
||||||
|
if (p.flush_response) {
|
||||||
p.rx_state = RX_STATE_IDLE;
|
p.rx_state = RX_STATE_IDLE;
|
||||||
p.response_pending = true;
|
p.response_pending = true;
|
||||||
p.response_error = true;
|
p.response_error = true;
|
||||||
|
} else if (p.flush_packet) {
|
||||||
|
usb_tx_info_t packet_info;
|
||||||
|
usb_create_packet(&packet_info, PACKET_CMD_DATA_FLUSHED);
|
||||||
|
if (usb_enqueue_packet(&packet_info)) {
|
||||||
|
p.rx_state = RX_STATE_IDLE;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
p.rx_state = RX_STATE_IDLE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,8 +8,9 @@
|
|||||||
|
|
||||||
typedef enum packet_cmd {
|
typedef enum packet_cmd {
|
||||||
PACKET_CMD_BUTTON_TRIGGER = 'B',
|
PACKET_CMD_BUTTON_TRIGGER = 'B',
|
||||||
PACKET_CMD_DD_REQUEST = 'D',
|
PACKET_CMD_DATA_FLUSHED = 'G',
|
||||||
PACKET_CMD_DEBUG_OUTPUT = 'U',
|
PACKET_CMD_DEBUG_OUTPUT = 'U',
|
||||||
|
PACKET_CMD_DD_REQUEST = 'D',
|
||||||
PACKET_CMD_ISV_OUTPUT = 'I',
|
PACKET_CMD_ISV_OUTPUT = 'I',
|
||||||
PACKET_CMD_SAVE_WRITEBACK = 'S',
|
PACKET_CMD_SAVE_WRITEBACK = 'S',
|
||||||
PACKET_CMD_UPDATE_STATUS = 'F',
|
PACKET_CMD_UPDATE_STATUS = 'F',
|
||||||
|
@ -26,6 +26,7 @@ enum DataType {
|
|||||||
RawBinary,
|
RawBinary,
|
||||||
Header,
|
Header,
|
||||||
Screenshot,
|
Screenshot,
|
||||||
|
Heartbeat,
|
||||||
Unknown,
|
Unknown,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -36,6 +37,7 @@ impl From<u8> for DataType {
|
|||||||
0x02 => Self::RawBinary,
|
0x02 => Self::RawBinary,
|
||||||
0x03 => Self::Header,
|
0x03 => Self::Header,
|
||||||
0x04 => Self::Screenshot,
|
0x04 => Self::Screenshot,
|
||||||
|
0x05 => Self::Heartbeat,
|
||||||
_ => Self::Unknown,
|
_ => Self::Unknown,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -48,6 +50,7 @@ impl From<DataType> for u8 {
|
|||||||
DataType::RawBinary => 0x02,
|
DataType::RawBinary => 0x02,
|
||||||
DataType::Header => 0x03,
|
DataType::Header => 0x03,
|
||||||
DataType::Screenshot => 0x04,
|
DataType::Screenshot => 0x04,
|
||||||
|
DataType::Heartbeat => 0x05,
|
||||||
DataType::Unknown => 0xFF,
|
DataType::Unknown => 0xFF,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -114,6 +117,26 @@ impl TryFrom<Vec<u8>> for ScreenshotMetadata {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct Heartbeat {
|
||||||
|
usb_protocol: u16,
|
||||||
|
version: u16,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TryFrom<&[u8]> for Heartbeat {
|
||||||
|
type Error = String;
|
||||||
|
fn try_from(value: &[u8]) -> Result<Self, Self::Error> {
|
||||||
|
if value.len() < 4 {
|
||||||
|
return Err("Invalid heartbeat data length".into());
|
||||||
|
}
|
||||||
|
let usb_protocol = u16::from_be_bytes(value[0..2].try_into().unwrap());
|
||||||
|
let version = u16::from_be_bytes(value[2..4].try_into().unwrap());
|
||||||
|
Ok(Heartbeat {
|
||||||
|
usb_protocol,
|
||||||
|
version,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
macro_rules! success {
|
macro_rules! success {
|
||||||
($($a: tt)*) => {
|
($($a: tt)*) => {
|
||||||
println!("{}", format!($($a)*).bright_blue());
|
println!("{}", format!($($a)*).bright_blue());
|
||||||
@ -134,6 +157,7 @@ macro_rules! stop {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const MAX_PACKET_LENGTH: usize = 8 * 1024 * 1024;
|
const MAX_PACKET_LENGTH: usize = 8 * 1024 * 1024;
|
||||||
|
const SUPPORTED_USB_PROTOCOL_VERSION: u16 = 2;
|
||||||
|
|
||||||
impl Handler {
|
impl Handler {
|
||||||
pub fn set_text_encoding(&mut self, encoding: Encoding) {
|
pub fn set_text_encoding(&mut self, encoding: Encoding) {
|
||||||
@ -195,6 +219,7 @@ impl Handler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
data.append(&mut b"\0".to_vec());
|
||||||
sc64::DebugPacket {
|
sc64::DebugPacket {
|
||||||
datatype: DataType::Text.into(),
|
datatype: DataType::Text.into(),
|
||||||
data,
|
data,
|
||||||
@ -220,6 +245,7 @@ impl Handler {
|
|||||||
DataType::RawBinary => self.handle_datatype_raw_binary(&data),
|
DataType::RawBinary => self.handle_datatype_raw_binary(&data),
|
||||||
DataType::Header => self.handle_datatype_header(&data),
|
DataType::Header => self.handle_datatype_header(&data),
|
||||||
DataType::Screenshot => self.handle_datatype_screenshot(&data),
|
DataType::Screenshot => self.handle_datatype_screenshot(&data),
|
||||||
|
DataType::Heartbeat => self.handle_datatype_heartbeat(&data),
|
||||||
_ => error!("Received unknown debug packet datatype: 0x{datatype:02X}"),
|
_ => error!("Received unknown debug packet datatype: 0x{datatype:02X}"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -252,13 +278,18 @@ impl Handler {
|
|||||||
Ok(mut file) => {
|
Ok(mut file) => {
|
||||||
if let Err(error) = file.write_all(&save_writeback.data) {
|
if let Err(error) = file.write_all(&save_writeback.data) {
|
||||||
error!("Couldn't write save [{filename}]: {error}");
|
error!("Couldn't write save [{filename}]: {error}");
|
||||||
}
|
} else {
|
||||||
success!("Wrote [{}] save to [{filename}]", save_writeback.save);
|
success!("Wrote [{}] save to [{filename}]", save_writeback.save);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
Err(error) => error!("Couldn't create save writeback file [{filename}]: {error}"),
|
Err(error) => error!("Couldn't create save writeback file [{filename}]: {error}"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn handle_data_flushed(&self) {
|
||||||
|
error!("Debug data write dropped due to timeout");
|
||||||
|
}
|
||||||
|
|
||||||
fn handle_datatype_text(&self, data: &[u8]) {
|
fn handle_datatype_text(&self, data: &[u8]) {
|
||||||
self.print_text(data);
|
self.print_text(data);
|
||||||
}
|
}
|
||||||
@ -269,9 +300,10 @@ impl Handler {
|
|||||||
Ok(mut file) => {
|
Ok(mut file) => {
|
||||||
if let Err(error) = file.write_all(data) {
|
if let Err(error) = file.write_all(data) {
|
||||||
error!("Couldn't write raw binary [{filename}]: {error}");
|
error!("Couldn't write raw binary [{filename}]: {error}");
|
||||||
}
|
} else {
|
||||||
success!("Wrote [{}] bytes to [{filename}]", data.len());
|
success!("Wrote [{}] bytes to [{filename}]", data.len());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
Err(error) => error!("Couldn't create raw binary file [{filename}]: {error}"),
|
Err(error) => error!("Couldn't create raw binary file [{filename}]: {error}"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -319,6 +351,23 @@ impl Handler {
|
|||||||
success!("Wrote {width}x{height} pixels to [{filename}]");
|
success!("Wrote {width}x{height} pixels to [{filename}]");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn handle_datatype_heartbeat(&mut self, data: &[u8]) {
|
||||||
|
let Heartbeat {
|
||||||
|
usb_protocol,
|
||||||
|
version,
|
||||||
|
} = match data.try_into() {
|
||||||
|
Ok(heartbeat) => heartbeat,
|
||||||
|
Err(error) => return error!("Error while parsing heartbeat datatype: {error}"),
|
||||||
|
};
|
||||||
|
if usb_protocol > SUPPORTED_USB_PROTOCOL_VERSION {
|
||||||
|
return error!("Unsupported USB protocol version: {usb_protocol}");
|
||||||
|
}
|
||||||
|
match version {
|
||||||
|
1 => {}
|
||||||
|
_ => return error!("Unsupported USB heartbeat version: {version}"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn print_text(&self, data: &[u8]) {
|
fn print_text(&self, data: &[u8]) {
|
||||||
match self.encoding {
|
match self.encoding {
|
||||||
Encoding::UTF8 => print!("{}", String::from_utf8_lossy(&data)),
|
Encoding::UTF8 => print!("{}", String::from_utf8_lossy(&data)),
|
||||||
|
@ -48,7 +48,7 @@ enum Commands {
|
|||||||
command: DownloadCommands,
|
command: DownloadCommands,
|
||||||
},
|
},
|
||||||
|
|
||||||
/// Upload ROM (and save), 64DD IPL then run disk server
|
/// Upload ROM (and save), 64DD IPL then run disk/debug server
|
||||||
_64DD(_64DDArgs),
|
_64DD(_64DDArgs),
|
||||||
|
|
||||||
/// Enter debug mode
|
/// Enter debug mode
|
||||||
@ -127,7 +127,7 @@ struct _64DDArgs {
|
|||||||
#[arg(short, long)]
|
#[arg(short, long)]
|
||||||
rom: Option<PathBuf>,
|
rom: Option<PathBuf>,
|
||||||
|
|
||||||
/// Path to the save file
|
/// Path to the save file (also used by save writeback mechanism)
|
||||||
#[arg(short, long, requires = "rom")]
|
#[arg(short, long, requires = "rom")]
|
||||||
save: Option<PathBuf>,
|
save: Option<PathBuf>,
|
||||||
|
|
||||||
@ -398,11 +398,13 @@ fn handle_64dd_command(connection: Connection, args: &_64DDArgs) -> Result<(), s
|
|||||||
|
|
||||||
let mut sc64 = init_sc64(connection, true)?;
|
let mut sc64 = init_sc64(connection, true)?;
|
||||||
|
|
||||||
|
let mut debug_handler = debug::new();
|
||||||
|
|
||||||
println!(
|
println!(
|
||||||
"{} {} {}",
|
"{}\n{}\n{}",
|
||||||
"[WARNING]:".bold().bright_yellow(),
|
"========== [WARNING] ==========".bold().bright_yellow(),
|
||||||
"Do not use this mode when real 64DD accessory is connected to the N64.".bright_yellow(),
|
"Do not use this mode when real 64DD accessory is connected to the N64".bright_yellow(),
|
||||||
"This might permanently damage either 64DD or SC64.".bright_yellow()
|
"Doing so might permanently damage either N64, 64DD or SC64".bright_yellow()
|
||||||
);
|
);
|
||||||
|
|
||||||
sc64.reset_state()?;
|
sc64.reset_state()?;
|
||||||
@ -478,10 +480,7 @@ fn handle_64dd_command(connection: Connection, args: &_64DDArgs) -> Result<(), s
|
|||||||
.iter()
|
.iter()
|
||||||
.map(|path| path.file_name().unwrap().to_string_lossy().to_string())
|
.map(|path| path.file_name().unwrap().to_string_lossy().to_string())
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let mut disks = disk::open_multiple(&disk_paths)?;
|
let mut disks = disk::open_multiple(&disk_paths)?;
|
||||||
let mut selected_disk_index: usize = 0;
|
|
||||||
let mut selected_disk: Option<&mut disk::Disk> = None;
|
|
||||||
|
|
||||||
let drive_type = match disks[0].get_format() {
|
let drive_type = match disks[0].get_format() {
|
||||||
disk::Format::Retail => sc64::DdDriveType::Retail,
|
disk::Format::Retail => sc64::DdDriveType::Retail,
|
||||||
@ -495,11 +494,22 @@ fn handle_64dd_command(connection: Connection, args: &_64DDArgs) -> Result<(), s
|
|||||||
println!(
|
println!(
|
||||||
"{}: {}",
|
"{}: {}",
|
||||||
"[64DD]".bold(),
|
"[64DD]".bold(),
|
||||||
"Press button on the SC64 device to cycle through provided disks"
|
"Press button on the back of SC64 device to cycle through provided disks"
|
||||||
.bold()
|
.bold()
|
||||||
.bright_green()
|
.bright_green()
|
||||||
);
|
);
|
||||||
|
|
||||||
|
let mut selected_disk_index: usize = 0;
|
||||||
|
let mut selected_disk = Some(&mut disks[selected_disk_index]);
|
||||||
|
println!(
|
||||||
|
"{}: Disk inserted [{}]",
|
||||||
|
"[64DD]".bold(),
|
||||||
|
disk_names[selected_disk_index].bright_green()
|
||||||
|
);
|
||||||
|
sc64.set_64dd_disk_state(sc64::DdDiskState::Inserted)?;
|
||||||
|
|
||||||
|
sc64.set_save_writeback(true)?;
|
||||||
|
|
||||||
let exit = setup_exit_flag();
|
let exit = setup_exit_flag();
|
||||||
while !exit.load(Ordering::Relaxed) {
|
while !exit.load(Ordering::Relaxed) {
|
||||||
if let Some(data_packet) = sc64.receive_data_packet()? {
|
if let Some(data_packet) = sc64.receive_data_packet()? {
|
||||||
@ -554,16 +564,27 @@ fn handle_64dd_command(connection: Connection, args: &_64DDArgs) -> Result<(), s
|
|||||||
selected_disk_index = 0;
|
selected_disk_index = 0;
|
||||||
}
|
}
|
||||||
selected_disk = Some(&mut disks[selected_disk_index]);
|
selected_disk = Some(&mut disks[selected_disk_index]);
|
||||||
sc64.set_64dd_disk_state(sc64::DdDiskState::Inserted)?;
|
|
||||||
println!(
|
println!(
|
||||||
"{}: Disk inserted [{}]",
|
"{}: Disk inserted [{}]",
|
||||||
"[64DD]".bold(),
|
"[64DD]".bold(),
|
||||||
disk_names[selected_disk_index].bright_green()
|
disk_names[selected_disk_index].bright_green()
|
||||||
);
|
);
|
||||||
|
sc64.set_64dd_disk_state(sc64::DdDiskState::Inserted)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
sc64::DataPacket::DebugData(debug_packet) => {
|
||||||
|
debug_handler.handle_debug_packet(debug_packet);
|
||||||
|
}
|
||||||
|
sc64::DataPacket::SaveWriteback(save_writeback) => {
|
||||||
|
debug_handler.handle_save_writeback(save_writeback, &args.save);
|
||||||
|
}
|
||||||
|
sc64::DataPacket::DataFlushed => {
|
||||||
|
debug_handler.handle_data_flushed();
|
||||||
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
} else if let Some(debug_packet) = debug_handler.process_user_input() {
|
||||||
|
sc64.send_debug_packet(debug_packet)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -608,6 +629,9 @@ fn handle_debug_command(connection: Connection, args: &DebugArgs) -> Result<(),
|
|||||||
sc64::DataPacket::SaveWriteback(save_writeback) => {
|
sc64::DataPacket::SaveWriteback(save_writeback) => {
|
||||||
debug_handler.handle_save_writeback(save_writeback, &args.save);
|
debug_handler.handle_save_writeback(save_writeback, &args.save);
|
||||||
}
|
}
|
||||||
|
sc64::DataPacket::DataFlushed => {
|
||||||
|
debug_handler.handle_data_flushed();
|
||||||
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
} else if let Some(debug_packet) = debug_handler.process_user_input() {
|
} else if let Some(debug_packet) = debug_handler.process_user_input() {
|
||||||
|
@ -580,6 +580,7 @@ impl From<Setting> for [u32; 2] {
|
|||||||
|
|
||||||
pub enum DataPacket {
|
pub enum DataPacket {
|
||||||
Button,
|
Button,
|
||||||
|
DataFlushed,
|
||||||
DebugData(DebugPacket),
|
DebugData(DebugPacket),
|
||||||
DiskRequest(DiskPacket),
|
DiskRequest(DiskPacket),
|
||||||
IsViewer64(Vec<u8>),
|
IsViewer64(Vec<u8>),
|
||||||
@ -592,6 +593,7 @@ impl TryFrom<Packet> for DataPacket {
|
|||||||
fn try_from(value: Packet) -> Result<Self, Self::Error> {
|
fn try_from(value: Packet) -> Result<Self, Self::Error> {
|
||||||
Ok(match value.id {
|
Ok(match value.id {
|
||||||
b'B' => Self::Button,
|
b'B' => Self::Button,
|
||||||
|
b'G' => Self::DataFlushed,
|
||||||
b'U' => Self::DebugData(value.data.try_into()?),
|
b'U' => Self::DebugData(value.data.try_into()?),
|
||||||
b'D' => Self::DiskRequest(value.data.try_into()?),
|
b'D' => Self::DiskRequest(value.data.try_into()?),
|
||||||
b'I' => Self::IsViewer64(value.data),
|
b'I' => Self::IsViewer64(value.data),
|
||||||
|
Loading…
Reference in New Issue
Block a user