Commit db22eee3 authored by Tristan Gingold's avatar Tristan Gingold

wrtd: cleanup, add rule delay, add log reason.

parent 25b129dc
/*
* Copyright (C) 2018 CERN (www.cern.ch)
* Author: Federico Vaga <federico.vaga@cern.ch>
* Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
*
* SPDX-License-Identifier: LGPL-3.0-or-later
*/
/*
* copyright (C) 2018 CERN (www.cern.ch)
* author Federico Vaga <federico.vaga@cern.ch>
* author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
*
* SPDX-License-Identifier: LGPL-3.0-or-later
*/
#define WRTD_IN_PORT 34700
#define WRTD_OUT_PORT 34701
struct wrtd_trigger_message {
uint32_t transmit_seconds;
uint32_t transmit_cycles;
int count;
struct wrtd_trigger_entry triggers[TDC_TRIGGER_COALESCE_LIMIT];
uint32_t pad; // stupid Etherbone for some reasons drops the last entry on TX
};
static inline void ts_add(struct wr_timestamp *a, const struct wr_timestamp *b)
{
a->frac += b->frac;
if(a->frac >= 4096)
{
a->frac -= 4096;
a->ticks ++;
}
a->ticks += b->ticks;
if(a->ticks >= 125000000)
{
a->ticks -= 125000000;
a->seconds++;
}
a->seconds += b->seconds;
}
static inline void ts_sub(struct wr_timestamp *a, const struct wr_timestamp *b)
{
a->frac -= b->frac;
if(a->frac < 0)
{
a->frac += 4096;
a->ticks --;
}
a->ticks -= b->ticks;
if(a->ticks < 0)
{
a->ticks += 125000000;
a->seconds--;
}
a->seconds -= b->seconds;
if(a->seconds == -1)
{
a->seconds = 0;
a->ticks -= 125000000;
}
}
......@@ -18,6 +18,9 @@
/* Remote message queue for network. */
#define WRTD_RMQ 0
/* By default use lxi-evntsvc. */
#define WRTD_UDP_PORT 5044
static void wrtd_local_output(struct wrtd_event *ev, unsigned ch);
static void wrtd_inputs(void);
static int wrtd_init(void);
......@@ -140,8 +143,8 @@ static void wrtd_init_tx(void)
.dst_mac = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
.dst_ip = 0xFFFFFFFF, /* broadcast on 255.255.255.255 */
.src_ip = 0xC0A85A11,
.dst_port = WRTD_OUT_PORT,
.src_port = WRTD_IN_PORT,
.dst_port = WRTD_UDP_PORT,
.src_port = WRTD_UDP_PORT,
.ethertype = 0x800, /* IPv4 */
.filter = 0 /* only the TX path of the endpoint is used */
};
......@@ -184,7 +187,7 @@ static void wrtd_send_network(struct wrtd_event *ev)
mq_send(TRTL_RMQ, WRTD_RMQ);
wrtd_log(WRTD_LOG_MSG_EV_NETWORK, 1, ev, NULL);
wrtd_log(WRTD_LOG_MSG_EV_NETWORK, WRTD_LOG_NETWORK_TX, ev, NULL);
}
#endif
......@@ -314,7 +317,7 @@ static void wrtd_rx_init(void)
static const struct trtl_ep_eth_address addr = {
.type = TRTL_EP_FRAME_UDP,
.dst_mac = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
.dst_port = WRTD_OUT_PORT,
.dst_port = WRTD_UDP_PORT,
.ethertype = 0x800, /* IPv4 */
.filter = (TRTL_EP_FILTER_UDP
| TRTL_EP_FILTER_DST_PORT
......@@ -344,7 +347,7 @@ static void wrtd_recv_network(void)
mq_discard(TRTL_RMQ, WRTD_RMQ);
wrtd_log(WRTD_LOG_MSG_EV_NETWORK, 2, &ev, NULL);
wrtd_log(WRTD_LOG_MSG_EV_NETWORK, WRTD_LOG_NETWORK_RX, &ev, NULL);
wrtd_route_in(&ev);
......@@ -371,7 +374,8 @@ static void wrtd_alarms(void)
if (ts_cmp(&al->setup_time, &now) > 0)
continue;
wrtd_log(WRTD_LOG_MSG_EV_GENERATED, 0, &al->event, &now);
wrtd_log(WRTD_LOG_MSG_EV_GENERATED, WRTD_LOG_GENERATED_ALARM,
&al->event, &now);
/* Trigger. */
wrtd_route_in(&al->event);
......
-include Makefile.specific
OBJS := wrtd-rt-fd.o
OBJS += acam.o gpio.o pll.o i2c.o calibrate.o fine-delay-init.o # Fine-Delay init
OBJS += common/wrtd-fw-common.o
OBJS += common/loop-queue.o
OBJS += acam.o gpio.o pll.o i2c.o calibrate.o fine-delay-init.o
OBJDIR += common
OUTPUT = wrtd-rt-fd
TRTL ?= ../../../dependencies/mock-turtle/
......
......@@ -13,7 +13,6 @@
#include "mockturtle-rt.h"
#include <mockturtle-framework.h>
#include "wrtd-common.h"
#include "wrtd-fw-common.h"
#include "hw/fd_channel_regs.h"
#include "hw/fd_main_regs.h"
......
......@@ -13,7 +13,6 @@
#include "mockturtle-rt.h"
#include <mockturtle-framework.h>
#include "wrtd-common.h"
#include "wrtd-fw-common.h"
#include "hw/fd_channel_regs.h"
#include "hw/fd_main_regs.h"
#include "fine-delay-init.h"
......
......@@ -12,18 +12,17 @@
#include "mockturtle-rt.h"
#include <mockturtle-framework.h>
#include "wrtd-common.h"
#include "wrtd-fw-common.h"
#include "hw/fd_channel_regs.h"
#include "hw/fd_main_regs.h"
#include "fine-delay-init.h"
#include "loop-queue.h"
#define OUT_TIMEOUT 10
#define FD_NUM_CHANNELS 4
#define NBR_LOCAL_INPUTS 0
#define NBR_LOCAL_OUTPUTS 4
#define NBR_LOCAL_OUTPUTS FD_NUM_CHANNELS
#define NBR_RULES 16
#define NBR_DEVICES 1
#define NBR_ALARMS 1
......@@ -35,6 +34,8 @@
#include "wrtd-rt-common.h"
#define FD_MAX_QUEUE_PULSES 4
/* Structure describing a single pulse in the Fine Delay software output
queue. */
struct pulse_queue_entry {
......@@ -263,7 +264,7 @@ static int check_output_timeout (struct wrtd_fd_channel *out)
now_sec = lr_readl(MT_CPU_LR_REG_TAI_SEC);
now_ns = lr_readl(MT_CPU_LR_REG_TAI_CYCLES) * 8;
if( out->last_programmed_sec > now_sec + OUT_TIMEOUT ) {
if(out->last_programmed_sec > now_sec + OUT_TIMEOUT) {
pr_error("Enqueued event very far in the future. Dropping.");
return 0;
}
......@@ -314,7 +315,7 @@ static void update_latency_stats(struct pulse_queue_entry *pq_ent)
*/
static void drop_trigger(struct wrtd_fd_channel *out,
struct pulse_queue_entry *pq_ent,
struct lrt_pulse_queue *q, int reason)
struct lrt_pulse_queue *q, unsigned reason)
{
out->idle = 1;
......@@ -327,7 +328,7 @@ static void drop_trigger(struct wrtd_fd_channel *out,
/* Disarm the FD output */
fd_ch_writel(out, FD_DCR_MODE, FD_REG_DCR);
wrtd_log(WRTD_LOG_MSG_EV_DISCARDED, 0, &pq_ent->ev, NULL);
wrtd_log(WRTD_LOG_MSG_EV_DISCARDED, reason, &pq_ent->ev, NULL);
}
......@@ -345,14 +346,16 @@ static void do_output (struct wrtd_fd_channel *out)
/* Check if the output has triggered */
if (!out->idle) {
if (!wr_is_timing_ok()) {
drop_trigger(out, pq_ent, q, WRTD_MISS_NO_WR);
/* Timing has been lost. */
drop_trigger(out, pq_ent, q, WRTD_LOG_DISCARD_NO_SYNC);
return;
}
if (!(dcr & FD_DCR_PG_TRIG)) {
/* Nope, armed but still waiting for trigger */
/* Armed but still waiting for trigger */
if (check_output_timeout (out)) {
/* Will never trigger. Missed. */
drop_trigger(out, pq_ent, q, WRTD_MISS_TIMEOUT);
drop_trigger(out, pq_ent, q,
WRTD_LOG_DISCARD_TIMEOUT);
}
} else {
/* Has been triggered. */
......@@ -373,7 +376,7 @@ static void do_output (struct wrtd_fd_channel *out)
ts = &pq_ent->ev.ts;
if (!wr_is_timing_ok()) {
drop_trigger(out, pq_ent, q, WRTD_MISS_NO_WR);
drop_trigger(out, pq_ent, q, WRTD_LOG_DISCARD_NO_SYNC);
return;
}
......@@ -396,7 +399,7 @@ static void do_output (struct wrtd_fd_channel *out)
fd_ch_writel(out, FD_DCR_MODE | FD_DCR_PG_ARM | FD_DCR_ENABLE,
FD_REG_DCR);
wrtd_log(WRTD_LOG_MSG_EV_CONSUMED, out->base_addr + 1,
wrtd_log(WRTD_LOG_MSG_EV_CONSUMED, WRTD_LOG_CONSUMED_START,
&pq_ent->ev, NULL);
ts_add2_ns (ts, 8000);
......@@ -419,7 +422,8 @@ static void wrtd_local_output(struct wrtd_event *ev, unsigned ch)
if (!pq_ent) {
/* overflow.
FIXME: stats ? */
wrtd_log(WRTD_LOG_MSG_EV_DISCARDED, 0, ev, NULL);
wrtd_log(WRTD_LOG_MSG_EV_DISCARDED, WRTD_LOG_DISCARD_OVERFLOW,
ev, NULL);
return;
}
......
......@@ -2,9 +2,6 @@
OBJS := wrtd-rt-tdc.o
OBJS += tdc-init.o
OBJS += common/wrtd-fw-common.o
OBJS += common/loop-queue.o
OBJDIR += common
OUTPUT = wrtd-rt-tdc
TRTL ?= ../../../dependencies/mock-turtle/
......
......@@ -12,10 +12,8 @@
#include "mockturtle-rt.h"
#include <mockturtle-framework.h>
#include "wrtd-common.h"
#include "wrtd-fw-common.h"
#include "hw/fmctdc-direct.h"
#include "hw/tdc_regs.h"
#include "loop-queue.h"
#include "wrtd-rt-tdc.h"
......@@ -139,7 +137,8 @@ static void tdc_input(void)
ev.id[3] = '1' + channel; /* channel starts from 0. */
ev.flags = 0;
wrtd_log(WRTD_LOG_MSG_EV_GENERATED, 0, &ev, NULL);
wrtd_log(WRTD_LOG_MSG_EV_GENERATED,
WRTD_LOG_GENERATED_DEVICE + channel, &ev, NULL);
/* Pass to wrtd. */
wrtd_route_in(&ev);
......@@ -262,7 +261,7 @@ static int wrtd_init(void)
wr_enable_lock(0);
loop_queue_init();
// FIXME: loop_queue_init();
wrtd_init_tx();
/* Skip WR sync and automatically generate some events when simulating */
......
This diff is collapsed.
......@@ -262,6 +262,31 @@ enum wrtd_status wrtd_attr_set_rule_destination(struct wrtd_dev *wrtd,
return WRTD_SUCCESS;
}
enum wrtd_status wrtd_attr_set_rule_delay(struct wrtd_dev *wrtd,
const char *rep_cap_id,
const struct wrtd_tstamp *value)
{
enum wrtd_status status;
unsigned int idx;
if (value->seconds != 0)
return wrtd_return_error(wrtd, WRTD_ERROR_INVALID_VALUE,
"rule delay is too large (>1s)");
status = wrtd_find_rule(wrtd, rep_cap_id, &idx);
WRTD_RETURN_IF_ERROR(status);
status = wrtd_rule_check_disabled(wrtd, idx);
WRTD_RETURN_IF_ERROR(status);
wrtd->rules[idx].rule.conf.delay_ns = value->ns;
status = wrtd_write_rule(wrtd, idx);
WRTD_RETURN_IF_ERROR(status);
return WRTD_SUCCESS;
}
enum wrtd_status wrtd_attr_get_rule_enable(struct wrtd_dev *wrtd,
const char *rep_cap_id,
bool *value)
......@@ -369,6 +394,8 @@ enum wrtd_status wrtd_set_attr_tstamp(struct wrtd_dev *wrtd,
return wrtd_attr_set_alarm_setup_time(wrtd, rep_cap_id, value);
case WRTD_ATTR_ALARM_PERIOD:
return wrtd_attr_set_alarm_period(wrtd, rep_cap_id, value);
case WRTD_ATTR_RULE_DELAY:
return wrtd_attr_set_rule_delay(wrtd, rep_cap_id, value);
default:
return wrtd_return_error
(wrtd, WRTD_ERROR_INVALID_ATTRIBUTE,
......
......@@ -42,13 +42,7 @@ extern void help_trig_id();
extern void decode_flags(char *buf, uint32_t flags);
extern void decode_mode(char *buf, int mode);
extern void decode_log_level(char *buf, uint32_t flags);
extern void format_ts(char *buf, struct wr_timestamp ts, int with_seconds);
extern void format_ago(char *buf, struct wr_timestamp ts, struct wr_timestamp current);
extern void format_id(char *buf, struct wrtd_trig_id id);
extern uint64_t ts_to_picos(struct wr_timestamp ts);
extern int parse_delay(char *dly, uint64_t *delay_ps);
extern int parse_trigger_id(const char *str, struct wrtd_trig_id *id);
extern int parse_mode (char *mode_str, enum wrtd_trigger_mode *mode);
extern int parse_log_level (char *list[], int count, int *log_level);
extern void ts_add_ps(struct wrtd_tstamp *ts, uint64_t ps);
extern void ts_sub_ps(struct wrtd_tstamp *ts, uint64_t ps);
......
......@@ -61,9 +61,6 @@ static void print_logging (struct wrtd_dev *wrtd, int n_read)
case WRTD_LOG_MSG_EV_GENERATED:
printf("generated");
break;
case WRTD_LOG_MSG_EV_RECEIVED:
printf("received ");
break;
case WRTD_LOG_MSG_EV_CONSUMED:
printf("consumed ");
break;
......
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