Handout
This commit is contained in:
55
kernel/arch/serial.cc
Normal file
55
kernel/arch/serial.cc
Normal file
@@ -0,0 +1,55 @@
|
||||
#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<uint8_t>(RegisterMask::DIVISOR_LATCH_ACCESS_BIT));
|
||||
|
||||
// config divisor
|
||||
uint16_t divisor = static_cast<uint16_t>(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<uint8_t>(data_bits) |
|
||||
static_cast<uint8_t>(stop_bits) |
|
||||
static_cast<uint8_t>(parity));
|
||||
|
||||
// FIFO: Enable & clear buffers
|
||||
writeReg(RegisterIndex::FIFO_CONTROL,
|
||||
static_cast<uint8_t>(RegisterMask::ENABLE_FIFO) |
|
||||
static_cast<uint8_t>(RegisterMask::CLEAR_RECEIVE_FIFO) |
|
||||
static_cast<uint8_t>(RegisterMask::CLEAR_TRANSMIT_FIFO));
|
||||
|
||||
// Modem Control: OUT2 (0000 1000) must be set for interrupt
|
||||
writeReg(RegisterIndex::MODEM_CONTROL,
|
||||
static_cast<uint8_t>(RegisterMask::OUT_2));
|
||||
}
|
||||
|
||||
void Serial::writeReg(RegisterIndex reg, uint8_t out) {
|
||||
IOPort p(static_cast<uint16_t>(port) + static_cast<uint16_t>(reg));
|
||||
p.outb(out);
|
||||
}
|
||||
|
||||
uint8_t Serial::readReg(RegisterIndex reg) {
|
||||
IOPort p(static_cast<uint16_t>(port) + static_cast<uint16_t>(reg));
|
||||
return p.inb();
|
||||
}
|
||||
|
||||
int Serial::write(uint8_t out) {
|
||||
while ((readReg(RegisterIndex::LINE_STATUS) &
|
||||
static_cast<uint8_t>(RegisterMask::TRANSMITTER_EMPTY)) == 0) {
|
||||
}
|
||||
|
||||
writeReg(RegisterIndex::TRANSMIT_BUFFER, out);
|
||||
return out;
|
||||
}
|
||||
Reference in New Issue
Block a user