diff --git a/.cargo/config b/hangman/.cargo/config similarity index 100% rename from .cargo/config rename to hangman/.cargo/config diff --git a/Cargo.lock b/hangman/Cargo.lock similarity index 99% rename from Cargo.lock rename to hangman/Cargo.lock index 129b5a9..2afe5aa 100644 --- a/Cargo.lock +++ b/hangman/Cargo.lock @@ -710,6 +710,7 @@ dependencies = [ "embedded-alloc", "embedded-storage", "embedded-storage-async", + "hangman-utils", "hex", "median", "nrf-softdevice", @@ -723,6 +724,14 @@ dependencies = [ "typenum", ] +[[package]] +name = "hangman-utils" +version = "0.1.0" +dependencies = [ + "defmt", + "num-traits", +] + [[package]] name = "hash32" version = "0.2.1" diff --git a/Cargo.toml b/hangman/Cargo.toml similarity index 97% rename from Cargo.toml rename to hangman/Cargo.toml index 7f16520..d28ae6c 100644 --- a/Cargo.toml +++ b/hangman/Cargo.toml @@ -26,6 +26,7 @@ embassy-usb = { version = "0.1", features = ["defmt"], optional = true} embedded-alloc = "0.5" embedded-storage = "0.3" embedded-storage-async = "0.4" +hangman-utils = { path = "../hangman_utils" } hex = { version = "0.4", default-features = false } median = { version = "0.3", default-features = false } nrf-softdevice = { version = "0.1", features = ["s113", "ble-gatt-server", "ble-peripheral", "critical-section-impl", "defmt"] } diff --git a/Embed.toml b/hangman/Embed.toml similarity index 100% rename from Embed.toml rename to hangman/Embed.toml diff --git a/build.rs b/hangman/build.rs similarity index 100% rename from build.rs rename to hangman/build.rs diff --git a/flash.sh b/hangman/flash.sh similarity index 100% rename from flash.sh rename to hangman/flash.sh diff --git a/memory.x b/hangman/memory.x similarity index 100% rename from memory.x rename to hangman/memory.x diff --git a/src/battery_voltage.rs b/hangman/src/battery_voltage.rs similarity index 100% rename from src/battery_voltage.rs rename to hangman/src/battery_voltage.rs diff --git a/src/bin/README.md b/hangman/src/bin/README.md similarity index 100% rename from src/bin/README.md rename to hangman/src/bin/README.md diff --git a/src/bin/blinky_p0.rs b/hangman/src/bin/blinky_p0.rs similarity index 100% rename from src/bin/blinky_p0.rs rename to hangman/src/bin/blinky_p0.rs diff --git a/src/bin/blinky_p1.rs b/hangman/src/bin/blinky_p1.rs similarity index 100% rename from src/bin/blinky_p1.rs rename to hangman/src/bin/blinky_p1.rs diff --git a/src/bin/calibration_p0.rs b/hangman/src/bin/calibration_p0.rs similarity index 100% rename from src/bin/calibration_p0.rs rename to hangman/src/bin/calibration_p0.rs diff --git a/src/bin/calibration_p1.rs b/hangman/src/bin/calibration_p1.rs similarity index 100% rename from src/bin/calibration_p1.rs rename to hangman/src/bin/calibration_p1.rs diff --git a/src/bin/dongle.rs b/hangman/src/bin/dongle.rs similarity index 100% rename from src/bin/dongle.rs rename to hangman/src/bin/dongle.rs diff --git a/src/bin/proto0_0.rs b/hangman/src/bin/proto0_0.rs similarity index 100% rename from src/bin/proto0_0.rs rename to hangman/src/bin/proto0_0.rs diff --git a/src/bin/proto1_0.rs b/hangman/src/bin/proto1_0.rs similarity index 100% rename from src/bin/proto1_0.rs rename to hangman/src/bin/proto1_0.rs diff --git a/src/ble/advertising.rs b/hangman/src/ble/advertising.rs similarity index 100% rename from src/ble/advertising.rs rename to hangman/src/ble/advertising.rs diff --git a/src/ble/gatt_server.rs b/hangman/src/ble/gatt_server.rs similarity index 100% rename from src/ble/gatt_server.rs rename to hangman/src/ble/gatt_server.rs diff --git a/src/ble/gatt_types.rs b/hangman/src/ble/gatt_types.rs similarity index 100% rename from src/ble/gatt_types.rs rename to hangman/src/ble/gatt_types.rs diff --git a/src/ble/mod.rs b/hangman/src/ble/mod.rs similarity index 100% rename from src/ble/mod.rs rename to hangman/src/ble/mod.rs diff --git a/src/ble/task.rs b/hangman/src/ble/task.rs similarity index 100% rename from src/ble/task.rs rename to hangman/src/ble/task.rs diff --git a/src/button.rs b/hangman/src/button.rs similarity index 100% rename from src/button.rs rename to hangman/src/button.rs diff --git a/src/console/board.rs b/hangman/src/console/board.rs similarity index 100% rename from src/console/board.rs rename to hangman/src/console/board.rs diff --git a/src/console/mod.rs b/hangman/src/console/mod.rs similarity index 100% rename from src/console/mod.rs rename to hangman/src/console/mod.rs diff --git a/src/console/task.rs b/hangman/src/console/task.rs similarity index 100% rename from src/console/task.rs rename to hangman/src/console/task.rs diff --git a/src/lib.rs b/hangman/src/lib.rs similarity index 100% rename from src/lib.rs rename to hangman/src/lib.rs diff --git a/src/nonvolatile.rs b/hangman/src/nonvolatile.rs similarity index 94% rename from src/nonvolatile.rs rename to hangman/src/nonvolatile.rs index 1baffb9..85f53d6 100644 --- a/src/nonvolatile.rs +++ b/hangman/src/nonvolatile.rs @@ -140,14 +140,3 @@ impl Nvm { .expect("Write to succeed"); } } - -#[cfg(test)] -mod test { - use super::*; - - #[test] - fn addresses() { - // Ensure that all of the registers and 4-byte checksum can fit on our Flash page - assert!(4 * (RegisterRead::COUNT + 1) <= MAX_ADDR - MIN_ADDR); - } -} diff --git a/src/sleep.rs b/hangman/src/sleep.rs similarity index 100% rename from src/sleep.rs rename to hangman/src/sleep.rs diff --git a/hangman/src/util.rs b/hangman/src/util.rs new file mode 100644 index 0000000..628826c --- /dev/null +++ b/hangman/src/util.rs @@ -0,0 +1,29 @@ +// Copyright 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use crate::pac; + +pub unsafe fn disable_all_gpio_sense() { + #[cfg(feature = "nrf52840")] + { + let p1 = unsafe { &(*pac::P1::ptr()) }; + for cnf in &p1.pin_cnf { + cnf.modify(|_, w| w.sense().disabled()); + } + } + let p0 = unsafe { &(*pac::P0::ptr()) }; + for cnf in &p0.pin_cnf { + cnf.modify(|_, w| w.sense().disabled()); + } +} diff --git a/src/weight/ads1230.rs b/hangman/src/weight/ads1230.rs similarity index 98% rename from src/weight/ads1230.rs rename to hangman/src/weight/ads1230.rs index 6eca457..e220423 100644 --- a/src/weight/ads1230.rs +++ b/hangman/src/weight/ads1230.rs @@ -14,7 +14,7 @@ /// Ads1230 driver using embassy_nrf-friendly types use super::{Sample, SampleProducerMut}; -use crate::{blocking_hal::prelude::_embedded_hal_blocking_delay_DelayUs, util, SharedDelay}; +use crate::{blocking_hal::prelude::_embedded_hal_blocking_delay_DelayUs, SharedDelay}; use embassy_nrf::gpio::{AnyPin, Input, Output}; use embassy_time::Instant; use embassy_time::{Duration, Timer}; @@ -126,7 +126,7 @@ impl<'d> Ads1230<'d> { // The ADS1230 gives a 20-bit signed reading, which is initially stored in a u32 container. // Unsigned for sane shifting and 32-bit because there is no u20 Rust primitive. Convert it // to a signed integer so that it is interpreted correctly. - let value = util::convert_signed_to_i32::<20>(raw_reading); + let value = hangman_utils::convert_signed_to_i32::<20>(raw_reading); // HX711 sometimes spontaneously returns -1 (0xFFFFFF) if value == -1 && n_skips < 3 { n_skips += 1; diff --git a/src/weight/average.rs b/hangman/src/weight/average.rs similarity index 100% rename from src/weight/average.rs rename to hangman/src/weight/average.rs diff --git a/src/weight/calibrate.rs b/hangman/src/weight/calibrate.rs similarity index 100% rename from src/weight/calibrate.rs rename to hangman/src/weight/calibrate.rs diff --git a/src/weight/hx711.rs b/hangman/src/weight/hx711.rs similarity index 97% rename from src/weight/hx711.rs rename to hangman/src/weight/hx711.rs index 3e99283..f732275 100644 --- a/src/weight/hx711.rs +++ b/hangman/src/weight/hx711.rs @@ -14,7 +14,7 @@ /// Hx711 driver using embassy_nrf-friendly types use super::{Sample, SampleProducerMut}; -use crate::{blocking_hal::prelude::_embedded_hal_blocking_delay_DelayUs, util, SharedDelay}; +use crate::{blocking_hal::prelude::_embedded_hal_blocking_delay_DelayUs, SharedDelay}; use embassy_nrf::gpio::{AnyPin, Input, Output}; use embassy_time::{Duration, Instant, Timer}; @@ -105,7 +105,7 @@ impl<'d> Hx711<'d> { // The HX711 gives a 24-bit signed reading, which is initially stored in a u32 container. // Unsigned for sane shifting and 32-bit because there is no u24 Rust primitive. Convert it // to a signed integer so that it is interpreted correctly. - let value = util::convert_signed_to_i32::<24>(raw_reading); + let value = hangman_utils::convert_signed_to_i32::<24>(raw_reading); // HX711 sometimes spontaneously returns -1 (0xFFFFFF) if value == -1 && n_skips < 3 { n_skips += 1; diff --git a/src/weight/median.rs b/hangman/src/weight/median.rs similarity index 100% rename from src/weight/median.rs rename to hangman/src/weight/median.rs diff --git a/src/weight/mod.rs b/hangman/src/weight/mod.rs similarity index 99% rename from src/weight/mod.rs rename to hangman/src/weight/mod.rs index a1fc3fe..f0767af 100644 --- a/src/weight/mod.rs +++ b/hangman/src/weight/mod.rs @@ -15,7 +15,6 @@ pub mod ads1230; pub mod average; mod calibrate; -mod factory_calibration; pub mod hx711; pub mod median; mod random; diff --git a/src/weight/random.rs b/hangman/src/weight/random.rs similarity index 100% rename from src/weight/random.rs rename to hangman/src/weight/random.rs diff --git a/src/weight/tare.rs b/hangman/src/weight/tare.rs similarity index 100% rename from src/weight/tare.rs rename to hangman/src/weight/tare.rs diff --git a/src/weight/task.rs b/hangman/src/weight/task.rs similarity index 95% rename from src/weight/task.rs rename to hangman/src/weight/task.rs index d12a40b..6ea7523 100644 --- a/src/weight/task.rs +++ b/hangman/src/weight/task.rs @@ -13,7 +13,6 @@ // limitations under the License. use super::calibrate::Calibrator; -use super::factory_calibration::{self, CalPoint, TwoPoint}; use super::tare::Tarer; #[cfg(feature = "nrf52832")] use super::Ads1230; @@ -25,6 +24,7 @@ use crate::MeasureCommandReceiver; use embassy_sync::blocking_mutex::raw::NoopRawMutex; use embassy_sync::mutex::Mutex; use embassy_time::{Duration, Instant, Timer}; +use hangman_utils::two_point_cal::{self, CalPoint, TwoPoint}; use nrf_softdevice::Softdevice; use static_cell::make_static; @@ -51,7 +51,7 @@ struct MeasurementContext { calibrator: &'static SharedCalibrator, tarer: Tarer<&'static SharedCalibrator>, nvm: Nvm, - factory_cal: TwoPoint, + factory_cal: TwoPoint, } async fn handle_command(cmd: Command, context: &mut MeasurementContext, adc: &SharedAdc) { @@ -113,11 +113,13 @@ async fn handle_command(cmd: Command, context: &mut MeasurementContext, adc: &Sh } let Sample { value, .. } = context.median.sample().await; let reading = filter.add_sample(value).unwrap(); - context.factory_cal.add_point(CalPoint { weight, reading }); + context.factory_cal.add_point(CalPoint { + expected_value: weight, + measured_value: reading, + }); } Command::SaveCalibration => { - if let Some(factory_calibration::Constants { m, b }) = - context.factory_cal.get_cal_constants() + if let Some(two_point_cal::Constants { m, b }) = context.factory_cal.get_cal_constants() { defmt::info!("New calibration: m = {=f32} b = {=i32}", m, b); super::write_calibration(&mut context.nvm, m, b).await; diff --git a/hangman_utils/Cargo.lock b/hangman_utils/Cargo.lock new file mode 100644 index 0000000..442e4cb --- /dev/null +++ b/hangman_utils/Cargo.lock @@ -0,0 +1,159 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "autocfg" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "defmt" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a99dd22262668b887121d4672af5a64b238f026099f1a2a1b322066c9ecfe9e0" +dependencies = [ + "bitflags", + "defmt-macros", +] + +[[package]] +name = "defmt-macros" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3a9f309eff1f79b3ebdf252954d90ae440599c26c2c553fe87a2d17195f2dcb" +dependencies = [ + "defmt-parser", + "proc-macro-error", + "proc-macro2", + "quote", + "syn 2.0.66", +] + +[[package]] +name = "defmt-parser" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff4a5fefe330e8d7f31b16a318f9ce81000d8e35e69b93eae154d16d2278f70f" +dependencies = [ + "thiserror", +] + +[[package]] +name = "hangman-utils" +version = "0.1.0" +dependencies = [ + "defmt", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn 1.0.109", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + +[[package]] +name = "proc-macro2" +version = "1.0.84" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec96c6a92621310b51366f1e28d05ef11489516e93be030060e5fc12024a49d6" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.66" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c42f3f41a2de00b01c0aaad383c5a45241efc8b2d1eda5661812fda5f3cdcff5" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "thiserror" +version = "1.0.61" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c546c80d6be4bc6a00c0f01730c08df82eaa7a7a61f11d656526506112cc1709" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.61" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.66", +] + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" diff --git a/hangman_utils/Cargo.toml b/hangman_utils/Cargo.toml new file mode 100644 index 0000000..d28d3d1 --- /dev/null +++ b/hangman_utils/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "hangman-utils" +version = "0.1.0" +edition = "2021" + +[dependencies] +defmt = { version = "0.3" } +num-traits = { version = "0.2", default-features = false } diff --git a/src/util.rs b/hangman_utils/src/lib.rs similarity index 81% rename from src/util.rs rename to hangman_utils/src/lib.rs index e28a77e..404e03b 100644 --- a/src/util.rs +++ b/hangman_utils/src/lib.rs @@ -1,4 +1,4 @@ -// Copyright 2023 Google LLC +// Copyright 2024 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -12,21 +12,12 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::pac; +#![cfg_attr(not(test), no_std)] +#![forbid(unsafe_op_in_unsafe_fn)] -pub unsafe fn disable_all_gpio_sense() { - #[cfg(feature = "nrf52840")] - { - let p1 = unsafe { &(*pac::P1::ptr()) }; - for cnf in &p1.pin_cnf { - cnf.modify(|_, w| w.sense().disabled()); - } - } - let p0 = unsafe { &(*pac::P0::ptr()) }; - for cnf in &p0.pin_cnf { - cnf.modify(|_, w| w.sense().disabled()); - } -} +#[macro_use] +pub mod log; +pub mod two_point_cal; /// Convert a signed integer in a u32 container to a signed integer pub const fn convert_signed_to_i32(mut input: u32) -> i32 { @@ -38,8 +29,6 @@ pub const fn convert_signed_to_i32(mut input: u32) -> i32 { input as i32 } -// TODO: figure out how to actually run these tests on host -// I promise I ran them in the playground. #[cfg(test)] mod tests { use super::*; diff --git a/hangman_utils/src/log.rs b/hangman_utils/src/log.rs new file mode 100644 index 0000000..b4068ef --- /dev/null +++ b/hangman_utils/src/log.rs @@ -0,0 +1,58 @@ +// Copyright 2024 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#[macro_export] +macro_rules! trace { + ($($arg:tt)*) => { + if !cfg!(test) { + defmt::trace!($($arg)*); + } + }; +} + +#[macro_export] +macro_rules! debug { + ($($arg:tt)*) => { + if !cfg!(test) { + defmt::debug!($($arg)*); + } + }; +} + +#[macro_export] +macro_rules! info { + ($($arg:tt)*) => { + if !cfg!(test) { + defmt::info!($($arg)*); + } + }; +} + +#[macro_export] +macro_rules! warn { + ($($arg:tt)*) => { + if !cfg!(test) { + defmt::warn!($($arg)*); + } + }; +} + +#[macro_export] +macro_rules! error { + ($($arg:tt)*) => { + if !cfg!(test) { + defmt::error!($($arg)*); + } + }; +} diff --git a/hangman_utils/src/two_point_cal.rs b/hangman_utils/src/two_point_cal.rs new file mode 100644 index 0000000..5e85eea --- /dev/null +++ b/hangman_utils/src/two_point_cal.rs @@ -0,0 +1,86 @@ +// Copyright 2024 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use defmt::Format; +use num_traits::PrimInt; + +#[derive(Copy, Clone, Format)] +pub struct CalPoint { + pub expected_value: f32, + pub measured_value: Reading, +} + +#[derive(Copy, Clone, Default, Format)] +pub struct TwoPoint { + zero: Option, + other: Option>, +} + +/// Calibration constants +/// +/// weight = m * (reading - b) +#[derive(Copy, Clone, Format)] +pub struct Constants { + pub m: f32, + pub b: Reading, +} + +impl TwoPoint { + pub fn add_point(&mut self, point: CalPoint) { + crate::debug!("New calibration point: {}", point); + if point.expected_value == 0.0 { + self.zero = Some(point.measured_value); + } else { + self.other = Some(point); + } + } + + pub fn get_cal_constants(&self) -> Option> { + let other = self.other?; + let b = self.zero?; + if other.measured_value == b { + crate::error!("Attempted divide by zero"); + return None; + } + let Some(denominator) = other.measured_value.checked_sub(&b) else { + crate::error!("Underflow: {} - {}", other.measured_value, b); + return None; + }; + let m = other.expected_value / denominator.to_f32().unwrap(); + Some(Constants { m, b }) + } +} + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn calibrate() { + let mut cal = TwoPoint::default(); + let zero = CalPoint { + expected_value: 0.0, + measured_value: 0x1234, + }; + let other = CalPoint { + expected_value: 100.0, + measured_value: 0x4567, + }; + cal.add_point(zero); + cal.add_point(other); + let Constants { m, b } = cal.get_cal_constants().unwrap(); + assert_eq!((zero.measured_value - b) as f32 * m, zero.expected_value); + assert_eq!((other.measured_value - b) as f32 * m, other.expected_value); + } +} diff --git a/src/weight/factory_calibration.rs b/src/weight/factory_calibration.rs deleted file mode 100644 index b1ef96e..0000000 --- a/src/weight/factory_calibration.rs +++ /dev/null @@ -1,81 +0,0 @@ -// Copyright 2023 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -use super::RawReading; -use defmt::Format; - -#[derive(Copy, Clone, Format)] -pub(crate) struct CalPoint { - pub(crate) weight: f32, - pub(crate) reading: RawReading, -} - -#[derive(Copy, Clone, Default, Format)] -pub(crate) struct TwoPoint { - zero: Option, - other: Option, -} - -/// Calibration constants -/// -/// weight = m * (reading - b) -#[derive(Copy, Clone, Format)] -pub(crate) struct Constants { - pub(crate) m: f32, - pub(crate) b: RawReading, -} - -impl TwoPoint { - pub(crate) fn add_point(&mut self, point: CalPoint) { - defmt::debug!("New calibration point: {}", point); - if point.weight == 0.0 { - self.zero = Some(point.reading); - } else { - self.other = Some(point); - } - } - - pub(crate) fn get_cal_constants(&self) -> Option { - let other = self.other?; - let b = self.zero?; - if other.reading - b == 0 { - defmt::warn!("Attempted divide by zero"); - return None; - } - let m = other.weight / (other.reading - b) as f32; - Some(Constants { m, b }) - } -} - -#[cfg(test)] -mod test { - use super::*; - - fn calibrate() { - let mut cal = TwoPoint::default(); - let zero = CalPoint { - weight: 0.0, - reading: 0x1234, - }; - let other = CalPoint { - weight: 100.0, - reading: 0x4567, - }; - cal.add_point(zero); - cal.add_point(other); - let Constants { m, b } = cal.get_cal_constants(); - assert_eq!((zero.reading - b) as f32 * m, zero.weight); - assert_eq!((other.reading - b) as f32 * m, other.weight); - } -}