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=y 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?

Related