mirror of
https://github.com/liquidraver/ZephCore.git
synced 2026-08-29 14:58:16 +00:00
wrapup lr2021 session
This commit is contained in:
@@ -313,52 +313,6 @@ static int lr20xx_spi_read_frame(struct lr20xx_hal_context *ctx, const uint8_t *
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if IS_ENABLED(CONFIG_LOG)
|
||||
/*
|
||||
* Dump one command frame from byte 0 — command echo, stat header and payload
|
||||
* all in one line, nothing discarded. The single-NSS read layout above has
|
||||
* never been checked against real silicon; this shows where the payload
|
||||
* actually starts instead of assuming it.
|
||||
*/
|
||||
void lr20xx_hal_debug_raw_frame(const void *context, const uint8_t *command,
|
||||
uint16_t command_length, uint16_t extra)
|
||||
{
|
||||
struct lr20xx_hal_context *ctx = (struct lr20xx_hal_context *)context;
|
||||
uint8_t rx[24] = { 0 };
|
||||
uint16_t total = command_length + extra;
|
||||
|
||||
if (total > sizeof(rx)) {
|
||||
total = sizeof(rx);
|
||||
}
|
||||
|
||||
const struct spi_buf tx_bufs[] = {
|
||||
{ .buf = (uint8_t *)command, .len = command_length },
|
||||
{ .buf = NULL, .len = (size_t)(total - command_length) },
|
||||
};
|
||||
const struct spi_buf rx_bufs[] = {
|
||||
{ .buf = rx, .len = total },
|
||||
};
|
||||
const struct spi_buf_set tx = { .buffers = tx_bufs, .count = 2 };
|
||||
const struct spi_buf_set rxs = { .buffers = rx_bufs, .count = 1 };
|
||||
|
||||
if (check_device_ready(ctx) != LR20XX_HAL_STATUS_OK) {
|
||||
LOG_WRN("raw frame: device not ready");
|
||||
return;
|
||||
}
|
||||
|
||||
gpio_pin_set_dt(&ctx->nss, 1);
|
||||
int ret = spi_transceive(ctx->spi_dev, &ctx->spi_cfg, &tx, &rxs);
|
||||
gpio_pin_set_dt(&ctx->nss, 0);
|
||||
|
||||
if (ret < 0) {
|
||||
LOG_ERR("raw frame: spi err %d", ret);
|
||||
return;
|
||||
}
|
||||
|
||||
LOG_HEXDUMP_INF(rx, total, "frame A: one NSS window, from byte 0");
|
||||
}
|
||||
#endif /* CONFIG_LOG */
|
||||
|
||||
lr20xx_hal_status_t lr20xx_hal_read(const void *context, const uint8_t *command,
|
||||
const uint16_t command_length,
|
||||
uint8_t *data, const uint16_t data_length)
|
||||
|
||||
@@ -68,12 +68,6 @@ void lr20xx_hal_enable_dio1_irq(struct lr20xx_hal_context *ctx);
|
||||
/** @brief Disable DIO1 interrupt */
|
||||
void lr20xx_hal_disable_dio1_irq(struct lr20xx_hal_context *ctx);
|
||||
|
||||
#if IS_ENABLED(CONFIG_LOG)
|
||||
/** @brief Log a whole command frame from byte 0, nothing discarded. */
|
||||
void lr20xx_hal_debug_raw_frame(const void *context, const uint8_t *command,
|
||||
uint16_t command_length, uint16_t extra);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1321,7 +1321,15 @@ static int lr20xx_lora_send_async(const struct device *dev,
|
||||
K_MSEC(lr20xx_cad_timeout_ms(data)));
|
||||
if (cad_ret > 0) {
|
||||
LOG_DBG("LBT: channel busy");
|
||||
if (was_in_rx && data->async_rx_cb != NULL) {
|
||||
/* Re-arm whenever there was anything to re-arm. The
|
||||
* async_rx_cb condition was safe while a busy CAD only
|
||||
* cost the RX mode, but lr20xx_dc_takeover() above has
|
||||
* already stood the duty cycle down by this point — so
|
||||
* bailing out without restarting leaves the radio
|
||||
* parked in standby, deaf, with nothing scheduled to
|
||||
* bring it back. rx_duty_cycle_enabled covers the case
|
||||
* the callback check would miss. */
|
||||
if (was_in_rx || data->rx_duty_cycle_enabled) {
|
||||
k_mutex_lock(&data->spi_mutex, K_FOREVER);
|
||||
lr20xx_start_rx(data, cfg);
|
||||
k_mutex_unlock(&data->spi_mutex);
|
||||
@@ -1970,34 +1978,13 @@ static int lr20xx_hw_init(struct lr20xx_data *data,
|
||||
|
||||
LOG_INF("LR20xx SDK get_version: major=%u minor=%u", ver.major, ver.minor);
|
||||
|
||||
#if IS_ENABLED(CONFIG_LOG)
|
||||
/* GET_VERSION (0x0101) must answer 0x01 0x18 for the documented FW 1.24.
|
||||
* Two dumps, because the two references disagree on the protocol and
|
||||
* our layout matches RadioLib on paper yet reads shifted on silicon:
|
||||
/* The frame A / frame B bring-up dumps lived here: two hexdumps of
|
||||
* GET_VERSION, one per candidate SPI framing, to settle which protocol
|
||||
* this chip actually speaks. Answered — the two-window read in
|
||||
* lr20xx_spi_read_frame() is correct, and TX/RX both work on it.
|
||||
* Removed rather than left firing on every boot.
|
||||
*
|
||||
* frame A = command and response in ONE NSS window (RadioLib's model)
|
||||
* frame B = a bare read in a SECOND window (the Semtech HAL's model)
|
||||
*
|
||||
* Whichever one contains 01 18 is the protocol this chip actually
|
||||
* speaks, and its offset is the skip the HAL should use.
|
||||
*/
|
||||
{
|
||||
const uint8_t ver_cmd[2] = { 0x01, 0x01 };
|
||||
uint8_t follow[8] = { 0 };
|
||||
|
||||
lr20xx_hal_debug_raw_frame(ctx, ver_cmd, sizeof(ver_cmd), 10);
|
||||
|
||||
if (lr20xx_hal_direct_read(ctx, follow, sizeof(follow)) ==
|
||||
LR20XX_HAL_STATUS_OK) {
|
||||
LOG_HEXDUMP_INF(follow, sizeof(follow),
|
||||
"frame B: bare read after GET_VERSION");
|
||||
} else {
|
||||
LOG_WRN("frame B: bare read failed");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* The only base FW version the datasheet documents is 1.24 (0x01/0x18).
|
||||
* The only base FW version the datasheet documents is 1.24 (0x01/0x18).
|
||||
* Anything else still runs — the mismatch is worth a line in the log
|
||||
* when a bring-up goes sideways, not a hard failure. */
|
||||
if (ver.major != 0x01 || ver.minor != 0x18) {
|
||||
@@ -2103,33 +2090,14 @@ static int lr20xx_hw_init(struct lr20xx_data *data,
|
||||
|
||||
DUMP_CHIP_STATE(data, "init-done");
|
||||
|
||||
#if IS_ENABLED(CONFIG_LOG)
|
||||
/* Does merely polling status raise CmdError? get_status is a bare
|
||||
* direct_read (no opcode) in this SDK, where RadioLib sends GET_STATUS
|
||||
* as a real command — so if the chip parses those clocked-out zeros as
|
||||
* a malformed command, our own polling is manufacturing the CMD_ERROR
|
||||
* storm rather than reporting one. Chip is idle here, so nothing else
|
||||
* can set the bit. */
|
||||
{
|
||||
lr20xx_system_irq_mask_t before = 0, after = 0;
|
||||
lr20xx_system_stat1_t s1 = {0};
|
||||
|
||||
lr20xx_system_clear_irq_status(ctx, LR20XX_SYSTEM_IRQ_ALL_MASK);
|
||||
lr20xx_system_get_status(ctx, NULL, NULL, &before);
|
||||
|
||||
for (int i = 0; i < 5; i++) {
|
||||
lr20xx_system_get_status(ctx, &s1, NULL, NULL);
|
||||
}
|
||||
|
||||
lr20xx_system_get_status(ctx, NULL, NULL, &after);
|
||||
LOG_INF("status-poll probe: irq before=0x%08x after=0x%08x "
|
||||
"(CMD_ERROR %s self-inflicted)", before, after,
|
||||
(after & LR20XX_SYSTEM_IRQ_CMD_ERROR) ? "IS" : "is NOT");
|
||||
lr20xx_system_clear_irq_status(ctx, LR20XX_SYSTEM_IRQ_ALL_MASK);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* DEBUG: what voltage does the chip see on its OWN supply pin? (mV,
|
||||
/* The status-poll probe lived here, asking whether merely polling
|
||||
* GetStatus raised CmdError — i.e. whether our own polling was
|
||||
* manufacturing the CMD_ERROR storm. It reported "is NOT" on every
|
||||
* run, and the real source is now known: the NSS wake pulse that
|
||||
* check_device_ready() used to fire at a merely-busy chip, which the
|
||||
* chip read as a clockless malformed command. Question closed.
|
||||
*
|
||||
* DEBUG: what voltage does the chip see on its OWN supply pin? (mV,
|
||||
* after MU calibration). If this reads low (≪3000mV) while the board
|
||||
* is powered, the LR2021 VBAT/supply pin is floating or miswired — that
|
||||
* is why it flags LOW_BATTERY and aborts TX no matter the system rail
|
||||
|
||||
Reference in New Issue
Block a user