Added UART detection and reporting.
This commit is contained in:
parent
0fcaae54c3
commit
bc102b7215
3 changed files with 77 additions and 0 deletions
|
|
@ -10,6 +10,7 @@ stripped to DJGPP-only codepaths and restyled.
|
||||||
|
|
||||||
- ISR-driven receive and transmit with 2048-byte ring buffers
|
- ISR-driven receive and transmit with 2048-byte ring buffers
|
||||||
- Auto-detected IRQ from BIOS data area
|
- Auto-detected IRQ from BIOS data area
|
||||||
|
- UART type detection (8250, 16450, 16550, 16550A)
|
||||||
- 16550 FIFO detection and configurable trigger threshold
|
- 16550 FIFO detection and configurable trigger threshold
|
||||||
- XON/XOFF, RTS/CTS, and DTR/DSR flow control
|
- XON/XOFF, RTS/CTS, and DTR/DSR flow control
|
||||||
- DPMI memory locking for ISR safety
|
- DPMI memory locking for ISR safety
|
||||||
|
|
@ -29,6 +30,16 @@ All functions take a COM port index (`int com`) as their first argument:
|
||||||
| `RS232_COM3` | 2 | COM3 |
|
| `RS232_COM3` | 2 | COM3 |
|
||||||
| `RS232_COM4` | 3 | COM4 |
|
| `RS232_COM4` | 3 | COM4 |
|
||||||
|
|
||||||
|
### UART Types
|
||||||
|
|
||||||
|
| Constant | Value | Description |
|
||||||
|
|---------------------|-------|--------------------------------------|
|
||||||
|
| `RS232_UART_UNKNOWN`| 0 | Unknown or undetected |
|
||||||
|
| `RS232_UART_8250` | 1 | 8250 — no FIFO, no scratch register |
|
||||||
|
| `RS232_UART_16450` | 2 | 16450 — scratch register, no FIFO |
|
||||||
|
| `RS232_UART_16550` | 3 | 16550 — broken FIFO (unusable) |
|
||||||
|
| `RS232_UART_16550A` | 4 | 16550A — working 16-byte FIFO |
|
||||||
|
|
||||||
### Handshaking Modes
|
### Handshaking Modes
|
||||||
|
|
||||||
| Constant | Value | Description |
|
| Constant | Value | Description |
|
||||||
|
|
@ -138,8 +149,18 @@ int rs232GetRts(int com); // RTS line state (0 or 1)
|
||||||
int rs232GetRxBuffered(int com); // Bytes in receive buffer
|
int rs232GetRxBuffered(int com); // Bytes in receive buffer
|
||||||
int rs232GetStop(int com); // Stop bits setting
|
int rs232GetStop(int com); // Stop bits setting
|
||||||
int rs232GetTxBuffered(int com); // Bytes in transmit buffer
|
int rs232GetTxBuffered(int com); // Bytes in transmit buffer
|
||||||
|
int rs232GetUartType(int com); // UART type (RS232_UART_* constant)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
`rs232GetUartType` probes the UART hardware to identify the chip:
|
||||||
|
|
||||||
|
1. **Scratch register test** — writes two values to register 7 and
|
||||||
|
reads them back. The 8250 lacks this register, so readback fails.
|
||||||
|
2. **FIFO test** — enables the FIFO via the FCR, then reads IIR bits
|
||||||
|
7:6. `0b11` = 16550A (working FIFO), `0b10` = 16550 (broken FIFO),
|
||||||
|
`0b00` = 16450 (no FIFO). The original FCR value is restored after
|
||||||
|
probing.
|
||||||
|
|
||||||
#### Setters
|
#### Setters
|
||||||
|
|
||||||
```c
|
```c
|
||||||
|
|
@ -175,6 +196,10 @@ int main(void) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Identify UART chip
|
||||||
|
int uartType = rs232GetUartType(RS232_COM1);
|
||||||
|
// uartType == RS232_UART_16550A on most systems
|
||||||
|
|
||||||
// Blocking send
|
// Blocking send
|
||||||
rs232Write(RS232_COM1, "Hello\r\n", 7);
|
rs232Write(RS232_COM1, "Hello\r\n", 7);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -107,6 +107,7 @@
|
||||||
#define UART_MCR 4
|
#define UART_MCR 4
|
||||||
#define UART_LSR 5
|
#define UART_LSR 5
|
||||||
#define UART_MSR 6
|
#define UART_MSR 6
|
||||||
|
#define UART_SCR 7 // scratch register (not present on 8250)
|
||||||
|
|
||||||
// UART read macros
|
// UART read macros
|
||||||
#define UART_READ_DATA(C) inportb((C)->base + UART_RX)
|
#define UART_READ_DATA(C) inportb((C)->base + UART_RX)
|
||||||
|
|
@ -955,6 +956,49 @@ int rs232GetTxBuffered(int com) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int rs232GetUartType(int com) {
|
||||||
|
Rs232StateT *port = &sComPorts[com];
|
||||||
|
uint8_t scratch;
|
||||||
|
uint8_t iir;
|
||||||
|
|
||||||
|
if (com < COM_MIN || com > COM_MAX) {
|
||||||
|
return RS232_ERR_INVALID_PORT;
|
||||||
|
}
|
||||||
|
if (!port->isOpen) {
|
||||||
|
return RS232_ERR_NOT_OPEN;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test scratch register — 8250 lacks it
|
||||||
|
outportb(port->base + UART_SCR, 0xA5);
|
||||||
|
scratch = inportb(port->base + UART_SCR);
|
||||||
|
if (scratch != 0xA5) {
|
||||||
|
return RS232_UART_8250;
|
||||||
|
}
|
||||||
|
outportb(port->base + UART_SCR, 0x5A);
|
||||||
|
scratch = inportb(port->base + UART_SCR);
|
||||||
|
if (scratch != 0x5A) {
|
||||||
|
return RS232_UART_8250;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Has scratch register — at least 16450. Try enabling FIFO.
|
||||||
|
outportb(port->base + UART_FCR, FCR_ENABLE);
|
||||||
|
iir = inportb(port->base + UART_IIR);
|
||||||
|
|
||||||
|
// Restore original FCR
|
||||||
|
outportb(port->base + UART_FCR, port->fcr);
|
||||||
|
|
||||||
|
// Check IIR bits 7:6 for FIFO status
|
||||||
|
switch (iir & 0xC0) {
|
||||||
|
case 0xC0:
|
||||||
|
return RS232_UART_16550A;
|
||||||
|
case 0x80:
|
||||||
|
return RS232_UART_16550;
|
||||||
|
default:
|
||||||
|
return RS232_UART_16450;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int rs232Open(int com, int32_t bps, int dataBits, char parity, int stopBits, int handshake) {
|
int rs232Open(int com, int32_t bps, int dataBits, char parity, int stopBits, int handshake) {
|
||||||
Rs232StateT *port = &sComPorts[com];
|
Rs232StateT *port = &sComPorts[com];
|
||||||
int rc = RS232_SUCCESS;
|
int rc = RS232_SUCCESS;
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,13 @@
|
||||||
#define RS232_HANDSHAKE_RTSCTS 2
|
#define RS232_HANDSHAKE_RTSCTS 2
|
||||||
#define RS232_HANDSHAKE_DTRDSR 3
|
#define RS232_HANDSHAKE_DTRDSR 3
|
||||||
|
|
||||||
|
// UART Types
|
||||||
|
#define RS232_UART_UNKNOWN 0
|
||||||
|
#define RS232_UART_8250 1
|
||||||
|
#define RS232_UART_16450 2
|
||||||
|
#define RS232_UART_16550 3
|
||||||
|
#define RS232_UART_16550A 4
|
||||||
|
|
||||||
// Error Codes
|
// Error Codes
|
||||||
#define RS232_SUCCESS 0
|
#define RS232_SUCCESS 0
|
||||||
#define RS232_ERR_UNKNOWN -1
|
#define RS232_ERR_UNKNOWN -1
|
||||||
|
|
@ -67,6 +74,7 @@ int rs232GetRts(int com);
|
||||||
int rs232GetRxBuffered(int com);
|
int rs232GetRxBuffered(int com);
|
||||||
int rs232GetStop(int com);
|
int rs232GetStop(int com);
|
||||||
int rs232GetTxBuffered(int com);
|
int rs232GetTxBuffered(int com);
|
||||||
|
int rs232GetUartType(int com);
|
||||||
|
|
||||||
// Read/write
|
// Read/write
|
||||||
int rs232Read(int com, char *data, int len);
|
int rs232Read(int com, char *data, int len);
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue