feat(mixer): Full MAX2871 integration for rad1o

This commit is contained in:
schneider
2017-01-27 21:41:24 +01:00
parent f063f87c49
commit 566c9ad4bd
6 changed files with 100 additions and 122 deletions

View File

@ -901,7 +901,7 @@ void pin_setup(void) {
spi_bus_start(&spi_bus_ssp1, &ssp_config_max2837); spi_bus_start(&spi_bus_ssp1, &ssp_config_max2837);
mixer_pin_setup(&mixer); mixer_bus_setup(&mixer);
rf_path_pin_setup(&rf_path); rf_path_pin_setup(&rf_path);

View File

@ -268,21 +268,6 @@ extern "C"
#define PORT_XCVR_B (GPIO4) #define PORT_XCVR_B (GPIO4)
#endif #endif
#ifdef RAD1O
#define PIN_VCO_CE (BIT13) /* GPIO2[13] on P5_4 */
#define PORT_VCO_CE (GPIO2)
#define PIN_VCO_SCLK (BIT6) /* GPIO5[6] on P2_6 */
#define PORT_VCO_SCLK (GPIO5)
#define PIN_VCO_SDATA (BIT3) /* GPIO3[3] on P6_4 */
#define PORT_VCO_SDATA (GPIO3)
#define PIN_VCO_LE (BIT14) /* GPIO2[14] on P5_5 */
#define PORT_VCO_LE (GPIO2)
#define PIN_VCO_MUX (BIT25) /* GPIO5[25] on PB_5 */
#define PORT_VCO_MUX (GPIO5)
#define PIN_SYNT_RFOUT_EN (BIT5) /* GPIO3[5] on P6_9 */
#define PORT_SYNT_RFOUT_EN (GPIO3)
#endif
#if (defined HACKRF_ONE || defined RAD1O) #if (defined HACKRF_ONE || defined RAD1O)
#define PIN_CPLD_TMS (GPIOPIN4) #define PIN_CPLD_TMS (GPIOPIN4)
#define PORT_CPLD_TMS (GPIO3) #define PORT_CPLD_TMS (GPIO3)

View File

@ -9,20 +9,18 @@
#define LOG(x,...) #define LOG(x,...)
#include <libopencm3/lpc43xx/ssp.h> #include <libopencm3/lpc43xx/ssp.h>
#include <libopencm3/lpc43xx/scu.h> #include <libopencm3/lpc43xx/scu.h>
//#include <libopencm3/lpc43xx/gpio.h>
#include "hackrf_core.h" #include "hackrf_core.h"
#endif #endif
#include <stdint.h> #include <stdint.h>
#include <string.h> #include <string.h>
static void max2871_spi_write(uint8_t r, uint32_t v); static void max2871_spi_write(max2871_driver_t* const drv, uint8_t r, uint32_t v);
static void max2871_write_registers(void); static void max2871_write_registers(max2871_driver_t* const drv);
static void delay_ms(int ms); static void delay_ms(int ms);
void max2871_setup(max2871_driver_t* const drv) void max2871_setup(max2871_driver_t* const drv)
{ {
#if 0 //XXX
/* Configure GPIO pins. */ /* Configure GPIO pins. */
scu_pinmux(SCU_VCO_CE, SCU_GPIO_FAST); scu_pinmux(SCU_VCO_CE, SCU_GPIO_FAST);
scu_pinmux(SCU_VCO_SCLK, SCU_GPIO_FAST | SCU_CONF_FUNCTION4); scu_pinmux(SCU_VCO_SCLK, SCU_GPIO_FAST | SCU_CONF_FUNCTION4);
@ -33,26 +31,26 @@ void max2871_setup(max2871_driver_t* const drv)
scu_pinmux(SCU_SYNT_RFOUT_EN, SCU_GPIO_FAST); scu_pinmux(SCU_SYNT_RFOUT_EN, SCU_GPIO_FAST);
/* Set GPIO pins as outputs. */ /* Set GPIO pins as outputs. */
GPIO_DIR(PORT_VCO_CE) |= PIN_VCO_CE; gpio_output(drv->gpio_vco_ce);
GPIO_DIR(PORT_VCO_SCLK) |= PIN_VCO_SCLK; gpio_output(drv->gpio_vco_sclk);
GPIO_DIR(PORT_VCO_SDATA) |= PIN_VCO_SDATA; gpio_output(drv->gpio_vco_sdata);
GPIO_DIR(PORT_VCO_LE) |= PIN_VCO_LE; gpio_output(drv->gpio_vco_le);
GPIO_DIR(PORT_SYNT_RFOUT_EN) |= PIN_SYNT_RFOUT_EN; gpio_output(drv->gpio_synt_rfout_en);
/* MUX is an input */ /* MUX is an input */
GPIO_DIR(PORT_VCO_MUX) &= ~(PIN_VCO_MUX); gpio_input(drv->gpio_vco_mux);
/* set to known state */ /* set to known state */
gpio_set(PORT_VCO_CE, PIN_VCO_CE); /* active high */ gpio_set(drv->gpio_vco_ce); /* active high */
gpio_clear(PORT_VCO_SCLK, PIN_VCO_SCLK); gpio_clear(drv->gpio_vco_sclk);
gpio_clear(PORT_VCO_SDATA, PIN_VCO_SDATA); gpio_clear(drv->gpio_vco_sdata);
gpio_set(PORT_VCO_LE, PIN_VCO_LE); /* active low */ gpio_set(drv->gpio_vco_le); /* active low */
gpio_set(PORT_SYNT_RFOUT_EN, PIN_SYNT_RFOUT_EN); /* active high */ gpio_set(drv->gpio_synt_rfout_en); /* active high */
max2871_regs_init(); max2871_regs_init();
int i; int i;
for(i = 5; i >= 0; i--) { for(i = 5; i >= 0; i--) {
max2871_spi_write(i, max2871_get_register(i)); max2871_spi_write(drv, i, max2871_get_register(i));
delay_ms(20); delay_ms(20);
} }
@ -103,10 +101,9 @@ void max2871_setup(max2871_driver_t* const drv)
max2871_set_ADCS(0); max2871_set_ADCS(0);
max2871_set_ADCM(0); max2871_set_ADCM(0);
max2871_write_registers(); max2871_write_registers(drv);
max2871_set_frequency(3500); max2871_set_frequency(drv, 3500);
#endif
} }
static void delay_ms(int ms) static void delay_ms(int ms)
@ -135,9 +132,7 @@ static void serial_delay(void)
* First 29 bits are data * First 29 bits are data
* Last 3 bits are register number * Last 3 bits are register number
*/ */
static void max2871_spi_write(uint8_t r, uint32_t v) { static void max2871_spi_write(max2871_driver_t* const drv, uint8_t r, uint32_t v) {
#if 0 //XXX
#if DEBUG #if DEBUG
LOG("0x%04x -> reg%d\n", v, r); LOG("0x%04x -> reg%d\n", v, r);
#else #else
@ -147,65 +142,62 @@ static void max2871_spi_write(uint8_t r, uint32_t v) {
uint32_t data = v | r; uint32_t data = v | r;
/* make sure everything is starting in the correct state */ /* make sure everything is starting in the correct state */
gpio_set(PORT_VCO_LE, PIN_VCO_LE); gpio_set(drv->gpio_vco_le);
gpio_clear(PORT_VCO_SCLK, PIN_VCO_SCLK); gpio_clear(drv->gpio_vco_sclk);
gpio_clear(PORT_VCO_SDATA, PIN_VCO_SDATA); gpio_clear(drv->gpio_vco_sdata);
/* start transaction by bringing LE low */ /* start transaction by bringing LE low */
gpio_clear(PORT_VCO_LE, PIN_VCO_LE); gpio_clear(drv->gpio_vco_le);
while (bits--) { while (bits--) {
if (data & msb) if (data & msb)
gpio_set(PORT_VCO_SDATA, PIN_VCO_SDATA); gpio_set(drv->gpio_vco_sdata);
else else
gpio_clear(PORT_VCO_SDATA, PIN_VCO_SDATA); gpio_clear(drv->gpio_vco_sdata);
data <<= 1; data <<= 1;
serial_delay(); serial_delay();
gpio_set(PORT_VCO_SCLK, PIN_VCO_SCLK); gpio_set(drv->gpio_vco_sclk);
serial_delay(); serial_delay();
gpio_clear(PORT_VCO_SCLK, PIN_VCO_SCLK); gpio_clear(drv->gpio_vco_sclk);
} }
gpio_set(PORT_VCO_LE, PIN_VCO_LE); gpio_set(drv->gpio_vco_le);
#endif
#endif #endif
} }
static uint32_t max2871_spi_read(void) static uint32_t max2871_spi_read(max2871_driver_t* const drv)
{ {
#if 0 //XXX
uint32_t bits = 32; uint32_t bits = 32;
uint32_t data = 0; uint32_t data = 0;
max2871_spi_write(0x06, 0x0); max2871_spi_write(drv, 0x06, 0x0);
serial_delay(); serial_delay();
gpio_set(PORT_VCO_SCLK, PIN_VCO_SCLK); gpio_set(drv->gpio_vco_sclk);
serial_delay(); serial_delay();
gpio_clear(PORT_VCO_SCLK, PIN_VCO_SCLK); gpio_clear(drv->gpio_vco_sclk);
serial_delay(); serial_delay();
while (bits--) { while (bits--) {
gpio_set(PORT_VCO_SCLK, PIN_VCO_SCLK); gpio_set(drv->gpio_vco_sclk);
serial_delay(); serial_delay();
gpio_clear(PORT_VCO_SCLK, PIN_VCO_SCLK); gpio_clear(drv->gpio_vco_sclk);
serial_delay(); serial_delay();
data <<= 1; data <<= 1;
data |= GPIO_STATE(PORT_VCO_MUX, PIN_VCO_MUX) ? 1 : 0; data |= gpio_read(drv->gpio_vco_mux) ? 1 : 0;
} }
return data; return data;
#endif
} }
static void max2871_write_registers(void) static void max2871_write_registers(max2871_driver_t* const drv)
{ {
int i; int i;
for(i = 5; i >= 0; i--) { for(i = 5; i >= 0; i--) {
max2871_spi_write(i, max2871_get_register(i)); max2871_spi_write(drv, i, max2871_get_register(i));
} }
} }
@ -221,41 +213,26 @@ uint64_t max2871_set_frequency(max2871_driver_t* const drv, uint16_t mhz)
} }
max2871_set_RFA_EN(0); max2871_set_RFA_EN(0);
max2871_write_registers(); max2871_write_registers(drv);
max2871_set_N(n); max2871_set_N(n);
max2871_set_DIVA(diva); max2871_set_DIVA(diva);
max2871_write_registers(); max2871_write_registers(drv);
while(max2871_spi_read() & MAX2871_VASA); while(max2871_spi_read(drv) & MAX2871_VASA);
max2871_set_RFA_EN(1); max2871_set_RFA_EN(1);
max2871_write_registers(); max2871_write_registers(drv);
return (mhz/40)*40 * 1000000; return (mhz/40)*40 * 1000000;
} }
void max2871_tx(max2871_driver_t* const drv)
{}
void max2871_rx(max2871_driver_t* const drv)
{}
void max2871_rxtx(max2871_driver_t* const drv)
{}
void max2871_enable(max2871_driver_t* const drv) void max2871_enable(max2871_driver_t* const drv)
{ {
#if 0 //XXX gpio_set(drv->gpio_vco_ce);
gpio_set(PORT_VCO_CE, PIN_VCO_CE); /* active high */
#endif
} }
void max2871_disable(max2871_driver_t* const drv) void max2871_disable(max2871_driver_t* const drv)
{ {
#if 0 //XXX gpio_clear(drv->gpio_vco_ce);
gpio_clear(PORT_VCO_CE, PIN_VCO_CE); /* active high */
#endif
}
void max2871_set_gpo(max2871_driver_t* const drv, uint8_t gpo)
{
(void) gpo;
} }

View File

@ -1,21 +1,21 @@
#ifndef MAX2871_H #ifndef MAX2871_H
#define MAX2871_H #define MAX2871_H
#include "gpio.h"
#include <stdint.h> #include <stdint.h>
typedef struct { typedef struct {
//spi_bus_t* const bus; gpio_t gpio_vco_ce;
//gpio_t gpio_reset; gpio_t gpio_vco_sclk;
uint16_t regs[1]; gpio_t gpio_vco_sdata;
uint32_t regs_dirty; gpio_t gpio_vco_le;
gpio_t gpio_synt_rfout_en;
gpio_t gpio_vco_mux;
} max2871_driver_t; } max2871_driver_t;
extern void max2871_setup(max2871_driver_t* const drv); extern void max2871_setup(max2871_driver_t* const drv);
extern uint64_t max2871_set_frequency(max2871_driver_t* const drv, uint16_t mhz); extern uint64_t max2871_set_frequency(max2871_driver_t* const drv, uint16_t mhz);
extern void max2871_tx(max2871_driver_t* const drv);
extern void max2871_rx(max2871_driver_t* const drv);
extern void max2871_rxtx(max2871_driver_t* const drv);
extern void max2871_enable(max2871_driver_t* const drv); extern void max2871_enable(max2871_driver_t* const drv);
extern void max2871_disable(max2871_driver_t* const drv); extern void max2871_disable(max2871_driver_t* const drv);
extern void max2871_set_gpo(max2871_driver_t* const drv, uint8_t gpo);
#endif #endif

View File

@ -5,18 +5,20 @@
#include "gpio_lpc.h" #include "gpio_lpc.h"
/* RFFC5071 GPIO serial interface PinMux */ /* RFFC5071 GPIO serial interface PinMux */
#ifdef JELLYBEAN
static struct gpio_t gpio_rffc5072_select = GPIO(3, 8);
static struct gpio_t gpio_rffc5072_clock = GPIO(3, 9);
static struct gpio_t gpio_rffc5072_data = GPIO(3, 10);
static struct gpio_t gpio_rffc5072_reset = GPIO(3, 11);
#endif
#if (defined JAWBREAKER || defined HACKRF_ONE) #if (defined JAWBREAKER || defined HACKRF_ONE)
static struct gpio_t gpio_rffc5072_select = GPIO(2, 13); static struct gpio_t gpio_rffc5072_select = GPIO(2, 13);
static struct gpio_t gpio_rffc5072_clock = GPIO(5, 6); static struct gpio_t gpio_rffc5072_clock = GPIO(5, 6);
static struct gpio_t gpio_rffc5072_data = GPIO(3, 3); static struct gpio_t gpio_rffc5072_data = GPIO(3, 3);
static struct gpio_t gpio_rffc5072_reset = GPIO(2, 14); static struct gpio_t gpio_rffc5072_reset = GPIO(2, 14);
#endif #endif
#ifdef RAD1O
static struct gpio_t gpio_vco_ce = GPIO(2, 13);
static struct gpio_t gpio_vco_sclk = GPIO(5, 6);
static struct gpio_t gpio_vco_sdata = GPIO(3, 3);
static struct gpio_t gpio_vco_le = GPIO(2, 14);
static struct gpio_t gpio_synt_rfout_en = GPIO(5, 25);
static struct gpio_t gpio_vco_mux = GPIO(3, 5);
#endif
#if (defined JAWBREAKER || defined HACKRF_ONE) #if (defined JAWBREAKER || defined HACKRF_ONE)
const rffc5071_spi_config_t rffc5071_spi_config = { const rffc5071_spi_config_t rffc5071_spi_config = {
@ -39,90 +41,104 @@ mixer_driver_t mixer = {
}; };
#endif #endif
#ifdef RAD1O #ifdef RAD1O
mixer_driver_t mixer; mixer_driver_t mixer = {
.gpio_vco_ce = &gpio_vco_ce,
.gpio_vco_sclk = &gpio_vco_sclk,
.gpio_vco_sdata = &gpio_vco_sdata,
.gpio_vco_le = &gpio_vco_le,
.gpio_synt_rfout_en = &gpio_synt_rfout_en,
.gpio_vco_mux = &gpio_vco_mux,
};
#endif #endif
void mixer_pin_setup(mixer_driver_t* const mixer) void mixer_bus_setup(mixer_driver_t* const mixer)
{ {
#if (defined JELLYBEAN || defined JAWBREAKER || defined HACKRF_ONE) #if (defined JAWBREAKER || defined HACKRF_ONE)
(void) mixer; (void) mixer;
spi_bus_start(&spi_bus_rffc5071, &rffc5071_spi_config); spi_bus_start(&spi_bus_rffc5071, &rffc5071_spi_config);
#endif #endif
#ifdef RAD1O #ifdef RAD1O
(void) mixer;
#endif #endif
} }
void mixer_setup(mixer_driver_t* const mixer) void mixer_setup(mixer_driver_t* const mixer)
{ {
#if (defined JELLYBEAN || defined JAWBREAKER || defined HACKRF_ONE) #if (defined JAWBREAKER || defined HACKRF_ONE)
rffc5071_setup(mixer); rffc5071_setup(mixer);
#endif #endif
#ifdef RAD1O #ifdef RAD1O
max2871_setup(mixer);
#endif #endif
} }
uint64_t mixer_set_frequency(mixer_driver_t* const mixer, uint16_t mhz) uint64_t mixer_set_frequency(mixer_driver_t* const mixer, uint16_t mhz)
{ {
#if (defined JELLYBEAN || defined JAWBREAKER || defined HACKRF_ONE) #if (defined JAWBREAKER || defined HACKRF_ONE)
return rffc5071_set_frequency(mixer, mhz); return rffc5071_set_frequency(mixer, mhz);
#endif #endif
#ifdef RAD1O #ifdef RAD1O
return max2871_set_frequency(mixer, mhz);
#endif #endif
} }
void mixer_tx(mixer_driver_t* const mixer) void mixer_tx(mixer_driver_t* const mixer)
{ {
#if (defined JELLYBEAN || defined JAWBREAKER || defined HACKRF_ONE) #if (defined JAWBREAKER || defined HACKRF_ONE)
rffc5071_tx(mixer); rffc5071_tx(mixer);
#endif #endif
#ifdef RAD1O #ifdef RAD1O
(void) mixer;
#endif #endif
} }
void mixer_rx(mixer_driver_t* const mixer) void mixer_rx(mixer_driver_t* const mixer)
{ {
#if (defined JELLYBEAN || defined JAWBREAKER || defined HACKRF_ONE) #if (defined JAWBREAKER || defined HACKRF_ONE)
rffc5071_rx(mixer); rffc5071_rx(mixer);
#endif #endif
#ifdef RAD1O #ifdef RAD1O
(void) mixer;
#endif #endif
} }
void mixer_rxtx(mixer_driver_t* const mixer) void mixer_rxtx(mixer_driver_t* const mixer)
{ {
#if (defined JELLYBEAN || defined JAWBREAKER || defined HACKRF_ONE) #if (defined JAWBREAKER || defined HACKRF_ONE)
rffc5071_rxtx(mixer); rffc5071_rxtx(mixer);
#endif #endif
#ifdef RAD1O #ifdef RAD1O
(void) mixer;
#endif #endif
} }
void mixer_enable(mixer_driver_t* const mixer) void mixer_enable(mixer_driver_t* const mixer)
{ {
#if (defined JELLYBEAN || defined JAWBREAKER || defined HACKRF_ONE) #if (defined JAWBREAKER || defined HACKRF_ONE)
rffc5071_enable(mixer); rffc5071_enable(mixer);
#endif #endif
#ifdef RAD1O #ifdef RAD1O
(void) mixer;
#endif #endif
} }
void mixer_disable(mixer_driver_t* const mixer) void mixer_disable(mixer_driver_t* const mixer)
{ {
#if (defined JELLYBEAN || defined JAWBREAKER || defined HACKRF_ONE) #if (defined JAWBREAKER || defined HACKRF_ONE)
rffc5071_disable(mixer); rffc5071_disable(mixer);
#endif #endif
#ifdef RAD1O #ifdef RAD1O
(void) mixer;
#endif #endif
} }
void mixer_set_gpo(mixer_driver_t* const mixer, uint8_t gpo) void mixer_set_gpo(mixer_driver_t* const mixer, uint8_t gpo)
{ {
#if (defined JELLYBEAN || defined JAWBREAKER || defined HACKRF_ONE) #if (defined JAWBREAKER || defined HACKRF_ONE)
rffc5071_set_gpo(mixer, gpo); rffc5071_set_gpo(mixer, gpo);
#endif #endif
#ifdef RAD1O #ifdef RAD1O
(void) mixer;
(void) gpo;
#endif #endif
} }

View File

@ -34,7 +34,7 @@ typedef max2871_driver_t mixer_driver_t;
#endif #endif
#include <stdint.h> #include <stdint.h>
extern void mixer_pin_setup(mixer_driver_t* const mixer); extern void mixer_bus_setup(mixer_driver_t* const mixer);
extern void mixer_setup(mixer_driver_t* const mixer); extern void mixer_setup(mixer_driver_t* const mixer);
/* Set frequency (MHz). */ /* Set frequency (MHz). */