For reference I am using NCS v2.0 and VSCode NCS plugin programming in C++.
I am trying to get the example ESB TX example working from the nordic sample (link).
(Notably I replaced the logging with my own logging code and stripped out the LED indications).
However, when I run the code, it crashes repeatedly, giving the following output:
Enhanced ShockBurst ptx sample
HF clock started
Initialization complete
Sending test packet
MPSL ASSERT: 112, 2189
I configured an MPSL assert handler which is how I determined the MPSL was crashing out.
I have my full code and prj.conf file below.
Can you give any guidance on what I'm doing wrong? I have a lot of features enabled in my prj.conf because I'm separately working on many other aspects of a large application which I want to incorporate ESB into. That includes Bluetooth, which perhaps is activating MPSL and a source of contention here?
Please let me know what I would need to change in order for this to work.
Code:
#include <zephyr/drivers/clock_control.h> #include <zephyr/drivers/clock_control/nrf_clock_control.h> #include <zephyr/drivers/gpio.h> #include <zephyr/irq.h> #include <zephyr/logging/log.h> #include <nrf.h> #include <esb.h> #include <zephyr/device.h> #include <zephyr/devicetree.h> #include <zephyr/kernel.h> #include <zephyr/types.h> #include "Log.h" static bool ready = true; static struct esb_payload rx_payload; inline static struct esb_payload tx_payload = { .length = 8, .pipe = 0, .data = { 0x01, 0x00, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 } }; #define _RADIO_SHORTS_COMMON \ (RADIO_SHORTS_READY_START_Msk | RADIO_SHORTS_END_DISABLE_Msk | \ RADIO_SHORTS_ADDRESS_RSSISTART_Msk | \ RADIO_SHORTS_DISABLED_RSSISTOP_Msk) void event_handler(struct esb_evt const *event) { ready = true; switch (event->evt_id) { case ESB_EVENT_TX_SUCCESS: Log("TX SUCCESS EVENT"); break; case ESB_EVENT_TX_FAILED: Log("TX FAILED EVENT"); break; case ESB_EVENT_RX_RECEIVED: while (esb_read_rx_payload(&rx_payload) == 0) { Log("Packet received, len %d : " "0x%02x, 0x%02x, 0x%02x, 0x%02x, " "0x%02x, 0x%02x, 0x%02x, 0x%02x", rx_payload.length, rx_payload.data[0], rx_payload.data[1], rx_payload.data[2], rx_payload.data[3], rx_payload.data[4], rx_payload.data[5], rx_payload.data[6], rx_payload.data[7]); } break; } } int clocks_start(void) { int err; int res; struct onoff_manager *clk_mgr; struct onoff_client clk_cli; clk_mgr = z_nrf_clock_control_get_onoff(CLOCK_CONTROL_NRF_SUBSYS_HF); if (!clk_mgr) { Log("Unable to get the Clock manager"); return -ENXIO; } sys_notify_init_spinwait(&clk_cli.notify); err = onoff_request(clk_mgr, &clk_cli); if (err < 0) { Log("Clock request failed: %d", err); return err; } do { err = sys_notify_fetch_result(&clk_cli.notify, &res); if (!err && res) { Log("Clock could not be started: %d", res); return res; } } while (err); Log("HF clock started"); return 0; } int esb_initialize(void) { int err; /* These are arbitrary default addresses. In end user products * different addresses should be used for each set of devices. */ uint8_t base_addr_0[4] = {0xE7, 0xE7, 0xE7, 0xE7}; uint8_t base_addr_1[4] = {0xC2, 0xC2, 0xC2, 0xC2}; uint8_t addr_prefix[8] = {0xE7, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8}; struct esb_config config = ESB_DEFAULT_CONFIG; config.protocol = ESB_PROTOCOL_ESB_DPL; config.retransmit_delay = 600; config.bitrate = ESB_BITRATE_2MBPS; config.event_handler = event_handler; config.mode = ESB_MODE_PTX; config.selective_auto_ack = true; err = esb_init(&config); if (err) { return err; } err = esb_set_base_address_0(base_addr_0); if (err) { return err; } err = esb_set_base_address_1(base_addr_1); if (err) { return err; } err = esb_set_prefixes(addr_prefix, ARRAY_SIZE(addr_prefix)); if (err) { return err; } return 0; } void main(void) { int err; Log("Enhanced ShockBurst ptx sample"); err = clocks_start(); if (err) { return; } err = esb_initialize(); if (err) { Log("ESB initialization failed, err %d", err); return; } Log("Initialization complete"); Log("Sending test packet"); tx_payload.noack = false; while (1) { if (ready) { ready = false; esb_flush_tx(); err = esb_write_payload(&tx_payload); if (err) { Log("Payload write failed, err %d", err); } tx_payload.data[1]++; } k_sleep(K_MSEC(100)); } }
prj.conf:
##################################################################### # set up project to use c++17 and useful libs/stl ##################################################################### CONFIG_CPLUSPLUS=y CONFIG_LIB_CPLUSPLUS=y CONFIG_NEWLIB_LIBC=y CONFIG_STD_CPP20=y CONFIG_NEWLIB_LIBC_FLOAT_PRINTF=y CONFIG_CBPRINTF_FP_SUPPORT=y ##################################################################### # maximum debugging - my code, kernel, everything ##################################################################### CONFIG_DEBUG_OPTIMIZATIONS=y CONFIG_DEBUG=y CONFIG_DEBUG_THREAD_INFO=y CONFIG_EXCEPTION_STACK_TRACE=y CONFIG_DEBUG_INFO=y ##################################################################### # system features ##################################################################### # Enable rebooting by code CONFIG_REBOOT=y # use internal RC oscillator instead of external 32KHz crystal # speeds up boot time # in my case, going from infinity down to instant CONFIG_CLOCK_CONTROL_NRF_K32SRC_RC=y # Disable NFC so I can use the GPIO pins CONFIG_NFCT_PINS_AS_GPIOS=y # monitor high-water mark on stack by placing known-values in stack # buffer before running CONFIG_INIT_STACKS=y CONFIG_MPU_STACK_GUARD=y ##################################################################### # Set up interfacing ##################################################################### # I want serial enabled in general CONFIG_SERIAL=y CONFIG_UART_INTERRUPT_DRIVEN=y CONFIG_UART_ASYNC_API=y # I want logging to function CONFIG_LOG=y # I want to use the serial interface for logging # but when I enable shell, this makes printf'd material come out twice, # once normally, and another time with the shell prefix. # so I'm disabling it for now. # CONFIG_LOG_BACKEND_UART=y # I want synchronous logging (no queue and print later) CONFIG_LOG_MODE_IMMEDIATE=y # I want to be able to influnce what gets logged at runtime (via shell) CONFIG_LOG_RUNTIME_FILTERING=y # I want the default to be that every module prints all levels # 0 = off # 1 = error # 2 = error and warning # 3 = error and warning and info # 4 = error and warning and info and debug CONFIG_LOG_DEFAULT_LEVEL=4 # show function name in output CONFIG_LOG_FUNC_NAME_PREFIX_ERR=y CONFIG_LOG_FUNC_NAME_PREFIX_WRN=y CONFIG_LOG_FUNC_NAME_PREFIX_INF=y CONFIG_LOG_FUNC_NAME_PREFIX_DBG=y # color it CONFIG_LOG_BACKEND_SWO=y CONFIG_LOG_BACKEND_SHOW_COLOR=y # redirect printk to the log # I am disabling this, because when shell enabled, prink output was # prefixed with shell. now I see it on serial with no prefix. #CONFIG_LOG_PRINTK=y # ##### Shell ##### # # I want the shell interface to operate CONFIG_SHELL=y ##################################################################### # set up stats ##################################################################### CONFIG_THREAD_RUNTIME_STATS=y ##################################################################### # set up pwm ##################################################################### CONFIG_PWM=y ##################################################################### # set up usb ##################################################################### # CONFIG_USB_DEVICE_STACK=y # CONFIG_USB_DEVICE_PRODUCT="Glow Bike" # CONFIG_USB_MASS_STORAGE=y ##################################################################### # set up disk ##################################################################### # CONFIG_DISK_ACCESS=y # CONFIG_DISK_DRIVERS=y # CONFIG_FLASH=y # CONFIG_DISK_DRIVER_FLASH=y # CONFIG_FLASH_MAP=y # CONFIG_FLASH_PAGE_LAYOUT=y # CONFIG_MPU_ALLOW_FLASH_WRITE=y # CONFIG_FILE_SYSTEM=y # CONFIG_FAT_FILESYSTEM_ELM=y # CONFIG_FS_FATFS_READ_ONLY=n # CONFIG_FS_FATFS_MOUNT_MKFS=y ##################################################################### # set multi-protocol service layer (multiple radio protocol support) ##################################################################### # enable multi-protocol service layer (doesn't work with CONFIG_BT_LL_SW_SPLIT seemingly) CONFIG_MPSL=y # limit to 1 for now, that's all I'm using atm CONFIG_MPSL_TIMESLOT_SESSION_COUNT=2 # let's see during dev CONFIG_MPSL_LOG_LEVEL_DBG=y # allow myself to catch assert errors in my own code (and still die) CONFIG_MPSL_ASSERT_HANDLER=y ##################################################################### # set up ble ##################################################################### CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=2048 CONFIG_BT_RX_STACK_SIZE=4096 CONFIG_MAIN_STACK_SIZE=4096 CONFIG_BT=y CONFIG_BT_HCI=y CONFIG_BT_CTLR=y # Use the zephyr BLE implementation instead of the SoftDevice from Nordic # CONFIG_BT_LL_SW_SPLIT=y CONFIG_BT_PERIPHERAL=y CONFIG_BT_CENTRAL=y CONFIG_BT_BROADCASTER=y CONFIG_BT_OBSERVER=y # Enable Security Manager Protocol (SMP), making it possible to pair devices over LE CONFIG_BT_SMP=y # allow me to set the code to show to users on their device via bt_passkey_set() CONFIG_BT_FIXED_PASSKEY=y # let me see more details about the other side of the connection CONFIG_BT_REMOTE_INFO=y # let me change and see changes to the PHY layer CONFIG_BT_USER_PHY_UPDATE=y # let me change and see changes to the data length (MTU?) CONFIG_BT_USER_DATA_LEN_UPDATE=y # let me express preferences for phy modulation CONFIG_BT_CTLR_PHY_CODED=y # CONFIG_BT_HCI_VS_EXT=y # CONFIG_BT_PHY_UPDATE=y # let me change (my) and measure (their) transmit power levels CONFIG_BT_CTLR_CONN_RSSI=y # CONFIG_BT_CTLR_ADVANCED_FEATURES=y ; # triggers warning, needed? CONFIG_BT_CTLR_TX_PWR_DYNAMIC_CONTROL=y # ? # CONFIG_BT_TPS=y ##################################################################### # set up ESB (extended shock burst) ##################################################################### CONFIG_ESB=y CONFIG_NCS_SAMPLES_DEFAULTS=y # fat frames # https://devzone.nordicsemi.com/f/nordic-q-a/84226/increasing-ble-mtu-data-length-for-notifications-on-ncs-v1-8 # https://github.com/zephyrproject-rtos/zephyr/issues/25648 # Uncoded LE Data Packet Format: # # | Preamble | Access | PDU (2 to 257 bytes) | CRC | # | | Address | LL Header | Link Layer PDU (0 to 251 bytes) | MIC | | # | | | | L2CAP Header | L2CAP PDU (0-247 bytes) | Optional | | # | | | | | ATT Header | ATT Payload | | | # | | | | | OpCode | Handle | | | | # | 1 byte | 4 bytes | 2 bytes | 4 bytes | 1 byte | 2 bytes | 0 - 244 bytes | 4 bytes | 3 bytes | # # L2CAP can be larger than 247 bytes, but will be split across multiple LL packets as a result. # ATT payloads can be larger than 244 bytes, but will be split across multiple LL packets as a result. # # # Kconfig Symbols: # CONFIG_BT_CTLR_DATA_LENGTH_MAX : Maximum payload size of the Link Layer PDU # CONFIG_BT_BUF_ACL_TX_SIZE : Maximum L2CAP PDU is limited to this value - 4 # CONFIG_BT_BUF_ACL_RX_SIZE : Maximum L2CAP PDU is limited to this value - 4 # CONFIG_BT_L2CAP_TX_MTU : Maximum L2CAP PDU size for transmission CONFIG_BT_BUF_ACL_RX_SIZE=251 CONFIG_BT_BUF_ACL_TX_SIZE=251 CONFIG_BT_L2CAP_TX_MTU=247 CONFIG_BT_CTLR_DATA_LENGTH_MAX=251 # CONFIG_BT_GATT_AUTO_UPDATE_MTU= CONFIG_BT_GATT_DYNAMIC_DB=y CONFIG_BT_DEVICE_APPEARANCE_DYNAMIC=y CONFIG_BT_DEVICE_NAME_DYNAMIC=y # unsure these #CONFIG_BT_EXT_ADV=y CONFIG_PM=n # settings subsystem required as well for bluetooth libs (for bonding) CONFIG_BT_SETTINGS=y CONFIG_FLASH=y CONFIG_FLASH_PAGE_LAYOUT=y CONFIG_FLASH_MAP=y CONFIG_NVS=y CONFIG_SETTINGS=y # major memory hog, ~2k per connection (wtf) CONFIG_BT_MAX_CONN=20 ##################################################################### # allow access to flash for read/write (non-volatile memory store) ##################################################################### # CONFIG_MAIN_STACK_SIZE=2048 # CONFIG_MPU_ALLOW_FLASH_WRITE=y # CONFIG_FLASH=y # CONFIG_FLASH_MAP=y # CONFIG_FLASH_PAGE_LAYOUT=y # CONFIG_FILE_SYSTEM=y # CONFIG_FILE_SYSTEM_LITTLEFS=y ##################################################################### # attempt to get RTT working, but no, still not working ##################################################################### # CONFIG_USE_SEGGER_RTT=y ##################################################################### # disable startup banner printed to serial by zephyr ##################################################################### CONFIG_BOOT_BANNER=n
Thanks.