The UART module does not process arrow (UP, DOWN, LEFT and RIGHT) and other multi-code keys correctly on raspberry pi 4. Such keys function correctly on qemu.
Analysis of the issue
With reference to BCM2711 TRM, when FIFO is disabled by clearing the FEN bit in the LCRH register, FIFO's become just 1-byte deep holding registers for incoming characters from the keyboard. Arrow keys are combination of three 1-byte long ASCII codes for each direction. In qemu, by reading the flags register and extracting a character until RXFE bit is set (RX FIFO non-empty) in a while loop gives correct sequence of characters in the key buffer. However, this approach does not work consistently on hardware. Sometimes only the first character is captured, other times the first two and so on. This undermines the backend developed for arrow keys in the shell program which expects 3 characters in sequence for a given direction key.
On the other hand, when FIFO is enabled by setting the FEN bit, the minimum level configurable via the IFLS register is 4 (1/8th of 32-byte FIFO) which means that the UART interrupt won't be fired until at least 4 characters are sent by the keyboard. This causes serious limitations to the working of the shell as no feedback is seen on the screen until 4 keys are pressed. The interrupt doesn't seem to be configurable for every character inserted into the FIFO buffer, otherwise this would have been the ideal solution for this problem.
The UART module does not process arrow (UP, DOWN, LEFT and RIGHT) and other multi-code keys correctly on raspberry pi 4. Such keys function correctly on qemu.
Analysis of the issue
With reference to BCM2711 TRM, when FIFO is disabled by clearing the FEN bit in the LCRH register, FIFO's become just 1-byte deep holding registers for incoming characters from the keyboard. Arrow keys are combination of three 1-byte long ASCII codes for each direction. In qemu, by reading the flags register and extracting a character until RXFE bit is set (RX FIFO non-empty) in a while loop gives correct sequence of characters in the key buffer. However, this approach does not work consistently on hardware. Sometimes only the first character is captured, other times the first two and so on. This undermines the backend developed for arrow keys in the shell program which expects 3 characters in sequence for a given direction key.
On the other hand, when FIFO is enabled by setting the FEN bit, the minimum level configurable via the IFLS register is 4 (1/8th of 32-byte FIFO) which means that the UART interrupt won't be fired until at least 4 characters are sent by the keyboard. This causes serious limitations to the working of the shell as no feedback is seen on the screen until 4 keys are pressed. The interrupt doesn't seem to be configurable for every character inserted into the FIFO buffer, otherwise this would have been the ideal solution for this problem.