Commit 8f422f8f authored by Tomasz Wlostowski's avatar Tomasz Wlostowski

software: added pulse generator mode, temperature calibration program and PPS/10MHz demo program

parent 828b9fab
......@@ -3,7 +3,7 @@
* File : fd_channel_regs.h
* Author : auto-generated by wbgen2 from fd_channel_wishbone_slave.wb
* Created : Mon Feb 27 13:58:08 2012
* Created : Wed Feb 29 12:04:02 2012
* Standard : ANSI C
THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE fd_channel_wishbone_slave.wb
......
......@@ -3,7 +3,7 @@
* File : fd_main_regs.h
* Author : auto-generated by wbgen2 from fd_main_wishbone_slave.wb
* Created : Mon Feb 27 13:58:07 2012
* Created : Wed Feb 29 12:04:02 2012
* Standard : ANSI C
THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE fd_main_wishbone_slave.wb
......
......@@ -66,6 +66,9 @@ int fdelay_configure_output(fdelay_device_t *dev, int channel, int enable, int64
int fdelay_configure_sync(fdelay_device_t *dev, int mode);
int fdelay_update_sync_status(fdelay_device_t *dev);
int fdelay_set_time(fdelay_device_t *dev, const fdelay_time_t t);
int fdelay_configure_pulse_gen(fdelay_device_t *dev, int channel, int enable, fdelay_time_t t_start, int64_t width_ps, int64_t delta_ps, int rep_count);
int fdelay_channel_triggered(fdelay_device_t *dev, int channel);
int fdelay_get_time(fdelay_device_t *dev, fdelay_time_t *t);
#endif
......@@ -2,7 +2,7 @@ CFLAGS = -I../include -g -Imini_bone -Ispll
OBJS_LIB = fdelay_lib.o rr_io.o i2c_master.o onewire.o mini_bone/minibone_lib.o mini_bone/ptpd_netif.o fdelay_bus.o
all: testprog lib testprog2
all: testprog lib testprog2 testprog3
lib: $(OBJS_LIB)
gcc -shared -o libfinedelay.so $(OBJS_LIB)
......@@ -13,5 +13,8 @@ testprog: lib fdelay_test.o
testprog2: lib fdelay_cal.o
gcc -o fdelay_cal $(OBJS_LIB) fdelay_cal.o -lm
testprog3: lib fdelay_pps_demo.o
gcc -o fdelay_pps_demo $(OBJS_LIB) fdelay_pps_demo.o -lm
clean:
rm -f libfinedelay.so $(OBJS_LIB)
\ No newline at end of file
......@@ -457,7 +457,7 @@ static double measure_output_delay(fdelay_device_t *dev, int channel, int fine,
int i;
/* Mapping between the channel of the delay card and the stop inputs of the ACAM */
int chan_to_acam[5] = {0, 4, 3, 2, 1};
int chan_to_acam[5] = {0, 1, 2, 3, 4};
/* Mapping between the channel number and the time tag FIFOs of the ACAM */
int chan_to_fifo[5] = {0, 8, 8, 8, 8};
......@@ -601,7 +601,6 @@ void calibrate_outputs(fdelay_device_t *dev)
acam_configure(dev, ACAM_IMODE);
fd_writel( FD_TDCSR_START_EN | FD_TDCSR_STOP_EN, FD_REG_TDCSR);
for(channel = 1; channel <= 4; channel++)
{
while(ds18x_read_temp(dev, &temp) < 0)
......@@ -868,6 +867,25 @@ static fdelay_time_t ts_sub(fdelay_time_t a, fdelay_time_t b)
if(a.coarse < 0)
{
a.coarse += 125000000;
a.utc --;
}
return a;
}
/* Add two timestamps */
static fdelay_time_t ts_add(fdelay_time_t a, fdelay_time_t b)
{
a.frac += b.frac;
if(a.frac >= (1<<FDELAY_FRAC_BITS))
{
a.frac -= (1<<FDELAY_FRAC_BITS);
a.coarse++;
}
a.coarse += b.coarse;
if(b.coarse >= 125000000)
{
a.coarse -= 125000000;
a.utc ++;
}
return a;
......@@ -989,6 +1007,66 @@ int fdelay_configure_output(fdelay_device_t *dev, int channel, int enable, int64
return 0;
}
/* Configures the output channel (channel) to produce pulses delayed from the trigger by (delay_ps).
The output pulse width is proviced in (width_ps) parameter. */
int fdelay_configure_pulse_gen(fdelay_device_t *dev, int channel, int enable, fdelay_time_t t_start, int64_t width_ps, int64_t delta_ps, int rep_count)
{
fd_decl_private(dev)
uint32_t base = (channel-1) * 0x20;
uint32_t dcr;
fdelay_time_t start, end, delta;
if(channel < 1 || channel > 4)
return -1;
start = t_start;
end = ts_add(start, fdelay_from_picos(width_ps));
delta = fdelay_from_picos(delta_ps);
// printf("Start: %lld: %d:%d\n", start.utc, start.coarse, start.frac);
chan_writel(hw->frr_cur[channel-1], FD_REG_FRR);
chan_writel(start.utc >> 32, FD_REG_U_STARTH);
chan_writel(start.utc & 0xffffffff, FD_REG_U_STARTL);
chan_writel(start.coarse, FD_REG_C_START);
chan_writel(start.frac, FD_REG_F_START);
chan_writel(end.utc >> 32, FD_REG_U_ENDH);
chan_writel(end.utc & 0xffffffff, FD_REG_U_ENDL);
chan_writel(end.coarse, FD_REG_C_END);
chan_writel(end.frac, FD_REG_F_END);
chan_writel(delta.utc & 0xf, FD_REG_U_DELTA);
chan_writel(delta.coarse, FD_REG_C_DELTA);
chan_writel(delta.frac, FD_REG_F_DELTA);
// chan_writel(0, FD_REG_RCR);
chan_writel(FD_RCR_REP_CNT_W(rep_count < 0 ? 0 :rep_count-1) | (rep_count < 0 ? FD_RCR_CONT : 0), FD_REG_RCR);
dcr = FD_DCR_MODE;
/* For narrowly spaced pulses, we don't have enough time to reload the tap number into the corresponding
SY89295 - therefore, the width/spacing resolution is limited to 4 ns. */
if((delta_ps - width_ps) < 200000 || (width_ps < 200000))
dcr |= FD_DCR_NO_FINE;
chan_writel(dcr | FD_DCR_UPDATE, FD_REG_DCR);
chan_writel(dcr | FD_DCR_ENABLE, FD_REG_DCR);
chan_writel(dcr | FD_DCR_ENABLE | FD_DCR_PG_ARM, FD_REG_DCR);
sgpio_set_pin(dev, SGPIO_OUTPUT_EN(channel), enable ? 1 : 0);
return 0;
}
int fdelay_channel_triggered(fdelay_device_t *dev, int channel)
{
fd_decl_private(dev)
return chan_readl(FD_REG_DCR) & FD_DCR_PG_TRIG ? 1: 0;
}
/* Todo: write get_time() */
int fdelay_set_time(fdelay_device_t *dev, const fdelay_time_t t)
{
......@@ -1008,6 +1086,20 @@ int fdelay_set_time(fdelay_device_t *dev, const fdelay_time_t t)
}
/* Todo: write get_time() */
int fdelay_get_time(fdelay_device_t *dev, fdelay_time_t *t)
{
fd_decl_private(dev)
uint32_t tcr;
tcr = fd_readl(FD_REG_TCR);
fd_writel(tcr | FD_TCR_CAP_TIME, FD_REG_TCR);
t->utc = fd_readl(FD_REG_TM_SECL);
t->coarse = fd_readl(FD_REG_TM_CYCLES);
return 0;
}
#if 0
/* To be rewritten to use interrupts and new WR FSM (see TCR register description).
......
#include <stdio.h>
#include "fdelay_lib.h"
#include "rr_io.h"
void my_writel(void *priv, uint32_t data, uint32_t addr)
{
rr_writel(data, addr);
}
uint32_t my_readl(void *priv, uint32_t addr)
{
uint32_t d = rr_readl(addr);
return d;
}
main()
{
fdelay_device_t dev;
rr_init();
dev.writel = my_writel;
dev.readl = my_readl;
dev.base_addr = 0x84000;
if(fdelay_init(&dev) < 0)
return -1;
fdelay_time_t t_cur, t_start;
fdelay_get_time(&dev, &t_cur);
printf("Current Time: %lld:%d\n", t_cur.utc, t_cur.coarse);
t_start.coarse = 0;
t_start.utc = t_cur.utc+2;
t_start.frac = 0;
fdelay_configure_pulse_gen(&dev, 1, 1, t_start, 48000LL, 100000LL, -1);
t_start.coarse = 124999999;
fdelay_configure_pulse_gen(&dev, 2, 1, t_start, 48000LL, 1000000000000LL, -1);
for(;;)
printf("ChannelTrigd: %d %d\n", fdelay_channel_triggered(&dev, 1), fdelay_channel_triggered(&dev, 2));
}
#include <stdio.h>
#include "fdelay_lib.h"
#include "rr_io.h"
void my_writel(void *priv, uint32_t data, uint32_t addr)
{
rr_writel(data, addr);
}
uint32_t my_readl(void *priv, uint32_t addr)
{
uint32_t d = rr_readl(addr);
return d;
}
main()
{
fdelay_device_t dev;
rr_init();
dev.writel = my_writel;
dev.readl = my_readl;
dev.base_addr = 0x84000;
if(fdelay_init(&dev) < 0)
return -1;
fdelay_configure_trigger(&dev, 1,1);
fdelay_configure_output(&dev,1,1,500000, 100000, 100000, 0);
fdelay_configure_output(&dev,2,1,500000, 100000, 100000, 0);
fdelay_configure_output(&dev,3,1,500000, 100000, 100000, 0);
fdelay_configure_output(&dev,4,1,500000, 100000, 100000, 0);
fdelay_configure_readout(&dev, 1);
// fd_update_spll(&dev);
int64_t prev = 0, dp, pmin=10000000000LL,pmax=0;
#if 0
for(;;)
{
fdelay_time_t ts;
if(fdelay_read(&dev, &ts, 1) == 1)
{
int64_t ts_p = fdelay_to_picos(ts), d;
d=ts_p - prev;
if(prev > 0)
{
if(d<pmin) pmin=d;
if(d>pmax) pmax=d;
fprintf(stderr,"Got it %lld:%d:%d delta %lld span %lld\n", ts.utc, ts.coarse, ts.frac, d, pmax-pmin);
}
prev = ts_p;
}
}
#endif
}
......@@ -28,6 +28,8 @@ main()
return -1;
fdelay_configure_trigger(&dev, 1,1);
fdelay_configure_output(&dev,1,1,500000, 100000, 100000, 0);
fdelay_configure_output(&dev,2,1,500000, 100000, 100000, 0);
fdelay_configure_output(&dev,3,1,500000, 100000, 100000, 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