diff --git a/artiq/runtime/Makefile b/artiq/runtime/Makefile index 045a162fe..7915f4d0e 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 rt2wb.o + bridge.o rtio.o ttl.o rt2wb.o dds.o CFLAGS += -I$(LIBALLOC_DIRECTORY) \ -I$(MISOC_DIRECTORY)/software/include/dyld \ diff --git a/artiq/runtime/dds.c b/artiq/runtime/dds.c index 396e652eb..fb9d34b05 100644 --- a/artiq/runtime/dds.c +++ b/artiq/runtime/dds.c @@ -2,7 +2,7 @@ #include #include "artiq_personality.h" -#include "rtio.h" +#include "rt2wb.h" #include "log.h" #include "dds.h" @@ -26,10 +26,7 @@ #endif #define DDS_WRITE(addr, data) do { \ - rtio_o_address_write(addr); \ - rtio_o_data_write(data); \ - rtio_o_timestamp_write(now); \ - rtio_write_and_process_status(now, CONFIG_RTIO_DDS_CHANNEL); \ + rt2wb_write(now, CONFIG_RTIO_DDS_CHANNEL, addr, data); \ now += DURATION_WRITE; \ } while(0) @@ -37,8 +34,6 @@ void dds_init(long long int timestamp, int channel) { long long int now; - rtio_chan_sel_write(CONFIG_RTIO_DDS_CHANNEL); - now = timestamp - DURATION_INIT; #ifdef CONFIG_DDS_ONEHOT_SEL @@ -94,10 +89,10 @@ static void dds_set_one(long long int now, long long int ref_time, unsigned int { unsigned int channel_enc; - if(channel >= CONFIG_DDS_CHANNEL_COUNT) { - core_log("Attempted to set invalid DDS channel\n"); - return; - } + if(channel >= CONFIG_DDS_CHANNEL_COUNT) { + core_log("Attempted to set invalid DDS channel\n"); + return; + } #ifdef CONFIG_DDS_ONEHOT_SEL channel_enc = 1 << channel; #else @@ -190,7 +185,6 @@ void dds_batch_exit(void) if(!batch_mode) artiq_raise_from_c("DDSBatchError", "DDS batch error", 0, 0, 0); - rtio_chan_sel_write(CONFIG_RTIO_DDS_CHANNEL); /* + FUD time */ now = batch_ref_time - batch_count*(DURATION_PROGRAM + DURATION_WRITE); for(i=0;i= 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) - artiq_raise_from_c("InternalError", - "RT2WB read failed on channel {0}", - channel, 0, 0); - } - /* input FIFO is empty - keep waiting */ - } + rtio_output(timestamp, channel, addr, 0); + rtio_input_wait(timestamp + duration, channel); data = rtio_i_data_read(); rtio_i_re_write(1); return data; diff --git a/artiq/runtime/rt2wb.h b/artiq/runtime/rt2wb.h index f2cbe57d4..afae9a5a7 100644 --- a/artiq/runtime/rt2wb.h +++ b/artiq/runtime/rt2wb.h @@ -1,6 +1,8 @@ #ifndef __RT2WB_H #define __RT2WB_H +#include "rtio.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, diff --git a/artiq/runtime/rtio.c b/artiq/runtime/rtio.c index 76514d19a..1680dbb6f 100644 --- a/artiq/runtime/rtio.c +++ b/artiq/runtime/rtio.c @@ -39,6 +39,44 @@ void rtio_process_exceptional_status(int status, long long int timestamp, int ch } } + +void rtio_output(long long int timestamp, int channel, unsigned int addr, + unsigned int data) +{ + rtio_chan_sel_write(channel); + rtio_o_timestamp_write(timestamp); + rtio_o_address_write(addr); + rtio_o_data_write(data); + rtio_write_and_process_status(timestamp, channel); +} + + +void rtio_input_wait(long long int timeout, int channel) +{ + int status; + + rtio_chan_sel_write(channel); + while((status = rtio_i_status_read())) { + if(status & RTIO_I_STATUS_OVERFLOW) { + rtio_i_overflow_reset_write(1); + artiq_raise_from_c("RTIOOverflow", + "RTIO input overflow on channel {0}", + channel, 0, 0); + } + if(rtio_get_counter() >= timeout) { + /* 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) + artiq_raise_from_c("InternalError", + "RTIO input timeout on channel {0}", + channel, 0, 0); + } + /* input FIFO is empty - keep waiting */ + } +} + + void rtio_log_va(long long int timestamp, const char *fmt, va_list args) { // This executes on the kernel CPU's stack, which is specifically designed diff --git a/artiq/runtime/rtio.h b/artiq/runtime/rtio.h index 87d8a9f37..1214b40c8 100644 --- a/artiq/runtime/rtio.h +++ b/artiq/runtime/rtio.h @@ -17,6 +17,9 @@ long long int rtio_get_counter(void); void rtio_process_exceptional_status(int status, long long int timestamp, int channel); 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_output(long long int timestamp, int channel, unsigned int address, + unsigned int data); +void rtio_input_wait(long long int timeout, int channel); static inline void rtio_write_and_process_status(long long int timestamp, int channel) {