diff --git a/macroboard.ino b/macroboard.ino index 7014ccc..ed00e7f 100644 --- a/macroboard.ino +++ b/macroboard.ino @@ -20,22 +20,6 @@ struct Button { const int button_count = 8; const Button buttons[button_count] = { - { - .pin_id = 2, - .last_state = LOW - }, - { - .pin_id = 3, - .last_state = LOW - }, - { - .pin_id = 4, - .last_state = LOW - }, - { - .pin_id = 5, - .last_state = LOW - }, { .pin_id = 6, .last_state = LOW @@ -51,6 +35,22 @@ const Button buttons[button_count] = { { .pin_id = 9, .last_state = LOW + }, + { + .pin_id = 10, + .last_state = LOW + }, + { + .pin_id = 11, + .last_state = LOW + }, + { + .pin_id = 12, + .last_state = LOW + }, + { + .pin_id = 13, + .last_state = LOW } }; @@ -98,43 +98,35 @@ void check_pin(Button* button, byte index) { if (button->last_state == LOW) { button->last_state = HIGH; - send_message("HIGH"); + /* + // assemble message + Serial.print(message_start); + Serial.print(index + 1); + Serial.print(message_end); + + // force new line + Serial.print('\n'); + */ + + debug_message(button->pin_id, "HIGH"); } } else { if (button->last_state == HIGH) { button->last_state = LOW; - send_message("LOW"); + debug_message(button->pin_id, "LOW"); } } } -void send_message(char c) { +void debug_message(byte pin_id, char c[]) { // assemble message Serial.print(message_start); + Serial.print(pin_id); + Serial.print(' '); Serial.print(c); Serial.print(message_end); // force new line Serial.print('\n'); } - -void send_message(char c[]) { - // assemble message - Serial.print(message_start); - Serial.print(c); - Serial.print(message_end); - - // force new line - Serial.print('\n'); -} - -void send_message(byte b) { - // assemble message - Serial.print(message_start); - Serial.print(b); - Serial.print(message_end); - - // force new line - Serial.print('\n'); -} diff --git a/src/service.rs b/src/service.rs index 3a80338..13c604f 100644 --- a/src/service.rs +++ b/src/service.rs @@ -1,24 +1,31 @@ -mod port; +mod service_specific; +use service_specific::*; use utilities::prelude::*; -use port::*; - fn main() -> VerboseResult<()> { - let settings = SerialPortSettings { + let mut port = Port::open(SerialPortSettings { baud_rate: 9600, data_bits: DataBits::Eight, parity: Parity::None, stop_bits: StopBits::One, flow_control: FlowControl::None, timeout: Duration::from_millis(2500), - }; + })?; - let port = Port::open(settings)?; + let mut message_builder = MessageBuilder::default(); loop { match port.read()? { - SerialReadResult::Message(msg) => println!("{}", msg), + SerialReadResult::Message(msg) => { + if let Some(remaining) = message_builder.check(msg) { + assert!(message_builder.is_complete()); + + println!("{}", message_builder.message()); + + message_builder = MessageBuilder::default(); + } + } SerialReadResult::Timeout => (), } } diff --git a/src/service_specific/message_builder.rs b/src/service_specific/message_builder.rs new file mode 100644 index 0000000..690cc2f --- /dev/null +++ b/src/service_specific/message_builder.rs @@ -0,0 +1,65 @@ +const MESSAGE_START: char = '<'; +const MESSAGE_END: char = '>'; + +#[derive(Debug)] +pub struct MessageBuilder { + message: String, + complete: bool, + started: bool, +} + +impl MessageBuilder { + pub fn check(&mut self, mut msg: String) -> Option { + // if message hasn't started, search for message start token + if !self.started { + let token_position = match msg.chars().position(|c| c == MESSAGE_START) { + Some(position) => position, + None => return None, + }; + + msg = msg.split_off(token_position + 1); + self.started = true; + } + + if !self.complete { + match msg.chars().position(|c| c == MESSAGE_END) { + Some(position) => { + let mut remaining_msg = msg.split_off(position); + + self.message.push_str(&msg); + self.complete = true; + + msg = remaining_msg; + } + None => { + self.message.push_str(&msg); + msg.clear(); + } + }; + } + + if msg.is_empty() { + None + } else { + Some(msg) + } + } + + pub fn is_complete(&self) -> bool { + self.complete + } + + pub fn message(&self) -> &str { + &self.message + } +} + +impl Default for MessageBuilder { + fn default() -> MessageBuilder { + MessageBuilder { + message: String::new(), + complete: false, + started: false, + } + } +} diff --git a/src/service_specific/mod.rs b/src/service_specific/mod.rs new file mode 100644 index 0000000..e0f9fe4 --- /dev/null +++ b/src/service_specific/mod.rs @@ -0,0 +1,5 @@ +mod message_builder; +mod port; + +pub use message_builder::*; +pub use port::*; diff --git a/src/port.rs b/src/service_specific/port.rs similarity index 85% rename from src/port.rs rename to src/service_specific/port.rs index a6f5b50..518eafd 100644 --- a/src/port.rs +++ b/src/service_specific/port.rs @@ -3,7 +3,6 @@ use serialport::prelude::*; use utilities::prelude::*; -use std::cell::RefCell; use std::io; pub use serialport::{DataBits, FlowControl, Parity, SerialPortSettings, StopBits}; @@ -15,7 +14,7 @@ pub enum SerialReadResult { } pub struct Port { - serial_port: RefCell>, + serial_port: Box, } impl Port { @@ -31,16 +30,14 @@ impl Port { ) })?; - Ok(Port { - serial_port: RefCell::new(port), - }) + Ok(Port { serial_port: port }) } #[allow(unused)] - pub fn read(&self) -> VerboseResult { + pub fn read(&mut self) -> VerboseResult { let mut buf: Vec = (0..255).collect(); - match self.serial_port.try_borrow_mut()?.read(&mut buf[..]) { + match self.serial_port.read(&mut buf[..]) { Ok(t) => Ok(SerialReadResult::Message( String::from_utf8(buf[0..t].to_vec()) .map_err(|err| format!("failed converting utf8 buffer ({})", err))?, @@ -51,9 +48,8 @@ impl Port { } #[allow(unused)] - pub fn write(&self, msg: &str) -> VerboseResult<()> { + pub fn write(&mut self, msg: &str) -> VerboseResult<()> { self.serial_port - .try_borrow_mut()? .write(msg.as_bytes()) .map_err(|err| format!("failed writing to serial port ({})", err))?;