From 21dabc920f0841e129f1b6c8b09c9a2f1322504e Mon Sep 17 00:00:00 2001 From: Martin Ling Date: Wed, 22 Dec 2021 02:29:41 +0000 Subject: [PATCH] Replace M0 state offset field with a byte count. Instead of this count wrapping at the buffer size, it now increments continuously. The offset within the buffer is now obtained from the lower bits of the count. This makes it possible to keep track of the total number of bytes transferred by the M0 core. The count will wrap at 2^32 bytes, which at 20Msps will occur every 107 seconds. --- firmware/hackrf_usb/m0_state.h | 2 +- firmware/hackrf_usb/sgpio_m0.s | 26 +++++++++++------------ firmware/hackrf_usb/usb_api_sweep.c | 5 +++-- firmware/hackrf_usb/usb_api_transceiver.c | 12 ++++++----- host/hackrf-tools/src/hackrf_debug.c | 2 +- host/libhackrf/src/hackrf.h | 4 ++-- 6 files changed, 27 insertions(+), 24 deletions(-) diff --git a/firmware/hackrf_usb/m0_state.h b/firmware/hackrf_usb/m0_state.h index 30950560..f3b4f90c 100644 --- a/firmware/hackrf_usb/m0_state.h +++ b/firmware/hackrf_usb/m0_state.h @@ -26,7 +26,7 @@ #include struct m0_state { - uint32_t offset; + uint32_t m0_count; uint32_t tx; }; diff --git a/firmware/hackrf_usb/sgpio_m0.s b/firmware/hackrf_usb/sgpio_m0.s index 0d1ab215..d521c6de 100644 --- a/firmware/hackrf_usb/sgpio_m0.s +++ b/firmware/hackrf_usb/sgpio_m0.s @@ -66,8 +66,8 @@ shadow registers. There are two key code paths, with the following worst-case timings: -RX: 140 cycles -TX: 125 cycles +RX: 141 cycles +TX: 126 cycles Design ====== @@ -105,7 +105,7 @@ registers and fixed memory addresses. .equ STATE_BASE, 0x20007000 // Offsets into the state structure. -.equ OFFSET, 0x00 +.equ M0_COUNT, 0x00 .equ TX, 0x04 // Our slice chain is set up as follows (ascending data age; arrows are reversed for flow): @@ -128,7 +128,8 @@ buf_base .req r12 buf_mask .req r11 sgpio_data .req r7 sgpio_int .req r6 -buf_ptr .req r5 +count .req r5 +buf_ptr .req r4 // Entry point. At this point, the libopencm3 startup code has set things up as // normal; .data and .bss are initialised, the stack is set up, etc. However, @@ -151,7 +152,7 @@ main: // Initialise state. zero .req r0 mov zero, #0 // zero = 0 // 1 - str zero, [state, #OFFSET] // state.offset = zero // 2 + str zero, [state, #M0_COUNT] // state.m0_count = zero // 2 str zero, [state, #TX] // state.tx = zero // 2 loop: @@ -186,7 +187,9 @@ loop: str int_status, [sgpio_int, #INT_CLEAR] // SGPIO_CLR_STATUS_1 = int_status // 8 // ... and grab the address of the buffer segment we want to write to / read from. - ldr buf_ptr, [state, #OFFSET] // buf_ptr = state.offset // 2 + ldr count, [state, #M0_COUNT] // count = state.m0_count // 2 + mov buf_ptr, buf_mask // buf_ptr = buf_mask // 1 + and buf_ptr, count // buf_ptr &= count // 1 add buf_ptr, buf_base // buf_ptr += buf_base // 1 tx .req r0 @@ -229,14 +232,11 @@ direction_rx: stm buf_ptr!, {r0-r3} // buf_ptr[0:16] = r0-r3; buf_ptr += 16 // 5 done: - offset .req r0 + // Finally, update the count... + add count, #32 // count += 32 // 1 - // Finally, update the buffer location... - mov offset, buf_mask // offset = buf_mask // 1 - and offset, buf_ptr // offset &= buf_ptr // 1 - - // ... and store the new position. - str offset, [state, #OFFSET] // state.offset = offset // 2 + // ... and store the new count. + str count, [state, #M0_COUNT] // state.m0_count = count // 2 b loop // goto loop // 3 diff --git a/firmware/hackrf_usb/usb_api_sweep.c b/firmware/hackrf_usb/usb_api_sweep.c index f0ccad77..5fef5224 100644 --- a/firmware/hackrf_usb/usb_api_sweep.c +++ b/firmware/hackrf_usb/usb_api_sweep.c @@ -101,8 +101,9 @@ void sweep_mode(uint32_t seq) { baseband_streaming_enable(&sgpio_config); while (transceiver_request.seq == seq) { + uint32_t m0_offset = m0_state.m0_count & USB_BULK_BUFFER_MASK; // Set up IN transfer of buffer 0. - if ( m0_state.offset >= 16384 && phase == 1) { + if ( m0_offset >= 16384 && phase == 1) { transfer = true; buffer = &usb_bulk_buffer[0x0000]; phase = 0; @@ -110,7 +111,7 @@ void sweep_mode(uint32_t seq) { } // Set up IN transfer of buffer 1. - if ( m0_state.offset < 16384 && phase == 0) { + if ( m0_offset < 16384 && phase == 0) { transfer = true; buffer = &usb_bulk_buffer[0x4000]; phase = 1; diff --git a/firmware/hackrf_usb/usb_api_transceiver.c b/firmware/hackrf_usb/usb_api_transceiver.c index f795808a..4ee9b7ce 100644 --- a/firmware/hackrf_usb/usb_api_transceiver.c +++ b/firmware/hackrf_usb/usb_api_transceiver.c @@ -296,7 +296,7 @@ void transceiver_startup(const transceiver_mode_t mode) { activate_best_clock_source(); hw_sync_enable(_hw_sync_mode); - m0_state.offset = 0; + m0_state.m0_count = 0; } usb_request_status_t usb_vendor_request_set_transceiver_mode( @@ -342,8 +342,9 @@ void rx_mode(uint32_t seq) { baseband_streaming_enable(&sgpio_config); while (transceiver_request.seq == seq) { + uint32_t m0_offset = m0_state.m0_count & USB_BULK_BUFFER_MASK; // Set up IN transfer of buffer 0. - if (16384 <= m0_state.offset && 1 == phase) { + if (16384 <= m0_offset && 1 == phase) { usb_transfer_schedule_block( &usb_endpoint_bulk_in, &usb_bulk_buffer[0x0000], @@ -353,7 +354,7 @@ void rx_mode(uint32_t seq) { phase = 0; } // Set up IN transfer of buffer 1. - if (16384 > m0_state.offset && 0 == phase) { + if (16384 > m0_offset && 0 == phase) { usb_transfer_schedule_block( &usb_endpoint_bulk_in, &usb_bulk_buffer[0x4000], @@ -384,8 +385,9 @@ void tx_mode(uint32_t seq) { baseband_streaming_enable(&sgpio_config); while (transceiver_request.seq == seq) { + uint32_t m0_offset = m0_state.m0_count & USB_BULK_BUFFER_MASK; // Set up OUT transfer of buffer 0. - if (16384 <= m0_state.offset && 1 == phase) { + if (16384 <= m0_offset && 1 == phase) { usb_transfer_schedule_block( &usb_endpoint_bulk_out, &usb_bulk_buffer[0x0000], @@ -395,7 +397,7 @@ void tx_mode(uint32_t seq) { phase = 0; } // Set up OUT transfer of buffer 1. - if (16384 > m0_state.offset && 0 == phase) { + if (16384 > m0_offset && 0 == phase) { usb_transfer_schedule_block( &usb_endpoint_bulk_out, &usb_bulk_buffer[0x4000], diff --git a/host/hackrf-tools/src/hackrf_debug.c b/host/hackrf-tools/src/hackrf_debug.c index 80863a88..d10cc605 100644 --- a/host/hackrf-tools/src/hackrf_debug.c +++ b/host/hackrf-tools/src/hackrf_debug.c @@ -379,7 +379,7 @@ int write_register(hackrf_device* device, uint8_t part, static void print_state(hackrf_m0_state *state) { printf("M0 state:\n"); - printf("Offset: %u bytes\n", state->offset); + printf("M0 count: %u bytes\n", state->m0_count); printf("TX: %u\n", state->tx); } diff --git a/host/libhackrf/src/hackrf.h b/host/libhackrf/src/hackrf.h index 63795f0e..ba0f0841 100644 --- a/host/libhackrf/src/hackrf.h +++ b/host/libhackrf/src/hackrf.h @@ -157,8 +157,8 @@ typedef struct { /** State of the SGPIO loop running on the M0 core. */ typedef struct { - /** Current offset in the buffer. */ - uint32_t offset; + /** Number of bytes transferred by the M0. */ + uint32_t m0_count; /** TX flag. */ uint32_t tx; } hackrf_m0_state;