This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

How to debug nRF52840 and nRF9160 designs on Thingy:91 board

Hi guys!

I am witnessing the things are evolving pretty fast around Thingy:91! What was up-to-date and actual yesterday is outdated today! That's why I would like to ask some fresh questions about some things...

  1. We were recently forced to move from 1.1.0 tag to master branch because we wanted to benefit from cloud_client example and connection with AWS IoT Cloud. In that master branch, we were unfortunately unable to debug our nRF9160/nRF52840 designs from Segger Embedded Studio, according to this thread. I see that there is a tag 1.2.0 available now. Is it possible to debug with SES from tag 1.2.0or from master?
  2. How can we keep nRF52840 as a nRF9160 controller/debugger and add some BLE functionality over that usb_uart_bridge? I can see some threads discussing about that(e.g. here) but I am unable to benefit from them because we are now in master branch and it's impossible to apply fixes and patches suggested for 1.1.0 tag. It is too bad that nRF52840 is used only as nRF9160 controller with so much troubles and efforts needed to add some basic BLE functionality.
  3. We need only to read advertisement messages from some Bluetooth beacons with known UUIDs. Can you reference me to some similar example?

Thanks in advance for your time and efforts!

Sincerely,

Bojan.

Parents
  • , I need your help, guys. We are hitting the wall and are unable to advance in our development since we are unable to debug our designs and benefit from nRF52840 BLE services on Thingy:91 board at the same time.

    , is it possible to debug with SES on branches 1.2.0 or master?

    , we were forced to move from the 1.1.0 tag to 1.2.0 or master because we need cloud_client example and communication with AWS IoT Cloud. I was unable to apply your R2 patches from here for hci_uart_with_usb_uart_bridge example on  1.2.0 or master. Any suggestion how can I do it?

    Thanks in advance, guys, for your time and efforts.

    Sincerely,

    Bojan.

  • Hi,

    1) SES debugging: There are issues with debugging with both SES v4.42a and 4.30c. The bugs has been reported internally, and we are working on a solution.
    Most likely we will release an updated version of SES. Note that a workaround for 4.30c is to set Project "zephyr/zephyr.elf" as active project. But, for the moment, I recommend using Segger Ozone instead of SES for debugging: https://www.segger.com/products/development-tools/ozone-j-link-debugger/

    2) My patch is made for NCS v1.1.0, I have not done a NCS v1.2.0 patch, but in the meantime you can try to add the changes manually by looking at the patch-files.

    3) Maybe you can take a look at the central_uart sample, and see how the UUID filtering is done there. 

  • Hello,  & .

    I somehow succeeded to combine usb_uart_bridge with central_uart example so that I can now see PCA20035 device from LTE Link Monitor and see printk() messages sent from nRF9160. Here attached you can see prj.conf and main.c files I used in a project. What I am unable to do, however, is to see printk() messages coming from nRF52840 code! I am currently developing BLE code for nRF52840 part and I would like to be able to debug it. Do you have any idea what I am missing here and how to print debug messages from nRF52840?

    Thanks in advance for your time and efforts!

    Sincerely,

    Bojan.

    /*
     * Copyright (c) 2019 Nordic Semiconductor ASA
     *
     * SPDX-License-Identifier: LicenseRef-BSD-5-Clause-Nordic
     */
    
    #include <zephyr.h>
    #include <device.h>
    #include <drivers/uart.h>
    #include <nrfx.h>
    #include <string.h>
    #include <hal/nrf_power.h>
    #include <power/reboot.h>
    #include <usb/usb_device.h>
    
    #include <errno.h>
    #include <stddef.h>
    #include <stdio.h>
    
    #include <arch/cpu.h>
    #include <sys/byteorder.h>
    #include <logging/log.h>
    #include <sys/util.h>
    #include <init.h>
    #include <net/buf.h>
    #include <bluetooth/bluetooth.h>
    #include <bluetooth/l2cap.h>
    #include <bluetooth/hci.h>
    #include <bluetooth/buf.h>
    #include <bluetooth/hci_raw.h>
    #include <nrfx.h>
    
    
    #define LOG_MODULE_NAME central_uart
    LOG_MODULE_REGISTER(LOG_MODULE_NAME);
    
    /* Overriding weak function to set iSerial runtime. */
    u8_t *usb_update_sn_string_descriptor(void)
    {
    	static u8_t buf[] = "PCA20035_12PLACEHLDRS";
    
    	snprintk(&buf[9], 13, "%04X%08X",
    		(uint32_t)(NRF_FICR->DEVICEADDR[1] & 0x0000FFFF)|0x0000C000,
    		(uint32_t)NRF_FICR->DEVICEADDR[0]);
    
    	return (u8_t *)&buf;
    }
    
    #define POWER_THREAD_STACKSIZE		CONFIG_IDLE_STACK_SIZE
    #define POWER_THREAD_PRIORITY		K_LOWEST_APPLICATION_THREAD_PRIO
    
    /* Heap block space is always one of 2^(2n) for n from 3 to 7.
     * (see reference/kernel/memory/heap.html for more info)
     * Here, we target 64-byte blocks. Since we want to fit one struct uart_data
     * into each block, the block layout becomes:
     * 16 bytes: reserved by the Zephyr heap block descriptor (not in struct)
     *  4 bytes: reserved by the Zephyr FIFO (in struct)
     * 40 bytes: UART data buffer (in struct)
     *  4 bytes: length field (in struct, padded for alignment)
     */
    #define UART_BUF_SIZE 40
    
    static K_FIFO_DEFINE(usb_0_tx_fifo);
    static K_FIFO_DEFINE(usb_1_tx_fifo);
    static K_FIFO_DEFINE(uart_0_tx_fifo);
    static K_FIFO_DEFINE(uart_1_tx_fifo);
    
    struct uart_data {
    	void *fifo_reserved;
    	u8_t buffer[UART_BUF_SIZE];
    	u16_t len;
    };
    
    static struct serial_dev {
    	struct device *dev;
    	void *peer;
    	struct k_fifo *fifo;
    	struct k_sem sem;
    	struct uart_data *rx;
    } devs[4];
    
    /* Frees data for incoming transmission on device blocked by full heap. */
    static int oom_free(struct serial_dev *sd)
    {
    	struct serial_dev *peer_sd = (struct serial_dev *)sd->peer;
    	struct uart_data *buf;
    
    	/* First, try to free from FIFO of peer device (blocked stream) */
    	buf = k_fifo_get(peer_sd->fifo, K_NO_WAIT);
    	if (buf) {
    		k_free(buf);
    		return 0;
    	}
    
    	/* Then, try FIFO of the receiving device (reverse of blocked stream) */
    	buf = k_fifo_get(sd->fifo, K_NO_WAIT);
    	if (buf) {
    		k_free(buf);
    		return 0;
    	}
    
    	/* Finally, try all of them */
    	for (int i = 0; i < ARRAY_SIZE(devs); i++) {
    		buf = k_fifo_get(sd->fifo, K_NO_WAIT);
    		if (buf) {
    			k_free(buf);
    			return 0;
    		}
    	}
    
    	return -1; /* Was not able to free any heap memory */
    }
    
    static void uart_interrupt_handler(void *user_data)
    {
    	struct serial_dev *sd = user_data;
    	struct device *dev = sd->dev;
    	struct serial_dev *peer_sd = (struct serial_dev *)sd->peer;
    
    	uart_irq_update(dev);
    
    	while (uart_irq_rx_ready(dev)) {
    		int data_length;
    
    		while (!sd->rx) {
    			sd->rx = k_malloc(sizeof(*sd->rx));
    			if (sd->rx) {
    				sd->rx->len = 0;
    			} else {
    				int err = oom_free(sd);
    
    				if (err) {
    					printk("Could not free memory. Rebooting.\n");
    					sys_reboot(SYS_REBOOT_COLD);
    				}
    			}
    		}
    
    		data_length = uart_fifo_read(dev, &sd->rx->buffer[sd->rx->len],
    					   UART_BUF_SIZE - sd->rx->len);
    		sd->rx->len += data_length;
    
    		if (sd->rx->len > 0) {
    			if ((sd->rx->len == UART_BUF_SIZE) ||
    			   (sd->rx->buffer[sd->rx->len - 1] == '\n') ||
    			   (sd->rx->buffer[sd->rx->len - 1] == '\r') ||
    			   (sd->rx->buffer[sd->rx->len - 1] == '\0')) {
    				k_fifo_put(peer_sd->fifo, sd->rx);
    				k_sem_give(&peer_sd->sem);
    
    				sd->rx = NULL;
    			}
    		}
    	}
    
    	if (uart_irq_tx_ready(dev)) {
    		struct uart_data *buf = k_fifo_get(sd->fifo, K_NO_WAIT);
    		u16_t written = 0;
    
    		/* Nothing in the FIFO, nothing to send */
    		if (!buf) {
    			uart_irq_tx_disable(dev);
    			return;
    		}
    
    		while (buf->len > written) {
    			written += uart_fifo_fill(dev,
    						  &buf->buffer[written],
    						  buf->len - written);
    		}
    
    		while (!uart_irq_tx_complete(dev)) {
    			/* Wait for the last byte to get
    			 * shifted out of the module
    			 */
    		}
    
    		if (k_fifo_is_empty(sd->fifo)) {
    			uart_irq_tx_disable(dev);
    		}
    
    		k_free(buf);
    	}
    }
    
    void power_thread(void)
    {
    	while (1) {
    		if (!nrf_power_usbregstatus_vbusdet_get(NRF_POWER)) {
    			nrf_power_system_off(NRF_POWER);
    		}
    		k_sleep(100);
    	}
    }
    
    void main(void)
    {
    	int ret;
    	struct serial_dev *usb_0_sd = &devs[0];
    	struct serial_dev *usb_1_sd = &devs[1];
    	struct serial_dev *uart_0_sd = &devs[2];
    	struct serial_dev *uart_1_sd = &devs[3];
    	struct device *usb_0_dev, *usb_1_dev, *uart_0_dev, *uart_1_dev;
    
    	usb_0_dev = device_get_binding("CDC_ACM_0");
    	if (!usb_0_dev) {
    		printk("CDC ACM device not found\n");
    		return;
    	}
    
    	usb_1_dev = device_get_binding("CDC_ACM_1");
    	if (!usb_1_dev) {
    		printk("CDC ACM device not found\n");
    		return;
    	}
    
    	uart_0_dev = device_get_binding("UART_0");
    	if (!uart_0_dev) {
    		printk("UART 0 init failed\n");
    	}
    
    	uart_1_dev = device_get_binding("UART_1");
    	if (!uart_1_dev) {
    		printk("UART 1 init failed\n");
    	}
    
    	usb_0_sd->dev = usb_0_dev;
    	usb_0_sd->fifo = &usb_0_tx_fifo;
    	usb_0_sd->peer = uart_0_sd;
    
    	usb_1_sd->dev = usb_1_dev;
    	usb_1_sd->fifo = &usb_1_tx_fifo;
    	usb_1_sd->peer = uart_1_sd;
    
    	uart_0_sd->dev = uart_0_dev;
    	uart_0_sd->fifo = &uart_0_tx_fifo;
    	uart_0_sd->peer = usb_0_sd;
    
    	uart_1_sd->dev = uart_1_dev;
    	uart_1_sd->fifo = &uart_1_tx_fifo;
    	uart_1_sd->peer = usb_1_sd;
    
    	k_sem_init(&usb_0_sd->sem, 0, 1);
    	k_sem_init(&usb_1_sd->sem, 0, 1);
    	k_sem_init(&uart_0_sd->sem, 0, 1);
    	k_sem_init(&uart_1_sd->sem, 0, 1);
    
    	uart_irq_callback_user_data_set(usb_0_dev, uart_interrupt_handler,
    		usb_0_sd);
    	uart_irq_callback_user_data_set(usb_1_dev, uart_interrupt_handler,
    		usb_1_sd);
    	uart_irq_callback_user_data_set(uart_0_dev, uart_interrupt_handler,
    		uart_0_sd);
    	uart_irq_callback_user_data_set(uart_1_dev, uart_interrupt_handler,
    		uart_1_sd);
    
    	ret = usb_enable(NULL);
    	if (ret != 0) {
    		printk("Failed to enable USB\n");
    		return;
    	}
    
    	uart_irq_rx_enable(usb_0_dev);
    	uart_irq_rx_enable(usb_1_dev);
    	uart_irq_rx_enable(uart_0_dev);
    	uart_irq_rx_enable(uart_1_dev);
    
    	printk("USB <--> UART bridge is now initialized\n");
    
    	struct k_poll_event events[4] = {
    		K_POLL_EVENT_STATIC_INITIALIZER(K_POLL_TYPE_SEM_AVAILABLE,
    						K_POLL_MODE_NOTIFY_ONLY,
    						&usb_0_sd->sem, 0),
    		K_POLL_EVENT_STATIC_INITIALIZER(K_POLL_TYPE_SEM_AVAILABLE,
    						K_POLL_MODE_NOTIFY_ONLY,
    						&usb_1_sd->sem, 0),
    		K_POLL_EVENT_STATIC_INITIALIZER(K_POLL_TYPE_SEM_AVAILABLE,
    						K_POLL_MODE_NOTIFY_ONLY,
    						&uart_0_sd->sem, 0),
    		K_POLL_EVENT_STATIC_INITIALIZER(K_POLL_TYPE_SEM_AVAILABLE,
    						K_POLL_MODE_NOTIFY_ONLY,
    						&uart_1_sd->sem, 0),
    	};
    
    	while (1) {
    		ret = k_poll(events, ARRAY_SIZE(events), K_FOREVER);
    		if (ret != 0) {
    			continue;
    		}
    
    		if (events[0].state == K_POLL_TYPE_SEM_AVAILABLE) {
    			events[0].state = K_POLL_STATE_NOT_READY;
    			k_sem_take(&usb_0_sd->sem, K_NO_WAIT);
    			uart_irq_tx_enable(usb_0_dev);
    		} else if (events[1].state == K_POLL_TYPE_SEM_AVAILABLE) {
    			events[1].state = K_POLL_STATE_NOT_READY;
    			k_sem_take(&usb_1_sd->sem, K_NO_WAIT);
    			uart_irq_tx_enable(usb_1_dev);
    		} else if (events[2].state == K_POLL_TYPE_SEM_AVAILABLE) {
    			events[2].state = K_POLL_STATE_NOT_READY;
    			k_sem_take(&uart_0_sd->sem, K_NO_WAIT);
    			uart_irq_tx_enable(uart_0_dev);
    		} else if (events[3].state == K_POLL_TYPE_SEM_AVAILABLE) {
    			events[3].state = K_POLL_STATE_NOT_READY;
    			k_sem_take(&uart_1_sd->sem, K_NO_WAIT);
    			uart_irq_tx_enable(uart_1_dev);
    		}
    	}
    }
    
    K_THREAD_DEFINE(power_thread_id, POWER_THREAD_STACKSIZE, power_thread,
    		NULL, NULL, NULL, POWER_THREAD_PRIORITY, 0, K_NO_WAIT);
    
    
    
    
    #if 0
    
    /*
     * Copyright (c) 2018 Nordic Semiconductor ASA
     *
     * SPDX-License-Identifier: LicenseRef-BSD-5-Clause-Nordic
     */
    
    /** @file
     *  @brief Nordic UART Service Client sample
     */
    
    #include <errno.h>
    #include <zephyr.h>
    #include <sys/byteorder.h>
    #include <sys/printk.h>
    
    #include <bluetooth/bluetooth.h>
    #include <bluetooth/hci.h>
    #include <bluetooth/conn.h>
    #include <bluetooth/uuid.h>
    #include <bluetooth/gatt.h>
    
    #include <bluetooth/services/nus.h>
    #include <bluetooth/services/nus_c.h>
    #include <bluetooth/gatt_dm.h>
    #include <bluetooth/scan.h>
    
    #include <settings/settings.h>
    
    #include <drivers/uart.h>
    
    
    #include <stddef.h>
    #include <stdio.h>
    #include <string.h>
    
    #include <arch/cpu.h>
    #include <logging/log.h>
    #include <sys/util.h>
    #include <device.h>
    #include <init.h>
    #include <net/buf.h>
    #include <bluetooth/l2cap.h>
    #include <bluetooth/hci.h>
    #include <bluetooth/buf.h>
    #include <bluetooth/hci_raw.h>
    #include <nrfx.h>
    #include <hal/nrf_power.h>
    #include <power/reboot.h>
    
    
    /* UART payload buffer element size. */
    #define UART_BUF_SIZE 40
    
    #define KEY_PASSKEY_ACCEPT DK_BTN1_MSK
    #define KEY_PASSKEY_REJECT DK_BTN2_MSK
    
    #define NUS_WRITE_TIMEOUT 150
    
    static struct device *uart;
    static bool rx_disabled;
    
    K_SEM_DEFINE(nus_write_sem, 0, 1);
    
    struct uart_data_t {
    	void *fifo_reserved;
    	u8_t  data[UART_BUF_SIZE];
    	u16_t len;
    };
    
    static K_FIFO_DEFINE(fifo_uart_tx_data);
    static K_FIFO_DEFINE(fifo_uart_rx_data);
    
    static struct bt_conn *default_conn;
    static struct bt_gatt_nus_c gatt_nus_c;
    
    static void ble_data_sent(u8_t err, const u8_t *const data, u16_t len)
    {
    	struct uart_data_t *buf;
    
    	/* Retrieve buffer context. */
    	buf = CONTAINER_OF(data, struct uart_data_t, data);
    	k_free(buf);
    
    	if (rx_disabled) {
    		rx_disabled = false;
    		uart_irq_rx_enable(uart);
    	}
    
    	k_sem_give(&nus_write_sem);
    
    	if (err) {
    		printk("ATT error code: 0x%02X\n", err);
    	}
    }
    
    static u8_t ble_data_received(const u8_t *const data, u16_t len)
    {
    	for (u16_t pos = 0; pos != len;) {
    		struct uart_data_t *tx = k_malloc(sizeof(*tx));
    
    		if (!tx) {
    			printk("Not able to allocate UART send data buffer\n");
    			return BT_GATT_ITER_CONTINUE;
    		}
    
    		/* Keep the last byte of TX buffer for potential LF char. */
    		size_t tx_data_size = sizeof(tx->data) - 1;
    
    		if ((len - pos) > tx_data_size) {
    			tx->len = tx_data_size;
    		} else {
    			tx->len = (len - pos);
    		}
    
    		memcpy(tx->data, &data[pos], tx->len);
    
    		pos += tx->len;
    
    		/* Append the LF character when the CR character triggered
    		 * transmission from the peer.
    		 */
    		if ((pos == len) && (data[len - 1] == '\r')) {
    			tx->data[tx->len] = '\n';
    			tx->len++;
    		}
    
    		k_fifo_put(&fifo_uart_tx_data, tx);
    	}
    
    	/* Start the UART transfer by enabling the TX ready interrupt */
    	uart_irq_tx_enable(uart);
    
    	return BT_GATT_ITER_CONTINUE;
    }
    
    static void uart_cb(struct device *uart)
    {
    	static struct uart_data_t *rx;
    
    	uart_irq_update(uart);
    
    	if (uart_irq_rx_ready(uart)) {
    		int data_length;
    
    		if (!rx) {
    			rx = k_malloc(sizeof(*rx));
    			if (rx) {
    				rx->len = 0;
    			} else {
    				/* Disable UART interface, it will be
    				 * enable again after releasing the buffer.
    				 */
    				uart_irq_rx_disable(uart);
    				rx_disabled = true;
    
    				printk("Not able to allocate UART receive buffer\n");
    
    				return;
    			}
    		}
    
    		data_length = uart_fifo_read(uart, &rx->data[rx->len],
    					     UART_BUF_SIZE - rx->len);
    		rx->len += data_length;
    
    		if (rx->len > 0) {
    			/* Send buffer to Bluetooth unit if either buffer size
    			 * is reached or the char \n or \r is received, which
    			 * ever comes first
    			 */
    			if ((rx->len == UART_BUF_SIZE) ||
    			   (rx->data[rx->len - 1] == '\n') ||
    			   (rx->data[rx->len - 1] == '\r')) {
    				k_fifo_put(&fifo_uart_rx_data, rx);
    				rx = NULL;
    			}
    		}
    	}
    
    	if (uart_irq_tx_ready(uart)) {
    		struct uart_data_t *buf =
    			k_fifo_get(&fifo_uart_tx_data, K_NO_WAIT);
    		u16_t written = 0;
    
    		/* Nothing in the FIFO, nothing to send */
    		if (!buf) {
    			uart_irq_tx_disable(uart);
    			return;
    		}
    
    		while (buf->len > written) {
    			written += uart_fifo_fill(uart,
    						  &buf->data[written],
    						  buf->len - written);
    		}
    
    		while (!uart_irq_tx_complete(uart)) {
    			/* Wait for the last byte to get
    			 * shifted out of the module
    			 */
    		}
    
    		if (k_fifo_is_empty(&fifo_uart_tx_data)) {
    			uart_irq_tx_disable(uart);
    		}
    
    		k_free(buf);
    	}
    }
    
    static void discovery_complete(struct bt_gatt_dm *dm,
    			       void *context)
    {
    	struct bt_gatt_nus_c *nus_c = context;
    	printk("Service discovery completed\n");
    
    	bt_gatt_dm_data_print(dm);
    
    	bt_gatt_nus_c_handles_assign(dm, nus_c);
    	bt_gatt_nus_c_tx_notif_enable(nus_c);
    
    	bt_gatt_dm_data_release(dm);
    }
    
    static void discovery_service_not_found(struct bt_conn *conn,
    					void *context)
    {
    	printk("Service not found\n");
    }
    
    static void discovery_error(struct bt_conn *conn,
    			    int err,
    			    void *context)
    {
    	printk("Error while discovering GATT database: (%d)\n", err);
    }
    
    struct bt_gatt_dm_cb discovery_cb = {
    	.completed         = discovery_complete,
    	.service_not_found = discovery_service_not_found,
    	.error_found       = discovery_error,
    };
    
    static void gatt_discover(struct bt_conn *conn)
    {
    	int err;
    
    	if (conn != default_conn) {
    		return;
    	}
    
    	err = bt_gatt_dm_start(conn,
    			       BT_UUID_NUS_SERVICE,
    			       &discovery_cb,
    			       &gatt_nus_c);
    	if (err) {
    		printk("could not start the discovery procedure, error "
    			"code: %d\n", err);
    	}
    }
    
    static void connected(struct bt_conn *conn, u8_t conn_err)
    {
    	char addr[BT_ADDR_LE_STR_LEN];
    	int err;
    
    	bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
    
    	if (conn_err) {
    		printk("Failed to connect to %s (%d)\n", addr, conn_err);
    		return;
    	}
    
    	printk("Connected: %s\n", addr);
    
    	err = bt_conn_set_security(conn, BT_SECURITY_L2);
    	if (err) {
    		printk("Failed to set security: %d\n", err);
    
    		gatt_discover(conn);
    	}
    
    	err = bt_scan_stop();
    	if ((!err) && (err != -EALREADY)) {
    		printk("Stop LE scan failed (err %d)\n", err);
    	}
    }
    
    static void disconnected(struct bt_conn *conn, u8_t reason)
    {
    	char addr[BT_ADDR_LE_STR_LEN];
    	int err;
    
    	bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
    
    	printk("Disconnected: %s (reason %u)\n", addr, reason);
    
    	if (default_conn != conn) {
    		return;
    	}
    
    	bt_conn_unref(default_conn);
    	default_conn = NULL;
    
    	err = bt_scan_start(BT_SCAN_TYPE_SCAN_ACTIVE);
    	if (err) {
    		printk("Scanning failed to start (err %d)\n", err);
    	}
    }
    
    static void security_changed(struct bt_conn *conn, bt_security_t level,
    			     enum bt_security_err err)
    {
    	char addr[BT_ADDR_LE_STR_LEN];
    
    	bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
    
    	if (!err) {
    		printk("Security changed: %s level %u\n", addr, level);
    	} else {
    		printk("Security failed: %s level %u err %d\n", addr, level,
    			err);
    	}
    
    	gatt_discover(conn);
    }
    
    static struct bt_conn_cb conn_callbacks = {
    	.connected = connected,
    	.disconnected = disconnected,
    	.security_changed = security_changed
    };
    
    static void scan_filter_match(struct bt_scan_device_info *device_info,
    			      struct bt_scan_filter_match *filter_match,
    			      bool connectable)
    {
    	char addr[BT_ADDR_LE_STR_LEN];
    
    	bt_addr_le_to_str(device_info->addr, addr, sizeof(addr));
    
    	printk("Filters matched. Address: %s connectable: %d\n",
    		addr, connectable);
    }
    
    static void scan_connecting_error(struct bt_scan_device_info *device_info)
    {
    	printk("Connecting failed\n");
    }
    
    static void scan_connecting(struct bt_scan_device_info *device_info,
    			    struct bt_conn *conn)
    {
    	default_conn = bt_conn_ref(conn);
    }
    
    static int uart_init(void)
    {
    	uart = device_get_binding(DT_UART_0_NAME);
    	if (!uart) {
    		printk("UART binding failed\n");
    		return -ENXIO;
    	}
    
    	uart_irq_callback_set(uart, uart_cb);
    	uart_irq_rx_enable(uart);
    
    	printk("UART initialized\n");
    	return 0;
    }
    
    static int nus_client_init(void)
    {
    	int err;
    	struct bt_gatt_nus_c_init_param nus_c_init_obj = {
    		.cbs = {
    			.data_received = ble_data_received,
    			.data_sent = ble_data_sent,
    		}
    	};
    
    	err = bt_gatt_nus_c_init(&gatt_nus_c, &nus_c_init_obj);
    	if (err) {
    		printk("NUS Client initialization failed (err %d)\n", err);
    		return err;
    	}
    
    	printk("NUS Client module initialized\n");
    	return err;
    }
    
    BT_SCAN_CB_INIT(scan_cb, scan_filter_match, NULL,
    		scan_connecting_error, scan_connecting);
    
    static int scan_init(void)
    {
    	int err;
    	struct bt_scan_init_param scan_init = {
    		.connect_if_match = 1,
    	};
    
    	bt_scan_init(&scan_init);
    	bt_scan_cb_register(&scan_cb);
    
    	err = bt_scan_filter_add(BT_SCAN_FILTER_TYPE_UUID, BT_UUID_NUS_SERVICE);
    	if (err) {
    		printk("Scanning filters cannot be set (err %d)\n", err);
    		return err;
    	}
    
    	err = bt_scan_filter_enable(BT_SCAN_UUID_FILTER, false);
    	if (err) {
    		printk("Filters cannot be turned on (err %d)\n", err);
    		return err;
    	}
    
    	printk("Scan module initialized\n");
    	return err;
    }
    
    
    static void auth_cancel(struct bt_conn *conn)
    {
    	char addr[BT_ADDR_LE_STR_LEN];
    
    	bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
    
    	printk("Pairing cancelled: %s\n", addr);
    }
    
    
    static void pairing_confirm(struct bt_conn *conn)
    {
    	char addr[BT_ADDR_LE_STR_LEN];
    
    	bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
    
    	bt_conn_auth_pairing_confirm(conn);
    
    	printk("Pairing confirmed: %s\n", addr);
    }
    
    
    static void pairing_complete(struct bt_conn *conn, bool bonded)
    {
    	char addr[BT_ADDR_LE_STR_LEN];
    
    	bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
    
    	printk("Pairing completed: %s, bonded: %d\n", addr, bonded);
    }
    
    
    static void pairing_failed(struct bt_conn *conn, enum bt_security_err reason)
    {
    	char addr[BT_ADDR_LE_STR_LEN];
    
    	bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
    
    	printk("Pairing failed conn: %s, reason %d\n", addr, reason);
    }
    
    static struct bt_conn_auth_cb conn_auth_callbacks = {
    	.cancel = auth_cancel,
    	.pairing_confirm = pairing_confirm,
    	.pairing_complete = pairing_complete,
    	.pairing_failed = pairing_failed
    };
    
    //Start
    /* Overriding weak function to set iSerial runtime. */
    u8_t *usb_update_sn_string_descriptor(void)
    {
    	static u8_t buf[] = "PCA20035_12PLACEHLDRS";
    
    	snprintk(&buf[9], 13, "%04X%08X",
    		(uint32_t)(NRF_FICR->DEVICEADDR[1] & 0x0000FFFF)|0x0000C000,
    		(uint32_t)NRF_FICR->DEVICEADDR[0]);
    
    	return (u8_t *)&buf;
    }
    
    
    /* Heap block space is always one of 2^(2n) for n from 3 to 7.
     * (see reference/kernel/memory/heap.html for more info)
     * Here, we target 64-byte blocks. Since we want to fit one struct uart_data
     * into each block, the block layout becomes:
     * 16 bytes: reserved by the Zephyr heap block descriptor (not in struct)
     *  4 bytes: reserved by the Zephyr FIFO (in struct)
     * 40 bytes: UART data buffer (in struct)
     *  4 bytes: length field (in struct, padded for alignment)
     */
    #define UART_BUF_SIZE 40
    
    static K_FIFO_DEFINE(usb_0_tx_fifo);
    
    static K_FIFO_DEFINE(uart_0_tx_fifo);
    
    
    struct uart_data {
    	void *fifo_reserved;
    	u8_t buffer[UART_BUF_SIZE];
    	u16_t len;
    };
    
    static struct serial_dev {
    	struct device *dev;
    	void *peer;
    	struct k_fifo *fifo;
    	struct k_sem sem;
    	struct uart_data *rx;
    } devs[2];
    
    /* Frees data for incoming transmission on device blocked by full heap. */
    static int oom_free(struct serial_dev *sd)
    {
    	struct serial_dev *peer_sd = (struct serial_dev *)sd->peer;
    	struct uart_data *buf;
    
    	/* First, try to free from FIFO of peer device (blocked stream) */
    	buf = k_fifo_get(peer_sd->fifo, K_NO_WAIT);
    	if (buf) {
    		k_free(buf);
    		return 0;
    	}
    
    	/* Then, try FIFO of the receiving device (reverse of blocked stream) */
    	buf = k_fifo_get(sd->fifo, K_NO_WAIT);
    	if (buf) {
    		k_free(buf);
    		return 0;
    	}
    
    	/* Finally, try all of them */
    	for (int i = 0; i < ARRAY_SIZE(devs); i++) {
    		buf = k_fifo_get(sd->fifo, K_NO_WAIT);
    		if (buf) {
    			k_free(buf);
    			return 0;
    		}
    	}
    
    	return -1; /* Was not able to free any heap memory */
    }
    
    static void uart_interrupt_handler(void *user_data)
    {
    	struct serial_dev *sd = user_data;
    	struct device *dev = sd->dev;
    	struct serial_dev *peer_sd = (struct serial_dev *)sd->peer;
    
    	uart_irq_update(dev);
    
    	while (uart_irq_rx_ready(dev)) {
    		int data_length;
    
    		while (!sd->rx) {
    			sd->rx = k_malloc(sizeof(*sd->rx));
    			if (sd->rx) {
    				sd->rx->len = 0;
    			} else {
    				int err = oom_free(sd);
    
    				if (err) {
    					printk("Could not free memory. Rebooting.\n");
    					sys_reboot(SYS_REBOOT_COLD);
    				}
    			}
    		}
    
    		data_length = uart_fifo_read(dev, &sd->rx->buffer[sd->rx->len],
    					   UART_BUF_SIZE - sd->rx->len);
    		sd->rx->len += data_length;
    
    		if (sd->rx->len > 0) {
    			if ((sd->rx->len == UART_BUF_SIZE) ||
    			   (sd->rx->buffer[sd->rx->len - 1] == '\n') ||
    			   (sd->rx->buffer[sd->rx->len - 1] == '\r') ||
    			   (sd->rx->buffer[sd->rx->len - 1] == '\0')) {
    				k_fifo_put(peer_sd->fifo, sd->rx);
    				k_sem_give(&peer_sd->sem);
    
    				sd->rx = NULL;
    			}
    		}
    	}
    
    	if (uart_irq_tx_ready(dev)) {
    		struct uart_data *buf = k_fifo_get(sd->fifo, K_NO_WAIT);
    		u16_t written = 0;
    
    		/* Nothing in the FIFO, nothing to send */
    		if (!buf) {
    			uart_irq_tx_disable(dev);
    			return;
    		}
    
    		while (buf->len > written) {
    			written += uart_fifo_fill(dev,
    						  &buf->buffer[written],
    						  buf->len - written);
    		}
    
    		while (!uart_irq_tx_complete(dev)) {
    			/* Wait for the last byte to get
    			 * shifted out of the module
    			 */
    		}
    
    		if (k_fifo_is_empty(sd->fifo)) {
    			uart_irq_tx_disable(dev);
    		}
    
    		k_free(buf);
    	}
    }
    
    void usb_uart_thread(void)
    {
    	int ret;
    	struct serial_dev *usb_0_sd = &devs[0];
    
    	struct serial_dev *uart_0_sd = &devs[1];
    
    	struct device *usb_0_dev, *uart_0_dev;
    
    	usb_0_dev = device_get_binding("CDC_ACM_0");
    	if (!usb_0_dev) {
    		printk("CDC ACM device not found\n");
    		return;
    	}
    
    	uart_0_dev = device_get_binding("UART_0");
    	if (!uart_0_dev) {
    		printk("UART 0 init failed\n");
    	}
    
    	usb_0_sd->dev = usb_0_dev;
    	usb_0_sd->fifo = &usb_0_tx_fifo;
    	usb_0_sd->peer = uart_0_sd;
    
    	uart_0_sd->dev = uart_0_dev;
    	uart_0_sd->fifo = &uart_0_tx_fifo;
    	uart_0_sd->peer = usb_0_sd;
    
    
    	k_sem_init(&usb_0_sd->sem, 0, 1);
    
    	k_sem_init(&uart_0_sd->sem, 0, 1);
    
    
    	uart_irq_callback_user_data_set(usb_0_dev, uart_interrupt_handler,
    		usb_0_sd);
    
    	uart_irq_callback_user_data_set(uart_0_dev, uart_interrupt_handler,
    		uart_0_sd);
    
    
    	uart_irq_rx_enable(usb_0_dev);
    
    	uart_irq_rx_enable(uart_0_dev);
    
    
    	printk("USB <--> UART bridge is now initialized\n");
    
    	struct k_poll_event events[2] = {
    		K_POLL_EVENT_STATIC_INITIALIZER(K_POLL_TYPE_SEM_AVAILABLE,
    						K_POLL_MODE_NOTIFY_ONLY,
    						&usb_0_sd->sem, 0),
    		K_POLL_EVENT_STATIC_INITIALIZER(K_POLL_TYPE_SEM_AVAILABLE,
    						K_POLL_MODE_NOTIFY_ONLY,
    						&uart_0_sd->sem, 0),
    	};
    
    	while (1) {
    		ret = k_poll(events, ARRAY_SIZE(events), K_FOREVER);
    		if (ret != 0) {
    			continue;
    		}
    
    		if (events[0].state == K_POLL_TYPE_SEM_AVAILABLE) {
    			events[0].state = K_POLL_STATE_NOT_READY;
    			k_sem_take(&usb_0_sd->sem, K_NO_WAIT);
    			uart_irq_tx_enable(usb_0_dev);
    		}  else if (events[1].state == K_POLL_TYPE_SEM_AVAILABLE) {
    			events[1].state = K_POLL_STATE_NOT_READY;
    			k_sem_take(&uart_0_sd->sem, K_NO_WAIT);
    			uart_irq_tx_enable(uart_0_dev);
    		} 
    	}
    }
    
    
    //END
    
    
    void main(void)
    {
    	int err;
    
    	printk("Starting Bluetooth Central UART example\n");
    
    	err = bt_conn_auth_cb_register(&conn_auth_callbacks);
    	if (err) {
    		printk("Failed to register authorization callbacks.\n");
    		return;
    	}
    
    	err = bt_enable(NULL);
    	if (err) {
    		printk("Bluetooth init failed (err %d)\n", err);
    		return;
    	}
    	printk("Bluetooth initialized\n");
    
    	if (IS_ENABLED(CONFIG_SETTINGS)) {
    		settings_load();
    	}
    
    	bt_conn_cb_register(&conn_callbacks);
    
    	int (*module_init[])(void) = {uart_init, scan_init, nus_client_init};
    	for (size_t i = 0; i < ARRAY_SIZE(module_init); i++) {
    		err = (*module_init[i])();
    		if (err) {
    			return;
    		}
    	}
    
    	err = bt_scan_start(BT_SCAN_TYPE_SCAN_ACTIVE);
    	if (err) {
    		printk("Scanning failed to start (err %d)\n", err);
    		return;
    	}
    	printk("Scanning successfully started\n");
            while(true){
                printk("print from nRF52840\n");
                LOG_DBG("print from nRF52840\n");
                k_sleep(1000);
            }
    	
            for (;;) {
    		/* Wait indefinitely for data to be sent over Bluetooth */
    		struct uart_data_t *buf = k_fifo_get(&fifo_uart_rx_data,
    						     K_FOREVER);
    
    		err = bt_gatt_nus_c_send(&gatt_nus_c, buf->data, buf->len);
    		if (err) {
    			printk("Failed to send data over BLE connection"
    			       "(err %d)\n", err);
    		}
    
    		err = k_sem_take(&nus_write_sem, NUS_WRITE_TIMEOUT);
    		if (err) {
    			printk("NUS send timeout\n");
    		}
    	}
    }
    
    K_THREAD_DEFINE(usb_uart_thread_id, 16384, usb_uart_thread, NULL, NULL,
    	NULL, K_LOWEST_APPLICATION_THREAD_PRIO, 0, K_NO_WAIT);
    #endif

    # General
    CONFIG_REBOOT=y
    CONFIG_HEAP_MEM_POOL_SIZE=8192
    CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=2048
    CONFIG_GPIO=y
    CONFIG_POLL=y
    CONFIG_BOOTLOADER_MCUBOOT=y
    CONFIG_EVENT_MANAGER=y
    CONFIG_LINKER_ORPHAN_SECTION_PLACE=y
    CONFIG_MPU_STACK_GUARD=y
    CONFIG_SPEED_OPTIMIZATIONS=y
    CONFIG_DEVICE_POWER_MANAGEMENT=y
    CONFIG_SYS_PM_POLICY_APP=y
    
    # USB
    CONFIG_USB=y
    CONFIG_USB_DEVICE_STACK=y
    CONFIG_USB_DEVICE_MANUFACTURER="Nordic Semiconductor"
    CONFIG_USB_DEVICE_PRODUCT="Thingy:91 UART"
    CONFIG_USB_DEVICE_VID=0x1915
    CONFIG_USB_DEVICE_PID=0x520F
    CONFIG_USB_DEVICE_SN="PCA20035 12PLACEHLDRS"
    CONFIG_USB_COMPOSITE_DEVICE=y
    CONFIG_USB_CDC_ACM=y
    CONFIG_USB_CDC_ACM_RINGBUF_SIZE=4096
    CONFIG_USB_CDC_ACM_DEVICE_COUNT=2
    
    # Settings
    CONFIG_FCB=y
    CONFIG_SETTINGS=y
    CONFIG_SETTINGS_FCB=y
    CONFIG_FLASH=y
    CONFIG_FLASH_PAGE_LAYOUT=y
    CONFIG_FLASH_MAP=y
    CONFIG_MPU_ALLOW_FLASH_WRITE=y
    
    # Logging
    CONFIG_LOG=y
    CONFIG_USE_SEGGER_RTT=y
    CONFIG_LOG_BACKEND_RTT=y
    CONFIG_LOG_BACKEND_RTT_MODE_DROP=y
    
    # UART
    CONFIG_SERIAL=y
    CONFIG_UART_INTERRUPT_DRIVEN=y
    CONFIG_UART_LINE_CTRL=y
    CONFIG_UART_0_NRF_UARTE=y
    CONFIG_UART_0_NRF_FLOW_CONTROL=n
    CONFIG_UART_1_NRF_UARTE=y
    CONFIG_UART_1_NRF_FLOW_CONTROL=n
    
    # Enable the UART driver
    CONFIG_CONSOLE=y
    CONFIG_UART_CONSOLE=y
    #CONFIG_UART_0_NRF_FLOW_CONTROL=y
    
    # BLE
    # Enable the BLE stack with GATT Client configuration
    CONFIG_BT=y
    CONFIG_BT_CENTRAL=y
    CONFIG_BT_SMP=y
    CONFIG_BT_GATT_CLIENT=y
    
    # Enable the BLE modules from NCS
    CONFIG_BT_GATT_NUS_C=y
    CONFIG_BT_SCAN=y
    CONFIG_BT_SCAN_FILTER_ENABLE=y
    CONFIG_BT_SCAN_UUID_CNT=1
    CONFIG_BT_GATT_DM=y
    CONFIG_HEAP_MEM_POOL_SIZE=2048
    
    # This example requires more workqueue stack
    CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=2048
    
    # Enable bonding
    CONFIG_BT_SETTINGS=y
    CONFIG_FLASH=y
    CONFIG_FLASH_PAGE_LAYOUT=y
    CONFIG_FLASH_MAP=y
    CONFIG_NVS=y
    CONFIG_SETTINGS=y
    

  • Hi bojan,

    good to see that you have had some progress. If you are using a J-link or a DK as programmer/debugger the simplest way to get debug output from the nRF52840 when it is set up as a uart/usb bridge is to enable RTT debugging 

    https://devzone.nordicsemi.com/f/nordic-q-a/46083/how-to-setup-zephyr-for-rtt-logging-with-nrf9160

  • Hello, & .

    I unfortunately was wrong! When I was able to see PCA20035 device from LTE Link Monitor, it was only usb_uart_bridge implemented! When I merge usb_uart_bridge with central_uart example, I am able to debug nRF52840 with RTT but unable to see PCA20035 device through LTE Link Monitor and debug nRF9160!

    Would you, PLEASE, take a look at the usb_uart_bridge_with_central_uart solution I was using, try it on your side and let me know what I am doing wrong?

    Other than that, do you have any info from inside the Nordic house, will you release new SES version soon that will allow us debugging?

    Thanks in advance. Looking forward to reading from you.

    Sincerely,

    Bojan.

    central_uart_with_usb_uart_bridge.zip

  • Hello I am beginner can you help me to learn the coding of nrf9160 and nrf9160DK 

  • Hello I am beginner can you help me to learn the coding for nrf9160and nrf9160DK

Reply Children
No Data
Related