mirror of https://github.com/m-labs/artiq.git
i2c: expose restart as syscall, add structure for I2C-over-DRTIO
This commit is contained in:
parent
268b7d8aaf
commit
c86029bca2
|
@ -8,6 +8,11 @@ def i2c_start(busno: TInt32) -> TNone:
|
||||||
raise NotImplementedError("syscall not simulated")
|
raise NotImplementedError("syscall not simulated")
|
||||||
|
|
||||||
|
|
||||||
|
@syscall(flags={"nounwind", "nowrite"})
|
||||||
|
def i2c_restart(busno: TInt32) -> TNone:
|
||||||
|
raise NotImplementedError("syscall not simulated")
|
||||||
|
|
||||||
|
|
||||||
@syscall(flags={"nounwind", "nowrite"})
|
@syscall(flags={"nounwind", "nowrite"})
|
||||||
def i2c_stop(busno: TInt32) -> TNone:
|
def i2c_stop(busno: TInt32) -> TNone:
|
||||||
raise NotImplementedError("syscall not simulated")
|
raise NotImplementedError("syscall not simulated")
|
||||||
|
|
|
@ -118,6 +118,7 @@ static mut API: &'static [(&'static str, *const ())] = &[
|
||||||
api!(drtio_get_fifo_space_req_count = ::rtio::drtio_dbg::get_fifo_space_req_count),
|
api!(drtio_get_fifo_space_req_count = ::rtio::drtio_dbg::get_fifo_space_req_count),
|
||||||
|
|
||||||
api!(i2c_start = ::nrt_bus::i2c::start),
|
api!(i2c_start = ::nrt_bus::i2c::start),
|
||||||
|
api!(i2c_restart = ::nrt_bus::i2c::restart),
|
||||||
api!(i2c_stop = ::nrt_bus::i2c::stop),
|
api!(i2c_stop = ::nrt_bus::i2c::stop),
|
||||||
api!(i2c_write = ::nrt_bus::i2c::write),
|
api!(i2c_write = ::nrt_bus::i2c::write),
|
||||||
api!(i2c_read = ::nrt_bus::i2c::read),
|
api!(i2c_read = ::nrt_bus::i2c::read),
|
||||||
|
|
|
@ -4,21 +4,28 @@ pub mod i2c {
|
||||||
use kernel_proto::*;
|
use kernel_proto::*;
|
||||||
|
|
||||||
pub extern fn start(busno: i32) {
|
pub extern fn start(busno: i32) {
|
||||||
send(&I2cStartRequest { busno: busno as u8 });
|
send(&I2cStartRequest { busno: busno as u32 });
|
||||||
|
recv!(&I2cBasicReply { succeeded } => if !succeeded {
|
||||||
|
raise!("I2CError", "I2C bus could not be accessed");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
pub extern fn restart(busno: i32) {
|
||||||
|
send(&I2cRestartRequest { busno: busno as u32 });
|
||||||
recv!(&I2cBasicReply { succeeded } => if !succeeded {
|
recv!(&I2cBasicReply { succeeded } => if !succeeded {
|
||||||
raise!("I2CError", "I2C bus could not be accessed");
|
raise!("I2CError", "I2C bus could not be accessed");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
pub extern fn stop(busno: i32) {
|
pub extern fn stop(busno: i32) {
|
||||||
send(&I2cStopRequest { busno: busno as u8 });
|
send(&I2cStopRequest { busno: busno as u32 });
|
||||||
recv!(&I2cBasicReply { succeeded } => if !succeeded {
|
recv!(&I2cBasicReply { succeeded } => if !succeeded {
|
||||||
raise!("I2CError", "I2C bus could not be accessed");
|
raise!("I2CError", "I2C bus could not be accessed");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
pub extern fn write(busno: i32, data: i32) -> bool {
|
pub extern fn write(busno: i32, data: i32) -> bool {
|
||||||
send(&I2cWriteRequest { busno: busno as u8, data: data as u8 });
|
send(&I2cWriteRequest { busno: busno as u32, data: data as u8 });
|
||||||
recv!(&I2cWriteReply { succeeded, ack } => {
|
recv!(&I2cWriteReply { succeeded, ack } => {
|
||||||
if !succeeded {
|
if !succeeded {
|
||||||
raise!("I2CError", "I2C bus could not be accessed");
|
raise!("I2CError", "I2C bus could not be accessed");
|
||||||
|
@ -28,7 +35,7 @@ pub mod i2c {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub extern fn read(busno: i32, ack: bool) -> i32 {
|
pub extern fn read(busno: i32, ack: bool) -> i32 {
|
||||||
send(&I2cReadRequest { busno: busno as u8, ack: ack });
|
send(&I2cReadRequest { busno: busno as u32, ack: ack });
|
||||||
recv!(&I2cReadReply { succeeded, data } => {
|
recv!(&I2cReadReply { succeeded, data } => {
|
||||||
if !succeeded {
|
if !succeeded {
|
||||||
raise!("I2CError", "I2C bus could not be accessed");
|
raise!("I2CError", "I2C bus could not be accessed");
|
||||||
|
|
|
@ -80,11 +80,12 @@ pub enum Message<'a> {
|
||||||
CachePutRequest { key: &'a str, value: &'a [i32] },
|
CachePutRequest { key: &'a str, value: &'a [i32] },
|
||||||
CachePutReply { succeeded: bool },
|
CachePutReply { succeeded: bool },
|
||||||
|
|
||||||
I2cStartRequest { busno: u8 },
|
I2cStartRequest { busno: u32 },
|
||||||
I2cStopRequest { busno: u8 },
|
I2cRestartRequest { busno: u32 },
|
||||||
I2cWriteRequest { busno: u8, data: u8 },
|
I2cStopRequest { busno: u32 },
|
||||||
|
I2cWriteRequest { busno: u32, data: u8 },
|
||||||
I2cWriteReply { succeeded: bool, ack: bool },
|
I2cWriteReply { succeeded: bool, ack: bool },
|
||||||
I2cReadRequest { busno: u8, ack: bool },
|
I2cReadRequest { busno: u32, ack: bool },
|
||||||
I2cReadReply { succeeded: bool, data: u8 },
|
I2cReadReply { succeeded: bool, data: u8 },
|
||||||
I2cBasicReply { succeeded: bool },
|
I2cBasicReply { succeeded: bool },
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,132 @@
|
||||||
use session::{kern_acknowledge, kern_send};
|
use session::{kern_acknowledge, kern_send};
|
||||||
use rtio_mgt;
|
use rtio_mgt;
|
||||||
use board;
|
|
||||||
use kernel_proto as kern;
|
use kernel_proto as kern;
|
||||||
use std::io;
|
use std::io;
|
||||||
use sched::Io;
|
use sched::Io;
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
#[cfg(has_drtio)]
|
||||||
|
mod drtio_i2c {
|
||||||
|
pub fn start(_busno: u32) -> Result<(), ()> {
|
||||||
|
Err(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn restart(_busno: u32) -> Result<(), ()> {
|
||||||
|
Err(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn stop(_busno: u32) -> Result<(), ()> {
|
||||||
|
Err(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn write(_busno: u32, _data: u8) -> Result<bool, ()> {
|
||||||
|
Err(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn read(_busno: u32, _ack: bool) -> Result<u8, ()> {
|
||||||
|
Err(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(has_drtio))]
|
||||||
|
mod drtio_i2c {
|
||||||
|
pub fn start(_busno: u32) -> Result<(), ()> {
|
||||||
|
Err(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn restart(_busno: u32) -> Result<(), ()> {
|
||||||
|
Err(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn stop(_busno: u32) -> Result<(), ()> {
|
||||||
|
Err(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn write(_busno: u32, _data: u8) -> Result<bool, ()> {
|
||||||
|
Err(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn read(_busno: u32, _ack: bool) -> Result<u8, ()> {
|
||||||
|
Err(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mod i2c {
|
||||||
|
use board;
|
||||||
|
use super::drtio_i2c;
|
||||||
|
|
||||||
|
pub fn start(busno: u32) -> Result<(), ()> {
|
||||||
|
let drtio = busno >> 16;
|
||||||
|
let dev_busno = busno as u8;
|
||||||
|
if drtio == 0 {
|
||||||
|
board::i2c::start(dev_busno)
|
||||||
|
} else {
|
||||||
|
drtio_i2c::start(busno)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn restart(busno: u32) -> Result<(), ()> {
|
||||||
|
let drtio = busno >> 16;
|
||||||
|
let dev_busno = busno as u8;
|
||||||
|
if drtio == 0 {
|
||||||
|
board::i2c::restart(dev_busno)
|
||||||
|
} else {
|
||||||
|
drtio_i2c::restart(busno)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn stop(busno: u32) -> Result<(), ()> {
|
||||||
|
let drtio = busno >> 16;
|
||||||
|
let dev_busno = busno as u8;
|
||||||
|
if drtio == 0 {
|
||||||
|
board::i2c::stop(dev_busno)
|
||||||
|
} else {
|
||||||
|
drtio_i2c::stop(busno)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn write(busno: u32, data: u8) -> Result<bool, ()> {
|
||||||
|
let drtio = busno >> 16;
|
||||||
|
let dev_busno = busno as u8;
|
||||||
|
if drtio == 0 {
|
||||||
|
board::i2c::write(dev_busno, data)
|
||||||
|
} else {
|
||||||
|
drtio_i2c::write(busno, data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn read(busno: u32, ack: bool) -> Result<u8, ()> {
|
||||||
|
let drtio = busno >> 16;
|
||||||
|
let dev_busno = busno as u8;
|
||||||
|
if drtio == 0 {
|
||||||
|
board::i2c::read(dev_busno, ack)
|
||||||
|
} else {
|
||||||
|
drtio_i2c::read(busno, ack)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
#[cfg(has_drtio)]
|
||||||
|
mod drtio_spi {
|
||||||
|
pub fn set_config(_busno: u32, _flags: u8, _write_div: u8, _read_div: u8) -> Result<(), ()> {
|
||||||
|
Err(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_xfer(_busno: u32, _chip_select: u16, _write_length: u8, _read_length: u8) -> Result<(), ()> {
|
||||||
|
Err(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn write(_busno: u32, _data: u32) -> Result<(), ()> {
|
||||||
|
Err(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn read(_busno: u32) -> Result<u32, ()> {
|
||||||
|
Err(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(has_drtio))]
|
||||||
mod drtio_spi {
|
mod drtio_spi {
|
||||||
pub fn set_config(_busno: u32, _flags: u8, _write_div: u8, _read_div: u8) -> Result<(), ()> {
|
pub fn set_config(_busno: u32, _flags: u8, _write_div: u8, _read_div: u8) -> Result<(), ()> {
|
||||||
Err(())
|
Err(())
|
||||||
|
@ -99,25 +221,29 @@ pub fn process_kern_hwreq(io: &Io, request: &kern::Message) -> io::Result<bool>
|
||||||
}
|
}
|
||||||
|
|
||||||
&kern::I2cStartRequest { busno } => {
|
&kern::I2cStartRequest { busno } => {
|
||||||
let succeeded = board::i2c::start(busno).is_ok();
|
let succeeded = i2c::start(busno).is_ok();
|
||||||
|
kern_send(io, &kern::I2cBasicReply { succeeded: succeeded })
|
||||||
|
}
|
||||||
|
&kern::I2cRestartRequest { busno } => {
|
||||||
|
let succeeded = i2c::restart(busno).is_ok();
|
||||||
kern_send(io, &kern::I2cBasicReply { succeeded: succeeded })
|
kern_send(io, &kern::I2cBasicReply { succeeded: succeeded })
|
||||||
}
|
}
|
||||||
&kern::I2cStopRequest { busno } => {
|
&kern::I2cStopRequest { busno } => {
|
||||||
let succeeded = board::i2c::stop(busno).is_ok();
|
let succeeded = i2c::stop(busno).is_ok();
|
||||||
kern_send(io, &kern::I2cBasicReply { succeeded: succeeded })
|
kern_send(io, &kern::I2cBasicReply { succeeded: succeeded })
|
||||||
}
|
}
|
||||||
&kern::I2cWriteRequest { busno, data } => {
|
&kern::I2cWriteRequest { busno, data } => {
|
||||||
match board::i2c::write(busno, data) {
|
match i2c::write(busno, data) {
|
||||||
Ok(ack) => kern_send(io, &kern::I2cWriteReply { succeeded: true, ack: ack }),
|
Ok(ack) => kern_send(io, &kern::I2cWriteReply { succeeded: true, ack: ack }),
|
||||||
Err(_) => kern_send(io, &kern::I2cWriteReply { succeeded: false, ack: false })
|
Err(_) => kern_send(io, &kern::I2cWriteReply { succeeded: false, ack: false })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
&kern::I2cReadRequest { busno, ack } => {
|
&kern::I2cReadRequest { busno, ack } => {
|
||||||
match board::i2c::read(busno, ack) {
|
match i2c::read(busno, ack) {
|
||||||
Ok(data) => kern_send(io, &kern::I2cReadReply { succeeded: true, data: data }),
|
Ok(data) => kern_send(io, &kern::I2cReadReply { succeeded: true, data: data }),
|
||||||
Err(_) => kern_send(io, &kern::I2cReadReply { succeeded: false, data: 0xff })
|
Err(_) => kern_send(io, &kern::I2cReadReply { succeeded: false, data: 0xff })
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
|
|
||||||
&kern::SpiSetConfigRequest { busno, flags, write_div, read_div } => {
|
&kern::SpiSetConfigRequest { busno, flags, write_div, read_div } => {
|
||||||
let succeeded = spi::set_config(busno, flags, write_div, read_div).is_ok();
|
let succeeded = spi::set_config(busno, flags, write_div, read_div).is_ok();
|
||||||
|
@ -136,7 +262,7 @@ pub fn process_kern_hwreq(io: &Io, request: &kern::Message) -> io::Result<bool>
|
||||||
Ok(data) => kern_send(io, &kern::SpiReadReply { succeeded: true, data: data }),
|
Ok(data) => kern_send(io, &kern::SpiReadReply { succeeded: true, data: data }),
|
||||||
Err(_) => kern_send(io, &kern::SpiReadReply { succeeded: false, data: 0 })
|
Err(_) => kern_send(io, &kern::SpiReadReply { succeeded: false, data: 0 })
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
|
|
||||||
_ => return Ok(false)
|
_ => return Ok(false)
|
||||||
}.and(Ok(true))
|
}.and(Ok(true))
|
||||||
|
|
Loading…
Reference in New Issue