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

Does the UART disable RTS when it sees CTS disabled?

We have two nRF51822 chips ("A" and "B") connected via GPIO pins on our board, communicating via UART using the app_uart SDK module (in APP_UART_FLOW_CONTROL_ENABLED mode). One of the chips ("B") does not need to be active all the time, so it shuts down when it has nothing to do via the following process:

  1. Disable receive via STOPRX task (if data was received when the RXTO event is received, it aborts).
  2. Queue a message over the UART to "A".
  3. Wait for the message to be completely sent.
  4. Suspend the UART via SUSPEND task (effectively just STOPTX since STOPRX already ran).
  5. Power down via sd_power_system_off.

Recently I made some changes to app_uart to register for and pass on the CTS and NCTS events, and I've observed that when "B" set RTS high/disabled via the STOPRX task, "A" appears to do the same. I.e., it seems that when "A" sees CTS go high it takes its RTS high too. It's as if the "SHORT" in nrf51_bitfields called UART_SHORTS_NCTS_STOPRX is automatically enabled, even when NRF_UART0->SHORTS is set to 0.

When I kept RTS low/enabled manually on "A" (using GPIO and not connecting it to the UART), I didn't see it set high when "B" set CTS high, so it seems this is being done by the UART. Can you confirm if this is expected, and if it's documented somewhere and I missed it?

  • Hi

    Yes, I think this is expected behavior. When one device is disabled and sets its RTS high, the other side does the same to indicate it has no data to send. Then when one of the devices has data to send it will set its RTS low and the other device should respond with setting its RTS low, indicating it is ready to receive data.

    I do not see this specified either in the nRF51 Reference Manual. It should be there.

  • No that doesn't make sense to me. The two should be entirely independent of each other. Just because B doesn't want to receive any more data, if A does it should keep RTS low and keep waiting. The only two things which should make A raise its RTS line (telling B to stop sending data) are either

    1. STOPRX being called in A

    2. A buffers 2 received bytes which haven't yet been read.

    You said that as part of B's shutdown sequence it sends data to A, how much is it sending and are you reading it in time? If it sends more than 2 bytes which get buffered than A will raise RTS at that point until they are.

    The only other thing occurs to me is GPIO config. Can you check you do have B's pins configured in the GPIO explicitly as in the manual so B's CTS is an input pin and not an output pin and I would think you want pull disabled. When the system goes into power off mode, the GPIO configuration is what the pins revert to, the UART no-longer controls them. That is the default, input, no pull, but worth checking.

    I note by the way that the manual doesn't even mention SHORTS for the UART, not even the latest version of the manual, although yes I do see them in the bitfields header. Nor do they make much sense to me either. I can't see instantly why a UART would want to stop reception just because it's not clear to send, transmission, possibly, but not reception.

  • That's what I expected too, but reality (as observed through my 'scope and gdb) matches Stefan's answer. Yes, the GPIO pins are set correctly (with RXD and CTS as NOPULL). B is sending 2 bytes and it is being read immediately.

  • That seems rather broken then. Just because B doesn't wish to receive, it should be able to send to A if A still wants to listen. If you wanted a unidirectional communication like that, how would you achieve it if one UART stops receiving just because it's prevented from transmitting.

    Time to get two boards out and try it I think.

  • I guess you can't do unidirectional (without co-operation, at least). Like I said, I am trying it.

Related