Compare commits

..

3 Commits

Author SHA1 Message Date
b69710ad97 RINGBUFFER FTW! 2024-01-07 23:28:32 +01:00
897ef263ca quicksave 2 2024-01-01 19:35:32 +01:00
e64eafd869 quicksave 2023-10-25 12:13:17 +02:00
3 changed files with 216 additions and 45 deletions

View File

@@ -1,51 +1,138 @@
#![no_std] #![no_std]
#![no_main] #![no_main]
#![feature(abi_avr_interrupt)]
use arduino_hal::hal::Atmega;
use arduino_hal::hal::port::{PE0, PE1, PD2, PD3};
use arduino_hal::port::Pin;
use arduino_hal::port::mode::{Input, Output};
use arduino_hal::Peripherals;
use arduino_hal::prelude::*;
use arduino_hal::usart::{UsartOps, Usart};
use avr_device::atmega2560::{USART0, USART1};
use panic_halt as _;
use embedded_hal::serial::Read;
mod webee; mod webee;
use webee::Webee; use webee::Webee;
use crate::webee::SendCmd::{Baudrate, Channel, MAC, PanId, Role, TransmitPower, ZigbeeNetworkKey}; use crate::webee::SendCmd::{Baudrate, Channel, MAC, PanId, Role, TransmitPower, ZigbeeNetworkKey};
use webee::BufferErr;
static mut WEBEE: Option<Webee<USART1, Pin<Input, PD2>, Pin<Output, PD3>>> = None;
static mut BUFFER_STATUS: Result<(), BufferErr> = Ok(());
use arduino_hal::Peripherals; #[avr_device::interrupt(atmega2560)]
use arduino_hal::prelude::*; unsafe fn USART1_RX() {
use panic_halt as _; let mut webee = WEBEE.as_mut().unwrap();
if let Ok(b) = webee.webee.read() {
if let Err(x) = webee.READ_BUFFER.write(b) {
BUFFER_STATUS = Err(x);
}
}
}
#[arduino_hal::entry] #[arduino_hal::entry]
fn main() -> ! { fn main() -> ! {
let dp = Peripherals::take().unwrap(); let dp = Peripherals::take().unwrap();
let pins = arduino_hal::pins!(dp); let pins = arduino_hal::pins!(dp);
let _status = pins.d13.into_output(); let mut err_led = pins.d13.into_output();
let mut serial = arduino_hal::default_serial!(dp, pins, 57600); let mut console = arduino_hal::default_serial!(dp, pins, 57600);
unsafe {
avr_device::interrupt::enable();
}
let mut webee = Webee::new( // let mut webee = Webee::new(
unsafe {
WEBEE = Some(Webee::new(
dp.USART1, dp.USART1,
pins.d19.forget_imode(), pins.d19.forget_imode(),
pins.d18.into_output(), pins.d18.into_output(),
); ));
}
ufmt::uwriteln!(&mut serial, "Webee initialized.").void_unwrap(); ufmt::uwriteln!(&mut console, "Webee initialized.").void_unwrap();
// -------------------------------- // --------------------------------
for cmd in [Role, Baudrate, PanId, Channel, TransmitPower, MAC, ZigbeeNetworkKey] { // let cmd = ZigbeeNetworkKey;
let command_string = cmd.to_str(); // let command_string = cmd.to_str();
let response = webee.send_cmd(cmd); // let response;
// unsafe {
// response = WEBEE.as_mut().unwrap().send_cmd(cmd);
// }
//
// ufmt::uwrite!(&mut serial, "[{}] {}:", response.len(), command_string).void_unwrap();
// for i in 0..response.len() {
// // for i in 0..10 {
// ufmt::uwrite!(&mut serial, " {:02X}", *response.get(i).unwrap()).void_unwrap();
// }
// ufmt::uwriteln!(&mut serial, "").void_unwrap();
ufmt::uwrite!(&mut serial, "{}:", command_string).void_unwrap(); // for cmd in [Role, Baudrate, PanId, Channel, TransmitPower, MAC, ZigbeeNetworkKey] {
for i in 0..response.len() { // let command_string = cmd.to_str();
ufmt::uwrite!(&mut serial, " {:02X}", *response.get(i).unwrap()).void_unwrap(); // let response;
} // unsafe {
ufmt::uwriteln!(&mut serial, "").void_unwrap(); // response = WEBEE.as_mut().unwrap().send_cmd(cmd);
} // }
//
// ufmt::uwrite!(&mut serial, "[{}] {}:", response.len(), command_string).void_unwrap();
// for i in 0..response.len() {
// // for i in 0..10 {
// ufmt::uwrite!(&mut serial, " {:02X}", *response.get(i).unwrap()).void_unwrap();
// }
// ufmt::uwriteln!(&mut serial, "").void_unwrap();
// }
// -------------------------------- // --------------------------------
let webee;
unsafe {
webee = WEBEE.as_mut().unwrap();
}
unsafe {
WEBEE.as_mut().unwrap().void_send_cmd(ZigbeeNetworkKey);
}
ufmt::uwriteln!(&mut console, "Starting Loop!").void_unwrap();
loop { loop {
let b = nb::block!(serial.read()).unwrap(); // Errors
if let Err(err) = unsafe { BUFFER_STATUS } {
err_led.toggle();
match err {
BufferErr::Full => {
arduino_hal::delay_ms(100);
}
BufferErr::Empty => {
arduino_hal::delay_ms(1000);
}
BufferErr::NotEnoughSpace => {
arduino_hal::delay_ms(5000);
}
}
continue;
}
ufmt::uwriteln!(&mut serial, "Got {:X}!", b).void_unwrap(); // Read a byte from the serial connection and put response in buffer.
if unsafe { webee.READ_BUFFER.has_data() } {
let b = match unsafe { webee.READ_BUFFER.read() } {
Ok(b) => b,
Err(x) => {
unsafe {
BUFFER_STATUS = Err(x);
}
continue;
}
};
unsafe {
ufmt::uwriteln!(&mut console, "Got {:02X}!\r", b).void_unwrap();
}
}
} }
} }

View File

@@ -1,3 +1,5 @@
mod ring_buffer;
use arduino_hal::delay_ms; use arduino_hal::delay_ms;
use arduino_hal::hal::Atmega; use arduino_hal::hal::Atmega;
use arduino_hal::port::{Pin, PinOps}; use arduino_hal::port::{Pin, PinOps};
@@ -6,11 +8,13 @@ use arduino_hal::usart::{Usart, UsartOps};
use arduino_hal::prelude::*; use arduino_hal::prelude::*;
use heapless::Vec; use heapless::Vec;
pub use crate::webee::ring_buffer::{RingBuffer, BufferErr};
pub struct Webee<USART: UsartOps<Atmega, RX, TX>, RX, TX> pub struct Webee<USART: UsartOps<Atmega, RX, TX>, RX, TX>
{ {
pub webee: Usart<USART, RX, TX>, pub webee: Usart<USART, RX, TX>,
pub READ_BUFFER: RingBuffer
} }
#[repr(u8)] #[repr(u8)]
@@ -26,7 +30,7 @@ pub enum SendCmd {
AllDataTransmission = 0xB9, AllDataTransmission = 0xB9,
MAC = 0xBA, MAC = 0xBA,
LocalShortAddress = 0xBB, LocalShortAddress = 0xBB,
ZigbeeNetworkKey = 0xBC ZigbeeNetworkKey = 0xBC,
} }
impl SendCmd where { impl SendCmd where {
@@ -56,8 +60,12 @@ where
TX: PinOps TX: PinOps
{ {
pub fn new(device: USART, rx: Pin<Input, RX>, tx: Pin<Output, TX>) -> Self { pub fn new(device: USART, rx: Pin<Input, RX>, tx: Pin<Output, TX>) -> Self {
let mut interface = Usart::new(device, rx, tx, 38400.into_baudrate());
interface.listen(arduino_hal::hal::usart::Event::RxComplete);
let instance = Self { let instance = Self {
webee: Usart::new(device, rx, tx, 38400.into_baudrate()) webee: interface,
READ_BUFFER: RingBuffer::new()
}; };
delay_ms(1000); delay_ms(1000);
@@ -69,7 +77,7 @@ where
self.webee.write_byte(*byte); self.webee.write_byte(*byte);
} }
return self.recv(); self.recv()
} }
pub fn void_send(&mut self, data: &[u8]) { pub fn void_send(&mut self, data: &[u8]) {
@@ -83,21 +91,29 @@ where
self.send(&frame) self.send(&frame)
} }
pub fn query_parameter(&mut self) { pub fn void_send_cmd(&mut self, cmd: SendCmd) {
let frame = [0x5A, 0xAA, cmd as u8];
self.void_send(frame.as_slice())
} }
pub fn query_parameter(&mut self) {}
pub fn recv(&mut self) -> Vec<u8, 128> { pub fn recv(&mut self) -> Vec<u8, 128> {
let mut buffer = Vec::new(); let mut buffer = Vec::new();
// Read first byte in blocking mode to wait until data is available // Read first byte in blocking mode to wait until data is available
buffer.push(self.webee.read_byte()).unwrap(); buffer.push(self.webee.read_byte()).unwrap();
delay_ms(10); delay_ms(10);
// for i in 0..5 {
// buffer.push(self.webee.read_byte()).unwrap();
// }
while let Ok(byte) = self.webee.read() { while let Ok(byte) = self.webee.read() {
buffer.push(byte).unwrap(); buffer.push(byte).unwrap();
delay_ms(10);
} }
return buffer; buffer
} }
// pub fn vec_to_string(vec: Vec<u8, 128>) -> &'static str { // pub fn vec_to_string(vec: Vec<u8, 128>) -> &'static str {

68
src/webee/ring_buffer.rs Normal file
View File

@@ -0,0 +1,68 @@
use arduino_hal::prelude::*;
use embedded_hal::serial::Read;
use ufmt::uWrite;
const BUFFER_SIZE: usize = 128;
pub struct RingBuffer {
data: [u8; BUFFER_SIZE],
start: u16,
end: u16,
}
#[derive(Copy, Clone)]
pub enum BufferErr {
Full,
Empty,
NotEnoughSpace,
}
impl RingBuffer {
pub const fn new() -> Self {
RingBuffer {
start: 0,
end: 0,
data: [0; BUFFER_SIZE],
}
}
const fn size_remaining(&self) -> u16 {
if self.has_data() {
(self.start + BUFFER_SIZE as u16 - self.end) % BUFFER_SIZE as u16
} else {
BUFFER_SIZE as u16
}
}
pub const fn has_data(&self) -> bool {
self.start != self.end
}
pub fn write(&mut self, data: u8) -> Result<(), BufferErr> {
let next = (self.end + 1) % BUFFER_SIZE as u16;
if next == self.start {
return Err(BufferErr::Full);
}
self.data[next as usize] = data;
self.end = next;
Ok(())
}
pub fn read(&mut self) -> Result<u8, BufferErr> {
if !self.has_data() {
return Err(BufferErr::Empty);
}
self.start = (self.start + 1) % BUFFER_SIZE as u16;
Ok(self.data[self.start as usize])
}
}
impl uWrite for RingBuffer {
type Error = BufferErr;
fn write_str(&mut self, s: &str) -> Result<(), Self::Error> {
if (self.size_remaining() as usize) < s.len() {
return Err(BufferErr::NotEnoughSpace);
}
for b in s.bytes() {
self.write(b)?;
}
Ok(())
}
}