Hello,
I have implemented a somewhat working RX algorithm for receiving data over UART but I'm looking for a good way to make it more robust. I haven't found any good answers to this in either the forum or the infocenter and I get a little bit confused regrading the driver setup.
My implementation:
- Custom board using nRF52840
- Using the nRF5 SDK v15.0.0.
- Using FreeRTOS, built from the "ble_app_hrs_freertos"-example. (At the moment without BLE stack initialization.)
- Implemented FreeRTOS task for handling UART communication.
- Have a module connected over UART that use AT-commands.
Assumptions:
- As it is AT-commands I always know the ending of the message, though I don't know the length as the reply to one command can be different.
- An example is reading the ID which gives 24 bytes as answer. If there is a failure, the answer is simply "+ERR=x".
- There is a response to every TX, thus I want to have RX after TX.
So far I have tried mostly with the "Serial port library" and I have tried using blocking-mode similar to:
uint32_t received_bytes = 0; err = nrf_serial_write(&serial_uart, tx_tmp, tx_size, NULL, NRF_SERIAL_MAX_TIMEOUT); err = nrf_serial_read(&serial_uart, rx_tmp, 50, &received_bytes, 100);
This does however only work for the first message. The second time I try with nrf_serial_read() I get an error as the handle for the timer is not null, somewhere around line 136 in app_timer_freertos.c (DUH, it is already created). For experimentation I changed to the following in app_timer_create() function in app_timer_freertos.c and now it works (even though I know it is a VERY ugly solution):
if (pinfo->osHandle == NULL) { /* New timer is created */ memset(pinfo, 0, sizeof(app_timer_info_t)); if (mode == APP_TIMER_MODE_SINGLE_SHOT) timer_mode = pdFALSE; else timer_mode = pdTRUE; pinfo->func = timeout_handler; pinfo->osHandle = xTimerCreate(" ", 1000, timer_mode, pinfo, app_timer_callback); if (pinfo->osHandle == NULL) err_code = NRF_ERROR_NULL; } else { xTimerReset(pinfo->osHandle, 100); /* Timer cannot be reinitialized using FreeRTOS API */ //return NRF_ERROR_INVALID_STATE; }
So is this a bug or am I using it totally wrong? Is the approach of using software timers good, or should I change to some other method?
Regards
Robert