feat(handshake): implement handshake between two MCU

but send and recieve data doesn't tested
This commit is contained in:
doryan 2025-03-20 21:50:17 +04:00
parent 87adfdf08f
commit 610a1f7bc0
2 changed files with 71 additions and 47 deletions

View File

@ -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) {

View File

@ -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();
// }
})
}
}