runtime: support DDS batches

This commit is contained in:
Sebastien Bourdeauducq 2015-05-08 16:51:54 +08:00
parent 53c6339307
commit 55f2fef576
6 changed files with 74 additions and 11 deletions

View File

@ -22,6 +22,8 @@ _syscalls = {
"ttl_set_sensitivity": "Iii:n", "ttl_set_sensitivity": "Iii:n",
"ttl_get": "iI:I", "ttl_get": "iI:I",
"dds_init": "Ii:n", "dds_init": "Ii:n",
"dds_batch_enter": "I:n",
"dds_batch_exit": "n:n",
"dds_set": "Iiiii:n", "dds_set": "Iiiii:n",
} }

View File

@ -6,9 +6,7 @@ from artiq.language.core import RuntimeException
# Must be kept in sync with soc/runtime/exceptions.h # Must be kept in sync with soc/runtime/exceptions.h
class InternalError(RuntimeException): class InternalError(RuntimeException):
"""Raised when the runtime encounters an internal error condition. """Raised when the runtime encounters an internal error condition."""
"""
eid = 1 eid = 1
@ -21,7 +19,6 @@ class RTIOUnderflow(RuntimeException):
(with respect to the event's timestamp). (with respect to the event's timestamp).
The offending event is discarded and the RTIO core keeps operating. The offending event is discarded and the RTIO core keeps operating.
""" """
eid = 3 eid = 3
@ -37,7 +34,6 @@ class RTIOSequenceError(RuntimeException):
not larger than the previous one. not larger than the previous one.
The offending event is discarded and the RTIO core keeps operating. The offending event is discarded and the RTIO core keeps operating.
""" """
eid = 4 eid = 4
@ -53,7 +49,6 @@ class RTIOOverflow(RuntimeException):
This does not interrupt operations further than cancelling the current This does not interrupt operations further than cancelling the current
read attempt and discarding some events. Reading can be reattempted after read attempt and discarding some events. Reading can be reattempted after
the exception is caught, and events will be partially retrieved. the exception is caught, and events will be partially retrieved.
""" """
eid = 5 eid = 5
@ -61,6 +56,13 @@ class RTIOOverflow(RuntimeException):
return "on channel {}".format(self.p0) return "on channel {}".format(self.p0)
class DDSBatchError(RuntimeException):
"""Raised when attempting to start a DDS batch while already in a batch,
or when too many commands are batched.
"""
eid = 6
exception_map = {e.eid: e for e in globals().values() exception_map = {e.eid: e for e in globals().values()
if inspect.isclass(e) if inspect.isclass(e)
and issubclass(e, RuntimeException) and issubclass(e, RuntimeException)

View File

@ -1,6 +1,7 @@
#include <generated/csr.h> #include <generated/csr.h>
#include <stdio.h> #include <stdio.h>
#include "exceptions.h"
#include "rtio.h" #include "rtio.h"
#include "dds.h" #include "dds.h"
@ -57,13 +58,62 @@ static void dds_set_one(long long int now, long long int timestamp, int channel,
DDS_WRITE(DDS_POW1, (pow >> 8) & 0x3f); DDS_WRITE(DDS_POW1, (pow >> 8) & 0x3f);
} }
struct dds_set_params {
int channel;
unsigned int ftw;
unsigned int pow;
int phase_mode;
};
static int batch_mode;
static int batch_count;
static long long int batch_fud_time;
static struct dds_set_params batch[DDS_MAX_BATCH];
void dds_batch_enter(long long int timestamp)
{
if(batch_mode)
exception_raise(EID_DDS_BATCH_ERROR);
batch_mode = 1;
batch_count = 0;
batch_fud_time = timestamp;
}
void dds_batch_exit(void)
{
long long int now;
int i;
if(!batch_mode)
exception_raise(EID_DDS_BATCH_ERROR);
now = batch_fud_time - batch_count*DURATION_PROGRAM;
for(i=0;i<batch_count;i++) {
dds_set_one(now, batch_fud_time,
batch[i].channel, batch[i].ftw, batch[i].pow, batch[i].phase_mode);
now += DURATION_PROGRAM;
}
DDS_WRITE(DDS_FUD, 0);
batch_mode = 0;
}
void dds_set(long long int timestamp, int channel, void dds_set(long long int timestamp, int channel,
unsigned int ftw, unsigned int pow, int phase_mode) unsigned int ftw, unsigned int pow, int phase_mode)
{ {
long long int now; if(batch_mode) {
if(batch_count >= DDS_MAX_BATCH)
exception_raise(EID_DDS_BATCH_ERROR);
/* timestamp parameter ignored (determined by batch) */
batch[batch_count].channel = channel;
batch[batch_count].ftw = ftw;
batch[batch_count].pow = pow;
batch[batch_count].phase_mode = phase_mode;
batch_count++;
} else {
long long int now;
rtio_chan_sel_write(RTIO_DDS_CHANNEL); rtio_chan_sel_write(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);
now = timestamp; now = timestamp;
DDS_WRITE(DDS_FUD, 0); DDS_WRITE(DDS_FUD, 0);
}
} }

View File

@ -4,6 +4,10 @@
#include <hw/common.h> #include <hw/common.h>
#include <generated/mem.h> #include <generated/mem.h>
/* Maximum number of commands in a batch */
#define DDS_MAX_BATCH 16
/* DDS core registers */
#define DDS_FTW0 0x0a #define DDS_FTW0 0x0a
#define DDS_FTW1 0x0b #define DDS_FTW1 0x0b
#define DDS_FTW2 0x0c #define DDS_FTW2 0x0c
@ -20,6 +24,8 @@ enum {
}; };
void dds_init(long long int timestamp, int channel); void dds_init(long long int timestamp, int channel);
void dds_batch_enter(long long int timestamp);
void dds_batch_exit(void);
void dds_set(long long int timestamp, int channel, void dds_set(long long int timestamp, int channel,
unsigned int ftw, unsigned int pow, int phase_mode); unsigned int ftw, unsigned int pow, int phase_mode);

View File

@ -8,6 +8,7 @@ enum {
EID_RTIO_UNDERFLOW = 3, EID_RTIO_UNDERFLOW = 3,
EID_RTIO_SEQUENCE_ERROR = 4, EID_RTIO_SEQUENCE_ERROR = 4,
EID_RTIO_OVERFLOW = 5, EID_RTIO_OVERFLOW = 5,
EID_DDS_BATCH_ERROR = 6,
}; };
int exception_setjmp(void *jb) __attribute__((returns_twice)); int exception_setjmp(void *jb) __attribute__((returns_twice));

View File

@ -23,6 +23,8 @@ services = [
("ttl_get", "ttl_get"), ("ttl_get", "ttl_get"),
("dds_init", "dds_init"), ("dds_init", "dds_init"),
("dds_batch_enter", "dds_batch_enter"),
("dds_batch_exit", "dds_batch_exit"),
("dds_set", "dds_set"), ("dds_set", "dds_set"),
]), ]),