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

UART usage - I cannot see the light in the SDK

In advance I would like to say I’m sorry for the frustration that this message reflects…Event though I have been using the UART for some time, adding more functionality makes me search documentation for a UART description, and this makes me really frustrated.

I have what I think is a relatively simple need, I want to use UART0 and UART1 on a nRF32840 (both for some RS485 communication).

 

I do not care if it is NRF_DRV, NRFX or APP layer, anything that can be made to work will do!

 

Originally, I thought that selecting between NRF or NRFX was simple; documents suggest that NRF is legacy and I should use the "new" NRFX layer.

So selecting NRFX_UART_ENABLE would be logical and then including nrfx_uart.c driver file.....

But nothing is that simple with this SDK.... there always seems to be a mess of dependencies between configuration macros and files you need to include. and absolutely nothing that documents it (except heavy reading of header files of course ;-). I would love to see. “If you want this layer, tick this in SDK config and include ….”)

Well initial suggestion as above for NRFX just creates a bunch of errors…. so what is the combination needed...

It seems I can choose between using:

1 nrf_drv_uart

2 nrfx_uart

3 nrfx_uarte

4 app_uart

Can anyone suggest settings that will make just one of these options work, it would be highly appreciated and hopefully spare me a lot of testing and experimentation.

What I’m looking for what is a combination of what should be in SDK Config for

NRFX_UARTE section

NRFX_UART section

NRF_DRV (UART_ENABLED) section

APP_UART_ENABLED (+APP_FIFO_ENABLED) section

And any other sections that have dependencies!

I want to be able to call ???_init, send one or more bytes and receive bytes one by one

Parents
  • Hello,

    I understand your frustratsion, as this seems to be quite confusing for a lot of users since we introduced the nrfx drivers. 

    First, let me say that there is no choice between legacy and nrfx drivers in the examples in the SDK. I believe some of the old drivers are still present, but you will see that all the examples use the nrfx drivers. Now, the confusing part is that the sdk_config.h file includes both the NRFX and the legacy defines. The reason for this was to make the examples easier to port (backward compatibility), but it has caused a lot of confusion.

    You are probably not aware of the file apply_old_config.h, but if you open it, you will see how the different defines are being set. Basically, if the legacy defines are defined, they will overwrite the NRFX_... defines from sdk_config.h. You will however see if you follow the definitions for the driver functions that there is a port layer between the legacy names and the nrfx drivers.

    E.g. nrf_drv_uart_init() calls nrfx_uart_init() or nrfx_uarte_init() depending on the NRF_DRV_UART_WITH_UARTE and NRF_DRV_UART_WITH_UART define.

    My recommendation is that you set all the NRF_UART defines and the NRFX_UART defines in sdk_config.h equal to each other, and take a look in apply_old_config.h.

    There is also an example in the SDK15.3.0\examples\peripheral\serial_uartes that uses both UARTs. You can read about it's description here.

    It should also be possible to use the app_uart library, that is used in e.g. the ble_app_uart example, and add another uart. Just set both the legacy and nrfx defines to be the same. If you do this, which I believe that you have tried, what sort of errors do you encounter?

    Best regards,

    Edvin

Reply
  • Hello,

    I understand your frustratsion, as this seems to be quite confusing for a lot of users since we introduced the nrfx drivers. 

    First, let me say that there is no choice between legacy and nrfx drivers in the examples in the SDK. I believe some of the old drivers are still present, but you will see that all the examples use the nrfx drivers. Now, the confusing part is that the sdk_config.h file includes both the NRFX and the legacy defines. The reason for this was to make the examples easier to port (backward compatibility), but it has caused a lot of confusion.

    You are probably not aware of the file apply_old_config.h, but if you open it, you will see how the different defines are being set. Basically, if the legacy defines are defined, they will overwrite the NRFX_... defines from sdk_config.h. You will however see if you follow the definitions for the driver functions that there is a port layer between the legacy names and the nrfx drivers.

    E.g. nrf_drv_uart_init() calls nrfx_uart_init() or nrfx_uarte_init() depending on the NRF_DRV_UART_WITH_UARTE and NRF_DRV_UART_WITH_UART define.

    My recommendation is that you set all the NRF_UART defines and the NRFX_UART defines in sdk_config.h equal to each other, and take a look in apply_old_config.h.

    There is also an example in the SDK15.3.0\examples\peripheral\serial_uartes that uses both UARTs. You can read about it's description here.

    It should also be possible to use the app_uart library, that is used in e.g. the ble_app_uart example, and add another uart. Just set both the legacy and nrfx defines to be the same. If you do this, which I believe that you have tried, what sort of errors do you encounter?

    Best regards,

    Edvin

Children
  • Thank you for the information !

    As you can see from my comments, from investigation I found out about the "feature" that you have to define both new NRFX and legacy layer identical. Why not automaticially define legacy if required.

    If I, as a new user selects to use the NRFX layer as recommended. Why do I the have to include lagacy layer also if it's just wrapping the new layer. That does seem to be the case. My app does not link without legacy layer included. 

    I find NO EXAMPLES using nrfx layer.

    I can find examples using APP layer (uart) and just now I found the example using the nrf_serial library (but seems to be using legacy layer) in the serial and serial_uartes examples.

    Any information on how to receive an unknown number of characters? I see the info about double buffering, but do not really find any detailed information or examples I can use.

  • So I just found the libaray nrf_serial.c but no documentation ;-(

    Previously I used weeks fighting with the serial port to get it to work properly I wonder why I did not see this library earlier. Maybe because I searched for things that used the nrfx_uart functions.

    It seems to have nice features but no description about what it really can do, so I will look into it.

    Now for serial port you have the choice of:

    1 nrf_drv_uart

    2 nrfx_uart

    3 nrfx_uarte

    4 app_uart

    5 nrf_serial

    What are the differences, limitations, features would be really great to have an overview.

    I still do not know what my best choice are, or which ones to avoid because they will not work. I have to use hours and hours experimenting.

  • And to top your list there is also nrf_libuarte, which would be #6...

    The uart/uarte difference is that uart doesn't use DMA, while uarte does.

    As to the nrfx/legacy defines, what I have done is to first set the defines equal. Then once I have verified that the nrfx driver works, I delete the legacy defines from my project's sdk_config. That way I end up with just one set of defines to configure the peripheral.

    I think you've already discovered that #1-3 are lower level drivers, and #4-6 are the choices for a higher level driver.

    What are the differences, limitations, features would be really great to have an overview.

    I still do not know what my best choice are, or which ones to avoid because they will not work.

    I'd like to see such an overview as well. And more documentation. I think nrf_serial and nrf_libuarte are the newest, so my advice would be to check out those. And if you want to go to the lower level then try nrfx_uarte.

  • Tried out nrf_serial library. But unfortunately again stuck.

    <error> app: ERROR 8 [NRF_ERROR_INVALID_STATE] at ..\..\..\..\..\..\components\libraries\log\src\nrf_log_backend_uart.c:67
    PC at: 0x00030559

    Cant really figure out why.

    In main I only initialize log and timers and then I try to initialize serial library.

    It fails inside nrf_serial_init() in the function nrf_drf_uart_init() when forwarding the call to nrfx_uart_init(). This function seems to get something wrong. Really difficult to see what.

    I have taken all configuration from the example only changed a little:

    NRF_SERIAL_DRV_UART_CONFIG_DEF(m_uart_drv_config,
    RX1_PIN_NUMBER, TX1_PIN_NUMBER,
    0, 0,
    NRF_UART_HWFC_DISABLED, NRF_UART_PARITY_EXCLUDED,
    NRF_UART_BAUDRATE_9600,
    UART_DEFAULT_CONFIG_IRQ_PRIORITY);

    #define SERIAL_FIFO_TX_SIZE 32
    #define SERIAL_FIFO_RX_SIZE 32

    NRF_SERIAL_QUEUES_DEF(serial_queues, SERIAL_FIFO_TX_SIZE, SERIAL_FIFO_RX_SIZE);

    #define SERIAL_BUFF_TX_SIZE 1
    #define SERIAL_BUFF_RX_SIZE 1

    NRF_SERIAL_BUFFERS_DEF(serial_buffs, SERIAL_BUFF_TX_SIZE, SERIAL_BUFF_RX_SIZE);
    NRF_SERIAL_CONFIG_DEF(serial_config, NRF_SERIAL_MODE_IRQ, &serial_queues, &serial_buffs, SerialEventHandler, SerialSleepHandler);
    NRF_SERIAL_UART_DEF(serial_uart, 0);

    And the just calling:

    ret = nrf_serial_init(&serial_uart, &m_uart_drv_config, &serial_config);
    APP_ERROR_CHECK(ret);

    As good as I could, I also copied the sdk_config parameters so all drivers are enabled no instances checked (as in the example).

    Anyone got a clue what I'm missing?

  • Forgot to mention that I am also running with a softdevice.

    How do I control if nrf_serial should use uart or uarte?

Related