From d28da13bd678cfe2861e26b5084b60bd4570065a Mon Sep 17 00:00:00 2001 From: Kesavan Yogeswaran Date: Sat, 6 Jul 2024 12:14:52 -0400 Subject: [PATCH] Re-implement broken make_static! macro static-cell's `make_static!` macro is broken in latest nightly: https://github.com/embassy-rs/static-cell/issues/16 Re-implement it by dropping the automatic type deduction magic. --- hangman/Cargo.lock | 7 ++----- hangman/Cargo.toml | 2 +- hangman/src/bin/blinky_p0.rs | 1 - hangman/src/bin/blinky_p1.rs | 1 - hangman/src/bin/calibration_p0.rs | 9 +++++---- hangman/src/bin/calibration_p1.rs | 9 +++++---- hangman/src/bin/dongle.rs | 11 ++++++----- hangman/src/bin/proto0_0.rs | 11 ++++++----- hangman/src/bin/proto1_0.rs | 8 ++++---- hangman/src/console/board.rs | 20 +++++++++++--------- hangman/src/lib.rs | 12 ++++++++++++ hangman/src/weight/task.rs | 15 ++++++++------- 12 files changed, 60 insertions(+), 46 deletions(-) diff --git a/hangman/Cargo.lock b/hangman/Cargo.lock index 2afe5aa..d9983f7 100644 --- a/hangman/Cargo.lock +++ b/hangman/Cargo.lock @@ -1172,9 +1172,6 @@ name = "portable-atomic" version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7170ef9988bc169ba16dd36a7fa041e5c4cbeb6a35b76d4c03daded371eae7c0" -dependencies = [ - "critical-section", -] [[package]] name = "proc-macro-error" @@ -1354,9 +1351,9 @@ checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" [[package]] name = "static_cell" -version = "1.3.0" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2cd3f559c6c41cde362aed95cd84765907e06057f087b17269b41750ec40a3e7" +checksum = "d89b0684884a883431282db1e4343f34afc2ff6996fe1f4a1664519b66e14c1e" dependencies = [ "portable-atomic", ] diff --git a/hangman/Cargo.toml b/hangman/Cargo.toml index d28ae6c..ed44cb2 100644 --- a/hangman/Cargo.toml +++ b/hangman/Cargo.toml @@ -36,7 +36,7 @@ num = { version = "0.4", default-features = false } once_cell = { version = "1.18", default-features = false, features = ["critical-section"] } panic-probe = { version = "0.3", features = ["print-defmt"] } rand = { version = "0.8", default-features = false, features = ["nightly"] } -static_cell = { version = "1", features = ["nightly"] } +static_cell = { version = "2", features = ["nightly"] } typenum = "1.17" [features] diff --git a/hangman/src/bin/blinky_p0.rs b/hangman/src/bin/blinky_p0.rs index 5c395d2..c19743a 100644 --- a/hangman/src/bin/blinky_p0.rs +++ b/hangman/src/bin/blinky_p0.rs @@ -33,7 +33,6 @@ use embedded_alloc::Heap; use hangman::{ble, pac}; use nrf_softdevice::{self as _, Softdevice}; use panic_probe as _; -// use static_cell::make_static; #[allow(dead_code)] enum Mode { diff --git a/hangman/src/bin/blinky_p1.rs b/hangman/src/bin/blinky_p1.rs index 0479722..5b8ec22 100644 --- a/hangman/src/bin/blinky_p1.rs +++ b/hangman/src/bin/blinky_p1.rs @@ -33,7 +33,6 @@ use embedded_alloc::Heap; use hangman::{ble, pac}; use nrf_softdevice::{self as _, Softdevice}; use panic_probe as _; -// use static_cell::make_static; #[allow(dead_code)] enum Mode { diff --git a/hangman/src/bin/calibration_p0.rs b/hangman/src/bin/calibration_p0.rs index 5adb30a..ec5c833 100644 --- a/hangman/src/bin/calibration_p0.rs +++ b/hangman/src/bin/calibration_p0.rs @@ -33,12 +33,11 @@ use embassy_nrf::{ use embassy_sync::{blocking_mutex::raw::NoopRawMutex, channel::Channel, mutex::Mutex}; use embedded_alloc::Heap; use hangman::{ - ble, blocking_hal, pac, + ble, blocking_hal, make_static, pac, weight::{self, average, Hx711}, }; use nrf_softdevice::{self as _, Softdevice}; use panic_probe as _; -use static_cell::make_static; type SharedDelay = Mutex; @@ -86,7 +85,8 @@ async fn main(spawner: Spawner) -> ! { let p = embassy_nrf::init(config()); let syst = pac::CorePeripherals::take().unwrap().SYST; - let delay: &'static SharedDelay = make_static!(Mutex::new(SysTickDelay::new(syst))); + let delay: &'static SharedDelay = + make_static!(SharedDelay, Mutex::new(SysTickDelay::new(syst))); let sd = ble::init_softdevice(); spawner.must_spawn(softdevice_task(sd)); @@ -105,7 +105,8 @@ async fn main(spawner: Spawner) -> ! { ); let hx711 = Hx711::new(hx711_data, hx711_clock, delay); - let ch: &hangman::MeasureCommandChannel = make_static!(Channel::new()); + let ch: &hangman::MeasureCommandChannel = + make_static!(hangman::MeasureCommandChannel, Channel::new()); spawner.must_spawn(weight::task_function(ch.receiver(), hx711, sd)); let mut button = gpio::Input::new(p.P1_06.degrade(), gpio::Pull::Up); diff --git a/hangman/src/bin/calibration_p1.rs b/hangman/src/bin/calibration_p1.rs index 39e40d5..dc2fc85 100644 --- a/hangman/src/bin/calibration_p1.rs +++ b/hangman/src/bin/calibration_p1.rs @@ -34,12 +34,11 @@ use embassy_sync::{blocking_mutex::raw::NoopRawMutex, channel::Channel, mutex::M use embassy_time::{Duration, Timer}; use embedded_alloc::Heap; use hangman::{ - ble, blocking_hal, pac, + ble, blocking_hal, make_static, pac, weight::{self, average, Ads1230}, }; use nrf_softdevice::{self as _, Softdevice}; use panic_probe as _; -use static_cell::make_static; type SharedDelay = Mutex; @@ -87,7 +86,8 @@ async fn main(spawner: Spawner) -> ! { let p = embassy_nrf::init(config()); let syst = pac::CorePeripherals::take().unwrap().SYST; - let delay: &'static SharedDelay = make_static!(Mutex::new(SysTickDelay::new(syst))); + let delay: &'static SharedDelay = + make_static!(SharedDelay, Mutex::new(SysTickDelay::new(syst))); let sd = ble::init_softdevice(); spawner.must_spawn(softdevice_task(sd)); @@ -118,7 +118,8 @@ async fn main(spawner: Spawner) -> ! { let mut adc = Ads1230::new(adc_data, adc_clock, vdda_on, delay); adc.schedule_offset_calibration().await; - let ch: &hangman::MeasureCommandChannel = make_static!(Channel::new()); + let ch: &hangman::MeasureCommandChannel = + make_static!(hangman::MeasureCommandChannel, Channel::new()); spawner.must_spawn(weight::task_function(ch.receiver(), adc, sd)); let mut button = gpio::Input::new(p.P0_09.degrade(), gpio::Pull::Up); diff --git a/hangman/src/bin/dongle.rs b/hangman/src/bin/dongle.rs index 9346678..9fccc31 100644 --- a/hangman/src/bin/dongle.rs +++ b/hangman/src/bin/dongle.rs @@ -38,13 +38,12 @@ use hangman::console; use hangman::{ battery_voltage, ble, blocking_hal, button::{self, Button}, - pac, util, + make_static, pac, util, weight::{self, Hx711}, MeasureCommandChannel, SharedDelay, }; use nrf_softdevice::{self as _, SocEvent, Softdevice}; use panic_probe as _; -use static_cell::make_static; #[global_allocator] /// Create a small heap. Not sure how to pass around closures without one. @@ -106,7 +105,8 @@ async fn main(spawner: Spawner) -> ! { // This will reset the GPIO latch signal let p = embassy_nrf::init(config()); let syst = pac::CorePeripherals::take().unwrap().SYST; - let delay: &'static SharedDelay = make_static!(Mutex::new(SysTickDelay::new(syst))); + let delay: &'static SharedDelay = + make_static!(SharedDelay, Mutex::new(SysTickDelay::new(syst))); // For debugging let _green_led = gpio::Output::new( @@ -129,7 +129,8 @@ async fn main(spawner: Spawner) -> ! { // USB setup // Hack: pretend USB is already connected. not a bad assumption since this is a dongle // There might be a race condition at startup between USB init and SD init. - let usb_detect_ref: &SoftwareVbusDetect = make_static!(SoftwareVbusDetect::new(true, true)); + let usb_detect_ref: &SoftwareVbusDetect = + make_static!(SoftwareVbusDetect, SoftwareVbusDetect::new(true, true)); let sd = ble::init_softdevice(); spawner.must_spawn(softdevice_task(sd, usb_detect_ref)); @@ -148,7 +149,7 @@ async fn main(spawner: Spawner) -> ! { #[cfg(feature = "console")] let (usb, class) = console::board::setup_usb(p.USBD, Irqs, usb_detect_ref); - let ch: &MeasureCommandChannel = make_static!(Channel::new()); + let ch: &MeasureCommandChannel = make_static!(MeasureCommandChannel, Channel::new()); spawner.must_spawn(weight::task_function(ch.receiver(), hx711, sd)); // Sample battery voltage while sampling to get a reading under load ch.sender() diff --git a/hangman/src/bin/proto0_0.rs b/hangman/src/bin/proto0_0.rs index 093645c..a6c73e9 100644 --- a/hangman/src/bin/proto0_0.rs +++ b/hangman/src/bin/proto0_0.rs @@ -36,13 +36,12 @@ use embedded_alloc::Heap; use hangman::{ battery_voltage, ble, blocking_hal, button::{self, Button}, - pac, util, + make_static, pac, util, weight::{self, Hx711}, MeasureCommandChannel, SharedDelay, }; use nrf_softdevice::{self as _, SocEvent, Softdevice}; use panic_probe as _; -use static_cell::make_static; #[global_allocator] /// Create a small heap. Not sure how to pass around closures without one. @@ -96,7 +95,8 @@ async fn main(spawner: Spawner) -> ! { let p = embassy_nrf::init(config()); let syst = pac::CorePeripherals::take().unwrap().SYST; - let delay: &'static SharedDelay = make_static!(Mutex::new(SysTickDelay::new(syst))); + let delay: &'static SharedDelay = + make_static!(SharedDelay, Mutex::new(SysTickDelay::new(syst))); // orange DATA 0.17 let hx711_data = gpio::Input::new(p.P0_17.degrade(), gpio::Pull::None); @@ -112,7 +112,8 @@ async fn main(spawner: Spawner) -> ! { // USB setup // Hack: pretend USB is already connected. not a bad assumption since this is a dongle // There might be a race condition at startup between USB init and SD init. - let usb_detect_ref: &SoftwareVbusDetect = make_static!(SoftwareVbusDetect::new(true, true)); + let usb_detect_ref: &SoftwareVbusDetect = + make_static!(SoftwareVbusDetect, SoftwareVbusDetect::new(true, true)); let sd = ble::init_softdevice(); spawner.must_spawn(softdevice_task(sd, usb_detect_ref)); @@ -128,7 +129,7 @@ async fn main(spawner: Spawner) -> ! { ) }; - let ch: &MeasureCommandChannel = make_static!(Channel::new()); + let ch: &MeasureCommandChannel = make_static!(MeasureCommandChannel, Channel::new()); spawner.must_spawn(weight::task_function(ch.receiver(), hx711, sd)); // Sample battery voltage while sampling to get a reading under load diff --git a/hangman/src/bin/proto1_0.rs b/hangman/src/bin/proto1_0.rs index a38dda3..1a87b6c 100644 --- a/hangman/src/bin/proto1_0.rs +++ b/hangman/src/bin/proto1_0.rs @@ -36,13 +36,12 @@ use embedded_alloc::Heap; use hangman::{ battery_voltage, ble, blocking_hal, button::{self, Button}, - pac, sleep, util, + make_static, pac, sleep, util, weight::{self, Ads1230}, MeasureCommandChannel, SharedDelay, }; use nrf_softdevice::{self as _, Softdevice}; use panic_probe as _; -use static_cell::make_static; #[global_allocator] /// Create a small heap. Not sure how to pass around closures without one. @@ -96,7 +95,8 @@ async fn main(spawner: Spawner) -> ! { let p = embassy_nrf::init(config()); let syst = pac::CorePeripherals::take().unwrap().SYST; - let delay: &'static SharedDelay = make_static!(Mutex::new(SysTickDelay::new(syst))); + let delay: &'static SharedDelay = + make_static!(SharedDelay, Mutex::new(SysTickDelay::new(syst))); let sd = ble::init_softdevice(); spawner.must_spawn(softdevice_task(sd)); @@ -143,7 +143,7 @@ async fn main(spawner: Spawner) -> ! { let mut adc = Ads1230::new(adc_data, adc_clock, vdda_on, delay); adc.schedule_offset_calibration().await; - let ch: &MeasureCommandChannel = make_static!(Channel::new()); + let ch: &MeasureCommandChannel = make_static!(MeasureCommandChannel, Channel::new()); spawner.must_spawn(weight::task_function(ch.receiver(), adc, sd)); // Sample battery voltage while sampling to get a reading under load diff --git a/hangman/src/console/board.rs b/hangman/src/console/board.rs index 78952d6..3d5ee68 100644 --- a/hangman/src/console/board.rs +++ b/hangman/src/console/board.rs @@ -13,12 +13,11 @@ // limitations under the License. use super::{Driver, UsbDriver}; -use crate::Irqs; +use crate::{make_static, Irqs}; use embassy_nrf::peripherals::USBD; use embassy_nrf::usb::vbus_detect::SoftwareVbusDetect; use embassy_usb::class::cdc_acm::{CdcAcmClass, State}; use embassy_usb::UsbDevice; -use static_cell::make_static; pub(crate) fn setup_usb( usbd: USBD, @@ -55,13 +54,16 @@ pub(crate) fn setup_usb( control_buf: [u8; 64], serial_state: State<'static>, } - let res: &mut Resources = make_static!(Resources { - device_descriptor: [0; 256], - config_descriptor: [0; 256], - bos_descriptor: [0; 256], - control_buf: [0; 64], - serial_state: State::new(), - }); + let res: &mut Resources = make_static!( + Resources, + Resources { + device_descriptor: [0; 256], + config_descriptor: [0; 256], + bos_descriptor: [0; 256], + control_buf: [0; 64], + serial_state: State::new(), + } + ); // Create embassy-usb DeviceBuilder using the driver and config. let mut builder = embassy_usb::Builder::new( diff --git a/hangman/src/lib.rs b/hangman/src/lib.rs index afd1a6b..604f066 100644 --- a/hangman/src/lib.rs +++ b/hangman/src/lib.rs @@ -55,3 +55,15 @@ pub type MeasureCommandChannel = pub const MEASURE_COMMAND_CHANNEL_SIZE: usize = 5; pub type MeasureCommandReceiver = Receiver<'static, NoopRawMutex, weight::Command, MEASURE_COMMAND_CHANNEL_SIZE>; + +/// Re-implementation of static_cell::make_static, which is broken on latest nightly +/// https://github.com/embassy-rs/static-cell/issues/16 +#[macro_export] +macro_rules! make_static { + ($t:ty, $val:expr) => ($crate::make_static!($t, $val,)); + ($t:ty, $val:expr, $(#[$m:meta])*) => {{ + $(#[$m])* + static STATIC_CELL: static_cell::StaticCell<$t> = static_cell::StaticCell::new(); + STATIC_CELL.init_with(|| $val) + }}; +} diff --git a/hangman/src/weight/task.rs b/hangman/src/weight/task.rs index 6ea7523..f75d923 100644 --- a/hangman/src/weight/task.rs +++ b/hangman/src/weight/task.rs @@ -19,14 +19,12 @@ use super::Ads1230; #[cfg(feature = "nrf52840")] use super::Hx711; use super::{average, median::Median, Command, RawReading, Sample, SampleProducerMut, SampleType}; -use crate::nonvolatile::Nvm; -use crate::MeasureCommandReceiver; +use crate::{make_static, nonvolatile::Nvm, 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; const THREAD_SLEEP_DELAY: Duration = Duration::from_millis(100); @@ -174,15 +172,18 @@ async fn measure(context: &mut MeasurementContext) { #[embassy_executor::task] pub async fn task_function(rx: MeasureCommandReceiver, adc: Adc, sd: &'static Softdevice) { defmt::debug!("Starting measurement task"); - let adc: &SharedAdc = make_static!(Mutex::new(adc)); - let median: &'static SharedFilteredAdc = make_static!(Mutex::new(Median::new(adc))); + let adc: &SharedAdc = make_static!(SharedAdc, Mutex::new(adc)); + let median: &'static SharedFilteredAdc = + make_static!(SharedFilteredAdc, Mutex::new(Median::new(adc))); let nvm = Nvm::new(sd); let cal_m = nvm.read_cal_m(); let cal_b = nvm.read_cal_b(); defmt::info!("Loaded calibration: m={=f32} b={=i32}", cal_m, cal_b); - let calibrator: &SharedCalibrator = - make_static!(Mutex::new(Calibrator::new(median, cal_m, cal_b))); + let calibrator: &SharedCalibrator = make_static!( + SharedCalibrator, + Mutex::new(Calibrator::new(median, cal_m, cal_b)) + ); let tarer = Tarer::new(calibrator); let mut context = MeasurementContext {