From 55f2fef576b6d976c4eb17174565c8d589871e20 Mon Sep 17 00:00:00 2001 From: Sebastien Bourdeauducq Date: Fri, 8 May 2015 16:51:54 +0800 Subject: [PATCH] runtime: support DDS batches --- artiq/coredevice/runtime.py | 2 + artiq/coredevice/runtime_exceptions.py | 14 +++--- soc/runtime/dds.c | 60 +++++++++++++++++++++++--- soc/runtime/dds.h | 6 +++ soc/runtime/exceptions.h | 1 + soc/runtime/gen_service_table.py | 2 + 6 files changed, 74 insertions(+), 11 deletions(-) diff --git a/artiq/coredevice/runtime.py b/artiq/coredevice/runtime.py index 395939329..1fff8f4fc 100644 --- a/artiq/coredevice/runtime.py +++ b/artiq/coredevice/runtime.py @@ -22,6 +22,8 @@ _syscalls = { "ttl_set_sensitivity": "Iii:n", "ttl_get": "iI:I", "dds_init": "Ii:n", + "dds_batch_enter": "I:n", + "dds_batch_exit": "n:n", "dds_set": "Iiiii:n", } diff --git a/artiq/coredevice/runtime_exceptions.py b/artiq/coredevice/runtime_exceptions.py index ec3241c02..aa9a2c1c5 100644 --- a/artiq/coredevice/runtime_exceptions.py +++ b/artiq/coredevice/runtime_exceptions.py @@ -6,9 +6,7 @@ from artiq.language.core import RuntimeException # Must be kept in sync with soc/runtime/exceptions.h class InternalError(RuntimeException): - """Raised when the runtime encounters an internal error condition. - - """ + """Raised when the runtime encounters an internal error condition.""" eid = 1 @@ -21,7 +19,6 @@ class RTIOUnderflow(RuntimeException): (with respect to the event's timestamp). The offending event is discarded and the RTIO core keeps operating. - """ eid = 3 @@ -37,7 +34,6 @@ class RTIOSequenceError(RuntimeException): not larger than the previous one. The offending event is discarded and the RTIO core keeps operating. - """ eid = 4 @@ -53,7 +49,6 @@ class RTIOOverflow(RuntimeException): This does not interrupt operations further than cancelling the current read attempt and discarding some events. Reading can be reattempted after the exception is caught, and events will be partially retrieved. - """ eid = 5 @@ -61,6 +56,13 @@ class RTIOOverflow(RuntimeException): 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() if inspect.isclass(e) and issubclass(e, RuntimeException) diff --git a/soc/runtime/dds.c b/soc/runtime/dds.c index 87aa8464c..5290723e9 100644 --- a/soc/runtime/dds.c +++ b/soc/runtime/dds.c @@ -1,6 +1,7 @@ #include #include +#include "exceptions.h" #include "rtio.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); } +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= 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); - dds_set_one(timestamp - DURATION_PROGRAM, timestamp, channel, ftw, pow, phase_mode); - now = timestamp; - DDS_WRITE(DDS_FUD, 0); + rtio_chan_sel_write(RTIO_DDS_CHANNEL); + dds_set_one(timestamp - DURATION_PROGRAM, timestamp, channel, ftw, pow, phase_mode); + now = timestamp; + DDS_WRITE(DDS_FUD, 0); + } } diff --git a/soc/runtime/dds.h b/soc/runtime/dds.h index c38935277..f0f551a5c 100644 --- a/soc/runtime/dds.h +++ b/soc/runtime/dds.h @@ -4,6 +4,10 @@ #include #include +/* Maximum number of commands in a batch */ +#define DDS_MAX_BATCH 16 + +/* DDS core registers */ #define DDS_FTW0 0x0a #define DDS_FTW1 0x0b #define DDS_FTW2 0x0c @@ -20,6 +24,8 @@ enum { }; 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, unsigned int ftw, unsigned int pow, int phase_mode); diff --git a/soc/runtime/exceptions.h b/soc/runtime/exceptions.h index 82e5889c1..1c820c060 100644 --- a/soc/runtime/exceptions.h +++ b/soc/runtime/exceptions.h @@ -8,6 +8,7 @@ enum { EID_RTIO_UNDERFLOW = 3, EID_RTIO_SEQUENCE_ERROR = 4, EID_RTIO_OVERFLOW = 5, + EID_DDS_BATCH_ERROR = 6, }; int exception_setjmp(void *jb) __attribute__((returns_twice)); diff --git a/soc/runtime/gen_service_table.py b/soc/runtime/gen_service_table.py index f29d5307a..b194662cd 100755 --- a/soc/runtime/gen_service_table.py +++ b/soc/runtime/gen_service_table.py @@ -23,6 +23,8 @@ services = [ ("ttl_get", "ttl_get"), ("dds_init", "dds_init"), + ("dds_batch_enter", "dds_batch_enter"), + ("dds_batch_exit", "dds_batch_exit"), ("dds_set", "dds_set"), ]),