From 88982f25cd71538b618f90c2af8820d95a2cd115 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Quei=C3=9Fner?= Date: Sun, 26 Jun 2016 15:48:43 +0200 Subject: [PATCH] Serial port driver. --- prototypes-rework/include/driver/serial.hpp | 37 ++++++++++++ prototypes-rework/libserial/Makefile | 12 ++++ prototypes-rework/libserial/serial.cpp | 66 +++++++++++++++++++++ prototypes-rework/video/src/init.cpp | 11 ---- 4 files changed, 115 insertions(+), 11 deletions(-) create mode 100644 prototypes-rework/include/driver/serial.hpp create mode 100644 prototypes-rework/libserial/Makefile create mode 100644 prototypes-rework/libserial/serial.cpp diff --git a/prototypes-rework/include/driver/serial.hpp b/prototypes-rework/include/driver/serial.hpp new file mode 100644 index 0000000..94b8595 --- /dev/null +++ b/prototypes-rework/include/driver/serial.hpp @@ -0,0 +1,37 @@ +#pragma once + +#include + +#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(); +}; \ No newline at end of file diff --git a/prototypes-rework/libserial/Makefile b/prototypes-rework/libserial/Makefile new file mode 100644 index 0000000..ff22aed --- /dev/null +++ b/prototypes-rework/libserial/Makefile @@ -0,0 +1,12 @@ +## +# Build serial port library. +## + +include ../config.mk + +LIBRARY = libserial.a + +all: builddir $(LIBRARY) + +include ../common.mk +include ../library.mk \ No newline at end of file diff --git a/prototypes-rework/libserial/serial.cpp b/prototypes-rework/libserial/serial.cpp new file mode 100644 index 0000000..381c5fa --- /dev/null +++ b/prototypes-rework/libserial/serial.cpp @@ -0,0 +1,66 @@ +#include +#include + +// 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); +} diff --git a/prototypes-rework/video/src/init.cpp b/prototypes-rework/video/src/init.cpp index 8714602..3c890a7 100644 --- a/prototypes-rework/video/src/init.cpp +++ b/prototypes-rework/video/src/init.cpp @@ -5,17 +5,6 @@ #include -// 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');