Custom BLE application won't function unless debugger is attached, or immediately following device flashing. Power reset leaves device in non-functional state.

Hello,

I've developed a custom PCB which uses an nRF52810 SOC. I've been developing the software for the device using NRF Connect SDK 2.6.1 in Visual Studio Code, and I flash the device using a J-Link debug probe via SWD. 

The software involves BLE (utilizing the Nordic UART Service NUS), some simple kernel-based timers, ADC readings, I2C read/writes, and GPIO writes. I also have no main function defined, if that would change anything.

In the software, I am defining two separate threads, one as a "thread_main" function, and the other to initialize and handle BLE.

The main problem I'm facing is that the device seems to only function when I start debugging, or immediately following a flash. Any subsequent power resets (disabling/enabling the power supply) leave the device in a non-functional state.

See below for my prj.conf file.

CONFIG_HEAP_MEM_POOL_SIZE=2048

CONFIG_BT=y
CONFIG_BT_PERIPHERAL=y
CONFIG_BT_DEVICE_NAME="DEV"
CONFIG_BT_DEVICE_APPEARANCE=833
CONFIG_BT_MAX_CONN=1
CONFIG_BT_MAX_PAIRED=1

# Enable the NUS service
CONFIG_BT_NUS=y

# Enable bonding
CONFIG_BT_SETTINGS=y
CONFIG_FLASH=y
CONFIG_FLASH_PAGE_LAYOUT=y
CONFIG_FLASH_MAP=y
CONFIG_NVS=y
CONFIG_SETTINGS=y

# Enable DK LED and Buttons library
# CONFIG_DK_LIBRARY=y

# Drivers and peripherals
CONFIG_I2C=y
CONFIG_WATCHDOG=y
CONFIG_SPI=n
CONFIG_GPIO=y

# Power management

# Interrupts
CONFIG_DYNAMIC_INTERRUPTS=n
CONFIG_IRQ_OFFLOAD=n

# Memory protection
CONFIG_THREAD_STACK_INFO=n
CONFIG_THREAD_CUSTOM_DATA=n
CONFIG_FPU=n

# Boot
CONFIG_BOOT_BANNER=n
CONFIG_BOOT_DELAY=0

# Console
CONFIG_CONSOLE=n
CONFIG_UART_CONSOLE=n
CONFIG_STDOUT_CONSOLE=n
CONFIG_PRINTK=n
CONFIG_EARLY_CONSOLE=n

# Build
CONFIG_SIZE_OPTIMIZATIONS=y

# ARM
CONFIG_ARM_MPU=y

# In order to correctly tune the stack sizes for the threads the following
# Configurations can enabled to print the current use:
# CONFIG_THREAD_NAME=y
# CONFIG_THREAD_ANALYZER=y
# CONFIG_THREAD_ANALYZER_AUTO=y
# CONFIG_THREAD_ANALYZER_RUN_UNLOCKED=y
# CONFIG_THREAD_ANALYZER_USE_PRINTK=y
#CONFIG_CONSOLE=y
#CONFIG_UART_CONSOLE=y
#CONFIG_SERIAL=y
#CONFIG_PRINTK=y

# Example output of thread analyzer
#SDC RX              : unused 800 usage 224 / 1024 (21 %)
#BT ECC              : unused 216 usage 888 / 1104 (80 %)
#BT RX               : unused 1736 usage 464 / 2200 (21 %)
#BT TX               : unused 1008 usage 528 / 1536 (34 %)
#ble_write_thread_id : unused 688 usage 336 / 1024 (32 %)
#sysworkq            : unused 1912 usage 136 / 2048 (6 %)
#MPSL signal         : unused 928 usage 96 / 1024 (9 %)
#idle 00             : unused 224 usage 96 / 320 (30 %)
#main                : unused 568 usage 456 / 1024 (44 %)
CONFIG_BT_RX_STACK_SIZE=1024
CONFIG_BT_HCI_TX_STACK_SIZE_WITH_PROMPT=y
CONFIG_BT_HCI_TX_STACK_SIZE=640
CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=1536
CONFIG_MPSL_WORK_STACK_SIZE=256
CONFIG_MAIN_STACK_SIZE=864
CONFIG_IDLE_STACK_SIZE=128
CONFIG_ISR_STACK_SIZE=1024
CONFIG_BT_NUS_THREAD_STACK_SIZE=512

# Disable features not needed
CONFIG_TIMESLICING=n
CONFIG_MINIMAL_LIBC_MALLOC=n
CONFIG_LOG=n
CONFIG_ASSERT=n

# Disable Bluetooth features not needed
CONFIG_BT_DEBUG_NONE=y
CONFIG_BT_ASSERT=n
CONFIG_BT_DATA_LEN_UPDATE=n
CONFIG_BT_PHY_UPDATE=n
CONFIG_BT_GATT_CACHING=n
CONFIG_BT_GATT_SERVICE_CHANGED=n
CONFIG_BT_GAP_PERIPHERAL_PREF_PARAMS=n
CONFIG_BT_SETTINGS_CCC_LAZY_LOADING=y
CONFIG_BT_HCI_VS_EXT=n

# Disable Bluetooth controller features not needed
CONFIG_BT_CTLR_PRIVACY=n
CONFIG_BT_CTLR_PHY_2M=n

# Reduce Bluetooth buffers
CONFIG_BT_BUF_EVT_DISCARDABLE_COUNT=1
CONFIG_BT_BUF_EVT_DISCARDABLE_SIZE=43
CONFIG_BT_BUF_EVT_RX_COUNT=2

CONFIG_BT_CONN_TX_MAX=2
CONFIG_BT_L2CAP_TX_BUF_COUNT=2
CONFIG_BT_BUF_ACL_TX_COUNT=3
CONFIG_BT_BUF_ACL_TX_SIZE=27

# Enable timers
CONFIG_TIMER=y
CONFIG_CLOCK_CONTROL_NRF=y

# Enable ADC
CONFIG_ADC=y

CONFIG_BOARD_ENABLE_DCDC=n

CONFIG_RESET_ON_FATAL_ERROR=y
CONFIG_GPIO_AS_PINRESET=n

CONFIG_BT_NUS_SECURITY_ENABLED=n

I've had to make lots of modifications for the device to be able to use BLE.

Also of note, I've had to add a software reset to the board.cmake file to allow the device to run in debug mode.

board_runner_args(nrfjprog "--softreset")

For the present, I've been interfacing with the device using the nRF Connect App for iOS. I would like to note that after a power-on reset, a single advertising packet is sent from the device roughly 15 seconds after power on. Before and after this, no packets are sent. In normal operation, the device advertises every 1.8s.

What I've tried:

  • Adding CONFIG_BOARD_ENABLE_DCDC=n to prj.conf AND board_defconfig with the accompanying code in the Kconfig file at the recommendation of several successful fixes on this forum. No result.
  • Checking return values of every NUS BLE function call, and upon return errors apply NVIC_SystemReset(), No result. I assume this function call does the same as the software reset that is performed by the debugger?
  • Attaching debugger to device following power reset, and upon doing so, it appears that the device is locked in an idle state. No threads are shown in the thread viewer, but I believe this is because of the need to build with optimization for size. Changing the build type to either optimization for speed or optimization for debugging messes with the BLE, and as such I can only use the first option.
  • Changing the NRF Connect SDK version, for some reason no other versions than 2.6.1 and 2.6.2 compile.
  • Adding a main() function that performs a k_thread_resume() on both threads. No result.

If need be, I can add the device tree file as well.

Is there anything I'm not thinking of that I should try in order to get the device to function?

Parents
  • Hi Jacob,

    You should be able to flash your custom board with a simple BLE sample from the SDK and get it to work without too many modifications. If that doesnt work, then it could indicate that there is something wrong with the board design. I see that you have already tried to disable the DC/DC, does this mean that you don't have these components placed on your board? Do you have a LFXO and HFXO crystal? What is the internal capacitance of the crystals, and what is the size of the parallel load capacitors? Maybe you can share the schematics?

    I can make the case private first if you prefer it,

    regards

    Jared 

  • Hi Jared!

    You are correct, I do not have components for the DC/DC converter. I also only have the HFXO, from which I am calibrating the internal RC Oscillator.

    I am on holiday for today and I cannot re-verify some of the examples, though I am fairly certain that I was able to get some samples functioning from just flashing them. Tomorrow I will be back in office, and I will be able to see if they work following the power on reset.

    Please see attached for the MCU schematics. I'd like to keep the case public as long as possible in case anyone else has this problem in the future.


    Furthermore, here is the device defconfig file:

    # Copyright (c) 2024 Nordic Semiconductor ASA
    # SPDX-License-Identifier: Apache-2.0
    
    CONFIG_SOC_SERIES_NRF52X=y
    CONFIG_SOC_NRF52810_QFAA=y
    CONFIG_BOARD_DEV=y
    
    # Enable MPU
    CONFIG_ARM_MPU=y
    
    # Enable hardware stack protection
    CONFIG_HW_STACK_PROTECTION=y
    
    # Enable GPIO
    CONFIG_GPIO=y
    
    # Enable 32KHz internal oscillator since I don't have an external oscillator
    CONFIG_CLOCK_CONTROL_NRF_K32SRC_RC=y
    CONFIG_CLOCK_CONTROL_NRF_K32SRC_RC_CALIBRATION=y
    
    # Enable I2C
    CONFIG_I2C=y
    
    CONFIG_NRF_RTC_TIMER=y
    CONFIG_CLOCK_CONTROL_NRF_K32SRC_RC=y
    CONFIG_CLOCK_CONTROL_NRF_CALIBRATION_LF_ALWAYS_ON=y
    CONFIG_CLOCK_CONTROL_NRF_CALIBRATION_PERIOD=64
    
    CONFIG_COUNTER=y
    
    CONFIG_BT=y
    CONFIG_ADC=y
    
    CONFIG_BOARD_ENABLE_DCDC=n

  • Hi,

    The schematic as well as the project config file looks ok. 

    How many boards did you produce? Do you see the issue on all of the boards? 

    Jacob-Lundstrom said:
    Tomorrow I will be back in office, and I will be able to see if they work following the power on reset.

    That would be great! Could you test both the basic examples such as hello world/blinky and more complex samples such as Bluetooth beacon application or Bluetooth peripheral uart sample. Try to build them with minimal modifications.

    If it works, then we can assume that your custom board is fully functional and this issue is not related to HW.

    regards

    Jared 

  • Jared,

    I'm inclined to believe that the hardware is working, as I am able to flash the device and then remove the debugger from the circuit while retaining functionality. However, when I try to flash the Bluetooth beacon example, the device exhibits the same behavior. Functions after flash, non-functional after power cycling. A Blinky program does the same.

    I have 14 boards built, and I've tried out 3 so far. They all behave the same.  I'll continue to test some more later.

    Another interesting point is that I just tested the Bluetooth beacon sample with the nRF52 DK (PCA10040) and the behavior of the DK is the same as I'm seeing on my custom boards: flash works, sample functions, unresponsive after power cycling.

  • On the off-chance the supply is a coin cell or similar, note a slow voltage rise time on VDD will exhibit the behaviour described as the power-on reset is not a fixed voltage threshold but a capacitively-coupled level inside the nRF52. The debugger or J-Link can override such a lost reset. If using a bench power supply or Li-ion battery then that wouldn't be an issue.

    I2C is enabled; note external pull-ups to SDA and SCL (ie. on a supply different to VDD) will exhibit the same behaviour.

Reply
  • On the off-chance the supply is a coin cell or similar, note a slow voltage rise time on VDD will exhibit the behaviour described as the power-on reset is not a fixed voltage threshold but a capacitively-coupled level inside the nRF52. The debugger or J-Link can override such a lost reset. If using a bench power supply or Li-ion battery then that wouldn't be an issue.

    I2C is enabled; note external pull-ups to SDA and SCL (ie. on a supply different to VDD) will exhibit the same behaviour.

Children
No Data
Related