NRF54L15 wedging when starting BLE advertising, peripheral_uart sample

Hi,

I'm working on software for a design incorporating an Ezurio module that uses an NRF54L15 chip.

I'm currently using the peripheral_uart example as a base for early experimentation, but the main() function code doesn't seem to be getting past advertising_start() function, it seems to end up wedged, I think mostly because the higher priority sysworkq task is erroring deep within bt_le_adv_start() from adv.c, ultimately ending with error -5 / EIO, and getting stuck in some sort of constant retry loop that prevents the main task ever getting any more cycles (or at least, other stuff in general to do with advertising in other tasks is taking up all the CPU time).

I think I've obviously got some sort of configuration error somewhere, probably from my cack-handed attempts at all this device tree and kconfig stuff, which I'm not entirely used to. I mostly based the device tree on the ezurio dev kit sample board in the zephyr github (at the moment the released sdk doesn't seem to have it, the perils of using new hardware), pruned to the basics. I suspect I've probably just pruned out some prerequisite peripheral somewhere, and it would be useful to have pointers to anything obvious I've missed.

I'm using the VScode based Nordic SDK stuff v3.0.2 on Windows 10, and a Segger J-link Plus as a debugger. The connected devices panel says the module uses a xxAA_ENGB stepping of the chip.

Extra Kconfig fragments:

CONFIG_CACHE_MANAGEMENT=y
CONFIG_HW_STACK_PROTECTION=y
CONFIG_GPIO=y
CONFIG_SERIAL=y
CONFIG_LOG=y
CONFIG_ASSERT=y
CONFIG_CONSOLE=y
CONFIG_BT_NUS=y
CONFIG_HEAP_MEM_POOL_SIZE=2048
CONFIG_BT_PERIPHERAL=y
#CONFIG_BT_SETTINGS=n
CONFIG_BT_MAX_PAIRED=1
CONFIG_BT_DEVICE_NAME="Shenanigans"
CONFIG_PARTITION_MANAGER_ENABLED=y
CONFIG_USE_SEGGER_RTT=y
CONFIG_ARM_MPU=y
CONFIG_EXTERNAL_CACHE=y
CONFIG_FLASH=y
#CONFIG_CLOCK_CONTROL_NRF_K32SRC_SYNTH=y
CONFIG_CLOCK_CONTROL_NRF_K32SRC_RC=y
CONFIG_CLOCK_CONTROL_NRF_K32SRC_RC_CALIBRATION=y
CONFIG_UART_CONSOLE=y
CONFIG_UART_ASYNC_API=y
CONFIG_BT=y
CONFIG_DEBUG_THREAD_INFO=y
CONFIG_LOG_PRINTK=n
CONFIG_LOG_BACKEND_UART=n
CONFIG_LOG_BACKEND_RTT=y
CONFIG_FLASH_MAP=y
CONFIG_DEBUG_OPTIMIZATIONS=y
CONFIG_BT_NUS_SECURITY_ENABLED=n
CONFIG_NRF_GRTC_START_SYSCOUNTER=y

Device tree:

/dts-v1/;
#include <nordic/nrf54l15_cpuapp.dtsi>
#include "testdevicev1-pinctrl.dtsi"

/ {
	model = "Foobar Test Device";
	compatible = "foobar,testdevicev1-cpuapp";

	chosen {
		zephyr,code-partition = &slot0_partition;
		zephyr,sram = &cpuapp_sram;
		zephyr,console = &uart20;
		zephyr,shell-uart = &uart20;
		zephyr,uart-mcumgr = &uart20;
		zephyr,bt-mon-uart = &uart20;
		zephyr,bt-c2h-uart = &uart20;
		zephyr,flash-controller = &rram_controller;
		zephyr,flash = &cpuapp_rram;
		zephyr,ieee802154 = &ieee802154;
	};
};

&cpuapp_sram {
	status = "okay";
};

&grtc {
	owned-channels = <0 1 2 3 4 5 6 7 8 9 10 11>;
	/* Channels 7-11 reserved for Zero Latency IRQs, 3-4 for FLPR */
	child-owned-channels = <3 4 7 8 9 10 11>;
	status = "okay";
};

&cpuapp_rram {
	partitions {
		compatible = "fixed-partitions";
		#address-cells = <1>;
		#size-cells = <1>;
		boot_partition: partition@0 {
			label = "mcuboot";
			reg = <0x0 DT_SIZE_K(64)>;
		};
		slot0_partition: partition@10000 {
			label = "image-0";
			reg = <0x10000 DT_SIZE_K(324)>;
		};
		slot0_ns_partition: partition@61000 {
			label = "image-0-nonsecure";
			reg = <0x61000 DT_SIZE_K(324)>;
		};
		slot1_partition: partition@b2000 {
			label = "image-1";
			reg = <0xb2000 DT_SIZE_K(324)>;
		};
		slot1_ns_partition: partition@103000 {
			label = "image-1-nonsecure";
			reg = <0x103000 DT_SIZE_K(324)>;
		};
		/* 32k from 0x154000 to 0x15bfff reserved for TF-M partitions */
		storage_partition: partition@15c000 {
			label = "storage";
			reg = <0x15c000 DT_SIZE_K(36)>;
		};
	};
};

&gpiote20 {
	status = "disabled";
};

&uart20 {
	current-speed = <115200>;
	pinctrl-0 = <&uart20_default>;
	pinctrl-names = "default";
	hw-flow-control;
	status = "okay";
};

&uicr {
	status = "okay";
};

&gpiote30 {
	status = "okay";
};

&power {
	status = "disabled";
};

&regulators {
	status = "okay";
};

&lfxo {
 	load-capacitors = "internal";
 	load-capacitance-femtofarad = <15500>;
 };

&hfxo {
	load-capacitors = "internal";
	load-capacitance-femtofarad = <15000>;
};

&gpio1 {
	status = "disabled";
};

&gpio2 {
	status = "okay";
};

&pinctrl {
	uart20_default: uart20_default {
		group1 {
			psels = <NRF_PSEL(UART_TX, 2, 2)>,
					<NRF_PSEL(UART_RX, 2, 0)>,
					<NRF_PSEL(UART_RTS, 2, 5)>,
					<NRF_PSEL(UART_CTS, 2, 4)>;
		};
	};
};

&temp {
	status = "okay";
};

&egu10 {
	status = "okay";
};


&vregmain {
	status = "okay";
	regulator-initial-mode = <NRF5X_REG_MODE_DCDC>;
};


&radio {
	status = "okay";
};

&ieee802154 {
	status = "okay";
};

&uart20 {
	status = "okay";
};

&clock {
	status = "okay";
};

&lfxo {
	status = "okay";
};

&cpuapp_systick {
	status = "okay";
};

The sample was edited to comment out the non-existent buttons / LEDs, but is otherwise just the basic sample.

Thank You,

Peter Davis

Parents
  • Hi!

    So advertising_start() is returning -5, correct ?

  • I don't think advertising_start() ever returns, the main task seems to halt in the k_work_submit, I suspect something it causing other tasks to take priority and never return control back to the main task:

    arch_swap(unsigned int key) (c:\ncs\v3.0.2\zephyr\arch\arm\include\cortex_m\kernel_arch_func.h:102)
    z_swap_irqlock(unsigned int key) (c:\ncs\v3.0.2\zephyr\kernel\include\kswap.h:208)
    z_reschedule_irqlock(uint32_t key) (c:\ncs\v3.0.2\zephyr\kernel\sched.c:747)
    z_reschedule_unlocked() (c:\ncs\v3.0.2\zephyr\include\zephyr\arch\arm\asm_inline_gcc.h:72)
    k_work_submit_to_queue(struct k_work_q * queue, struct k_work * work) (c:\ncs\v3.0.2\zephyr\kernel\work.c:403)
    k_work_submit(struct k_work * work) (c:\ncs\v3.0.2\zephyr\kernel\work.c:415)
    advertising_start() (d:\etc\src\main.c:354)
    main() (d:\etc\src\main.c:664)

    I seem to be stuck with a repeating loop of the sysworkq task trying to enable advertising, getting around here:

    bt_hci_cmd_send_sync(uint16_t opcode, struct net_buf * buf, struct net_buf ** rsp) (c:\ncs\v3.0.2\zephyr\subsys\bluetooth\host\hci_core.c:446)
    bt_le_adv_set_enable_legacy(struct bt_le_ext_adv * adv, _Bool enable) (c:\ncs\v3.0.2\zephyr\subsys\bluetooth\host\adv.c:338)
    bt_le_adv_set_enable(struct bt_le_ext_adv * adv, _Bool enable) (c:\ncs\v3.0.2\zephyr\subsys\bluetooth\host\adv.c:388)
    bt_le_adv_start_legacy(struct bt_le_ext_adv * adv, const struct bt_le_adv_param * param, const struct bt_data * ad, size_t ad_len, const struct bt_data * sd, size_t sd_len) (c:\ncs\v3.0.2\zephyr\subsys\bluetooth\host\adv.c:1079)
    bt_le_adv_start(const struct bt_le_adv_param * param, const struct bt_data * ad, size_t ad_len, const struct bt_data * sd, size_t sd_len) (c:\ncs\v3.0.2\zephyr\subsys\bluetooth\host\adv.c:1412)
    adv_work_handler(struct k_work * work) (d:\etc\src\main.c:342)
    work_queue_main(void * workq_ptr, void * p2, void * p3) (c:\ncs\v3.0.2\zephyr\kernel\work.c:684)
    z_thread_entry(k_thread_entry_t entry, void * p1, void * p2, void * p3) (c:\ncs\v3.0.2\zephyr\lib\os\thread_entry.c:48)
    z_thread_entry(k_thread_entry_t entry, void * p1, void * p2, void * p3) (c:\ncs\v3.0.2\zephyr\lib\os\thread_entry.c:48)

    It appears that we error out trying to enable advertising, "opcode 0x200a, status 0xac", which seems to be the correct HCI opcode for LE advertising, but not a valid status code??? This is then turned into the -EIO / -5 that I seem percolating back through the sysworkq call stack..

Reply Children
  • Had another look, found that a different sample (multiple_adv_set) worked with the same board files, then I realised at some point I'd contrived to delete part of a line in C:\ncs\v3.0.2\nrf\subsys\bluetooth\controller\hci_internal.c changing return sdc_hci_cmd_le_set_adv_enable((void *)cmd_params); to return ((void *)cmd_params); which well, broke everything. I'm not sure how I managed that, I suspect it got fat fingered when I was trying to figure out some of the other stuff. Guess I need to remember the SDK files aren't write protected....

    I've probably wasted a few peoples time with all this fuss, so thank you for helping out trying to answer the queries and so on. Hopefully I won't have as much trouble now...

Related