diff --git a/firmware/common/max2837.c b/firmware/common/max2837.c index 020763d6..73d9e1cd 100644 --- a/firmware/common/max2837.c +++ b/firmware/common/max2837.c @@ -1,3 +1,25 @@ +/* + * Copyright 2012 Will Code? (TODO: Proper attribution) + * Copyright 2014 Jared Boone + * + * This file is part of HackRF. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + /* * 'gcc -DTEST -DDEBUG -O2 -o test max2837.c' prints out what test * program would do if it had a real spi library @@ -9,6 +31,7 @@ #include #include #include "max2837.h" +#include "max2837_drv.h" #include "max2837_regs.def" // private register def macros #if (defined DEBUG || defined BUS_PIRATE) @@ -16,9 +39,6 @@ #define LOG printf #else #define LOG(x,...) -#include -#include -#include #include "hackrf_core.h" #endif @@ -85,51 +105,7 @@ void max2837_init(void) void max2837_setup(void) { LOG("# max2837_setup\n"); -#if !defined TEST - /* Configure XCVR_CTL GPIO pins. */ -#ifdef JELLYBEAN - scu_pinmux(SCU_XCVR_RXHP, SCU_GPIO_FAST); - scu_pinmux(SCU_XCVR_B1, SCU_GPIO_FAST); - scu_pinmux(SCU_XCVR_B2, SCU_GPIO_FAST); - scu_pinmux(SCU_XCVR_B3, SCU_GPIO_FAST); - scu_pinmux(SCU_XCVR_B4, SCU_GPIO_FAST); - scu_pinmux(SCU_XCVR_B5, SCU_GPIO_FAST); - scu_pinmux(SCU_XCVR_B6, SCU_GPIO_FAST); - scu_pinmux(SCU_XCVR_B7, SCU_GPIO_FAST); -#endif - scu_pinmux(SCU_XCVR_ENABLE, SCU_GPIO_FAST); - scu_pinmux(SCU_XCVR_RXENABLE, SCU_GPIO_FAST); - scu_pinmux(SCU_XCVR_TXENABLE, SCU_GPIO_FAST); - - /* Set GPIO pins as outputs. */ - GPIO2_DIR |= (PIN_XCVR_ENABLE | PIN_XCVR_RXENABLE | PIN_XCVR_TXENABLE); -#ifdef JELLYBEAN - GPIO_DIR(PORT_XCVR_RXHP) |= PIN_XCVR_RXHP; - GPIO_DIR(PORT_XCVR_B) |= - PIN_XCVR_B1 - | PIN_XCVR_B2 - | PIN_XCVR_B3 - | PIN_XCVR_B4 - | PIN_XCVR_B5 - | PIN_XCVR_B6 - | PIN_XCVR_B7 - ; -#endif - - max2837_mode_shutdown(); -#ifdef JELLYBEAN - gpio_set(PORT_XCVR_RXHP, PIN_XCVR_RXHP); - gpio_set(PORT_XCVR_B, - PIN_XCVR_B1 - | PIN_XCVR_B2 - | PIN_XCVR_B3 - | PIN_XCVR_B4 - | PIN_XCVR_B5 - | PIN_XCVR_B6 - | PIN_XCVR_B7 - ); -#endif -#endif + max2837_pin_config(); max2837_init(); LOG("# max2837_init done\n"); @@ -159,29 +135,6 @@ void max2837_setup(void) max2837_regs_commit(); } -/* SPI register read. */ -uint16_t max2837_spi_read(uint8_t r) { - gpio_clear(PORT_XCVR_CS, PIN_XCVR_CS); - const uint16_t value = ssp_transfer(SSP1_NUM, (uint16_t)((1 << 15) | (r << 10))); - gpio_set(PORT_XCVR_CS, PIN_XCVR_CS); - return value & 0x3ff; -} - -/* SPI register write */ -void max2837_spi_write(uint8_t r, uint16_t v) { - -#ifdef BUS_PIRATE - LOG("{0x%02x 0x%02x]\n", 0x00 | ((uint16_t)r<<2) | ((v>>8) & 0x3), - v & 0xff); -#elif DEBUG - LOG("0x%03x -> reg%d\n", v, r); -#else - gpio_clear(PORT_XCVR_CS, PIN_XCVR_CS); - ssp_transfer(SSP1_NUM, (uint16_t)((r << 10) | (v & 0x3ff))); - gpio_set(PORT_XCVR_CS, PIN_XCVR_CS); -#endif -} - uint16_t max2837_reg_read(uint8_t r) { if ((max2837_regs_dirty >> r) & 0x1) { @@ -197,12 +150,6 @@ void max2837_reg_write(uint8_t r, uint16_t v) MAX2837_REG_SET_CLEAN(r); } -/* This functions should not be needed, and might be confusing. DELETE. */ -void max2837_regs_read(void) -{ - ; -} - static inline void max2837_reg_commit(uint8_t r) { max2837_reg_write(r,max2837_regs[r]); @@ -218,60 +165,6 @@ void max2837_regs_commit(void) } } -void max2837_mode_shutdown(void) { - /* All circuit blocks are powered down, except the 4-wire serial bus - * and its internal programmable registers. - */ - gpio_clear(PORT_XCVR_ENABLE, - (PIN_XCVR_ENABLE | PIN_XCVR_RXENABLE | PIN_XCVR_TXENABLE)); -} - -void max2837_mode_standby(void) { - /* Used to enable the frequency synthesizer block while the rest of the - * device is powered down. In this mode, PLL, VCO, and LO generator - * are on, so that Tx or Rx modes can be quickly enabled from this mode. - * These and other blocks can be selectively enabled in this mode. - */ - gpio_clear(PORT_XCVR_ENABLE, (PIN_XCVR_RXENABLE | PIN_XCVR_TXENABLE)); - gpio_set(PORT_XCVR_ENABLE, PIN_XCVR_ENABLE); -} - -void max2837_mode_tx(void) { - /* All Tx circuit blocks are powered on. The external PA is powered on - * after a programmable delay using the on-chip PA bias DAC. The slow- - * charging Rx circuits are in a precharged “idle-off” state for fast - * Tx-to-Rx turnaround time. - */ - gpio_clear(PORT_XCVR_ENABLE, PIN_XCVR_RXENABLE); - gpio_set(PORT_XCVR_ENABLE, - (PIN_XCVR_ENABLE | PIN_XCVR_TXENABLE)); -} - -void max2837_mode_rx(void) { - /* All Rx circuit blocks are powered on and active. Antenna signal is - * applied; RF is downconverted, filtered, and buffered at Rx BB I and Q - * outputs. The slow- charging Tx circuits are in a precharged “idle-off” - * state for fast Rx-to-Tx turnaround time. - */ - gpio_clear(PORT_XCVR_ENABLE, PIN_XCVR_TXENABLE); - gpio_set(PORT_XCVR_ENABLE, - (PIN_XCVR_ENABLE | PIN_XCVR_RXENABLE)); -} - -max2837_mode_t max2837_mode(void) { - if( gpio_get(PORT_XCVR_ENABLE, PIN_XCVR_ENABLE) ) { - if( gpio_get(PORT_XCVR_ENABLE, PIN_XCVR_TXENABLE) ) { - return MAX2837_MODE_TX; - } else if( gpio_get(PORT_XCVR_ENABLE, PIN_XCVR_RXENABLE) ) { - return MAX2837_MODE_RX; - } else { - return MAX2837_MODE_STANDBY; - } - } else { - return MAX2837_MODE_SHUTDOWN; - } -} - void max2837_set_mode(const max2837_mode_t new_mode) { switch(new_mode) { case MAX2837_MODE_SHUTDOWN: diff --git a/firmware/common/max2837.h b/firmware/common/max2837.h index 582a0966..d1563d86 100644 --- a/firmware/common/max2837.h +++ b/firmware/common/max2837.h @@ -1,9 +1,33 @@ +/* + * Copyright 2012 Will Code? (TODO: Proper attribution) + * Copyright 2014 Jared Boone + * + * This file is part of HackRF. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + #ifndef __MAX2837_H #define __MAX2837_H #include #include +#include "max2837_drv.h" + /* TODO - make this a private header for max2837.c only, make new max2837.h */ /* 32 registers, each containing 10 bits of data. */ @@ -29,21 +53,11 @@ extern uint16_t max2837_reg_read(uint8_t r); * clean. */ extern void max2837_reg_write(uint8_t r, uint16_t v); -/* Read all registers from chip and copy to memory. Mark all clean. */ -extern void max2837_regs_read(void); - /* Write all dirty registers via SPI from memory. Mark all clean. Some * operations require registers to be written in a certain order. Use * provided routines for those operations. */ extern void max2837_regs_commit(void); -typedef enum { - MAX2837_MODE_SHUTDOWN, - MAX2837_MODE_STANDBY, - MAX2837_MODE_TX, - MAX2837_MODE_RX -} max2837_mode_t; - void max2837_mode_shutdown(void); void max2837_mode_standby(void); void max2837_mode_tx(void); diff --git a/firmware/common/max2837_drv.c b/firmware/common/max2837_drv.c new file mode 100644 index 00000000..235869c1 --- /dev/null +++ b/firmware/common/max2837_drv.c @@ -0,0 +1,159 @@ +/* + * Copyright 2012 Will Code? (TODO: Proper attribution) + * Copyright 2014 Jared Boone + * + * This file is part of HackRF. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#include "max2837_drv.h" + +#if (defined DEBUG || defined BUS_PIRATE) +#include +#define LOG printf +#else +#define LOG(x,...) +#include +#include +#include +#include "hackrf_core.h" +#endif + +void max2837_pin_config(void) { +#if !defined TEST + /* Configure XCVR_CTL GPIO pins. */ +#ifdef JELLYBEAN + scu_pinmux(SCU_XCVR_RXHP, SCU_GPIO_FAST); + scu_pinmux(SCU_XCVR_B1, SCU_GPIO_FAST); + scu_pinmux(SCU_XCVR_B2, SCU_GPIO_FAST); + scu_pinmux(SCU_XCVR_B3, SCU_GPIO_FAST); + scu_pinmux(SCU_XCVR_B4, SCU_GPIO_FAST); + scu_pinmux(SCU_XCVR_B5, SCU_GPIO_FAST); + scu_pinmux(SCU_XCVR_B6, SCU_GPIO_FAST); + scu_pinmux(SCU_XCVR_B7, SCU_GPIO_FAST); +#endif + scu_pinmux(SCU_XCVR_ENABLE, SCU_GPIO_FAST); + scu_pinmux(SCU_XCVR_RXENABLE, SCU_GPIO_FAST); + scu_pinmux(SCU_XCVR_TXENABLE, SCU_GPIO_FAST); + + /* Set GPIO pins as outputs. */ + GPIO2_DIR |= (PIN_XCVR_ENABLE | PIN_XCVR_RXENABLE | PIN_XCVR_TXENABLE); +#ifdef JELLYBEAN + GPIO_DIR(PORT_XCVR_RXHP) |= PIN_XCVR_RXHP; + GPIO_DIR(PORT_XCVR_B) |= + PIN_XCVR_B1 + | PIN_XCVR_B2 + | PIN_XCVR_B3 + | PIN_XCVR_B4 + | PIN_XCVR_B5 + | PIN_XCVR_B6 + | PIN_XCVR_B7 + ; +#endif + + max2837_mode_shutdown(); +#ifdef JELLYBEAN + gpio_set(PORT_XCVR_RXHP, PIN_XCVR_RXHP); + gpio_set(PORT_XCVR_B, + PIN_XCVR_B1 + | PIN_XCVR_B2 + | PIN_XCVR_B3 + | PIN_XCVR_B4 + | PIN_XCVR_B5 + | PIN_XCVR_B6 + | PIN_XCVR_B7 + ); +#endif +#endif +} + +void max2837_mode_shutdown(void) { + /* All circuit blocks are powered down, except the 4-wire serial bus + * and its internal programmable registers. + */ + gpio_clear(PORT_XCVR_ENABLE, + (PIN_XCVR_ENABLE | PIN_XCVR_RXENABLE | PIN_XCVR_TXENABLE)); +} + +void max2837_mode_standby(void) { + /* Used to enable the frequency synthesizer block while the rest of the + * device is powered down. In this mode, PLL, VCO, and LO generator + * are on, so that Tx or Rx modes can be quickly enabled from this mode. + * These and other blocks can be selectively enabled in this mode. + */ + gpio_clear(PORT_XCVR_ENABLE, (PIN_XCVR_RXENABLE | PIN_XCVR_TXENABLE)); + gpio_set(PORT_XCVR_ENABLE, PIN_XCVR_ENABLE); +} + +void max2837_mode_tx(void) { + /* All Tx circuit blocks are powered on. The external PA is powered on + * after a programmable delay using the on-chip PA bias DAC. The slow- + * charging Rx circuits are in a precharged “idle-off” state for fast + * Tx-to-Rx turnaround time. + */ + gpio_clear(PORT_XCVR_ENABLE, PIN_XCVR_RXENABLE); + gpio_set(PORT_XCVR_ENABLE, + (PIN_XCVR_ENABLE | PIN_XCVR_TXENABLE)); +} + +void max2837_mode_rx(void) { + /* All Rx circuit blocks are powered on and active. Antenna signal is + * applied; RF is downconverted, filtered, and buffered at Rx BB I and Q + * outputs. The slow- charging Tx circuits are in a precharged “idle-off” + * state for fast Rx-to-Tx turnaround time. + */ + gpio_clear(PORT_XCVR_ENABLE, PIN_XCVR_TXENABLE); + gpio_set(PORT_XCVR_ENABLE, + (PIN_XCVR_ENABLE | PIN_XCVR_RXENABLE)); +} + +max2837_mode_t max2837_mode(void) { + if( gpio_get(PORT_XCVR_ENABLE, PIN_XCVR_ENABLE) ) { + if( gpio_get(PORT_XCVR_ENABLE, PIN_XCVR_TXENABLE) ) { + return MAX2837_MODE_TX; + } else if( gpio_get(PORT_XCVR_ENABLE, PIN_XCVR_RXENABLE) ) { + return MAX2837_MODE_RX; + } else { + return MAX2837_MODE_STANDBY; + } + } else { + return MAX2837_MODE_SHUTDOWN; + } +} + +/* SPI register read. */ +uint16_t max2837_spi_read(uint8_t r) { + gpio_clear(PORT_XCVR_CS, PIN_XCVR_CS); + const uint16_t value = ssp_transfer(SSP1_NUM, (uint16_t)((1 << 15) | (r << 10))); + gpio_set(PORT_XCVR_CS, PIN_XCVR_CS); + return value & 0x3ff; +} + +/* SPI register write */ +void max2837_spi_write(uint8_t r, uint16_t v) { + +#ifdef BUS_PIRATE + LOG("{0x%02x 0x%02x]\n", 0x00 | ((uint16_t)r<<2) | ((v>>8) & 0x3), + v & 0xff); +#elif DEBUG + LOG("0x%03x -> reg%d\n", v, r); +#else + gpio_clear(PORT_XCVR_CS, PIN_XCVR_CS); + ssp_transfer(SSP1_NUM, (uint16_t)((r << 10) | (v & 0x3ff))); + gpio_set(PORT_XCVR_CS, PIN_XCVR_CS); +#endif +} diff --git a/firmware/common/max2837_drv.h b/firmware/common/max2837_drv.h new file mode 100644 index 00000000..a2d61253 --- /dev/null +++ b/firmware/common/max2837_drv.h @@ -0,0 +1,45 @@ +/* + * Copyright 2012 Will Code? (TODO: Proper attribution) + * Copyright 2014 Jared Boone + * + * This file is part of HackRF. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef __MAX2837_DRV_H +#define __MAX2837_DRV_H + +#include + +typedef enum { + MAX2837_MODE_SHUTDOWN, + MAX2837_MODE_STANDBY, + MAX2837_MODE_TX, + MAX2837_MODE_RX +} max2837_mode_t; + +void max2837_pin_config(void); +void max2837_mode_shutdown(void); +void max2837_mode_standby(void); +void max2837_mode_tx(void); +void max2837_mode_rx(void); +max2837_mode_t max2837_mode(void); + +uint16_t max2837_spi_read(uint8_t r); +void max2837_spi_write(uint8_t r, uint16_t v); + +#endif // __MAX2837_DRV_H diff --git a/firmware/hackrf-common.cmake b/firmware/hackrf-common.cmake index df5d5c96..091f9d43 100644 --- a/firmware/hackrf-common.cmake +++ b/firmware/hackrf-common.cmake @@ -135,6 +135,7 @@ macro(DeclareTargets) ${PATH_HACKRF_FIRMWARE_COMMON}/rf_path.c ${PATH_HACKRF_FIRMWARE_COMMON}/si5351c.c ${PATH_HACKRF_FIRMWARE_COMMON}/max2837.c + ${PATH_HACKRF_FIRMWARE_COMMON}/max2837_drv.c ${PATH_HACKRF_FIRMWARE_COMMON}/max5864.c ${PATH_HACKRF_FIRMWARE_COMMON}/rffc5071.c m0_bin.s