Merge pull request #1045 from martinling/usb-isr
Move transceiver mode changes out of USB ISR.
This commit is contained in:
@ -146,7 +146,7 @@ void usb_configuration_changed(
|
|||||||
usb_device_t* const device
|
usb_device_t* const device
|
||||||
) {
|
) {
|
||||||
/* Reset transceiver to idle state until other commands are received */
|
/* Reset transceiver to idle state until other commands are received */
|
||||||
set_transceiver_mode(TRANSCEIVER_MODE_OFF);
|
request_transceiver_mode(TRANSCEIVER_MODE_OFF);
|
||||||
if( device->configuration->number == 1 ) {
|
if( device->configuration->number == 1 ) {
|
||||||
// transceiver configuration
|
// transceiver configuration
|
||||||
led_on(LED1);
|
led_on(LED1);
|
||||||
@ -263,29 +263,30 @@ int main(void) {
|
|||||||
operacake_init(operacake_allow_gpio);
|
operacake_init(operacake_allow_gpio);
|
||||||
|
|
||||||
while(true) {
|
while(true) {
|
||||||
|
transceiver_request_t request;
|
||||||
|
|
||||||
// Briefly disable USB interrupt so that we can
|
// Briefly disable USB interrupt so that we can
|
||||||
// atomically retrieve both the transceiver mode
|
// atomically retrieve both the transceiver mode
|
||||||
// and the mode change sequence number. They are
|
// and the mode change sequence number. They are
|
||||||
// changed together by the set_transceiver_mode
|
// changed together by request_transceiver_mode()
|
||||||
// vendor request handler.
|
// called from the USB ISR.
|
||||||
|
|
||||||
nvic_disable_irq(NVIC_USB0_IRQ);
|
nvic_disable_irq(NVIC_USB0_IRQ);
|
||||||
|
request = transceiver_request;
|
||||||
transceiver_mode_t mode = transceiver_mode();
|
|
||||||
uint32_t seq = transceiver_mode_seq();
|
|
||||||
|
|
||||||
nvic_enable_irq(NVIC_USB0_IRQ);
|
nvic_enable_irq(NVIC_USB0_IRQ);
|
||||||
|
|
||||||
switch (mode) {
|
switch (request.mode) {
|
||||||
|
case TRANSCEIVER_MODE_OFF:
|
||||||
|
off_mode(request.seq);
|
||||||
|
break;
|
||||||
case TRANSCEIVER_MODE_RX:
|
case TRANSCEIVER_MODE_RX:
|
||||||
rx_mode(seq);
|
rx_mode(request.seq);
|
||||||
break;
|
break;
|
||||||
case TRANSCEIVER_MODE_TX:
|
case TRANSCEIVER_MODE_TX:
|
||||||
tx_mode(seq);
|
tx_mode(request.seq);
|
||||||
break;
|
break;
|
||||||
case TRANSCEIVER_MODE_RX_SWEEP:
|
case TRANSCEIVER_MODE_RX_SWEEP:
|
||||||
sweep_mode(seq);
|
sweep_mode(request.seq);
|
||||||
break;
|
break;
|
||||||
case TRANSCEIVER_MODE_CPLD_UPDATE:
|
case TRANSCEIVER_MODE_CPLD_UPDATE:
|
||||||
cpld_update();
|
cpld_update();
|
||||||
|
@ -47,7 +47,7 @@ static uint32_t step_width = 0;
|
|||||||
static uint32_t offset = 0;
|
static uint32_t offset = 0;
|
||||||
static enum sweep_style style = LINEAR;
|
static enum sweep_style style = LINEAR;
|
||||||
|
|
||||||
/* Do this before starting sweep mode with set_transceiver_mode(). */
|
/* Do this before starting sweep mode with request_transceiver_mode(). */
|
||||||
usb_request_status_t usb_vendor_request_init_sweep(
|
usb_request_status_t usb_vendor_request_init_sweep(
|
||||||
usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage)
|
usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage)
|
||||||
{
|
{
|
||||||
@ -96,9 +96,11 @@ void sweep_mode(uint32_t seq) {
|
|||||||
uint8_t *buffer;
|
uint8_t *buffer;
|
||||||
bool transfer = false;
|
bool transfer = false;
|
||||||
|
|
||||||
|
transceiver_startup(TRANSCEIVER_MODE_RX_SWEEP);
|
||||||
|
|
||||||
baseband_streaming_enable(&sgpio_config);
|
baseband_streaming_enable(&sgpio_config);
|
||||||
|
|
||||||
while (transceiver_mode_seq() == seq) {
|
while (transceiver_request.seq == seq) {
|
||||||
// Set up IN transfer of buffer 0.
|
// Set up IN transfer of buffer 0.
|
||||||
if ( m0_state.offset >= 16384 && phase == 1) {
|
if ( m0_state.offset >= 16384 && phase == 1) {
|
||||||
transfer = true;
|
transfer = true;
|
||||||
@ -165,4 +167,6 @@ void sweep_mode(uint32_t seq) {
|
|||||||
blocks_queued = 0;
|
blocks_queued = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
transceiver_shutdown();
|
||||||
}
|
}
|
||||||
|
@ -237,34 +237,46 @@ 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;
|
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) {
|
void set_hw_sync_mode(const hw_sync_mode_t new_hw_sync_mode) {
|
||||||
_hw_sync_mode = new_hw_sync_mode;
|
_hw_sync_mode = new_hw_sync_mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
transceiver_mode_t transceiver_mode(void) {
|
volatile transceiver_request_t transceiver_request = {
|
||||||
return _transceiver_mode;
|
.mode = TRANSCEIVER_MODE_OFF,
|
||||||
|
.seq = 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Must be called from an atomic context (normally USB ISR)
|
||||||
|
void request_transceiver_mode(transceiver_mode_t mode)
|
||||||
|
{
|
||||||
|
usb_endpoint_flush(&usb_endpoint_bulk_in);
|
||||||
|
usb_endpoint_flush(&usb_endpoint_bulk_out);
|
||||||
|
|
||||||
|
transceiver_request.mode = mode;
|
||||||
|
transceiver_request.seq++;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t transceiver_mode_seq(void) {
|
void transceiver_shutdown(void)
|
||||||
return _transceiver_mode_seq;
|
{
|
||||||
}
|
|
||||||
|
|
||||||
void set_transceiver_mode(const transceiver_mode_t new_transceiver_mode) {
|
|
||||||
baseband_streaming_disable(&sgpio_config);
|
baseband_streaming_disable(&sgpio_config);
|
||||||
operacake_sctimer_reset_state();
|
operacake_sctimer_reset_state();
|
||||||
|
|
||||||
usb_endpoint_flush(&usb_endpoint_bulk_in);
|
usb_endpoint_flush(&usb_endpoint_bulk_in);
|
||||||
usb_endpoint_flush(&usb_endpoint_bulk_out);
|
usb_endpoint_flush(&usb_endpoint_bulk_out);
|
||||||
|
|
||||||
_transceiver_mode = new_transceiver_mode;
|
led_off(LED2);
|
||||||
|
led_off(LED3);
|
||||||
|
rf_path_set_direction(&rf_path, RF_PATH_DIRECTION_OFF);
|
||||||
|
m0_state.tx = false;
|
||||||
|
}
|
||||||
|
|
||||||
hackrf_ui()->set_transceiver_mode(_transceiver_mode);
|
void transceiver_startup(const transceiver_mode_t mode) {
|
||||||
|
|
||||||
switch (_transceiver_mode) {
|
hackrf_ui()->set_transceiver_mode(mode);
|
||||||
|
|
||||||
|
switch (mode) {
|
||||||
case TRANSCEIVER_MODE_RX_SWEEP:
|
case TRANSCEIVER_MODE_RX_SWEEP:
|
||||||
case TRANSCEIVER_MODE_RX:
|
case TRANSCEIVER_MODE_RX:
|
||||||
led_off(LED3);
|
led_off(LED3);
|
||||||
@ -278,24 +290,13 @@ void set_transceiver_mode(const transceiver_mode_t new_transceiver_mode) {
|
|||||||
rf_path_set_direction(&rf_path, RF_PATH_DIRECTION_TX);
|
rf_path_set_direction(&rf_path, RF_PATH_DIRECTION_TX);
|
||||||
m0_state.tx = true;
|
m0_state.tx = true;
|
||||||
break;
|
break;
|
||||||
case TRANSCEIVER_MODE_OFF:
|
|
||||||
default:
|
default:
|
||||||
led_off(LED2);
|
break;
|
||||||
led_off(LED3);
|
|
||||||
rf_path_set_direction(&rf_path, RF_PATH_DIRECTION_OFF);
|
|
||||||
m0_state.tx = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
activate_best_clock_source();
|
||||||
if( _transceiver_mode != TRANSCEIVER_MODE_OFF ) {
|
hw_sync_enable(_hw_sync_mode);
|
||||||
activate_best_clock_source();
|
m0_state.offset = 0;
|
||||||
|
|
||||||
hw_sync_enable(_hw_sync_mode);
|
|
||||||
|
|
||||||
m0_state.offset = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
_transceiver_mode_seq++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
usb_request_status_t usb_vendor_request_set_transceiver_mode(
|
usb_request_status_t usb_vendor_request_set_transceiver_mode(
|
||||||
@ -309,7 +310,7 @@ usb_request_status_t usb_vendor_request_set_transceiver_mode(
|
|||||||
case TRANSCEIVER_MODE_TX:
|
case TRANSCEIVER_MODE_TX:
|
||||||
case TRANSCEIVER_MODE_RX_SWEEP:
|
case TRANSCEIVER_MODE_RX_SWEEP:
|
||||||
case TRANSCEIVER_MODE_CPLD_UPDATE:
|
case TRANSCEIVER_MODE_CPLD_UPDATE:
|
||||||
set_transceiver_mode(endpoint->setup.value);
|
request_transceiver_mode(endpoint->setup.value);
|
||||||
usb_transfer_schedule_ack(endpoint->in);
|
usb_transfer_schedule_ack(endpoint->in);
|
||||||
return USB_REQUEST_STATUS_OK;
|
return USB_REQUEST_STATUS_OK;
|
||||||
default:
|
default:
|
||||||
@ -336,9 +337,11 @@ usb_request_status_t usb_vendor_request_set_hw_sync_mode(
|
|||||||
void rx_mode(uint32_t seq) {
|
void rx_mode(uint32_t seq) {
|
||||||
unsigned int phase = 1;
|
unsigned int phase = 1;
|
||||||
|
|
||||||
|
transceiver_startup(TRANSCEIVER_MODE_RX);
|
||||||
|
|
||||||
baseband_streaming_enable(&sgpio_config);
|
baseband_streaming_enable(&sgpio_config);
|
||||||
|
|
||||||
while (_transceiver_mode_seq == seq) {
|
while (transceiver_request.seq == seq) {
|
||||||
// Set up IN transfer of buffer 0.
|
// Set up IN transfer of buffer 0.
|
||||||
if (16384 <= m0_state.offset && 1 == phase) {
|
if (16384 <= m0_state.offset && 1 == phase) {
|
||||||
usb_transfer_schedule_block(
|
usb_transfer_schedule_block(
|
||||||
@ -360,11 +363,15 @@ void rx_mode(uint32_t seq) {
|
|||||||
phase = 1;
|
phase = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
transceiver_shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
void tx_mode(uint32_t seq) {
|
void tx_mode(uint32_t seq) {
|
||||||
unsigned int phase = 1;
|
unsigned int phase = 1;
|
||||||
|
|
||||||
|
transceiver_startup(TRANSCEIVER_MODE_TX);
|
||||||
|
|
||||||
memset(&usb_bulk_buffer[0x0000], 0, 0x8000);
|
memset(&usb_bulk_buffer[0x0000], 0, 0x8000);
|
||||||
// Set up OUT transfer of buffer 1.
|
// Set up OUT transfer of buffer 1.
|
||||||
usb_transfer_schedule_block(
|
usb_transfer_schedule_block(
|
||||||
@ -376,7 +383,7 @@ void tx_mode(uint32_t seq) {
|
|||||||
// Start transmitting zeros while the host fills buffer 1.
|
// Start transmitting zeros while the host fills buffer 1.
|
||||||
baseband_streaming_enable(&sgpio_config);
|
baseband_streaming_enable(&sgpio_config);
|
||||||
|
|
||||||
while (_transceiver_mode_seq == seq) {
|
while (transceiver_request.seq == seq) {
|
||||||
// Set up OUT transfer of buffer 0.
|
// Set up OUT transfer of buffer 0.
|
||||||
if (16384 <= m0_state.offset && 1 == phase) {
|
if (16384 <= m0_state.offset && 1 == phase) {
|
||||||
usb_transfer_schedule_block(
|
usb_transfer_schedule_block(
|
||||||
@ -398,4 +405,13 @@ void tx_mode(uint32_t seq) {
|
|||||||
phase = 1;
|
phase = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
transceiver_shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
void off_mode(uint32_t seq)
|
||||||
|
{
|
||||||
|
hackrf_ui()->set_transceiver_mode(TRANSCEIVER_MODE_OFF);
|
||||||
|
|
||||||
|
while (transceiver_request.seq == seq);
|
||||||
}
|
}
|
||||||
|
@ -27,6 +27,13 @@
|
|||||||
#include <usb_type.h>
|
#include <usb_type.h>
|
||||||
#include <usb_request.h>
|
#include <usb_request.h>
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
transceiver_mode_t mode;
|
||||||
|
uint32_t seq;
|
||||||
|
} transceiver_request_t;
|
||||||
|
|
||||||
|
extern volatile transceiver_request_t transceiver_request;
|
||||||
|
|
||||||
void set_hw_sync_mode(const hw_sync_mode_t new_hw_sync_mode);
|
void set_hw_sync_mode(const hw_sync_mode_t new_hw_sync_mode);
|
||||||
usb_request_status_t usb_vendor_request_set_transceiver_mode(
|
usb_request_status_t usb_vendor_request_set_transceiver_mode(
|
||||||
usb_endpoint_t* const endpoint,
|
usb_endpoint_t* const endpoint,
|
||||||
@ -56,11 +63,12 @@ usb_request_status_t usb_vendor_request_set_freq_explicit(
|
|||||||
usb_request_status_t usb_vendor_request_set_hw_sync_mode(
|
usb_request_status_t usb_vendor_request_set_hw_sync_mode(
|
||||||
usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage);
|
usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage);
|
||||||
|
|
||||||
transceiver_mode_t transceiver_mode(void);
|
void request_transceiver_mode(transceiver_mode_t mode);
|
||||||
uint32_t transceiver_mode_seq(void);
|
void transceiver_startup(transceiver_mode_t mode);
|
||||||
void set_transceiver_mode(const transceiver_mode_t new_transceiver_mode);
|
void transceiver_shutdown(void);
|
||||||
void start_streaming_on_hw_sync();
|
void start_streaming_on_hw_sync();
|
||||||
void rx_mode(uint32_t seq);
|
void rx_mode(uint32_t seq);
|
||||||
void tx_mode(uint32_t seq);
|
void tx_mode(uint32_t seq);
|
||||||
|
void off_mode(uint32_t seq);
|
||||||
|
|
||||||
#endif/*__USB_API_TRANSCEIVER_H__*/
|
#endif/*__USB_API_TRANSCEIVER_H__*/
|
||||||
|
Reference in New Issue
Block a user