From ffcaba10fd4365e992c75ea0efca81e7622548be Mon Sep 17 00:00:00 2001 From: crosstyan Date: Thu, 7 Aug 2025 00:26:53 +0800 Subject: [PATCH] refactor: remove mut_shared_buffer function and streamline buffer handling in SPI transactions --- inc/hal_spi.hpp | 2 - src/hal_spi.cpp | 124 ++++++++++++++++++++++++++---------------------- 2 files changed, 66 insertions(+), 60 deletions(-) diff --git a/inc/hal_spi.hpp b/inc/hal_spi.hpp index 003f8b1..b79560d 100644 --- a/inc/hal_spi.hpp +++ b/inc/hal_spi.hpp @@ -35,8 +35,6 @@ constexpr uint8_t SPI_READ_BUFFER_CMD = RADIOLIB_SX126X_CMD_READ_BUFFER; constexpr size_t DEFAULT_TIMEOUT_MS = 1000; -std::span mut_shared_buffer(); - struct spi_config_t { spi_host_device_t host_id; int clock_speed_hz; diff --git a/src/hal_spi.cpp b/src/hal_spi.cpp index db2ff1f..f6d7cba 100644 --- a/src/hal_spi.cpp +++ b/src/hal_spi.cpp @@ -14,29 +14,21 @@ // https://docs.espressif.com/projects/esp-idf/en/v5.3.2/esp32h2/api-reference/peripherals/spi_master.html // https://github.com/espressif/esp-idf/blob/v5.3.2/examples/peripherals/spi_master/lcd/main/spi_master_example_main.c namespace app::driver::hal::spi { -constexpr auto SPI_CMD_BIT_SIZE = 8; -constexpr auto SPI_BUFFER_OFFSET_BIT_SIZE = 8; -constexpr auto SPI_REGISTER_ADDR_BIT_SIZE = 16; -constexpr auto MAX_BUFFER_SIZE = 256; +static constexpr uint8_t CMD_BIT_SIZE = 8; +static constexpr uint8_t OFFSET_BIT_SIZE = 8; +static constexpr uint8_t REG_ADDR_BIT_SIZE = 16; + +static constexpr auto MAX_BUFFER_SIZE = 256; namespace details { static bool is_initialized = false; static spi_device_handle_t spi_device; - /// should satisfy most of the control register write/read - /// without overlap with the data buffer - constexpr auto DATA_BUFFER_OFFSET = 24; - static_assert(DATA_BUFFER_OFFSET < MAX_BUFFER_SIZE, - "DATA_BUFFER_OFFSET must be less than MAX_BUFFER_SIZE"); - static uint8_t _shared_buffer[MAX_BUFFER_SIZE]; - /** - * @brief used in generic stream io - */ - static std::span shared_buffer = std::span{_shared_buffer}; + static uint8_t _data_buffer[MAX_BUFFER_SIZE]; /** * @brief only used in read/write buffer io */ - static std::span data_buffer = std::span{_shared_buffer + DATA_BUFFER_OFFSET, MAX_BUFFER_SIZE - DATA_BUFFER_OFFSET}; + static std::span data_buffer = std::span{_data_buffer}; } /** @@ -59,10 +51,6 @@ static constexpr auto verify_statuses = [](std::span statuses) { return error::OK; }; -std::span mut_shared_buffer() { - return std::span{details::shared_buffer}; -} - void init(spi_config_t config) { if (details::is_initialized) { return; @@ -162,9 +150,15 @@ inline bool wait_for_not_busy(const size_t timeout_ms) { /*! READ */ +constexpr auto STACK_BUFFER_SIZE = 32; +constexpr auto PADDING = 0xFE; + Result read_stream(uint8_t cmd, std::span data, const size_t timeout_ms) { - if (data.size() > MAX_BUFFER_SIZE - 1) { + std::array _rx_buf; + std::array _tx_buf; + + if (data.size() > STACK_BUFFER_SIZE - 1) { return ue_t{error::INVALID_SIZE}; } @@ -172,7 +166,9 @@ read_stream(uint8_t cmd, std::span data, const size_t timeout_ms) { return ue_t{error::TIMEOUT}; } - auto rx_buffer = details::shared_buffer.subspan(0, data.size() + 1); + auto rx_buffer = std::span{_rx_buf}.subspan(0, data.size() + 1); + auto tx_buffer = std::span{_tx_buf}.subspan(0, rx_buffer.size()); + std::ranges::fill(tx_buffer, PADDING); spi_transaction_ext_t transaction; transaction = spi_transaction_ext_t{ @@ -181,16 +177,16 @@ read_stream(uint8_t cmd, std::span data, const size_t timeout_ms) { .cmd = cmd, .length = static_cast(rx_buffer.size() * 8), .rxlength = static_cast(rx_buffer.size() * 8), - .tx_buffer = nullptr, + .tx_buffer = tx_buffer.data(), .rx_buffer = rx_buffer.data(), }, - .command_bits = static_cast(SPI_CMD_BIT_SIZE), + .command_bits = CMD_BIT_SIZE, .address_bits = 0, .dummy_bits = 0, }; esp_err_t err = spi_device_transmit(details::spi_device, &transaction.base); if (err != ESP_OK) { - ESP_LOGE(TAG, "failed to transfer %s (%d)", esp_err_to_name(err), err); + ESP_LOGE(TAG, "spi transmit: %s (%d)", esp_err_to_name(err), err); return ue_t{error::FAILED}; } @@ -208,7 +204,9 @@ read_stream(uint8_t cmd, std::span data, const size_t timeout_ms) { Result write_stream(uint8_t cmd, std::span data, const size_t timeout_ms) { - if (data.size() > MAX_BUFFER_SIZE) { + std::array _rx_buf; + + if (data.size() > STACK_BUFFER_SIZE - 1) { return ue_t{error::INVALID_SIZE}; } @@ -216,7 +214,7 @@ write_stream(uint8_t cmd, std::span data, const size_t timeout_ms return ue_t{error::TIMEOUT}; } - const auto rx_buffer = details::shared_buffer.subspan(0, data.size()); + const auto rx_buffer = std::span{_rx_buf}.subspan(0, data.size()); spi_transaction_ext_t transaction; transaction = spi_transaction_ext_t{ .base = { @@ -227,13 +225,13 @@ write_stream(uint8_t cmd, std::span data, const size_t timeout_ms .tx_buffer = data.data(), .rx_buffer = rx_buffer.data(), }, - .command_bits = static_cast(SPI_CMD_BIT_SIZE), + .command_bits = CMD_BIT_SIZE, .address_bits = 0, .dummy_bits = 0, }; esp_err_t err = spi_device_transmit(details::spi_device, &transaction.base); if (err != ESP_OK) { - ESP_LOGE(TAG, "failed to transfer %s (%d)", esp_err_to_name(err), err); + ESP_LOGE(TAG, "spi transmit: %s (%d)", esp_err_to_name(err), err); return ue_t{error::FAILED}; } @@ -249,7 +247,10 @@ write_stream(uint8_t cmd, std::span data, const size_t timeout_ms Result read_register(uint16_t reg, std::span data, const size_t timeout_ms) { - if (data.size() > MAX_BUFFER_SIZE - 1) { + std::array _rx_buf; + std::array _tx_buf; + + if (data.size() > STACK_BUFFER_SIZE - 1) { return ue_t{error::INVALID_SIZE}; } @@ -264,24 +265,27 @@ read_register(uint16_t reg, std::span data, const size_t timeout_ms) { // if the tx_buffer is nullptr. spi_transaction_ext_t transaction; - auto rx_buffer = details::shared_buffer.subspan(0, data.size() + 1); - transaction = spi_transaction_ext_t{ - .base = { - .flags = SPI_TRANS_VARIABLE_CMD | SPI_TRANS_VARIABLE_ADDR, - .cmd = SPI_READ_COMMAND, - .addr = reg, - .length = static_cast(rx_buffer.size() * 8), - .rxlength = static_cast(rx_buffer.size() * 8), - .tx_buffer = nullptr, - .rx_buffer = rx_buffer.data(), - }, - .command_bits = static_cast(SPI_CMD_BIT_SIZE), - .address_bits = static_cast(SPI_REGISTER_ADDR_BIT_SIZE), - .dummy_bits = 0, - }; + auto rx_buffer = std::span{_rx_buf}.subspan(0, data.size() + 1); + auto tx_buffer = std::span{_tx_buf}.subspan(0, rx_buffer.size()); + std::ranges::fill(tx_buffer, PADDING); + + transaction = spi_transaction_ext_t{ + .base = { + .flags = SPI_TRANS_VARIABLE_CMD | SPI_TRANS_VARIABLE_ADDR, + .cmd = SPI_READ_COMMAND, + .addr = reg, + .length = static_cast(rx_buffer.size() * 8), + .rxlength = static_cast(rx_buffer.size() * 8), + .tx_buffer = tx_buffer.data(), + .rx_buffer = rx_buffer.data(), + }, + .command_bits = static_cast(CMD_BIT_SIZE), + .address_bits = static_cast(REG_ADDR_BIT_SIZE), + .dummy_bits = 0, + }; esp_err_t err = spi_device_transmit(details::spi_device, &transaction.base); if (err != ESP_OK) { - ESP_LOGE(TAG, "failed to transfer %s (%d)", esp_err_to_name(err), err); + ESP_LOGE(TAG, "spi transmit: %s (%d)", esp_err_to_name(err), err); return ue_t{error::FAILED}; } @@ -297,7 +301,8 @@ read_register(uint16_t reg, std::span data, const size_t timeout_ms) { Result write_register(uint16_t offset, std::span data, const size_t timeout_ms) { - if (data.size() > MAX_BUFFER_SIZE) { + std::array _rx_buf; + if (data.size() > STACK_BUFFER_SIZE - 1) { return ue_t{error::INVALID_SIZE}; } @@ -305,7 +310,7 @@ write_register(uint16_t offset, std::span data, const size_t time return ue_t{error::TIMEOUT}; } - auto rx_buffer = details::shared_buffer.subspan(0, data.size()); + auto rx_buffer = std::span{_rx_buf}.subspan(0, data.size()); spi_transaction_ext_t transaction; transaction = spi_transaction_ext_t{ @@ -318,14 +323,14 @@ write_register(uint16_t offset, std::span data, const size_t time .tx_buffer = data.data(), .rx_buffer = rx_buffer.data(), }, - .command_bits = static_cast(SPI_CMD_BIT_SIZE), - .address_bits = static_cast(SPI_REGISTER_ADDR_BIT_SIZE), + .command_bits = static_cast(CMD_BIT_SIZE), + .address_bits = static_cast(REG_ADDR_BIT_SIZE), .dummy_bits = 0, }; esp_err_t err = spi_device_transmit(details::spi_device, &transaction.base); if (err != ESP_OK) { - ESP_LOGE(TAG, "failed to transfer %s (%d)", esp_err_to_name(err), err); + ESP_LOGE(TAG, "spi transmit: %s (%d)", esp_err_to_name(err), err); return ue_t{error::FAILED}; } @@ -345,7 +350,10 @@ read_buffer(uint8_t offset, uint8_t size, const size_t timeout_ms) { return ue_t{error::INVALID_SIZE}; } - auto rx_buffer = details::data_buffer.subspan(0, size_required); + auto rx_buffer = details::data_buffer.subspan(0, size_required); + auto _tx_buffer = std::make_unique(rx_buffer.size()); + auto tx_buffer = std::span{_tx_buffer.get(), rx_buffer.size()}; + std::ranges::fill(tx_buffer, PADDING); spi_transaction_ext_t transaction; transaction = spi_transaction_ext_t{ @@ -355,16 +363,16 @@ read_buffer(uint8_t offset, uint8_t size, const size_t timeout_ms) { .addr = offset, .length = static_cast(rx_buffer.size() * 8), .rxlength = static_cast(rx_buffer.size() * 8), - .tx_buffer = nullptr, + .tx_buffer = tx_buffer.data(), .rx_buffer = rx_buffer.data(), }, - .command_bits = static_cast(SPI_CMD_BIT_SIZE), - .address_bits = static_cast(SPI_BUFFER_OFFSET_BIT_SIZE), + .command_bits = static_cast(CMD_BIT_SIZE), + .address_bits = static_cast(OFFSET_BIT_SIZE), .dummy_bits = 0, }; esp_err_t err = spi_device_transmit(details::spi_device, &transaction.base); if (err != ESP_OK) { - ESP_LOGE(TAG, "failed to transfer %s (%d)", esp_err_to_name(err), err); + ESP_LOGE(TAG, "spi transmit: %s (%d)", esp_err_to_name(err), err); return ue_t{error::FAILED}; } @@ -401,14 +409,14 @@ write_buffer(uint8_t offset, std::span data_from_host, const size .tx_buffer = data_from_host.data(), .rx_buffer = rx_buffer.data(), }, - .command_bits = static_cast(SPI_CMD_BIT_SIZE), - .address_bits = static_cast(SPI_BUFFER_OFFSET_BIT_SIZE), + .command_bits = static_cast(CMD_BIT_SIZE), + .address_bits = static_cast(OFFSET_BIT_SIZE), .dummy_bits = 0, }; esp_err_t err = spi_device_transmit(details::spi_device, &transaction.base); if (err != ESP_OK) { - ESP_LOGE(TAG, "failed to transfer %s (%d)", esp_err_to_name(err), err); + ESP_LOGE(TAG, "spi transmit: %s (%d)", esp_err_to_name(err), err); return ue_t{error::FAILED}; }