Skip to content

Commit

Permalink
Add hardware timestamp in the pcap capture header
Browse files Browse the repository at this point in the history
If the hardware timestamp is not 0, it will be used as start time and
a new offset field will be updated with the difference with the system
time.

For more information see issue PandABlocks-FPGA#172
  • Loading branch information
EmilioPeJu committed Feb 15, 2024
1 parent e5a5dab commit 82805d4
Show file tree
Hide file tree
Showing 7 changed files with 55 additions and 6 deletions.
4 changes: 4 additions & 0 deletions config_d/registers
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,10 @@ BLOCKS_COMPAT_VERSION = 0
# frequency of 125 MHz will be reported and used.
NOMINAL_CLOCK 24

# Hardware timestamps
PCAP_TS_SEC 25
PCAP_TS_NSEC 26


# These registers are used by the kernel driver to read the data capture stream.
# This block is not used by the server, but is here for documentation and other
Expand Down
29 changes: 27 additions & 2 deletions server/data_server.c
Original file line number Diff line number Diff line change
Expand Up @@ -101,13 +101,38 @@ static const struct data_capture *data_capture;
static struct timespec pcap_arm_ts;
/* PCAP becomes armed & enabled timestamp */
static struct timespec pcap_start_ts;
static int64_t pcap_hw_ts_offset;

/* Data completion code at end of experiment. */
static unsigned int completion_code;
/* Sample count at end of experiment. */
static uint64_t experiment_sample_count;


/* Save start timestamp, either from hardware (if that timestamp is not 0), or
* from the driver (which was saved in the interrupt handler triggered by the
* start event) */
static void update_start_timestamp(void)
{
struct timespec pcap_drv_start_ts, pcap_hw_start_ts;
hw_get_start_ts(&pcap_drv_start_ts);
hw_get_hw_start_ts(&pcap_hw_start_ts);
if (pcap_hw_start_ts.tv_sec == 0 && pcap_hw_start_ts.tv_nsec == 0) {
pcap_start_ts = pcap_drv_start_ts;
pcap_hw_ts_offset = 0;
} else {
int64_t drv_ts_num =
(int64_t) pcap_drv_start_ts.tv_sec * 1000000000
+ pcap_drv_start_ts.tv_nsec;
int64_t hw_ts_num =
(int64_t) pcap_hw_start_ts.tv_sec * 1000000000
+ pcap_hw_start_ts.tv_nsec;
pcap_start_ts = pcap_hw_start_ts;
pcap_hw_ts_offset = drv_ts_num - hw_ts_num;
}
}


/* Performs a complete experiment capture: start data buffer, process the data
* stream until hardware is complete, stop data buffer. */
static void capture_experiment(void)
Expand Down Expand Up @@ -135,7 +160,7 @@ static void capture_experiment(void)
* timestamp, that's how it goes. */
if (!ts_captured)
{
hw_get_start_ts(&pcap_start_ts);
update_start_timestamp();
ts_captured = true;
}

Expand Down Expand Up @@ -687,7 +712,7 @@ error__t process_data_socket(int scon)
ok = send_data_header(
captured_fields, data_capture,
&connection.options, connection.file, lost_samples,
&pcap_arm_ts, &pcap_start_ts);
&pcap_arm_ts, &pcap_start_ts, pcap_hw_ts_offset);

uint64_t sent_samples = 0;
if (ok)
Expand Down
7 changes: 7 additions & 0 deletions server/hardware.c
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,13 @@ void hw_get_start_ts(struct timespec *ts)
ts->tv_nsec = (typeof(ts->tv_nsec)) compat_ts.tv_nsec;
}


void hw_get_hw_start_ts(struct timespec *ts)
{
ts->tv_sec = (time_t) read_named_register(PCAP_TS_SEC);
ts->tv_nsec = (typeof(ts->tv_nsec)) read_named_register(PCAP_TS_NSEC);
}

#endif


Expand Down
2 changes: 2 additions & 0 deletions server/hardware.h
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,8 @@ const char *hw_decode_completion(unsigned int completion);

/* This function gets the timestamp when PCAP becomes armed and enabled */
void hw_get_start_ts(struct timespec *ts);
/* This one is latched in hardware instead of the driver */
void hw_get_hw_start_ts(struct timespec *ts);

/* This function controls the arm/disarm state of data capture. Data capture is
* armed by writing true with this function, after which hw_read_streamed_data()
Expand Down
9 changes: 6 additions & 3 deletions server/prepare.c
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,7 @@ static void send_capture_info(
struct buffered_file *file,
const struct data_capture *capture, const struct data_options *options,
uint64_t missed_samples, struct timespec *pcap_arm_tsp,
struct timespec *pcap_start_tsp)
struct timespec *pcap_start_tsp, int64_t pcap_hw_ts_offset)
{
static const char *data_format_strings[] = {
[DATA_FORMAT_UNFRAMED] = "Unframed",
Expand All @@ -303,6 +303,7 @@ static void send_capture_info(
format_timestamp_message(
timestamp_message, MAX_RESULT_LENGTH, pcap_start_tsp);
format_attribute(&element, "start_time", "%s", timestamp_message);
format_attribute(&element, "hw_time_offset", "%"PRIi64, pcap_hw_ts_offset);
format_attribute(&element, "missed", "%"PRIu64, missed_samples);
format_attribute(&element, "process", "%s", data_process);
format_attribute(&element, "format", "%s", data_format);
Expand Down Expand Up @@ -377,13 +378,15 @@ bool send_data_header(
const struct data_capture *capture,
const struct data_options *options,
struct buffered_file *file, uint64_t missed_samples,
struct timespec *pcap_arm_tsp, struct timespec *pcap_start_tsp)
struct timespec *pcap_arm_tsp, struct timespec *pcap_start_tsp,
int64_t pcap_hw_ts_offset)
{
struct xml_element header =
start_element(file, "header", options->xml_header, true, true);

send_capture_info(
file, capture, options, missed_samples, pcap_arm_tsp, pcap_start_tsp);
file, capture, options, missed_samples, pcap_arm_tsp, pcap_start_tsp,
pcap_hw_ts_offset);

/* Format the field capture descriptions. */
struct xml_element field_group =
Expand Down
3 changes: 2 additions & 1 deletion server/prepare.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ bool send_data_header(
const struct data_capture *capture,
const struct data_options *options,
struct buffered_file *file, uint64_t lost_samples,
struct timespec *pcap_arm_tsp, struct timespec *pcap_start_tsp);
struct timespec *pcap_arm_tsp, struct timespec *pcap_start_tsp,
int64_t pcap_hw_ts_offset);


/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
Expand Down
7 changes: 7 additions & 0 deletions server/sim_hardware.c
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,13 @@ void hw_get_start_ts(struct timespec *ts)
}


void hw_get_hw_start_ts(struct timespec *ts)
{
ts->tv_sec = 0;
ts->tv_nsec = 0;
}


/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* Long table support. */

Expand Down

0 comments on commit 82805d4

Please sign in to comment.