diff --git a/drv/b15f.cpp b/drv/b15f.cpp index c58b4eb..edc8c1c 100644 --- a/drv/b15f.cpp +++ b/drv/b15f.cpp @@ -11,24 +11,7 @@ void B15F::init() { std::cout << PRE << "Stelle Verbindung mit Adapter her... " << std::flush; - int code = system(std::string("stty " + std::to_string(BAUDRATE) + " -F " + SERIAL_DEVICE).c_str()); - if(code) - { - throw DriverException("Konnte serielle Verbindung nicht initialisieren. Ist der Adapter angeschlossen?"); - } - - usart = open(SERIAL_DEVICE.c_str(), O_RDWR | O_NOCTTY | O_NDELAY); - struct termios options; - tcgetattr(usart, &options); - options.c_cflag = CS8 | CLOCAL | CREAD; - options.c_iflag = IGNPAR; - options.c_oflag = 0; - options.c_lflag = 0; - options.c_cc[VTIME]=100; // timeout in Dezisekunden - cfsetspeed(&options, BAUDRATE); - tcsetattr(usart, TCSANOW, &options); - tcflush(usart, TCIOFLUSH); // leere Puffer in beiden Richtungen - + usart.openDevice(SERIAL_DEVICE); std::cout << "OK" << std::endl; delay_ms(1); @@ -82,13 +65,13 @@ void B15F::reconnect() void B15F::discard(void) { - tcflush(usart, TCOFLUSH); // leere Ausgangspuffer + usart.clearOutputBuffer(); for(uint8_t i = 0; i < 8; i++) { - writeByte(RQ_DISC); // sende discard Befehl (verwerfe input) + usart.writeByte(RQ_DISC); // sende discard Befehl (verwerfe input) delay_ms((16000 / BAUDRATE) + 1); // warte mindestens eine Millisekunde, gegebenenfalls mehr } - tcflush(usart, TCIFLUSH); // leere Eingangspuffer + usart.clearInputBuffer(); } bool B15F::testConnection() @@ -97,11 +80,11 @@ bool B15F::testConnection() srand(time(NULL)); uint8_t dummy = rand() % 256; - writeByte(RQ_TEST); - writeByte(dummy); + usart.writeByte(RQ_TEST); + usart.writeByte(dummy); - uint8_t aw = readByte(); - uint8_t mirror = readByte(); + uint8_t aw = usart.readByte(); + uint8_t mirror = usart.readByte(); return aw == MSG_OK && mirror == dummy; } @@ -111,10 +94,10 @@ bool B15F::testIntConv() srand(time(NULL)); uint16_t dummy = rand() % (0xFFFF / 3); - writeByte(RQ_INT); - writeInt(dummy); + usart.writeByte(RQ_INT); + usart.writeInt(dummy); - uint16_t aw = readInt(); + uint16_t aw = usart.readInt(); return aw == dummy * 3; } @@ -125,20 +108,20 @@ std::vector B15F::getBoardInfo(void) { std::vector info; - writeByte(RQ_INFO); - uint8_t n = readByte(); + usart.writeByte(RQ_INFO); + uint8_t n = usart.readByte(); while(n--) { - uint8_t len = readByte(); + uint8_t len = usart.readByte(); std::string str; while(len--) - str += static_cast(readByte()); + str += static_cast(usart.readByte()); info.push_back(str); } - uint8_t aw = readByte(); + uint8_t aw = usart.readByte(); if(aw != MSG_OK) throw DriverException("Board Info fehlerhalft"); @@ -156,10 +139,10 @@ bool B15F::digitalWrite0(uint8_t port) { try { - writeByte(RQ_BA0); - writeByte(port); + usart.writeByte(RQ_BA0); + usart.writeByte(port); - uint8_t aw = readByte(); + uint8_t aw = usart.readByte(); return aw == MSG_OK; } catch(DriverException& de) @@ -173,10 +156,10 @@ bool B15F::digitalWrite1(uint8_t port) { try { - writeByte(RQ_BA1); - writeByte(port); + usart.writeByte(RQ_BA1); + usart.writeByte(port); - uint8_t aw = readByte(); + uint8_t aw = usart.readByte(); return aw == MSG_OK; } catch(DriverException& de) @@ -190,8 +173,8 @@ uint8_t B15F::digitalRead0() { try { - writeByte(RQ_BE0); - return readByte(); + usart.writeByte(RQ_BE0); + return usart.readByte(); } catch(DriverException& de) { @@ -204,8 +187,8 @@ uint8_t B15F::digitalRead1() { try { - writeByte(RQ_BE1); - return readByte(); + usart.writeByte(RQ_BE1); + return usart.readByte(); } catch(DriverException& de) { @@ -218,12 +201,12 @@ bool B15F::analogWrite0(uint16_t value) { try { - writeByte(RQ_AA0); + usart.writeByte(RQ_AA0); delay_ms(1); - writeInt(value); + usart.writeInt(value); delay_ms(1); - uint8_t aw = readByte(); + uint8_t aw = usart.readByte(); return aw == MSG_OK; } catch(DriverException& de) @@ -237,10 +220,10 @@ bool B15F::analogWrite1(uint16_t value) { try { - writeByte(RQ_AA1); - writeInt(value); + usart.writeByte(RQ_AA1); + usart.writeInt(value); - uint8_t aw = readByte(); + uint8_t aw = usart.readByte(); return aw == MSG_OK; } catch(DriverException& de) @@ -254,10 +237,10 @@ uint16_t B15F::analogRead(uint8_t channel) { try { - writeByte(RQ_ADC); + usart.writeByte(RQ_ADC); delay_ms(1); - writeByte(channel); - return readInt(); + usart.writeByte(channel); + return usart.readInt(); } catch(DriverException& de) { @@ -273,13 +256,13 @@ bool B15F::analogSequence(uint8_t channel_a, uint16_t* buffer_a, uint32_t offset try { - writeByte(RQ_ADC_DAC_STROKE); - writeByte(channel_a); - writeByte(channel_b); - writeInt(start); - writeInt(static_cast(delta)); - writeInt(count); - uint8_t aw = readByte(); + usart.writeByte(RQ_ADC_DAC_STROKE); + usart.writeByte(channel_a); + usart.writeByte(channel_b); + usart.writeInt(start); + usart.writeInt(static_cast(delta)); + usart.writeInt(count); + uint8_t aw = usart.readByte(); if(aw != MSG_OK) { @@ -290,7 +273,7 @@ bool B15F::analogSequence(uint8_t channel_a, uint16_t* buffer_a, uint32_t offset uint8_t block[5]; // 4 Datenbyte + crc for(uint16_t i = 0; i < count; i++) { - bool crc_ok = readBlock(&block[0], 0); + bool crc_ok = usart.readBlock(&block[0], 0); if (!crc_ok) { @@ -303,7 +286,7 @@ bool B15F::analogSequence(uint8_t channel_a, uint16_t* buffer_a, uint32_t offset buffer_b[offset_b + i] = ((uint16_t) block[2]) | (((uint16_t) block[3]) << 8); } - aw = readByte(); + aw = usart.readByte(); if(aw == MSG_OK) return aw; @@ -317,126 +300,6 @@ bool B15F::analogSequence(uint8_t channel_a, uint16_t* buffer_a, uint32_t offset } } - -void B15F::writeByte(uint8_t b) -{ - if(write(usart, &b, 1) != 1) - throw DriverException("Fehler beim Senden. (byte)"); -} - -void B15F::writeInt(uint16_t v) -{ - if(write(usart, reinterpret_cast(&v), 2) != 2) - throw DriverException("Fehler beim Senden. (int)"); -} - -uint8_t B15F::readByte() -{ - char b; - auto start = std::chrono::steady_clock::now(); - auto end = start; - uint16_t elapsed = 0; - while(elapsed < timeout) - { - int n_ready; - int code = ioctl(usart, FIONREAD, &n_ready); - if(code != 0) - std::cout << PRE << "n_ready code: " << code << std::endl; - - if(n_ready > 0) - { - //std::cout << code << " \tready: " << n_ready << std::endl; - - code = read(usart, &b, 1); - if (code > 0) - return static_cast(b); - if (code < 0) - std::cout << PRE << "usart code: " << code << std::endl; - } - - end = std::chrono::steady_clock::now(); - elapsed = std::chrono::duration_cast(end - start).count(); - } - - if(elapsed >= timeout) - throw DriverException("Verbindung unterbrochen. (timeout)"); -} - -uint16_t B15F::readInt() -{ - return readByte() | readByte() << 8; -} - -bool B15F::readBlock(uint8_t* buffer, uint16_t offset) -{ - uint8_t len = readByte(); - uint8_t crc = 0; - buffer += offset; - - // wait for block - int n_ready; - uint16_t elapsed = 0; - auto start = std::chrono::steady_clock::now(); - auto end = start; - while(elapsed < block_timeout) - { - int code = ioctl(usart, FIONREAD, &n_ready); - if(code != 0) - { - std::cout << PRE << "n_ready code: " << code << std::endl; - return false; - } - - if(n_ready >= len + 1) - break; - - end = std::chrono::steady_clock::now(); - elapsed = std::chrono::duration_cast(end - start).count(); - } - if(elapsed >= timeout) - { - std::cout << PRE << "block timeout: " << std::endl; - return false; - } - - while(len--) - { - *buffer = readByte(); - - crc ^= *buffer++; - for (uint8_t i = 0; i < 8; i++) - { - if (crc & 1) - crc ^= CRC7_POLY; - crc >>= 1; - } - } - - crc ^= readByte(); - for (uint8_t i = 0; i < 8; i++) - { - if (crc & 1) - crc ^= CRC7_POLY; - crc >>= 1; - } - - if(TEST == 1) - crc = 1; - if(TEST > 100) - TEST = 0; - - if (crc == 0) - { - writeByte(MSG_OK); - return true; - } - else - { - writeByte(MSG_FAIL); - return false; - } -} - void B15F::delay_ms(uint16_t ms) { std::this_thread::sleep_for(std::chrono::milliseconds(ms)); diff --git a/drv/b15f.h b/drv/b15f.h index 4d48b21..132c4c8 100644 --- a/drv/b15f.h +++ b/drv/b15f.h @@ -14,6 +14,7 @@ #include #include #include +#include "usart.h" #include "driverexception.h" #include "timeoutexception.h" @@ -59,35 +60,12 @@ public: static B15F& getInstance(void); private: - int usart = -1; uint16_t timeout = 1000; // ms uint16_t block_timeout = 1; // ms - int TEST = 0; + USART usart; static B15F* instance; - - /*********************************************** - * Grundfunktionen für die serielle Verbindung * - ***********************************************/ - - /** - * Übergibt ein Byte an die USART Schnittstelle - */ - void writeByte(uint8_t); - - /** - * Übergibt ein Integer an die USART Schnittstelle - */ - void writeInt(uint16_t); - - /** - * Übergibt ein Integer an die USART Schnittstelle - * \throws TimeoutException - */ - uint8_t readByte(void); - uint16_t readInt(void); - bool readBlock(uint8_t* buffer, uint16_t offset); // CONSTANTS @@ -98,7 +76,6 @@ private: constexpr static uint16_t RECONNECT_TIMEOUT = 64; // ms constexpr static uint8_t RECONNECT_TRIES = 3; constexpr static uint32_t BAUDRATE = 115200; - constexpr static uint8_t CRC7_POLY = 0x91; // REQUESTS constexpr static uint8_t RQ_DISC = 0; diff --git a/drv/b15f.o b/drv/b15f.o index 47f3a9c..5b6d8ec 100644 Binary files a/drv/b15f.o and b/drv/b15f.o differ diff --git a/drv/usart.cpp b/drv/usart.cpp index 554c598..5760d8e 100644 --- a/drv/usart.cpp +++ b/drv/usart.cpp @@ -1,10 +1,6 @@ #include "usart.h" -USART::USART(std::string device) : device(device) -{ -} - -void USART::openDevice() +void USART::openDevice(std::string device) { file_desc = open(device.c_str(), O_RDWR | O_NOCTTY | O_NDELAY); if(file_desc <= 0) @@ -53,6 +49,127 @@ void USART::clearOutputBuffer() throw USARTException("Fehler beim Leeren des Ausgangspuffers"); } +void USART::writeByte(uint8_t b) +{ + if(write(file_desc, &b, 1) != 1) + throw USARTException("Fehler beim Senden: writeByte()"); +} + +void USART::writeInt(uint16_t d) +{ + if(write(file_desc, reinterpret_cast(&d), 2) != 2) + throw USARTException("Fehler beim Senden: writeInt()"); +} + +uint8_t USART::readByte(void) +{ + char b; + auto start = std::chrono::steady_clock::now(); + auto end = start; + uint16_t elapsed = 0; + while(elapsed < timeout) + { + int n_ready; + int code = ioctl(file_desc, FIONREAD, &n_ready); + if(code != 0) + std::cout << "n_ready code: " << code << std::endl; + + if(n_ready > 0) + { + //std::cout << code << " \tready: " << n_ready << std::endl; + + code = read(file_desc, &b, 1); + if (code > 0) + return static_cast(b); + if (code < 0) + std::cout << "usart code: " << code << std::endl; + } + + end = std::chrono::steady_clock::now(); + elapsed = std::chrono::duration_cast(end - start).count(); + } + + if(elapsed >= timeout) + throw USARTException("Verbindung unterbrochen. (timeout)"); +} + +uint16_t USART::readInt(void) +{ + return readByte() | readByte() << 8; +} + +bool USART::readBlock(uint8_t* buffer, uint16_t offset) +{ + uint8_t len = readByte(); + uint8_t crc = 0; + buffer += offset; + + uint32_t block_timeout = timeout / 10; + + // wait for block + int n_ready; + uint16_t elapsed = 0; + auto start = std::chrono::steady_clock::now(); + auto end = start; + while(elapsed < block_timeout) + { + int code = ioctl(file_desc, FIONREAD, &n_ready); + if(code != 0) + { + std::cout << "n_ready code: " << code << std::endl; + return false; + } + + if(n_ready >= len + 1) + break; + + end = std::chrono::steady_clock::now(); + elapsed = std::chrono::duration_cast(end - start).count(); + } + if(elapsed >= timeout) + { + std::cout << "block timeout: " << std::endl; + return false; + } + + while(len--) + { + *buffer = readByte(); + + crc ^= *buffer++; + for (uint8_t i = 0; i < 8; i++) + { + if (crc & 1) + crc ^= CRC7_POLY; + crc >>= 1; + } + } + + crc ^= readByte(); + for (uint8_t i = 0; i < 8; i++) + { + if (crc & 1) + crc ^= CRC7_POLY; + crc >>= 1; + } + + if(TEST == 1) + crc = 1; + if(TEST > 100) + TEST = 0; + + if (crc == 0) + { + writeByte(0xFF); + return true; + } + else + { + writeByte(0xFE); + return false; + } +} + uint32_t USART::getBaudrate() { return baudrate; diff --git a/drv/usart.h b/drv/usart.h index 7d17d20..a23cab1 100644 --- a/drv/usart.h +++ b/drv/usart.h @@ -1,7 +1,9 @@ #ifndef USART_H #define USART_H +#include #include +#include #include #include #include @@ -11,7 +13,6 @@ class USART { public: - USART(std::string device); /************************************************* * Methoden für die Verwaltung der Schnittstelle * @@ -19,9 +20,10 @@ public: /** * Öffnet die USART Schnittstelle + * \param device Linux-Gerätepfad * \throws USARTException */ - void openDevice(void); + void openDevice(std::string device); /** * Schließt die USART Schnittstelle @@ -56,6 +58,17 @@ public: */ void writeByte(uint8_t b); + /** + * Sendet ein Integer über die USART Schnittstelle + * \param b das zu sendende Byte + * \throws USARTException + */ + void writeInt(uint16_t d); + + uint8_t readByte(void); + uint16_t readInt(void); + bool readBlock(uint8_t* buffer, uint16_t offset); + /*************************************/ @@ -92,10 +105,12 @@ public: private: - std::string device; // Gerätepfad int file_desc = -1; // Linux Dateideskriptor uint32_t baudrate = 9600; + int TEST = 0; uint8_t timeout = 10; // in Dezisekunden + + constexpr static uint8_t CRC7_POLY = 0x91; }; diff --git a/drv/usart.o b/drv/usart.o index 3039e27..da366a5 100644 Binary files a/drv/usart.o and b/drv/usart.o differ diff --git a/main b/main index da5b077..36cd534 100755 Binary files a/main and b/main differ diff --git a/main.cpp b/main.cpp index 6f27b98..5293528 100644 --- a/main.cpp +++ b/main.cpp @@ -182,8 +182,9 @@ void beispielFunktionen() int main() { - USART usart("/dev/ttyUSB0"); - usart.openDevice(); + USART usart; + usart.openDevice("/dev/ttyUSB0"); + usart.closeDevice(); diff --git a/main.o b/main.o index 551fea6..e53cb55 100644 Binary files a/main.o and b/main.o differ