Serial port driver.
This commit is contained in:
parent
f147ee1901
commit
88982f25cd
4 changed files with 115 additions and 11 deletions
37
prototypes-rework/include/driver/serial.hpp
Normal file
37
prototypes-rework/include/driver/serial.hpp
Normal file
|
@ -0,0 +1,37 @@
|
|||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define SERIAL_COM1 0x3F8
|
||||
#define SERIAL_COM2 0x2F8
|
||||
#define SERIAL_COM3 0x3E8
|
||||
#define SERIAL_COM4 0x2E8
|
||||
|
||||
enum class Partiy
|
||||
{
|
||||
None = 0x0,
|
||||
Even = 0x4,
|
||||
Odd = 0x6,
|
||||
High = 0x5,
|
||||
Low = 0x7,
|
||||
};
|
||||
|
||||
class SerialPort
|
||||
{
|
||||
private:
|
||||
uint16_t mBase;
|
||||
public:
|
||||
SerialPort(
|
||||
uint32_t portBase,
|
||||
uint32_t baud = 9600,
|
||||
Partiy parity = Partiy::None,
|
||||
uint8_t dataBits = 8);
|
||||
|
||||
bool isTransmitEmpty() const;
|
||||
|
||||
bool isReceiveEmpty() const;
|
||||
|
||||
void write(uint8_t c);
|
||||
|
||||
uint8_t read();
|
||||
};
|
12
prototypes-rework/libserial/Makefile
Normal file
12
prototypes-rework/libserial/Makefile
Normal file
|
@ -0,0 +1,12 @@
|
|||
##
|
||||
# Build serial port library.
|
||||
##
|
||||
|
||||
include ../config.mk
|
||||
|
||||
LIBRARY = libserial.a
|
||||
|
||||
all: builddir $(LIBRARY)
|
||||
|
||||
include ../common.mk
|
||||
include ../library.mk
|
66
prototypes-rework/libserial/serial.cpp
Normal file
66
prototypes-rework/libserial/serial.cpp
Normal file
|
@ -0,0 +1,66 @@
|
|||
#include <driver/serial.hpp>
|
||||
#include <io.hpp>
|
||||
|
||||
// Code adapted from:
|
||||
// http://www.lowlevel.eu/wiki/Serielle_Schnittstelle
|
||||
|
||||
#define IER 1
|
||||
#define IIR 2
|
||||
#define FCR 2
|
||||
#define LCR 3
|
||||
#define MCR 4
|
||||
#define LSR 5
|
||||
#define MSR 6
|
||||
|
||||
SerialPort::SerialPort(uint32_t portBase, uint32_t baud, Partiy parity, uint8_t dataBits) :
|
||||
mBase(portBase)
|
||||
{
|
||||
union {
|
||||
uint8_t b[2];
|
||||
uint16_t w;
|
||||
} divisor;
|
||||
divisor.w = 115200 / baud;
|
||||
|
||||
// Interrupt ausschalten
|
||||
outb(this->mBase + IER, 0x00);
|
||||
|
||||
// DLAB-Bit setzen
|
||||
outb(this->mBase + LCR, 0x80);
|
||||
|
||||
// Teiler (low) setzen
|
||||
outb(this->mBase + 0, divisor.b[0]);
|
||||
|
||||
// Teiler (high) setzen
|
||||
outb(this->mBase + 1, divisor.b[1]);
|
||||
|
||||
int iparity = (int)parity;
|
||||
|
||||
// Anzahl Bits, Parität, usw setzen (DLAB zurücksetzen)
|
||||
outb(this->mBase + LCR, ((iparity&0x7)<<3)|((dataBits-5)&0x3));
|
||||
|
||||
// Initialisierung abschließen
|
||||
outb(this->mBase + FCR, 0xC7);
|
||||
outb(this->mBase + MCR, 0x0B);
|
||||
}
|
||||
|
||||
bool SerialPort::isTransmitEmpty() const
|
||||
{
|
||||
return inb(this->mBase + LSR) & 0x20;
|
||||
}
|
||||
|
||||
bool SerialPort::isReceiveEmpty() const
|
||||
{
|
||||
return (inb(this->mBase + LSR) & 1) == 0;
|
||||
}
|
||||
|
||||
void SerialPort::write(uint8_t c)
|
||||
{
|
||||
while (this->isTransmitEmpty() == false);
|
||||
outb(this->mBase, c);
|
||||
}
|
||||
|
||||
uint8_t SerialPort::read()
|
||||
{
|
||||
while (this->isReceiveEmpty());
|
||||
return inb(this->mBase);
|
||||
}
|
|
@ -5,17 +5,6 @@
|
|||
|
||||
#include <driver/video.hpp>
|
||||
|
||||
// Prüft, ob man bereits schreiben kann
|
||||
static uint8_t is_transmit_empty(uint16_t base) {
|
||||
return inb(base+5) & 0x20;
|
||||
}
|
||||
|
||||
// Byte senden
|
||||
static void write_com(uint16_t base, uint8_t chr) {
|
||||
while (is_transmit_empty(base)==0);
|
||||
outb(base,chr);
|
||||
}
|
||||
|
||||
extern "C" void init(multiboot::Structure const & data)
|
||||
{
|
||||
write_com(0x3F8, 'H');
|
||||
|
|
Loading…
Reference in a new issue