perf: batch UART FIFO writes — poll once per 16 bytes instead of per byte
uart_puts: burst-write up to 16 chars before polling LSR uart_puthex: write all 8 hex digits without polling (8 < 16 FIFO depth) Reduces AXI register reads from ~50 to ~3 per CRC output. Each saved poll: -1 uncached AXI read (~390ns)
This commit is contained in:
@@ -16,21 +16,31 @@
|
|||||||
#define UART_THR (*(volatile unsigned char *)0xbf000000)
|
#define UART_THR (*(volatile unsigned char *)0xbf000000)
|
||||||
#define UART_LSR (*(volatile unsigned char *)0xbf000005)
|
#define UART_LSR (*(volatile unsigned char *)0xbf000005)
|
||||||
#define LSR_THRE 0x20
|
#define LSR_THRE 0x20
|
||||||
|
#define UART_FIFO_DEPTH 16
|
||||||
|
|
||||||
static inline void uart_tx(unsigned char c) {
|
static inline void uart_tx(unsigned char c) {
|
||||||
while (!(UART_LSR & LSR_THRE)) {}
|
while (!(UART_LSR & LSR_THRE)) {}
|
||||||
UART_THR = c;
|
UART_THR = c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Burst-write a null-terminated string — polls only when FIFO may be full */
|
||||||
static void uart_puts(const char *s) {
|
static void uart_puts(const char *s) {
|
||||||
while (*s) uart_tx(*s++);
|
int n = 0;
|
||||||
|
while (*s) {
|
||||||
|
UART_THR = *s++;
|
||||||
|
if (++n >= UART_FIFO_DEPTH) {
|
||||||
|
while (!(UART_LSR & LSR_THRE)) {}
|
||||||
|
n = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Write 8 hex digits + suffix in one burst to minimize AXI polls */
|
||||||
static void uart_puthex(unsigned int val) {
|
static void uart_puthex(unsigned int val) {
|
||||||
int i;
|
int i;
|
||||||
for (i = 28; i >= 0; i -= 4) {
|
for (i = 28; i >= 0; i -= 4) {
|
||||||
unsigned char nibble = (val >> i) & 0xF;
|
unsigned char nibble = (val >> i) & 0xF;
|
||||||
uart_tx(nibble < 10 ? '0' + nibble : 'a' + nibble - 10);
|
UART_THR = nibble < 10 ? '0' + nibble : 'a' + nibble - 10;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user