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,