forked from M-Labs/artiq
runtime/rtio: fix rtio_input_wait(), add RTIOTimeout
This commit is contained in:
parent
16537d347e
commit
6c899e6ba6
|
@ -1,12 +1,13 @@
|
||||||
from artiq.coredevice import exceptions, dds
|
from artiq.coredevice import exceptions, dds, spi
|
||||||
from artiq.coredevice.exceptions import (RTIOUnderflow, RTIOSequenceError,
|
from artiq.coredevice.exceptions import (RTIOUnderflow, RTIOSequenceError,
|
||||||
RTIOCollisionError, RTIOOverflow,
|
RTIOCollisionError, RTIOOverflow,
|
||||||
DDSBatchError, CacheError)
|
DDSBatchError, CacheError,
|
||||||
|
RTIOTimeout)
|
||||||
from artiq.coredevice.dds import (PHASE_MODE_CONTINUOUS, PHASE_MODE_ABSOLUTE,
|
from artiq.coredevice.dds import (PHASE_MODE_CONTINUOUS, PHASE_MODE_ABSOLUTE,
|
||||||
PHASE_MODE_TRACKING)
|
PHASE_MODE_TRACKING)
|
||||||
|
|
||||||
__all__ = []
|
__all__ = []
|
||||||
__all__ += ["RTIOUnderflow", "RTIOSequenceError", "RTIOCollisionError",
|
__all__ += ["RTIOUnderflow", "RTIOSequenceError", "RTIOCollisionError",
|
||||||
"RTIOOverflow", "DDSBatchError", "CacheError"]
|
"RTIOOverflow", "DDSBatchError", "CacheError", "RTIOTimeout"]
|
||||||
__all__ += ["PHASE_MODE_CONTINUOUS", "PHASE_MODE_ABSOLUTE",
|
__all__ += ["PHASE_MODE_CONTINUOUS", "PHASE_MODE_ABSOLUTE",
|
||||||
"PHASE_MODE_TRACKING"]
|
"PHASE_MODE_TRACKING"]
|
||||||
|
|
|
@ -108,6 +108,17 @@ class RTIOOverflow(Exception):
|
||||||
"""
|
"""
|
||||||
artiq_builtin = True
|
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):
|
class DDSBatchError(Exception):
|
||||||
"""Raised when attempting to start a DDS batch while already in a batch,
|
"""Raised when attempting to start a DDS batch while already in a batch,
|
||||||
or when too many commands are batched.
|
or when too many commands are batched.
|
||||||
|
|
|
@ -16,8 +16,20 @@ unsigned int rt2wb_read_sync(long long int timestamp, int channel, int addr,
|
||||||
int duration)
|
int duration)
|
||||||
{
|
{
|
||||||
unsigned int data;
|
unsigned int data;
|
||||||
|
int status;
|
||||||
|
|
||||||
rtio_output(timestamp, channel, addr, 0);
|
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();
|
data = rtio_i_data_read();
|
||||||
rtio_i_re_write(1);
|
rtio_i_re_write(1);
|
||||||
return data;
|
return data;
|
||||||
|
|
|
@ -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;
|
int status;
|
||||||
|
|
||||||
|
@ -59,21 +59,19 @@ void rtio_input_wait(long long int timeout, int channel)
|
||||||
while((status = rtio_i_status_read())) {
|
while((status = rtio_i_status_read())) {
|
||||||
if(status & RTIO_I_STATUS_OVERFLOW) {
|
if(status & RTIO_I_STATUS_OVERFLOW) {
|
||||||
rtio_i_overflow_reset_write(1);
|
rtio_i_overflow_reset_write(1);
|
||||||
artiq_raise_from_c("RTIOOverflow",
|
break;
|
||||||
"RTIO input overflow on channel {0}",
|
|
||||||
channel, 0, 0);
|
|
||||||
}
|
}
|
||||||
if(rtio_get_counter() >= timeout) {
|
if(rtio_get_counter() >= timeout) {
|
||||||
/* check empty flag again to prevent race condition.
|
/* check empty flag again to prevent race condition.
|
||||||
* now we are sure that the time limit has been exceeded.
|
* now we are sure that the time limit has been exceeded.
|
||||||
*/
|
*/
|
||||||
if(rtio_i_status_read() & RTIO_I_STATUS_EMPTY)
|
status = rtio_i_status_read();
|
||||||
artiq_raise_from_c("InternalError",
|
if(status & RTIO_I_STATUS_EMPTY)
|
||||||
"RTIO input timeout on channel {0}",
|
break;
|
||||||
channel, 0, 0);
|
|
||||||
}
|
}
|
||||||
/* input FIFO is empty - keep waiting */
|
/* input FIFO is empty - keep waiting */
|
||||||
}
|
}
|
||||||
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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_log_va(long long int timestamp, const char *format, va_list args);
|
||||||
void rtio_output(long long int timestamp, int channel, unsigned int address,
|
void rtio_output(long long int timestamp, int channel, unsigned int address,
|
||||||
unsigned int data);
|
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)
|
static inline void rtio_write_and_process_status(long long int timestamp, int channel)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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 ttl_get(int channel, long long int time_limit)
|
||||||
{
|
{
|
||||||
long long int r;
|
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();
|
r = rtio_i_timestamp_read();
|
||||||
rtio_i_re_write(1);
|
rtio_i_re_write(1);
|
||||||
return r;
|
return r;
|
||||||
|
|
Loading…
Reference in New Issue