blob: 1c613d177570dd84c8b1692763ec7c5ab0294333 [file] [log] [blame]
#include <stdbool.h>
#include <stdio.h>
#include "mystuff.h"
#include "file.h"
#include "io.h"
enum {
THR = 0,
RBR = 0,
DLL = 0,
DLM = 1,
IER = 1,
IIR = 2,
FCR = 2,
LCR = 3,
MCR = 4,
LSR = 5,
MSR = 6,
SCR = 7,
};
int serial_init(struct serial_if *sif)
{
uint16_t port = sif->port;
uint8_t dll, dlm, lcr;
/* Set 115200n81 */
outb(0x83, port + LCR);
outb(0x01, port + DLL);
outb(0x00, port + DLM);
(void)inb(port + IER); /* Synchronize */
dll = inb(port + DLL);
dlm = inb(port + DLM);
lcr = inb(port + LCR);
outb(0x03, port + LCR);
(void)inb(port + IER); /* Synchronize */
if (dll != 0x01 || dlm != 0x00 || lcr != 0x83)
return -1; /* This doesn't look like a serial port */
/* Disable interrupts */
outb(port + IER, 0);
/* Enable 16550A FIFOs if available */
outb(port + FCR, 0x01); /* Enable FIFO */
(void)inb(port + IER); /* Synchronize */
if (inb(port + IIR) < 0xc0)
outb(port + FCR, 0x00); /* Disable FIFOs if non-functional */
(void)inb(port + IER); /* Synchronize */
return 0;
}
void serial_write(struct serial_if *sif, const void *data, size_t n)
{
uint16_t port = sif->port;
const char *p = data;
uint8_t lsr;
while (n--) {
do {
lsr = inb(port + LSR);
} while (!(lsr & 0x20));
outb(*p++, port + THR);
}
}
void serial_read(struct serial_if *sif, void *data, size_t n)
{
uint16_t port = sif->port;
char *p = data;
uint8_t lsr;
while (n--) {
do {
lsr = inb(port + LSR);
} while (!(lsr & 0x01));
*p++ = inb(port + RBR);
}
}