add simple request building macros
This commit is contained in:
parent
ca5125eaf9
commit
c6523b70d3
|
@ -11,3 +11,5 @@ path = "src/lib.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
serialport = "4.2.0"
|
serialport = "4.2.0"
|
||||||
|
rand = "0.8.5"
|
||||||
|
|
||||||
|
|
57
src/b15f.rs
57
src/b15f.rs
|
@ -2,13 +2,11 @@
|
||||||
//! interacting with the B15 on a high level. If you are writing code
|
//! interacting with the B15 on a high level. If you are writing code
|
||||||
//! for the B15, this is the module you want to use.
|
//! for the B15, this is the module you want to use.
|
||||||
|
|
||||||
use std::{process::Command, time::Duration, fmt::{Debug, Display}, thread::sleep, error::Error};
|
use std::{process::Command, time::Duration, fmt::Debug, thread::sleep};
|
||||||
|
use rand::Rng;
|
||||||
use serialport::SerialPort;
|
use serialport::SerialPort;
|
||||||
|
|
||||||
use crate::request::Request;
|
use crate::{request::Request, build_request};
|
||||||
|
|
||||||
/// Hardcoded commit hash of the most recent firmware
|
|
||||||
static COMMIT_HASH: &'static str = "bc459c80cec755d7df2c11a807d74e085cbed332";
|
|
||||||
|
|
||||||
macro_rules! log {
|
macro_rules! log {
|
||||||
($text: literal, $($arg:tt)*) => (println!(concat!("[B15F] ", $text), $($arg)*));
|
($text: literal, $($arg:tt)*) => (println!(concat!("[B15F] ", $text), $($arg)*));
|
||||||
|
@ -31,6 +29,8 @@ pub struct B15F {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl B15F {
|
impl B15F {
|
||||||
|
const MSG_OK: u8 = 0xFF;
|
||||||
|
|
||||||
/// Creates a new instance of the B15
|
/// Creates a new instance of the B15
|
||||||
///
|
///
|
||||||
/// This function will establish a connection to a connected B15 and return
|
/// This function will establish a connection to a connected B15 and return
|
||||||
|
@ -52,19 +52,32 @@ impl B15F {
|
||||||
};
|
};
|
||||||
|
|
||||||
log_start!("Testing connection");
|
log_start!("Testing connection");
|
||||||
for tries in 0..3 {
|
let mut tries = 3;
|
||||||
|
while tries > 0 {
|
||||||
drv.discard();
|
drv.discard();
|
||||||
|
|
||||||
|
match drv.test_connection() {
|
||||||
|
Ok(()) => break,
|
||||||
|
Err(_) => {} // Do nothing
|
||||||
|
};
|
||||||
|
|
||||||
|
tries -= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if tries == 0 {
|
||||||
|
panic!("Testing connection failed!");
|
||||||
|
}
|
||||||
|
|
||||||
log_end!("Ok!");
|
log_end!("Ok!");
|
||||||
|
|
||||||
let info = drv.get_board_info();
|
let info = drv.get_board_info();
|
||||||
log!("AVR firmware version: {} built at {} ({})", info[0], info[1], info[2]);
|
log!("AVR firmware version: {} built at {} ({})", info[0], info[1], info[2]);
|
||||||
|
|
||||||
let avr_commit_hash = info[3];
|
// let avr_commit_hash = info[3];
|
||||||
if avr_commit_hash != COMMIT_HASH {
|
// if avr_commit_hash != COMMIT_HASH {
|
||||||
log!("Different commit hashes: {} vs {}", avr_commit_hash, COMMIT_HASH);
|
// log!("Different commit hashes: {} vs {}", avr_commit_hash, COMMIT_HASH);
|
||||||
return Err("Versions incompatible. Please update the software!".into());
|
// return Err("Versions incompatible. Please update the software!".into());
|
||||||
}
|
// }
|
||||||
|
|
||||||
Ok(drv)
|
Ok(drv)
|
||||||
}
|
}
|
||||||
|
@ -112,16 +125,34 @@ impl B15F {
|
||||||
|
|
||||||
/// Clears data in the USART buffers on this device and on the B15
|
/// Clears data in the USART buffers on this device and on the B15
|
||||||
pub fn discard(&mut self) {
|
pub fn discard(&mut self) {
|
||||||
|
// TODO: In general, unwrap() will cause panic on failure and crash the application.
|
||||||
|
// It would be better to implement error handling
|
||||||
self.usart.clear(serialport::ClearBuffer::Output).unwrap();
|
self.usart.clear(serialport::ClearBuffer::Output).unwrap();
|
||||||
|
|
||||||
for i in 0..16 {
|
for _ in 0..16 {
|
||||||
self.usart.write(&Request::new().discard().done()[..]).unwrap();
|
self.usart.write(build_request![Request::Discard]).unwrap();
|
||||||
sleep(Duration::from_millis(4));
|
sleep(Duration::from_millis(4));
|
||||||
}
|
}
|
||||||
|
|
||||||
self.usart.clear(serialport::ClearBuffer::Input).unwrap()
|
self.usart.clear(serialport::ClearBuffer::Input).unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Tests the connetion to the B15
|
||||||
|
pub fn test_connection(&mut self) -> Result<(), String> {
|
||||||
|
let dummy: u8 = rand::thread_rng().gen_range(0x00..=0xFF);
|
||||||
|
|
||||||
|
self.usart.write(build_request![Request::Test, dummy]).unwrap();
|
||||||
|
|
||||||
|
let mut buffer: [u8; 2]= [0; 2];
|
||||||
|
self.usart.read(&mut buffer).unwrap();
|
||||||
|
|
||||||
|
if buffer[0] != B15F::MSG_OK || buffer[1] != dummy {
|
||||||
|
panic!("Test request failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(any(target_arch = "arm", target_arch = "aarch64"))]
|
#[cfg(any(target_arch = "arm", target_arch = "aarch64"))]
|
||||||
fn get_devices() -> Vec<String> {
|
fn get_devices() -> Vec<String> {
|
||||||
let output = Command::new("bash")
|
let output = Command::new("bash")
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#![deny(missing_docs,
|
#![deny(missing_docs,
|
||||||
missing_debug_implementations,
|
missing_debug_implementations,
|
||||||
trivial_casts, trivial_numeric_casts,
|
trivial_casts,
|
||||||
unsafe_code,
|
unsafe_code,
|
||||||
unstable_features,
|
unstable_features,
|
||||||
unused_import_braces, unused_qualifications)]
|
unused_import_braces, unused_qualifications)]
|
||||||
|
|
|
@ -5,26 +5,18 @@
|
||||||
//! if you are trying to interact with the B15 consider using
|
//! if you are trying to interact with the B15 consider using
|
||||||
//! the `b15f::B15F` structure instead.
|
//! the `b15f::B15F` structure instead.
|
||||||
|
|
||||||
|
// TODO: There should be a more elegant way to do this
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
/// Builds a new request buffer from the given data
|
||||||
|
macro_rules! build_request {
|
||||||
|
[$($x:expr),*] => (
|
||||||
|
&[$($x as u8),*]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[repr(u8)]
|
#[repr(u8)]
|
||||||
enum RequestType {
|
pub enum Request {
|
||||||
Discard = 0
|
Discard = 0,
|
||||||
}
|
Test = 1
|
||||||
|
|
||||||
pub struct Request {
|
|
||||||
req: Vec<u8>
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Request {
|
|
||||||
pub fn new() -> Request {
|
|
||||||
Request { req: vec![] }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn discard(mut self) -> Self {
|
|
||||||
self.req.push(RequestType::Discard as u8);
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn done(self) -> Vec<u8> {
|
|
||||||
self.req
|
|
||||||
}
|
|
||||||
}
|
}
|
Loading…
Reference in a new issue