feat(handshake): implement handshake between two MCU
but send and recieve data doesn't tested
This commit is contained in:
parent
87adfdf08f
commit
610a1f7bc0
|
@ -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<P> {
|
||||
|
@ -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) {
|
||||
|
|
73
src/main.rs
73
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<u8, 5> = Vec::new();
|
||||
|
||||
pub static mut SERIAL: Option<HalfDuplexSerial<PD3>> = None;
|
||||
|
||||
static mut RX_LED: Option<Pin<Output, PD5>> = None;
|
||||
static mut POLL_INDICATOR: Option<Pin<Output, PD2>> = 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<MHz16> = 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();
|
||||
// }
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue