This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Sending more than one character with NUS leads to crash

Hi!

My setup:

* nRF52 DK

* nRF5_SDK_15.0.0_a53641a

* s132_nrf52_6.0.0

* SES V3.34b 64-bit

* android ver.8 smartphone with nRF Connect

I have implemented the UART service to multiperipheral application but it doesn't work well. I have added required files, made some changes in main.c:

Fullscreen
1
2
3
4
5
6
7
8
#include "ble_nus.h"
#include "app_uart.h"
#if defined (UART_PRESENT)
#include "nrf_uart.h"
#endif
#if defined (UARTE_PRESENT)
#include "nrf_uarte.h"
#endif
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
#define NUS_SERVICE_UUID_TYPE BLE_UUID_TYPE_VENDOR_BEGIN /**< UUID type for the Nordic UART Service (vendor specific). */
#define UART_TX_BUF_SIZE 256 /**< UART TX buffer size. */
#define UART_RX_BUF_SIZE 256 /**< UART RX buffer size. */
static uint16_t m_conn_handle = BLE_CONN_HANDLE_INVALID; /**< Handle of the current connection. */
static uint16_t m_ble_nus_max_data_len = BLE_GATT_ATT_MTU_DEFAULT - 3; /**< Maximum length of data (in bytes) that can be transmitted to the peer by the Nordic UART service module. */
static ble_uuid_t m_adv_uuids[] = /**< Universally unique service identifier. */
{
{BLE_UUID_NUS_SERVICE, NUS_SERVICE_UUID_TYPE}
};
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Fullscreen
1
BLE_NUS_DEF(m_nus, NRF_SDH_BLE_TOTAL_LINK_COUNT); /**< BLE NUS service instance. */
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

just the function from the infocenter:

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
void uart_event_handle(app_uart_evt_t * p_event)
{
static uint8_t data_array[BLE_NUS_MAX_DATA_LEN];
static uint8_t index = 0;
uint32_t err_code;
switch (p_event->evt_type)
{
case APP_UART_DATA_READY:
UNUSED_VARIABLE(app_uart_get(&data_array[index]));
index++;
if ((data_array[index - 1] == '\n') || (index >= (m_ble_nus_max_data_len)))
{
NRF_LOG_DEBUG("Ready to send data over BLE NUS");
NRF_LOG_HEXDUMP_DEBUG(data_array, index);
do
{
uint16_t length = (uint16_t)index;
err_code = ble_nus_data_send(&m_nus, data_array, &length, m_conn_handle);
if ( (err_code != NRF_ERROR_INVALID_STATE) && (err_code != NRF_ERROR_BUSY) &&
(err_code != NRF_ERROR_NOT_FOUND) )
{
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
static void nus_uart_init(void)
{
uint32_t err_code;
app_uart_comm_params_t const comm_params =
{
.rx_pin_no = RX_PIN_NUMBER,
.tx_pin_no = TX_PIN_NUMBER,
.rts_pin_no = RTS_PIN_NUMBER,
.cts_pin_no = CTS_PIN_NUMBER,
.flow_control = APP_UART_FLOW_CONTROL_DISABLED,
.use_parity = false,
#if defined (UART_PRESENT)
.baud_rate = NRF_UART_BAUDRATE_115200
#else
.baud_rate = NRF_UARTE_BAUDRATE_115200
#endif
};
APP_UART_FIFO_INIT(&comm_params,
UART_RX_BUF_SIZE,
UART_TX_BUF_SIZE,
uart_event_handle,
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
static void nus_data_handler(ble_nus_evt_t * p_evt)
{
if (p_evt->type == BLE_NUS_EVT_RX_DATA)
{
uint32_t err_code;
NRF_LOG_DEBUG("Received data from BLE NUS. Writing data on UART.");
NRF_LOG_HEXDUMP_DEBUG(p_evt->params.rx_data.p_data, p_evt->params.rx_data.length);
for (uint32_t i = 0; i < p_evt->params.rx_data.length; i++)
{
do
{
err_code = app_uart_put(p_evt->params.rx_data.p_data[i]);
if ((err_code != NRF_SUCCESS) && (err_code != NRF_ERROR_BUSY))
{
NRF_LOG_ERROR("Failed receiving NUS message. Error 0x%x. ", err_code);
APP_ERROR_CHECK(err_code);
}
} while (err_code == NRF_ERROR_BUSY);
}
if (p_evt->params.rx_data.p_data[p_evt->params.rx_data.length - 1] == '\r')
{
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

adding NUS to LBS:

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/**@brief Function for initializing services that will be used by the application.
*/
static void services_init(void)
{
ret_code_t err_code;
ble_lbs_init_t init;
ble_nus_init_t nus_init;
nrf_ble_qwr_init_t qwr_init = {0};
// Initialize Queued Write Module instances.
qwr_init.error_handler = nrf_qwr_error_handler;
for (uint32_t i = 0; i < LINK_TOTAL; i++)
{
err_code = nrf_ble_qwr_init(&m_qwr[i], &qwr_init);
APP_ERROR_CHECK(err_code);
}
// Initialize LBS.
init.led_write_handler = led_write_handler;
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

main:

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
int main(void)
{
bool erase_bonds = true;
// Initialize.
nus_uart_init();
log_init();
NRF_LOG_INFO("______________________");
timers_init();
//alarms_init(); //[pawel] timery dzialaja
leds_init();
buttons_init();
power_management_init();
ble_stack_init();
gap_params_init();
gatt_init();
services_init();
advertising_init();
conn_params_init();
peer_manager_init(&erase_bonds);
// Start execution.
NRF_LOG_INFO("Multiperipheral example started.");
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

and in sdk_config.h (I don't really know which defines to set and which not, so I relied on app_ble_uart example config file):

sdk_config.h (too big file for embedded code so hastebin)

I am able to send only one character (for example "6") through the mobile app with the UART service. The chip is receiving it and printing it in the terminal.

When I try to send more (for example "62") I got crash and reset. Below is the call stack provided by the debugger:

I believe error 0x08 refers to NRF_ERROR_INVALID_STATE.

Any suggestion what may cause such behaviour?