mirror of
https://github.com/Polprzewodnikowy/SummerCart64.git
synced 2024-11-21 21:49:15 +01:00
[SC64][SW] Optimized memory usage in the sc64deployer
This commit is contained in:
parent
e9ee025e21
commit
d8976def97
@ -892,19 +892,15 @@ fn handle_test_command(connection: Connection) -> Result<(), sc64::Error> {
|
|||||||
|
|
||||||
println!("{}: USB", "[SC64 Tests]".bold());
|
println!("{}: USB", "[SC64 Tests]".bold());
|
||||||
|
|
||||||
print!(" Performing USB write speed test... ");
|
|
||||||
stdout().flush().unwrap();
|
|
||||||
println!(
|
|
||||||
"{}",
|
|
||||||
format!("{:.2} MiB/s", sc64.test_usb_speed(true)?).bright_green()
|
|
||||||
);
|
|
||||||
|
|
||||||
print!(" Performing USB read speed test... ");
|
print!(" Performing USB read speed test... ");
|
||||||
stdout().flush().unwrap();
|
stdout().flush().unwrap();
|
||||||
println!(
|
let read_speed = sc64.test_usb_speed(sc64::SpeedTestDirection::Read)?;
|
||||||
"{}",
|
println!("{}", format!("{read_speed:.2} MiB/s",).bright_green());
|
||||||
format!("{:.2} MiB/s", sc64.test_usb_speed(false)?).bright_green()
|
|
||||||
);
|
print!(" Performing USB write speed test... ");
|
||||||
|
stdout().flush().unwrap();
|
||||||
|
let write_speed = sc64.test_usb_speed(sc64::SpeedTestDirection::Write)?;
|
||||||
|
println!("{}", format!("{write_speed:.2} MiB/s",).bright_green());
|
||||||
|
|
||||||
println!("{}: SDRAM (pattern)", "[SC64 Tests]".bold());
|
println!("{}: SDRAM (pattern)", "[SC64 Tests]".bold());
|
||||||
|
|
||||||
|
@ -38,12 +38,6 @@ impl TryFrom<u32> for DataType {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Command {
|
|
||||||
pub id: u8,
|
|
||||||
pub args: [u32; 2],
|
|
||||||
pub data: Vec<u8>,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct Response {
|
pub struct Response {
|
||||||
pub id: u8,
|
pub id: u8,
|
||||||
pub data: Vec<u8>,
|
pub data: Vec<u8>,
|
||||||
@ -167,14 +161,14 @@ pub trait Backend {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn send_command(&mut self, command: &Command) -> std::io::Result<()> {
|
fn send_command(&mut self, id: u8, args: [u32; 2], data: &[u8]) -> std::io::Result<()> {
|
||||||
self.write_all(b"CMD")?;
|
self.write_all(b"CMD")?;
|
||||||
self.write_all(&command.id.to_be_bytes())?;
|
self.write_all(&id.to_be_bytes())?;
|
||||||
|
|
||||||
self.write_all(&command.args[0].to_be_bytes())?;
|
self.write_all(&args[0].to_be_bytes())?;
|
||||||
self.write_all(&command.args[1].to_be_bytes())?;
|
self.write_all(&args[1].to_be_bytes())?;
|
||||||
|
|
||||||
self.write_all(&command.data)?;
|
self.write_all(data)?;
|
||||||
|
|
||||||
self.flush()?;
|
self.flush()?;
|
||||||
|
|
||||||
@ -332,17 +326,17 @@ impl Backend for TcpBackend {
|
|||||||
self.stream.shutdown(std::net::Shutdown::Both).ok();
|
self.stream.shutdown(std::net::Shutdown::Both).ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn send_command(&mut self, command: &Command) -> std::io::Result<()> {
|
fn send_command(&mut self, id: u8, args: [u32; 2], data: &[u8]) -> std::io::Result<()> {
|
||||||
let payload_data_type: u32 = DataType::Command.into();
|
let payload_data_type: u32 = DataType::Command.into();
|
||||||
self.write_all(&payload_data_type.to_be_bytes())?;
|
self.write_all(&payload_data_type.to_be_bytes())?;
|
||||||
|
|
||||||
self.write_all(&command.id.to_be_bytes())?;
|
self.write_all(&id.to_be_bytes())?;
|
||||||
self.write_all(&command.args[0].to_be_bytes())?;
|
self.write_all(&args[0].to_be_bytes())?;
|
||||||
self.write_all(&command.args[1].to_be_bytes())?;
|
self.write_all(&args[1].to_be_bytes())?;
|
||||||
|
|
||||||
let command_data_length = command.data.len() as u32;
|
let command_data_length = data.len() as u32;
|
||||||
self.write_all(&command_data_length.to_be_bytes())?;
|
self.write_all(&command_data_length.to_be_bytes())?;
|
||||||
self.write_all(&command.data)?;
|
self.write_all(data)?;
|
||||||
|
|
||||||
self.flush()?;
|
self.flush()?;
|
||||||
|
|
||||||
@ -445,22 +439,29 @@ pub struct Link {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Link {
|
impl Link {
|
||||||
pub fn execute_command(&mut self, command: &Command) -> Result<Vec<u8>, Error> {
|
pub fn execute_command(
|
||||||
self.execute_command_raw(command, false, false)
|
&mut self,
|
||||||
|
id: u8,
|
||||||
|
args: [u32; 2],
|
||||||
|
data: &[u8],
|
||||||
|
) -> Result<Vec<u8>, Error> {
|
||||||
|
self.execute_command_raw(id, args, data, false, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn execute_command_raw(
|
pub fn execute_command_raw(
|
||||||
&mut self,
|
&mut self,
|
||||||
command: &Command,
|
id: u8,
|
||||||
|
args: [u32; 2],
|
||||||
|
data: &[u8],
|
||||||
no_response: bool,
|
no_response: bool,
|
||||||
ignore_error: bool,
|
ignore_error: bool,
|
||||||
) -> Result<Vec<u8>, Error> {
|
) -> Result<Vec<u8>, Error> {
|
||||||
self.backend.send_command(command)?;
|
self.backend.send_command(id, args, data)?;
|
||||||
if no_response {
|
if no_response {
|
||||||
return Ok(vec![]);
|
return Ok(vec![]);
|
||||||
}
|
}
|
||||||
let response = self.receive_response()?;
|
let response = self.receive_response()?;
|
||||||
if command.id != response.id {
|
if id != response.id {
|
||||||
return Err(Error::new("Command response ID didn't match"));
|
return Err(Error::new("Command response ID didn't match"));
|
||||||
}
|
}
|
||||||
if !ignore_error && response.error {
|
if !ignore_error && response.error {
|
||||||
|
@ -15,13 +15,14 @@ pub use self::{
|
|||||||
types::{
|
types::{
|
||||||
BootMode, ButtonMode, ButtonState, CicSeed, DataPacket, DdDiskState, DdDriveType, DdMode,
|
BootMode, ButtonMode, ButtonState, CicSeed, DataPacket, DdDiskState, DdDriveType, DdMode,
|
||||||
DebugPacket, DiagnosticData, DiskPacket, DiskPacketKind, FpgaDebugData, ISViewer,
|
DebugPacket, DiagnosticData, DiskPacket, DiskPacketKind, FpgaDebugData, ISViewer,
|
||||||
MemoryTestPattern, MemoryTestPatternResult, SaveType, SaveWriteback, Switch, TvType,
|
MemoryTestPattern, MemoryTestPatternResult, SaveType, SaveWriteback, SpeedTestDirection,
|
||||||
|
Switch, TvType,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
use self::{
|
use self::{
|
||||||
cic::{sign_ipl3, IPL3_LENGTH, IPL3_OFFSET},
|
cic::{sign_ipl3, IPL3_LENGTH, IPL3_OFFSET},
|
||||||
link::{Command, Link},
|
link::Link,
|
||||||
time::{convert_from_datetime, convert_to_datetime},
|
time::{convert_from_datetime, convert_to_datetime},
|
||||||
types::{
|
types::{
|
||||||
get_config, get_setting, Config, ConfigId, FirmwareStatus, Setting, SettingId, UpdateStatus,
|
get_config, get_setting, Config, ConfigId, FirmwareStatus, Setting, SettingId, UpdateStatus,
|
||||||
@ -105,11 +106,7 @@ const MEMORY_CHUNK_LENGTH: usize = 8 * 1024 * 1024;
|
|||||||
|
|
||||||
impl SC64 {
|
impl SC64 {
|
||||||
fn command_identifier_get(&mut self) -> Result<[u8; 4], Error> {
|
fn command_identifier_get(&mut self) -> Result<[u8; 4], Error> {
|
||||||
let data = self.link.execute_command(&Command {
|
let data = self.link.execute_command(b'v', [0, 0], &[])?;
|
||||||
id: b'v',
|
|
||||||
args: [0, 0],
|
|
||||||
data: vec![],
|
|
||||||
})?;
|
|
||||||
if data.len() != 4 {
|
if data.len() != 4 {
|
||||||
return Err(Error::new(
|
return Err(Error::new(
|
||||||
"Invalid data length received for identifier get command",
|
"Invalid data length received for identifier get command",
|
||||||
@ -119,11 +116,7 @@ impl SC64 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn command_version_get(&mut self) -> Result<(u16, u16, u32), Error> {
|
fn command_version_get(&mut self) -> Result<(u16, u16, u32), Error> {
|
||||||
let data = self.link.execute_command(&Command {
|
let data = self.link.execute_command(b'V', [0, 0], &[])?;
|
||||||
id: b'V',
|
|
||||||
args: [0, 0],
|
|
||||||
data: vec![],
|
|
||||||
})?;
|
|
||||||
if data.len() != 8 {
|
if data.len() != 8 {
|
||||||
return Err(Error::new(
|
return Err(Error::new(
|
||||||
"Invalid data length received for version get command",
|
"Invalid data length received for version get command",
|
||||||
@ -136,11 +129,7 @@ impl SC64 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn command_state_reset(&mut self) -> Result<(), Error> {
|
fn command_state_reset(&mut self) -> Result<(), Error> {
|
||||||
self.link.execute_command(&Command {
|
self.link.execute_command(b'R', [0, 0], &[])?;
|
||||||
id: b'R',
|
|
||||||
args: [0, 0],
|
|
||||||
data: vec![],
|
|
||||||
})?;
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -156,20 +145,14 @@ impl SC64 {
|
|||||||
((if disable { 1 } else { 0 }) << 24) | ((seed as u32) << 16) | checksum_high,
|
((if disable { 1 } else { 0 }) << 24) | ((seed as u32) << 16) | checksum_high,
|
||||||
checksum_low,
|
checksum_low,
|
||||||
];
|
];
|
||||||
self.link.execute_command(&Command {
|
self.link.execute_command(b'B', args, &[])?;
|
||||||
id: b'B',
|
|
||||||
args,
|
|
||||||
data: vec![],
|
|
||||||
})?;
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn command_config_get(&mut self, config_id: ConfigId) -> Result<Config, Error> {
|
fn command_config_get(&mut self, config_id: ConfigId) -> Result<Config, Error> {
|
||||||
let data = self.link.execute_command(&Command {
|
let data = self
|
||||||
id: b'c',
|
.link
|
||||||
args: [config_id.into(), 0],
|
.execute_command(b'c', [config_id.into(), 0], &[])?;
|
||||||
data: vec![],
|
|
||||||
})?;
|
|
||||||
if data.len() != 4 {
|
if data.len() != 4 {
|
||||||
return Err(Error::new(
|
return Err(Error::new(
|
||||||
"Invalid data length received for config get command",
|
"Invalid data length received for config get command",
|
||||||
@ -180,20 +163,14 @@ impl SC64 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn command_config_set(&mut self, config: Config) -> Result<(), Error> {
|
fn command_config_set(&mut self, config: Config) -> Result<(), Error> {
|
||||||
self.link.execute_command(&Command {
|
self.link.execute_command(b'C', config.into(), &[])?;
|
||||||
id: b'C',
|
|
||||||
args: config.into(),
|
|
||||||
data: vec![],
|
|
||||||
})?;
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn command_setting_get(&mut self, setting_id: SettingId) -> Result<Setting, Error> {
|
fn command_setting_get(&mut self, setting_id: SettingId) -> Result<Setting, Error> {
|
||||||
let data = self.link.execute_command(&Command {
|
let data = self
|
||||||
id: b'a',
|
.link
|
||||||
args: [setting_id.into(), 0],
|
.execute_command(b'a', [setting_id.into(), 0], &[])?;
|
||||||
data: vec![],
|
|
||||||
})?;
|
|
||||||
if data.len() != 4 {
|
if data.len() != 4 {
|
||||||
return Err(Error::new(
|
return Err(Error::new(
|
||||||
"Invalid data length received for setting get command",
|
"Invalid data length received for setting get command",
|
||||||
@ -204,20 +181,12 @@ impl SC64 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn command_setting_set(&mut self, setting: Setting) -> Result<(), Error> {
|
fn command_setting_set(&mut self, setting: Setting) -> Result<(), Error> {
|
||||||
self.link.execute_command(&Command {
|
self.link.execute_command(b'A', setting.into(), &[])?;
|
||||||
id: b'A',
|
|
||||||
args: setting.into(),
|
|
||||||
data: vec![],
|
|
||||||
})?;
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn command_time_get(&mut self) -> Result<NaiveDateTime, Error> {
|
fn command_time_get(&mut self) -> Result<NaiveDateTime, Error> {
|
||||||
let data = self.link.execute_command(&Command {
|
let data = self.link.execute_command(b't', [0, 0], &[])?;
|
||||||
id: b't',
|
|
||||||
args: [0, 0],
|
|
||||||
data: vec![],
|
|
||||||
})?;
|
|
||||||
if data.len() != 8 {
|
if data.len() != 8 {
|
||||||
return Err(Error::new(
|
return Err(Error::new(
|
||||||
"Invalid data length received for time get command",
|
"Invalid data length received for time get command",
|
||||||
@ -227,20 +196,15 @@ impl SC64 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn command_time_set(&mut self, datetime: NaiveDateTime) -> Result<(), Error> {
|
fn command_time_set(&mut self, datetime: NaiveDateTime) -> Result<(), Error> {
|
||||||
self.link.execute_command(&Command {
|
self.link
|
||||||
id: b'T',
|
.execute_command(b'T', convert_from_datetime(datetime), &[])?;
|
||||||
args: convert_from_datetime(datetime),
|
|
||||||
data: vec![],
|
|
||||||
})?;
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn command_memory_read(&mut self, address: u32, length: usize) -> Result<Vec<u8>, Error> {
|
fn command_memory_read(&mut self, address: u32, length: usize) -> Result<Vec<u8>, Error> {
|
||||||
let data = self.link.execute_command(&Command {
|
let data = self
|
||||||
id: b'm',
|
.link
|
||||||
args: [address, length as u32],
|
.execute_command(b'm', [address, length as u32], &[])?;
|
||||||
data: vec![],
|
|
||||||
})?;
|
|
||||||
if data.len() != length {
|
if data.len() != length {
|
||||||
return Err(Error::new(
|
return Err(Error::new(
|
||||||
"Invalid data length received for memory read command",
|
"Invalid data length received for memory read command",
|
||||||
@ -250,21 +214,16 @@ impl SC64 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn command_memory_write(&mut self, address: u32, data: &[u8]) -> Result<(), Error> {
|
fn command_memory_write(&mut self, address: u32, data: &[u8]) -> Result<(), Error> {
|
||||||
self.link.execute_command(&Command {
|
self.link
|
||||||
id: b'M',
|
.execute_command(b'M', [address, data.len() as u32], data)?;
|
||||||
args: [address, data.len() as u32],
|
|
||||||
data: data.to_vec(),
|
|
||||||
})?;
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn command_usb_write(&mut self, datatype: u8, data: &[u8]) -> Result<(), Error> {
|
fn command_usb_write(&mut self, datatype: u8, data: &[u8]) -> Result<(), Error> {
|
||||||
self.link.execute_command_raw(
|
self.link.execute_command_raw(
|
||||||
&Command {
|
b'U',
|
||||||
id: b'U',
|
[datatype as u32, data.len() as u32],
|
||||||
args: [datatype as u32, data.len() as u32],
|
data,
|
||||||
data: data.to_vec(),
|
|
||||||
},
|
|
||||||
true,
|
true,
|
||||||
false,
|
false,
|
||||||
)?;
|
)?;
|
||||||
@ -272,29 +231,17 @@ impl SC64 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn command_dd_set_block_ready(&mut self, error: bool) -> Result<(), Error> {
|
fn command_dd_set_block_ready(&mut self, error: bool) -> Result<(), Error> {
|
||||||
self.link.execute_command(&Command {
|
self.link.execute_command(b'D', [error as u32, 0], &[])?;
|
||||||
id: b'D',
|
|
||||||
args: [error as u32, 0],
|
|
||||||
data: vec![],
|
|
||||||
})?;
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn command_writeback_enable(&mut self) -> Result<(), Error> {
|
fn command_writeback_enable(&mut self) -> Result<(), Error> {
|
||||||
self.link.execute_command(&Command {
|
self.link.execute_command(b'W', [0, 0], &[])?;
|
||||||
id: b'W',
|
|
||||||
args: [0, 0],
|
|
||||||
data: vec![],
|
|
||||||
})?;
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn command_flash_wait_busy(&mut self, wait: bool) -> Result<u32, Error> {
|
fn command_flash_wait_busy(&mut self, wait: bool) -> Result<u32, Error> {
|
||||||
let data = self.link.execute_command(&Command {
|
let data = self.link.execute_command(b'p', [wait as u32, 0], &[])?;
|
||||||
id: b'p',
|
|
||||||
args: [wait as u32, 0],
|
|
||||||
data: vec![],
|
|
||||||
})?;
|
|
||||||
if data.len() != 4 {
|
if data.len() != 4 {
|
||||||
return Err(Error::new(
|
return Err(Error::new(
|
||||||
"Invalid data length received for flash wait busy command",
|
"Invalid data length received for flash wait busy command",
|
||||||
@ -305,24 +252,14 @@ impl SC64 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn command_flash_erase_block(&mut self, address: u32) -> Result<(), Error> {
|
fn command_flash_erase_block(&mut self, address: u32) -> Result<(), Error> {
|
||||||
self.link.execute_command(&Command {
|
self.link.execute_command(b'P', [address, 0], &[])?;
|
||||||
id: b'P',
|
|
||||||
args: [address, 0],
|
|
||||||
data: vec![],
|
|
||||||
})?;
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn command_firmware_backup(&mut self, address: u32) -> Result<(FirmwareStatus, u32), Error> {
|
fn command_firmware_backup(&mut self, address: u32) -> Result<(FirmwareStatus, u32), Error> {
|
||||||
let data = self.link.execute_command_raw(
|
let data = self
|
||||||
&Command {
|
.link
|
||||||
id: b'f',
|
.execute_command_raw(b'f', [address, 0], &[], false, true)?;
|
||||||
args: [address, 0],
|
|
||||||
data: vec![],
|
|
||||||
},
|
|
||||||
false,
|
|
||||||
true,
|
|
||||||
)?;
|
|
||||||
if data.len() != 8 {
|
if data.len() != 8 {
|
||||||
return Err(Error::new(
|
return Err(Error::new(
|
||||||
"Invalid data length received for firmware backup command",
|
"Invalid data length received for firmware backup command",
|
||||||
@ -338,15 +275,9 @@ impl SC64 {
|
|||||||
address: u32,
|
address: u32,
|
||||||
length: usize,
|
length: usize,
|
||||||
) -> Result<FirmwareStatus, Error> {
|
) -> Result<FirmwareStatus, Error> {
|
||||||
let data = self.link.execute_command_raw(
|
let data =
|
||||||
&Command {
|
self.link
|
||||||
id: b'F',
|
.execute_command_raw(b'F', [address, length as u32], &[], false, true)?;
|
||||||
args: [address, length as u32],
|
|
||||||
data: vec![],
|
|
||||||
},
|
|
||||||
false,
|
|
||||||
true,
|
|
||||||
)?;
|
|
||||||
if data.len() != 4 {
|
if data.len() != 4 {
|
||||||
return Err(Error::new(
|
return Err(Error::new(
|
||||||
"Invalid data length received for firmware update command",
|
"Invalid data length received for firmware update command",
|
||||||
@ -356,20 +287,12 @@ impl SC64 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn command_fpga_debug_data_get(&mut self) -> Result<FpgaDebugData, Error> {
|
fn command_fpga_debug_data_get(&mut self) -> Result<FpgaDebugData, Error> {
|
||||||
let data = self.link.execute_command(&Command {
|
let data = self.link.execute_command(b'?', [0, 0], &[])?;
|
||||||
id: b'?',
|
|
||||||
args: [0, 0],
|
|
||||||
data: vec![],
|
|
||||||
})?;
|
|
||||||
Ok(data.try_into()?)
|
Ok(data.try_into()?)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn command_diagnostic_data_get(&mut self) -> Result<DiagnosticData, Error> {
|
fn command_diagnostic_data_get(&mut self) -> Result<DiagnosticData, Error> {
|
||||||
let data = self.link.execute_command(&Command {
|
let data = self.link.execute_command(b'%', [0, 0], &[])?;
|
||||||
id: b'%',
|
|
||||||
args: [0, 0],
|
|
||||||
data: vec![],
|
|
||||||
})?;
|
|
||||||
Ok(data.try_into()?)
|
Ok(data.try_into()?)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -752,22 +675,27 @@ impl SC64 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn test_usb_speed(&mut self, write: bool) -> Result<f64, Error> {
|
pub fn test_usb_speed(&mut self, direction: SpeedTestDirection) -> Result<f64, Error> {
|
||||||
const TEST_ADDRESS: u32 = SDRAM_ADDRESS;
|
const TEST_ADDRESS: u32 = SDRAM_ADDRESS;
|
||||||
const TEST_LENGTH: usize = 8 * 1024 * 1024;
|
const TEST_LENGTH: usize = 16 * 1024 * 1024;
|
||||||
const MIB_DIVIDER: f64 = 1024.0 * 1024.0;
|
const MIB_DIVIDER: f64 = 1024.0 * 1024.0;
|
||||||
|
|
||||||
let data = vec![0x00; TEST_LENGTH];
|
let data = vec![0x00; TEST_LENGTH];
|
||||||
|
|
||||||
let time = std::time::Instant::now();
|
let time = std::time::Instant::now();
|
||||||
|
|
||||||
if write {
|
match direction {
|
||||||
self.command_memory_write(TEST_ADDRESS, &data)?;
|
SpeedTestDirection::Read => {
|
||||||
} else {
|
|
||||||
self.command_memory_read(TEST_ADDRESS, TEST_LENGTH)?;
|
self.command_memory_read(TEST_ADDRESS, TEST_LENGTH)?;
|
||||||
}
|
}
|
||||||
|
SpeedTestDirection::Write => {
|
||||||
|
self.command_memory_write(TEST_ADDRESS, &data)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Ok((TEST_LENGTH as f64 / MIB_DIVIDER) / time.elapsed().as_secs_f64())
|
let elapsed = time.elapsed();
|
||||||
|
|
||||||
|
Ok((TEST_LENGTH as f64 / MIB_DIVIDER) / elapsed.as_secs_f64())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn test_sdram_pattern(
|
pub fn test_sdram_pattern(
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
use super::{
|
use super::{
|
||||||
error::Error,
|
error::Error,
|
||||||
link::{
|
link::{list_local_devices, new_local, AsynchronousPacket, DataType, Response, UsbPacket},
|
||||||
list_local_devices, new_local, AsynchronousPacket, Command, DataType, Response, UsbPacket,
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
use std::io::{Read, Write};
|
use std::io::{Read, Write};
|
||||||
|
|
||||||
@ -50,7 +48,7 @@ impl StreamHandler {
|
|||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
fn receive_command(&mut self) -> std::io::Result<Option<Command>> {
|
fn receive_command(&mut self) -> std::io::Result<Option<(u8, [u32; 2], Vec<u8>)>> {
|
||||||
if let Some(header) = self.try_read_header()? {
|
if let Some(header) = self.try_read_header()? {
|
||||||
if let Ok(data_type) = TryInto::<DataType>::try_into(u32::from_be_bytes(header)) {
|
if let Ok(data_type) = TryInto::<DataType>::try_into(u32::from_be_bytes(header)) {
|
||||||
if !matches!(data_type, DataType::Command) {
|
if !matches!(data_type, DataType::Command) {
|
||||||
@ -77,7 +75,7 @@ impl StreamHandler {
|
|||||||
let mut data = vec![0u8; command_data_length];
|
let mut data = vec![0u8; command_data_length];
|
||||||
self.reader.read_exact(&mut data)?;
|
self.reader.read_exact(&mut data)?;
|
||||||
|
|
||||||
Ok(Some(Command { id, args, data }))
|
Ok(Some((id, args, data)))
|
||||||
} else {
|
} else {
|
||||||
Ok(None)
|
Ok(None)
|
||||||
}
|
}
|
||||||
@ -121,8 +119,8 @@ fn server_accept_connection(port: String, connection: &mut StreamHandler) -> Res
|
|||||||
|
|
||||||
loop {
|
loop {
|
||||||
match connection.receive_command() {
|
match connection.receive_command() {
|
||||||
Ok(Some(command)) => {
|
Ok(Some((id, args, data))) => {
|
||||||
link.execute_command_raw(&command, true, true)?;
|
link.execute_command_raw(id, args, &data, true, true)?;
|
||||||
}
|
}
|
||||||
Ok(None) => {}
|
Ok(None) => {}
|
||||||
Err(error) => match error.kind() {
|
Err(error) => match error.kind() {
|
||||||
|
@ -1018,6 +1018,11 @@ impl Display for DiagnosticData {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub enum SpeedTestDirection {
|
||||||
|
Read,
|
||||||
|
Write
|
||||||
|
}
|
||||||
|
|
||||||
pub enum MemoryTestPattern {
|
pub enum MemoryTestPattern {
|
||||||
OwnAddress(bool),
|
OwnAddress(bool),
|
||||||
AllZeros,
|
AllZeros,
|
||||||
|
Loading…
Reference in New Issue
Block a user