diff --git a/firmware/hackrf_usb/m0_state.h b/firmware/hackrf_usb/m0_state.h index f3b4f90c..ee6c7ba4 100644 --- a/firmware/hackrf_usb/m0_state.h +++ b/firmware/hackrf_usb/m0_state.h @@ -27,6 +27,7 @@ struct m0_state { uint32_t m0_count; + uint32_t m4_count; uint32_t tx; }; diff --git a/firmware/hackrf_usb/sgpio_m0.s b/firmware/hackrf_usb/sgpio_m0.s index d521c6de..983e7781 100644 --- a/firmware/hackrf_usb/sgpio_m0.s +++ b/firmware/hackrf_usb/sgpio_m0.s @@ -106,7 +106,8 @@ registers and fixed memory addresses. // Offsets into the state structure. .equ M0_COUNT, 0x00 -.equ TX, 0x04 +.equ M4_COUNT, 0x04 +.equ TX, 0x08 // Our slice chain is set up as follows (ascending data age; arrows are reversed for flow): // L -> F -> K -> C -> J -> E -> I -> A @@ -153,6 +154,7 @@ main: zero .req r0 mov zero, #0 // zero = 0 // 1 str zero, [state, #M0_COUNT] // state.m0_count = zero // 2 + str zero, [state, #M4_COUNT] // state.m4_count = zero // 2 str zero, [state, #TX] // state.tx = zero // 2 loop: diff --git a/firmware/hackrf_usb/usb_api_sweep.c b/firmware/hackrf_usb/usb_api_sweep.c index 5fef5224..78b2d758 100644 --- a/firmware/hackrf_usb/usb_api_sweep.c +++ b/firmware/hackrf_usb/usb_api_sweep.c @@ -87,6 +87,12 @@ usb_request_status_t usb_vendor_request_init_sweep( return USB_REQUEST_STATUS_OK; } +void sweep_bulk_transfer_complete(void *user_data, unsigned int bytes_transferred) +{ + (void) user_data; + m0_state.m4_count += bytes_transferred; +} + void sweep_mode(uint32_t seq) { unsigned int blocks_queued = 0; unsigned int phase = 1; @@ -134,10 +140,21 @@ void sweep_mode(uint32_t seq) { &usb_endpoint_bulk_in, buffer, 0x4000, - NULL, NULL + sweep_bulk_transfer_complete, + NULL ); } transfer = false; + } else { + // Account for having discarded a buffer. + + // Disable USB IRQ whilst doing so, since this requires + // a read-modify-write, and sweep_bulk_transfer_complete() + // might be called from the USB ISR while we are changing + // this count. + nvic_disable_irq(NVIC_USB0_IRQ); + m0_state.m4_count += 0x4000; + nvic_enable_irq(NVIC_USB0_IRQ); } if ((dwell_blocks + THROWAWAY_BUFFERS) <= blocks_queued) { diff --git a/firmware/hackrf_usb/usb_api_transceiver.c b/firmware/hackrf_usb/usb_api_transceiver.c index 4ee9b7ce..945ed445 100644 --- a/firmware/hackrf_usb/usb_api_transceiver.c +++ b/firmware/hackrf_usb/usb_api_transceiver.c @@ -297,6 +297,7 @@ void transceiver_startup(const transceiver_mode_t mode) { activate_best_clock_source(); hw_sync_enable(_hw_sync_mode); m0_state.m0_count = 0; + m0_state.m4_count = 0; } usb_request_status_t usb_vendor_request_set_transceiver_mode( @@ -334,6 +335,12 @@ usb_request_status_t usb_vendor_request_set_hw_sync_mode( } } +void transceiver_bulk_transfer_complete(void *user_data, unsigned int bytes_transferred) +{ + (void) user_data; + m0_state.m4_count += bytes_transferred; +} + void rx_mode(uint32_t seq) { unsigned int phase = 1; @@ -349,7 +356,8 @@ void rx_mode(uint32_t seq) { &usb_endpoint_bulk_in, &usb_bulk_buffer[0x0000], 0x4000, - NULL, NULL + transceiver_bulk_transfer_complete, + NULL ); phase = 0; } @@ -359,7 +367,8 @@ void rx_mode(uint32_t seq) { &usb_endpoint_bulk_in, &usb_bulk_buffer[0x4000], 0x4000, - NULL, NULL + transceiver_bulk_transfer_complete, + NULL ); phase = 1; } @@ -374,12 +383,15 @@ void tx_mode(uint32_t seq) { transceiver_startup(TRANSCEIVER_MODE_TX); memset(&usb_bulk_buffer[0x0000], 0, 0x8000); + // Account for having filled buffer 0. + m0_state.m4_count += 0x4000; // Set up OUT transfer of buffer 1. usb_transfer_schedule_block( &usb_endpoint_bulk_out, &usb_bulk_buffer[0x4000], 0x4000, - NULL, NULL + transceiver_bulk_transfer_complete, + NULL ); // Start transmitting zeros while the host fills buffer 1. baseband_streaming_enable(&sgpio_config); @@ -392,7 +404,8 @@ void tx_mode(uint32_t seq) { &usb_endpoint_bulk_out, &usb_bulk_buffer[0x0000], 0x4000, - NULL, NULL + transceiver_bulk_transfer_complete, + NULL ); phase = 0; } @@ -402,7 +415,8 @@ void tx_mode(uint32_t seq) { &usb_endpoint_bulk_out, &usb_bulk_buffer[0x4000], 0x4000, - NULL, NULL + transceiver_bulk_transfer_complete, + NULL ); phase = 1; } diff --git a/host/hackrf-tools/src/hackrf_debug.c b/host/hackrf-tools/src/hackrf_debug.c index d10cc605..9d8f5475 100644 --- a/host/hackrf-tools/src/hackrf_debug.c +++ b/host/hackrf-tools/src/hackrf_debug.c @@ -380,6 +380,7 @@ int write_register(hackrf_device* device, uint8_t part, static void print_state(hackrf_m0_state *state) { printf("M0 state:\n"); printf("M0 count: %u bytes\n", state->m0_count); + printf("M4 count: %u bytes\n", state->m4_count); printf("TX: %u\n", state->tx); } diff --git a/host/libhackrf/src/hackrf.h b/host/libhackrf/src/hackrf.h index ba0f0841..0039c3f2 100644 --- a/host/libhackrf/src/hackrf.h +++ b/host/libhackrf/src/hackrf.h @@ -159,6 +159,8 @@ typedef struct { typedef struct { /** Number of bytes transferred by the M0. */ uint32_t m0_count; + /** Number of bytes transferred by the M4. */ + uint32_t m4_count; /** TX flag. */ uint32_t tx; } hackrf_m0_state;