From 6d57c08e28ee1e5519dbc39349b6918c584ab3d9 Mon Sep 17 00:00:00 2001
From: Jared Boone <jboone@earfeast.com>
Date: Mon, 10 Nov 2014 12:40:11 -0800
Subject: [PATCH 31/68] MAX2837: Add virtual function for setting device mode.

---
 firmware/common/hackrf_core.c    |  1 +
 firmware/common/max2837.c        | 33 ++++++++--------------------
 firmware/common/max2837.h        |  2 ++
 firmware/common/max2837_target.c | 46 +++++++++++++++++++++++-----------------
 firmware/common/max2837_target.h |  8 ++-----
 firmware/common/tuning.c         |  2 +-
 6 files changed, 41 insertions(+), 51 deletions(-)

--- a/firmware/common/hackrf_core.c
+++ b/firmware/common/hackrf_core.c
@@ -86,6 +86,7 @@
 
 max2837_driver_t max2837 = {
 	.spi = &spi_ssp1,
+	.set_mode = max2837_target_set_mode,
 };
 
 max5864_driver_t max5864 = {
--- a/firmware/common/max2837.c
+++ b/firmware/common/max2837.c
@@ -80,8 +80,8 @@
 static void max2837_init(max2837_driver_t* const drv)
 {
 	spi_init(drv->spi, &ssp_config_max2837);
-	max2837_mode_shutdown(drv);
 	max2837_target_init(drv);
+	max2837_set_mode(drv, MAX2837_MODE_SHUTDOWN);
 
 	memcpy(drv->regs, max2837_regs_default, sizeof(drv->regs));
 	drv->regs_dirty = 0xffffffff;
@@ -165,54 +165,39 @@
 }
 
 void max2837_set_mode(max2837_driver_t* const drv, const max2837_mode_t new_mode) {
-	switch(new_mode) {
-	case MAX2837_MODE_SHUTDOWN:
-		max2837_mode_shutdown(drv);
-		break;
-		
-	case MAX2837_MODE_STANDBY:
-		max2837_mode_standby(drv);
-		break;
-		
-	case MAX2837_MODE_TX:
-		max2837_mode_tx(drv);
-		break;
-
-	case MAX2837_MODE_RX:
-		max2837_mode_rx(drv);
-		break;
-		
-	default:
-		break;
-	}
+	drv->set_mode(drv, new_mode);
+}
+
+max2837_mode_t max2837_mode(max2837_driver_t* const drv) {
+	return drv->mode;
 }
 
 void max2837_start(max2837_driver_t* const drv)
 {
 	set_MAX2837_EN_SPI(drv, 1);
 	max2837_regs_commit(drv);
-	max2837_mode_standby(drv);
+	max2837_set_mode(drv, MAX2837_MODE_STANDBY);
 }
 
 void max2837_tx(max2837_driver_t* const drv)
 {
 	set_MAX2837_ModeCtrl(drv, MAX2837_ModeCtrl_TxLPF);
 	max2837_regs_commit(drv);
-	max2837_mode_tx(drv);
+	max2837_set_mode(drv, MAX2837_MODE_TX);
 }
 
 void max2837_rx(max2837_driver_t* const drv)
 {
 	set_MAX2837_ModeCtrl(drv, MAX2837_ModeCtrl_RxLPF);
 	max2837_regs_commit(drv);
-	max2837_mode_rx(drv);
+	max2837_set_mode(drv, MAX2837_MODE_RX);
 }
 
 void max2837_stop(max2837_driver_t* const drv)
 {
 	set_MAX2837_EN_SPI(drv, 0);
 	max2837_regs_commit(drv);
-	max2837_mode_shutdown(drv);
+	max2837_set_mode(drv, MAX2837_MODE_SHUTDOWN);
 }
 
 void max2837_set_frequency(max2837_driver_t* const drv, uint32_t freq)
--- a/firmware/common/max2837.h
+++ b/firmware/common/max2837.h
@@ -41,6 +41,8 @@
 
 typedef struct {
 	spi_t* const spi;
+	void (*set_mode)(max2837_driver_t* const drv, const max2837_mode_t new_mode);
+	max2837_mode_t mode;
 	uint16_t regs[MAX2837_NUM_REGS];
 	uint32_t regs_dirty;
 } max2837_driver_t;
--- a/firmware/common/max2837_target.c
+++ b/firmware/common/max2837_target.c
@@ -92,17 +92,16 @@
 	gpio_set(PORT_XCVR_CS, PIN_XCVR_CS);
 }
 
-void max2837_mode_shutdown(max2837_driver_t* const drv) {
-	(void)drv;
+static void max2837_target_mode_shutdown(max2837_driver_t* const drv) {
 	/* 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));
+	drv->mode = MAX2837_MODE_SHUTDOWN;
 }
 
-void max2837_mode_standby(max2837_driver_t* const drv) {
-	(void)drv;
+static void max2837_target_mode_standby(max2837_driver_t* const drv) {
 	/* 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.
@@ -110,10 +109,10 @@
 	 */
 	gpio_clear(PORT_XCVR_ENABLE, (PIN_XCVR_RXENABLE | PIN_XCVR_TXENABLE));
 	gpio_set(PORT_XCVR_ENABLE, PIN_XCVR_ENABLE);
+	drv->mode = MAX2837_MODE_STANDBY;
 }
 
-void max2837_mode_tx(max2837_driver_t* const drv) {
-	(void)drv;
+static void max2837_target_mode_tx(max2837_driver_t* const drv) {
 	/* 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
@@ -122,10 +121,10 @@
 	gpio_clear(PORT_XCVR_ENABLE, PIN_XCVR_RXENABLE);
 	gpio_set(PORT_XCVR_ENABLE,
 			(PIN_XCVR_ENABLE | PIN_XCVR_TXENABLE));
+	drv->mode = MAX2837_MODE_TX;
 }
 
-void max2837_mode_rx(max2837_driver_t* const drv) {
-	(void)drv;
+static void max2837_target_mode_rx(max2837_driver_t* const drv) {
 	/* 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”
@@ -134,19 +133,26 @@
 	gpio_clear(PORT_XCVR_ENABLE, PIN_XCVR_TXENABLE);
 	gpio_set(PORT_XCVR_ENABLE,
 			(PIN_XCVR_ENABLE | PIN_XCVR_RXENABLE));
+	drv->mode = MAX2837_MODE_RX;
 }
 
-max2837_mode_t max2837_mode(max2837_driver_t* const drv) {
-	(void)drv;
-	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_target_set_mode(max2837_driver_t* const drv, const max2837_mode_t new_mode) {
+	switch(new_mode) {
+	default:
+	case MAX2837_MODE_SHUTDOWN:
+		max2837_target_mode_shutdown(drv);
+		break;
+
+	case MAX2837_MODE_STANDBY:
+		max2837_target_mode_standby(drv);
+		break;
+
+	case MAX2837_MODE_TX:
+		max2837_target_mode_tx(drv);
+		break;
+
+	case MAX2837_MODE_RX:
+		max2837_target_mode_rx(drv);
+		break;
 	}
 }
--- a/firmware/common/max2837_target.h
+++ b/firmware/common/max2837_target.h
@@ -27,13 +27,9 @@
 #include "spi.h"
 
 void max2837_target_init(max2837_driver_t* const drv);
+void max2837_target_set_mode(max2837_driver_t* const drv, const max2837_mode_t new_mode);
+
 void max2837_target_spi_select(spi_t* const spi);
 void max2837_target_spi_unselect(spi_t* const spi);
 
-void max2837_mode_shutdown(max2837_driver_t* const drv);
-void max2837_mode_standby(max2837_driver_t* const drv);
-void max2837_mode_tx(max2837_driver_t* const drv);
-void max2837_mode_rx(max2837_driver_t* const drv);
-max2837_mode_t max2837_mode(max2837_driver_t* const drv);
-
 #endif // __MAX2837_TARGET_H
--- a/firmware/common/tuning.c
+++ b/firmware/common/tuning.c
@@ -65,7 +65,7 @@
 	success = true;
 
 	const max2837_mode_t prior_max2837_mode = max2837_mode(&max2837);
-	max2837_mode_standby(&max2837);
+	max2837_set_mode(&max2837, MAX2837_MODE_STANDBY);
 	if(freq_mhz < MAX_LP_FREQ_MHZ)
 	{
 		rf_path_set_filter(RF_PATH_FILTER_LOW_PASS);
