summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorXaviDCR92 <xavi.dcr@gmail.com>2019-01-12 01:23:12 +0100
committerXaviDCR92 <xavi.dcr@gmail.com>2019-01-12 01:23:12 +0100
commit35e37535556d7d2cce3bb04a9f6bff810ebefccc (patch)
tree749a665ca052622e974a7b180c4ab8c607a6d706 /src
parentdec723669aa2a5e54ab675d93bd980a56f1be0c2 (diff)
Sending a PSX-EXE is now totally implemented.
Diffstat (limited to 'src')
-rw-r--r--src/app.rs10
-rw-r--r--src/transfer.rs135
2 files changed, 98 insertions, 47 deletions
diff --git a/src/app.rs b/src/app.rs
index 1b14410..a0df9e7 100644
--- a/src/app.rs
+++ b/src/app.rs
@@ -68,16 +68,22 @@ fn serial_comm(addr : Option<&String>, port_name : &String, baud_rate : Option<&
let mut state = TransferState::FirstContact;
let mut prev_state = state;
+ let mut sent_bytes = 0 as usize;
+
+ let exe_data = transfer::get_exe_data(&folder).unwrap();
loop {
state = match state {
TransferState::FirstContact => transfer::first_contact(&mut port),
TransferState::WaitAck => {
- state = transfer::wait_ack(&mut port, prev_state);
+ state = transfer::wait_ack_default(&mut port, prev_state);
prev_state = state;
state
},
- TransferState::SendHeader => transfer::send_header(&mut port, folder),
+ TransferState::SendHeader => transfer::send_header(&mut port, &exe_data),
+ TransferState::SendExeSize => transfer::send_exe_size(&mut port, &exe_data),
+ TransferState::CleaningRAM => transfer::wait_ack_default(&mut port, prev_state),
+ TransferState::SendExeData => transfer::send_exe_data(&mut port, &mut sent_bytes, &exe_data),
TransferState::Finished => break
};
}
diff --git a/src/transfer.rs b/src/transfer.rs
index 8960c8d..ba1501c 100644
--- a/src/transfer.rs
+++ b/src/transfer.rs
@@ -3,6 +3,9 @@ pub enum TransferState {
FirstContact,
WaitAck,
SendHeader,
+ SendExeSize,
+ CleaningRAM,
+ SendExeData,
Finished
}
@@ -16,7 +19,6 @@ pub fn first_contact(port : &mut serial::SystemPort) -> TransferState {
Err(_) => TransferState::FirstContact,
Ok(b) => {
if b == 1 {
- println!("Written 1 byte: {}", INITIAL_TRANSMISSION);
TransferState::WaitAck
}
else
@@ -27,76 +29,119 @@ pub fn first_contact(port : &mut serial::SystemPort) -> TransferState {
}
}
-pub fn wait_ack(port : &mut serial::SystemPort, prev_state: TransferState) -> TransferState {
-
+fn wait_ack(port : &mut serial::SystemPort, buffer : &mut [u8]) -> Result<usize, std::io::Error> {
// For some reason, this trait has to be imported,
// but shouldn't serial::SerialPort be already doing this?
use std::io::Read;
- let mut buffer : [u8; 1] = [0];
-
use serial::SerialPort;
- (*port).set_timeout(std::time::Duration::from_secs(2)).expect("Could not adjust timeout");
+ const TIMEOUT_SECONDS : u64 = 2;
- match (*port).read(&mut buffer) {
- Err(_) => {
- prev_state
- },
- Ok(b) => {
- if b == 1 {
- if buffer[0] == 'b' as u8 {
- println!("Received ACK");
- match prev_state {
- TransferState::FirstContact => {
- println!("Now send header");
- TransferState::SendHeader
- },
- _ => TransferState::Finished
- }
- }
- else
- {
- prev_state
+ (*port).set_timeout(std::time::Duration::from_secs(TIMEOUT_SECONDS)).expect("Could not adjust timeout");
+
+ (*port).read(buffer)
+}
+
+pub fn wait_ack_default(port : &mut serial::SystemPort, prev_state: TransferState) -> TransferState {
+ let mut buffer : [u8; 1] = [0];
+
+ match wait_ack(port, &mut buffer) {
+ Ok(1) => {
+ if *(buffer.get(0).unwrap()) == 'b' as u8 {
+ match prev_state {
+ TransferState::FirstContact => TransferState::SendHeader,
+ TransferState::SendHeader => TransferState::SendExeSize,
+ TransferState::SendExeSize => TransferState::CleaningRAM,
+ TransferState::CleaningRAM => TransferState::SendExeData,
+ TransferState::SendExeData => TransferState::SendExeData,
+ _ => TransferState::Finished
}
}
else
{
prev_state
}
+ },
+ _ => {
+ match prev_state {
+ TransferState::SendExeSize => TransferState::CleaningRAM,
+ _ => prev_state
+ }
}
}
}
-pub fn send_header(port : &mut serial::SystemPort, folder : &String) -> TransferState {
- match get_exe_data(&folder) {
- None => TransferState::Finished,
- Some(header) => {
- const HEADER_SIZE : usize = 32 as usize;
- const PACKET_SIZE : usize = 8 as usize;
+const PACKET_SIZE : usize = 8 as usize;
- for packet in (0..HEADER_SIZE).step_by(PACKET_SIZE) {
- match header.get(packet..(packet + PACKET_SIZE)) {
- None => return TransferState::Finished,
- Some(chunk) => {
- use std::{thread, time};
+pub fn send_header(port : &mut serial::SystemPort, exe_data: &Vec<u8>) -> TransferState {
- thread::sleep(time::Duration::from_millis(100));
+ const HEADER_SIZE : usize = 32 as usize;
+ for packet in (0..HEADER_SIZE).step_by(PACKET_SIZE) {
+ match exe_data.get(packet..(packet + PACKET_SIZE)) {
+ None => return TransferState::Finished,
+ Some(chunk) => {
+ use std::{thread, time};
- use std::io::Write;
- (*port).write(&chunk).expect("Could not write EXE header into the device");
+ thread::sleep(time::Duration::from_millis(100));
- println!("Sent packet {:?}", &chunk);
- }
- }
+ use std::io::Write;
+ (*port).write(&chunk).expect("Could not write EXE header into the device");
}
+ }
+ }
- TransferState::WaitAck
+ TransferState::WaitAck
+}
+
+const EXE_DATA_OFFSET : usize = 2048 as usize;
+
+pub fn send_exe_size(port: &mut serial::SystemPort, exe_data: &Vec<u8>) -> TransferState {
+ if exe_data.len() > EXE_DATA_OFFSET {
+ let exe_size = exe_data.len() - EXE_DATA_OFFSET;
+
+ use std::io::Write;
+
+ let exe_size_vec : [u8; 4] = [(exe_size & 0xFF) as u8,
+ ((exe_size & 0xFF00) >> 8) as u8,
+ ((exe_size & 0xFF0000) >> 16) as u8,
+ ((exe_size & 0xFF000000) >> 24) as u8];
+ (*port).write(&exe_size_vec).expect("Could not write EXE size into the device");
+
+ TransferState::WaitAck
+ }
+ else
+ {
+ println!("PSX-EXE is too small");
+ TransferState::Finished
+ }
+}
+
+pub fn send_exe_data(port: &mut serial::SystemPort, sent_bytes: &mut usize, exe_data: &Vec<u8>) -> TransferState {
+ let exe_size = exe_data.len();
+
+ let total_sent_bytes = *sent_bytes + EXE_DATA_OFFSET;
+
+ if total_sent_bytes < exe_size {
+ match exe_data.get(total_sent_bytes..(total_sent_bytes + PACKET_SIZE)) {
+ None => return TransferState::Finished,
+ Some(chunk) => {
+ use std::io::Write;
+ (*port).write(&chunk).expect("Could not write EXE header into the device");
+
+ *sent_bytes += PACKET_SIZE;
+ }
}
+
+ TransferState::WaitAck
+ }
+ else
+ {
+ TransferState::Finished
}
}
-fn get_exe_data(folder: &String) -> Option<Vec<u8>> {
+pub fn get_exe_data(folder: &String) -> Option<Vec<u8>> {
match get_exe_name(folder) {
None => None,
Some(exe_name) => {
@@ -106,7 +151,7 @@ fn get_exe_data(folder: &String) -> Option<Vec<u8>> {
match fs::read(&exe_path) {
Err(e) => {
- println!("{:?}. File path: {}", e, exe_path);
+ println!("{}. File path: {}", e, exe_path);
None
},
Ok(data) => {