Add uart Header struct
This commit is contained in:
15
Cargo.lock
generated
15
Cargo.lock
generated
@ -103,6 +103,20 @@ name = "bytemuck"
|
|||||||
version = "1.13.1"
|
version = "1.13.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "17febce684fd15d89027105661fec94afb475cb995fbc59d2865198446ba2eea"
|
checksum = "17febce684fd15d89027105661fec94afb475cb995fbc59d2865198446ba2eea"
|
||||||
|
dependencies = [
|
||||||
|
"bytemuck_derive",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bytemuck_derive"
|
||||||
|
version = "1.4.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "fdde5c9cd29ebd706ce1b35600920a33550e402fc998a2e53ad3b42c3c47a192"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.16",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "byteorder"
|
name = "byteorder"
|
||||||
@ -1331,6 +1345,7 @@ name = "tangentbord1"
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"atomic-polyfill 1.0.2",
|
"atomic-polyfill 1.0.2",
|
||||||
|
"bytemuck",
|
||||||
"cortex-m",
|
"cortex-m",
|
||||||
"cortex-m-rt",
|
"cortex-m-rt",
|
||||||
"crc-any",
|
"crc-any",
|
||||||
|
|||||||
@ -37,6 +37,7 @@ atomic-polyfill = "1.0.2"
|
|||||||
critical-section = "1.1.1"
|
critical-section = "1.1.1"
|
||||||
crc-any = "2.4.3"
|
crc-any = "2.4.3"
|
||||||
serde = { version = "1.0.163", default-features = false, features = ["derive"] }
|
serde = { version = "1.0.163", default-features = false, features = ["derive"] }
|
||||||
|
bytemuck = { version = "1.13.1", features = ["derive"] }
|
||||||
|
|
||||||
#[patch."https://git.nubo.sh/hulthe/tgnt.git"]
|
#[patch."https://git.nubo.sh/hulthe/tgnt.git"]
|
||||||
#tgnt = { path = "../tgnt" }
|
#tgnt = { path = "../tgnt" }
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
#![no_std]
|
#![no_std]
|
||||||
#![feature(type_alias_impl_trait)]
|
#![feature(type_alias_impl_trait)]
|
||||||
|
#![feature(split_array)]
|
||||||
|
|
||||||
use embassy_rp::{
|
use embassy_rp::{
|
||||||
bind_interrupts,
|
bind_interrupts,
|
||||||
|
|||||||
48
src/uart.rs
48
src/uart.rs
@ -1,3 +1,6 @@
|
|||||||
|
use core::mem::size_of;
|
||||||
|
|
||||||
|
use bytemuck::{cast, AnyBitPattern, NoUninit};
|
||||||
use crc_any::CRCu16;
|
use crc_any::CRCu16;
|
||||||
use embassy_executor::Spawner;
|
use embassy_executor::Spawner;
|
||||||
use embassy_rp::peripherals::{PIN_0, PIN_1, UART0};
|
use embassy_rp::peripherals::{PIN_0, PIN_1, UART0};
|
||||||
@ -46,26 +49,41 @@ async fn uart_task(uart: BufferedUart<'static, UART0>, this_half: Half, mut even
|
|||||||
let (mut rx, mut tx) = uart.split();
|
let (mut rx, mut tx) = uart.split();
|
||||||
let (mut events_rx, mut events_tx) = events.split();
|
let (mut events_rx, mut events_tx) = events.split();
|
||||||
|
|
||||||
const HEADER_LEN: usize = 4;
|
#[repr(C)]
|
||||||
|
#[derive(Clone, Copy, Debug, NoUninit, AnyBitPattern)]
|
||||||
|
struct Header {
|
||||||
|
/// The length of the payload.
|
||||||
|
len: u8,
|
||||||
|
|
||||||
|
/// An arbitrary value to feed the crc, should be different for each message.
|
||||||
|
random: u8,
|
||||||
|
|
||||||
|
/// A little-endian crc16.
|
||||||
|
crc: [u8; 2],
|
||||||
|
}
|
||||||
|
|
||||||
|
const HEADER_LEN: usize = size_of::<Header>();
|
||||||
|
|
||||||
let rx_task = async {
|
let rx_task = async {
|
||||||
let mut buf: heapless::Vec<u8, 1024> = Vec::new();
|
let mut buf: heapless::Vec<u8, 1024> = Vec::new();
|
||||||
loop {
|
loop {
|
||||||
if let &[len, random, crc1, crc2, ref rest @ ..] = buf.as_slice() {
|
if buf.len() >= HEADER_LEN {
|
||||||
let crc = u16::from_le_bytes([crc1, crc2]);
|
let (&header, rest) = buf.split_array_ref::<HEADER_LEN>();
|
||||||
|
let header: Header = cast(header);
|
||||||
|
let crc = u16::from_le_bytes(header.crc);
|
||||||
let mut calculated_crc = CRCu16::crc16();
|
let mut calculated_crc = CRCu16::crc16();
|
||||||
calculated_crc.digest(&[len, random]);
|
calculated_crc.digest(&[header.len, header.random]);
|
||||||
let calculated_crc = calculated_crc.get_crc();
|
let calculated_crc = calculated_crc.get_crc();
|
||||||
|
|
||||||
if calculated_crc != crc {
|
if calculated_crc != crc {
|
||||||
log::error!("invalid uart package crc: {:x?}", &buf[..HEADER_LEN]);
|
log::error!("invalid uart header crc: {header:x?}");
|
||||||
buf.remove(0); // pop the first byte and hope we find a good packet header
|
buf.remove(0); // pop the first byte and hope we find a good packet header
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
log::debug!("got uart header {:x?}", &buf[..HEADER_LEN]);
|
log::debug!("got uart header {header:x?}");
|
||||||
|
|
||||||
let len = usize::from(len);
|
let len = usize::from(header.len);
|
||||||
if rest.len() >= len {
|
if rest.len() >= len {
|
||||||
let r = postcard::from_bytes(&rest[..len]);
|
let r = postcard::from_bytes(&rest[..len]);
|
||||||
|
|
||||||
@ -106,7 +124,7 @@ async fn uart_task(uart: BufferedUart<'static, UART0>, this_half: Half, mut even
|
|||||||
|
|
||||||
let tx_task = async {
|
let tx_task = async {
|
||||||
let mut buf = [0u8; 256 + HEADER_LEN];
|
let mut buf = [0u8; 256 + HEADER_LEN];
|
||||||
let mut counter = 1u8;
|
let mut counter = 0u8;
|
||||||
loop {
|
loop {
|
||||||
// forward messages to the other keyboard half
|
// forward messages to the other keyboard half
|
||||||
let event = events_rx.recv().await;
|
let event = events_rx.recv().await;
|
||||||
@ -115,7 +133,7 @@ async fn uart_task(uart: BufferedUart<'static, UART0>, this_half: Half, mut even
|
|||||||
}
|
}
|
||||||
|
|
||||||
let message = Message::KeyboardEvent(event);
|
let message = Message::KeyboardEvent(event);
|
||||||
let (header, body) = buf.split_at_mut(HEADER_LEN);
|
let (buf_header, body) = buf.split_array_mut();
|
||||||
let serialized = match postcard::to_slice(&message, body) {
|
let serialized = match postcard::to_slice(&message, body) {
|
||||||
Ok(s) => s,
|
Ok(s) => s,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
@ -125,16 +143,20 @@ async fn uart_task(uart: BufferedUart<'static, UART0>, this_half: Half, mut even
|
|||||||
};
|
};
|
||||||
|
|
||||||
// add a "random" value to feed the crc
|
// add a "random" value to feed the crc
|
||||||
let random = counter;
|
|
||||||
counter = counter.wrapping_add(1);
|
counter = counter.wrapping_add(1);
|
||||||
|
let random = counter;
|
||||||
|
|
||||||
let len = serialized.len() as u8;
|
let len = serialized.len() as u8;
|
||||||
|
|
||||||
let mut crc = CRCu16::crc16();
|
let mut crc = CRCu16::crc16();
|
||||||
crc.digest(&[len, random]);
|
crc.digest(&[len, random]);
|
||||||
let [crc1, crc2] = crc.get_crc().to_le_bytes();
|
let header = Header {
|
||||||
|
len: serialized.len() as u8,
|
||||||
header.copy_from_slice(&[len, random, crc1, crc2]);
|
random,
|
||||||
|
crc: crc.get_crc().to_le_bytes(),
|
||||||
|
};
|
||||||
|
let header: [u8; HEADER_LEN] = cast(header);
|
||||||
|
*buf_header = header;
|
||||||
|
|
||||||
let package = &buf[..HEADER_LEN + usize::from(len)];
|
let package = &buf[..HEADER_LEN + usize::from(len)];
|
||||||
tx.write_all(package).await.ok();
|
tx.write_all(package).await.ok();
|
||||||
|
|||||||
Reference in New Issue
Block a user