forked from M-Labs/artiq
libdrtioaux: do not attempt to access non-existent DRTIO gateware
This commit is contained in:
parent
257527629a
commit
016743f079
artiq/firmware
@ -2,6 +2,7 @@
|
|||||||
authors = ["M-Labs"]
|
authors = ["M-Labs"]
|
||||||
name = "drtioaux"
|
name = "drtioaux"
|
||||||
version = "0.0.0"
|
version = "0.0.0"
|
||||||
|
build = "build.rs"
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
name = "drtioaux"
|
name = "drtioaux"
|
||||||
|
15
artiq/firmware/libdrtioaux/build.rs
Normal file
15
artiq/firmware/libdrtioaux/build.rs
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
use std::env;
|
||||||
|
use std::path::Path;
|
||||||
|
use std::io::{BufRead, BufReader};
|
||||||
|
use std::fs::File;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let out_dir = env::var("BUILDINC_DIRECTORY").unwrap();
|
||||||
|
let cfg_path = Path::new(&out_dir).join("generated").join("rust-cfg");
|
||||||
|
println!("cargo:rerun-if-changed={}", cfg_path.to_str().unwrap());
|
||||||
|
|
||||||
|
let f = BufReader::new(File::open(&cfg_path).unwrap());
|
||||||
|
for line in f.lines() {
|
||||||
|
println!("cargo:rustc-cfg={}", line.unwrap());
|
||||||
|
}
|
||||||
|
}
|
@ -10,7 +10,7 @@ extern crate byteorder;
|
|||||||
mod proto;
|
mod proto;
|
||||||
mod crc32;
|
mod crc32;
|
||||||
|
|
||||||
use std::io::{self, Cursor, Read, Write};
|
use std::io::{self, Read, Write};
|
||||||
use core::slice;
|
use core::slice;
|
||||||
use proto::*;
|
use proto::*;
|
||||||
|
|
||||||
@ -40,108 +40,114 @@ impl Packet {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const AUX_TX_BASE: usize = board::mem::DRTIO_AUX_BASE;
|
#[cfg(has_drtio)]
|
||||||
const AUX_TX_SIZE: usize = board::mem::DRTIO_AUX_SIZE/2;
|
pub mod hw {
|
||||||
const AUX_RX_BASE: usize = AUX_TX_BASE + AUX_TX_SIZE;
|
use super::*;
|
||||||
|
use std::io::Cursor;
|
||||||
|
|
||||||
fn rx_has_error() -> bool {
|
const AUX_TX_BASE: usize = board::mem::DRTIO_AUX_BASE;
|
||||||
unsafe {
|
const AUX_TX_SIZE: usize = board::mem::DRTIO_AUX_SIZE/2;
|
||||||
let error = board::csr::drtio::aux_rx_error_read() != 0;
|
const AUX_RX_BASE: usize = AUX_TX_BASE + AUX_TX_SIZE;
|
||||||
if error {
|
|
||||||
board::csr::drtio::aux_rx_error_write(1)
|
|
||||||
}
|
|
||||||
error
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct RxBuffer(&'static [u8]);
|
fn rx_has_error() -> bool {
|
||||||
|
|
||||||
impl Drop for RxBuffer {
|
|
||||||
fn drop(&mut self) {
|
|
||||||
unsafe {
|
unsafe {
|
||||||
board::csr::drtio::aux_rx_present_write(1);
|
let error = board::csr::drtio::aux_rx_error_read() != 0;
|
||||||
|
if error {
|
||||||
|
board::csr::drtio::aux_rx_error_write(1)
|
||||||
|
}
|
||||||
|
error
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
fn rx_get_buffer() -> Option<RxBuffer> {
|
struct RxBuffer(&'static [u8]);
|
||||||
unsafe {
|
|
||||||
if board::csr::drtio::aux_rx_present_read() == 1 {
|
|
||||||
let length = board::csr::drtio::aux_rx_length_read();
|
|
||||||
let sl = slice::from_raw_parts(AUX_RX_BASE as *mut u8, length as usize);
|
|
||||||
Some(RxBuffer(sl))
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn recv_packet() -> io::Result<Option<Packet>> {
|
impl Drop for RxBuffer {
|
||||||
if rx_has_error() {
|
fn drop(&mut self) {
|
||||||
return Err(io::Error::new(io::ErrorKind::Other, "gateware reported error"))
|
unsafe {
|
||||||
}
|
board::csr::drtio::aux_rx_present_write(1);
|
||||||
let buffer = rx_get_buffer();
|
|
||||||
match buffer {
|
|
||||||
Some(rxb) => {
|
|
||||||
let slice = rxb.0;
|
|
||||||
let mut reader = Cursor::new(slice);
|
|
||||||
|
|
||||||
let len = slice.len();
|
|
||||||
if len < 8 {
|
|
||||||
return Err(io::Error::new(io::ErrorKind::InvalidData, "packet too short"))
|
|
||||||
}
|
|
||||||
let computed_crc = crc32::checksum_ieee(&reader.get_ref()[0..len-4]);
|
|
||||||
reader.set_position((len-4) as u64);
|
|
||||||
let crc = read_u32(&mut reader)?;
|
|
||||||
if crc != computed_crc {
|
|
||||||
return Err(io::Error::new(io::ErrorKind::InvalidData, "packet CRC failed"))
|
|
||||||
}
|
|
||||||
reader.set_position(0);
|
|
||||||
|
|
||||||
let packet_r = Packet::read_from(&mut reader);
|
|
||||||
match packet_r {
|
|
||||||
Ok(packet) => Ok(Some(packet)),
|
|
||||||
Err(e) => Err(e)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None => Ok(None)
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
fn tx_get_buffer() -> &'static mut [u8] {
|
fn rx_get_buffer() -> Option<RxBuffer> {
|
||||||
unsafe {
|
unsafe {
|
||||||
while board::csr::drtio::aux_tx_read() != 0 {}
|
if board::csr::drtio::aux_rx_present_read() == 1 {
|
||||||
slice::from_raw_parts_mut(AUX_TX_BASE as *mut u8, AUX_TX_SIZE)
|
let length = board::csr::drtio::aux_rx_length_read();
|
||||||
}
|
let sl = slice::from_raw_parts(AUX_RX_BASE as *mut u8, length as usize);
|
||||||
}
|
Some(RxBuffer(sl))
|
||||||
|
} else {
|
||||||
fn tx_ack_buffer(length: u16) {
|
None
|
||||||
unsafe {
|
}
|
||||||
board::csr::drtio::aux_tx_length_write(length);
|
|
||||||
board::csr::drtio::aux_tx_write(1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn send_packet(packet: &Packet) -> io::Result<()> {
|
|
||||||
let sl = tx_get_buffer();
|
|
||||||
|
|
||||||
let mut writer = Cursor::new(sl);
|
|
||||||
packet.write_to(&mut writer)?;
|
|
||||||
let mut len = writer.position();
|
|
||||||
|
|
||||||
let padding = 4 - (len % 4);
|
|
||||||
if padding != 4 {
|
|
||||||
for _ in 0..padding {
|
|
||||||
write_u8(&mut writer, 0)?;
|
|
||||||
}
|
}
|
||||||
len += padding;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let crc = crc32::checksum_ieee(&writer.get_ref()[0..len as usize]);
|
pub fn recv() -> io::Result<Option<Packet>> {
|
||||||
write_u32(&mut writer, crc)?;
|
if rx_has_error() {
|
||||||
len += 4;
|
return Err(io::Error::new(io::ErrorKind::Other, "gateware reported error"))
|
||||||
|
}
|
||||||
|
let buffer = rx_get_buffer();
|
||||||
|
match buffer {
|
||||||
|
Some(rxb) => {
|
||||||
|
let slice = rxb.0;
|
||||||
|
let mut reader = Cursor::new(slice);
|
||||||
|
|
||||||
tx_ack_buffer(len as u16);
|
let len = slice.len();
|
||||||
|
if len < 8 {
|
||||||
|
return Err(io::Error::new(io::ErrorKind::InvalidData, "packet too short"))
|
||||||
|
}
|
||||||
|
let computed_crc = crc32::checksum_ieee(&reader.get_ref()[0..len-4]);
|
||||||
|
reader.set_position((len-4) as u64);
|
||||||
|
let crc = read_u32(&mut reader)?;
|
||||||
|
if crc != computed_crc {
|
||||||
|
return Err(io::Error::new(io::ErrorKind::InvalidData, "packet CRC failed"))
|
||||||
|
}
|
||||||
|
reader.set_position(0);
|
||||||
|
|
||||||
Ok(())
|
let packet_r = Packet::read_from(&mut reader);
|
||||||
|
match packet_r {
|
||||||
|
Ok(packet) => Ok(Some(packet)),
|
||||||
|
Err(e) => Err(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None => Ok(None)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn tx_get_buffer() -> &'static mut [u8] {
|
||||||
|
unsafe {
|
||||||
|
while board::csr::drtio::aux_tx_read() != 0 {}
|
||||||
|
slice::from_raw_parts_mut(AUX_TX_BASE as *mut u8, AUX_TX_SIZE)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn tx_ack_buffer(length: u16) {
|
||||||
|
unsafe {
|
||||||
|
board::csr::drtio::aux_tx_length_write(length);
|
||||||
|
board::csr::drtio::aux_tx_write(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn send(packet: &Packet) -> io::Result<()> {
|
||||||
|
let sl = tx_get_buffer();
|
||||||
|
|
||||||
|
let mut writer = Cursor::new(sl);
|
||||||
|
packet.write_to(&mut writer)?;
|
||||||
|
let mut len = writer.position();
|
||||||
|
|
||||||
|
let padding = 4 - (len % 4);
|
||||||
|
if padding != 4 {
|
||||||
|
for _ in 0..padding {
|
||||||
|
write_u8(&mut writer, 0)?;
|
||||||
|
}
|
||||||
|
len += padding;
|
||||||
|
}
|
||||||
|
|
||||||
|
let crc = crc32::checksum_ieee(&writer.get_ref()[0..len as usize]);
|
||||||
|
write_u32(&mut writer, crc)?;
|
||||||
|
len += 4;
|
||||||
|
|
||||||
|
tx_ack_buffer(len as u16);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -113,9 +113,9 @@ mod drtio {
|
|||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
count += 1;
|
count += 1;
|
||||||
drtioaux::send_packet(&drtioaux::Packet::EchoRequest).unwrap();
|
drtioaux::hw::send(&drtioaux::Packet::EchoRequest).unwrap();
|
||||||
io.sleep(100).unwrap();
|
io.sleep(100).unwrap();
|
||||||
let pr = drtioaux::recv_packet();
|
let pr = drtioaux::hw::recv();
|
||||||
match pr {
|
match pr {
|
||||||
Ok(Some(drtioaux::Packet::EchoReply)) => return count,
|
Ok(Some(drtioaux::Packet::EchoReply)) => return count,
|
||||||
_ => {}
|
_ => {}
|
||||||
|
@ -14,14 +14,13 @@ extern crate drtioaux;
|
|||||||
|
|
||||||
fn process_aux_packet(p: drtioaux::Packet) {
|
fn process_aux_packet(p: drtioaux::Packet) {
|
||||||
match p {
|
match p {
|
||||||
drtioaux::Packet::EchoRequest => drtioaux::send_packet(&drtioaux::Packet::EchoReply).unwrap(),
|
drtioaux::Packet::EchoRequest => drtioaux::hw::send(&drtioaux::Packet::EchoReply).unwrap(),
|
||||||
_ => warn!("received unexpected aux packet {:?}", p)
|
_ => warn!("received unexpected aux packet {:?}", p)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fn process_aux_packets() {
|
fn process_aux_packets() {
|
||||||
let pr = drtioaux::recv_packet();
|
let pr = drtioaux::hw::recv();
|
||||||
match pr {
|
match pr {
|
||||||
Ok(None) => {},
|
Ok(None) => {},
|
||||||
Ok(Some(p)) => process_aux_packet(p),
|
Ok(Some(p)) => process_aux_packet(p),
|
||||||
|
Loading…
Reference in New Issue
Block a user