Commit aa280177 authored by Tomasz Wlostowski's avatar Tomasz Wlostowski

rt: softpll-ng: started porting the main PLL (wip)

parent ec86bd6a
CROSS_COMPILE ?= /opt/gcc-lm32/bin/lm32-elf- CROSS_COMPILE ?= /opt/gcc-lm32/bin/lm32-elf-
OBJS = main.o dev/uart.o dev/timer.o lib/mprintf.o dev/ad9516.o OBJS = main.o dev/uart.o dev/timer.o lib/mprintf.o dev/ad9516.o dev/softpll_ng.o
CFLAGS_PLATFORM = -mmultiply-enabled -mbarrel-shift-enabled CFLAGS_PLATFORM = -mmultiply-enabled -mbarrel-shift-enabled
LDFLAGS_PLATFORM = -mmultiply-enabled -mbarrel-shift-enabled -nostdlib -T target/lm32/ram.ld LDFLAGS_PLATFORM = -mmultiply-enabled -mbarrel-shift-enabled -nostdlib -T target/lm32/ram.ld
...@@ -9,7 +9,7 @@ OBJS_PLATFORM=target/lm32/crt0.o target/lm32/irq.o ...@@ -9,7 +9,7 @@ OBJS_PLATFORM=target/lm32/crt0.o target/lm32/irq.o
CC=$(CROSS_COMPILE)gcc CC=$(CROSS_COMPILE)gcc
OBJCOPY=$(CROSS_COMPILE)objcopy OBJCOPY=$(CROSS_COMPILE)objcopy
OBJDUMP=$(CROSS_COMPILE)objdump OBJDUMP=$(CROSS_COMPILE)objdump
CFLAGS= $(CFLAGS_PLATFORM) -ffunction-sections -fdata-sections -Os -Iinclude -include include/trace.h CFLAGS= $(CFLAGS_PLATFORM) -ffunction-sections -fdata-sections -Os -Iinclude -include include/trace.h -Wall
LDFLAGS= $(LDFLAGS_PLATFORM) -ffunction-sections -fdata-sections -Os -Iinclude LDFLAGS= $(LDFLAGS_PLATFORM) -ffunction-sections -fdata-sections -Os -Iinclude
SIZE = $(CROSS_COMPILE)size SIZE = $(CROSS_COMPILE)size
OBJS += $(OBJS_PLATFORM) OBJS += $(OBJS_PLATFORM)
...@@ -24,6 +24,9 @@ all: $(OBJS) ...@@ -24,6 +24,9 @@ all: $(OBJS)
clean: clean:
rm -f $(OBJS) $(OUTPUT).elf $(OUTPUT).bin $(OUTPUT).ram 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
%.o: %.c %.o: %.c
${CC} $(CFLAGS) $(LIB_DIR) -c $^ -o $@ ${CC} $(CFLAGS) $(LIB_DIR) -c $^ -o $@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h>
#include "board.h" #include "board.h"
#include "timer.h"
#include "hw/softpll_regs.h" #include "hw/softpll_regs.h"
#include "irq.h" #include "irq.h"
...@@ -11,8 +13,11 @@ static volatile struct SPLL_WB *SPLL = (volatile struct SPLL_WB *) BASE_SOFTPLL; ...@@ -11,8 +13,11 @@ static volatile struct SPLL_WB *SPLL = (volatile struct SPLL_WB *) BASE_SOFTPLL;
/* The includes below contain code (not only declarations) to enable the compiler /* The includes below contain code (not only declarations) to enable the compiler
to inline functions where necessary and save some CPU cycles */ to inline functions where necessary and save some CPU cycles */
#include "spll_defs.h" #include "spll_defs.h"
#include "spll_common.h" #include "spll_common.h"
#include "spll_debug.h"
#include "spll_helper.h" #include "spll_helper.h"
...@@ -24,11 +29,12 @@ struct spll_pmeas_channel { ...@@ -24,11 +29,12 @@ struct spll_pmeas_channel {
int n_tags; int n_tags;
}; };
static volatile uint32_t spll_pmeas_mask = 0; static struct spll_helper_state helper;
static struct spll_pmeas_channel pmeas[MAX_CHAN_REF + MAX_CHAN_OUT];
volatile struct spll_helper_state helper;
volatile struct spll_pmeas_channel pmeas[32];
static void pmeas_update(struct spll_pmeas_channel *chan, int tag) static void pmeas_update(struct spll_pmeas_channel *chan, int tag)
{ {
...@@ -56,7 +62,7 @@ static void pmeas_enable(int channel) ...@@ -56,7 +62,7 @@ static void pmeas_enable(int channel)
SPLL->RCER |= (1<<channel); SPLL->RCER |= (1<<channel);
spll_pmeas_mask |= (1<<channel); // spll_pmeas_mask |= (1<<channel);
} }
void _irq_entry() void _irq_entry()
...@@ -86,6 +92,14 @@ void spll_init() ...@@ -86,6 +92,14 @@ void spll_init()
volatile int dummy; volatile int dummy;
disable_irq(); disable_irq();
n_chan_ref = SPLL_CSR_N_REF_R(SPLL->CSR);
n_chan_out = SPLL_CSR_N_OUT_R(SPLL->CSR);
TRACE("SPLL_Init: %d ref channels, %d out channels\n", n_chan_ref, n_chan_out);
SPLL->DAC_HPLL = 0;
timer_delay(100000);
SPLL->CSR= 0 ; SPLL->CSR= 0 ;
SPLL->OCER = 0; SPLL->OCER = 0;
SPLL->RCER = 0; SPLL->RCER = 0;
...@@ -108,32 +122,24 @@ void spll_test() ...@@ -108,32 +122,24 @@ void spll_test()
volatile int dummy; volatile int dummy;
spll_init(); spll_init();
helper_start(&helper, 8); helper_start(&helper, 0);
enable_irq(); enable_irq();
while(!spll_check_lock()) { TRACE("%d %d %x %x\n",irq_count, delta, SPLL->TRR_CSR, SPLL->OCER); }
SPLL->DCCR = SPLL_DCCR_GATE_DIV_W(24);
SPLL->RCGER = (1<<7) | (1<<6);
pmeas_enable(7);
pmeas_enable(6);
for(;;) {
TRACE("RCER %x Phase %d/%d rdy %d/%d, py %d\n", SPLL->RCER, pmeas[7].current, pmeas[6].current, pmeas[7].ready, pmeas[6].ready, py);
}
} }
/*
#define CHAN_AUX 7 #define CHAN_AUX 7
#define CHAN_EXT 6 #define CHAN_EXT 6
/* measures external reference vs local clock phase */
int spll_gm_measure_ext_phase() int spll_gm_measure_ext_phase()
{ {
SPLL->CSR = 0; SPLL->CSR = 0;
SPLL->DCCR = SPLL_DCCR_GATE_DIV_W(25); SPLL->DCCR = SPLL_DCCR_GATE_DIV_W(25);
SPLL->RCGER = (1<<CHAN_AUX); SPLL->RCGER = (1<<CHAN_AUX);
SPLL->RCGER = (1<<CHAN_EXT); SPLL->RCGER = (1<<CHAN_EXT);
} }
\ No newline at end of file */
\ No newline at end of file
...@@ -4,6 +4,8 @@ White Rabbit Softcore PLL (SoftPLL) - common definitions ...@@ -4,6 +4,8 @@ White Rabbit Softcore PLL (SoftPLL) - common definitions
*/ */
static int n_chan_ref, n_chan_out;
/* PI regulator state */ /* PI regulator state */
typedef struct { typedef struct {
int ki, kp; /* integral and proportional gains (1<<PI_FRACBITS == 1.0f) */ int ki, kp; /* integral and proportional gains (1<<PI_FRACBITS == 1.0f) */
...@@ -93,20 +95,20 @@ static void ld_init(spll_lock_det_t *ld) ...@@ -93,20 +95,20 @@ static void ld_init(spll_lock_det_t *ld)
ld->lock_cnt = 0; ld->lock_cnt = 0;
} }
#define DBG_Y 0
#define DBG_ERR 1
#define DBG_TAG 2
#define DBG_REF 5
#define DBG_PERIOD 3
#define DBG_EVENT 4
#define DBG_SAMPLE_ID 6
#define DBG_HELPER 0x20
#define DBG_PRELOCK 0x40
#define DBG_EVT_START 1
#define DBG_EVT_LOCKED 2
static inline void spll_debug(int what, int value, int last) static void spll_enable_tagger(int channel, int enable)
{ {
SPLL->DFR_SPLL = (last ? 0x80000000 : 0) | (value & 0xffffff) | (what << 24); if(channel >= n_chan_ref) /* Output channel? */
{
if(enable)
SPLL->OCER |= 1<< (channel - n_chan_ref);
else
SPLL->OCER &= ~ (1<< (channel - n_chan_ref));
} else {
if(enable)
SPLL->RCER |= 1<<channel;
else
SPLL->RCER &= ~ (1<<channel);
}
TRACE("spll_enable_channel: ch %d, OCER %x, RCER %x\n", channel, SPLL->OCER, SPLL->RCER);
} }
\ No newline at end of file
#define DBG_Y 0
#define DBG_ERR 1
#define DBG_TAG 2
#define DBG_REF 5
#define DBG_PERIOD 3
#define DBG_EVENT 4
#define DBG_SAMPLE_ID 6
#define DBG_HELPER 0x20
#define DBG_PRELOCK 0x40
#define DBG_EVT_START 1
#define DBG_EVT_LOCKED 2
static inline void spll_debug(int what, int value, int last)
{
SPLL->DFR_SPLL = (last ? 0x80000000 : 0) | (value & 0xffffff) | (what << 24);
}
...@@ -19,12 +19,9 @@ White Rabbit Softcore PLL (SoftPLL) - common definitions ...@@ -19,12 +19,9 @@ White Rabbit Softcore PLL (SoftPLL) - common definitions
/* Fractional bits in PI controller coefficients */ /* Fractional bits in PI controller coefficients */
#define PI_FRACBITS 12 #define PI_FRACBITS 12
/* Number of reference channels */ /* Max. number of reference channels */
#define N_CHAN_REF 7 #define MAX_CHAN_REF 7
/* Local reference input */ /* Max. number of output channels */
#define ID_LOCAL_REF 6 #define MAX_CHAN_OUT 1
/* Number of output channels */
#define N_CHAN_OUT 1
...@@ -42,7 +42,7 @@ void helper_prelock_enable(int ref_channel, int enable) ...@@ -42,7 +42,7 @@ void helper_prelock_enable(int ref_channel, int enable)
SPLL->CSR = 0; SPLL->CSR = 0;
dummy = SPLL->PER_HPLL; dummy = SPLL->PER_HPLL; /* clean any pending frequency measurement to avoid distubing the control loop */
if(enable) if(enable)
SPLL->CSR = SPLL_CSR_PER_SEL_W(ref_channel) | SPLL_CSR_PER_EN; SPLL->CSR = SPLL_CSR_PER_SEL_W(ref_channel) | SPLL_CSR_PER_EN;
else else
...@@ -92,7 +92,7 @@ struct spll_helper_phase_state { ...@@ -92,7 +92,7 @@ struct spll_helper_phase_state {
spll_lock_det_t ld; spll_lock_det_t ld;
}; };
void helper_phase_init(struct spll_helper_phase_state *s) void helper_phase_init(struct spll_helper_phase_state *s, int ref_channel)
{ {
/* Phase branch PI controller */ /* Phase branch PI controller */
...@@ -109,7 +109,7 @@ void helper_phase_init(struct spll_helper_phase_state *s) ...@@ -109,7 +109,7 @@ void helper_phase_init(struct spll_helper_phase_state *s)
s->ld.threshold = 200; s->ld.threshold = 200;
s->ld.lock_samples = 1000; s->ld.lock_samples = 1000;
s->ld.delock_samples = 900; s->ld.delock_samples = 900;
s->ref_src = 8; s->ref_src = ref_channel;
s->p_setpoint = 0; s->p_setpoint = 0;
s->p_adder = 0; s->p_adder = 0;
s->sample_n = 0; s->sample_n = 0;
...@@ -120,11 +120,7 @@ void helper_phase_init(struct spll_helper_phase_state *s) ...@@ -120,11 +120,7 @@ void helper_phase_init(struct spll_helper_phase_state *s)
void helper_phase_enable(int ref_channel, int enable) void helper_phase_enable(int ref_channel, int enable)
{ {
if(enable) spll_enable_tagger(ref_channel, enable);
SPLL->OCER = 1; /* fixme: use ref_channel */
else
SPLL->OCER = 0;
// spll_debug(DBG_EVENT | DBG_HELPER, DBG_EVT_START, 1); // spll_debug(DBG_EVENT | DBG_HELPER, DBG_EVT_START, 1);
} }
...@@ -186,13 +182,12 @@ void helper_start(struct spll_helper_state *s, int ref_channel) ...@@ -186,13 +182,12 @@ void helper_start(struct spll_helper_state *s, int ref_channel)
s->ref_channel = ref_channel; s->ref_channel = ref_channel;
helper_prelock_init(&s->prelock); helper_prelock_init(&s->prelock);
helper_phase_init(&s->phase); helper_phase_init(&s->phase, ref_channel);
helper_prelock_enable(ref_channel, 1); helper_prelock_enable(ref_channel, 1);
spll_debug(DBG_EVENT | DBG_PRELOCK | DBG_HELPER, DBG_EVT_START, 1); spll_debug(DBG_EVENT | DBG_PRELOCK | DBG_HELPER, DBG_EVT_START, 1);
} }
void helper_update(struct spll_helper_state *s, int tag, int source) int helper_update(struct spll_helper_state *s, int tag, int source)
{ {
switch(s->state) switch(s->state)
{ {
...@@ -204,13 +199,9 @@ void helper_update(struct spll_helper_state *s, int tag, int source) ...@@ -204,13 +199,9 @@ void helper_update(struct spll_helper_state *s, int tag, int source)
s->phase.pi.bias = s->prelock.pi.y; s->phase.pi.bias = s->prelock.pi.y;
helper_phase_enable(s->ref_channel, 1); helper_phase_enable(s->ref_channel, 1);
} }
break; return SPLL_LOCKING;
case HELPER_PHASE: case HELPER_PHASE:
if(helper_phase_update(&s->phase, tag, source)==SPLL_LOCKED) return helper_phase_update(&s->phase, tag, source);
{
// spll_debug(DBG_EVENT | DBG_HELPER, DBG_EVT_LOCKED, 1);
}
break;
} }
return SPLL_LOCKING;
} }
\ No newline at end of file
...@@ -2,16 +2,18 @@ ...@@ -2,16 +2,18 @@
#include "uart.h" #include "uart.h"
#include "timer.h" #include "timer.h"
void _irq_entry() {}; //void _irq_entry() {};
main() main()
{ {
uart_init(); uart_init();
ad9516_init(); ad9516_init();
spll_test();
for(;;) for(;;)
{ {
mprintf("Ping!\n"); mprintf("Ping [lock %d]!\n", spll_check_lock());
timer_delay(TICS_PER_SECOND); timer_delay(TICS_PER_SECOND);
} }
} }
\ No newline at end of file
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