124 lines
4.5 KiB
C
124 lines
4.5 KiB
C
// RS-232 Serial Port Library for DJGPP
|
|
// Ported from DOS Serial Library 1.4 by Karl Stenerud (MIT License)
|
|
//
|
|
// ISR-driven UART communication with ring buffers and flow control.
|
|
// Supports up to 4 simultaneous COM ports with auto-detected IRQ.
|
|
//
|
|
// Architecture:
|
|
// A single ISR (comGeneralIsr) handles all open COM ports. When any
|
|
// UART interrupts, the ISR loops over all open ports draining their
|
|
// FIFOs into per-port ring buffers. The application reads from these
|
|
// buffers at its leisure. This decouples the UART's byte-at-a-time
|
|
// pace from application-level processing.
|
|
//
|
|
// Ring buffers are power-of-2 sized (2048 bytes) so head/tail index
|
|
// wrapping is a single AND, not a modulo -- critical for ISR speed.
|
|
//
|
|
// Flow control (XON/XOFF, RTS/CTS, DTR/DSR) operates entirely within
|
|
// the ISR using watermark thresholds. When the RX buffer is 80% full,
|
|
// we signal the remote to stop; at 20%, we allow it to resume. This
|
|
// prevents buffer overflow without application involvement.
|
|
//
|
|
// The ISR and its data structures are locked in memory via DPMI to
|
|
// prevent page faults during interrupt handling -- a requirement for
|
|
// any ISR running under a DPMI host (DOS extender, Windows, etc.).
|
|
|
|
#ifndef RS232_H
|
|
#define RS232_H
|
|
|
|
#include <stdint.h>
|
|
#include <stdbool.h>
|
|
|
|
// COM Ports
|
|
#define RS232_COM1 0
|
|
#define RS232_COM2 1
|
|
#define RS232_COM3 2
|
|
#define RS232_COM4 3
|
|
|
|
// Handshaking Modes
|
|
#define RS232_HANDSHAKE_NONE 0
|
|
#define RS232_HANDSHAKE_XONXOFF 1
|
|
#define RS232_HANDSHAKE_RTSCTS 2
|
|
#define RS232_HANDSHAKE_DTRDSR 3
|
|
|
|
// UART Types (detected by probing scratch register and FIFO capability)
|
|
// 8250: No scratch register, no FIFO (original IBM PC)
|
|
// 16450: Has scratch register, no FIFO
|
|
// 16550: Has FIFO but it's buggy (rare)
|
|
// 16550A: Has working 16-byte FIFO (most common in 486+ era hardware)
|
|
#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
|
|
#define RS232_SUCCESS 0
|
|
#define RS232_ERR_UNKNOWN -1
|
|
#define RS232_ERR_NOT_OPEN -2
|
|
#define RS232_ERR_ALREADY_OPEN -3
|
|
#define RS232_ERR_NO_UART -4
|
|
#define RS232_ERR_INVALID_PORT -5
|
|
#define RS232_ERR_INVALID_BASE -6
|
|
#define RS232_ERR_INVALID_IRQ -7
|
|
#define RS232_ERR_INVALID_BPS -8
|
|
#define RS232_ERR_INVALID_DATA -9
|
|
#define RS232_ERR_INVALID_PARITY -10
|
|
#define RS232_ERR_INVALID_STOP -11
|
|
#define RS232_ERR_INVALID_HANDSHAKE -12
|
|
#define RS232_ERR_INVALID_FIFO -13
|
|
#define RS232_ERR_NULL_PTR -14
|
|
#define RS232_ERR_IRQ_NOT_FOUND -15
|
|
#define RS232_ERR_LOCK_MEM -16
|
|
|
|
|
|
// Buffer management
|
|
int rs232ClearRxBuffer(int com);
|
|
int rs232ClearTxBuffer(int com);
|
|
|
|
// Open/close
|
|
int rs232Close(int com);
|
|
int rs232Open(int com, int32_t bps, int dataBits, char parity, int stopBits, int handshake);
|
|
|
|
// Getters
|
|
int rs232GetBase(int com);
|
|
int32_t rs232GetBps(int com);
|
|
int rs232GetCts(int com);
|
|
int rs232GetData(int com);
|
|
int rs232GetDsr(int com);
|
|
int rs232GetDtr(int com);
|
|
int rs232GetHandshake(int com);
|
|
int rs232GetIrq(int com);
|
|
int rs232GetLsr(int com);
|
|
int rs232GetMcr(int com);
|
|
int rs232GetMsr(int com);
|
|
char rs232GetParity(int com);
|
|
int rs232GetRts(int com);
|
|
int rs232GetRxBuffered(int com);
|
|
int rs232GetStop(int com);
|
|
int rs232GetTxBuffered(int com);
|
|
int rs232GetUartType(int com);
|
|
|
|
// Read/write
|
|
// rs232Read: non-blocking drain from RX ring buffer, returns bytes read
|
|
// rs232Write: blocking polled write directly to UART THR (bypasses TX buffer)
|
|
// rs232WriteBuf: non-blocking write to TX ring buffer, ISR drains to UART
|
|
int rs232Read(int com, char *data, int len);
|
|
int rs232Write(int com, const char *data, int len);
|
|
int rs232WriteBuf(int com, const char *data, int len);
|
|
|
|
// Setters
|
|
int rs232Set(int com, int32_t bps, int dataBits, char parity, int stopBits, int handshake);
|
|
int rs232SetBase(int com, int base);
|
|
int rs232SetBps(int com, int32_t bps);
|
|
int rs232SetData(int com, int dataBits);
|
|
int rs232SetDtr(int com, bool dtr);
|
|
int rs232SetFifoThreshold(int com, int threshold);
|
|
int rs232SetHandshake(int com, int handshake);
|
|
int rs232SetIrq(int com, int irq);
|
|
int rs232SetMcr(int com, int mcr);
|
|
int rs232SetParity(int com, char parity);
|
|
int rs232SetRts(int com, bool rts);
|
|
int rs232SetStop(int com, int stopBits);
|
|
|
|
#endif
|