Skip to content

Commit

Permalink
Merge branches 'nominal-clock' and 'scaled-samples'
Browse files Browse the repository at this point in the history
Addresses issue #8 which can now be closed
  • Loading branch information
Araneidae committed Sep 22, 2023
3 parents 1f07bd9 + c15020f + 2b39c87 commit 19f58f6
Show file tree
Hide file tree
Showing 9 changed files with 52 additions and 13 deletions.
7 changes: 6 additions & 1 deletion config_d/registers
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,11 @@ BLOCKS_COMPAT_VERSION = 0
# Range of MAC addresses
MAC_ADDRESS_BASE 16 .. 23

# Nominal clock. If this register is non zero the value returned will be
# used as the reported clock frequency in Hz, otherwise the standard
# frequency of 125 MHz will be reported and used.
NOMINAL_CLOCK 24


# 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 All @@ -71,4 +76,4 @@ BLOCKS_COMPAT_VERSION = 0

# Kernel driver compatiblity version check register. The value in this
# register must match DRIVER_COMPAT_VERSION.
DRV_COMPAT_VERSION 7
COMPAT_VERSION 7
7 changes: 7 additions & 0 deletions docs/commands.rst
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,9 @@ below:
| ``*SAVESTATE=`` | Triggers immediate save to file of the |
| | persistence file state. |
+-------------------------------+----------------------------------------------+
| ``*CLOCK_FREQ?`` | Returns currently configured system clock |
| | frequency |
+-------------------------------+----------------------------------------------+

``*IDN?``
Returns system identification string, for example the following::
Expand Down Expand Up @@ -398,3 +401,7 @@ below:
launched) with the current state. Returns after a file system ``sync``
call, so it is safe to power-off the system after this command has
completed.

``*CLOCK_FREQ?``
Returns currently configured FPGA clock frequency as used to convert between
times in natural units and times in clock ticks.
2 changes: 1 addition & 1 deletion driver/panda_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ static int panda_probe(struct platform_device *pdev)
pcap->irq = rc;

/* Check the driver and FPGA protocol version match. */
TEST_OK(readl(pcap->reg_base + DRV_COMPAT_VERSION) == DRIVER_COMPAT_VERSION,
TEST_OK(readl(pcap->reg_base + COMPAT_VERSION) == DRIVER_COMPAT_VERSION,
rc = -EINVAL, bad_version, "Driver compatibility version mismatch");

/* Create character device support. */
Expand Down
2 changes: 1 addition & 1 deletion server/config_server.c
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ uint64_t update_change_index(
else
/* If this change isn't to be reported, push the report index out to
* the indefinite future. */
reported[i] = (uint64_t) (int64_t) -1;
reported[i] = UINT64_MAX;
return change_index;
}

Expand Down
4 changes: 2 additions & 2 deletions server/ext_out.c
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ static enum capture_mode get_capture_mode(enum ext_out_type ext_type)
switch (ext_type)
{
case EXT_OUT_TIMESTAMP: return CAPTURE_MODE_SCALED64;
case EXT_OUT_SAMPLES: return CAPTURE_MODE_UNSCALED;
case EXT_OUT_SAMPLES: return CAPTURE_MODE_SCALED32;
case EXT_OUT_BITS: return CAPTURE_MODE_UNSCALED;
default:
ASSERT_FAIL();
Expand All @@ -177,7 +177,7 @@ static void get_capture_info(
.capture_mode = get_capture_mode(ext_out->ext_type),
.capture_string = "Value",
/* Scaling info only used for timestamp fields. */
.scale = 1.0 / CLOCK_FREQUENCY,
.scale = 1.0 / hw_read_nominal_clock(),
.offset = 0.0,
.units = "s",
};
Expand Down
10 changes: 10 additions & 0 deletions server/hardware.c
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,16 @@ uint32_t hw_read_fpga_capabilities(void)
}


uint32_t hw_read_nominal_clock(void)
{
uint32_t frequency = read_named_register(NOMINAL_CLOCK);
if (frequency > 0)
return frequency;
else
return NOMINAL_CLOCK_FREQUENCY;
}


/******************************************************************************/
/* Data capture. */

Expand Down
5 changes: 4 additions & 1 deletion server/hardware.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
#define MAX_PCAP_WRITE_COUNT 64


#define CLOCK_FREQUENCY 125000000 // 8ns per tick
#define NOMINAL_CLOCK_FREQUENCY 125000000 // 8ns per tick
#define MAX_CLOCK_VALUE ((1ULL << 48) - 1)


Expand Down Expand Up @@ -100,6 +100,9 @@ void hw_write_mac_address(unsigned int offset, uint64_t mac_address);
/* Returns the value of the FPGA capabilities register. */
uint32_t hw_read_fpga_capabilities(void);

/* Returns the currently configured nominal clock frequency in Hz. */
uint32_t hw_read_nominal_clock(void);


/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* Table API. */
Expand Down
11 changes: 11 additions & 0 deletions server/system_command.c
Original file line number Diff line number Diff line change
Expand Up @@ -464,6 +464,16 @@ static error__t put_savestate(
}


/* *CLOCK_FREQ?
*
* Returns current configured clock frequency. */
static error__t get_clock_freq(
const char *command, struct connection_result *result)
{
return format_one_result(result, "%d", hw_read_nominal_clock());
}


/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* System command dispatch. */

Expand Down Expand Up @@ -495,6 +505,7 @@ static const struct command_table_entry command_table_list[] = {
{ "ENUMS", true, .get = get_enums, },
{ "PCAP", true, .get = get_pcap, .put = put_pcap, },
{ "SAVESTATE", false, .put = put_savestate, },
{ "CLOCK_FREQ", false, .get = get_clock_freq, },
};

static struct hash_table *command_table;
Expand Down
17 changes: 10 additions & 7 deletions server/time.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,10 @@ static const struct enum_set time_units_enum_set = {

static const double time_conversion[] =
{
(double) 60 * CLOCK_FREQUENCY, // TIME_MINS
CLOCK_FREQUENCY, // TIME_SECS
CLOCK_FREQUENCY / 1e3, // TIME_MSECS
CLOCK_FREQUENCY / 1e6, // TIME_USECS
60.0, // TIME_MINS
1.0, // TIME_SECS
1e-3, // TIME_MSECS
1e-6, // TIME_USECS
};

static const struct enumeration *time_units_enumeration;
Expand Down Expand Up @@ -120,7 +120,8 @@ static error__t time_class_format(
uint64_t value, unsigned int scale, char result[], size_t length)
{
return format_double(
result, length, (double) value / time_conversion[scale]);
result, length,
(double) value / time_conversion[scale] / hw_read_nominal_clock());
}


Expand Down Expand Up @@ -173,7 +174,8 @@ static error__t time_class_parse(
* result of the calculation below and detect range overflow ... good
* luck with that, seems that whether overflow is actually reported is
* target dependent, and doesn't work for us. Ho hum. */
DO(value = scaled_value * time_conversion[scale]) ?:
DO(value =
scaled_value * time_conversion[scale] * hw_read_nominal_clock()) ?:
TEST_OK_(0 <= value && value <= max_value,
"Time setting out of range") ?:
DO(*result = (uint64_t) llround(value));
Expand Down Expand Up @@ -289,7 +291,8 @@ static error__t time_min_format(
struct time_field *field = &state->values[number];
return format_double(
result, length,
(double) (state->min_value + 1) / time_conversion[field->time_scale]);
(double) (state->min_value + 1) /
time_conversion[field->time_scale] / hw_read_nominal_clock());
}


Expand Down

0 comments on commit 19f58f6

Please sign in to comment.