forked from M-Labs/artiq
rt2wb, exceptions: remove RTIOTimeout
Assume that rt2wb transactions either collide and are then reported (https://github.com/m-labs/artiq/issues/308) or that they complete and the delay with which they complete does not matter. If a transaction is ack'ed with a delay because the WB core's downstream logic is busy, that may lead to a later collision with another WB transaction.
This commit is contained in:
parent
c2fe9a08ae
commit
324660ab40
|
@ -1,13 +1,12 @@
|
||||||
from artiq.coredevice import exceptions, dds, spi
|
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", "RTIOTimeout"]
|
"RTIOOverflow", "DDSBatchError", "CacheError"]
|
||||||
__all__ += ["PHASE_MODE_CONTINUOUS", "PHASE_MODE_ABSOLUTE",
|
__all__ += ["PHASE_MODE_CONTINUOUS", "PHASE_MODE_ABSOLUTE",
|
||||||
"PHASE_MODE_TRACKING"]
|
"PHASE_MODE_TRACKING"]
|
||||||
|
|
|
@ -108,17 +108,6 @@ 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.
|
||||||
|
|
|
@ -11,8 +11,3 @@ def rt2wb_output(time_mu: TInt64, channel: TInt32, addr: TInt32, data: TInt32
|
||||||
@syscall
|
@syscall
|
||||||
def rt2wb_input(channel: TInt32) -> TInt32:
|
def rt2wb_input(channel: TInt32) -> TInt32:
|
||||||
raise NotImplementedError("syscall not simulated")
|
raise NotImplementedError("syscall not simulated")
|
||||||
|
|
||||||
|
|
||||||
@syscall
|
|
||||||
def rt2wb_input_sync(timeout_mu: TInt64, channel: TInt32) -> TInt32:
|
|
||||||
raise NotImplementedError("syscall not simulated")
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
from artiq.language.core import (kernel, portable, seconds_to_mu, now_mu,
|
from artiq.language.core import (kernel, portable, seconds_to_mu, now_mu,
|
||||||
delay_mu, int)
|
delay_mu, int)
|
||||||
from artiq.language.units import MHz
|
from artiq.language.units import MHz
|
||||||
from artiq.coredevice.rt2wb import rt2wb_output, rt2wb_input, rt2wb_input_sync
|
from artiq.coredevice.rt2wb import rt2wb_output, rt2wb_input
|
||||||
|
|
||||||
|
|
||||||
SPI_DATA_ADDR, SPI_XFER_ADDR, SPI_CONFIG_ADDR = range(3)
|
SPI_DATA_ADDR, SPI_XFER_ADDR, SPI_CONFIG_ADDR = range(3)
|
||||||
|
@ -55,17 +55,12 @@ class SPIMaster:
|
||||||
self.read_period_mu = int(read_div*self.ref_period_mu)
|
self.read_period_mu = int(read_div*self.ref_period_mu)
|
||||||
delay_mu(3*self.ref_period_mu)
|
delay_mu(3*self.ref_period_mu)
|
||||||
|
|
||||||
@portable
|
|
||||||
def get_xfer_period_mu(self, write_length, read_length):
|
|
||||||
return int(write_length*self.write_period_mu +
|
|
||||||
read_length*self.read_period_mu)
|
|
||||||
|
|
||||||
@kernel
|
@kernel
|
||||||
def set_xfer(self, chip_select=0, write_length=0, read_length=0):
|
def set_xfer(self, chip_select=0, write_length=0, read_length=0):
|
||||||
rt2wb_output(now_mu(), self.channel, SPI_XFER_ADDR,
|
rt2wb_output(now_mu(), self.channel, SPI_XFER_ADDR,
|
||||||
chip_select | (write_length << 16) | (read_length << 24))
|
chip_select | (write_length << 16) | (read_length << 24))
|
||||||
self.xfer_period_mu = self.get_xfer_period_mu(write_length,
|
self.xfer_period_mu = int(write_length*self.write_period_mu +
|
||||||
read_length)
|
read_length*self.read_period_mu)
|
||||||
delay_mu(3*self.ref_period_mu)
|
delay_mu(3*self.ref_period_mu)
|
||||||
|
|
||||||
@kernel
|
@kernel
|
||||||
|
@ -74,28 +69,28 @@ class SPIMaster:
|
||||||
delay_mu(3*self.ref_period_mu)
|
delay_mu(3*self.ref_period_mu)
|
||||||
|
|
||||||
@kernel
|
@kernel
|
||||||
def read(self):
|
def read_async(self):
|
||||||
|
# every read_async() must be matched by an input_async()
|
||||||
rt2wb_output(now_mu(), self.channel, SPI_DATA_ADDR | SPI_RT2WB_READ, 0)
|
rt2wb_output(now_mu(), self.channel, SPI_DATA_ADDR | SPI_RT2WB_READ, 0)
|
||||||
delay_mu(3*self.ref_period_mu)
|
delay_mu(3*self.ref_period_mu)
|
||||||
|
|
||||||
@kernel
|
@kernel
|
||||||
def input(self):
|
def input_async(self):
|
||||||
|
# matches the preeeding read_async()
|
||||||
return rt2wb_input(self.channel)
|
return rt2wb_input(self.channel)
|
||||||
|
|
||||||
@kernel
|
|
||||||
def _rt2wb_read_sync(self, addr=0):
|
|
||||||
t = now_mu()
|
|
||||||
rt2wb_output(t, self.channel, addr | SPI_RT2WB_READ, 0)
|
|
||||||
return rt2wb_input_sync(t + 3*self.ref_period_mu, self.channel)
|
|
||||||
|
|
||||||
@kernel
|
@kernel
|
||||||
def read_sync(self):
|
def read_sync(self):
|
||||||
return self._rt2wb_read_sync(SPI_DATA_ADDR)
|
rt2wb_output(now_mu(), self.channel, SPI_DATA_ADDR | SPI_RT2WB_READ, 0)
|
||||||
|
return rt2wb_input(self.channel)
|
||||||
@kernel
|
|
||||||
def _get_config_sync(self):
|
|
||||||
return self._rt2wb_read_sync(SPI_CONFIG_ADDR)
|
|
||||||
|
|
||||||
@kernel
|
@kernel
|
||||||
def _get_xfer_sync(self):
|
def _get_xfer_sync(self):
|
||||||
return self._rt2wb_read_sync(SPI_XFER_ADDR)
|
rt2wb_output(now_mu(), self.channel, SPI_XFER_ADDR | SPI_RT2WB_READ, 0)
|
||||||
|
return rt2wb_input(self.channel)
|
||||||
|
|
||||||
|
@kernel
|
||||||
|
def _get_config_sync(self):
|
||||||
|
rt2wb_output(now_mu(), self.channel, SPI_CONFIG_ADDR | SPI_RT2WB_READ,
|
||||||
|
0)
|
||||||
|
return rt2wb_input(self.channel)
|
||||||
|
|
|
@ -124,7 +124,6 @@ static const struct symbol runtime_exports[] = {
|
||||||
|
|
||||||
{"rt2wb_output", &rt2wb_output},
|
{"rt2wb_output", &rt2wb_output},
|
||||||
{"rt2wb_input", &rt2wb_input},
|
{"rt2wb_input", &rt2wb_input},
|
||||||
{"rt2wb_input_sync", &rt2wb_input_sync},
|
|
||||||
|
|
||||||
{"cache_get", &cache_get},
|
{"cache_get", &cache_get},
|
||||||
{"cache_put", &cache_put},
|
{"cache_put", &cache_put},
|
||||||
|
|
|
@ -18,38 +18,14 @@ unsigned int rt2wb_input(int channel)
|
||||||
int status;
|
int status;
|
||||||
|
|
||||||
rtio_chan_sel_write(channel);
|
rtio_chan_sel_write(channel);
|
||||||
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",
|
artiq_raise_from_c("RTIOOverflow",
|
||||||
"RT2WB input overflow on channel {0}",
|
"RT2WB input overflow on channel {0}",
|
||||||
channel, 0, 0);
|
channel, 0, 0);
|
||||||
}
|
}
|
||||||
if (status & RTIO_I_STATUS_EMPTY)
|
}
|
||||||
artiq_raise_from_c("RTIOTimeout",
|
|
||||||
"RT2WB input timeout on channel {0}",
|
|
||||||
channel, 0, 0);
|
|
||||||
|
|
||||||
data = rtio_i_data_read();
|
|
||||||
rtio_i_re_write(1);
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
unsigned int rt2wb_input_sync(long long int timeout, int channel)
|
|
||||||
{
|
|
||||||
unsigned int data;
|
|
||||||
int status;
|
|
||||||
|
|
||||||
status = rtio_input_wait(timeout, channel);
|
|
||||||
if (status & RTIO_I_STATUS_OVERFLOW)
|
|
||||||
artiq_raise_from_c("RTIOOverflow",
|
|
||||||
"RT2WB input overflow on channel {0}",
|
|
||||||
channel, 0, 0);
|
|
||||||
if (status & RTIO_I_STATUS_EMPTY)
|
|
||||||
artiq_raise_from_c("RTIOTimeout",
|
|
||||||
"RT2WB input 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);
|
||||||
|
|
Loading…
Reference in New Issue