SDConnect on nRF5340 : using UARTE with unknown rx length

I am struggling with the same requirement as this ticket :  RE: NRFX UART RX CONTINUOUS RECEIVE where RX LEN is unknown 

ie receive from a UARTE without knowing in advance how many rx bytes to expect. This is typical for exchanging AT type commands on a UART with another system...the receiver doesn't know how long the command being sent is going to be. In my previous nRF51/nRF52 projects, I just use UART ISR to get each byte, add to my fifo buffer, and detect LF/CR to know when I got a complete line...but this was before SDKConnect and not using UARTE.

Some questions:

 - Using an nRF5340, its seems my only option is to use SDKConnect with Zephyr, yes? No more SoftDevice builds?

- do I understand correctly that the nrf5340 does NOT support basic UART, only UARTE? Only EasyDMA operation is possible (in the same way it doesn't seem to support TWI, only TWIM)

- I have multiple UARTs to service - but if as per the final reply in the ticket above I have to use 2 timers per channel (one to count bytes received, one to do the 'idle line' timeout) it seems I won't have enough timers?

what is the correct way to handle a UART on the nrf5340 for this use case?

Thanks

Brian

btw, I did look at the tutorials, but they are very basic (and use the zephyr driver which uses the same timer mechanism) so weren't much help... But if there is a good sample that is useable for a real application Id be very happy...

Parents
  • Hello,

    Using an nRF5340, its seems my only option is to use SDKConnect with Zephyr, yes? No more SoftDevice builds?

    This is correct. Instead of using the Softdevice which implements the Bluetooth host and Bluetooth controller, we now have a Softdevice controller which typically reside on the network core, and the Zephyr host on the application. Communication between host and controller is through the standard HCI interface. You can read more about the architecture here: https://docs.nordicsemi.com/bundle/ncs-latest/page/nrf/device_guides/nrf53/features_nrf53.html#protocols_and_use_cases_for_the_nrf5340_dk

    - do I understand correctly that the nrf5340 does NOT support basic UART, only UARTE? Only EasyDMA operation is possible (in the same way it doesn't seem to support TWI, only TWIM)

    Yes, the nRF5340 does not include the legacy serial peripherals without easyDMA.

    - I have multiple UARTs to service - but if as per the final reply in the ticket above I have to use 2 timers per channel (one to count bytes received, one to do the 'idle line' timeout) it seems I won't have enough timers?

    The idle timeout timer is a Zephyr timer instance which runs off the system clock (RTC) . Byte counting with a TIMERs and PPI is optional, and is enabled through these Kconfig symbols: https://github.com/nrfconnect/sdk-zephyr/blob/35aedfa532875b79524a00267cdaaa17ca3049f5/drivers/serial/Kconfig.nrfx#L82 

    Best regards,

    Vidar

     https://docs.nordicsemi.com/bundle/ncs-latest/page/zephyr/hardware/peripherals/uart.html 

  • Thanks for the info.

    Looking then at the Zephyr system uart driver implementation  (as per the link):

    - can I use it in  'interrupt driven API' mode on an nRF5340?

    - is there a code example/sample of an application that uses this mode?

    - in this mode, how many UART devices can I open like this simultaneously? (ie does each instance use a resource like a TIMER/PPI to do its byte counting?)

    - how (non)efficient is this mode compared to 'asynchronous API' mode? (in terms of CPU overhead at a specific baud rate when the data is arriving at that rate (ie no idle periods)

    thanks

    Brian

  • Hi Brian,

    Yes, you can use the interrupt-driven API on the nRF53. Usage of this API is demonstrated by the UART echo sample (zephyr/samples/drivers/uart/echo_bot/). You can enable all UART instances with this driver as long as you make sure to not enable other peripherals which share ID with your UARTE instances (Peripherals with shared ID).

    Peripherals sharing ID with UARTE2

    https://docs.nordicsemi.com/bundle/ps_nrf5340/page/chapters/memory/appmem.html#ariaid-title3

    BrianW said:
    how (non)efficient is this mode compared to 'asynchronous API' mode? (in terms of CPU overhead at a specific baud rate when the data is arriving at that rate (ie no idle periods)

    There is some more overhead since it uses smaller DMA buffers, but it's usually not notiecable as long as you use hardware flow control. Without hardware flow control, you will may need to use the async API to acheive reliable reception.

    Best regards,

    Vidar

  • I was not planning to use hardward flow control : do you have an idea at what baud rate it would be neccessary (using the interrupt-driven api)?

    On the 'peripheral shared id' question :

    - the QSPI peripheral for the flash is independant of SPIs 0-4, yes?

    - when using the wifi nRF7002 chip, does this use the SPI peripheral on the NET processor? (and hence does not use up one of the peripherals on the APP processor...)

    thanks

  • The QSPI is completely indepentent and does not share peripheral ID with any of the other peripherals

    I was not planning to use hardward flow control : do you have an idea at what baud rate it would be neccessary (using the interrupt-driven api)?

    Unfortunately, I don't think you will be able to achieve reliable reception with 3 UART instances running concurrently when you don't have HWFC. The async API mitigates this problem as it can work with larger DMA buffers and double-buffering. 

  • The QSPI is completely indepentent and does not share peripheral ID with any of the other peripherals

    Ok, thanks. 

    Unfortunately, I don't think you will be able to achieve reliable reception with 3 UART instances running concurrently when you don't have HWFC. The async API mitigates this problem as it can work with larger DMA buffers and double-buffering. 

    Ok... 

    Is there an api call (zephyr or nrfx-uarte) that allows the application to make the easydma switch to the 2nd buffer without aborting it? This would at least let me check for received data before the buffer is full, without potentially stopping the uarte in the middle of a character....

    - when using the wifi nRF7002 chip, does this use the SPI peripheral on the NET processor? (and hence does not use up one of the peripherals on the APP processor...)

    Any guidance on this one? I haven't started on the wifi operation yet (we are just at PCB schema and component selection...)

  • I don't see the benefit of using the interrupt-driven API over the async API. A third option is to use the nRFX UARTE driver directly if the zephyr drivers don't meet your requirements.

    Any guidance on this one? I haven't started on the wifi operation yet (we are just at PCB schema and component selection...)

    The Wifi stack runs on the application core, and there are specific pins which are dedicated to the QSPI, see https://docs.nordicsemi.com/bundle/ps_nrf5340/page/qspi.html#ariaid-title2 

Reply Children
  • I don't see the benefit of using the interrupt-driven API over the async API. A third option is to use the nRFX UARTE driver directly if the zephyr drivers don't meet your requirements.

    As I said, its for a 'AT command' type exchange:

    ie receive from a UARTE without knowing in advance how many rx bytes to expect. This is typical for exchanging AT type commands on a UART with another system...the receiver doesn't know how long the command being sent is going to be. 

    The end of each block is determined by a CRLF, not by a fixed size. 

    The nrfx UARTE api has the same issue - no event for the RX until the receive buffer is full...

    Hence the typical rx function is exactly like the UART echo example you pointed me towards : check each rx byte and trigger treatment of the line when you see a CR/LF...

    I guess the zephyr interrupt api is implemented as a 1 byte rx buffer, to get an interrupt per byte... 

    The Wifi stack runs on the application core,

    Ok. So it needs to use a general SPI peripheral on the app core to talk to the nrf7002 then? (since the QSPI is going to be used for the flash - there is only 1 QSPI peripheral on the nRF5340, yes?)

    I'm now going to be lacking a serial type peripheral... (3 UART+1TWIM+2 SPI+1 QSPI)....

  • I understand it's for AT commands, but with the async implementation, it seems like you should not have to worry about varying packet lengths. 

    BrianW said:
    Ok. So it needs to use a general SPI peripheral on the app core to talk to the nrf7002 then? (since the QSPI is going to be used for the flash - there is only 1 QSPI peripheral on the nRF5340, yes?)

    Yes, there is only one QSPI peripheral on the device, so it looks like you will be missing one serial peripheral if you only use the app core. 

    Edit: I forgot to add that, depending on the use case, you may be able to use one instance for both SPIM and TWIM. The Zephyr drivers do not support this, but it is possible with the nrfx driver. 

    Edit 2: The nrfx peripheral resource sharing example demonstrates how you can use shared peripherals with the nrfx drivers.

  • Edit 2: The nrfx peripheral resource sharing example demonstrates how you can use shared peripherals with the nrfx drivers.

    Excellent, I should be able to time share between one of my UARTs and the epaper SPIM...

    Thanks! 

  • I'm glad to hear that you may be able to work around this by sharing the same peripheral ID. If possible, it might be easier to share an instance between SPIM and TWIM instead of UART. If all UART instances are going to be used for receiving AT commands, it might be beneficial for them to have the same implementation.

  • One of my UART instances is intended to talk to a ISO7816 smartcard :-)

    The setup for this UART looks it will be fairly customised and definitely different from the AT command exchanges on the other 2 anyway...

    I'm hoping this will work for a basic IOS7816-3 communication (T=0 or T=1), if not it may be more of a bit-bang solution... Any pointers to a example of this operation on a nrf gratefully received! 

Related