diff --git a/src/half_duplex_serial.rs b/src/half_duplex_serial.rs index 4d150fb..6ee83c4 100644 --- a/src/half_duplex_serial.rs +++ b/src/half_duplex_serial.rs @@ -10,10 +10,13 @@ use arduino_hal::{ Pin, PinMode, PinOps, }, }; -use avr_device::{asm::delay_cycles, interrupt}; +use avr_device::{ + asm::delay_cycles, + interrupt::{self, disable, enable}, +}; use embedded_hal::digital::{InputPin, OutputPin}; -use super::static_pins_impl::StaticPin; +use super::static_pins_impl::StaticPinOps; use heapless::Vec; pub struct HalfDuplexSerial

{ @@ -50,6 +53,9 @@ where fn poll(&self) -> PollResult; fn response(&self); + fn is_low(&self) -> bool; + fn is_high(&self) -> bool; + fn write_byte(&self, data: u8); fn read_byte(&self) -> ReadByteResult; @@ -74,33 +80,50 @@ where P: PinOps + StaticPinOps, { fn poll(&self) -> PollResult { - let pin_pos = 1u8 << P::PIN_NUM; - + P::into_output(); P::into_input(); - if P::read() & pin_pos == 0 { + delay_us(SERIAL_TRANSMIT_DELAY_US / 2); + + if self.is_low() { + P::into_pull_up_input(); + return PollResult::Err(PollError::NotFound); } - delay_us(3); + P::into_pull_up_input(); + + delay_us(SERIAL_TRANSMIT_DELAY_US / 2); + + if self.is_high() { + P::into_pull_up_input(); - if P::read() & pin_pos != 0 { return PollResult::Err(PollError::NotReady); } - P::into_pullup_input(); + while self.is_low() {} PollResult::Ok(()) } fn response(&self) { - delay_us(1); + while self.is_low() {} P::into_output(); - delay_us(4); - P::into_pull_up_input(); + delay_us(SERIAL_TRANSMIT_DELAY_US); + P::into_pull_up_input(); + } + + #[inline] + fn is_low(&self) -> bool { + (P::read() & (1 << P::PIN_NUM)) == 0 + } + + #[inline] + fn is_high(&self) -> bool { + (P::read() & (1 << P::PIN_NUM)) != 0 } fn write_byte(&self, data: u8) { diff --git a/src/main.rs b/src/main.rs index f33830e..613785f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,12 +4,13 @@ #![feature(abi_avr_interrupt)] #![feature(asm_experimental_arch)] #![feature(thread_local)] +#![allow(clippy::wrong_self_convention)] #[macro_use] extern crate static_pins; use arduino_hal::{ - delay_ms, delay_us, + delay_ms, hal::{ pins, port::{PD2, PD3, PD5}, @@ -30,14 +31,23 @@ use keyboard::*; #[allow(unused)] use panic_handler::*; -// static mut SERIAL_BUFFER: Vec = Vec::new(); - pub static mut SERIAL: Option> = None; static mut RX_LED: Option> = None; static mut POLL_INDICATOR: Option> = None; -// const MODIFIER_MASK: u8 = 0xE0; +fn error_poll_status_display(delay: u16) { + unsafe { + if let Some(poll_status) = POLL_INDICATOR.as_mut() { + for _ in 0..=5 { + delay_ms(delay); + poll_status.toggle(); + } + poll_status.set_low(); + } + delay_ms(500) + } +} #[arduino_hal::entry] fn main() -> ! { @@ -52,39 +62,35 @@ fn main() -> ! { let mut rx_led = pins.pd5.into_output(); let poll_indicator = pins.pd2.into_output(); - // let mut delay: Delay = Delay::new(); - + // let one_wire_pin = StaticPin::new(pins.pd3.into_pull_up_input()); pins.pb0.into_output().set_low(); - rx_led.set_low(); - let data_line = HalfDuplexSerial::new(pins.pd3.into_pull_up_input(), &dp.EXINT); - unsafe { + SERIAL = Some(HalfDuplexSerial::new( + pins.pd3.into_pull_up_input(), + &dp.EXINT, + )); POLL_INDICATOR = Some(poll_indicator); - SERIAL = Some(data_line); RX_LED = Some(rx_led); enable(); + loop { - let scan = matrix.scan(); - if scan[0].is_some() || scan[1].is_some() { - if let Some(data_line) = SERIAL.as_mut() { - match data_line.poll() { - Ok(_) => { - if let Some(rx_led) = RX_LED.as_mut() { - rx_led.toggle(); + let pressed_keys = matrix.scan(); + if pressed_keys[0].is_some() || pressed_keys[1].is_some() { + free(|_| { + if let Some(serial) = SERIAL.as_ref() { + match serial.poll() { + Ok(_) => { + if let Some(led) = POLL_INDICATOR.as_mut() { + led.set_high(); + } } + Err(PollError::NotFound) => error_poll_status_display(150), + Err(PollError::NotReady) => error_poll_status_display(750), } - Err(poll_error) => match poll_error { - PollError::NotFound => { - // panic!("1"); - } - PollError::NotReady => { - // panic!("2"); - } - }, } - } + }); } } } @@ -92,15 +98,10 @@ fn main() -> ! { #[avr_device::interrupt(atmega32u4)] unsafe fn INT3() { - free(|_| { - if let Some(serial) = SERIAL.as_ref() { - serial.response(); + if let Some(serial) = SERIAL.as_ref() { + serial.response(); + if let Some(led) = POLL_INDICATOR.as_mut() { + led.toggle(); } - if let Some(poll_status) = POLL_INDICATOR.as_mut() { - poll_status.toggle(); - } - // if let Some(rx_led) = RX_LED.as_mut() { - // rx_led.toggle(); - // } - }) + } }