Hi,
if the internal buffer is full, a read() returns a steady stream of
zeros until one valid character is received. According to my experiments
this happens if the FT232 receives characters while the device is not
opened. After the 257th byte the device returns overrun errors, which
are translated to zero bytes (with TTY_OVERRUN flag set). The 257 bytes
makes sense because the internal RX FIFO is 256 bytes and there is room
for one more byte in the receive register, before the overrun occurs.
Unfortunately, this happens until one (valid?) character is received.
The FT232RL seems to set the overrun flag and only clears it on the next
received character. This flag is polled every $poll_interval
microseconds and for each single poll there is one zero character placed
in the tty buffer (and the overrun error is incremented).
How to reproduce:
- Connect a FT232RL based adapter (ttyUSB0) to another serial port
(ttyS0) using a null modem cable
- make sure the serial settings are correct
$ stty -F /dev/ttyUSB0 115200 raw -echo clocal
$ stty -F /dev/ttyS0 115200 raw -echo clocal
- open ttyUSB0 at least one time
$ cat /dev/ttyUSB0 (cancel with ^C)
- write 258 bytes to ttyS0
$ dd if=/dev/zero of=/dev/ttyS0 bs=258 count=1
- open and read from ttyUSB0
$ od -A none -t x1 -w1 -v /dev/ttyUSB0
- now you should see some zeros
- write to ttyUSB0 again
$ echo -n hello world > /dev/ttyS0
- there should be more zeros before the "hello world" characters.
Alternatively you could read the overrun count of the icount struct
(ioctl(TIOCGICOUNT)). You can find my example code at [1]:
- setup the ttyS0 and ttyUSB0 like in the example above
- write at least 258 bytes to ttyS0
$ dd if=/dev/zero of=/dev/ttyS0 bs=258 count=1
- read the overrun count of ttyUSB0
$ tty_icount /dev/ttyUSB0
you should see the overrun counter going crazy until you send one
more character.
Before commit cc01f17d5 (USB: ftdi_sio: re-implement read processing)
there was a similar note in the driver:
/* if a parity error is detected you get status packets forever
until a character is sent without a parity error.
This doesn't work well since the application receives a
never ending stream of bad data - even though new data
hasn't been sent. Therefore I (bill) have taken this out.
However - this might make sense for framing errors and so on
so I am leaving the code in for now.
*/
So I guess this is still true for the parity error, but in this case
there will be no character inserted into the tty buffer. Only the
counter will be incremented indefinitely. I guess this is not the
correct behaviour, either?
The first byte of the status packet is compared to a saved
"prev_status", maybe we should do the same for the second byte, too?
Btw. this does not happen if, the adapter is plugged in for the first
time. I see that the open causes issues a reset, I guess this doesn't
reset this error condition.
-michael
[1] https://gist.github.com/mwalle/484dff9249d78664feee17fec970d3cd
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html