Commit 708b2d4a authored by Tomasz Wlostowski's avatar Tomasz Wlostowski

softpll: added minipc server (not fully tested yet)

parent 0bab1a9d
CROSS_COMPILE ?= /opt/gcc-lm32/bin/lm32-elf-
OBJS = main.o dev/uart.o dev/timer.o lib/mprintf.o dev/ad9516.o dev/softpll_ng.o ipc/minipc-mem-server.o ipc_test.o
OBJS = main.o dev/uart.o dev/timer.o lib/mprintf.o dev/ad9516.o dev/softpll_ng.o ipc/minipc-mem-server.o ipc/rt_ipc.o
CFLAGS_PLATFORM = -mmultiply-enabled -mbarrel-shift-enabled
CFLAGS_PLATFORM = -mmultiply-enabled -mbarrel-shift-enabled -Idev
LDFLAGS_PLATFORM = -mmultiply-enabled -mbarrel-shift-enabled -nostdlib -T target/lm32/ram.ld
OBJS_PLATFORM=target/lm32/crt0.o target/lm32/irq.o
CC=$(CROSS_COMPILE)gcc
OBJCOPY=$(CROSS_COMPILE)objcopy
OBJDUMP=$(CROSS_COMPILE)objdump
CFLAGS= $(CFLAGS_PLATFORM) -ffunction-sections -fdata-sections -Os -Iinclude -include include/trace.h -Wall -ffreestanding -Iipc
CFLAGS= $(CFLAGS_PLATFORM) -ffunction-sections -fdata-sections -Os -Iinclude -include include/trace.h -ffreestanding -Iipc
LDFLAGS= $(LDFLAGS_PLATFORM) -ffunction-sections -fdata-sections -Os -Iinclude -ffreestanding
SIZE = $(CROSS_COMPILE)size
OBJS += $(OBJS_PLATFORM)
......@@ -25,7 +25,7 @@ clean:
rm -f $(OBJS) $(OUTPUT).elf $(OUTPUT).bin $(OUTPUT).ram
scp: all
scp rt_cpu.bin root@pts-test03.cern.ch:/tftpboot/192.168.1.2/root
scp rt_cpu.bin root@pts-test03.cern.ch:/tftpboot/rootfs/wr/lib/firmware
%.o: %.c
${CC} $(CFLAGS) $(LIB_DIR) -c $^ -o $@
......
......@@ -50,8 +50,6 @@ struct minipc_ch *minipc_server_create(const char *name, int flags)
}
link->flags |= MPC_FLAG_SHMEM; /* needed? */
mprintf("BaseAddr: 0x%x\n", addr);
link->memaddr = (void *)addr;
link->memsize = memsize;
link->pid = 0; /* hack: nrequest */
......@@ -79,7 +77,7 @@ static void *calloc(size_t unused, size_t unused2)
struct mpc_flist *p;
for (p = __static_flist, i = 0; i < MINIPC_MAX_EXPORT; p++, i++)
if (!p->next)
if (!p->pd)
break;
if (i == MINIPC_MAX_EXPORT) {
errno = ENOMEM;
......@@ -91,7 +89,7 @@ static void *calloc(size_t unused, size_t unused2)
static void free(void *ptr)
{
struct mpc_flist *p = ptr;
p->next = NULL;
p->pd = NULL;
}
......
......@@ -13,9 +13,7 @@
#ifndef __MINIPC_H__
#define __MINIPC_H__
#include <stdio.h>
#include <stdint.h>
#if __STDC_HOSTED__ /* freestanding servers have less material */
#include <stdio.h>
#include <sys/select.h>
......
/*
* Mini-ipc: an example freestanding server, based in memory
*
* Copyright (C) 2011,2012 CERN (www.cern.ch)
* Author: Alessandro Rubini <rubini@gnudd.com>
*
* This code is copied from trivial-server, and made even more trivial
*/
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include "minipc.h"
#include "rt_ipc.h"
#include <softpll_ng.h>
static struct rts_pll_state pstate;
static void clear_state()
{
int i;
for(i=0;i<RTS_PLL_CHANNELS;i++)
{
pstate.channels[i].priority = 0;
pstate.channels[i].phase_setpoint = 0;
pstate.channels[i].phase_loopback = 0;
pstate.channels[i].flags = CHAN_REF_VALID;
}
pstate.flags = 0;
pstate.current_ref = 0;
pstate.mode = RTS_MODE_DISABLED;
}
/* Sets the phase setpoint on a given channel */
int rts_adjust_phase(int channel, int32_t phase_setpoint)
{
TRACE("Adjusting phase: ref channel %d, setpoint=%d ps.\n", channel, phase_setpoint);
spll_set_phase_shift(0, phase_setpoint);
pstate.channels[channel].phase_setpoint = phase_setpoint;
return 0;
}
/* Sets the RT subsystem mode (Boundary Clock or Grandmaster) */
int rts_set_mode(int mode)
{
int i;
const struct {
int mode_rt;
int mode_spll;
int do_init;
char *desc;
} options[] = {
{ RTS_MODE_GM_EXTERNAL, SPLL_MODE_GRAND_MASTER, 1, "Grand Master (external clock)" },
{ RTS_MODE_GM_FREERUNNING, SPLL_MODE_FREE_RUNNING_MASTER, 1, "Grand Master (free-running clock)" },
{ RTS_MODE_BC, SPLL_MODE_SLAVE, 0, "Boundary Clock (slave)" },
{ RTS_MODE_DISABLED, SPLL_MODE_DISABLED, 1, "PLL disabled" },
{ 0,0,0, NULL }
};
pstate.mode = mode;
for(i=0;options[i].desc != NULL;i++)
if(mode == options[i].mode_rt)
{
TRACE("RT: Setting mode to %s.\n", options[i].desc);
if(options[i].do_init)
spll_init(options[i].mode_spll, 0, 1);
else
spll_init(SPLL_MODE_DISABLED, 0, 0);
}
return 0;
}
/* Reference channel configuration (BC mode only) */
int rts_lock_channel(int channel, int priority)
{
if(pstate.mode != RTS_MODE_BC)
{
TRACE("trying to lock while not in slave mode,..\n");
return -1;
}
TRACE("RT [slave]: Locking to: %d (prio %d)\n", channel, priority);
spll_init(SPLL_MODE_SLAVE, channel, 0);
pstate.current_ref = channel;
return 0;
}
int rts_init()
{
TRACE("Initializing the RT Subsystem...\n");
clear_state();
}
void rts_update()
{
int i;
int n_ref;
spll_get_num_channels(&n_ref, NULL);
pstate.flags = (spll_check_lock(0) ? RTS_DMTD_LOCKED | RTS_REF_LOCKED : 0);
for(i=0;i<RTS_PLL_CHANNELS;i++)
{
#define CH pstate.channels[i]
CH.flags = 0;
CH.phase_loopback = 0;
CH.phase_current = 0;
// CH.phase_setpoint = 0;
CH.phase_loopback = 0;
if(i >= n_ref)
CH.flags = CHAN_DISABLED;
else {
if(i==pstate.current_ref)
spll_get_phase_shift(0, &CH.phase_current, NULL);
if(spll_read_ptracker(i, &CH.phase_loopback))
CH.flags |= CHAN_PMEAS_READY;
}
#undef CH
}
}
/* fixme: this assumes the host is BE */
static int htonl(int i)
{
return i;
}
static int rts_get_state_func(const struct minipc_pd *pd, uint32_t *args, void *ret)
{
struct rts_pll_state *tmp = (struct rts_pll_state *)ret;
int i;
TRACE("IPC Call: %s [rv at %x]\n", __FUNCTION__, ret);
/* gaaaah, somebody should write a SWIG plugin for generating this stuff. */
tmp->current_ref = htonl(pstate.current_ref);
tmp->flags = htonl(pstate.flags);
tmp->holdover_duration = htonl(pstate.holdover_duration);
tmp->mode = htonl(pstate.mode);
for(i=0; i<RTS_PLL_CHANNELS;i++)
{
tmp->channels[i].priority = htonl(pstate.channels[i].priority);
tmp->channels[i].phase_setpoint = htonl(pstate.channels[i].phase_setpoint);
tmp->channels[i].phase_current = htonl(pstate.channels[i].phase_current);
tmp->channels[i].phase_loopback = htonl(pstate.channels[i].phase_loopback);
tmp->channels[i].flags = htonl(pstate.channels[i].flags);
}
return 0;
}
static int rts_set_mode_func(const struct minipc_pd *pd, uint32_t *args, void *ret)
{
*(int *) ret = rts_set_mode(args[0]);
}
static int rts_lock_channel_func(const struct minipc_pd *pd, uint32_t *args, void *ret)
{
*(int *) ret = rts_lock_channel(args[0], (int)args[1]);
}
static int rts_adjust_phase_func(const struct minipc_pd *pd, uint32_t *args, void *ret)
{
*(int *) ret = rts_adjust_phase((int)args[0], (int)args[1]);
}
const struct minipc_pd rtipc_rts_get_state_struct = {
.f = rts_get_state_func,
.name = "aaaa",
.retval = MINIPC_ARG_ENCODE(MINIPC_ATYPE_STRUCT, struct rts_pll_state),
.args = {
MINIPC_ARG_END
},
};
const struct minipc_pd rtipc_rts_set_mode_struct = {
.f = rts_set_mode_func,
.name = "bbbb",
.retval = MINIPC_ARG_ENCODE(MINIPC_ATYPE_INT, int),
.args = {
MINIPC_ARG_ENCODE(MINIPC_ATYPE_INT, int ),
MINIPC_ARG_END
},
};
const struct minipc_pd rtipc_rts_lock_channel_struct = {
.f = rts_lock_channel_func,
.name = "cccc",
.retval = MINIPC_ARG_ENCODE(MINIPC_ATYPE_INT, int),
.args = {
MINIPC_ARG_ENCODE(MINIPC_ATYPE_INT, int ),
MINIPC_ARG_ENCODE(MINIPC_ATYPE_INT, int ),
MINIPC_ARG_END
},
};
const struct minipc_pd rtipc_rts_adjust_phase_struct = {
.f = rts_adjust_phase_func,
.name = "dddd",
.retval = MINIPC_ARG_ENCODE(MINIPC_ATYPE_INT, int),
.args = {
MINIPC_ARG_ENCODE(MINIPC_ATYPE_INT, int ),
MINIPC_ARG_ENCODE(MINIPC_ATYPE_INT, int ),
MINIPC_ARG_END
},
};
/* The mailbox is mapped at 0x7000 in the linker script */
static __attribute__((section(".mbox"))) _mailbox[1024];
static struct minipc_ch *server;
int rtipc_init()
{
server = minipc_server_create("mem:7000", 0);
if (!server)
return 1;
minipc_export(server, &rtipc_rts_set_mode_struct);
minipc_export(server, &rtipc_rts_get_state_struct);
minipc_export(server, &rtipc_rts_lock_channel_struct);
minipc_export(server, &rtipc_rts_adjust_phase_struct);
return 0;
}
void rtipc_action()
{
minipc_server_action(server, 1000);
}
#ifndef __RT_IPC_H
#define __RT_IPC_H
#include <stdint.h>
#define RTS_PLL_CHANNELS 32
#define RTS_PLL_CHANNELS 18
/* Individual channel flags */
/* Reference input frequency valid */
......@@ -9,9 +12,10 @@
#define CHAN_FREQ_OUT_OF_RANGE (1<<1)
/* Phase is drifting too fast */
#define CHAN_DRIFTING (1<<2)
#define LOCK_DISABLED -1
/* Channel phase measurement is ready */
#define CHAN_PMEAS_READY (1<<3)
/* Channel not available/disabled */
#define CHAN_DISABLED (1<<4)
/* DMTD clock is present */
#define RTS_DMTD_LOCKED (1<<0)
......@@ -35,13 +39,16 @@
#define RTS_HOLDOVER_ACTIVE (1<<6)
/* Grandmaster mode active (uses 10 MHz / 1-PPS reference) */
#define RTS_MODE_GRANDMASTER (1<<7)
#define RTS_MODE_GM_EXTERNAL 1
/* Free-running grandmaster (uses local TCXO) */
#define RTS_MODE_GM_FREERUNNING 2
/* Boundary clock mode active (uses network reference) */
#define RTS_MODE_BC (1<<8)
#define RTS_MODE_BC 3
/* When set, phase_loopback contains a valid phase measurement */
#define RTS_LOOPBACK_PHASE_READY (1<<9)
/* PLL disabled */
#define RTS_MODE_DISABLED 4
/* null reference input */
#define REF_NONE 255
......@@ -52,23 +59,28 @@ struct rts_pll_state {
/* State of an individual input channel (i.e. switch port) */
struct channel {
/* Switchover priority: 0 = highest, 1 - 254 = high..low, 255 = channel disabled (a master port) */
uint32_t priority;
/* channel phase setpoint in picoseconds << 16. Used only when channel is a slave. */
int32_t phase_setpoint;
/* TX-RX Loopback phase measurement in picoseconds << 16. */
int32_t phase_looback;
uint32_t priority;
/* channel phase setpoint in picoseconds. Used only when channel is a slave. */
int32_t phase_setpoint;
/* current phase shift in picoseconds. Used only when channel is a slave. */
int32_t phase_current;
/* TX-RX Loopback phase measurement in picoseconds. */
int32_t phase_loopback;
/* flags (per channel - see CHAN_xxx defines) */
uint32_t flags;
uint32_t flags;
} channels[RTS_PLL_CHANNELS];
/* flags (global - RTS_xxx defines) */
uint32_t flags;
/* flags (global - RTS_xxx defines) */
uint32_t flags;
/* duration of current holdover period in 10us units */
int32_t holdover_duration;
/* current reference source - or REF_NONE if free-running or grandmaster */
uint32_t current_ref;
/* mode of operation (RTS_MODE_xxx) */
uint32_t mode;
};
/* API */
......@@ -77,10 +89,13 @@ struct rts_pll_state {
int rts_get_state(struct rts_pll_state *state);
/* Sets the phase setpoint on a given channel */
int rts_adjust_phase(uint8_t channel, int32_t phase_setpoint);
int rts_adjust_phase(int channel, int32_t phase_setpoint);
/* Sets the RT subsystem mode (Boundary Clock or Grandmaster) */
int rts_set_mode(uint32_t mode);
int rts_set_mode(int mode);
/* Reference channel configuration (BC mode only) */
int rts_lock_channel(uint32_t channel, int32_t priority);
int rts_lock_channel(int channel, int priority);
#endif
......@@ -2,6 +2,7 @@
#include "uart.h"
#include "timer.h"
#include "dev/softpll_ng.h"
#include "minipc.h"
......@@ -9,10 +10,26 @@
main()
{
uint32_t start_tics = 0;
uart_init();
ad9516_init();
char tmp[100];
// spll_test();
ipc_test();
}
\ No newline at end of file
rts_init();
rtipc_init();
for(;;)
{
uint32_t tics = timer_get_tics();
if(tics - start_tics > TICS_PER_SECOND)
{
spll_show_stats();
start_tics = tics;
}
rts_update();
rtipc_action();
}
return 0;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment