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

Serial communication in different modes

I'm implementing communication with an MCU via UART. There are two types of communication – messages, and MCU DFU data. Messages are <256 bytes of data. MCU DFU is >50kb data and is already implemented on the MCU using XModem. When a DFU start message is sent to the MCU from the nRF, the protocol will switch to Xmodem and the nRF will send the MCU DFU data.

We have chosen MIN as the wire protocol for messages as a reliable transport. The MIN C API works as follows:

  • RX: on data received, pass a variable length data buffer to min_poll
  • TX: min_tx_space callback to return available buffer length, min_tx_start, min_tx_byte (multiple calls), and min_tx_finished callbacks to send data

The XModem API works as follows:

  • RX: callback to receive a single byte with timeout
  • TX: callback to send a single byte with timeout

I need to implement these on the nRF. After evaluating the myriad of libraries (UART, UARTE, Serial, libuarte) it seems nrf_libuarte_async is most appropriate for the MIN messages, is this correct?

How can I switch from this async mode of operation to a synchronous mode of operation with XModem?

Parents
  • Hi,

    To me it looks like the nrf_libuarte_async is a good fit for your use case and the MIN protocol, since messages are sent async and the MIN protocol supports messages of different length. 

    I am not sure I understand what you mean when you say you would like to switch to synchronous operation. To me it looks like the synchronous operation required by the XModem protocol is something that must be implemented in your application. Since you know the amount of bytes being sent and (N)ACKs returned it sounds like you can manage without the async timeout handling while in MCU DFU mode. It is possible to uninit the libarute_async and initialize e.g. the libarte_drv lib, then switch back to libuarte_async when done in the MCU DFU mode.

    Regard,
    Håkon

  • Is there an example using libuarte with RTC and timer instead of app timer? It's hitting the ASSERT in nrfx_timer.c:143

    m_cb[p_instance->instance_id].state == NRFX_DRV_STATE_INITIALIZED

  • I was calling nrf_libuarte_async_enable twice, there should probably be a check in nrf_libuarte_async_enable for this.

  • Which SDK are you using?
    In SDK 16.0.0, the example in perhipheral/libuarte uses RTC by default for timeout. The selection is done in line 60  in main.c

    NRF_LIBUARTE_ASYNC_DEFINE(libuarte, 000, NRF_LIBUARTE_PERIPHERAL_NOT_USED, 2553);
    However, a timer is used as well for counting bytes. 
     
    I was under the impression that nrf_libuarte_async_unitnit(...) would free up all used peripherals. Did you uninitialize using this function before trying to init again?
  • Ah yes, so it does, I got confused with the parameters. That is probably why the IRQ priority issue has gone under the radar.

    Calling nrf_libuarte_async_enable twice was a mistake, but the function does not check if the instance has already been enabled, so the resulting error is confusing.

Reply Children
No Data
Related