From 48d80c32c67803c85dfcfa8df47ec3d43aca8a71 Mon Sep 17 00:00:00 2001 From: Emilio Perez Juarez Date: Mon, 22 Dec 2025 00:03:14 +0000 Subject: [PATCH 1/2] Let FPGA sim server know about streaming tables - The 'more' flag is now included in the length of the table write - The table write command now reads a status code to allow failing the command, this is needed, for example, when sending a streaming table but the block is not ready because of a DMA underrun condition. - A new command(Q) was added to obtain the number of queued words, this is analoguous to the ioctl command to do the same. --- python/sim_server | 3 +++ server/hardware.c | 29 +++++++++++++++++------------ server/hardware.h | 2 +- server/sim_hardware.c | 24 +++++++++++++++++++++--- server/sim_hardware.h | 2 ++ server/table.c | 3 ++- 6 files changed, 46 insertions(+), 17 deletions(-) diff --git a/python/sim_server b/python/sim_server index 7edbd592..a908c281 100755 --- a/python/sim_server +++ b/python/sim_server @@ -75,6 +75,9 @@ def run_simulation(conn): length, = struct.unpack('I', read(conn, 4)) data = read(conn, length * 4) sim_registers.write_table(block, num, reg, data) + conn.sendall(struct.pack('I', 0)) + elif command == b'Q': + conn.sendall(struct.pack('I', 0)) elif command == b'D': # Retrieve increment of data stream length, = struct.unpack('I', read(conn, 4)) diff --git a/server/hardware.c b/server/hardware.c index 8bcb173e..9129ab59 100644 --- a/server/hardware.c +++ b/server/hardware.c @@ -509,9 +509,26 @@ static error__t hw_long_table_write( }; return TEST_IO(ioctl(block_id, PANDA_BLOCK_SEND, &request)); } + +static size_t hw_long_table_get_queued_words(int block_id) +{ + size_t result = 0; + ioctl(block_id, PANDA_BLOCK_NWORDS, &result); + return result; +} #endif +size_t hw_table_get_queued_words(struct hw_table *table, unsigned int number) +{ + if (table->table_type == LONG_TABLE) + return hw_long_table_get_queued_words( + table->long_table.block_ids[number]); + else + return 0; +} + + static error__t create_long_table( struct hw_table *table, unsigned int order, unsigned int nbuffers, size_t *block_length, unsigned int base_reg, unsigned int length_reg) @@ -651,18 +668,6 @@ void hw_close_table(struct hw_table *table) } -size_t hw_get_queued_words(struct hw_table *table, unsigned int number) -{ - if (table->table_type == LONG_TABLE) - { - size_t result = 0; - ioctl(table->long_table.block_ids[number], PANDA_BLOCK_NWORDS, &result); - return result; - } - return 0; -} - - /******************************************************************************/ diff --git a/server/hardware.h b/server/hardware.h index fab940c1..5a8f4108 100644 --- a/server/hardware.h +++ b/server/hardware.h @@ -147,7 +147,7 @@ void hw_close_table(struct hw_table *table); /* Returns the number of 4-byte words scheduled, it's valid for long tables * only, otherwise 0 */ -size_t hw_get_queued_words(struct hw_table *table, unsigned int number); +size_t hw_table_get_queued_words(struct hw_table *table, unsigned int number); /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* Streamed data capture. */ diff --git a/server/sim_hardware.c b/server/sim_hardware.c index 4e98b877..1a3ea193 100644 --- a/server/sim_hardware.c +++ b/server/sim_hardware.c @@ -254,12 +254,30 @@ error__t hw_long_table_write( memcpy(block->data, data, nbytes); ASSERT_OK(length == (uint32_t) length); + uint32_t length_with_flag = (uint32_t) length; + if (streaming_mode && !last_table) + length_with_flag |= 0x80000000; + uint32_t result = 0; WITH_MUTEX(mutex) handle_error( write_command_int('T', - block->block_base, block->number, 0, (uint32_t) length) ?: - write_all(block->data, nbytes)); - return ERROR_OK; + block->block_base, block->number, 0, length_with_flag) ?: + write_all(block->data, nbytes) ?: + read_all(&result, 4)); + return TEST_OK_(result == 0, "Long table write failed"); +} + + +size_t hw_long_table_get_queued_words(int block_id) +{ + ASSERT_OK(0 <= block_id && block_id < (int) block_id_count); + struct table_block *block = &block_id_table[block_id]; + uint32_t result = 0; + WITH_MUTEX(mutex) + handle_error( + write_command('Q', block->block_base, block->number, 0) ?: + read_all(&result, 4)); + return (size_t) result; } diff --git a/server/sim_hardware.h b/server/sim_hardware.h index 52fdbd21..3a40dfef 100644 --- a/server/sim_hardware.h +++ b/server/sim_hardware.h @@ -17,3 +17,5 @@ void hw_long_table_release(int block_id, void *data); error__t hw_long_table_write( int block_id, const void *data, size_t length, bool streaming_mode, bool last_table); + +size_t hw_long_table_get_queued_words(int block_id); diff --git a/server/table.c b/server/table.c index 4ff3704d..b5f08fb5 100644 --- a/server/table.c +++ b/server/table.c @@ -721,9 +721,10 @@ static error__t table_queued_lines_format( char result[], size_t length) { struct table_state *state = class_data; + size_t queued_words = hw_table_get_queued_words(state->table, number); return format_string( result, length, "%zu", - hw_get_queued_words(state->table, number) / state->field_set.row_words); + queued_words / state->field_set.row_words); } From b8c429274a0909840416e53d24dc1841545e6949 Mon Sep 17 00:00:00 2001 From: Emilio Perez Juarez Date: Wed, 25 Mar 2026 00:35:50 +0000 Subject: [PATCH 2/2] Shut up compiler warning about truncated string --- server/base64.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/base64.c b/server/base64.c index 4000dd37..f87cded9 100644 --- a/server/base64.c +++ b/server/base64.c @@ -6,7 +6,7 @@ #include "base64.h" /* Encoding lookup table. */ -static const char encode[64] = +static const char encode[64] __attribute__((nonstring)) = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; /* Decode lookup table, setup during initialisation. */