Changed to a cargo workspace
Added postcard protocol definitions
This commit is contained in:
parent
2cc6651aca
commit
833e4d5a56
|
@ -1,19 +0,0 @@
|
|||
[target.'cfg(all(target_arch = "arm", target_os = "none"))']
|
||||
# TODO(2) replace `$CHIP` with your chip's name (see `probe-run --list-chips` output)
|
||||
runner = "probe-run --chip STM32F103CB"
|
||||
rustflags = [
|
||||
"-C", "linker=flip-link",
|
||||
"-C", "link-arg=-Tlink.x",
|
||||
"-C", "link-arg=-Tdefmt.x",
|
||||
# This is needed if your flash or ram addresses are not aligned to 0x10000 in memory.x
|
||||
# See https://github.com/rust-embedded/cortex-m-quickstart/pull/95
|
||||
"-C", "link-arg=--nmagic",
|
||||
]
|
||||
|
||||
[build]
|
||||
target = "thumbv7m-none-eabi" # Cortex-M3
|
||||
|
||||
|
||||
[alias]
|
||||
rb = "run --bin"
|
||||
rrb = "run --release --bin"
|
63
Cargo.toml
63
Cargo.toml
|
@ -1,61 +1,8 @@
|
|||
[package]
|
||||
# TODO(1) fix `authors` and `name` if you didn't use `cargo-generate`
|
||||
authors = ["sebastian <sebastian@sebastians-site.de>"]
|
||||
name = "cheapsdp"
|
||||
edition = "2018"
|
||||
version = "0.1.0"
|
||||
[workspace]
|
||||
resolver = "2"
|
||||
|
||||
[dependencies]
|
||||
cortex-m = { version = "0.7", features = ["critical-section-single-core"] }
|
||||
defmt = { version = "0.3", features = ["encoding-rzcobs"] }
|
||||
panic-probe = { version = "0.3", features = ["print-defmt"] }
|
||||
rtic = { version = "2.0.1", features = [ "thumbv7-backend" ] }
|
||||
defmt-rtt = "0.4"
|
||||
embedded-hal = "0.2.3"
|
||||
stm32f1xx-hal = { version = "0.10.0", features = ["stm32f103", "rt", "medium"] }
|
||||
nb = "1.0.0"
|
||||
arrayvec = { version = "0.7.0", default-features = false }
|
||||
systick-monotonic = "1.0.0"
|
||||
rtic-monotonics = {version = "1.4.1", features = ["cortex-m-systick"] }
|
||||
usb-device = "0.2.8"
|
||||
usbd-serial = "0.1.1"
|
||||
rtic-sync = {version = "1.1.1"}
|
||||
ufmt = "0.2.0"
|
||||
members = [
|
||||
"firmware", "protocol",
|
||||
]
|
||||
|
||||
# cargo build/run
|
||||
[profile.dev]
|
||||
codegen-units = 1
|
||||
debug = 2
|
||||
debug-assertions = true # <-
|
||||
incremental = false
|
||||
opt-level = 'z' # <-
|
||||
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 # <-
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
[target.'cfg(all(target_arch = "arm", target_os = "none"))']
|
||||
# TODO(2) replace `$CHIP` with your chip's name (see `probe-run --list-chips` output)
|
||||
runner = "probe-run --chip STM32F103CB"
|
||||
rustflags = [
|
||||
"-C", "linker=flip-link",
|
||||
"-C", "link-arg=-Tlink.x",
|
||||
"-C", "link-arg=-Tdefmt.x",
|
||||
# This is needed if your flash or ram addresses are not aligned to 0x10000 in memory.x
|
||||
# See https://github.com/rust-embedded/cortex-m-quickstart/pull/95
|
||||
"-C", "link-arg=--nmagic",
|
||||
]
|
||||
|
||||
|
||||
# cargo build/run
|
||||
[profile.dev]
|
||||
codegen-units = 1
|
||||
debug = 2
|
||||
debug-assertions = true # <-
|
||||
incremental = false
|
||||
opt-level = 'z' # <-
|
||||
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 # <-
|
|
@ -0,0 +1,27 @@
|
|||
cargo-features = ["per-package-target"]
|
||||
|
||||
[package]
|
||||
# TODO(1) fix `authors` and `name` if you didn't use `cargo-generate`
|
||||
authors = ["sebastian <sebastian@sebastians-site.de>"]
|
||||
name = "cheapsdo-firmware"
|
||||
edition = "2021"
|
||||
version = "0.1.0"
|
||||
default-target = "thumbv7m-none-eabi" # Cortex-M3
|
||||
|
||||
[dependencies]
|
||||
cortex-m = { version = "0.7", features = ["critical-section-single-core"] }
|
||||
defmt = { version = "0.3", features = ["encoding-rzcobs"] }
|
||||
defmt-brtt = { version = "0.1", default-features = false, features = ["rtt"] }
|
||||
panic-probe = { version = "0.3", features = ["print-defmt"] }
|
||||
rtic = { version = "2.0.1", features = [ "thumbv7-backend" ] }
|
||||
defmt-rtt = "0.4"
|
||||
embedded-hal = "0.2.3"
|
||||
stm32f1xx-hal = { version = "0.10.0", features = ["stm32f103", "rt", "medium"] }
|
||||
nb = "1.0.0"
|
||||
systick-monotonic = "1.0.0"
|
||||
rtic-monotonics = {version = "1.4.1", features = ["cortex-m-systick"] }
|
||||
usb-device = "0.2.8"
|
||||
usbd-serial = "0.1.1"
|
||||
cheapsdo-protocol = { path = "../protocol" }
|
||||
postcard = {version = "1.0.8", features = ["use-defmt"]}
|
||||
heapless = {version = "0.8.0", features = ["defmt-03"]}
|
|
@ -1,6 +1,7 @@
|
|||
#![no_std]
|
||||
#![no_main]
|
||||
#![feature(type_alias_impl_trait)]
|
||||
#![feature(slice_split_once)]
|
||||
use defmt_rtt as _; // global logger
|
||||
|
||||
use panic_probe as _;
|
||||
|
@ -18,10 +19,7 @@ use rtic::app;
|
|||
#[app(device = stm32f1xx_hal::pac, peripherals = true, dispatchers = [SPI3])]
|
||||
mod app {
|
||||
|
||||
use core::fmt::Write;
|
||||
|
||||
use cortex_m::asm::delay;
|
||||
use embedded_hal::digital::v2::OutputPin;
|
||||
use rtic_monotonics::systick::*;
|
||||
|
||||
use stm32f1xx_hal::{
|
||||
|
@ -37,6 +35,13 @@ mod app {
|
|||
use stm32f1xx_hal::usb::{Peripheral, UsbBus, UsbBusType};
|
||||
use usb_device::prelude::*;
|
||||
|
||||
use heapless::Vec;
|
||||
use postcard::{from_bytes_cobs, to_vec_cobs};
|
||||
|
||||
use cheapsdo_protocol::{*, DeviceMessage};
|
||||
|
||||
const USB_BUFFER_SIZE : usize = 64;
|
||||
|
||||
#[local]
|
||||
struct Local {
|
||||
board_led: gpioc::PC13<Output<PushPull>>,
|
||||
|
@ -51,6 +56,7 @@ mod app {
|
|||
serial: usbd_serial::SerialPort<'static, UsbBusType>,
|
||||
current_freq: f64,
|
||||
short_avg: f64,
|
||||
buffer: Vec<u8, USB_BUFFER_SIZE>,
|
||||
}
|
||||
|
||||
const TARGET_FREQ: f64 = 10.0f64;
|
||||
|
@ -193,7 +199,6 @@ mod app {
|
|||
.device_class(usbd_serial::USB_CLASS_CDC)
|
||||
.build();
|
||||
|
||||
|
||||
update_pwm::spawn().unwrap();
|
||||
|
||||
(
|
||||
|
@ -202,6 +207,7 @@ mod app {
|
|||
usb_dev,
|
||||
current_freq: 0.0f64,
|
||||
short_avg: 0.0f64,
|
||||
buffer: Vec::new(),
|
||||
},
|
||||
Local {
|
||||
board_led,
|
||||
|
@ -212,6 +218,7 @@ mod app {
|
|||
)
|
||||
}
|
||||
|
||||
|
||||
const WINDOW_LEN: usize = 100;
|
||||
|
||||
#[task(local=[tim2, tim3, pwm, board_led], shared=[current_freq, short_avg])]
|
||||
|
@ -287,7 +294,6 @@ mod app {
|
|||
*avg = short_avg;
|
||||
});
|
||||
|
||||
|
||||
let diff = (TARGET_FREQ - short_avg) * 1_000_000.0;
|
||||
if diff > 1.0 || diff < -1.0 {
|
||||
cur_pwm += diff as i32 * 15;
|
||||
|
@ -307,52 +313,97 @@ mod app {
|
|||
}
|
||||
}
|
||||
|
||||
#[task(binds = USB_HP_CAN_TX, shared = [usb_dev, serial, current_freq, short_avg])]
|
||||
#[task(binds = USB_HP_CAN_TX, shared = [usb_dev, serial, buffer, current_freq, short_avg])]
|
||||
fn usb_tx(cx: usb_tx::Context) {
|
||||
let mut usb_dev = cx.shared.usb_dev;
|
||||
let mut serial = cx.shared.serial;
|
||||
let mut buffer = cx.shared.buffer;
|
||||
let mut current_freq = cx.shared.current_freq;
|
||||
let mut short_avg = cx.shared.short_avg;
|
||||
|
||||
(&mut usb_dev, &mut serial, &mut current_freq, &mut short_avg).lock(|usb_dev, serial, current_freq, short_avg| {
|
||||
usb_poll(usb_dev, serial, current_freq, short_avg);
|
||||
});
|
||||
(
|
||||
&mut usb_dev,
|
||||
&mut serial,
|
||||
&mut buffer,
|
||||
&mut current_freq,
|
||||
&mut short_avg,
|
||||
)
|
||||
.lock(|usb_dev, serial, buffer, current_freq, short_avg| {
|
||||
usb_poll(usb_dev, serial, buffer, current_freq, short_avg);
|
||||
});
|
||||
}
|
||||
|
||||
#[task(binds = USB_LP_CAN_RX0, shared = [usb_dev, serial, current_freq, short_avg])]
|
||||
#[task(binds = USB_LP_CAN_RX0, shared = [usb_dev, serial, buffer, current_freq, short_avg])]
|
||||
fn usb_rx0(cx: usb_rx0::Context) {
|
||||
let mut usb_dev = cx.shared.usb_dev;
|
||||
let mut serial = cx.shared.serial;
|
||||
let mut buffer = cx.shared.buffer;
|
||||
let mut current_freq = cx.shared.current_freq;
|
||||
let mut short_avg = cx.shared.short_avg;
|
||||
|
||||
(&mut usb_dev, &mut serial, &mut current_freq, &mut short_avg).lock(|usb_dev, serial, current_freq, short_avg| {
|
||||
usb_poll(usb_dev, serial, current_freq, short_avg);
|
||||
});
|
||||
(
|
||||
&mut usb_dev,
|
||||
&mut serial,
|
||||
&mut buffer,
|
||||
&mut current_freq,
|
||||
&mut short_avg,
|
||||
)
|
||||
.lock(|usb_dev, serial, buffer, current_freq, short_avg| {
|
||||
usb_poll(usb_dev, serial, buffer, current_freq, short_avg);
|
||||
});
|
||||
}
|
||||
|
||||
fn usb_poll<B: usb_device::bus::UsbBus>(
|
||||
usb_dev: &mut usb_device::prelude::UsbDevice<'static, B>,
|
||||
serial: &mut usbd_serial::SerialPort<'static, B>,
|
||||
current_freq: &mut f64,
|
||||
buffer: &mut Vec<u8, USB_BUFFER_SIZE>,
|
||||
current_freq: &mut f64,
|
||||
short_avg: &mut f64,
|
||||
) {
|
||||
if !usb_dev.poll(&mut [serial]) {
|
||||
return;
|
||||
}
|
||||
|
||||
let mut buf = [0u8; 8];
|
||||
|
||||
match serial.read(&mut buf) {
|
||||
let mut tmp = [0u8; 16];
|
||||
match serial.read(&mut tmp) {
|
||||
Ok(count) if count > 0 => {
|
||||
if buf[0] == b'?' {
|
||||
|
||||
let mut data = arrayvec::ArrayString::<32>::new();
|
||||
write!(data, "{}|{}\n\r", current_freq, short_avg).unwrap();
|
||||
serial.write(data.as_bytes()).unwrap();
|
||||
};
|
||||
if buffer.extend_from_slice(&tmp[0..count]).is_err() {
|
||||
buffer.clear();
|
||||
defmt::error!("Buffer overflow while waiting for the end of the packet");
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
loop {
|
||||
if let Some((msg, rest)) = buffer.split_once(|&x| x == 0) {
|
||||
let mut message = [0u8; 128];
|
||||
message.clone_from_slice(msg);
|
||||
let host_msg = from_bytes_cobs::<HostMessage>(&mut message);
|
||||
|
||||
match host_msg {
|
||||
Ok(host_msg) => match host_msg {
|
||||
HostMessage::RequestStatus => {
|
||||
let device_msg = DeviceMessage::Status(StatusMessage{
|
||||
measured_frequency: *current_freq,
|
||||
average_frequency: *short_avg,
|
||||
pwm: 0,
|
||||
});
|
||||
|
||||
let bytes = to_vec_cobs::<DeviceMessage, USB_BUFFER_SIZE>(&device_msg).unwrap();
|
||||
serial.write(bytes.as_slice()).unwrap();
|
||||
},
|
||||
HostMessage::SetPLLOutputs => {
|
||||
defmt::error!("PLL output is not implemented yet")
|
||||
}
|
||||
}
|
||||
Err(err) => defmt::error!("Unable to parse host message: {}", err),
|
||||
};
|
||||
|
||||
*buffer = Vec::<u8, USB_BUFFER_SIZE>::from_slice(rest).unwrap();
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
[package]
|
||||
name = "cheapsdo-protocol"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
serde = {version = "1.0.193", default-features = false, features = ["derive"]}
|
|
@ -0,0 +1,21 @@
|
|||
#![no_std]
|
||||
|
||||
use serde::{Serialize, Deserialize};
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, PartialEq)]
|
||||
pub enum DeviceMessage {
|
||||
Status(StatusMessage),
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, PartialEq)]
|
||||
pub enum HostMessage {
|
||||
RequestStatus,
|
||||
SetPLLOutputs,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, PartialEq)]
|
||||
pub struct StatusMessage {
|
||||
pub measured_frequency: f64,
|
||||
pub average_frequency: f64,
|
||||
pub pwm: u16,
|
||||
}
|
Loading…
Reference in New Issue