runtime/rtio: fix rtio_input_wait(), add RTIOTimeout

This commit is contained in:
Robert Jördens 2016-02-29 19:49:15 +01:00
parent 16537d347e
commit 6c899e6ba6
6 changed files with 43 additions and 14 deletions

View File

@ -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"]

View File

@ -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.

View File

@ -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;

View File

@ -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;
}

View File

@ -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)
{

View File

@ -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;