diff --git a/firmware/common/hackrf_core.c b/firmware/common/hackrf_core.c index 201fe367..db5029ad 100644 --- a/firmware/common/hackrf_core.c +++ b/firmware/common/hackrf_core.c @@ -37,6 +37,8 @@ max2837_driver_t max2837; +rffc5071_driver_t rffc5072; + void delay(uint32_t duration) { uint32_t i; diff --git a/firmware/common/hackrf_core.h b/firmware/common/hackrf_core.h index 74652cd2..afa3379d 100644 --- a/firmware/common/hackrf_core.h +++ b/firmware/common/hackrf_core.h @@ -33,6 +33,7 @@ extern "C" #include #include "max2837_drv.h" +#include "rffc5071_drv.h" /* hardware identification number */ #define BOARD_ID_JELLYBEAN 0 @@ -352,6 +353,7 @@ typedef enum { void delay(uint32_t duration); extern max2837_driver_t max2837; +extern rffc5071_driver_t rffc5072; void cpu_clock_init(void); void cpu_clock_pll1_low_speed(void); diff --git a/firmware/common/rf_path.c b/firmware/common/rf_path.c index 14353363..071564da 100644 --- a/firmware/common/rf_path.c +++ b/firmware/common/rf_path.c @@ -149,16 +149,16 @@ static void switchctrl_set_hackrf_one(uint8_t ctrl) { gpio_set(PORT_NO_RX_AMP_PWR, PIN_NO_RX_AMP_PWR); if (ctrl & SWITCHCTRL_ANT_PWR) { - rffc5071_set_gpo(0x00); /* turn on antenna power by clearing GPO1 */ + rffc5071_set_gpo(&rffc5072, 0x00); /* turn on antenna power by clearing GPO1 */ } else { - rffc5071_set_gpo(0x01); /* turn off antenna power by setting GPO1 */ + rffc5071_set_gpo(&rffc5072, 0x01); /* turn off antenna power by setting GPO1 */ } } #endif static void switchctrl_set(const uint8_t gpo) { #ifdef JAWBREAKER - rffc5071_set_gpo(gpo); + rffc5071_set_gpo(&rffc5072, gpo); #elif HACKRF_ONE switchctrl_set_hackrf_one(gpo); #else @@ -215,7 +215,7 @@ void rf_path_init(void) { max2837_setup(&max2837); max2837_start(&max2837); - rffc5071_setup(); + rffc5071_setup(&rffc5072); switchctrl_set(switchctrl); } @@ -229,11 +229,11 @@ void rf_path_set_direction(const rf_path_direction_t direction) { /* TX amplifier is in path, be sure to enable TX amplifier. */ switchctrl &= ~SWITCHCTRL_NO_TX_AMP_PWR; } - rffc5071_tx(); + rffc5071_tx(&rffc5072); if( switchctrl & SWITCHCTRL_MIX_BYPASS ) { - rffc5071_disable(); + rffc5071_disable(&rffc5072); } else { - rffc5071_enable(); + rffc5071_enable(&rffc5072); } ssp1_set_mode_max5864(); max5864_tx(); @@ -248,11 +248,11 @@ void rf_path_set_direction(const rf_path_direction_t direction) { /* RX amplifier is in path, be sure to enable RX amplifier. */ switchctrl &= ~SWITCHCTRL_NO_RX_AMP_PWR; } - rffc5071_rx(); + rffc5071_rx(&rffc5072); if( switchctrl & SWITCHCTRL_MIX_BYPASS ) { - rffc5071_disable(); + rffc5071_disable(&rffc5072); } else { - rffc5071_enable(); + rffc5071_enable(&rffc5072); } ssp1_set_mode_max5864(); max5864_rx(); @@ -268,7 +268,7 @@ void rf_path_set_direction(const rf_path_direction_t direction) { #endif /* Set RF path to receive direction when "off" */ switchctrl &= ~SWITCHCTRL_TX; - rffc5071_disable(); + rffc5071_disable(&rffc5072); ssp1_set_mode_max5864(); max5864_standby(); ssp1_set_mode_max2837(); @@ -285,18 +285,18 @@ void rf_path_set_filter(const rf_path_filter_t filter) { default: case RF_PATH_FILTER_BYPASS: switchctrl |= SWITCHCTRL_MIX_BYPASS; - rffc5071_disable(); + rffc5071_disable(&rffc5072); break; case RF_PATH_FILTER_LOW_PASS: switchctrl &= ~(SWITCHCTRL_HP | SWITCHCTRL_MIX_BYPASS); - rffc5071_enable(); + rffc5071_enable(&rffc5072); break; case RF_PATH_FILTER_HIGH_PASS: switchctrl &= ~SWITCHCTRL_MIX_BYPASS; switchctrl |= SWITCHCTRL_HP; - rffc5071_enable(); + rffc5071_enable(&rffc5072); break; } diff --git a/firmware/common/rffc5071.c b/firmware/common/rffc5071.c index 1384a8c7..6234a318 100644 --- a/firmware/common/rffc5071.c +++ b/firmware/common/rffc5071.c @@ -46,7 +46,7 @@ #endif /* Default register values. */ -static uint16_t rffc5071_regs_default[RFFC5071_NUM_REGS] = { +static const uint16_t rffc5071_regs_default[RFFC5071_NUM_REGS] = { 0xbefa, /* 00 */ 0x4064, /* 01 */ 0x9055, /* 02 */ @@ -79,135 +79,130 @@ static uint16_t rffc5071_regs_default[RFFC5071_NUM_REGS] = { 0x1000, /* 1D */ 0x0005, /* 1E */ }; -uint16_t rffc5071_regs[RFFC5071_NUM_REGS]; - -/* Mark all regsisters dirty so all will be written at init. */ -uint32_t rffc5071_regs_dirty = 0x7fffffff; - /* Set up all registers according to defaults specified in docs. */ -void rffc5071_init(void) +void rffc5071_init(rffc5071_driver_t* const drv) { LOG("# rffc5071_init\n"); - memcpy(rffc5071_regs, rffc5071_regs_default, sizeof(rffc5071_regs)); - rffc5071_regs_dirty = 0x7fffffff; + memcpy(drv->regs, rffc5071_regs_default, sizeof(drv->regs)); + drv->regs_dirty = 0x7fffffff; /* Write default register values to chip. */ - rffc5071_regs_commit(); + rffc5071_regs_commit(drv); } /* * Set up pins for GPIO and SPI control, configure SSP peripheral for SPI, and * set our own default register configuration. */ -void rffc5071_setup(void) +void rffc5071_setup(rffc5071_driver_t* const drv) { - rffc5071_init(); + rffc5071_init(drv); LOG("# rffc5071_setup\n"); - rffc5071_pin_config(); + rffc5071_pin_config(drv); /* initial setup */ /* put zeros in freq contol registers */ - set_RFFC5071_P2N(0); - set_RFFC5071_P2LODIV(0); - set_RFFC5071_P2PRESC(0); - set_RFFC5071_P2VCOSEL(0); + set_RFFC5071_P2N(drv, 0); + set_RFFC5071_P2LODIV(drv, 0); + set_RFFC5071_P2PRESC(drv, 0); + set_RFFC5071_P2VCOSEL(drv, 0); - set_RFFC5071_P2N(0); - set_RFFC5071_P2LODIV(0); - set_RFFC5071_P2PRESC(0); - set_RFFC5071_P2VCOSEL(0); + set_RFFC5071_P2N(drv, 0); + set_RFFC5071_P2LODIV(drv, 0); + set_RFFC5071_P2PRESC(drv, 0); + set_RFFC5071_P2VCOSEL(drv, 0); - set_RFFC5071_P2N(0); - set_RFFC5071_P2LODIV(0); - set_RFFC5071_P2PRESC(0); - set_RFFC5071_P2VCOSEL(0); + set_RFFC5071_P2N(drv, 0); + set_RFFC5071_P2LODIV(drv, 0); + set_RFFC5071_P2PRESC(drv, 0); + set_RFFC5071_P2VCOSEL(drv, 0); /* set ENBL and MODE to be configured via 3-wire interface, * not control pins. */ - set_RFFC5071_SIPIN(1); + set_RFFC5071_SIPIN(drv, 1); /* GPOs are active at all times */ - set_RFFC5071_GATE(1); + set_RFFC5071_GATE(drv, 1); - rffc5071_regs_commit(); + rffc5071_regs_commit(drv); } -uint16_t rffc5071_reg_read(uint8_t r) +uint16_t rffc5071_reg_read(rffc5071_driver_t* const drv, uint8_t r) { /* Readback register is not cached. */ if (r == RFFC5071_READBACK_REG) - return rffc5071_spi_read(r); + return rffc5071_spi_read(drv, r); /* Discard uncommited write when reading. This shouldn't * happen, and probably has not been tested. */ - if ((rffc5071_regs_dirty >> r) & 0x1) { - rffc5071_regs[r] = rffc5071_spi_read(r); + if ((drv->regs_dirty >> r) & 0x1) { + drv->regs[r] = rffc5071_spi_read(drv, r); }; - return rffc5071_regs[r]; + return drv->regs[r]; } -void rffc5071_reg_write(uint8_t r, uint16_t v) +void rffc5071_reg_write(rffc5071_driver_t* const drv, uint8_t r, uint16_t v) { - rffc5071_regs[r] = v; - rffc5071_spi_write(r, v); - RFFC5071_REG_SET_CLEAN(r); + drv->regs[r] = v; + rffc5071_spi_write(drv, r, v); + RFFC5071_REG_SET_CLEAN(drv, r); } -static inline void rffc5071_reg_commit(uint8_t r) +static inline void rffc5071_reg_commit(rffc5071_driver_t* const drv, uint8_t r) { - rffc5071_reg_write(r,rffc5071_regs[r]); + rffc5071_reg_write(drv, r, drv->regs[r]); } -void rffc5071_regs_commit(void) +void rffc5071_regs_commit(rffc5071_driver_t* const drv) { int r; for(r = 0; r < RFFC5071_NUM_REGS; r++) { - if ((rffc5071_regs_dirty >> r) & 0x1) { - rffc5071_reg_commit(r); + if ((drv->regs_dirty >> r) & 0x1) { + rffc5071_reg_commit(drv, r); } } } -void rffc5071_tx(void) { +void rffc5071_tx(rffc5071_driver_t* const drv) { LOG("# rffc5071_tx\n"); - set_RFFC5071_ENBL(0); - set_RFFC5071_FULLD(0); - set_RFFC5071_MODE(1); /* mixer 2 used for both RX and TX */ - rffc5071_regs_commit(); + set_RFFC5071_ENBL(drv, 0); + set_RFFC5071_FULLD(drv, 0); + set_RFFC5071_MODE(drv, 1); /* mixer 2 used for both RX and TX */ + rffc5071_regs_commit(drv); } -void rffc5071_rx(void) { +void rffc5071_rx(rffc5071_driver_t* const drv) { LOG("# rfc5071_rx\n"); - set_RFFC5071_ENBL(0); - set_RFFC5071_FULLD(0); - set_RFFC5071_MODE(1); /* mixer 2 used for both RX and TX */ - rffc5071_regs_commit(); + set_RFFC5071_ENBL(drv, 0); + set_RFFC5071_FULLD(drv, 0); + set_RFFC5071_MODE(drv, 1); /* mixer 2 used for both RX and TX */ + rffc5071_regs_commit(drv); } /* * This function turns on both mixer (full-duplex) on the RFFC5071, but our * current hardware designs do not support full-duplex operation. */ -void rffc5071_rxtx(void) { +void rffc5071_rxtx(rffc5071_driver_t* const drv) { LOG("# rfc5071_rxtx\n"); - set_RFFC5071_ENBL(0); - set_RFFC5071_FULLD(1); /* mixer 1 and mixer 2 (RXTX) */ - rffc5071_regs_commit(); + set_RFFC5071_ENBL(drv, 0); + set_RFFC5071_FULLD(drv, 1); /* mixer 1 and mixer 2 (RXTX) */ + rffc5071_regs_commit(drv); - rffc5071_enable(); + rffc5071_enable(drv); } -void rffc5071_disable(void) { +void rffc5071_disable(rffc5071_driver_t* const drv) { LOG("# rfc5071_disable\n"); - set_RFFC5071_ENBL(0); - rffc5071_regs_commit(); + set_RFFC5071_ENBL(drv, 0); + rffc5071_regs_commit(drv); } -void rffc5071_enable(void) { +void rffc5071_enable(rffc5071_driver_t* const drv) { LOG("# rfc5071_enable\n"); - set_RFFC5071_ENBL(1); - rffc5071_regs_commit(); + set_RFFC5071_ENBL(drv, 1); + rffc5071_regs_commit(drv); } #define LO_MAX 5400 @@ -215,7 +210,7 @@ void rffc5071_enable(void) { #define FREQ_ONE_MHZ (1000*1000) /* configure frequency synthesizer in integer mode (lo in MHz) */ -uint64_t rffc5071_config_synth_int(uint16_t lo) { +uint64_t rffc5071_config_synth_int(rffc5071_driver_t* const drv, uint16_t lo) { uint8_t lodiv; uint16_t fvco; uint8_t fbkdiv; @@ -244,10 +239,10 @@ uint64_t rffc5071_config_synth_int(uint16_t lo) { * and will be unaffected. */ if (fvco > 3200) { fbkdiv = 4; - set_RFFC5071_PLLCPL(3); + set_RFFC5071_PLLCPL(drv, 3); } else { fbkdiv = 2; - set_RFFC5071_PLLCPL(2); + set_RFFC5071_PLLCPL(drv, 2); } uint64_t tmp_n = ((uint64_t)fvco << 29ULL) / (fbkdiv*REF_FREQ) ; @@ -262,59 +257,59 @@ uint64_t rffc5071_config_synth_int(uint16_t lo) { lo, n_lo, lodiv, fvco, fbkdiv, n, tune_freq); /* Path 1 */ - set_RFFC5071_P1LODIV(n_lo); - set_RFFC5071_P1N(n); - set_RFFC5071_P1PRESC(fbkdiv >> 1); - set_RFFC5071_P1NMSB(p1nmsb); - set_RFFC5071_P1NLSB(p1nlsb); + set_RFFC5071_P1LODIV(drv, n_lo); + set_RFFC5071_P1N(drv, n); + set_RFFC5071_P1PRESC(drv, fbkdiv >> 1); + set_RFFC5071_P1NMSB(drv, p1nmsb); + set_RFFC5071_P1NLSB(drv, p1nlsb); /* Path 2 */ - set_RFFC5071_P2LODIV(n_lo); - set_RFFC5071_P2N(n); - set_RFFC5071_P2PRESC(fbkdiv >> 1); - set_RFFC5071_P2NMSB(p1nmsb); - set_RFFC5071_P2NLSB(p1nlsb); + set_RFFC5071_P2LODIV(drv, n_lo); + set_RFFC5071_P2N(drv, n); + set_RFFC5071_P2PRESC(drv, fbkdiv >> 1); + set_RFFC5071_P2NMSB(drv, p1nmsb); + set_RFFC5071_P2NLSB(drv, p1nlsb); - rffc5071_regs_commit(); + rffc5071_regs_commit(drv); return tune_freq_hz; } /* !!!!!!!!!!! hz is currently ignored !!!!!!!!!!! */ -uint64_t rffc5071_set_frequency(uint16_t mhz) { +uint64_t rffc5071_set_frequency(rffc5071_driver_t* const drv, uint16_t mhz) { uint32_t tune_freq; - rffc5071_disable(); - tune_freq = rffc5071_config_synth_int(mhz); - rffc5071_enable(); + rffc5071_disable(drv); + tune_freq = rffc5071_config_synth_int(drv, mhz); + rffc5071_enable(drv); return tune_freq; } -void rffc5071_set_gpo(uint8_t gpo) +void rffc5071_set_gpo(rffc5071_driver_t* const drv, uint8_t gpo) { /* We set GPO for both paths just in case. */ - set_RFFC5071_P1GPO(gpo); - set_RFFC5071_P2GPO(gpo); + set_RFFC5071_P1GPO(drv, gpo); + set_RFFC5071_P2GPO(drv, gpo); - rffc5071_regs_commit(); + rffc5071_regs_commit(drv); } #ifdef TEST int main(int ac, char **av) { - rffc5071_setup(); - rffc5071_tx(0); - rffc5071_set_frequency(500, 0); - rffc5071_set_frequency(525, 0); - rffc5071_set_frequency(550, 0); - rffc5071_set_frequency(1500, 0); - rffc5071_set_frequency(1525, 0); - rffc5071_set_frequency(1550, 0); - rffc5071_disable(); - rffc5071_rx(0); - rffc5071_disable(); - rffc5071_rxtx(); - rffc5071_disable(); + rffc5071_setup(drv); + rffc5071_tx(drv, 0); + rffc5071_set_frequency(drv, 500, 0); + rffc5071_set_frequency(drv, 525, 0); + rffc5071_set_frequency(drv, 550, 0); + rffc5071_set_frequency(drv, 1500, 0); + rffc5071_set_frequency(drv, 1525, 0); + rffc5071_set_frequency(drv, 1550, 0); + rffc5071_disable(drv); + rffc5071_rx(drv, 0); + rffc5071_disable(drv); + rffc5071_rxtx(drv); + rffc5071_disable(drv); } #endif //TEST diff --git a/firmware/common/rffc5071.h b/firmware/common/rffc5071.h index 98c31a3e..7b2a7801 100644 --- a/firmware/common/rffc5071.h +++ b/firmware/common/rffc5071.h @@ -23,43 +23,38 @@ #ifndef __RFFC5071_H #define __RFFC5071_H -/* 31 registers, each containing 16 bits of data. */ -#define RFFC5071_NUM_REGS 31 +#include -extern uint16_t rffc5071_regs[RFFC5071_NUM_REGS]; -extern uint32_t rffc5071_regs_dirty; - -#define RFFC5071_REG_SET_CLEAN(r) rffc5071_regs_dirty &= ~(1UL< reg%d\n", v, r); #else diff --git a/firmware/common/rffc5071_drv.h b/firmware/common/rffc5071_drv.h index eea5ee50..441071ad 100644 --- a/firmware/common/rffc5071_drv.h +++ b/firmware/common/rffc5071_drv.h @@ -23,9 +23,17 @@ #ifndef __RFFC5071_DRV_H #define __RFFC5071_DRV_H -void rffc5071_pin_config(); +/* 31 registers, each containing 16 bits of data. */ +#define RFFC5071_NUM_REGS 31 -uint16_t rffc5071_spi_read(uint8_t r); -void rffc5071_spi_write(uint8_t r, uint16_t v); +typedef struct { + uint16_t regs[RFFC5071_NUM_REGS]; + uint32_t regs_dirty; +} rffc5071_driver_t; + +void rffc5071_pin_config(rffc5071_driver_t* const drv); + +uint16_t rffc5071_spi_read(rffc5071_driver_t* const drv, uint8_t r); +void rffc5071_spi_write(rffc5071_driver_t* const drv, uint8_t r, uint16_t v); #endif // __RFFC5071_DRV_H diff --git a/firmware/common/rffc5071_regs.def b/firmware/common/rffc5071_regs.def index d17a064f..ae45a677 100644 --- a/firmware/common/rffc5071_regs.def +++ b/firmware/common/rffc5071_regs.def @@ -23,6 +23,9 @@ #ifndef __RFFC5071_REGS_DEF #define __RFFC5071_REGS_DEF +#define RFFC5071_REG_SET_CLEAN(_d, _r) (_d->regs_dirty &= ~(1UL<<_r)) +#define RFFC5071_REG_SET_DIRTY(_d, _r) (_d->regs_dirty |= (1UL<<_r)) + #define RFFC5071_READBACK_REG 31 /* Generate static inline accessors that operate on the global @@ -38,13 +41,13 @@ /* n=name, r=regnum, o=offset (bits from LSB) of LSB of field, * l=length (bits) */ #define __MREG__(n,r,o,l) \ -static inline uint16_t get_##n(void) { \ - return (rffc5071_regs[r] >> o) & ((1L<regs[r] >> o) & ((1L<regs[r] &= (uint16_t)(~(((1L<regs[r] |= (uint16_t)(((v&((1L<= MIN_BYPASS_FREQ_MHZ) && (freq_mhz < MAX_BYPASS_FREQ_MHZ) ) @@ -97,7 +97,7 @@ bool set_freq(const uint64_t freq) rf_path_set_filter(RF_PATH_FILTER_HIGH_PASS); RFFC5071_freq_mhz = freq_mhz - (max2837_freq_nominal_hz / FREQ_ONE_MHZ); /* Set Freq and read real freq */ - real_RFFC5071_freq_hz = rffc5071_set_frequency(RFFC5071_freq_mhz); + real_RFFC5071_freq_hz = rffc5071_set_frequency(&rffc5072, RFFC5071_freq_mhz); max2837_set_frequency(&max2837, freq - real_RFFC5071_freq_hz); sgpio_cpld_stream_rx_set_q_invert(0); }else @@ -137,7 +137,7 @@ bool set_freq_explicit(const uint64_t if_freq_hz, const uint64_t lo_freq_hz, sgpio_cpld_stream_rx_set_q_invert(0); } if (path != RF_PATH_FILTER_BYPASS) { - (void)rffc5071_set_frequency(lo_freq_hz / FREQ_ONE_MHZ); + (void)rffc5071_set_frequency(&rffc5072, lo_freq_hz / FREQ_ONE_MHZ); } return true; } diff --git a/firmware/hackrf_usb/usb_api_register.c b/firmware/hackrf_usb/usb_api_register.c index 3dfb5a49..c8b8678a 100644 --- a/firmware/hackrf_usb/usb_api_register.c +++ b/firmware/hackrf_usb/usb_api_register.c @@ -115,7 +115,7 @@ usb_request_status_t usb_vendor_request_write_rffc5071( { if( endpoint->setup.index < RFFC5071_NUM_REGS ) { - rffc5071_reg_write(endpoint->setup.index, endpoint->setup.value); + rffc5071_reg_write(&rffc5072, endpoint->setup.index, endpoint->setup.value); usb_transfer_schedule_ack(endpoint->in); return USB_REQUEST_STATUS_OK; } @@ -134,7 +134,7 @@ usb_request_status_t usb_vendor_request_read_rffc5071( { if( endpoint->setup.index < RFFC5071_NUM_REGS ) { - value = rffc5071_reg_read(endpoint->setup.index); + value = rffc5071_reg_read(&rffc5072, endpoint->setup.index); endpoint->buffer[0] = value & 0xff; endpoint->buffer[1] = value >> 8; usb_transfer_schedule_block(endpoint->in, &endpoint->buffer, 2, diff --git a/firmware/mixertx/mixertx.c b/firmware/mixertx/mixertx.c index ba3c6482..c7150d57 100644 --- a/firmware/mixertx/mixertx.c +++ b/firmware/mixertx/mixertx.c @@ -44,7 +44,7 @@ int main(void) ssp1_set_mode_max2837(); max2837_setup(&max2837); - rffc5071_setup(); + rffc5071_setup(&rffc5072); gpio_set(PORT_LED1_3, (PIN_LED2)); /* LED2 on */ max2837_set_frequency(&max2837, freq);