coredevice, firmware: Add rtio_input_timestamped_data

Integration tests to follow as part of an RTIO counter phy that
makes use of this.
pull/1209/head
David Nadlinger 2018-12-11 20:49:42 +00:00
parent 8e30c4574b
commit e608d6ffd3
3 changed files with 55 additions and 1 deletions

View File

@ -1,5 +1,5 @@
from artiq.language.core import syscall
from artiq.language.types import TInt64, TInt32, TNone, TList
from artiq.language.types import TInt32, TInt64, TList, TNone, TTuple
@syscall(flags={"nowrite"})
@ -20,3 +20,12 @@ def rtio_input_timestamp(timeout_mu: TInt64, channel: TInt32) -> TInt64:
@syscall(flags={"nowrite"})
def rtio_input_data(channel: TInt32) -> TInt32:
raise NotImplementedError("syscall not simulated")
@syscall(flags={"nowrite"})
def rtio_input_timestamped_data(timeout_mu: TInt64,
channel: TInt32) -> TTuple([TInt64, TInt32]):
"""Wait for an input event up to timeout_mu on the given channel, and
return a tuple of timestamp and attached data, or (-1, 0) if the timeout is
reached."""
raise NotImplementedError("syscall not simulated")

View File

@ -104,6 +104,7 @@ static mut API: &'static [(&'static str, *const ())] = &[
api!(rtio_output_wide = ::rtio::output_wide),
api!(rtio_input_timestamp = ::rtio::input_timestamp),
api!(rtio_input_data = ::rtio::input_data),
api!(rtio_input_timestamped_data = ::rtio::input_timestamped_data),
api!(dma_record_start = ::dma_record_start),
api!(dma_record_stop = ::dma_record_stop),

View File

@ -1,7 +1,14 @@
#[repr(C)]
pub struct TimestampedData {
timestamp: i64,
data: i32,
}
#[cfg(has_rtio)]
mod imp {
use core::ptr::{read_volatile, write_volatile};
use cslice::CSlice;
use rtio::TimestampedData;
use board_misoc::csr;
use ::send;
@ -149,6 +156,38 @@ mod imp {
}
}
pub extern fn input_timestamped_data(timeout: i64, channel: i32) -> TimestampedData {
unsafe {
csr::rtio::target_write((channel as u32) << 8);
csr::rtio::i_timeout_write(timeout as u64);
let mut status = RTIO_I_STATUS_WAIT_STATUS;
while status & RTIO_I_STATUS_WAIT_STATUS != 0 {
status = csr::rtio::i_status_read();
}
if status & RTIO_I_STATUS_OVERFLOW != 0 {
csr::rtio::i_overflow_reset_write(1);
raise!("RTIOOverflow",
"RTIO input overflow on channel {0}",
channel as i64, 0, 0);
}
if status & RTIO_I_STATUS_WAIT_EVENT != 0 {
return TimestampedData { timestamp: -1, data: 0 }
}
if status & RTIO_I_STATUS_DESTINATION_UNREACHABLE != 0 {
raise!("RTIODestinationUnreachable",
"RTIO destination unreachable, input, on channel {0}",
channel as i64, 0, 0);
}
TimestampedData {
timestamp: csr::rtio::i_timestamp_read() as i64,
data: rtio_i_data_read(0) as i32
}
}
}
#[cfg(has_rtio_log)]
pub fn log(data: &[u8]) {
unsafe {
@ -179,6 +218,7 @@ mod imp {
#[cfg(not(has_rtio))]
mod imp {
use cslice::CSlice;
use rtio::TimestampedData;
pub extern fn init() {
unimplemented!("not(has_rtio)")
@ -208,6 +248,10 @@ mod imp {
unimplemented!("not(has_rtio)")
}
pub extern fn input_timestamped_data(_timeout: i64, _channel: i32) -> TimestampedData {
unimplemented!("not(has_rtio)")
}
pub fn log(_data: &[u8]) {
unimplemented!("not(has_rtio)")
}