RINGBUFFER FTW!
This commit is contained in:
109
src/main.rs
109
src/main.rs
@@ -1,9 +1,16 @@
|
|||||||
#![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::Peripherals;
|
||||||
use arduino_hal::prelude::*;
|
use arduino_hal::prelude::*;
|
||||||
|
use arduino_hal::usart::{UsartOps, Usart};
|
||||||
|
use avr_device::atmega2560::{USART0, USART1};
|
||||||
use panic_halt as _;
|
use panic_halt as _;
|
||||||
|
|
||||||
use embedded_hal::serial::Read;
|
use embedded_hal::serial::Read;
|
||||||
@@ -12,43 +19,65 @@ 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(());
|
||||||
|
|
||||||
|
|
||||||
|
#[avr_device::interrupt(atmega2560)]
|
||||||
|
unsafe fn USART1_RX() {
|
||||||
|
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 mut 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 {
|
unsafe {
|
||||||
avr_device::interrupt::enable();
|
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();
|
||||||
|
|
||||||
// --------------------------------
|
// --------------------------------
|
||||||
|
|
||||||
let cmd = 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 {
|
||||||
ufmt::uwrite!(&mut serial, "[{}] {}:", response.len(), command_string).void_unwrap();
|
// response = WEBEE.as_mut().unwrap().send_cmd(cmd);
|
||||||
for i in 0..response.len() {
|
// }
|
||||||
// for i in 0..10 {
|
//
|
||||||
ufmt::uwrite!(&mut serial, " {:02X}", *response.get(i).unwrap()).void_unwrap();
|
// ufmt::uwrite!(&mut serial, "[{}] {}:", response.len(), command_string).void_unwrap();
|
||||||
}
|
// for i in 0..response.len() {
|
||||||
ufmt::uwriteln!(&mut serial, "").void_unwrap();
|
// // for i in 0..10 {
|
||||||
|
// ufmt::uwrite!(&mut serial, " {:02X}", *response.get(i).unwrap()).void_unwrap();
|
||||||
|
// }
|
||||||
|
// ufmt::uwriteln!(&mut serial, "").void_unwrap();
|
||||||
|
|
||||||
// for cmd in [Role, Baudrate, PanId, Channel, TransmitPower, MAC, ZigbeeNetworkKey] {
|
// for cmd in [Role, Baudrate, PanId, Channel, TransmitPower, MAC, 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();
|
// ufmt::uwrite!(&mut serial, "[{}] {}:", response.len(), command_string).void_unwrap();
|
||||||
// for i in 0..response.len() {
|
// for i in 0..response.len() {
|
||||||
@@ -60,10 +89,50 @@ fn main() -> ! {
|
|||||||
|
|
||||||
// --------------------------------
|
// --------------------------------
|
||||||
|
|
||||||
loop {
|
let webee;
|
||||||
let b = nb::block!(serial.read()).unwrap();
|
unsafe {
|
||||||
|
webee = WEBEE.as_mut().unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
ufmt::uwriteln!(&mut serial, "Got {:X}!", b).void_unwrap();
|
unsafe {
|
||||||
|
WEBEE.as_mut().unwrap().void_send_cmd(ZigbeeNetworkKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
ufmt::uwriteln!(&mut console, "Starting Loop!").void_unwrap();
|
||||||
|
|
||||||
|
loop {
|
||||||
|
// 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
14
src/webee.rs
14
src/webee.rs
@@ -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)]
|
||||||
@@ -57,10 +61,11 @@ Webee<
|
|||||||
{
|
{
|
||||||
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());
|
let mut interface = Usart::new(device, rx, tx, 38400.into_baudrate());
|
||||||
// interface.listen(arduino_hal::hal::usart::Event::RxComplete);
|
interface.listen(arduino_hal::hal::usart::Event::RxComplete);
|
||||||
|
|
||||||
let instance = Self {
|
let instance = Self {
|
||||||
webee: interface
|
webee: interface,
|
||||||
|
READ_BUFFER: RingBuffer::new()
|
||||||
};
|
};
|
||||||
|
|
||||||
delay_ms(1000);
|
delay_ms(1000);
|
||||||
@@ -86,6 +91,11 @@ Webee<
|
|||||||
self.send(&frame)
|
self.send(&frame)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 query_parameter(&mut self) {}
|
||||||
|
|
||||||
pub fn recv(&mut self) -> Vec<u8, 128> {
|
pub fn recv(&mut self) -> Vec<u8, 128> {
|
||||||
|
|||||||
68
src/webee/ring_buffer.rs
Normal file
68
src/webee/ring_buffer.rs
Normal 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(())
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user