blob: 0e3cce68a5016bb5e83b4e7174a9cfa6631301db [file] [log] [blame]
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 = 0x20006;
pub const MASTER_BUFFER_SIZE: usize = 32;
pub const SLAVE_BUFFER_SIZE: usize = 32;
mod command_nr {
pub const CHECK_PRESENT: usize = 0;
pub const MASTER_WRITE: usize = 1;
pub const MASTER_READ: usize = 2;
pub const SLAVE_LISTEN: usize = 3;
pub const SLAVE_ENABLE_READ: usize = 4;
pub const SLAVE_STOP_LISTEN: usize = 5;
pub const SLAVE_SET_ADDRESS: usize = 6;
pub const MASTER_WRITE_READ: usize = 7;
}
mod subscribe_nr {
pub const SUBSCRIBE_CALLBACK: usize = 0;
}
mod allow_nr {
pub const MASTER_WRIE: usize = 0;
pub const MASTER_READ: usize = 1;
pub const SLAVE_READ: usize = 2;
pub const SLAVE_WRITE: usize = 2;
}
#[non_exhaustive]
pub struct I2cMSDriverFactory;
impl I2cMSDriverFactory {
pub fn init_driver(&mut self) -> TockResult<I2cMSDriver> {
let i2c_ms = I2cMSDriver {
lifetime: PhantomData,
};
Ok(i2c_ms)
}
}
struct I2cMSEventConsumer;
impl<CB: FnMut(usize, usize)> Consumer<CB> for I2cMSEventConsumer {
fn consume(callback: &mut CB, _: usize, _: usize, _: usize) {
callback(0, 0);
}
}
pub struct I2cMSMasterWriteBuffer {
buffer: [u8; MASTER_BUFFER_SIZE],
}
impl Default for I2cMSMasterWriteBuffer {
fn default() -> Self {
I2cMSMasterWriteBuffer {
buffer: [0; MASTER_BUFFER_SIZE],
}
}
}
impl Deref for I2cMSMasterWriteBuffer {
type Target = [u8; MASTER_BUFFER_SIZE];
fn deref(&self) -> &Self::Target {
&self.buffer
}
}
impl DerefMut for I2cMSMasterWriteBuffer {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.buffer
}
}
pub struct I2cMSMasterReadBuffer {
buffer: [u8; MASTER_BUFFER_SIZE],
}
impl Default for I2cMSMasterReadBuffer {
fn default() -> Self {
I2cMSMasterReadBuffer {
buffer: [0; MASTER_BUFFER_SIZE],
}
}
}
impl Deref for I2cMSMasterReadBuffer {
type Target = [u8; MASTER_BUFFER_SIZE];
fn deref(&self) -> &Self::Target {
&self.buffer
}
}
impl DerefMut for I2cMSMasterReadBuffer {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.buffer
}
}
pub struct I2cMSSlaveReadBuffer {
buffer: [u8; SLAVE_BUFFER_SIZE],
}
impl Default for I2cMSSlaveReadBuffer {
fn default() -> Self {
I2cMSSlaveReadBuffer {
buffer: [0; SLAVE_BUFFER_SIZE],
}
}
}
impl Deref for I2cMSSlaveReadBuffer {
type Target = [u8; SLAVE_BUFFER_SIZE];
fn deref(&self) -> &Self::Target {
&self.buffer
}
}
impl DerefMut for I2cMSSlaveReadBuffer {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.buffer
}
}
pub struct I2cMSSlaveWriteBuffer {
buffer: [u8; SLAVE_BUFFER_SIZE],
}
impl Default for I2cMSSlaveWriteBuffer {
fn default() -> Self {
I2cMSSlaveWriteBuffer {
buffer: [0; SLAVE_BUFFER_SIZE],
}
}
}
impl Deref for I2cMSSlaveWriteBuffer {
type Target = [u8; SLAVE_BUFFER_SIZE];
fn deref(&self) -> &Self::Target {
&self.buffer
}
}
impl DerefMut for I2cMSSlaveWriteBuffer {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.buffer
}
}
pub struct I2cMSDriver<'a> {
lifetime: PhantomData<&'a ()>,
}
impl<'a> I2cMSDriver<'a> {
pub fn init_master_write_buffer(
&self,
buffer: &'a mut I2cMSMasterWriteBuffer,
) -> TockResult<SharedMemory> {
syscalls::allow(DRIVER_NUMBER, allow_nr::MASTER_WRIE, &mut buffer.buffer)
.map_err(Into::into)
}
pub fn init_master_read_buffer(
&self,
buffer: &'a mut I2cMSMasterReadBuffer,
) -> TockResult<SharedMemory> {
syscalls::allow(DRIVER_NUMBER, allow_nr::MASTER_READ, &mut buffer.buffer)
.map_err(Into::into)
}
pub fn init_slave_read_buffer(
&self,
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 I2cMSSlaveWriteBuffer,
) -> TockResult<SharedMemory> {
syscalls::allow(DRIVER_NUMBER, allow_nr::SLAVE_WRITE, &mut buffer.buffer)
.map_err(Into::into)
}
pub fn subscribe<CB: FnMut(usize, usize)>(
&self,
callback: &'a mut CB,
) -> TockResult<CallbackSubscription> {
syscalls::subscribe::<I2cMSEventConsumer, _>(
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 master_write(&self, address: usize, length: usize) -> TockResult<usize> {
syscalls::command(
DRIVER_NUMBER,
command_nr::MASTER_WRITE,
address & 0xFFFF | length << 16,
0,
)
.map_err(Into::into)
}
pub fn master_read(&self, address: usize, length: usize) -> TockResult<usize> {
syscalls::command(
DRIVER_NUMBER,
command_nr::MASTER_READ,
address & 0xFFFF | length << 16,
0,
)
.map_err(Into::into)
}
pub fn slave_listen(&self) -> TockResult<usize> {
syscalls::command(DRIVER_NUMBER, command_nr::SLAVE_LISTEN, 0, 0).map_err(Into::into)
}
pub fn slave_enable_read(&self) -> TockResult<usize> {
syscalls::command(DRIVER_NUMBER, command_nr::SLAVE_ENABLE_READ, 0, 0).map_err(Into::into)
}
pub fn slave_stop_listen(&self) -> TockResult<usize> {
syscalls::command(DRIVER_NUMBER, command_nr::SLAVE_STOP_LISTEN, 0, 0).map_err(Into::into)
}
pub fn slave_set_address(&self, address: usize) -> TockResult<usize> {
syscalls::command(DRIVER_NUMBER, command_nr::SLAVE_SET_ADDRESS, address, 0)
.map_err(Into::into)
}
pub fn master_write_read(
&self,
address: usize,
read_length: usize,
write_length: usize,
) -> TockResult<usize> {
syscalls::command(
DRIVER_NUMBER,
command_nr::MASTER_WRITE_READ,
address & 0xFF | read_length << 8 | write_length << 16,
0,
)
.map_err(Into::into)
}
}