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 \
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 \

View File

@ -2,7 +2,7 @@
#include <stdio.h>
#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<batch_count;i++) {
@ -216,7 +210,6 @@ void dds_set(long long int timestamp, int channel,
batch[batch_count].amplitude = amplitude;
batch_count++;
} else {
rtio_chan_sel_write(CONFIG_RTIO_DDS_CHANNEL);
dds_set_one(timestamp - DURATION_PROGRAM, timestamp, channel, ftw, pow, phase_mode,
amplitude);
}

View File

@ -8,40 +8,16 @@
void rt2wb_write(long long int timestamp, int channel, int addr,
unsigned int data)
{
rtio_chan_sel_write(channel);
rtio_o_address_write(addr);
rtio_o_data_write(data);
rtio_o_timestamp_write(timestamp);
rtio_write_and_process_status(timestamp, channel);
rtio_output(timestamp, channel, addr, data);
}
unsigned int rt2wb_read_sync(long long int timestamp, int channel,
int addr, int duration)
unsigned int rt2wb_read_sync(long long int timestamp, int channel, int addr,
int duration)
{
int status;
unsigned int data;
rt2wb_write(timestamp, channel, addr, 0);
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 */
}
rtio_output(timestamp, channel, addr, 0);
rtio_input_wait(timestamp + duration, channel);
data = rtio_i_data_read();
rtio_i_re_write(1);
return data;

View File

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

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)
{
// 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_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)
{