Remove SubscribableCallback from ADC driver
diff --git a/CHANGELOG.md b/CHANGELOG.md index 0524df2..0ab5997 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md
@@ -20,6 +20,7 @@ - Buttons - GPIO - Temperature + - ADC (partially) - The timer API now supports concurrent sleep operations ### Syscalls
diff --git a/examples/adc.rs b/examples/adc.rs index ef100a3..2304889 100644 --- a/examples/adc.rs +++ b/examples/adc.rs
@@ -8,23 +8,25 @@ #[libtock::main] async fn main() -> TockResult<()> { let Drivers { - console_driver, + mut adc_driver_factory, timer_context, - adc_driver, + console_driver, .. } = libtock::retrieve_drivers()?; + let adc_driver = adc_driver_factory.init_driver()?; let mut driver = timer_context.create_timer_driver(); let timer_driver = driver.activate()?; let mut console = console_driver.create_console(); - let mut with_callback = adc_driver.with_callback(|channel: usize, value: usize| { - writeln!(console, "channel: {}, value: {}", channel, value).unwrap(); - }); - let adc = with_callback.init()?; + let mut callback = |channel, value| { + writeln!(console, "channel: {}, value: {}", channel, value).unwrap(); + }; + + let _subscription = adc_driver.subscribe(&mut callback)?; loop { - adc.sample(0)?; + adc_driver.sample(0)?; timer_driver.sleep(Duration::from_ms(2000)).await?; } }
diff --git a/examples/adc_buffer.rs b/examples/adc_buffer.rs index b948b93..d06f356 100644 --- a/examples/adc_buffer.rs +++ b/examples/adc_buffer.rs
@@ -10,25 +10,28 @@ /// Reads a 128 byte sample into a buffer and prints the first value to the console. async fn main() -> TockResult<()> { let Drivers { + mut adc_driver_factory, console_driver, - adc_driver, .. } = libtock::retrieve_drivers()?; + + let adc_driver = adc_driver_factory.init_driver()?; let mut console = console_driver.create_console(); + let mut adc_buffer = AdcBuffer::default(); let mut temp_buffer = [0; libtock::adc::BUFFER_SIZE]; - let adc_buffer = libtock::adc::Adc::init_buffer(&mut adc_buffer)?; + let adc_buffer = adc_driver.init_buffer(&mut adc_buffer)?; - let mut with_callback = adc_driver.with_callback(|_, _| { + let mut callback = |_, _| { adc_buffer.read_bytes(&mut temp_buffer[..]); writeln!(console, "First sample in buffer: {}", temp_buffer[0]).unwrap(); - }); + }; - let adc = with_callback.init()?; + let _subscription = adc_driver.subscribe(&mut callback)?; loop { - adc.sample_continuous_buffered(0, 128)?; + adc_driver.sample_continuous_buffered(0, 128)?; unsafe { syscalls::raw::yieldk() }; } }
diff --git a/src/adc.rs b/src/adc.rs index 23b7f86..7d351df 100644 --- a/src/adc.rs +++ b/src/adc.rs
@@ -1,9 +1,11 @@ -use crate::callback::{CallbackSubscription, SubscribableCallback}; +use crate::callback::CallbackSubscription; +use crate::callback::Consumer; use crate::result::TockResult; use crate::shared_memory::SharedMemory; use crate::syscalls; +use core::marker::PhantomData; -pub const DRIVER_NUM: usize = 0x0005; +pub const DRIVER_NUMBER: usize = 0x0005; pub const BUFFER_SIZE: usize = 128; mod command_nr { @@ -25,11 +27,16 @@ } #[non_exhaustive] -pub struct AdcDriver; +pub struct AdcDriverFactory; -impl AdcDriver { - pub fn with_callback<CB>(self, callback: CB) -> WithCallback<CB> { - WithCallback { callback } +impl AdcDriverFactory { + pub fn init_driver(&mut self) -> TockResult<Adc> { + let adc = Adc { + // num_channels + num_channels: syscalls::command(DRIVER_NUMBER, command_nr::COUNT, 0, 0)?, + lifetime: PhantomData, + }; + Ok(adc) } } @@ -47,66 +54,61 @@ } pub struct Adc<'a> { - count: usize, - #[allow(dead_code)] // Used in drop - subscription: CallbackSubscription<'a>, + num_channels: usize, + lifetime: PhantomData<&'a ()>, } -pub struct WithCallback<CB> { - callback: CB, -} +struct AdcEventConsumer; -impl<CB: FnMut(usize, usize)> SubscribableCallback for WithCallback<CB> { - fn call_rust(&mut self, _: usize, channel: usize, value: usize) { - (self.callback)(channel, value); - } -} - -impl<CB: FnMut(usize, usize)> WithCallback<CB> { - pub fn init(&mut self) -> TockResult<Adc> { - let adc = Adc { - count: syscalls::command(DRIVER_NUM, command_nr::COUNT, 0, 0)?, - subscription: syscalls::subscribe_cb( - DRIVER_NUM, - subscribe_nr::SUBSCRIBE_CALLBACK, - self, - )?, - }; - Ok(adc) +impl<CB: FnMut(usize, usize)> Consumer<CB> for AdcEventConsumer { + fn consume(data: &mut CB, _: usize, channel: usize, value: usize) { + data(channel, value); } } impl<'a> Adc<'a> { - pub fn init_buffer(buffer: &'a mut AdcBuffer) -> TockResult<SharedMemory> { - syscalls::allow(DRIVER_NUM, allow_nr::BUFFER, &mut buffer.buffer).map_err(Into::into) + pub fn init_buffer(&self, buffer: &'a mut AdcBuffer) -> TockResult<SharedMemory> { + syscalls::allow(DRIVER_NUMBER, allow_nr::BUFFER, &mut buffer.buffer).map_err(Into::into) } - pub fn init_alt_buffer(alt_buffer: &'a mut AdcBuffer) -> TockResult<SharedMemory> { - syscalls::allow(DRIVER_NUM, allow_nr::BUFFER_ALT, &mut alt_buffer.buffer) + pub fn init_alt_buffer(&self, alt_buffer: &'a mut AdcBuffer) -> TockResult<SharedMemory> { + syscalls::allow(DRIVER_NUMBER, allow_nr::BUFFER_ALT, &mut alt_buffer.buffer) .map_err(Into::into) } /// Return the number of available channels pub fn count(&self) -> usize { - self.count + self.num_channels + } + + pub fn subscribe<CB: FnMut(usize, usize)>( + &self, + callback: &'a mut CB, + ) -> TockResult<CallbackSubscription> { + syscalls::subscribe::<AdcEventConsumer, _>( + DRIVER_NUMBER, + subscribe_nr::SUBSCRIBE_CALLBACK, + callback, + ) + .map_err(Into::into) } /// Start a single sample of channel pub fn sample(&self, channel: usize) -> TockResult<()> { - syscalls::command(DRIVER_NUM, command_nr::START, channel, 0)?; + syscalls::command(DRIVER_NUMBER, command_nr::START, channel, 0)?; Ok(()) } /// Start continuous sampling of channel pub fn sample_continuous(&self, channel: usize) -> TockResult<()> { - syscalls::command(DRIVER_NUM, command_nr::START_REPEAT, channel, 0)?; + syscalls::command(DRIVER_NUMBER, command_nr::START_REPEAT, channel, 0)?; Ok(()) } /// Start continuous sampling to first buffer pub fn sample_continuous_buffered(&self, channel: usize, frequency: usize) -> TockResult<()> { syscalls::command( - DRIVER_NUM, + DRIVER_NUMBER, command_nr::START_REPEAT_BUFFER, channel, frequency, @@ -121,7 +123,7 @@ frequency: usize, ) -> TockResult<()> { syscalls::command( - DRIVER_NUM, + DRIVER_NUMBER, command_nr::START_REPEAT_BUFFER_ALT, channel, frequency, @@ -131,7 +133,7 @@ /// Stop any started sampling operation pub fn stop(&self) -> TockResult<()> { - syscalls::command(DRIVER_NUM, command_nr::STOP, 0, 0)?; + syscalls::command(DRIVER_NUMBER, command_nr::STOP, 0, 0)?; Ok(()) } }
diff --git a/src/drivers.rs b/src/drivers.rs index b25addf..b7c9845 100644 --- a/src/drivers.rs +++ b/src/drivers.rs
@@ -1,4 +1,4 @@ -use crate::adc::AdcDriver; +use crate::adc::AdcDriverFactory; use crate::buttons::ButtonsDriverFactory; use crate::console::ConsoleDriver; use crate::gpio::GpioDriverFactory; @@ -26,7 +26,7 @@ pub gpio_driver_factory: GpioDriverFactory, pub temperature_driver_factory: TemperatureDriverFactory, pub buttons_driver_factory: ButtonsDriverFactory, - pub adc_driver: AdcDriver, + pub adc_driver_factory: AdcDriverFactory, pub rng_driver: RngDriver, pub ble_advertising_driver: BleAdvertisingDriver, pub ble_scanning_driver: BleScanningDriver, @@ -56,7 +56,7 @@ #[allow(clippy::declare_interior_mutable_const)] const DRIVERS: Drivers = Drivers { - adc_driver: AdcDriver, + adc_driver_factory: AdcDriverFactory, ble_advertising_driver: BleAdvertisingDriver, ble_scanning_driver: BleScanningDriver, buttons_driver_factory: ButtonsDriverFactory,