diff --git a/artiq/coredevice/dds.py b/artiq/coredevice/dds.py index 7799c1d31..8ab434664 100644 --- a/artiq/coredevice/dds.py +++ b/artiq/coredevice/dds.py @@ -79,7 +79,9 @@ class DDS(AutoDB): @kernel def init(self): - """Resets and initializes the DDS channel.""" + """Resets and initializes the DDS channel. + + The runtime does this for all channels upon core device startup.""" syscall("dds_init", time_to_cycles(now()), self.channel) @kernel diff --git a/soc/runtime/Makefile b/soc/runtime/Makefile index 1d93d6e63..3cf2708dc 100644 --- a/soc/runtime/Makefile +++ b/soc/runtime/Makefile @@ -1,6 +1,6 @@ include $(MSCDIR)/software/common.mak -OBJECTS := isr.o flash_storage.o clock.o elf_loader.o services.o session.o log.o test_mode.o kloader.o mailbox.o ksupport_data.o kserver.o main.o +OBJECTS := isr.o flash_storage.o clock.o elf_loader.o services.o session.o log.o test_mode.o kloader.o bridge_ctl.o mailbox.o ksupport_data.o kserver.o main.o OBJECTS_KSUPPORT := ksupport.o exception_jmp.o exceptions.o mailbox.o bridge.o rtio.o ttl.o dds.o CFLAGS += -Ilwip/src/include -Iliblwip diff --git a/soc/runtime/bridge.c b/soc/runtime/bridge.c index 19cfd4b4e..c61875236 100644 --- a/soc/runtime/bridge.c +++ b/soc/runtime/bridge.c @@ -58,6 +58,10 @@ void bridge_main(void) mailbox_acknowledge(); break; } + case MESSAGE_TYPE_BRG_DDS_INITALL: + dds_init_all(); + mailbox_acknowledge(); + break; case MESSAGE_TYPE_BRG_DDS_SEL: { struct msg_brg_dds_sel *msg; diff --git a/soc/runtime/bridge_ctl.c b/soc/runtime/bridge_ctl.c new file mode 100644 index 000000000..1103a222c --- /dev/null +++ b/soc/runtime/bridge_ctl.c @@ -0,0 +1,113 @@ +#include + +#include "kloader.h" +#include "mailbox.h" +#include "messages.h" + +void brg_start(void) +{ + struct msg_base *umsg; + + kloader_start_bridge(); + + while(1) { + umsg = mailbox_wait_and_receive(); + if(umsg->type == MESSAGE_TYPE_BRG_READY) { + mailbox_acknowledge(); + break; + } else { + printf("Warning: unexpected message %d from AMP bridge\n", umsg->type); + mailbox_acknowledge(); + } + } +} + +void brg_stop(void) +{ + kloader_stop(); +} + +void brg_ttloe(int n, int value) +{ + struct msg_brg_ttl_out msg; + + msg.type = MESSAGE_TYPE_BRG_TTL_OE; + msg.channel = n; + msg.value = value; + mailbox_send_and_wait(&msg); +} + +void brg_ttlo(int n, int value) +{ + struct msg_brg_ttl_out msg; + + msg.type = MESSAGE_TYPE_BRG_TTL_O; + msg.channel = n; + msg.value = value; + mailbox_send_and_wait(&msg); +} + +void brg_ddsinitall(void) +{ + struct msg_base msg; + + msg.type = MESSAGE_TYPE_BRG_DDS_INITALL; + mailbox_send_and_wait(&msg); +} + +void brg_ddssel(int channel) +{ + struct msg_brg_dds_sel msg; + + msg.type = MESSAGE_TYPE_BRG_DDS_SEL; + msg.channel = channel; + mailbox_send_and_wait(&msg); +} + +void brg_ddsreset(void) +{ + struct msg_base msg; + + msg.type = MESSAGE_TYPE_BRG_DDS_RESET; + mailbox_send_and_wait(&msg); +} + +unsigned int brg_ddsread(unsigned int address) +{ + struct msg_brg_dds_read_request msg; + struct msg_brg_dds_read_reply *rmsg; + unsigned int r; + + msg.type = MESSAGE_TYPE_BRG_DDS_READ_REQUEST; + msg.address = address; + mailbox_send(&msg); + while(1) { + rmsg = mailbox_wait_and_receive(); + if(rmsg->type == MESSAGE_TYPE_BRG_DDS_READ_REPLY) { + r = rmsg->data; + mailbox_acknowledge(); + return r; + } else { + printf("Warning: unexpected message %d from AMP bridge\n", rmsg->type); + mailbox_acknowledge(); + } + } +} + +void brg_ddswrite(unsigned int address, unsigned int data) +{ + struct msg_brg_dds_write msg; + + msg.type = MESSAGE_TYPE_BRG_DDS_WRITE; + msg.address = address; + msg.data = data; + mailbox_send_and_wait(&msg); +} + +void brg_ddsfud(void) +{ + struct msg_base msg; + + msg.type = MESSAGE_TYPE_BRG_DDS_FUD; + mailbox_send_and_wait(&msg); +} diff --git a/soc/runtime/bridge_ctl.h b/soc/runtime/bridge_ctl.h new file mode 100644 index 000000000..d87f83812 --- /dev/null +++ b/soc/runtime/bridge_ctl.h @@ -0,0 +1,17 @@ +#ifndef __BRIDGE_CTL_H +#define __BRIDGE_CTL_H + +void brg_start(void); +void brg_stop(void); + +void brg_ttloe(int n, int value); +void brg_ttlo(int n, int value); + +void brg_ddsinitall(void); +void brg_ddssel(int channel); +void brg_ddsreset(void); +unsigned int brg_ddsread(unsigned int address); +void brg_ddswrite(unsigned int address, unsigned int data); +void brg_ddsfud(void); + +#endif /* __BRIDGE_CTL_H */ diff --git a/soc/runtime/dds.c b/soc/runtime/dds.c index ea8a44a90..2429eb2b6 100644 --- a/soc/runtime/dds.c +++ b/soc/runtime/dds.c @@ -6,6 +6,7 @@ #include "dds.h" #define DURATION_WRITE 5 +#define DURATION_INIT (8*DURATION_WRITE) #define DURATION_PROGRAM (8*DURATION_WRITE) #define DDS_WRITE(addr, data) do { \ @@ -16,13 +17,26 @@ now += DURATION_WRITE; \ } while(0) +void dds_init_all(void) +{ + int i; + long long int now; + + now = rtio_get_counter() + 10000; + for(i=0;i #include +/* Number of DDS channels to initialize */ +#define DDS_CHANNEL_COUNT 8 + /* Maximum number of commands in a batch */ #define DDS_MAX_BATCH 16 @@ -23,6 +26,7 @@ enum { PHASE_MODE_TRACKING = 2 }; +void dds_init_all(void); void dds_init(long long int timestamp, int channel); void dds_batch_enter(long long int timestamp); void dds_batch_exit(void); diff --git a/soc/runtime/kloader.c b/soc/runtime/kloader.c index 6cbea69d8..f73723981 100644 --- a/soc/runtime/kloader.c +++ b/soc/runtime/kloader.c @@ -117,7 +117,7 @@ void kloader_start_idle_kernel(void) #endif } -void kloader_stop_kernel(void) +void kloader_stop(void) { kernel_cpu_reset_write(1); mailbox_acknowledge(); diff --git a/soc/runtime/kloader.h b/soc/runtime/kloader.h index 10993ca41..bf484b4e1 100644 --- a/soc/runtime/kloader.h +++ b/soc/runtime/kloader.h @@ -12,6 +12,6 @@ kernel_function kloader_find(const char *name); void kloader_start_bridge(void); void kloader_start_idle_kernel(void); void kloader_start_user_kernel(kernel_function k); -void kloader_stop_kernel(void); +void kloader_stop(void); #endif /* __KLOADER_H */ diff --git a/soc/runtime/main.c b/soc/runtime/main.c index 5e2e547da..95889fd07 100644 --- a/soc/runtime/main.c +++ b/soc/runtime/main.c @@ -21,12 +21,22 @@ #include #endif +#include "bridge_ctl.h" +#include "kloader.h" #include "flash_storage.h" #include "clock.h" #include "test_mode.h" #include "kserver.h" #include "session.h" +static void common_init(void) +{ + clock_init(); + brg_start(); + brg_ddsinitall(); + kloader_stop(); +} + #ifdef CSR_ETHMAC_BASE u32_t sys_now(void) @@ -127,7 +137,6 @@ static void network_init(void) static void regular_main(void) { puts("Accepting sessions on Ethernet."); - clock_init(); network_init(); kserver_init(); @@ -186,7 +195,6 @@ static void serial_service(void) static void regular_main(void) { puts("Accepting sessions on serial link."); - clock_init(); /* Open the session for the serial control. */ session_start(); @@ -246,6 +254,7 @@ int main(void) test_main(); } else { puts("Entering regular mode."); + common_init(); regular_main(); } return 0; diff --git a/soc/runtime/messages.h b/soc/runtime/messages.h index 4a4e10737..221b394a3 100644 --- a/soc/runtime/messages.h +++ b/soc/runtime/messages.h @@ -19,6 +19,7 @@ enum { MESSAGE_TYPE_BRG_READY, MESSAGE_TYPE_BRG_TTL_O, MESSAGE_TYPE_BRG_TTL_OE, + MESSAGE_TYPE_BRG_DDS_INITALL, MESSAGE_TYPE_BRG_DDS_SEL, MESSAGE_TYPE_BRG_DDS_RESET, MESSAGE_TYPE_BRG_DDS_READ_REQUEST, diff --git a/soc/runtime/session.c b/soc/runtime/session.c index bfcc6b823..a0f2d3ab7 100644 --- a/soc/runtime/session.c +++ b/soc/runtime/session.c @@ -67,13 +67,13 @@ void session_start(void) { buffer_in_index = 0; memset(&buffer_out[4], 0, 4); - kloader_stop_kernel(); + kloader_stop(); user_kernel_state = USER_KERNEL_NONE; } void session_end(void) { - kloader_stop_kernel(); + kloader_stop(); kloader_start_idle_kernel(); } @@ -417,7 +417,7 @@ static int process_kmsg(struct msg_base *umsg) buffer_out[8] = REMOTEMSG_TYPE_KERNEL_FINISHED; submit_output(9); - kloader_stop_kernel(); + kloader_stop(); user_kernel_state = USER_KERNEL_LOADED; mailbox_acknowledge(); break; @@ -429,7 +429,7 @@ static int process_kmsg(struct msg_base *umsg) memcpy(&buffer_out[13], msg->eparams, 3*8); submit_output(9+4+3*8); - kloader_stop_kernel(); + kloader_stop(); user_kernel_state = USER_KERNEL_LOADED; mailbox_acknowledge(); break; diff --git a/soc/runtime/test_mode.c b/soc/runtime/test_mode.c index 5b018c4d9..0b0ee6426 100644 --- a/soc/runtime/test_mode.c +++ b/soc/runtime/test_mode.c @@ -7,113 +7,11 @@ #include #include -#include "kloader.h" -#include "mailbox.h" -#include "messages.h" #include "dds.h" #include "flash_storage.h" +#include "bridge_ctl.h" #include "test_mode.h" -/* bridge access functions */ - -static void amp_bridge_init(void) -{ - struct msg_base *umsg; - - kloader_start_bridge(); - - while(1) { - umsg = mailbox_wait_and_receive(); - if(umsg->type == MESSAGE_TYPE_BRG_READY) { - printf("AMP bridge ready\n"); - mailbox_acknowledge(); - break; - } else { - printf("Warning: unexpected message %d from AMP bridge\n", umsg->type); - mailbox_acknowledge(); - } - } -} - -static void p_ttloe(int n, int value) -{ - struct msg_brg_ttl_out msg; - - msg.type = MESSAGE_TYPE_BRG_TTL_OE; - msg.channel = n; - msg.value = value; - mailbox_send_and_wait(&msg); -} - -static void p_ttlo(int n, int value) -{ - struct msg_brg_ttl_out msg; - - msg.type = MESSAGE_TYPE_BRG_TTL_O; - msg.channel = n; - msg.value = value; - mailbox_send_and_wait(&msg); -} - -static void p_ddssel(int channel) -{ - struct msg_brg_dds_sel msg; - - msg.type = MESSAGE_TYPE_BRG_DDS_SEL; - msg.channel = channel; - mailbox_send_and_wait(&msg); -} - -static void p_ddsreset(void) -{ - struct msg_base msg; - - msg.type = MESSAGE_TYPE_BRG_DDS_RESET; - mailbox_send_and_wait(&msg); -} - -static unsigned int p_ddsread(unsigned int address) -{ - struct msg_brg_dds_read_request msg; - struct msg_brg_dds_read_reply *rmsg; - unsigned int r; - - msg.type = MESSAGE_TYPE_BRG_DDS_READ_REQUEST; - msg.address = address; - mailbox_send(&msg); - while(1) { - rmsg = mailbox_wait_and_receive(); - if(rmsg->type == MESSAGE_TYPE_BRG_DDS_READ_REPLY) { - r = rmsg->data; - mailbox_acknowledge(); - return r; - } else { - printf("Warning: unexpected message %d from AMP bridge\n", rmsg->type); - mailbox_acknowledge(); - } - } -} - -static void p_ddswrite(unsigned int address, unsigned int data) -{ - struct msg_brg_dds_write msg; - - msg.type = MESSAGE_TYPE_BRG_DDS_WRITE; - msg.address = address; - msg.data = data; - mailbox_send_and_wait(&msg); -} - -static void p_ddsfud(void) -{ - struct msg_base msg; - - msg.type = MESSAGE_TYPE_BRG_DDS_FUD; - mailbox_send_and_wait(&msg); -} - -/* */ - static void leds(char *value) { char *c; @@ -173,7 +71,7 @@ static void ttloe(char *n, char *value) return; } - p_ttloe(n2, value2); + brg_ttloe(n2, value2); } static void ttlo(char *n, char *value) @@ -197,7 +95,7 @@ static void ttlo(char *n, char *value) return; } - p_ttlo(n2, value2); + brg_ttlo(n2, value2); } static void ddssel(char *n) @@ -216,7 +114,7 @@ static void ddssel(char *n) return; } - p_ddssel(n2); + brg_ddssel(n2); } static void ddsw(char *addr, char *value) @@ -240,7 +138,7 @@ static void ddsw(char *addr, char *value) return; } - p_ddswrite(addr2, value2); + brg_ddswrite(addr2, value2); } static void ddsr(char *addr) @@ -259,12 +157,12 @@ static void ddsr(char *addr) return; } - printf("0x%02x\n", p_ddsread(addr2)); + printf("0x%02x\n", brg_ddsread(addr2)); } static void ddsfud(void) { - p_ddsfud(); + brg_ddsfud(); } static void ddsftw(char *n, char *ftw) @@ -288,27 +186,27 @@ static void ddsftw(char *n, char *ftw) return; } - p_ddssel(n2); - p_ddswrite(DDS_FTW0, ftw2 & 0xff); - p_ddswrite(DDS_FTW1, (ftw2 >> 8) & 0xff); - p_ddswrite(DDS_FTW2, (ftw2 >> 16) & 0xff); - p_ddswrite(DDS_FTW3, (ftw2 >> 24) & 0xff); - p_ddsfud(); + brg_ddssel(n2); + brg_ddswrite(DDS_FTW0, ftw2 & 0xff); + brg_ddswrite(DDS_FTW1, (ftw2 >> 8) & 0xff); + brg_ddswrite(DDS_FTW2, (ftw2 >> 16) & 0xff); + brg_ddswrite(DDS_FTW3, (ftw2 >> 24) & 0xff); + brg_ddsfud(); } static void ddsreset(void) { - p_ddsreset(); + brg_ddsreset(); } static void ddsinit(void) { - p_ddsreset(); - p_ddswrite(0x00, 0x78); - p_ddswrite(0x01, 0x00); - p_ddswrite(0x02, 0x00); - p_ddswrite(0x03, 0x00); - p_ddsfud(); + brg_ddsreset(); + brg_ddswrite(0x00, 0x78); + brg_ddswrite(0x01, 0x00); + brg_ddswrite(0x02, 0x00); + brg_ddswrite(0x03, 0x00); + brg_ddsfud(); } static void ddstest_one(unsigned int i) @@ -320,20 +218,20 @@ static void ddstest_one(unsigned int i) }; unsigned int f, g, j; - p_ddssel(i); + brg_ddssel(i); ddsinit(); for(j=0; j<12; j++) { f = v[j]; - p_ddswrite(0x0a, f & 0xff); - p_ddswrite(0x0b, (f >> 8) & 0xff); - p_ddswrite(0x0c, (f >> 16) & 0xff); - p_ddswrite(0x0d, (f >> 24) & 0xff); - p_ddsfud(); - g = p_ddsread(0x0a); - g |= p_ddsread(0x0b) << 8; - g |= p_ddsread(0x0c) << 16; - g |= p_ddsread(0x0d) << 24; + brg_ddswrite(0x0a, f & 0xff); + brg_ddswrite(0x0b, (f >> 8) & 0xff); + brg_ddswrite(0x0c, (f >> 16) & 0xff); + brg_ddswrite(0x0d, (f >> 24) & 0xff); + brg_ddsfud(); + g = brg_ddsread(0x0a); + g |= brg_ddsread(0x0b) << 8; + g |= brg_ddsread(0x0c) << 16; + g |= brg_ddsread(0x0d) << 24; if(g != f) printf("readback fail on DDS %d, 0x%08x != 0x%08x\n", i, g, f); } @@ -479,7 +377,7 @@ void test_main(void) { char buffer[64]; - amp_bridge_init(); + brg_start(); while(1) { putsnonl("\e[1mtest>\e[0m ");