Reading commands works
This commit is contained in:
parent
a7ae3731a4
commit
a7b8f1ca67
17
Cargo.lock
generated
17
Cargo.lock
generated
|
@ -17,12 +17,6 @@ version = "1.0.62"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1485d4d2cc45e7b201ee3767015c96faa5904387c9d87c6efdd0fb511f12d305"
|
checksum = "1485d4d2cc45e7b201ee3767015c96faa5904387c9d87c6efdd0fb511f12d305"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "arrayvec"
|
|
||||||
version = "0.7.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "atomic-polyfill"
|
name = "atomic-polyfill"
|
||||||
version = "0.1.10"
|
version = "0.1.10"
|
||||||
|
@ -941,15 +935,6 @@ dependencies = [
|
||||||
"unicode-ident",
|
"unicode-ident",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "profont"
|
|
||||||
version = "0.6.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "bd908932b251e9f146130df7566e8f7c5b0c6ddb29f6d67571f3579f59043c36"
|
|
||||||
dependencies = [
|
|
||||||
"embedded-graphics",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "quote"
|
name = "quote"
|
||||||
version = "1.0.21"
|
version = "1.0.21"
|
||||||
|
@ -1031,7 +1016,6 @@ dependencies = [
|
||||||
name = "rotor-control-stm32"
|
name = "rotor-control-stm32"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"arrayvec",
|
|
||||||
"cortex-m",
|
"cortex-m",
|
||||||
"cortex-m-rt",
|
"cortex-m-rt",
|
||||||
"defmt",
|
"defmt",
|
||||||
|
@ -1048,7 +1032,6 @@ dependencies = [
|
||||||
"heapless",
|
"heapless",
|
||||||
"nb 1.0.0",
|
"nb 1.0.0",
|
||||||
"panic-probe",
|
"panic-probe",
|
||||||
"profont",
|
|
||||||
"ssd1306",
|
"ssd1306",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
41
Cargo.toml
41
Cargo.toml
|
@ -26,11 +26,42 @@ nb = "1.0.0"
|
||||||
|
|
||||||
ssd1306 = "0.7.1"
|
ssd1306 = "0.7.1"
|
||||||
embedded-graphics = "0.7.1"
|
embedded-graphics = "0.7.1"
|
||||||
profont = "0.6.1"
|
|
||||||
arrayvec = { version = "0.7.2", default-features = false}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# cargo build/run
|
||||||
[profile.dev]
|
[profile.dev]
|
||||||
opt-level = "s"
|
codegen-units = 1
|
||||||
|
debug = 2
|
||||||
|
debug-assertions = true # <-
|
||||||
|
incremental = false
|
||||||
|
opt-level = 3 # <-
|
||||||
|
overflow-checks = true # <-
|
||||||
|
|
||||||
|
# cargo test
|
||||||
|
[profile.test]
|
||||||
|
codegen-units = 1
|
||||||
|
debug = 2
|
||||||
|
debug-assertions = true # <-
|
||||||
|
incremental = false
|
||||||
|
opt-level = 3 # <-
|
||||||
|
overflow-checks = true # <-
|
||||||
|
|
||||||
|
# cargo build/run --release
|
||||||
|
[profile.release]
|
||||||
|
codegen-units = 1
|
||||||
|
debug = 2
|
||||||
|
debug-assertions = false # <-
|
||||||
|
incremental = false
|
||||||
|
#lto = 'fat'
|
||||||
|
opt-level = 3 # <-
|
||||||
|
overflow-checks = false # <-
|
||||||
|
|
||||||
|
# cargo test --release
|
||||||
|
[profile.bench]
|
||||||
|
codegen-units = 1
|
||||||
|
debug = 2
|
||||||
|
debug-assertions = false # <-
|
||||||
|
incremental = false
|
||||||
|
lto = 'fat'
|
||||||
|
opt-level = 3 # <-
|
||||||
|
overflow-checks = false # <-
|
||||||
|
|
|
@ -6,16 +6,17 @@ use embassy_stm32::time::Hertz;
|
||||||
use embassy_time::{Duration, Timer};
|
use embassy_time::{Duration, Timer};
|
||||||
|
|
||||||
use embedded_graphics::{
|
use embedded_graphics::{
|
||||||
mono_font::MonoTextStyle,
|
mono_font::{
|
||||||
|
MonoTextStyle,
|
||||||
|
{ascii::FONT_5X7, ascii::FONT_7X13},
|
||||||
|
},
|
||||||
pixelcolor::BinaryColor,
|
pixelcolor::BinaryColor,
|
||||||
prelude::*,
|
prelude::*,
|
||||||
primitives::{PrimitiveStyleBuilder, Rectangle},
|
primitives::{PrimitiveStyleBuilder, Rectangle},
|
||||||
text::Text,
|
text::Text,
|
||||||
};
|
};
|
||||||
use profont::{PROFONT_12_POINT, PROFONT_7_POINT};
|
|
||||||
use ssd1306::{prelude::*, I2CDisplayInterface, Ssd1306};
|
|
||||||
|
|
||||||
use arrayvec::ArrayString;
|
use ssd1306::{prelude::*, I2CDisplayInterface, Ssd1306};
|
||||||
|
|
||||||
#[embassy_executor::task]
|
#[embassy_executor::task]
|
||||||
pub async fn display_task(i2c1: peripherals::I2C1, sda: peripherals::PB6, scl: peripherals::PB7) {
|
pub async fn display_task(i2c1: peripherals::I2C1, sda: peripherals::PB6, scl: peripherals::PB7) {
|
||||||
|
@ -27,9 +28,9 @@ pub async fn display_task(i2c1: peripherals::I2C1, sda: peripherals::PB6, scl: p
|
||||||
.into_buffered_graphics_mode();
|
.into_buffered_graphics_mode();
|
||||||
display.init().unwrap();
|
display.init().unwrap();
|
||||||
|
|
||||||
let text_large = MonoTextStyle::new(&PROFONT_12_POINT, BinaryColor::On);
|
let text_large = MonoTextStyle::new(&FONT_7X13, BinaryColor::On);
|
||||||
let text_large_inv = MonoTextStyle::new(&PROFONT_12_POINT, BinaryColor::Off);
|
let text_large_inv = MonoTextStyle::new(&FONT_7X13, BinaryColor::Off);
|
||||||
let text_small = MonoTextStyle::new(&PROFONT_7_POINT, BinaryColor::On);
|
let text_small = MonoTextStyle::new(&FONT_5X7, BinaryColor::On);
|
||||||
|
|
||||||
let style_filled = PrimitiveStyleBuilder::new()
|
let style_filled = PrimitiveStyleBuilder::new()
|
||||||
.fill_color(BinaryColor::On)
|
.fill_color(BinaryColor::On)
|
||||||
|
|
97
src/usb.rs
97
src/usb.rs
|
@ -1,3 +1,5 @@
|
||||||
|
use defmt::Format;
|
||||||
|
|
||||||
use embassy_executor::Spawner;
|
use embassy_executor::Spawner;
|
||||||
use embassy_stm32::gpio::{Level, Output, Speed};
|
use embassy_stm32::gpio::{Level, Output, Speed};
|
||||||
use embassy_stm32::peripherals;
|
use embassy_stm32::peripherals;
|
||||||
|
@ -9,7 +11,9 @@ use embassy_usb::Builder;
|
||||||
use embassy_usb_serial::{CdcAcmClass, State};
|
use embassy_usb_serial::{CdcAcmClass, State};
|
||||||
use futures::future::join;
|
use futures::future::join;
|
||||||
|
|
||||||
use arrayvec::{ArrayString, ArrayVec};
|
use core::fmt::Write;
|
||||||
|
|
||||||
|
use heapless::String;
|
||||||
|
|
||||||
#[embassy_executor::task]
|
#[embassy_executor::task]
|
||||||
pub async fn usb_task(usb: peripherals::USB, dp_pin: peripherals::PA12, dm_pin: peripherals::PA11) {
|
pub async fn usb_task(usb: peripherals::USB, dp_pin: peripherals::PA12, dm_pin: peripherals::PA11) {
|
||||||
|
@ -45,13 +49,16 @@ pub async fn usb_task(usb: peripherals::USB, dp_pin: peripherals::PA12, dm_pin:
|
||||||
// Build the builder.
|
// Build the builder.
|
||||||
let mut usb = builder.build();
|
let mut usb = builder.build();
|
||||||
|
|
||||||
|
let az_actual: u16 = 0;
|
||||||
|
let el_actual: u16 = 0;
|
||||||
|
|
||||||
// Do stuff with the class!
|
// Do stuff with the class!
|
||||||
let usb_handler_fut = async {
|
let usb_handler_fut = async {
|
||||||
loop {
|
loop {
|
||||||
class.wait_connection().await;
|
class.wait_connection().await;
|
||||||
defmt::info!("USB connected");
|
defmt::info!("USB connected");
|
||||||
let mut packet = [0; 64];
|
let mut packet = [0; 64];
|
||||||
let mut buffer = ArrayVec::<u8, 64>::new();
|
let mut buffer: String<64> = String::new();
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
let n = match class.read_packet(&mut packet).await {
|
let n = match class.read_packet(&mut packet).await {
|
||||||
|
@ -62,39 +69,56 @@ pub async fn usb_task(usb: peripherals::USB, dp_pin: peripherals::PA12, dm_pin:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if buffer.try_extend_from_slice(&packet[..n]).is_err() {
|
for byte in &packet[..n] {
|
||||||
buffer.clear();
|
if buffer.len() == 64 {
|
||||||
buffer.try_extend_from_slice(&packet[..n]).unwrap();
|
buffer.clear();
|
||||||
}
|
|
||||||
|
|
||||||
let mut line_end = 0;
|
|
||||||
for i in 0..buffer.len() {
|
|
||||||
if buffer[i] == '\r' as u8 {
|
|
||||||
line_end = i;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
buffer.push(*byte as char).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
defmt::info!("Line end: {}", line_end);
|
let line_end = match buffer.rfind('\r') {
|
||||||
defmt::info!("buffer: {}", buffer.as_slice());
|
Some(n) => n,
|
||||||
|
_ => continue,
|
||||||
|
};
|
||||||
|
|
||||||
|
defmt::info!("Line buffer: {:x}", buffer.as_bytes());
|
||||||
|
|
||||||
if line_end > 0 {
|
if line_end > 0 {
|
||||||
let cmd = parse_command(&buffer.as_slice()[..line_end]);
|
let cmd = parse_command(&buffer.as_str()[..line_end]);
|
||||||
for _ in 0..line_end + 1 {
|
defmt::info!("Command: {}", cmd);
|
||||||
buffer.remove(0);
|
|
||||||
}
|
|
||||||
defmt::info!("truncated buffer");
|
|
||||||
|
|
||||||
if cmd != Gs232Cmd::Unkown {
|
let mut resp: String<16> = String::new();
|
||||||
match class.write_packet(b"\r").await {
|
match cmd {
|
||||||
Ok(_) => {}
|
Gs232Cmd::GetAl => {
|
||||||
Err(err) => {
|
write!(&mut resp, "AZ={}\r", az_actual).unwrap();
|
||||||
defmt::error!("Unable to write packet: {}", err);
|
}
|
||||||
break;
|
Gs232Cmd::GetEz => {
|
||||||
}
|
write!(&mut resp, "EL={}\r", el_actual).unwrap();
|
||||||
};
|
}
|
||||||
|
Gs232Cmd::GetAlEz => {
|
||||||
|
write!(&mut resp, "AZ={} EL={}\r", az_actual, el_actual).unwrap();
|
||||||
|
}
|
||||||
|
Gs232Cmd::MoveTo(_az, _el) => {
|
||||||
|
resp.push_str("\r").unwrap();
|
||||||
|
}
|
||||||
|
Gs232Cmd::Stop => {
|
||||||
|
resp.push_str("\r").unwrap();
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
defmt::error!("Uknown command: {}", &buffer.as_str()[..line_end]);
|
||||||
|
resp.push_str("Unkown command!\r").unwrap();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
match class.write_packet(resp.as_bytes()).await {
|
||||||
|
Ok(_) => {}
|
||||||
|
Err(err) => {
|
||||||
|
defmt::error!("Unable to write packet: {}", err);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
buffer = String::from(&buffer.as_str()[line_end + 1..]);
|
||||||
}
|
}
|
||||||
defmt::info!("USB disconnected");
|
defmt::info!("USB disconnected");
|
||||||
}
|
}
|
||||||
|
@ -103,7 +127,7 @@ pub async fn usb_task(usb: peripherals::USB, dp_pin: peripherals::PA12, dm_pin:
|
||||||
join(usb.run(), usb_handler_fut).await;
|
join(usb.run(), usb_handler_fut).await;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq)]
|
#[derive(Format, PartialEq)]
|
||||||
enum Gs232Cmd {
|
enum Gs232Cmd {
|
||||||
Unkown,
|
Unkown,
|
||||||
GetAl,
|
GetAl,
|
||||||
|
@ -113,8 +137,8 @@ enum Gs232Cmd {
|
||||||
Stop,
|
Stop,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_command(data: &[u8]) -> Gs232Cmd {
|
fn parse_command(data: &str) -> Gs232Cmd {
|
||||||
match data[0] as char {
|
match data.chars().nth(0).unwrap() {
|
||||||
'B' => {
|
'B' => {
|
||||||
if data.len() == 1 {
|
if data.len() == 1 {
|
||||||
Gs232Cmd::GetAl
|
Gs232Cmd::GetAl
|
||||||
|
@ -124,7 +148,7 @@ fn parse_command(data: &[u8]) -> Gs232Cmd {
|
||||||
}
|
}
|
||||||
|
|
||||||
'C' => {
|
'C' => {
|
||||||
if data.len() == 2 && data[1] as char == '2' {
|
if data.len() == 2 && data.chars().nth(1).unwrap() as char == '2' {
|
||||||
Gs232Cmd::GetAlEz
|
Gs232Cmd::GetAlEz
|
||||||
} else if data.len() == 1 {
|
} else if data.len() == 1 {
|
||||||
Gs232Cmd::GetEz
|
Gs232Cmd::GetEz
|
||||||
|
@ -135,8 +159,15 @@ fn parse_command(data: &[u8]) -> Gs232Cmd {
|
||||||
|
|
||||||
'W' => {
|
'W' => {
|
||||||
if data.len() == 8 {
|
if data.len() == 8 {
|
||||||
|
if let Ok(az) = data[1..4].parse::<u16>() {
|
||||||
Gs232Cmd::Unkown
|
if let Ok(el) = data[5..].parse::<u16>() {
|
||||||
|
Gs232Cmd::MoveTo(az, el)
|
||||||
|
} else {
|
||||||
|
Gs232Cmd::Unkown
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Gs232Cmd::Unkown
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
Gs232Cmd::Unkown
|
Gs232Cmd::Unkown
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue