diff --git a/examples/twr_aloha/control.c b/examples/twr_aloha/control.c index 748c9430f113..42d1332d04e1 100644 --- a/examples/twr_aloha/control.c +++ b/examples/twr_aloha/control.c @@ -149,6 +149,7 @@ static bool _complete_cb(struct uwb_dev *inst, struct uwb_mac_interface *cbs) event_post(uwb_core_get_eventq(), &_rng_listen_event.super); return false; } + /* get received frame */ struct uwb_rng_instance *rng = (struct uwb_rng_instance *)cbs->inst_ptr; @@ -157,6 +158,15 @@ static bool _complete_cb(struct uwb_dev *inst, struct uwb_mac_interface *cbs) /* parse data*/ uwb_core_rng_data_t data; + /* with ss twr, the last frame will hold the initiator as the src address, + with ds twr, it will hold the responder address */ + if (IS_ACTIVE(CONFIG_TWR_PRINTF_INITIATOR_ONLY) && + ((frame->code < UWB_DATA_CODE_DS_TWR && frame->src_address != _udev->uid) || + (frame->code >= UWB_DATA_CODE_DS_TWR && frame->dst_address != _udev->uid))) { + event_post(uwb_core_get_eventq(), &_rng_listen_event.super); + return true; + } + data.src = frame->src_address; data.dest = frame->dst_address; data.time = ztimer_now(ZTIMER_MSEC); @@ -205,7 +215,7 @@ static void _rng_listen(void *arg) if (!ztimer_is_set(ZTIMER_MSEC, &_rng_request_event.periodic.timer.timer)) { _status &= ~TWR_STATUS_INITIATOR; } - if (_status && TWR_STATUS_RESPONDER) { + if (_status & TWR_STATUS_RESPONDER) { /* wake up if needed */ if (_udev->status.sleeping) { uwb_wakeup(_udev); @@ -217,8 +227,7 @@ static void _rng_listen(void *arg) } else { /* go to sleep if possible */ - if (_rng_request_event.periodic.timer.interval > CONFIG_TWR_MIN_IDLE_SLEEP_MS || - !(_status && TWR_STATUS_INITIATOR)) { + if (_rng_request_event.periodic.timer.interval > CONFIG_TWR_MIN_IDLE_SLEEP_MS) { uwb_sleep_config(_udev); uwb_enter_sleep(_udev); } @@ -254,7 +263,7 @@ static void _rng_request(void *arg) uwb_phy_forcetrxoff(_udev); } - uwb_rng_request(_rng, event->addr, (uwb_dataframe_code_t)event->proto); + uwb_rng_request(_rng, event->addr, (uwb_dataframe_code_t)event->proto); } void uwb_core_rng_start(uint16_t addr, twr_protocol_t proto, uint32_t interval, @@ -285,7 +294,14 @@ void uwb_core_rng_init(void) /* set initial status */ _status = 0; /* got to sleep on boot */ - struct uwb_dev*_udev = uwb_dev_idx_lookup(0); + struct uwb_dev *_udev = uwb_dev_idx_lookup(0); + uwb_sleep_config(_udev); uwb_enter_sleep(_udev); } + +uint32_t uwb_core_rng_req_remaining(void) +{ + /* doesn't matter if its not atomic */ + return _rng_request_event.periodic.count; +} diff --git a/examples/twr_aloha/control.h b/examples/twr_aloha/control.h index 50859f3880bb..195a41c24b30 100644 --- a/examples/twr_aloha/control.h +++ b/examples/twr_aloha/control.h @@ -31,14 +31,21 @@ extern "C" { * @brief Block after a request is sent */ #ifndef CONFIG_TWR_SHELL_BLOCKING -#define CONFIG_TWR_SHELL_BLOCKING 1 +#define CONFIG_TWR_SHELL_BLOCKING 1 #endif /** * @brief Minimum idle time to enable putting the radio to sleep */ #ifndef CONFIG_TWR_MIN_IDLE_SLEEP_MS -#define CONFIG_TWR_MIN_IDLE_SLEEP_MS 20 +#define CONFIG_TWR_MIN_IDLE_SLEEP_MS 20 +#endif + +/* + * @brief Block after a request is sent + */ +#ifndef CONFIG_TWR_PRINTF_INITIATOR_ONLY +#define CONFIG_TWR_PRINTF_INITIATOR_ONLY 1 #endif /** @@ -100,6 +107,11 @@ void uwb_core_rng_listen_disable(void); void uwb_core_rng_start(uint16_t addr, twr_protocol_t proto, uint32_t interval, uint32_t count); +/** + * @brief Returns remaining rng requests + */ +uint32_t uwb_core_rng_req_remaining(void); + #ifdef __cplusplus } #endif diff --git a/examples/twr_aloha/tests-with-config/01-run.py b/examples/twr_aloha/tests-with-config/01-run.py index 3346919b2765..a75ad7f1ffff 100755 --- a/examples/twr_aloha/tests-with-config/01-run.py +++ b/examples/twr_aloha/tests-with-config/01-run.py @@ -23,6 +23,7 @@ class TwrShell(Reboot, TwrCmd): "hwaddr": None, "hwaddr64": None, "panid": None, + "channel": None, } def parse_netif(self): @@ -41,6 +42,9 @@ def hwaddr64(self): def panid(self): return self._netif["panid"] + def channel(self): + return self._netif["channel"] + class TestTWRBase(unittest.TestCase): DEBUG = False @@ -68,7 +72,7 @@ def test_ifconfig(self): assert self.shell.panid() == "DE:CA" assert self.shell.hwaddr() is not None assert self.shell.hwaddr64() is not None - assert self.shell.panid() is not None + assert self.shell.channel() == "5" # default channel is 5 def test_listen(self): assert "[twr]: start listening" in self.shell.twr_listen(on=True) diff --git a/examples/twr_aloha/twr_shell.c b/examples/twr_aloha/twr_shell.c index edceb07caf53..fdf6640cf722 100644 --- a/examples/twr_aloha/twr_shell.c +++ b/examples/twr_aloha/twr_shell.c @@ -35,6 +35,14 @@ #define IEEE802154_SHORT_ADDRESS_LEN_STR_MAX \ (sizeof("00:00")) +/* See 7.2.31.1 Units of TX Power Control */ +#define DW1000_TX_POWER_COARSE_SHIFT (5) +#define DW1000_TX_POWER_COARSE_MASK (0xE0) +#define DW1000_TX_POWER_FINE_MASK (0x1F) +#define DW1000_TX_POWER_MULTI (10) +#define DW1000_TX_POWER_COARSE_STEP (30) /* 3dbM * 10 */ +#define DW1000_TX_POWER_FINE_STEP (5) /* 0.5dbM * 10 */ + int _twr_ifconfig(int argc, char **argv) { (void)argc; @@ -49,11 +57,24 @@ int _twr_ifconfig(int argc, char **argv) printf("\tHWaddr: %s ", l2util_addr_to_str(buffer, IEEE802154_SHORT_ADDRESS_LEN, addr_str)); byteorder_htobebufs(buffer, udev->pan_id); + printf("Channel: %d ", udev->config.channel); printf("NID: %s\n\n", l2util_addr_to_str(buffer, IEEE802154_SHORT_ADDRESS_LEN, addr_str)); byteorder_htobebufll(buffer, udev->euid); printf("\t\tLong HWaddr: %s\n", l2util_addr_to_str(buffer, IEEE802154_LONG_ADDRESS_LEN, addr_str)); + /* 000 -> 18dBM gain, 110 -> 0dBm gain */ + int tx_power = + DW1000_TX_POWER_COARSE_STEP * + (6 - + ((udev->config.txrf.BOOSTNORM & DW1000_TX_POWER_COARSE_MASK) >> + DW1000_TX_POWER_COARSE_SHIFT)) + + (udev->config.txrf.BOOSTNORM & DW1000_TX_POWER_FINE_MASK) * + DW1000_TX_POWER_FINE_STEP; + + printf("\t\tTX-Power: %d.%ddBm ", tx_power / DW1000_TX_POWER_MULTI, + tx_power > (tx_power / DW1000_TX_POWER_MULTI) * DW1000_TX_POWER_MULTI ? 5 : 0); + printf("TC-PGdelay: 0x%02x\n", udev->config.txrf.PGdly); return 0; } @@ -100,7 +121,8 @@ int _twr_handler(int argc, char **argv) uint32_t count = 1; uint32_t interval_ms = 1000; int proto = UWB_DATA_CODE_SS_TWR; - uint8_t addr[IEEE802154_SHORT_ADDRESS_LEN_STR_MAX]; + uint8_t addr[IEEE802154_SHORT_ADDRESS_LEN]; + uint16_t short_addr = 0x0000; int res = 0; if (argc < 3) { _print_usage(); @@ -117,6 +139,11 @@ int _twr_handler(int argc, char **argv) "(hex pairs delimited by colons)"); res = 1; } + short_addr = addr[1] + (addr[0] << 8); + if (short_addr == 0x0000) { + printf("[ERROR]: invalid addr %s\n", arg); + res = 1; + } } else { switch (arg[1]) { @@ -173,15 +200,18 @@ int _twr_handler(int argc, char **argv) } } } - if (res != 0) { + if (res != 0 || (short_addr == 0x0000)) { _print_usage(); return 1; } - uint16_t short_addr = addr[1] + (addr[0] << 8); puts("[twr]: start ranging"); uwb_core_rng_start(short_addr, proto, interval_ms, count); if (IS_ACTIVE(CONFIG_TWR_SHELL_BLOCKING)) { - ztimer_sleep(ZTIMER_MSEC, interval_ms * (count + 1)); + while (uwb_core_rng_req_remaining()) { + ztimer_sleep(ZTIMER_MSEC, interval_ms); + } + /* some time to finish up */ + ztimer_sleep(ZTIMER_MSEC, 100 + interval_ms); } return 0; } diff --git a/examples/twr_aloha/twr_shell.py b/examples/twr_aloha/twr_shell.py index 13dde0b15947..d002251108e7 100644 --- a/examples/twr_aloha/twr_shell.py +++ b/examples/twr_aloha/twr_shell.py @@ -18,6 +18,7 @@ class TwrIfconfigParser(ShellInteractionParser): hwaddr_c = re.compile(r"HWaddr:\s+(?P[0-9a-fA-F:]+)\s") hwaddr64_c = re.compile(r"Long HWaddr:\s+(?P[0-9a-fA-F:]+)") panid_c = re.compile(r"NID:\s+(?P[0-9a-fA-F:]+)") + channel_c = re.compile(r"Channel:\s+(?P[0-9]+)") def parse(self, cmd_output): netif = { @@ -25,6 +26,7 @@ def parse(self, cmd_output): "hwaddr": None, "hwaddr64": None, "panid": None, + "channel": None, } for line in cmd_output.splitlines(): m = self.iface_c.search(line) @@ -39,6 +41,9 @@ def parse(self, cmd_output): m = self.panid_c.search(line) if m is not None: netif["panid"] = m.group("name") + m = self.channel_c.search(line) + if m is not None: + netif["channel"] = m.group("name") return netif @@ -55,9 +60,9 @@ def twr_listen(self, on=True, timeout=-1, async_=False): args=("lst", "on" if on else "off"), timeout=timeout, async_=async_ ) - def twr_req(self, count=1, interval=1000, proto="ss", timeout=-1, async_=False): + def twr_req(self, addr="ff:ff", count=1, interval=1000, proto="ss", timeout=-1, async_=False): return self.twr_cmd( - args=("req", f"-c {count}", f"-p {proto}", f"-i {interval}"), + args=("req", f"{addr}", f"-c {count}", f"-p {proto}", f"-i {interval}"), timeout=timeout, async_=async_, )