From df7d15d1fecb8e707f9618a28d344afb0e40bafb Mon Sep 17 00:00:00 2001 From: Robert Jordens Date: Mon, 29 Feb 2016 13:54:36 +0100 Subject: [PATCH] runtime: refactor spi into rt2wb --- artiq/coredevice/rt2wb.py | 14 ++++++++++ artiq/coredevice/spi.py | 45 +++++++++++++------------------- artiq/runtime/Makefile | 2 +- artiq/runtime/ksupport.c | 6 ++--- artiq/runtime/{spi.c => rt2wb.c} | 30 ++++++++++----------- artiq/runtime/rt2wb.h | 10 +++++++ artiq/runtime/spi.h | 20 -------------- 7 files changed, 60 insertions(+), 67 deletions(-) create mode 100644 artiq/coredevice/rt2wb.py rename artiq/runtime/{spi.c => rt2wb.c} (56%) create mode 100644 artiq/runtime/rt2wb.h delete mode 100644 artiq/runtime/spi.h diff --git a/artiq/coredevice/rt2wb.py b/artiq/coredevice/rt2wb.py new file mode 100644 index 000000000..150afd1fb --- /dev/null +++ b/artiq/coredevice/rt2wb.py @@ -0,0 +1,14 @@ +from artiq.language.core import * +from artiq.language.types import * + + +@syscall +def rt2wb_write(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: + raise NotImplementedError("syscall not simulated") diff --git a/artiq/coredevice/spi.py b/artiq/coredevice/spi.py index 6265ff3b6..4145a5513 100644 --- a/artiq/coredevice/spi.py +++ b/artiq/coredevice/spi.py @@ -1,16 +1,6 @@ from artiq.language.core import * from artiq.language.types import * - - -@syscall -def spi_write(time_mu: TInt64, channel: TInt32, addr: TInt32, data: TInt32 - ) -> TNone: - raise NotImplementedError("syscall not simulated") - - -@syscall -def spi_read(time_mu: TInt64, channel: TInt32, addr: TInt32) -> TInt32: - raise NotImplementedError("syscall not simulated") +from artiq.coredevice.rt2wb import * SPI_DATA_ADDR, SPI_XFER_ADDR, SPI_CONFIG_ADDR = range(3) @@ -34,14 +24,14 @@ class SPIMaster: """ def __init__(self, dmgr, ref_period, channel): self.core = dmgr.get("core") - self.ref_period_mu = int(seconds_to_mu(ref_period, self.core), 64) + self.ref_period_mu = seconds_to_mu(ref_period, self.core) self.channel = channel self.write_div = 0 self.read_div = 0 # a full transfer takes prep_mu + xfer_mu - self.prep_mu = int(0, 64) - # chaned transfers can happen every xfer_mu - self.xfer_mu = int(0, 64) + self.prep_mu = 0 + # chained transfers can happen every xfer_mu + self.xfer_mu = 0 # The second transfer of a chain be written ref_period_mu # after the first. Read data is available every xfer_mu starting # a bit before prep_mu + xfer_mu. @@ -49,40 +39,41 @@ class SPIMaster: @portable def predict_xfer_mu(self, write_length, read_length): # this is only the intrinsic bit cycle duration - return self.ref_period_mu*( + return int(self.ref_period_mu*( write_length*self.write_div + - read_length*self.read_div) + read_length*self.read_div)) @portable def predict_prep_mu(self, write_div): - return self.ref_period_mu*( + return int(self.ref_period_mu*( 2 + # intermediate transfers # one write_div for the wait+idle cycle - self.write_div) + self.write_div)) @kernel def set_config(self, flags=0, write_div=6, read_div=6): self.write_div = write_div self.read_div = read_div self.prep_mu = self.predict_prep_mu(write_div) - spi_write(now_mu(), self.channel, SPI_CONFIG_ADDR, flags | - ((write_div - 2) << 8) | ((read_div - 2) << 20)) + rt2wb_write(now_mu(), self.channel, SPI_CONFIG_ADDR, flags | + ((write_div - 2) << 8) | ((read_div - 2) << 20)) delay_mu(self.ref_period_mu) @kernel def set_xfer(self, chip_select=0, write_length=0, read_length=0): self.xfer_mu = self.predict_xfer_mu(write_length, read_length) - spi_write(now_mu(), self.channel, SPI_XFER_ADDR, - chip_select | (write_length << 16) | (read_length << 24)) + rt2wb_write(now_mu(), self.channel, SPI_XFER_ADDR, + chip_select | (write_length << 16) | (read_length << 24)) delay_mu(self.ref_period_mu) @kernel def write(self, data): - spi_write(now_mu(), self.channel, SPI_DATA_ADDR, data) - delay_mu(self.prep_mu + self.xfer_mu) + rt2wb_write(now_mu(), self.channel, SPI_DATA_ADDR, data) + delay_mu(int(self.prep_mu + self.xfer_mu)) @kernel - def read(self): - r = spi_read(now_mu(), self.channel, SPI_DATA_ADDR) + def read_sync(self): + r = rt2wb_read_sync(now_mu(), self.channel, SPI_DATA_ADDR, + int(self.ref_period_mu)) delay_mu(self.ref_period_mu) return r diff --git a/artiq/runtime/Makefile b/artiq/runtime/Makefile index 46e3aedb9..045a162fe 100644 --- a/artiq/runtime/Makefile +++ b/artiq/runtime/Makefile @@ -7,7 +7,7 @@ OBJECTS := isr.o clock.o rtiocrg.o flash_storage.o mailbox.o \ session.o log.o analyzer.o moninj.o net_server.o bridge_ctl.o \ ksupport_data.o kloader.o test_mode.o main.o OBJECTS_KSUPPORT := ksupport.o artiq_personality.o mailbox.o \ - bridge.o rtio.o ttl.o dds.o spi.o + bridge.o rtio.o ttl.o dds.o rt2wb.o CFLAGS += -I$(LIBALLOC_DIRECTORY) \ -I$(MISOC_DIRECTORY)/software/include/dyld \ diff --git a/artiq/runtime/ksupport.c b/artiq/runtime/ksupport.c index bcdd7d028..892f66ccb 100644 --- a/artiq/runtime/ksupport.c +++ b/artiq/runtime/ksupport.c @@ -15,8 +15,8 @@ #include "artiq_personality.h" #include "ttl.h" #include "dds.h" -#include "spi.h" #include "rtio.h" +#include "rt2wb.h" double round(double x); @@ -122,8 +122,8 @@ static const struct symbol runtime_exports[] = { {"dds_batch_exit", &dds_batch_exit}, {"dds_set", &dds_set}, - {"spi_write", &spi_write}, - {"spi_read", &spi_read}, + {"rt2wb_write", &rt2wb_write}, + {"rt2wb_read_sync", &rt2wb_read_sync}, {"cache_get", &cache_get}, {"cache_put", &cache_put}, diff --git a/artiq/runtime/spi.c b/artiq/runtime/rt2wb.c similarity index 56% rename from artiq/runtime/spi.c rename to artiq/runtime/rt2wb.c index 17e86dea7..0758bb6d5 100644 --- a/artiq/runtime/spi.c +++ b/artiq/runtime/rt2wb.c @@ -1,15 +1,11 @@ #include -#include #include "artiq_personality.h" #include "rtio.h" -#include "log.h" -#include "spi.h" +#include "rt2wb.h" -#define DURATION_WRITE (1 << CONFIG_RTIO_FINE_TS_WIDTH) - -void spi_write(long long int timestamp, int channel, int addr, +void rt2wb_write(long long int timestamp, int channel, int addr, unsigned int data) { rtio_chan_sel_write(channel); @@ -20,31 +16,33 @@ void spi_write(long long int timestamp, int channel, int addr, } -unsigned int spi_read(long long int timestamp, int channel, int addr) +unsigned int rt2wb_read_sync(long long int timestamp, int channel, + int addr, int duration) { int status; - long long int time_limit = timestamp + DURATION_WRITE; - unsigned int r; + unsigned int data; - spi_write(timestamp, channel, addr | SPI_WB_READ, 0); + rt2wb_write(timestamp, channel, addr, 0); while((status = rtio_i_status_read())) { - if(rtio_i_status_read() & RTIO_I_STATUS_OVERFLOW) { + if(status & RTIO_I_STATUS_OVERFLOW) { rtio_i_overflow_reset_write(1); artiq_raise_from_c("RTIOOverflow", - "RTIO overflow at channel {0}", + "RTIO WB overflow on channel {0}", channel, 0, 0); } - if(rtio_get_counter() >= time_limit) { + if(rtio_get_counter() >= timestamp + duration) { /* 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) - return -1; + artiq_raise_from_c("InternalError", + "RTIO WB read failed on channel {0}", + channel, 0, 0); } /* input FIFO is empty - keep waiting */ } - r = rtio_i_data_read(); + data = rtio_i_data_read(); rtio_i_re_write(1); - return r; + return data; } diff --git a/artiq/runtime/rt2wb.h b/artiq/runtime/rt2wb.h new file mode 100644 index 000000000..f2cbe57d4 --- /dev/null +++ b/artiq/runtime/rt2wb.h @@ -0,0 +1,10 @@ +#ifndef __RT2WB_H +#define __RT2WB_H + +void rt2wb_write(long long int timestamp, int channel, int address, + unsigned int data); +unsigned int rt2wb_read_sync(long long int timestamp, int channel, int address, + int duration); + +#endif /* __RT2WB_H */ + diff --git a/artiq/runtime/spi.h b/artiq/runtime/spi.h deleted file mode 100644 index 6a5ba08f1..000000000 --- a/artiq/runtime/spi.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef __SPI_H -#define __SPI_H - -#include -#include -#include - -#define SPI_ADDR_DATA 0 -#define SPI_ADDR_XFER 1 -#define SPI_ADDR_CONFIG 2 -#define SPI_WB_READ (1 << 2) - -#define SPI_XFER_CS(x) (x) -#define SPI_XFER_WRITE_LENGTH(x) ((x) << 16) -#define SPI_XFER_READ_LENGTH(x) ((x) << 24) - -void spi_write(long long int timestamp, int channel, int address, unsigned int data); -unsigned int spi_read(long long int timestamp, int channel, int address); - -#endif /* __SPI_H */