Commit 814529a9 authored by Juan David González Cobas's avatar Juan David González Cobas

Merge remote-tracking branch 'gitlab/tom-rf' into david-libertm-devel

parents 46291d0c e1603011
......@@ -287,4 +287,4 @@ makeall_copy: $(addprefix $(DEFCONFIG_NAME),$(MAKEALL_COPY_LIST))
PYTHON ?= python3
load:
- killall -9 usb-bootloader.py
- ./tools/uart-bootloader/usb-bootloader.py -b default -s 921600 -p "$(PORT)" wrc.bin
- ./tools/uart-bootloader/usb-bootloader.py -b default -s 921600 -t -p "$(PORT)" wrc.bin
......@@ -118,6 +118,9 @@
#define ERTM14_NCO_RESET_DEFAULT_LATENCY (16000/16)
#define ERTM14_NCO_RESET_DEFAULT_TIMEOUT (160000/16)
/* power on flag */
#define ERTM_FLAGS_POWERED_ON (1<<0)
struct ertm14_dds_state
{
uint32_t ftw;
......@@ -164,6 +167,7 @@ PACKED struct ertm14_mmc_state
{
struct ertm14_mmc_version_info info;
struct ertm14_mmc_sensor_state sensors[ERTM14_MAX_SENSORS_COUNT];
uint32_t flags;
};
struct proto_wrc_sensor
......@@ -226,6 +230,7 @@ struct ertm14_version_info {
/* MMC firmware versions */
char ertm14_firmware_version[32];
char ertm15_firmware_version[32];
uint32_t calibration_date;
/* unused */
struct ertm14_device_metadata
firmware_metadata;
......
This diff is collapsed.
......@@ -233,6 +233,21 @@ static void set_dds_sync_source( struct ertm14_board_state *cfg, struct ertm14_b
}
static void set_pps_mode( char *mode )
{
if(!mode)
{
pp_printf("PPS mode expected\n");
return;
}
int m = atoi(mode);
pp_printf("Setting PPS output mode to: %d\n", m);
ertm14_set_pps_out_mode( m );
}
/* FIXME: this should be in a .h file */
extern void phy_calibration_disable(void);
extern void streamers_reset_rx_stats(void);
......@@ -313,6 +328,10 @@ static int cmd_ertm(const char *args[])
set_streamers_timeout( &nstate, &mask, strtol(args[1], NULL, 0) );
} else if (!strcasecmp(args[0], "reset-stats")) {
streamers_reset_rx_stats();
} else if (!strcasecmp(args[0], "pps-mode")) {
set_pps_mode( args[1] );
} else if (!strcasecmp(args[0], "ccal")) {
ertm14_sync_pulse_cal( );
}
......
......@@ -90,11 +90,6 @@ int uart_link_send( struct uart_link* link, struct uart_packet* pkt )
return 0;
}
#define RX_FSM_PACKET_ERROR -2
#define RX_FSM_NO_DATA -1
#define RX_FSM_NEED_DATA 0
#define RX_FSM_GOT_PACKET 1
static int recv_fsm( struct uart_link* link, struct uart_packet **pkt )
{
int rx_byte = link->recv_byte( link );
......@@ -103,6 +98,15 @@ static int recv_fsm( struct uart_link* link, struct uart_packet **pkt )
return RX_FSM_NEED_DATA;
ulink_dbg( "Rx %x state %d\n", rx_byte, link->state );
#ifndef __linux__
if(link->state != LINK_STATE_IDLE && link->extra_verbose)
{
int d = timer_get_tics() - link->ts;
if( d>=1 )
pp_printf("Choke @ %d %d\n", d, link->rx_count );
link->ts = timer_get_tics();
}
#endif
switch( link->state )
{
......@@ -111,6 +115,12 @@ static int recv_fsm( struct uart_link* link, struct uart_packet **pkt )
{
link->state = LINK_STATE_SYNC;
link->check_crc = crc_xmodem_update( 0, 0x55 );
#ifndef __linux__
if( link->extra_verbose )
pp_printf("RxS %d\n", timer_get_tics() );
link->ts = timer_get_tics();
#endif
}
break;
......@@ -148,7 +158,12 @@ static int recv_fsm( struct uart_link* link, struct uart_packet **pkt )
else
link->state = LINK_STATE_PAYLOAD;
#ifndef __linux__
if( link->extra_verbose )
pp_printf("RxPL %d\n", timer_get_tics() );
// link->ts = timer_get_tics();
#endif
break;
case LINK_STATE_PAYLOAD:
......@@ -157,6 +172,8 @@ static int recv_fsm( struct uart_link* link, struct uart_packet **pkt )
link->state = LINK_STATE_CRC0;
}
link->check_crc = crc_xmodem_update( link->check_crc, rx_byte);
if( link->rx_count < UART_LINK_MAX_PAYLOAD )
......@@ -184,7 +201,12 @@ static int recv_fsm( struct uart_link* link, struct uart_packet **pkt )
else
{
*pkt = &link->rx_packet;
#ifndef __linux__
if( link->extra_verbose )
pp_printf("RxF %d [%d] size %d\n", timer_get_tics(), timer_get_tics()-link->ts, link->rx_count );
#endif
return RX_FSM_GOT_PACKET;
}
break;
}
......@@ -200,13 +222,23 @@ int uart_link_recv( struct uart_link* link, struct uart_packet **pkt, int timeou
for(;;)
{
int ret = recv_fsm( link, pkt );
int delta = link->get_ms_tics( link ) - start_tics;
/* If we're waiting for more data (which is likely to come in the few next milliseconds),
don't preempt the loop as the global task scheduler in WRPC may return here with a lag of several milliseconds
causing a noticeable slowdown in commiunication (few ms accumulated per each byte received).
It's not the best solution (proper one would be to have polling for the exact number of bytes in the RX FIFO of the UART),
but works just fine for the control UART API. */
if( ret == RX_FSM_NEED_DATA && delta < link->rx_next_timeout_ms )
continue;
if ( timeout_ms == 0 )
return ret;
else if( ret == RX_FSM_PACKET_ERROR || ret == RX_FSM_GOT_PACKET )
return ret;
else { // check timeout
if( link->get_ms_tics( link ) - start_tics >= timeout_ms )
if( delta >= timeout_ms )
{
ulink_dbg( "Rx timeout expired\n");
uart_link_reset( link );
......
......@@ -70,8 +70,16 @@ struct uart_link
uint16_t rx_crc, check_crc;
uint32_t rx_last_tics;
struct uart_packet rx_packet;
int ts;
int extra_verbose;
int rx_next_timeout_ms;
};
#define RX_FSM_PACKET_ERROR -2
#define RX_FSM_NO_DATA -1
#define RX_FSM_NEED_DATA 0
#define RX_FSM_GOT_PACKET 1
#ifdef __linux__
#include <unistd.h>
#define linux_usleep(u) usleep(u)
......
......@@ -15,15 +15,15 @@
{0x08, 0x01},
{0x09, 0x00},
{0x0a, 0x64}, // N divider = 100 (VCO @ 1GHz, PFD @ 10 MHz)
{0x0b, 0x04}, // disable FILTR for 100 MHz
{0x0b, 0x04 | (1<<6)}, // disable FILTR for 100 MHz, EZSync mode = STANDALONE
{0x0c, 0x00},
{0x0d, 0x81}, // PECL0: 1 GHz
{0x0d, 0x81}, // PECL0: 1 GHz (for DDSes)
{0x0e, 0x00},
{0x0f, 0x84}, // PECL1: 250 MHz
{0x10, 0x00},
{0x11, 0x80 | 0x10}, // PECL2: 62.5 MHz
{0x11, 0x80 | 0x10}, // PECL2: 62.5 MHz (not configured yet)
{0x12, 0x00},
{0x13, 0x81}, // PECL3: 1 GHz
{0x13, 0x82}, // PECL3: 500 MHz (for CLKAB)
{0x14, 0x00},
{0x15, 0x81}, // LV-CM: unused
{0x16, 0x00}}
......
......@@ -102,8 +102,8 @@ int wrc_board_early_init()
ep_enable( &wrc_endpoint_dev, 1, 1);
timer_delay_ms(200);
spll_set_aux_mode( 0, SPLL_AUX_MODE_TRACKING_SOURCE );
spll_set_aux_mode( 1, SPLL_AUX_MODE_TRACKING_SOURCE );
spll_set_aux_mode( 0, SPLL_AUX_MODE_PHASE_MONITOR );
spll_set_aux_mode( 1, SPLL_AUX_MODE_PHASE_MONITOR );
return 0;
}
......
......@@ -31,7 +31,7 @@ static struct ad9910_config_reg ad9910_default_config[] = {
{0, 0x02000002 | (1<<13), 32}, // CFR1, unidir mode for SDIO, autoclear phase accumulator on IOUPDATE
{1, 0x00000800, 32}, // CFR2, TW - enabled sync pulse timing validation
{2, 0x1f3fc000, 32}, // CFR3: no PLL
{3, 0x00007f64, 32}, // Aux DAC control: DAC Full scale current
{3, 0x00000064, 32}, // Aux DAC control: DAC Full scale current
{4, 0xffffffff, 32}, // IO update rate
{7, 0x00000000, 32}, // default FTW
{8, 0x0000, 16}, // default phase offset
......@@ -111,8 +111,8 @@ int ad9910_program( struct ad9910_device *dev, uint64_t ftw_n, int phase, int fs
if(r.addr == 3)
{
r.value &= 0xffffff00;
r.value |= fs_current; // Aux DAC control: DAC Full scale current
r.value &= 0xffffff00ULL;
r.value |= (uint64_t) fs_current; // Aux DAC control: DAC Full scale current
} else
if( r.addr == 0xe ) // profile 0
r.value = prof0_cr;
......@@ -140,3 +140,17 @@ void ad9910_configure_sync( struct ad9910_device *dev, int enable, int fine_dela
ad9910_write( dev, 0xa, r10 , 32 );
ad9910_trigger_update( dev );
}
void ad9910_enable_external_ioupdate( struct ad9910_device *dev, int enable )
{
uint64_t cfr2 = ad9910_read(dev, 1, 32 );
pp_printf("CFR2 = 0x%08x\n", (uint32_t) cfr2 );
if( enable )
cfr2 &= ~ (1<<23);
else
cfr2 |= (1<<23);
ad9910_write( dev, 1, cfr2, 32 );
}
\ No newline at end of file
......@@ -106,6 +106,8 @@ void fine_pulse_gen_force_pulse( struct fine_pulse_gen_device* dev, int channel
writel( trig_mask, dev->base + FPG_REG_CSR ); // configure
ch->flags |= FINE_PULSE_GEN_CH_ARMED;
}
void fine_pulse_gen_trigger( struct fine_pulse_gen_device* dev, uint32_t mask, int force_now )
......
......@@ -27,6 +27,7 @@
#include "dev/gpio.h"
#include "dev/leds.h"
#ifndef BOARD_MAX_LEDS
#warning Please define BOARD_MAX_LEDS!
#define BOARD_MAX_LEDS 1
#endif
......@@ -86,6 +87,8 @@ static void led_update_single(struct led_device *led)
for (i = 0; i < n; i++)
{
int32_t t = (timer_get_tics() - led->start_tics);
switch (led->state[i])
{
case LED_ON:
......@@ -96,18 +99,25 @@ static void led_update_single(struct led_device *led)
break;
case LED_BLINK_SINGLE:
{
gen_gpio_out(led->pins[i], led->type & LED_TYPE_INVERT ? 0 : 1 );
if( t > led->blink_period )
led->state[i] = LED_OFF;
break;
}
case LED_BLINK_SINGLE_NEGATIVE:
{
gen_gpio_out(led->pins[i], led->type & LED_TYPE_INVERT ? 1 : 0 );
if( t > led->blink_period )
led->state[i] = LED_ON;
break;
}
case LED_BLINK:
{
int32_t t = (timer_get_tics() - led->start_tics);
int v = 1;
int v;
if (t > led->blink_period && led->state[i] == LED_BLINK_SINGLE)
{
led->state[i] = LED_OFF;
gen_gpio_out(led->pins[i], led->type & LED_TYPE_INVERT ? 1 : 0);
}
else
{
if( led->blink_period == 0 )
break;
t %= led->blink_period;
v = t < led->blink_period_on ? 1 : 0;
......@@ -115,7 +125,7 @@ static void led_update_single(struct led_device *led)
v = 1 - v;
gen_gpio_out(led->pins[i], v);
}
break;
}
......
......@@ -36,6 +36,7 @@ struct gpio_pin;
#define LED_OFF 1
#define LED_BLINK 2
#define LED_BLINK_SINGLE (1<<4)
#define LED_BLINK_SINGLE_NEGATIVE (1<<5)
#define LED_COLOR_1 (1<<0)
#define LED_COLOR_2 (1<<1)
......
......@@ -48,7 +48,6 @@ void ltc695x_write(struct ltc695x_device *dev, uint32_t reg, uint8_t value) {
bb_spi_cs(dev->bus, 0);
};
#define LTC695x_R0_LOCK (1<<2)
int ltc695x_configure(struct ltc695x_device *dev, struct ltc695x_config* cfg)
{
......@@ -61,23 +60,6 @@ int ltc695x_configure(struct ltc695x_device *dev, struct ltc695x_config* cfg)
return 0;
}
#define LTC6953_PD_NORMAL (0)
#define LTC6953_PD_MUTE (1)
#define LTC6953_PD_OUTPUT (2)
#define LTC6953_PD_OUTPUT_AND_DIVIDER (3)
#define LTC6953_OR0_MP_DIV_MASK (0xf8)
#define LTC6953_OR0_MP_DIV_SHIFT (3)
#define LTC6953_OR0_MD_DIV_MASK (0x7)
#define LTC6953_OR0_MD_DIV_SHIFT (0)
#define LTC6953_OR1_SRQEN (1<<7)
#define LTC6953_OR1_OINV (1<<4)
#define LTC6953_OR1_MODE_MASK (0x60)
#define LTC6953_OR1_MODE_SHIFT (5)
int ltc6953_set_pdown( struct ltc695x_device *dev, int out, int pd )
{
int shift = (out & 0x3) * 2;
......@@ -105,7 +87,7 @@ int ltc6953_configure_output( struct ltc695x_device *dev, int output, int divide
{
uint8_t div_mp, div_md;
dev_dbg("ltc6953 out %d div=%d inv=%d\n", output, divider, invert );
//dev_dbg("ltc6953 out %d div=%d inv=%d\n", output, divider, invert );
// Mx = (MPx + 1) • 2^MDx
// Note: For proper operation, MDx must be 0 if Mx is less than or equal to 32.
......@@ -126,10 +108,10 @@ int ltc6953_configure_output( struct ltc695x_device *dev, int output, int divide
int base = (output * 4 + 0xc);
dev_dbg("div_mp = %d, div_md = %d\n", div_mp, div_md);
//dev_dbg("div_mp = %d, div_md = %d\n", div_mp, div_md);
dev_dbg("ltc6953 r%02x = %02x\n", base+0, or0 );
dev_dbg("ltc6953 r%02x = %02x\n", base+1, or1 );
//dev_dbg("ltc6953 r%02x = %02x\n", base+0, or0 );
//dev_dbg("ltc6953 r%02x = %02x\n", base+1, or1 );
ltc695x_write( dev, base + 0, or0 );
ltc695x_write( dev, base + 1, or1 );
......@@ -149,5 +131,25 @@ int ltc6953_set_srqen( struct ltc695x_device *dev, int output, int en )
ltc695x_write( dev, base + 1, or1 );
return 0;
}
int ltc6950_set_syncen( struct ltc695x_device *dev, uint32_t out_mask )
{
int i;
for(i=0;i<5;i++)
{
uint8_t r = ltc695x_read( dev, 0xc + 2 * i );
if( out_mask & ( 1<<i ) )
r |= 0x80; // set the SYNC_EN bit
else
r &= ~0x80;
ltc695x_write( dev, 0xc + 2 * i, r );
}
return 0;
}
\ No newline at end of file
......@@ -27,6 +27,27 @@
#include "dev/gpio.h"
#include "dev/bb_spi.h"
#define LTC6953_PD_NORMAL (0)
#define LTC6953_PD_MUTE (1)
#define LTC6953_PD_OUTPUT (2)
#define LTC6953_PD_OUTPUT_AND_DIVIDER (3)
#define LTC6953_OR0_MP_DIV_MASK (0xf8)
#define LTC6953_OR0_MP_DIV_SHIFT (3)
#define LTC6953_OR0_MD_DIV_MASK (0x7)
#define LTC6953_OR0_MD_DIV_SHIFT (0)
#define LTC6953_OR1_SRQEN (1<<7)
#define LTC6953_OR1_OINV (1<<4)
#define LTC6953_OR1_MODE_MASK (0x60)
#define LTC6953_OR1_MODE_SHIFT (5)
#define LTC695x_R0_LOCK (1<<2)
struct ltc695x_device {
struct spi_bus *bus;
};
......@@ -50,5 +71,6 @@ int ltc695x_configure(struct ltc695x_device *dev, struct ltc695x_config* cfg);
int ltc6953_enable_output( struct ltc695x_device *dev, int output, int enabled );
int ltc6953_configure_output( struct ltc695x_device *dev, int output, int divider, int invert );
int ltc6953_set_srqen( struct ltc695x_device *dev, int output, int en );
int ltc6950_set_syncen( struct ltc695x_device *dev, uint32_t out_mask );
#endif
......@@ -26,6 +26,7 @@
#define CAL_PARAM_DDS_REF_IOUPDATE_DELAY_PS ASCII_TO_U32('e', '1', '4', '1')
#define CAL_PARAM_CLKA_SYNC_DELAY_PS ASCII_TO_U32('e', '1', '4', '2')
#define CAL_PARAM_CLKB_SYNC_DELAY_PS ASCII_TO_U32('e', '1', '4', '3')
#define CAL_PARAM_CALIBRATION_DATE ASCII_TO_U32('d','a','t','e')
#define SFP_SECTION_PATTERN 0xdeadbeef
......
......@@ -293,6 +293,19 @@ void mac_to_str(uint64_t mac, char *dst)
void display_version_info(struct ertm_board_info *bi)
{
char mac[20];
char buf[1024];
time_t cal_time = bi->calibration_date;
if( cal_time != 0 )
{
struct tm ts;
ts = *localtime(&cal_time);
strftime(buf, sizeof(buf), "%a %Y-%m-%d %H:%M:%S %Z", &ts);
printf("Calibration date: %s\n", buf);
}
else
printf("WARNING! UNCALIBRATED BOARD\n");
mac_to_str(bi->ertm14_mac1, mac);
printf(
......@@ -301,9 +314,9 @@ void display_version_info(struct ertm_board_info *bi)
"ERTM15: Serial No: %s\n"
"ERTM15: MMC FW Version: %s\n"
"ERTM14: MAC: %s\n"
"WRPCSW: commit: %s\n"
"WRPCSW: build date: %s %s\n"
"WRPCSW: build by %s\n",
"WRPCSW: commit: %s\n"
"WRPCSW: build date: %s %s\n"
"WRPCSW: build by %s\n",
bi->ertm14_serial, bi->ertm14_firmware_version,
bi->ertm15_serial, bi->ertm15_firmware_version,
mac,
......
......@@ -520,6 +520,8 @@ static int get_version_info(struct ertm_status *st,
*/
bytes_to_64_mac(&bi->ertm14_mac1, bi->ertm14_mac1_bytes);
bytes_to_64_mac(&bi->ertm14_mac2, bi->ertm14_mac2_bytes);
bi->calibration_date = ntohl( bi->calibration_date );
if (res < 0)
return res;
res = ertm_proto_cycle(link, ertm14_get_fpga_info, NULL, fpga);
......
......@@ -145,6 +145,8 @@ struct ertm_board_info {
/* MMC firmware versions */
char ertm14_firmware_version[32];
char ertm15_firmware_version[32];
uint32_t calibration_date;
/* unused */
struct ertm_device_metadata
firmware_metadata;
......@@ -189,6 +191,7 @@ struct ertm_nco_reset {
};
uint32_t current_stream_id;
uint32_t rx_count;
uint32_t rx_timeouts;
uint32_t reset_count;
uint32_t connector;
uint32_t unused[7];
......
......@@ -153,7 +153,8 @@ int wrc_mon_gui(void)
}
}
spll_get_num_channels(NULL, &n_out);
if (!state.state) {
return 1;
}
......@@ -221,11 +222,8 @@ int wrc_mon_gui(void)
/*cprintf(C_GREY, "Synchronization source: ");
cprintf(C_WHITE, "%s\n", cur_servo_state.sync_source);*/
spll_get_num_channels(NULL, &n_out);
for(i = 0; i < n_out - 1; i++) {
for(i = 0; i <= n_out - 1; i++) {
cprintf(C_GREY, "Aux clock %d status: ", i);
aux_stat = spll_get_aux_status(i);
......@@ -233,13 +231,13 @@ int wrc_mon_gui(void)
if (aux_stat.flags & SPLL_AUX_SLAVE_ENABLED)
cprintf(C_GREEN, "enabled");
if (aux_stat.flags & SPLL_AUX_TRACKING_ENABLED )
cprintf(C_GREEN, "tracking source");
if (aux_stat.flags & SPLL_AUX_MONITOR_ENABLED )
cprintf(C_GREEN, "monitor");
if (aux_stat.flags & SPLL_AUX_SLAVE_LOCKED)
cprintf(C_GREEN, ", locked");
if( aux_stat.flags & SPLL_AUX_TRACKING_READY )
if( aux_stat.flags & SPLL_AUX_MONITOR_READY )
{
cprintf(C_GREEN, ", ready");
cprintf(C_WHITE, " (AUX-to-WR offset: %d ps)", aux_stat.phase );
......@@ -434,6 +432,20 @@ uint32_t wrc_temp_get(char *name)
return s->value;
}
int wrc_ptp_get_servo_state( void )
{
struct wr_servo_state *ss =
&((struct wr_data *)ppi->ext_data)->servo_state;
int32_t asym = (int32_t)(ss->picos_mu-2LL * ss->delta_ms);
int wr_mode = (ss->flags & WR_FLAG_VALID) ? 1 : 0;
return ss->state;
}
int wrc_ptp_get_state( void )
{
return ppi->state;
}
int wrc_wr_diags(void)
{
struct hal_port_state ps;
......@@ -525,7 +537,7 @@ int wrc_wr_diags(void)
spll_get_num_channels(NULL, &n_out);
if (n_out > 8) n_out = 8; /* hardware limit. */
for(i = 0; i < n_out; i++) {
aux_stat |= (( SPLL_AUX_SLAVE_LOCKED | SPLL_AUX_TRACKING_READY ) & spll_get_aux_status(i).flags) << i;
aux_stat |= (( SPLL_AUX_SLAVE_LOCKED | SPLL_AUX_MONITOR_READY ) & spll_get_aux_status(i).flags) << i;
}
wdiags_write_aux_state(aux_stat);
......@@ -606,7 +618,7 @@ int wrc_diags_dump(struct WRC_DIAGS_WB *buf)
if (n_out > 8) n_out = 8; /* hardware limit. */
aux_stat = 0;
for(i = 0; i < n_out; i++) {
aux_stat |= (( SPLL_AUX_SLAVE_LOCKED | SPLL_AUX_TRACKING_READY ) & spll_get_aux_status(i).flags) << i;
aux_stat |= (( SPLL_AUX_SLAVE_LOCKED | SPLL_AUX_MONITOR_READY ) & spll_get_aux_status(i).flags) << i;
}
buf->WDIAG_ASTAT = SYSC_WDIAG_ASTAT_AUX_W(aux_stat);
......
......@@ -44,8 +44,8 @@
#define AUX_LOCK_PLL 2
#define AUX_ALIGN_PHASE 3
#define AUX_SLAVE_READY 4
#define AUX_WAIT_TRACKING_LOCK 5
#define AUX_TRACKING_READY 6
#define AUX_WAIT_MONITOR_LOCK 5
#define AUX_MONITOR_READY 6
#define ALIGN_STATE_EXT_OFF 0
#define ALIGN_STATE_START 1
......
......@@ -92,7 +92,7 @@ static inline void update_ptrackers(struct softpll_state *s, int tag_value, int
for( i = 0; i < spll_n_chan_out - 1; i++ )
{
struct spll_aux_state *aux = &s->aux[i];
if( aux->mode != SPLL_AUX_MODE_TRACKING_SOURCE )
if( aux->mode != SPLL_AUX_MODE_PHASE_MONITOR )
continue;
if( tag_source == spll_n_chan_ref + i + 1)
......@@ -602,10 +602,10 @@ static int spll_update_aux_clocks(void)
s->seq_state = AUX_LOCK_PLL;
done_sth++;
}
else if ( s->mode == SPLL_AUX_MODE_TRACKING_SOURCE )
else if ( s->mode == SPLL_AUX_MODE_PHASE_MONITOR )
{
pll_verbose("softpll: enabled tracking aux channel %d\n", ch);
s->seq_state = AUX_WAIT_TRACKING_LOCK;
pll_verbose("softpll: enabled phase monitor on aux channel %d\n", ch);
s->seq_state = AUX_WAIT_MONITOR_LOCK;
ptracker_init( &s->pll.tracker, ch + spll_n_chan_ref, PTRACKER_AVERAGE_SAMPLES );
ptracker_start( &s->pll.tracker );
done_sth++;
......@@ -614,20 +614,20 @@ static int spll_update_aux_clocks(void)
}
break;
case AUX_WAIT_TRACKING_LOCK:
case AUX_WAIT_MONITOR_LOCK:
if( s->pll.tracker.ready )
{
s->seq_state = AUX_TRACKING_READY;
s->seq_state = AUX_MONITOR_READY;
s->phase_value = s->pll.tracker.phase_val;
set_channel_status(ch, 1);
done_sth++;
break;
}
case AUX_TRACKING_READY:
case AUX_MONITOR_READY:
if (!softpll.mpll.locked)
{
pll_verbose("softpll: aux tracking channel %d disabled due to PLL LOS\n", ch);
pll_verbose("softpll: aux phase monitor channel %d disabled due to PLL LOS\n", ch);
set_channel_status(ch, 0);
s->seq_state = AUX_DISABLED;
done_sth++;
......@@ -684,14 +684,14 @@ struct spll_aux_clock_status spll_get_aux_status(int channel )
case AUX_LOCK_PLL:
rval.flags = SPLL_AUX_SLAVE_ENABLED;
break;
case AUX_WAIT_TRACKING_LOCK:
rval.flags = SPLL_AUX_TRACKING_ENABLED;
case AUX_WAIT_MONITOR_LOCK:
rval.flags = SPLL_AUX_MONITOR_ENABLED;
break;
case AUX_TRACKING_READY:
rval.flags = SPLL_AUX_TRACKING_ENABLED | SPLL_AUX_TRACKING_READY;
case AUX_MONITOR_READY:
rval.flags = SPLL_AUX_MONITOR_ENABLED | SPLL_AUX_MONITOR_READY;
break;
case AUX_SLAVE_READY:
rval.flags = SPLL_AUX_SLAVE_ENABLED | SPLL_AUX_SLAVE_LOCKED;
rval.flags = SPLL_AUX_MONITOR_ENABLED | SPLL_AUX_SLAVE_LOCKED;
break;
}
......
......@@ -27,13 +27,13 @@
#define SPLL_ALL_CHANNELS 0xffffffff
#define SPLL_AUX_MODE_SLAVE 0 /* Aux clock is disciplined from the local WR time base */
#define SPLL_AUX_MODE_TRACKING_SOURCE 1 /* Aux clock is a tracking source for the local WR time base */
#define SPLL_AUX_MODE_PHASE_MONITOR 1 /* Aux clock phase is monitored by this softPLL using another reference clock */
/* Aux clock flags */
#define SPLL_AUX_SLAVE_ENABLED (1<<0) /* Locking the particular aux channel to the WR reference is enabled */
#define SPLL_AUX_SLAVE_LOCKED (1<<1) /* The particular aux clock is already locked to WR reference */
#define SPLL_AUX_TRACKING_ENABLED (1<<2) /* The particilar aux clock is used as a tracking source for a WR reference */
#define SPLL_AUX_TRACKING_READY (1<<3) /* The particilar aux clock is used as a tracking source for a WR reference */
#define SPLL_AUX_MONITOR_ENABLED (1<<2) /* The particilar aux clock phase is monitored against the local WR reference */
#define SPLL_AUX_MONITOR_READY (1<<3)
/* Channels for spll_measure_frequency() */
......
#!/usr/bin/python
import matplotlib.pyplot as plt
import numpy
import sys
import time
import serial
import struct
import getopt
import signal
import sys
kill_usb = False
def signal_handler(sig, frame):
global kill_usb
print('You pressed Ctrl+C!')
kill_usb = True
sys.exit(0)
class SerialIF:
def __init__(self, device="/dev/ttyUSB1"):
self.ser = serial.Serial(
port=device, baudrate=921600, timeout=0, rtscts=False)
#self.ser.set_buffer_size(rx_size = 12800, tx_size = 12800)
def reset_board(self):
self.ser.setRTS(True)
time.sleep(0.01)
self.ser.setRTS(False)
time.sleep(0.01)
self.ser.setRTS(True)
time.sleep(0.01)
def send(self, x, wait=0):
if isinstance(x, int):
self.ser.write(struct.pack("B", x))
elif isinstance(x, str):
#print("SendSTR '%s'" % x)
for c in x:
self.ser.write(c)
if(wait):
time.sleep(wait)
else:
self.ser.write(x)
def recv(self):
global kill_usb
while True:
if kill_usb:
return None
try:
#print("State")
state = self.ser.read(1)
if state == None or len(state) == 0:
continue
return ord(state)
except:
pass
def recv_nonblock(self):
try:
state = self.ser.read(1)
return ord(state)
except:
return None
def recv_n(self,n=1):
rv=""
for i in range(0,n):
rv+=chr(self.recv())
return rv
def recv_u32(self):
return struct.unpack(">I", self.recv_n(4))
def purge(self, timeout=0.2):
t_start = time.time()
n=0
#print("Purge strt\n")
while(time.time() < t_start + timeout):
k = self.recv_nonblock()
if k != None:
#print('RX %c', chr(k))
n+=1
#print("Purged %d bytes" % n)
import threading
def sign_extend(value, bits):
sign_bit = 1 << (bits - 1)
return (value & (sign_bit - 1)) - (value & sign_bit)
class SPLLSample:
EVT_START = 1
EVT_LOCKED = 2
EVT_GAIN_SWITCH = 3
DBG_Y = 0
DBG_ERR = 1
DBG_TAG = 2
DBG_REF = 5
DBG_PERIOD = 3
DBG_SAMPLE_ID = 6
DBG_GAIN = 7
DBG_TAG_MASK = 0x70
DBG_TAG_SHIFT = 4
DBG_EVENT = 0x40
DBG_HELPER = 0x20
DBG_EXT = 0x10
DBG_MAIN = 0x0
def __init__(self,id=0):
self.is_event = False
self.event_id = 0
self.m_y = None
self.h_y = None
self.m_ref = None
self.m_tag = None
self.m_err = None
self.h_err = None
self.m_gain_stage = None
self.id = id
def parse(self, x):
last = True if (x & 0x80000000) else False
value = x & 0xffffff
what = x >> 24
if ( what & self.DBG_TAG_MASK ) == self.DBG_MAIN:
if ( what & 0xf ) == self.DBG_Y:
self.m_y = value
elif ( what & 0xf ) == self.DBG_GAIN:
self.m_gain_stage = value * 10000
elif ( what & 0xf ) == self.DBG_ERR:
self.m_err = sign_extend(value,24)
elif ( what & 0xf ) == self.DBG_REF:
self.m_ref = value
elif ( what & 0xf ) == self.DBG_TAG:
self.m_tag = value
elif ( what & self.DBG_TAG_MASK ) == self.DBG_HELPER:
if ( what & 0xf ) == self.DBG_Y:
self.h_y = value
elif ( what & 0xf ) == self.DBG_ERR:
self.h_err = sign_extend(value,24)
elif ( what & self.DBG_EVENT ):
self.is_event = True
evt_str = ""
if (what & 0x30) == self.DBG_HELPER:
evt_str="helper"
elif (what & 0x30) == self.DBG_MAIN:
evt_str="main"
evt_str+="-"
if(value & 0xf) == self.EVT_START:
evt_str+="start"
elif(value & 0xf) == self.EVT_LOCKED:
evt_str+="locked"
elif(value & 0xf) == self.EVT_GAIN_SWITCH:
evt_str+="gain-switch"
self.event_id =evt_str
# print("Event %x" % self.event_id)
return last
class LoggerThread(threading.Thread):
def __init__(self, port):
threading.Thread.__init__(self)
self.port = port
self.samples=[]
self.finish = False
self.n_samples = 0
def run(self):
print("Logger started\n")
nsamples = 0
self.n_samples = nsamples
syncw = [ 0, 0, 0, 0];
#print(len(syncw[0:3]))
while not self.finish:
syncw = [ syncw[1], syncw[2], syncw[3], self.port.recv() ];
#print("%x %x %x %x" % (syncw[0], syncw[1], syncw[2], syncw[3]))
if syncw == [0xca, 0xfe, 0xba, 0xbe]:
#print ("Sync Found")
break
nsamples += 1
if nsamples > 100:
return
nsamples = 0
s = SPLLSample(nsamples)
while not self.finish:
self.port.send('x'[0])
ns = self.port.recv_u32()[0]
#print("ns %d" % ns)
for i in range(0, ns):
x = self.port.recv_u32()[0]
#if x & 0xff000000 == 0x20000000:
#sys.stdout.write("* ")
#print("%08x" % x)
if( s.parse(x) ):
self.samples.append(s)
s = SPLLSample(nsamples)
nsamples+=1
self.n_samples = nsamples
#if nsamples > 10:
# break
x = self.port.recv_u32()[0]
#print("Last %x" % x)
#for s in self.samples:
#print(s.h_y)
def get_samples(self):
return self.samples
def get_samples_count(self):
return self.n_samples
def kill(self):
self.finish = True
def main(argv):
signal.signal(signal.SIGINT, signal_handler)
if len(argv) <= 1:
print ("eRTM14 SoftPLL debugger - a tool for recording live SoftPLL response.\n")
print ("Usage: %s usb_port_device [acq_time] [restart_pll]" % argv[0])
print ("Where:")
print (" - acq_time: optional time (in seconds) of data acquisition, default = 10s")
print (" - restart_pll: when 1, the PLL is restarted prior to acquisition (default = 0)")
print ("")
print ("WARNING: This is an internal toy of WRPC developers. Don't ask for any support or documentation.")
return
our_port = argv[1]
acq_time = 10 if len(argv) <= 2 else int(argv[2])
restart_pll = 1 if len(argv) <= 3 else int(argv[3])
port = SerialIF( device = our_port )
port.send(chr(0x1b), wait=0.1);
port.send(chr(0x1b), wait=0.1);
port.purge();
port.send('\r\rptp stop\r', wait=0.01);
port.purge();
port.send('\r\rpll init 4 0 0\r', wait=0.01);
port.purge();
port.send('pll init 3 0 0\r', wait=0.01);
port.purge();
port.send('pll dbgdump\r', wait=0.01);
meas_thread = LoggerThread(port)
meas_thread.start()
#while True:
#n = len( meas_thread.get_samples() )
#print("Acquired %d samples\n" % n )
#if n > 100:
#break
#time.sleep(0.2)
for i in range(0, acq_time):
sys.stdout.write('Acquiring data (got %d samples, %d seconds to go) \r' %( meas_thread.get_samples_count(), acq_time - i) )
sys.stdout.flush()
time.sleep(1)
meas_thread.kill()
meas_thread.join()
samples = meas_thread.get_samples()
n = len(samples)
print(n)
ht=[]
hy=[]
herr=[]
mt=[]
my=[]
merr=[]
events=[]
mref=[]
mtag=[]
mstage=[]
for s in samples:
if s.h_y != None:
ht.append( s.id )
hy.append( s.h_y )
herr.append( s.h_err )
if s.m_y != None:
mt.append( s.id )
my.append( s.m_y )
mref.append( s.m_ref )
mtag.append( s.m_tag )
merr.append( s.m_err )
mstage.append( s.m_gain_stage )
if s.is_event:
events.append(s)
#print(my)
# print (map( lambda s : s.h_y, samples ))
# plt.plot(t, map( lambda s : s.h_y, samples ) )
plt.plot(ht, hy, label = "helper[y]")
plt.plot(ht, herr, label = "helper[err]")
plt.plot(mt, my, label = "main[y]")
plt.plot(mt, merr, label = "main[err]")
#plt.plot(mt, mstage, label = "main[stage]")
#plt.plot(mt, mref, label = "main[int]")
#plt.plot(mt, mref, label = "main[ref tag]")
#plt.plot(mt, mtag, label = "main[fb tag]")
plt.legend();
f_out = open("hpll.csv","wb")
f_out.write("ERROR DAC\n")
for s in samples:
if s.h_y != None:
f_out.write("%d %d\n" % (s.h_err, s.h_y) )
f_out.close()
f_out = open("mpll.csv","wb")
f_out.write("ERROR DAC\n")
for s in samples:
ref = s.m_ref if s.m_ref != None else 0
fb = s.m_tag if s.m_tag != None else 0
y = s.m_y if s.m_y != None else 0
err = s.m_err if s.m_err != None else 0
f_out.write("%d %d %d %d\n" % (err, y, ref, fb) )
f_out.close()
for e in events:
print("PROCEVT %s" % e.event_id)
plt.text(e.id, 0, e.event_id, rotation="vertical")
plt.grid()
plt.show()
if __name__ == "__main__":
main(sys.argv)
......@@ -156,6 +156,7 @@ class DSIBootloader:
CMD_GO = 5
CMD_BOOT_INIT = 1
CMD_ENTER_BOOT_MODE = 8
CMD_RESET_PAYLOAD = 9
RSP_OK = 1
RSP_CRC_ERROR = 2
......@@ -181,6 +182,9 @@ class DSIBootloader:
def cmd_reset_to_boot_mode(self):
return self.sock.tx_frame(self.CMD_ENTER_BOOT_MODE, [])
def cmd_reset_mmc_payload(self):
return self.sock.tx_frame(self.CMD_RESET_PAYLOAD, [])
def cmd_read_flash_id(self):
data = [(addr >> 24) & 0xff, (addr >> 16) & 0xff, (addr >> 8) & 0xff,
addr & 0xff]
......@@ -273,7 +277,13 @@ class DSIBootloader:
else:
raise Exception("Unknown flash target: %s" % target)
return self.do_program_flash(image, offset)
def reset_payload(self, target):
if self.target_board == "ertm14m0":
print("Resetting eRTM14 payload")
return self.cmd_reset_mmc_payload()
def program_flash(self, fw, target):
#print("PGM", target)
if self.target_board == "ertm14m0" or self.target_board == "ertm14m1":
......@@ -376,9 +386,8 @@ def run_terminal(ser):
a = ser.recv_nonblock()
if (a != None):
sys.stderr.write(chr(a))
# sys.stderr.write(a).decode('utf-8'))
# flush is needed FIXME:
# sys.stderr.flush()
if(chr(a) == '\n'):
sys.stderr.write('\r')
a = os.read(sys.stdin.fileno(), 1)
if a and (ord(a) == 1 or ord(a) == 4):
......@@ -395,11 +404,12 @@ def main(argv):
our_port = "/dev/ttyUSB0"
do_flash = False
run_term = False
do_reset = False
flash_target = None
board_target = None
ser_speed=115200
try:
opts, args = getopt.getopt(argv[1:], "hb:f:s:p:t", ["uart"])
opts, args = getopt.getopt(argv[1:], "hrb:f:s:p:t", ["uart"])
except getopt.GetoptError:
print('Usage: %s [-f] [-p serial_port_device] file.bin' % argv[0])
sys.exit(2)
......@@ -410,6 +420,9 @@ def main(argv):
print(
'-f / --flash [fpga|autoexec|wrc|sdbfs] - flashes the FPGA bitstream/autoexec file/WRC image instead of loading the CPU image (can brick your board!)'
)
print(
'-r / --reset - asks the MMC to reset the payload FPGA (eRTM14)'
)
print(
'-p / --port: - specifies the serial port device (default: %s)'
% our_port)
......@@ -427,10 +440,12 @@ def main(argv):
ser_speed = int(arg)
elif opt in ("-t", "--term"):
run_term = True
elif opt in ("-r", "--reset"):
do_reset = True
else:
print("Unrecognized option '%s'" % opt)
if len(args) == 0:
if len(args) == 0 and not do_reset:
print("No filename specified.")
sys.exit(2)
......@@ -445,12 +460,16 @@ def main(argv):
board_target, ser_speed), file=sys.stderr)
exit(1)
fw = bytearray(open(args[0], "rb").read())
if not do_reset:
fw = bytearray(open(args[0], "rb").read())
if not do_reset:
boot.boot_enter()
boot.boot_enter()
if do_flash:
if do_reset:
boot.reset_payload(flash_target)
elif do_flash:
boot.program_flash(fw, flash_target)
else:
boot.load_ram(fw, 0x0)
......
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