#include "serial.h" #include "ioport.h" Serial::Serial(ComPort port, BaudRate baud_rate, DataBits data_bits, StopBits stop_bits, Parity parity) : port(port) { // initialize FIFO mode, no irqs for sending, irq if first byte was received // line control, select r/w of divisor latch register writeReg(RegisterIndex::LINE_CONTROL, static_cast(RegisterMask::DIVISOR_LATCH_ACCESS_BIT)); // config divisor uint16_t divisor = static_cast(baud_rate); // write low byte of divisor latch writeReg(RegisterIndex::DIVISOR_LOW, divisor & 0xff); // write high byte writeReg(RegisterIndex::DIVISOR_HIGH, (divisor >> 8) & 0xff); // deselect r/w of divisor latch register // configure line control writeReg(RegisterIndex::LINE_CONTROL, static_cast(data_bits) | static_cast(stop_bits) | static_cast(parity)); // FIFO: Enable & clear buffers writeReg(RegisterIndex::FIFO_CONTROL, static_cast(RegisterMask::ENABLE_FIFO) | static_cast(RegisterMask::CLEAR_RECEIVE_FIFO) | static_cast(RegisterMask::CLEAR_TRANSMIT_FIFO)); // Modem Control: OUT2 (0000 1000) must be set for interrupt writeReg(RegisterIndex::MODEM_CONTROL, static_cast(RegisterMask::OUT_2)); } void Serial::writeReg(RegisterIndex reg, uint8_t out) { IOPort p(static_cast(port) + static_cast(reg)); p.outb(out); } uint8_t Serial::readReg(RegisterIndex reg) { IOPort p(static_cast(port) + static_cast(reg)); return p.inb(); } int Serial::write(uint8_t out) { while ((readReg(RegisterIndex::LINE_STATUS) & static_cast(RegisterMask::TRANSMITTER_EMPTY)) == 0) { } writeReg(RegisterIndex::TRANSMIT_BUFFER, out); return out; }