Merge #254
254: I2C: Add support for all of Tock's I2C capsules r=jrvanwhy a=alistair23
Tock actually has two I2C capsules, this PR adds support for both in libtock-rs.
Co-authored-by: Alistair Francis <alistair.francis@wdc.com>
diff --git a/src/drivers.rs b/src/drivers.rs
index 7df124b..8604691 100644
--- a/src/drivers.rs
+++ b/src/drivers.rs
@@ -4,7 +4,8 @@
use crate::ctap::CtapDriverFactory;
use crate::gpio::GpioDriverFactory;
use crate::hmac::HmacDriverFactory;
-use crate::i2c::I2cDriverFactory;
+use crate::i2c_master::I2cDriverFactory;
+use crate::i2c_master_slave::I2cMSDriverFactory;
use crate::leds::LedsDriverFactory;
use crate::result::OtherError;
use crate::result::TockError;
@@ -31,6 +32,7 @@
pub temperature: TemperatureDriverFactory,
pub buttons: ButtonsDriverFactory,
pub adc: AdcDriverFactory,
+ pub i2c_ms: I2cMSDriverFactory,
pub i2c: I2cDriverFactory,
pub rng: RngDriver,
pub ble_advertising: BleAdvertisingDriverFactory,
@@ -79,6 +81,7 @@
},
gpio: GpioDriverFactory,
hmac: HmacDriverFactory,
+ i2c_ms: I2cMSDriverFactory,
i2c: I2cDriverFactory,
temperature: TemperatureDriverFactory,
rng: RngDriver,
diff --git a/src/i2c_master.rs b/src/i2c_master.rs
new file mode 100644
index 0000000..55f2ee1
--- /dev/null
+++ b/src/i2c_master.rs
@@ -0,0 +1,112 @@
+use crate::callback::CallbackSubscription;
+use crate::callback::Consumer;
+use crate::result::TockResult;
+use crate::syscalls;
+use core::marker::PhantomData;
+use core::ops::Deref;
+use core::ops::DerefMut;
+use libtock_core::shared_memory::SharedMemory;
+
+const DRIVER_NUMBER: usize = 0x20003;
+
+pub const BUFFER_SIZE: usize = 64;
+
+mod command_nr {
+ pub const CHECK_PRESENT: usize = 0;
+ pub const WRITE: usize = 1;
+ pub const READ: usize = 2;
+ pub const WRITE_READ: usize = 3;
+}
+
+mod subscribe_nr {
+ pub const SUBSCRIBE_CALLBACK: usize = 1;
+}
+
+mod allow_nr {
+ pub const BUFFER: usize = 1;
+}
+
+#[non_exhaustive]
+pub struct I2cDriverFactory;
+
+impl I2cDriverFactory {
+ pub fn init_driver(&mut self) -> TockResult<I2cDriver> {
+ let i2c = I2cDriver {
+ lifetime: PhantomData,
+ };
+ Ok(i2c)
+ }
+}
+
+struct I2cEventConsumer;
+
+impl<CB: FnMut(usize, usize)> Consumer<CB> for I2cEventConsumer {
+ fn consume(callback: &mut CB, _: usize, _: usize, _: usize) {
+ callback(0, 0);
+ }
+}
+
+pub struct I2cBuffer {
+ buffer: [u8; BUFFER_SIZE],
+}
+
+impl Default for I2cBuffer {
+ fn default() -> Self {
+ I2cBuffer {
+ buffer: [0; BUFFER_SIZE],
+ }
+ }
+}
+
+impl Deref for I2cBuffer {
+ type Target = [u8; BUFFER_SIZE];
+
+ fn deref(&self) -> &Self::Target {
+ &self.buffer
+ }
+}
+
+impl DerefMut for I2cBuffer {
+ fn deref_mut(&mut self) -> &mut Self::Target {
+ &mut self.buffer
+ }
+}
+
+pub struct I2cDriver<'a> {
+ lifetime: PhantomData<&'a ()>,
+}
+
+impl<'a> I2cDriver<'a> {
+ pub fn init_buffer(&self, buffer: &'a mut I2cBuffer) -> TockResult<SharedMemory> {
+ syscalls::allow(DRIVER_NUMBER, allow_nr::BUFFER, &mut buffer.buffer).map_err(Into::into)
+ }
+
+ pub fn subscribe<CB: FnMut(usize, usize)>(
+ &self,
+ callback: &'a mut CB,
+ ) -> TockResult<CallbackSubscription> {
+ syscalls::subscribe::<I2cEventConsumer, _>(
+ DRIVER_NUMBER,
+ subscribe_nr::SUBSCRIBE_CALLBACK,
+ callback,
+ )
+ .map_err(Into::into)
+ }
+
+ pub fn check_present(&self) -> TockResult<usize> {
+ syscalls::command(DRIVER_NUMBER, command_nr::CHECK_PRESENT, 0, 0).map_err(Into::into)
+ }
+
+ pub fn write(&self, address: usize, length: usize) -> TockResult<usize> {
+ syscalls::command(DRIVER_NUMBER, command_nr::WRITE, address, length).map_err(Into::into)
+ }
+
+ pub fn read(&self, address: usize, length: usize) -> TockResult<usize> {
+ syscalls::command(DRIVER_NUMBER, command_nr::READ, address, length).map_err(Into::into)
+ }
+
+ pub fn write_read(&self, address: usize, length: usize) -> TockResult<usize> {
+ syscalls::command(DRIVER_NUMBER, command_nr::WRITE_READ, address, length)
+ .map_err(Into::into)
+ }
+}
diff --git a/src/i2c.rs b/src/i2c_master_slave.rs
similarity index 80%
rename from src/i2c.rs
rename to src/i2c_master_slave.rs
index 8256af8..0e3cce6 100644
--- a/src/i2c.rs
+++ b/src/i2c_master_slave.rs
@@ -35,38 +35,38 @@
}
#[non_exhaustive]
-pub struct I2cDriverFactory;
+pub struct I2cMSDriverFactory;
-impl I2cDriverFactory {
- pub fn init_driver(&mut self) -> TockResult<I2cDriver> {
- let i2c = I2cDriver {
+impl I2cMSDriverFactory {
+ pub fn init_driver(&mut self) -> TockResult<I2cMSDriver> {
+ let i2c_ms = I2cMSDriver {
lifetime: PhantomData,
};
- Ok(i2c)
+ Ok(i2c_ms)
}
}
-struct I2cEventConsumer;
+struct I2cMSEventConsumer;
-impl<CB: FnMut(usize, usize)> Consumer<CB> for I2cEventConsumer {
+impl<CB: FnMut(usize, usize)> Consumer<CB> for I2cMSEventConsumer {
fn consume(callback: &mut CB, _: usize, _: usize, _: usize) {
callback(0, 0);
}
}
-pub struct I2cMasterWriteBuffer {
+pub struct I2cMSMasterWriteBuffer {
buffer: [u8; MASTER_BUFFER_SIZE],
}
-impl Default for I2cMasterWriteBuffer {
+impl Default for I2cMSMasterWriteBuffer {
fn default() -> Self {
- I2cMasterWriteBuffer {
+ I2cMSMasterWriteBuffer {
buffer: [0; MASTER_BUFFER_SIZE],
}
}
}
-impl Deref for I2cMasterWriteBuffer {
+impl Deref for I2cMSMasterWriteBuffer {
type Target = [u8; MASTER_BUFFER_SIZE];
fn deref(&self) -> &Self::Target {
@@ -74,25 +74,25 @@
}
}
-impl DerefMut for I2cMasterWriteBuffer {
+impl DerefMut for I2cMSMasterWriteBuffer {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.buffer
}
}
-pub struct I2cMasterReadBuffer {
+pub struct I2cMSMasterReadBuffer {
buffer: [u8; MASTER_BUFFER_SIZE],
}
-impl Default for I2cMasterReadBuffer {
+impl Default for I2cMSMasterReadBuffer {
fn default() -> Self {
- I2cMasterReadBuffer {
+ I2cMSMasterReadBuffer {
buffer: [0; MASTER_BUFFER_SIZE],
}
}
}
-impl Deref for I2cMasterReadBuffer {
+impl Deref for I2cMSMasterReadBuffer {
type Target = [u8; MASTER_BUFFER_SIZE];
fn deref(&self) -> &Self::Target {
@@ -100,25 +100,25 @@
}
}
-impl DerefMut for I2cMasterReadBuffer {
+impl DerefMut for I2cMSMasterReadBuffer {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.buffer
}
}
-pub struct I2cSlaveReadBuffer {
+pub struct I2cMSSlaveReadBuffer {
buffer: [u8; SLAVE_BUFFER_SIZE],
}
-impl Default for I2cSlaveReadBuffer {
+impl Default for I2cMSSlaveReadBuffer {
fn default() -> Self {
- I2cSlaveReadBuffer {
+ I2cMSSlaveReadBuffer {
buffer: [0; SLAVE_BUFFER_SIZE],
}
}
}
-impl Deref for I2cSlaveReadBuffer {
+impl Deref for I2cMSSlaveReadBuffer {
type Target = [u8; SLAVE_BUFFER_SIZE];
fn deref(&self) -> &Self::Target {
@@ -126,25 +126,25 @@
}
}
-impl DerefMut for I2cSlaveReadBuffer {
+impl DerefMut for I2cMSSlaveReadBuffer {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.buffer
}
}
-pub struct I2cSlaveWriteBuffer {
+pub struct I2cMSSlaveWriteBuffer {
buffer: [u8; SLAVE_BUFFER_SIZE],
}
-impl Default for I2cSlaveWriteBuffer {
+impl Default for I2cMSSlaveWriteBuffer {
fn default() -> Self {
- I2cSlaveWriteBuffer {
+ I2cMSSlaveWriteBuffer {
buffer: [0; SLAVE_BUFFER_SIZE],
}
}
}
-impl Deref for I2cSlaveWriteBuffer {
+impl Deref for I2cMSSlaveWriteBuffer {
type Target = [u8; SLAVE_BUFFER_SIZE];
fn deref(&self) -> &Self::Target {
@@ -152,20 +152,20 @@
}
}
-impl DerefMut for I2cSlaveWriteBuffer {
+impl DerefMut for I2cMSSlaveWriteBuffer {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.buffer
}
}
-pub struct I2cDriver<'a> {
+pub struct I2cMSDriver<'a> {
lifetime: PhantomData<&'a ()>,
}
-impl<'a> I2cDriver<'a> {
+impl<'a> I2cMSDriver<'a> {
pub fn init_master_write_buffer(
&self,
- buffer: &'a mut I2cMasterWriteBuffer,
+ buffer: &'a mut I2cMSMasterWriteBuffer,
) -> TockResult<SharedMemory> {
syscalls::allow(DRIVER_NUMBER, allow_nr::MASTER_WRIE, &mut buffer.buffer)
.map_err(Into::into)
@@ -173,7 +173,7 @@
pub fn init_master_read_buffer(
&self,
- buffer: &'a mut I2cMasterReadBuffer,
+ buffer: &'a mut I2cMSMasterReadBuffer,
) -> TockResult<SharedMemory> {
syscalls::allow(DRIVER_NUMBER, allow_nr::MASTER_READ, &mut buffer.buffer)
.map_err(Into::into)
@@ -181,14 +181,14 @@
pub fn init_slave_read_buffer(
&self,
- buffer: &'a mut I2cSlaveReadBuffer,
+ buffer: &'a mut I2cMSSlaveReadBuffer,
) -> TockResult<SharedMemory> {
syscalls::allow(DRIVER_NUMBER, allow_nr::SLAVE_READ, &mut buffer.buffer).map_err(Into::into)
}
pub fn init_slave_write_buffer(
&self,
- buffer: &'a mut I2cSlaveWriteBuffer,
+ buffer: &'a mut I2cMSSlaveWriteBuffer,
) -> TockResult<SharedMemory> {
syscalls::allow(DRIVER_NUMBER, allow_nr::SLAVE_WRITE, &mut buffer.buffer)
.map_err(Into::into)
@@ -198,7 +198,7 @@
&self,
callback: &'a mut CB,
) -> TockResult<CallbackSubscription> {
- syscalls::subscribe::<I2cEventConsumer, _>(
+ syscalls::subscribe::<I2cMSEventConsumer, _>(
DRIVER_NUMBER,
subscribe_nr::SUBSCRIBE_CALLBACK,
callback,
diff --git a/src/lib.rs b/src/lib.rs
index 619c379..6f5be5a 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -13,7 +13,8 @@
pub mod futures;
pub mod gpio;
pub mod hmac;
-pub mod i2c;
+pub mod i2c_master;
+pub mod i2c_master_slave;
pub mod leds;
pub mod result;
pub mod rng;