Some in-progress work
This commit is contained in:
parent
c56fa32b2c
commit
b76a115054
4
serial.c
4
serial.c
@ -703,7 +703,7 @@ again:
|
||||
return (char*)&reply[1];
|
||||
}
|
||||
|
||||
void serial_read_region(int addr, unsigned char *data, int nbytes)
|
||||
void c_serial_read_region(int addr, unsigned char *data, int nbytes)
|
||||
{
|
||||
static const int DATASZ = 64;
|
||||
unsigned char cmd[6], reply[8 + DATASZ];
|
||||
@ -741,7 +741,7 @@ again:
|
||||
}
|
||||
}
|
||||
|
||||
void serial_write_region(int addr, unsigned char *data, int nbytes)
|
||||
void c_serial_write_region(int addr, unsigned char *data, int nbytes)
|
||||
{
|
||||
//static const int DATASZ = 64;
|
||||
static const int DATASZ = 16;
|
||||
|
@ -77,6 +77,10 @@ pub fn connect() -> Radio {
|
||||
let trace_flag = false; //TODO fix
|
||||
if let Some(device_path) = crate::serial::serial_init(0x28e9, 0x018a, trace_flag) {
|
||||
if let Some(identifier) = crate::serial::identify(&device_path) {
|
||||
unsafe {
|
||||
crate::serial::device_path = Some(device_path);
|
||||
}
|
||||
|
||||
return identifier;
|
||||
}
|
||||
}
|
||||
|
150
src/serial.rs
150
src/serial.rs
@ -1,8 +1,11 @@
|
||||
use std::ffi::{CStr};
|
||||
use libc::{c_char};
|
||||
use libc::{c_char, c_int, c_uchar, c_void};
|
||||
use std::process::exit;
|
||||
use std::time::Duration;
|
||||
|
||||
//hack to handle the serial device path state
|
||||
pub static mut device_path: Option<String> = None;
|
||||
|
||||
extern {
|
||||
fn find_path(vid: libc::c_int, pid: libc::c_int) -> *const c_char;
|
||||
fn serial_identify(s: *const c_char) -> *const c_char;
|
||||
@ -61,6 +64,151 @@ fn send_receive(port: &mut dyn serial::SerialPort, command: &[u8], reply_len: us
|
||||
buf
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn serial_read_region(addr: c_int, data: *mut c_uchar, nbytes: c_int) {
|
||||
use serial::prelude::*;
|
||||
|
||||
let dev_path = unsafe {
|
||||
match device_path {
|
||||
Some(ref s) => s.clone(),
|
||||
None => {
|
||||
eprintln!("No serial device path set, exiting");
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
let mut port = match serial::open(&dev_path) {
|
||||
Ok(port) => port,
|
||||
Err(err) => {
|
||||
println!("{}", err);
|
||||
exit(-1);
|
||||
}
|
||||
};
|
||||
|
||||
port.reconfigure(&|settings: &mut dyn SerialPortSettings| {
|
||||
settings.set_baud_rate(serial::BaudRate::Baud115200)?;
|
||||
settings.set_char_size(serial::CharSize::Bits8);
|
||||
Ok(())
|
||||
}).unwrap();
|
||||
port.set_timeout(Duration::new(1,0)).unwrap();
|
||||
|
||||
const DATA_SIZE: usize = 64;
|
||||
let num_bytes = nbytes as usize;
|
||||
let addr = addr as usize;
|
||||
|
||||
let mut output_data = vec![];
|
||||
|
||||
let mut n = 0;
|
||||
while n < num_bytes {
|
||||
// Serial read command: 'R' aa aa aa aa 0x10
|
||||
let cmd: [u8; 6] = [
|
||||
0x52, // ASCII 'R'
|
||||
((addr + n) >> 24) as u8,
|
||||
((addr + n) >> 16) as u8,
|
||||
((addr + n) >> 8) as u8,
|
||||
(addr + n) as u8,
|
||||
64,
|
||||
];
|
||||
let reply_len = 8 + DATA_SIZE;
|
||||
eprintln!("Here in serial_read_region");
|
||||
let reply = send_receive(&mut port, &cmd, reply_len, true);
|
||||
if reply[0] != b'W' || reply[7+DATA_SIZE] != 0x6 {
|
||||
eprintln!("serial_read_region: wrong read reply: {:?} shit: {}", reply, reply[7+DATA_SIZE]);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
//Compute checksum
|
||||
let mut checksum: u8 = reply[1];
|
||||
for idx in 2..6+DATA_SIZE {
|
||||
checksum = checksum.overflowing_add(reply[idx]).0;
|
||||
}
|
||||
let expected_checksum = reply[6+DATA_SIZE];
|
||||
if checksum != expected_checksum {
|
||||
eprintln!("serial_read_region: wrong read checksum {}, expected {}", checksum, expected_checksum);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
output_data.extend(reply.into_iter());
|
||||
n += DATA_SIZE;
|
||||
}
|
||||
|
||||
let n = output_data.len();
|
||||
let ptr = output_data.as_ptr() as *const c_void;
|
||||
unsafe {
|
||||
libc::memcpy(data as *mut c_void, ptr, n);
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn serial_write_region(addr: c_int, data: *mut c_uchar, nbytes: c_int) {
|
||||
use serial::prelude::*;
|
||||
|
||||
let dev_path = unsafe {
|
||||
match device_path {
|
||||
Some(ref s) => s.clone(),
|
||||
None => {
|
||||
eprintln!("No serial device path set, exiting");
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
let mut port = match serial::open(&dev_path) {
|
||||
Ok(port) => port,
|
||||
Err(err) => {
|
||||
println!("{}", err);
|
||||
exit(-1);
|
||||
}
|
||||
};
|
||||
|
||||
port.reconfigure(&|settings: &mut dyn SerialPortSettings| {
|
||||
settings.set_baud_rate(serial::BaudRate::Baud115200)?;
|
||||
settings.set_char_size(serial::CharSize::Bits8);
|
||||
Ok(())
|
||||
}).unwrap();
|
||||
port.set_timeout(Duration::new(1,0)).unwrap();
|
||||
|
||||
const DATA_SIZE: usize = 16;
|
||||
|
||||
let num_bytes = nbytes as usize;
|
||||
let addr = addr as usize;
|
||||
|
||||
let mut n = 0;
|
||||
while n < num_bytes {
|
||||
let mut cmd: [u8; 8 + DATA_SIZE] = [0; 8 + DATA_SIZE];
|
||||
cmd[0] = 0x57; // ASCII 'W'
|
||||
cmd[1] = ((addr + n) >> 24) as u8;
|
||||
cmd[2] = ((addr + n) >> 16) as u8;
|
||||
cmd[3] = ((addr + n) >> 8) as u8;
|
||||
cmd[4] = (addr + n) as u8;
|
||||
cmd[5] = DATA_SIZE as u8;
|
||||
|
||||
let ptr = unsafe {
|
||||
cmd.as_mut_ptr().offset(6) as *mut c_void
|
||||
};
|
||||
unsafe {
|
||||
libc::memcpy(ptr, data.offset(n as isize) as *const c_void, DATA_SIZE);
|
||||
}
|
||||
|
||||
//Compute checksum
|
||||
let mut checksum: u8 = cmd[1];
|
||||
for idx in 2..(6+DATA_SIZE) {
|
||||
checksum = checksum.overflowing_add(cmd[idx]).0;
|
||||
}
|
||||
cmd[DATA_SIZE+6] = checksum;
|
||||
cmd[DATA_SIZE+7] = b'\x06'; // CMD_ACK byte
|
||||
let reply = send_receive(&mut port, &cmd, 1, true);
|
||||
if reply[0] != b'\x06' {
|
||||
eprintln!("serial_write_region: wrong acknowledge {:?}, expected: {:?}", reply, b'\x06');
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
n += DATA_SIZE as usize;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// Query and return the device identification string.
|
||||
/// On error, return None.
|
||||
pub fn identify(dev_path: &str) -> Option<String> {
|
||||
|
Loading…
Reference in New Issue
Block a user