nrf_dm sample issues with NRF5340.

Hello.

Im tring use nrf_dm sample with nRF5340 on nRF Connect SDK V2.9.0, with a custom board.

To create build, I use nrf5340dk board.

I got the error when I try dm with other device:

*** Booting nRF Connect SDK v2.9.0-7787b2649840 ***
*** Using Zephyr OS v3.7.99-1f8f3dc29142 ***
[00:00:00.021,240] <inf> remote: Starting Remote Controller

[00:00:00.027,404] <inf> DM_SRV: Starting Distance Measurement sample

[00:00:00.049,621] <inf> bt_hci_core: HW Platform: Nordic Semiconductor (0x0002)
[00:00:00.057,525] <inf> bt_hci_core: HW Variant: nRF53x (0x0003)
[00:00:00.064,117] <inf> bt_hci_core: Firmware: Standard Bluetooth controller (0x00) Version 45.41337 Build 3074452168
[00:00:00.077,575] <inf> bt_hci_core: Identity: DD:15:5D:30:B6:B5 (random)
[00:00:00.084,991] <inf> bt_hci_core: HCI: version 6.0 (0x0e) revision 0x206b, manufacturer 0x0059
[00:00:00.094,482] <inf> bt_hci_core: LMP: version 6.0 (0x0e) subver 0x206b
[00:00:00.101,959] <inf> DM_SRV: DM Bluetooth LE Synchronization initialization

[00:00:06.312,957] <err> os: ***** USAGE FAULT *****
[00:00:06.318,756] <err> os:   Stack overflow (context area not valid)
[00:00:06.326,080] <err> os: r0/a1:  0xed5bb548  r1/a2:  0x719aa156  r2/a3:  0xc962b81b
[00:00:06.334,960] <err> os: r3/a4:  0xbe6eeaee r12/ip:  0x8155a866 r14/lr:  0xc47b98df
[00:00:06.343,811] <err> os:  xpsr:  0x00000000
[00:00:06.349,151] <err> os: s[ 0]:  0x20013948  s[ 1]:  0x00000000  s[ 2]:  0x0000000a  s[ 3]:  0x00000017
[00:00:06.359,924] <err> os: s[ 4]:  0x20072004  s[ 5]:  0x00027461  s[ 6]:  0x20072004  s[ 7]:  0x00000017
[00:00:06.370,666] <err> os: s[ 8]:  0x20072004  s[ 9]:  0x00000200  s[10]:  0x20005898  s[11]:  0x00018f7b
[00:00:06.381,164] <err> os: s[12]:  0x00000400  s[13]:  0x00000400  s[14]:  0x00000000  s[15]:  0x00000017
[00:00:06.391,601] <err> os: fpscr:  0x00000017
[00:00:06.396,820] <err> os: Faulting instruction address (r15/pc): 0x00000001
[00:00:06.404,693] <err> os: >>> ZEPHYR FATAL ERROR 2: Stack overflow on CPU 0
[00:00:06.412,597] <err> os: Current thread: 0x20005d00 (BT RX WQ)
[00:00:06.419,555] <err> os: Halting system
 

my prj.conf:

#
# Copyright (c) 2021 Nordic Semiconductor ASA
#
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
#

# BT
CONFIG_BT=y

CONFIG_BT_CENTRAL=y
CONFIG_BT_PERIPHERAL=y

CONFIG_BT_SCAN=y
CONFIG_BT_SCAN_FILTER_ENABLE=y
CONFIG_BT_SCAN_NAME_CNT=1
CONFIG_BT_SCAN_MANUFACTURER_DATA_CNT=1
CONFIG_BT_SCAN_WITH_IDENTITY=y
CONFIG_BT_ID_MAX=1

# test
CONFIG_BT_LL_SW_SPLIT=y

CONFIG_BT_EXT_ADV=y

CONFIG_BT_DEVICE_NAME="nRF_DM"
CONFIG_BT_DDFS=y

CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=40000

# Distance Measurement
CONFIG_DM_MODULE=y

CONFIG_MPSL=y
CONFIG_MPSL_TIMESLOT_SESSION_COUNT=1

CONFIG_DM_MODULE_LOG_LEVEL_DBG=n
CONFIG_DM_GPIO_DEBUG=y
CONFIG_PWM=y

CONFIG_NCS_SAMPLES_DEFAULTS=y
CONFIG_DK_LIBRARY=y

CONFIG_DM_HIGH_PRECISION_CALC=y

CONFIG_HEAP_MEM_POOL_SIZE=8192

# Main stack
CONFIG_MAIN_STACK_SIZE=8192

# LOG and RTT
CONFIG_LOG=y
CONFIG_CONSOLE=y
CONFIG_RTT_CONSOLE=y
CONFIG_USE_SEGGER_RTT=y
CONFIG_LOG_BACKEND_RTT=y
CONFIG_LOG_MODE_IMMEDIATE=y

# Debug
CONFIG_DEBUG_THREAD_INFO=y
CONFIG_DEBUG=y
CONFIG_DEBUG_OPTIMIZATIONS=y

my cpuapp.conf:

# Distance Measurement
CONFIG_DM_MODULE_RPC=y
CONFIG_DM_MODULE_RPC_CLIENT=y

CONFIG_TEST_RANDOM_GENERATOR=y

# NRF RPC
CONFIG_NRF_RPC_THREAD_POOL_SIZE=2

# Enable the CPUNET core
CONFIG_SOC_NRF53_CPUNET_ENABLE=y

# Clock
CONFIG_CLOCK_CONTROL_NRF_K32SRC_RC=n
CONFIG_CLOCK_CONTROL_NRF_K32SRC_SYNTH=y
CONFIG_CLOCK_CONTROL_NRF_K32SRC_XTAL=n
CONFIG_SOC_ENABLE_LFXO=n
CONFIG_NORDIC_QSPI_NOR=n

my cpunet.conf:

# enable NORA-B12 fem
CONFIG_MPSL=y
CONFIG_MPSL_FEM=y
CONFIG_MPSL_FEM_SIMPLE_GPIO=y
CONFIG_BT_CTLR_TX_PWR_ANTENNA=13

my main.c:

/*
 * Copyright (c) 2021 Nordic Semiconductor ASA
 *
 * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
 */

/** @file
 *  @brief Nordic Distance Measurement sample
 */

#include <stdint.h>
#include <zephyr/kernel.h>
#include <zephyr/sys/printk.h>
#include <zephyr/sys/byteorder.h>

#include <zephyr/bluetooth/bluetooth.h>
#include <bluetooth/scan.h>
#include <bluetooth/services/ddfs.h>

#include <dm.h>
#include "peer.h"
#include "service.h"

#define DEVICE_NAME             CONFIG_BT_DEVICE_NAME
#define DEVICE_NAME_LEN         (sizeof(DEVICE_NAME) - 1)

#define RUN_LED_BLINK_INTERVAL  1000

#define SUPPORT_DM_CODE         0xFF55AA5A

struct adv_mfg_data {
	uint16_t company_code;	    /* Company Identifier Code. */
	uint32_t support_dm_code;   /* To identify the device that supports distance measurement. */
	uint32_t rng_seed;          /* Random seed used for generating hopping patterns. */
} __packed;

static struct adv_mfg_data mfg_data;
struct bt_le_adv_param adv_param_conn =
	BT_LE_ADV_PARAM_INIT(BT_LE_ADV_OPT_CONNECTABLE |
			     BT_LE_ADV_OPT_NOTIFY_SCAN_REQ,
			     BT_GAP_ADV_FAST_INT_MIN_2,
			     BT_GAP_ADV_FAST_INT_MAX_2,
			     NULL);

struct bt_le_adv_param adv_param_noconn =
	BT_LE_ADV_PARAM_INIT(BT_LE_ADV_OPT_USE_IDENTITY |
			     BT_LE_ADV_OPT_SCANNABLE |
			     BT_LE_ADV_OPT_NOTIFY_SCAN_REQ,
			     BT_GAP_ADV_FAST_INT_MIN_2,
			     BT_GAP_ADV_FAST_INT_MAX_2,
			     NULL);


static struct bt_le_adv_param *adv_param = &adv_param_conn;

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(BT_DATA_MANUFACTURER_DATA, (unsigned char *)&mfg_data, sizeof(mfg_data)),
	BT_DATA_BYTES(BT_DATA_UUID128_ALL, BT_UUID_DDFS_VAL),
};

static struct bt_le_scan_param scan_param = {
	.type     = BT_LE_SCAN_TYPE_ACTIVE,
	.interval = BT_GAP_SCAN_FAST_INTERVAL,
	.window   = BT_GAP_SCAN_FAST_WINDOW,
	.options  = BT_LE_SCAN_OPT_NONE,
	.timeout  = 0,
};

static struct bt_scan_init_param scan_init = {
	.connect_if_match = 0,
	.scan_param = &scan_param,
	.conn_param = NULL
};

static uint32_t scanner_random_share;

static struct bt_le_ext_adv *adv;
static void adv_work_handle(struct k_work *item);
static K_WORK_DEFINE(adv_work, adv_work_handle);
static void adv_update_data(void);
static uint32_t scanner_addr_to_random_share(const bt_addr_t *p_scanner_addr);
static uint32_t get_id_addr_random_share(void);

static struct bt_scan_manufacturer_data scan_mfg_data = {
	.data = (unsigned char *)&mfg_data,
	.data_len = sizeof(mfg_data.company_code) + sizeof(mfg_data.support_dm_code),
};

static bool data_cb(struct bt_data *data, void *user_data)
{
	static struct adv_mfg_data *recv_mfg_data;
	static struct dm_request req;

	switch (data->type) {
	case BT_DATA_MANUFACTURER_DATA:
		if (sizeof(struct adv_mfg_data) == data->data_len) {
			recv_mfg_data = (struct adv_mfg_data *)data->data;

			bt_addr_le_copy(&req.bt_addr, user_data);
			req.role = DM_ROLE_INITIATOR;
			req.ranging_mode = peer_ranging_mode_get();
			/* We need to make sure that we only initiate a ranging to a single peer.
			 * A scan response that is received by this device can be received by
			 * multiple other devices which can all start a ranging at the same time
			 * as a consequence. To prevent this, we need to make sure that we set a
			 * per-peer random as the random seed. This helps the ranging library to
			 * avoid interference from other devices trying to range at the same time.
			 *
			 * This means that the initiator and the reflector need to set the same
			 * value for the random seed.
			 */
			req.rng_seed =
				sys_le32_to_cpu(recv_mfg_data->rng_seed) + scanner_random_share;
			req.start_delay_us = 0;
			req.extra_window_time_us = 0;

			dm_request_add(&req);
		}
		return false;
	default:
		return true;
	}
}

static uint32_t get_id_addr_random_share(void)
{
	bt_addr_le_t addrs[CONFIG_BT_ID_MAX];
	size_t count = CONFIG_BT_ID_MAX;

	bt_id_get(addrs, &count);

	__ASSERT(count == 1, "The sample assumes a single ID addr");

	return scanner_addr_to_random_share(&addrs[0].a);
}

static uint32_t scanner_addr_to_random_share(const bt_addr_t *p_scanner_addr)
{
	return (p_scanner_addr->val[0] | p_scanner_addr->val[1] << 8 |
		p_scanner_addr->val[2] << 16 | p_scanner_addr->val[3] << 24) +
	       (p_scanner_addr->val[4] | p_scanner_addr->val[5] << 8);
}

static void scan_filter_match(struct bt_scan_device_info *device_info,
			      struct bt_scan_filter_match *filter_match,
			      bool connectable)
{
	static bt_addr_le_t addr;

	bt_addr_le_copy(&addr, device_info->recv_info->addr);
	peer_supported_add(device_info->recv_info->addr);
	bt_data_parse(device_info->adv_data, data_cb, &addr);
}

BT_SCAN_CB_INIT(scan_cb, scan_filter_match, NULL, NULL, NULL);

static void adv_scanned_cb(struct bt_le_ext_adv *adv,
			struct bt_le_ext_adv_scanned_info *info)
{
	static struct dm_request req;

	if (peer_supported_test(info->addr)) {
		bt_addr_le_copy(&req.bt_addr, info->addr);
		req.role = DM_ROLE_REFLECTOR;
		req.ranging_mode = peer_ranging_mode_get();

		/* We need to make sure that we only initiate a ranging to a single peer.
		 * A scan response from this device can be received by multiple peers which can
		 * all start a ranging at the same time as a consequence. To prevent this,
		 * we need to make sure that we set a per-peer random as the random seed.
		 * This helps the ranging library to avoid interference from other devices
		 * trying to range at the same time.
		 *
		 * This means that the initiator and the reflector need to set the same value
		 * for the random seed.
		 */
		req.rng_seed = peer_rng_seed_get() + scanner_addr_to_random_share(&info->addr->a);
		req.start_delay_us = 0;
		req.extra_window_time_us = 0;

		dm_request_add(&req);
		adv_update_data();
	}
}

const static struct bt_le_ext_adv_cb adv_cb = {
	.scanned = adv_scanned_cb,
};

static void adv_update_data(void)
{
	int err;

	if (!adv) {
		return;
	}
	mfg_data.rng_seed = peer_rng_seed_prepare();
	err = bt_le_ext_adv_set_data(adv, ad, ARRAY_SIZE(ad), sd, ARRAY_SIZE(sd));
	if (err) {
		printk("Failed setting adv data (err %d)\n", err);
	}
}

static int adv_start(void)
{
	int err;
	struct bt_le_ext_adv_start_param ext_adv_start_param = {0};

	if (adv) {
		err = bt_le_ext_adv_stop(adv);
		if (err) {
			printk("Failed to stop extended advertising  (err %d)\n", err);
			return err;
		}
			err = bt_le_ext_adv_delete(adv);
		if (err) {
			printk("Failed to delete advertising set  (err %d)\n", err);
			return err;
		}
	}

	err = bt_le_ext_adv_create(adv_param, &adv_cb, &adv);
	if (err) {
		printk("Failed to create advertising set (err %d)\n", err);
		return err;
	}

	err = bt_le_ext_adv_set_data(adv, ad, ARRAY_SIZE(ad), sd, ARRAY_SIZE(sd));
	if (err) {
		printk("Failed setting adv data (err %d)\n", err);
		return err;
	}

	err = bt_le_ext_adv_start(adv, &ext_adv_start_param);
	if (err) {
		printk("Failed to start extended advertising  (err %d)\n", err);
		return err;
	}

	return err;
}

static int scan_start(void)
{
	int err;

	bt_scan_init(&scan_init);
	bt_scan_cb_register(&scan_cb);

	err = bt_scan_filter_add(BT_SCAN_FILTER_TYPE_MANUFACTURER_DATA, &scan_mfg_data);
	if (err) {
		printk("Scanning filters cannot be set (err %d)\n", err);
		return err;
	}

	err = bt_scan_filter_enable(BT_SCAN_MANUFACTURER_DATA_FILTER, false);
	if (err) {
		printk("Filters cannot be turned on (err %d)\n", err);
		return err;
	}

	scanner_random_share = get_id_addr_random_share();

	err = bt_scan_start(BT_SCAN_TYPE_SCAN_ACTIVE);
	if (err) {
		printk("Scanning failed to start (err %d)\n", err);
		return err;
	}

	return err;
}

static void adv_work_handle(struct k_work *item)
{
	adv_start();
}

static void connected(struct bt_conn *conn, uint8_t conn_err)
{
	adv_param = &adv_param_noconn;
	k_work_submit(&adv_work);
}

static void disconnected(struct bt_conn *conn, uint8_t reason)
{
	adv_param = &adv_param_conn;
	k_work_submit(&adv_work);
}

BT_CONN_CB_DEFINE(conn_callbacks) = {
	.connected = connected,
	.disconnected = disconnected,
};

static int bt_sync_init(void)
{
	/* Synchronisation is based on advertising and scanning modes.
	 * It occurs when SCAN_REQ and SCAN_RESP packets are exchanged.
	*/
	int err;

	printk("DM Bluetooth LE Synchronization initialization\n");

	mfg_data.company_code = sys_cpu_to_le16(CONFIG_BT_COMPANY_ID_NORDIC);
	mfg_data.support_dm_code = sys_cpu_to_le32(SUPPORT_DM_CODE);
	mfg_data.rng_seed = sys_cpu_to_le32(peer_rng_seed_prepare());

	err = adv_start();
	if (err) {
		printk("Failed to start advertising (err %d)\n", err);
		return err;
	}

	err = scan_start();
	if (err) {
		printk("Failed to start scanning (err %d)\n", err);
	}

	return err;
}

static void data_ready(struct dm_result *result)
{
	if (result->status) {
		peer_update(result);
	}
}

static struct dm_cb dm_cb = {
	.data_ready = data_ready,
};

int main(void)
{
	int err;
	static struct dm_init_param init_param;

	printk("Starting Distance Measurement example\n");

	err = peer_init();
	if (err) {
		printk("Peer init failed (err %d)\n", err);
		return 0;
	}

	init_param.cb = &dm_cb;

	err = dm_init(&init_param);
	if (err) {
		printk("Distance measurement init failed (err %d)\n", err);
		return 0;
	}

	err = service_ddfs_init();
	if (err) {
		printk("DDF Service init failed (err %d)\n", err);
		return 0;
	}

	err = bt_enable(NULL);
	if (err) {
		printk("Bluetooth init failed (err %d)\n", err);
		return 0;
	}

	err = bt_sync_init();
	if (err) {
		printk("Synchronisation init failed (err %d)\n", err);
		return 0;
	}

	for (;;) {
		k_sleep(K_MSEC(RUN_LED_BLINK_INTERVAL));
		service_azimuth_elevation_simulation();
	}
}

Someone can help me? Tanks a lot.

Parents
  • Hi

    When you build a project sample for a custom board it's important that you make changes to it so that it matches the actual custom board HW configurations. You can only use the DK as a template, and should change it according to any changes you have in your HW.

    The most common issue is that you don't have an external 32.768kHz crystal on your custom board, since this is optional, but then you need to configure the project to use the internal RC oscillator instead. However this is only guesswork since I don't know how your custom board looks. I'd recommend we start with a HW review so we can make sure the custom board looks okay and that there aren't any glaring issues there. I've set this case to private mode so you can share schematics and gerber files here. That way only yourself and Nordic employees will be able to view its contents.

    It would also be helpful to know what the "other distance measurement device" you're trying to connect to here is exactly. The error message points to a stack overflow somewhere so you can try to increase your stack sizes ( CONFIG_MAIN_STACK_SIZE and CONFIG_HEAP_MEM_POOL_SIZE.

    Best regards,

    Simon

Reply
  • Hi

    When you build a project sample for a custom board it's important that you make changes to it so that it matches the actual custom board HW configurations. You can only use the DK as a template, and should change it according to any changes you have in your HW.

    The most common issue is that you don't have an external 32.768kHz crystal on your custom board, since this is optional, but then you need to configure the project to use the internal RC oscillator instead. However this is only guesswork since I don't know how your custom board looks. I'd recommend we start with a HW review so we can make sure the custom board looks okay and that there aren't any glaring issues there. I've set this case to private mode so you can share schematics and gerber files here. That way only yourself and Nordic employees will be able to view its contents.

    It would also be helpful to know what the "other distance measurement device" you're trying to connect to here is exactly. The error message points to a stack overflow somewhere so you can try to increase your stack sizes ( CONFIG_MAIN_STACK_SIZE and CONFIG_HEAP_MEM_POOL_SIZE.

    Best regards,

    Simon

Children
No Data
Related