Hello!
I am programming BLE with the nRF52840-DK. [Toolchain Manager: v1.3.0, IDE: Visual Studio Code (VSCode), SDK: ncs v2.6.0, window11 pro]
I am integrating NUS Central and cdc_acm. My current goal is to send data received via Bluetooth to a PC (PuTTY) through USB.
I want to continuously receive sensor data via Bluetooth (data rate: about 1.3Mbps). However, I find it quite challenging. I wrote code to send the data received in the Bluetooth receive callback function directly to USB. However, the buffer storing the data quickly fills up.
It seems that the UART transmission (uart_tx) is not ready every time the Bluetooth receive callback is executed. This might be the cause of the issue. Is there another solution?
The code was written with reference to CDC ACM and NUS central.
Here is the related code:
#define RING_BUF_SIZE 2048
#define tx_data_SIZE 512
uint8_t buffer1[RING_BUF_SIZE];
uint8_t buffer2[RING_BUF_SIZE];
static uint8_t buffer[tx_data_SIZE];
struct ring_buf ringbuf1, ringbuf2;
static struct ring_buf *current_rx_buf;
static struct ring_buf *current_tx_buf;
static uint8_t ble_data_received(struct bt_nus_client *nus, const uint8_t *data, uint16_t len) {
ARG_UNUSED(nus);
//LOG_INF("ble_data_received -%dth, %d bytes", rx_count, len);
int ret = 0;
int rb_len = ring_buf_put(current_rx_buf, data, len);
if (rb_len < len) {
LOG_WRN("ble_data_received - %dth Current RX buffer full, dropped %d bytes", rx_count, len - rb_len);
}
uart_irq_tx_enable(usbd_dev);
if(uart_irq_update(usbd_dev) && uart_irq_is_pending(usbd_dev)){
if (uart_irq_tx_ready(usbd_dev)){
if (current_rx_buf == &ringbuf1) {
current_rx_buf = &ringbuf2;
current_tx_buf = &ringbuf1;
//LOG_INF("ble_data_received - tx ringbuf1");
} else {
current_rx_buf = &ringbuf1;
current_tx_buf = &ringbuf2; //LOG_INF("ble_data_received - tx ringbuf2");
}
//LOG_INF("ble_data_received - if");
int rb_len = ring_buf_get(current_tx_buf, buffer, sizeof(buffer));
if (rb_len == 0) {
uart_irq_tx_disable(usbd_dev);
} else {
int send_len = uart_fifo_fill(usbd_dev, buffer, rb_len);
//LOG_INF("ble_data_received - Sent: %d bytes", send_len);
if (send_len < rb_len) {
ring_buf_put(current_tx_buf, buffer + send_len, rb_len - send_len);
}
}
}
}
rx_count++;
return BT_GATT_ITER_CONTINUE;
}
static int nus_client_init(void){
int err;
struct bt_nus_client_init_param init = {
.cb = {
.received = ble_data_received,
.sent = ble_data_sent,
}
};
err = bt_nus_client_init(&nus_client, &init);
LOG_INF("bt_nus_client_init >>> err:%d", err);
return err;
int main(void) {
int main_err;
uint32_t baudrate = 0U;
uint32_t dtr = 0U;
ring_buf_init(&ringbuf1, sizeof(buffer1), buffer1);
ring_buf_init(&ringbuf2, sizeof(buffer2), buffer2);
current_rx_buf = &ringbuf1;
current_tx_buf = &ringbuf2;
}