#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 writeReg(INTERRUPT_ENABLE_REGISTER, RECEIVED_DATA_AVAILABLE); // line control, select r/w of divisor latch register writeReg(LINE_CONTROL_REGISTER, DIVISOR_LATCH_ACCESS_BIT); writeReg(DIVISOR_LOW_REGISTER, baud_rate & 0xFF); writeReg(DIVISOR_HIGH_REGISTER, (baud_rate>>8) & 0xFF); // also turns DLAB off uint8_t val = parity; val |= stop_bits; val |= data_bits; writeReg(LINE_CONTROL_REGISTER, val); // FIFO: Enable & clear buffers writeReg(FIFO_CONTROL_REGISTER, ENABLE_FIFO | CLEAR_RECEIVE_FIFO | CLEAR_TRANSMIT_FIFO); // Modem Control: OUT2 (0000 1000) must be set for interrupt writeReg(MODEM_CONTROL_REGISTER, OUT_2); } void Serial::writeReg(RegisterIndex reg, char out) { uint16_t addr = port; IOPort iop = IOPort(addr += reg); iop.outb(out); } char Serial::readReg(RegisterIndex reg) { uint16_t addr = port; IOPort iop = IOPort(addr += reg); return iop.inb(); } int Serial::write(char out) { //TODO fix behavior when \r\n ist actually sent if(out == '\n') write('\r'); while(!(readReg(LINE_STATUS_REGISTER) & TRANSMITTER_EMPTY)); writeReg(TRANSMIT_BUFFER_REGISTER, out); return out; }