Subject: MPSL ASSERT: 69, 108 and HardFault when using ESB (CONFIG_ESB_MPSL_TIMESLOT) with BLE dual connection and ZMS on NCS v3.3.0 / nRF54L10

Hi,

I'm running NCS v3.3.0 on a Nordic nRF54L10 (nRF54L Series, Cortex-M33) with:
- BLE peripheral role, max 2 connections (dual connected simultaneously)
- ESB in CONFIG_ESB_MPSL_TIMESLOT mode
- ZMS library for non-volatile storage
- ESB PTX/PRX role switching every ~4 ms
(check if TX data pending → enter PTX → after TX done/callback → switch back to PRX)

Under combined BLE traffic (2 connections) + ESB communication, the device randomly crashes:

<err> mpsl_init: MPSL ASSERT: 69, 108
<err> os: ***** HARD FAULT *****
<err> os: Fault escalation (see below)
<err> os: ARCH_EXCEPT with reason 3
>>> ZEPHYR FATAL ERROR 3: Kernel oops on CPU 0
Current thread: 0x20007010 (idle)
Halting system

Key configuration:

# BLE
CONFIG_BT=y
CONFIG_BT_PERIPHERAL=y
CONFIG_BT_MAX_CONN=2
CONFIG_BT_DEVICE_NAME="RD-QED2"
CONFIG_BT_GATT_CLIENT=y
CONFIG_BT_USER_DATA_LEN_UPDATE=y
CONFIG_BT_CTLR_DATA_LENGTH_MAX=251
CONFIG_BT_BUF_ACL_RX_SIZE=251
CONFIG_BT_BUF_ACL_TX_SIZE=251
CONFIG_BT_L2CAP_TX_MTU=247
CONFIG_BT_CTLR_SDC_MAX_CONN_EVENT_LEN_DEFAULT=5000
CONFIG_BT_RADIO_NOTIFICATION_CONN_CB=y

# MPSL / ESB
CONFIG_MPSL=y
CONFIG_ESB_MPSL_TIMESLOT=y
CONFIG_MPSL_TIMESLOT_SESSION_COUNT=1
CONFIG_MPSL_WORK_STACK_SIZE=2048
CONFIG_ESB=y
CONFIG_ESB_CLOCK_INIT=y
CONFIG_ESB_TX_FIFO_SIZE=16
CONFIG_ESB_DYNAMIC_INTERRUPTS=y
CONFIG_ESB_RADIO_IRQ_PRIORITY=0
CONFIG_ESB_EVENT_IRQ_PRIORITY=1
CONFIG_NRFX_GPPI=y
CONFIG_DYNAMIC_INTERRUPTS=y
CONFIG_DYNAMIC_DIRECT_INTERRUPTS=y
CONFIG_MPSL_ASSERT_HANDLER=n

# ZMS
CONFIG_ZMS=y
CONFIG_PM_PARTITION_SIZE_ZMS_STORAGE=0x4000

My questions:
1. What does "MPSL ASSERT: 69, 108" mean in MPSL timeslot context? Is it an invalid timeslot request or incorrect return from the timeslot signal callback (e.g. p_next == NULL / bad extend action)?
2. Are there known issues/recommendations when toggling ESB PTX⇄PRX inside an MPSL timeslot while BLE (2 connections) is active on nRF54L Series?
3. Could BT_CTLR_SDC_MAX_CONN_EVENT_LEN_DEFAULT=5000 (5 ms) conflict with the 4 ms ESB role-check cycle and cause timeslot overruns / rejected requests?
4. What is the correct / safe sequence to stop ESB (PTX→PRX switch) and re-enter the MPSL timeslot to avoid this MPSL assertion?

Any clarification or reference would be greatly appreciated.

Thanks!

Parents
  • Hello,

    Can you try to set CONFIG_MPSL_HFCLK_LATENCY=1650 in the prj.conf file and try again to run the sample?

    Thanks.

    BR
    Kazi

  • We also encountered this issue on NRF52840 (nRF Connect SDK v3.3.0).

    00> [00:11:55.572,296] <err> mpsl_init: MPSL ASSERT: 69, 108[0m
    00> [00:11:55.572,296] <err> os: ***** HARD FAULT *****
    00> [00:11:55.572,296] <err> os:   Fault escalation (see below)
    00> [00:11:55.572,326] <err> os: ARCH_EXCEPT with reason 3
    00> 
    00> [00:11:55.572,357] <err> os: r0/a1:  0x00000003  r1/a2:  0x00000000  r2/a3:  0x00000007
    00> [00:11:55.572,387] <err> os: r3/a4:  0x00000003 r12/ip:  0x2abc7cee r14/lr:  0x0000ee7d
    00> [00:11:55.572,387] <err> os:  xpsr:  0x01000011
    00> [00:11:55.572,418] <err> os: Faulting instruction address (r15/pc): 0x0001b5a0
    00> [00:11:55.572,448] <err> os: >>> ZEPHYR FATAL ERROR 3: Kernel oops on CPU 0
    00> [00:11:55.572,448] <err> os: Fault during interrupt handling
    00> 
    00> [00:11:55.572,509] <err> os: Current thread: 0x20002868 (idle)
    00> [00:11:56.082,794] <err> fatal_error: Resetting system

    No BLE connection.

    /*
     * Copyright (c) 2025 Nordic Semiconductor ASA
     *
     * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
     */
    
    #include <zephyr/bluetooth/bluetooth.h>
    #include <zephyr/bluetooth/conn.h>
    #include <zephyr/bluetooth/gatt.h>
    #include <zephyr/bluetooth/hci.h>
    #include <zephyr/kernel.h>
    #include <zephyr/logging/log.h>
    #include <zephyr/logging/log_ctrl.h>
    #include <zephyr/sys/reboot.h>
    #include <zephyr/random/random.h>
    #include <bluetooth/services/lbs.h>
    #include <dk_buttons_and_leds.h>
    #include <esb.h>
    
    LOG_MODULE_REGISTER(esb_prx_ble, CONFIG_ESB_PRX_BLE_LOG_LEVEL);
    
    #define DEVICE_NAME             CONFIG_BT_DEVICE_NAME "-ESB-PRX"
    #define DEVICE_NAME_LEN         (sizeof(DEVICE_NAME) - 1)
    
    #define CON_STATUS_LED          DK_LED1
    #define USER_LED                DK_LED2
    #define ESB_LED_1               DK_LED3
    #define ESB_LED_2               DK_LED4
    #define USER_BUTTON             DK_BTN1_MSK
    
    static bool app_button_state;
    static struct k_work adv_work;
    
    static struct esb_payload rx_payload;
    static struct esb_payload tx_payload = ESB_CREATE_PAYLOAD(0,
    	0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17);
    
    static bool rx_active = false;
    static void rx_work_handler(struct k_work* work);
    K_WORK_DELAYABLE_DEFINE(rx_work, rx_work_handler);
    
    static const struct bt_data ad[] = {
    	BT_DATA_BYTES(BT_DATA_FLAGS, (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR)),
    	BT_DATA(BT_DATA_NAME_COMPLETE, DEVICE_NAME, DEVICE_NAME_LEN),
    };
    
    static const struct bt_data sd[] = {
    	BT_DATA_BYTES(BT_DATA_UUID128_ALL, BT_UUID_LBS_VAL),
    };
    
    static void esb_err_stat(int err)
    {
        static uint8_t esb_err_count = 0;
        static int err_buf[10] = { 0 };
        if (err) {
            if (esb_err_count >= 10) {
                esb_err_count = 0;
            }
            err_buf[esb_err_count] = err;
            esb_err_count++;
        }
        for (int i = 0; i < 10 && err_buf[i] != 0; i++) {
            LOG_ERR("ESB error buffer[%d] = %d", i, err_buf[i]);
        }
    }
    static void rx_work_handler(struct k_work* work)
    {
        int err;
        static uint8_t start_rx_failed_count = 0;
        if (rx_active) {
            err = esb_stop_rx();
            if (err) {
                LOG_INF("RX stop failed, err %d", err);
            }
    
            uint32_t jitter = sys_rand32_get() % 20;
            k_work_schedule(&rx_work, K_MSEC(40 + jitter));
        } else {
            err = esb_start_rx();
            esb_err_stat(err);
            if (err) {
                start_rx_failed_count++;
                LOG_ERR("RX setup failed %d times, err %d", start_rx_failed_count, err);
                log_panic();
    
                if(start_rx_failed_count >= 30) {
                    sys_reboot(SYS_REBOOT_COLD);
                }
            } else {
                start_rx_failed_count = 0;
            }
            
            k_work_schedule(&rx_work, K_MSEC(14));
        }
        rx_active = !rx_active;
    }
    
    static void adv_work_handler(struct k_work* work)
    {
        int err = bt_le_adv_start(
            BT_LE_ADV_PARAM(BT_LE_ADV_OPT_CONN,
                BT_GAP_ADV_SLOW_INT_MIN,
                BT_GAP_ADV_SLOW_INT_MAX, NULL), ad, ARRAY_SIZE(ad), sd, ARRAY_SIZE(sd));
    
    	if (err) {
    		LOG_ERR("Advertising failed to start (err %d)", err);
    		return;
    	}
    
    	LOG_INF("Advertising successfully started");
    }
    
    static void advertising_start(void)
    {
    	k_work_submit(&adv_work);
    }
    
    static void connected(struct bt_conn *conn, uint8_t err)
    {
    	if (err) {
    		LOG_ERR("Connection failed, err 0x%02x %s", err, bt_hci_err_to_str(err));
    		return;
    	}
    
    	LOG_INF("Connected");
    
    	dk_set_led_on(CON_STATUS_LED);
    }
    
    static void disconnected(struct bt_conn *conn, uint8_t reason)
    {
    	LOG_INF("Disconnected, reason 0x%02x %s", reason, bt_hci_err_to_str(reason));
    
    	dk_set_led_off(CON_STATUS_LED);
    }
    
    static void recycled_cb(void)
    {
    	LOG_INF("Connection object available from previous conn. Disconnect is complete!");
    	advertising_start();
    }
    
    BT_CONN_CB_DEFINE(conn_callbacks) = {
    	.connected        = connected,
    	.disconnected     = disconnected,
    	.recycled         = recycled_cb,
    };
    
    static void app_led_cb(bool led_state)
    {
    	dk_set_led(USER_LED, led_state);
    }
    
    static bool app_button_cb(void)
    {
    	return app_button_state;
    }
    
    static struct bt_lbs_cb lbs_callbacks = {
    	.led_cb    = app_led_cb,
    	.button_cb = app_button_cb,
    };
    
    static void button_changed(uint32_t button_state, uint32_t has_changed)
    {
    	if (has_changed & USER_BUTTON) {
    		uint32_t user_button_state = button_state & USER_BUTTON;
    
    		bt_lbs_send_button_state(user_button_state);
    		app_button_state = user_button_state ? true : false;
    	}
    }
    
    static void leds_update(uint8_t value)
    {
    	const bool led1_state = !(value % 8 > 2 && value % 8 <= 6);
    	const bool led2_state = !(value % 8 > 3);
    
    	dk_set_led(ESB_LED_1, led1_state);
    	dk_set_led(ESB_LED_2, led2_state);
    }
    
    void event_handler(struct esb_evt const *event)
    {
    	int err;
    
    	switch (event->evt_id) {
    	case ESB_EVENT_TX_SUCCESS:
    		LOG_DBG("TX SUCCESS EVENT");
    		break;
    	case ESB_EVENT_TX_FAILED:
    		LOG_DBG("TX FAILED EVENT");
    		break;
    	case ESB_EVENT_RX_RECEIVED:
            while ((err = esb_read_rx_payload(&rx_payload)) == 0) {
                static uint8_t target_buf[3] = { 0x6e, 0x26, 0xb1 };
                if (memcmp(rx_payload.data, target_buf, sizeof(target_buf))) {
                    continue;
                }
                static uint32_t rx_count = 0, last_uptime = 0;
                static uint16_t last_seq_num = 0x8000, missed_count = 0;
                uint16_t new_seq_num = rx_payload.data[6] | (rx_payload.data[5] << 8);
                uint32_t uptime = k_uptime_seconds();
                rx_count++;
                if(new_seq_num  - last_seq_num > 1 && last_seq_num != 0x8000) {
                    missed_count += new_seq_num - last_seq_num - 1;
                    LOG_WRN("Missed %d packets, total missed %d", new_seq_num - last_seq_num - 1, missed_count);
                    LOG_HEXDUMP_WRN(rx_payload.data, rx_payload.length, "New packet data");
                }
                LOG_INF("T:%u, RX %u, last_seq 0x%04x, new_seq 0x%04x, missed %u", uptime, rx_count, last_seq_num, new_seq_num, missed_count);
                last_seq_num = new_seq_num;
    
                static bool last_led_state = false;
                if (uptime - last_uptime > 2) {
                    dk_set_led(DK_LED1, last_led_state);
                    last_led_state = !last_led_state;
                    last_uptime = uptime;
                }
    		}
    		if (err && err != -ENODATA) {
    			LOG_ERR("Error while reading rx packet");
    		}
    		break;
    	case ESB_EVENT_TIMESLOT_FAILED:
    		LOG_ERR("TIMESLOT FAILED EVENT");
    		break;
    	}
    }
    
    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.
    	 */
    	const uint8_t base_addr_0[4] = {0xE7, 0xE7, 0xE7, 0xE7};
    	const uint8_t base_addr_1[4] = {0xC2, 0xC2, 0xC2, 0xC2};
    	const uint8_t addr_prefix[8] = {0xE7, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8};
    
        const struct esb_config config = {
            .protocol           = ESB_PROTOCOL_ESB_DPL,
            .mode               = ESB_MODE_PRX,
            .event_handler      = event_handler,
            .bitrate            = ESB_BITRATE_1MBPS,
            .crc                = ESB_CRC_16BIT,
            .tx_output_power    = ESB_TX_POWER_8DBM,
            .retransmit_delay   = 600,
            .retransmit_count   = 1,
            .tx_mode            = ESB_TXMODE_AUTO,
            .payload_length     = CONFIG_ESB_MAX_PAYLOAD_LENGTH,
            .selective_auto_ack = true,
            .use_fast_ramp_up = IS_ENABLED(CONFIG_ESB_FAST_SWITCHING)
        };
    
    	err = esb_init(&config);
    	if (err) {
    		return err;
        }
        
        err = esb_set_address_length(ARRAY_SIZE(base_addr_0));
        if (err) {
            LOG_ERR("esb set address length failed %d", 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;
    	}
    
        err = esb_set_rf_channel(81);
        if (err) {
            return err;
        }
    
        return 0;
    }
    
    int main(void)
    {
    	int err;
    
        LOG_INF("Build date: %s, build time: %s", __DATE__, __TIME__);
    	// LOG_INF("Starting Enhanced ShockBurst prx with Peripheral LBS sample");
    
    	err = dk_leds_init();
    	if (err) {
    		LOG_ERR("LEDs init failed (err %d)", err);
    		return 0;
    	}
    
    	err = dk_buttons_init(button_changed);
    	if (err) {
    		LOG_ERR("Cannot init buttons (err: %d)", err);
    	}
    
    	err = bt_enable(NULL);
    	if (err) {
    		LOG_ERR("Bluetooth init failed (err %d)", err);
    		return 0;
    	}
    
    	LOG_INF("Bluetooth initialized");
    
    	err = bt_lbs_init(&lbs_callbacks);
    	if (err) {
    		LOG_ERR("Failed to init LBS (err:%d)", err);
    		return 0;
    	}
    
    	k_work_init(&adv_work, adv_work_handler);
    	advertising_start();
    
    	err = esb_initialize();
    	if (err) {
    		LOG_ERR("ESB initialization failed, err %d", err);
    		return 0;
    	}
    
    	// LOG_INF("ESB initialized");
    
    	// err = esb_write_payload(&tx_payload);
    	// if (err) {
    	// 	LOG_ERR("Write payload, err %d", err);
    	// 	return 0;
    	// }
    
    	// LOG_INF("Setting up for packet reception");
    
    	// err = esb_start_rx();
    	// if (err) {
    	// 	LOG_ERR("RX setup failed, err %d", err);
    	// 	return 0;
    	// }
        k_work_schedule(&rx_work, K_MSEC(3000));
    
    	return 0;
    }

Reply
  • We also encountered this issue on NRF52840 (nRF Connect SDK v3.3.0).

    00> [00:11:55.572,296] <err> mpsl_init: MPSL ASSERT: 69, 108[0m
    00> [00:11:55.572,296] <err> os: ***** HARD FAULT *****
    00> [00:11:55.572,296] <err> os:   Fault escalation (see below)
    00> [00:11:55.572,326] <err> os: ARCH_EXCEPT with reason 3
    00> 
    00> [00:11:55.572,357] <err> os: r0/a1:  0x00000003  r1/a2:  0x00000000  r2/a3:  0x00000007
    00> [00:11:55.572,387] <err> os: r3/a4:  0x00000003 r12/ip:  0x2abc7cee r14/lr:  0x0000ee7d
    00> [00:11:55.572,387] <err> os:  xpsr:  0x01000011
    00> [00:11:55.572,418] <err> os: Faulting instruction address (r15/pc): 0x0001b5a0
    00> [00:11:55.572,448] <err> os: >>> ZEPHYR FATAL ERROR 3: Kernel oops on CPU 0
    00> [00:11:55.572,448] <err> os: Fault during interrupt handling
    00> 
    00> [00:11:55.572,509] <err> os: Current thread: 0x20002868 (idle)
    00> [00:11:56.082,794] <err> fatal_error: Resetting system

    No BLE connection.

    /*
     * Copyright (c) 2025 Nordic Semiconductor ASA
     *
     * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
     */
    
    #include <zephyr/bluetooth/bluetooth.h>
    #include <zephyr/bluetooth/conn.h>
    #include <zephyr/bluetooth/gatt.h>
    #include <zephyr/bluetooth/hci.h>
    #include <zephyr/kernel.h>
    #include <zephyr/logging/log.h>
    #include <zephyr/logging/log_ctrl.h>
    #include <zephyr/sys/reboot.h>
    #include <zephyr/random/random.h>
    #include <bluetooth/services/lbs.h>
    #include <dk_buttons_and_leds.h>
    #include <esb.h>
    
    LOG_MODULE_REGISTER(esb_prx_ble, CONFIG_ESB_PRX_BLE_LOG_LEVEL);
    
    #define DEVICE_NAME             CONFIG_BT_DEVICE_NAME "-ESB-PRX"
    #define DEVICE_NAME_LEN         (sizeof(DEVICE_NAME) - 1)
    
    #define CON_STATUS_LED          DK_LED1
    #define USER_LED                DK_LED2
    #define ESB_LED_1               DK_LED3
    #define ESB_LED_2               DK_LED4
    #define USER_BUTTON             DK_BTN1_MSK
    
    static bool app_button_state;
    static struct k_work adv_work;
    
    static struct esb_payload rx_payload;
    static struct esb_payload tx_payload = ESB_CREATE_PAYLOAD(0,
    	0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17);
    
    static bool rx_active = false;
    static void rx_work_handler(struct k_work* work);
    K_WORK_DELAYABLE_DEFINE(rx_work, rx_work_handler);
    
    static const struct bt_data ad[] = {
    	BT_DATA_BYTES(BT_DATA_FLAGS, (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR)),
    	BT_DATA(BT_DATA_NAME_COMPLETE, DEVICE_NAME, DEVICE_NAME_LEN),
    };
    
    static const struct bt_data sd[] = {
    	BT_DATA_BYTES(BT_DATA_UUID128_ALL, BT_UUID_LBS_VAL),
    };
    
    static void esb_err_stat(int err)
    {
        static uint8_t esb_err_count = 0;
        static int err_buf[10] = { 0 };
        if (err) {
            if (esb_err_count >= 10) {
                esb_err_count = 0;
            }
            err_buf[esb_err_count] = err;
            esb_err_count++;
        }
        for (int i = 0; i < 10 && err_buf[i] != 0; i++) {
            LOG_ERR("ESB error buffer[%d] = %d", i, err_buf[i]);
        }
    }
    static void rx_work_handler(struct k_work* work)
    {
        int err;
        static uint8_t start_rx_failed_count = 0;
        if (rx_active) {
            err = esb_stop_rx();
            if (err) {
                LOG_INF("RX stop failed, err %d", err);
            }
    
            uint32_t jitter = sys_rand32_get() % 20;
            k_work_schedule(&rx_work, K_MSEC(40 + jitter));
        } else {
            err = esb_start_rx();
            esb_err_stat(err);
            if (err) {
                start_rx_failed_count++;
                LOG_ERR("RX setup failed %d times, err %d", start_rx_failed_count, err);
                log_panic();
    
                if(start_rx_failed_count >= 30) {
                    sys_reboot(SYS_REBOOT_COLD);
                }
            } else {
                start_rx_failed_count = 0;
            }
            
            k_work_schedule(&rx_work, K_MSEC(14));
        }
        rx_active = !rx_active;
    }
    
    static void adv_work_handler(struct k_work* work)
    {
        int err = bt_le_adv_start(
            BT_LE_ADV_PARAM(BT_LE_ADV_OPT_CONN,
                BT_GAP_ADV_SLOW_INT_MIN,
                BT_GAP_ADV_SLOW_INT_MAX, NULL), ad, ARRAY_SIZE(ad), sd, ARRAY_SIZE(sd));
    
    	if (err) {
    		LOG_ERR("Advertising failed to start (err %d)", err);
    		return;
    	}
    
    	LOG_INF("Advertising successfully started");
    }
    
    static void advertising_start(void)
    {
    	k_work_submit(&adv_work);
    }
    
    static void connected(struct bt_conn *conn, uint8_t err)
    {
    	if (err) {
    		LOG_ERR("Connection failed, err 0x%02x %s", err, bt_hci_err_to_str(err));
    		return;
    	}
    
    	LOG_INF("Connected");
    
    	dk_set_led_on(CON_STATUS_LED);
    }
    
    static void disconnected(struct bt_conn *conn, uint8_t reason)
    {
    	LOG_INF("Disconnected, reason 0x%02x %s", reason, bt_hci_err_to_str(reason));
    
    	dk_set_led_off(CON_STATUS_LED);
    }
    
    static void recycled_cb(void)
    {
    	LOG_INF("Connection object available from previous conn. Disconnect is complete!");
    	advertising_start();
    }
    
    BT_CONN_CB_DEFINE(conn_callbacks) = {
    	.connected        = connected,
    	.disconnected     = disconnected,
    	.recycled         = recycled_cb,
    };
    
    static void app_led_cb(bool led_state)
    {
    	dk_set_led(USER_LED, led_state);
    }
    
    static bool app_button_cb(void)
    {
    	return app_button_state;
    }
    
    static struct bt_lbs_cb lbs_callbacks = {
    	.led_cb    = app_led_cb,
    	.button_cb = app_button_cb,
    };
    
    static void button_changed(uint32_t button_state, uint32_t has_changed)
    {
    	if (has_changed & USER_BUTTON) {
    		uint32_t user_button_state = button_state & USER_BUTTON;
    
    		bt_lbs_send_button_state(user_button_state);
    		app_button_state = user_button_state ? true : false;
    	}
    }
    
    static void leds_update(uint8_t value)
    {
    	const bool led1_state = !(value % 8 > 2 && value % 8 <= 6);
    	const bool led2_state = !(value % 8 > 3);
    
    	dk_set_led(ESB_LED_1, led1_state);
    	dk_set_led(ESB_LED_2, led2_state);
    }
    
    void event_handler(struct esb_evt const *event)
    {
    	int err;
    
    	switch (event->evt_id) {
    	case ESB_EVENT_TX_SUCCESS:
    		LOG_DBG("TX SUCCESS EVENT");
    		break;
    	case ESB_EVENT_TX_FAILED:
    		LOG_DBG("TX FAILED EVENT");
    		break;
    	case ESB_EVENT_RX_RECEIVED:
            while ((err = esb_read_rx_payload(&rx_payload)) == 0) {
                static uint8_t target_buf[3] = { 0x6e, 0x26, 0xb1 };
                if (memcmp(rx_payload.data, target_buf, sizeof(target_buf))) {
                    continue;
                }
                static uint32_t rx_count = 0, last_uptime = 0;
                static uint16_t last_seq_num = 0x8000, missed_count = 0;
                uint16_t new_seq_num = rx_payload.data[6] | (rx_payload.data[5] << 8);
                uint32_t uptime = k_uptime_seconds();
                rx_count++;
                if(new_seq_num  - last_seq_num > 1 && last_seq_num != 0x8000) {
                    missed_count += new_seq_num - last_seq_num - 1;
                    LOG_WRN("Missed %d packets, total missed %d", new_seq_num - last_seq_num - 1, missed_count);
                    LOG_HEXDUMP_WRN(rx_payload.data, rx_payload.length, "New packet data");
                }
                LOG_INF("T:%u, RX %u, last_seq 0x%04x, new_seq 0x%04x, missed %u", uptime, rx_count, last_seq_num, new_seq_num, missed_count);
                last_seq_num = new_seq_num;
    
                static bool last_led_state = false;
                if (uptime - last_uptime > 2) {
                    dk_set_led(DK_LED1, last_led_state);
                    last_led_state = !last_led_state;
                    last_uptime = uptime;
                }
    		}
    		if (err && err != -ENODATA) {
    			LOG_ERR("Error while reading rx packet");
    		}
    		break;
    	case ESB_EVENT_TIMESLOT_FAILED:
    		LOG_ERR("TIMESLOT FAILED EVENT");
    		break;
    	}
    }
    
    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.
    	 */
    	const uint8_t base_addr_0[4] = {0xE7, 0xE7, 0xE7, 0xE7};
    	const uint8_t base_addr_1[4] = {0xC2, 0xC2, 0xC2, 0xC2};
    	const uint8_t addr_prefix[8] = {0xE7, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8};
    
        const struct esb_config config = {
            .protocol           = ESB_PROTOCOL_ESB_DPL,
            .mode               = ESB_MODE_PRX,
            .event_handler      = event_handler,
            .bitrate            = ESB_BITRATE_1MBPS,
            .crc                = ESB_CRC_16BIT,
            .tx_output_power    = ESB_TX_POWER_8DBM,
            .retransmit_delay   = 600,
            .retransmit_count   = 1,
            .tx_mode            = ESB_TXMODE_AUTO,
            .payload_length     = CONFIG_ESB_MAX_PAYLOAD_LENGTH,
            .selective_auto_ack = true,
            .use_fast_ramp_up = IS_ENABLED(CONFIG_ESB_FAST_SWITCHING)
        };
    
    	err = esb_init(&config);
    	if (err) {
    		return err;
        }
        
        err = esb_set_address_length(ARRAY_SIZE(base_addr_0));
        if (err) {
            LOG_ERR("esb set address length failed %d", 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;
    	}
    
        err = esb_set_rf_channel(81);
        if (err) {
            return err;
        }
    
        return 0;
    }
    
    int main(void)
    {
    	int err;
    
        LOG_INF("Build date: %s, build time: %s", __DATE__, __TIME__);
    	// LOG_INF("Starting Enhanced ShockBurst prx with Peripheral LBS sample");
    
    	err = dk_leds_init();
    	if (err) {
    		LOG_ERR("LEDs init failed (err %d)", err);
    		return 0;
    	}
    
    	err = dk_buttons_init(button_changed);
    	if (err) {
    		LOG_ERR("Cannot init buttons (err: %d)", err);
    	}
    
    	err = bt_enable(NULL);
    	if (err) {
    		LOG_ERR("Bluetooth init failed (err %d)", err);
    		return 0;
    	}
    
    	LOG_INF("Bluetooth initialized");
    
    	err = bt_lbs_init(&lbs_callbacks);
    	if (err) {
    		LOG_ERR("Failed to init LBS (err:%d)", err);
    		return 0;
    	}
    
    	k_work_init(&adv_work, adv_work_handler);
    	advertising_start();
    
    	err = esb_initialize();
    	if (err) {
    		LOG_ERR("ESB initialization failed, err %d", err);
    		return 0;
    	}
    
    	// LOG_INF("ESB initialized");
    
    	// err = esb_write_payload(&tx_payload);
    	// if (err) {
    	// 	LOG_ERR("Write payload, err %d", err);
    	// 	return 0;
    	// }
    
    	// LOG_INF("Setting up for packet reception");
    
    	// err = esb_start_rx();
    	// if (err) {
    	// 	LOG_ERR("RX setup failed, err %d", err);
    	// 	return 0;
    	// }
        k_work_schedule(&rx_work, K_MSEC(3000));
    
    	return 0;
    }

Children
Related