extra clock after RFFC serial transactions, Jawbreaker RF switch control

This commit is contained in:
Michael Ossmann
2012-09-20 11:59:33 -06:00
parent 425a384832
commit 237df75789
3 changed files with 55 additions and 40 deletions

View File

@ -24,6 +24,12 @@
* program would do if it had a real spi library * program would do if it had a real spi library
*/ */
/*
* The actual part on Jawbreaker is the RFFC5072, not the RFFC5071, but the
* RFFC5071 may be installed instead. The only difference between the parts is
* that the RFFC5071 includes a second mixer.
*/
#include <stdint.h> #include <stdint.h>
#include <string.h> #include <string.h>
#include "rffc5071.h" #include "rffc5071.h"
@ -139,24 +145,10 @@ void rffc5071_setup(void)
* not control pins. */ * not control pins. */
set_RFFC5071_SIPIN(1); set_RFFC5071_SIPIN(1);
/* Initial settings for Lollipop switches, same for both #ifdef JAWBREAKER
* paths. These could use some #defines that iron out the /* initial safe switch control settings */
* (non)inverted signals. rffc5071_set_gpo(SWITCHCTRL_SAFE);
* #endif
* bit0: SWTXB1 (!tx_bypass)
* bit1: SWRXB1 (rx_bypass)
* bit2: SWTXA1 (tx_hp)
* bit3: unused (lock bit)
* bit4: SWRXA1 (rx_hp)
* bit5 SWD1 (!tx_ant)
*
* Unknown whether shift is needed. There are 7 register bits
* to hold 6 GPO bits. */
set_RFFC5071_P1GPO(0b010100<<1);
set_RFFC5071_P2GPO(0b010100<<1);
/* send lock flag on GPO4 */
set_RFFC5071_LOCK(1);
/* GPOs are active at all times */ /* GPOs are active at all times */
set_RFFC5071_GATE(1); set_RFFC5071_GATE(1);
@ -256,6 +248,15 @@ uint16_t rffc5071_spi_read(uint8_t r) {
serial_delay(); serial_delay();
gpio_set(PORT_MIXER_ENX, PIN_MIXER_ENX); gpio_set(PORT_MIXER_ENX, PIN_MIXER_ENX);
/*
* The device requires a clock while ENX is high after a serial
* transaction. This is not clearly documented.
*/
gpio_set(PORT_MIXER_SCLK, PIN_MIXER_SCLK);
serial_delay();
gpio_clear(PORT_MIXER_SCLK, PIN_MIXER_SCLK);
return data; return data;
#endif /* DEBUG */ #endif /* DEBUG */
} }
@ -316,8 +317,17 @@ void rffc5071_spi_write(uint8_t r, uint16_t v) {
gpio_clear(PORT_MIXER_SCLK, PIN_MIXER_SCLK); gpio_clear(PORT_MIXER_SCLK, PIN_MIXER_SCLK);
} }
serial_delay();
gpio_set(PORT_MIXER_ENX, PIN_MIXER_ENX); gpio_set(PORT_MIXER_ENX, PIN_MIXER_ENX);
/*
* The device requires a clock while ENX is high after a serial
* transaction. This is not clearly documented.
*/
serial_delay();
gpio_set(PORT_MIXER_SCLK, PIN_MIXER_SCLK);
serial_delay();
gpio_clear(PORT_MIXER_SCLK, PIN_MIXER_SCLK);
#endif #endif
} }
@ -476,6 +486,15 @@ uint16_t rffc5071_set_frequency(uint16_t mhz, uint32_t hz) {
return tune_freq; return tune_freq;
} }
void rffc5071_set_gpo(uint8_t gpo)
{
/* We set GPO for both paths just in case. */
set_RFFC5071_P1GPO(gpo);
set_RFFC5071_P2GPO(gpo);
rffc5071_regs_commit();
}
#ifdef TEST #ifdef TEST
int main(int ac, char **av) int main(int ac, char **av)
{ {

View File

@ -31,6 +31,21 @@ extern uint32_t rffc5071_regs_dirty;
#define RFFC5071_REG_SET_CLEAN(r) rffc5071_regs_dirty &= ~(1UL<<r) #define RFFC5071_REG_SET_CLEAN(r) rffc5071_regs_dirty &= ~(1UL<<r)
#define RFFC5071_REG_SET_DIRTY(r) rffc5071_regs_dirty |= (1UL<<r) #define RFFC5071_REG_SET_DIRTY(r) rffc5071_regs_dirty |= (1UL<<r)
#ifdef JAWBREAKER
/*
* RF switches on Jawbreaker are controlled by General Purpose Outputs (GPO) on
* the RFFC5072.
*/
#define SWITCHCTRL_NO_TX_AMP_PWR (1 << 0) /* turn off TX amp power */
#define SWITCHCTRL_AMP_BYPASS (1 << 1) /* bypass amp section */
#define SWITCHCTRL_TX (1 << 2) /* 1 for TX mode, 0 for RX mode */
#define SWITCHCTRL_MIX_BYPASS (1 << 3) /* bypass RFFC5072 mixer section */
#define SWITCHCTRL_HP (1 << 4) /* 1 for high-pass, 0 for low-pass */
#define SWITCHCTRL_NO_RX_AMP_PWR (1 << 5) /* turn off RX amp power */
#define SWITCHCTRL_SAFE (SWITCHCTRL_NO_TX_AMP_PWR | SWITCHCTRL_AMP_BYPASS | SWITCHCTRL_TX | SWITCHCTRL_MIX_BYPASS | SWITCHCTRL_HP | SWITCHCTRL_NO_RX_AMP_PWR)
#endif
/* 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(void);
extern void rffc5071_setup(void); extern void rffc5071_setup(void);
@ -62,4 +77,6 @@ extern void rffc5071_rxtx(void);
extern void rffc5071_enable(void); extern void rffc5071_enable(void);
extern void rffc5071_disable(void); extern void rffc5071_disable(void);
extern void rffc5071_set_gpo(uint8_t);
#endif // __RFFC5071_H #endif // __RFFC5071_H

View File

@ -329,27 +329,6 @@ int main(void) {
rffc5071_rx(); rffc5071_rx();
rffc5071_set_frequency(500, 0); // 500 MHz, 0 Hz (Hz ignored) rffc5071_set_frequency(500, 0); // 500 MHz, 0 Hz (Hz ignored)
#ifdef LOLLIPOP_SWITCH_SET_UP_DONE_IN_RFFC5071
/* lollipop */
uint8_t gpo =
(1 << 0) /* SWTXB1 (!tx_bypass) */
| (0 << 1) /* SWRXB1 (rx_bypass) */
| (1 << 2) /* SWTXA1 (tx_hp) */
| (0 << 3) /* unused */
| (1 << 4) /* SWRXA1 (rx_hp) */
| (0 << 5); /* SWD1 (!tx_ant) */
/* licorice */
//uint8_t gpo =
//(0 << 0) /* MIX_BYPASS */
//| (0 << 1) /* AMP_BYPASS */
//| (0 << 2) /* TX */
//| (0 << 3) /* unused */
//| (0 << 4) /* HP */
//| (0 << 5); /* !AMP_PWR */
rffc5071_reg_write(RFFC5071_GPO, (gpo << 9) | (gpo << 2) | 0x3);
gpio_set(PORT_LED1_3, (PIN_LED1)); /* LED1 on */
#endif
max2837_set_frequency(freq); max2837_set_frequency(freq);
max2837_start(); max2837_start();
max2837_rx(); max2837_rx();