adafruit / Adafruit_BluefruitLE_nRF51

Arduino library for nRF51822-based Adafruit Bluefruit LE modules
197 stars 122 forks source link

flow control not working with hardware serial #34

Open steinerlein opened 7 years ago

steinerlein commented 7 years ago

This has been already been discussed here: https://forums.adafruit.com/viewtopic.php?t=116112

I have also collected some information on the symptoms here: https://github.com/steinerlein/flow_control_test

After investigating a bit further I modified the begin procedure here: https://github.com/adafruit/Adafruit_BluefruitLE_nRF51/commit/6428f12c02d501da698674c4ed6163d7fae17d18

This only solves part of the problem though, as I have found that due to the slow baudrate of 9600 the mcu will continue sending from the TX buffer, even though the RTS line is pulled high by the Bluefriend module. I have tried shrinking the TX buffer to 4 bytes, but that did not work out very well. For this last part I have no solution ready yet.

conoror commented 5 years ago

I realise it is two years later but I'd like to comment on this as I've just seen this myself (although just through code inspection of Adafruit_BluefruitLE_UART.cpp. In the write method, you can see the check of RTS before the call to the relevant serial write(). If that serial write is buffered, this is a pointless check.

SoftwareSerial has no write buffer so this will work. HardwareSerial (or AltSoftSerial for that matter) can buffer 10s of bytes before even the first one is sent. If the nRF51822 de-asserts RTS in the meantime, well, tough. As the OP has seen, the mcu continues sending until the buffer is drained.

This is not Adafruit's fault. Flow control support must be implemented in the HardwareSerial library at point of transmit. And it's not straightforward - you can't block waiting for RTS right there in the serial IRQ so therefore RTS must be done by disabling the TX irq and reenabling it with another RTS triggered IRQ. AltSoftSerial will have a similar issue unless you disable TX buffering and block on RTS...

As an aside, the nrf datasheet says RTS is disasserted when there is 4 bytes left in the RX buffer. With a PIC micro (and presumably an Atmega), serial has a one byte tx buffer and one byte send buffer. So you can queue two bytes immediately in hardware. So I suppose the TX buffer could be shrunk to 2 bytes (not 4) to have a hope of having less than 4 bytes queued when RTS is disasserted? Sounds icky.

The downside of SoftwareSerial is that it blocks everything during any TX or RX (by disabling interrupts as far as I can see) but I don't see how the Adafruit Bluefruit UART will work with anything else without significant library support.

I'd use the SPI version :-)

ladyada commented 5 years ago

yes this is pretty much why we designed the SPI version - UART on nRF51 is iffy :/