RFFC507x: De-singleton the driver code.
This commit is contained in:
@ -37,6 +37,8 @@
|
|||||||
|
|
||||||
max2837_driver_t max2837;
|
max2837_driver_t max2837;
|
||||||
|
|
||||||
|
rffc5071_driver_t rffc5072;
|
||||||
|
|
||||||
void delay(uint32_t duration)
|
void delay(uint32_t duration)
|
||||||
{
|
{
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
|
@ -33,6 +33,7 @@ extern "C"
|
|||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
#include "max2837_drv.h"
|
#include "max2837_drv.h"
|
||||||
|
#include "rffc5071_drv.h"
|
||||||
|
|
||||||
/* hardware identification number */
|
/* hardware identification number */
|
||||||
#define BOARD_ID_JELLYBEAN 0
|
#define BOARD_ID_JELLYBEAN 0
|
||||||
@ -352,6 +353,7 @@ typedef enum {
|
|||||||
|
|
||||||
void delay(uint32_t duration);
|
void delay(uint32_t duration);
|
||||||
extern max2837_driver_t max2837;
|
extern max2837_driver_t max2837;
|
||||||
|
extern rffc5071_driver_t rffc5072;
|
||||||
|
|
||||||
void cpu_clock_init(void);
|
void cpu_clock_init(void);
|
||||||
void cpu_clock_pll1_low_speed(void);
|
void cpu_clock_pll1_low_speed(void);
|
||||||
|
@ -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);
|
gpio_set(PORT_NO_RX_AMP_PWR, PIN_NO_RX_AMP_PWR);
|
||||||
|
|
||||||
if (ctrl & SWITCHCTRL_ANT_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 {
|
} 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
|
#endif
|
||||||
|
|
||||||
static void switchctrl_set(const uint8_t gpo) {
|
static void switchctrl_set(const uint8_t gpo) {
|
||||||
#ifdef JAWBREAKER
|
#ifdef JAWBREAKER
|
||||||
rffc5071_set_gpo(gpo);
|
rffc5071_set_gpo(&rffc5072, gpo);
|
||||||
#elif HACKRF_ONE
|
#elif HACKRF_ONE
|
||||||
switchctrl_set_hackrf_one(gpo);
|
switchctrl_set_hackrf_one(gpo);
|
||||||
#else
|
#else
|
||||||
@ -215,7 +215,7 @@ void rf_path_init(void) {
|
|||||||
max2837_setup(&max2837);
|
max2837_setup(&max2837);
|
||||||
max2837_start(&max2837);
|
max2837_start(&max2837);
|
||||||
|
|
||||||
rffc5071_setup();
|
rffc5071_setup(&rffc5072);
|
||||||
switchctrl_set(switchctrl);
|
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. */
|
/* TX amplifier is in path, be sure to enable TX amplifier. */
|
||||||
switchctrl &= ~SWITCHCTRL_NO_TX_AMP_PWR;
|
switchctrl &= ~SWITCHCTRL_NO_TX_AMP_PWR;
|
||||||
}
|
}
|
||||||
rffc5071_tx();
|
rffc5071_tx(&rffc5072);
|
||||||
if( switchctrl & SWITCHCTRL_MIX_BYPASS ) {
|
if( switchctrl & SWITCHCTRL_MIX_BYPASS ) {
|
||||||
rffc5071_disable();
|
rffc5071_disable(&rffc5072);
|
||||||
} else {
|
} else {
|
||||||
rffc5071_enable();
|
rffc5071_enable(&rffc5072);
|
||||||
}
|
}
|
||||||
ssp1_set_mode_max5864();
|
ssp1_set_mode_max5864();
|
||||||
max5864_tx();
|
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. */
|
/* RX amplifier is in path, be sure to enable RX amplifier. */
|
||||||
switchctrl &= ~SWITCHCTRL_NO_RX_AMP_PWR;
|
switchctrl &= ~SWITCHCTRL_NO_RX_AMP_PWR;
|
||||||
}
|
}
|
||||||
rffc5071_rx();
|
rffc5071_rx(&rffc5072);
|
||||||
if( switchctrl & SWITCHCTRL_MIX_BYPASS ) {
|
if( switchctrl & SWITCHCTRL_MIX_BYPASS ) {
|
||||||
rffc5071_disable();
|
rffc5071_disable(&rffc5072);
|
||||||
} else {
|
} else {
|
||||||
rffc5071_enable();
|
rffc5071_enable(&rffc5072);
|
||||||
}
|
}
|
||||||
ssp1_set_mode_max5864();
|
ssp1_set_mode_max5864();
|
||||||
max5864_rx();
|
max5864_rx();
|
||||||
@ -268,7 +268,7 @@ void rf_path_set_direction(const rf_path_direction_t direction) {
|
|||||||
#endif
|
#endif
|
||||||
/* Set RF path to receive direction when "off" */
|
/* Set RF path to receive direction when "off" */
|
||||||
switchctrl &= ~SWITCHCTRL_TX;
|
switchctrl &= ~SWITCHCTRL_TX;
|
||||||
rffc5071_disable();
|
rffc5071_disable(&rffc5072);
|
||||||
ssp1_set_mode_max5864();
|
ssp1_set_mode_max5864();
|
||||||
max5864_standby();
|
max5864_standby();
|
||||||
ssp1_set_mode_max2837();
|
ssp1_set_mode_max2837();
|
||||||
@ -285,18 +285,18 @@ void rf_path_set_filter(const rf_path_filter_t filter) {
|
|||||||
default:
|
default:
|
||||||
case RF_PATH_FILTER_BYPASS:
|
case RF_PATH_FILTER_BYPASS:
|
||||||
switchctrl |= SWITCHCTRL_MIX_BYPASS;
|
switchctrl |= SWITCHCTRL_MIX_BYPASS;
|
||||||
rffc5071_disable();
|
rffc5071_disable(&rffc5072);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RF_PATH_FILTER_LOW_PASS:
|
case RF_PATH_FILTER_LOW_PASS:
|
||||||
switchctrl &= ~(SWITCHCTRL_HP | SWITCHCTRL_MIX_BYPASS);
|
switchctrl &= ~(SWITCHCTRL_HP | SWITCHCTRL_MIX_BYPASS);
|
||||||
rffc5071_enable();
|
rffc5071_enable(&rffc5072);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RF_PATH_FILTER_HIGH_PASS:
|
case RF_PATH_FILTER_HIGH_PASS:
|
||||||
switchctrl &= ~SWITCHCTRL_MIX_BYPASS;
|
switchctrl &= ~SWITCHCTRL_MIX_BYPASS;
|
||||||
switchctrl |= SWITCHCTRL_HP;
|
switchctrl |= SWITCHCTRL_HP;
|
||||||
rffc5071_enable();
|
rffc5071_enable(&rffc5072);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,7 +46,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Default register values. */
|
/* Default register values. */
|
||||||
static uint16_t rffc5071_regs_default[RFFC5071_NUM_REGS] = {
|
static const uint16_t rffc5071_regs_default[RFFC5071_NUM_REGS] = {
|
||||||
0xbefa, /* 00 */
|
0xbefa, /* 00 */
|
||||||
0x4064, /* 01 */
|
0x4064, /* 01 */
|
||||||
0x9055, /* 02 */
|
0x9055, /* 02 */
|
||||||
@ -79,135 +79,130 @@ static uint16_t rffc5071_regs_default[RFFC5071_NUM_REGS] = {
|
|||||||
0x1000, /* 1D */
|
0x1000, /* 1D */
|
||||||
0x0005, /* 1E */ };
|
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. */
|
/* 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");
|
LOG("# rffc5071_init\n");
|
||||||
memcpy(rffc5071_regs, rffc5071_regs_default, sizeof(rffc5071_regs));
|
memcpy(drv->regs, rffc5071_regs_default, sizeof(drv->regs));
|
||||||
rffc5071_regs_dirty = 0x7fffffff;
|
drv->regs_dirty = 0x7fffffff;
|
||||||
|
|
||||||
/* Write default register values to chip. */
|
/* 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 up pins for GPIO and SPI control, configure SSP peripheral for SPI, and
|
||||||
* set our own default register configuration.
|
* 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");
|
LOG("# rffc5071_setup\n");
|
||||||
|
|
||||||
rffc5071_pin_config();
|
rffc5071_pin_config(drv);
|
||||||
|
|
||||||
/* initial setup */
|
/* initial setup */
|
||||||
/* put zeros in freq contol registers */
|
/* put zeros in freq contol registers */
|
||||||
set_RFFC5071_P2N(0);
|
set_RFFC5071_P2N(drv, 0);
|
||||||
set_RFFC5071_P2LODIV(0);
|
set_RFFC5071_P2LODIV(drv, 0);
|
||||||
set_RFFC5071_P2PRESC(0);
|
set_RFFC5071_P2PRESC(drv, 0);
|
||||||
set_RFFC5071_P2VCOSEL(0);
|
set_RFFC5071_P2VCOSEL(drv, 0);
|
||||||
|
|
||||||
set_RFFC5071_P2N(0);
|
set_RFFC5071_P2N(drv, 0);
|
||||||
set_RFFC5071_P2LODIV(0);
|
set_RFFC5071_P2LODIV(drv, 0);
|
||||||
set_RFFC5071_P2PRESC(0);
|
set_RFFC5071_P2PRESC(drv, 0);
|
||||||
set_RFFC5071_P2VCOSEL(0);
|
set_RFFC5071_P2VCOSEL(drv, 0);
|
||||||
|
|
||||||
set_RFFC5071_P2N(0);
|
set_RFFC5071_P2N(drv, 0);
|
||||||
set_RFFC5071_P2LODIV(0);
|
set_RFFC5071_P2LODIV(drv, 0);
|
||||||
set_RFFC5071_P2PRESC(0);
|
set_RFFC5071_P2PRESC(drv, 0);
|
||||||
set_RFFC5071_P2VCOSEL(0);
|
set_RFFC5071_P2VCOSEL(drv, 0);
|
||||||
|
|
||||||
/* set ENBL and MODE to be configured via 3-wire interface,
|
/* set ENBL and MODE to be configured via 3-wire interface,
|
||||||
* not control pins. */
|
* not control pins. */
|
||||||
set_RFFC5071_SIPIN(1);
|
set_RFFC5071_SIPIN(drv, 1);
|
||||||
|
|
||||||
/* GPOs are active at all times */
|
/* 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. */
|
/* Readback register is not cached. */
|
||||||
if (r == RFFC5071_READBACK_REG)
|
if (r == RFFC5071_READBACK_REG)
|
||||||
return rffc5071_spi_read(r);
|
return rffc5071_spi_read(drv, r);
|
||||||
|
|
||||||
/* Discard uncommited write when reading. This shouldn't
|
/* Discard uncommited write when reading. This shouldn't
|
||||||
* happen, and probably has not been tested. */
|
* happen, and probably has not been tested. */
|
||||||
if ((rffc5071_regs_dirty >> r) & 0x1) {
|
if ((drv->regs_dirty >> r) & 0x1) {
|
||||||
rffc5071_regs[r] = rffc5071_spi_read(r);
|
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;
|
drv->regs[r] = v;
|
||||||
rffc5071_spi_write(r, v);
|
rffc5071_spi_write(drv, r, v);
|
||||||
RFFC5071_REG_SET_CLEAN(r);
|
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;
|
int r;
|
||||||
for(r = 0; r < RFFC5071_NUM_REGS; r++) {
|
for(r = 0; r < RFFC5071_NUM_REGS; r++) {
|
||||||
if ((rffc5071_regs_dirty >> r) & 0x1) {
|
if ((drv->regs_dirty >> r) & 0x1) {
|
||||||
rffc5071_reg_commit(r);
|
rffc5071_reg_commit(drv, r);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void rffc5071_tx(void) {
|
void rffc5071_tx(rffc5071_driver_t* const drv) {
|
||||||
LOG("# rffc5071_tx\n");
|
LOG("# rffc5071_tx\n");
|
||||||
set_RFFC5071_ENBL(0);
|
set_RFFC5071_ENBL(drv, 0);
|
||||||
set_RFFC5071_FULLD(0);
|
set_RFFC5071_FULLD(drv, 0);
|
||||||
set_RFFC5071_MODE(1); /* mixer 2 used for both RX and TX */
|
set_RFFC5071_MODE(drv, 1); /* mixer 2 used for both RX and TX */
|
||||||
rffc5071_regs_commit();
|
rffc5071_regs_commit(drv);
|
||||||
}
|
}
|
||||||
|
|
||||||
void rffc5071_rx(void) {
|
void rffc5071_rx(rffc5071_driver_t* const drv) {
|
||||||
LOG("# rfc5071_rx\n");
|
LOG("# rfc5071_rx\n");
|
||||||
set_RFFC5071_ENBL(0);
|
set_RFFC5071_ENBL(drv, 0);
|
||||||
set_RFFC5071_FULLD(0);
|
set_RFFC5071_FULLD(drv, 0);
|
||||||
set_RFFC5071_MODE(1); /* mixer 2 used for both RX and TX */
|
set_RFFC5071_MODE(drv, 1); /* mixer 2 used for both RX and TX */
|
||||||
rffc5071_regs_commit();
|
rffc5071_regs_commit(drv);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This function turns on both mixer (full-duplex) on the RFFC5071, but our
|
* This function turns on both mixer (full-duplex) on the RFFC5071, but our
|
||||||
* current hardware designs do not support full-duplex operation.
|
* 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");
|
LOG("# rfc5071_rxtx\n");
|
||||||
set_RFFC5071_ENBL(0);
|
set_RFFC5071_ENBL(drv, 0);
|
||||||
set_RFFC5071_FULLD(1); /* mixer 1 and mixer 2 (RXTX) */
|
set_RFFC5071_FULLD(drv, 1); /* mixer 1 and mixer 2 (RXTX) */
|
||||||
rffc5071_regs_commit();
|
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");
|
LOG("# rfc5071_disable\n");
|
||||||
set_RFFC5071_ENBL(0);
|
set_RFFC5071_ENBL(drv, 0);
|
||||||
rffc5071_regs_commit();
|
rffc5071_regs_commit(drv);
|
||||||
}
|
}
|
||||||
|
|
||||||
void rffc5071_enable(void) {
|
void rffc5071_enable(rffc5071_driver_t* const drv) {
|
||||||
LOG("# rfc5071_enable\n");
|
LOG("# rfc5071_enable\n");
|
||||||
set_RFFC5071_ENBL(1);
|
set_RFFC5071_ENBL(drv, 1);
|
||||||
rffc5071_regs_commit();
|
rffc5071_regs_commit(drv);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define LO_MAX 5400
|
#define LO_MAX 5400
|
||||||
@ -215,7 +210,7 @@ void rffc5071_enable(void) {
|
|||||||
#define FREQ_ONE_MHZ (1000*1000)
|
#define FREQ_ONE_MHZ (1000*1000)
|
||||||
|
|
||||||
/* configure frequency synthesizer in integer mode (lo in MHz) */
|
/* 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;
|
uint8_t lodiv;
|
||||||
uint16_t fvco;
|
uint16_t fvco;
|
||||||
uint8_t fbkdiv;
|
uint8_t fbkdiv;
|
||||||
@ -244,10 +239,10 @@ uint64_t rffc5071_config_synth_int(uint16_t lo) {
|
|||||||
* and will be unaffected. */
|
* and will be unaffected. */
|
||||||
if (fvco > 3200) {
|
if (fvco > 3200) {
|
||||||
fbkdiv = 4;
|
fbkdiv = 4;
|
||||||
set_RFFC5071_PLLCPL(3);
|
set_RFFC5071_PLLCPL(drv, 3);
|
||||||
} else {
|
} else {
|
||||||
fbkdiv = 2;
|
fbkdiv = 2;
|
||||||
set_RFFC5071_PLLCPL(2);
|
set_RFFC5071_PLLCPL(drv, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t tmp_n = ((uint64_t)fvco << 29ULL) / (fbkdiv*REF_FREQ) ;
|
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);
|
lo, n_lo, lodiv, fvco, fbkdiv, n, tune_freq);
|
||||||
|
|
||||||
/* Path 1 */
|
/* Path 1 */
|
||||||
set_RFFC5071_P1LODIV(n_lo);
|
set_RFFC5071_P1LODIV(drv, n_lo);
|
||||||
set_RFFC5071_P1N(n);
|
set_RFFC5071_P1N(drv, n);
|
||||||
set_RFFC5071_P1PRESC(fbkdiv >> 1);
|
set_RFFC5071_P1PRESC(drv, fbkdiv >> 1);
|
||||||
set_RFFC5071_P1NMSB(p1nmsb);
|
set_RFFC5071_P1NMSB(drv, p1nmsb);
|
||||||
set_RFFC5071_P1NLSB(p1nlsb);
|
set_RFFC5071_P1NLSB(drv, p1nlsb);
|
||||||
|
|
||||||
/* Path 2 */
|
/* Path 2 */
|
||||||
set_RFFC5071_P2LODIV(n_lo);
|
set_RFFC5071_P2LODIV(drv, n_lo);
|
||||||
set_RFFC5071_P2N(n);
|
set_RFFC5071_P2N(drv, n);
|
||||||
set_RFFC5071_P2PRESC(fbkdiv >> 1);
|
set_RFFC5071_P2PRESC(drv, fbkdiv >> 1);
|
||||||
set_RFFC5071_P2NMSB(p1nmsb);
|
set_RFFC5071_P2NMSB(drv, p1nmsb);
|
||||||
set_RFFC5071_P2NLSB(p1nlsb);
|
set_RFFC5071_P2NLSB(drv, p1nlsb);
|
||||||
|
|
||||||
rffc5071_regs_commit();
|
rffc5071_regs_commit(drv);
|
||||||
|
|
||||||
return tune_freq_hz;
|
return tune_freq_hz;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* !!!!!!!!!!! hz is currently ignored !!!!!!!!!!! */
|
/* !!!!!!!!!!! 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;
|
uint32_t tune_freq;
|
||||||
|
|
||||||
rffc5071_disable();
|
rffc5071_disable(drv);
|
||||||
tune_freq = rffc5071_config_synth_int(mhz);
|
tune_freq = rffc5071_config_synth_int(drv, mhz);
|
||||||
rffc5071_enable();
|
rffc5071_enable(drv);
|
||||||
|
|
||||||
return tune_freq;
|
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. */
|
/* We set GPO for both paths just in case. */
|
||||||
set_RFFC5071_P1GPO(gpo);
|
set_RFFC5071_P1GPO(drv, gpo);
|
||||||
set_RFFC5071_P2GPO(gpo);
|
set_RFFC5071_P2GPO(drv, gpo);
|
||||||
|
|
||||||
rffc5071_regs_commit();
|
rffc5071_regs_commit(drv);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef TEST
|
#ifdef TEST
|
||||||
int main(int ac, char **av)
|
int main(int ac, char **av)
|
||||||
{
|
{
|
||||||
rffc5071_setup();
|
rffc5071_setup(drv);
|
||||||
rffc5071_tx(0);
|
rffc5071_tx(drv, 0);
|
||||||
rffc5071_set_frequency(500, 0);
|
rffc5071_set_frequency(drv, 500, 0);
|
||||||
rffc5071_set_frequency(525, 0);
|
rffc5071_set_frequency(drv, 525, 0);
|
||||||
rffc5071_set_frequency(550, 0);
|
rffc5071_set_frequency(drv, 550, 0);
|
||||||
rffc5071_set_frequency(1500, 0);
|
rffc5071_set_frequency(drv, 1500, 0);
|
||||||
rffc5071_set_frequency(1525, 0);
|
rffc5071_set_frequency(drv, 1525, 0);
|
||||||
rffc5071_set_frequency(1550, 0);
|
rffc5071_set_frequency(drv, 1550, 0);
|
||||||
rffc5071_disable();
|
rffc5071_disable(drv);
|
||||||
rffc5071_rx(0);
|
rffc5071_rx(drv, 0);
|
||||||
rffc5071_disable();
|
rffc5071_disable(drv);
|
||||||
rffc5071_rxtx();
|
rffc5071_rxtx(drv);
|
||||||
rffc5071_disable();
|
rffc5071_disable(drv);
|
||||||
}
|
}
|
||||||
#endif //TEST
|
#endif //TEST
|
||||||
|
@ -23,43 +23,38 @@
|
|||||||
#ifndef __RFFC5071_H
|
#ifndef __RFFC5071_H
|
||||||
#define __RFFC5071_H
|
#define __RFFC5071_H
|
||||||
|
|
||||||
/* 31 registers, each containing 16 bits of data. */
|
#include <stdint.h>
|
||||||
#define RFFC5071_NUM_REGS 31
|
|
||||||
|
|
||||||
extern uint16_t rffc5071_regs[RFFC5071_NUM_REGS];
|
#include "rffc5071_drv.h"
|
||||||
extern uint32_t rffc5071_regs_dirty;
|
|
||||||
|
|
||||||
#define RFFC5071_REG_SET_CLEAN(r) rffc5071_regs_dirty &= ~(1UL<<r)
|
|
||||||
#define RFFC5071_REG_SET_DIRTY(r) rffc5071_regs_dirty |= (1UL<<r)
|
|
||||||
|
|
||||||
/* Initialize chip. Call _setup() externally, as it calls _init(). */
|
/* Initialize chip. Call _setup() externally, as it calls _init(). */
|
||||||
extern void rffc5071_init(void);
|
extern void rffc5071_init(rffc5071_driver_t* const drv);
|
||||||
extern void rffc5071_setup(void);
|
extern void rffc5071_setup(rffc5071_driver_t* const drv);
|
||||||
|
|
||||||
/* Read a register via SPI. Save a copy to memory and return
|
/* Read a register via SPI. Save a copy to memory and return
|
||||||
* value. Discard any uncommited changes and mark CLEAN. */
|
* value. Discard any uncommited changes and mark CLEAN. */
|
||||||
extern uint16_t rffc5071_reg_read(uint8_t r);
|
extern uint16_t rffc5071_reg_read(rffc5071_driver_t* const drv, uint8_t r);
|
||||||
|
|
||||||
/* Write value to register via SPI and save a copy to memory. Mark
|
/* Write value to register via SPI and save a copy to memory. Mark
|
||||||
* CLEAN. */
|
* CLEAN. */
|
||||||
extern void rffc5071_reg_write(uint8_t r, uint16_t v);
|
extern void rffc5071_reg_write(rffc5071_driver_t* const drv, uint8_t r, uint16_t v);
|
||||||
|
|
||||||
/* Write all dirty registers via SPI from memory. Mark all clean. Some
|
/* Write all dirty registers via SPI from memory. Mark all clean. Some
|
||||||
* operations require registers to be written in a certain order. Use
|
* operations require registers to be written in a certain order. Use
|
||||||
* provided routines for those operations. */
|
* provided routines for those operations. */
|
||||||
extern void rffc5071_regs_commit(void);
|
extern void rffc5071_regs_commit(rffc5071_driver_t* const drv);
|
||||||
|
|
||||||
/* Set frequency (MHz). */
|
/* Set frequency (MHz). */
|
||||||
extern uint64_t rffc5071_set_frequency(uint16_t mhz);
|
extern uint64_t rffc5071_set_frequency(rffc5071_driver_t* const drv, uint16_t mhz);
|
||||||
|
|
||||||
/* Set up rx only, tx only, or full duplex. Chip should be disabled
|
/* Set up rx only, tx only, or full duplex. Chip should be disabled
|
||||||
* before _tx, _rx, or _rxtx are called. */
|
* before _tx, _rx, or _rxtx are called. */
|
||||||
extern void rffc5071_tx(void);
|
extern void rffc5071_tx(rffc5071_driver_t* const drv);
|
||||||
extern void rffc5071_rx(void);
|
extern void rffc5071_rx(rffc5071_driver_t* const drv);
|
||||||
extern void rffc5071_rxtx(void);
|
extern void rffc5071_rxtx(rffc5071_driver_t* const drv);
|
||||||
extern void rffc5071_enable(void);
|
extern void rffc5071_enable(rffc5071_driver_t* const drv);
|
||||||
extern void rffc5071_disable(void);
|
extern void rffc5071_disable(rffc5071_driver_t* const drv);
|
||||||
|
|
||||||
extern void rffc5071_set_gpo(uint8_t);
|
extern void rffc5071_set_gpo(rffc5071_driver_t* const drv, uint8_t);
|
||||||
|
|
||||||
#endif // __RFFC5071_H
|
#endif // __RFFC5071_H
|
||||||
|
@ -31,7 +31,8 @@
|
|||||||
#include "hackrf_core.h"
|
#include "hackrf_core.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void rffc5071_pin_config() {
|
void rffc5071_pin_config(rffc5071_driver_t* const drv) {
|
||||||
|
(void)drv;
|
||||||
#if !defined TEST
|
#if !defined TEST
|
||||||
/* Configure GPIO pins. */
|
/* Configure GPIO pins. */
|
||||||
scu_pinmux(SCU_MIXER_ENX, SCU_GPIO_FAST);
|
scu_pinmux(SCU_MIXER_ENX, SCU_GPIO_FAST);
|
||||||
@ -69,7 +70,8 @@ static void serial_delay(void)
|
|||||||
* next 7 bits are register address.
|
* next 7 bits are register address.
|
||||||
* Then receive 16 bits (register value).
|
* Then receive 16 bits (register value).
|
||||||
*/
|
*/
|
||||||
uint16_t rffc5071_spi_read(uint8_t r) {
|
uint16_t rffc5071_spi_read(rffc5071_driver_t* const drv, uint8_t r) {
|
||||||
|
(void)drv;
|
||||||
|
|
||||||
int bits = 9;
|
int bits = 9;
|
||||||
int msb = 1 << (bits -1);
|
int msb = 1 << (bits -1);
|
||||||
@ -166,7 +168,8 @@ uint16_t rffc5071_spi_read(uint8_t r) {
|
|||||||
* next 7 bits are register address,
|
* next 7 bits are register address,
|
||||||
* next 16 bits are register value.
|
* next 16 bits are register value.
|
||||||
*/
|
*/
|
||||||
void rffc5071_spi_write(uint8_t r, uint16_t v) {
|
void rffc5071_spi_write(rffc5071_driver_t* const drv, uint8_t r, uint16_t v) {
|
||||||
|
(void)drv;
|
||||||
|
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
LOG("0x%04x -> reg%d\n", v, r);
|
LOG("0x%04x -> reg%d\n", v, r);
|
||||||
|
@ -23,9 +23,17 @@
|
|||||||
#ifndef __RFFC5071_DRV_H
|
#ifndef __RFFC5071_DRV_H
|
||||||
#define __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);
|
typedef struct {
|
||||||
void rffc5071_spi_write(uint8_t r, uint16_t v);
|
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
|
#endif // __RFFC5071_DRV_H
|
||||||
|
@ -23,6 +23,9 @@
|
|||||||
#ifndef __RFFC5071_REGS_DEF
|
#ifndef __RFFC5071_REGS_DEF
|
||||||
#define __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
|
#define RFFC5071_READBACK_REG 31
|
||||||
|
|
||||||
/* Generate static inline accessors that operate on the global
|
/* 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,
|
/* n=name, r=regnum, o=offset (bits from LSB) of LSB of field,
|
||||||
* l=length (bits) */
|
* l=length (bits) */
|
||||||
#define __MREG__(n,r,o,l) \
|
#define __MREG__(n,r,o,l) \
|
||||||
static inline uint16_t get_##n(void) { \
|
static inline uint16_t get_##n(rffc5071_driver_t* const _d) { \
|
||||||
return (rffc5071_regs[r] >> o) & ((1L<<l)-1); \
|
return (_d->regs[r] >> o) & ((1L<<l)-1); \
|
||||||
} \
|
} \
|
||||||
static inline void set_##n(uint16_t v) { \
|
static inline void set_##n(rffc5071_driver_t* const _d, uint16_t v) { \
|
||||||
rffc5071_regs[r] &= (uint16_t)(~(((1L<<l)-1)<<o)); \
|
_d->regs[r] &= (uint16_t)(~(((1L<<l)-1)<<o)); \
|
||||||
rffc5071_regs[r] |= (uint16_t)(((v&((1L<<l)-1))<<o)); \
|
_d->regs[r] |= (uint16_t)(((v&((1L<<l)-1))<<o)); \
|
||||||
RFFC5071_REG_SET_DIRTY(r); \
|
RFFC5071_REG_SET_DIRTY(_d, r); \
|
||||||
}
|
}
|
||||||
|
|
||||||
/* REG 00 (0): LF */
|
/* REG 00 (0): LF */
|
||||||
|
@ -72,7 +72,7 @@ bool set_freq(const uint64_t freq)
|
|||||||
max2837_freq_nominal_hz = 2650000000 - (freq / 7);
|
max2837_freq_nominal_hz = 2650000000 - (freq / 7);
|
||||||
RFFC5071_freq_mhz = (max2837_freq_nominal_hz / FREQ_ONE_MHZ) + freq_mhz;
|
RFFC5071_freq_mhz = (max2837_freq_nominal_hz / FREQ_ONE_MHZ) + freq_mhz;
|
||||||
/* Set Freq and read real freq */
|
/* 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, real_RFFC5071_freq_hz - freq);
|
max2837_set_frequency(&max2837, real_RFFC5071_freq_hz - freq);
|
||||||
sgpio_cpld_stream_rx_set_q_invert(1);
|
sgpio_cpld_stream_rx_set_q_invert(1);
|
||||||
}else if( (freq_mhz >= MIN_BYPASS_FREQ_MHZ) && (freq_mhz < MAX_BYPASS_FREQ_MHZ) )
|
}else if( (freq_mhz >= 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);
|
rf_path_set_filter(RF_PATH_FILTER_HIGH_PASS);
|
||||||
RFFC5071_freq_mhz = freq_mhz - (max2837_freq_nominal_hz / FREQ_ONE_MHZ);
|
RFFC5071_freq_mhz = freq_mhz - (max2837_freq_nominal_hz / FREQ_ONE_MHZ);
|
||||||
/* Set Freq and read real freq */
|
/* 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);
|
max2837_set_frequency(&max2837, freq - real_RFFC5071_freq_hz);
|
||||||
sgpio_cpld_stream_rx_set_q_invert(0);
|
sgpio_cpld_stream_rx_set_q_invert(0);
|
||||||
}else
|
}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);
|
sgpio_cpld_stream_rx_set_q_invert(0);
|
||||||
}
|
}
|
||||||
if (path != RF_PATH_FILTER_BYPASS) {
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -115,7 +115,7 @@ usb_request_status_t usb_vendor_request_write_rffc5071(
|
|||||||
{
|
{
|
||||||
if( endpoint->setup.index < RFFC5071_NUM_REGS )
|
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);
|
usb_transfer_schedule_ack(endpoint->in);
|
||||||
return USB_REQUEST_STATUS_OK;
|
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 )
|
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[0] = value & 0xff;
|
||||||
endpoint->buffer[1] = value >> 8;
|
endpoint->buffer[1] = value >> 8;
|
||||||
usb_transfer_schedule_block(endpoint->in, &endpoint->buffer, 2,
|
usb_transfer_schedule_block(endpoint->in, &endpoint->buffer, 2,
|
||||||
|
@ -44,7 +44,7 @@ int main(void)
|
|||||||
|
|
||||||
ssp1_set_mode_max2837();
|
ssp1_set_mode_max2837();
|
||||||
max2837_setup(&max2837);
|
max2837_setup(&max2837);
|
||||||
rffc5071_setup();
|
rffc5071_setup(&rffc5072);
|
||||||
gpio_set(PORT_LED1_3, (PIN_LED2)); /* LED2 on */
|
gpio_set(PORT_LED1_3, (PIN_LED2)); /* LED2 on */
|
||||||
|
|
||||||
max2837_set_frequency(&max2837, freq);
|
max2837_set_frequency(&max2837, freq);
|
||||||
|
Reference in New Issue
Block a user