From 6c899e6ba64ff83d9fb14ccbe048e14650d0e7c9 Mon Sep 17 00:00:00 2001 From: Robert Jordens Date: Mon, 29 Feb 2016 19:49:15 +0100 Subject: [PATCH] runtime/rtio: fix rtio_input_wait(), add RTIOTimeout --- artiq/coredevice/__init__.py | 7 ++++--- artiq/coredevice/exceptions.py | 11 +++++++++++ artiq/runtime/rt2wb.c | 14 +++++++++++++- artiq/runtime/rtio.c | 14 ++++++-------- artiq/runtime/rtio.h | 2 +- artiq/runtime/ttl.c | 9 ++++++++- 6 files changed, 43 insertions(+), 14 deletions(-) diff --git a/artiq/coredevice/__init__.py b/artiq/coredevice/__init__.py index 76e782a3f..aa4ab5066 100644 --- a/artiq/coredevice/__init__.py +++ b/artiq/coredevice/__init__.py @@ -1,12 +1,13 @@ -from artiq.coredevice import exceptions, dds +from artiq.coredevice import exceptions, dds, spi from artiq.coredevice.exceptions import (RTIOUnderflow, RTIOSequenceError, RTIOCollisionError, RTIOOverflow, - DDSBatchError, CacheError) + DDSBatchError, CacheError, + RTIOTimeout) from artiq.coredevice.dds import (PHASE_MODE_CONTINUOUS, PHASE_MODE_ABSOLUTE, PHASE_MODE_TRACKING) __all__ = [] __all__ += ["RTIOUnderflow", "RTIOSequenceError", "RTIOCollisionError", - "RTIOOverflow", "DDSBatchError", "CacheError"] + "RTIOOverflow", "DDSBatchError", "CacheError", "RTIOTimeout"] __all__ += ["PHASE_MODE_CONTINUOUS", "PHASE_MODE_ABSOLUTE", "PHASE_MODE_TRACKING"] diff --git a/artiq/coredevice/exceptions.py b/artiq/coredevice/exceptions.py index 05d9d1c29..3b5dba547 100644 --- a/artiq/coredevice/exceptions.py +++ b/artiq/coredevice/exceptions.py @@ -108,6 +108,17 @@ class RTIOOverflow(Exception): """ artiq_builtin = True +class RTIOTimeout(Exception): + """Raised when an RTIO input operation does not complete within the expected + time. This is only raised by channels where a response is guaranteed, such + as RT2WB (DDS and SPI). + + This does not interrupt operations further than cancelling the current read + attempt. Reading can be reattempted after the exception is caught, and + events that have arrived in the meantime will be retrieved. + """ + artiq_builtin = True + class DDSBatchError(Exception): """Raised when attempting to start a DDS batch while already in a batch, or when too many commands are batched. diff --git a/artiq/runtime/rt2wb.c b/artiq/runtime/rt2wb.c index 50f4fee55..30742ed24 100644 --- a/artiq/runtime/rt2wb.c +++ b/artiq/runtime/rt2wb.c @@ -16,8 +16,20 @@ unsigned int rt2wb_read_sync(long long int timestamp, int channel, int addr, int duration) { unsigned int data; + int status; + rtio_output(timestamp, channel, addr, 0); - rtio_input_wait(timestamp + duration, channel); + + status = rtio_input_wait(timestamp + duration, channel); + if (status & RTIO_I_STATUS_OVERFLOW) + artiq_raise_from_c("RTIOOverflow", + "RT2WB read overflow on channel {0}", + channel, 0, 0); + if (status & RTIO_I_STATUS_EMPTY) + artiq_raise_from_c("RTIOTimeout", + "RT2WB read timeout on channel {0}", + channel, 0, 0); + data = rtio_i_data_read(); rtio_i_re_write(1); return data; diff --git a/artiq/runtime/rtio.c b/artiq/runtime/rtio.c index 1680dbb6f..00eecbc2f 100644 --- a/artiq/runtime/rtio.c +++ b/artiq/runtime/rtio.c @@ -51,7 +51,7 @@ void rtio_output(long long int timestamp, int channel, unsigned int addr, } -void rtio_input_wait(long long int timeout, int channel) +int rtio_input_wait(long long int timeout, int channel) { int status; @@ -59,21 +59,19 @@ void rtio_input_wait(long long int timeout, int channel) while((status = rtio_i_status_read())) { if(status & RTIO_I_STATUS_OVERFLOW) { rtio_i_overflow_reset_write(1); - artiq_raise_from_c("RTIOOverflow", - "RTIO input overflow on channel {0}", - channel, 0, 0); + break; } if(rtio_get_counter() >= timeout) { /* check empty flag again to prevent race condition. * now we are sure that the time limit has been exceeded. */ - if(rtio_i_status_read() & RTIO_I_STATUS_EMPTY) - artiq_raise_from_c("InternalError", - "RTIO input timeout on channel {0}", - channel, 0, 0); + status = rtio_i_status_read(); + if(status & RTIO_I_STATUS_EMPTY) + break; } /* input FIFO is empty - keep waiting */ } + return status; } diff --git a/artiq/runtime/rtio.h b/artiq/runtime/rtio.h index 1214b40c8..d311fbb55 100644 --- a/artiq/runtime/rtio.h +++ b/artiq/runtime/rtio.h @@ -19,7 +19,7 @@ void rtio_log(long long int timestamp, const char *format, ...); void rtio_log_va(long long int timestamp, const char *format, va_list args); void rtio_output(long long int timestamp, int channel, unsigned int address, unsigned int data); -void rtio_input_wait(long long int timeout, int channel); +int rtio_input_wait(long long int timeout, int channel); static inline void rtio_write_and_process_status(long long int timestamp, int channel) { diff --git a/artiq/runtime/ttl.c b/artiq/runtime/ttl.c index bdd6d82b3..603eb2a8c 100644 --- a/artiq/runtime/ttl.c +++ b/artiq/runtime/ttl.c @@ -22,8 +22,15 @@ void ttl_set_sensitivity(long long int timestamp, int channel, int sensitivity) long long int ttl_get(int channel, long long int time_limit) { long long int r; + int status = rtio_input_wait(time_limit, channel); + + if (status & RTIO_I_STATUS_OVERFLOW) + artiq_raise_from_c("RTIOOverflow", + "RTIO input overflow on channel {0}", + channel, 0, 0); + if (status & RTIO_I_STATUS_EMPTY) + return -1; - rtio_input_wait(time_limit, channel); r = rtio_i_timestamp_read(); rtio_i_re_write(1); return r;