nrf52840dongle reboot when push notification to central in gpio callback

I using NCS V2.1.2 toolchain and two nrf52840_dongle and following this tutorial: https://webinars.nordicsemi.com/developing-bluetooth-low-energy-6

First dongle follow the code on tutorial and second dongle using nrf connect desktop bluetooth low energy.

Because using dongle instead of nrf52840-DK i was implement USB CDC ACM console follow example code (for debug), it work well and i can get log information on nRF Terminal .

For button pressed function i add to gpio callback, when press button variable btn_count increase then send to desktop bluetooth app

If i do not enable notification on desktop bluetooth app, i can send data by press button on first dongle then pressing read button on desktop bluetooth app, i can send data back from desktop bluetooth app to peripheral (the first dongle) like tutorial does. 

But, when i enable notification on desktop bluetooth app then press button on peripheral it will reboot immediate, i still can send data from desktop bluetooth app to peripheral normal, only reboot when press button and enable notification.

if i put  this code in while of main:

k_sleep(K_SECONDS(1));
btn_count++;
send_button_notification(current_conn, btn_count, 1);
then enable notification on desktop bluetooth app, it work normal. 
all main.c in here 
#include <zephyr/zephyr.h>
#include <zephyr/sys/printk.h>
#include <zephyr/usb/usb_device.h>
#include <zephyr/drivers/uart.h>

#include <logging/log.h>
#include <zephyr/drivers/gpio.h>

#include "remote.h"

BUILD_ASSERT(DT_NODE_HAS_COMPAT(DT_CHOSEN(zephyr_console), zephyr_cdc_acm_uart),
	     "Console device is not ACM CDC UART device");

#define LED0_NODE 	DT_ALIAS(led0)
#define SW0_NODE	DT_ALIAS(sw0)

static const struct gpio_dt_spec led = GPIO_DT_SPEC_GET(LED0_NODE, gpios);
static const struct gpio_dt_spec led1_blue = GPIO_DT_SPEC_GET_OR(DT_ALIAS(led3), gpios, {0});

static const struct gpio_dt_spec button = GPIO_DT_SPEC_GET_OR(SW0_NODE, gpios, {0});
// static struct gpio_dt_spec button = GPIO_DT_SPEC_GET(DT_ALIAS(sw0), gpios); //OK 

static struct gpio_callback button_cb_data;

uint8_t btn_count=0;

#define LOG_MODULE_NAME app
LOG_MODULE_REGISTER(LOG_MODULE_NAME, LOG_LEVEL_DBG);

struct bt_conn *current_conn;

void on_connected(struct bt_conn *conn, uint8_t err);
void on_disconnected(struct bt_conn *conn, uint8_t reason);
void on_notif_changed(enum bt_button_notifications_enabled status);
void on_data_received(struct bt_conn *conn, const uint8_t *const data, uint16_t len);

struct bt_conn_cb bluetooth_callbacks = {
	.connected		    = on_connected,
	.disconnected   	= on_disconnected,
	// .le_param_req		= le_param_req,
	// .le_param_updated	= le_param_updated
};

struct bt_remote_service_cb remote_callbacks = {
	.notif_changed = on_notif_changed,
	.data_received = on_data_received,
};

void on_connected(struct bt_conn *conn, uint8_t err){
	struct bt_conn_info info;

	if(err){
		LOG_INF("connection err %d", err);
		return;
	}

	LOG_INF("Connected OK");
	current_conn = bt_conn_ref(conn);
	gpio_pin_set(led.port, led.pin, 1); //on led
}

void on_disconnected (struct bt_conn *conn, uint8_t reason){
	LOG_INF("On disconnected, reason %d", reason);
	if (current_conn){
		bt_conn_unref(current_conn);
		current_conn = NULL;
	}
	gpio_pin_set_dt(&led, 0); //off led 
}

void on_notif_changed(enum bt_button_notifications_enabled status){
	if (status == BT_BUTTON_NOTIFICATIONS_ENABLED){
		LOG_INF("Notification enabled");
	} else {
		LOG_INF("Notifications disable");
	}
}

void on_data_received(struct bt_conn *conn, const uint8_t *const data, uint16_t len)
{
	uint8_t temp_str[len+1];
	memcpy(temp_str, data, len);
	temp_str[len] = 0x00;

	LOG_INF("Received data on conn %p. Len: %d", (void *)conn, len);
	LOG_INF("Data: %s", temp_str);
}

void button_pressed(const struct device *dev, struct gpio_callback *cb, uint32_t pins) {
	int err=0;
	uint32_t bit_to_pin = 0;
	for (int i = 0; i < 32; i++) {
		if ((pins >> i) == 1) {
			bit_to_pin = i;
			break;
		}
	}
	// printk("Button pressed at %" PRIu32 "\n", k_cycle_get_32()); //CDC ACM OK 
	
	gpio_pin_toggle(led.port, led.pin); //OK 
	btn_count++;
	LOG_INF("Button %d pressed %d", bit_to_pin, btn_count);
	set_button_value(btn_count);

	err = send_button_notification(current_conn, btn_count, 1);
	if (err){
		LOG_ERR("couldn't send notification, err: %d", err);
	}
}

void main(void)
{
	int ret, err;
	if (!device_is_ready(led.port)) return;
	if (!device_is_ready(led1_blue.port)) {
		return;
	}
	ret = gpio_pin_configure_dt(&led, GPIO_OUTPUT_INACTIVE); //init low 
	if (ret < 0) return;
	gpio_pin_configure_dt(&led1_blue, GPIO_OUTPUT);

	/* USB CDC ACM */
	const struct device *dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_console));
	uint32_t dtr = 0;
	if (usb_enable(NULL)) {
		return;
	}
	/* Poll if the DTR flag was set, chỗ này sẽ đợi mở terminal mới thực hiện tiếp */
	while (!dtr) {
	 	uart_line_ctrl_get(dev, UART_LINE_CTRL_DTR, &dtr);
	 	/* Give CPU resources to low priority threads. */
		k_sleep(K_MSEC(100));
	}
	/*************** end CDC ACM ***************/
	
	LOG_INF("Hello CDC ACM BLE from: %s\n", CONFIG_BOARD);
	
	if (!device_is_ready(button.port)) {
		LOG_ERR("Error: button device %s is not ready\n",
		       button.port->name);
		k_sleep(K_MSEC(5000));
		return;
	}
	ret = gpio_pin_configure_dt(&button, GPIO_INPUT | GPIO_PULL_UP); 
	ret = gpio_pin_interrupt_configure_dt(&button, GPIO_INT_EDGE_RISING); 
	gpio_init_callback(&button_cb_data, button_pressed, BIT(button.pin)); 
	gpio_add_callback(button.port, &button_cb_data); 

	/* 
		
	 */
	err = bluetooth_init(&bluetooth_callbacks, &remote_callbacks);
	if (err){
		LOG_ERR("Bluetooth returned %d", err);
	}

	LOG_INF("RUNNING");

	while (1) {
		// printk("Hello World! %s\n", CONFIG_ARCH);
		k_sleep(K_SECONDS(1));
		// k_sleep(K_MSEC(300));
		// btn_count++;
		// send_button_notification(current_conn, btn_count, 1);

		gpio_pin_toggle_dt(&led1_blue);	
	}
}
Parents
  • Hello,

    Because using dongle instead of nrf52840-DK i was implement USB CDC ACM console follow example code (for debug),

    What does that mean? Do you get the log module output through the USB (LOG_INF(), LOG_ERR(), ...), or are you able to send custom log messages through the USB? The reason I ask is because the log module will let you know if anything is wrong, while a custom log module isn't aware of those errors. 

    Does your log every say: "couldn't send notification, err: %d", err" if the notifications are either enabled or disabled before it reboots?

    When it reboots? Does the log say anything?

    I really recommend that you get hold of a DK when developing applications. It makes things a lot easier for you, being able to step through the code to see what's going on.

    Best regards,

    Edvin

  • Hi Edvin, 

    Does your log every say: "couldn't send notification, err: %d", err" if the notifications are either enabled or disabled before it reboots?

    Yes, when notification are disable my log say that, here my log when notification disable and press button:

    [00:05:46.200,775] <inf> app: Button 6 pressed 1
    [00:05:46.200,836] <wrn> bt_gatt: Device is not subscribed to characteristic
    [00:05:46.200,866] <inf> remote: send button notification code: -22
    [00:05:46.200,866] <err> app: couldn't send notification, err: -22
    [00:05:46.201,110] <inf> app: Button 6 pressed 2
    [00:05:46.201,171] <wrn> bt_gatt: Device is not subscribed to characteristic
    [00:05:46.201,202] <inf> remote: send button notification code: -22
    [00:05:46.201,202] <err> app: couldn't send notification, err: -22

    when notification enable my log say:

    00:10:09.652,130] <inf> remote: notification enabled
    [00:10:09.652,160] <inf> app: Notification enabled

    When it reboots? Does the log say anything?

    when notification are enable and i press button, it will disconnect Bluetooth and reboot. 

    [00:10:09.652,130] <inf> remote: notification enabled
    [00:10:09.652,160] <inf> app: Notification enabled
    
    
    Disconnected
    
    Connected via Serial Port with settings /dev/tty.usbmodem141301 115200 8n1 rtscts:off

  • Can you send me a copy of your project, so that I can try to reproduce it on a DK?

    So it just disconnects from the Serial Port, suggesting that the application crashed, and it is not able to print it in the log. I am afraid it is still very hard to develop without a debugger. So you should really consider getting hold of a DK. But please send me the project, and I can look at it for this issue in particular.

    BR,
    Edvin

  • Can you send me a copy of your project, so that I can try to reproduce it on a DK

    Sure, how can i send to you !?

    So you should really consider getting hold of a DK

    I dont have nrf52840DK, i have nrf5340-DK, i try implement to nrf5340-DK but not success. I struggle with multiCore on nrf5340 so maybe i will stick to nrf52840 for current project. 

Reply Children
Related