Hello, I have 2 PCBs for drone communication using nRF52820 and nRF21540 FEM module. I'm using the ESB protocol to communicate via radio. There are ready-made esb_prx and esb_ptx codes provided by nRF Connect. Additionally, my PCB has an external 32MHz clock. I'm providing all my code below: DTS, prjconfig, main. Currently, I cannot establish communication.What is the problem?
/* * Copyright (c) 2018 Nordic Semiconductor ASA * * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause */ #include <zephyr/drivers/clock_control.h> #include <zephyr/drivers/clock_control/nrf_clock_control.h> #if defined(NRF54L15_XXAA) #include <hal/nrf_clock.h> #endif /* defined(NRF54L15_XXAA) */ #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 <dk_buttons_and_leds.h> #if defined(CONFIG_CLOCK_CONTROL_NRF2) #include <hal/nrf_lrcconf.h> #endif LOG_MODULE_REGISTER(esb_ptx, CONFIG_ESB_PTX_APP_LOG_LEVEL); static bool ready = true; static struct esb_payload rx_payload; static struct esb_payload tx_payload = ESB_CREATE_PAYLOAD(0, 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_DBG("TX SUCCESS EVENT"); break; case ESB_EVENT_TX_FAILED: LOG_DBG("TX FAILED EVENT"); break; case ESB_EVENT_RX_RECEIVED: while (esb_read_rx_payload(&rx_payload) == 0) { LOG_DBG("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; } } #if defined(CONFIG_CLOCK_CONTROL_NRF) 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_ERR("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_ERR("Clock request failed: %d", err); return err; } do { err = sys_notify_fetch_result(&clk_cli.notify, &res); if (!err && res) { LOG_ERR("Clock could not be started: %d", res); return res; } } while (err); #if defined(NRF54L15_XXAA) /* MLTPAN-20 */ nrf_clock_task_trigger(NRF_CLOCK, NRF_CLOCK_TASK_PLLSTART); #endif /* defined(NRF54L15_XXAA) */ LOG_DBG("HF clock started"); return 0; } #elif defined(CONFIG_CLOCK_CONTROL_NRF2) int clocks_start(void) { int err; int res; const struct device *radio_clk_dev = DEVICE_DT_GET_OR_NULL(DT_CLOCKS_CTLR(DT_NODELABEL(radio))); struct onoff_client radio_cli; /** Keep radio domain powered all the time to reduce latency. */ nrf_lrcconf_poweron_force_set(NRF_LRCCONF010, NRF_LRCCONF_POWER_DOMAIN_1, true); sys_notify_init_spinwait(&radio_cli.notify); err = nrf_clock_control_request(radio_clk_dev, NULL, &radio_cli); do { err = sys_notify_fetch_result(&radio_cli.notify, &res); if (!err && res) { LOG_ERR("Clock could not be started: %d", res); return res; } } while (err == -EAGAIN); nrf_lrcconf_clock_always_run_force_set(NRF_LRCCONF000, 0, true); nrf_lrcconf_task_trigger(NRF_LRCCONF000, NRF_LRCCONF_TASK_CLKSTART_0); LOG_DBG("HF clock started"); return 0; } #else BUILD_ASSERT(false, "No Clock Control driver"); #endif /* defined(CONFIG_CLOCK_CONTROL_NRF2) */ 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; if (IS_ENABLED(CONFIG_ESB_FAST_SWITCHING)) { config.use_fast_ramp_up = 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; } static void leds_update(uint8_t value) { uint32_t leds_mask = (!(value % 8 > 0 && value % 8 <= 4) ? DK_LED1_MSK : 0) | (!(value % 8 > 1 && value % 8 <= 5) ? DK_LED2_MSK : 0) | (!(value % 8 > 2 && value % 8 <= 6) ? DK_LED3_MSK : 0) | (!(value % 8 > 3) ? DK_LED4_MSK : 0); dk_set_leds(leds_mask); } int main(void) { int err; LOG_INF("Enhanced ShockBurst ptx sample"); err = clocks_start(); if (err) { return 0; } err = dk_leds_init(); if (err) { LOG_ERR("LEDs initialization failed, err %d", err); return 0; } err = esb_initialize(); if (err) { LOG_ERR("ESB initialization failed, err %d", err); return 0; } LOG_INF("Initialization complete"); LOG_INF("Sending test packet"); tx_payload.noack = false; while (1) { if (ready) { ready = false; esb_flush_tx(); leds_update(tx_payload.data[1]); err = esb_write_payload(&tx_payload); if (err) { LOG_ERR("Payload write failed, err %d", err); } tx_payload.data[1]++; } k_sleep(K_MSEC(100)); } }
/* * Copyright (c) 2018 Nordic Semiconductor ASA * * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause */ #include <zephyr/device.h> #include <zephyr/devicetree.h> #include <zephyr/drivers/clock_control.h> #include <zephyr/drivers/clock_control/nrf_clock_control.h> #if defined(NRF54L15_XXAA) #include <hal/nrf_clock.h> #endif /* defined(NRF54L15_XXAA) */ #include <zephyr/drivers/gpio.h> #include <zephyr/irq.h> #include <zephyr/logging/log.h> #include <nrf.h> #include <esb.h> #include <zephyr/kernel.h> #include <zephyr/types.h> #include <dk_buttons_and_leds.h> #if defined(CONFIG_CLOCK_CONTROL_NRF2) #include <hal/nrf_lrcconf.h> #endif LOG_MODULE_REGISTER(esb_prx, CONFIG_ESB_PRX_APP_LOG_LEVEL); 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 void leds_update(uint8_t value) { uint32_t leds_mask = (!(value % 8 > 0 && value % 8 <= 4) ? DK_LED1_MSK : 0) | (!(value % 8 > 1 && value % 8 <= 5) ? DK_LED2_MSK : 0) | (!(value % 8 > 2 && value % 8 <= 6) ? DK_LED3_MSK : 0) | (!(value % 8 > 3) ? DK_LED4_MSK : 0); dk_set_leds(leds_mask); } void event_handler(struct esb_evt const *event) { 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: if (esb_read_rx_payload(&rx_payload) == 0) { LOG_DBG("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]); leds_update(rx_payload.data[1]); } else { LOG_ERR("Error while reading rx packet"); } break; } } #if defined(CONFIG_CLOCK_CONTROL_NRF) 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_ERR("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_ERR("Clock request failed: %d", err); return err; } do { err = sys_notify_fetch_result(&clk_cli.notify, &res); if (!err && res) { LOG_ERR("Clock could not be started: %d", res); return res; } } while (err); #if defined(NRF54L15_XXAA) /* MLTPAN-20 */ nrf_clock_task_trigger(NRF_CLOCK, NRF_CLOCK_TASK_PLLSTART); #endif /* defined(NRF54L15_XXAA) */ LOG_DBG("HF clock started"); return 0; } #elif defined(CONFIG_CLOCK_CONTROL_NRF2) int clocks_start(void) { int err; int res; const struct device *radio_clk_dev = DEVICE_DT_GET_OR_NULL(DT_CLOCKS_CTLR(DT_NODELABEL(radio))); struct onoff_client radio_cli; /** Keep radio domain powered all the time to reduce latency. */ nrf_lrcconf_poweron_force_set(NRF_LRCCONF010, NRF_LRCCONF_POWER_DOMAIN_1, true); sys_notify_init_spinwait(&radio_cli.notify); err = nrf_clock_control_request(radio_clk_dev, NULL, &radio_cli); do { err = sys_notify_fetch_result(&radio_cli.notify, &res); if (!err && res) { LOG_ERR("Clock could not be started: %d", res); return res; } } while (err == -EAGAIN); nrf_lrcconf_clock_always_run_force_set(NRF_LRCCONF000, 0, true); nrf_lrcconf_task_trigger(NRF_LRCCONF000, NRF_LRCCONF_TASK_CLKSTART_0); LOG_DBG("HF clock started"); return 0; } #else BUILD_ASSERT(false, "No Clock Control driver"); #endif /* defined(CONFIG_CLOCK_CONTROL_NRF2) */ 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.bitrate = ESB_BITRATE_2MBPS; config.mode = ESB_MODE_PRX; config.event_handler = event_handler; config.selective_auto_ack = true; if (IS_ENABLED(CONFIG_ESB_FAST_SWITCHING)) { config.use_fast_ramp_up = 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; } int main(void) { int err; LOG_INF("Enhanced ShockBurst prx sample"); err = clocks_start(); if (err) { return 0; } err = dk_leds_init(); if (err) { LOG_ERR("LEDs initialization failed, err %d", err); return 0; } err = esb_initialize(); if (err) { LOG_ERR("ESB initialization failed, err %d", err); return 0; } LOG_INF("Initialization complete"); err = esb_write_payload(&tx_payload); if (err) { LOG_ERR("Write payload, err %d", err); return 0; } LOG_INF("Setting up for packet receiption"); err = esb_start_rx(); if (err) { LOG_ERR("RX setup failed, err %d", err); return 0; } /* return to idle thread */ return 0; }
/dts-v1/; #include <nordic/nrf52820_qdaa.dtsi> #include "TST-pinctrl.dtsi" / { model = "testing"; compatible = "BY,TST"; chosen { zephyr,sram = &sram0; zephyr,flash = &flash0; zephyr,code-partition = &slot0_partition; zephyr,console = &cdc_acm_uart0; zephyr,shell-uart = &cdc_acm_uart0; zephyr,uart-mcumgr = &cdc_acm_uart0; }; nrf_radio_fem: nrf21540_fem { compatible = "nordic,nrf21540-fem"; tx-en-gpios = <&gpio0 17 GPIO_ACTIVE_HIGH>; rx-en-gpios = <&gpio0 16 GPIO_ACTIVE_HIGH>; pdn-gpios = <&gpio0 8 GPIO_ACTIVE_HIGH>; mode-gpios = <&gpio0 29 GPIO_ACTIVE_HIGH>; spi-if = <&nrf_radio_fem_spi>; supply-voltage-mv = <3300>; tx-en-settle-time-us = <13>; rx-en-settle-time-us = <13>; pdn-settle-time-us = <18>; trx-hold-time-us = <5>; }; leds { compatible = "gpio-leds"; led0: led_0 { gpios = <&gpio0 28 GPIO_ACTIVE_HIGH>; label = "Green LED 0"; }; led1: led_1 { gpios = <&gpio0 30 GPIO_ACTIVE_HIGH>; label = "Green LED 1"; }; }; aliases { led0 = &led0; led1 = &led1; }; }; &flash0 { partitions { compatible = "fixed-partitions"; #address-cells = <1>; #size-cells = <1>; boot_partition: partition@0 { label = "mcuboot"; reg = <0x00000000 DT_SIZE_K(48)>; }; slot0_partition: partition@c000 { label = "image-0"; reg = <0x0000c000 DT_SIZE_K(92)>; }; slot1_partition: partition@23000 { label = "image-1"; reg = <0x00023000 DT_SIZE_K(92)>; }; storage_partition: partition@3a000 { label = "storage"; reg = <0x0003a000 DT_SIZE_K(24)>; }; }; }; &gpiote { status = "okay"; }; &gpio0 { status = "okay"; }; &clock { status = "okay"; }; zephyr_udc0: &usbd { compatible = "nordic,nrf-usbd"; status = "okay"; }; &usbd { cdc_acm_uart0: cdc_acm_uart0 { compatible = "zephyr,cdc-acm-uart"; label = "CDC_ACM_0"; }; }; &spi1 { compatible = "nordic,nrf-spi"; status = "okay"; pinctrl-0 = <&spi1_default>; pinctrl-1 = <&spi1_sleep>; pinctrl-names = "default", "sleep"; cs-gpios = <&gpio0 2 GPIO_ACTIVE_LOW>; nrf_radio_fem_spi: nrf21540_fem_spi@0 { compatible = "nordic,nrf21540-fem-spi"; status = "okay"; reg = <0>; spi-max-frequency = <8000000>; spi-cpol; spi-cpha; }; }; &radio { fem = <&nrf_radio_fem>; status = "okay"; };
# # Copyright (c) 2019 Nordic Semiconductor ASA # # SPDX-License-Identifier: LicenseRef-Nordic-5-Clause # CONFIG_NCS_SAMPLES_DEFAULTS=y CONFIG_ESB=y CONFIG_DK_LIBRARY=y CONFIG_CLOCK_CONTROL=y CONFIG_CLOCK_CONTROL_NRF_K32SRC_SYNTH=y CONFIG_CLOCK_CONTROL_NRF_K32SRC_XTAL=n CONFIG_CLOCK_CONTROL_NRF_K32SRC_RC=n CONFIG_MPSL=y CONFIG_MPSL_FEM=y CONFIG_MPSL_FEM_NRF21540_GPIO_SPI=y CONFIG_USE_SEGGER_RTT=y CONFIG_RTT_CONSOLE=y CONFIG_LOG=y CONFIG_LOG_BACKEND_RTT=y CONFIG_LOG_DEFAULT_LEVEL=2