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

How does serial handling work? (Goal = append 1.5B of logic high before the start bit)

Hi,

I am trying to figure out how serial handling works. Specific questions bolded below. To the best I can see, what I think happens when transmitting is:

  • NRF_SERIAL_DRV_UART_CONFIG_DEF is called to configure the Tx & Rx pins. --after this configuration happens, do these pins become untouchable by everything except whatever is under the hood in the nordic serial library? ex: if I write separate code to set or clear the Tx or Rx pins does it not have any effect?
  • NRF_SERIAL_BUFFERS_DEF and NRF_SERIAL_QUEUES_DEF create buffer and queue instances --The brief says, "Creates an instance of serial port buffers" (plural). If it is a single instance, how can it be multiple buffers and multiple queues?
  • Based on this post, NRF_SERIAL_CONFIG_DEF is called to configure the port mode (Polling, IRQ, or DMA) & associate buffers, queues, and event handler.
  • NRF_SERIAL_UART_DEF is called to create instance of serial port -- what exactly does this do?
  • a buffer (typically 1 byte) is filled, then empties into a queue (as long as you want it to be). --how are buffers and queues are filled and emptied?
  • When the queue gets full, something happens to cause it to transmit. --what causes transmission to occur? When transmission occurs, does the serial library append a start and stop bit? How & where does this happen? *
  • When transmission is complete, an event is generated, which in turn generates an interrupt and passes the event to the serial event handler. --what specifically generates the event and interrupt / how does the system know that transmission is complete?

Please let me know if any of this is wrong, it probably is.

The only documentation I could find on serial handling is as follows, and doesn't explain the above questions:

1. Serial port library: infocenter.nordicsemi.com/index.jsp

2. UART: https://infocenter.nordicsemi.com/index.jsp?topic=%2Fcom.nordic.infocenter.sdk5.v14.2.0%2Fserial_example.html

How are these two things related? 

I also found this Serial port library example documentation here, but it does not say what the example code folder is called or where it lives in the SDK. Can you please share this info? 

I have two goals: 

1. Transmit a certain set of bytes over and over in a loop (because of gaps in knowledge above, I cannot figure out how to do this yet)

2. Upon every Tx, transmit 1.5 bytes (12 bits) of logic high before start bit is sent

(Suggestions for solving these are welcome!)

For #2, I saw this suggestion (Option 1) here to do it by timing it, but shouldn't I be able to handle this with the serial library? Or do you think if I use the serial library, I will have to modify the library directly?

Thank you so much!

Parents
  • Hello,

    I will attempt to answer every question in your ticket, please let me know if I have missed a question or if anything still should be unclear.

    --after this configuration happens, do these pins become untouchable by everything except whatever is under the hood in the nordic serial library? ex: if I write separate code to set or clear the Tx or Rx pins does it not have any effect?

    You may configure pins using the GPIO HAL after the pins have been initialized by the UART driver. However, I would recommend against this, since this will probably place the driver in an invalid state, resulting in an error.

    --The brief says, "Creates an instance of serial port buffers" (plural). If it is a single instance, how can it be multiple buffers and multiple queues?

    Its is a single instance of a nrf_serial_buffers_t struct being created, but it holds buffers for both TX and RX.

    NRF_SERIAL_UART_DEF is called to create instance of serial port -- what exactly does this do?

    It allocates the memory required for a serial uart port instance. Please see this documentation for details about the contents of this instance.

    a buffer (typically 1 byte) is filled, then empties into a queue (as long as you want it to be). --how are buffers and queues are filled and emptied?

    This happens using the nrf_serial_read and nrf_serial_write functions, please see the serial port abstraction layer API Reference for these functions.
    The UART peripheral will receive and write bytes from the buffers, and the CPU will place things in these buffers using the write and read / other API functions.

    --what causes transmission to occur? When transmission occurs, does the serial library append a start and stop bit? How & where does this happen? *

    This is handled by the UART peripheral, I highly recommend reading this documentation to gain a better understanding of how the transmissions work.
    All these questions are answered in the documentation I linked, but in short: The transmission occur by triggering the UART peripherals STARTTX TASK. The UART peripheral appends stop and start, yes. This all happens in the UART peripheral, once the CPU places things in the TXD buffer and triggers the STARTTX TASK. The STARTTX TASK can also be triggered by other events, through PPI ( no CPU action required to trigger the STARTTX TASK ).
    I think it is important that you note the distinction between the UART peripheral ( hardware ) and the serial library or UART driver ( which is software, interfacing with the UART peripheral ).

    --what specifically generates the event and interrupt / how does the system know that transmission is complete?

    This is also answered in the UART peripheral documentation, but this comes from the UART peripheral. The UART peripheral generates the events.

    Please let me know if any of this is wrong, it probably is.

    The only documentation I could find on serial handling is as follows, and doesn't explain the above questions:

    1. Serial port library: infocenter.nordicsemi.com/index.jsp

    2. UART: https://infocenter.nordicsemi.com/index.jsp?topic=%2Fcom.nordic.infocenter.sdk5.v14.2.0%2Fserial_example.html

    How are these two things related? 

    You are mixing up some terms which leads me to believe that your underlying understanding of UART, the UART peripheral and the different possible ways to communicate through UART ( UART in itself is in fact not a protocol, but a physical interface. ) might need some improvement.
    The link referenced as "1. Serial port library" is also incorrect, and leads to the USBD CDC ACM example - which is not related to UART at all.
    The example you reference as "2. UART" is actually the serial port library example.

    If you are starting out I would recommend reading about what UART is in general, the UART peripheral of the nRF device that you have and lastly the driver API Reference for the driver you will be using ( either the serial port library or the nrfx_uart, I recommend the latter to begin with ). It could also be beneficial to start with the UART peripheral example which demonstrates the basic functionality of the UART peripheral with the UART legacy driver. The UART peripheral example is probably the best place to start, as it is more straight forward than the serial port library.

    1. Transmit a certain set of bytes over and over in a loop (because of gaps in knowledge above, I cannot figure out how to do this yet)

    This is a very good starting point, and perfect for the UART example since it contains a LOOPBACK test. I think you should look at primarily the nrf_drv / nrfx UART driver, when familiarizing with the UART peripheral.

    I suggest that you begin by looking into the UART example and the UART peripheral documentation first, and then you can let me know if you should have any questions or if anything in the example should be unclear. I think you will gain a better understanding by doing this, instead of starting in-medias-res with the serial port library.

    Please do not hesitate to ask if you should encounter any issues or questions!

    Best regards,
    Karl 

  • Thank you so much, Karl, for this extremely detailed answer!

    Sorry about the mixed up links. It seems like a weird bug, the URL that shows up when I load the page after I click on something the sidebar search is different from the URL associated with the page when I click "copy URL", you can see from this screenshots here: 

       This is what I meant to link for serial port library and UART.

    NRF_SERIAL_UART_DEF is called to create instance of serial port -- what exactly does this do?

    It allocates the memory required for a serial uart port instance.

    I see there is an Rx and Tx timer configured here; where can I find more details on how long these timers are set until they time out, plus what happens upon timeout?

    The transmission occur by triggering the UART peripherals STARTTX TASK. The UART peripheral appends stop and start, yes.

    Thank you for the links to the UART documentation and example.The below is from the UART example code, and it seems to print "UART Start!", but none of the commands surrounding this log statement seem to have anything to do with UART. How is the STARTTX task actually triggered? 

Reply
  • Thank you so much, Karl, for this extremely detailed answer!

    Sorry about the mixed up links. It seems like a weird bug, the URL that shows up when I load the page after I click on something the sidebar search is different from the URL associated with the page when I click "copy URL", you can see from this screenshots here: 

       This is what I meant to link for serial port library and UART.

    NRF_SERIAL_UART_DEF is called to create instance of serial port -- what exactly does this do?

    It allocates the memory required for a serial uart port instance.

    I see there is an Rx and Tx timer configured here; where can I find more details on how long these timers are set until they time out, plus what happens upon timeout?

    The transmission occur by triggering the UART peripherals STARTTX TASK. The UART peripheral appends stop and start, yes.

    Thank you for the links to the UART documentation and example.The below is from the UART example code, and it seems to print "UART Start!", but none of the commands surrounding this log statement seem to have anything to do with UART. How is the STARTTX task actually triggered? 

Children
  • nordev said:
    Thank you so much, Karl, for this extremely detailed answer!

    No problem at all, I am happy to help!

    nordev said:
    Sorry about the mixed up links. It seems like a weird bug, the URL that shows up when I load the page after I click on something the sidebar search is different from the URL associated with the page when I click "copy URL", you can see from this screenshots here:

    It is no problem at all - I am not able to see the attached screenshots though, but I think I understand what you meant.
    You will need to use the "copy link" option in the top right corner of the pages, to get the correct links to content inside the Infocenter.

    nordev said:
    I see there is an Rx and Tx timer configured here; where can I find more details on how long these timers are set until they time out, plus what happens upon timeout?

    Not quite - there is no configuration happening here, but an RX and TX timer id is allocated. You need to be precise with the wording here, because it means entirely different things.
    When working with libraries like this, you seldomly need to know when each timer trigger specifically - usually this is either according to your own custom configuration, or according to a protocol specification.
    If you would like to look at what is happening "behind the scenes" of any driver they are available in the SDK directory SDKPATH/modules/nrfx/drivers/src
    So, for example, you might want to take a look at the nrfx_uart.c file, to see what the driver is doing behind the scenes. Again thought, I must say that the whole point of the driver is that you do not necessarily need to understand every part of what is happening behind the scenes in order to use it.
    Going by the API reference documentation for the UART driver will be enough to properly utilize the peripheral, if you already are familiar with the UART peripheral.
    But, having the source code available and knowing where to look can be very helpful in understanding some operations - just do not despair if you take a look at a driver and not necessarily understand much of it right away.
    To familiarize with how to use UART I would instead read up on what the UART peripheral does, and look at existing examples and how they use it.
    Have you successfully run the UART examples loopback test?

    Again, you are referencing the serial port library API Reference. I highly recommend sticking to the UART driver to begin with. The Serial Port library is more sophisticated than the UART one, and you will really benefit from familiarizing with the UART driver before looking into the serial port library.

    nordev said:
    Thank you for the links to the UART documentation and example.The below is from the UART example code, and it seems to print "UART Start!", but none of the commands surrounding this log statement seem to have anything to do with UART. How is the STARTTX task actually triggered? 

    Are you familiar with the NRF logger module? What is happening in those two lines is in fact that the printf statement is sent through UART ( because of the RETARGET definition in the sdk_config.h file ), and the NRF_LOG_INFO message is sent through the RTT debug logger. Please see the answer by my colleague in this ticket regarding retargetting of stdio functions.

    Best regards,
    Karl

Related