Dear Nordic,
I am implementing firmware on a nRF52840 Development Kit (DK) with the following functionality already implemented:
- BLE: 1 service based on ble_uart, another service based on ble_lbs.
I can send commands from my phone to the DK, which can turn on a LED and start taking measurements.
I send the measurement results to three separate characteristics, which my phone can be notified of.
- Timer1: every second, set a flag
- TWI, in main loop: when timer1 flag is set, receive bytes from sensors on external board
Using:
Segger Embedded Studio
nRF5_SDK_17.1.0
s140 software device
Issue
When debugging the program, after a seemingly random amount of time, I get a J-Link error which stops the debugging operation. Sometimes this takes 1 minute, sometimes 10 minutes.
After the error occurs, I can still send commands and receive values via my phone. My phone (nrf connect app) remains connected. If I send the command to toggle the LED, for example, the device still does so. If the LED was on before the error occured, the LED remains on and can still be turned off when I send the command.
What has me stumped is that I never receive a crashlog nor error message. And I am not sure whether that is simply because the device does not crash/ reset or because I haven't set up the error handling correctly.
I have HARDFAULT_HANDLER_ENABLED 1. I set breakpoints in all the files related to error handling, but it simply does not enter any of the breakpoints before the error happens.
I raised the debug_log levels of all related peripherals to 4 (debug), and the latest log message I receive is:
<warning> TWIM: Function: nrfx_twim_xfer, error code: NRF_SUCCESS.
<debug> TWIM: TWIM: Event: NRF_TWIM_EVENT_STOPPED.
<debug> nrf_sdh_ble: BLE event: 0x57.
Which is similiar to normal operations. The BLE event is always the last message.
I am, however, not sure if a function that includes NRF_LOG_FINAL_FLUSH() is ever called, so I might be missing debug information here.
Main Loop
for (;;)
{
idle_state_handle();
// Idle_state_handle puts the device to sleep UNTIL an event occurs. This event can be any interrupt, such as the Timer or Bluetooth module.
// The device effectively halts at idle_state_handle(). After an interrupt, the following code is handled until it is stopped by the idle_state_handle() again.
// Therefore: after the device gets out of idle state, check if the interrupt source was the timer (which sets b_timer_ticked = true), and initiate measurements.
if(b_take_measurements && b_timer_ticked)
{
timer_tick_counter++;
#ifndef NDEBUG
NRF_LOG_DEBUG("Loop Timer Tick Count: %d", timer_tick_counter);
#endif
// Read ADC hydrogen data, process into bytes, Start new measurement and send data.
hydrogen_value = ads1114_read_data(&m_twi, &twi_transfer_done);
float_to_bytes(hydrogen_value, hydrogen_send_array);
err_code = ble_nus_data_send_hydrogen(&m_nus, hydrogen_send_array, &hydrogen_send_array_size, m_conn_handle);
ads1114_configure(&m_twi, &twi_transfer_done); //NOTE; configure also starts a measurement and points to measurement
compare_hydrogen_threshold(hydrogen_value);
//NOTE: Every 4th tick, a humidity and temperature reading will be performed
//HDC1080 datasheet recommends measurements every 500 ms
//Timer is configured for 125 ms, 4 timer ticks is 500 ms
if(timer_tick_counter >= 4)
{
hdc1080_readings_t measurements = hdc1080_read_measurements(&m_twi, &twi_transfer_done);
hdc1080_start_conversion(&m_twi, &twi_transfer_done);
// Separate temperature into bytes to Bluetooth array and send
float_to_bytes(measurements.temperature, temperature_send_array);
err_code = ble_nus_data_send_temperature(&m_nus, temperature_send_array, &temperature_send_array_size, m_conn_handle);
// Separate humidity into bytes to Bluetooth array and send
float_to_bytes(measurements.humidity, humidity_send_array);
err_code = ble_nus_data_send_humidity(&m_nus, humidity_send_array, &humidity_send_array_size, m_conn_handle);
timer_tick_counter = 0;
}
b_timer_ticked = false;
}
}
Includes
#include <stdint.h>
#include <string.h>
#include "nordic_common.h"
#include "nrf.h"
#include "ble_hci.h"
#include "ble_advdata.h"
#include "ble_advertising.h"
#include "ble_conn_params.h"
#include "nrf_sdh.h"
#include "nrf_sdh_soc.h"
#include "nrf_sdh_ble.h"
#include "nrf_ble_gatt.h"
#include "nrf_ble_qwr.h"
#include "app_timer.h"
#include "ble_nus.h"
#include "app_uart.h"
#include "app_util_platform.h"
#include "bsp_btn_ble.h"
#include "nrf_pwr_mgmt.h"
//manually added
#include "nrf_drv_twi.h"
#include "nrf_drv_timer.h"
#include "nrf_log.h"
#include "nrf_log_ctrl.h"
#include "nrf_log_default_backends.h"
#include "ads1114.h"
#include "ad5144a.h"
#include "hdc1080.h"
#include "gasena_ble_command_service.h"
Please find attached my sdk_config.h
Questions
1. Could you please assist me with figuring out the root of this issue? I realise it might be Segger related, but I feel like my firmware is the culprit here.
2. Do you see anything missing in my config file or #includes that could lead to me not handling errors correctly and without log files?
3. Is it possible for the device to reset but still remain connected to my phone, and immediately turn [edit: ON] the LED because of some Bluetooth wizardry? Or should the LED turn off and the device disconnect after debugging has stopped?
Kind regards,