forked from M-Labs/artiq
firmware: add support for moninj and kern_hwreq over DRTIO switching
This commit is contained in:
parent
1ef39a98a7
commit
ae72e3a51e
|
@ -10,9 +10,6 @@ pub use proto_artiq::drtioaux_proto::Packet;
|
||||||
// this is parametric over T because there's no impl Fail for !.
|
// this is parametric over T because there's no impl Fail for !.
|
||||||
#[derive(Fail, Debug)]
|
#[derive(Fail, Debug)]
|
||||||
pub enum Error<T> {
|
pub enum Error<T> {
|
||||||
#[fail(display = "invalid node number")]
|
|
||||||
NoRoute,
|
|
||||||
|
|
||||||
#[fail(display = "gateware reported error")]
|
#[fail(display = "gateware reported error")]
|
||||||
GatewareError,
|
GatewareError,
|
||||||
#[fail(display = "packet CRC failed")]
|
#[fail(display = "packet CRC failed")]
|
||||||
|
@ -25,6 +22,9 @@ pub enum Error<T> {
|
||||||
#[fail(display = "unexpected reply")]
|
#[fail(display = "unexpected reply")]
|
||||||
UnexpectedReply,
|
UnexpectedReply,
|
||||||
|
|
||||||
|
#[fail(display = "routing error")]
|
||||||
|
RoutingError,
|
||||||
|
|
||||||
#[fail(display = "protocol error: {}", _0)]
|
#[fail(display = "protocol error: {}", _0)]
|
||||||
Protocol(#[cause] ProtocolError<T>)
|
Protocol(#[cause] ProtocolError<T>)
|
||||||
}
|
}
|
||||||
|
@ -150,26 +150,3 @@ pub fn send_link(linkno: u8, packet: &Packet) -> Result<(), Error<!>> {
|
||||||
Ok(writer.position())
|
Ok(writer.position())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: routing
|
|
||||||
fn get_linkno(nodeno: u8) -> Result<u8, Error<!>> {
|
|
||||||
if nodeno == 0 || nodeno as usize > DRTIOAUX.len() {
|
|
||||||
return Err(Error::NoRoute)
|
|
||||||
}
|
|
||||||
Ok(nodeno - 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn recv(nodeno: u8) -> Result<Option<Packet>, Error<!>> {
|
|
||||||
let linkno = get_linkno(nodeno)?;
|
|
||||||
recv_link(linkno)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn recv_timeout(nodeno: u8, timeout_ms: Option<u64>) -> Result<Packet, Error<!>> {
|
|
||||||
let linkno = get_linkno(nodeno)?;
|
|
||||||
recv_timeout_link(linkno, timeout_ms)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn send(nodeno: u8, packet: &Packet) -> Result<(), Error<!>> {
|
|
||||||
let linkno = get_linkno(nodeno)?;
|
|
||||||
send_link(linkno, packet)
|
|
||||||
}
|
|
||||||
|
|
|
@ -33,24 +33,24 @@ pub enum Packet {
|
||||||
RoutingSetRank { rank: u8 },
|
RoutingSetRank { rank: u8 },
|
||||||
RoutingAck,
|
RoutingAck,
|
||||||
|
|
||||||
MonitorRequest { channel: u16, probe: u8 },
|
MonitorRequest { destination: u8, channel: u16, probe: u8 },
|
||||||
MonitorReply { value: u32 },
|
MonitorReply { value: u32 },
|
||||||
InjectionRequest { channel: u16, overrd: u8, value: u8 },
|
InjectionRequest { destination: u8, channel: u16, overrd: u8, value: u8 },
|
||||||
InjectionStatusRequest { channel: u16, overrd: u8 },
|
InjectionStatusRequest { destination: u8, channel: u16, overrd: u8 },
|
||||||
InjectionStatusReply { value: u8 },
|
InjectionStatusReply { value: u8 },
|
||||||
|
|
||||||
I2cStartRequest { busno: u8 },
|
I2cStartRequest { destination: u8, busno: u8 },
|
||||||
I2cRestartRequest { busno: u8 },
|
I2cRestartRequest { destination: u8, busno: u8 },
|
||||||
I2cStopRequest { busno: u8 },
|
I2cStopRequest { destination: u8, busno: u8 },
|
||||||
I2cWriteRequest { busno: u8, data: u8 },
|
I2cWriteRequest { destination: u8, busno: u8, data: u8 },
|
||||||
I2cWriteReply { succeeded: bool, ack: bool },
|
I2cWriteReply { succeeded: bool, ack: bool },
|
||||||
I2cReadRequest { busno: u8, ack: bool },
|
I2cReadRequest { destination: u8, busno: u8, ack: bool },
|
||||||
I2cReadReply { succeeded: bool, data: u8 },
|
I2cReadReply { succeeded: bool, data: u8 },
|
||||||
I2cBasicReply { succeeded: bool },
|
I2cBasicReply { succeeded: bool },
|
||||||
|
|
||||||
SpiSetConfigRequest { busno: u8, flags: u8, length: u8, div: u8, cs: u8 },
|
SpiSetConfigRequest { destination: u8, busno: u8, flags: u8, length: u8, div: u8, cs: u8 },
|
||||||
SpiWriteRequest { busno: u8, data: u32 },
|
SpiWriteRequest { destination: u8, busno: u8, data: u32 },
|
||||||
SpiReadRequest { busno: u8 },
|
SpiReadRequest { destination: u8, busno: u8 },
|
||||||
SpiReadReply { succeeded: bool, data: u32 },
|
SpiReadReply { succeeded: bool, data: u32 },
|
||||||
SpiBasicReply { succeeded: bool },
|
SpiBasicReply { succeeded: bool },
|
||||||
}
|
}
|
||||||
|
@ -98,6 +98,7 @@ impl Packet {
|
||||||
0x32 => Packet::RoutingAck,
|
0x32 => Packet::RoutingAck,
|
||||||
|
|
||||||
0x40 => Packet::MonitorRequest {
|
0x40 => Packet::MonitorRequest {
|
||||||
|
destination: reader.read_u8()?,
|
||||||
channel: reader.read_u16()?,
|
channel: reader.read_u16()?,
|
||||||
probe: reader.read_u8()?
|
probe: reader.read_u8()?
|
||||||
},
|
},
|
||||||
|
@ -105,11 +106,13 @@ impl Packet {
|
||||||
value: reader.read_u32()?
|
value: reader.read_u32()?
|
||||||
},
|
},
|
||||||
0x50 => Packet::InjectionRequest {
|
0x50 => Packet::InjectionRequest {
|
||||||
|
destination: reader.read_u8()?,
|
||||||
channel: reader.read_u16()?,
|
channel: reader.read_u16()?,
|
||||||
overrd: reader.read_u8()?,
|
overrd: reader.read_u8()?,
|
||||||
value: reader.read_u8()?
|
value: reader.read_u8()?
|
||||||
},
|
},
|
||||||
0x51 => Packet::InjectionStatusRequest {
|
0x51 => Packet::InjectionStatusRequest {
|
||||||
|
destination: reader.read_u8()?,
|
||||||
channel: reader.read_u16()?,
|
channel: reader.read_u16()?,
|
||||||
overrd: reader.read_u8()?
|
overrd: reader.read_u8()?
|
||||||
},
|
},
|
||||||
|
@ -118,15 +121,19 @@ impl Packet {
|
||||||
},
|
},
|
||||||
|
|
||||||
0x80 => Packet::I2cStartRequest {
|
0x80 => Packet::I2cStartRequest {
|
||||||
|
destination: reader.read_u8()?,
|
||||||
busno: reader.read_u8()?
|
busno: reader.read_u8()?
|
||||||
},
|
},
|
||||||
0x81 => Packet::I2cRestartRequest {
|
0x81 => Packet::I2cRestartRequest {
|
||||||
|
destination: reader.read_u8()?,
|
||||||
busno: reader.read_u8()?
|
busno: reader.read_u8()?
|
||||||
},
|
},
|
||||||
0x82 => Packet::I2cStopRequest {
|
0x82 => Packet::I2cStopRequest {
|
||||||
|
destination: reader.read_u8()?,
|
||||||
busno: reader.read_u8()?
|
busno: reader.read_u8()?
|
||||||
},
|
},
|
||||||
0x83 => Packet::I2cWriteRequest {
|
0x83 => Packet::I2cWriteRequest {
|
||||||
|
destination: reader.read_u8()?,
|
||||||
busno: reader.read_u8()?,
|
busno: reader.read_u8()?,
|
||||||
data: reader.read_u8()?
|
data: reader.read_u8()?
|
||||||
},
|
},
|
||||||
|
@ -135,6 +142,7 @@ impl Packet {
|
||||||
ack: reader.read_bool()?
|
ack: reader.read_bool()?
|
||||||
},
|
},
|
||||||
0x85 => Packet::I2cReadRequest {
|
0x85 => Packet::I2cReadRequest {
|
||||||
|
destination: reader.read_u8()?,
|
||||||
busno: reader.read_u8()?,
|
busno: reader.read_u8()?,
|
||||||
ack: reader.read_bool()?
|
ack: reader.read_bool()?
|
||||||
},
|
},
|
||||||
|
@ -147,6 +155,7 @@ impl Packet {
|
||||||
},
|
},
|
||||||
|
|
||||||
0x90 => Packet::SpiSetConfigRequest {
|
0x90 => Packet::SpiSetConfigRequest {
|
||||||
|
destination: reader.read_u8()?,
|
||||||
busno: reader.read_u8()?,
|
busno: reader.read_u8()?,
|
||||||
flags: reader.read_u8()?,
|
flags: reader.read_u8()?,
|
||||||
length: reader.read_u8()?,
|
length: reader.read_u8()?,
|
||||||
|
@ -155,10 +164,12 @@ impl Packet {
|
||||||
},
|
},
|
||||||
/* 0x91: was Packet::SpiSetXferRequest */
|
/* 0x91: was Packet::SpiSetXferRequest */
|
||||||
0x92 => Packet::SpiWriteRequest {
|
0x92 => Packet::SpiWriteRequest {
|
||||||
|
destination: reader.read_u8()?,
|
||||||
busno: reader.read_u8()?,
|
busno: reader.read_u8()?,
|
||||||
data: reader.read_u32()?
|
data: reader.read_u32()?
|
||||||
},
|
},
|
||||||
0x93 => Packet::SpiReadRequest {
|
0x93 => Packet::SpiReadRequest {
|
||||||
|
destination: reader.read_u8()?,
|
||||||
busno: reader.read_u8()?
|
busno: reader.read_u8()?
|
||||||
},
|
},
|
||||||
0x94 => Packet::SpiReadReply {
|
0x94 => Packet::SpiReadReply {
|
||||||
|
@ -223,8 +234,9 @@ impl Packet {
|
||||||
Packet::RoutingAck =>
|
Packet::RoutingAck =>
|
||||||
writer.write_u8(0x32)?,
|
writer.write_u8(0x32)?,
|
||||||
|
|
||||||
Packet::MonitorRequest { channel, probe } => {
|
Packet::MonitorRequest { destination, channel, probe } => {
|
||||||
writer.write_u8(0x40)?;
|
writer.write_u8(0x40)?;
|
||||||
|
writer.write_u8(destination)?;
|
||||||
writer.write_u16(channel)?;
|
writer.write_u16(channel)?;
|
||||||
writer.write_u8(probe)?;
|
writer.write_u8(probe)?;
|
||||||
},
|
},
|
||||||
|
@ -232,14 +244,16 @@ impl Packet {
|
||||||
writer.write_u8(0x41)?;
|
writer.write_u8(0x41)?;
|
||||||
writer.write_u32(value)?;
|
writer.write_u32(value)?;
|
||||||
},
|
},
|
||||||
Packet::InjectionRequest { channel, overrd, value } => {
|
Packet::InjectionRequest { destination, channel, overrd, value } => {
|
||||||
writer.write_u8(0x50)?;
|
writer.write_u8(0x50)?;
|
||||||
|
writer.write_u8(destination)?;
|
||||||
writer.write_u16(channel)?;
|
writer.write_u16(channel)?;
|
||||||
writer.write_u8(overrd)?;
|
writer.write_u8(overrd)?;
|
||||||
writer.write_u8(value)?;
|
writer.write_u8(value)?;
|
||||||
},
|
},
|
||||||
Packet::InjectionStatusRequest { channel, overrd } => {
|
Packet::InjectionStatusRequest { destination, channel, overrd } => {
|
||||||
writer.write_u8(0x51)?;
|
writer.write_u8(0x51)?;
|
||||||
|
writer.write_u8(destination)?;
|
||||||
writer.write_u16(channel)?;
|
writer.write_u16(channel)?;
|
||||||
writer.write_u8(overrd)?;
|
writer.write_u8(overrd)?;
|
||||||
},
|
},
|
||||||
|
@ -248,20 +262,24 @@ impl Packet {
|
||||||
writer.write_u8(value)?;
|
writer.write_u8(value)?;
|
||||||
},
|
},
|
||||||
|
|
||||||
Packet::I2cStartRequest { busno } => {
|
Packet::I2cStartRequest { destination, busno } => {
|
||||||
writer.write_u8(0x80)?;
|
writer.write_u8(0x80)?;
|
||||||
|
writer.write_u8(destination)?;
|
||||||
writer.write_u8(busno)?;
|
writer.write_u8(busno)?;
|
||||||
},
|
},
|
||||||
Packet::I2cRestartRequest { busno } => {
|
Packet::I2cRestartRequest { destination, busno } => {
|
||||||
writer.write_u8(0x81)?;
|
writer.write_u8(0x81)?;
|
||||||
|
writer.write_u8(destination)?;
|
||||||
writer.write_u8(busno)?;
|
writer.write_u8(busno)?;
|
||||||
},
|
},
|
||||||
Packet::I2cStopRequest { busno } => {
|
Packet::I2cStopRequest { destination, busno } => {
|
||||||
writer.write_u8(0x82)?;
|
writer.write_u8(0x82)?;
|
||||||
|
writer.write_u8(destination)?;
|
||||||
writer.write_u8(busno)?;
|
writer.write_u8(busno)?;
|
||||||
},
|
},
|
||||||
Packet::I2cWriteRequest { busno, data } => {
|
Packet::I2cWriteRequest { destination, busno, data } => {
|
||||||
writer.write_u8(0x83)?;
|
writer.write_u8(0x83)?;
|
||||||
|
writer.write_u8(destination)?;
|
||||||
writer.write_u8(busno)?;
|
writer.write_u8(busno)?;
|
||||||
writer.write_u8(data)?;
|
writer.write_u8(data)?;
|
||||||
},
|
},
|
||||||
|
@ -270,8 +288,9 @@ impl Packet {
|
||||||
writer.write_bool(succeeded)?;
|
writer.write_bool(succeeded)?;
|
||||||
writer.write_bool(ack)?;
|
writer.write_bool(ack)?;
|
||||||
},
|
},
|
||||||
Packet::I2cReadRequest { busno, ack } => {
|
Packet::I2cReadRequest { destination, busno, ack } => {
|
||||||
writer.write_u8(0x85)?;
|
writer.write_u8(0x85)?;
|
||||||
|
writer.write_u8(destination)?;
|
||||||
writer.write_u8(busno)?;
|
writer.write_u8(busno)?;
|
||||||
writer.write_bool(ack)?;
|
writer.write_bool(ack)?;
|
||||||
},
|
},
|
||||||
|
@ -285,21 +304,24 @@ impl Packet {
|
||||||
writer.write_bool(succeeded)?;
|
writer.write_bool(succeeded)?;
|
||||||
},
|
},
|
||||||
|
|
||||||
Packet::SpiSetConfigRequest { busno, flags, length, div, cs } => {
|
Packet::SpiSetConfigRequest { destination, busno, flags, length, div, cs } => {
|
||||||
writer.write_u8(0x90)?;
|
writer.write_u8(0x90)?;
|
||||||
|
writer.write_u8(destination)?;
|
||||||
writer.write_u8(busno)?;
|
writer.write_u8(busno)?;
|
||||||
writer.write_u8(flags)?;
|
writer.write_u8(flags)?;
|
||||||
writer.write_u8(length)?;
|
writer.write_u8(length)?;
|
||||||
writer.write_u8(div)?;
|
writer.write_u8(div)?;
|
||||||
writer.write_u8(cs)?;
|
writer.write_u8(cs)?;
|
||||||
},
|
},
|
||||||
Packet::SpiWriteRequest { busno, data } => {
|
Packet::SpiWriteRequest { destination, busno, data } => {
|
||||||
writer.write_u8(0x92)?;
|
writer.write_u8(0x92)?;
|
||||||
|
writer.write_u8(destination)?;
|
||||||
writer.write_u8(busno)?;
|
writer.write_u8(busno)?;
|
||||||
writer.write_u32(data)?;
|
writer.write_u32(data)?;
|
||||||
},
|
},
|
||||||
Packet::SpiReadRequest { busno } => {
|
Packet::SpiReadRequest { destination, busno } => {
|
||||||
writer.write_u8(0x93)?;
|
writer.write_u8(0x93)?;
|
||||||
|
writer.write_u8(destination)?;
|
||||||
writer.write_u8(busno)?;
|
writer.write_u8(busno)?;
|
||||||
},
|
},
|
||||||
Packet::SpiReadReply { succeeded, data } => {
|
Packet::SpiReadReply { succeeded, data } => {
|
||||||
|
|
|
@ -2,13 +2,16 @@ use kernel_proto as kern;
|
||||||
use sched::{Io, Error as SchedError};
|
use sched::{Io, Error as SchedError};
|
||||||
use session::{kern_acknowledge, kern_send, Error};
|
use session::{kern_acknowledge, kern_send, Error};
|
||||||
use rtio_mgt;
|
use rtio_mgt;
|
||||||
|
use board_artiq::drtio_routing;
|
||||||
|
use board_artiq::i2c as local_i2c;
|
||||||
|
use board_artiq::spi as local_spi;
|
||||||
|
|
||||||
#[cfg(has_drtio)]
|
#[cfg(has_drtio)]
|
||||||
mod drtio_i2c {
|
mod remote_i2c {
|
||||||
use drtioaux;
|
use drtioaux;
|
||||||
|
|
||||||
fn basic_reply(nodeno: u8) -> Result<(), ()> {
|
fn basic_reply(linkno: u8) -> Result<(), ()> {
|
||||||
match drtioaux::recv_timeout(nodeno, None) {
|
match drtioaux::recv_timeout_link(linkno, None) {
|
||||||
Ok(drtioaux::Packet::I2cBasicReply { succeeded }) => {
|
Ok(drtioaux::Packet::I2cBasicReply { succeeded }) => {
|
||||||
if succeeded { Ok(()) } else { Err(()) }
|
if succeeded { Ok(()) } else { Err(()) }
|
||||||
}
|
}
|
||||||
|
@ -23,39 +26,49 @@ mod drtio_i2c {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn start(nodeno: u8, busno: u8) -> Result<(), ()> {
|
pub fn start(linkno: u8, destination: u8, busno: u8) -> Result<(), ()> {
|
||||||
let request = drtioaux::Packet::I2cStartRequest { busno: busno };
|
let request = drtioaux::Packet::I2cStartRequest {
|
||||||
if drtioaux::send(nodeno, &request).is_err() {
|
destination: destination,
|
||||||
|
busno: busno
|
||||||
|
};
|
||||||
|
if drtioaux::send_link(linkno, &request).is_err() {
|
||||||
return Err(())
|
return Err(())
|
||||||
}
|
}
|
||||||
basic_reply(nodeno)
|
basic_reply(linkno)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn restart(nodeno: u8, busno: u8) -> Result<(), ()> {
|
pub fn restart(linkno: u8, destination: u8, busno: u8) -> Result<(), ()> {
|
||||||
let request = drtioaux::Packet::I2cRestartRequest { busno: busno };
|
let request = drtioaux::Packet::I2cRestartRequest {
|
||||||
if drtioaux::send(nodeno, &request).is_err() {
|
destination: destination,
|
||||||
|
busno: busno
|
||||||
|
};
|
||||||
|
if drtioaux::send_link(linkno, &request).is_err() {
|
||||||
return Err(())
|
return Err(())
|
||||||
}
|
}
|
||||||
basic_reply(nodeno)
|
basic_reply(linkno)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn stop(nodeno: u8, busno: u8) -> Result<(), ()> {
|
pub fn stop(linkno: u8, destination: u8, busno: u8) -> Result<(), ()> {
|
||||||
let request = drtioaux::Packet::I2cStopRequest { busno: busno };
|
let request = drtioaux::Packet::I2cStopRequest {
|
||||||
if drtioaux::send(nodeno, &request).is_err() {
|
destination: destination,
|
||||||
|
busno: busno
|
||||||
|
};
|
||||||
|
if drtioaux::send_link(linkno, &request).is_err() {
|
||||||
return Err(())
|
return Err(())
|
||||||
}
|
}
|
||||||
basic_reply(nodeno)
|
basic_reply(linkno)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn write(nodeno: u8, busno: u8, data: u8) -> Result<bool, ()> {
|
pub fn write(linkno: u8, destination: u8, busno: u8, data: u8) -> Result<bool, ()> {
|
||||||
let request = drtioaux::Packet::I2cWriteRequest {
|
let request = drtioaux::Packet::I2cWriteRequest {
|
||||||
|
destination: destination,
|
||||||
busno: busno,
|
busno: busno,
|
||||||
data: data
|
data: data
|
||||||
};
|
};
|
||||||
if drtioaux::send(nodeno, &request).is_err() {
|
if drtioaux::send_link(linkno, &request).is_err() {
|
||||||
return Err(())
|
return Err(())
|
||||||
}
|
}
|
||||||
match drtioaux::recv_timeout(nodeno, None) {
|
match drtioaux::recv_timeout_link(linkno, None) {
|
||||||
Ok(drtioaux::Packet::I2cWriteReply { succeeded, ack }) => {
|
Ok(drtioaux::Packet::I2cWriteReply { succeeded, ack }) => {
|
||||||
if succeeded { Ok(ack) } else { Err(()) }
|
if succeeded { Ok(ack) } else { Err(()) }
|
||||||
}
|
}
|
||||||
|
@ -70,15 +83,16 @@ mod drtio_i2c {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn read(nodeno: u8, busno: u8, ack: bool) -> Result<u8, ()> {
|
pub fn read(linkno: u8, destination: u8, busno: u8, ack: bool) -> Result<u8, ()> {
|
||||||
let request = drtioaux::Packet::I2cReadRequest {
|
let request = drtioaux::Packet::I2cReadRequest {
|
||||||
|
destination: destination,
|
||||||
busno: busno,
|
busno: busno,
|
||||||
ack: ack
|
ack: ack
|
||||||
};
|
};
|
||||||
if drtioaux::send(nodeno, &request).is_err() {
|
if drtioaux::send_link(linkno, &request).is_err() {
|
||||||
return Err(())
|
return Err(())
|
||||||
}
|
}
|
||||||
match drtioaux::recv_timeout(nodeno, None) {
|
match drtioaux::recv_timeout_link(linkno, None) {
|
||||||
Ok(drtioaux::Packet::I2cReadReply { succeeded, data }) => {
|
Ok(drtioaux::Packet::I2cReadReply { succeeded, data }) => {
|
||||||
if succeeded { Ok(data) } else { Err(()) }
|
if succeeded { Ok(data) } else { Err(()) }
|
||||||
}
|
}
|
||||||
|
@ -94,90 +108,12 @@ mod drtio_i2c {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(has_drtio))]
|
|
||||||
mod drtio_i2c {
|
|
||||||
pub fn start(_nodeno: u8, _busno: u8) -> Result<(), ()> {
|
|
||||||
Err(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn restart(_nodeno: u8, _busno: u8) -> Result<(), ()> {
|
|
||||||
Err(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn stop(_nodeno: u8, _busno: u8) -> Result<(), ()> {
|
|
||||||
Err(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn write(_nodeno: u8, _busno: u8, _data: u8) -> Result<bool, ()> {
|
|
||||||
Err(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn read(_nodeno: u8, _busno: u8, _ack: bool) -> Result<u8, ()> {
|
|
||||||
Err(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mod i2c {
|
|
||||||
use board_artiq::i2c as local_i2c;
|
|
||||||
use super::drtio_i2c;
|
|
||||||
|
|
||||||
pub fn start(busno: u32) -> Result<(), ()> {
|
|
||||||
let nodeno = (busno >> 16) as u8;
|
|
||||||
let node_busno = busno as u8;
|
|
||||||
if nodeno == 0 {
|
|
||||||
local_i2c::start(node_busno)
|
|
||||||
} else {
|
|
||||||
drtio_i2c::start(nodeno, node_busno)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn restart(busno: u32) -> Result<(), ()> {
|
|
||||||
let nodeno = (busno >> 16) as u8;
|
|
||||||
let node_busno = busno as u8;
|
|
||||||
if nodeno == 0 {
|
|
||||||
local_i2c::restart(node_busno)
|
|
||||||
} else {
|
|
||||||
drtio_i2c::restart(nodeno, node_busno)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn stop(busno: u32) -> Result<(), ()> {
|
|
||||||
let nodeno = (busno >> 16) as u8;
|
|
||||||
let node_busno = busno as u8;
|
|
||||||
if nodeno == 0 {
|
|
||||||
local_i2c::stop(node_busno)
|
|
||||||
} else {
|
|
||||||
drtio_i2c::stop(nodeno, node_busno)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn write(busno: u32, data: u8) -> Result<bool, ()> {
|
|
||||||
let nodeno = (busno >> 16 )as u8;
|
|
||||||
let node_busno = busno as u8;
|
|
||||||
if nodeno == 0 {
|
|
||||||
local_i2c::write(node_busno, data)
|
|
||||||
} else {
|
|
||||||
drtio_i2c::write(nodeno, node_busno, data)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn read(busno: u32, ack: bool) -> Result<u8, ()> {
|
|
||||||
let nodeno = (busno >> 16) as u8;
|
|
||||||
let node_busno = busno as u8;
|
|
||||||
if nodeno == 0 {
|
|
||||||
local_i2c::read(node_busno, ack)
|
|
||||||
} else {
|
|
||||||
drtio_i2c::read(nodeno, node_busno, ack)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(has_drtio)]
|
#[cfg(has_drtio)]
|
||||||
mod drtio_spi {
|
mod remote_spi {
|
||||||
use drtioaux;
|
use drtioaux;
|
||||||
|
|
||||||
fn basic_reply(nodeno: u8) -> Result<(), ()> {
|
fn basic_reply(linkno: u8) -> Result<(), ()> {
|
||||||
match drtioaux::recv_timeout(nodeno, None) {
|
match drtioaux::recv_timeout_link(linkno, None) {
|
||||||
Ok(drtioaux::Packet::SpiBasicReply { succeeded }) => {
|
Ok(drtioaux::Packet::SpiBasicReply { succeeded }) => {
|
||||||
if succeeded { Ok(()) } else { Err(()) }
|
if succeeded { Ok(()) } else { Err(()) }
|
||||||
}
|
}
|
||||||
|
@ -192,37 +128,42 @@ mod drtio_spi {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_config(nodeno: u8, busno: u8, flags: u8, length: u8, div: u8, cs: u8) -> Result<(), ()> {
|
pub fn set_config(linkno: u8, destination: u8, busno: u8, flags: u8, length: u8, div: u8, cs: u8) -> Result<(), ()> {
|
||||||
let request = drtioaux::Packet::SpiSetConfigRequest {
|
let request = drtioaux::Packet::SpiSetConfigRequest {
|
||||||
|
destination: destination,
|
||||||
busno: busno,
|
busno: busno,
|
||||||
flags: flags,
|
flags: flags,
|
||||||
length: length,
|
length: length,
|
||||||
div: div,
|
div: div,
|
||||||
cs: cs
|
cs: cs
|
||||||
};
|
};
|
||||||
if drtioaux::send(nodeno, &request).is_err() {
|
if drtioaux::send_link(linkno, &request).is_err() {
|
||||||
return Err(())
|
return Err(())
|
||||||
}
|
}
|
||||||
basic_reply(nodeno)
|
basic_reply(linkno)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn write(nodeno: u8, busno: u8, data: u32) -> Result<(), ()> {
|
pub fn write(linkno: u8, destination: u8, busno: u8, data: u32) -> Result<(), ()> {
|
||||||
let request = drtioaux::Packet::SpiWriteRequest {
|
let request = drtioaux::Packet::SpiWriteRequest {
|
||||||
|
destination: destination,
|
||||||
busno: busno,
|
busno: busno,
|
||||||
data: data
|
data: data
|
||||||
};
|
};
|
||||||
if drtioaux::send(nodeno, &request).is_err() {
|
if drtioaux::send_link(linkno, &request).is_err() {
|
||||||
return Err(())
|
return Err(())
|
||||||
}
|
}
|
||||||
basic_reply(nodeno)
|
basic_reply(linkno)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn read(nodeno: u8, busno: u8) -> Result<u32, ()> {
|
pub fn read(linkno: u8, destination: u8, busno: u8) -> Result<u32, ()> {
|
||||||
let request = drtioaux::Packet::SpiReadRequest { busno: busno };
|
let request = drtioaux::Packet::SpiReadRequest {
|
||||||
if drtioaux::send(nodeno, &request).is_err() {
|
destination: destination,
|
||||||
|
busno: busno
|
||||||
|
};
|
||||||
|
if drtioaux::send_link(linkno, &request).is_err() {
|
||||||
return Err(())
|
return Err(())
|
||||||
}
|
}
|
||||||
match drtioaux::recv_timeout(nodeno, None) {
|
match drtioaux::recv_timeout_link(linkno, None) {
|
||||||
Ok(drtioaux::Packet::SpiReadReply { succeeded, data }) => {
|
Ok(drtioaux::Packet::SpiReadReply { succeeded, data }) => {
|
||||||
if succeeded { Ok(data) } else { Err(()) }
|
if succeeded { Ok(data) } else { Err(()) }
|
||||||
}
|
}
|
||||||
|
@ -238,58 +179,32 @@ mod drtio_spi {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[cfg(has_drtio)]
|
||||||
|
macro_rules! dispatch {
|
||||||
|
($mod_local:ident, $mod_remote:ident, $routing_table:ident, $busno:expr, $func:ident $(, $param:expr)*) => {{
|
||||||
|
let destination = ($busno >> 16) as u8;
|
||||||
|
let busno = $busno as u8;
|
||||||
|
let hop = $routing_table.0[destination as usize][0];
|
||||||
|
if hop == 0 {
|
||||||
|
$mod_local::$func(busno, $($param, )*)
|
||||||
|
} else {
|
||||||
|
let linkno = hop - 1;
|
||||||
|
$mod_remote::$func(linkno, destination, busno, $($param, )*)
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(not(has_drtio))]
|
#[cfg(not(has_drtio))]
|
||||||
mod drtio_spi {
|
macro_rules! dispatch {
|
||||||
pub fn set_config(_nodeno: u8, _busno: u8, _flags: u8,
|
($mod_local:ident, $mod_remote:ident, $routing_table:ident, $busno:expr, $func:ident $(, $param:expr)*) => {{
|
||||||
_length: u8, _div: u8, _cs: u8) -> Result<(), ()> {
|
let busno = $busno as u8;
|
||||||
Err(())
|
$mod_local::$func(busno, $($param, )*)
|
||||||
}
|
}}
|
||||||
|
|
||||||
pub fn write(_nodeno: u8, _busno: u8, _data: u32) -> Result<(), ()> {
|
|
||||||
Err(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn read(_nodeno: u8, _busno: u8) -> Result<u32, ()> {
|
|
||||||
Err(())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mod spi {
|
pub fn process_kern_hwreq(io: &Io, _routing_table: &drtio_routing::RoutingTable,
|
||||||
use board_artiq::spi as local_spi;
|
request: &kern::Message) -> Result<bool, Error<SchedError>> {
|
||||||
use super::drtio_spi;
|
|
||||||
|
|
||||||
pub fn set_config(busno: u32, flags: u8, length: u8, div: u8, cs: u8) -> Result<(), ()> {
|
|
||||||
let nodeno = (busno >> 16) as u8;
|
|
||||||
let node_busno = busno as u8;
|
|
||||||
if nodeno == 0 {
|
|
||||||
local_spi::set_config(node_busno, flags, length, div, cs)
|
|
||||||
} else {
|
|
||||||
drtio_spi::set_config(nodeno, node_busno, flags, length, div, cs)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn write(busno: u32, data: u32) -> Result<(), ()> {
|
|
||||||
let nodeno = (busno >> 16) as u8;
|
|
||||||
let node_busno = busno as u8;
|
|
||||||
if nodeno == 0 {
|
|
||||||
local_spi::write(node_busno, data)
|
|
||||||
} else {
|
|
||||||
drtio_spi::write(nodeno, node_busno, data)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn read(busno: u32) -> Result<u32, ()> {
|
|
||||||
let nodeno = (busno >> 16) as u8;
|
|
||||||
let node_busno = busno as u8;
|
|
||||||
if nodeno == 0 {
|
|
||||||
local_spi::read(node_busno)
|
|
||||||
} else {
|
|
||||||
drtio_spi::read(nodeno, node_busno)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn process_kern_hwreq(io: &Io, request: &kern::Message) -> Result<bool, Error<SchedError>> {
|
|
||||||
match request {
|
match request {
|
||||||
&kern::RtioInitRequest => {
|
&kern::RtioInitRequest => {
|
||||||
info!("resetting RTIO");
|
info!("resetting RTIO");
|
||||||
|
@ -303,40 +218,42 @@ pub fn process_kern_hwreq(io: &Io, request: &kern::Message) -> Result<bool, Erro
|
||||||
}
|
}
|
||||||
|
|
||||||
&kern::I2cStartRequest { busno } => {
|
&kern::I2cStartRequest { busno } => {
|
||||||
let succeeded = i2c::start(busno).is_ok();
|
let succeeded = dispatch!(local_i2c, remote_i2c, _routing_table, busno, start).is_ok();
|
||||||
kern_send(io, &kern::I2cBasicReply { succeeded: succeeded })
|
kern_send(io, &kern::I2cBasicReply { succeeded: succeeded })
|
||||||
}
|
}
|
||||||
&kern::I2cRestartRequest { busno } => {
|
&kern::I2cRestartRequest { busno } => {
|
||||||
let succeeded = i2c::restart(busno).is_ok();
|
let succeeded = dispatch!(local_i2c, remote_i2c, _routing_table, busno, restart).is_ok();
|
||||||
kern_send(io, &kern::I2cBasicReply { succeeded: succeeded })
|
kern_send(io, &kern::I2cBasicReply { succeeded: succeeded })
|
||||||
}
|
}
|
||||||
&kern::I2cStopRequest { busno } => {
|
&kern::I2cStopRequest { busno } => {
|
||||||
let succeeded = i2c::stop(busno).is_ok();
|
let succeeded = dispatch!(local_i2c, remote_i2c, _routing_table, busno, stop).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 i2c::write(busno, data) {
|
match dispatch!(local_i2c, remote_i2c, _routing_table, busno, write, 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 i2c::read(busno, ack) {
|
match dispatch!(local_i2c, remote_i2c, _routing_table, busno, read, 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, length, div, cs } => {
|
&kern::SpiSetConfigRequest { busno, flags, length, div, cs } => {
|
||||||
let succeeded = spi::set_config(busno, flags, length, div, cs).is_ok();
|
let succeeded = dispatch!(local_spi, remote_spi, _routing_table, busno,
|
||||||
|
set_config, flags, length, div, cs).is_ok();
|
||||||
kern_send(io, &kern::SpiBasicReply { succeeded: succeeded })
|
kern_send(io, &kern::SpiBasicReply { succeeded: succeeded })
|
||||||
},
|
},
|
||||||
&kern::SpiWriteRequest { busno, data } => {
|
&kern::SpiWriteRequest { busno, data } => {
|
||||||
let succeeded = spi::write(busno, data).is_ok();
|
let succeeded = dispatch!(local_spi, remote_spi, _routing_table, busno,
|
||||||
|
write, data).is_ok();
|
||||||
kern_send(io, &kern::SpiBasicReply { succeeded: succeeded })
|
kern_send(io, &kern::SpiBasicReply { succeeded: succeeded })
|
||||||
}
|
}
|
||||||
&kern::SpiReadRequest { busno } => {
|
&kern::SpiReadRequest { busno } => {
|
||||||
match spi::read(busno) {
|
match dispatch!(local_spi, remote_spi, _routing_table, busno, read) {
|
||||||
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 })
|
||||||
}
|
}
|
||||||
|
|
|
@ -282,22 +282,28 @@ fn startup_ethernet() {
|
||||||
.ip_addrs([IpCidr::new(protocol_addr, 0)])
|
.ip_addrs([IpCidr::new(protocol_addr, 0)])
|
||||||
.finalize();
|
.finalize();
|
||||||
|
|
||||||
#[cfg(has_drtio_routing)]
|
#[cfg(has_drtio)]
|
||||||
let drtio_routing_table = urc::Urc::new(RefCell::new(
|
let drtio_routing_table = urc::Urc::new(RefCell::new(
|
||||||
drtio_routing::config_routing_table(csr::DRTIO.len())));
|
drtio_routing::config_routing_table(csr::DRTIO.len())));
|
||||||
|
#[cfg(not(has_drtio))]
|
||||||
|
let drtio_routing_table = urc::Urc::new(RefCell::new(
|
||||||
|
drtio_routing::RoutingTable::default_empty()));
|
||||||
|
|
||||||
let mut scheduler = sched::Scheduler::new();
|
let mut scheduler = sched::Scheduler::new();
|
||||||
let io = scheduler.io();
|
let io = scheduler.io();
|
||||||
|
|
||||||
#[cfg(has_drtio_routing)]
|
|
||||||
rtio_mgt::startup(&io, &drtio_routing_table);
|
rtio_mgt::startup(&io, &drtio_routing_table);
|
||||||
#[cfg(not(has_drtio_routing))]
|
|
||||||
rtio_mgt::startup(&io, &drtio_routing::RoutingTable::default_empty());
|
|
||||||
|
|
||||||
io.spawn(4096, mgmt::thread);
|
io.spawn(4096, mgmt::thread);
|
||||||
io.spawn(16384, session::thread);
|
{
|
||||||
|
let drtio_routing_table = drtio_routing_table.clone();
|
||||||
|
io.spawn(16384, move |io| { session::thread(io, &drtio_routing_table) });
|
||||||
|
}
|
||||||
#[cfg(any(has_rtio_moninj, has_drtio))]
|
#[cfg(any(has_rtio_moninj, has_drtio))]
|
||||||
io.spawn(4096, moninj::thread);
|
{
|
||||||
|
let drtio_routing_table = drtio_routing_table.clone();
|
||||||
|
io.spawn(4096, move |io| { moninj::thread(io, &drtio_routing_table) });
|
||||||
|
}
|
||||||
#[cfg(has_rtio_analyzer)]
|
#[cfg(has_rtio_analyzer)]
|
||||||
io.spawn(4096, analyzer::thread);
|
io.spawn(4096, analyzer::thread);
|
||||||
|
|
||||||
|
|
|
@ -1,151 +1,137 @@
|
||||||
use alloc::btree_map::BTreeMap;
|
use alloc::btree_map::BTreeMap;
|
||||||
|
use core::cell::RefCell;
|
||||||
|
|
||||||
use io::Error as IoError;
|
use io::Error as IoError;
|
||||||
use moninj_proto::*;
|
use moninj_proto::*;
|
||||||
use sched::{Io, TcpListener, TcpStream, Error as SchedError};
|
use sched::{Io, TcpListener, TcpStream, Error as SchedError};
|
||||||
use board_misoc::{clock, csr};
|
use urc::Urc;
|
||||||
#[cfg(has_drtio)]
|
use board_misoc::clock;
|
||||||
use drtioaux;
|
use board_artiq::drtio_routing;
|
||||||
|
|
||||||
#[cfg(has_rtio_moninj)]
|
#[cfg(has_rtio_moninj)]
|
||||||
fn read_probe_local(channel: u16, probe: u8) -> u32 {
|
mod local_moninj {
|
||||||
unsafe {
|
use board_misoc::csr;
|
||||||
csr::rtio_moninj::mon_chan_sel_write(channel as _);
|
|
||||||
csr::rtio_moninj::mon_probe_sel_write(probe);
|
pub fn read_probe(channel: u16, probe: u8) -> u32 {
|
||||||
csr::rtio_moninj::mon_value_update_write(1);
|
unsafe {
|
||||||
csr::rtio_moninj::mon_value_read() as u32
|
csr::rtio_moninj::mon_chan_sel_write(channel as _);
|
||||||
|
csr::rtio_moninj::mon_probe_sel_write(probe);
|
||||||
|
csr::rtio_moninj::mon_value_update_write(1);
|
||||||
|
csr::rtio_moninj::mon_value_read() as u32
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn inject(channel: u16, overrd: u8, value: u8) {
|
||||||
|
unsafe {
|
||||||
|
csr::rtio_moninj::inj_chan_sel_write(channel as _);
|
||||||
|
csr::rtio_moninj::inj_override_sel_write(overrd);
|
||||||
|
csr::rtio_moninj::inj_value_write(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn read_injection_status(channel: u16, overrd: u8) -> u8 {
|
||||||
|
unsafe {
|
||||||
|
csr::rtio_moninj::inj_chan_sel_write(channel as _);
|
||||||
|
csr::rtio_moninj::inj_override_sel_write(overrd);
|
||||||
|
csr::rtio_moninj::inj_value_read()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(has_rtio_moninj))]
|
||||||
|
mod local_moninj {
|
||||||
|
pub fn read_probe(_channel: u16, _probe: u8) -> u32 { 0 }
|
||||||
|
|
||||||
|
pub fn inject(_channel: u16, _overrd: u8, _value: u8) { }
|
||||||
|
|
||||||
|
pub fn read_injection_status(_channel: u16, _overrd: u8) -> u8 { 0 }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(has_drtio)]
|
||||||
|
mod remote_moninj {
|
||||||
|
use drtioaux;
|
||||||
|
|
||||||
|
pub fn read_probe(linkno: u8, destination: u8, channel: u16, probe: u8) -> u32 {
|
||||||
|
let request = drtioaux::Packet::MonitorRequest {
|
||||||
|
destination: destination,
|
||||||
|
channel: channel,
|
||||||
|
probe: probe
|
||||||
|
};
|
||||||
|
match drtioaux::send_link(linkno, &request) {
|
||||||
|
Ok(_) => (),
|
||||||
|
Err(e) => {
|
||||||
|
error!("aux packet error ({})", e);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
match drtioaux::recv_timeout_link(linkno, None) {
|
||||||
|
Ok(drtioaux::Packet::MonitorReply { value }) => return value,
|
||||||
|
Ok(_) => error!("received unexpected aux packet"),
|
||||||
|
Err(e) => error!("aux packet error ({})", e)
|
||||||
|
}
|
||||||
|
0
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn inject(linkno: u8, destination: u8, channel: u16, overrd: u8, value: u8) {
|
||||||
|
let request = drtioaux::Packet::InjectionRequest {
|
||||||
|
destination: destination,
|
||||||
|
channel: channel,
|
||||||
|
overrd: overrd,
|
||||||
|
value: value
|
||||||
|
};
|
||||||
|
match drtioaux::send_link(linkno, &request) {
|
||||||
|
Ok(_) => (),
|
||||||
|
Err(e) => error!("aux packet error ({})", e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn read_injection_status(linkno: u8, destination: u8, channel: u16, overrd: u8) -> u8 {
|
||||||
|
let request = drtioaux::Packet::InjectionStatusRequest {
|
||||||
|
destination: destination,
|
||||||
|
channel: channel,
|
||||||
|
overrd: overrd
|
||||||
|
};
|
||||||
|
match drtioaux::send_link(linkno, &request) {
|
||||||
|
Ok(_) => (),
|
||||||
|
Err(e) => {
|
||||||
|
error!("aux packet error ({})", e);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
match drtioaux::recv_timeout_link(linkno, None) {
|
||||||
|
Ok(drtioaux::Packet::InjectionStatusReply { value }) => return value,
|
||||||
|
Ok(_) => error!("received unexpected aux packet"),
|
||||||
|
Err(e) => error!("aux packet error ({})", e)
|
||||||
|
}
|
||||||
|
0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(has_drtio)]
|
#[cfg(has_drtio)]
|
||||||
fn read_probe_drtio(nodeno: u8, channel: u16, probe: u8) -> u32 {
|
macro_rules! dispatch {
|
||||||
let request = drtioaux::Packet::MonitorRequest { channel: channel, probe: probe };
|
($routing_table:ident, $channel:expr, $func:ident $(, $param:expr)*) => {{
|
||||||
match drtioaux::send(nodeno, &request) {
|
let destination = ($channel >> 16) as u8;
|
||||||
Ok(_) => (),
|
let channel = $channel as u16;
|
||||||
Err(e) => {
|
let hop = $routing_table.0[destination as usize][0];
|
||||||
error!("aux packet error ({})", e);
|
if hop == 0 {
|
||||||
return 0;
|
local_moninj::$func(channel, $($param, )*)
|
||||||
|
} else {
|
||||||
|
let linkno = hop - 1;
|
||||||
|
remote_moninj::$func(linkno, destination, channel, $($param, )*)
|
||||||
}
|
}
|
||||||
}
|
}}
|
||||||
match drtioaux::recv_timeout(nodeno, None) {
|
|
||||||
Ok(drtioaux::Packet::MonitorReply { value }) => return value,
|
|
||||||
Ok(_) => error!("received unexpected aux packet"),
|
|
||||||
Err(e) => error!("aux packet error ({})", e)
|
|
||||||
}
|
|
||||||
0
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_probe(channel: u32, probe: u8) -> u32 {
|
#[cfg(not(has_drtio))]
|
||||||
let nodeno = (channel >> 16) as u8;
|
macro_rules! dispatch {
|
||||||
let node_channel = channel as u16;
|
($routing_table:ident, $channel:expr, $func:ident $(, $param:expr)*) => {{
|
||||||
#[cfg(has_rtio_moninj)]
|
let channel = $channel as u8;
|
||||||
{
|
local_moninj::$func(channel, $($param, )*)
|
||||||
if nodeno == 0 {
|
}}
|
||||||
return read_probe_local(node_channel, probe)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#[cfg(has_drtio)]
|
|
||||||
{
|
|
||||||
if nodeno != 0 {
|
|
||||||
return read_probe_drtio(nodeno, node_channel, probe)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
error!("read_probe: unrecognized channel number {}", channel);
|
|
||||||
0
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(has_rtio_moninj)]
|
fn connection_worker(io: &Io, _routing_table: &drtio_routing::RoutingTable,
|
||||||
fn inject_local(channel: u16, overrd: u8, value: u8) {
|
mut stream: &mut TcpStream) -> Result<(), Error<SchedError>> {
|
||||||
unsafe {
|
|
||||||
csr::rtio_moninj::inj_chan_sel_write(channel as _);
|
|
||||||
csr::rtio_moninj::inj_override_sel_write(overrd);
|
|
||||||
csr::rtio_moninj::inj_value_write(value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(has_drtio)]
|
|
||||||
fn inject_drtio(nodeno: u8, channel: u16, overrd: u8, value: u8) {
|
|
||||||
let request = drtioaux::Packet::InjectionRequest {
|
|
||||||
channel: channel,
|
|
||||||
overrd: overrd,
|
|
||||||
value: value
|
|
||||||
};
|
|
||||||
match drtioaux::send(nodeno, &request) {
|
|
||||||
Ok(_) => (),
|
|
||||||
Err(e) => error!("aux packet error ({})", e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn inject(channel: u32, overrd: u8, value: u8) {
|
|
||||||
let nodeno = (channel >> 16) as u8;
|
|
||||||
let node_channel = channel as u16;
|
|
||||||
#[cfg(has_rtio_moninj)]
|
|
||||||
{
|
|
||||||
if nodeno == 0 {
|
|
||||||
inject_local(node_channel, overrd, value);
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#[cfg(has_drtio)]
|
|
||||||
{
|
|
||||||
if nodeno != 0 {
|
|
||||||
inject_drtio(nodeno, node_channel, overrd, value);
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
error!("inject: unrecognized channel number {}", channel);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(has_rtio_moninj)]
|
|
||||||
fn read_injection_status_local(channel: u16, overrd: u8) -> u8 {
|
|
||||||
unsafe {
|
|
||||||
csr::rtio_moninj::inj_chan_sel_write(channel as _);
|
|
||||||
csr::rtio_moninj::inj_override_sel_write(overrd);
|
|
||||||
csr::rtio_moninj::inj_value_read()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(has_drtio)]
|
|
||||||
fn read_injection_status_drtio(nodeno: u8, channel: u16, overrd: u8) -> u8 {
|
|
||||||
let request = drtioaux::Packet::InjectionStatusRequest {
|
|
||||||
channel: channel,
|
|
||||||
overrd: overrd
|
|
||||||
};
|
|
||||||
match drtioaux::send(nodeno, &request) {
|
|
||||||
Ok(_) => (),
|
|
||||||
Err(e) => {
|
|
||||||
error!("aux packet error ({})", e);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
match drtioaux::recv_timeout(nodeno, None) {
|
|
||||||
Ok(drtioaux::Packet::InjectionStatusReply { value }) => return value,
|
|
||||||
Ok(_) => error!("received unexpected aux packet"),
|
|
||||||
Err(e) => error!("aux packet error ({})", e)
|
|
||||||
}
|
|
||||||
0
|
|
||||||
}
|
|
||||||
|
|
||||||
fn read_injection_status(channel: u32, probe: u8) -> u8 {
|
|
||||||
let nodeno = (channel >> 16) as u8;
|
|
||||||
let node_channel = channel as u16;
|
|
||||||
#[cfg(has_rtio_moninj)]
|
|
||||||
{
|
|
||||||
if nodeno == 0 {
|
|
||||||
return read_injection_status_local(node_channel, probe)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#[cfg(has_drtio)]
|
|
||||||
{
|
|
||||||
if nodeno != 0 {
|
|
||||||
return read_injection_status_drtio(nodeno, node_channel, probe)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
error!("read_injection_status: unrecognized channel number {}", channel);
|
|
||||||
0
|
|
||||||
}
|
|
||||||
|
|
||||||
fn connection_worker(io: &Io, mut stream: &mut TcpStream) -> Result<(), Error<SchedError>> {
|
|
||||||
let mut probe_watch_list = BTreeMap::new();
|
let mut probe_watch_list = BTreeMap::new();
|
||||||
let mut inject_watch_list = BTreeMap::new();
|
let mut inject_watch_list = BTreeMap::new();
|
||||||
let mut next_check = 0;
|
let mut next_check = 0;
|
||||||
|
@ -173,9 +159,9 @@ fn connection_worker(io: &Io, mut stream: &mut TcpStream) -> Result<(), Error<Sc
|
||||||
let _ = inject_watch_list.remove(&(channel, overrd));
|
let _ = inject_watch_list.remove(&(channel, overrd));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
HostMessage::Inject { channel, overrd, value } => inject(channel, overrd, value),
|
HostMessage::Inject { channel, overrd, value } => dispatch!(_routing_table, channel, inject, overrd, value),
|
||||||
HostMessage::GetInjectionStatus { channel, overrd } => {
|
HostMessage::GetInjectionStatus { channel, overrd } => {
|
||||||
let value = read_injection_status(channel, overrd);
|
let value = dispatch!(_routing_table, channel, read_injection_status, overrd);
|
||||||
let reply = DeviceMessage::InjectionStatus {
|
let reply = DeviceMessage::InjectionStatus {
|
||||||
channel: channel,
|
channel: channel,
|
||||||
overrd: overrd,
|
overrd: overrd,
|
||||||
|
@ -192,7 +178,7 @@ fn connection_worker(io: &Io, mut stream: &mut TcpStream) -> Result<(), Error<Sc
|
||||||
|
|
||||||
if clock::get_ms() > next_check {
|
if clock::get_ms() > next_check {
|
||||||
for (&(channel, probe), previous) in probe_watch_list.iter_mut() {
|
for (&(channel, probe), previous) in probe_watch_list.iter_mut() {
|
||||||
let current = read_probe(channel, probe);
|
let current = dispatch!(_routing_table, channel, read_probe, probe);
|
||||||
if previous.is_none() || previous.unwrap() != current {
|
if previous.is_none() || previous.unwrap() != current {
|
||||||
let message = DeviceMessage::MonitorStatus {
|
let message = DeviceMessage::MonitorStatus {
|
||||||
channel: channel,
|
channel: channel,
|
||||||
|
@ -207,7 +193,7 @@ fn connection_worker(io: &Io, mut stream: &mut TcpStream) -> Result<(), Error<Sc
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (&(channel, overrd), previous) in inject_watch_list.iter_mut() {
|
for (&(channel, overrd), previous) in inject_watch_list.iter_mut() {
|
||||||
let current = read_injection_status(channel, overrd);
|
let current = dispatch!(_routing_table, channel, read_injection_status, overrd);
|
||||||
if previous.is_none() || previous.unwrap() != current {
|
if previous.is_none() || previous.unwrap() != current {
|
||||||
let message = DeviceMessage::InjectionStatus {
|
let message = DeviceMessage::InjectionStatus {
|
||||||
channel: channel,
|
channel: channel,
|
||||||
|
@ -228,15 +214,17 @@ fn connection_worker(io: &Io, mut stream: &mut TcpStream) -> Result<(), Error<Sc
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn thread(io: Io) {
|
pub fn thread(io: Io, routing_table: &Urc<RefCell<drtio_routing::RoutingTable>>) {
|
||||||
let listener = TcpListener::new(&io, 2047);
|
let listener = TcpListener::new(&io, 2047);
|
||||||
listener.listen(1383).expect("moninj: cannot listen");
|
listener.listen(1383).expect("moninj: cannot listen");
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
|
let routing_table = routing_table.clone();
|
||||||
let stream = listener.accept().expect("moninj: cannot accept").into_handle();
|
let stream = listener.accept().expect("moninj: cannot accept").into_handle();
|
||||||
io.spawn(16384, move |io| {
|
io.spawn(16384, move |io| {
|
||||||
|
let routing_table = routing_table.borrow();
|
||||||
let mut stream = TcpStream::from_handle(&io, stream);
|
let mut stream = TcpStream::from_handle(&io, stream);
|
||||||
match connection_worker(&io, &mut stream) {
|
match connection_worker(&io, &routing_table, &mut stream) {
|
||||||
Ok(()) => {},
|
Ok(()) => {},
|
||||||
Err(err) => error!("moninj aborted: {}", err)
|
Err(err) => error!("moninj aborted: {}", err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@ use rtio_dma::Manager as DmaManager;
|
||||||
use cache::Cache;
|
use cache::Cache;
|
||||||
use kern_hwreq;
|
use kern_hwreq;
|
||||||
use watchdog::WatchdogSet;
|
use watchdog::WatchdogSet;
|
||||||
|
use board_artiq::drtio_routing;
|
||||||
|
|
||||||
use rpc_proto as rpc;
|
use rpc_proto as rpc;
|
||||||
use session_proto as host;
|
use session_proto as host;
|
||||||
|
@ -323,7 +324,8 @@ fn process_host_message(io: &Io,
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn process_kern_message(io: &Io, mut stream: Option<&mut TcpStream>,
|
fn process_kern_message(io: &Io, routing_table: &drtio_routing::RoutingTable,
|
||||||
|
mut stream: Option<&mut TcpStream>,
|
||||||
session: &mut Session) -> Result<bool, Error<SchedError>> {
|
session: &mut Session) -> Result<bool, Error<SchedError>> {
|
||||||
kern_recv_notrace(io, |request| {
|
kern_recv_notrace(io, |request| {
|
||||||
match (request, session.kernel_state) {
|
match (request, session.kernel_state) {
|
||||||
|
@ -341,7 +343,7 @@ fn process_kern_message(io: &Io, mut stream: Option<&mut TcpStream>,
|
||||||
|
|
||||||
kern_recv_dotrace(request);
|
kern_recv_dotrace(request);
|
||||||
|
|
||||||
if kern_hwreq::process_kern_hwreq(io, request)? {
|
if kern_hwreq::process_kern_hwreq(io, routing_table, request)? {
|
||||||
return Ok(false)
|
return Ok(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -490,7 +492,7 @@ fn process_kern_queued_rpc(stream: &mut TcpStream,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn host_kernel_worker(io: &Io,
|
fn host_kernel_worker(io: &Io, routing_table: &drtio_routing::RoutingTable,
|
||||||
stream: &mut TcpStream,
|
stream: &mut TcpStream,
|
||||||
congress: &mut Congress) -> Result<(), Error<SchedError>> {
|
congress: &mut Congress) -> Result<(), Error<SchedError>> {
|
||||||
let mut session = Session::new(congress);
|
let mut session = Session::new(congress);
|
||||||
|
@ -507,7 +509,7 @@ fn host_kernel_worker(io: &Io,
|
||||||
}
|
}
|
||||||
|
|
||||||
if mailbox::receive() != 0 {
|
if mailbox::receive() != 0 {
|
||||||
process_kern_message(io, Some(stream), &mut session)?;
|
process_kern_message(io, routing_table, Some(stream), &mut session)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
if session.kernel_state == KernelState::Running {
|
if session.kernel_state == KernelState::Running {
|
||||||
|
@ -526,7 +528,7 @@ fn host_kernel_worker(io: &Io,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn flash_kernel_worker(io: &Io,
|
fn flash_kernel_worker(io: &Io, routing_table: &drtio_routing::RoutingTable,
|
||||||
congress: &mut Congress,
|
congress: &mut Congress,
|
||||||
config_key: &str) -> Result<(), Error<SchedError>> {
|
config_key: &str) -> Result<(), Error<SchedError>> {
|
||||||
let mut session = Session::new(congress);
|
let mut session = Session::new(congress);
|
||||||
|
@ -549,7 +551,7 @@ fn flash_kernel_worker(io: &Io,
|
||||||
}
|
}
|
||||||
|
|
||||||
if mailbox::receive() != 0 {
|
if mailbox::receive() != 0 {
|
||||||
if process_kern_message(io, None, &mut session)? {
|
if process_kern_message(io, routing_table, None, &mut session)? {
|
||||||
return Ok(())
|
return Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -581,7 +583,7 @@ fn respawn<F>(io: &Io, handle: &mut Option<ThreadHandle>, f: F)
|
||||||
*handle = Some(io.spawn(16384, f))
|
*handle = Some(io.spawn(16384, f))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn thread(io: Io) {
|
pub fn thread(io: Io, routing_table: &Urc<RefCell<drtio_routing::RoutingTable>>) {
|
||||||
let listener = TcpListener::new(&io, 65535);
|
let listener = TcpListener::new(&io, 65535);
|
||||||
listener.listen(1381).expect("session: cannot listen");
|
listener.listen(1381).expect("session: cannot listen");
|
||||||
info!("accepting network sessions");
|
info!("accepting network sessions");
|
||||||
|
@ -590,11 +592,13 @@ pub fn thread(io: Io) {
|
||||||
|
|
||||||
let mut kernel_thread = None;
|
let mut kernel_thread = None;
|
||||||
{
|
{
|
||||||
|
let routing_table = routing_table.clone();
|
||||||
let congress = congress.clone();
|
let congress = congress.clone();
|
||||||
respawn(&io, &mut kernel_thread, move |io| {
|
respawn(&io, &mut kernel_thread, move |io| {
|
||||||
|
let routing_table = routing_table.borrow();
|
||||||
let mut congress = congress.borrow_mut();
|
let mut congress = congress.borrow_mut();
|
||||||
info!("running startup kernel");
|
info!("running startup kernel");
|
||||||
match flash_kernel_worker(&io, &mut congress, "startup_kernel") {
|
match flash_kernel_worker(&io, &routing_table, &mut congress, "startup_kernel") {
|
||||||
Ok(()) =>
|
Ok(()) =>
|
||||||
info!("startup kernel finished"),
|
info!("startup kernel finished"),
|
||||||
Err(Error::KernelNotFound) =>
|
Err(Error::KernelNotFound) =>
|
||||||
|
@ -623,12 +627,14 @@ pub fn thread(io: Io) {
|
||||||
}
|
}
|
||||||
info!("new connection from {}", stream.remote_endpoint());
|
info!("new connection from {}", stream.remote_endpoint());
|
||||||
|
|
||||||
|
let routing_table = routing_table.clone();
|
||||||
let congress = congress.clone();
|
let congress = congress.clone();
|
||||||
let stream = stream.into_handle();
|
let stream = stream.into_handle();
|
||||||
respawn(&io, &mut kernel_thread, move |io| {
|
respawn(&io, &mut kernel_thread, move |io| {
|
||||||
|
let routing_table = routing_table.borrow();
|
||||||
let mut congress = congress.borrow_mut();
|
let mut congress = congress.borrow_mut();
|
||||||
let mut stream = TcpStream::from_handle(&io, stream);
|
let mut stream = TcpStream::from_handle(&io, stream);
|
||||||
match host_kernel_worker(&io, &mut stream, &mut *congress) {
|
match host_kernel_worker(&io, &routing_table, &mut stream, &mut *congress) {
|
||||||
Ok(()) => (),
|
Ok(()) => (),
|
||||||
Err(Error::Protocol(host::Error::Io(IoError::UnexpectedEnd))) =>
|
Err(Error::Protocol(host::Error::Io(IoError::UnexpectedEnd))) =>
|
||||||
info!("connection closed"),
|
info!("connection closed"),
|
||||||
|
@ -646,10 +652,12 @@ pub fn thread(io: Io) {
|
||||||
if kernel_thread.as_ref().map_or(true, |h| h.terminated()) {
|
if kernel_thread.as_ref().map_or(true, |h| h.terminated()) {
|
||||||
info!("no connection, starting idle kernel");
|
info!("no connection, starting idle kernel");
|
||||||
|
|
||||||
|
let routing_table = routing_table.clone();
|
||||||
let congress = congress.clone();
|
let congress = congress.clone();
|
||||||
respawn(&io, &mut kernel_thread, move |io| {
|
respawn(&io, &mut kernel_thread, move |io| {
|
||||||
|
let routing_table = routing_table.borrow();
|
||||||
let mut congress = congress.borrow_mut();
|
let mut congress = congress.borrow_mut();
|
||||||
match flash_kernel_worker(&io, &mut *congress, "idle_kernel") {
|
match flash_kernel_worker(&io, &routing_table, &mut *congress, "idle_kernel") {
|
||||||
Ok(()) =>
|
Ok(()) =>
|
||||||
info!("idle kernel finished, standing by"),
|
info!("idle kernel finished, standing by"),
|
||||||
Err(Error::Protocol(host::Error::Io(
|
Err(Error::Protocol(host::Error::Io(
|
||||||
|
|
|
@ -46,6 +46,27 @@ fn drtiosat_tsc_loaded() -> bool {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[cfg(has_drtio_routing)]
|
||||||
|
macro_rules! forward {
|
||||||
|
($routing_table:expr, $destination:expr, $rank:expr, $repeaters:expr, $packet:expr) => {{
|
||||||
|
let hop = $routing_table.0[$destination as usize][$rank as usize];
|
||||||
|
if hop != 0 {
|
||||||
|
let repno = (hop - 1) as usize;
|
||||||
|
if repno < $repeaters.len() {
|
||||||
|
return $repeaters[repno].aux_forward($packet);
|
||||||
|
} else {
|
||||||
|
return Err(drtioaux::Error::RoutingError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(has_drtio_routing))]
|
||||||
|
macro_rules! forward {
|
||||||
|
($routing_table:expr, $destination:expr, $rank:expr, $repeaters:expr, $packet:expr) => {}
|
||||||
|
}
|
||||||
|
|
||||||
fn process_aux_packet(_repeaters: &mut [repeater::Repeater],
|
fn process_aux_packet(_repeaters: &mut [repeater::Repeater],
|
||||||
_routing_table: &mut drtio_routing::RoutingTable, _rank: &mut u8,
|
_routing_table: &mut drtio_routing::RoutingTable, _rank: &mut u8,
|
||||||
packet: drtioaux::Packet) -> Result<(), drtioaux::Error<!>> {
|
packet: drtioaux::Packet) -> Result<(), drtioaux::Error<!>> {
|
||||||
|
@ -174,7 +195,8 @@ fn process_aux_packet(_repeaters: &mut [repeater::Repeater],
|
||||||
drtioaux::send_link(0, &drtioaux::Packet::RoutingAck)
|
drtioaux::send_link(0, &drtioaux::Packet::RoutingAck)
|
||||||
}
|
}
|
||||||
|
|
||||||
drtioaux::Packet::MonitorRequest { channel, probe } => {
|
drtioaux::Packet::MonitorRequest { destination, channel, probe } => {
|
||||||
|
forward!(_routing_table, destination, *_rank, _repeaters, &packet);
|
||||||
let value;
|
let value;
|
||||||
#[cfg(has_rtio_moninj)]
|
#[cfg(has_rtio_moninj)]
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -190,7 +212,8 @@ fn process_aux_packet(_repeaters: &mut [repeater::Repeater],
|
||||||
let reply = drtioaux::Packet::MonitorReply { value: value as u32 };
|
let reply = drtioaux::Packet::MonitorReply { value: value as u32 };
|
||||||
drtioaux::send_link(0, &reply)
|
drtioaux::send_link(0, &reply)
|
||||||
},
|
},
|
||||||
drtioaux::Packet::InjectionRequest { channel, overrd, value } => {
|
drtioaux::Packet::InjectionRequest { destination, channel, overrd, value } => {
|
||||||
|
forward!(_routing_table, destination, *_rank, _repeaters, &packet);
|
||||||
#[cfg(has_rtio_moninj)]
|
#[cfg(has_rtio_moninj)]
|
||||||
unsafe {
|
unsafe {
|
||||||
csr::rtio_moninj::inj_chan_sel_write(channel as _);
|
csr::rtio_moninj::inj_chan_sel_write(channel as _);
|
||||||
|
@ -199,7 +222,8 @@ fn process_aux_packet(_repeaters: &mut [repeater::Repeater],
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
},
|
},
|
||||||
drtioaux::Packet::InjectionStatusRequest { channel, overrd } => {
|
drtioaux::Packet::InjectionStatusRequest { destination, channel, overrd } => {
|
||||||
|
forward!(_routing_table, destination, *_rank, _repeaters, &packet);
|
||||||
let value;
|
let value;
|
||||||
#[cfg(has_rtio_moninj)]
|
#[cfg(has_rtio_moninj)]
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -214,19 +238,23 @@ fn process_aux_packet(_repeaters: &mut [repeater::Repeater],
|
||||||
drtioaux::send_link(0, &drtioaux::Packet::InjectionStatusReply { value: value })
|
drtioaux::send_link(0, &drtioaux::Packet::InjectionStatusReply { value: value })
|
||||||
},
|
},
|
||||||
|
|
||||||
drtioaux::Packet::I2cStartRequest { busno } => {
|
drtioaux::Packet::I2cStartRequest { destination, busno } => {
|
||||||
|
forward!(_routing_table, destination, *_rank, _repeaters, &packet);
|
||||||
let succeeded = i2c::start(busno).is_ok();
|
let succeeded = i2c::start(busno).is_ok();
|
||||||
drtioaux::send_link(0, &drtioaux::Packet::I2cBasicReply { succeeded: succeeded })
|
drtioaux::send_link(0, &drtioaux::Packet::I2cBasicReply { succeeded: succeeded })
|
||||||
}
|
}
|
||||||
drtioaux::Packet::I2cRestartRequest { busno } => {
|
drtioaux::Packet::I2cRestartRequest { destination, busno } => {
|
||||||
|
forward!(_routing_table, destination, *_rank, _repeaters, &packet);
|
||||||
let succeeded = i2c::restart(busno).is_ok();
|
let succeeded = i2c::restart(busno).is_ok();
|
||||||
drtioaux::send_link(0, &drtioaux::Packet::I2cBasicReply { succeeded: succeeded })
|
drtioaux::send_link(0, &drtioaux::Packet::I2cBasicReply { succeeded: succeeded })
|
||||||
}
|
}
|
||||||
drtioaux::Packet::I2cStopRequest { busno } => {
|
drtioaux::Packet::I2cStopRequest { destination, busno } => {
|
||||||
|
forward!(_routing_table, destination, *_rank, _repeaters, &packet);
|
||||||
let succeeded = i2c::stop(busno).is_ok();
|
let succeeded = i2c::stop(busno).is_ok();
|
||||||
drtioaux::send_link(0, &drtioaux::Packet::I2cBasicReply { succeeded: succeeded })
|
drtioaux::send_link(0, &drtioaux::Packet::I2cBasicReply { succeeded: succeeded })
|
||||||
}
|
}
|
||||||
drtioaux::Packet::I2cWriteRequest { busno, data } => {
|
drtioaux::Packet::I2cWriteRequest { destination, busno, data } => {
|
||||||
|
forward!(_routing_table, destination, *_rank, _repeaters, &packet);
|
||||||
match i2c::write(busno, data) {
|
match i2c::write(busno, data) {
|
||||||
Ok(ack) => drtioaux::send_link(0,
|
Ok(ack) => drtioaux::send_link(0,
|
||||||
&drtioaux::Packet::I2cWriteReply { succeeded: true, ack: ack }),
|
&drtioaux::Packet::I2cWriteReply { succeeded: true, ack: ack }),
|
||||||
|
@ -234,7 +262,8 @@ fn process_aux_packet(_repeaters: &mut [repeater::Repeater],
|
||||||
&drtioaux::Packet::I2cWriteReply { succeeded: false, ack: false })
|
&drtioaux::Packet::I2cWriteReply { succeeded: false, ack: false })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
drtioaux::Packet::I2cReadRequest { busno, ack } => {
|
drtioaux::Packet::I2cReadRequest { destination, busno, ack } => {
|
||||||
|
forward!(_routing_table, destination, *_rank, _repeaters, &packet);
|
||||||
match i2c::read(busno, ack) {
|
match i2c::read(busno, ack) {
|
||||||
Ok(data) => drtioaux::send_link(0,
|
Ok(data) => drtioaux::send_link(0,
|
||||||
&drtioaux::Packet::I2cReadReply { succeeded: true, data: data }),
|
&drtioaux::Packet::I2cReadReply { succeeded: true, data: data }),
|
||||||
|
@ -243,17 +272,20 @@ fn process_aux_packet(_repeaters: &mut [repeater::Repeater],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
drtioaux::Packet::SpiSetConfigRequest { busno, flags, length, div, cs } => {
|
drtioaux::Packet::SpiSetConfigRequest { destination, busno, flags, length, div, cs } => {
|
||||||
|
forward!(_routing_table, destination, *_rank, _repeaters, &packet);
|
||||||
let succeeded = spi::set_config(busno, flags, length, div, cs).is_ok();
|
let succeeded = spi::set_config(busno, flags, length, div, cs).is_ok();
|
||||||
drtioaux::send_link(0,
|
drtioaux::send_link(0,
|
||||||
&drtioaux::Packet::SpiBasicReply { succeeded: succeeded })
|
&drtioaux::Packet::SpiBasicReply { succeeded: succeeded })
|
||||||
},
|
},
|
||||||
drtioaux::Packet::SpiWriteRequest { busno, data } => {
|
drtioaux::Packet::SpiWriteRequest { destination, busno, data } => {
|
||||||
|
forward!(_routing_table, destination, *_rank, _repeaters, &packet);
|
||||||
let succeeded = spi::write(busno, data).is_ok();
|
let succeeded = spi::write(busno, data).is_ok();
|
||||||
drtioaux::send_link(0,
|
drtioaux::send_link(0,
|
||||||
&drtioaux::Packet::SpiBasicReply { succeeded: succeeded })
|
&drtioaux::Packet::SpiBasicReply { succeeded: succeeded })
|
||||||
}
|
}
|
||||||
drtioaux::Packet::SpiReadRequest { busno } => {
|
drtioaux::Packet::SpiReadRequest { destination, busno } => {
|
||||||
|
forward!(_routing_table, destination, *_rank, _repeaters, &packet);
|
||||||
match spi::read(busno) {
|
match spi::read(busno) {
|
||||||
Ok(data) => drtioaux::send_link(0,
|
Ok(data) => drtioaux::send_link(0,
|
||||||
&drtioaux::Packet::SpiReadReply { succeeded: true, data: data }),
|
&drtioaux::Packet::SpiReadReply { succeeded: true, data: data }),
|
||||||
|
|
Loading…
Reference in New Issue