Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GPIO UART - Missing characters when sending longer strings #1855

Closed
endlesscoil opened this issue Feb 23, 2017 · 11 comments
Closed

GPIO UART - Missing characters when sending longer strings #1855

endlesscoil opened this issue Feb 23, 2017 · 11 comments

Comments

@endlesscoil
Copy link

endlesscoil commented Feb 23, 2017

After upgrading from the 4.4.x kernel branch to 4.9.x using rpi-update I started noticing missing data on the GPIO UART when transmitting longer strings that are being echoed, character by character, back to the sender.

The initial tests were performed with our circuit board that uses the UART for communication. Normal communication seemed to work fine since in most cases sends to our device are single characters, but one case when we sent a larger configuration string caused missing data to become apparent. This device uses 115200 baud and has had no issues with previous versions of the Pi boards or firmware. See Test #1 below.

In order to eliminate our device firmware as causing the issue I replaced it with a TTL serial adapter connected to my workstation with a simple python script that read and echoed each character it received. See Test #2 below.

The tests were performed simply by pasting a long string into 'screen' that had the UART open. After a certain point the communication breaks in a specific pattern. See comparisons below. It should be noted that none of the missing characters were received by our device or the echo script. I was able to replicate the issue with 9600, 19200, 115200, and 330400 baud. It seems like the lower the baudrate the more consistent the issue. At 9600 baud it happens nearly every time, while 115200 might take a few attempts.

Device: Raspberry Pi 3 Model B
Base image: 2017-01-11-raspbian-jessie-lite.img
Initial kernel version: Linux raspberrypi 4.4.34-v7+ #930 SMP Wed Nov 23 15:20:41 GMT 2016 armv7l GNU/Linux
Upgraded kernel version: Linux raspberrypi 4.9.11-v7+ #971 SMP Mon Feb 20 20:44:55 GMT 2017 armv7l GNU/Linux

Steps performed:

  1. Flashed 2017-01-11-raspbian-jessie-lite.img to SD card
  2. Enable SSH on boot partition
  3. Boot
  4. Removed console=ttyAMA0,115200 from /boot/cmdline.txt
  5. sudo systemctl disable serial-getty@ttyAMA0.service
  6. Added enable_uart=1 to /boot/config.txt
  7. Reboot
  8. Verified device works correctly.
  9. sudo apt-get install rpi-update
  10. sudo rpi-update
  11. Reboot

Test Results #1 (with our device):

Sent: ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890
Received: ABCDEFGHIJKQY7EMU3

Comparison:

ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890
ABCDEFGHIJK     Q       Y       7       E       M       U       3    

Test Results #2 (with echo script):

Sent: ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890
Received: ABCDEFGHIJKLMNOPQRSY7EMU3

Comparison:

ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890
ABCDEFGHIJKLMNOPQRS     Y       7       E       M       U       3       
@JamesH65
Copy link
Contributor

We now use 4.9 as default, and this report seems to be the only one we have had in., so something is awry. Please update to the latest kernel release kernel and retest.

@JamesH65 JamesH65 added the Waiting for external input Waiting for a comment from the originator of the issue, or a collaborator. label May 18, 2017
@endlesscoil
Copy link
Author

So I'm not seeing the issue with my echo script anymore, however I am still seeing it with our device itself. I'll do some more testing and report back.

@endlesscoil
Copy link
Author

Okay, so I think I've made a little progress on this. It appears to be an issue with the mini-uart in the 4.9.x kernel that was not present in the 4.4.x series.

Latest OK Kernel: Linux raspberrypi 4.4.50-v7+ # 970 SMP Mon Feb 20 19:18:29 GMT 2017 armv7l GNU/Linux
Latest Failing Kernel: Linux raspberrypi 4.9.32-v7+ # 1008 SMP Thu Jun 15 17:44:57 BST 2017 armv7l GNU/Linux

Product Test
First, I eliminated our hardware as the source of the issue by testing all three versions that we sell (USB, DB9 Serial, GPIO) using our latest firmware. No issues were seen with the USB or Serial versions.

As for the GPIO version, the error case isn't reproducible by just, for example, holding down a key inside of screen. I've only seen it while sending a "large" amount of data at it. My current real-world test string is 92 characters, however the breaking point seems much smaller than that: anything over 11 characters starts the pattern of missing characters. Maybe the transmit buffer is filling up too fast, at which point the slower clock can no longer keep up with it?

Test String and Echoed Response

Sent: MODE=A&CONFIGBITS=ff04&ADDRESS=18&LRR=N&COM=N&EXP=NNNNN&REL=NNNN&MASK=ffffffff&DEDUPLICATE=N
Received: MODE=A&CONFSD8CPR&fET

Comparison:

MODE=A&CONFIGBITS=ff04&ADDRESS=18&LRR=N&COM=N&EXP=NNNNN&REL=NNNN&MASK=ffffffff&DEDUPLICATE=N
MODE=A&CONF     S       D       8       C       P       R       &       f       E       T

Workaround
I was able to workaround the issue by forcing it back over to the hardware UART by swapping enable_uart=1 for dtoverlay=pi3-miniuart-bt. The issue with missing characters is no longer present at that point. I think this is an acceptable workaround for us, however it still seems like something is wrong with the mini-uart if it previously worked, and it would be nice to allow our users to use the built-in Bluetooth.

Please let me know if you need anything else.

@pelwell
Copy link
Contributor

pelwell commented Jun 16, 2017

Thanks for the update - this is on my queue to look at.

@pelwell
Copy link
Contributor

pelwell commented Jun 16, 2017

The underlying cause is likely to be behind #2052 as well.

@pelwell pelwell added Assigned for implementation/action and removed Waiting for external input Waiting for a comment from the originator of the issue, or a collaborator. labels Jun 16, 2017
@pelwell
Copy link
Contributor

pelwell commented Jun 21, 2017

I have a one line patch that fixes this, but I need a bit longer to understand why it is needed and whether it is the right solution.

@DaveXanatos
Copy link

Thanks, looking forward to testing when available.

pelwell pushed a commit that referenced this issue Jun 22, 2017
The BCM2835 MINI UART has non-standard THRE semantics. Conventionally
the bit means that the FIFO is empty (although there may still be a
byte in the transmit register), but on 2835 it indicates that the FIFO
is not empty. This causes interrupts after every byte is transmitted,
with the FIFO providing some interrupt latency tolerance.

A consequence of this difference is that the usual strategy of writing
multiple bytes into the TX FIFO after checking THRE once is unsafe.
In the worst case of 7 bytes in the FIFO, writing 8 bytes loses all
but the first since by then the FIFO is full.

There is an HFIFO ("Hidden FIFO") bit which is almost what is needed,
but it only adds more bytes while both THRE and TEMT are set, i.e.
when the TX side is completely idle. This is unnecessarily pessimistic.

Add a new special case, predicated on CAP_MINI, that loops until THRE
is no longer set. With this change, the FIFO fills quickly but
subsequent writes are paced by the transmission rate.

See: #1855

Signed-off-by: Phil Elwell <[email protected]>
@pelwell
Copy link
Contributor

pelwell commented Jun 22, 2017

The regression is caused by a bug/difference in the UART hardware exposed by switching to the dedicated upstream AUX UART driver instead of using a generic 16550 driver with a few additional settings.

The 8250/16550 driver supports many different variations on the original 8250 design, with parameters and flags to modify the behaviour. It also supports a number of pre-canned configurations, selected using Device Tree compatible strings.

Linux 4.9 introduced a bcm2835-aux-uart configuration. Because the driver is configured through its own probe function (as opposed to the generic 8250 probe function) its defaults are configured slightly differently. In particular the tx_loadsz value defaults to the fifosize value before the underlying 16550 default value is applied, which for the AUX UART means that the value changes from 1 to 8.

tx_loadsz controls how many bytes are written to the TX FIFO on each attempt - larger values should reduce interrupts and increase line utilisation. Unfortunately the MINI UART has a THRE (TX FIFO "empty") bit that is really means "not full", so writing more than one byte after checking THRE can lead to data loss. Luckily we already have a CAP_MINI flag indicating that we are dealing with a MINI UART, so it is easy to add an extra test within the transmit loop that the FIFO hasn't just gone full.

A patch adding this extra THRE checking is now in rpi-4.9.y and will be in the next firmware release.

pelwell pushed a commit that referenced this issue Jun 22, 2017
The BCM2835 MINI UART has non-standard THRE semantics. Conventionally
the bit means that the FIFO is empty (although there may still be a
byte in the transmit register), but on 2835 it indicates that the FIFO
is not empty. This causes interrupts after every byte is transmitted,
with the FIFO providing some interrupt latency tolerance.

A consequence of this difference is that the usual strategy of writing
multiple bytes into the TX FIFO after checking THRE once is unsafe.
In the worst case of 7 bytes in the FIFO, writing 8 bytes loses all
but the first since by then the FIFO is full.

There is an HFIFO ("Hidden FIFO") bit which is almost what is needed,
but it only adds more bytes while both THRE and TEMT are set, i.e.
when the TX side is completely idle. This is unnecessarily pessimistic.

Add a new special case, predicated on CAP_MINI, that loops until THRE
is no longer set. With this change, the FIFO fills quickly but
subsequent writes are paced by the transmission rate.

See: #1855

Signed-off-by: Phil Elwell <[email protected]>
pelwell pushed a commit that referenced this issue Jun 22, 2017
The BCM2835 MINI UART has non-standard THRE semantics. Conventionally
the bit means that the FIFO is empty (although there may still be a
byte in the transmit register), but on 2835 it indicates that the FIFO
is not empty. This causes interrupts after every byte is transmitted,
with the FIFO providing some interrupt latency tolerance.

A consequence of this difference is that the usual strategy of writing
multiple bytes into the TX FIFO after checking THRE once is unsafe.
In the worst case of 7 bytes in the FIFO, writing 8 bytes loses all
but the first since by then the FIFO is full.

There is an HFIFO ("Hidden FIFO") bit which is almost what is needed,
but it only adds more bytes while both THRE and TEMT are set, i.e.
when the TX side is completely idle. This is unnecessarily pessimistic.

Add a new special case, predicated on CAP_MINI, that loops until THRE
is no longer set. With this change, the FIFO fills quickly but
subsequent writes are paced by the transmission rate.

See: #1855

Signed-off-by: Phil Elwell <[email protected]>
pelwell pushed a commit that referenced this issue Jun 22, 2017
The BCM2835 MINI UART has non-standard THRE semantics. Conventionally
the bit means that the FIFO is empty (although there may still be a
byte in the transmit register), but on 2835 it indicates that the FIFO
is not empty. This causes interrupts after every byte is transmitted,
with the FIFO providing some interrupt latency tolerance.

A consequence of this difference is that the usual strategy of writing
multiple bytes into the TX FIFO after checking THRE once is unsafe.
In the worst case of 7 bytes in the FIFO, writing 8 bytes loses all
but the first since by then the FIFO is full.

There is an HFIFO ("Hidden FIFO") bit which is almost what is needed,
but it only adds more bytes while both THRE and TEMT are set, i.e.
when the TX side is completely idle. This is unnecessarily pessimistic.

Add a new special case, predicated on CAP_MINI, that loops until THRE
is no longer set. With this change, the FIFO fills quickly but
subsequent writes are paced by the transmission rate.

See: #1855

Signed-off-by: Phil Elwell <[email protected]>
popcornmix added a commit to raspberrypi/firmware that referenced this issue Jun 22, 2017
See: raspberrypi/linux#2077

kernel: drm/vc4: tiled scanout
See: raspberrypi/linux#2074

kernel: bcm2708: Drop CMA alignment from FKMS mode as well
See: raspberrypi/linux#2079

kernel: USB: serial: ch341: change initial line-control settings
See: raspberrypi/linux#2075

kernel: serial: 8250: Fix THRE flag usage for CAP_MINI
See: raspberrypi/linux#1855
popcornmix added a commit to Hexxeh/rpi-firmware that referenced this issue Jun 22, 2017
See: raspberrypi/linux#2077

kernel: drm/vc4: tiled scanout
See: raspberrypi/linux#2074

kernel: bcm2708: Drop CMA alignment from FKMS mode as well
See: raspberrypi/linux#2079

kernel: USB: serial: ch341: change initial line-control settings
See: raspberrypi/linux#2075

kernel: serial: 8250: Fix THRE flag usage for CAP_MINI
See: raspberrypi/linux#1855
@popcornmix
Copy link
Collaborator

Latest rpi-update kernel contains @pelwell's latest fix.

@endlesscoil
Copy link
Author

Looks good! The issue is no longer reproducible on my end as of 4.9.33.

Thanks!

@DaveXanatos
Copy link

It is with deep gratitude that I report that after apt-get update, apt-get upgrade and rpi-update, that my serial communications are now working perfectly. My last test was with 89 bytes, and I have found no new artifacts resultant from the update. All my OpenCV, PocketSphinx and other installations are working fine, but now all my cluster nodes can talk to each other. Thank you, very much.

popcornmix pushed a commit that referenced this issue Jun 25, 2017
The BCM2835 MINI UART has non-standard THRE semantics. Conventionally
the bit means that the FIFO is empty (although there may still be a
byte in the transmit register), but on 2835 it indicates that the FIFO
is not empty. This causes interrupts after every byte is transmitted,
with the FIFO providing some interrupt latency tolerance.

A consequence of this difference is that the usual strategy of writing
multiple bytes into the TX FIFO after checking THRE once is unsafe.
In the worst case of 7 bytes in the FIFO, writing 8 bytes loses all
but the first since by then the FIFO is full.

There is an HFIFO ("Hidden FIFO") bit which is almost what is needed,
but it only adds more bytes while both THRE and TEMT are set, i.e.
when the TX side is completely idle. This is unnecessarily pessimistic.

Add a new special case, predicated on CAP_MINI, that loops until THRE
is no longer set. With this change, the FIFO fills quickly but
subsequent writes are paced by the transmission rate.

See: #1855

Signed-off-by: Phil Elwell <[email protected]>
@pelwell pelwell closed this as completed Jun 27, 2017
popcornmix pushed a commit that referenced this issue Jun 27, 2017
The BCM2835 MINI UART has non-standard THRE semantics. Conventionally
the bit means that the FIFO is empty (although there may still be a
byte in the transmit register), but on 2835 it indicates that the FIFO
is not empty. This causes interrupts after every byte is transmitted,
with the FIFO providing some interrupt latency tolerance.

A consequence of this difference is that the usual strategy of writing
multiple bytes into the TX FIFO after checking THRE once is unsafe.
In the worst case of 7 bytes in the FIFO, writing 8 bytes loses all
but the first since by then the FIFO is full.

There is an HFIFO ("Hidden FIFO") bit which is almost what is needed,
but it only adds more bytes while both THRE and TEMT are set, i.e.
when the TX side is completely idle. This is unnecessarily pessimistic.

Add a new special case, predicated on CAP_MINI, that loops until THRE
is no longer set. With this change, the FIFO fills quickly but
subsequent writes are paced by the transmission rate.

See: #1855

Signed-off-by: Phil Elwell <[email protected]>
popcornmix pushed a commit that referenced this issue Jun 30, 2017
The BCM2835 MINI UART has non-standard THRE semantics. Conventionally
the bit means that the FIFO is empty (although there may still be a
byte in the transmit register), but on 2835 it indicates that the FIFO
is not empty. This causes interrupts after every byte is transmitted,
with the FIFO providing some interrupt latency tolerance.

A consequence of this difference is that the usual strategy of writing
multiple bytes into the TX FIFO after checking THRE once is unsafe.
In the worst case of 7 bytes in the FIFO, writing 8 bytes loses all
but the first since by then the FIFO is full.

There is an HFIFO ("Hidden FIFO") bit which is almost what is needed,
but it only adds more bytes while both THRE and TEMT are set, i.e.
when the TX side is completely idle. This is unnecessarily pessimistic.

Add a new special case, predicated on CAP_MINI, that loops until THRE
is no longer set. With this change, the FIFO fills quickly but
subsequent writes are paced by the transmission rate.

See: #1855

Signed-off-by: Phil Elwell <[email protected]>
popcornmix pushed a commit that referenced this issue Jul 4, 2017
The BCM2835 MINI UART has non-standard THRE semantics. Conventionally
the bit means that the FIFO is empty (although there may still be a
byte in the transmit register), but on 2835 it indicates that the FIFO
is not empty. This causes interrupts after every byte is transmitted,
with the FIFO providing some interrupt latency tolerance.

A consequence of this difference is that the usual strategy of writing
multiple bytes into the TX FIFO after checking THRE once is unsafe.
In the worst case of 7 bytes in the FIFO, writing 8 bytes loses all
but the first since by then the FIFO is full.

There is an HFIFO ("Hidden FIFO") bit which is almost what is needed,
but it only adds more bytes while both THRE and TEMT are set, i.e.
when the TX side is completely idle. This is unnecessarily pessimistic.

Add a new special case, predicated on CAP_MINI, that loops until THRE
is no longer set. With this change, the FIFO fills quickly but
subsequent writes are paced by the transmission rate.

See: #1855

Signed-off-by: Phil Elwell <[email protected]>
popcornmix pushed a commit that referenced this issue Jul 6, 2017
The BCM2835 MINI UART has non-standard THRE semantics. Conventionally
the bit means that the FIFO is empty (although there may still be a
byte in the transmit register), but on 2835 it indicates that the FIFO
is not empty. This causes interrupts after every byte is transmitted,
with the FIFO providing some interrupt latency tolerance.

A consequence of this difference is that the usual strategy of writing
multiple bytes into the TX FIFO after checking THRE once is unsafe.
In the worst case of 7 bytes in the FIFO, writing 8 bytes loses all
but the first since by then the FIFO is full.

There is an HFIFO ("Hidden FIFO") bit which is almost what is needed,
but it only adds more bytes while both THRE and TEMT are set, i.e.
when the TX side is completely idle. This is unnecessarily pessimistic.

Add a new special case, predicated on CAP_MINI, that loops until THRE
is no longer set. With this change, the FIFO fills quickly but
subsequent writes are paced by the transmission rate.

See: #1855

Signed-off-by: Phil Elwell <[email protected]>
lategoodbye pushed a commit to lategoodbye/rpi-zero that referenced this issue Jul 9, 2017
The BCM2835 MINI UART has non-standard THRE semantics. Conventionally
the bit means that the FIFO is empty (although there may still be a
byte in the transmit register), but on 2835 it indicates that the FIFO
is not empty. This causes interrupts after every byte is transmitted,
with the FIFO providing some interrupt latency tolerance.

A consequence of this difference is that the usual strategy of writing
multiple bytes into the TX FIFO after checking THRE once is unsafe.
In the worst case of 7 bytes in the FIFO, writing 8 bytes loses all
but the first since by then the FIFO is full.

There is an HFIFO ("Hidden FIFO") bit which is almost what is needed,
but it only adds more bytes while both THRE and TEMT are set, i.e.
when the TX side is completely idle. This is unnecessarily pessimistic.

Add a new special case, predicated on CAP_MINI, that loops until THRE
is no longer set. With this change, the FIFO fills quickly but
subsequent writes are paced by the transmission rate.

See: raspberrypi/linux#1855

Signed-off-by: Phil Elwell <[email protected]>
popcornmix pushed a commit that referenced this issue Jul 12, 2017
The BCM2835 MINI UART has non-standard THRE semantics. Conventionally
the bit means that the FIFO is empty (although there may still be a
byte in the transmit register), but on 2835 it indicates that the FIFO
is not empty. This causes interrupts after every byte is transmitted,
with the FIFO providing some interrupt latency tolerance.

A consequence of this difference is that the usual strategy of writing
multiple bytes into the TX FIFO after checking THRE once is unsafe.
In the worst case of 7 bytes in the FIFO, writing 8 bytes loses all
but the first since by then the FIFO is full.

There is an HFIFO ("Hidden FIFO") bit which is almost what is needed,
but it only adds more bytes while both THRE and TEMT are set, i.e.
when the TX side is completely idle. This is unnecessarily pessimistic.

Add a new special case, predicated on CAP_MINI, that loops until THRE
is no longer set. With this change, the FIFO fills quickly but
subsequent writes are paced by the transmission rate.

See: #1855

Signed-off-by: Phil Elwell <[email protected]>
popcornmix pushed a commit that referenced this issue Jul 13, 2017
The BCM2835 MINI UART has non-standard THRE semantics. Conventionally
the bit means that the FIFO is empty (although there may still be a
byte in the transmit register), but on 2835 it indicates that the FIFO
is not empty. This causes interrupts after every byte is transmitted,
with the FIFO providing some interrupt latency tolerance.

A consequence of this difference is that the usual strategy of writing
multiple bytes into the TX FIFO after checking THRE once is unsafe.
In the worst case of 7 bytes in the FIFO, writing 8 bytes loses all
but the first since by then the FIFO is full.

There is an HFIFO ("Hidden FIFO") bit which is almost what is needed,
but it only adds more bytes while both THRE and TEMT are set, i.e.
when the TX side is completely idle. This is unnecessarily pessimistic.

Add a new special case, predicated on CAP_MINI, that loops until THRE
is no longer set. With this change, the FIFO fills quickly but
subsequent writes are paced by the transmission rate.

See: #1855

Signed-off-by: Phil Elwell <[email protected]>
popcornmix pushed a commit that referenced this issue Jul 13, 2017
The BCM2835 MINI UART has non-standard THRE semantics. Conventionally
the bit means that the FIFO is empty (although there may still be a
byte in the transmit register), but on 2835 it indicates that the FIFO
is not empty. This causes interrupts after every byte is transmitted,
with the FIFO providing some interrupt latency tolerance.

A consequence of this difference is that the usual strategy of writing
multiple bytes into the TX FIFO after checking THRE once is unsafe.
In the worst case of 7 bytes in the FIFO, writing 8 bytes loses all
but the first since by then the FIFO is full.

There is an HFIFO ("Hidden FIFO") bit which is almost what is needed,
but it only adds more bytes while both THRE and TEMT are set, i.e.
when the TX side is completely idle. This is unnecessarily pessimistic.

Add a new special case, predicated on CAP_MINI, that loops until THRE
is no longer set. With this change, the FIFO fills quickly but
subsequent writes are paced by the transmission rate.

See: #1855

Signed-off-by: Phil Elwell <[email protected]>
popcornmix pushed a commit that referenced this issue Jul 16, 2017
The BCM2835 MINI UART has non-standard THRE semantics. Conventionally
the bit means that the FIFO is empty (although there may still be a
byte in the transmit register), but on 2835 it indicates that the FIFO
is not empty. This causes interrupts after every byte is transmitted,
with the FIFO providing some interrupt latency tolerance.

A consequence of this difference is that the usual strategy of writing
multiple bytes into the TX FIFO after checking THRE once is unsafe.
In the worst case of 7 bytes in the FIFO, writing 8 bytes loses all
but the first since by then the FIFO is full.

There is an HFIFO ("Hidden FIFO") bit which is almost what is needed,
but it only adds more bytes while both THRE and TEMT are set, i.e.
when the TX side is completely idle. This is unnecessarily pessimistic.

Add a new special case, predicated on CAP_MINI, that loops until THRE
is no longer set. With this change, the FIFO fills quickly but
subsequent writes are paced by the transmission rate.

See: #1855

Signed-off-by: Phil Elwell <[email protected]>
popcornmix pushed a commit that referenced this issue Jul 16, 2017
The BCM2835 MINI UART has non-standard THRE semantics. Conventionally
the bit means that the FIFO is empty (although there may still be a
byte in the transmit register), but on 2835 it indicates that the FIFO
is not empty. This causes interrupts after every byte is transmitted,
with the FIFO providing some interrupt latency tolerance.

A consequence of this difference is that the usual strategy of writing
multiple bytes into the TX FIFO after checking THRE once is unsafe.
In the worst case of 7 bytes in the FIFO, writing 8 bytes loses all
but the first since by then the FIFO is full.

There is an HFIFO ("Hidden FIFO") bit which is almost what is needed,
but it only adds more bytes while both THRE and TEMT are set, i.e.
when the TX side is completely idle. This is unnecessarily pessimistic.

Add a new special case, predicated on CAP_MINI, that loops until THRE
is no longer set. With this change, the FIFO fills quickly but
subsequent writes are paced by the transmission rate.

See: #1855

Signed-off-by: Phil Elwell <[email protected]>
popcornmix pushed a commit that referenced this issue Jul 21, 2017
The BCM2835 MINI UART has non-standard THRE semantics. Conventionally
the bit means that the FIFO is empty (although there may still be a
byte in the transmit register), but on 2835 it indicates that the FIFO
is not empty. This causes interrupts after every byte is transmitted,
with the FIFO providing some interrupt latency tolerance.

A consequence of this difference is that the usual strategy of writing
multiple bytes into the TX FIFO after checking THRE once is unsafe.
In the worst case of 7 bytes in the FIFO, writing 8 bytes loses all
but the first since by then the FIFO is full.

There is an HFIFO ("Hidden FIFO") bit which is almost what is needed,
but it only adds more bytes while both THRE and TEMT are set, i.e.
when the TX side is completely idle. This is unnecessarily pessimistic.

Add a new special case, predicated on CAP_MINI, that loops until THRE
is no longer set. With this change, the FIFO fills quickly but
subsequent writes are paced by the transmission rate.

See: #1855

Signed-off-by: Phil Elwell <[email protected]>
popcornmix pushed a commit that referenced this issue Jul 21, 2017
The BCM2835 MINI UART has non-standard THRE semantics. Conventionally
the bit means that the FIFO is empty (although there may still be a
byte in the transmit register), but on 2835 it indicates that the FIFO
is not empty. This causes interrupts after every byte is transmitted,
with the FIFO providing some interrupt latency tolerance.

A consequence of this difference is that the usual strategy of writing
multiple bytes into the TX FIFO after checking THRE once is unsafe.
In the worst case of 7 bytes in the FIFO, writing 8 bytes loses all
but the first since by then the FIFO is full.

There is an HFIFO ("Hidden FIFO") bit which is almost what is needed,
but it only adds more bytes while both THRE and TEMT are set, i.e.
when the TX side is completely idle. This is unnecessarily pessimistic.

Add a new special case, predicated on CAP_MINI, that loops until THRE
is no longer set. With this change, the FIFO fills quickly but
subsequent writes are paced by the transmission rate.

See: #1855

Signed-off-by: Phil Elwell <[email protected]>
popcornmix pushed a commit that referenced this issue Jul 29, 2017
The BCM2835 MINI UART has non-standard THRE semantics. Conventionally
the bit means that the FIFO is empty (although there may still be a
byte in the transmit register), but on 2835 it indicates that the FIFO
is not empty. This causes interrupts after every byte is transmitted,
with the FIFO providing some interrupt latency tolerance.

A consequence of this difference is that the usual strategy of writing
multiple bytes into the TX FIFO after checking THRE once is unsafe.
In the worst case of 7 bytes in the FIFO, writing 8 bytes loses all
but the first since by then the FIFO is full.

There is an HFIFO ("Hidden FIFO") bit which is almost what is needed,
but it only adds more bytes while both THRE and TEMT are set, i.e.
when the TX side is completely idle. This is unnecessarily pessimistic.

Add a new special case, predicated on CAP_MINI, that loops until THRE
is no longer set. With this change, the FIFO fills quickly but
subsequent writes are paced by the transmission rate.

See: #1855

Signed-off-by: Phil Elwell <[email protected]>
popcornmix pushed a commit that referenced this issue Aug 8, 2017
The BCM2835 MINI UART has non-standard THRE semantics. Conventionally
the bit means that the FIFO is empty (although there may still be a
byte in the transmit register), but on 2835 it indicates that the FIFO
is not empty. This causes interrupts after every byte is transmitted,
with the FIFO providing some interrupt latency tolerance.

A consequence of this difference is that the usual strategy of writing
multiple bytes into the TX FIFO after checking THRE once is unsafe.
In the worst case of 7 bytes in the FIFO, writing 8 bytes loses all
but the first since by then the FIFO is full.

There is an HFIFO ("Hidden FIFO") bit which is almost what is needed,
but it only adds more bytes while both THRE and TEMT are set, i.e.
when the TX side is completely idle. This is unnecessarily pessimistic.

Add a new special case, predicated on CAP_MINI, that loops until THRE
is no longer set. With this change, the FIFO fills quickly but
subsequent writes are paced by the transmission rate.

See: #1855

Signed-off-by: Phil Elwell <[email protected]>
popcornmix pushed a commit that referenced this issue Aug 10, 2017
The BCM2835 MINI UART has non-standard THRE semantics. Conventionally
the bit means that the FIFO is empty (although there may still be a
byte in the transmit register), but on 2835 it indicates that the FIFO
is not empty. This causes interrupts after every byte is transmitted,
with the FIFO providing some interrupt latency tolerance.

A consequence of this difference is that the usual strategy of writing
multiple bytes into the TX FIFO after checking THRE once is unsafe.
In the worst case of 7 bytes in the FIFO, writing 8 bytes loses all
but the first since by then the FIFO is full.

There is an HFIFO ("Hidden FIFO") bit which is almost what is needed,
but it only adds more bytes while both THRE and TEMT are set, i.e.
when the TX side is completely idle. This is unnecessarily pessimistic.

Add a new special case, predicated on CAP_MINI, that loops until THRE
is no longer set. With this change, the FIFO fills quickly but
subsequent writes are paced by the transmission rate.

See: #1855

Signed-off-by: Phil Elwell <[email protected]>
popcornmix pushed a commit that referenced this issue Aug 13, 2017
The BCM2835 MINI UART has non-standard THRE semantics. Conventionally
the bit means that the FIFO is empty (although there may still be a
byte in the transmit register), but on 2835 it indicates that the FIFO
is not empty. This causes interrupts after every byte is transmitted,
with the FIFO providing some interrupt latency tolerance.

A consequence of this difference is that the usual strategy of writing
multiple bytes into the TX FIFO after checking THRE once is unsafe.
In the worst case of 7 bytes in the FIFO, writing 8 bytes loses all
but the first since by then the FIFO is full.

There is an HFIFO ("Hidden FIFO") bit which is almost what is needed,
but it only adds more bytes while both THRE and TEMT are set, i.e.
when the TX side is completely idle. This is unnecessarily pessimistic.

Add a new special case, predicated on CAP_MINI, that loops until THRE
is no longer set. With this change, the FIFO fills quickly but
subsequent writes are paced by the transmission rate.

See: #1855

Signed-off-by: Phil Elwell <[email protected]>
popcornmix pushed a commit that referenced this issue Aug 13, 2017
The BCM2835 MINI UART has non-standard THRE semantics. Conventionally
the bit means that the FIFO is empty (although there may still be a
byte in the transmit register), but on 2835 it indicates that the FIFO
is not empty. This causes interrupts after every byte is transmitted,
with the FIFO providing some interrupt latency tolerance.

A consequence of this difference is that the usual strategy of writing
multiple bytes into the TX FIFO after checking THRE once is unsafe.
In the worst case of 7 bytes in the FIFO, writing 8 bytes loses all
but the first since by then the FIFO is full.

There is an HFIFO ("Hidden FIFO") bit which is almost what is needed,
but it only adds more bytes while both THRE and TEMT are set, i.e.
when the TX side is completely idle. This is unnecessarily pessimistic.

Add a new special case, predicated on CAP_MINI, that loops until THRE
is no longer set. With this change, the FIFO fills quickly but
subsequent writes are paced by the transmission rate.

See: #1855

Signed-off-by: Phil Elwell <[email protected]>
popcornmix pushed a commit that referenced this issue Aug 23, 2017
The BCM2835 MINI UART has non-standard THRE semantics. Conventionally
the bit means that the FIFO is empty (although there may still be a
byte in the transmit register), but on 2835 it indicates that the FIFO
is not empty. This causes interrupts after every byte is transmitted,
with the FIFO providing some interrupt latency tolerance.

A consequence of this difference is that the usual strategy of writing
multiple bytes into the TX FIFO after checking THRE once is unsafe.
In the worst case of 7 bytes in the FIFO, writing 8 bytes loses all
but the first since by then the FIFO is full.

There is an HFIFO ("Hidden FIFO") bit which is almost what is needed,
but it only adds more bytes while both THRE and TEMT are set, i.e.
when the TX side is completely idle. This is unnecessarily pessimistic.

Add a new special case, predicated on CAP_MINI, that loops until THRE
is no longer set. With this change, the FIFO fills quickly but
subsequent writes are paced by the transmission rate.

See: #1855

Signed-off-by: Phil Elwell <[email protected]>
popcornmix pushed a commit that referenced this issue Aug 25, 2017
The BCM2835 MINI UART has non-standard THRE semantics. Conventionally
the bit means that the FIFO is empty (although there may still be a
byte in the transmit register), but on 2835 it indicates that the FIFO
is not empty. This causes interrupts after every byte is transmitted,
with the FIFO providing some interrupt latency tolerance.

A consequence of this difference is that the usual strategy of writing
multiple bytes into the TX FIFO after checking THRE once is unsafe.
In the worst case of 7 bytes in the FIFO, writing 8 bytes loses all
but the first since by then the FIFO is full.

There is an HFIFO ("Hidden FIFO") bit which is almost what is needed,
but it only adds more bytes while both THRE and TEMT are set, i.e.
when the TX side is completely idle. This is unnecessarily pessimistic.

Add a new special case, predicated on CAP_MINI, that loops until THRE
is no longer set. With this change, the FIFO fills quickly but
subsequent writes are paced by the transmission rate.

See: #1855

Signed-off-by: Phil Elwell <[email protected]>
popcornmix pushed a commit that referenced this issue Aug 30, 2017
The BCM2835 MINI UART has non-standard THRE semantics. Conventionally
the bit means that the FIFO is empty (although there may still be a
byte in the transmit register), but on 2835 it indicates that the FIFO
is not empty. This causes interrupts after every byte is transmitted,
with the FIFO providing some interrupt latency tolerance.

A consequence of this difference is that the usual strategy of writing
multiple bytes into the TX FIFO after checking THRE once is unsafe.
In the worst case of 7 bytes in the FIFO, writing 8 bytes loses all
but the first since by then the FIFO is full.

There is an HFIFO ("Hidden FIFO") bit which is almost what is needed,
but it only adds more bytes while both THRE and TEMT are set, i.e.
when the TX side is completely idle. This is unnecessarily pessimistic.

Add a new special case, predicated on CAP_MINI, that loops until THRE
is no longer set. With this change, the FIFO fills quickly but
subsequent writes are paced by the transmission rate.

See: #1855

Signed-off-by: Phil Elwell <[email protected]>
popcornmix pushed a commit that referenced this issue Sep 8, 2017
The BCM2835 MINI UART has non-standard THRE semantics. Conventionally
the bit means that the FIFO is empty (although there may still be a
byte in the transmit register), but on 2835 it indicates that the FIFO
is not empty. This causes interrupts after every byte is transmitted,
with the FIFO providing some interrupt latency tolerance.

A consequence of this difference is that the usual strategy of writing
multiple bytes into the TX FIFO after checking THRE once is unsafe.
In the worst case of 7 bytes in the FIFO, writing 8 bytes loses all
but the first since by then the FIFO is full.

There is an HFIFO ("Hidden FIFO") bit which is almost what is needed,
but it only adds more bytes while both THRE and TEMT are set, i.e.
when the TX side is completely idle. This is unnecessarily pessimistic.

Add a new special case, predicated on CAP_MINI, that loops until THRE
is no longer set. With this change, the FIFO fills quickly but
subsequent writes are paced by the transmission rate.

See: #1855

Signed-off-by: Phil Elwell <[email protected]>
popcornmix pushed a commit that referenced this issue Sep 13, 2017
The BCM2835 MINI UART has non-standard THRE semantics. Conventionally
the bit means that the FIFO is empty (although there may still be a
byte in the transmit register), but on 2835 it indicates that the FIFO
is not empty. This causes interrupts after every byte is transmitted,
with the FIFO providing some interrupt latency tolerance.

A consequence of this difference is that the usual strategy of writing
multiple bytes into the TX FIFO after checking THRE once is unsafe.
In the worst case of 7 bytes in the FIFO, writing 8 bytes loses all
but the first since by then the FIFO is full.

There is an HFIFO ("Hidden FIFO") bit which is almost what is needed,
but it only adds more bytes while both THRE and TEMT are set, i.e.
when the TX side is completely idle. This is unnecessarily pessimistic.

Add a new special case, predicated on CAP_MINI, that loops until THRE
is no longer set. With this change, the FIFO fills quickly but
subsequent writes are paced by the transmission rate.

See: #1855

Signed-off-by: Phil Elwell <[email protected]>
popcornmix pushed a commit that referenced this issue Sep 14, 2017
The BCM2835 MINI UART has non-standard THRE semantics. Conventionally
the bit means that the FIFO is empty (although there may still be a
byte in the transmit register), but on 2835 it indicates that the FIFO
is not empty. This causes interrupts after every byte is transmitted,
with the FIFO providing some interrupt latency tolerance.

A consequence of this difference is that the usual strategy of writing
multiple bytes into the TX FIFO after checking THRE once is unsafe.
In the worst case of 7 bytes in the FIFO, writing 8 bytes loses all
but the first since by then the FIFO is full.

There is an HFIFO ("Hidden FIFO") bit which is almost what is needed,
but it only adds more bytes while both THRE and TEMT are set, i.e.
when the TX side is completely idle. This is unnecessarily pessimistic.

Add a new special case, predicated on CAP_MINI, that loops until THRE
is no longer set. With this change, the FIFO fills quickly but
subsequent writes are paced by the transmission rate.

See: #1855

Signed-off-by: Phil Elwell <[email protected]>
popcornmix pushed a commit that referenced this issue Sep 22, 2017
The BCM2835 MINI UART has non-standard THRE semantics. Conventionally
the bit means that the FIFO is empty (although there may still be a
byte in the transmit register), but on 2835 it indicates that the FIFO
is not empty. This causes interrupts after every byte is transmitted,
with the FIFO providing some interrupt latency tolerance.

A consequence of this difference is that the usual strategy of writing
multiple bytes into the TX FIFO after checking THRE once is unsafe.
In the worst case of 7 bytes in the FIFO, writing 8 bytes loses all
but the first since by then the FIFO is full.

There is an HFIFO ("Hidden FIFO") bit which is almost what is needed,
but it only adds more bytes while both THRE and TEMT are set, i.e.
when the TX side is completely idle. This is unnecessarily pessimistic.

Add a new special case, predicated on CAP_MINI, that loops until THRE
is no longer set. With this change, the FIFO fills quickly but
subsequent writes are paced by the transmission rate.

See: #1855

Signed-off-by: Phil Elwell <[email protected]>
popcornmix pushed a commit that referenced this issue Oct 29, 2017
The BCM2835 MINI UART has non-standard THRE semantics. Conventionally
the bit means that the FIFO is empty (although there may still be a
byte in the transmit register), but on 2835 it indicates that the FIFO
is not empty. This causes interrupts after every byte is transmitted,
with the FIFO providing some interrupt latency tolerance.

A consequence of this difference is that the usual strategy of writing
multiple bytes into the TX FIFO after checking THRE once is unsafe.
In the worst case of 7 bytes in the FIFO, writing 8 bytes loses all
but the first since by then the FIFO is full.

There is an HFIFO ("Hidden FIFO") bit which is almost what is needed,
but it only adds more bytes while both THRE and TEMT are set, i.e.
when the TX side is completely idle. This is unnecessarily pessimistic.

Add a new special case, predicated on CAP_MINI, that loops until THRE
is no longer set. With this change, the FIFO fills quickly but
subsequent writes are paced by the transmission rate.

See: #1855

Signed-off-by: Phil Elwell <[email protected]>
raspbian-autopush pushed a commit to raspbian-packages/linux-4.9 that referenced this issue Nov 2, 2017
commit 78711c4
Author: Phil Elwell <[email protected]>
Date:   Wed Jun 21 17:19:04 2017 +0100

    serial: 8250: Fix THRE flag usage for CAP_MINI
    
    The BCM2835 MINI UART has non-standard THRE semantics. Conventionally
    the bit means that the FIFO is empty (although there may still be a
    byte in the transmit register), but on 2835 it indicates that the FIFO
    is not empty. This causes interrupts after every byte is transmitted,
    with the FIFO providing some interrupt latency tolerance.
    
    A consequence of this difference is that the usual strategy of writing
    multiple bytes into the TX FIFO after checking THRE once is unsafe.
    In the worst case of 7 bytes in the FIFO, writing 8 bytes loses all
    but the first since by then the FIFO is full.
    
    There is an HFIFO ("Hidden FIFO") bit which is almost what is needed,
    but it only adds more bytes while both THRE and TEMT are set, i.e.
    when the TX side is completely idle. This is unnecessarily pessimistic.
    
    Add a new special case, predicated on CAP_MINI, that loops until THRE
    is no longer set. With this change, the FIFO fills quickly but
    subsequent writes are paced by the transmission rate.
    
    See: raspberrypi/linux#1855
    
    Signed-off-by: Phil Elwell <[email protected]>


Gbp-Pq: Topic rpi
Gbp-Pq: Name rpi_1299_78711c43a7c4458c1da9cff778637da86fe62992.patch
ryncsn pushed a commit to ryncsn/linux-rasp that referenced this issue Nov 21, 2017
The BCM2835 MINI UART has non-standard THRE semantics. Conventionally
the bit means that the FIFO is empty (although there may still be a
byte in the transmit register), but on 2835 it indicates that the FIFO
is not empty. This causes interrupts after every byte is transmitted,
with the FIFO providing some interrupt latency tolerance.

A consequence of this difference is that the usual strategy of writing
multiple bytes into the TX FIFO after checking THRE once is unsafe.
In the worst case of 7 bytes in the FIFO, writing 8 bytes loses all
but the first since by then the FIFO is full.

There is an HFIFO ("Hidden FIFO") bit which is almost what is needed,
but it only adds more bytes while both THRE and TEMT are set, i.e.
when the TX side is completely idle. This is unnecessarily pessimistic.

Add a new special case, predicated on CAP_MINI, that loops until THRE
is no longer set. With this change, the FIFO fills quickly but
subsequent writes are paced by the transmission rate.

See: raspberrypi#1855

Signed-off-by: Phil Elwell <[email protected]>
raspbian-autopush pushed a commit to raspbian-packages/linux-4.9 that referenced this issue Apr 7, 2018
commit 5ac5167
Author: Phil Elwell <[email protected]>
Date:   Wed Jun 21 17:19:04 2017 +0100

    serial: 8250: Fix THRE flag usage for CAP_MINI
    
    The BCM2835 MINI UART has non-standard THRE semantics. Conventionally
    the bit means that the FIFO is empty (although there may still be a
    byte in the transmit register), but on 2835 it indicates that the FIFO
    is not empty. This causes interrupts after every byte is transmitted,
    with the FIFO providing some interrupt latency tolerance.
    
    A consequence of this difference is that the usual strategy of writing
    multiple bytes into the TX FIFO after checking THRE once is unsafe.
    In the worst case of 7 bytes in the FIFO, writing 8 bytes loses all
    but the first since by then the FIFO is full.
    
    There is an HFIFO ("Hidden FIFO") bit which is almost what is needed,
    but it only adds more bytes while both THRE and TEMT are set, i.e.
    when the TX side is completely idle. This is unnecessarily pessimistic.
    
    Add a new special case, predicated on CAP_MINI, that loops until THRE
    is no longer set. With this change, the FIFO fills quickly but
    subsequent writes are paced by the transmission rate.
    
    See: raspberrypi/linux#1855
    
    Signed-off-by: Phil Elwell <[email protected]>


Gbp-Pq: Topic rpi
Gbp-Pq: Name rpi_1301_5ac5167d59228d99bf5e49f7c958e48379f30a6f.patch
raspbian-autopush pushed a commit to raspbian-packages/linux-4.9 that referenced this issue Nov 11, 2018
commit 5ac5167
Author: Phil Elwell <[email protected]>
Date:   Wed Jun 21 17:19:04 2017 +0100

    serial: 8250: Fix THRE flag usage for CAP_MINI
    
    The BCM2835 MINI UART has non-standard THRE semantics. Conventionally
    the bit means that the FIFO is empty (although there may still be a
    byte in the transmit register), but on 2835 it indicates that the FIFO
    is not empty. This causes interrupts after every byte is transmitted,
    with the FIFO providing some interrupt latency tolerance.
    
    A consequence of this difference is that the usual strategy of writing
    multiple bytes into the TX FIFO after checking THRE once is unsafe.
    In the worst case of 7 bytes in the FIFO, writing 8 bytes loses all
    but the first since by then the FIFO is full.
    
    There is an HFIFO ("Hidden FIFO") bit which is almost what is needed,
    but it only adds more bytes while both THRE and TEMT are set, i.e.
    when the TX side is completely idle. This is unnecessarily pessimistic.
    
    Add a new special case, predicated on CAP_MINI, that loops until THRE
    is no longer set. With this change, the FIFO fills quickly but
    subsequent writes are paced by the transmission rate.
    
    See: raspberrypi/linux#1855
    
    Signed-off-by: Phil Elwell <[email protected]>


Gbp-Pq: Topic rpi
Gbp-Pq: Name rpi_1301_5ac5167d59228d99bf5e49f7c958e48379f30a6f.patch
Clome pushed a commit to Clome/ubuntu-kernel that referenced this issue Jul 2, 2024
The BCM2835 MINI UART has non-standard THRE semantics. Conventionally
the bit means that the FIFO is empty (although there may still be a
byte in the transmit register), but on 2835 it indicates that the FIFO
is not empty. This causes interrupts after every byte is transmitted,
with the FIFO providing some interrupt latency tolerance.

A consequence of this difference is that the usual strategy of writing
multiple bytes into the TX FIFO after checking THRE once is unsafe.
In the worst case of 7 bytes in the FIFO, writing 8 bytes loses all
but the first since by then the FIFO is full.

There is an HFIFO ("Hidden FIFO") bit which is almost what is needed,
but it only adds more bytes while both THRE and TEMT are set, i.e.
when the TX side is completely idle. This is unnecessarily pessimistic.

Add a new special case, predicated on CAP_MINI, that loops until THRE
is no longer set. With this change, the FIFO fills quickly but
subsequent writes are paced by the transmission rate.

See: raspberrypi/linux#1855

Signed-off-by: Phil Elwell <[email protected]>
Signed-off-by: Seth Forshee <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants