diff --git a/firmware/hackrf_usb/Makefile b/firmware/hackrf_usb/Makefile index 3d2b4d53..1b6fe51e 100644 --- a/firmware/hackrf_usb/Makefile +++ b/firmware/hackrf_usb/Makefile @@ -23,6 +23,7 @@ BINARY = hackrf_usb SRC = $(BINARY).c \ + rf_path.c \ usb.c \ usb_request.c \ usb_standard_request.c \ diff --git a/firmware/hackrf_usb/Makefile_rom_to_ram b/firmware/hackrf_usb/Makefile_rom_to_ram index bd71216d..7ab7af69 100644 --- a/firmware/hackrf_usb/Makefile_rom_to_ram +++ b/firmware/hackrf_usb/Makefile_rom_to_ram @@ -23,6 +23,7 @@ BINARY = hackrf_usb_rom_to_ram SRC = hackrf_usb.c \ + rf_path.c \ usb.c \ usb_request.c \ usb_standard_request.c \ diff --git a/firmware/hackrf_usb/hackrf_usb.c b/firmware/hackrf_usb/hackrf_usb.c index 737bc013..1fccaaf9 100644 --- a/firmware/hackrf_usb/hackrf_usb.c +++ b/firmware/hackrf_usb/hackrf_usb.c @@ -45,6 +45,8 @@ #include "usb_descriptor.h" #include "usb_standard_request.h" +#include "rf_path.h" + static volatile transceiver_mode_t transceiver_mode = TRANSCEIVER_MODE_OFF; void sgpio_isr_rx(); @@ -79,119 +81,6 @@ typedef struct { set_sample_r_params_t set_sample_r_params; -#ifdef JAWBREAKER -/* - * RF switches on Jawbreaker are controlled by General Purpose Outputs (GPO) on - * the RFFC5072. - */ -#define SWITCHCTRL_NO_TX_AMP_PWR (1 << 0) /* GPO1 turn off TX amp power */ -#define SWITCHCTRL_AMP_BYPASS (1 << 1) /* GPO2 bypass amp section */ -#define SWITCHCTRL_TX (1 << 2) /* GPO3 1 for TX mode, 0 for RX mode */ -#define SWITCHCTRL_MIX_BYPASS (1 << 3) /* GPO4 bypass RFFC5072 mixer section */ -#define SWITCHCTRL_HP (1 << 4) /* GPO5 1 for high-pass, 0 for low-pass */ -#define SWITCHCTRL_NO_RX_AMP_PWR (1 << 5) /* GPO6 turn off RX amp power */ - -/* - GPO6 GPO5 GPO4 GPO3 GPO2 GPO1 -!RXAMP HP MIXBP TX AMPBP !TXAMP Mix mode Amp mode - 1 X 1 1 1 1 TX bypass Bypass - 1 X 1 1 0 0 TX bypass TX amplified - 1 1 0 1 1 1 TX high Bypass - 1 1 0 1 0 0 TX high TX amplified - 1 0 0 1 1 1 TX low Bypass - 1 0 0 1 0 0 TX low TX amplified - 1 X 1 0 1 1 RX bypass Bypass - 0 X 1 0 0 1 RX bypass RX amplified - 1 1 0 0 1 1 RX high Bypass - 0 1 0 0 0 1 RX high RX amplified - 1 0 0 0 1 1 RX low Bypass - 0 0 0 0 0 1 RX low RX amplified -*/ - -/* - * Safe (initial) switch settings turn off both amplifiers and enable both amp - * bypass and mixer bypass. - */ -#define SWITCHCTRL_SAFE (SWITCHCTRL_NO_TX_AMP_PWR | SWITCHCTRL_AMP_BYPASS | SWITCHCTRL_TX | SWITCHCTRL_MIX_BYPASS | SWITCHCTRL_HP | SWITCHCTRL_NO_RX_AMP_PWR) -#endif - -uint8_t switchctrl = SWITCHCTRL_SAFE; - -typedef enum { - RF_PATH_DIRECTION_RX, - RF_PATH_DIRECTION_TX, -} rf_path_direction_t; - -void rf_path_set_direction(const rf_path_direction_t direction) { - /* Turn off TX and RX amplifiers, then enable based on direction and bypass state. */ - switchctrl |= SWITCHCTRL_NO_TX_AMP_PWR | SWITCHCTRL_NO_RX_AMP_PWR; - if( direction == RF_PATH_DIRECTION_TX ) { - switchctrl |= SWITCHCTRL_TX; - if( (switchctrl & SWITCHCTRL_AMP_BYPASS) == 0 ) { - /* TX amplifier is in path, be sure to enable TX amplifier. */ - switchctrl &= ~SWITCHCTRL_NO_TX_AMP_PWR; - } - rffc5071_tx(); - } else { - switchctrl &= ~SWITCHCTRL_TX; - if( (switchctrl & SWITCHCTRL_AMP_BYPASS) == 0 ) { - /* RX amplifier is in path, be sure to enable RX amplifier. */ - switchctrl &= ~SWITCHCTRL_NO_RX_AMP_PWR; - } - rffc5071_rx(); - } - - rffc5071_set_gpo(switchctrl); -} - -typedef enum { - RF_PATH_FILTER_BYPASS, - RF_PATH_FILTER_LOW_PASS, - RF_PATH_FILTER_HIGH_PASS, -} rf_path_filter_t; - -void rf_path_set_filter(const rf_path_filter_t filter) { - switch(filter) { - default: - case RF_PATH_FILTER_BYPASS: - switchctrl |= SWITCHCTRL_MIX_BYPASS; - rffc5071_disable(); - break; - - case RF_PATH_FILTER_LOW_PASS: - switchctrl &= ~(SWITCHCTRL_HP | SWITCHCTRL_MIX_BYPASS); - rffc5071_enable(); - break; - - case RF_PATH_FILTER_HIGH_PASS: - switchctrl &= ~SWITCHCTRL_MIX_BYPASS; - switchctrl |= SWITCHCTRL_HP; - rffc5071_enable(); - break; - } - - rffc5071_set_gpo(switchctrl); -} - -void rf_path_set_lna(const uint_fast8_t enable) { - if( enable ) { - if( switchctrl & SWITCHCTRL_TX ) { - /* AMP_BYPASS=0, NO_RX_AMP_PWR=1, NO_TX_AMP_PWR=0 */ - switchctrl |= SWITCHCTRL_NO_RX_AMP_PWR; - switchctrl &= ~(SWITCHCTRL_AMP_BYPASS | SWITCHCTRL_NO_TX_AMP_PWR); - } else { - /* AMP_BYPASS=0, NO_RX_AMP_PWR=0, NO_TX_AMP_PWR=1 */ - switchctrl |= SWITCHCTRL_NO_TX_AMP_PWR; - switchctrl &= ~(SWITCHCTRL_AMP_BYPASS | SWITCHCTRL_NO_RX_AMP_PWR); - } - } else { - /* AMP_BYPASS=1, NO_RX_AMP_PWR=1, NO_TX_AMP_PWR=1 */ - switchctrl |= SWITCHCTRL_AMP_BYPASS | SWITCHCTRL_NO_TX_AMP_PWR | SWITCHCTRL_NO_RX_AMP_PWR; - } - - rffc5071_set_gpo(switchctrl); -} - #define FREQ_ONE_MHZ (1000*1000) #define MIN_LP_FREQ_MHZ (5) @@ -1107,10 +996,8 @@ int main(void) { max2837_set_frequency(ifreq); rffc5071_setup(); -#ifdef JAWBREAKER - /* initial safe switch control settings */ - rffc5071_set_gpo(switchctrl); -#endif + + rf_path_init(); while(true) { // Wait until buffer 0 is transmitted/received. diff --git a/firmware/hackrf_usb/rf_path.c b/firmware/hackrf_usb/rf_path.c new file mode 100644 index 00000000..e511bf41 --- /dev/null +++ b/firmware/hackrf_usb/rf_path.c @@ -0,0 +1,109 @@ +#include "rf_path.h" + +#include + +#ifdef JAWBREAKER +/* + * RF switches on Jawbreaker are controlled by General Purpose Outputs (GPO) on + * the RFFC5072. + */ +#define SWITCHCTRL_NO_TX_AMP_PWR (1 << 0) /* GPO1 turn off TX amp power */ +#define SWITCHCTRL_AMP_BYPASS (1 << 1) /* GPO2 bypass amp section */ +#define SWITCHCTRL_TX (1 << 2) /* GPO3 1 for TX mode, 0 for RX mode */ +#define SWITCHCTRL_MIX_BYPASS (1 << 3) /* GPO4 bypass RFFC5072 mixer section */ +#define SWITCHCTRL_HP (1 << 4) /* GPO5 1 for high-pass, 0 for low-pass */ +#define SWITCHCTRL_NO_RX_AMP_PWR (1 << 5) /* GPO6 turn off RX amp power */ + +/* + GPO6 GPO5 GPO4 GPO3 GPO2 GPO1 +!RXAMP HP MIXBP TX AMPBP !TXAMP Mix mode Amp mode + 1 X 1 1 1 1 TX bypass Bypass + 1 X 1 1 0 0 TX bypass TX amplified + 1 1 0 1 1 1 TX high Bypass + 1 1 0 1 0 0 TX high TX amplified + 1 0 0 1 1 1 TX low Bypass + 1 0 0 1 0 0 TX low TX amplified + 1 X 1 0 1 1 RX bypass Bypass + 0 X 1 0 0 1 RX bypass RX amplified + 1 1 0 0 1 1 RX high Bypass + 0 1 0 0 0 1 RX high RX amplified + 1 0 0 0 1 1 RX low Bypass + 0 0 0 0 0 1 RX low RX amplified +*/ + +/* + * Safe (initial) switch settings turn off both amplifiers and enable both amp + * bypass and mixer bypass. + */ +#define SWITCHCTRL_SAFE (SWITCHCTRL_NO_TX_AMP_PWR | SWITCHCTRL_AMP_BYPASS | SWITCHCTRL_TX | SWITCHCTRL_MIX_BYPASS | SWITCHCTRL_HP | SWITCHCTRL_NO_RX_AMP_PWR) +#endif + +uint8_t switchctrl = SWITCHCTRL_SAFE; + +void rf_path_init(void) { + rffc5071_set_gpo(switchctrl); +} + +void rf_path_set_direction(const rf_path_direction_t direction) { + /* Turn off TX and RX amplifiers, then enable based on direction and bypass state. */ + switchctrl |= SWITCHCTRL_NO_TX_AMP_PWR | SWITCHCTRL_NO_RX_AMP_PWR; + if( direction == RF_PATH_DIRECTION_TX ) { + switchctrl |= SWITCHCTRL_TX; + if( (switchctrl & SWITCHCTRL_AMP_BYPASS) == 0 ) { + /* TX amplifier is in path, be sure to enable TX amplifier. */ + switchctrl &= ~SWITCHCTRL_NO_TX_AMP_PWR; + } + rffc5071_tx(); + } else { + switchctrl &= ~SWITCHCTRL_TX; + if( (switchctrl & SWITCHCTRL_AMP_BYPASS) == 0 ) { + /* RX amplifier is in path, be sure to enable RX amplifier. */ + switchctrl &= ~SWITCHCTRL_NO_RX_AMP_PWR; + } + rffc5071_rx(); + } + + rffc5071_set_gpo(switchctrl); +} + +void rf_path_set_filter(const rf_path_filter_t filter) { + switch(filter) { + default: + case RF_PATH_FILTER_BYPASS: + switchctrl |= SWITCHCTRL_MIX_BYPASS; + rffc5071_disable(); + break; + + case RF_PATH_FILTER_LOW_PASS: + switchctrl &= ~(SWITCHCTRL_HP | SWITCHCTRL_MIX_BYPASS); + rffc5071_enable(); + break; + + case RF_PATH_FILTER_HIGH_PASS: + switchctrl &= ~SWITCHCTRL_MIX_BYPASS; + switchctrl |= SWITCHCTRL_HP; + rffc5071_enable(); + break; + } + + rffc5071_set_gpo(switchctrl); +} + +void rf_path_set_lna(const uint_fast8_t enable) { + if( enable ) { + if( switchctrl & SWITCHCTRL_TX ) { + /* AMP_BYPASS=0, NO_RX_AMP_PWR=1, NO_TX_AMP_PWR=0 */ + switchctrl |= SWITCHCTRL_NO_RX_AMP_PWR; + switchctrl &= ~(SWITCHCTRL_AMP_BYPASS | SWITCHCTRL_NO_TX_AMP_PWR); + } else { + /* AMP_BYPASS=0, NO_RX_AMP_PWR=0, NO_TX_AMP_PWR=1 */ + switchctrl |= SWITCHCTRL_NO_TX_AMP_PWR; + switchctrl &= ~(SWITCHCTRL_AMP_BYPASS | SWITCHCTRL_NO_RX_AMP_PWR); + } + } else { + /* AMP_BYPASS=1, NO_RX_AMP_PWR=1, NO_TX_AMP_PWR=1 */ + switchctrl |= SWITCHCTRL_AMP_BYPASS | SWITCHCTRL_NO_TX_AMP_PWR | SWITCHCTRL_NO_RX_AMP_PWR; + } + + rffc5071_set_gpo(switchctrl); +} diff --git a/firmware/hackrf_usb/rf_path.h b/firmware/hackrf_usb/rf_path.h new file mode 100644 index 00000000..fea572f7 --- /dev/null +++ b/firmware/hackrf_usb/rf_path.h @@ -0,0 +1,25 @@ +#ifndef __RFPATH_H__ +#define __RFPATH_H__ + +#include + +void rf_path_init(void); + +typedef enum { + RF_PATH_DIRECTION_RX, + RF_PATH_DIRECTION_TX, +} rf_path_direction_t; + +void rf_path_set_direction(const rf_path_direction_t direction); + +typedef enum { + RF_PATH_FILTER_BYPASS, + RF_PATH_FILTER_LOW_PASS, + RF_PATH_FILTER_HIGH_PASS, +} rf_path_filter_t; + +void rf_path_set_filter(const rf_path_filter_t filter); + +void rf_path_set_lna(const uint_fast8_t enable); + +#endif/*__RFPATH_H__*/ diff --git a/firmware/hackrf_usb_rom_to_ram/Makefile b/firmware/hackrf_usb_rom_to_ram/Makefile index 0d2ea0e2..ac5fda3f 100644 --- a/firmware/hackrf_usb_rom_to_ram/Makefile +++ b/firmware/hackrf_usb_rom_to_ram/Makefile @@ -25,6 +25,7 @@ BINARY = hackrf_usb_rom_to_ram SRC_DIR = hackrf_usb SRC = hackrf_usb.c \ + rf_path.c \ usb.c \ usb_request.c \ usb_standard_request.c \