From e608d6ffd3b3a597aa89a30c005c075fe9f64873 Mon Sep 17 00:00:00 2001 From: David Nadlinger Date: Tue, 11 Dec 2018 20:49:42 +0000 Subject: [PATCH] coredevice, firmware: Add rtio_input_timestamped_data Integration tests to follow as part of an RTIO counter phy that makes use of this. --- artiq/coredevice/rtio.py | 11 ++++++++- artiq/firmware/ksupport/api.rs | 1 + artiq/firmware/ksupport/rtio.rs | 44 +++++++++++++++++++++++++++++++++ 3 files changed, 55 insertions(+), 1 deletion(-) diff --git a/artiq/coredevice/rtio.py b/artiq/coredevice/rtio.py index bde9d5064..7b5ab38a2 100644 --- a/artiq/coredevice/rtio.py +++ b/artiq/coredevice/rtio.py @@ -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") diff --git a/artiq/firmware/ksupport/api.rs b/artiq/firmware/ksupport/api.rs index ffd0d38b8..00c0f23e6 100644 --- a/artiq/firmware/ksupport/api.rs +++ b/artiq/firmware/ksupport/api.rs @@ -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), diff --git a/artiq/firmware/ksupport/rtio.rs b/artiq/firmware/ksupport/rtio.rs index 8c112ea50..fc64f554b 100644 --- a/artiq/firmware/ksupport/rtio.rs +++ b/artiq/firmware/ksupport/rtio.rs @@ -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)") }