Merge branch 'master' of git://github.com/mossmann/hackrf

This commit is contained in:
TitanMKD
2012-09-20 12:51:27 +02:00
4 changed files with 204 additions and 51 deletions

View File

@ -28,8 +28,6 @@
#include <libopencm3/lpc43xx/scu.h> #include <libopencm3/lpc43xx/scu.h>
#include <libopencm3/lpc43xx/ssp.h> #include <libopencm3/lpc43xx/ssp.h>
#ifdef JELLYBEAN
void delay(uint32_t duration) void delay(uint32_t duration)
{ {
uint32_t i; uint32_t i;
@ -51,6 +49,19 @@ void cpu_clock_init(void)
si5351c_configure_pll_sources_for_xtal(); si5351c_configure_pll_sources_for_xtal();
si5351c_configure_pll1_multisynth(); si5351c_configure_pll1_multisynth();
#ifdef JELLYBEAN
/*
* Jellybean/Lemondrop clocks:
* CLK0 -> MAX2837
* CLK1 -> MAX5864/CPLD
* CLK2 -> CPLD
* CLK3 -> CPLD
* CLK4 -> LPC4330
* CLK5 -> RFFC5072
* CLK6 -> extra
* CLK7 -> extra
*/
/* MS0/CLK0 is the source for the MAX2837 clock input. */ /* MS0/CLK0 is the source for the MAX2837 clock input. */
si5351c_configure_multisynth(0, 2048, 0, 1, 0); /* 40MHz */ si5351c_configure_multisynth(0, 2048, 0, 1, 0); /* 40MHz */
@ -68,6 +79,42 @@ void cpu_clock_init(void)
/* MS5/CLK5 is the source for the RFFC5071 mixer. */ /* MS5/CLK5 is the source for the RFFC5071 mixer. */
si5351c_configure_multisynth(5, 1536, 0, 1, 0); /* 50MHz */ si5351c_configure_multisynth(5, 1536, 0, 1, 0); /* 50MHz */
#endif
#ifdef JAWBREAKER
/*
* Jawbreaker clocks:
* CLK0 -> MAX5864/CPLD
* CLK1 -> CPLD
* CLK2 -> SGPIO
* CLK3 -> external clock output
* CLK4 -> RFFC5072
* CLK5 -> MAX2837
* CLK6 -> none
* CLK7 -> LPC4330 (but LPC4330 starts up on its own crystal)
*/
/* MS0/CLK0 is the source for the MAX5864/CPLD (CODEC_CLK). */
si5351c_configure_multisynth(0, 4608, 0, 1, 1); /* 10MHz */
/* MS0/CLK1 is the source for the CPLD (CODEC_X2_CLK). */
si5351c_configure_multisynth(1, 4608, 0, 1, 0); /* 20MHz */
/* MS0/CLK2 is the source for SGPIO (CODEC_X2_CLK) */
si5351c_configure_multisynth(2, 4608, 0, 1, 0); /* 20MHz */
/* MS0/CLK3 is the source for the external clock output. */
si5351c_configure_multisynth(3, 4608, 0, 1, 0); /* 20MHz */
/* MS4/CLK4 is the source for the RFFC5071 mixer. */
si5351c_configure_multisynth(4, 1536, 0, 1, 0); /* 50MHz */
/* MS5/CLK5 is the source for the MAX2837 clock input. */
si5351c_configure_multisynth(5, 2048, 0, 1, 0); /* 40MHz */
/* MS7/CLK7 is the source for the LPC43xx microcontroller. */
//si5351c_configure_multisynth(7, 8021, 0, 3, 0); /* 12MHz */
#endif
si5351c_configure_clock_control(); si5351c_configure_clock_control();
si5351c_enable_clock_outputs(); si5351c_enable_clock_outputs();
@ -203,5 +250,3 @@ void ssp1_set_mode_max5864(void)
SSP_MASTER, SSP_MASTER,
SSP_SLAVE_OUT_ENABLE); SSP_SLAVE_OUT_ENABLE);
} }
#endif

View File

@ -30,15 +30,19 @@ extern "C"
#endif #endif
/* hardware identification number */ /* hardware identification number */
#define BOARD_ID_JELLYBEAN 0 #define BOARD_ID_JELLYBEAN 0
#define BOARD_ID_JAWBREAKER 1
#ifdef JELLYBEAN #ifdef JELLYBEAN
#define BOARD_ID BOARD_ID_JELLYBEAN #define BOARD_ID BOARD_ID_JELLYBEAN
#endif #endif
#ifdef JELLYBEAN #ifdef JAWBREAKER
#define BOARD_ID BOARD_ID_JAWBREAKER
#endif
/* /*
* Jellybean SCU PinMux * SCU PinMux
*/ */
/* GPIO Output PinMux */ /* GPIO Output PinMux */
@ -94,14 +98,28 @@ extern "C"
#define SCU_AD_CS (P5_7) /* GPIO2[7] on P5_7 */ #define SCU_AD_CS (P5_7) /* GPIO2[7] on P5_7 */
/* RFFC5071 GPIO serial interface PinMux */ /* RFFC5071 GPIO serial interface PinMux */
#ifdef JELLYBEAN
#define SCU_MIXER_ENX (P7_0) /* GPIO3[8] on P7_0 */ #define SCU_MIXER_ENX (P7_0) /* GPIO3[8] on P7_0 */
#define SCU_MIXER_SCLK (P7_1) /* GPIO3[9] on P7_1 */ #define SCU_MIXER_SCLK (P7_1) /* GPIO3[9] on P7_1 */
#define SCU_MIXER_SDATA (P7_2) /* GPIO3[10] on P7_2 */ #define SCU_MIXER_SDATA (P7_2) /* GPIO3[10] on P7_2 */
#define SCU_MIXER_RESETX (P7_3) /* GPIO3[11] on P7_3 */
#endif
#ifdef JAWBREAKER
#define SCU_MIXER_ENX (P5_4) /* GPIO2[13] on P5_4 */
#define SCU_MIXER_SCLK (P2_6) /* GPIO5[6] on P2_6 */
#define SCU_MIXER_SDATA (P6_4) /* GPIO3[3] on P6_4 */
#define SCU_MIXER_RESETX (P5_5) /* GPIO2[14] on P5_5 */
#endif
/* RF LDO control */
#ifdef JAWBREAKER
#define RF_LDO_ENABLE (P5_0) /* GPIO2[9] on P5_0 */
#endif
/* TODO add other Pins */ /* TODO add other Pins */
/* /*
* Jellybean GPIO Pins * GPIO Pins
*/ */
/* GPIO Output */ /* GPIO Output */
@ -123,10 +141,31 @@ extern "C"
#define PIN_AD_CS (BIT7) /* GPIO2[7] on P5_7 */ #define PIN_AD_CS (BIT7) /* GPIO2[7] on P5_7 */
#define PORT_AD_CS (GPIO2) /* PORT for AD_CS */ #define PORT_AD_CS (GPIO2) /* PORT for AD_CS */
#define PIN_MIXER_ENX (BIT8) /* GPIO3[8] on P7_0 */ #ifdef JELLYBEAN
#define PIN_MIXER_SCLK (BIT9) /* GPIO3[9] on P7_1 */ #define PIN_MIXER_ENX (BIT8) /* GPIO3[8] on P7_0 */
#define PIN_MIXER_SDATA (BIT10) /* GPIO3[10] on P7_2 */ #define PORT_MIXER_ENX (GPIO3)
#define PORT_MIXER (GPIO3) /* PORT for mixer serial interface */ #define PIN_MIXER_SCLK (BIT9) /* GPIO3[9] on P7_1 */
#define PORT_MIXER_SCLK (GPIO3)
#define PIN_MIXER_SDATA (BIT10) /* GPIO3[10] on P7_2 */
#define PORT_MIXER_SDATA (GPIO3)
#define PIN_MIXER_RESETX (BIT11) /* GPIO3[11] on P7_3 */
#define PORT_MIXER_RESETX (GPIO3)
#endif
#ifdef JAWBREAKER
#define PIN_MIXER_ENX (BIT13) /* GPIO2[13] on P5_4 */
#define PORT_MIXER_ENX (GPIO2)
#define PIN_MIXER_SCLK (BIT6) /* GPIO5[6] on P2_6 */
#define PORT_MIXER_SCLK (GPIO5)
#define PIN_MIXER_SDATA (BIT3) /* GPIO3[3] on P6_4 */
#define PORT_MIXER_SDATA (GPIO3)
#define PIN_MIXER_RESETX (BIT14) /* GPIO2[14] on P5_5 */
#define PORT_MIXER_RESETX (GPIO2)
#endif
#ifdef JAWBREAKER
#define PIN_RF_LDO_ENABLE (BIT9) /* GPIO2[9] on P5_0 */
#define PORT_RF_LDO_ENABLE (GPIO2) /* PORT for RF_LDO_ENABLE */
#endif
/* GPIO Input */ /* GPIO Input */
#define PIN_BOOT0 (BIT8) /* GPIO0[8] on P1_1 */ #define PIN_BOOT0 (BIT8) /* GPIO0[8] on P1_1 */
@ -145,14 +184,14 @@ extern "C"
#define PORT_CPLD_TDI (GPIO3) #define PORT_CPLD_TDI (GPIO3)
/* Read GPIO Pin */ /* Read GPIO Pin */
#define BOOT0_STATE ((GPIO0_PIN & PIN_BOOT0)==PIN_BOOT0) #define GPIO_STATE(port, pin) ((GPIO_PIN(port) & (pin)) == (pin))
#define BOOT1_STATE ((GPIO0_PIN & PIN_BOOT1)==PIN_BOOT1) #define BOOT0_STATE GPIO_STATE(GPIO0, PIN_BOOT0)
#define BOOT2_STATE ((GPIO5_PIN & PIN_BOOT2)==PIN_BOOT2) #define BOOT1_STATE GPIO_STATE(GPIO0, PIN_BOOT1)
#define BOOT3_STATE ((GPIO1_PIN & PIN_BOOT3)==PIN_BOOT3) #define BOOT2_STATE GPIO_STATE(GPIO5, PIN_BOOT2)
#define MIXER_SDATA_STATE ((GPIO3_PIN & PIN_MIXER_SDATA)==PIN_MIXER_SDATA) #define BOOT3_STATE GPIO_STATE(GPIO1, PIN_BOOT3)
#define MIXER_SDATA_STATE GPIO_STATE(PORT_MIXER_SDATA, PIN_MIXER_SDATA)
/* TODO add other Pins */ /* TODO add other Pins */
#endif
void cpu_clock_init(void); void cpu_clock_init(void);
void ssp1_init(void); void ssp1_init(void);

View File

@ -103,13 +103,19 @@ void rffc5071_setup(void)
scu_pinmux(SCU_MIXER_ENX, SCU_GPIO_FAST); scu_pinmux(SCU_MIXER_ENX, SCU_GPIO_FAST);
scu_pinmux(SCU_MIXER_SCLK, SCU_GPIO_FAST); scu_pinmux(SCU_MIXER_SCLK, SCU_GPIO_FAST);
scu_pinmux(SCU_MIXER_SDATA, SCU_GPIO_FAST); scu_pinmux(SCU_MIXER_SDATA, SCU_GPIO_FAST);
scu_pinmux(SCU_MIXER_RESETX, SCU_GPIO_FAST);
/* Set GPIO pins as outputs. */ /* Set GPIO pins as outputs. */
GPIO3_DIR |= (PIN_MIXER_ENX | PIN_MIXER_SCLK | PIN_MIXER_SDATA); GPIO_DIR(PORT_MIXER_ENX) |= PIN_MIXER_ENX;
GPIO_DIR(PORT_MIXER_SCLK) |= PIN_MIXER_SCLK;
GPIO_DIR(PORT_MIXER_SDATA) |= PIN_MIXER_SDATA;
GPIO_DIR(PORT_MIXER_RESETX) |= PIN_MIXER_RESETX;
/* set to known state */ /* set to known state */
gpio_set(PORT_MIXER, PIN_MIXER_ENX); /* active low */ gpio_set(PORT_MIXER_ENX, PIN_MIXER_ENX); /* active low */
gpio_clear(PORT_MIXER, (PIN_MIXER_SCLK | PIN_MIXER_SDATA)); gpio_clear(PORT_MIXER_SCLK, PIN_MIXER_SCLK);
gpio_clear(PORT_MIXER_SDATA, PIN_MIXER_SDATA);
gpio_set(PORT_MIXER_RESETX, PIN_MIXER_RESETX); /* active low */
#endif #endif
/* initial setup */ /* initial setup */
@ -185,69 +191,70 @@ uint16_t rffc5071_spi_read(uint8_t r) {
return 0; return 0;
#else #else
/* make sure everything is starting in the correct state */ /* make sure everything is starting in the correct state */
gpio_set(PORT_MIXER, PIN_MIXER_ENX); gpio_set(PORT_MIXER_ENX, PIN_MIXER_ENX);
gpio_clear(PORT_MIXER, (PIN_MIXER_SCLK | PIN_MIXER_SDATA)); gpio_clear(PORT_MIXER_SCLK, PIN_MIXER_SCLK);
gpio_clear(PORT_MIXER_SDATA, PIN_MIXER_SDATA);
/* /*
* The device requires two clocks while ENX is high before a serial * The device requires two clocks while ENX is high before a serial
* transaction. This is not clearly documented. * transaction. This is not clearly documented.
*/ */
serial_delay(); serial_delay();
gpio_set(PORT_MIXER, PIN_MIXER_SCLK); gpio_set(PORT_MIXER_SCLK, PIN_MIXER_SCLK);
serial_delay(); serial_delay();
gpio_clear(PORT_MIXER, PIN_MIXER_SCLK); gpio_clear(PORT_MIXER_SCLK, PIN_MIXER_SCLK);
serial_delay(); serial_delay();
gpio_set(PORT_MIXER, PIN_MIXER_SCLK); gpio_set(PORT_MIXER_SCLK, PIN_MIXER_SCLK);
serial_delay(); serial_delay();
gpio_clear(PORT_MIXER, PIN_MIXER_SCLK); gpio_clear(PORT_MIXER_SCLK, PIN_MIXER_SCLK);
/* start transaction by bringing ENX low */ /* start transaction by bringing ENX low */
gpio_clear(PORT_MIXER, PIN_MIXER_ENX); gpio_clear(PORT_MIXER_ENX, PIN_MIXER_ENX);
while (bits--) { while (bits--) {
if (data & msb) if (data & msb)
gpio_set(PORT_MIXER, PIN_MIXER_SDATA); gpio_set(PORT_MIXER_SDATA, PIN_MIXER_SDATA);
else else
gpio_clear(PORT_MIXER, PIN_MIXER_SDATA); gpio_clear(PORT_MIXER_SDATA, PIN_MIXER_SDATA);
data <<= 1; data <<= 1;
serial_delay(); serial_delay();
gpio_set(PORT_MIXER, PIN_MIXER_SCLK); gpio_set(PORT_MIXER_SCLK, PIN_MIXER_SCLK);
serial_delay(); serial_delay();
gpio_clear(PORT_MIXER, PIN_MIXER_SCLK); gpio_clear(PORT_MIXER_SCLK, PIN_MIXER_SCLK);
} }
serial_delay(); serial_delay();
gpio_set(PORT_MIXER, PIN_MIXER_SCLK); gpio_set(PORT_MIXER_SCLK, PIN_MIXER_SCLK);
serial_delay(); serial_delay();
gpio_clear(PORT_MIXER, PIN_MIXER_SCLK); gpio_clear(PORT_MIXER_SCLK, PIN_MIXER_SCLK);
bits = 16; bits = 16;
data = 0; data = 0;
/* set SDATA line as input */ /* set SDATA line as input */
GPIO3_DIR &= ~PIN_MIXER_SDATA; GPIO_DIR(PORT_MIXER_SDATA) &= ~PIN_MIXER_SDATA;
while (bits--) { while (bits--) {
data <<= 1; data <<= 1;
serial_delay(); serial_delay();
gpio_set(PORT_MIXER, PIN_MIXER_SCLK); gpio_set(PORT_MIXER_SCLK, PIN_MIXER_SCLK);
serial_delay(); serial_delay();
gpio_clear(PORT_MIXER, PIN_MIXER_SCLK); gpio_clear(PORT_MIXER_SCLK, PIN_MIXER_SCLK);
if (MIXER_SDATA_STATE) if (MIXER_SDATA_STATE)
data |= 1; data |= 1;
} }
/* set SDATA line as output */ /* set SDATA line as output */
GPIO3_DIR |= PIN_MIXER_SDATA; GPIO_DIR(PORT_MIXER_SDATA) |= PIN_MIXER_SDATA;
serial_delay(); serial_delay();
gpio_set(PORT_MIXER, PIN_MIXER_ENX); gpio_set(PORT_MIXER_ENX, PIN_MIXER_ENX);
return data; return data;
#endif /* DEBUG */ #endif /* DEBUG */
@ -272,44 +279,45 @@ void rffc5071_spi_write(uint8_t r, uint16_t v) {
uint32_t data = ((r & 0x7f) << 16) | v; uint32_t data = ((r & 0x7f) << 16) | v;
/* make sure everything is starting in the correct state */ /* make sure everything is starting in the correct state */
gpio_set(PORT_MIXER, PIN_MIXER_ENX); gpio_set(PORT_MIXER_ENX, PIN_MIXER_ENX);
gpio_clear(PORT_MIXER, (PIN_MIXER_SCLK | PIN_MIXER_SDATA)); gpio_clear(PORT_MIXER_SCLK, PIN_MIXER_SCLK);
gpio_clear(PORT_MIXER_SDATA, PIN_MIXER_SDATA);
/* /*
* The device requires two clocks while ENX is high before a serial * The device requires two clocks while ENX is high before a serial
* transaction. This is not clearly documented. * transaction. This is not clearly documented.
*/ */
serial_delay(); serial_delay();
gpio_set(PORT_MIXER, PIN_MIXER_SCLK); gpio_set(PORT_MIXER_SCLK, PIN_MIXER_SCLK);
serial_delay(); serial_delay();
gpio_clear(PORT_MIXER, PIN_MIXER_SCLK); gpio_clear(PORT_MIXER_SCLK, PIN_MIXER_SCLK);
serial_delay(); serial_delay();
gpio_set(PORT_MIXER, PIN_MIXER_SCLK); gpio_set(PORT_MIXER_SCLK, PIN_MIXER_SCLK);
serial_delay(); serial_delay();
gpio_clear(PORT_MIXER, PIN_MIXER_SCLK); gpio_clear(PORT_MIXER_SCLK, PIN_MIXER_SCLK);
/* start transaction by bringing ENX low */ /* start transaction by bringing ENX low */
gpio_clear(PORT_MIXER, PIN_MIXER_ENX); gpio_clear(PORT_MIXER_ENX, PIN_MIXER_ENX);
while (bits--) { while (bits--) {
if (data & msb) if (data & msb)
gpio_set(PORT_MIXER, PIN_MIXER_SDATA); gpio_set(PORT_MIXER_SDATA, PIN_MIXER_SDATA);
else else
gpio_clear(PORT_MIXER, PIN_MIXER_SDATA); gpio_clear(PORT_MIXER_SDATA, PIN_MIXER_SDATA);
data <<= 1; data <<= 1;
serial_delay(); serial_delay();
gpio_set(PORT_MIXER, PIN_MIXER_SCLK); gpio_set(PORT_MIXER_SCLK, PIN_MIXER_SCLK);
serial_delay(); serial_delay();
gpio_clear(PORT_MIXER, PIN_MIXER_SCLK); gpio_clear(PORT_MIXER_SCLK, PIN_MIXER_SCLK);
} }
serial_delay(); serial_delay();
gpio_set(PORT_MIXER, PIN_MIXER_ENX); gpio_set(PORT_MIXER_ENX, PIN_MIXER_ENX);
#endif #endif
} }

View File

@ -161,6 +161,7 @@ void si5351c_configure_multisynth(const uint_fast8_t ms_number,
si5351c_write(data, sizeof(data)); si5351c_write(data, sizeof(data));
} }
#ifdef JELLYBEAN
/* /*
* Registers 16 through 23: CLKx Control * Registers 16 through 23: CLKx Control
* CLK0: * CLK0:
@ -211,6 +212,66 @@ void si5351c_configure_clock_control()
uint8_t data[] = { 16, 0x4F, 0x4B, 0x4B, 0x4B, 0x0F, 0x4F, 0xC0, 0xC0 }; uint8_t data[] = { 16, 0x4F, 0x4B, 0x4B, 0x4B, 0x0F, 0x4F, 0xC0, 0xC0 };
si5351c_write(data, sizeof(data)); si5351c_write(data, sizeof(data));
} }
#endif
#ifdef JAWBREAKER
/*
* Registers 16 through 23: CLKx Control
* CLK0:
* CLK0_PDN=0 (powered up)
* MS0_INT=1 (integer mode)
* MS0_SRC=0 (PLLA as source for MultiSynth 0)
* CLK0_INV=0 (not inverted)
* CLK0_SRC=3 (MS0 as input source)
* CLK0_IDRV=3 (8mA)
* CLK1:
* CLK1_PDN=0 (powered up)
* MS1_INT=1 (integer mode)
* MS1_SRC=0 (PLLA as source for MultiSynth 1)
* CLK1_INV=0 (not inverted)
* CLK1_SRC=2 (MS0 as input source)
* CLK1_IDRV=3 (8mA)
* CLK2:
* CLK2_PDN=0 (powered up)
* MS2_INT=1 (integer mode)
* MS2_SRC=0 (PLLA as source for MultiSynth 2)
* CLK2_INV=0 (not inverted)
* CLK2_SRC=2 (MS0 as input source)
* CLK2_IDRV=3 (8mA)
* CLK3:
* CLK3_PDN=0 (powered up)
* MS3_INT=1 (integer mode)
* MS3_SRC=0 (PLLA as source for MultiSynth 3)
* CLK3_INV=0 (inverted)
* CLK3_SRC=2 (MS0 as input source)
* CLK3_IDRV=3 (8mA)
* CLK4:
* CLK4_PDN=0 (powered up)
* MS4_INT=1 (integer mode)
* MS4_SRC=0 (PLLA as source for MultiSynth 4)
* CLK4_INV=0 (not inverted)
* CLK4_SRC=3 (MS4 as input source)
* CLK4_IDRV=3 (8mA)
* CLK5:
* CLK5_PDN=0 (powered up)
* MS5_INT=1 (integer mode)
* MS5_SRC=0 (PLLA as source for MultiSynth 5)
* CLK5_INV=0 (not inverted)
* CLK5_SRC=3 (MS5 as input source)
* CLK5_IDRV=3 (8mA)
* CLK6: (not connected)
* CLK5_PDN=1 (powered down)
* MS5_INT=1 (integer mode)
* CLK7: (not connected)
* CLK7_PDN=1 (powered down)
* MS7_INT=0 (fractional mode -- to support 12MHz to LPC)
*/
void si5351c_configure_clock_control()
{
uint8_t data[] = { 16, 0x4F, 0x4B, 0x4B, 0x4B, 0x4F, 0x4F, 0xC0, 0x80 };
si5351c_write(data, sizeof(data));
}
#endif
/* Enable CLK outputs 0, 1, 2, 3, 4, 5 only. */ /* Enable CLK outputs 0, 1, 2, 3, 4, 5 only. */
void si5351c_enable_clock_outputs() void si5351c_enable_clock_outputs()