diff --git a/firmware/common/fpga.c b/firmware/common/fpga.c index f68b6525..ec4ff2ec 100644 --- a/firmware/common/fpga.c +++ b/firmware/common/fpga.c @@ -25,7 +25,6 @@ #include #include "ice40_spi.h" -#include "max283x.h" /* Driver instance. */ fpga_driver_t fpga = { @@ -57,9 +56,7 @@ void fpga_setup(fpga_driver_t* const drv) uint8_t fpga_reg_read(fpga_driver_t* const drv, uint8_t r) { uint8_t v; - ssp1_set_mode_ice40(); v = ice40_spi_read(drv->bus, r); - ssp1_set_mode_max283x(); drv->regs[r] = v; return v; } @@ -67,9 +64,7 @@ uint8_t fpga_reg_read(fpga_driver_t* const drv, uint8_t r) void fpga_reg_write(fpga_driver_t* const drv, uint8_t r, uint8_t v) { drv->regs[r] = v; - ssp1_set_mode_ice40(); ice40_spi_write(drv->bus, r, v); - ssp1_set_mode_max283x(); FPGA_REG_SET_CLEAN(drv, r); } diff --git a/firmware/common/fpga_image.c b/firmware/common/fpga_image.c index 3ebadad8..6b440337 100644 --- a/firmware/common/fpga_image.c +++ b/firmware/common/fpga_image.c @@ -26,7 +26,6 @@ #include "fpga.h" #include "ice40_spi.h" #include "lz4_blk.h" -#include "max283x.h" #include "selftest.h" struct fpga_image_read_ctx { @@ -86,7 +85,6 @@ bool fpga_image_load(struct fpga_loader_t* loader, unsigned int index) // A callback function is used by the FPGA programmer // to obtain consecutive gateware chunks. ice40_spi_target_init(&ice40); - ssp1_set_mode_ice40(); struct fpga_image_read_ctx fpga_image_ctx = { .loader = loader, .addr = loader->start_addr + bitstream_offset, @@ -96,7 +94,6 @@ bool fpga_image_load(struct fpga_loader_t* loader, unsigned int index) loader->out_buffer, fpga_image_read_block_cb, &fpga_image_ctx); - ssp1_set_mode_max283x(); // Update selftest result. selftest.fpga_image_load = success ? PASSED : FAILED; diff --git a/firmware/common/fpga_selftest.c b/firmware/common/fpga_selftest.c index 06f2e8ee..b9d7025e 100644 --- a/firmware/common/fpga_selftest.c +++ b/firmware/common/fpga_selftest.c @@ -71,10 +71,8 @@ bool fpga_spi_selftest(void) // Test writing a register and reading it back. uint8_t reg = 6; uint8_t write_value = 0xA5; - ssp1_set_mode_ice40(); ice40_spi_write(&ice40, reg, write_value); uint8_t read_value = ice40_spi_read(&ice40, reg); - ssp1_set_mode_max283x(); // Update selftest result. selftest.fpga_spi = (read_value == write_value) ? PASSED : FAILED; diff --git a/firmware/common/ice40_spi.c b/firmware/common/ice40_spi.c index 2685092a..ce646fd6 100644 --- a/firmware/common/ice40_spi.c +++ b/firmware/common/ice40_spi.c @@ -40,11 +40,6 @@ 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(); @@ -67,14 +62,14 @@ void ice40_spi_target_init(ice40_spi_driver_t* const drv) uint8_t ice40_spi_read(ice40_spi_driver_t* const drv, uint8_t r) { uint8_t value[3] = {r & 0x7F, 0, 0}; - spi_bus_transfer(drv->bus, value, 3); + spi_bus_transfer(drv->bus, &ssp_config_ice40_fpga, value, 3); return value[2]; } void ice40_spi_write(ice40_spi_driver_t* const drv, uint8_t r, uint16_t v) { uint8_t value[3] = {(r & 0x7F) | 0x80, v, 0}; - spi_bus_transfer(drv->bus, value, 3); + spi_bus_transfer(drv->bus, &ssp_config_ice40_fpga, value, 3); } static void spi_ssp1_wait_for_tx_fifo_not_full(void) @@ -107,6 +102,8 @@ bool ice40_spi_syscfg_program( size_t (*read_block_cb)(void* ctx), void* read_ctx) { + spi_bus_start(drv->bus, &ssp_config_ice40_fpga); + // Drive CRESET_B = 0, SPI_SS = 0, SPI_SCK = 1. gpio_clear(drv->gpio_creset); gpio_clear(drv->gpio_select); diff --git a/firmware/common/ice40_spi.h b/firmware/common/ice40_spi.h index a1362033..331814aa 100644 --- a/firmware/common/ice40_spi.h +++ b/firmware/common/ice40_spi.h @@ -48,4 +48,3 @@ bool ice40_spi_syscfg_program( /* 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/max2831.c b/firmware/common/max2831.c index 05d5cb29..08e59a59 100644 --- a/firmware/common/max2831.c +++ b/firmware/common/max2831.c @@ -109,7 +109,7 @@ static void max2831_write(max2831_driver_t* const drv, uint8_t r, uint16_t v) { uint32_t word = (((uint32_t) v & 0x3fff) << 4) | (r & 0xf); uint16_t values[2] = {word >> 9, word & 0x1ff}; - spi_bus_transfer(drv->bus, values, 2); + spi_bus_transfer(drv->bus, drv->config, values, 2); } uint16_t max2831_reg_read(max2831_driver_t* const drv, uint8_t r) diff --git a/firmware/common/max2831.h b/firmware/common/max2831.h index 0885fd39..f1a28c54 100644 --- a/firmware/common/max2831.h +++ b/firmware/common/max2831.h @@ -50,6 +50,7 @@ typedef enum { typedef struct _max2831_driver_t { spi_bus_t* bus; + void* config; gpio_t gpio_enable; gpio_t gpio_rxtx; gpio_t gpio_rxhp; diff --git a/firmware/common/max2837.c b/firmware/common/max2837.c index 561a17f9..f512c6af 100644 --- a/firmware/common/max2837.c +++ b/firmware/common/max2837.c @@ -156,14 +156,14 @@ void max2837_setup(max2837_driver_t* const drv) static uint16_t max2837_read(max2837_driver_t* const drv, uint8_t r) { uint16_t value = (1 << 15) | (r << 10); - spi_bus_transfer(drv->bus, &value, 1); + spi_bus_transfer(drv->bus, drv->config, &value, 1); return value & 0x3ff; } static void max2837_write(max2837_driver_t* const drv, uint8_t r, uint16_t v) { uint16_t value = (r << 10) | (v & 0x3ff); - spi_bus_transfer(drv->bus, &value, 1); + spi_bus_transfer(drv->bus, drv->config, &value, 1); } uint16_t max2837_reg_read(max2837_driver_t* const drv, uint8_t r) diff --git a/firmware/common/max2837.h b/firmware/common/max2837.h index f32bde6e..a33179ac 100644 --- a/firmware/common/max2837.h +++ b/firmware/common/max2837.h @@ -43,6 +43,7 @@ typedef enum { typedef struct _max2837_driver_t { spi_bus_t* bus; + void* config; gpio_t gpio_enable; gpio_t gpio_rx_enable; gpio_t gpio_tx_enable; diff --git a/firmware/common/max2839.c b/firmware/common/max2839.c index 87917ed8..a938b733 100644 --- a/firmware/common/max2839.c +++ b/firmware/common/max2839.c @@ -164,14 +164,14 @@ void max2839_setup(max2839_driver_t* const drv) static uint16_t max2839_read(max2839_driver_t* const drv, uint8_t r) { uint16_t value = (1 << 15) | (r << 10); - spi_bus_transfer(drv->bus, &value, 1); + spi_bus_transfer(drv->bus, drv->config, &value, 1); return value & 0x3ff; } static void max2839_write(max2839_driver_t* const drv, uint8_t r, uint16_t v) { uint16_t value = (r << 10) | (v & 0x3ff); - spi_bus_transfer(drv->bus, &value, 1); + spi_bus_transfer(drv->bus, drv->config, &value, 1); } uint16_t max2839_reg_read(max2839_driver_t* const drv, uint8_t r) diff --git a/firmware/common/max2839.h b/firmware/common/max2839.h index 0e397294..6430ce37 100644 --- a/firmware/common/max2839.h +++ b/firmware/common/max2839.h @@ -46,6 +46,7 @@ typedef enum { typedef struct _max2839_driver_t { spi_bus_t* bus; + void* config; gpio_t gpio_enable; gpio_t gpio_rxtx; void (*target_init)(struct _max2839_driver_t* const drv); diff --git a/firmware/common/max283x.c b/firmware/common/max283x.c index e7221bb0..c0478ae0 100644 --- a/firmware/common/max283x.c +++ b/firmware/common/max283x.c @@ -29,7 +29,6 @@ #include "fixed_point.h" #include "platform_detect.h" #include "platform_gpio.h" -#include "spi_bus.h" #ifdef IS_PRALINE #include "max2831_target.h" @@ -56,14 +55,10 @@ ssp_config_t ssp_config_max283x = { 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 = { .bus = &spi_bus_ssp1, + .config = &ssp_config_max283x, .target_init = max2831_target_init, .set_mode = max2831_target_set_mode, }; @@ -72,6 +67,7 @@ max2831_driver_t max2831 = { #ifdef IS_NOT_PRALINE max2837_driver_t max2837 = { .bus = &spi_bus_ssp1, + .config = &ssp_config_max283x, .target_init = max2837_target_init, .set_mode = max2837_target_set_mode, }; @@ -80,6 +76,7 @@ max2837_driver_t max2837 = { #ifdef IS_HACKRF_ONE max2839_driver_t max2839 = { .bus = &spi_bus_ssp1, + .config = &ssp_config_max283x, .target_init = max2839_target_init, .set_mode = max2839_target_set_mode, }; diff --git a/firmware/common/max283x.h b/firmware/common/max283x.h index 4db5edfe..7c9c03dd 100644 --- a/firmware/common/max283x.h +++ b/firmware/common/max283x.h @@ -143,4 +143,3 @@ 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 88d781b9..5f3417fc 100644 --- a/firmware/common/max5864.c +++ b/firmware/common/max5864.c @@ -48,14 +48,9 @@ max5864_driver_t max5864 = { .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); + spi_bus_transfer(drv->bus, &ssp_config_max5864, &value, 1); } static void max5864_init(max5864_driver_t* const drv) diff --git a/firmware/common/max5864.h b/firmware/common/max5864.h index a617cdf0..0f561685 100644 --- a/firmware/common/max5864.h +++ b/firmware/common/max5864.h @@ -42,4 +42,3 @@ 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/pins.c b/firmware/common/pins.c index 3010cd9f..1f98fd9a 100644 --- a/firmware/common/pins.c +++ b/firmware/common/pins.c @@ -318,8 +318,6 @@ void pins_setup(void) } #endif - ssp1_set_mode_max283x(); - mixer_bus_setup(&mixer); #ifdef IS_H1_R9 diff --git a/firmware/common/rf_path.c b/firmware/common/rf_path.c index b497a197..27dd548f 100644 --- a/firmware/common/rf_path.c +++ b/firmware/common/rf_path.c @@ -494,11 +494,9 @@ void rf_path_pin_setup(rf_path_t* const rf_path) void rf_path_init(rf_path_t* const rf_path) { - ssp1_set_mode_max5864(); max5864_setup(&max5864); max5864_shutdown(&max5864); - ssp1_set_mode_max283x(); max283x_setup(&max283x); max283x_start(&max283x); @@ -536,9 +534,7 @@ void rf_path_set_direction(rf_path_t* const rf_path, const rf_path_direction_t d } else { mixer_enable(&mixer); } - ssp1_set_mode_max5864(); max5864_tx(&max5864); - ssp1_set_mode_max283x(); max283x_tx(&max283x); break; @@ -553,9 +549,7 @@ void rf_path_set_direction(rf_path_t* const rf_path, const rf_path_direction_t d } else { mixer_enable(&mixer); } - ssp1_set_mode_max5864(); max5864_rx(&max5864); - ssp1_set_mode_max283x(); max283x_rx(&max283x); break; @@ -564,9 +558,7 @@ void rf_path_set_direction(rf_path_t* const rf_path, const rf_path_direction_t d case RF_PATH_DIRECTION_RX_CALIBRATION: rf_path->switchctrl &= ~SWITCHCTRL_TX; mixer_disable(&mixer); - ssp1_set_mode_max5864(); max5864_xcvr(&max5864); - ssp1_set_mode_max283x(); if (direction == RF_PATH_DIRECTION_TX_CALIBRATION) { max283x_tx_calibration(&max283x); } else { @@ -581,9 +573,7 @@ void rf_path_set_direction(rf_path_t* const rf_path, const rf_path_direction_t d /* Set RF path to receive direction when "off" */ rf_path->switchctrl &= ~SWITCHCTRL_TX; mixer_disable(&mixer); - ssp1_set_mode_max5864(); max5864_standby(&max5864); - ssp1_set_mode_max283x(); max283x_set_mode(&max283x, MAX283x_MODE_STANDBY); break; } diff --git a/firmware/common/rffc5071.c b/firmware/common/rffc5071.c index 2a1866d2..0644a1fa 100644 --- a/firmware/common/rffc5071.c +++ b/firmware/common/rffc5071.c @@ -202,7 +202,7 @@ static uint16_t rffc5071_spi_read(rffc5071_driver_t* const drv, uint8_t r) (void) drv; uint16_t data[] = {0x80 | (r & 0x7f), 0xffff}; - spi_bus_transfer(drv->bus, data, 2); + spi_bus_transfer(drv->bus, drv->bus->config, data, 2); return data[1]; } @@ -211,7 +211,7 @@ static void rffc5071_spi_write(rffc5071_driver_t* const drv, uint8_t r, uint16_t (void) drv; uint16_t data[] = {0x00 | (r & 0x7f), v}; - spi_bus_transfer(drv->bus, data, 2); + spi_bus_transfer(drv->bus, drv->bus->config, data, 2); } uint16_t rffc5071_reg_read(rffc5071_driver_t* const drv, uint8_t r) diff --git a/firmware/common/spi_bus.c b/firmware/common/spi_bus.c index 1b05c298..a667db8a 100644 --- a/firmware/common/spi_bus.c +++ b/firmware/common/spi_bus.c @@ -31,17 +31,29 @@ void spi_bus_start(spi_bus_t* const bus, const void* const config) void spi_bus_stop(spi_bus_t* const bus) { bus->stop(bus); + bus->config = NULL; } -void spi_bus_transfer(spi_bus_t* const bus, void* const data, const size_t count) +void spi_bus_transfer( + spi_bus_t* const bus, + const void* const config, + void* const data, + const size_t count) { + if (config != bus->config) { + spi_bus_start(bus, config); + } bus->transfer(bus, data, count); } void spi_bus_transfer_gather( spi_bus_t* const bus, + const void* const config, const spi_transfer_t* const transfers, const size_t count) { + if (config != bus->config) { + spi_bus_start(bus, config); + } bus->transfer_gather(bus, transfers, count); } diff --git a/firmware/common/spi_bus.h b/firmware/common/spi_bus.h index 07d5787d..bc9c7dee 100644 --- a/firmware/common/spi_bus.h +++ b/firmware/common/spi_bus.h @@ -46,8 +46,13 @@ typedef struct _spi_bus_t { void spi_bus_start(spi_bus_t* const bus, const void* const config); void spi_bus_stop(spi_bus_t* const bus); -void spi_bus_transfer(spi_bus_t* const bus, void* const data, const size_t count); +void spi_bus_transfer( + spi_bus_t* const bus, + const void* const config, + void* const data, + const size_t count); void spi_bus_transfer_gather( spi_bus_t* const bus, + const void* const config, const spi_transfer_t* const transfers, const size_t count); diff --git a/firmware/common/ui_rad1o.c b/firmware/common/ui_rad1o.c index acaa2153..a6d3e544 100644 --- a/firmware/common/ui_rad1o.c +++ b/firmware/common/ui_rad1o.c @@ -26,7 +26,6 @@ #include #include "clock_gen.h" -#include "max283x.h" #include "rf_path.h" #include "transceiver_mode.h" @@ -195,9 +194,6 @@ static void ui_update(void) rad1o_lcdNl(); rad1o_lcdDisplay(); - - // Don't ask... - ssp1_set_mode_max283x(); } static void rad1o_ui_init(void) @@ -211,8 +207,6 @@ static void rad1o_ui_deinit(void) { rad1o_lcdDeInit(); enabled = false; - // Don't ask... - ssp1_set_mode_max283x(); } static void rad1o_ui_set_frequency(uint64_t frequency) diff --git a/firmware/common/w25q80bv.c b/firmware/common/w25q80bv.c index 11c6d5c0..9afa9bea 100644 --- a/firmware/common/w25q80bv.c +++ b/firmware/common/w25q80bv.c @@ -67,6 +67,22 @@ w25q80bv_driver_t spi_flash = { .target_init = w25q80bv_target_init, }; +static void w25q80bv_transfer( + w25q80bv_driver_t* const drv, + void* const data, + const size_t count) +{ + spi_bus_transfer(drv->bus, &ssp_config_w25q80bv, data, count); +} + +static void w25q80bv_transfer_gather( + w25q80bv_driver_t* const drv, + const spi_transfer_t* const transfers, + size_t size) +{ + spi_bus_transfer_gather(drv->bus, &ssp_config_w25q80bv, transfers, size); +} + /* * 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. @@ -96,7 +112,7 @@ void w25q80bv_setup(w25q80bv_driver_t* const drv) uint8_t w25q80bv_get_status(w25q80bv_driver_t* const drv) { uint8_t data[] = {W25Q80BV_READ_STATUS1, 0xFF}; - spi_bus_transfer(drv->bus, data, ARRAY_SIZE(data)); + w25q80bv_transfer(drv, data, ARRAY_SIZE(data)); return data[1]; } @@ -104,7 +120,7 @@ uint8_t w25q80bv_get_status(w25q80bv_driver_t* const drv) uint8_t w25q80bv_get_device_id(w25q80bv_driver_t* const drv) { uint8_t data[] = {W25Q80BV_DEVICE_ID, 0xFF, 0xFF, 0xFF, 0xFF}; - spi_bus_transfer(drv->bus, data, ARRAY_SIZE(data)); + w25q80bv_transfer(drv, data, ARRAY_SIZE(data)); return data[4]; } @@ -124,7 +140,7 @@ void w25q80bv_get_unique_id(w25q80bv_driver_t* const drv, w25q80bv_unique_id_t* 0xFF, 0xFF, 0xFF}; - spi_bus_transfer(drv->bus, data, ARRAY_SIZE(data)); + w25q80bv_transfer(drv, data, ARRAY_SIZE(data)); for (size_t i = 0; i < 8; i++) { unique_id->id_8b[i] = data[5 + i]; @@ -141,7 +157,7 @@ void w25q80bv_write_enable(w25q80bv_driver_t* const drv) w25q80bv_wait_while_busy(drv); uint8_t data[] = {W25Q80BV_WRITE_ENABLE}; - spi_bus_transfer(drv->bus, data, ARRAY_SIZE(data)); + w25q80bv_transfer(drv, data, ARRAY_SIZE(data)); while (!(w25q80bv_get_status(drv) & W25Q80BV_STATUS_WEL)) {} } @@ -159,7 +175,7 @@ void w25q80bv_chip_erase(w25q80bv_driver_t* const drv) w25q80bv_write_enable(drv); uint8_t data[] = {W25Q80BV_CHIP_ERASE}; - spi_bus_transfer(drv->bus, data, ARRAY_SIZE(data)); + w25q80bv_transfer(drv, data, ARRAY_SIZE(data)); } /* write up a 256 byte page or partial page */ @@ -190,7 +206,7 @@ static void w25q80bv_page_program( const spi_transfer_t transfers[] = {{header, ARRAY_SIZE(header)}, {data, len}}; - spi_bus_transfer_gather(drv->bus, transfers, ARRAY_SIZE(transfers)); + w25q80bv_transfer_gather(drv, transfers, ARRAY_SIZE(transfers)); } /* write an arbitrary number of bytes */ @@ -265,7 +281,7 @@ void w25q80bv_read( const spi_transfer_t transfers[] = {{header, ARRAY_SIZE(header)}, {data, len}}; - spi_bus_transfer_gather(drv->bus, transfers, ARRAY_SIZE(transfers)); + w25q80bv_transfer_gather(drv, transfers, ARRAY_SIZE(transfers)); } void w25q80bv_clear_status(w25q80bv_driver_t* const drv) @@ -273,16 +289,16 @@ void w25q80bv_clear_status(w25q80bv_driver_t* const drv) w25q80bv_wait_while_busy(drv); w25q80bv_write_enable(drv); uint8_t data[] = {W25Q80BV_WRITE_STATUS, 0x00, 0x00}; - spi_bus_transfer(drv->bus, data, ARRAY_SIZE(data)); + w25q80bv_transfer(drv, data, ARRAY_SIZE(data)); } void w25q80bv_get_full_status(w25q80bv_driver_t* const drv, uint8_t* data) { uint8_t cmd[] = {W25Q80BV_READ_STATUS1, 0xFF}; - spi_bus_transfer(drv->bus, cmd, ARRAY_SIZE(cmd)); + w25q80bv_transfer(drv, cmd, ARRAY_SIZE(cmd)); data[0] = cmd[1]; cmd[0] = W25Q80BV_READ_STATUS2; cmd[1] = 0xFF; - spi_bus_transfer(drv->bus, cmd, ARRAY_SIZE(cmd)); + w25q80bv_transfer(drv, cmd, ARRAY_SIZE(cmd)); data[1] = cmd[1]; }