Commit 17b2de51 authored by Tomasz Wlostowski's avatar Tomasz Wlostowski

Merge branch 'master' of github.com:twlostow/wr-core-software

parents 2aa0b9af a294935b
*.o
*.elf
*.ram
*.bin
*.*~
tools/zpu-loader
tools/vuart_console
tools/genraminit
wrc_disasm.S
......@@ -2,8 +2,29 @@ PLATFORM = lm32
OBJS_WRC = wrc_main.o dev/uart.o dev/endpoint.o dev/minic.o dev/pps_gen.o dev/timer.o dev/softpll.o lib/mprintf.o
D = ptpd-noposix
PTPD_CFLAGS = -ffreestanding -DPTPD_FREESTANDING -DWRPC_EXTRA_SLIM -DPTPD_MSBF -DPTPD_DBG
PTPD_CFLAGS += -Wall -ggdb -I$D/wrsw_hal \
-I$D/libptpnetif -I$D/PTPWRd \
-include $D/compat.h -include $D/libposix/ptpd-wrappers.h
PTPD_CFLAGS += -DPTPD_NO_DAEMON -DNEW_SINGLE_WRFSM #-DPTPD_DBGMSG
OBJS_PTPD = $D/PTPWRd/arith.o
OBJS_PTPD += $D/PTPWRd/bmc.o
OBJS_PTPD += $D/PTPWRd/dep/msg.o
OBJS_PTPD += $D/PTPWRd/dep/net.o
OBJS_PTPD += $D/PTPWRd/dep/servo.o
OBJS_PTPD += $D/PTPWRd/dep/sys.o
OBJS_PTPD += $D/PTPWRd/dep/timer.o
OBJS_PTPD += $D/PTPWRd/dep/wr_servo.o
OBJS_PTPD += $D/PTPWRd/protocol.o
OBJS_PTPD += $D/PTPWRd/wr_protocol.o
OBJS_PTPD_FREE = $D/libposix/freestanding-startup.o
OBJS_PTPD_FREE += $D/libposix/freestanding-display.o
OBJS_PTPD_FREE += $D/libposix/wr_nolibs.o
OBJS_PTPD_FREE += $D/libposix/freestanding-wrapper.o
ifeq ($(PLATFORM), zpu)
CROSS_COMPILE ?= /opt/gcc-zpu/bin/zpu-elf-
CFLAGS_PLATFORM = -abel -Wl,--relax -Wl,--gc-sections
LDFLAGS_PLATFORM = -abel -Wl,--relax -Wl,--gc-sections
OBJS_PLATFORM=
......@@ -11,29 +32,31 @@ else
CROSS_COMPILE ?= /opt/gcc-lm32/bin/lm32-elf-
CFLAGS_PLATFORM = -mmultiply-enabled -mbarrel-shift-enabled
LDFLAGS_PLATFORM = -mmultiply-enabled -mbarrel-shift-enabled -nostdlib -T target/lm32/ram.ld
OBJS_PLATFORM=target/lm32/crt0.o
OBJS_PLATFORM=target/lm32/crt0.o target/lm32/irq.o
endif
CC=$(CROSS_COMPILE)gcc
OBJCOPY=$(CROSS_COMPILE)objcopy
OBJDUMP=$(CROSS_COMPILE)objdump
CFLAGS= $(CFLAGS_PLATFORM) -ffunction-sections -fdata-sections -Os -Iinclude
CFLAGS= $(CFLAGS_PLATFORM) -ffunction-sections -fdata-sections -Os -Iinclude -include include/trace.h $(PTPD_CFLAGS)
LDFLAGS= $(LDFLAGS_PLATFORM) -ffunction-sections -fdata-sections -Os -Iinclude
OBJS=$(OBJS_PLATFORM) $(OBJS_WRC)
SIZE = $(CROSS_COMPILE)size
OBJS=$(OBJS_PLATFORM) $(OBJS_WRC) $(OBJS_PTPD) $(OBJS_PTPD_FREE)
OUTPUT=wrc
all: $(OBJS)
$(SIZE) -t $(OBJS)
${CC} -o $(OUTPUT).elf $(OBJS) $(LDFLAGS)
${OBJCOPY} -O binary $(OUTPUT).elf $(OUTPUT).bin
${OBJDUMP} -d $(OUTPUT).elf > $(OUTPUT)_disasm.S
./tools/genraminit $(OUTPUT).bin 0 > $(OUTPUT).ram
clean:
rm -f $(OBJS) $(OUTPUT).elf $(OUTPUT).bin $(OUTPUT).ram
%.o: %.c
${CC} $(CFLAGS) $(INCLUDE_DIR) $(LIB_DIR) -c $^ -o $@
${CC} $(CFLAGS) $(PTPD_CFLAGS) $(INCLUDE_DIR) $(LIB_DIR) -c $^ -o $@
load: all
./tools/zpu-loader $(OUTPUT).bin
......
#include <stdio.h>
#include "board.h"
#include<endpoint.h>
#include <hw/endpoint_regs.h>
#include <hw/endpoint_mdio.h>
#define DMTD_AVG_SAMPLES 256
#define DMTD_MAX_PHASE 16384
#define UIS_PER_SERIAL_BIT 800
static int autoneg_enabled;
......@@ -34,14 +32,24 @@ static void pcs_write(int location,
}
static void set_mac_addr(uint8_t dev_addr[])
{
EP->MACL = ((uint32_t)dev_addr[3] << 24)
| ((uint32_t)dev_addr[2] << 16)
| ((uint32_t)dev_addr[1] << 8)
| ((uint32_t)dev_addr[0]);
{
EP->MACL = ((uint32_t)dev_addr[2] << 24)
| ((uint32_t)dev_addr[3] << 16)
| ((uint32_t)dev_addr[4] << 8)
| ((uint32_t)dev_addr[5]);
EP->MACH = ((uint32_t)dev_addr[0] << 8)
| ((uint32_t)dev_addr[1]);
}
EP->MACH = ((uint32_t)dev_addr[5] << 8)
| ((uint32_t)dev_addr[4]);
void get_mac_addr(uint8_t dev_addr[])
{
dev_addr[5] = (uint8_t)(EP->MACL & 0x000000ff);
dev_addr[4] = (uint8_t)(EP->MACL & 0x0000ff00) >> 8;
dev_addr[3] = (uint8_t)(EP->MACL & 0x00ff0000) >> 16;
dev_addr[2] = (uint8_t)(EP->MACL & 0xff000000) >> 24;
dev_addr[1] = (uint8_t)(EP->MACH & 0x000000ff);
dev_addr[0] = (uint8_t)(EP->MACH & 0x0000ff00) >> 8;
}
......@@ -71,8 +79,13 @@ int ep_enable(int enabled, int autoneg)
EP->ECR = EP_ECR_TX_EN_FRA | EP_ECR_RX_EN_FRA | EP_ECR_RST_CNT;
autoneg_enabled = autoneg;
pcs_write(MDIO_REG_MCR, MDIO_MCR_RESET); /* reset the PHY */
#if 1
pcs_write(MDIO_REG_MCR, MDIO_MCR_PDOWN); /* reset the PHY */
timer_delay(2000);
pcs_write(MDIO_REG_MCR, 0); /* reset the PHY */
// pcs_write(MDIO_REG_MCR, MDIO_MCR_RESET); /* reset the PHY */
#endif
pcs_write(MDIO_REG_ADVERTISE, 0);
mcr = MDIO_MCR_SPEED1000_MASK | MDIO_MCR_FULLDPLX_MASK;
......@@ -98,6 +111,7 @@ int ep_link_up()
return (msr & flags) == flags ? 1 : 0;
}
int ep_get_deltas(uint32_t *delta_tx, uint32_t *delta_rx)
{
*delta_tx = 0;
......@@ -108,5 +122,36 @@ void ep_show_counters()
{
int i;
for(i=0;i<16;i++)
mprintf("cntr%d = %d\n", i, EP->RMON_RAM[i]);
TRACE_DEV("cntr%d = %d\n", i, EP->RMON_RAM[i]);
}
int ep_get_psval(int32_t *psval)
{
uint32_t val;
val = EP->DMSR;
if(val & EP_DMSR_PS_RDY)
*psval = EP_DMSR_PS_VAL_R(val);
else
*psval = 0;
return val & EP_DMSR_PS_RDY;
}
int ep_cal_pattern_enable()
{
uint32_t val;
val = pcs_read(MDIO_REG_WR_SPEC);
val |= MDIO_WR_SPEC_TX_CAL;
pcs_write(MDIO_REG_WR_SPEC, val);
return 0;
}
int ep_cal_pattern_disable()
{
uint32_t val;
val = pcs_read(MDIO_REG_WR_SPEC);
val &= (~MDIO_WR_SPEC_TX_CAL);
pcs_write(MDIO_REG_WR_SPEC, val);
}
......@@ -37,8 +37,8 @@
fc = (raw >> 28) & 0xf;
static volatile uint32_t dma_tx_buf[MINIC_DMA_RX_BUF_SIZE / 4];
static volatile uint32_t dma_rx_buf[MINIC_DMA_TX_BUF_SIZE / 4];
static volatile uint32_t dma_tx_buf[MINIC_DMA_TX_BUF_SIZE / 4];
static volatile uint32_t dma_rx_buf[MINIC_DMA_RX_BUF_SIZE / 4];
struct wr_minic {
volatile uint32_t *rx_head, *rx_base;
......@@ -72,6 +72,7 @@ static void minic_new_rx_buffer()
minic_writel(MINIC_REG_MCR, 0);
minic_writel(MINIC_REG_RX_ADDR, (uint32_t) minic.rx_base);
minic_writel(MINIC_REG_RX_AVAIL, (minic.rx_size - MINIC_MTU) >> 2);
// TRACE_DEV("Sizeof: %d Size : %d Avail: %d\n", minic.rx_size, (minic.rx_size - MINIC_MTU) >> 2);
minic_writel(MINIC_REG_MCR, MINIC_MCR_RX_EN);
}
......@@ -87,7 +88,10 @@ static void minic_new_tx_buffer()
void minic_init()
{
minic_writel(MINIC_REG_EIC_IDR, MINIC_EIC_IDR_RX);
minic_writel(MINIC_REG_EIC_ISR, MINIC_EIC_ISR_RX);
minic.rx_base = dma_rx_buf;
minic.rx_size = sizeof(dma_rx_buf);
......@@ -99,13 +103,18 @@ void minic_init()
minic_writel(MINIC_REG_EIC_IER, MINIC_EIC_IER_RX);
}
void minic_disable()
{
minic_writel(MINIC_REG_MCR, 0);
}
int minic_poll_rx()
{
uint32_t isr;
isr = minic_readl(MINIC_REG_EIC_ISR);
return isr;
return (isr & MINIC_EIC_ISR_RX) ? 1 : 0;//>>1;
}
int minic_rx_frame(uint8_t *hdr, uint8_t *payload, uint32_t buf_size, struct hw_timestamp *hwts)
......@@ -121,10 +130,12 @@ int minic_rx_frame(uint8_t *hdr, uint8_t *payload, uint32_t buf_size, struct hw_
return 0;
desc_hdr = *minic.rx_head;
// TRACE_DEV("RX_FRAME_ENTER\n\nRxHead %x buffer at %x\n", minic.rx_head, minic.rx_base);
if(!RX_DESC_VALID(desc_hdr)) /* invalid descriptor? Weird, the RX_ADDR seems to be saying something different. Ignore the packet and purge the RX buffer. */
{
// mprintf("weird, invalid RX descriptor (%x, head %x)\n", desc_hdr, rx_head);
TRACE_DEV("weird, invalid RX descriptor (%x, head %x)\n", desc_hdr, minic.rx_head);
minic_new_rx_buffer();
return 0;
}
......@@ -132,6 +143,8 @@ int minic_rx_frame(uint8_t *hdr, uint8_t *payload, uint32_t buf_size, struct hw_
payload_size = RX_DESC_SIZE(desc_hdr);
num_words = ((payload_size + 3) >> 2) + 1;
// TRACE_DEV("NWords %d\n", num_words);
/* valid packet */
if(!RX_DESC_ERROR(desc_hdr))
{
......@@ -161,7 +174,11 @@ int minic_rx_frame(uint8_t *hdr, uint8_t *payload, uint32_t buf_size, struct hw_
else
hwts->ahead = 0;
hwts->nsec = counter_r * 8;
TRACE_DEV("TS minic_rx_frame: %d.%d\n", hwts->utc, hwts->nsec);
}
n_recvd = (buf_size < payload_size ? buf_size : payload_size);
......@@ -169,14 +186,23 @@ int minic_rx_frame(uint8_t *hdr, uint8_t *payload, uint32_t buf_size, struct hw_
/* FIXME: VLAN support */
memcpy(hdr, (void*)minic.rx_head + 4, ETH_HEADER_SIZE);
//TRACE_DEV("%s: packet: ", __FUNCTION__);
//for(i=0; i<ETH_HEADER_SIZE; i++) TRACE_DEV("%x ", *(hdr+i));
memcpy(payload, (void*)minic.rx_head + 4 + ETH_HEADER_SIZE, n_recvd - ETH_HEADER_SIZE);
//for(i=0; i<n_recvd-ETH_HEADER_SIZE; i++) TRACE_DEV("%x ", *(payload+i));
/* for(i=0;i<n_recvd;i++)
mprintf("%x ", buf[i]);
mprintf("---\n");*/
/* for(i=0;i<n_recvd-14;i++)
TRACE_DEV("%x ", payload[i]);
TRACE_DEV("---\n");
*/
// TRACE_DEV("nwords_avant: %d\n", num_words);
minic.rx_head += num_words;
} else { // RX_DESC_ERROR
// TRACE_DEV("nwords_avant_err: %d\n", num_words);
minic.rx_head += num_words;
}
......@@ -184,6 +210,7 @@ int minic_rx_frame(uint8_t *hdr, uint8_t *payload, uint32_t buf_size, struct hw_
if(rx_addr_cur < (uint32_t)minic.rx_head) /* nothing new in the buffer? */
{
// TRACE_DEV("MoreData? %x, head %x\n", rx_addr_cur, minic.rx_head);
if(minic_readl(MINIC_REG_MCR) & MINIC_MCR_RX_FULL)
minic_new_rx_buffer();
......@@ -201,12 +228,21 @@ int minic_tx_frame(uint8_t *hdr, uint8_t *payload, uint32_t size, struct hw_time
{
uint32_t d_hdr, mcr, nwords;
minic_new_tx_buffer();
nwords = ((size + 1) >> 1) - 1;
memset(minic.tx_head, 0x0, size + 16);
memset((void*)minic.tx_head + 4, 0, size < 60 ? 60 : size);
memcpy((void*)minic.tx_head + 4, hdr, ETH_HEADER_SIZE);
memcpy((void*)minic.tx_head + 4 + ETH_HEADER_SIZE, payload, size - ETH_HEADER_SIZE);
if(size < 60)
size = 60;
nwords = ((size + 1) >> 1) - 1;
if(hwts)
{
......@@ -249,6 +285,9 @@ int minic_tx_frame(uint8_t *hdr, uint8_t *payload, uint32_t size, struct hw_time
hwts->utc = utc;
hwts->ahead = 0;
hwts->nsec = counter_r * 8;
TRACE_DEV("TS minic_tx_frame: %d.%d\n", hwts->utc, hwts->nsec);
}
tx_oob_val++;
......
......@@ -24,7 +24,7 @@ void pps_gen_init()
ppsg_writel( PPSG_REG_CR, cr);
ppsg_writel( PPSG_REG_ADJ_UTCLO, 1285700840);
ppsg_writel( PPSG_REG_ADJ_UTCLO, 100 );
ppsg_writel( PPSG_REG_ADJ_UTCHI, 0);
ppsg_writel( PPSG_REG_ADJ_NSEC, 0);
......@@ -36,24 +36,30 @@ void pps_gen_adjust_nsec(int32_t how_much)
{
uint32_t cr;
mprintf("AdjustPPS: %d nanoseconds\n", how_much);
TRACE_DEV("ADJ: nsec %d nanoseconds\n", how_much);
#if 1
ppsg_writel( PPSG_REG_ADJ_UTCLO, 0);
ppsg_writel( PPSG_REG_ADJ_UTCHI, 0);
ppsg_writel( PPSG_REG_ADJ_NSEC, ( how_much / 8 ));
ppsg_writel( PPSG_REG_CR, PPSG_CR_CNT_EN | PPSG_CR_PWIDTH_W(PPS_PULSE_WIDTH) | PPSG_CR_CNT_ADJ);
#endif
}
void shw_pps_gen_adjust_utc(int32_t how_much)
void pps_gen_adjust_utc(int32_t how_much)
{
uint32_t cr;
mprintf("AdjustUTC: %d seconds\n", how_much);
#if 1
TRACE_DEV("ADJ: utc %d seconds\n", how_much);
ppsg_writel( PPSG_REG_ADJ_UTCLO, how_much);
ppsg_writel( PPSG_REG_ADJ_UTCHI, 0);
ppsg_writel( PPSG_REG_ADJ_NSEC, 0);
ppsg_writel( PPSG_REG_CR, PPSG_CR_CNT_EN | PPSG_CR_PWIDTH_W(PPS_PULSE_WIDTH) | PPSG_CR_CNT_ADJ);
#endif
}
int pps_gen_busy()
......
#include "board.h"
#include "irq.h"
volatile int irq_cnt = 0;
__attribute__((interrupt)) void softpll_irq()
#include <hw/softpll_regs.h>
#define TAG_BITS 17
#define HPLL_N 14
#define HPLL_DAC_BIAS 30000
#define PI_FRACBITS 12
#define CHAN_FB 8
#define CHAN_REF 4
#define CHAN_PERIOD 2
//#define CHAN_HPLL 1
#define READY_FB (8<<4)
#define READY_REF (4<<4)
#define READY_PERIOD (2<<4)
//#define READY_HPLL (1<<4)
static volatile struct SPLL_WB *SPLL = (volatile struct SPLL_WB *) BASE_SOFTPLL;
struct softpll_config {
int hpll_f_kp;
int hpll_f_ki;
int hpll_f_setpoint;
int hpll_ld_f_samples;
int hpll_ld_f_threshold;
int hpll_p_kp;
int hpll_p_ki;
int hpll_ld_p_samples;
int hpll_ld_p_threshold;
int hpll_delock_threshold;
int hpll_dac_bias;
int dpll_f_kp;
int dpll_f_ki;
int dpll_p_kp;
int dpll_p_ki;
int dpll_ld_samples;
int dpll_ld_threshold;
int dpll_delock_threshold;
int dpll_dac_bias;
int dpll_deglitcher_threshold;
};
const struct softpll_config pll_cfg =
{
/* Helper PLL */
28*32*16, // f_kp
20*32*16, // f_ki
16, // setpoint
1000, // lock detect freq samples
2, // lock detect freq threshold
2.0*32*16, // p_kp
0.05*32*16, // p_ki
1000, // lock detect phase samples
300, // lock detect phase threshold
500, // delock threshold
32000, // HPLL dac bias
/* DMTD PLL */
100, // f_kp
600, // f_ki
1304, // p_kp
10, // p_ki
1000, // lock detect samples
500, // lock detect threshold
500, // delock threshold
32000, // DPLL dac bias
1000 // deglitcher threshold
};
struct softpll_state {
int h_lock_counter;
int h_i;
int h_dac_bias;
int h_p_setpoint;
int h_freq_mode;
int h_locked;
int d_dac_bias;
int d_tag_ref_d0;
int d_tag_fb_d0;
int d_tag_ref_ready;
int d_tag_fb_ready;
int d_period_ref;
int d_period_fb;
int d_freq_mode;
int d_lock_counter;
int d_i;
int d_p_setpoint;
int d_phase_shift;
int d_locked;
};
int eee, dve;
static volatile struct softpll_state pstate;
void _irq_entry()
{
int dv;
int tag_ref_ready = 0;
int tag_fb_ready = 0;
int tag_ref;
int tag_fb;
if(SPLL->CSR & READY_REF)
{
tag_ref = SPLL->TAG_REF;
tag_ref_ready = 1;
}
if(SPLL->CSR & READY_FB)
{
tag_fb = SPLL->TAG_FB;
tag_fb_ready = 1;
}
/* HPLL: active frequency branch */
if(pstate.h_freq_mode)
{
int freq_err = SPLL->PER_HPLL;
if(freq_err & 0x100) freq_err |= 0xffffff00; /* sign-extend */
freq_err += pll_cfg.hpll_f_setpoint;
/* PI control */
pstate.h_i += freq_err;
dv = ((pstate.h_i * pll_cfg.hpll_f_ki + freq_err * pll_cfg.hpll_f_kp) >> PI_FRACBITS) + pll_cfg.hpll_dac_bias;
SPLL->DAC_HPLL = dv; /* update DAC */
/* lock detection */
if(freq_err >= -pll_cfg.hpll_ld_f_threshold && freq_err <= pll_cfg.hpll_ld_f_threshold)
pstate.h_lock_counter++;
else
pstate.h_lock_counter=0;
/* frequency has been stable for quite a while? switch to phase branch */
if(pstate.h_lock_counter == pll_cfg.hpll_ld_f_samples)
{
pstate.h_freq_mode = 0;
pstate.h_dac_bias = dv;
pstate.h_i = 0;
pstate.h_lock_counter = 0;
SPLL->CSR = SPLL_CSR_TAG_EN_W(CHAN_REF);
}
/* HPLL: active phase branch */
} else if (tag_ref_ready) {
if(pstate.h_p_setpoint < 0) /* we don't have yet any phase samples? */
pstate.h_p_setpoint = tag_ref & 0x3fff;
else {
int phase_err;
phase_err = (tag_ref & 0x3fff) - pstate.h_p_setpoint;
pstate.h_i += phase_err;
dv = ((pstate.h_i * pll_cfg.hpll_p_ki + phase_err * pll_cfg.hpll_p_kp) >> PI_FRACBITS) + pstate.h_dac_bias;
SPLL->DAC_HPLL = dv; /* Update DAC */
if(abs(phase_err) >= pll_cfg.hpll_delock_threshold && pstate.h_locked)
{
SPLL->CSR = SPLL_CSR_TAG_EN_W(CHAN_PERIOD); /* fall back to freq mode */
pstate.h_locked = 0;
pstate.h_freq_mode = 1;
}
if(abs(phase_err) <= pll_cfg.hpll_ld_p_threshold && !pstate.h_locked)
pstate.h_lock_counter++;
else
pstate.h_lock_counter = 0;
if(pstate.h_lock_counter == pll_cfg.hpll_ld_p_samples)
{
SPLL->CSR |= SPLL_CSR_TAG_EN_W(CHAN_FB); /* enable feedback channel and start DMPLL */
pstate.h_locked = 1;
pstate.d_tag_ref_d0 = -1;
pstate.d_tag_fb_d0 = -1;
pstate.d_freq_mode = 1;
pstate.d_p_setpoint = 0;
pstate.d_lock_counter = 0;
pstate.d_i = 0;
pstate.d_locked = 0;
}
}
}
/* DMPLL */
if(pstate.h_locked && pstate.d_freq_mode)
{
int freq_err;
if(tag_ref_ready)
{
if(pstate.d_tag_ref_d0 > 0)
{
int tmp = tag_ref - pstate.d_tag_ref_d0;
if(tmp < 0) tmp += (1<<TAG_BITS)-1;
pstate.d_period_ref = tmp;
}
pstate.d_tag_ref_d0 = tag_ref;
}
if(tag_fb_ready)
{
if(pstate.d_tag_fb_d0 > 0)
{
int tmp = tag_fb - pstate.d_tag_fb_d0;
if(tmp < 0) tmp += (1<<TAG_BITS)-1;
pstate.d_period_fb = tmp;
}
pstate.d_tag_fb_d0 = tag_fb;
}
freq_err = - pstate.d_period_fb + pstate.d_period_ref;
pstate.d_i += freq_err;
dv = ((pstate.d_i * pll_cfg.dpll_f_ki + freq_err * pll_cfg.dpll_f_kp) >> PI_FRACBITS) + pll_cfg.dpll_dac_bias;
SPLL->DAC_DMPLL = dv;
if(abs(freq_err) <= pll_cfg.dpll_ld_threshold)
pstate.d_lock_counter++;
else
pstate.d_lock_counter=0;
/* frequency has been stable for quite a while? switch to phase branch */
if(pstate.d_lock_counter == pll_cfg.dpll_ld_samples)
{
pstate.d_freq_mode = 0;
pstate.d_dac_bias = dv;
pstate.d_i = 0;
pstate.d_lock_counter = 0;
pstate.d_tag_ref_ready = 0;
pstate.d_tag_fb_ready = 0;
pstate.d_p_setpoint = 0;
}
}
/* DMPLL phase-lock */
if(pstate.h_locked && !pstate.d_freq_mode)
{
int phase_err = 0;
if(tag_ref_ready)
pstate.d_tag_ref_d0 = tag_ref;
tag_ref = pstate.d_tag_ref_d0 ;
tag_fb += pstate.d_p_setpoint; // was tag_fb
tag_fb &= (1<<TAG_BITS)-1;
//if(tag_ref > (1<<TAG_BITS)) tag_ref -= (1<<TAG_BITS);
//if(tag_ref < 0) tag_ref += (1<<TAG_BITS);
if(tag_fb_ready)
{
while (tag_ref > 16384 ) tag_ref-=16384;
while (tag_fb > 16384 ) tag_fb-=16384;
phase_err = tag_ref-tag_fb;
pstate.d_i += phase_err;
dv = ((pstate.d_i * pll_cfg.dpll_p_ki + phase_err * pll_cfg.dpll_p_kp) >> PI_FRACBITS) + pll_cfg.dpll_dac_bias;
SPLL->DAC_DMPLL = dv;
eee=phase_err;
}
if(pstate.d_p_setpoint < pstate.d_phase_shift)
pstate.d_p_setpoint++;
else if(pstate.d_p_setpoint > pstate.d_phase_shift)
pstate.d_p_setpoint--;
if(abs(phase_err) <= pll_cfg.dpll_ld_threshold && !pstate.d_locked)
pstate.d_lock_counter++;
else
pstate.d_lock_counter = 0;
if(pstate.d_lock_counter == pll_cfg.dpll_ld_samples)
pstate.d_locked = 1;
}
clear_irq();
}
void softpll_enable()
{
SPLL->DAC_HPLL = pll_cfg.hpll_dac_bias;
SPLL->DAC_DMPLL = pll_cfg.dpll_dac_bias;
SPLL->DEGLITCH_THR = pll_cfg.dpll_deglitcher_threshold;
pstate.h_p_setpoint = -1;
pstate.h_i = 0;
pstate.h_freq_mode = 1;
pstate.h_lock_counter = 0;
pstate.h_locked = 0;
SPLL->CSR = SPLL_CSR_TAG_EN_W(CHAN_PERIOD);
SPLL->EIC_IER = 1;
enable_irq();
// softpll_test();
}
int softpll_check_lock()
{
TRACE_DEV("LCK h:f%d l%d d: f%d l%d\n",
pstate.h_freq_mode ,pstate.h_locked,
pstate.d_freq_mode, pstate.d_locked);
return pstate.h_locked && pstate.d_locked;
}
int softpll_busy()
{
return pstate.d_p_setpoint != pstate.d_phase_shift;
}
void softpll_set_phase(int ps)
{
pstate.d_phase_shift = (int32_t) (((int64_t)ps * 16384LL) / 8000LL);
TRACE_DEV("ADJ: phase %d [ps], %d units\n", ps, pstate.d_phase_shift);
}
void softpll_disable()
{
SPLL->CSR = 0;
disable_irq();
}
int softpll_get_setpoint()
{
irq_cnt++;
uart_write_byte('x');
}
\ No newline at end of file
return pstate.d_p_setpoint;
}
......@@ -7,6 +7,7 @@
#define BASE_PPSGEN 0x50000
#define BASE_EP 0x20000
#define BASE_MINIC 0x10000
#define BASE_SOFTPLL 0x40000
#define CPU_CLOCK 62500000ULL
......
#ifndef __ENDPOINT_H
#define __ENDPOINT_H
#define DMTD_AVG_SAMPLES 256
#define DMTD_MAX_PHASE 16384
void ep_init(uint8_t mac_addr[]);
void get_mac_addr(uint8_t dev_addr[]);
int ep_enable(int enabled, int autoneg);
int ep_link_up();
int ep_get_deltas(uint32_t *delta_tx, uint32_t *delta_rx);
int ep_get_psval(int32_t *psval);
int ep_cal_pattern_enable();
int ep_cal_pattern_disable();
#endif
/*
Register definitions for slave core: WR Softcore PLL
* File : softpll_regs.h
* Author : auto-generated by wbgen2 from wr_softpll.wb
* Created : Sat Apr 9 13:29:44 2011
* Standard : ANSI C
THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE wr_softpll.wb
DO NOT HAND-EDIT UNLESS IT'S ABSOLUTELY NECESSARY!
*/
#ifndef __WBGEN2_REGDEFS_WR_SOFTPLL_WB
#define __WBGEN2_REGDEFS_WR_SOFTPLL_WB
#include <inttypes.h>
#if defined( __GNUC__)
#define PACKED __attribute__ ((packed))
#else
#error "Unsupported compiler?"
#endif
#ifndef __WBGEN2_MACROS_DEFINED__
#define __WBGEN2_MACROS_DEFINED__
#define WBGEN2_GEN_MASK(offset, size) (((1<<(size))-1) << (offset))
#define WBGEN2_GEN_WRITE(value, offset, size) (((value) & ((1<<(size))-1)) << (offset))
#define WBGEN2_GEN_READ(reg, offset, size) (((reg) >> (offset)) & ((1<<(size))-1))
#define WBGEN2_SIGN_EXTEND(value, bits) (((value) & (1<<bits) ? ~((1<<(bits))-1): 0 ) | (value))
#endif
/* definitions for register: SPLL Control/Status Register */
/* definitions for field: Tagger enable in reg: SPLL Control/Status Register */
#define SPLL_CSR_TAG_EN_MASK WBGEN2_GEN_MASK(0, 4)
#define SPLL_CSR_TAG_EN_SHIFT 0
#define SPLL_CSR_TAG_EN_W(value) WBGEN2_GEN_WRITE(value, 0, 4)
#define SPLL_CSR_TAG_EN_R(reg) WBGEN2_GEN_READ(reg, 0, 4)
/* definitions for field: Tag ready in reg: SPLL Control/Status Register */
#define SPLL_CSR_TAG_RDY_MASK WBGEN2_GEN_MASK(4, 4)
#define SPLL_CSR_TAG_RDY_SHIFT 4
#define SPLL_CSR_TAG_RDY_W(value) WBGEN2_GEN_WRITE(value, 4, 4)
#define SPLL_CSR_TAG_RDY_R(reg) WBGEN2_GEN_READ(reg, 4, 4)
/* definitions for register: HPLL Frequency Error */
/* definitions for register: DMPLL Tag ref */
/* definitions for register: DMPLL Tag fb */
/* definitions for register: HPLL DAC Output */
/* definitions for register: DMPLL DAC Output */
/* definitions for register: Deglitcher threshold */
/* definitions for register: Interrupt disable register */
/* definitions for field: Got a tag in reg: Interrupt disable register */
#define SPLL_EIC_IDR_TAG WBGEN2_GEN_MASK(0, 1)
/* definitions for register: Interrupt enable register */
/* definitions for field: Got a tag in reg: Interrupt enable register */
#define SPLL_EIC_IER_TAG WBGEN2_GEN_MASK(0, 1)
/* definitions for register: Interrupt mask register */
/* definitions for field: Got a tag in reg: Interrupt mask register */
#define SPLL_EIC_IMR_TAG WBGEN2_GEN_MASK(0, 1)
/* definitions for register: Interrupt status register */
/* definitions for field: Got a tag in reg: Interrupt status register */
#define SPLL_EIC_ISR_TAG WBGEN2_GEN_MASK(0, 1)
PACKED struct SPLL_WB {
/* [0x0]: REG SPLL Control/Status Register */
uint32_t CSR;
/* [0x4]: REG HPLL Frequency Error */
uint32_t PER_HPLL;
/* [0x8]: REG DMPLL Tag ref */
uint32_t TAG_REF;
/* [0xc]: REG DMPLL Tag fb */
uint32_t TAG_FB;
/* [0x10]: REG HPLL DAC Output */
uint32_t DAC_HPLL;
/* [0x14]: REG DMPLL DAC Output */
uint32_t DAC_DMPLL;
/* [0x18]: REG Deglitcher threshold */
uint32_t DEGLITCH_THR;
/* padding to: 8 words */
uint32_t __padding_0[1];
/* [0x20]: REG Interrupt disable register */
uint32_t EIC_IDR;
/* [0x24]: REG Interrupt enable register */
uint32_t EIC_IER;
/* [0x28]: REG Interrupt mask register */
uint32_t EIC_IMR;
/* [0x2c]: REG Interrupt status register */
uint32_t EIC_ISR;
};
#endif
......@@ -4,9 +4,11 @@
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned int uint32_t;
typedef signed long long uint64_t;
typedef signed char int8_t;
typedef signed short int16_t;
typedef signed int int32_t;
typedef signed long long int64_t;
#endif
#ifndef __IRQ_H
#define __IRQ_H
static inline void clear_irq()
{
unsigned int val = 1;
asm volatile ("wcsr ip, %0"::"r"(val));
}
#endif
......@@ -3,7 +3,10 @@
#include "types.h"
#define ETH_HEADER_SIZE 14
void minic_init();
void minic_disable();
int minic_poll_rx();
int minic_rx_frame(uint8_t *hdr, uint8_t *payload, uint32_t buf_size, struct hw_timestamp *hwts);
......
#ifndef __SOFTPLL_H
#define __SOFTPLL_H
void softpll_enable();
int softpll_check_lock();
void softpll_disable();
int softpll_busy();
void softpll_set_phase(int ps);
int softpll_get_setpoint();
#endif
//#ifndef __TRACE_H__
//#define __TRACE_H__
#define MSGS_PROTO 1 // PTPWRd/protocol.c
#define MSGS_WRPROTO 1 // PTPWRd/wr_protocol.c
#define MSGS_WRSERVO 1 // PTPWRd/dep/wr_servo.c
#define MSGS_MSG 0 // PTPWRd/dep/msg.c PTPWRd/dep/startup.c
#define MSGS_NET 0 // PTPWRd/dep/net.c
#define MSGS_ERR 1
#define MSGS_BMC 0 // PTPWRd/bmc.c
#define MSGS_PTPD 0 // PTPWRd/ptpd.c
#define MSGS_WRAPPER 1 // libposix/freestanding_wrapper.c
#define MSGS_DISPLAY 0 // libposix/freestanding_display.c
#define MSGS_DEV 1 // dev/*
#if MSGS_PROTO
#define TRACE_PROTO(...) mprintf("[PROTO ]: " __VA_ARGS__)
#else
#define TRACE_PROTO(...)
#endif
#if MSGS_WRPROTO
#define TRACE_WRPROTO(...) mprintf("[WRPROTO]: " __VA_ARGS__)
#else
#define TRACE_WRPROTO(...)
#endif
#if MSGS_WRSERVO
#define TRACE_WRSERVO(...) mprintf("[WR SRV ]: " __VA_ARGS__)
#else
#define TRACE_WRSERVO(...)
#endif
#if MSGS_MSG
#define TRACE_MSG(...) mprintf("[MSG ]: " __VA_ARGS__)
#else
#define TRACE_MSG(...)
#endif
#if MSGS_NET
#define TRACE_NET(...) mprintf("[NET ]: " __VA_ARGS__)
#else
#define TRACE_NET(...)
#endif
#if MSGS_ERR
#define TRACE_ERR(...) mprintf("[ERROR ]: " __VA_ARGS__)
#else
#define TRACE_ERR(...)
#endif
#if MSGS_BMC
#define TRACE_BMC(...) mprintf("[BMC ]: " __VA_ARGS__)
#else
#define TRACE_BMC(...)
#endif
#if MSGS_PTPD
#define TRACE_PTPD(...) mprintf("[PTPD ]: " __VA_ARGS__)
#else
#define TRACE_PTPD(...)
#endif
#if MSGS_WRAPPER
#define TRACE_WRAP(...) mprintf("[WRAPPER]: " __VA_ARGS__)
#else
#define TRACE_WRAP(...)
#endif
#if MSGS_DISPLAY
#define TRACE_DISP(...) mprintf("[DISPLAY]: " __VA_ARGS__)
#else
#define TRACE_DISP(...)
#endif
#if MSGS_DEV
#define TRACE_DEV(...) mprintf("[DEV ]: " __VA_ARGS__)
#else
#define TRACE_DEV(...)
#endif
//#endif
......@@ -30,6 +30,21 @@
.global _start
_start:
bi _crt0_enter
.org 0xc0
_interrupt_handler:
sw (sp+0),ra
calli _save_all
mvi r1,2
calli _irq_entry
bi _restore_all_and_return
nop
nop
nop
.org 0x100
_crt0_enter:
/* Setup stack and global pointer */
mvhi sp, hi(_fstack)
......@@ -37,24 +52,6 @@ _start:
mvhi gp, hi(_gp)
ori gp, gp, lo(_gp)
bi _crt0_enter
.org 0xc0
_interrupt_handler:
sw (sp+0),ra
calli _save_all
mvi r1,2
calli _irq_entry
bi _restore_all_and_return
nop
nop
nop
_crt0_enter:
/* Clear BSS */
mvhi r1, hi(_fbss)
ori r1, r1, lo(_fbss)
......@@ -65,13 +62,6 @@ _crt0_enter:
calli memset
mvi r1, 0xffffffff
wcsr im, r1
mvi r1, 0x1
wcsr ie, r1
/* Call main program */
mvi r1, 0
mvi r2, 0
......@@ -79,75 +69,75 @@ _crt0_enter:
calli main
_save_all:
addi sp,sp,-128
sw (sp+4),r1
sw (sp+8),r2
sw (sp+12),r3
sw (sp+16),r4
sw (sp+20),r5
sw (sp+24),r6
sw (sp+28),r7
sw (sp+32),r8
sw (sp+36),r9
sw (sp+40),r10
sw (sp+44),r11
sw (sp+48),r12
sw (sp+52),r13
sw (sp+56),r14
sw (sp+60),r15
sw (sp+64),r16
sw (sp+68),r17
sw (sp+72),r18
sw (sp+76),r19
sw (sp+80),r20
sw (sp+84),r21
sw (sp+88),r22
sw (sp+92),r23
sw (sp+96),r24
sw (sp+100),r25
sw (sp+104),gp
sw (sp+108),fp
sw (sp+120),ea
sw (sp+124),ba
lw r1,(sp+128)
sw (sp+116),r1
mv r1,sp
addi r1,r1,128
sw (sp+112),r1
ret
addi sp,sp,-128
sw (sp+4),r1
sw (sp+8),r2
sw (sp+12),r3
sw (sp+16),r4
sw (sp+20),r5
sw (sp+24),r6
sw (sp+28),r7
sw (sp+32),r8
sw (sp+36),r9
sw (sp+40),r10
sw (sp+44),r11
sw (sp+48),r12
sw (sp+52),r13
sw (sp+56),r14
sw (sp+60),r15
sw (sp+64),r16
sw (sp+68),r17
sw (sp+72),r18
sw (sp+76),r19
sw (sp+80),r20
sw (sp+84),r21
sw (sp+88),r22
sw (sp+92),r23
sw (sp+96),r24
sw (sp+100),r25
sw (sp+104),gp
sw (sp+108),fp
sw (sp+120),ea
sw (sp+124),ba
lw r1,(sp+128)
sw (sp+116),r1
mv r1,sp
addi r1,r1,128
sw (sp+112),r1
ret
_restore_all_and_return:
lw r1,(sp+4)
lw r2,(sp+8)
lw r3,(sp+12)
lw r4,(sp+16)
lw r5,(sp+20)
lw r6,(sp+24)
lw r7,(sp+28)
lw r8,(sp+32)
lw r9,(sp+36)
lw r10,(sp+40)
lw r11,(sp+44)
lw r12,(sp+48)
lw r13,(sp+52)
lw r14,(sp+56)
lw r15,(sp+60)
lw r16,(sp+64)
lw r17,(sp+68)
lw r18,(sp+72)
lw r19,(sp+76)
lw r20,(sp+80)
lw r21,(sp+84)
lw r22,(sp+88)
lw r23,(sp+92)
lw r24,(sp+96)
lw r25,(sp+100)
lw gp,(sp+104)
lw fp,(sp+108)
lw ra,(sp+116)
lw ea,(sp+120)
lw ba,(sp+124)
lw sp,(sp+112)
eret
lw r1,(sp+4)
lw r2,(sp+8)
lw r3,(sp+12)
lw r4,(sp+16)
lw r5,(sp+20)
lw r6,(sp+24)
lw r7,(sp+28)
lw r8,(sp+32)
lw r9,(sp+36)
lw r10,(sp+40)
lw r11,(sp+44)
lw r12,(sp+48)
lw r13,(sp+52)
lw r14,(sp+56)
lw r15,(sp+60)
lw r16,(sp+64)
lw r17,(sp+68)
lw r18,(sp+72)
lw r19,(sp+76)
lw r20,(sp+80)
lw r21,(sp+84)
lw r22,(sp+88)
lw r23,(sp+92)
lw r24,(sp+96)
lw r25,(sp+100)
lw gp,(sp+104)
lw fp,(sp+108)
lw ra,(sp+116)
lw ea,(sp+120)
lw ba,(sp+124)
lw sp,(sp+112)
eret
#include "irq.h"
void disable_irq()
{
unsigned int ie, im;
unsigned int Mask = ~1;
/* disable peripheral interrupts in case they were enabled */
asm volatile ("rcsr %0,ie":"=r"(ie));
ie &= (~0x1);
asm volatile ("wcsr ie, %0"::"r"(ie));
/* disable mask-bit in im */
asm volatile ("rcsr %0, im":"=r"(im));
im &= Mask;
asm volatile ("wcsr im, %0"::"r"(im));
}
void enable_irq()
{
unsigned int ie, im;
unsigned int Mask = 1;
/* disable peripheral interrupts in-case they were enabled*/
asm volatile ("rcsr %0,ie":"=r"(ie));
ie &= (~0x1);
asm volatile ("wcsr ie, %0"::"r"(ie));
/* enable mask-bit in im */
asm volatile ("rcsr %0, im":"=r"(im));
im |= Mask;
asm volatile ("wcsr im, %0"::"r"(im));
ie |= 0x1;
asm volatile ("wcsr ie, %0"::"r"(ie));
}
......@@ -6,35 +6,100 @@
#include "endpoint.h"
#include "minic.h"
#include "pps_gen.h"
#include "ptpd-noposix/PTPWRd/ptpd.h"
//#include "ptpd-noposix/PTPWRd/datatypes.h"
RunTimeOpts rtOpts = {
.announceInterval = DEFAULT_ANNOUNCE_INTERVAL,
.syncInterval = DEFAULT_SYNC_INTERVAL,
.clockQuality.clockAccuracy = DEFAULT_CLOCK_ACCURACY,
.clockQuality.clockClass = DEFAULT_CLOCK_CLASS,
.clockQuality.offsetScaledLogVariance = DEFAULT_CLOCK_VARIANCE,
.priority1 = DEFAULT_PRIORITY1,
.priority2 = DEFAULT_PRIORITY2,
.domainNumber = DEFAULT_DOMAIN_NUMBER,
.slaveOnly = SLAVE_ONLY,
.currentUtcOffset = DEFAULT_UTC_OFFSET,
.noResetClock = DEFAULT_NO_RESET_CLOCK,
.noAdjust = NO_ADJUST,
.inboundLatency.nanoseconds = DEFAULT_INBOUND_LATENCY,
.outboundLatency.nanoseconds = DEFAULT_OUTBOUND_LATENCY,
.s = DEFAULT_DELAY_S,
.ap = DEFAULT_AP,
.ai = DEFAULT_AI,
.max_foreign_records = DEFAULT_MAX_FOREIGN_RECORDS,
/**************** White Rabbit *************************/
.portNumber = NUMBER_PORTS,
.wrNodeMode = NON_WR,
.calibrationPeriod = WR_DEFAULT_CAL_PERIOD,
.calibrationPattern = WR_DEFAULT_CAL_PATTERN,
.calibrationPatternLen = WR_DEFAULT_CAL_PATTERN_LEN,
.E2E_mode = TRUE,
/********************************************************/
};
static PtpClock *ptpclock;
const uint8_t mac_addr[] = {0x00, 0x50, 0xde, 0xad, 0xba, 0xbe};
const uint8_t dst_mac_addr[] = {0x00, 0x00, 0x12, 0x24, 0x46, 0x11};
volatile int count = 0;
uint32_t tag_prev;
uint32_t tics_last;
void _irq_entry()
void silly_minic_test()
{
volatile uint32_t dummy_tag;
dummy_tag= *(volatile uint32_t*) 0x40004;
// mprintf("tag %d\n", dummy_tag-tag_prev);
count++;
if(timer_get_tics() - tics_last > 1000)
uint8_t hdr[14];
uint8_t buf_hdr[18], buf[256];
for(;;)
{
tics_last = timer_get_tics();
mprintf("cnt: %d delta %d\n", count, tag_prev-dummy_tag);
count = 0;
memcpy(buf_hdr, dst_mac_addr, 6);
memset(buf_hdr+6, 0, 6);
buf_hdr[12] = 0xc0;
buf_hdr[13] = 0xef;
minic_tx_frame(buf_hdr, buf, 64, buf);
mprintf("Send\n");
timer_delay(1000);
}
tag_prev=dummy_tag;
}
void test_transition()
{
int phase = 0;
softpll_enable();
while(!softpll_check_lock()) timer_delay(1000);
for(;;)
{ struct hw_timestamp hwts;
uint8_t buf_hdr[18], buf[128];
if(minic_rx_frame(buf_hdr, buf, 128, &hwts) > 0)
{
printf("phase %d ahead %d\n", phase, hwts.ahead);
phase+=100;
softpll_set_phase(phase);
timer_delay(10);
}
}
}
int main(void)
{
int rx, tx;
const uint8_t mac_addr[] = {0x00, 0x00, 0xde, 0xad, 0xba, 0xbe};
const uint8_t dst_mac_addr[] = {0x00, 0x00, 0x12, 0x24, 0x46, 0x11};
uint8_t hdr[14];
int16_t ret;
uart_init();
......@@ -43,39 +108,59 @@ int main(void)
gpio_dir(GPIO_PIN_LED, 1);
ep_init(mac_addr);
ep_enable(1, 1);
ep_enable(1, 0);
mprintf("is link up ?\n");
while(!ep_link_up());
mprintf("yes it is\n");
ep_get_deltas(&tx, &rx);
mprintf("delta: tx = %d, rx=%d\n", tx, rx);
minic_init();
//minic_disable();
pps_gen_init();
// test_transition();
//(unsigned int *)(0x40000) = 0x1;
netStartup();
ptpclock = ptpdStartup(0, NULL, &ret, &rtOpts);
toState(PTP_INITIALIZING, &rtOpts, ptpclock);
for(;;)
{
//mprintf("\n\n\n");
protocol_nonblock(&rtOpts, ptpclock);
update_rx_queues();
timer_delay(10);
}
//(unsigned int *)(0x40000) = 0x1;
// *(unsigned int *)(0x40024) = 0x1;
for(;;)
{
struct hw_timestamp hwts;
uint32_t utc, nsec;
uint8_t buf[1024];
//for(;;)
// {
// struct hw_timestamp hwts;
// uint32_t utc, nsec;
// uint8_t buf[1024];
memcpy(hdr, dst_mac_addr, 6);
hdr[12] = 0x88;
hdr[13] = 0xf7;
minic_tx_frame(hdr, buf, 500, &hwts);
// memcpy(hdr, dst_mac_addr, 6);
// hdr[12] = 0x88;
// hdr[13] = 0xf7;
//
// minic_tx_frame(hdr, buf, 500, &hwts);
mprintf("TxTs: utc %d nsec %d\n", hwts.utc, hwts.nsec);
delay(1000000);
// mprintf("TxTs: utc %d nsec %d\n", hwts.utc, hwts.nsec);
//
// delay(1000000);
mprintf("cnt:%d\n", count);
}
// mprintf("cnt:%d\n", count);
// }
}
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