Commit b8252869 authored by Federico Vaga's avatar Federico Vaga

wrtd:*:out: use librt to handle channel state

Signed-off-by: Federico Vaga's avatarFederico Vaga <federico.vaga@cern.ch>


NOTE
This commit has been created by `git subtree` on the Mock Turtle repository
on tag mock-turtle-2.0

This commit will not compile
parent 6370cb5a
Dictionary
==========
The main purpose of this dictionary is to explain the
White-Rabbit Trigger-Distribution terminology.
channel
dead time
delay
input
output
pulse
trigger
trigger condition
\ No newline at end of file
......@@ -359,4 +359,97 @@ struct wrtd_in {
uint32_t dead_time; /**< TDC dead time, in 8ns ticks */
};
enum wrtd_out_state_machine_steps {
OUT_ST_IDLE = 0,
OUT_ST_ARMED,
OUT_ST_TEST_PENDING,
OUT_ST_CONDITION_HIT,
};
/**
* Rule defining the behaviour of a trigger output upon reception of a
* trigger message with matching ID
*/
struct lrt_output_rule {
uint32_t delay_cycles; /**< Delay to add to the timestamp enclosed
within the trigger message */
uint16_t delay_frac;
uint16_t state; /**< State of the rule (empty, disabled,
conditional action, condition, etc.) */
struct lrt_output_rule *cond_ptr; /**< Pointer to conditional action.
Used for rules that define
triggering conditions. */
uint32_t latency_worst; /**< Worst-case latency (in 8ns ticks)*/
uint32_t latency_avg_sum; /**< Average latency accumulator and
number of samples */
uint32_t latency_avg_nsamples;
int hits; /**< Number of times the rule has successfully produced
a pulse */
int misses; /**< Number of times the rule has missed a pulse
(for any reason) */
};
#define ENTRY_FLAG_VALID (1 << 0)
/* Structure describing a single pulse in the Fine Delay software output queue */
struct pulse_queue_entry {
/* Trigger that produced the pulse */
struct wrtd_trigger_entry trig;
/* Origin timestamp cycles count (for latency statistics) */
int origin_cycles;
/* Rule that produced the pulse */
struct lrt_output_rule *rule;
};
/* Pulse FIFO for a single Fine Delay output */
struct lrt_pulse_queue {
struct pulse_queue_entry data[FD_MAX_QUEUE_PULSES];
int head, tail, count;
};
struct wrtd_out_channel_stats {
unsigned int hits;
unsigned int miss_timeout;
unsigned int miss_deadtime;
unsigned int miss_overflow;
unsigned int miss_no_timing;
struct wrtd_trigger_entry last_executed; /**< Last enqueued trigger
(i.e. the last one that
entered the output queue) */
struct wrtd_trigger_entry last_enqueued; /**< Last timestamp value
written to output config */
struct wr_timestamp last_programmed; /**< Last timestamp value written
to output config */
struct wrtd_trigger_entry last_lost;
};
struct wrtd_out_channel_config {
uint8_t idle; /**< Idle flag */
uint8_t state; /**< Arm state */
uint8_t mode; /**< Trigger mode */
uint8_t flags; /**< Flags (logging, etc) */
uint32_t log_level; /**< Current logging level */
uint32_t dead_time; /**< Dead time (8ns cycles) */
uint32_t width_cycles; /**< Pulse width (8ns cycles) */
};
struct wrtd_out_channel_private {
struct lrt_pulse_queue queue; /**< Output pulse queue */
struct lrt_output_rule *pending_trig; /**< Pending conditonal trigger */
struct wr_timestamp prev_pulse; /**< Last enqueued trigger + delay
(for dead time checking). */
};
struct wrtd_out_channel {
uint32_t base_addr;
int n;
struct wrtd_out_channel_stats stats;
struct wrtd_out_channel_config config;
struct wrtd_out_channel_private priv;
};
#endif
......@@ -250,49 +250,48 @@ void wrtd_log_close(struct wrnc_hmq *hmq)
static int wrtd_log_level_set(struct wrtd_node *dev, unsigned int channel,
uint32_t log_level, enum wrtd_core core)
{
struct wrnc_msg msg = wrnc_msg_init(4);
uint32_t seq = 0;
if (core) { /* Output */
uint32_t id = WRTD_CMD_FD_CHAN_SET_LOG_LEVEL;
struct wrtd_desc *wrtd = (struct wrtd_desc *)dev;
struct wrnc_structure_tlv tlv;
struct wrnc_proto_header hdr;
struct wrtd_out_channel ochan;
struct wrtd_in_channel ichan;
int err;
hdr.flags = WRNC_PROTO_FLAG_SYNC;
if (core) {
if (channel >= FD_NUM_CHANNELS) {
errno = EWRTD_INVALID_CHANNEL;
return -1;
}
/* Build the message */
wrnc_msg_header(&msg, &id, &seq);
wrnc_msg_uint32(&msg, &channel);
wrnc_msg_uint32(&msg, &log_level);
return wrtd_trivial_request(dev, &msg, core);
} else { /* Input */
struct wrtd_desc *wrtd = (struct wrtd_desc *)dev;
struct wrtd_in_channel chan;
struct wrnc_structure_tlv tlv = {
.index = IN_STRUCT_CHAN_0 + channel,
.size = sizeof(struct wrtd_in_channel),
.structure = &chan,
};
struct wrnc_proto_header hdr = {
.slot_io = (WRTD_IN_TDC_CONTROL << 4) |
(WRTD_OUT_TDC_CONTROL & 0xF),
.flags = WRNC_PROTO_FLAG_SYNC,
};
int err;
tlv.index = OUT_STRUCT_CHAN_0 + channel;
tlv.size = sizeof(struct wrtd_out_channel);
tlv.structure = &ochan;
hdr.slot_io = (WRTD_IN_FD_CONTROL << 4) |
(WRTD_OUT_FD_CONTROL & 0xF);
/* TODO set promiscuous mode */
} else {
if (channel >= TDC_NUM_CHANNELS) {
errno = EWRTD_INVALID_CHANNEL;
return -1;
}
err = wrnc_rt_structure_get(wrtd->wrnc, &hdr, &tlv, 1);
if (err)
return err;
chan.config.log_level = log_level;
return wrnc_rt_structure_set(wrtd->wrnc, &hdr, &tlv, 1);
tlv.index = IN_STRUCT_CHAN_0 + channel;
tlv.size = sizeof(struct wrtd_in_channel);
tlv.structure = &ichan;
hdr.slot_io = (WRTD_IN_TDC_CONTROL << 4) |
(WRTD_OUT_TDC_CONTROL & 0xF);
}
err = wrnc_rt_structure_get(wrtd->wrnc, &hdr, &tlv, 1);
if (err)
return err;
if (core)
ochan.config.log_level = log_level;
else
ichan.config.log_level = log_level;
return wrnc_rt_structure_set(wrtd->wrnc, &hdr, &tlv, 1);
}
......
......@@ -141,10 +141,19 @@ int wrtd_out_state_get(struct wrtd_node *dev, unsigned int output,
struct wrtd_output_state *state)
{
struct wrtd_desc *wrtd = (struct wrtd_desc *)dev;
struct wrnc_msg msg = wrnc_msg_init(20);
int err, dummy = 0;
uint32_t seq = 0, id;
uint32_t dead_time_ticks, pulse_width_ticks;
struct wrtd_out_channel chan;
struct wrnc_structure_tlv tlv = {
.index = OUT_STRUCT_CHAN_0 + output,
.size = sizeof(struct wrtd_out_channel)
- sizeof(struct wrtd_out_channel_private),
.structure = &chan,
};
struct wrnc_proto_header hdr = {
.slot_io = (WRTD_IN_FD_CONTROL << 4) |
(WRTD_OUT_FD_CONTROL & 0xF),
.flags = WRNC_PROTO_FLAG_SYNC,
};
int err;
if (output >= FD_NUM_CHANNELS) {
errno = EWRTD_INVALID_CHANNEL;
......@@ -156,63 +165,37 @@ int wrtd_out_state_get(struct wrtd_node *dev, unsigned int output,
return -1;
}
/* Build the message */
id = WRTD_CMD_FD_CHAN_GET_STATE;
wrnc_msg_header (&msg, &id, &seq);
wrnc_msg_uint32 (&msg, &output);
/* Send the message and get answer */
err = wrtd_out_send_and_receive_sync(wrtd, &msg);
if (err) {
errno = EWRTD_INVALID_ANSWER_STATE;
return -1;
}
/* Deserialize and check the answer */
wrnc_msg_header(&msg, &id, &seq);
if(id != WRTD_REP_STATE)
{
errno = EWRTD_INVALID_ANSWER_STATE;
return -1;
}
err = wrnc_rt_structure_get(wrtd->wrnc, &hdr, &tlv, 1);
if (err)
return err;
wrnc_msg_int32(&msg, &state->output);
wrnc_msg_uint32(&msg, &state->executed_pulses);
wrnc_msg_uint32(&msg, &state->missed_pulses_late);
wrnc_msg_uint32(&msg, &state->missed_pulses_deadtime);
wrnc_msg_uint32(&msg, &state->missed_pulses_overflow);
wrnc_msg_uint32(&msg, &state->missed_pulses_no_timing);
wrtd_msg_trigger_entry(&msg, &state->last_executed);
wrtd_msg_trigger_entry(&msg, &state->last_enqueued);
wrtd_msg_trigger_entry(&msg, &state->last_received);
wrtd_msg_trigger_entry(&msg, &state->last_lost);
wrnc_msg_int32(&msg, &dummy);
wrnc_msg_int32(&msg, &dummy);
wrnc_msg_int32(&msg, (int *) &state->mode);
wrnc_msg_uint32(&msg, &state->flags);
wrnc_msg_uint32(&msg, &state->log_level);
wrnc_msg_uint32(&msg, &dead_time_ticks);
wrnc_msg_uint32(&msg, &pulse_width_ticks);
wrnc_msg_uint32(&msg, &state->received_messages);
wrnc_msg_uint32(&msg, &state->received_loopback);
/* Check for deserialization errors (buffer underflow/overflow) */
if ( wrnc_msg_check_error(&msg) ) {
errno = EWRTD_INVALID_ANSWER_STATE;
return -1;
}
/* Copy to state structure */
state->output = chan.n;
state->executed_pulses = chan.stats.hits;
state->missed_pulses_late = chan.stats.miss_timeout;
state->missed_pulses_deadtime = chan.stats.miss_deadtime;
state->missed_pulses_overflow = chan.stats.miss_overflow;
state->missed_pulses_no_timing = chan.stats.miss_no_timing;
state->last_executed = chan.stats.last_executed;
state->last_enqueued = chan.stats.last_enqueued;
/* state->last_received = TODO;*/
state->last_lost = chan.stats.last_lost;
state->mode = chan.config.mode;
state->flags = chan.config.flags;
state->log_level = chan.config.log_level;
/* TODO */
/* state->received_messages */
/* state->received_loopback */
state->pulse_width.seconds = 0;
state->pulse_width.frac = 0;
state->pulse_width.ticks = pulse_width_ticks;
state->pulse_width.ticks = chan.config.width_cycles;
state->dead_time.seconds = 0;
state->dead_time.frac = 0;
state->dead_time.ticks = dead_time_ticks;
state->dead_time.ticks = chan.config.dead_time;
return 0;
}
......@@ -229,7 +212,18 @@ int wrtd_out_enable(struct wrtd_node *dev, unsigned int output,
int enable)
{
struct wrtd_desc *wrtd = (struct wrtd_desc *)dev;
struct wrnc_msg msg;
struct wrtd_out_channel chan;
struct wrnc_structure_tlv tlv = {
.index = OUT_STRUCT_CHAN_0 + output,
.size = sizeof(struct wrtd_out_channel)
- sizeof(struct wrtd_out_channel_private),
.structure = &chan,
};
struct wrnc_proto_header hdr = {
.slot_io = (WRTD_IN_FD_CONTROL << 4) |
(WRTD_OUT_FD_CONTROL & 0xF),
.flags = WRNC_PROTO_FLAG_SYNC,
};
int err;
if (output >= FD_NUM_CHANNELS) {
......@@ -237,19 +231,21 @@ int wrtd_out_enable(struct wrtd_node *dev, unsigned int output,
return -1;
}
/* Build the message */
msg.datalen = 4;
msg.data[0] = WRTD_CMD_FD_CHAN_ENABLE;
msg.data[1] = 0;
msg.data[2] = output;
msg.data[3] = !!enable;
/* Send the message and get answer */
err = wrtd_out_send_and_receive_sync(wrtd, &msg);
err = wrnc_rt_structure_get(wrtd->wrnc, &hdr, &tlv, 1);
if (err)
return err;
return wrtd_validate_acknowledge(&msg);
if (enable) {
chan.config.flags |= WRTD_ENABLED;
} else {
chan.config.flags &= ~(WRTD_ENABLED | WRTD_ARMED |
WRTD_TRIGGERED | WRTD_LAST_VALID);
chan.config.state = OUT_ST_IDLE;
/* run pulse_queue_init ( &out->queue ); on RT side */
/* set variable fd_ch_writel(out, FD_DCR_MODE, FD_REG_DCR); */
}
return wrnc_rt_structure_set(wrtd->wrnc, &hdr, &tlv, 1);
}
......@@ -532,38 +528,38 @@ int wrtd_out_pulse_width_set(struct wrtd_node *dev, unsigned int output,
uint64_t width_ps)
{
struct wrtd_desc *wrtd = (struct wrtd_desc *)dev;
struct wrnc_msg msg = wrnc_msg_init (16);
int err, tmp = 0;
uint32_t seq = 0, id;
struct wrtd_out_channel chan;
struct wrnc_structure_tlv tlv = {
.index = OUT_STRUCT_CHAN_0 + output,
.size = sizeof(struct wrtd_out_channel)
- sizeof(struct wrtd_out_channel_private),
.structure = &chan,
};
struct wrnc_proto_header hdr = {
.slot_io = (WRTD_IN_FD_CONTROL << 4) |
(WRTD_OUT_FD_CONTROL & 0xF),
.flags = WRNC_PROTO_FLAG_SYNC,
};
int err;
if (output >= FD_NUM_CHANNELS) {
errno = EWRTD_INVALID_CHANNEL;
return -1;
}
if (width_ps < 1000ULL * 250 || width_ps >= 1000ULL * 1000 * 1000 * 1000 )
{
if (width_ps < 1000ULL * 250 ||
width_ps >= 1000ULL * 1000 * 1000 * 1000) {
errno = EWRTD_INVALID_PULSE_WIDTH;
return -1;
}
/* Build the message */
id = WRTD_CMD_FD_CHAN_SET_WIDTH;
wrnc_msg_header (&msg, &id, &seq);
wrnc_msg_uint32 (&msg, &output);
tmp = width_ps / 8000ULL;
wrnc_msg_int32 (&msg, &tmp);
err = wrnc_rt_structure_get(wrtd->wrnc, &hdr, &tlv, 1);
if (err)
return err;
/* Send the message and get answer */
err = wrtd_out_send_and_receive_sync(wrtd, &msg);
if (err) {
errno = EWRTD_INVALID_ANSWER_STATE;
return -1;
}
chan.config.width_cycles = width_ps / 8000ULL;
return wrtd_validate_acknowledge(&msg);
return wrnc_rt_structure_set(wrtd->wrnc, &hdr, &tlv, 1);
}
......@@ -584,20 +580,33 @@ int wrtd_out_pulse_width_set(struct wrtd_node *dev, unsigned int output,
int wrtd_out_dead_time_set(struct wrtd_node *dev, unsigned int output,
uint64_t dead_time_ps)
{
struct wrnc_msg msg = wrnc_msg_init(5);
uint32_t id, seq = 0, ticks = dead_time_ps / 8000;
struct wrtd_desc *wrtd = (struct wrtd_desc *)dev;
struct wrtd_out_channel chan;
struct wrnc_structure_tlv tlv = {
.index = OUT_STRUCT_CHAN_0 + output,
.size = sizeof(struct wrtd_out_channel)
- sizeof(struct wrtd_out_channel_private),
.structure = &chan,
};
struct wrnc_proto_header hdr = {
.slot_io = (WRTD_IN_FD_CONTROL << 4) |
(WRTD_OUT_FD_CONTROL & 0xF),
.flags = WRNC_PROTO_FLAG_SYNC,
};
int err;
if (output >= FD_NUM_CHANNELS) {
errno = EWRTD_INVALID_CHANNEL;
return -1;
}
id = WRTD_CMD_FD_CHAN_DEAD_TIME;
wrnc_msg_header (&msg, &id, &seq);
wrnc_msg_uint32 (&msg, &output);
wrnc_msg_uint32 (&msg, &ticks);
err = wrnc_rt_structure_get(wrtd->wrnc, &hdr, &tlv, 1);
if (err)
return err;
return wrtd_out_trivial_request (dev, &msg);
chan.config.dead_time = dead_time_ps / 8000;
return wrnc_rt_structure_set(wrtd->wrnc, &hdr, &tlv, 1);
}
......@@ -665,21 +674,38 @@ int wrtd_out_trigger_mode_set(struct wrtd_node *dev,
unsigned int output,
enum wrtd_trigger_mode mode)
{
struct wrnc_msg msg = wrnc_msg_init(4);
uint32_t seq = 0, id, m = mode;
struct wrtd_desc *wrtd = (struct wrtd_desc *)dev;
struct wrtd_out_channel chan;
struct wrnc_structure_tlv tlv = {
.index = OUT_STRUCT_CHAN_0 + output,
.size = sizeof(struct wrtd_out_channel)
- sizeof(struct wrtd_out_channel_private),
.structure = &chan,
};
struct wrnc_proto_header hdr = {
.slot_io = (WRTD_IN_FD_CONTROL << 4) |
(WRTD_OUT_FD_CONTROL & 0xF),
.flags = WRNC_PROTO_FLAG_SYNC,
};
int err;
if (output >= FD_NUM_CHANNELS) {
errno = EWRTD_INVALID_CHANNEL;
return -1;
}
/* Build the message */
id = WRTD_CMD_FD_CHAN_SET_MODE;
wrnc_msg_header(&msg, &id, &seq);
wrnc_msg_uint32(&msg, &output);
wrnc_msg_uint32(&msg, &m);
err = wrnc_rt_structure_get(wrtd->wrnc, &hdr, &tlv, 1);
if (err)
return err;
return wrtd_out_trivial_request (dev, &msg);
chan.config.mode = mode;
chan.config.flags &= (WRTD_TRIGGERED | WRTD_LAST_VALID);
if (chan.config.mode == WRTD_TRIGGER_MODE_SINGLE) {
chan.config.flags &= ~WRTD_ARMED;
chan.config.state = OUT_ST_IDLE;
}
return wrnc_rt_structure_set(wrtd->wrnc, &hdr, &tlv, 1);
}
......@@ -692,20 +718,40 @@ int wrtd_out_trigger_mode_set(struct wrtd_node *dev,
*/
int wrtd_out_arm(struct wrtd_node *dev, unsigned int output, int armed)
{
struct wrnc_msg msg = wrnc_msg_init(4);
uint32_t seq = 0, id = WRTD_CMD_FD_CHAN_ARM;
struct wrtd_desc *wrtd = (struct wrtd_desc *)dev;
struct wrtd_out_channel chan;
struct wrnc_structure_tlv tlv = {
.index = OUT_STRUCT_CHAN_0 + output,
.size = sizeof(struct wrtd_out_channel)
- sizeof(struct wrtd_out_channel_private),
.structure = &chan,
};
struct wrnc_proto_header hdr = {
.slot_io = (WRTD_IN_FD_CONTROL << 4) |
(WRTD_OUT_FD_CONTROL & 0xF),
.flags = WRNC_PROTO_FLAG_SYNC,
};
int err;
if (output >= FD_NUM_CHANNELS) {
errno = EWRTD_INVALID_CHANNEL;
return -1;
}
/* Build the message */
wrnc_msg_header(&msg, &id, &seq);
wrnc_msg_uint32(&msg, &output);
wrnc_msg_int32(&msg, &armed);
err = wrnc_rt_structure_get(wrtd->wrnc, &hdr, &tlv, 1);
if (err)
return err;
return wrtd_out_trivial_request (dev, &msg);
chan.config.flags &= ~WRTD_TRIGGERED;
if (armed) {
chan.config.flags |= WRTD_ARMED;
chan.config.state = OUT_ST_ARMED;
} else {
chan.config.flags &= ~WRTD_ARMED;
chan.config.state = OUT_ST_IDLE;
}
return wrnc_rt_structure_set(wrtd->wrnc, &hdr, &tlv, 1);
}
......@@ -716,19 +762,37 @@ int wrtd_out_arm(struct wrtd_node *dev, unsigned int output, int armed)
*/
int wrtd_out_counters_reset(struct wrtd_node *dev, unsigned int output)
{
struct wrnc_msg msg = wrnc_msg_init(3);
uint32_t seq = 0, id = WRTD_CMD_FD_CHAN_RESET_COUNTERS;
struct wrtd_desc *wrtd = (struct wrtd_desc *)dev;
struct wrtd_out_channel chan;
struct wrnc_structure_tlv tlv = {
.index = OUT_STRUCT_CHAN_0 + output,
.size = sizeof(struct wrtd_out_channel)
- sizeof(struct wrtd_out_channel_private),
.structure = &chan,
};
struct wrnc_proto_header hdr = {
.slot_io = (WRTD_IN_FD_CONTROL << 4) |
(WRTD_OUT_FD_CONTROL & 0xF),
.flags = WRNC_PROTO_FLAG_SYNC,
};
int err;
if (output >= FD_NUM_CHANNELS) {
errno = EWRTD_INVALID_CHANNEL;
return -1;
}
/* Build the message */
wrnc_msg_header(&msg, &id, &seq);
wrnc_msg_uint32(&msg, &output);
err = wrnc_rt_structure_get(wrtd->wrnc, &hdr, &tlv, 1);
if (err)
return err;
return wrtd_out_trivial_request (dev, &msg);
chan.stats.miss_timeout = 0;
chan.stats.miss_deadtime = 0;
chan.stats.miss_no_timing = 0;
chan.stats.miss_overflow = 0;
chan.config.flags &= ~WRTD_LAST_VALID;
return wrnc_rt_structure_set(wrtd->wrnc, &hdr, &tlv, 1);
}
......
......@@ -27,14 +27,8 @@
#include <librt.h>
#define OUT_ST_IDLE 0
#define OUT_ST_ARMED 1
#define OUT_ST_TEST_PENDING 2
#define OUT_ST_CONDITION_HIT 3
#define OUT_TIMEOUT 10
static const uint32_t version = GIT_VERSION;
static uint32_t promiscuous_mode = 0;
......@@ -110,30 +104,6 @@ int wr_is_timing_ok()
/**
* Rule defining the behaviour of a trigger output upon reception of a
* trigger message with matching ID
*/
struct lrt_output_rule {
uint32_t delay_cycles; /**< Delay to add to the timestamp enclosed
within the trigger message */
uint16_t delay_frac;
uint16_t state; /**< State of the rule (empty, disabled,
conditional action, condition, etc.) */
struct lrt_hash_entry *cond_ptr; /**< Pointer to conditional action.
Used for rules that define
triggering conditions. */
uint32_t latency_worst; /**< Worst-case latency (in 8ns ticks)*/
uint32_t latency_avg_sum; /**< Average latency accumulator and
number of samples */
uint32_t latency_avg_nsamples;
int hits; /**< Number of times the rule has successfully produced
a pulse */
int misses; /**< Number of times the rule has missed a pulse
(for any reason) */
};
#define ENTRY_FLAG_VALID (1 << 0)
/**
* Trigger handled by this real-time application
*/
......@@ -323,22 +293,6 @@ int rtfd_trigger_entry_rules_count(unsigned int ch)
}
/* Structure describing a single pulse in the Fine Delay software output queue */
struct pulse_queue_entry {
/* Trigger that produced the pulse */
struct wrtd_trigger_entry trig;
/* Origin timestamp cycles count (for latency statistics) */
int origin_cycles;
/* Rule that produced the pulse */
struct lrt_output_rule *rule;
};
/* Pulse FIFO for a single Fine Delay output */
struct lrt_pulse_queue
{
struct pulse_queue_entry data[FD_MAX_QUEUE_PULSES];
int head, tail, count;
};
/* State of a single Trigger Output */
struct lrt_output {
......@@ -394,7 +348,8 @@ struct lrt_trigger_handle {
};
/* Output state array */
static struct lrt_output outputs[FD_NUM_CHANNELS];
static struct lrt_output outputs[1];
static struct wrtd_out_channel wrtd_out_channels[FD_NUM_CHANNELS];
/* Received message counters */
static int rx_ebone = 0, rx_loopback = 0;
/* Last received trigger (i.e. last received packet from Etherbone). */
......@@ -882,31 +837,6 @@ static inline void ctl_nack( uint32_t seq, int err )
hmq_msg_send (&buf);
}
static inline void ctl_chan_enable (uint32_t seq, struct wrnc_msg *ibuf)
{
int ch, enabled;
wrnc_msg_int32(ibuf, &ch);
wrnc_msg_int32(ibuf, &enabled);
struct lrt_output *out = &outputs[ch];
if(enabled) {
out->flags |= WRTD_ENABLED;
} else {
out->flags &= ~(WRTD_ENABLED | WRTD_ARMED | WRTD_TRIGGERED | WRTD_LAST_VALID);
out->state = OUT_ST_IDLE;
/* clear the pulse queue and disable the physical output */
pulse_queue_init ( &out->queue );
fd_ch_writel(out, FD_DCR_MODE, FD_REG_DCR);
}
// pp_printf("chan-enable %d %d flags %x\n", ch, enabled, out->flags);
ctl_ack (seq);
}
static inline void ctl_trig_assign (uint32_t seq, struct wrnc_msg *ibuf)
{
......@@ -1136,31 +1066,6 @@ static inline void ctl_chan_get_trigger_state (uint32_t seq, struct wrnc_msg *ib
send_hash_entry (seq, handle.channel, 1, handle.cond ? handle.cond : handle.trig );
}
static inline void ctl_chan_reset_counters (uint32_t seq, struct wrnc_msg *ibuf)
{
int ch;
wrnc_msg_int32(ibuf, &ch);
struct lrt_output *st = &outputs[ch];
st->hits = 0;
st->miss_timeout = 0;
st->miss_deadtime = 0;
st->miss_no_timing = 0;
st->miss_overflow = 0;
st->flags &= ~WRTD_LAST_VALID;
ctl_ack (seq);
}
static inline void ctl_chan_set_dead_time (uint32_t seq, struct wrnc_msg *ibuf)
{
int ch;
wrnc_msg_int32(ibuf, &ch);
wrnc_msg_int32(ibuf, &outputs[ch].dead_time);
ctl_ack(seq);
}
static inline void ctl_base_time (uint32_t seq, struct wrnc_msg *ibuf)
{
......@@ -1203,53 +1108,6 @@ static inline void ctl_chan_set_delay (uint32_t seq, struct wrnc_msg *ibuf)
ctl_ack(seq);
}
static inline void ctl_chan_get_state (uint32_t seq, struct wrnc_msg *ibuf)
{
int ch;
wrnc_msg_int32(ibuf, &ch);
struct lrt_output *st = &outputs[ch];
struct wrnc_msg obuf = ctl_claim_out_buf();
uint32_t id_state = WRTD_REP_STATE;
if(st->state != OUT_ST_IDLE)
st->flags |= WRTD_ARMED;
st->flags &= ~WRTD_NO_WR;
if( !wr_is_timing_ok() )
st->flags |= WRTD_NO_WR;
/* Create the response */
wrnc_msg_header(&obuf, &id_state, &seq);
wrnc_msg_int32(&obuf, &ch);
wrnc_msg_int32(&obuf, &st->hits);
wrnc_msg_int32(&obuf, &st->miss_timeout);
wrnc_msg_int32(&obuf, &st->miss_deadtime);
wrnc_msg_int32(&obuf, &st->miss_overflow);
wrnc_msg_int32(&obuf, &st->miss_no_timing);
wrtd_msg_trigger_entry(&obuf, &st->last_executed);
wrtd_msg_trigger_entry(&obuf, &st->last_enqueued);
wrtd_msg_trigger_entry(&obuf, &last_received);
wrtd_msg_trigger_entry(&obuf, &st->last_lost);
wrnc_msg_int32(&obuf, &st->idle);
wrnc_msg_int32(&obuf, &st->state);
wrnc_msg_int32(&obuf, &st->mode);
wrnc_msg_uint32(&obuf, &st->flags);
wrnc_msg_uint32(&obuf, &st->log_level);
wrnc_msg_int32(&obuf, &st->dead_time);
wrnc_msg_int32(&obuf, &st->width_cycles);
wrnc_msg_int32(&obuf, &rx_ebone);
wrnc_msg_int32(&obuf, &rx_loopback);
hmq_msg_send (&obuf);
}
static inline void ctl_software_trigger (uint32_t seq, struct wrnc_msg *ibuf)
{
......@@ -1311,73 +1169,6 @@ static inline void ctl_software_trigger (uint32_t seq, struct wrnc_msg *ibuf)
}
static inline void ctl_chan_set_mode (uint32_t seq, struct wrnc_msg *ibuf)
{
int ch;
wrnc_msg_int32(ibuf, &ch);
struct lrt_output *st = &outputs[ch];
wrnc_msg_int32(ibuf, &st->mode);
st->flags &= ( WRTD_TRIGGERED | WRTD_LAST_VALID) ;
if( st->mode == WRTD_TRIGGER_MODE_SINGLE ) {
st->flags &= ~WRTD_ARMED;
st->state = OUT_ST_IDLE;
}
ctl_ack(seq);
}
static inline void ctl_chan_set_width (uint32_t seq, struct wrnc_msg *ibuf)
{
int ch;
wrnc_msg_int32(ibuf, &ch);
struct lrt_output *st = &outputs[ch];
wrnc_msg_int32(ibuf, &st->width_cycles);
ctl_ack(seq);
}
static inline void ctl_chan_arm (uint32_t seq, struct wrnc_msg *ibuf)
{
int ch, armed;
wrnc_msg_int32(ibuf, &ch);
wrnc_msg_int32(ibuf, &armed);
struct lrt_output *st = &outputs[ch];
st->flags &= ~WRTD_TRIGGERED;
if(armed) {
st->flags |= WRTD_ARMED;
st->state = OUT_ST_ARMED;
} else {
st->flags &= ~WRTD_ARMED;
st->state = OUT_ST_IDLE;
}
ctl_ack(seq);
}
static inline void ctl_chan_set_log_level (uint32_t seq, struct wrnc_msg *ibuf)
{
int ch, i;
wrnc_msg_int32(ibuf, &ch);
struct lrt_output *st = &outputs[ch];
wrnc_msg_uint32(ibuf, &st->log_level);
ctl_ack(seq);
/* Set promiscuous_mode - so it's enable if at least one channel
has enable it */
promiscuous_mode = 0;
for (i = 0; i < FD_NUM_CHANNELS; i++)
promiscuous_mode |= (outputs[i].log_level & WRTD_LOG_PROMISC);
}
/* Receives command messages and call matching command handlers */
static inline void do_control()
{
......@@ -1408,20 +1199,7 @@ static inline void do_control()
_CMD(WRTD_CMD_FD_TRIG_SET_DELAY, ctl_chan_set_delay)
_CMD(WRTD_CMD_FD_TRIG_GET_BY_ID, ctl_chan_get_trigger_by_id)
_CMD(WRTD_CMD_FD_TRIG_GET_STATE, ctl_chan_get_trigger_state)
_CMD(WRTD_CMD_FD_CHAN_RESET_COUNTERS, ctl_chan_reset_counters)
_CMD(WRTD_CMD_FD_CHAN_ENABLE, ctl_chan_enable)
_CMD(WRTD_CMD_FD_CHAN_SET_MODE, ctl_chan_set_mode)
_CMD(WRTD_CMD_FD_CHAN_ARM, ctl_chan_arm)
_CMD(WRTD_CMD_FD_CHAN_GET_STATE, ctl_chan_get_state)
_CMD(WRTD_CMD_FD_CHAN_SET_LOG_LEVEL, ctl_chan_set_log_level)
_CMD(WRTD_CMD_FD_CHAN_SET_WIDTH, ctl_chan_set_width)
_CMD(WRTD_CMD_FD_READ_HASH, ctl_read_hash)
_CMD(WRTD_CMD_FD_BASE_TIME, ctl_base_time)
_CMD(WRTD_CMD_FD_CHAN_DEAD_TIME, ctl_chan_set_dead_time)
_CMD(WRTD_CMD_FD_VERSION, ctl_version)
default:
break;
}
......@@ -1465,24 +1243,24 @@ void init_outputs()
*/
static struct rt_structure wrtd_out_structures[] = {
[OUT_STRUCT_CHAN_0] = {
.struct_ptr = &outputs[0],
.len = sizeof(struct lrt_output),
.struct_ptr = &wrtd_out_channels[0],
.len = sizeof(struct wrtd_out_channel)
- sizeof(struct wrtd_out_channel_private),
},
[OUT_STRUCT_CHAN_1] = {
.struct_ptr = &outputs[1],
.len = sizeof(struct lrt_output),
.struct_ptr = &wrtd_out_channels[1],
.len = sizeof(struct wrtd_out_channel)
- sizeof(struct wrtd_out_channel_private),
},
[OUT_STRUCT_CHAN_2] = {
.struct_ptr = &outputs[2],
.len = sizeof(struct lrt_output),
.struct_ptr = &wrtd_out_channels[2],
.len = sizeof(struct wrtd_out_channel)
- sizeof(struct wrtd_out_channel_private),
},
[OUT_STRUCT_CHAN_3] = {
.struct_ptr = &outputs[3],
.len = sizeof(struct lrt_output),
},
[OUT_STRUCT_CHAN_4] = {
.struct_ptr = &outputs[4],
.len = sizeof(struct lrt_output),
.struct_ptr = &wrtd_out_channels[3],
.len = sizeof(struct wrtd_out_channel)
- sizeof(struct wrtd_out_channel_private),
},
};
......@@ -1576,6 +1354,7 @@ void init(void)
int main(void)
{
pp_printf("struct len %d vs %d\n", wrtd_out_structures[1].len, sizeof(struct wrtd_out_channel));
init();
rt_init(&app);
......
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