From e6c02bea62d80af1b08a89c7178a9490a4b1747d Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Sun, 9 Nov 2014 13:48:15 -0800 Subject: [PATCH] MAX5864: Abstract SPI, extract target code --- firmware/common/hackrf_core.c | 49 ++++-------- firmware/common/hackrf_core.h | 3 +- firmware/common/max5864.c | 44 ++++++----- firmware/common/max5864.h | 20 +++-- firmware/common/max5864_spi.c | 78 +++++++++++++++++++ firmware/common/max5864_spi.h | 33 ++++++++ firmware/common/max5864_target.c | 38 +++++++++ firmware/common/max5864_target.h | 29 +++++++ firmware/common/rf_path.c | 9 ++- firmware/hackrf-common.cmake | 2 + firmware/hackrf_usb/hackrf_usb.c | 2 - firmware/mixertx/mixertx.c | 1 - firmware/sgpio-rx/sgpio-rx.c | 1 - firmware/sgpio/sgpio_test.c | 4 +- .../sgpio_passthrough/sgpio_passthrough.c | 1 - firmware/simpletx/simpletx.c | 1 - 16 files changed, 240 insertions(+), 75 deletions(-) create mode 100644 firmware/common/max5864_spi.c create mode 100644 firmware/common/max5864_spi.h create mode 100644 firmware/common/max5864_target.c create mode 100644 firmware/common/max5864_target.h diff --git a/firmware/common/hackrf_core.c b/firmware/common/hackrf_core.c index 5cb7bd4f..a85984bc 100644 --- a/firmware/common/hackrf_core.c +++ b/firmware/common/hackrf_core.c @@ -26,6 +26,9 @@ #include "max2837.h" #include "max2837_spi.h" #include "max2837_target.h" +#include "max5864.h" +#include "max5864_spi.h" +#include "max5864_target.h" #include "rffc5071.h" #include "rffc5071_spi.h" #include "sgpio.h" @@ -48,6 +51,15 @@ max2837_driver_t max2837 = { .spi = &max2837_spi, }; +spi_t max5864_spi = { + .init = max5864_spi_init, + .transfer = max5864_spi_transfer, + .transfer_gather = max5864_spi_transfer_gather, +}; + +max5864_driver_t max5864 = { + .spi = &max5864_spi, +}; spi_t rffc5071_spi = { .init = rffc5071_spi_init, @@ -530,17 +542,6 @@ void cpu_clock_pll1_max_speed(void) } -void ssp1_init(void) -{ - /* - * Configure CS_AD pin to keep the MAX5864 SPI disabled while we use the - * SPI bus for the MAX2837. FIXME: this should probably be somewhere else. - */ - scu_pinmux(SCU_AD_CS, SCU_GPIO_FAST); - GPIO_SET(PORT_AD_CS) = PIN_AD_CS; - GPIO_DIR(PORT_AD_CS) |= PIN_AD_CS; -} - void ssp1_set_mode_max2837(void) { spi_init(max2837.spi); @@ -548,25 +549,7 @@ void ssp1_set_mode_max2837(void) void ssp1_set_mode_max5864(void) { - /* FIXME speed up once everything is working reliably */ - /* - // Freq About 0.0498MHz / 49.8KHz => Freq = PCLK / (CPSDVSR * [SCR+1]) with PCLK=PLL1=204MHz - const uint8_t serial_clock_rate = 32; - const uint8_t clock_prescale_rate = 128; - */ - // Freq About 4.857MHz => Freq = PCLK / (CPSDVSR * [SCR+1]) with PCLK=PLL1=204MHz - const uint8_t serial_clock_rate = 21; - const uint8_t clock_prescale_rate = 2; - - ssp_init(SSP1_NUM, - SSP_DATA_8BITS, - SSP_FRAME_SPI, - SSP_CPOL_0_CPHA_0, - serial_clock_rate, - clock_prescale_rate, - SSP_MODE_NORMAL, - SSP_MASTER, - SSP_SLAVE_OUT_ENABLE); + spi_init(max5864.spi); } void pin_setup(void) { @@ -612,12 +595,6 @@ void pin_setup(void) { rf_path_pin_setup(); - /* Configure SSP1 Peripheral (to be moved later in SSP driver) */ - scu_pinmux(SCU_SSP1_MISO, (SCU_SSP_IO | SCU_CONF_FUNCTION5)); - scu_pinmux(SCU_SSP1_MOSI, (SCU_SSP_IO | SCU_CONF_FUNCTION5)); - scu_pinmux(SCU_SSP1_SCK, (SCU_SSP_IO | SCU_CONF_FUNCTION1)); - scu_pinmux(SCU_SSP1_SSEL, (SCU_SSP_IO | SCU_CONF_FUNCTION1)); - /* Configure external clock in */ scu_pinmux(SCU_PINMUX_GP_CLKIN, SCU_CLK_IN | SCU_CONF_FUNCTION1); diff --git a/firmware/common/hackrf_core.h b/firmware/common/hackrf_core.h index 2eea5da4..32356031 100644 --- a/firmware/common/hackrf_core.h +++ b/firmware/common/hackrf_core.h @@ -33,6 +33,7 @@ extern "C" #include #include "max2837.h" +#include "max5864.h" #include "rffc5071.h" #include "w25q80bv.h" @@ -354,13 +355,13 @@ typedef enum { void delay(uint32_t duration); extern max2837_driver_t max2837; +extern max5864_driver_t max5864; extern rffc5071_driver_t rffc5072; extern w25q80bv_driver_t spi_flash; void cpu_clock_init(void); void cpu_clock_pll1_low_speed(void); void cpu_clock_pll1_max_speed(void); -void ssp1_init(void); void ssp1_set_mode_max2837(void); void ssp1_set_mode_max5864(void); diff --git a/firmware/common/max5864.c b/firmware/common/max5864.c index 094ed700..773b0d2a 100644 --- a/firmware/common/max5864.c +++ b/firmware/common/max5864.c @@ -21,16 +21,20 @@ #include -#include -#include - -#include "hackrf_core.h" #include "max5864.h" +#include "max5864_target.h" -void max5864_spi_write(uint_fast8_t value) { - gpio_clear(PORT_AD_CS, PIN_AD_CS); - ssp_transfer(SSP1_NUM, value); - gpio_set(PORT_AD_CS, PIN_AD_CS); +static void max5864_write(max5864_driver_t* const drv, uint8_t value) { + spi_transfer(drv->spi, &value, 1); +} + +void max5864_init(max5864_driver_t* const drv) { + spi_init(drv->spi); + max5864_target_init(drv); +} + +void max5864_setup(max5864_driver_t* const drv) { + max5864_init(drv); } /* Set MAX5864 operation mode to "Shutdown": @@ -39,9 +43,9 @@ void max5864_spi_write(uint_fast8_t value) { * ADCs: off (bus is tri-stated) * DACs: off (set input bus to zero or OVdd) */ -void max5864_shutdown() +void max5864_shutdown(max5864_driver_t* const drv) { - max5864_spi_write(0x00); + max5864_write(drv, 0x00); } /* Set MAX5864 operation mode to "Standby": @@ -50,9 +54,9 @@ void max5864_shutdown() * ADCs: off (bus is tri-stated) * DACs: off (set input bus to zero or OVdd) */ -void max5864_standby() +void max5864_standby(max5864_driver_t* const drv) { - max5864_spi_write(0x05); + max5864_write(drv, 0x05); } /* Set MAX5864 operation mode to "Idle": @@ -61,9 +65,9 @@ void max5864_standby() * ADCs: off (bus is tri-stated) * DACs: off (set input bus to zero or OVdd) */ -void max5864_idle() +void max5864_idle(max5864_driver_t* const drv) { - max5864_spi_write(0x01); + max5864_write(drv, 0x01); } /* Set MAX5864 operation mode to "Rx": @@ -72,9 +76,9 @@ void max5864_idle() * ADCs: on * DACs: off (set input bus to zero or OVdd) */ -void max5864_rx() +void max5864_rx(max5864_driver_t* const drv) { - max5864_spi_write(0x02); + max5864_write(drv, 0x02); } /* Set MAX5864 operation mode to "Tx": @@ -83,9 +87,9 @@ void max5864_rx() * ADCs: off (bus is tri-stated) * DACs: on */ -void max5864_tx() +void max5864_tx(max5864_driver_t* const drv) { - max5864_spi_write(0x03); + max5864_write(drv, 0x03); } /* Set MAX5864 operation mode to "Xcvr": @@ -94,7 +98,7 @@ void max5864_tx() * ADCs: on * DACs: on */ -void max5864_xcvr() +void max5864_xcvr(max5864_driver_t* const drv) { - max5864_spi_write(0x04); + max5864_write(drv, 0x04); } diff --git a/firmware/common/max5864.h b/firmware/common/max5864.h index 72519645..0b5a8bb9 100644 --- a/firmware/common/max5864.h +++ b/firmware/common/max5864.h @@ -22,11 +22,19 @@ #ifndef __MAX5864_H #define __MAX5864_H -void max5864_shutdown(); -void max5864_standby(); -void max5864_idle(); -void max5864_rx(); -void max5864_tx(); -void max5864_xcvr(); +#include "spi.h" + +typedef struct max5864_driver_t { + spi_t* const spi; +} max5864_driver_t; + +void max5864_setup(max5864_driver_t* const drv); + +void max5864_shutdown(max5864_driver_t* const drv); +void max5864_standby(max5864_driver_t* const drv); +void max5864_idle(max5864_driver_t* const drv); +void max5864_rx(max5864_driver_t* const drv); +void max5864_tx(max5864_driver_t* const drv); +void max5864_xcvr(max5864_driver_t* const drv); #endif // __MAX5864_H diff --git a/firmware/common/max5864_spi.c b/firmware/common/max5864_spi.c new file mode 100644 index 00000000..c30750ba --- /dev/null +++ b/firmware/common/max5864_spi.c @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2014 Jared Boone, ShareBrained Technology, Inc. + * + * 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 "max5864_spi.h" + +#include +#include +#include + +#include "hackrf_core.h" + +void max5864_spi_init(spi_t* const spi) { + (void)spi; + + /* FIXME speed up once everything is working reliably */ + /* + // Freq About 0.0498MHz / 49.8KHz => Freq = PCLK / (CPSDVSR * [SCR+1]) with PCLK=PLL1=204MHz + const uint8_t serial_clock_rate = 32; + const uint8_t clock_prescale_rate = 128; + */ + // Freq About 4.857MHz => Freq = PCLK / (CPSDVSR * [SCR+1]) with PCLK=PLL1=204MHz + const uint8_t serial_clock_rate = 21; + const uint8_t clock_prescale_rate = 2; + + ssp_init(SSP1_NUM, + SSP_DATA_8BITS, + SSP_FRAME_SPI, + SSP_CPOL_0_CPHA_0, + serial_clock_rate, + clock_prescale_rate, + SSP_MODE_NORMAL, + SSP_MASTER, + SSP_SLAVE_OUT_ENABLE); + + /* Configure SSP1 Peripheral (to be moved later in SSP driver) */ + scu_pinmux(SCU_SSP1_MISO, (SCU_SSP_IO | SCU_CONF_FUNCTION5)); + scu_pinmux(SCU_SSP1_MOSI, (SCU_SSP_IO | SCU_CONF_FUNCTION5)); + scu_pinmux(SCU_SSP1_SCK, (SCU_SSP_IO | SCU_CONF_FUNCTION1)); +} + +void max5864_spi_transfer_gather(spi_t* const spi, const spi_transfer_t* const transfers, const size_t count) { + (void)spi; + + gpio_clear(PORT_AD_CS, PIN_AD_CS); + for(size_t i=0; i + +#include "spi.h" + +void max5864_spi_init(spi_t* const spi); +void max5864_spi_transfer(spi_t* const spi, void* const value, const size_t count); +void max5864_spi_transfer_gather(spi_t* const spi, const spi_transfer_t* const transfers, const size_t count); + +#endif/*__MAX5864_SPI_H__*/ diff --git a/firmware/common/max5864_target.c b/firmware/common/max5864_target.c new file mode 100644 index 00000000..0c61f6f2 --- /dev/null +++ b/firmware/common/max5864_target.c @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2014 Jared Boone, ShareBrained Technology, Inc. + * + * 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 "max5864_target.h" + +#include +#include +#include "hackrf_core.h" + +void max5864_target_init(max5864_driver_t* const drv) { + (void)drv; + + /* + * Configure CS_AD pin to keep the MAX5864 SPI disabled while we use the + * SPI bus for the MAX2837. FIXME: this should probably be somewhere else. + */ + scu_pinmux(SCU_AD_CS, SCU_GPIO_FAST); + GPIO_SET(PORT_AD_CS) = PIN_AD_CS; + GPIO_DIR(PORT_AD_CS) |= PIN_AD_CS; +} diff --git a/firmware/common/max5864_target.h b/firmware/common/max5864_target.h new file mode 100644 index 00000000..be684e2c --- /dev/null +++ b/firmware/common/max5864_target.h @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2014 Jared Boone, ShareBrained Technology, Inc. + * + * 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 __MAX5864_TARGET_H__ +#define __MAX5864_TARGET_H__ + +#include "max5864.h" + +void max5864_target_init(max5864_driver_t* const drv); + +#endif/*__MAX5864_TARGET_H__*/ diff --git a/firmware/common/rf_path.c b/firmware/common/rf_path.c index 071564da..589961aa 100644 --- a/firmware/common/rf_path.c +++ b/firmware/common/rf_path.c @@ -209,7 +209,8 @@ void rf_path_pin_setup() { void rf_path_init(void) { ssp1_set_mode_max5864(); - max5864_shutdown(); + max5864_setup(&max5864); + max5864_shutdown(&max5864); ssp1_set_mode_max2837(); max2837_setup(&max2837); @@ -236,7 +237,7 @@ void rf_path_set_direction(const rf_path_direction_t direction) { rffc5071_enable(&rffc5072); } ssp1_set_mode_max5864(); - max5864_tx(); + max5864_tx(&max5864); ssp1_set_mode_max2837(); max2837_tx(&max2837); sgpio_configure(SGPIO_DIRECTION_TX); @@ -255,7 +256,7 @@ void rf_path_set_direction(const rf_path_direction_t direction) { rffc5071_enable(&rffc5072); } ssp1_set_mode_max5864(); - max5864_rx(); + max5864_rx(&max5864); ssp1_set_mode_max2837(); max2837_rx(&max2837); sgpio_configure(SGPIO_DIRECTION_RX); @@ -270,7 +271,7 @@ void rf_path_set_direction(const rf_path_direction_t direction) { switchctrl &= ~SWITCHCTRL_TX; rffc5071_disable(&rffc5072); ssp1_set_mode_max5864(); - max5864_standby(); + max5864_standby(&max5864); ssp1_set_mode_max2837(); max2837_set_mode(&max2837, MAX2837_MODE_STANDBY); sgpio_configure(SGPIO_DIRECTION_RX); diff --git a/firmware/hackrf-common.cmake b/firmware/hackrf-common.cmake index 72620aef..ff5bcba0 100644 --- a/firmware/hackrf-common.cmake +++ b/firmware/hackrf-common.cmake @@ -138,6 +138,8 @@ macro(DeclareTargets) ${PATH_HACKRF_FIRMWARE_COMMON}/max2837_spi.c ${PATH_HACKRF_FIRMWARE_COMMON}/max2837_target.c ${PATH_HACKRF_FIRMWARE_COMMON}/max5864.c + ${PATH_HACKRF_FIRMWARE_COMMON}/max5864_spi.c + ${PATH_HACKRF_FIRMWARE_COMMON}/max5864_target.c ${PATH_HACKRF_FIRMWARE_COMMON}/rffc5071.c ${PATH_HACKRF_FIRMWARE_COMMON}/rffc5071_spi.c ${PATH_HACKRF_FIRMWARE_COMMON}/spi.c diff --git a/firmware/hackrf_usb/hackrf_usb.c b/firmware/hackrf_usb/hackrf_usb.c index 42fc4482..2e6a4140 100644 --- a/firmware/hackrf_usb/hackrf_usb.c +++ b/firmware/hackrf_usb/hackrf_usb.c @@ -208,8 +208,6 @@ int main(void) { usb_run(&usb_device); - ssp1_init(); - rf_path_init(); unsigned int phase = 0; diff --git a/firmware/mixertx/mixertx.c b/firmware/mixertx/mixertx.c index c7150d57..e23e00d7 100644 --- a/firmware/mixertx/mixertx.c +++ b/firmware/mixertx/mixertx.c @@ -38,7 +38,6 @@ int main(void) enable_rf_power(); #endif cpu_clock_init(); - ssp1_init(); gpio_set(PORT_LED1_3, (PIN_LED1)); /* LED1 on */ diff --git a/firmware/sgpio-rx/sgpio-rx.c b/firmware/sgpio-rx/sgpio-rx.c index dbee1d3f..dca4c489 100644 --- a/firmware/sgpio-rx/sgpio-rx.c +++ b/firmware/sgpio-rx/sgpio-rx.c @@ -96,7 +96,6 @@ int main(void) { enable_rf_power(); #endif cpu_clock_init(); - ssp1_init(); rf_path_init(); rf_path_set_direction(RF_PATH_DIRECTION_RX); diff --git a/firmware/sgpio/sgpio_test.c b/firmware/sgpio/sgpio_test.c index 6e391c10..de3ee605 100644 --- a/firmware/sgpio/sgpio_test.c +++ b/firmware/sgpio/sgpio_test.c @@ -72,12 +72,12 @@ int main(void) { pin_setup(); enable_1v8_power(); cpu_clock_init(); - ssp1_init(); gpio_set(PORT_LED1_3, PIN_LED1); ssp1_set_mode_max5864(); - max5864_xcvr(); + max5864_setup(&max5864); + max5864_xcvr(&max5864); while (1) { diff --git a/firmware/sgpio_passthrough/sgpio_passthrough.c b/firmware/sgpio_passthrough/sgpio_passthrough.c index 8e4d38d5..d1cc0491 100644 --- a/firmware/sgpio_passthrough/sgpio_passthrough.c +++ b/firmware/sgpio_passthrough/sgpio_passthrough.c @@ -353,7 +353,6 @@ int main(void) pin_setup(); enable_1v8_power(); cpu_clock_init(); - ssp1_init(); gpio_set(PORT_LED1_3, PIN_LED1); //test_sgpio_sliceA_D(); diff --git a/firmware/simpletx/simpletx.c b/firmware/simpletx/simpletx.c index d6f9072d..78178ee9 100644 --- a/firmware/simpletx/simpletx.c +++ b/firmware/simpletx/simpletx.c @@ -37,7 +37,6 @@ int main(void) enable_rf_power(); #endif cpu_clock_init(); - ssp1_init(); gpio_set(PORT_LED1_3, (PIN_LED1)); /* LED1 on */