runtime/rt2wb: use input/output terminology and add (async) input

This commit is contained in:
Robert Jördens 2016-03-01 00:21:32 +01:00
parent 764795a8fe
commit 7d7a710a56
6 changed files with 77 additions and 44 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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 */