USB CDC + BLE NUS will cause the BT function unstable

Hi 

   I found some Bluetooth send the data unstable problem after i enable the usb cdc acm function. Can you help me to 

check my setting that has missing or not thanks.

prj.conf

 

#
# Copyright (c) 2019 Nordic Semiconductor ASA
#
# SPDX-License-Identifier: LicenseRef-BSD-5-Clause-Nordic
#
# General config
CONFIG_ASSERT=y

# Make sure printk is printing to the UART console
CONFIG_CONSOLE=y
CONFIG_UART_CONSOLE=y


CONFIG_BT=y
CONFIG_BT_PERIPHERAL=y
CONFIG_BT_DEVICE_NAME="Laminar P1"
CONFIG_BT_DEVICE_APPEARANCE=833
CONFIG_BT_MAX_CONN=1
CONFIG_BT_MAX_PAIRED=1

# Enable the NUS service
CONFIG_BT_NUS=y

CONFIG_BT_CONN_TX_MAX=30
CONFIG_BT_L2CAP_TX_BUF_COUNT=30
CONFIG_BT_L2CAP_TX_MTU=247
#CONFIG_BT_L2CAP_TX_MTU=498
CONFIG_BT_BUF_ACL_TX_COUNT=18
#CONFIG_BT_BUF_ACL_TX_SIZE=251
CONFIG_BT_BUF_ACL_TX_SIZE=502
CONFIG_BT_BUF_ACL_RX_SIZE=502

CONFIG_BT_GAP_AUTO_UPDATE_CONN_PARAMS=n
CONFIG_BT_CTLR_DATA_LENGTH_MAX=251
CONFIG_BT_CONN_PARAM_UPDATE_TIMEOUT=300
CONFIG_BT_USER_PHY_UPDATE=y
CONFIG_BT_GATT_CLIENT=y
CONFIG_BT_GATT_DM=y
CONFIG_BT_DATA_LEN_UPDATE=y
CONFIG_BT_USER_DATA_LEN_UPDATE=y


# This example requires more workqueue stack
CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=8192
CONFIG_SYSTEM_WORKQUEUE_PRIORITY=-10

# Logging
CONFIG_SERIAL=y
CONFIG_LOG=y
CONFIG_LOG_PRINTK=y
CONFIG_USE_SEGGER_RTT=n
CONFIG_LOG_BUFFER_SIZE=4096

# Stacks and heaps
CONFIG_MAIN_STACK_SIZE=16384
CONFIG_BT_RX_STACK_SIZE=16384
CONFIG_HEAP_MEM_POOL_SIZE=4096
CONFIG_SHELL_STACK_SIZE=8192
CONFIG_SHELL_THREAD_PRIORITY_OVERRIDE=y
CONFIG_SHELL_PRINTF_BUFF_SIZE=4096



# I2C
CONFIG_I2C=y
CONFIG_NRFX_TWIM1=y

# I2S
CONFIG_I2S=y
CONFIG_I2S_NRFX=y
CONFIG_I2S_NRFX_TX_BLOCK_COUNT=300

#SPIM
CONFIG_SPI=y
CONFIG_SPI_SLAVE=n
CONFIG_SPI_ASYNC=y
CONFIG_NRFX_SPIM3=y
CONFIG_NRFX_SPIM4=y
CONFIG_POLL=y

# Rebooot
CONFIG_REBOOT=n
CONFIG_RESET_ON_FATAL_ERROR=n

CONFIG_FLASH=y
CONFIG_FLASH_MAP=y
CONFIG_FLASH_PAGE_LAYOUT=y

# file system
CONFIG_FILE_SYSTEM=y
CONFIG_FILE_SYSTEM_SHELL=y
CONFIG_FILE_SYSTEM_LITTLEFS=y
CONFIG_FAT_FILESYSTEM_ELM=n

CONFIG_SHELL=y


#USB related configs
CONFIG_USB_DEVICE_STACK=y
#CONFIG_USB_DEVICE_PRODUCT="Zephyr MSC sample"
CONFIG_USB_DRIVER_LOG_LEVEL_ERR=y
CONFIG_USB_MASS_STORAGE=n
CONFIG_USB_DEVICE_LOG_LEVEL_ERR=y
CONFIG_USB_MASS_STORAGE_LOG_LEVEL_ERR=n
#CONFIG_USB_DEVICE_PID=0x0008
CONFIG_DISK_DRIVER_FLASH=y
CONFIG_APP_MSC_STORAGE_FLASH_FATFS=n
CONFIG_APP_MSC_STORAGE_FLASH_LITTLEFS=y

# enable QSPI flash
CONFIG_NORDIC_QSPI_NOR=y
CONFIG_NORDIC_QSPI_NOR_FLASH_LAYOUT_PAGE_SIZE=4096
CONFIG_MPU_ALLOW_FLASH_WRITE=y

CONFIG_BOOTLOADER_MCUBOOT=n
CONFIG_CMSIS_DSP=y
CONFIG_CMSIS_DSP_FASTMATH=y
CONFIG_NEWLIB_LIBC=y
CONFIG_FPU=y
CONFIG_NEWLIB_LIBC_FLOAT_PRINTF=y

# Enable CAF_BUTTONS
CONFIG_CAF=y
CONFIG_CAF_BUTTONS=y
CONFIG_CAF_BUTTONS_POLARITY_INVERSED=y
CONFIG_CAF_CLICK_DETECTOR=y
CONFIG_CAF_CLICK_DETECTOR_LONG_CLICK_MSEC=1000

# normal voltage mode
CONFIG_BOARD_ENABLE_DCDC_HV=n
# disable NFC pin to GPIO
CONFIG_NFCT_PINS_AS_GPIOS=y
# Enable the memory DMA
CONFIG_DMA=n

# ADC config
CONFIG_ADC=y

# Power manager
CONFIG_PM=n

# USB CDC ACM
CONFIG_STDOUT_CONSOLE=y
CONFIG_USB_DEVICE_PRODUCT="Zephyr CDC ACM sample"
CONFIG_USB_DEVICE_PID=0x0001
CONFIG_UART_INTERRUPT_DRIVEN=y
CONFIG_UART_LINE_CTRL=y
hci_rpmsg.conf
#
# Copyright (c) 2021 Nordic Semiconductor
#
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
#

#CONFIG_BT_BUF_ACL_TX_SIZE=251
CONFIG_BT_CTLR_DATA_LENGTH_MAX=251
#CONFIG_BT_BUF_ACL_RX_SIZE=251
CONFIG_BT_BUF_ACL_TX_SIZE=502
CONFIG_BT_BUF_ACL_RX_SIZE=502
CONFIG_BT_BUF_ACL_TX_COUNT=18

CONFIG_BT_MAX_CONN=2

CONFIG_BT_CONN_TX_MAX=50
CONFIG_BT_L2CAP_TX_BUF_COUNT=50
#CONFIG_BT_L2CAP_TX_MTU=498
CONFIG_BT_L2CAP_TX_MTU=247
nrf5340dk_nrf5340_cpuapp.overlay
chosen {
        nordic,pm-ext-flash = &mx66l1g;
        zephyr,console = &cdc_acm_uart0;
        zephyr,shell-uart = &cdc_acm_uart0;
 };
&zephyr_udc0 {
    cdc_acm_uart0: cdc_acm_uart0 {
        compatible = "zephyr,cdc-acm-uart";
        tx-fifo-size = <4096>;
        rx-fifo-size = <4096>;
    };
};
/* Remove flow control pins*/
&gpio_fwd {
    uart {
        gpios =  <&gpio1 0 0>; //<&gpio1 1 0>,
    };
};
Stanly
  • Hi!

    Could you explain these "data unstable problem" ? What's the issue?

  • I just plug in the usb to monitor the log print out and enable the ble nus send the data at the same time but suddenly the bt not send the data out after 5sec. After that the usb cdc port seems disconnect and flush the device manager again. If i use the uart0 device that's no this issue happened.

    Stanly 

  • Do you have any logs from that?

    Also, what version of nRF Connect SDK are you using?

  • Hi,

        I didn't get any error from my usb cdc acm log, should i turn on any settings of bt module. I can try to capture log again. the SDK version is v2.4.2, Zephyr version 3.3.99.

    Stanly

  • Hi Sigurd:

         I found the root cause that will cause the timer trigger every 5 sec that will call the work to the workqueue and BT RX recevice the command it will also use the work to do the collect the sensor data then use the nus_send_data to send the data out. Thus i guess the timer maybe got the high priority to do the work first but i do not know why the BT work will stop. Do you have any suggest to prevent this problem happens thanks.

    In my code:

    struct k_work charging_led_work;
    struct k_work_q d1stream_q;
    struct k_work d1stream_work;
    #define STACKSIZE 16384
    #define PRIORITY -6

    K_THREAD_STACK_DEFINE(stack_area, STACKSIZE);
    /* Initial the system work queue for d1stream work task*/
    void sys_work_q_init(){
        k_work_queue_init(&d1stream_q);
        k_work_queue_start(&d1stream_q, stack_area, K_THREAD_STACK_SIZEOF(stack_area), PRIORITY, NULL);
      }
    void handle_sc_cmd(uint8_t* cmd_data, int length){
        //char *token;
        //char *array[3];
        //int i = 0;
        int err = 0;
        int sysparm_ret = 0;
        int sysparm_id = 0;
       
        // 1. First try to open the connection.
        SDS_HANDLE handle = sds_Open();
        if (is_SDS_HANDLE(handle)) {
    #ifdef Debug_log
            LOG_INF("[handle_sc_cmd] Open handle success (0x%x)\n", (P2UI)handle);
    #endif
        } else {
            LOG_ERR("[handle_sc_cmd]ERROR sds_Open() FAILED\n");
        }

        // 2. check the cmd param[0] (ex: sysparam , getreg, setreg)
        //scom_cmd = cmd_data[0];
        if(cmd_data[0] == scom_AddCmd_D1Stream){
        //if(cmd_data[0] == 0x61){
            d1stream_loop = ((int)cmd_data[4])<< 24 |
                        ((int)cmd_data[3])<< 16 |
                        ((int)cmd_data[2])<< 8 |
                        ((int)cmd_data[1]);
            if(d1stream_loop == 65535){
                d1stream_stop = SDS_STAT_ERR;
            } else if(d1stream_loop == 0xffffffff){
                d1stream_loop = -1;
                sds_Close(handle);
                k_work_submit_to_queue(&d1stream_q, &d1stream_work);
            } else {
                sds_Close(handle);
                k_work_submit_to_queue(&d1stream_q, &d1stream_work);
            }
        }
    }
    static void bt_receive_cb(struct bt_conn *conn, const uint8_t *const data,
                  uint16_t len)
    {
        char addr[BT_ADDR_LE_STR_LEN] = {0};
       
        bt_addr_le_to_str(bt_conn_get_dst(conn), addr, ARRAY_SIZE(addr));
    #ifdef Debug_log
        LOG_INF("Received data from: %s", (addr));
        for(int i = 0; i < len; i++){
            LOG_INF("data : 0x%02x", data[i]);
        }

        LOG_INF("len = %d ", len);
    #endif
       
        handle_sc_cmd(data, len);
    }
    static struct bt_nus_cb nus_cb = {
        .received = bt_receive_cb,
        .send_enabled = bt_send_enabled_cb,
    };
    void charging_led_work_cb(struct k_work *work){
        int32_t val_mv = adc_reading();

        if(val_mv >= BATTERY_CHARGE_90){
            hmb_set_leds_state(HMB_ALL_LEDS_MSK,HMB_ALL_LEDS_MSK);
        } else if((val_mv >= BATTERY_CHARGE_70 )){
            for(int i = 0 ;i < 3; i++){
                hmb_set_leds_state(HMB_LED2_MSK|HMB_LED3_MSK|HMB_LED5_MSK|HMB_LED6_MSK, HMB_ALL_LEDS_MSK);
                k_sleep(K_MSEC(1000));
                hmb_set_leds_state(HMB_ALL_LEDS_MSK,HMB_ALL_LEDS_MSK);
                k_sleep(K_MSEC(1000));
            }
        } else if(val_mv  >= BATTERY_CHARGE_30){
            for(int i = 0 ;i < 3; i++){
                hmb_set_leds_state(HMB_LED3_MSK|HMB_LED6_MSK,HMB_ALL_LEDS_MSK);
                k_sleep(K_MSEC(1000));
                hmb_set_leds_state(HMB_LED3_MSK|HMB_LED6_MSK|HMB_LED2_MSK|HMB_LED5_MSK,HMB_ALL_LEDS_MSK);
                k_sleep(K_MSEC(1000));
            }
        } else if(val_mv  >= BATTERY_CHARGE_0){
            for(int i = 0 ;i < 3; i++){
                hmb_set_leds_state(HMB_LED3_MSK|HMB_LED6_MSK,HMB_ALL_LEDS_MSK);
                k_sleep(K_MSEC(1000));
                hmb_set_leds_state(HMB_NO_LEDS_MSK, HMB_ALL_LEDS_MSK);
                k_sleep(K_MSEC(1000));
            }

        }
    }
    void charging_led(struct k_timer *timer_id){
        k_work_submit(&charging_led_work);
    }

    void main(){

    ...

    sys_work_q_init();

    k_timer_start(&m_charging_timer, K_SECONDS(5), K_SECONDS(5));

    }

    K_TIMER_DEFINE(m_charging_timer, charging_led, NULL);
    K_WORK_DEFINE(charging_led_work, charging_led_work_cb);
    K_WORK_DEFINE(d1stream_work, d1stream_work_cb);
    Stanly
Related