ieee802154: add debug feature for driver

pull/11836/head
zhangwenxu 2023-06-01 17:07:51 +08:00
rodzic 6e9c386a27
commit 82c7aab6fd
6 zmienionych plików z 538 dodań i 51 usunięć

Wyświetl plik

@ -22,6 +22,10 @@ if(CONFIG_IEEE802154_ENABLED)
endif()
if(CONFIG_IEEE802154_DEBUG)
list(APPEND srcs "driver/esp_ieee802154_debug.c")
endif()
idf_component_register(
SRCS "${srcs}"
INCLUDE_DIRS "${include}"

Wyświetl plik

@ -82,4 +82,81 @@ menu "IEEE 802.15.4"
help
Enabling this option allows the IEEE802.15.4 module to be powered down during automatic light sleep,
which reduces current consumption.
menuconfig IEEE802154_DEBUG
bool "Enable IEEE802154 Debug"
default n
help
Enabling this option allows different kinds of IEEE802154 debug output.
All IEEE802154 debug features increase the size of the final binary.
config IEEE802154_ASSERT
bool "Enrich the assert information with IEEE802154 state and event"
depends on IEEE802154_DEBUG
default n
help
Enabling this option to add some probe codes in the driver, and these informations
will be printed when assert.
config IEEE802154_RECORD_EVENT
bool "Enable record event information for debugging"
depends on IEEE802154_DEBUG
default n
help
Enabling this option to record event, when assert, the recorded event will be printed.
config IEEE802154_RECORD_EVENT_SIZE
int "Record event table size"
depends on IEEE802154_RECORD_EVENT
range 1 50
default 30
help
set the record event table size
config IEEE802154_RECORD_STATE
bool "Enable record state information for debugging"
depends on IEEE802154_DEBUG
default n
help
Enabling this option to record state, when assert, the recorded state will be printed.
config IEEE802154_RECORD_STATE_SIZE
int "Record state table size"
depends on IEEE802154_RECORD_STATE
range 1 50
default 10
help
set the record state table size
config IEEE802154_RECORD_CMD
bool "Enable record command information for debugging"
depends on IEEE802154_DEBUG
default n
help
Enabling this option to record the command, when assert, the recorded
command will be printed.
config IEEE802154_RECORD_CMD_SIZE
int "Record command table size"
depends on IEEE802154_RECORD_CMD
range 1 50
default 10
help
set the record command table size
config IEEE802154_RECORD_ABORT
bool "Enable record abort information for debugging"
depends on IEEE802154_DEBUG
default n
help
Enabling this option to record the abort, when assert, the recorded
abort will be printed.
config IEEE802154_RECORD_ABORT_SIZE
int "Record abort table size"
depends on IEEE802154_RECORD_ABORT
range 1 50
default 10
help
set the record abort table size
endmenu # IEEE 802.15.4

Wyświetl plik

@ -13,6 +13,7 @@
#include "esp_ieee802154_frame.h"
#include "esp_ieee802154_pib.h"
#include "esp_ieee802154_types.h"
#include "esp_ieee802154_util.h"
static ieee802154_pending_table_t ieee802154_pending_table;
@ -153,7 +154,7 @@ bool ieee802154_ack_config_pending_bit(const uint8_t *frame)
}
break;
default:
assert(false);
IEEE802154_ASSERT(false);
}
if (set_to_hw) {

Wyświetl plik

@ -0,0 +1,239 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdio.h>
#include "hal/ieee802154_ll.h"
#include "esp_ieee802154_util.h"
#include "esp_log.h"
#if CONFIG_IEEE802154_DEBUG
ieee802154_probe_info_t g_ieee802154_probe;
#define TAG "ieee802154_debug"
#if CONFIG_IEEE802154_RECORD_EVENT
static char *ieee802154_get_event_string(ieee802154_ll_event_t events)
{
char *event_string = "";
switch (events) {
case IEEE802154_EVENT_TX_DONE:
event_string = "TX_DONE";
break;
case IEEE802154_EVENT_RX_DONE:
event_string = "RX_DONE";
break;
case IEEE802154_EVENT_ACK_TX_DONE:
event_string = "ACK_TX_DONE";
break;
case IEEE802154_EVENT_ACK_RX_DONE:
event_string = "ACK_RX_DONE";
break;
case IEEE802154_EVENT_RX_ABORT:
event_string = "RX_ABORT";
break;
case IEEE802154_EVENT_TX_ABORT:
event_string = "TX_ABORT";
break;
case IEEE802154_EVENT_ED_DONE:
event_string = "ED_DONE";
break;
case IEEE802154_EVENT_TIMER0_OVERFLOW:
event_string = "TIMER0_OVERFLOW";
break;
case IEEE802154_EVENT_TIMER1_OVERFLOW:
event_string = "TIMER1_OVERFLOW";
break;
case IEEE802154_EVENT_CLOCK_COUNT_MATCH:
event_string = "CLOCK_COUNT_MATCH";
break;
case IEEE802154_EVENT_TX_SFD_DONE:
event_string = "TX_SFD_DONE";
break;
case IEEE802154_EVENT_RX_SFD_DONE:
event_string = "RX_SFD_DONE";
break;
default:
event_string = "Multi events";
break;
}
return event_string;
}
#endif // CONFIG_IEEE802154_RECORD_EVENT
#if CONFIG_IEEE802154_RECORD_STATE || CONFIG_IEEE802154_RECORD_EVENT
static char *ieee802154_state_string[] = {
"DISABLE",
"IDLE",
"RX",
"TX_ACK",
"TX_ENH_ACK",
"TX_CCA",
"TX",
"DTM_TX",
"RX_ACK",
"ED",
"CCA",
};
#endif // CONFIG_IEEE802154_RECORD_STATE
#if CONFIG_IEEE802154_RECORD_CMD
static char *ieee802154_get_cmd_string(ieee802154_ll_cmd_t cmd)
{
char *cmd_string = "";
switch (cmd) {
case IEEE802154_CMD_TX_START:
cmd_string = "tx";
break;
case IEEE802154_CMD_RX_START:
cmd_string = "rx";
break;
case IEEE802154_CMD_CCA_TX_START:
cmd_string = "tx cca";
break;
case IEEE802154_CMD_ED_START:
cmd_string = "ed";
break;
case IEEE802154_CMD_STOP:
cmd_string = "stop";
break;
case IEEE802154_CMD_TEST_TX_START:
cmd_string = "test tx";
break;
case IEEE802154_CMD_TEST_RX_START:
cmd_string = "test rx";
break;
case IEEE802154_CMD_TEST_STOP:
cmd_string = "test stop";
break;
case IEEE802154_CMD_TIMER0_START:
cmd_string = "timer0 start";
break;
case IEEE802154_CMD_TIMER0_STOP:
cmd_string = "timer0 stop";
break;
case IEEE802154_CMD_TIMER1_START:
cmd_string = "timer1 start";
break;
case IEEE802154_CMD_TIMER1_STOP:
cmd_string = "timer1 stop";
break;
}
return cmd_string;
}
#endif // CONFIG_IEEE802154_RECORD_CMD
#if CONFIG_IEEE802154_RECORD_EVENT || CONFIG_IEEE802154_RECORD_ABORT
static char *ieee80154_rx_abort_reason_string[] = {
"RSVD", // = 0,
"RX_STOP", // = 1,
"SFD_TIMEOUT", // = 2,
"CRC_ERROR ", // = 3,
"INVALID_LEN", // = 4,
"FILTER_FAIL", // = 5,
"NO_RSS ", // = 6,
"COEX_BREAK ", // = 7,
"UNEXPECTED_ACK", // = 8,
"RX_RESTART", // = 9,
"RSVD", "RSVD", "RSVD", "RSVD", "RSVD", "RSVD", // = 10~15,
"TX_ACK_TIMEOUT", // = 16,
"TX_ACK_STOP", // = 17,
"TX_ACK_COEX_BREAK", // = 18,
"ENHACK_SECURITY_ERROR", // = 19,
"RSVD", "RSVD", "RSVD", "RSVD", // = 20~23
"ED_ABORT", // = 24,
"ED_STOP", // = 25,
"ED_COEX_REJECT", // = 26,
};
static char *ieee80154_tx_abort_reason_string[] = {
"RSVD", // = 0,
"RX_ACK_STOP", // = 1,
"RX_ACK_SFD_TIMEOUT", // = 2,
"RX_ACK_CRC_ERROR", // = 3,
"RX_ACK_INVALID_LEN", // = 4,
"RX_ACK_FILTER_FAIL", // = 5,
"RX_ACK_NO_RSS", // = 6,
"RX_ACK_COEX_BREAK", // = 7,
"RX_ACK_TYPE_NOT_ACK", // = 8,
"RX_ACK_RESTART", // = 9,
"RSVD", "RSVD", "RSVD", "RSVD", "RSVD", "RSVD", // = 10~15,
"RX_ACK_TIMEOUT", // = 16,
"TX_STOP", // = 17,
"TX_COEX_BREAK", // = 18,
"TX_SECURITY_ERROR", // = 19,
"RSVD", "RSVD", "RSVD", "RSVD", // = 20~23
"CCA_FAILED", // = 24,
"CCA_BUSY", // = 25,
};
#endif // CONFIG_IEEE802154_RECORD_EVENT
#if CONFIG_IEEE802154_ASSERT
void ieee802154_assert_print(void)
{
#if CONFIG_IEEE802154_RECORD_EVENT
ESP_EARLY_LOGW(TAG, "Print the record event, current event index: %d", g_ieee802154_probe.event_index);
for (uint8_t i = 0; i < IEEE802154_ASSERT_RECORD_EVENT_SIZE; i++) {
char event_log[200] = { 0 };
char abort_log[100] = { 0 };
snprintf(event_log, 200,"index %2d: event: 0x%4x, %15s, state:%10s, timestamp: %lld", i, g_ieee802154_probe.event[i].event,
ieee802154_get_event_string(g_ieee802154_probe.event[i].event),
ieee802154_state_string[g_ieee802154_probe.event[i].state],
g_ieee802154_probe.event[i].timestamp);
if (g_ieee802154_probe.event[i].event == IEEE802154_EVENT_RX_ABORT) {
snprintf(abort_log, 100, "rx abort reason: %4x, %20s", g_ieee802154_probe.event[i].abort_reason.rx,
ieee80154_rx_abort_reason_string[g_ieee802154_probe.event[i].abort_reason.rx]);
} else if (g_ieee802154_probe.event[i].event == IEEE802154_EVENT_TX_ABORT) {
snprintf(abort_log, 100, "tx abort reason: %4x, %20s", g_ieee802154_probe.event[i].abort_reason.tx,
ieee80154_tx_abort_reason_string[g_ieee802154_probe.event[i].abort_reason.tx]);
}
ESP_EARLY_LOGW(TAG, "%s %s", event_log, abort_log);
}
ESP_EARLY_LOGW(TAG,"Print the record event done.\n");
#endif // CONFIG_IEEE802154_RECORD_EVENT
#if CONFIG_IEEE802154_RECORD_STATE
ESP_EARLY_LOGW(TAG, "Print the record state, current state index: %d", g_ieee802154_probe.state_index);
for (uint8_t i = 0; i < IEEE802154_ASSERT_RECORD_STATE_SIZE; i++) {
ESP_EARLY_LOGW(TAG, "index %2d: line:%5s, state:%10s, timestamp: %lld",
i, g_ieee802154_probe.state[i].line_str,
ieee802154_state_string[g_ieee802154_probe.state[i].state],
g_ieee802154_probe.state[i].timestamp);
}
ESP_EARLY_LOGW(TAG,"Print the record state done.\n");
#endif // CONFIG_IEEE802154_RECORD_STATE
#if CONFIG_IEEE802154_RECORD_CMD
ESP_EARLY_LOGW(TAG, "Print the record cmd, current cmd index: %d", g_ieee802154_probe.cmd_index);
for (uint8_t i = 0; i < IEEE802154_ASSERT_RECORD_CMD_SIZE; i++) {
ESP_EARLY_LOGW(TAG, "index %2d: line:%5s, cmd:%10s, timestamp: %lld",
i, g_ieee802154_probe.cmd[i].line_str,
ieee802154_get_cmd_string(g_ieee802154_probe.cmd[i].cmd),
g_ieee802154_probe.cmd[i].timestamp);
}
ESP_EARLY_LOGW(TAG,"Print the record cmd done.\n");
#endif // CONFIG_IEEE802154_RECORD_CMD
#if CONFIG_IEEE802154_RECORD_ABORT
ESP_EARLY_LOGW(TAG, "Print the record abort, current abort index: %d", g_ieee802154_probe.abort_index);
for (uint8_t i = 0; i < IEEE802154_ASSERT_RECORD_ABORT_SIZE; i++) {
if (g_ieee802154_probe.abort[i].is_tx_abort) {
ESP_EARLY_LOGW(TAG, "index %2d: tx abort: %4x, %15s, timestamp: %lld",
i, g_ieee802154_probe.abort[i].abort_reason.tx,
ieee80154_tx_abort_reason_string[g_ieee802154_probe.abort[i].abort_reason.tx],
g_ieee802154_probe.abort[i].timestamp);
} else {
ESP_EARLY_LOGW(TAG, "index %2d: rx abort: %4x, %15s, timestamp: %lld",
i, g_ieee802154_probe.abort[i].abort_reason.rx,
ieee80154_rx_abort_reason_string[g_ieee802154_probe.abort[i].abort_reason.rx],
g_ieee802154_probe.abort[i].timestamp);
}
}
ESP_EARLY_LOGW(TAG,"Print the record abort done.\n");
#endif // CONFIG_IEEE802154_RECORD_ABORT
}
#endif // CONFIG_IEEE802154_ASSERT
#endif // CONFIG_IEEE802154_DEBUG

Wyświetl plik

@ -102,7 +102,7 @@ static bool stop_rx(void)
{
ieee802154_ll_events events;
ieee802154_ll_set_cmd(IEEE802154_CMD_STOP);
ieee802154_set_cmd(IEEE802154_CMD_STOP);
events = ieee802154_ll_get_events();
if (events & IEEE802154_EVENT_RX_DONE) {
@ -116,7 +116,7 @@ static bool stop_rx(void)
static bool stop_tx_ack(void)
{
ieee802154_ll_set_cmd(IEEE802154_CMD_STOP);
ieee802154_set_cmd(IEEE802154_CMD_STOP);
esp_ieee802154_receive_done((uint8_t *)s_rx_frame[s_rx_index], &s_rx_frame_info[s_rx_index]);
@ -129,7 +129,7 @@ static bool stop_tx(void)
{
ieee802154_ll_events events;
ieee802154_ll_set_cmd(IEEE802154_CMD_STOP);
ieee802154_set_cmd(IEEE802154_CMD_STOP);
events = ieee802154_ll_get_events();
@ -151,7 +151,7 @@ static bool stop_tx(void)
static bool stop_cca(void)
{
ieee802154_ll_set_cmd(IEEE802154_CMD_STOP);
ieee802154_set_cmd(IEEE802154_CMD_STOP);
ieee802154_ll_clear_events(IEEE802154_EVENT_ED_DONE | IEEE802154_EVENT_RX_ABORT);
return true;
}
@ -167,7 +167,7 @@ static bool stop_rx_ack(void)
{
ieee802154_ll_events events;
ieee802154_ll_set_cmd(IEEE802154_CMD_STOP);
ieee802154_set_cmd(IEEE802154_CMD_STOP);
events = ieee802154_ll_get_events();
@ -187,7 +187,7 @@ static bool stop_rx_ack(void)
static bool stop_ed(void)
{
ieee802154_ll_set_cmd(IEEE802154_CMD_STOP);
ieee802154_set_cmd(IEEE802154_CMD_STOP);
ieee802154_ll_clear_events(IEEE802154_EVENT_ED_DONE | IEEE802154_EVENT_RX_ABORT);
@ -238,7 +238,7 @@ IEEE802154_STATIC bool stop_current_operation(void)
break;
default:
assert(false);
IEEE802154_ASSERT(false);
break;
}
@ -250,9 +250,9 @@ static void enable_rx(void)
set_next_rx_buffer();
IEEE802154_SET_TXRX_PTI(IEEE802154_SCENE_RX);
ieee802154_ll_set_cmd(IEEE802154_CMD_RX_START);
ieee802154_set_cmd(IEEE802154_CMD_RX_START);
s_ieee802154_state = IEEE802154_STATE_RX;
ieee802154_set_state(IEEE802154_STATE_RX);
}
static IRAM_ATTR void next_operation(void)
@ -260,7 +260,7 @@ static IRAM_ATTR void next_operation(void)
if (ieee802154_pib_get_rx_when_idle()) {
enable_rx();
} else {
s_ieee802154_state = IEEE802154_STATE_IDLE;
ieee802154_set_state(IEEE802154_STATE_IDLE);
}
}
@ -295,7 +295,7 @@ static IRAM_ATTR void isr_handle_tx_done(void)
next_operation();
} else if (s_ieee802154_state == IEEE802154_STATE_TX || s_ieee802154_state == IEEE802154_STATE_TX_CCA) {
if (ieee802154_frame_is_ack_required(s_tx_frame) && ieee802154_ll_get_rx_auto_ack()) {
s_ieee802154_state = IEEE802154_STATE_RX_ACK;
ieee802154_set_state(IEEE802154_STATE_RX_ACK);
receive_ack_timeout_timer_start(200000); // 200ms for receive ack timeout
} else {
esp_ieee802154_transmit_done(s_tx_frame, NULL, NULL);
@ -315,7 +315,7 @@ static IRAM_ATTR void isr_handle_rx_done(void)
&& ieee802154_ll_get_tx_auto_ack()) {
// auto tx ack only works for the frame with version 0b00 and 0b01
s_rx_frame_info[s_rx_index].pending = ieee802154_ack_config_pending_bit(s_rx_frame[s_rx_index]);
s_ieee802154_state = IEEE802154_STATE_TX_ACK;
ieee802154_set_state(IEEE802154_STATE_TX_ACK);
} else if (ieee802154_frame_is_ack_required(s_rx_frame[s_rx_index]) && ieee802154_frame_get_version(s_rx_frame[s_rx_index]) == IEEE802154_FRAME_VERSION_2
&& ieee802154_ll_get_tx_enhance_ack()) {
s_rx_frame_info[s_rx_index].pending = ieee802154_ack_config_pending_bit(s_rx_frame[s_rx_index]);
@ -327,11 +327,11 @@ static IRAM_ATTR void isr_handle_rx_done(void)
s_tx_frame = s_enh_ack_frame;
ieee802154_sec_update();
ieee802154_ll_enhack_generate_done_notify();
s_ieee802154_state = IEEE802154_STATE_TX_ENH_ACK;
ieee802154_set_state(IEEE802154_STATE_TX_ENH_ACK);
#endif
} else {
// Stop current process if generator returns errors.
ieee802154_ll_set_cmd(IEEE802154_CMD_STOP);
ieee802154_set_cmd(IEEE802154_CMD_STOP);
esp_ieee802154_receive_done((uint8_t *)s_rx_frame[s_rx_index], &s_rx_frame_info[s_rx_index]);
next_operation();
}
@ -375,25 +375,25 @@ static IRAM_ATTR void isr_handle_rx_abort(void)
case IEEE802154_RX_ABORT_BY_NO_RSS:
case IEEE802154_RX_ABORT_BY_UNEXPECTED_ACK:
case IEEE802154_RX_ABORT_BY_RX_RESTART:
assert(s_ieee802154_state == IEEE802154_STATE_RX);
IEEE802154_ASSERT(s_ieee802154_state == IEEE802154_STATE_RX);
#if CONFIG_IEEE802154_TEST
esp_ieee802154_receive_failed(rx_status);
next_operation();
#endif
break;
case IEEE802154_RX_ABORT_BY_COEX_BREAK:
assert(s_ieee802154_state == IEEE802154_STATE_RX);
IEEE802154_ASSERT(s_ieee802154_state == IEEE802154_STATE_RX);
esp_ieee802154_receive_failed(rx_status);
break;
case IEEE802154_RX_ABORT_BY_ED_ABORT:
case IEEE802154_RX_ABORT_BY_ED_COEX_REJECT:
assert(s_ieee802154_state == IEEE802154_STATE_ED || s_ieee802154_state == IEEE802154_STATE_CCA);
IEEE802154_ASSERT(s_ieee802154_state == IEEE802154_STATE_ED || s_ieee802154_state == IEEE802154_STATE_CCA);
esp_ieee802154_ed_failed(rx_status);
next_operation();
break;
case IEEE802154_RX_ABORT_BY_TX_ACK_TIMEOUT:
case IEEE802154_RX_ABORT_BY_TX_ACK_COEX_BREAK:
assert(s_ieee802154_state == IEEE802154_STATE_TX_ACK || s_ieee802154_state == IEEE802154_STATE_TX_ENH_ACK);
IEEE802154_ASSERT(s_ieee802154_state == IEEE802154_STATE_TX_ACK || s_ieee802154_state == IEEE802154_STATE_TX_ENH_ACK);
#if !CONFIG_IEEE802154_TEST
esp_ieee802154_receive_done((uint8_t *)s_rx_frame[s_rx_index], &s_rx_frame_info[s_rx_index]);
next_operation();
@ -402,7 +402,7 @@ static IRAM_ATTR void isr_handle_rx_abort(void)
#endif
break;
case IEEE802154_RX_ABORT_BY_ENHACK_SECURITY_ERROR:
assert(s_ieee802154_state == IEEE802154_STATE_TX_ENH_ACK);
IEEE802154_ASSERT(s_ieee802154_state == IEEE802154_STATE_TX_ENH_ACK);
#if !CONFIG_IEEE802154_TEST
esp_ieee802154_receive_done((uint8_t *)s_rx_frame[s_rx_index], &s_rx_frame_info[s_rx_index]);
next_operation();
@ -411,7 +411,7 @@ static IRAM_ATTR void isr_handle_rx_abort(void)
#endif
break;
default:
assert(false);
IEEE802154_ASSERT(false);
}
}
@ -432,37 +432,37 @@ static IRAM_ATTR void isr_handle_tx_abort(void)
case IEEE802154_TX_ABORT_BY_RX_ACK_COEX_BREAK:
case IEEE802154_TX_ABORT_BY_RX_ACK_TYPE_NOT_ACK:
case IEEE802154_TX_ABORT_BY_RX_ACK_RESTART:
assert(s_ieee802154_state == IEEE802154_STATE_RX_ACK);
IEEE802154_ASSERT(s_ieee802154_state == IEEE802154_STATE_RX_ACK);
esp_ieee802154_transmit_failed(s_tx_frame, ESP_IEEE802154_TX_ERR_INVALID_ACK);
break;
case IEEE802154_TX_ABORT_BY_RX_ACK_TIMEOUT:
assert(s_ieee802154_state == IEEE802154_STATE_RX_ACK);
IEEE802154_ASSERT(s_ieee802154_state == IEEE802154_STATE_RX_ACK);
ieee802154_ll_disable_events(IEEE802154_EVENT_TIMER0_OVERFLOW);
esp_ieee802154_transmit_failed(s_tx_frame, ESP_IEEE802154_TX_ERR_NO_ACK);
next_operation();
break;
case IEEE802154_TX_ABORT_BY_TX_COEX_BREAK:
assert(s_ieee802154_state == IEEE802154_STATE_TX || s_ieee802154_state == IEEE802154_STATE_TX_CCA);
IEEE802154_ASSERT(s_ieee802154_state == IEEE802154_STATE_TX || s_ieee802154_state == IEEE802154_STATE_TX_CCA);
esp_ieee802154_transmit_failed(s_tx_frame, ESP_IEEE802154_TX_ERR_COEXIST);
next_operation();
break;
case IEEE802154_TX_ABORT_BY_TX_SECURITY_ERROR:
assert(s_ieee802154_state == IEEE802154_STATE_TX || s_ieee802154_state == IEEE802154_STATE_TX_CCA);
IEEE802154_ASSERT(s_ieee802154_state == IEEE802154_STATE_TX || s_ieee802154_state == IEEE802154_STATE_TX_CCA);
esp_ieee802154_transmit_failed(s_tx_frame, ESP_IEEE802154_TX_ERR_SECURITY);
next_operation();
break;
case IEEE802154_TX_ABORT_BY_CCA_FAILED:
assert(s_ieee802154_state == IEEE802154_STATE_TX_CCA);
IEEE802154_ASSERT(s_ieee802154_state == IEEE802154_STATE_TX_CCA);
esp_ieee802154_transmit_failed(s_tx_frame, ESP_IEEE802154_TX_ERR_ABORT);
next_operation();
break;
case IEEE802154_TX_ABORT_BY_CCA_BUSY:
assert(s_ieee802154_state == IEEE802154_STATE_TX_CCA);
IEEE802154_ASSERT(s_ieee802154_state == IEEE802154_STATE_TX_CCA);
esp_ieee802154_transmit_failed(s_tx_frame, ESP_IEEE802154_TX_ERR_CCA_BUSY);
next_operation();
break;
default:
assert(false);
IEEE802154_ASSERT(false);
break;
}
}
@ -482,11 +482,13 @@ static void ieee802154_isr(void *arg)
{
ieee802154_ll_events events = ieee802154_ll_get_events();
IEEE802154_PROBE(events);
ieee802154_ll_clear_events(events);
if (events & IEEE802154_EVENT_RX_SFD_DONE) {
// IEEE802154_STATE_TX && IEEE802154_STATE_TX_CCA && IEEE802154_STATE_TX_ENH_ACK for isr processing delay
assert(s_ieee802154_state == IEEE802154_STATE_RX || s_ieee802154_state == IEEE802154_STATE_RX_ACK || s_ieee802154_state == IEEE802154_STATE_TX || s_ieee802154_state == IEEE802154_STATE_TX_CCA || s_ieee802154_state == IEEE802154_STATE_TX_ENH_ACK);
IEEE802154_ASSERT(s_ieee802154_state == IEEE802154_STATE_RX || s_ieee802154_state == IEEE802154_STATE_RX_ACK || s_ieee802154_state == IEEE802154_STATE_TX || s_ieee802154_state == IEEE802154_STATE_TX_CCA || s_ieee802154_state == IEEE802154_STATE_TX_ENH_ACK);
s_rx_frame_info[s_rx_index].timestamp = esp_timer_get_time();
esp_ieee802154_receive_sfd_done();
@ -496,7 +498,7 @@ static void ieee802154_isr(void *arg)
if (events & IEEE802154_EVENT_TX_SFD_DONE) {
// ZB-81: IEEE802154_STATE_TX_ACK is also a possible state
assert(s_ieee802154_state == IEEE802154_STATE_TX || s_ieee802154_state == IEEE802154_STATE_TX_CCA || s_ieee802154_state == IEEE802154_STATE_TEST_TX || s_ieee802154_state == IEEE802154_STATE_TX_ENH_ACK || s_ieee802154_state == IEEE802154_STATE_TX_ACK);
IEEE802154_ASSERT(s_ieee802154_state == IEEE802154_STATE_TX || s_ieee802154_state == IEEE802154_STATE_TX_CCA || s_ieee802154_state == IEEE802154_STATE_TEST_TX || s_ieee802154_state == IEEE802154_STATE_TX_ENH_ACK || s_ieee802154_state == IEEE802154_STATE_TX_ACK);
esp_ieee802154_transmit_sfd_done(s_tx_frame);
@ -504,7 +506,7 @@ static void ieee802154_isr(void *arg)
}
if (events & IEEE802154_EVENT_TX_DONE) {
assert(s_ieee802154_state == IEEE802154_STATE_TX || s_ieee802154_state == IEEE802154_STATE_TX_CCA || s_ieee802154_state == IEEE802154_STATE_TEST_TX || s_ieee802154_state == IEEE802154_STATE_TX_ENH_ACK);
IEEE802154_ASSERT(s_ieee802154_state == IEEE802154_STATE_TX || s_ieee802154_state == IEEE802154_STATE_TX_CCA || s_ieee802154_state == IEEE802154_STATE_TEST_TX || s_ieee802154_state == IEEE802154_STATE_TX_ENH_ACK);
isr_handle_tx_done();
@ -512,7 +514,7 @@ static void ieee802154_isr(void *arg)
}
if (events & IEEE802154_EVENT_RX_DONE) {
assert(s_ieee802154_state == IEEE802154_STATE_RX);
IEEE802154_ASSERT(s_ieee802154_state == IEEE802154_STATE_RX);
isr_handle_rx_done();
@ -521,7 +523,7 @@ static void ieee802154_isr(void *arg)
if (events & IEEE802154_EVENT_ACK_TX_DONE) {
// IEEE802154_STATE_RX for isr processing delay
assert(s_ieee802154_state == IEEE802154_STATE_TX_ACK || s_ieee802154_state == IEEE802154_STATE_RX || s_ieee802154_state == IEEE802154_STATE_TX_ENH_ACK);
IEEE802154_ASSERT(s_ieee802154_state == IEEE802154_STATE_TX_ACK || s_ieee802154_state == IEEE802154_STATE_RX || s_ieee802154_state == IEEE802154_STATE_TX_ENH_ACK);
isr_handle_ack_tx_done();
@ -530,7 +532,7 @@ static void ieee802154_isr(void *arg)
if (events & IEEE802154_EVENT_ACK_RX_DONE) {
// IEEE802154_STATE_TX && IEEE802154_STATE_TX_CCA && IEEE802154_STATE_TX_ENH_ACK for isr processing delay
assert(s_ieee802154_state == IEEE802154_STATE_RX_ACK || s_ieee802154_state == IEEE802154_STATE_TX || s_ieee802154_state == IEEE802154_STATE_TX_CCA || s_ieee802154_state == IEEE802154_STATE_TX_ENH_ACK);
IEEE802154_ASSERT(s_ieee802154_state == IEEE802154_STATE_RX_ACK || s_ieee802154_state == IEEE802154_STATE_TX || s_ieee802154_state == IEEE802154_STATE_TX_CCA || s_ieee802154_state == IEEE802154_STATE_TX_ENH_ACK);
isr_handle_ack_rx_done();
@ -550,7 +552,7 @@ static void ieee802154_isr(void *arg)
}
if (events & IEEE802154_EVENT_ED_DONE) {
assert(s_ieee802154_state == IEEE802154_STATE_ED || s_ieee802154_state == IEEE802154_STATE_CCA);
IEEE802154_ASSERT(s_ieee802154_state == IEEE802154_STATE_ED || s_ieee802154_state == IEEE802154_STATE_CCA);
isr_handle_ed_done();
@ -559,10 +561,10 @@ static void ieee802154_isr(void *arg)
if (events & IEEE802154_EVENT_TIMER0_OVERFLOW) {
#if !CONFIG_IEEE802154_TEST
assert(s_ieee802154_state == IEEE802154_STATE_RX_ACK);
IEEE802154_ASSERT(s_ieee802154_state == IEEE802154_STATE_RX_ACK);
#else
extern bool ieee802154_timer0_test;
assert(ieee802154_timer0_test || s_ieee802154_state == IEEE802154_STATE_RX_ACK);
IEEE802154_ASSERT(ieee802154_timer0_test || s_ieee802154_state == IEEE802154_STATE_RX_ACK);
#endif
isr_handle_timer0_done();
@ -576,7 +578,7 @@ static void ieee802154_isr(void *arg)
}
// all events should be handled
assert(events == 0);
IEEE802154_ASSERT(events == 0);
}
@ -599,7 +601,7 @@ void ieee802154_enable(void)
void ieee802154_disable(void)
{
modem_clock_module_disable(ieee802154_periph.module);
s_ieee802154_state = IEEE802154_STATE_DISABLE;
ieee802154_set_state(IEEE802154_STATE_DISABLE);
}
esp_err_t ieee802154_mac_init(void)
@ -631,6 +633,7 @@ esp_err_t ieee802154_mac_init(void)
#endif
memset(s_rx_frame, 0, sizeof(s_rx_frame));
ieee802154_set_state(IEEE802154_STATE_IDLE);
// TODO: Add flags for IEEE802154 ISR allocating. TZ-102
ret = esp_intr_alloc(ieee802154_periph.irq_id, 0, ieee802154_isr, NULL, NULL);
@ -645,7 +648,7 @@ IEEE802154_STATIC void start_ed(uint32_t duration)
{
ieee802154_ll_enable_events(IEEE802154_EVENT_ED_DONE);
ieee802154_ll_set_ed_duration(duration);
ieee802154_ll_set_cmd(IEEE802154_CMD_ED_START);
ieee802154_set_cmd(IEEE802154_CMD_ED_START);
}
IEEE802154_STATIC void tx_init(const uint8_t *frame)
@ -671,11 +674,11 @@ esp_err_t ieee802154_transmit(const uint8_t *frame, bool cca)
IEEE802154_SET_TXRX_PTI(IEEE802154_SCENE_TX);
if (cca) {
ieee802154_ll_set_cmd(IEEE802154_CMD_CCA_TX_START);
s_ieee802154_state = IEEE802154_STATE_TX_CCA;
ieee802154_set_cmd(IEEE802154_CMD_CCA_TX_START);
ieee802154_set_state(IEEE802154_STATE_TX_CCA);
} else {
ieee802154_ll_set_cmd(IEEE802154_CMD_TX_START);
s_ieee802154_state = IEEE802154_STATE_TX;
ieee802154_set_cmd(IEEE802154_CMD_TX_START);
ieee802154_set_state(IEEE802154_STATE_TX);
}
ieee802154_exit_critical();
@ -696,7 +699,7 @@ esp_err_t ieee802154_transmit_at(const uint8_t *frame, bool cca, uint32_t time)
IEEE802154_SET_TXRX_PTI(IEEE802154_SCENE_TX_AT);
if (cca) {
tx_target_time = time - IEEE802154_ED_TRIG_TX_RAMPUP_TIME_US;
s_ieee802154_state = IEEE802154_STATE_TX_CCA;
ieee802154_set_state(IEEE802154_STATE_TX_CCA);
ieee802154_enter_critical();
ieee802154_etm_set_event_task(IEEE802154_ETM_CHANNEL0, ETM_EVENT_TIMER0_OVERFLOW, ETM_TASK_ED_TRIG_TX);
current_time = (uint32_t)esp_timer_get_time();
@ -706,9 +709,9 @@ esp_err_t ieee802154_transmit_at(const uint8_t *frame, bool cca, uint32_t time)
} else {
tx_target_time = time - IEEE802154_TX_RAMPUP_TIME_US;
if (ieee802154_frame_get_type(frame) == IEEE802154_FRAME_TYPE_ACK && ieee802154_frame_get_version(frame) == IEEE802154_FRAME_VERSION_2) {
s_ieee802154_state = IEEE802154_STATE_TX_ENH_ACK;
ieee802154_set_state(IEEE802154_STATE_TX_ENH_ACK);
} else {
s_ieee802154_state = IEEE802154_STATE_TX;
ieee802154_set_state(IEEE802154_STATE_TX);
}
ieee802154_enter_critical();
ieee802154_etm_set_event_task(IEEE802154_ETM_CHANNEL0, ETM_EVENT_TIMER0_OVERFLOW, ETM_TASK_TX_START);
@ -749,7 +752,7 @@ esp_err_t ieee802154_receive_at(uint32_t time)
rx_init();
IEEE802154_SET_TXRX_PTI(IEEE802154_SCENE_RX_AT);
set_next_rx_buffer();
s_ieee802154_state = IEEE802154_STATE_RX;
ieee802154_set_state(IEEE802154_STATE_RX);
ieee802154_enter_critical();
ieee802154_etm_set_event_task(IEEE802154_ETM_CHANNEL1, ETM_EVENT_TIMER0_OVERFLOW, ETM_TASK_RX_START);
current_time = (uint32_t)esp_timer_get_time();
@ -801,7 +804,7 @@ esp_err_t ieee802154_sleep(void)
ieee802154_enter_critical();
stop_current_operation();
s_ieee802154_state = IEEE802154_STATE_SLEEP;
ieee802154_set_state(IEEE802154_STATE_IDLE);
ieee802154_exit_critical();
return ESP_OK;
@ -816,7 +819,7 @@ esp_err_t ieee802154_energy_detect(uint32_t duration)
ieee802154_pib_update();
start_ed(duration);
s_ieee802154_state = IEEE802154_STATE_ED;
ieee802154_set_state(IEEE802154_STATE_ED);
ieee802154_exit_critical();
return ESP_OK;
@ -831,7 +834,7 @@ esp_err_t ieee802154_cca(void)
ieee802154_pib_update();
start_ed(CCA_DETECTION_TIME);
s_ieee802154_state = IEEE802154_STATE_CCA;
ieee802154_set_state(IEEE802154_STATE_CCA);
ieee802154_exit_critical();
return ESP_OK;

Wyświetl plik

@ -8,9 +8,172 @@
#include <stdint.h>
#include <stdbool.h>
#include "esp_ieee802154_dev.h"
#include "hal/ieee802154_ll.h"
#include "esp_timer.h"
#ifdef __cplusplus
extern "C" {
#endif
#define IEEE802154_PROBE(a) do { \
IEEE802154_RECORD_EVENT(a); \
ieee802154_record_abort(a); \
} while(0)
#if CONFIG_IEEE802154_RECORD_EVENT
#define IEEE802154_ASSERT_RECORD_EVENT_SIZE CONFIG_IEEE802154_RECORD_EVENT_SIZE
#define IEEE802154_RECORD_EVENT(a) do { \
g_ieee802154_probe.event[g_ieee802154_probe.event_index].event = a; \
g_ieee802154_probe.event[g_ieee802154_probe.event_index].state = ieee802154_get_state(); \
if (a == IEEE802154_EVENT_RX_ABORT) { \
g_ieee802154_probe.event[g_ieee802154_probe.event_index].abort_reason.rx \
= ieee802154_ll_get_rx_abort_reason(); \
} else if (a == IEEE802154_EVENT_TX_ABORT) { \
g_ieee802154_probe.event[g_ieee802154_probe.event_index].abort_reason.tx \
= ieee802154_ll_get_tx_abort_reason(); \
} \
g_ieee802154_probe.event[g_ieee802154_probe.event_index++].timestamp = esp_timer_get_time(); \
g_ieee802154_probe.event_index = (g_ieee802154_probe.event_index == IEEE802154_ASSERT_RECORD_EVENT_SIZE) ? \
0 : g_ieee802154_probe.event_index; \
} while(0)
/**
* @brief The table of recording IEEE802154 event command.
*/
typedef struct {
ieee802154_ll_events event; /*!< record current radio event */
ieee802154_state_t state; /*!< record current radio state */
union {
ieee802154_ll_rx_abort_reason_t rx;
ieee802154_ll_tx_abort_reason_t tx;
} abort_reason; /*!< record current radio abort reason */
uint64_t timestamp; /*!< record timestamp*/
} ieee802154_event_info_t;
#else
#define IEEE802154_RECORD_EVENT(a)
#endif // CONFIG_IEEE802154_RECORD_EVENT
#if CONFIG_IEEE802154_RECORD_STATE
#define IEEE802154_ASSERT_RECORD_STATE_SIZE CONFIG_IEEE802154_RECORD_STATE_SIZE
#define ieee802154_set_state(a) do { s_ieee802154_state = a; \
sprintf(g_ieee802154_probe.state[g_ieee802154_probe.state_index].line_str, "%d", __LINE__); \
g_ieee802154_probe.state[g_ieee802154_probe.state_index].timestamp = esp_timer_get_time(); \
g_ieee802154_probe.state[g_ieee802154_probe.state_index++].state = a; \
g_ieee802154_probe.state_index = \
(g_ieee802154_probe.state_index == IEEE802154_ASSERT_RECORD_STATE_SIZE) ? 0 : g_ieee802154_probe.state_index; \
} while(0)
/**
* @brief The table of recording IEEE802154 state command.
*/
typedef struct {
char line_str[5]; /*!< record which line in esp_ieee802154_dev.c changes the state */
ieee802154_state_t state; /*!< record current radio state */
uint64_t timestamp; /*!< record timestamp */
} ieee802154_state_info_t;
#else
#define ieee802154_set_state(state) (s_ieee802154_state = state)
#endif // CONFIG_IEEE802154_RECORD_STATE
#if CONFIG_IEEE802154_RECORD_CMD
#define IEEE802154_ASSERT_RECORD_CMD_SIZE CONFIG_IEEE802154_RECORD_CMD_SIZE
#define ieee802154_set_cmd(a) do { ieee802154_ll_set_cmd(a); \
sprintf(g_ieee802154_probe.cmd[g_ieee802154_probe.cmd_index].line_str, "%d", __LINE__); \
g_ieee802154_probe.cmd[g_ieee802154_probe.cmd_index].timestamp = esp_timer_get_time(); \
g_ieee802154_probe.cmd[g_ieee802154_probe.cmd_index++].cmd = a; \
g_ieee802154_probe.cmd_index = \
(g_ieee802154_probe.cmd_index == IEEE802154_ASSERT_RECORD_CMD_SIZE) ? 0 : g_ieee802154_probe.cmd_index; \
} while(0)
/**
* @brief The table of recording IEEE802154 radio command.
*/
typedef struct {
char line_str[5]; /*!< record which line in esp_ieee802154_dev.c set the command */
ieee802154_ll_cmd_t cmd; /*!< record current command */
uint64_t timestamp; /*!< record timestamp */
} ieee802154_cmd_info_t;
#else
#define ieee802154_set_cmd(cmd) ieee802154_ll_set_cmd(cmd)
#endif //CONFIG_IEEE802154_RECORD_CMD
#if CONFIG_IEEE802154_RECORD_ABORT
#define IEEE802154_ASSERT_RECORD_ABORT_SIZE CONFIG_IEEE802154_RECORD_ABORT_SIZE
#define ieee802154_record_abort(a) do { \
if (a == IEEE802154_EVENT_RX_ABORT) { \
g_ieee802154_probe.abort[g_ieee802154_probe.abort_index].abort_reason.rx \
= ieee802154_ll_get_rx_abort_reason(); \
g_ieee802154_probe.abort[g_ieee802154_probe.abort_index].is_tx_abort = 0; \
g_ieee802154_probe.abort[g_ieee802154_probe.abort_index++].timestamp = esp_timer_get_time(); \
g_ieee802154_probe.abort_index = (g_ieee802154_probe.abort_index == IEEE802154_ASSERT_RECORD_ABORT_SIZE) ? \
0 : g_ieee802154_probe.abort_index; \
} else if (a == IEEE802154_EVENT_TX_ABORT) { \
g_ieee802154_probe.abort[g_ieee802154_probe.abort_index].abort_reason.tx \
= ieee802154_ll_get_tx_abort_reason();\
g_ieee802154_probe.abort[g_ieee802154_probe.abort_index].is_tx_abort = 1; \
g_ieee802154_probe.abort[g_ieee802154_probe.abort_index++].timestamp = esp_timer_get_time(); \
g_ieee802154_probe.abort_index = (g_ieee802154_probe.abort_index == IEEE802154_ASSERT_RECORD_ABORT_SIZE) ? \
0 : g_ieee802154_probe.abort_index; \
} \
} while(0)
/**
* @brief The table of recording IEEE802154 radio abort.
*/
typedef struct {
bool is_tx_abort; /*!< record current abort type */
union {
ieee802154_ll_rx_abort_reason_t rx;
ieee802154_ll_tx_abort_reason_t tx;
} abort_reason; /*!< record current radio abort reason */
uint64_t timestamp; /*!< record timestamp*/
} ieee802154_abort_info_t;
#else
#define ieee802154_record_abort(a)
#endif // CONFIG_IEEE802154_RECORD_ABORT
/**
* @brief The table of recording IEEE802154 information.
*/
typedef struct {
#if CONFIG_IEEE802154_RECORD_EVENT
ieee802154_event_info_t event[IEEE802154_ASSERT_RECORD_EVENT_SIZE]; /*!< record radio event */
uint8_t event_index; /*!< the index of event */
#endif // CONFIG_IEEE802154_RECORD_EVENT
#if CONFIG_IEEE802154_RECORD_STATE
ieee802154_state_info_t state[IEEE802154_ASSERT_RECORD_STATE_SIZE]; /*!< record radio state */
uint8_t state_index; /*!< the index of state */
#endif // CONFIG_IEEE802154_RECORD_STATE
#if CONFIG_IEEE802154_RECORD_CMD
ieee802154_cmd_info_t cmd[IEEE802154_ASSERT_RECORD_CMD_SIZE]; /*!< record radio command */
uint8_t cmd_index; /*!< the index of command */
#endif // CONFIG_IEEE802154_RECORD_CMD
#if CONFIG_IEEE802154_RECORD_ABORT
ieee802154_abort_info_t abort[IEEE802154_ASSERT_RECORD_ABORT_SIZE]; /*!< record radio abort */
uint8_t abort_index; /*!< the index of abort */
#endif // CONFIG_IEEE802154_RECORD_ABORT
} ieee802154_probe_info_t;
extern ieee802154_probe_info_t g_ieee802154_probe;
#if CONFIG_IEEE802154_ASSERT
/**
* @brief This function print rich information, which is useful for debug.
* Only can be used when `IEEE802154_ASSERT` is enabled.
*
*/
void ieee802154_assert_print(void);
#define IEEE802154_ASSERT(a) do { \
if(!(a)) { \
ieee802154_assert_print(); \
assert(a); \
} \
} while (0)
#else // CONFIG_IEEE802154_ASSERT
#define IEEE802154_ASSERT(a) assert(a)
#endif // CONFIG_IEEE802154_ASSERT
// TODO: replace etm code using common interface
#define IEEE802154_ETM_CHANNEL0 0