From 7d7a710a561b77618d7a321c64ca77ea5a868441 Mon Sep 17 00:00:00 2001 From: Robert Jordens Date: Tue, 1 Mar 2016 00:21:32 +0100 Subject: [PATCH] runtime/rt2wb: use input/output terminology and add (async) input --- artiq/coredevice/rt2wb.py | 12 ++++++--- artiq/coredevice/spi.py | 57 ++++++++++++++++++++++----------------- artiq/runtime/dds.c | 2 +- artiq/runtime/ksupport.c | 5 ++-- artiq/runtime/rt2wb.c | 39 ++++++++++++++++++++------- artiq/runtime/rt2wb.h | 6 ++--- 6 files changed, 77 insertions(+), 44 deletions(-) diff --git a/artiq/coredevice/rt2wb.py b/artiq/coredevice/rt2wb.py index 150afd1fb..80d1cb041 100644 --- a/artiq/coredevice/rt2wb.py +++ b/artiq/coredevice/rt2wb.py @@ -3,12 +3,16 @@ from artiq.language.types import * @syscall -def rt2wb_write(time_mu: TInt64, channel: TInt32, addr: TInt32, data: TInt32 - ) -> TNone: +def rt2wb_output(time_mu: TInt64, channel: TInt32, addr: TInt32, data: TInt32 + ) -> TNone: raise NotImplementedError("syscall not simulated") @syscall -def rt2wb_read_sync(time_mu: TInt64, channel: TInt32, addr: TInt32, - duration_mu: TInt32) -> TInt32: +def rt2wb_input(channel: TInt32) -> TInt32: + raise NotImplementedError("syscall not simulated") + + +@syscall +def rt2wb_input_sync(timeout_mu: TInt64, channel: TInt32) -> TInt32: raise NotImplementedError("syscall not simulated") diff --git a/artiq/coredevice/spi.py b/artiq/coredevice/spi.py index 330ddd168..c0daba932 100644 --- a/artiq/coredevice/spi.py +++ b/artiq/coredevice/spi.py @@ -1,7 +1,7 @@ from artiq.language.core import (kernel, portable, seconds_to_mu, now_mu, - delay_mu) + delay_mu, int) from artiq.language.units import MHz -from artiq.coredevice.rt2wb import rt2wb_write, rt2wb_read_sync +from artiq.coredevice.rt2wb import rt2wb_output, rt2wb_input, rt2wb_input_sync SPI_DATA_ADDR, SPI_XFER_ADDR, SPI_CONFIG_ADDR = range(3) @@ -28,11 +28,11 @@ class SPIMaster: def __init__(self, dmgr, ref_period, channel): self.core = dmgr.get("core") self.ref_period = ref_period - self.ref_period_mu = seconds_to_mu(ref_period, self.core) + self.ref_period_mu = int(seconds_to_mu(ref_period, self.core)) self.channel = channel - self.write_period_mu = 0 - self.read_period_mu = 0 - self.xfer_period_mu = 0 + self.write_period_mu = int(0) + self.read_period_mu = int(0) + self.xfer_period_mu = int(0) # A full transfer takes write_period_mu + xfer_period_mu. # Chained transfers can happen every xfer_period_mu. # The second transfer of a chain can be written 2*ref_period_mu @@ -49,11 +49,11 @@ class SPIMaster: @kernel def set_config_mu(self, flags=0, write_div=6, read_div=6): - rt2wb_write(now_mu(), self.channel, SPI_CONFIG_ADDR, flags | - ((write_div - 2) << 16) | ((read_div - 2) << 24)) + rt2wb_output(now_mu(), self.channel, SPI_CONFIG_ADDR, flags | + ((write_div - 2) << 16) | ((read_div - 2) << 24)) self.write_period_mu = int(write_div*self.ref_period_mu) self.read_period_mu = int(read_div*self.ref_period_mu) - delay_mu(2*self.ref_period_mu) + delay_mu(3*self.ref_period_mu) @portable def get_xfer_period_mu(self, write_length, read_length): @@ -62,33 +62,40 @@ class SPIMaster: @kernel def set_xfer(self, chip_select=0, write_length=0, read_length=0): - rt2wb_write(now_mu(), self.channel, SPI_XFER_ADDR, - chip_select | (write_length << 16) | (read_length << 24)) - self.xfer_period_mu = self.get_xfer_period_mu( - write_length, read_length) - delay_mu(int(2*self.ref_period_mu)) + rt2wb_output(now_mu(), self.channel, SPI_XFER_ADDR, + chip_select | (write_length << 16) | (read_length << 24)) + self.xfer_period_mu = self.get_xfer_period_mu(write_length, + read_length) + delay_mu(3*self.ref_period_mu) @kernel def write(self, data): - rt2wb_write(now_mu(), self.channel, SPI_DATA_ADDR, data) - delay_mu(int(self.write_period_mu + self.xfer_period_mu)) + rt2wb_output(now_mu(), self.channel, SPI_DATA_ADDR, data) + delay_mu(3*self.ref_period_mu) @kernel - def read_async(self): - rt2wb_write(now_mu(), self.channel, SPI_DATA_ADDR | SPI_RT2WB_READ, 0) - delay_mu(int(2*self.ref_period_mu)) + def read(self): + rt2wb_output(now_mu(), self.channel, SPI_DATA_ADDR | SPI_RT2WB_READ, 0) + delay_mu(3*self.ref_period_mu) + + @kernel + def input(self): + 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 def read_sync(self): - return rt2wb_read_sync(now_mu(), self.channel, SPI_DATA_ADDR | - SPI_RT2WB_READ, int(2*self.ref_period_mu)) + return self._rt2wb_read_sync(SPI_DATA_ADDR) @kernel def _get_config_sync(self): - return rt2wb_read_sync(now_mu(), self.channel, SPI_CONFIG_ADDR | - SPI_RT2WB_READ, int(2*self.ref_period_mu)) + return self._rt2wb_read_sync(SPI_CONFIG_ADDR) @kernel def _get_xfer_sync(self): - return rt2wb_read_sync(now_mu(), self.channel, SPI_XFER_ADDR | - SPI_RT2WB_READ, int(2*self.ref_period_mu)) + return self._rt2wb_read_sync(SPI_XFER_ADDR) diff --git a/artiq/runtime/dds.c b/artiq/runtime/dds.c index fb9d34b05..f76da5724 100644 --- a/artiq/runtime/dds.c +++ b/artiq/runtime/dds.c @@ -26,7 +26,7 @@ #endif #define DDS_WRITE(addr, data) do { \ - rt2wb_write(now, CONFIG_RTIO_DDS_CHANNEL, addr, data); \ + rt2wb_output(now, CONFIG_RTIO_DDS_CHANNEL, addr, data); \ now += DURATION_WRITE; \ } while(0) diff --git a/artiq/runtime/ksupport.c b/artiq/runtime/ksupport.c index 892f66ccb..a95744450 100644 --- a/artiq/runtime/ksupport.c +++ b/artiq/runtime/ksupport.c @@ -122,8 +122,9 @@ static const struct symbol runtime_exports[] = { {"dds_batch_exit", &dds_batch_exit}, {"dds_set", &dds_set}, - {"rt2wb_write", &rt2wb_write}, - {"rt2wb_read_sync", &rt2wb_read_sync}, + {"rt2wb_output", &rt2wb_output}, + {"rt2wb_input", &rt2wb_input}, + {"rt2wb_input_sync", &rt2wb_input_sync}, {"cache_get", &cache_get}, {"cache_put", &cache_put}, diff --git a/artiq/runtime/rt2wb.c b/artiq/runtime/rt2wb.c index 30742ed24..3956028db 100644 --- a/artiq/runtime/rt2wb.c +++ b/artiq/runtime/rt2wb.c @@ -5,29 +5,50 @@ #include "rt2wb.h" -void rt2wb_write(long long int timestamp, int channel, int addr, +void rt2wb_output(long long int timestamp, int channel, int addr, unsigned int data) { rtio_output(timestamp, channel, addr, data); } -unsigned int rt2wb_read_sync(long long int timestamp, int channel, int addr, - int duration) +unsigned int rt2wb_input(int channel) { unsigned int data; int status; - rtio_output(timestamp, channel, addr, 0); - - status = rtio_input_wait(timestamp + duration, channel); - if (status & RTIO_I_STATUS_OVERFLOW) + rtio_chan_sel_write(channel); + status = rtio_i_status_read(); + if (status & RTIO_I_STATUS_OVERFLOW) { + rtio_i_overflow_reset_write(1); artiq_raise_from_c("RTIOOverflow", - "RT2WB read overflow on channel {0}", + "RT2WB input overflow on channel {0}", channel, 0, 0); + } if (status & RTIO_I_STATUS_EMPTY) artiq_raise_from_c("RTIOTimeout", - "RT2WB read timeout on channel {0}", + "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(); diff --git a/artiq/runtime/rt2wb.h b/artiq/runtime/rt2wb.h index afae9a5a7..d421397f4 100644 --- a/artiq/runtime/rt2wb.h +++ b/artiq/runtime/rt2wb.h @@ -3,10 +3,10 @@ #include "rtio.h" -void rt2wb_write(long long int timestamp, int channel, int address, +void rt2wb_output(long long int timestamp, int channel, int addr, unsigned int data); -unsigned int rt2wb_read_sync(long long int timestamp, int channel, int address, - int duration); +unsigned int rt2wb_input(int channel); +unsigned int rt2wb_input_sync(long long int timeout, int channel); #endif /* __RT2WB_H */