2
0
mirror of https://github.com/m-labs/artiq.git synced 2024-12-25 19:28:26 +08:00

runtime: reset all DDSes upon startup

This commit is contained in:
Sebastien Bourdeauducq 2015-05-09 17:11:34 +08:00
parent 1ceb06fb16
commit ce4b5739ed
13 changed files with 208 additions and 144 deletions

View File

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

View File

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

View File

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

113
soc/runtime/bridge_ctl.c Normal file
View File

@ -0,0 +1,113 @@
#include <stdio.h>
#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);
}

17
soc/runtime/bridge_ctl.h Normal file
View File

@ -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 */

View File

@ -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<DDS_CHANNEL_COUNT;i++) {
dds_init(now, i);
now += DURATION_INIT;
}
while(rtio_get_counter() < now);
}
void dds_init(long long int timestamp, int channel)
{
long long int now;
rtio_chan_sel_write(RTIO_DDS_CHANNEL);
now = timestamp - 7*DURATION_WRITE;
now = timestamp - DURATION_INIT;
DDS_WRITE(DDS_GPIO, channel);
DDS_WRITE(DDS_GPIO, channel | (1 << 7));
@ -32,6 +46,8 @@ void dds_init(long long int timestamp, int channel)
DDS_WRITE(0x01, 0x00);
DDS_WRITE(0x02, 0x00);
DDS_WRITE(0x03, 0x00);
DDS_WRITE(DDS_FUD, 0);
}
static void dds_set_one(long long int now, long long int timestamp, int channel,

View File

@ -4,6 +4,9 @@
#include <hw/common.h>
#include <generated/mem.h>
/* 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);

View File

@ -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();

View File

@ -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 */

View File

@ -21,12 +21,22 @@
#include <lwip/timers.h>
#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;

View File

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

View File

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

View File

@ -7,113 +7,11 @@
#include <generated/csr.h>
#include <console.h>
#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 ");