refactor: adjust SPI transaction queue size and improve read_stream validation
This commit is contained in:
@ -118,7 +118,7 @@ struct transmit_state_t {
|
||||
* @brief private namespace; Don't use anything in this namespace outside of this file
|
||||
*/
|
||||
namespace details {
|
||||
extern uint32_t __tcxo_delay__;
|
||||
inline uint32_t __tcxo_delay__;
|
||||
}
|
||||
|
||||
constexpr auto delay_ms = app::utils::delay_ms;
|
||||
@ -141,9 +141,9 @@ reset() {
|
||||
}
|
||||
gpio::set_mode(RST_PIN, gpio::Mode::OUTPUT);
|
||||
gpio::digital_write(RST_PIN, false);
|
||||
delay_ms(100);
|
||||
delay_ms(250);
|
||||
gpio::digital_write(RST_PIN, true);
|
||||
delay_ms(100);
|
||||
delay_ms(1'000);
|
||||
const auto instant = Instant<>{};
|
||||
constexpr auto INTERVAL = std::chrono::duration<uint16_t, std::milli>{spi::DEFAULT_TIMEOUT_MS};
|
||||
decltype(standby()) res = ue_t{error_t{error::FAILED}};
|
||||
@ -833,7 +833,7 @@ set_tx_params(const uint8_t pwr, const uint8_t ramp_time = RADIOLIB_SX126X_PA_RA
|
||||
\param sync_word LoRa sync word to be set.
|
||||
\param control_bits Undocumented control bits, required for compatibility purposes.
|
||||
*/
|
||||
inline Result<Unit, error_t> set_sync_word(const uint8_t sync_word = RADIOLIB_SX126X_SYNC_WORD_PRIVATE, const uint8_t control_bits = 0x44) {
|
||||
inline Result<Unit, error_t> set_lora_sync_word(const uint8_t sync_word = RADIOLIB_SX126X_SYNC_WORD_PRIVATE, const uint8_t control_bits = 0x44) {
|
||||
const auto pkt_type = get_packet_type();
|
||||
APP_RADIO_RETURN_ERR(pkt_type);
|
||||
if (*pkt_type != RADIOLIB_SX126X_PACKET_TYPE_LORA) {
|
||||
@ -1062,16 +1062,16 @@ kick_inf_rx(const modulation_params_t &mod_params, const packet_params_t &packet
|
||||
};
|
||||
|
||||
res = set_modulation_params(mod_params.sf, mod_params.bw, mod_params.cr, mod_params.ldr_optimize);
|
||||
APP_RADIO_RETURN_ERR_CTX(res, "failed to set modulation params");
|
||||
APP_RADIO_RETURN_ERR_CTX(res, "modulation params");
|
||||
res = set_packet_params(packet_params.preamble_len, packet_params.payload_len, packet_params.crc_type, packet_params.hdr_type);
|
||||
APP_RADIO_RETURN_ERR_CTX(res, "failed to set packet params");
|
||||
APP_RADIO_RETURN_ERR_CTX(res, "packet params");
|
||||
|
||||
res = set_dio_irq_params(irq_params);
|
||||
APP_RADIO_RETURN_ERR_CTX(res, "failed to set dio irq params");
|
||||
APP_RADIO_RETURN_ERR_CTX(res, "dio irq params");
|
||||
res = clear_irq_status();
|
||||
APP_RADIO_RETURN_ERR_CTX(res, "failed to clear irq status");
|
||||
APP_RADIO_RETURN_ERR_CTX(res, "clear irq status");
|
||||
res = rx(RADIOLIB_SX126X_RX_TIMEOUT_INF);
|
||||
APP_RADIO_RETURN_ERR_CTX(res, "failed to set rx");
|
||||
APP_RADIO_RETURN_ERR_CTX(res, "set rx");
|
||||
return {};
|
||||
}
|
||||
|
||||
@ -1172,6 +1172,31 @@ async_transmit(const std::span<const uint8_t> data,
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief initialize TX & RX enable pins and put them in high level
|
||||
* @note I'm not sure if this is necessary anymore, just in case
|
||||
*/
|
||||
static constexpr auto init_tx_rx_en = [] {
|
||||
constexpr auto TX_EN_PIN = app::driver::llcc68::TX_EN_PIN;
|
||||
constexpr auto RX_EN_PIN = app::driver::llcc68::RX_EN_PIN;
|
||||
|
||||
// both pins must be defined
|
||||
if (TX_EN_PIN == GPIO_NUM_NC or RX_EN_PIN == GPIO_NUM_NC) {
|
||||
return;
|
||||
}
|
||||
|
||||
gpio_config_t io_conf = {
|
||||
.pin_bit_mask = (1ULL << TX_EN_PIN) | (1ULL << RX_EN_PIN),
|
||||
.mode = GPIO_MODE_OUTPUT,
|
||||
.pull_up_en = GPIO_PULLUP_DISABLE,
|
||||
.pull_down_en = GPIO_PULLDOWN_DISABLE,
|
||||
.intr_type = GPIO_INTR_DISABLE,
|
||||
};
|
||||
ESP_ERROR_CHECK(gpio_config(&io_conf));
|
||||
ESP_ERROR_CHECK(gpio_set_level(TX_EN_PIN, true));
|
||||
ESP_ERROR_CHECK(gpio_set_level(RX_EN_PIN, true));
|
||||
};
|
||||
|
||||
static constexpr auto init_pins = [](void (*isr)(void *), void *arg) {
|
||||
if (RST_PIN != GPIO_NUM_NC) {
|
||||
gpio::set_mode(RST_PIN, gpio::Mode::OUTPUT);
|
||||
@ -1196,6 +1221,9 @@ static constexpr auto init_pins = [](void (*isr)(void *), void *arg) {
|
||||
}
|
||||
gpio_isr_handler_add(pin, isr, arg);
|
||||
}
|
||||
|
||||
// initialize TX & RX enable pins
|
||||
init_tx_rx_en();
|
||||
};
|
||||
|
||||
static constexpr auto begin = [](const lora_parameters_t ¶ms) -> Result<Unit, error_t> {
|
||||
@ -1215,66 +1243,69 @@ static constexpr auto begin = [](const lora_parameters_t ¶ms) -> Result<Unit
|
||||
/* explicit not reset the chip by pin, due to unexpected side effect */
|
||||
|
||||
res = standby();
|
||||
APP_RADIO_RETURN_ERR_CTX(res, "failed to standby");
|
||||
APP_RADIO_RETURN_ERR_CTX(res, "standby");
|
||||
|
||||
const auto [ok, chip] = find_chip();
|
||||
if (not ok) {
|
||||
return ue_t{error_t{error::RADIO_CHIP_NOT_FOUND}};
|
||||
}
|
||||
|
||||
if (not USE_XTAL) {
|
||||
// FIXME
|
||||
// according to https://github.com/nopnop2002/esp-idf-sx126x
|
||||
// we should set TCXO voltage
|
||||
if constexpr (not USE_XTAL) {
|
||||
const auto voltage_ = set_TCXO(DEFAULT_TCXO_VOLTAGE);
|
||||
details::__tcxo_delay__ = *voltage_;
|
||||
APP_RADIO_RETURN_ERR_CTX(res, "failed to set TCXO");
|
||||
APP_RADIO_RETURN_ERR_CTX(res, "set TCXO");
|
||||
}
|
||||
const auto &mod_params = params.mod_params;
|
||||
const auto &packet_params = params.packet_params;
|
||||
|
||||
// SetPacketType
|
||||
res = config_packet_type(mod_params.sf);
|
||||
APP_RADIO_RETURN_ERR_CTX(res, "failed to config packet type");
|
||||
APP_RADIO_RETURN_ERR_CTX(res, "config packet type");
|
||||
|
||||
res = set_modulation_params(mod_params.sf,
|
||||
mod_params.bw,
|
||||
mod_params.cr,
|
||||
mod_params.ldr_optimize);
|
||||
APP_RADIO_RETURN_ERR_CTX(res, "failed to set modulation params");
|
||||
APP_RADIO_RETURN_ERR_CTX(res, "set modulation params");
|
||||
|
||||
res = set_sync_word(params.sync_word);
|
||||
APP_RADIO_RETURN_ERR_CTX(res, "failed to set sync word");
|
||||
res = set_lora_sync_word(params.sync_word);
|
||||
APP_RADIO_RETURN_ERR_CTX(res, "sync word");
|
||||
|
||||
if constexpr (USE_REGULATOR_LDO) {
|
||||
res = set_regulator_ldo();
|
||||
APP_RADIO_RETURN_ERR_CTX(res, "failed to set regulator LDO");
|
||||
APP_RADIO_RETURN_ERR_CTX(res, "regulator LDO");
|
||||
} else {
|
||||
res = set_regulator_dc_dc();
|
||||
APP_RADIO_RETURN_ERR_CTX(res, "failed to set regulator DC-DC");
|
||||
APP_RADIO_RETURN_ERR_CTX(res, "regulator DC-DC");
|
||||
}
|
||||
|
||||
res = set_current_limit<60.0f>();
|
||||
APP_RADIO_RETURN_ERR_CTX(res, "failed to set current limit");
|
||||
APP_RADIO_RETURN_ERR_CTX(res, "current limit");
|
||||
|
||||
res = set_dio2_as_rf_switch(false);
|
||||
APP_RADIO_RETURN_ERR_CTX(res, "failed to set dio2 as rf switch");
|
||||
APP_RADIO_RETURN_ERR_CTX(res, "set dio2 as rf switch");
|
||||
|
||||
res = set_frequency(params.frequency);
|
||||
APP_RADIO_RETURN_ERR_CTX(res, "failed to set frequency");
|
||||
APP_RADIO_RETURN_ERR_CTX(res, "set frequency");
|
||||
|
||||
// SetPacketParams
|
||||
res = set_packet_params(packet_params.preamble_len,
|
||||
packet_params.payload_len,
|
||||
packet_params.crc_type,
|
||||
packet_params.hdr_type);
|
||||
APP_RADIO_RETURN_ERR_CTX(res, "failed to set packet params");
|
||||
APP_RADIO_RETURN_ERR_CTX(res, "set packet params");
|
||||
|
||||
res = set_output_power(chip_type_to_max_tx_power(chip));
|
||||
APP_RADIO_RETURN_ERR_CTX(res, "failed to set output power");
|
||||
APP_RADIO_RETURN_ERR_CTX(res, "set output power");
|
||||
|
||||
res = fix_pa_clamping();
|
||||
APP_RADIO_RETURN_ERR_CTX(res, "failed to fix pa clamping");
|
||||
APP_RADIO_RETURN_ERR_CTX(res, "fix pa clamping");
|
||||
|
||||
res = standby();
|
||||
APP_RADIO_RETURN_ERR_CTX(res, "failed to standby");
|
||||
APP_RADIO_RETURN_ERR_CTX(res, "standby");
|
||||
return {};
|
||||
};
|
||||
}
|
||||
|
||||
@ -87,7 +87,7 @@ void init(spi_config_t config) {
|
||||
.clock_speed_hz = config.clock_speed_hz,
|
||||
.spics_io_num = CS_PIN,
|
||||
.flags = SPI_DEVICE_NO_DUMMY,
|
||||
.queue_size = 2,
|
||||
.queue_size = 1,
|
||||
};
|
||||
|
||||
ESP_ERROR_CHECK(spi_bus_initialize(config.host_id, &bus_config, SPI_DMA_CH_AUTO));
|
||||
@ -158,7 +158,7 @@ read_stream(uint8_t cmd, std::span<uint8_t> data, const size_t timeout_ms) {
|
||||
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) {
|
||||
if (data.empty() or data.size() > STACK_BUFFER_SIZE - 1) {
|
||||
return ue_t{error::INVALID_SIZE};
|
||||
}
|
||||
|
||||
@ -170,12 +170,18 @@ read_stream(uint8_t cmd, std::span<uint8_t> data, const size_t timeout_ms) {
|
||||
auto tx_buffer = std::span{_tx_buf}.subspan(0, rx_buffer.size());
|
||||
std::ranges::fill(tx_buffer, PADDING);
|
||||
|
||||
spi_transaction_ext_t transaction;
|
||||
spi_transaction_ext_t transaction{};
|
||||
// during the Command and Address phases, the members spi_transaction_t::cmd
|
||||
// and spi_transaction_t::addr are sent to the bus, nothing is read at this
|
||||
// time.
|
||||
transaction = spi_transaction_ext_t{
|
||||
.base = {
|
||||
.flags = SPI_TRANS_VARIABLE_CMD,
|
||||
.cmd = cmd,
|
||||
.length = static_cast<size_t>(rx_buffer.size() * 8),
|
||||
.flags = SPI_TRANS_VARIABLE_CMD,
|
||||
.cmd = cmd,
|
||||
// total data length, in bits
|
||||
.length = static_cast<size_t>(rx_buffer.size() * 8),
|
||||
// total data length received, should be not greater than length in
|
||||
// full-duplex mode (0 defaults this to the value of length).
|
||||
.rxlength = static_cast<size_t>(rx_buffer.size() * 8),
|
||||
.tx_buffer = tx_buffer.data(),
|
||||
.rx_buffer = rx_buffer.data(),
|
||||
@ -215,7 +221,7 @@ write_stream(uint8_t cmd, std::span<const uint8_t> data, const size_t timeout_ms
|
||||
}
|
||||
|
||||
const auto rx_buffer = std::span{_rx_buf}.subspan(0, data.size());
|
||||
spi_transaction_ext_t transaction;
|
||||
spi_transaction_ext_t transaction{};
|
||||
transaction = spi_transaction_ext_t{
|
||||
.base = {
|
||||
.flags = SPI_TRANS_VARIABLE_CMD,
|
||||
|
||||
Reference in New Issue
Block a user