diff --git a/firmware/hackrf_usb/hackrf_usb.c b/firmware/hackrf_usb/hackrf_usb.c index b20623145..cf9854896 100644 --- a/firmware/hackrf_usb/hackrf_usb.c +++ b/firmware/hackrf_usb/hackrf_usb.c @@ -263,15 +263,29 @@ int main(void) { operacake_init(operacake_allow_gpio); while(true) { - switch (transceiver_mode()) { + + // Briefly disable USB interrupt so that we can + // atomically retrieve both the transceiver mode + // and the mode change sequence number. They are + // changed together by the set_transceiver_mode + // vendor request handler. + + nvic_disable_irq(NVIC_USB0_IRQ); + + transceiver_mode_t mode = transceiver_mode(); + uint32_t seq = transceiver_mode_seq(); + + nvic_enable_irq(NVIC_USB0_IRQ); + + switch (mode) { case TRANSCEIVER_MODE_RX: - rx_mode(); + rx_mode(seq); break; case TRANSCEIVER_MODE_TX: - tx_mode(); + tx_mode(seq); break; case TRANSCEIVER_MODE_RX_SWEEP: - sweep_mode(); + sweep_mode(seq); break; case TRANSCEIVER_MODE_CPLD_UPDATE: cpld_update(); diff --git a/firmware/hackrf_usb/usb_api_sweep.c b/firmware/hackrf_usb/usb_api_sweep.c index 648a812db..52075cdba 100644 --- a/firmware/hackrf_usb/usb_api_sweep.c +++ b/firmware/hackrf_usb/usb_api_sweep.c @@ -87,7 +87,7 @@ usb_request_status_t usb_vendor_request_init_sweep( return USB_REQUEST_STATUS_OK; } -void sweep_mode(void) { +void sweep_mode(uint32_t seq) { unsigned int blocks_queued = 0; unsigned int phase = 1; bool odd = true; @@ -98,7 +98,7 @@ void sweep_mode(void) { baseband_streaming_enable(&sgpio_config); - while (TRANSCEIVER_MODE_RX_SWEEP == transceiver_mode()) { + while (transceiver_mode_seq() == seq) { // Set up IN transfer of buffer 0. if ( m0_state.offset >= 16384 && phase == 1) { transfer = true; diff --git a/firmware/hackrf_usb/usb_api_sweep.h b/firmware/hackrf_usb/usb_api_sweep.h index 11ba4395e..bdc3ba7c3 100644 --- a/firmware/hackrf_usb/usb_api_sweep.h +++ b/firmware/hackrf_usb/usb_api_sweep.h @@ -34,6 +34,6 @@ enum sweep_style { usb_request_status_t usb_vendor_request_init_sweep( usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage); -void sweep_mode(void); +void sweep_mode(uint32_t seq); #endif /* __USB_API_SWEEP_H__ */ diff --git a/firmware/hackrf_usb/usb_api_transceiver.c b/firmware/hackrf_usb/usb_api_transceiver.c index a580bca79..afbb75c62 100644 --- a/firmware/hackrf_usb/usb_api_transceiver.c +++ b/firmware/hackrf_usb/usb_api_transceiver.c @@ -238,6 +238,7 @@ usb_request_status_t usb_vendor_request_set_freq_explicit( } static volatile transceiver_mode_t _transceiver_mode = TRANSCEIVER_MODE_OFF; +static volatile uint32_t _transceiver_mode_seq = 0; static volatile hw_sync_mode_t _hw_sync_mode = HW_SYNC_MODE_OFF; void set_hw_sync_mode(const hw_sync_mode_t new_hw_sync_mode) { @@ -248,6 +249,10 @@ transceiver_mode_t transceiver_mode(void) { return _transceiver_mode; } +uint32_t transceiver_mode_seq(void) { + return _transceiver_mode_seq; +} + void set_transceiver_mode(const transceiver_mode_t new_transceiver_mode) { baseband_streaming_disable(&sgpio_config); operacake_sctimer_reset_state(); @@ -287,6 +292,8 @@ void set_transceiver_mode(const transceiver_mode_t new_transceiver_mode) { m0_state.offset = 0; } + + _transceiver_mode_seq++; } usb_request_status_t usb_vendor_request_set_transceiver_mode( @@ -324,12 +331,12 @@ usb_request_status_t usb_vendor_request_set_hw_sync_mode( } } -void rx_mode(void) { +void rx_mode(uint32_t seq) { unsigned int phase = 1; baseband_streaming_enable(&sgpio_config); - while (TRANSCEIVER_MODE_RX == _transceiver_mode) { + while (_transceiver_mode_seq == seq) { // Set up IN transfer of buffer 0. if (16384 <= m0_state.offset && 1 == phase) { usb_transfer_schedule_block( @@ -353,7 +360,7 @@ void rx_mode(void) { } } -void tx_mode(void) { +void tx_mode(uint32_t seq) { unsigned int phase = 1; memset(&usb_bulk_buffer[0x0000], 0, 0x8000); @@ -367,7 +374,7 @@ void tx_mode(void) { // Start transmitting zeros while the host fills buffer 1. baseband_streaming_enable(&sgpio_config); - while (TRANSCEIVER_MODE_TX == _transceiver_mode) { + while (_transceiver_mode_seq == seq) { // Set up OUT transfer of buffer 0. if (16384 <= m0_state.offset && 1 == phase) { usb_transfer_schedule_block( diff --git a/firmware/hackrf_usb/usb_api_transceiver.h b/firmware/hackrf_usb/usb_api_transceiver.h index 968bc4ede..0101bfb98 100644 --- a/firmware/hackrf_usb/usb_api_transceiver.h +++ b/firmware/hackrf_usb/usb_api_transceiver.h @@ -57,9 +57,10 @@ usb_request_status_t usb_vendor_request_set_hw_sync_mode( usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage); transceiver_mode_t transceiver_mode(void); +uint32_t transceiver_mode_seq(void); void set_transceiver_mode(const transceiver_mode_t new_transceiver_mode); void start_streaming_on_hw_sync(); -void rx_mode(void); -void tx_mode(void); +void rx_mode(uint32_t seq); +void tx_mode(uint32_t seq); #endif/*__USB_API_TRANSCEIVER_H__*/