runtime: refactor rt2wb/dds

This commit is contained in:
Robert Jördens 2016-02-29 19:16:29 +01:00
parent d3c94827eb
commit 5dae9f8aa8
6 changed files with 55 additions and 43 deletions

View File

@ -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 \ session.o log.o analyzer.o moninj.o net_server.o bridge_ctl.o \
ksupport_data.o kloader.o test_mode.o main.o ksupport_data.o kloader.o test_mode.o main.o
OBJECTS_KSUPPORT := ksupport.o artiq_personality.o mailbox.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) \ CFLAGS += -I$(LIBALLOC_DIRECTORY) \
-I$(MISOC_DIRECTORY)/software/include/dyld \ -I$(MISOC_DIRECTORY)/software/include/dyld \

View File

@ -2,7 +2,7 @@
#include <stdio.h> #include <stdio.h>
#include "artiq_personality.h" #include "artiq_personality.h"
#include "rtio.h" #include "rt2wb.h"
#include "log.h" #include "log.h"
#include "dds.h" #include "dds.h"
@ -26,10 +26,7 @@
#endif #endif
#define DDS_WRITE(addr, data) do { \ #define DDS_WRITE(addr, data) do { \
rtio_o_address_write(addr); \ rt2wb_write(now, CONFIG_RTIO_DDS_CHANNEL, addr, data); \
rtio_o_data_write(data); \
rtio_o_timestamp_write(now); \
rtio_write_and_process_status(now, CONFIG_RTIO_DDS_CHANNEL); \
now += DURATION_WRITE; \ now += DURATION_WRITE; \
} while(0) } while(0)
@ -37,8 +34,6 @@ void dds_init(long long int timestamp, int channel)
{ {
long long int now; long long int now;
rtio_chan_sel_write(CONFIG_RTIO_DDS_CHANNEL);
now = timestamp - DURATION_INIT; now = timestamp - DURATION_INIT;
#ifdef CONFIG_DDS_ONEHOT_SEL #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; unsigned int channel_enc;
if(channel >= CONFIG_DDS_CHANNEL_COUNT) { if(channel >= CONFIG_DDS_CHANNEL_COUNT) {
core_log("Attempted to set invalid DDS channel\n"); core_log("Attempted to set invalid DDS channel\n");
return; return;
} }
#ifdef CONFIG_DDS_ONEHOT_SEL #ifdef CONFIG_DDS_ONEHOT_SEL
channel_enc = 1 << channel; channel_enc = 1 << channel;
#else #else
@ -190,7 +185,6 @@ void dds_batch_exit(void)
if(!batch_mode) if(!batch_mode)
artiq_raise_from_c("DDSBatchError", "DDS batch error", 0, 0, 0); artiq_raise_from_c("DDSBatchError", "DDS batch error", 0, 0, 0);
rtio_chan_sel_write(CONFIG_RTIO_DDS_CHANNEL);
/* + FUD time */ /* + FUD time */
now = batch_ref_time - batch_count*(DURATION_PROGRAM + DURATION_WRITE); now = batch_ref_time - batch_count*(DURATION_PROGRAM + DURATION_WRITE);
for(i=0;i<batch_count;i++) { for(i=0;i<batch_count;i++) {
@ -216,7 +210,6 @@ void dds_set(long long int timestamp, int channel,
batch[batch_count].amplitude = amplitude; batch[batch_count].amplitude = amplitude;
batch_count++; batch_count++;
} else { } else {
rtio_chan_sel_write(CONFIG_RTIO_DDS_CHANNEL);
dds_set_one(timestamp - DURATION_PROGRAM, timestamp, channel, ftw, pow, phase_mode, dds_set_one(timestamp - DURATION_PROGRAM, timestamp, channel, ftw, pow, phase_mode,
amplitude); amplitude);
} }

View File

@ -8,40 +8,16 @@
void rt2wb_write(long long int timestamp, int channel, int addr, void rt2wb_write(long long int timestamp, int channel, int addr,
unsigned int data) unsigned int data)
{ {
rtio_chan_sel_write(channel); rtio_output(timestamp, channel, addr, data);
rtio_o_address_write(addr);
rtio_o_data_write(data);
rtio_o_timestamp_write(timestamp);
rtio_write_and_process_status(timestamp, channel);
} }
unsigned int rt2wb_read_sync(long long int timestamp, int channel, unsigned int rt2wb_read_sync(long long int timestamp, int channel, int addr,
int addr, int duration) int duration)
{ {
int status;
unsigned int data; unsigned int data;
rtio_output(timestamp, channel, addr, 0);
rt2wb_write(timestamp, channel, addr, 0); rtio_input_wait(timestamp + duration, channel);
while((status = rtio_i_status_read())) {
if(status & RTIO_I_STATUS_OVERFLOW) {
rtio_i_overflow_reset_write(1);
artiq_raise_from_c("RTIOOverflow",
"RT2WB overflow on channel {0}",
channel, 0, 0);
}
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)
artiq_raise_from_c("InternalError",
"RT2WB read failed on channel {0}",
channel, 0, 0);
}
/* input FIFO is empty - keep waiting */
}
data = rtio_i_data_read(); data = rtio_i_data_read();
rtio_i_re_write(1); rtio_i_re_write(1);
return data; return data;

View File

@ -1,6 +1,8 @@
#ifndef __RT2WB_H #ifndef __RT2WB_H
#define __RT2WB_H #define __RT2WB_H
#include "rtio.h"
void rt2wb_write(long long int timestamp, int channel, int address, void rt2wb_write(long long int timestamp, int channel, int address,
unsigned int data); unsigned int data);
unsigned int rt2wb_read_sync(long long int timestamp, int channel, int address, unsigned int rt2wb_read_sync(long long int timestamp, int channel, int address,

View File

@ -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) 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 // This executes on the kernel CPU's stack, which is specifically designed

View File

@ -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_process_exceptional_status(int status, long long int timestamp, int channel);
void rtio_log(long long int timestamp, const char *format, ...); 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_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) static inline void rtio_write_and_process_status(long long int timestamp, int channel)
{ {