refactor: remove mut_shared_buffer function and streamline buffer handling in SPI transactions
This commit is contained in:
@ -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<uint8_t> mut_shared_buffer();
|
||||
|
||||
struct spi_config_t {
|
||||
spi_host_device_t host_id;
|
||||
int clock_speed_hz;
|
||||
|
||||
124
src/hal_spi.cpp
124
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<uint8_t> 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<uint8_t> data_buffer = std::span{_shared_buffer + DATA_BUFFER_OFFSET, MAX_BUFFER_SIZE - DATA_BUFFER_OFFSET};
|
||||
static std::span<uint8_t> data_buffer = std::span{_data_buffer};
|
||||
}
|
||||
|
||||
/**
|
||||
@ -59,10 +51,6 @@ static constexpr auto verify_statuses = [](std::span<const uint8_t> statuses) {
|
||||
return error::OK;
|
||||
};
|
||||
|
||||
std::span<uint8_t> 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<Unit, error_t>
|
||||
read_stream(uint8_t cmd, std::span<uint8_t> data, const size_t timeout_ms) {
|
||||
if (data.size() > MAX_BUFFER_SIZE - 1) {
|
||||
std::array<uint8_t, STACK_BUFFER_SIZE> _rx_buf;
|
||||
std::array<uint8_t, STACK_BUFFER_SIZE> _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<uint8_t> 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<uint8_t> data, const size_t timeout_ms) {
|
||||
.cmd = cmd,
|
||||
.length = static_cast<size_t>(rx_buffer.size() * 8),
|
||||
.rxlength = static_cast<size_t>(rx_buffer.size() * 8),
|
||||
.tx_buffer = nullptr,
|
||||
.tx_buffer = tx_buffer.data(),
|
||||
.rx_buffer = rx_buffer.data(),
|
||||
},
|
||||
.command_bits = static_cast<uint8_t>(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<uint8_t> data, const size_t timeout_ms) {
|
||||
|
||||
Result<Unit, error_t>
|
||||
write_stream(uint8_t cmd, std::span<const uint8_t> data, const size_t timeout_ms) {
|
||||
if (data.size() > MAX_BUFFER_SIZE) {
|
||||
std::array<uint8_t, STACK_BUFFER_SIZE> _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<const uint8_t> 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<const uint8_t> data, const size_t timeout_ms
|
||||
.tx_buffer = data.data(),
|
||||
.rx_buffer = rx_buffer.data(),
|
||||
},
|
||||
.command_bits = static_cast<uint8_t>(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<const uint8_t> data, const size_t timeout_ms
|
||||
|
||||
Result<Unit, error_t>
|
||||
read_register(uint16_t reg, std::span<uint8_t> data, const size_t timeout_ms) {
|
||||
if (data.size() > MAX_BUFFER_SIZE - 1) {
|
||||
std::array<uint8_t, STACK_BUFFER_SIZE> _rx_buf;
|
||||
std::array<uint8_t, STACK_BUFFER_SIZE> _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<uint8_t> 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<size_t>(rx_buffer.size() * 8),
|
||||
.rxlength = static_cast<size_t>(rx_buffer.size() * 8),
|
||||
.tx_buffer = nullptr,
|
||||
.rx_buffer = rx_buffer.data(),
|
||||
},
|
||||
.command_bits = static_cast<uint8_t>(SPI_CMD_BIT_SIZE),
|
||||
.address_bits = static_cast<uint8_t>(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<size_t>(rx_buffer.size() * 8),
|
||||
.rxlength = static_cast<size_t>(rx_buffer.size() * 8),
|
||||
.tx_buffer = tx_buffer.data(),
|
||||
.rx_buffer = rx_buffer.data(),
|
||||
},
|
||||
.command_bits = static_cast<uint8_t>(CMD_BIT_SIZE),
|
||||
.address_bits = static_cast<uint8_t>(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<uint8_t> data, const size_t timeout_ms) {
|
||||
|
||||
Result<Unit, error_t>
|
||||
write_register(uint16_t offset, std::span<const uint8_t> data, const size_t timeout_ms) {
|
||||
if (data.size() > MAX_BUFFER_SIZE) {
|
||||
std::array<uint8_t, STACK_BUFFER_SIZE> _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<const uint8_t> 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<const uint8_t> data, const size_t time
|
||||
.tx_buffer = data.data(),
|
||||
.rx_buffer = rx_buffer.data(),
|
||||
},
|
||||
.command_bits = static_cast<uint8_t>(SPI_CMD_BIT_SIZE),
|
||||
.address_bits = static_cast<uint8_t>(SPI_REGISTER_ADDR_BIT_SIZE),
|
||||
.command_bits = static_cast<uint8_t>(CMD_BIT_SIZE),
|
||||
.address_bits = static_cast<uint8_t>(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<uint8_t[]>(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<size_t>(rx_buffer.size() * 8),
|
||||
.rxlength = static_cast<size_t>(rx_buffer.size() * 8),
|
||||
.tx_buffer = nullptr,
|
||||
.tx_buffer = tx_buffer.data(),
|
||||
.rx_buffer = rx_buffer.data(),
|
||||
},
|
||||
.command_bits = static_cast<uint8_t>(SPI_CMD_BIT_SIZE),
|
||||
.address_bits = static_cast<uint8_t>(SPI_BUFFER_OFFSET_BIT_SIZE),
|
||||
.command_bits = static_cast<uint8_t>(CMD_BIT_SIZE),
|
||||
.address_bits = static_cast<uint8_t>(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<const uint8_t> data_from_host, const size
|
||||
.tx_buffer = data_from_host.data(),
|
||||
.rx_buffer = rx_buffer.data(),
|
||||
},
|
||||
.command_bits = static_cast<uint8_t>(SPI_CMD_BIT_SIZE),
|
||||
.address_bits = static_cast<uint8_t>(SPI_BUFFER_OFFSET_BIT_SIZE),
|
||||
.command_bits = static_cast<uint8_t>(CMD_BIT_SIZE),
|
||||
.address_bits = static_cast<uint8_t>(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};
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user