diff --git a/firmware/common/clock_gen.c b/firmware/common/clock_gen.c index b62308ceb..0f0085c2d 100644 --- a/firmware/common/clock_gen.c +++ b/firmware/common/clock_gen.c @@ -23,7 +23,6 @@ #include -#include "drivers.h" #include "hackrf_ui.h" #include "i2c_bus.h" #include "platform_detect.h" @@ -36,14 +35,14 @@ void clock_gen_init(void) { - i2c_bus_start(clock_gen.bus, &i2c_config_si5351c_fast_clock); + i2c_bus_start(si5351c.bus, &i2c_config_si5351c_fast_clock); - si5351c_init(&clock_gen); - si5351c_disable_all_outputs(&clock_gen); - si5351c_disable_oeb_pin_control(&clock_gen); - si5351c_power_down_all_clocks(&clock_gen); - si5351c_set_crystal_configuration(&clock_gen); - si5351c_enable_xo_and_ms_fanout(&clock_gen); + si5351c_init(&si5351c); + si5351c_disable_all_outputs(&si5351c); + si5351c_disable_oeb_pin_control(&si5351c); + si5351c_power_down_all_clocks(&si5351c); + si5351c_set_crystal_configuration(&si5351c); + si5351c_enable_xo_and_ms_fanout(&si5351c); /* * Clocks on HackRF One r9: @@ -76,7 +75,7 @@ void clock_gen_init(void) if (IS_H1_R9) { /* MS0/CLK0 is the reference for both RFFC5071 and MAX2839. */ si5351c_configure_multisynth( - &clock_gen, + &si5351c, 0, 20 * 128 - 512, 0, @@ -88,7 +87,7 @@ void clock_gen_init(void) if (IS_NOT_H1_R9) { /* MS4/CLK4 is the source for the RFFC5071 mixer (MAX2837 on rad1o). */ si5351c_configure_multisynth( - &clock_gen, + &si5351c, 4, 20 * 128 - 512, 0, @@ -96,7 +95,7 @@ void clock_gen_init(void) 0); /* 800/20 = 40MHz */ /* MS5/CLK5 is the source for the MAX2837 clock input (MAX2871 on rad1o). */ si5351c_configure_multisynth( - &clock_gen, + &si5351c, 5, 20 * 128 - 512, 0, @@ -111,19 +110,19 @@ void clock_gen_init(void) /* Set to 10 MHz, the common rate between Jawbreaker and HackRF One. */ sample_rate_set(SR_FP_MHZ(10), true); - si5351c_configure_clock_control(&clock_gen); - si5351c_set_clock_source(&clock_gen, PLL_SOURCE_XTAL); + si5351c_configure_clock_control(&si5351c); + si5351c_set_clock_source(&si5351c, PLL_SOURCE_XTAL); // soft reset - si5351c_reset_pll(&clock_gen, SI5351C_PLL_BOTH); - si5351c_enable_clock_outputs(&clock_gen); + si5351c_reset_pll(&si5351c, SI5351C_PLL_BOTH); + si5351c_enable_clock_outputs(&si5351c); } void clock_gen_shutdown(void) { - i2c_bus_start(clock_gen.bus, &i2c_config_si5351c_fast_clock); - si5351c_disable_all_outputs(&clock_gen); - si5351c_disable_oeb_pin_control(&clock_gen); - si5351c_power_down_all_clocks(&clock_gen); + i2c_bus_start(si5351c.bus, &i2c_config_si5351c_fast_clock); + si5351c_disable_all_outputs(&si5351c); + si5351c_disable_oeb_pin_control(&si5351c); + si5351c_power_down_all_clocks(&si5351c); } clock_source_t activate_best_clock_source(void) @@ -140,7 +139,7 @@ clock_source_t activate_best_clock_source(void) clock_source_t source = CLOCK_SOURCE_HACKRF; /* Check for external clock input. */ - if (si5351c_clkin_signal_valid(&clock_gen)) { + if (si5351c_clkin_signal_valid(&si5351c)) { source = CLOCK_SOURCE_EXTERNAL; } else { #ifdef IS_EXPANSION_COMPATIBLE @@ -149,7 +148,7 @@ clock_source_t activate_best_clock_source(void) if (portapack_reference_oscillator && portapack()) { portapack_reference_oscillator(true); delay(510000); /* loop iterations @ 204MHz for >10ms for oscillator to enable. */ - if (si5351c_clkin_signal_valid(&clock_gen)) { + if (si5351c_clkin_signal_valid(&si5351c)) { source = CLOCK_SOURCE_PORTAPACK; } else { portapack_reference_oscillator(false); @@ -161,7 +160,7 @@ clock_source_t activate_best_clock_source(void) } si5351c_set_clock_source( - &clock_gen, + &si5351c, (source == CLOCK_SOURCE_HACKRF) ? PLL_SOURCE_XTAL : PLL_SOURCE_CLKIN); hackrf_ui()->set_clock_source(source); @@ -342,9 +341,9 @@ fp_28_36_t sample_rate_set(const fp_28_36_t sample_rate, const bool program) if (IS_NOT_PRALINE) { /* Integer mode can be enabled if p1 is even and p2 is zero. */ if (p1 & 0x1 || p2) { - si5351c_set_int_mode(&clock_gen, 0, 0); + si5351c_set_int_mode(&si5351c, 0, 0); } else { - si5351c_set_int_mode(&clock_gen, 0, 1); + si5351c_set_int_mode(&si5351c, 0, 1); } #ifdef IS_H1_R9 @@ -353,7 +352,7 @@ fp_28_36_t sample_rate_set(const fp_28_36_t sample_rate, const bool program) * On HackRF One r9 all sample clocks are externally derived * from MS1/CLK1 operating at twice the sample rate. */ - si5351c_configure_multisynth(&clock_gen, 1, p1, p2, p3, 0); + si5351c_configure_multisynth(&si5351c, 1, p1, p2, p3, 0); } #endif #ifdef IS_NOT_H1_R9 @@ -363,11 +362,11 @@ fp_28_36_t sample_rate_set(const fp_28_36_t sample_rate, const bool program) * different sample clocks, all derived from multisynth 0. */ /* MS0/CLK0 is the source for the MAX5864/CPLD (CODEC_CLK). */ - si5351c_configure_multisynth(&clock_gen, 0, p1, p2, p3, 1); + si5351c_configure_multisynth(&si5351c, 0, p1, p2, p3, 1); /* MS0/CLK1 is the source for the CPLD (CODEC_X2_CLK). */ si5351c_configure_multisynth( - &clock_gen, + &si5351c, 1, 0, 0, @@ -376,7 +375,7 @@ fp_28_36_t sample_rate_set(const fp_28_36_t sample_rate, const bool program) /* MS0/CLK2 is the source for SGPIO (CODEC_X2_CLK) */ si5351c_configure_multisynth( - &clock_gen, + &si5351c, 2, 0, 0, @@ -389,17 +388,17 @@ fp_28_36_t sample_rate_set(const fp_28_36_t sample_rate, const bool program) #ifdef IS_PRALINE if (IS_PRALINE) { /* MS0/CLK0 is the source for the MAX5864 (AFE_CLK). */ - si5351c_configure_multisynth(&clock_gen, 0, p1, p2, p3, 1); + si5351c_configure_multisynth(&si5351c, 0, p1, p2, p3, 1); /* MS1/CLK1 is the source for the FPGA (FPGA_CLK and SCT_CLK). */ - si5351c_configure_multisynth(&clock_gen, 1, p1, p2, p3, 1); + si5351c_configure_multisynth(&si5351c, 1, p1, p2, p3, 1); /* Delay FPGA_CLK relative to AFE_CLK. */ uint8_t phase_offset = 0; if (p1 < 2100) { phase_offset = (p1 >> 4) - 6; } - si5351c_set_phase(&clock_gen, 1, phase_offset); + si5351c_set_phase(&si5351c, 1, phase_offset); if ((detected_revision() & ~BOARD_REV_GSG) < BOARD_REV_PRALINE_R1_1) { /* @@ -407,12 +406,12 @@ fp_28_36_t sample_rate_set(const fp_28_36_t sample_rate, const bool program) * CLK1. We configure both so that behavior is consistent with * newer boards that use CLK1 for both FPGA_CLK and SCT_CLK. */ - si5351c_configure_multisynth(&clock_gen, 2, p1, p2, p3, 1); - si5351c_set_phase(&clock_gen, 2, phase_offset); + si5351c_configure_multisynth(&si5351c, 2, p1, p2, p3, 1); + si5351c_set_phase(&si5351c, 2, phase_offset); } /* Reset PLL to synchronize output clock phase. */ - si5351c_reset_pll(&clock_gen, SI5351C_PLL_A); + si5351c_reset_pll(&si5351c, SI5351C_PLL_A); } #endif diff --git a/firmware/common/clock_io.c b/firmware/common/clock_io.c index 279eb8c5e..b0904f894 100644 --- a/firmware/common/clock_io.c +++ b/firmware/common/clock_io.c @@ -30,9 +30,11 @@ #include #include -#include "drivers.h" #include "gpdma.h" #include "gpio.h" +#ifdef IS_NOT_PRALINE + #include "sgpio.h" +#endif #ifdef IS_PRALINE #include "fpga.h" #include "platform_gpio.h" diff --git a/firmware/common/cpld_jtag.c b/firmware/common/cpld_jtag.c index 034ba196f..92f89f271 100644 --- a/firmware/common/cpld_jtag.c +++ b/firmware/common/cpld_jtag.c @@ -34,6 +34,13 @@ static uint32_t xsvf_buffer_len, xsvf_pos; static unsigned char* xsvf_buffer; #endif +/* Driver instance. */ +jtag_gpio_t jtag_gpio_cpld = {}; + +jtag_t jtag_cpld = { + .gpio = &jtag_gpio_cpld, +}; + void cpld_jtag_take(jtag_t* const jtag) { const jtag_gpio_t* const gpio = jtag->gpio; diff --git a/firmware/common/cpld_jtag.h b/firmware/common/cpld_jtag.h index 0994c8585..14f70437c 100644 --- a/firmware/common/cpld_jtag.h +++ b/firmware/common/cpld_jtag.h @@ -59,3 +59,7 @@ int cpld_jtag_program( unsigned char* const buffer, refill_buffer_cb refill); unsigned char cpld_jtag_get_next_byte(void); + +/* Driver instance. */ +extern jtag_gpio_t jtag_gpio_cpld; +extern jtag_t jtag_cpld; diff --git a/firmware/common/cpu_clock.c b/firmware/common/cpu_clock.c index b69f0773b..aa4ac9107 100644 --- a/firmware/common/cpu_clock.c +++ b/firmware/common/cpu_clock.c @@ -29,8 +29,8 @@ #endif #include "delay.h" -#include "drivers.h" #include "i2c_bus.h" +#include "si5351c.h" #ifdef IS_NOT_RAD1O #include "platform_detect.h" #endif @@ -116,7 +116,7 @@ void cpu_clock_init(void) //FIXME disable I2C /* Kick I2C0 down to 400kHz when we switch over to APB1 clock = 204MHz */ - i2c_bus_start(clock_gen.bus, &i2c_config_si5351c_fast_clock); + i2c_bus_start(si5351c.bus, &i2c_config_si5351c_fast_clock); /* * 12MHz clock is entering LPC XTAL1/OSC input now. diff --git a/firmware/common/da7219.c b/firmware/common/da7219.c index 5af022d2c..7ae916cba 100644 --- a/firmware/common/da7219.c +++ b/firmware/common/da7219.c @@ -22,7 +22,6 @@ #include #include "da7219.h" -#include "drivers.h" #include "i2c_bus.h" #define DA7219_REG_CHIP_ID1 0x81 diff --git a/firmware/common/drivers.c b/firmware/common/drivers.c deleted file mode 100644 index a6bd536a3..000000000 --- a/firmware/common/drivers.c +++ /dev/null @@ -1,178 +0,0 @@ -/* - * Copyright 2026 Great Scott Gadgets - * - * 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 "drivers.h" - -#include - -#include -#include - -#include "clock_gen.h" -#include "i2c_lpc.h" -#include "max283x.h" -#include "max5864_target.h" -#include "spi_bus.h" -#include "w25q80bv_target.h" -#if defined(IS_PRALINE) - #include "fpga.h" - #include "ice40_spi.h" -#endif - -i2c_bus_t i2c0 = { - .obj = (void*) I2C0_BASE, - .start = i2c_lpc_start, - .stop = i2c_lpc_stop, - .transfer = i2c_lpc_transfer, -}; - -i2c_bus_t i2c1 = { - .obj = (void*) I2C1_BASE, - .start = i2c_lpc_start, - .stop = i2c_lpc_stop, - .transfer = i2c_lpc_transfer, -}; - -// const i2c_lpc_config_t i2c_config_si5351c_slow_clock = { -// .duty_cycle_count = 15, -// }; - -const i2c_lpc_config_t i2c_config_si5351c_fast_clock = { - .duty_cycle_count = 255, -}; - -si5351c_driver_t clock_gen = { - .bus = &i2c0, - .i2c_address = 0x60, -}; - -ssp_config_t ssp_config_max283x = { - /* 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 - .serial_clock_rate = 21, - .clock_prescale_rate = 2, -}; - -max283x_driver_t max283x = {}; - -ssp_config_t ssp_config_max5864 = { - /* 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 - .data_bits = SSP_DATA_8BITS, - .serial_clock_rate = 21, - .clock_prescale_rate = 2, -}; - -spi_bus_t spi_bus_ssp1 = { - .obj = (void*) SSP1_BASE, - .config = &ssp_config_max5864, - .start = spi_ssp_start, - .stop = spi_ssp_stop, - .transfer = spi_ssp_transfer, - .transfer_gather = spi_ssp_transfer_gather, -}; - -max5864_driver_t max5864 = { - .bus = &spi_bus_ssp1, - .target_init = max5864_target_init, -}; - -ssp_config_t ssp_config_w25q80bv = { - .data_bits = SSP_DATA_8BITS, - .serial_clock_rate = 2, - .clock_prescale_rate = 2, -}; - -spi_bus_t spi_bus_ssp0 = { - .obj = (void*) SSP0_BASE, - .config = &ssp_config_w25q80bv, - .start = spi_ssp_start, - .stop = spi_ssp_stop, - .transfer = spi_ssp_transfer, - .transfer_gather = spi_ssp_transfer_gather, -}; - -w25q80bv_driver_t spi_flash = { - .bus = &spi_bus_ssp0, - .target_init = w25q80bv_target_init, -}; - -sgpio_config_t sgpio_config = { - .slice_mode_multislice = true, -}; - -#ifdef IS_PRALINE -ssp_config_t ssp_config_ice40_fpga = { - .data_bits = SSP_DATA_8BITS, - .spi_mode = SSP_CPOL_1_CPHA_1, - .serial_clock_rate = 21, - .clock_prescale_rate = 2, -}; - -ice40_spi_driver_t ice40 = { - .bus = &spi_bus_ssp1, -}; - -fpga_driver_t fpga = { - .bus = &ice40, -}; -#endif - -radio_t radio = { - .sample_rate_cb = sample_rate_set, -}; - -rf_path_t rf_path = { - .switchctrl = 0, -}; - -jtag_gpio_t jtag_gpio_cpld = {}; - -jtag_t jtag_cpld = { - .gpio = &jtag_gpio_cpld, -}; - -void ssp1_set_mode_max283x(void) -{ - spi_bus_start(&spi_bus_ssp1, &ssp_config_max283x); -} - -void ssp1_set_mode_max5864(void) -{ - spi_bus_start(max5864.bus, &ssp_config_max5864); -} - -#ifdef IS_PRALINE -void ssp1_set_mode_ice40(void) -{ - spi_bus_start(&spi_bus_ssp1, &ssp_config_ice40_fpga); -} -#endif diff --git a/firmware/common/drivers.h b/firmware/common/drivers.h deleted file mode 100644 index 6aa45f87d..000000000 --- a/firmware/common/drivers.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright 2026 Great Scott Gadgets - * - * 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. - */ - -#pragma once - -#ifdef __cplusplus -extern "C" { -#endif - -#include "cpld_jtag.h" -#include "i2c_bus.h" -#include "i2c_lpc.h" -#include "max283x.h" -#include "max5864.h" -#include "mixer.h" -#include "platform_detect.h" // IWYU pragma: keep -#include "radio.h" -#include "rf_path.h" -#include "sgpio.h" -#include "si5351c.h" -#include "spi_ssp.h" -#include "w25q80bv.h" -#if defined(IS_PRALINE) - #include "fpga.h" - #include "ice40_spi.h" -#endif - -/* TODO: Hide these configurations */ -extern const i2c_lpc_config_t i2c_config_si5351c_fast_clock; -extern si5351c_driver_t clock_gen; -extern ssp_config_t ssp_config_max283x; -extern ssp_config_t ssp_config_max5864; -extern ssp_config_t ssp_config_w25q80bv; - -#if defined(IS_PRALINE) -extern ssp_config_t ssp_config_ice40_fpga; -extern ice40_spi_driver_t ice40; -extern fpga_driver_t fpga; -#endif -extern max283x_driver_t max283x; -extern max5864_driver_t max5864; -extern mixer_driver_t mixer; -extern w25q80bv_driver_t spi_flash; -extern sgpio_config_t sgpio_config; -extern radio_t radio; -extern rf_path_t rf_path; -extern jtag_gpio_t jtag_gpio_cpld; -extern jtag_t jtag_cpld; -extern i2c_bus_t i2c0; - -void ssp1_set_mode_max283x(void); -void ssp1_set_mode_max5864(void); -#if defined(IS_PRALINE) -void ssp1_set_mode_ice40(void); -#endif - -#ifdef __cplusplus -} -#endif diff --git a/firmware/common/fpga.c b/firmware/common/fpga.c index 172810a82..f68b6525e 100644 --- a/firmware/common/fpga.c +++ b/firmware/common/fpga.c @@ -24,8 +24,13 @@ #include -#include "drivers.h" #include "ice40_spi.h" +#include "max283x.h" + +/* Driver instance. */ +fpga_driver_t fpga = { + .bus = &ice40, +}; /* Set up all registers according to the loaded bitstream's defaults. */ void fpga_init(fpga_driver_t* const drv) diff --git a/firmware/common/fpga.h b/firmware/common/fpga.h index 65826b216..1765fcdd1 100644 --- a/firmware/common/fpga.h +++ b/firmware/common/fpga.h @@ -91,4 +91,5 @@ bool fpga_spi_selftest(void); bool fpga_sgpio_selftest(void); bool fpga_if_xcvr_selftest(void); -//void narrowband_filter_set(const uint8_t value); +/* Driver instance. */ +extern fpga_driver_t fpga; diff --git a/firmware/common/fpga_image.c b/firmware/common/fpga_image.c index 989d16b2f..3ebadad83 100644 --- a/firmware/common/fpga_image.c +++ b/firmware/common/fpga_image.c @@ -23,10 +23,10 @@ #include #include -#include "drivers.h" #include "fpga.h" #include "ice40_spi.h" #include "lz4_blk.h" +#include "max283x.h" #include "selftest.h" struct fpga_image_read_ctx { diff --git a/firmware/common/fpga_selftest.c b/firmware/common/fpga_selftest.c index 30e70ea27..c51dd0086 100644 --- a/firmware/common/fpga_selftest.c +++ b/firmware/common/fpga_selftest.c @@ -25,7 +25,6 @@ #include "clock_gen.h" #include "delay.h" -#include "drivers.h" #include "fixed_point.h" #include "fpga.h" #include "ice40_spi.h" diff --git a/firmware/common/i2c_bus.c b/firmware/common/i2c_bus.c index 6d8dcd258..c0d5b79dd 100644 --- a/firmware/common/i2c_bus.c +++ b/firmware/common/i2c_bus.c @@ -22,6 +22,25 @@ #include "i2c_bus.h" +#include + +#include "i2c_lpc.h" + +/* Driver instances. */ +i2c_bus_t i2c0 = { + .obj = (void*) I2C0_BASE, + .start = i2c_lpc_start, + .stop = i2c_lpc_stop, + .transfer = i2c_lpc_transfer, +}; + +i2c_bus_t i2c1 = { + .obj = (void*) I2C1_BASE, + .start = i2c_lpc_start, + .stop = i2c_lpc_stop, + .transfer = i2c_lpc_transfer, +}; + void i2c_bus_start(i2c_bus_t* const bus, const void* const config) { bus->start(bus, config); diff --git a/firmware/common/i2c_bus.h b/firmware/common/i2c_bus.h index 7519ba140..fa1211c17 100644 --- a/firmware/common/i2c_bus.h +++ b/firmware/common/i2c_bus.h @@ -47,3 +47,7 @@ void i2c_bus_transfer( const size_t tx_count, uint8_t* const rx, const size_t rx_count); + +/* Driver instances. */ +extern i2c_bus_t i2c0; +extern i2c_bus_t i2c1; diff --git a/firmware/common/ice40_spi.c b/firmware/common/ice40_spi.c index c8364b8af..2685092a4 100644 --- a/firmware/common/ice40_spi.c +++ b/firmware/common/ice40_spi.c @@ -28,6 +28,23 @@ #include "delay.h" #include "platform_scu.h" +/* Driver instance. */ +ssp_config_t ssp_config_ice40_fpga = { + .data_bits = SSP_DATA_8BITS, + .spi_mode = SSP_CPOL_1_CPHA_1, + .serial_clock_rate = 21, + .clock_prescale_rate = 2, +}; + +ice40_spi_driver_t ice40 = { + .bus = &spi_bus_ssp1, +}; + +void ssp1_set_mode_ice40(void) +{ + spi_bus_start(&spi_bus_ssp1, &ssp_config_ice40_fpga); +} + void ice40_spi_target_init(ice40_spi_driver_t* const drv) { const platform_scu_t* scu = platform_scu(); diff --git a/firmware/common/ice40_spi.h b/firmware/common/ice40_spi.h index 4ceddffa7..a13620336 100644 --- a/firmware/common/ice40_spi.h +++ b/firmware/common/ice40_spi.h @@ -27,6 +27,7 @@ #include "gpio.h" #include "spi_bus.h" +#include "spi_ssp.h" typedef struct { spi_bus_t* const bus; @@ -43,3 +44,8 @@ bool ice40_spi_syscfg_program( uint8_t* buf, size_t (*read_block_cb)(void* ctx), void* read_ctx); + +/* Driver instance. */ +extern ssp_config_t ssp_config_ice40_fpga; +extern ice40_spi_driver_t ice40; +void ssp1_set_mode_ice40(void); diff --git a/firmware/common/max283x.c b/firmware/common/max283x.c index 3b49ab6e8..e7221bb02 100644 --- a/firmware/common/max283x.c +++ b/firmware/common/max283x.c @@ -41,7 +41,25 @@ #include "max2839_target.h" #endif -extern spi_bus_t spi_bus_ssp1; +/* Driver instance. */ +ssp_config_t ssp_config_max283x = { + /* 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 + .serial_clock_rate = 21, + .clock_prescale_rate = 2, +}; + +max283x_driver_t max283x = {}; + +void ssp1_set_mode_max283x(void) +{ + spi_bus_start(&spi_bus_ssp1, &ssp_config_max283x); +} #ifdef IS_PRALINE max2831_driver_t max2831 = { diff --git a/firmware/common/max283x.h b/firmware/common/max283x.h index 01bb40b08..b4e446201 100644 --- a/firmware/common/max283x.h +++ b/firmware/common/max283x.h @@ -28,6 +28,7 @@ #include "fixed_point.h" #include "platform_detect.h" +#include "spi_ssp.h" #ifdef IS_PRALINE #include "max2831.h" @@ -139,3 +140,8 @@ void max283x_set_rx_hpf_frequency( /* Perform MAX2831 TX and RX calibration. */ void max283x_tx_calibration(max283x_driver_t* const drv); void max283x_rx_calibration(max283x_driver_t* const drv); + +/* Driver instance. */ +extern ssp_config_t ssp_config_max283x; +extern max283x_driver_t max283x; +void ssp1_set_mode_max283x(void); diff --git a/firmware/common/max5864.c b/firmware/common/max5864.c index b91a1cd13..88d781b96 100644 --- a/firmware/common/max5864.c +++ b/firmware/common/max5864.c @@ -24,6 +24,35 @@ #include +#include + +#include "max5864_target.h" +#include "spi_bus.h" + +/* Driver instance. */ +ssp_config_t ssp_config_max5864 = { + /* 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 + .data_bits = SSP_DATA_8BITS, + .serial_clock_rate = 21, + .clock_prescale_rate = 2, +}; + +max5864_driver_t max5864 = { + .bus = &spi_bus_ssp1, + .target_init = max5864_target_init, +}; + +void ssp1_set_mode_max5864(void) +{ + spi_bus_start(max5864.bus, &ssp_config_max5864); +} + static void max5864_write(max5864_driver_t* const drv, uint8_t value) { spi_bus_transfer(drv->bus, &value, 1); diff --git a/firmware/common/max5864.h b/firmware/common/max5864.h index 56d730cc3..a617cdf0a 100644 --- a/firmware/common/max5864.h +++ b/firmware/common/max5864.h @@ -23,6 +23,7 @@ #pragma once #include "spi_bus.h" +#include "spi_ssp.h" typedef struct _max5864_driver_t { spi_bus_t* const bus; @@ -37,3 +38,8 @@ 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); + +/* Driver instance. */ +extern ssp_config_t ssp_config_max5864; +extern max5864_driver_t max5864; +void ssp1_set_mode_max5864(void); diff --git a/firmware/common/mixer.h b/firmware/common/mixer.h index f7861725e..35c0f047a 100644 --- a/firmware/common/mixer.h +++ b/firmware/common/mixer.h @@ -65,3 +65,6 @@ extern fp_40_24_t mixer_set_frequency( extern void mixer_enable(mixer_driver_t* const mixer); extern void mixer_disable(mixer_driver_t* const mixer); extern void mixer_set_gpo(mixer_driver_t* const drv, uint8_t gpo); + +/* Mixer instance. */ +extern mixer_driver_t mixer; diff --git a/firmware/common/operacake.c b/firmware/common/operacake.c index 24ca6541b..f50c4f7e9 100644 --- a/firmware/common/operacake.c +++ b/firmware/common/operacake.c @@ -26,7 +26,6 @@ #include -#include "drivers.h" #include "gpio.h" #include "gpio_lpc.h" #include "i2c_bus.h" diff --git a/firmware/common/pins.c b/firmware/common/pins.c index 6f8123cb2..c51de3832 100644 --- a/firmware/common/pins.c +++ b/firmware/common/pins.c @@ -26,9 +26,11 @@ #include #include -#include "drivers.h" +#include "cpld_jtag.h" #include "gpio.h" #include "leds.h" +#include "max283x.h" +#include "max5864.h" #include "mixer.h" #include "platform_detect.h" #include "platform_gpio.h" @@ -36,8 +38,10 @@ #include "power.h" #include "rf_path.h" #include "sgpio.h" +#include "w25q80bv.h" #if defined(IS_PRALINE) #include "clock_io.h" + #include "ice40_spi.h" #endif void pins_shutdown(void) diff --git a/firmware/common/portapack.c b/firmware/common/portapack.c index f25a4a6e8..d3d848fcf 100644 --- a/firmware/common/portapack.c +++ b/firmware/common/portapack.c @@ -26,7 +26,6 @@ #include "cpld_jtag.h" #include "delay.h" -#include "drivers.h" #include "gpio.h" #include "gpio_lpc.h" #include "platform_gpio.h" diff --git a/firmware/common/radio.c b/firmware/common/radio.c index 8cf73cc81..eb01b5de9 100644 --- a/firmware/common/radio.c +++ b/firmware/common/radio.c @@ -26,7 +26,6 @@ #include #include "clock_io.h" -#include "drivers.h" #include "fixed_point.h" #include "max283x.h" #include "mixer.h" diff --git a/firmware/common/radio.h b/firmware/common/radio.h index 7ab46c80b..b785c2817 100644 --- a/firmware/common/radio.h +++ b/firmware/common/radio.h @@ -260,3 +260,11 @@ bool radio_update(radio_t* const radio); * the request bank for the new mode. */ void radio_switch_opmode(radio_t* const radio, const transceiver_mode_t mode); + +/** + * Driver instance. + * + * This needs to be configured and provided by the application + * binary. e.g. firmware/hackrf_usb/hackrf_usb.c + */ +extern radio_t radio; diff --git a/firmware/common/rf_path.c b/firmware/common/rf_path.c index ea1c0d451..e3292532f 100644 --- a/firmware/common/rf_path.c +++ b/firmware/common/rf_path.c @@ -23,7 +23,6 @@ #include "rf_path.h" -#include "drivers.h" #include "max283x.h" #include "max5864.h" #include "mixer.h" @@ -36,6 +35,11 @@ #include "platform_gpio.h" #endif +/* RF Path instance. */ +rf_path_t rf_path = { + .switchctrl = 0, +}; + /* * RF switches on Jawbreaker are controlled by General Purpose Outputs (GPO) on * the RFFC5072. diff --git a/firmware/common/rf_path.h b/firmware/common/rf_path.h index 12f83b535..ca7641e44 100644 --- a/firmware/common/rf_path.h +++ b/firmware/common/rf_path.h @@ -106,3 +106,6 @@ void rf_path_set_antenna(rf_path_t* const rf_path, const uint_fast8_t enable); #ifdef IS_PRALINE void narrowband_filter_set(const uint8_t value); #endif + +/* RF Path instance. */ +extern rf_path_t rf_path; diff --git a/firmware/common/rom_iap.c b/firmware/common/rom_iap.c index 09da0b7cc..25dfa2690 100644 --- a/firmware/common/rom_iap.c +++ b/firmware/common/rom_iap.c @@ -22,7 +22,6 @@ #include -#include "drivers.h" #include "rom_iap.h" #include "spi_bus.h" #include "w25q80bv.h" diff --git a/firmware/common/sgpio.c b/firmware/common/sgpio.c index 568f1208b..e6151e467 100644 --- a/firmware/common/sgpio.c +++ b/firmware/common/sgpio.c @@ -35,6 +35,11 @@ #include "clock_io.h" #endif +/* Driver configuration instance. */ +sgpio_config_t sgpio_config = { + .slice_mode_multislice = true, +}; + static void update_q_invert(sgpio_config_t* const config); void sgpio_configure_pin_functions(sgpio_config_t* const config) diff --git a/firmware/common/sgpio.h b/firmware/common/sgpio.h index 409cef0ce..767d6f48c 100644 --- a/firmware/common/sgpio.h +++ b/firmware/common/sgpio.h @@ -50,3 +50,6 @@ void sgpio_cpld_stream_disable(sgpio_config_t* const config); bool sgpio_cpld_stream_is_enabled(sgpio_config_t* const config); void sgpio_cpld_set_mixer_invert(sgpio_config_t* const config, uint_fast8_t invert); + +/* Driver configuration instance. */ +extern sgpio_config_t sgpio_config; diff --git a/firmware/common/si5351c.c b/firmware/common/si5351c.c index c97674054..a7b605f5b 100644 --- a/firmware/common/si5351c.c +++ b/firmware/common/si5351c.c @@ -25,6 +25,7 @@ #include "clock_io.h" #include "delay.h" +#include "i2c_lpc.h" #include "platform_detect.h" #include "selftest.h" #include "si5351c.h" @@ -35,6 +36,18 @@ #include "platform_scu.h" #endif +/* Driver instance. */ +// const i2c_lpc_config_t i2c_config_si5351c_slow_clock = { +// .duty_cycle_count = 15, +// }; +const i2c_lpc_config_t i2c_config_si5351c_fast_clock = { + .duty_cycle_count = 255, +}; +si5351c_driver_t si5351c = { + .bus = &i2c0, + .i2c_address = 0x60, +}; + static enum pll_sources active_clock_source = PLL_SOURCE_UNINITIALIZED; /* External clock output default is deactivated as it creates noise */ static bool clkout_enabled = false; diff --git a/firmware/common/si5351c.h b/firmware/common/si5351c.h index 9e6b9ab81..b38eac90b 100644 --- a/firmware/common/si5351c.h +++ b/firmware/common/si5351c.h @@ -31,6 +31,7 @@ extern "C" { #include #include "i2c_bus.h" +#include "i2c_lpc.h" #define SI_INTDIV(x) (x * 128 - 512) @@ -115,6 +116,10 @@ void si5351c_set_phase( const uint8_t ms_number, const uint8_t offset); +/* Driver Instance. */ +extern const i2c_lpc_config_t i2c_config_si5351c_fast_clock; +extern si5351c_driver_t si5351c; + #ifdef __cplusplus } #endif diff --git a/firmware/common/spi_bus.c b/firmware/common/spi_bus.c index a26b4bab6..a5332699b 100644 --- a/firmware/common/spi_bus.c +++ b/firmware/common/spi_bus.c @@ -22,8 +22,30 @@ #include "spi_bus.h" +#include + +#include "spi_ssp.h" + +/* Driver instances. */ +spi_bus_t spi_bus_ssp0 = { + .obj = (void*) SSP0_BASE, + .start = spi_ssp_start, + .stop = spi_ssp_stop, + .transfer = spi_ssp_transfer, + .transfer_gather = spi_ssp_transfer_gather, +}; + +spi_bus_t spi_bus_ssp1 = { + .obj = (void*) SSP1_BASE, + .start = spi_ssp_start, + .stop = spi_ssp_stop, + .transfer = spi_ssp_transfer, + .transfer_gather = spi_ssp_transfer_gather, +}; + void spi_bus_start(spi_bus_t* const bus, const void* const config) { + bus->config = config; bus->start(bus, config); } diff --git a/firmware/common/spi_bus.h b/firmware/common/spi_bus.h index 07d5787d8..23b3107b3 100644 --- a/firmware/common/spi_bus.h +++ b/firmware/common/spi_bus.h @@ -51,3 +51,7 @@ void spi_bus_transfer_gather( spi_bus_t* const bus, const spi_transfer_t* const transfers, const size_t count); + +/* Driver instances. */ +extern spi_bus_t spi_bus_ssp0; +extern spi_bus_t spi_bus_ssp1; diff --git a/firmware/common/ui_rad1o.c b/firmware/common/ui_rad1o.c index 757e11f1e..378798b0f 100644 --- a/firmware/common/ui_rad1o.c +++ b/firmware/common/ui_rad1o.c @@ -27,7 +27,7 @@ #include #include "clock_gen.h" -#include "drivers.h" +#include "max283x.h" #include "rf_path.h" #include "transceiver_mode.h" #ifdef IS_NOT_RAD1O diff --git a/firmware/common/w25q80bv.c b/firmware/common/w25q80bv.c index f569bedf0..11c6d5c0b 100644 --- a/firmware/common/w25q80bv.c +++ b/firmware/common/w25q80bv.c @@ -27,11 +27,15 @@ * programming the flash. */ +#include "w25q80bv.h" + #include #include +#include + #include "platform_detect.h" -#include "w25q80bv.h" +#include "w25q80bv_target.h" #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) @@ -51,6 +55,18 @@ #define W25Q80BV_DEVICE_ID_RES 0x13 /* Expected device_id for W25Q80BV */ +/* Driver instance. */ +ssp_config_t ssp_config_w25q80bv = { + .data_bits = SSP_DATA_8BITS, + .serial_clock_rate = 2, + .clock_prescale_rate = 2, +}; + +w25q80bv_driver_t spi_flash = { + .bus = &spi_bus_ssp0, + .target_init = w25q80bv_target_init, +}; + /* * Set up pins for GPIO and SPI control, configure SSP0 peripheral for SPI. * SSP0_CS is controlled by GPIO in order to handle various transfer lengths. diff --git a/firmware/common/w25q80bv.h b/firmware/common/w25q80bv.h index a43d64450..21d0814be 100644 --- a/firmware/common/w25q80bv.h +++ b/firmware/common/w25q80bv.h @@ -28,6 +28,7 @@ #include "gpio.h" #include "spi_bus.h" +#include "spi_ssp.h" #define W25Q80BV_DEVICE_ID_RES 0x13 /* Expected device_id for W25Q80BV */ #define W25Q16DV_DEVICE_ID_RES 0x14 /* Expected device_id for W25Q16DV */ @@ -65,3 +66,7 @@ void w25q80bv_read( uint32_t len, uint8_t* const data); void w25q80bv_clear_status(w25q80bv_driver_t* const drv); + +/* Driver instance. */ +extern ssp_config_t ssp_config_w25q80bv; +extern w25q80bv_driver_t spi_flash; diff --git a/firmware/hackrf-common.cmake b/firmware/hackrf-common.cmake index 04d8b1a3f..eb1d57160 100644 --- a/firmware/hackrf-common.cmake +++ b/firmware/hackrf-common.cmake @@ -168,10 +168,10 @@ endmacro() macro(DeclareTargets) SET(SRC_M4 ${SRC_M4} - ${PATH_HACKRF_FIRMWARE_COMMON}/drivers.c ${PATH_HACKRF_FIRMWARE_COMMON}/power.c ${PATH_HACKRF_FIRMWARE_COMMON}/cpu_clock.c ${PATH_HACKRF_FIRMWARE_COMMON}/delay.c + ${PATH_HACKRF_FIRMWARE_COMMON}/cpld_jtag.c ${PATH_HACKRF_FIRMWARE_COMMON}/pins.c ${PATH_HACKRF_FIRMWARE_COMMON}/leds.c ${PATH_HACKRF_FIRMWARE_COMMON}/sgpio.c diff --git a/firmware/hackrf_usb/CMakeLists.txt b/firmware/hackrf_usb/CMakeLists.txt index 3fd3ea871..fe392f49c 100644 --- a/firmware/hackrf_usb/CMakeLists.txt +++ b/firmware/hackrf_usb/CMakeLists.txt @@ -66,7 +66,6 @@ set(SRC_M4 usb_api_adc.c "${PATH_HACKRF_FIRMWARE_COMMON}/usb_queue.c" "${PATH_HACKRF_FIRMWARE_COMMON}/fault_handler.c" - "${PATH_HACKRF_FIRMWARE_COMMON}/cpld_jtag.c" "${PATH_HACKRF_FIRMWARE_COMMON}/crc.c" "${PATH_HACKRF_FIRMWARE_COMMON}/rom_iap.c" "${PATH_HACKRF_FIRMWARE_COMMON}/operacake.c" diff --git a/firmware/hackrf_usb/hackrf_usb.c b/firmware/hackrf_usb/hackrf_usb.c index 54431ff3c..7419d063e 100644 --- a/firmware/hackrf_usb/hackrf_usb.c +++ b/firmware/hackrf_usb/hackrf_usb.c @@ -33,7 +33,6 @@ #include #include #include -#include #include #include #include @@ -98,6 +97,10 @@ extern uint32_t __m0_end__; extern uint32_t __ram_m0_start__; extern uint32_t _etext_ram, _text_ram, _etext_rom; +radio_t radio = { + .sample_rate_cb = sample_rate_set, +}; + static usb_request_handler_fn vendor_request_handler[] = { NULL, usb_vendor_request_set_transceiver_mode, diff --git a/firmware/hackrf_usb/usb_api_cpld.c b/firmware/hackrf_usb/usb_api_cpld.c index ed2beeda6..391b93667 100644 --- a/firmware/hackrf_usb/usb_api_cpld.c +++ b/firmware/hackrf_usb/usb_api_cpld.c @@ -29,7 +29,6 @@ #include #include -#include #include #include #include diff --git a/firmware/hackrf_usb/usb_api_register.c b/firmware/hackrf_usb/usb_api_register.c index 58c1684c7..30d1d4934 100644 --- a/firmware/hackrf_usb/usb_api_register.c +++ b/firmware/hackrf_usb/usb_api_register.c @@ -27,7 +27,6 @@ #include #include -#include #include #include #include @@ -101,7 +100,7 @@ usb_request_status_t usb_vendor_request_write_si5351c( if (endpoint->setup.index < 256) { if (endpoint->setup.value < 256) { si5351c_write_single( - &clock_gen, + &si5351c, endpoint->setup.index, endpoint->setup.value); usb_transfer_schedule_ack(endpoint->in); @@ -121,7 +120,7 @@ usb_request_status_t usb_vendor_request_read_si5351c( if (stage == USB_TRANSFER_STAGE_SETUP) { if (endpoint->setup.index < 256) { const uint8_t value = - si5351c_read_single(&clock_gen, endpoint->setup.index); + si5351c_read_single(&si5351c, endpoint->setup.index); endpoint->buffer[0] = value; usb_transfer_schedule_block( endpoint->in, @@ -211,7 +210,7 @@ usb_request_status_t usb_vendor_request_set_clkout_enable( const usb_transfer_stage_t stage) { if (stage == USB_TRANSFER_STAGE_SETUP) { - si5351c_clkout_enable(&clock_gen, endpoint->setup.value); + si5351c_clkout_enable(&si5351c, endpoint->setup.value); usb_transfer_schedule_ack(endpoint->in); } return USB_REQUEST_STATUS_OK; @@ -222,7 +221,7 @@ usb_request_status_t usb_vendor_request_get_clkin_status( const usb_transfer_stage_t stage) { if (stage == USB_TRANSFER_STAGE_SETUP) { - endpoint->buffer[0] = si5351c_clkin_signal_valid(&clock_gen); + endpoint->buffer[0] = si5351c_clkin_signal_valid(&si5351c); usb_transfer_schedule_block( endpoint->in, &endpoint->buffer, diff --git a/firmware/hackrf_usb/usb_api_spiflash.c b/firmware/hackrf_usb/usb_api_spiflash.c index 2c944a104..d490eb0ee 100644 --- a/firmware/hackrf_usb/usb_api_spiflash.c +++ b/firmware/hackrf_usb/usb_api_spiflash.c @@ -26,7 +26,6 @@ #include #include -#include #include #include #include diff --git a/firmware/hackrf_usb/usb_api_sweep.c b/firmware/hackrf_usb/usb_api_sweep.c index ae3b399d1..72ff24674 100644 --- a/firmware/hackrf_usb/usb_api_sweep.c +++ b/firmware/hackrf_usb/usb_api_sweep.c @@ -25,13 +25,13 @@ #include -#include #include #include #include #include #include #include +#include #include #include #include diff --git a/firmware/hackrf_usb/usb_api_transceiver.c b/firmware/hackrf_usb/usb_api_transceiver.c index b6c6782be..7f6f9473f 100644 --- a/firmware/hackrf_usb/usb_api_transceiver.c +++ b/firmware/hackrf_usb/usb_api_transceiver.c @@ -27,13 +27,13 @@ #include #include -#include #include #include #include #include #include #include +#include #include #include #include