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
*/
/*
* 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 <string.h>
#include "rffc5071.h"
@ -139,24 +145,10 @@ void rffc5071_setup(void)
* not control pins. */
set_RFFC5071_SIPIN(1);
/* Initial settings for Lollipop switches, same for both
* paths. These could use some #defines that iron out the
* (non)inverted signals.
*
* 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);
#ifdef JAWBREAKER
/* initial safe switch control settings */
rffc5071_set_gpo(SWITCHCTRL_SAFE);
#endif
/* GPOs are active at all times */
set_RFFC5071_GATE(1);
@ -256,6 +248,15 @@ uint16_t rffc5071_spi_read(uint8_t r) {
serial_delay();
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;
#endif /* DEBUG */
}
@ -316,8 +317,17 @@ void rffc5071_spi_write(uint8_t r, uint16_t v) {
gpio_clear(PORT_MIXER_SCLK, PIN_MIXER_SCLK);
}
serial_delay();
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
}
@ -476,6 +486,15 @@ uint16_t rffc5071_set_frequency(uint16_t mhz, uint32_t hz) {
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
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_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(). */
extern void rffc5071_init(void);
extern void rffc5071_setup(void);
@ -62,4 +77,6 @@ extern void rffc5071_rxtx(void);
extern void rffc5071_enable(void);
extern void rffc5071_disable(void);
extern void rffc5071_set_gpo(uint8_t);
#endif // __RFFC5071_H

View File

@ -329,27 +329,6 @@ int main(void) {
rffc5071_rx();
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_start();
max2837_rx();