mirror of https://github.com/m-labs/artiq.git
drtio: initial firmware support for multi-link
This commit is contained in:
parent
94ee48860a
commit
9045b4cc19
|
@ -1,3 +1,9 @@
|
||||||
|
"""
|
||||||
|
DRTIO debugging functions.
|
||||||
|
|
||||||
|
Those syscalls are intended for ARTIQ developers only.
|
||||||
|
"""
|
||||||
|
|
||||||
from artiq.language.core import syscall
|
from artiq.language.core import syscall
|
||||||
from artiq.language.types import TTuple, TInt32, TInt64, TNone
|
from artiq.language.types import TTuple, TInt32, TInt64, TNone
|
||||||
|
|
||||||
|
@ -18,9 +24,9 @@ def drtio_get_fifo_space(channel: TInt32) -> TNone:
|
||||||
|
|
||||||
|
|
||||||
@syscall(flags={"nounwind", "nowrite"})
|
@syscall(flags={"nounwind", "nowrite"})
|
||||||
def drtio_get_packet_counts() -> TTuple([TInt32, TInt32]):
|
def drtio_get_packet_counts(linkno: TInt32) -> TTuple([TInt32, TInt32]):
|
||||||
raise NotImplementedError("syscall not simulated")
|
raise NotImplementedError("syscall not simulated")
|
||||||
|
|
||||||
@syscall(flags={"nounwind", "nowrite"})
|
@syscall(flags={"nounwind", "nowrite"})
|
||||||
def drtio_get_fifo_space_req_count() -> TInt32:
|
def drtio_get_fifo_space_req_count(linkno: TInt32) -> TInt32:
|
||||||
raise NotImplementedError("syscall not simulated")
|
raise NotImplementedError("syscall not simulated")
|
||||||
|
|
|
@ -182,14 +182,14 @@ pub mod drtio_dbg {
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct PacketCounts(i32, i32);
|
pub struct PacketCounts(i32, i32);
|
||||||
|
|
||||||
pub extern fn get_packet_counts() -> PacketCounts {
|
pub extern fn get_packet_counts(linkno: i32) -> PacketCounts {
|
||||||
send(&DrtioPacketCountRequest);
|
send(&DrtioPacketCountRequest { linkno: linkno as u8 });
|
||||||
recv!(&DrtioPacketCountReply { tx_cnt, rx_cnt }
|
recv!(&DrtioPacketCountReply { tx_cnt, rx_cnt }
|
||||||
=> PacketCounts(tx_cnt as i32, rx_cnt as i32))
|
=> PacketCounts(tx_cnt as i32, rx_cnt as i32))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub extern fn get_fifo_space_req_count() -> i32 {
|
pub extern fn get_fifo_space_req_count(linkno: i32) -> i32 {
|
||||||
send(&DrtioFifoSpaceReqCountRequest);
|
send(&DrtioFifoSpaceReqCountRequest { linkno: linkno as u8 });
|
||||||
recv!(&DrtioFifoSpaceReqCountReply { cnt }
|
recv!(&DrtioFifoSpaceReqCountReply { cnt }
|
||||||
=> cnt as i32)
|
=> cnt as i32)
|
||||||
}
|
}
|
||||||
|
|
|
@ -252,50 +252,49 @@ pub mod hw {
|
||||||
use super::*;
|
use super::*;
|
||||||
use std::io::Cursor;
|
use std::io::Cursor;
|
||||||
|
|
||||||
const AUX_TX_BASE: usize = board::mem::DRTIO_AUX_BASE;
|
fn rx_has_error(linkno: u8) -> bool {
|
||||||
const AUX_TX_SIZE: usize = board::mem::DRTIO_AUX_SIZE/2;
|
let linkno = linkno as usize;
|
||||||
const AUX_RX_BASE: usize = AUX_TX_BASE + AUX_TX_SIZE;
|
|
||||||
|
|
||||||
fn rx_has_error() -> bool {
|
|
||||||
unsafe {
|
unsafe {
|
||||||
let error = board::csr::drtio::aux_rx_error_read() != 0;
|
let error = (board::csr::DRTIO[linkno].aux_rx_error_read)() != 0;
|
||||||
if error {
|
if error {
|
||||||
board::csr::drtio::aux_rx_error_write(1)
|
(board::csr::DRTIO[linkno].aux_rx_error_write)(1)
|
||||||
}
|
}
|
||||||
error
|
error
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct RxBuffer(&'static [u8]);
|
struct RxBuffer(u8, &'static [u8]);
|
||||||
|
|
||||||
impl Drop for RxBuffer {
|
impl Drop for RxBuffer {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
unsafe {
|
unsafe {
|
||||||
board::csr::drtio::aux_rx_present_write(1);
|
(board::csr::DRTIO[self.0 as usize].aux_rx_present_write)(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn rx_get_buffer() -> Option<RxBuffer> {
|
fn rx_get_buffer(linkno: u8) -> Option<RxBuffer> {
|
||||||
|
let linkidx = linkno as usize;
|
||||||
unsafe {
|
unsafe {
|
||||||
if board::csr::drtio::aux_rx_present_read() == 1 {
|
if (board::csr::DRTIO[linkidx].aux_rx_present_read)() == 1 {
|
||||||
let length = board::csr::drtio::aux_rx_length_read();
|
let length = (board::csr::DRTIO[linkidx].aux_rx_length_read)();
|
||||||
let sl = slice::from_raw_parts(AUX_RX_BASE as *mut u8, length as usize);
|
let base = board::mem::DRTIO_AUX[linkidx].base + board::mem::DRTIO_AUX[linkidx].size/2;
|
||||||
Some(RxBuffer(sl))
|
let sl = slice::from_raw_parts(base as *mut u8, length as usize);
|
||||||
|
Some(RxBuffer(linkno, sl))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn recv() -> io::Result<Option<Packet>> {
|
pub fn recv_link(linkno: u8) -> io::Result<Option<Packet>> {
|
||||||
if rx_has_error() {
|
if rx_has_error(linkno) {
|
||||||
return Err(io::Error::new(io::ErrorKind::Other, "gateware reported error"))
|
return Err(io::Error::new(io::ErrorKind::Other, "gateware reported error"))
|
||||||
}
|
}
|
||||||
let buffer = rx_get_buffer();
|
let buffer = rx_get_buffer(linkno);
|
||||||
match buffer {
|
match buffer {
|
||||||
Some(rxb) => {
|
Some(rxb) => {
|
||||||
let slice = rxb.0;
|
let slice = rxb.1;
|
||||||
let mut reader = Cursor::new(slice);
|
let mut reader = Cursor::new(slice);
|
||||||
|
|
||||||
let len = slice.len();
|
let len = slice.len();
|
||||||
|
@ -320,11 +319,11 @@ pub mod hw {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn recv_timeout(timeout_ms: Option<u64>) -> io::Result<Packet> {
|
pub fn recv_timeout_link(linkno: u8, timeout_ms: Option<u64>) -> io::Result<Packet> {
|
||||||
let timeout_ms = timeout_ms.unwrap_or(10);
|
let timeout_ms = timeout_ms.unwrap_or(10);
|
||||||
let limit = board::clock::get_ms() + timeout_ms;
|
let limit = board::clock::get_ms() + timeout_ms;
|
||||||
while board::clock::get_ms() < limit {
|
while board::clock::get_ms() < limit {
|
||||||
match recv() {
|
match recv_link(linkno) {
|
||||||
Ok(None) => (),
|
Ok(None) => (),
|
||||||
Ok(Some(packet)) => return Ok(packet),
|
Ok(Some(packet)) => return Ok(packet),
|
||||||
Err(e) => return Err(e)
|
Err(e) => return Err(e)
|
||||||
|
@ -333,22 +332,26 @@ pub mod hw {
|
||||||
return Err(io::Error::new(io::ErrorKind::TimedOut, "timed out waiting for data"))
|
return Err(io::Error::new(io::ErrorKind::TimedOut, "timed out waiting for data"))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn tx_get_buffer() -> &'static mut [u8] {
|
fn tx_get_buffer(linkno: u8) -> &'static mut [u8] {
|
||||||
|
let linkno = linkno as usize;
|
||||||
unsafe {
|
unsafe {
|
||||||
while board::csr::drtio::aux_tx_read() != 0 {}
|
while (board::csr::DRTIO[linkno].aux_tx_read)() != 0 {}
|
||||||
slice::from_raw_parts_mut(AUX_TX_BASE as *mut u8, AUX_TX_SIZE)
|
let base = board::mem::DRTIO_AUX[linkno].base;
|
||||||
|
let size = board::mem::DRTIO_AUX[linkno].size/2;
|
||||||
|
slice::from_raw_parts_mut(base as *mut u8, size)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn tx_ack_buffer(length: u16) {
|
fn tx_ack_buffer(linkno: u8, length: u16) {
|
||||||
|
let linkno = linkno as usize;
|
||||||
unsafe {
|
unsafe {
|
||||||
board::csr::drtio::aux_tx_length_write(length);
|
(board::csr::DRTIO[linkno].aux_tx_length_write)(length);
|
||||||
board::csr::drtio::aux_tx_write(1)
|
(board::csr::DRTIO[linkno].aux_tx_write)(1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn send(packet: &Packet) -> io::Result<()> {
|
pub fn send_link(linkno: u8, packet: &Packet) -> io::Result<()> {
|
||||||
let sl = tx_get_buffer();
|
let sl = tx_get_buffer(linkno);
|
||||||
|
|
||||||
let mut writer = Cursor::new(sl);
|
let mut writer = Cursor::new(sl);
|
||||||
packet.write_to(&mut writer)?;
|
packet.write_to(&mut writer)?;
|
||||||
|
@ -366,8 +369,31 @@ pub mod hw {
|
||||||
write_u32(&mut writer, crc)?;
|
write_u32(&mut writer, crc)?;
|
||||||
len += 4;
|
len += 4;
|
||||||
|
|
||||||
tx_ack_buffer(len as u16);
|
tx_ack_buffer(linkno, len as u16);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: routing
|
||||||
|
fn get_linkno(nodeno: u8) -> io::Result<u8> {
|
||||||
|
if nodeno == 0 || nodeno as usize > board::csr::DRTIO.len() {
|
||||||
|
return Err(io::Error::new(io::ErrorKind::NotFound, "invalid node number"))
|
||||||
|
}
|
||||||
|
Ok(nodeno - 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn recv(nodeno: u8) -> io::Result<Option<Packet>> {
|
||||||
|
let linkno = get_linkno(nodeno)?;
|
||||||
|
recv_link(linkno)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn recv_timeout(nodeno: u8, timeout_ms: Option<u64>) -> io::Result<Packet> {
|
||||||
|
let linkno = get_linkno(nodeno)?;
|
||||||
|
recv_timeout_link(linkno, timeout_ms)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn send(nodeno: u8, packet: &Packet) -> io::Result<()> {
|
||||||
|
let linkno = get_linkno(nodeno)?;
|
||||||
|
send_link(linkno, packet)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,9 +50,9 @@ pub enum Message<'a> {
|
||||||
DrtioChannelStateReply { fifo_space: u16, last_timestamp: u64 },
|
DrtioChannelStateReply { fifo_space: u16, last_timestamp: u64 },
|
||||||
DrtioResetChannelStateRequest { channel: u32 },
|
DrtioResetChannelStateRequest { channel: u32 },
|
||||||
DrtioGetFifoSpaceRequest { channel: u32 },
|
DrtioGetFifoSpaceRequest { channel: u32 },
|
||||||
DrtioPacketCountRequest,
|
DrtioPacketCountRequest { linkno: u8 },
|
||||||
DrtioPacketCountReply { tx_cnt: u32, rx_cnt: u32 },
|
DrtioPacketCountReply { tx_cnt: u32, rx_cnt: u32 },
|
||||||
DrtioFifoSpaceReqCountRequest,
|
DrtioFifoSpaceReqCountRequest { linkno: u8 },
|
||||||
DrtioFifoSpaceReqCountReply { cnt: u32 },
|
DrtioFifoSpaceReqCountReply { cnt: u32 },
|
||||||
|
|
||||||
RunFinished,
|
RunFinished,
|
||||||
|
|
|
@ -8,8 +8,8 @@ use sched::Io;
|
||||||
mod drtio_i2c {
|
mod drtio_i2c {
|
||||||
use drtioaux;
|
use drtioaux;
|
||||||
|
|
||||||
fn basic_reply() -> Result<(), ()> {
|
fn basic_reply(nodeno: u8) -> Result<(), ()> {
|
||||||
match drtioaux::hw::recv_timeout(None) {
|
match drtioaux::hw::recv_timeout(nodeno, None) {
|
||||||
Ok(drtioaux::Packet::I2cBasicReply { succeeded }) => {
|
Ok(drtioaux::Packet::I2cBasicReply { succeeded }) => {
|
||||||
if succeeded { Ok(()) } else { Err(()) }
|
if succeeded { Ok(()) } else { Err(()) }
|
||||||
}
|
}
|
||||||
|
@ -24,31 +24,39 @@ mod drtio_i2c {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn start(busno: u32) -> Result<(), ()> {
|
pub fn start(nodeno: u8, busno: u8) -> Result<(), ()> {
|
||||||
let request = drtioaux::Packet::I2cStartRequest { busno: busno as u8 };
|
let request = drtioaux::Packet::I2cStartRequest { busno: busno };
|
||||||
drtioaux::hw::send(&request).unwrap();
|
if drtioaux::hw::send(nodeno, &request).is_err() {
|
||||||
basic_reply()
|
return Err(())
|
||||||
|
}
|
||||||
|
basic_reply(nodeno)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn restart(busno: u32) -> Result<(), ()> {
|
pub fn restart(nodeno: u8, busno: u8) -> Result<(), ()> {
|
||||||
let request = drtioaux::Packet::I2cRestartRequest { busno: busno as u8 };
|
let request = drtioaux::Packet::I2cRestartRequest { busno: busno };
|
||||||
drtioaux::hw::send(&request).unwrap();
|
if drtioaux::hw::send(nodeno, &request).is_err() {
|
||||||
basic_reply()
|
return Err(())
|
||||||
|
}
|
||||||
|
basic_reply(nodeno)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn stop(busno: u32) -> Result<(), ()> {
|
pub fn stop(nodeno: u8, busno: u8) -> Result<(), ()> {
|
||||||
let request = drtioaux::Packet::I2cStopRequest { busno: busno as u8 };
|
let request = drtioaux::Packet::I2cStopRequest { busno: busno };
|
||||||
drtioaux::hw::send(&request).unwrap();
|
if drtioaux::hw::send(nodeno, &request).is_err() {
|
||||||
basic_reply()
|
return Err(())
|
||||||
|
}
|
||||||
|
basic_reply(nodeno)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn write(busno: u32, data: u8) -> Result<bool, ()> {
|
pub fn write(nodeno: u8, busno: u8, data: u8) -> Result<bool, ()> {
|
||||||
let request = drtioaux::Packet::I2cWriteRequest {
|
let request = drtioaux::Packet::I2cWriteRequest {
|
||||||
busno: busno as u8,
|
busno: busno,
|
||||||
data: data
|
data: data
|
||||||
};
|
};
|
||||||
drtioaux::hw::send(&request).unwrap();
|
if drtioaux::hw::send(nodeno, &request).is_err() {
|
||||||
match drtioaux::hw::recv_timeout(None) {
|
return Err(())
|
||||||
|
}
|
||||||
|
match drtioaux::hw::recv_timeout(nodeno, 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(()) }
|
||||||
}
|
}
|
||||||
|
@ -63,13 +71,15 @@ mod drtio_i2c {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn read(busno: u32, ack: bool) -> Result<u8, ()> {
|
pub fn read(nodeno: u8, busno: u8, ack: bool) -> Result<u8, ()> {
|
||||||
let request = drtioaux::Packet::I2cReadRequest {
|
let request = drtioaux::Packet::I2cReadRequest {
|
||||||
busno: busno as u8,
|
busno: busno,
|
||||||
ack: ack
|
ack: ack
|
||||||
};
|
};
|
||||||
drtioaux::hw::send(&request).unwrap();
|
if drtioaux::hw::send(nodeno, &request).is_err() {
|
||||||
match drtioaux::hw::recv_timeout(None) {
|
return Err(())
|
||||||
|
}
|
||||||
|
match drtioaux::hw::recv_timeout(nodeno, 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(()) }
|
||||||
}
|
}
|
||||||
|
@ -87,23 +97,23 @@ mod drtio_i2c {
|
||||||
|
|
||||||
#[cfg(not(has_drtio))]
|
#[cfg(not(has_drtio))]
|
||||||
mod drtio_i2c {
|
mod drtio_i2c {
|
||||||
pub fn start(_busno: u32) -> Result<(), ()> {
|
pub fn start(_nodeno: u8, _busno: u8) -> Result<(), ()> {
|
||||||
Err(())
|
Err(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn restart(_busno: u32) -> Result<(), ()> {
|
pub fn restart(_nodeno: u8, _busno: u8) -> Result<(), ()> {
|
||||||
Err(())
|
Err(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn stop(_busno: u32) -> Result<(), ()> {
|
pub fn stop(_nodeno: u8, _busno: u8) -> Result<(), ()> {
|
||||||
Err(())
|
Err(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn write(_busno: u32, _data: u8) -> Result<bool, ()> {
|
pub fn write(_nodeno: u8, _busno: u8, _data: u8) -> Result<bool, ()> {
|
||||||
Err(())
|
Err(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn read(_busno: u32, _ack: bool) -> Result<u8, ()> {
|
pub fn read(_nodeno: u8, _busno: u8, _ack: bool) -> Result<u8, ()> {
|
||||||
Err(())
|
Err(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -113,52 +123,52 @@ mod i2c {
|
||||||
use super::drtio_i2c;
|
use super::drtio_i2c;
|
||||||
|
|
||||||
pub fn start(busno: u32) -> Result<(), ()> {
|
pub fn start(busno: u32) -> Result<(), ()> {
|
||||||
let drtio = busno >> 16;
|
let nodeno = (busno >> 16) as u8;
|
||||||
let dev_busno = busno as u8;
|
let node_busno = busno as u8;
|
||||||
if drtio == 0 {
|
if nodeno == 0 {
|
||||||
board::i2c::start(dev_busno)
|
board::i2c::start(node_busno)
|
||||||
} else {
|
} else {
|
||||||
drtio_i2c::start(busno)
|
drtio_i2c::start(nodeno, node_busno)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn restart(busno: u32) -> Result<(), ()> {
|
pub fn restart(busno: u32) -> Result<(), ()> {
|
||||||
let drtio = busno >> 16;
|
let nodeno = (busno >> 16) as u8;
|
||||||
let dev_busno = busno as u8;
|
let node_busno = busno as u8;
|
||||||
if drtio == 0 {
|
if nodeno == 0 {
|
||||||
board::i2c::restart(dev_busno)
|
board::i2c::restart(node_busno)
|
||||||
} else {
|
} else {
|
||||||
drtio_i2c::restart(busno)
|
drtio_i2c::restart(nodeno, node_busno)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn stop(busno: u32) -> Result<(), ()> {
|
pub fn stop(busno: u32) -> Result<(), ()> {
|
||||||
let drtio = busno >> 16;
|
let nodeno = (busno >> 16) as u8;
|
||||||
let dev_busno = busno as u8;
|
let node_busno = busno as u8;
|
||||||
if drtio == 0 {
|
if nodeno == 0 {
|
||||||
board::i2c::stop(dev_busno)
|
board::i2c::stop(node_busno)
|
||||||
} else {
|
} else {
|
||||||
drtio_i2c::stop(busno)
|
drtio_i2c::stop(nodeno, node_busno)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn write(busno: u32, data: u8) -> Result<bool, ()> {
|
pub fn write(busno: u32, data: u8) -> Result<bool, ()> {
|
||||||
let drtio = busno >> 16;
|
let nodeno = (busno >> 16 )as u8;
|
||||||
let dev_busno = busno as u8;
|
let node_busno = busno as u8;
|
||||||
if drtio == 0 {
|
if nodeno == 0 {
|
||||||
board::i2c::write(dev_busno, data)
|
board::i2c::write(node_busno, data)
|
||||||
} else {
|
} else {
|
||||||
drtio_i2c::write(busno, data)
|
drtio_i2c::write(nodeno, node_busno, data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn read(busno: u32, ack: bool) -> Result<u8, ()> {
|
pub fn read(busno: u32, ack: bool) -> Result<u8, ()> {
|
||||||
let drtio = busno >> 16;
|
let nodeno = (busno >> 16) as u8;
|
||||||
let dev_busno = busno as u8;
|
let node_busno = busno as u8;
|
||||||
if drtio == 0 {
|
if nodeno == 0 {
|
||||||
board::i2c::read(dev_busno, ack)
|
board::i2c::read(node_busno, ack)
|
||||||
} else {
|
} else {
|
||||||
drtio_i2c::read(busno, ack)
|
drtio_i2c::read(nodeno, node_busno, ack)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -167,8 +177,8 @@ mod i2c {
|
||||||
mod drtio_spi {
|
mod drtio_spi {
|
||||||
use drtioaux;
|
use drtioaux;
|
||||||
|
|
||||||
fn basic_reply() -> Result<(), ()> {
|
fn basic_reply(nodeno: u8) -> Result<(), ()> {
|
||||||
match drtioaux::hw::recv_timeout(None) {
|
match drtioaux::hw::recv_timeout(nodeno, None) {
|
||||||
Ok(drtioaux::Packet::SpiBasicReply { succeeded }) => {
|
Ok(drtioaux::Packet::SpiBasicReply { succeeded }) => {
|
||||||
if succeeded { Ok(()) } else { Err(()) }
|
if succeeded { Ok(()) } else { Err(()) }
|
||||||
}
|
}
|
||||||
|
@ -183,41 +193,49 @@ mod drtio_spi {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_config(busno: u32, flags: u8, write_div: u8, read_div: u8) -> Result<(), ()> {
|
pub fn set_config(nodeno: u8, busno: u8, flags: u8, write_div: u8, read_div: u8) -> Result<(), ()> {
|
||||||
let request = drtioaux::Packet::SpiSetConfigRequest {
|
let request = drtioaux::Packet::SpiSetConfigRequest {
|
||||||
busno: busno as u8,
|
busno: busno,
|
||||||
flags: flags,
|
flags: flags,
|
||||||
write_div: write_div,
|
write_div: write_div,
|
||||||
read_div: read_div
|
read_div: read_div
|
||||||
};
|
};
|
||||||
drtioaux::hw::send(&request).unwrap();
|
if drtioaux::hw::send(nodeno, &request).is_err() {
|
||||||
basic_reply()
|
return Err(())
|
||||||
|
}
|
||||||
|
basic_reply(nodeno)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_xfer(busno: u32, chip_select: u16, write_length: u8, read_length: u8) -> Result<(), ()> {
|
pub fn set_xfer(nodeno: u8, busno: u8, chip_select: u16, write_length: u8, read_length: u8) -> Result<(), ()> {
|
||||||
let request = drtioaux::Packet::SpiSetXferRequest {
|
let request = drtioaux::Packet::SpiSetXferRequest {
|
||||||
busno: busno as u8,
|
busno: busno,
|
||||||
chip_select: chip_select,
|
chip_select: chip_select,
|
||||||
write_length: write_length,
|
write_length: write_length,
|
||||||
read_length: read_length
|
read_length: read_length
|
||||||
};
|
};
|
||||||
drtioaux::hw::send(&request).unwrap();
|
if drtioaux::hw::send(nodeno, &request).is_err() {
|
||||||
basic_reply()
|
return Err(())
|
||||||
|
}
|
||||||
|
basic_reply(nodeno)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn write(busno: u32, data: u32) -> Result<(), ()> {
|
pub fn write(nodeno: u8, busno: u8, data: u32) -> Result<(), ()> {
|
||||||
let request = drtioaux::Packet::SpiWriteRequest {
|
let request = drtioaux::Packet::SpiWriteRequest {
|
||||||
busno: busno as u8,
|
busno: busno,
|
||||||
data: data
|
data: data
|
||||||
};
|
};
|
||||||
drtioaux::hw::send(&request).unwrap();
|
if drtioaux::hw::send(nodeno, &request).is_err() {
|
||||||
basic_reply()
|
return Err(())
|
||||||
|
}
|
||||||
|
basic_reply(nodeno)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn read(busno: u32) -> Result<u32, ()> {
|
pub fn read(nodeno: u8, busno: u8) -> Result<u32, ()> {
|
||||||
let request = drtioaux::Packet::SpiReadRequest { busno: busno as u8 };
|
let request = drtioaux::Packet::SpiReadRequest { busno: busno };
|
||||||
drtioaux::hw::send(&request).unwrap();
|
if drtioaux::hw::send(nodeno, &request).is_err() {
|
||||||
match drtioaux::hw::recv_timeout(None) {
|
return Err(())
|
||||||
|
}
|
||||||
|
match drtioaux::hw::recv_timeout(nodeno, 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(()) }
|
||||||
}
|
}
|
||||||
|
@ -235,19 +253,19 @@ mod drtio_spi {
|
||||||
|
|
||||||
#[cfg(not(has_drtio))]
|
#[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(_nodeno: u8, _busno: u8, _flags: u8, _write_div: u8, _read_div: u8) -> Result<(), ()> {
|
||||||
Err(())
|
Err(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_xfer(_busno: u32, _chip_select: u16, _write_length: u8, _read_length: u8) -> Result<(), ()> {
|
pub fn set_xfer(_nodeno: u8, _busno: u8, _chip_select: u16, _write_length: u8, _read_length: u8) -> Result<(), ()> {
|
||||||
Err(())
|
Err(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn write(_busno: u32, _data: u32) -> Result<(), ()> {
|
pub fn write(_nodeno: u8, _busno: u8, _data: u32) -> Result<(), ()> {
|
||||||
Err(())
|
Err(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn read(_busno: u32) -> Result<u32, ()> {
|
pub fn read(_nodeno: u8, _busno: u8) -> Result<u32, ()> {
|
||||||
Err(())
|
Err(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -257,42 +275,42 @@ mod spi {
|
||||||
use super::drtio_spi;
|
use super::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<(), ()> {
|
||||||
let drtio = busno >> 16;
|
let nodeno = (busno >> 16) as u8;
|
||||||
let dev_busno = busno as u8;
|
let node_busno = busno as u8;
|
||||||
if drtio == 0 {
|
if nodeno == 0 {
|
||||||
board::spi::set_config(dev_busno, flags, write_div, read_div)
|
board::spi::set_config(node_busno, flags, write_div, read_div)
|
||||||
} else {
|
} else {
|
||||||
drtio_spi::set_config(busno, flags, write_div, read_div)
|
drtio_spi::set_config(nodeno, node_busno, flags, write_div, read_div)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_xfer(busno: u32, chip_select: u16, write_length: u8, read_length: u8) -> Result<(), ()> {
|
pub fn set_xfer(busno: u32, chip_select: u16, write_length: u8, read_length: u8) -> Result<(), ()> {
|
||||||
let drtio = busno >> 16;
|
let nodeno = (busno >> 16) as u8;
|
||||||
let dev_busno = busno as u8;
|
let node_busno = busno as u8;
|
||||||
if drtio == 0 {
|
if nodeno == 0 {
|
||||||
board::spi::set_xfer(dev_busno, chip_select, write_length, read_length)
|
board::spi::set_xfer(node_busno, chip_select, write_length, read_length)
|
||||||
} else {
|
} else {
|
||||||
drtio_spi::set_xfer(busno, chip_select, write_length, read_length)
|
drtio_spi::set_xfer(nodeno, node_busno, chip_select, write_length, read_length)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn write(busno: u32, data: u32) -> Result<(), ()> {
|
pub fn write(busno: u32, data: u32) -> Result<(), ()> {
|
||||||
let drtio = busno >> 16;
|
let nodeno = (busno >> 16) as u8;
|
||||||
let dev_busno = busno as u8;
|
let node_busno = busno as u8;
|
||||||
if drtio == 0 {
|
if nodeno == 0 {
|
||||||
board::spi::write(dev_busno, data)
|
board::spi::write(node_busno, data)
|
||||||
} else {
|
} else {
|
||||||
drtio_spi::write(busno, data)
|
drtio_spi::write(nodeno, node_busno, data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn read(busno: u32) -> Result<u32, ()> {
|
pub fn read(busno: u32) -> Result<u32, ()> {
|
||||||
let drtio = busno >> 16;
|
let nodeno = (busno >> 16) as u8;
|
||||||
let dev_busno = busno as u8;
|
let node_busno = busno as u8;
|
||||||
if drtio == 0 {
|
if nodeno == 0 {
|
||||||
board::spi::read(dev_busno)
|
board::spi::read(node_busno)
|
||||||
} else {
|
} else {
|
||||||
drtio_spi::read(busno)
|
drtio_spi::read(nodeno, node_busno)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -318,12 +336,12 @@ pub fn process_kern_hwreq(io: &Io, request: &kern::Message) -> io::Result<bool>
|
||||||
rtio_mgt::drtio_dbg::get_fifo_space(channel);
|
rtio_mgt::drtio_dbg::get_fifo_space(channel);
|
||||||
kern_acknowledge()
|
kern_acknowledge()
|
||||||
}
|
}
|
||||||
&kern::DrtioPacketCountRequest => {
|
&kern::DrtioPacketCountRequest { linkno } => {
|
||||||
let (tx_cnt, rx_cnt) = rtio_mgt::drtio_dbg::get_packet_counts();
|
let (tx_cnt, rx_cnt) = rtio_mgt::drtio_dbg::get_packet_counts(linkno);
|
||||||
kern_send(io, &kern::DrtioPacketCountReply { tx_cnt: tx_cnt, rx_cnt: rx_cnt })
|
kern_send(io, &kern::DrtioPacketCountReply { tx_cnt: tx_cnt, rx_cnt: rx_cnt })
|
||||||
}
|
}
|
||||||
&kern::DrtioFifoSpaceReqCountRequest => {
|
&kern::DrtioFifoSpaceReqCountRequest { linkno } => {
|
||||||
let cnt = rtio_mgt::drtio_dbg::get_fifo_space_req_count();
|
let cnt = rtio_mgt::drtio_dbg::get_fifo_space_req_count(linkno);
|
||||||
kern_send(io, &kern::DrtioFifoSpaceReqCountReply { cnt: cnt })
|
kern_send(io, &kern::DrtioFifoSpaceReqCountReply { cnt: cnt })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,8 +6,6 @@ use sched::{TcpListener, TcpStream};
|
||||||
use board::{clock, csr};
|
use board::{clock, csr};
|
||||||
#[cfg(has_drtio)]
|
#[cfg(has_drtio)]
|
||||||
use drtioaux;
|
use drtioaux;
|
||||||
#[cfg(has_drtio)]
|
|
||||||
use rtio_mgt;
|
|
||||||
|
|
||||||
use moninj_proto::*;
|
use moninj_proto::*;
|
||||||
|
|
||||||
|
@ -35,32 +33,36 @@ fn read_probe_local(channel: u16, probe: u8) -> u32 {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(has_drtio)]
|
#[cfg(has_drtio)]
|
||||||
fn read_probe_drtio(channel: u16, probe: u8) -> u32 {
|
fn read_probe_drtio(nodeno: u8, channel: u16, probe: u8) -> u32 {
|
||||||
if rtio_mgt::drtio::link_is_running() {
|
|
||||||
let request = drtioaux::Packet::MonitorRequest { channel: channel, probe: probe };
|
let request = drtioaux::Packet::MonitorRequest { channel: channel, probe: probe };
|
||||||
drtioaux::hw::send(&request).unwrap();
|
match drtioaux::hw::send(nodeno, &request) {
|
||||||
match drtioaux::hw::recv_timeout(None) {
|
Ok(_) => (),
|
||||||
|
Err(e) => {
|
||||||
|
error!("aux packet error ({})", e);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
match drtioaux::hw::recv_timeout(nodeno, None) {
|
||||||
Ok(drtioaux::Packet::MonitorReply { value }) => return value,
|
Ok(drtioaux::Packet::MonitorReply { value }) => return value,
|
||||||
Ok(_) => error!("received unexpected aux packet"),
|
Ok(_) => error!("received unexpected aux packet"),
|
||||||
Err(e) => error!("aux packet error ({})", e)
|
Err(e) => error!("aux packet error ({})", e)
|
||||||
}
|
}
|
||||||
0
|
0
|
||||||
} else {
|
|
||||||
0
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_probe(channel: u32, probe: u8) -> u32 {
|
fn read_probe(channel: u32, probe: u8) -> u32 {
|
||||||
|
let nodeno = (channel >> 16) as u8;
|
||||||
|
let node_channel = channel as u16;
|
||||||
#[cfg(has_rtio_moninj)]
|
#[cfg(has_rtio_moninj)]
|
||||||
{
|
{
|
||||||
if channel & 0xff0000 == 0 {
|
if nodeno == 0 {
|
||||||
return read_probe_local(channel as u16, probe)
|
return read_probe_local(node_channel, probe)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[cfg(has_drtio)]
|
#[cfg(has_drtio)]
|
||||||
{
|
{
|
||||||
if channel & 0xff0000 != 0 {
|
if nodeno != 0 {
|
||||||
return read_probe_drtio(channel as u16, probe)
|
return read_probe_drtio(nodeno, node_channel, probe)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
error!("read_probe: unrecognized channel number {}", channel);
|
error!("read_probe: unrecognized channel number {}", channel);
|
||||||
|
@ -77,29 +79,32 @@ fn inject_local(channel: u16, overrd: u8, value: u8) {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(has_drtio)]
|
#[cfg(has_drtio)]
|
||||||
fn inject_drtio(channel: u16, overrd: u8, value: u8) {
|
fn inject_drtio(nodeno: u8, channel: u16, overrd: u8, value: u8) {
|
||||||
if rtio_mgt::drtio::link_is_running() {
|
|
||||||
let request = drtioaux::Packet::InjectionRequest {
|
let request = drtioaux::Packet::InjectionRequest {
|
||||||
channel: channel,
|
channel: channel,
|
||||||
overrd: overrd,
|
overrd: overrd,
|
||||||
value: value
|
value: value
|
||||||
};
|
};
|
||||||
drtioaux::hw::send(&request).unwrap();
|
match drtioaux::hw::send(nodeno, &request) {
|
||||||
|
Ok(_) => (),
|
||||||
|
Err(e) => error!("aux packet error ({})", e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn inject(channel: u32, overrd: u8, value: u8) {
|
fn inject(channel: u32, overrd: u8, value: u8) {
|
||||||
|
let nodeno = (channel >> 16) as u8;
|
||||||
|
let node_channel = channel as u16;
|
||||||
#[cfg(has_rtio_moninj)]
|
#[cfg(has_rtio_moninj)]
|
||||||
{
|
{
|
||||||
if channel & 0xff0000 == 0 {
|
if nodeno == 0 {
|
||||||
inject_local(channel as u16, overrd, value);
|
inject_local(node_channel, overrd, value);
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[cfg(has_drtio)]
|
#[cfg(has_drtio)]
|
||||||
{
|
{
|
||||||
if channel & 0xff0000 != 0 {
|
if nodeno != 0 {
|
||||||
inject_drtio(channel as u16, overrd, value);
|
inject_drtio(nodeno, node_channel, overrd, value);
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -116,35 +121,39 @@ fn read_injection_status_local(channel: u16, overrd: u8) -> u8 {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(has_drtio)]
|
#[cfg(has_drtio)]
|
||||||
fn read_injection_status_drtio(channel: u16, overrd: u8) -> u8 {
|
fn read_injection_status_drtio(nodeno: u8, channel: u16, overrd: u8) -> u8 {
|
||||||
if rtio_mgt::drtio::link_is_running() {
|
|
||||||
let request = drtioaux::Packet::InjectionStatusRequest {
|
let request = drtioaux::Packet::InjectionStatusRequest {
|
||||||
channel: channel,
|
channel: channel,
|
||||||
overrd: overrd
|
overrd: overrd
|
||||||
};
|
};
|
||||||
drtioaux::hw::send(&request).unwrap();
|
match drtioaux::hw::send(nodeno, &request) {
|
||||||
match drtioaux::hw::recv_timeout(None) {
|
Ok(_) => (),
|
||||||
|
Err(e) => {
|
||||||
|
error!("aux packet error ({})", e);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
match drtioaux::hw::recv_timeout(nodeno, None) {
|
||||||
Ok(drtioaux::Packet::InjectionStatusReply { value }) => return value,
|
Ok(drtioaux::Packet::InjectionStatusReply { value }) => return value,
|
||||||
Ok(_) => error!("received unexpected aux packet"),
|
Ok(_) => error!("received unexpected aux packet"),
|
||||||
Err(e) => error!("aux packet error ({})", e)
|
Err(e) => error!("aux packet error ({})", e)
|
||||||
}
|
}
|
||||||
0
|
0
|
||||||
} else {
|
|
||||||
0
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_injection_status(channel: u32, probe: u8) -> u8 {
|
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)]
|
#[cfg(has_rtio_moninj)]
|
||||||
{
|
{
|
||||||
if channel & 0xff0000 == 0 {
|
if nodeno == 0 {
|
||||||
return read_injection_status_local(channel as u16, probe)
|
return read_injection_status_local(node_channel, probe)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[cfg(has_drtio)]
|
#[cfg(has_drtio)]
|
||||||
{
|
{
|
||||||
if channel & 0xff0000 != 0 {
|
if nodeno != 0 {
|
||||||
return read_injection_status_drtio(channel as u16, probe)
|
return read_injection_status_drtio(nodeno, node_channel, probe)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
error!("read_injection_status: unrecognized channel number {}", channel);
|
error!("read_injection_status: unrecognized channel number {}", channel);
|
||||||
|
|
|
@ -43,80 +43,70 @@ pub mod drtio {
|
||||||
|
|
||||||
pub fn startup(io: &Io) {
|
pub fn startup(io: &Io) {
|
||||||
io.spawn(4096, link_thread);
|
io.spawn(4096, link_thread);
|
||||||
io.spawn(4096, local_error_thread);
|
|
||||||
io.spawn(4096, aux_error_thread);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static mut LINK_RUNNING: bool = false;
|
fn link_rx_up(linkno: u8) -> bool {
|
||||||
|
let linkno = linkno as usize;
|
||||||
fn link_set_running(running: bool) {
|
|
||||||
unsafe {
|
unsafe {
|
||||||
LINK_RUNNING = running
|
(csr::DRTIO[linkno].link_status_read)() == 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn link_is_running() -> bool {
|
fn reset_phy(linkno: u8) {
|
||||||
|
let linkno = linkno as usize;
|
||||||
unsafe {
|
unsafe {
|
||||||
LINK_RUNNING
|
(csr::DRTIO[linkno].reset_phy_write)(1);
|
||||||
|
while (csr::DRTIO[linkno].o_wait_read)() == 1 {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn link_is_up() -> bool {
|
fn sync_tsc(linkno: u8) {
|
||||||
|
let linkno = linkno as usize;
|
||||||
unsafe {
|
unsafe {
|
||||||
csr::drtio::link_status_read() == 1
|
(csr::DRTIO[linkno].set_time_write)(1);
|
||||||
|
while (csr::DRTIO[linkno].set_time_read)() == 1 {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn reset_phy() {
|
fn init_link(linkno: u8) {
|
||||||
|
let linkidx = linkno as usize;
|
||||||
unsafe {
|
unsafe {
|
||||||
csr::drtio::reset_phy_write(1);
|
(csr::DRTIO[linkidx].reset_write)(1);
|
||||||
while csr::drtio::o_wait_read() == 1 {}
|
while (csr::DRTIO[linkidx].o_wait_read)() == 1 {}
|
||||||
}
|
}
|
||||||
}
|
// TODO: determine actual number of remote FIFOs
|
||||||
|
for channel in 0..16 {
|
||||||
fn sync_tsc() {
|
|
||||||
unsafe {
|
unsafe {
|
||||||
csr::drtio::set_time_write(1);
|
(csr::DRTIO[linkidx].chan_sel_override_write)(channel);
|
||||||
while csr::drtio::set_time_read() == 1 {}
|
(csr::DRTIO[linkidx].chan_sel_override_en_write)(1);
|
||||||
|
|
||||||
|
(csr::DRTIO[linkidx].o_reset_channel_status_write)(1);
|
||||||
|
(csr::DRTIO[linkidx].o_get_fifo_space_write)(1);
|
||||||
|
while (csr::DRTIO[linkidx].o_wait_read)() == 1 {}
|
||||||
|
info!("[LINK#{}] FIFO space on channel {} is {}",
|
||||||
|
linkno, channel, (csr::DRTIO[linkidx].o_dbg_fifo_space_read)());
|
||||||
|
|
||||||
|
(csr::DRTIO[linkidx].chan_sel_override_en_write)(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn init_channel(channel: u16) {
|
|
||||||
unsafe {
|
|
||||||
csr::drtio::chan_sel_override_write(channel);
|
|
||||||
csr::drtio::chan_sel_override_en_write(1);
|
|
||||||
|
|
||||||
csr::drtio::o_reset_channel_status_write(1);
|
|
||||||
csr::drtio::o_get_fifo_space_write(1);
|
|
||||||
while csr::drtio::o_wait_read() == 1 {}
|
|
||||||
info!("FIFO space on channel {} is {}", channel, csr::drtio::o_dbg_fifo_space_read());
|
|
||||||
|
|
||||||
csr::drtio::chan_sel_override_en_write(0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn init() {
|
pub fn init() {
|
||||||
if link_is_running() {
|
for linkno in 0..csr::DRTIO.len() {
|
||||||
unsafe {
|
init_link(linkno as u8);
|
||||||
csr::drtio::reset_write(1);
|
|
||||||
while csr::drtio::o_wait_read() == 1 {}
|
|
||||||
}
|
|
||||||
for channel in 0..16 {
|
|
||||||
init_channel(channel);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ping_remote(io: &Io) -> u32 {
|
fn ping_remote(linkno: u8, io: &Io) -> u32 {
|
||||||
let mut count = 0;
|
let mut count = 0;
|
||||||
loop {
|
loop {
|
||||||
if !link_is_up() {
|
if !link_rx_up(linkno) {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
count += 1;
|
count += 1;
|
||||||
drtioaux::hw::send(&drtioaux::Packet::EchoRequest).unwrap();
|
drtioaux::hw::send_link(linkno, &drtioaux::Packet::EchoRequest).unwrap();
|
||||||
io.sleep(100).unwrap();
|
io.sleep(100).unwrap();
|
||||||
let pr = drtioaux::hw::recv();
|
let pr = drtioaux::hw::recv_link(linkno);
|
||||||
match pr {
|
match pr {
|
||||||
Ok(Some(drtioaux::Packet::EchoReply)) => return count,
|
Ok(Some(drtioaux::Packet::EchoReply)) => return count,
|
||||||
_ => {}
|
_ => {}
|
||||||
|
@ -124,59 +114,72 @@ pub mod drtio {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn link_thread(io: Io) {
|
fn process_local_errors(linkno: u8) {
|
||||||
loop {
|
let errors;
|
||||||
io.until(link_is_up).unwrap();
|
let linkidx = linkno as usize;
|
||||||
info!("link RX is up, pinging");
|
|
||||||
|
|
||||||
let ping_count = ping_remote(&io);
|
|
||||||
if ping_count > 0 {
|
|
||||||
info!("remote replied after {} packets", ping_count);
|
|
||||||
link_set_running(true);
|
|
||||||
init(); // clear all FIFOs first
|
|
||||||
reset_phy();
|
|
||||||
sync_tsc();
|
|
||||||
info!("link initialization completed");
|
|
||||||
}
|
|
||||||
|
|
||||||
io.until(|| !link_is_up()).unwrap();
|
|
||||||
link_set_running(false);
|
|
||||||
info!("link is down");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn local_error_thread(io: Io) {
|
|
||||||
loop {
|
|
||||||
unsafe {
|
unsafe {
|
||||||
io.until(|| csr::drtio::protocol_error_read() != 0).unwrap();
|
errors = (csr::DRTIO[linkidx].protocol_error_read)();
|
||||||
let errors = csr::drtio::protocol_error_read();
|
(csr::DRTIO[linkidx].protocol_error_write)(errors);
|
||||||
|
}
|
||||||
|
if errors != 0 {
|
||||||
|
error!("[LINK#{}] found error(s)", linkno);
|
||||||
if errors & 1 != 0 {
|
if errors & 1 != 0 {
|
||||||
error!("received packet of an unknown type");
|
error!("[LINK#{}] received packet of an unknown type", linkno);
|
||||||
}
|
}
|
||||||
if errors & 2 != 0 {
|
if errors & 2 != 0 {
|
||||||
error!("received truncated packet");
|
error!("[LINK#{}] received truncated packet", linkno);
|
||||||
}
|
}
|
||||||
if errors & 4 != 0 {
|
if errors & 4 != 0 {
|
||||||
error!("timeout attempting to get remote FIFO space");
|
error!("[LINK#{}] timeout attempting to get remote FIFO space", linkno);
|
||||||
}
|
|
||||||
csr::drtio::protocol_error_write(errors);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn aux_error_thread(io: Io) {
|
fn process_aux_errors(linkno: u8) {
|
||||||
loop {
|
drtioaux::hw::send_link(linkno, &drtioaux::Packet::RtioErrorRequest).unwrap();
|
||||||
io.sleep(200).unwrap();
|
match drtioaux::hw::recv_timeout_link(linkno, None) {
|
||||||
if link_is_running() {
|
|
||||||
drtioaux::hw::send(&drtioaux::Packet::RtioErrorRequest).unwrap();
|
|
||||||
match drtioaux::hw::recv_timeout(None) {
|
|
||||||
Ok(drtioaux::Packet::RtioNoErrorReply) => (),
|
Ok(drtioaux::Packet::RtioNoErrorReply) => (),
|
||||||
Ok(drtioaux::Packet::RtioErrorCollisionReply) => error!("RTIO collision (in satellite)"),
|
Ok(drtioaux::Packet::RtioErrorCollisionReply) =>
|
||||||
Ok(drtioaux::Packet::RtioErrorBusyReply) => error!("RTIO busy (in satellite)"),
|
error!("[LINK#{}] RTIO collision", linkno),
|
||||||
Ok(_) => error!("received unexpected aux packet"),
|
Ok(drtioaux::Packet::RtioErrorBusyReply) =>
|
||||||
Err(e) => error!("aux packet error ({})", e)
|
error!("[LINK#{}] RTIO busy", linkno),
|
||||||
|
Ok(_) => error!("[LINK#{}] received unexpected aux packet", linkno),
|
||||||
|
Err(e) => error!("[LINK#{}] aux packet error ({})", linkno, e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn link_thread(io: Io) {
|
||||||
|
let mut link_up = vec![false; csr::DRTIO.len()];
|
||||||
|
|
||||||
|
loop {
|
||||||
|
for linkno in 0..csr::DRTIO.len() {
|
||||||
|
let linkno = linkno as u8;
|
||||||
|
if !link_up[linkno as usize] {
|
||||||
|
if link_rx_up(linkno) {
|
||||||
|
info!("[LINK#{}] link RX became up, pinging", linkno);
|
||||||
|
let ping_count = ping_remote(linkno, &io);
|
||||||
|
if ping_count > 0 {
|
||||||
|
info!("[LINK#{}] remote replied after {} packets", linkno, ping_count);
|
||||||
|
init_link(linkno); // clear all FIFOs first
|
||||||
|
reset_phy(linkno);
|
||||||
|
sync_tsc(linkno);
|
||||||
|
info!("[LINK#{}] link initialization completed", linkno);
|
||||||
|
link_up[linkno as usize] = true;
|
||||||
|
} else {
|
||||||
|
info!("[LINK#{}] ping failed", linkno);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if link_rx_up(linkno) {
|
||||||
|
process_local_errors(linkno);
|
||||||
|
process_aux_errors(linkno);
|
||||||
|
} else {
|
||||||
|
info!("[LINK#{}] link is down", linkno);
|
||||||
|
link_up[linkno as usize] = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
io.sleep(200).unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -248,45 +251,55 @@ pub fn init_core() {
|
||||||
pub mod drtio_dbg {
|
pub mod drtio_dbg {
|
||||||
use board::csr;
|
use board::csr;
|
||||||
|
|
||||||
|
// TODO: routing
|
||||||
pub fn get_channel_state(channel: u32) -> (u16, u64) {
|
pub fn get_channel_state(channel: u32) -> (u16, u64) {
|
||||||
|
let linkno = ((channel >> 16) - 1) as usize;
|
||||||
|
let node_channel = channel as u16;
|
||||||
unsafe {
|
unsafe {
|
||||||
csr::drtio::chan_sel_override_write(channel as u16);
|
(csr::DRTIO[linkno].chan_sel_override_write)(node_channel as u16);
|
||||||
csr::drtio::chan_sel_override_en_write(1);
|
(csr::DRTIO[linkno].chan_sel_override_en_write)(1);
|
||||||
let fifo_space = csr::drtio::o_dbg_fifo_space_read();
|
let fifo_space = (csr::DRTIO[linkno].o_dbg_fifo_space_read)();
|
||||||
let last_timestamp = csr::drtio::o_dbg_last_timestamp_read();
|
let last_timestamp = (csr::DRTIO[linkno].o_dbg_last_timestamp_read)();
|
||||||
csr::drtio::chan_sel_override_en_write(0);
|
(csr::DRTIO[linkno].chan_sel_override_en_write)(0);
|
||||||
(fifo_space, last_timestamp)
|
(fifo_space, last_timestamp)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn reset_channel_state(channel: u32) {
|
pub fn reset_channel_state(channel: u32) {
|
||||||
|
let linkno = ((channel >> 16) - 1) as usize;
|
||||||
|
let node_channel = channel as u16;
|
||||||
unsafe {
|
unsafe {
|
||||||
csr::drtio::chan_sel_override_write(channel as u16);
|
(csr::DRTIO[linkno].chan_sel_override_write)(node_channel);
|
||||||
csr::drtio::chan_sel_override_en_write(1);
|
(csr::DRTIO[linkno].chan_sel_override_en_write)(1);
|
||||||
csr::drtio::o_reset_channel_status_write(1);
|
(csr::DRTIO[linkno].o_reset_channel_status_write)(1);
|
||||||
csr::drtio::chan_sel_override_en_write(0);
|
(csr::DRTIO[linkno].chan_sel_override_en_write)(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_fifo_space(channel: u32) {
|
pub fn get_fifo_space(channel: u32) {
|
||||||
|
let linkno = ((channel >> 16) - 1) as usize;
|
||||||
|
let node_channel = channel as u16;
|
||||||
unsafe {
|
unsafe {
|
||||||
csr::drtio::chan_sel_override_write(channel as u16);
|
(csr::DRTIO[linkno].chan_sel_override_write)(node_channel);
|
||||||
csr::drtio::chan_sel_override_en_write(1);
|
(csr::DRTIO[linkno].chan_sel_override_en_write)(1);
|
||||||
csr::drtio::o_get_fifo_space_write(1);
|
(csr::DRTIO[linkno].o_get_fifo_space_write)(1);
|
||||||
csr::drtio::chan_sel_override_en_write(0);
|
(csr::DRTIO[linkno].chan_sel_override_en_write)(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_packet_counts() -> (u32, u32) {
|
pub fn get_packet_counts(linkno: u8) -> (u32, u32) {
|
||||||
|
let linkno = linkno as usize;
|
||||||
unsafe {
|
unsafe {
|
||||||
csr::drtio::update_packet_cnt_write(1);
|
(csr::DRTIO[linkno].update_packet_cnt_write)(1);
|
||||||
(csr::drtio::packet_cnt_tx_read(), csr::drtio::packet_cnt_rx_read())
|
((csr::DRTIO[linkno].packet_cnt_tx_read)(),
|
||||||
|
(csr::DRTIO[linkno].packet_cnt_rx_read)())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_fifo_space_req_count() -> u32 {
|
pub fn get_fifo_space_req_count(linkno: u8) -> u32 {
|
||||||
|
let linkno = linkno as usize;
|
||||||
unsafe {
|
unsafe {
|
||||||
csr::drtio::o_dbg_fifo_space_req_cnt_read()
|
(csr::DRTIO[linkno].o_dbg_fifo_space_req_cnt_read)()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -299,7 +312,7 @@ pub mod drtio_dbg {
|
||||||
|
|
||||||
pub fn get_fifo_space(_channel: u32) {}
|
pub fn get_fifo_space(_channel: u32) {}
|
||||||
|
|
||||||
pub fn get_packet_counts() -> (u32, u32) { (0, 0) }
|
pub fn get_packet_counts(_linkno: u8) -> (u32, u32) { (0, 0) }
|
||||||
|
|
||||||
pub fn get_fifo_space_req_count() -> u32 { 0 }
|
pub fn get_fifo_space_req_count(_linkno: u8) -> u32 { 0 }
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,25 +15,25 @@ fn process_aux_packet(p: &drtioaux::Packet) {
|
||||||
// In the code below, *_chan_sel_write takes an u8 if there are fewer than 256 channels,
|
// In the code below, *_chan_sel_write takes an u8 if there are fewer than 256 channels,
|
||||||
// and u16 otherwise; hence the `as _` conversion.
|
// and u16 otherwise; hence the `as _` conversion.
|
||||||
match *p {
|
match *p {
|
||||||
drtioaux::Packet::EchoRequest => drtioaux::hw::send(&drtioaux::Packet::EchoReply).unwrap(),
|
drtioaux::Packet::EchoRequest => drtioaux::hw::send_link(0, &drtioaux::Packet::EchoReply).unwrap(),
|
||||||
|
|
||||||
drtioaux::Packet::RtioErrorRequest => {
|
drtioaux::Packet::RtioErrorRequest => {
|
||||||
let errors;
|
let errors;
|
||||||
unsafe {
|
unsafe {
|
||||||
errors = board::csr::drtio::rtio_error_read();
|
errors = (board::csr::DRTIO[0].rtio_error_read)();
|
||||||
}
|
}
|
||||||
if errors & 1 != 0 {
|
if errors & 1 != 0 {
|
||||||
unsafe {
|
unsafe {
|
||||||
board::csr::drtio::rtio_error_write(1);
|
(board::csr::DRTIO[0].rtio_error_write)(1);
|
||||||
}
|
}
|
||||||
drtioaux::hw::send(&drtioaux::Packet::RtioErrorCollisionReply).unwrap();
|
drtioaux::hw::send_link(0, &drtioaux::Packet::RtioErrorCollisionReply).unwrap();
|
||||||
} else if errors & 2 != 0 {
|
} else if errors & 2 != 0 {
|
||||||
unsafe {
|
unsafe {
|
||||||
board::csr::drtio::rtio_error_write(2);
|
(board::csr::DRTIO[0].rtio_error_write)(2);
|
||||||
}
|
}
|
||||||
drtioaux::hw::send(&drtioaux::Packet::RtioErrorBusyReply).unwrap();
|
drtioaux::hw::send_link(0, &drtioaux::Packet::RtioErrorBusyReply).unwrap();
|
||||||
} else {
|
} else {
|
||||||
drtioaux::hw::send(&drtioaux::Packet::RtioNoErrorReply).unwrap();
|
drtioaux::hw::send_link(0, &drtioaux::Packet::RtioNoErrorReply).unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,7 +51,7 @@ fn process_aux_packet(p: &drtioaux::Packet) {
|
||||||
value = 0;
|
value = 0;
|
||||||
}
|
}
|
||||||
let reply = drtioaux::Packet::MonitorReply { value: value as u32 };
|
let reply = drtioaux::Packet::MonitorReply { value: value as u32 };
|
||||||
drtioaux::hw::send(&reply).unwrap();
|
drtioaux::hw::send_link(0, &reply).unwrap();
|
||||||
},
|
},
|
||||||
drtioaux::Packet::InjectionRequest { channel, overrd, value } => {
|
drtioaux::Packet::InjectionRequest { channel, overrd, value } => {
|
||||||
#[cfg(has_rtio_moninj)]
|
#[cfg(has_rtio_moninj)]
|
||||||
|
@ -74,50 +74,50 @@ fn process_aux_packet(p: &drtioaux::Packet) {
|
||||||
value = 0;
|
value = 0;
|
||||||
}
|
}
|
||||||
let reply = drtioaux::Packet::InjectionStatusReply { value: value };
|
let reply = drtioaux::Packet::InjectionStatusReply { value: value };
|
||||||
drtioaux::hw::send(&reply).unwrap();
|
drtioaux::hw::send_link(0, &reply).unwrap();
|
||||||
},
|
},
|
||||||
|
|
||||||
drtioaux::Packet::I2cStartRequest { busno } => {
|
drtioaux::Packet::I2cStartRequest { busno } => {
|
||||||
let succeeded = board::i2c::start(busno).is_ok();
|
let succeeded = board::i2c::start(busno).is_ok();
|
||||||
drtioaux::hw::send(&drtioaux::Packet::I2cBasicReply { succeeded: succeeded }).unwrap();
|
drtioaux::hw::send_link(0, &drtioaux::Packet::I2cBasicReply { succeeded: succeeded }).unwrap();
|
||||||
}
|
}
|
||||||
drtioaux::Packet::I2cRestartRequest { busno } => {
|
drtioaux::Packet::I2cRestartRequest { busno } => {
|
||||||
let succeeded = board::i2c::restart(busno).is_ok();
|
let succeeded = board::i2c::restart(busno).is_ok();
|
||||||
drtioaux::hw::send(&drtioaux::Packet::I2cBasicReply { succeeded: succeeded }).unwrap();
|
drtioaux::hw::send_link(0, &drtioaux::Packet::I2cBasicReply { succeeded: succeeded }).unwrap();
|
||||||
}
|
}
|
||||||
drtioaux::Packet::I2cStopRequest { busno } => {
|
drtioaux::Packet::I2cStopRequest { busno } => {
|
||||||
let succeeded = board::i2c::stop(busno).is_ok();
|
let succeeded = board::i2c::stop(busno).is_ok();
|
||||||
drtioaux::hw::send(&drtioaux::Packet::I2cBasicReply { succeeded: succeeded }).unwrap();
|
drtioaux::hw::send_link(0, &drtioaux::Packet::I2cBasicReply { succeeded: succeeded }).unwrap();
|
||||||
}
|
}
|
||||||
drtioaux::Packet::I2cWriteRequest { busno, data } => {
|
drtioaux::Packet::I2cWriteRequest { busno, data } => {
|
||||||
match board::i2c::write(busno, data) {
|
match board::i2c::write(busno, data) {
|
||||||
Ok(ack) => drtioaux::hw::send(&drtioaux::Packet::I2cWriteReply { succeeded: true, ack: ack }).unwrap(),
|
Ok(ack) => drtioaux::hw::send_link(0, &drtioaux::Packet::I2cWriteReply { succeeded: true, ack: ack }).unwrap(),
|
||||||
Err(_) => drtioaux::hw::send(&drtioaux::Packet::I2cWriteReply { succeeded: false, ack: false }).unwrap()
|
Err(_) => drtioaux::hw::send_link(0, &drtioaux::Packet::I2cWriteReply { succeeded: false, ack: false }).unwrap()
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
drtioaux::Packet::I2cReadRequest { busno, ack } => {
|
drtioaux::Packet::I2cReadRequest { busno, ack } => {
|
||||||
match board::i2c::read(busno, ack) {
|
match board::i2c::read(busno, ack) {
|
||||||
Ok(data) => drtioaux::hw::send(&drtioaux::Packet::I2cReadReply { succeeded: true, data: data }).unwrap(),
|
Ok(data) => drtioaux::hw::send_link(0, &drtioaux::Packet::I2cReadReply { succeeded: true, data: data }).unwrap(),
|
||||||
Err(_) => drtioaux::hw::send(&drtioaux::Packet::I2cReadReply { succeeded: false, data: 0xff }).unwrap()
|
Err(_) => drtioaux::hw::send_link(0, &drtioaux::Packet::I2cReadReply { succeeded: false, data: 0xff }).unwrap()
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
drtioaux::Packet::SpiSetConfigRequest { busno, flags, write_div, read_div } => {
|
drtioaux::Packet::SpiSetConfigRequest { busno, flags, write_div, read_div } => {
|
||||||
let succeeded = board::spi::set_config(busno, flags, write_div, read_div).is_ok();
|
let succeeded = board::spi::set_config(busno, flags, write_div, read_div).is_ok();
|
||||||
drtioaux::hw::send(&drtioaux::Packet::SpiBasicReply { succeeded: succeeded }).unwrap();
|
drtioaux::hw::send_link(0, &drtioaux::Packet::SpiBasicReply { succeeded: succeeded }).unwrap();
|
||||||
},
|
},
|
||||||
drtioaux::Packet::SpiSetXferRequest { busno, chip_select, write_length, read_length } => {
|
drtioaux::Packet::SpiSetXferRequest { busno, chip_select, write_length, read_length } => {
|
||||||
let succeeded = board::spi::set_xfer(busno, chip_select, write_length, read_length).is_ok();
|
let succeeded = board::spi::set_xfer(busno, chip_select, write_length, read_length).is_ok();
|
||||||
drtioaux::hw::send(&drtioaux::Packet::SpiBasicReply { succeeded: succeeded }).unwrap();
|
drtioaux::hw::send_link(0, &drtioaux::Packet::SpiBasicReply { succeeded: succeeded }).unwrap();
|
||||||
}
|
}
|
||||||
drtioaux::Packet::SpiWriteRequest { busno, data } => {
|
drtioaux::Packet::SpiWriteRequest { busno, data } => {
|
||||||
let succeeded = board::spi::write(busno, data).is_ok();
|
let succeeded = board::spi::write(busno, data).is_ok();
|
||||||
drtioaux::hw::send(&drtioaux::Packet::SpiBasicReply { succeeded: succeeded }).unwrap();
|
drtioaux::hw::send_link(0, &drtioaux::Packet::SpiBasicReply { succeeded: succeeded }).unwrap();
|
||||||
}
|
}
|
||||||
drtioaux::Packet::SpiReadRequest { busno } => {
|
drtioaux::Packet::SpiReadRequest { busno } => {
|
||||||
match board::spi::read(busno) {
|
match board::spi::read(busno) {
|
||||||
Ok(data) => drtioaux::hw::send(&drtioaux::Packet::SpiReadReply { succeeded: true, data: data }).unwrap(),
|
Ok(data) => drtioaux::hw::send_link(0, &drtioaux::Packet::SpiReadReply { succeeded: true, data: data }).unwrap(),
|
||||||
Err(_) => drtioaux::hw::send(&drtioaux::Packet::SpiReadReply { succeeded: false, data: 0 }).unwrap()
|
Err(_) => drtioaux::hw::send_link(0, &drtioaux::Packet::SpiReadReply { succeeded: false, data: 0 }).unwrap()
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -126,7 +126,7 @@ fn process_aux_packet(p: &drtioaux::Packet) {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn process_aux_packets() {
|
fn process_aux_packets() {
|
||||||
let pr = drtioaux::hw::recv();
|
let pr = drtioaux::hw::recv_link(0);
|
||||||
match pr {
|
match pr {
|
||||||
Ok(None) => (),
|
Ok(None) => (),
|
||||||
Ok(Some(p)) => process_aux_packet(&p),
|
Ok(Some(p)) => process_aux_packet(&p),
|
||||||
|
@ -138,8 +138,8 @@ fn process_aux_packets() {
|
||||||
fn process_errors() {
|
fn process_errors() {
|
||||||
let errors;
|
let errors;
|
||||||
unsafe {
|
unsafe {
|
||||||
errors = board::csr::drtio::protocol_error_read();
|
errors = (board::csr::DRTIO[0].protocol_error_read)();
|
||||||
board::csr::drtio::protocol_error_write(errors);
|
(board::csr::DRTIO[0].protocol_error_write)(errors);
|
||||||
}
|
}
|
||||||
if errors & 1 != 0 {
|
if errors & 1 != 0 {
|
||||||
error!("received packet of an unknown type");
|
error!("received packet of an unknown type");
|
||||||
|
@ -185,7 +185,7 @@ const SI5324_SETTINGS: board::si5324::FrequencySettings
|
||||||
|
|
||||||
fn drtio_link_is_up() -> bool {
|
fn drtio_link_is_up() -> bool {
|
||||||
unsafe {
|
unsafe {
|
||||||
board::csr::drtio::link_status_read() == 1
|
(board::csr::DRTIO[0].link_status_read)() == 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -53,11 +53,14 @@ class Master(MiniSoC, AMPSoC):
|
||||||
sys_clk_freq=self.clk_freq,
|
sys_clk_freq=self.clk_freq,
|
||||||
clock_div2=True)
|
clock_div2=True)
|
||||||
|
|
||||||
self.submodules.drtio = DRTIOMaster(self.transceiver)
|
self.submodules.drtio0 = DRTIOMaster(self.transceiver)
|
||||||
self.csr_devices.append("drtio")
|
self.csr_devices.append("drtio0")
|
||||||
self.add_wb_slave(self.mem_map["drtio_aux"], 0x800,
|
self.add_wb_slave(self.mem_map["drtio_aux"], 0x800,
|
||||||
self.drtio.aux_controller.bus)
|
self.drtio0.aux_controller.bus)
|
||||||
self.add_memory_region("drtio_aux", self.mem_map["drtio_aux"] | self.shadow_base, 0x800)
|
self.add_memory_region("drtio0_aux", self.mem_map["drtio_aux"] | self.shadow_base, 0x800)
|
||||||
|
self.config["has_drtio"] = None
|
||||||
|
self.add_csr_group("drtio", ["drtio0"])
|
||||||
|
self.add_memory_group("drtio_aux", ["drtio0_aux"])
|
||||||
|
|
||||||
platform.add_extension(ad9154_fmc_ebz)
|
platform.add_extension(ad9154_fmc_ebz)
|
||||||
ad9154_spi = platform.request("ad9154_spi")
|
ad9154_spi = platform.request("ad9154_spi")
|
||||||
|
@ -100,7 +103,7 @@ class Master(MiniSoC, AMPSoC):
|
||||||
self.register_kernel_cpu_csrdevice("rtio_dma")
|
self.register_kernel_cpu_csrdevice("rtio_dma")
|
||||||
self.submodules.cri_con = rtio.CRIInterconnectShared(
|
self.submodules.cri_con = rtio.CRIInterconnectShared(
|
||||||
[self.rtio.cri, self.rtio_dma.cri],
|
[self.rtio.cri, self.rtio_dma.cri],
|
||||||
[self.rtio_core.cri, self.drtio.cri])
|
[self.rtio_core.cri, self.drtio0.cri])
|
||||||
self.register_kernel_cpu_csrdevice("cri_con")
|
self.register_kernel_cpu_csrdevice("cri_con")
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -56,13 +56,16 @@ class Satellite(BaseSoC):
|
||||||
sys_clk_freq=self.clk_freq)
|
sys_clk_freq=self.clk_freq)
|
||||||
self.submodules.rx_synchronizer = gtx_7series.RXSynchronizer(
|
self.submodules.rx_synchronizer = gtx_7series.RXSynchronizer(
|
||||||
self.transceiver.rtio_clk_freq, initial_phase=180.0)
|
self.transceiver.rtio_clk_freq, initial_phase=180.0)
|
||||||
self.submodules.drtio = DRTIOSatellite(
|
self.submodules.drtio0 = DRTIOSatellite(
|
||||||
self.transceiver, rtio_channels, self.rx_synchronizer)
|
self.transceiver, rtio_channels, self.rx_synchronizer)
|
||||||
self.csr_devices.append("rx_synchronizer")
|
self.csr_devices.append("rx_synchronizer")
|
||||||
self.csr_devices.append("drtio")
|
self.csr_devices.append("drtio0")
|
||||||
self.add_wb_slave(self.mem_map["drtio_aux"], 0x800,
|
self.add_wb_slave(self.mem_map["drtio_aux"], 0x800,
|
||||||
self.drtio.aux_controller.bus)
|
self.drtio0.aux_controller.bus)
|
||||||
self.add_memory_region("drtio_aux", self.mem_map["drtio_aux"] | self.shadow_base, 0x800)
|
self.add_memory_region("drtio0_aux", self.mem_map["drtio_aux"] | self.shadow_base, 0x800)
|
||||||
|
self.config["has_drtio"] = None
|
||||||
|
self.add_csr_group("drtio", ["drtio0"])
|
||||||
|
self.add_memory_group("drtio_aux", ["drtio0_aux"])
|
||||||
|
|
||||||
self.config["RTIO_FREQUENCY"] = str(self.transceiver.rtio_clk_freq/1e6)
|
self.config["RTIO_FREQUENCY"] = str(self.transceiver.rtio_clk_freq/1e6)
|
||||||
si5324_clkin = platform.request("si5324_clkin")
|
si5324_clkin = platform.request("si5324_clkin")
|
||||||
|
|
|
@ -15,7 +15,7 @@ requirements:
|
||||||
- python >=3.5.3,<3.6
|
- python >=3.5.3,<3.6
|
||||||
- setuptools 33.1.1
|
- setuptools 33.1.1
|
||||||
- migen 0.5.dev py_117+gite826cb9
|
- migen 0.5.dev py_117+gite826cb9
|
||||||
- misoc 0.6.dev py_32+gitc49a361c
|
- misoc 0.6.dev py_35+gitd6f86c03
|
||||||
- jesd204b 0.3
|
- jesd204b 0.3
|
||||||
- binutils-or1k-linux >=2.27
|
- binutils-or1k-linux >=2.27
|
||||||
- llvm-or1k
|
- llvm-or1k
|
||||||
|
|
Loading…
Reference in New Issue