Skip to content

Commit

Permalink
Adds temperature dumping
Browse files Browse the repository at this point in the history
  • Loading branch information
ansg191 committed Jan 4, 2024
1 parent 9d689f5 commit 751b163
Show file tree
Hide file tree
Showing 3 changed files with 139 additions and 38 deletions.
12 changes: 6 additions & 6 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -242,22 +242,22 @@ mod app {

// Append to buffer
if buffer.push_back(b).is_err() {
panic!("Buffer overflow");
error!("Buffer overflow");
}
}
Err(nb::Error::WouldBlock) => break,
Err(nb::Error::Other(serial::Error::Framing)) => {
panic!("USART error: Framing");
error!("USART error: Framing");
}
Err(nb::Error::Other(serial::Error::Noise)) => panic!("USART error: Noise"),
Err(nb::Error::Other(serial::Error::Noise)) => error!("USART error: Noise"),
Err(nb::Error::Other(serial::Error::Overrun)) => {
panic!("USART error: Overrun");
error!("USART error: Overrun");
}
Err(nb::Error::Other(serial::Error::Parity)) => {
panic!("USART error: Parity");
error!("USART error: Parity");
}

Err(nb::Error::Other(_)) => defmt::panic!("USART error: Unknown"),
Err(nb::Error::Other(_)) => defmt::error!("USART error: Unknown"),
// Err(nb::Error::Other(e)) => core::panic!("USART error: {:?}", e),
}
});
Expand Down
29 changes: 29 additions & 0 deletions src/storage/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,12 @@ impl<const N: usize> Storage<N> {
let temp = Temp::now_from_temp(temp);
self.temps.write(temp);
}

pub fn oldest(&self) -> OldestOrdered<'_, N> {
OldestOrdered {
iter: self.temps.oldest_ordered(),
}
}
}

#[derive(Debug, Copy, Clone)]
Expand Down Expand Up @@ -52,4 +58,27 @@ impl Temp {
fn now_from_temp(temp: Temperature) -> Self {
Self::now(temp.saturating_to_num())
}

#[inline]
const fn secs(self) -> u32 {
u32::from_le_bytes([self.secs[0], self.secs[1], self.secs[2], 0])
}

#[inline]
fn value(self) -> Temperature {
self.value.to_num()
}
}

#[derive(Clone)]
pub struct OldestOrdered<'a, const N: usize> {
iter: heapless::OldestOrdered<'a, Temp, N>,
}

impl<'a, const N: usize> Iterator for OldestOrdered<'a, N> {
type Item = (u32, Temperature);

fn next(&mut self) -> Option<Self::Item> {
self.iter.next().map(|temp| (temp.secs(), temp.value()))
}
}
136 changes: 104 additions & 32 deletions src/terminal.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,32 @@
use core::fmt::Write;

use defmt::*;
use defmt::{panic, *};
use embedded_hal::digital::v2::OutputPin;
use heapless::{Deque, Vec};
use num_traits::AsPrimitive;
use rtic::Mutex;
use stm32f0xx_hal::prelude::*;

use crate::{app::terminal::Context, ds18b20::Resolution};
use crate::{app::terminal::Context, ds18b20::Resolution, thermometer::Temperature};

pub const BUFFER_SIZE: usize = 32;
const OK_STR: &str = "ok\r\n";

const HELP_STR: &str = "Commands:\r
help\r
devices\r
resolution <9|10|11|12>?\r
pid\r
pid <kp> <ki> <kd>\r
temp\r
cooler <on|off>?\r
watch temp\r
dump temps\r
dump events\r
erase\r
reset\r
";

/// Terminal handler
///
/// Commands:
Expand Down Expand Up @@ -83,6 +99,20 @@ pub fn terminal(mut cx: Context<'_>) {
}
Some(b) => unknown_argument(&mut cx, b),
},
Some(b"dump") => match args.next() {
None | Some(&[]) => print_uart(&mut cx, "Missing argument\r\n"),
Some(b"temps") => cx.shared.storage.lock(|storage| {
for (secs, temp) in storage.oldest() {
cx.shared.usart.lock(|tx| {
print_uint(tx, secs);
print_uart_locked(tx, " ");
print_temp(tx, temp);
print_uart_locked(tx, "\r\n");
});
}
}),
Some(b) => unknown_argument(&mut cx, b),
},
Some(b"reset") => {
print_uart(&mut cx, "Resetting...\r\n");
cortex_m::peripheral::SCB::sys_reset();
Expand Down Expand Up @@ -120,22 +150,6 @@ fn get_line(buffer: &mut Deque<u8, BUFFER_SIZE>) -> Option<Vec<u8, BUFFER_SIZE>>
Some(line)
}

fn print_uart(cx: &mut Context, str: &str) {
cx.shared.usart.lock(|tx| {
if tx.write_str(str).is_err() {
defmt::panic!("Failed to write to UART");
}
});
}

fn unknown_argument(cx: &mut Context, arg: &[u8]) {
print_uart(cx, "Unknown argument: '");
// SAFETY: b may not be valid UTF-8, but we don't care cause we're just printing it
// Also, including UTF8 checks would add a lot to the binary size
print_uart(cx, unsafe { core::str::from_utf8_unchecked(arg) });
print_uart(cx, "'\r\n");
}

#[inline]
pub const fn is_newline(b: u8) -> bool {
b == b'\n' || b == b'\r'
Expand All @@ -146,17 +160,75 @@ pub const fn is_whitespace(b: u8) -> bool {
b == b' ' || b == b'\n' || b == b'\r' || b == b'\t'
}

const HELP_STR: &str = "Commands:\r
help\r
devices\r
resolution <9|10|11|12>?\r
pid\r
pid <kp> <ki> <kd>\r
temp\r
cooler <on|off>?\r
watch temp\r
dump temps\r
dump events\r
erase\r
reset\r
";
fn print_uart(cx: &mut Context, str: &str) {
cx.shared.usart.lock(|tx| print_uart_locked(tx, str));
}

fn print_uart_locked<W: Write>(tx: &mut W, str: &str) {
if tx.write_str(str).is_err() {
panic!("Failed to write to UART");
}
}

fn unknown_argument(cx: &mut Context, arg: &[u8]) {
cx.shared.usart.lock(|tx| {
print_uart_locked(tx, "Unknown argument: '");
// SAFETY: b may not be valid UTF-8, but we don't care cause we're just printing it
// Also, including UTF8 checks would add a lot to the binary size
print_uart_locked(tx, unsafe { core::str::from_utf8_unchecked(arg) });
print_uart_locked(tx, "'\r\n");
});
}

fn print_temp<W: Write>(tx: &mut W, temp: Temperature) {
const FRAC_TOTAL: u32 = 10u32.pow(Temperature::FRAC_NBITS);

let sign = temp.is_negative();

let int_part = temp.to_bits().unsigned_abs() >> Temperature::FRAC_NBITS;
let frac_part = temp.frac().to_bits().unsigned_abs();

let mut total = 0;
for i in 0..Temperature::FRAC_NBITS {
let bit = (frac_part >> i) & 1;
let value = FRAC_TOTAL / (1 << (Temperature::FRAC_NBITS - i));
total += bit * value;
}

trace!(
"int_part: {=u32}, total: {=u32}, sign: {=bool}",
int_part,
total,
sign
);

if sign {
print_uart_locked(tx, "-");
}
print_uint(tx, int_part);
print_uart_locked(tx, ".");
print_uint(tx, total);
}

fn print_uint<W: Write>(tx: &mut W, mut num: u32) {
const BUF_SIZE: usize = 10;

let mut buf = [0u8; BUF_SIZE];
let mut idx = 0;

loop {
let digit: u8 = (num % 10).as_();
num /= 10;

buf[BUF_SIZE - idx - 1] = b'0' + digit;
idx += 1;

if num == 0 {
break;
}
}

let buf = &buf[BUF_SIZE - idx..];
// SAFETY: buf is guaranteed to be valid ASCII
print_uart_locked(tx, unsafe { core::str::from_utf8_unchecked(buf) });
}

0 comments on commit 751b163

Please sign in to comment.