diff --git a/control/src/cli.cpp.orig b/control/src/cli.cpp.orig deleted file mode 100644 index bbab408..0000000 --- a/control/src/cli.cpp.orig +++ /dev/null @@ -1,120 +0,0 @@ -//#define B15F_CLI_DEBUG - -#include -#include // sudo apt-get install libncurses5-dev -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "drv/b15f.h" -#include "ui/ui.h" -#include "ui/view_selection.h" -#include "ui/view_info.h" -#include "ui/view_monitor.h" -#include "ui/view_promt.h" - -constexpr uint8_t WIN_WIDTH = 80; -constexpr uint8_t WIN_HEIGHT = 24; - -volatile int win_changed_cooldown = 0; -volatile bool t_refresh_active = false; - -void signal_handler(int signal) -{ - if(signal == SIGWINCH) - { - win_changed_cooldown = 10; // 100ms - - if (!t_refresh_active) - { - if(t_refresh.joinable()) - t_refresh.join(); - t_refresh_active = true; - t_refresh = std::thread([]() - { - - while(win_changed_cooldown--) - std::this_thread::sleep_for(std::chrono::milliseconds(10)); - - t_refresh_active = false; - - if(win_stack.size()) - win_stack.back()->repaint(); - - }); - } - - } - else if(signal == SIGINT) - { - cleanup(); - std::cout << "SIGINT - Abbruch." << std::endl; - exit(EXIT_FAILURE); - } -} - -void abort_handler(std::exception& ex) -{ - ViewInfo* view = new ViewInfo(); - view->setTitle("Fehler"); - std::string msg(ex.what()); - msg += "\n\nBeende in 5 Sekunden."; - view->setText(msg.c_str()); - view->setLabelClose(""); - view->repaint(); - - std::this_thread::sleep_for(std::chrono::milliseconds(5000)); - - cleanup(); - std::cerr << std::endl << "*** EXCEPTION ***" << std::endl << ex.what() << std::endl; - exit(EXIT_FAILURE); -} - -void init() -{ - // init b15 driver - B15F::getInstance(); -#ifndef B15F_CLI_DEBUG - std::cout << std::endl << "Starte in 3s ..." << std::endl; - sleep(3); -#endif - - // init all ncurses stuff - initscr(); - start_color(); - curs_set(0); // 0: invisible, 1: normal, 2: very visible - clear(); - noecho(); - cbreak(); // Line buffering disabled. pass on everything - mousemask(ALL_MOUSE_EVENTS, NULL); - - // connect signals to handler - signal(SIGWINCH, signal_handler); - signal(SIGINT, signal_handler); - - // set view context - View::setWinContext(newwin(WIN_HEIGHT, WIN_WIDTH, 0, 0)); - - // set graphical error handler - B15F::setAbortHandler(&abort_handler); -} - - -int main() -{ - init(); - - int exit_code = EXIT_SUCCESS; - - show_main(0); - - cleanup(); - - return exit_code; -} diff --git a/control/src/drv/b15f.cpp b/control/src/drv/b15f.cpp index c96ae52..7d9aabe 100644 --- a/control/src/drv/b15f.cpp +++ b/control/src/drv/b15f.cpp @@ -24,8 +24,15 @@ void B15F::reconnect() delay_ms(RECONNECT_TIMEOUT); discard(); - if (testConnection()) - return; + try + { + testConnection(); + return; // no exceptionm means success + } + catch(DriverException& eDE) + { + // discard exception + } } abort("Verbindung kann nicht repariert werden"); @@ -54,7 +61,7 @@ void B15F::discard(void) } } -bool B15F::testConnection() +void B15F::testConnection() { // erzeuge zufälliges Byte srand(time(NULL)); @@ -70,10 +77,11 @@ bool B15F::testConnection() uint8_t aw[2]; usart.receive(&aw[0], 0, sizeof(aw)); - return aw[0] == MSG_OK && aw[1] == dummy; + assertCode(aw[0], MSG_OK); + assertCode(aw[1], dummy); } -bool B15F::testIntConv() +void B15F::testIntConv() { srand(time(NULL)); uint16_t dummy = rand() % (0xFFFF / 3); @@ -89,7 +97,7 @@ bool B15F::testIntConv() uint16_t aw; usart.receive(reinterpret_cast(&aw), 0, sizeof(aw)); - return aw == dummy * 3; + assertCode(aw, dummy * 3); } @@ -643,22 +651,34 @@ void B15F::init() std::cout << PRE << "Teste Verbindung... " << std::flush; - uint8_t tries = 3; - while (tries--) + int tries = 4; + while (--tries) { - // verwerfe Daten, die µC noch hat - //discard(); + discard(); - if (!testConnection()) + try + { + testConnection(); + } + catch(DriverException& eDE) + { continue; + } - if (!testIntConv()) + try + { + testIntConv(); + } + catch(DriverException& eDE) + { continue; + } break; } - if (tries == 0) + if (!tries) abort("Verbindungstest fehlgeschlagen. Neueste Version im Einsatz?"); + std::cout << "OK" << std::endl; diff --git a/control/src/drv/b15f.cpp.orig b/control/src/drv/b15f.cpp.orig deleted file mode 100644 index f7deca9..0000000 --- a/control/src/drv/b15f.cpp.orig +++ /dev/null @@ -1,669 +0,0 @@ -#include "b15f.h" - -B15F *B15F::instance = nullptr; -errorhandler_t B15F::errorhandler = nullptr; - - -/************************************* - * Grundfunktionen des B15F Treibers * - *************************************/ - -B15F &B15F::getInstance(void) -{ - if (!instance) - instance = new B15F(); - - return *instance; -} - -void B15F::reconnect() -{ - uint8_t tries = RECONNECT_TRIES; - while (tries--) - { - delay_ms(RECONNECT_TIMEOUT); - discard(); - - if (testConnection()) - return; - } - - abort("Verbindung kann nicht repariert werden"); -} - -void B15F::discard(void) -{ - try - { - uint8_t rq[] = - { - RQ_DISCARD - }; - - usart.clearOutputBuffer(); - for (uint8_t i = 0; i < 16; i++) - { - usart.transmit(&rq[0], 0, sizeof(rq)); // sende discard Befehl (verwerfe input) - delay_ms(4); - } - usart.clearInputBuffer(); - } - catch (std::exception &ex) - { - abort(ex); - } -} - -bool B15F::testConnection() -{ - // erzeuge zufälliges Byte - srand(time(NULL)); - uint8_t dummy = rand() % 256; - - uint8_t rq[] = - { - RQ_TEST, - dummy - }; - usart.transmit(&rq[0], 0, sizeof(rq)); - - uint8_t aw[2]; - usart.receive(&aw[0], 0, sizeof(aw)); - - return aw[0] == MSG_OK && aw[1] == dummy; -} - -bool B15F::testIntConv() -{ - srand(time(NULL)); - uint16_t dummy = rand() % (0xFFFF / 3); - - uint8_t rq[] = - { - RQ_INT_TEST, - static_cast(dummy & 0xFF), - static_cast(dummy >> 8) - }; - usart.transmit(&rq[0], 0, sizeof(rq)); - - uint16_t aw; - usart.receive(reinterpret_cast(&aw), 0, sizeof(aw)); - - return aw == dummy * 3; -} - - -std::vector B15F::getBoardInfo(void) -{ - std::vector info; - - uint8_t rq[] = - { - RQ_INFO - }; - usart.transmit(&rq[0], 0, sizeof(rq)); - - uint8_t n; - usart.receive(&n, 0, sizeof(n)); - while (n--) - { - uint8_t len; - usart.receive(&len, 0, sizeof(len)); - - char str[len + 1]; - str[len] = '\0'; - usart.receive(reinterpret_cast(&str[0]), 0, len); - - info.push_back(std::string(str)); - } - - uint8_t aw; - usart.receive(&aw, 0, sizeof(aw)); - if (aw != MSG_OK) - abort("Board Info fehlerhalft: code " + std::to_string((int) aw)); - - return info; -} - -void B15F::delay_ms(uint16_t ms) -{ - std::this_thread::sleep_for(std::chrono::milliseconds(ms)); -} - -void B15F::delay_us(uint16_t us) -{ - std::this_thread::sleep_for(std::chrono::microseconds(us)); -} - -void B15F::reverse(uint8_t& b) -{ - b = (b & 0xF0) >> 4 | (b & 0x0F) << 4; - b = (b & 0xCC) >> 2 | (b & 0x33) << 2; - b = (b & 0xAA) >> 1 | (b & 0x55) << 1; -} - -// https://stackoverflow.com/a/478960 -std::string B15F::exec(std::string cmd) -{ - std::array buffer; - std::string result; - std::unique_ptr pipe(popen(cmd.c_str(), "r"), pclose); - if (!pipe) - { - throw std::runtime_error("popen() failed!"); - } - while (fgets(buffer.data(), buffer.size(), pipe.get()) != nullptr) - { - result += buffer.data(); - } - return result; -} - -void B15F::abort(std::string msg) -{ - DriverException ex(msg); - abort(ex); -} - -void B15F::abort(std::exception &ex) -{ - if (errorhandler) - errorhandler(ex); - else - { - std::cout << ex.what() << std::endl; - throw DriverException(ex.what()); - } -} - -void B15F::setAbortHandler(errorhandler_t func) -{ - errorhandler = func; -} - -/*************************************/ - - - -/************************* - * Steuerbefehle für B15 * - *************************/ - -void B15F::activateSelfTestMode() -{ - uint8_t rq[] = - { - RQ_SELF_TEST - }; - - assertRequestLength(rq, RQ_SELF_TEST); - usart.transmit(&rq[0], 0, sizeof(rq)); - - uint8_t aw; - usart.receive(&aw, 0, sizeof(aw)); - assertCode(aw, MSG_OK); -} - -void B15F::digitalWrite0(uint8_t port) -{ - uint8_t rq[] = - { - RQ_DIGITAL_WRITE_0, - port - }; - - assertRequestLength(rq, RQ_DIGITAL_WRITE_0); - usart.transmit(&rq[0], 0, sizeof(rq)); - - uint8_t aw; - usart.receive(&aw, 0, sizeof(aw)); - assertCode(aw, MSG_OK); -} - -void B15F::digitalWrite1(uint8_t port) -{ - uint8_t rq[] = - { - RQ_DIGITAL_WRITE_1, - port - }; - - assertRequestLength(rq, RQ_DIGITAL_WRITE_1); - usart.transmit(&rq[0], 0, sizeof(rq)); - - uint8_t aw; - usart.receive(&aw, 0, sizeof(aw)); - assertCode(aw, MSG_OK); -} - -uint8_t B15F::digitalRead0() -{ - usart.clearInputBuffer(); - uint8_t rq[] = - { - RQ_DIGITAL_READ_0 - }; - - assertRequestLength(rq, RQ_DIGITAL_READ_0); - usart.transmit(&rq[0], 0, sizeof(rq)); - - uint8_t aw; - usart.receive(&aw, 0, sizeof(aw)); - return aw; -} - -uint8_t B15F::digitalRead1() -{ - usart.clearInputBuffer(); - uint8_t rq[] = - { - RQ_DIGITAL_READ_1 - }; - - assertRequestLength(rq, RQ_DIGITAL_READ_1); - usart.transmit(&rq[0], 0, sizeof(rq)); - - uint8_t aw; - usart.receive(&aw, 0, sizeof(aw)); - return aw; -} - -uint8_t B15F::readDipSwitch() -{ - usart.clearInputBuffer(); - uint8_t rq[] = - { - RQ_READ_DIP_SWITCH - }; - - assertRequestLength(rq, RQ_READ_DIP_SWITCH); - usart.transmit(&rq[0], 0, sizeof(rq)); - - uint8_t aw; - usart.receive(&aw, 0, sizeof(aw)); - - reverse(aw); // DIP Schalter muss invertiert werden! - - return aw; -} - -void B15F::analogWrite0(uint16_t value) -{ - uint8_t rq[] = - { - RQ_ANALOG_WRITE_0, - static_cast(value & 0xFF), - static_cast(value >> 8) - }; - - assertRequestLength(rq, RQ_ANALOG_WRITE_0); - usart.transmit(&rq[0], 0, sizeof(rq)); - - uint8_t aw; - usart.receive(&aw, 0, sizeof(aw)); - assertCode(aw, MSG_OK); -} - -void B15F::analogWrite1(uint16_t value) -{ - uint8_t rq[] = - { - RQ_ANALOG_WRITE_1, - static_cast(value & 0xFF), - static_cast(value >> 8) - }; - - assertRequestLength(rq, RQ_ANALOG_WRITE_1); - usart.transmit(&rq[0], 0, sizeof(rq)); - - uint8_t aw; - usart.receive(&aw, 0, sizeof(aw)); - assertCode(aw, MSG_OK); -} - -uint16_t B15F::analogRead(uint8_t channel) -{ - usart.clearInputBuffer(); - if (channel > 7) - abort("Bad ADC channel: " + std::to_string(channel)); - - uint8_t rq[] = - { - RQ_ANALOG_READ, - channel - }; - - assertRequestLength(rq, RQ_ANALOG_READ); - usart.transmit(&rq[0], 0, sizeof(rq)); - - uint16_t aw; - usart.receive(reinterpret_cast(&aw), 0, sizeof(aw)); - - if (aw > 1023) - abort("Bad ADC data detected (1)"); - return aw; -} - -void B15F::analogSequence(uint8_t channel_a, uint16_t *buffer_a, uint32_t offset_a, uint8_t channel_b, uint16_t *buffer_b, - uint32_t offset_b, uint16_t start, int16_t delta, uint16_t count) -{ - // prepare pointers - buffer_a += offset_a; - buffer_b += offset_b; - - - usart.clearInputBuffer(); - uint8_t rq[] = - { - RQ_ADC_DAC_STROKE, - channel_a, - channel_b, - static_cast(start & 0xFF), - static_cast(start >> 8), - static_cast(delta & 0xFF), - static_cast(delta >> 8), - static_cast(count & 0xFF), - static_cast(count >> 8) - }; - - assertRequestLength(rq, RQ_ADC_DAC_STROKE); - usart.transmit(&rq[0], 0, sizeof(rq)); - - for (uint16_t i = 0; i < count; i++) - { - if (buffer_a) - { - usart.receive(reinterpret_cast(&buffer_a[i]), 0, 2); - - if (buffer_a[i] > 1023) // check for broken usart connection - abort("Bad ADC data detected (2)"); - } - else - { - usart.drop(2); - } - - if (buffer_b) - { - usart.receive(reinterpret_cast(&buffer_b[i]), 0, 2); - - if (buffer_b[i] > 1023) // check for broken usart connection - abort("Bad ADC data detected (3)"); - } - else - { - usart.drop(2); - } - } - - uint8_t aw; - usart.receive(&aw, 0, sizeof(aw)); - assertCode(aw, MSG_OK); -} - -uint8_t B15F::pwmSetFrequency(uint32_t freq) -{ - usart.clearInputBuffer(); - - uint8_t rq[] = - { - RQ_PWM_SET_FREQ, - static_cast((freq >> 0) & 0xFF), - static_cast((freq >> 8) & 0xFF), - static_cast((freq >> 16) & 0xFF), - static_cast((freq >> 24) & 0xFF) - }; - - assertRequestLength(rq, RQ_PWM_SET_FREQ); - usart.transmit(&rq[0], 0, sizeof(rq)); - - uint8_t aw; - usart.receive(&aw, 0, sizeof(aw)); - return aw; -} - -void B15F::pwmSetValue(uint8_t value) -{ - usart.clearInputBuffer(); - - uint8_t rq[] = - { - RQ_PWM_SET_VALUE, - value - }; - - assertRequestLength(rq, RQ_PWM_SET_VALUE); - usart.transmit(&rq[0], 0, sizeof(rq)); - - uint8_t aw; - usart.receive(&aw, 0, sizeof(aw)); - assertCode(aw, MSG_OK); -} - -void B15F::setMem8(volatile uint8_t* adr, uint8_t val) -{ - usart.clearInputBuffer(); - - uint8_t rq[] = - { - RQ_SET_MEM_8, - static_cast(reinterpret_cast(adr) & 0xFF), - static_cast(reinterpret_cast(adr) >> 8), - val - }; - - assertRequestLength(rq, RQ_SET_MEM_8); - usart.transmit(&rq[0], 0, sizeof(rq)); - - uint8_t aw; - usart.receive(&aw, 0, sizeof(aw)); - assertCode(aw, MSG_OK); -} - -uint8_t B15F::getMem8(volatile uint8_t* adr) -{ - usart.clearInputBuffer(); - - uint8_t rq[] = - { - RQ_GET_MEM_8, - static_cast(reinterpret_cast(adr) & 0xFF), - static_cast(reinterpret_cast(adr) >> 8) - }; - - assertRequestLength(rq, RQ_GET_MEM_8); - usart.transmit(&rq[0], 0, sizeof(rq)); - - uint8_t aw; - usart.receive(&aw, 0, sizeof(aw)); - return aw; -} - -void B15F::setMem16(volatile uint16_t* adr, uint16_t val) -{ - usart.clearInputBuffer(); - - uint8_t rq[] = - { - RQ_SET_MEM_16, - static_cast(reinterpret_cast(adr) & 0xFF), - static_cast(reinterpret_cast(adr) >> 8), - static_cast(val & 0xFF), - static_cast(val >> 8) - }; - - assertRequestLength(rq, RQ_SET_MEM_16); - usart.transmit(&rq[0], 0, sizeof(rq)); - - uint16_t aw; - usart.receive(reinterpret_cast(&aw), 0, sizeof(aw)); - assertCode(aw, MSG_OK); -} - -uint16_t B15F::getMem16(volatile uint16_t* adr) -{ - usart.clearInputBuffer(); - - uint8_t rq[] = - { - RQ_GET_MEM_16, - static_cast(reinterpret_cast(adr) & 0xFF), - static_cast(reinterpret_cast(adr) >> 8) - }; - - assertRequestLength(rq, RQ_GET_MEM_16); - usart.transmit(&rq[0], 0, sizeof(rq)); - - uint16_t aw; - usart.receive(reinterpret_cast(&aw), 0, sizeof(aw)); - return aw; -} - -void B15F::setRegister(volatile uint8_t* adr, uint8_t val) -{ - setMem8(adr, val); -} - -uint8_t B15F::getRegister(volatile uint8_t* adr) -{ - return getMem8(adr); -} - -uint16_t* B15F::getInterruptCounterOffset() -{ - usart.clearInputBuffer(); - - uint8_t rq[] = - { - RQ_COUNTER_OFFSET - }; - - assertRequestLength(rq, RQ_COUNTER_OFFSET); - usart.transmit(&rq[0], 0, sizeof(rq)); - - uint16_t aw; - usart.receive(reinterpret_cast(&aw), 0, sizeof(aw)); - return reinterpret_cast(aw); -} - -void B15F::setServoEnabled(void) -{ - usart.clearInputBuffer(); - - uint8_t rq[] = - { - RQ_SERVO_ENABLE - }; - - assertRequestLength(rq, RQ_SERVO_ENABLE); - usart.transmit(&rq[0], 0, sizeof(rq)); - - uint8_t aw; - usart.receive(&aw, 0, sizeof(aw)); - assertCode(aw, MSG_OK); -} - -void B15F::setServoDisabled(void) -{ - usart.clearInputBuffer(); - - uint8_t rq[] = - { - RQ_SERVO_DISABLE - }; - - assertRequestLength(rq, RQ_SERVO_DISABLE); - usart.transmit(&rq[0], 0, sizeof(rq)); - - uint8_t aw; - usart.receive(&aw, 0, sizeof(aw)); - assertCode(aw, MSG_OK); -} - -void B15F::setServoPosition(uint16_t pos) -{ - if(pos > 19000) - throw DriverException("Impulslänge ist zu lang: " + std::to_string(pos)); - - usart.clearInputBuffer(); - - uint8_t rq[] = - { - RQ_SERVO_SET_POS, - static_cast(pos & 0xFF), - static_cast(pos >> 8) - }; - - assertRequestLength(rq, RQ_SERVO_SET_POS); - usart.transmit(&rq[0], 0, sizeof(rq)); - - uint8_t aw; - usart.receive(&aw, 0, sizeof(aw)); - assertCode(aw, MSG_OK); -} - -/*************************/ - - -/********************** - * Private Funktionen * - **********************/ - -B15F::B15F() -{ - init(); -} - - -void B15F::init() -{ - -#ifdef __arm__ - // Raspberry Pi serial interface - std::string device = exec("bash -c 'ls /dev/ttyAMA* 2> /dev/null'"); -#else - // normal PC serial interface - std::string device = exec("bash -c 'ls /dev/ttyUSB* 2> /dev/null'"); -#endif - - while (device.find(' ') != std::string::npos || device.find('\n') != std::string::npos || - device.find('\t') != std::string::npos) - device.pop_back(); - - if (device.length() == 0) - abort("Adapter nicht gefunden"); - - std::cout << PRE << "Verwende Adapter: " << device << std::endl; - - - std::cout << PRE << "Stelle Verbindung mit Adapter her... " << std::flush; - usart.setBaudrate(BAUDRATE); - usart.openDevice(device); - std::cout << "OK" << std::endl; - - - std::cout << PRE << "Teste Verbindung... " << std::flush; - uint8_t tries = 3; - while (tries--) - { - // verwerfe Daten, die µC noch hat - //discard(); - - if (!testConnection()) - continue; - - if (!testIntConv()) - continue; - - break; - } - if (tries == 0) - abort("Verbindungstest fehlgeschlagen. Neueste Version im Einsatz?"); - std::cout << "OK" << std::endl; - - - // Gib board info aus - std::vector info = getBoardInfo(); - std::cout << PRE << "AVR Firmware Version: " << info[0] << " um " << info[1] << " Uhr (" << info[2] << ")" - << std::endl; -} diff --git a/control/src/drv/b15f.h b/control/src/drv/b15f.h index 9b6a98c..53d649e 100644 --- a/control/src/drv/b15f.h +++ b/control/src/drv/b15f.h @@ -27,6 +27,10 @@ typedef std::function errorhandler_t; +// Wrapper für Codeposition-Ersetzung +#define assertCode(code, expectation) assertCodeFunc(code, expectation, &__FUNCTION__[0], &__FILE__[0], __LINE__) +#define assertRequestLength(rq, rq_num) assertRequestLengthFunc(rq, rq_num,& __FUNCTION__[0], &__FILE__[0], __LINE__) + /*! main driver class */ @@ -60,13 +64,13 @@ public: * Testet die USART Verbindung auf Funktion * \throws DriverException */ - bool testConnection(void); + void testConnection(void); /** * Testet die Integer Konvertierung der USART Verbindung * \throws DriverException */ - bool testIntConv(void); + void testIntConv(void); /** * Liefert Informationen zur aktuellen Firmware des B15 @@ -330,10 +334,10 @@ private: * \throws DriverException */ template - void assertCode(CodeType& code, ExpectationType expectation) const + void assertCodeFunc(CodeType& code, ExpectationType expectation, const char* func, const char* file, int line) const { if(code != static_cast(expectation)) - throw DriverException("Ungültige Antwort erhalten: " + std::to_string((int) code) + " (erwartet: " + std::to_string((int) expectation) + ")"); + throw DriverException("Ungültige Antwort erhalten: " + std::to_string((int) code) + " (erwartet: " + std::to_string((int) expectation) + ") in " + std::string(func) + ": " + std::string(file) + "#" + std::to_string(line)); } /** @@ -341,10 +345,10 @@ private: * \throws DriverException */ template - void assertRequestLength(uint8_t (&)[RequestLength], uint8_t rq_num) + void assertRequestLengthFunc(uint8_t (&)[RequestLength], uint8_t rq_num, const char* func, const char* file, int line) { if(RequestLength != rq_len[rq_num]) - throw DriverException("Ungültige Request Länge: " + std::to_string(RequestLength) + " (erwartet: " + std::to_string(rq_len[rq_num]) + ")"); + throw DriverException("Ungültige Request Länge: " + std::to_string(RequestLength) + " (erwartet: " + std::to_string(rq_len[rq_num]) + ") in " + std::string(func) + ": " + std::string(file) + "#" + std::to_string(line)); } USART usart; //!< USART Instanz für serielle Verbindung diff --git a/control/src/drv/b15f.h.orig b/control/src/drv/b15f.h.orig deleted file mode 100644 index 65110cf..0000000 --- a/control/src/drv/b15f.h.orig +++ /dev/null @@ -1,355 +0,0 @@ -#ifndef B15F_H -#define B15F_H - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "requests.h" -#include "usart.h" -#include "driverexception.h" -#include "timeoutexception.h" - -// wichtig für die Register-Zugriffe -#define _AVR_IO_H_ 1 // Erzwinge die Inklusion -#include "/usr/lib/avr/include/avr/sfr_defs.h" -#include "/usr/lib/avr/include/avr/iom1284p.h" - -typedef std::function errorhandler_t; - - -/*! main driver class */ - -class B15F -{ -public: - - /************************************* - * Grundfunktionen des B15F Treibers * - *************************************/ - - /** - * Liefert eine Referenz zur aktuellen Treiber-Instanz, die Verbindung wird gegebenenfalls automatisch hergestellt. - * @throws DriverException - */ - static B15F& getInstance(void); - - /** - * Versucht die Verbindung zum B15 wiederherzustellen - * \throws DriverException - */ - void reconnect(void); - - /** - * Verwirft Daten im USART Puffer auf dieser Maschine und B15 - * \throws DriverException - */ - void discard(void); - - /** - * Testet die USART Verbindung auf Funktion - * \throws DriverException - */ - bool testConnection(void); - - /** - * Testet die Integer Konvertierung der USART Verbindung - * \throws DriverException - */ - bool testIntConv(void); - - /** - * Liefert Informationen zur aktuellen Firmware des B15 - * \throws DriverException - */ - std::vector getBoardInfo(void); - - /** - * Lässt den Treiber für eine angegebene Zeit pausieren - * \param ms Verzögerung in Millisekunden - */ - void delay_ms(uint16_t ms); - - /** - * Lässt den Treiber für eine angegebene Zeit pausieren - * \param us Verzögerung in Microsekunden - */ - void delay_us(uint16_t us); - - /** - * Invertiert das Bitmuster eines Bytes - * z.B.: 10100001 --> 10000101 - * \param b Byte, das invertiert wird - */ - void reverse(uint8_t& b); - - /** - * Führt ein Befehl auf dieser Maschine aus und liefert stdout zurück - * \param cmd Der Befehl - */ - static std::string exec(std::string cmd); - - /** - * Multithread sicherer Abbruch des B15F-Treibers - * \param msg Beschreibung der Abbruchursache - */ - static void abort(std::string msg); - - /** - * Multithread sicherer Abbruch des B15F-Treibers - * \param ex Exception als Abbruchursache - */ - static void abort(std::exception& ex); - - /** - * Setzt eine Fehlerbehandlungsroutine für den Treiberabbruch (abort) - * \param func Funktion, die Exception als Parameter bekommt - */ - static void setAbortHandler(errorhandler_t func); - - /*************************************/ - - - - /************************* - * Steuerbefehle für B15 * - *************************/ - - /** - * Versetzt das Board in den Selbsttest-Modus - * WICHTIG: Es darf dabei nichts an den Klemmen angeschlossen sein! - * \throws DriverException - */ - void activateSelfTestMode(void); - - /** - * Setzt den Wert des digitalen Ausgabeports 0 - * \param port Wert für gesamten Port - * \throws DriverException - */ - void digitalWrite0(uint8_t); - - /** - * Setzt den Wert des digitalen Ausgabeports 1 - * \param port Wert für gesamten Port - * \throws DriverException - */ - void digitalWrite1(uint8_t); - - /** - * Liest den Wert des digitalen Eingabeports 0 - * \return Wert für gesamten Port - * \throws DriverException - */ - uint8_t digitalRead0(void); - - /** - * Liest den Wert des digitalen Eingabeports 1 - * \return Wert für gesamten Port - * \throws DriverException - */ - uint8_t digitalRead1(void); - - /** - * Liest den Wert des digitalen Eingabeports, an dem der DIP-switch angeschlossen ist (S7) - * \return Wert für gesamten Port - * \throws DriverException - */ - uint8_t readDipSwitch(void); - - /** - * Setzt den Wert des Digital-Analog-Converters (DAC / DAU) 0 - * \param port 10-Bit Wert - * \throws DriverException - */ - void analogWrite0(uint16_t port); - - /** - * Setzt den Wert des Digital-Analog-Converters (DAC / DAU) 1 - * \param port 10-Bit Wert - * \throws DriverException - */ - void analogWrite1(uint16_t port); - - /** - * Liest den Wert des Analog-Digital-Converters (ADC / ADU) - * \param channel Kanalwahl von 0 - 7 - * \throws DriverException - */ - uint16_t analogRead(uint8_t channel); - - /** - * DAC 0 wird auf den Startwert gesetzt und dann schrittweise um Delta inkrementiert. - * Für jeden eingestelleten DAC-Wert werden zwei ADCs (channel_a und channel_b) angesprochen und die Werte übermittelt. - * Die Werte werden in buffer_a für Kanal a und buffer_b für Kanal b gespeichert. - * \param channel_a Auswahl des ADC a, von 0 - 7 - * \param buffer_a Speichertort für Werte des Kanals a - * \param offset_a Anzahl an Werten des Kanals a, die im Speicher übersprungen werden sollen - * \param channel_b Auswahl des ADC b, von 0 - 7 - * \param buffer_b Speichertort für Werte des Kanals b - * \param offset_b Anzahl an Werten des Kanals b, die im Speicher übersprungen werden - * \param start Startwert des DACs - * \param delta Schrittweite, mit welcher der DAC inkrementiert wird - * \param count Anzahl an Inkrementierungen - * \throws DriverException - */ - void analogSequence(uint8_t channel_a, uint16_t* buffer_a, uint32_t offset_a, uint8_t channel_b, uint16_t* buffer_b, uint32_t offset_b, uint16_t start, int16_t delta, uint16_t count); - - /** - * Frequenz von PWM an PB4. - * Setzt die Register so, dass näherungsweise die gewünschte Frequenz erzeugt wird. - * Ist freq == 0 wird PWM deaktiviert. - * Standardfrequenz: 31300 (empfohlen, da dann TOP == 255) - * \param freq PWM Frequenz - * \return TOP Wert des PWM Value für die gesetzte Frequenz - * \throws DriverException - */ - uint8_t pwmSetFrequency(uint32_t freq); - - /** - * Setzt den PWM Wert an PB4. - * \param value PWM Wert [0..TOP] - * \throws DriverException - */ - void pwmSetValue(uint8_t value); - - /** - * Setzt direkt den Wert einer MCU Speicherzelle der Größe 8 Bit. - * Diese kann ein Register oder RAM-Daten sein. - * *Wichtig:* bei einer falschen Adresse kann das Board 15 ernsthaften Schaden nehmen! - * \param adr Speicheradresse - * \param val Neuer Wert für die Zelle - * \return true, falls Vorgang erfolgreich - */ - void setMem8(volatile uint8_t* adr, uint8_t val); - - /** - * Liefert den Wert einer MCU Speicherzelle der Größe 8 Bit. - * Diese kann ein Register oder RAM-Daten sein. - * \param adr Speicheradresse - * \return Wert der Speicherzelle - */ - uint8_t getMem8(volatile uint8_t* adr); - - /** - * Setzt direkt den Wert einer MCU Speicherzelle der Größe 16 Bit. - * Diese kann ein Register oder RAM-Daten sein. - * *Wichtig:* bei einer falschen Adresse kann das Board 15 ernsthaften Schaden nehmen! - * \param adr Speicheradresse - * \param val Neuer Wert für die Zelle - * \throws DriverException - */ - void setMem16(volatile uint16_t* adr, uint16_t val); - - /** - * Liefert den Wert einer MCU Speicherzelle der Größe 16 Bit. - * Diese kann ein Register oder RAM-Daten sein. - * \param adr Speicheradresse - * \return Wert der Speicherzelle - */ - uint16_t getMem16(volatile uint16_t* adr); - - /** - * Diese Funktion ist ein Alias für setMem8(). - * *Wichtig:* bei einer falschen Adresse kann das Board 15 ernsthaften Schaden nehmen! - * \param adr Speicheradresse - * \param val Neuer Wert für das Register - * \throws DriverException - */ - void setRegister(volatile uint8_t* adr, uint8_t val); - - /** - * Diese Funktion ist ein Alias für getMem8(). - * \param adr Speicheradresse - * \return Wert des Registers - */ - uint8_t getRegister(volatile uint8_t* adr); - - /** - * Liefert die Adresse des ersten Interrupt Counters (BASISR). - * \return Adresse (in der MCU) - */ - uint16_t* getInterruptCounterOffset(void); - - /** - * Aktiviert das Servo Signal an PB2 und Initialisiert es mit 1,5ms Pulselänge. - * \throws DriverException - */ - void setServoEnabled(void); - - /** - * Deaktiviert das Servo Signal an PB2. - * \throws DriverException - */ - void setServoDisabled(void); - - /** - * Setzt die Pulselänge des Servo Signals und damit die Position. - * \param pos Pulselänge des Signals in Mikrosekunden - * \throws DriverException - */ - void setServoPosition(uint16_t pos); - - /*************************/ - - - // CONSTANTS - const std::string PRE = "[B15F] "; //!< B15F stdout prefix - constexpr static uint8_t MSG_OK = 0xFF; //!< Value to acknowledge a received command - constexpr static uint8_t MSG_FAIL = 0xFE; //!< Value to reject a received command - constexpr static uint16_t RECONNECT_TIMEOUT = 64; //!< Time in ms after which a reconnect attempt aborts - constexpr static uint16_t WDT_TIMEOUT = 15; //!< Time in ms after which the watch dog timer resets the MCU - constexpr static uint8_t RECONNECT_TRIES = 3; //!< Maximum count of reconnect attempts after which the driver stops - constexpr static uint32_t BAUDRATE = 57600; //!< USART baudrate for communication with the MCU - -private: - - /** - * Privater Konstruktor - */ - B15F(void); - - /** - * Initialisiert und testet die Verbindung zum B15 - * \throws DriverException - */ - void init(void); - - /** - * Wirft eine Exception, falls der Code ungleich dem erwarteten Wert ist. - * \throws DriverException - */ - template - void assertCode(CodeType& code, ExpectationType expectation) const - { - if(code != static_cast(expectation)) - throw DriverException("Ungültige Antwort erhalten: " + std::to_string((int) code) + " (erwartet: " + std::to_string((int) expectation) + ")"); - } - - /** - * Wirft eine Exception, falls die Request die falsche Länge hat. - * \throws DriverException - */ - template - void assertRequestLength(uint8_t (&)[RequestLength], uint8_t rq_num) - { - if(RequestLength != rq_len[rq_num]) - throw DriverException("Ungültige Request Länge: " + std::to_string(RequestLength) + " (erwartet: " + std::to_string(rq_len[rq_num]) + ")"); - } - - USART usart; //!< USART Instanz für serielle Verbindung - static B15F* instance; //!< private Instanz für Singleton - static errorhandler_t errorhandler; //!< Error Handler für Exceptions und Fehler -}; - -#endif // B15F_H diff --git a/docs/html/annotated.html b/docs/html/annotated.html index b918d7a..017eeb2 100644 --- a/docs/html/annotated.html +++ b/docs/html/annotated.html @@ -85,7 +85,7 @@ $(function() { diff --git a/docs/html/b15f_8cpp_source.html b/docs/html/b15f_8cpp_source.html index f5b5929..6fe33f8 100644 --- a/docs/html/b15f_8cpp_source.html +++ b/docs/html/b15f_8cpp_source.html @@ -70,58 +70,58 @@ $(function() {
b15f.cpp
-
1 #include "b15f.h"
2 
3 B15F *B15F::instance = nullptr;
4 errorhandler_t B15F::errorhandler = nullptr;
5 
6 
7 /*************************************
8  * Grundfunktionen des B15F Treibers *
9  *************************************/
10 
12 {
13  if (!instance)
14  instance = new B15F();
15 
16  return *instance;
17 }
18 
19 void B15F::reconnect()
20 {
21  uint8_t tries = RECONNECT_TRIES;
22  while (tries--)
23  {
25  discard();
26 
27  if (testConnection())
28  return;
29  }
30 
31  abort("Verbindung kann nicht repariert werden");
32 }
33 
34 void B15F::discard(void)
35 {
36  try
37  {
38  uint8_t rq[] =
39  {
40  RQ_DISCARD
41  };
42 
43  usart.clearOutputBuffer();
44  for (uint8_t i = 0; i < 16; i++)
45  {
46  usart.transmit(&rq[0], 0, sizeof(rq)); // sende discard Befehl (verwerfe input)
47  delay_ms(4);
48  }
49  usart.clearInputBuffer();
50  }
51  catch (std::exception &ex)
52  {
53  abort(ex);
54  }
55 }
56 
58 {
59  // erzeuge zufälliges Byte
60  srand(time(NULL));
61  uint8_t dummy = rand() % 256;
62 
63  uint8_t rq[] =
64  {
65  RQ_TEST,
66  dummy
67  };
68  usart.transmit(&rq[0], 0, sizeof(rq));
69 
70  uint8_t aw[2];
71  usart.receive(&aw[0], 0, sizeof(aw));
72 
73  return aw[0] == MSG_OK && aw[1] == dummy;
74 }
75 
76 bool B15F::testIntConv()
77 {
78  srand(time(NULL));
79  uint16_t dummy = rand() % (0xFFFF / 3);
80 
81  uint8_t rq[] =
82  {
83  RQ_INT_TEST,
84  static_cast<uint8_t >(dummy & 0xFF),
85  static_cast<uint8_t >(dummy >> 8)
86  };
87  usart.transmit(&rq[0], 0, sizeof(rq));
88 
89  uint16_t aw;
90  usart.receive(reinterpret_cast<uint8_t *>(&aw), 0, sizeof(aw));
91 
92  return aw == dummy * 3;
93 }
94 
95 
96 std::vector<std::string> B15F::getBoardInfo(void)
97 {
98  std::vector<std::string> info;
99 
100  uint8_t rq[] =
101  {
102  RQ_INFO
103  };
104  usart.transmit(&rq[0], 0, sizeof(rq));
105 
106  uint8_t n;
107  usart.receive(&n, 0, sizeof(n));
108  while (n--)
109  {
110  uint8_t len;
111  usart.receive(&len, 0, sizeof(len));
112 
113  char str[len + 1];
114  str[len] = '\0';
115  usart.receive(reinterpret_cast<uint8_t *>(&str[0]), 0, len);
116 
117  info.push_back(std::string(str));
118  }
119 
120  uint8_t aw;
121  usart.receive(&aw, 0, sizeof(aw));
122  if (aw != MSG_OK)
123  abort("Board Info fehlerhalft: code " + std::to_string((int) aw));
124 
125  return info;
126 }
127 
128 void B15F::delay_ms(uint16_t ms)
129 {
130  std::this_thread::sleep_for(std::chrono::milliseconds(ms));
131 }
132 
133 void B15F::delay_us(uint16_t us)
134 {
135  std::this_thread::sleep_for(std::chrono::microseconds(us));
136 }
137 
138 void B15F::reverse(uint8_t& b)
139 {
140  b = (b & 0xF0) >> 4 | (b & 0x0F) << 4;
141  b = (b & 0xCC) >> 2 | (b & 0x33) << 2;
142  b = (b & 0xAA) >> 1 | (b & 0x55) << 1;
143 }
144 
145 // https://stackoverflow.com/a/478960
146 std::string B15F::exec(std::string cmd)
147 {
148  std::array<char, 128> buffer;
149  std::string result;
150  std::unique_ptr<FILE, decltype(&pclose)> pipe(popen(cmd.c_str(), "r"), pclose);
151  if (!pipe)
152  {
153  throw std::runtime_error("popen() failed!");
154  }
155  while (fgets(buffer.data(), buffer.size(), pipe.get()) != nullptr)
156  {
157  result += buffer.data();
158  }
159  return result;
160 }
161 
162 void B15F::abort(std::string msg)
163 {
164  DriverException ex(msg);
165  abort(ex);
166 }
167 
168 void B15F::abort(std::exception &ex)
169 {
170  if (errorhandler)
171  errorhandler(ex);
172  else
173  {
174  std::cout << ex.what() << std::endl;
175  throw DriverException(ex.what());
176  }
177 }
178 
179 void B15F::setAbortHandler(errorhandler_t func)
180 {
181  errorhandler = func;
182 }
183 
184 /*************************************/
185 
186 
187 
188 /*************************
189  * Steuerbefehle für B15 *
190  *************************/
191 
193 {
194  uint8_t rq[] =
195  {
196  RQ_SELF_TEST
197  };
198 
199  assertRequestLength(rq, RQ_SELF_TEST);
200  usart.transmit(&rq[0], 0, sizeof(rq));
201 
202  uint8_t aw;
203  usart.receive(&aw, 0, sizeof(aw));
204  assertCode(aw, MSG_OK);
205 }
206 
207 void B15F::digitalWrite0(uint8_t port)
208 {
209  uint8_t rq[] =
210  {
211  RQ_DIGITAL_WRITE_0,
212  port
213  };
214 
215  assertRequestLength(rq, RQ_DIGITAL_WRITE_0);
216  usart.transmit(&rq[0], 0, sizeof(rq));
217 
218  uint8_t aw;
219  usart.receive(&aw, 0, sizeof(aw));
220  assertCode(aw, MSG_OK);
221 }
222 
223 void B15F::digitalWrite1(uint8_t port)
224 {
225  uint8_t rq[] =
226  {
227  RQ_DIGITAL_WRITE_1,
228  port
229  };
230 
231  assertRequestLength(rq, RQ_DIGITAL_WRITE_1);
232  usart.transmit(&rq[0], 0, sizeof(rq));
233 
234  uint8_t aw;
235  usart.receive(&aw, 0, sizeof(aw));
236  assertCode(aw, MSG_OK);
237 }
238 
239 uint8_t B15F::digitalRead0()
240 {
241  usart.clearInputBuffer();
242  uint8_t rq[] =
243  {
244  RQ_DIGITAL_READ_0
245  };
246 
247  assertRequestLength(rq, RQ_DIGITAL_READ_0);
248  usart.transmit(&rq[0], 0, sizeof(rq));
249 
250  uint8_t aw;
251  usart.receive(&aw, 0, sizeof(aw));
252  return aw;
253 }
254 
255 uint8_t B15F::digitalRead1()
256 {
257  usart.clearInputBuffer();
258  uint8_t rq[] =
259  {
260  RQ_DIGITAL_READ_1
261  };
262 
263  assertRequestLength(rq, RQ_DIGITAL_READ_1);
264  usart.transmit(&rq[0], 0, sizeof(rq));
265 
266  uint8_t aw;
267  usart.receive(&aw, 0, sizeof(aw));
268  return aw;
269 }
270 
271 uint8_t B15F::readDipSwitch()
272 {
273  usart.clearInputBuffer();
274  uint8_t rq[] =
275  {
276  RQ_READ_DIP_SWITCH
277  };
278 
279  assertRequestLength(rq, RQ_READ_DIP_SWITCH);
280  usart.transmit(&rq[0], 0, sizeof(rq));
281 
282  uint8_t aw;
283  usart.receive(&aw, 0, sizeof(aw));
284 
285  reverse(aw); // DIP Schalter muss invertiert werden!
286 
287  return aw;
288 }
289 
290 void B15F::analogWrite0(uint16_t value)
291 {
292  uint8_t rq[] =
293  {
294  RQ_ANALOG_WRITE_0,
295  static_cast<uint8_t >(value & 0xFF),
296  static_cast<uint8_t >(value >> 8)
297  };
298 
299  assertRequestLength(rq, RQ_ANALOG_WRITE_0);
300  usart.transmit(&rq[0], 0, sizeof(rq));
301 
302  uint8_t aw;
303  usart.receive(&aw, 0, sizeof(aw));
304  assertCode(aw, MSG_OK);
305 }
306 
307 void B15F::analogWrite1(uint16_t value)
308 {
309  uint8_t rq[] =
310  {
311  RQ_ANALOG_WRITE_1,
312  static_cast<uint8_t >(value & 0xFF),
313  static_cast<uint8_t >(value >> 8)
314  };
315 
316  assertRequestLength(rq, RQ_ANALOG_WRITE_1);
317  usart.transmit(&rq[0], 0, sizeof(rq));
318 
319  uint8_t aw;
320  usart.receive(&aw, 0, sizeof(aw));
321  assertCode(aw, MSG_OK);
322 }
323 
324 uint16_t B15F::analogRead(uint8_t channel)
325 {
326  usart.clearInputBuffer();
327  if (channel > 7)
328  abort("Bad ADC channel: " + std::to_string(channel));
329 
330  uint8_t rq[] =
331  {
332  RQ_ANALOG_READ,
333  channel
334  };
335 
336  assertRequestLength(rq, RQ_ANALOG_READ);
337  usart.transmit(&rq[0], 0, sizeof(rq));
338 
339  uint16_t aw;
340  usart.receive(reinterpret_cast<uint8_t *>(&aw), 0, sizeof(aw));
341 
342  if (aw > 1023)
343  abort("Bad ADC data detected (1)");
344  return aw;
345 }
346 
347 void B15F::analogSequence(uint8_t channel_a, uint16_t *buffer_a, uint32_t offset_a, uint8_t channel_b, uint16_t *buffer_b,
348  uint32_t offset_b, uint16_t start, int16_t delta, uint16_t count)
349 {
350  // prepare pointers
351  buffer_a += offset_a;
352  buffer_b += offset_b;
353 
354 
355  usart.clearInputBuffer();
356  uint8_t rq[] =
357  {
358  RQ_ADC_DAC_STROKE,
359  channel_a,
360  channel_b,
361  static_cast<uint8_t >(start & 0xFF),
362  static_cast<uint8_t >(start >> 8),
363  static_cast<uint8_t >(delta & 0xFF),
364  static_cast<uint8_t >(delta >> 8),
365  static_cast<uint8_t >(count & 0xFF),
366  static_cast<uint8_t >(count >> 8)
367  };
368 
369  assertRequestLength(rq, RQ_ADC_DAC_STROKE);
370  usart.transmit(&rq[0], 0, sizeof(rq));
371 
372  for (uint16_t i = 0; i < count; i++)
373  {
374  if (buffer_a)
375  {
376  usart.receive(reinterpret_cast<uint8_t *>(&buffer_a[i]), 0, 2);
377 
378  if (buffer_a[i] > 1023) // check for broken usart connection
379  abort("Bad ADC data detected (2)");
380  }
381  else
382  {
383  usart.drop(2);
384  }
385 
386  if (buffer_b)
387  {
388  usart.receive(reinterpret_cast<uint8_t *>(&buffer_b[i]), 0, 2);
389 
390  if (buffer_b[i] > 1023) // check for broken usart connection
391  abort("Bad ADC data detected (3)");
392  }
393  else
394  {
395  usart.drop(2);
396  }
397  }
398 
399  uint8_t aw;
400  usart.receive(&aw, 0, sizeof(aw));
401  assertCode(aw, MSG_OK);
402 }
403 
404 uint8_t B15F::pwmSetFrequency(uint32_t freq)
405 {
406  usart.clearInputBuffer();
407 
408  uint8_t rq[] =
409  {
410  RQ_PWM_SET_FREQ,
411  static_cast<uint8_t>((freq >> 0) & 0xFF),
412  static_cast<uint8_t>((freq >> 8) & 0xFF),
413  static_cast<uint8_t>((freq >> 16) & 0xFF),
414  static_cast<uint8_t>((freq >> 24) & 0xFF)
415  };
416 
417  assertRequestLength(rq, RQ_PWM_SET_FREQ);
418  usart.transmit(&rq[0], 0, sizeof(rq));
419 
420  uint8_t aw;
421  usart.receive(&aw, 0, sizeof(aw));
422  return aw;
423 }
424 
425 void B15F::pwmSetValue(uint8_t value)
426 {
427  usart.clearInputBuffer();
428 
429  uint8_t rq[] =
430  {
431  RQ_PWM_SET_VALUE,
432  value
433  };
434 
435  assertRequestLength(rq, RQ_PWM_SET_VALUE);
436  usart.transmit(&rq[0], 0, sizeof(rq));
437 
438  uint8_t aw;
439  usart.receive(&aw, 0, sizeof(aw));
440  assertCode(aw, MSG_OK);
441 }
442 
443 void B15F::setMem8(volatile uint8_t* adr, uint8_t val)
444 {
445  usart.clearInputBuffer();
446 
447  uint8_t rq[] =
448  {
449  RQ_SET_MEM_8,
450  static_cast<uint8_t >(reinterpret_cast<size_t>(adr) & 0xFF),
451  static_cast<uint8_t >(reinterpret_cast<size_t>(adr) >> 8),
452  val
453  };
454 
455  assertRequestLength(rq, RQ_SET_MEM_8);
456  usart.transmit(&rq[0], 0, sizeof(rq));
457 
458  uint8_t aw;
459  usart.receive(&aw, 0, sizeof(aw));
460  assertCode(aw, MSG_OK);
461 }
462 
463 uint8_t B15F::getMem8(volatile uint8_t* adr)
464 {
465  usart.clearInputBuffer();
466 
467  uint8_t rq[] =
468  {
469  RQ_GET_MEM_8,
470  static_cast<uint8_t >(reinterpret_cast<size_t>(adr) & 0xFF),
471  static_cast<uint8_t >(reinterpret_cast<size_t>(adr) >> 8)
472  };
473 
474  assertRequestLength(rq, RQ_GET_MEM_8);
475  usart.transmit(&rq[0], 0, sizeof(rq));
476 
477  uint8_t aw;
478  usart.receive(&aw, 0, sizeof(aw));
479  return aw;
480 }
481 
482 void B15F::setMem16(volatile uint16_t* adr, uint16_t val)
483 {
484  usart.clearInputBuffer();
485 
486  uint8_t rq[] =
487  {
488  RQ_SET_MEM_16,
489  static_cast<uint8_t >(reinterpret_cast<size_t>(adr) & 0xFF),
490  static_cast<uint8_t >(reinterpret_cast<size_t>(adr) >> 8),
491  static_cast<uint8_t >(val & 0xFF),
492  static_cast<uint8_t >(val >> 8)
493  };
494 
495  assertRequestLength(rq, RQ_SET_MEM_16);
496  usart.transmit(&rq[0], 0, sizeof(rq));
497 
498  uint16_t aw;
499  usart.receive(reinterpret_cast<uint8_t *>(&aw), 0, sizeof(aw));
500  assertCode(aw, MSG_OK);
501 }
502 
503 uint16_t B15F::getMem16(volatile uint16_t* adr)
504 {
505  usart.clearInputBuffer();
506 
507  uint8_t rq[] =
508  {
509  RQ_GET_MEM_16,
510  static_cast<uint8_t >(reinterpret_cast<size_t>(adr) & 0xFF),
511  static_cast<uint8_t >(reinterpret_cast<size_t>(adr) >> 8)
512  };
513 
514  assertRequestLength(rq, RQ_GET_MEM_16);
515  usart.transmit(&rq[0], 0, sizeof(rq));
516 
517  uint16_t aw;
518  usart.receive(reinterpret_cast<uint8_t *>(&aw), 0, sizeof(aw));
519  return aw;
520 }
521 
522 void B15F::setRegister(volatile uint8_t* adr, uint8_t val)
523 {
524  setMem8(adr, val);
525 }
526 
527 uint8_t B15F::getRegister(volatile uint8_t* adr)
528 {
529  return getMem8(adr);
530 }
531 
533 {
534  usart.clearInputBuffer();
535 
536  uint8_t rq[] =
537  {
538  RQ_COUNTER_OFFSET
539  };
540 
541  assertRequestLength(rq, RQ_COUNTER_OFFSET);
542  usart.transmit(&rq[0], 0, sizeof(rq));
543 
544  uint16_t aw;
545  usart.receive(reinterpret_cast<uint8_t *>(&aw), 0, sizeof(aw));
546  return reinterpret_cast<uint16_t*>(aw);
547 }
548 
549 void B15F::setServoEnabled(void)
550 {
551  usart.clearInputBuffer();
552 
553  uint8_t rq[] =
554  {
555  RQ_SERVO_ENABLE
556  };
557 
558  assertRequestLength(rq, RQ_SERVO_ENABLE);
559  usart.transmit(&rq[0], 0, sizeof(rq));
560 
561  uint8_t aw;
562  usart.receive(&aw, 0, sizeof(aw));
563  assertCode(aw, MSG_OK);
564 }
565 
566 void B15F::setServoDisabled(void)
567 {
568  usart.clearInputBuffer();
569 
570  uint8_t rq[] =
571  {
572  RQ_SERVO_DISABLE
573  };
574 
575  assertRequestLength(rq, RQ_SERVO_DISABLE);
576  usart.transmit(&rq[0], 0, sizeof(rq));
577 
578  uint8_t aw;
579  usart.receive(&aw, 0, sizeof(aw));
580  assertCode(aw, MSG_OK);
581 }
582 
583 void B15F::setServoPosition(uint16_t pos)
584 {
585  if(pos > 19000)
586  throw DriverException("Impulslänge ist zu lang: " + std::to_string(pos));
587 
588  usart.clearInputBuffer();
589 
590  uint8_t rq[] =
591  {
592  RQ_SERVO_SET_POS,
593  static_cast<uint8_t >(pos & 0xFF),
594  static_cast<uint8_t >(pos >> 8)
595  };
596 
597  assertRequestLength(rq, RQ_SERVO_SET_POS);
598  usart.transmit(&rq[0], 0, sizeof(rq));
599 
600  uint8_t aw;
601  usart.receive(&aw, 0, sizeof(aw));
602  assertCode(aw, MSG_OK);
603 }
604 
605 /*************************/
606 
607 
608 /**********************
609  * Private Funktionen *
610  **********************/
611 
612 B15F::B15F()
613 {
614  init();
615 }
616 
617 
618 void B15F::init()
619 {
620 
621 #ifdef __arm__
622  // Raspberry Pi serial interface
623  std::string device = exec("bash -c 'ls /dev/ttyAMA* 2> /dev/null'");
624 #else
625  // normal PC serial interface
626  std::string device = exec("bash -c 'ls /dev/ttyUSB* 2> /dev/null'");
627 #endif
628 
629  while (device.find(' ') != std::string::npos || device.find('\n') != std::string::npos ||
630  device.find('\t') != std::string::npos)
631  device.pop_back();
632 
633  if (device.length() == 0)
634  abort("Adapter nicht gefunden");
635 
636  std::cout << PRE << "Verwende Adapter: " << device << std::endl;
637 
638 
639  std::cout << PRE << "Stelle Verbindung mit Adapter her... " << std::flush;
640  usart.setBaudrate(BAUDRATE);
641  usart.openDevice(device);
642  std::cout << "OK" << std::endl;
643 
644 
645  std::cout << PRE << "Teste Verbindung... " << std::flush;
646  uint8_t tries = 3;
647  while (tries--)
648  {
649  // verwerfe Daten, die µC noch hat
650  //discard();
651 
652  if (!testConnection())
653  continue;
654 
655  if (!testIntConv())
656  continue;
657 
658  break;
659  }
660  if (tries == 0)
661  abort("Verbindungstest fehlgeschlagen. Neueste Version im Einsatz?");
662  std::cout << "OK" << std::endl;
663 
664 
665  // Gib board info aus
666  std::vector<std::string> info = getBoardInfo();
667  std::cout << PRE << "AVR Firmware Version: " << info[0] << " um " << info[1] << " Uhr (" << info[2] << ")"
668  << std::endl;
669 }
-
void pwmSetValue(uint8_t value)
Definition: b15f.cpp:423
-
static std::string exec(std::string cmd)
Definition: b15f.cpp:145
-
void analogWrite0(uint16_t port)
Definition: b15f.cpp:288
-
void setServoPosition(uint16_t pos)
Definition: b15f.cpp:581
-
void analogWrite1(uint16_t port)
Definition: b15f.cpp:305
-
uint16_t getMem16(volatile uint16_t *adr)
Definition: b15f.cpp:501
-
void delay_us(uint16_t us)
Definition: b15f.cpp:132
-
uint8_t digitalRead0(void)
Definition: b15f.cpp:237
-
uint8_t pwmSetFrequency(uint32_t freq)
Definition: b15f.cpp:402
-
void digitalWrite0(uint8_t)
Definition: b15f.cpp:205
-
void analogSequence(uint8_t channel_a, uint16_t *buffer_a, uint32_t offset_a, uint8_t channel_b, uint16_t *buffer_b, uint32_t offset_b, uint16_t start, int16_t delta, uint16_t count)
Definition: b15f.cpp:345
-
bool testConnection(void)
Definition: b15f.cpp:56
-
uint8_t readDipSwitch(void)
Definition: b15f.cpp:269
-
uint8_t getRegister(volatile uint8_t *adr)
Definition: b15f.cpp:525
-
uint8_t getMem8(volatile uint8_t *adr)
Definition: b15f.cpp:461
-
void delay_ms(uint16_t ms)
Definition: b15f.cpp:127
+
1 #include "b15f.h"
2 
3 B15F *B15F::instance = nullptr;
4 errorhandler_t B15F::errorhandler = nullptr;
5 
6 
7 /*************************************
8  * Grundfunktionen des B15F Treibers *
9  *************************************/
10 
12 {
13  if (!instance)
14  instance = new B15F();
15 
16  return *instance;
17 }
18 
19 void B15F::reconnect()
20 {
21  uint8_t tries = RECONNECT_TRIES;
22  while (tries--)
23  {
25  discard();
26 
27  try
28  {
30  return; // no exceptionm means success
31  }
32  catch(DriverException& eDE)
33  {
34  // discard exception
35  }
36  }
37 
38  abort("Verbindung kann nicht repariert werden");
39 }
40 
41 void B15F::discard(void)
42 {
43  try
44  {
45  uint8_t rq[] =
46  {
47  RQ_DISCARD
48  };
49 
50  usart.clearOutputBuffer();
51  for (uint8_t i = 0; i < 16; i++)
52  {
53  usart.transmit(&rq[0], 0, sizeof(rq)); // sende discard Befehl (verwerfe input)
54  delay_ms(4);
55  }
56  usart.clearInputBuffer();
57  }
58  catch (std::exception &ex)
59  {
60  abort(ex);
61  }
62 }
63 
65 {
66  // erzeuge zufälliges Byte
67  srand(time(NULL));
68  uint8_t dummy = rand() % 256;
69 
70  uint8_t rq[] =
71  {
72  RQ_TEST,
73  dummy
74  };
75  usart.transmit(&rq[0], 0, sizeof(rq));
76 
77  uint8_t aw[2];
78  usart.receive(&aw[0], 0, sizeof(aw));
79 
80  assertCode(aw[0], MSG_OK);
81  assertCode(aw[1], dummy);
82 }
83 
84 void B15F::testIntConv()
85 {
86  srand(time(NULL));
87  uint16_t dummy = rand() % (0xFFFF / 3);
88 
89  uint8_t rq[] =
90  {
91  RQ_INT_TEST,
92  static_cast<uint8_t >(dummy & 0xFF),
93  static_cast<uint8_t >(dummy >> 8)
94  };
95  usart.transmit(&rq[0], 0, sizeof(rq));
96 
97  uint16_t aw;
98  usart.receive(reinterpret_cast<uint8_t *>(&aw), 0, sizeof(aw));
99 
100  assertCode(aw, dummy * 3);
101 }
102 
103 
104 std::vector<std::string> B15F::getBoardInfo(void)
105 {
106  std::vector<std::string> info;
107 
108  uint8_t rq[] =
109  {
110  RQ_INFO
111  };
112  usart.transmit(&rq[0], 0, sizeof(rq));
113 
114  uint8_t n;
115  usart.receive(&n, 0, sizeof(n));
116  while (n--)
117  {
118  uint8_t len;
119  usart.receive(&len, 0, sizeof(len));
120 
121  char str[len + 1];
122  str[len] = '\0';
123  usart.receive(reinterpret_cast<uint8_t *>(&str[0]), 0, len);
124 
125  info.push_back(std::string(str));
126  }
127 
128  uint8_t aw;
129  usart.receive(&aw, 0, sizeof(aw));
130  if (aw != MSG_OK)
131  abort("Board Info fehlerhalft: code " + std::to_string((int) aw));
132 
133  return info;
134 }
135 
136 void B15F::delay_ms(uint16_t ms)
137 {
138  std::this_thread::sleep_for(std::chrono::milliseconds(ms));
139 }
140 
141 void B15F::delay_us(uint16_t us)
142 {
143  std::this_thread::sleep_for(std::chrono::microseconds(us));
144 }
145 
146 void B15F::reverse(uint8_t& b)
147 {
148  b = (b & 0xF0) >> 4 | (b & 0x0F) << 4;
149  b = (b & 0xCC) >> 2 | (b & 0x33) << 2;
150  b = (b & 0xAA) >> 1 | (b & 0x55) << 1;
151 }
152 
153 // https://stackoverflow.com/a/478960
154 std::string B15F::exec(std::string cmd)
155 {
156  std::array<char, 128> buffer;
157  std::string result;
158  std::unique_ptr<FILE, decltype(&pclose)> pipe(popen(cmd.c_str(), "r"), pclose);
159  if (!pipe)
160  {
161  throw std::runtime_error("popen() failed!");
162  }
163  while (fgets(buffer.data(), buffer.size(), pipe.get()) != nullptr)
164  {
165  result += buffer.data();
166  }
167  return result;
168 }
169 
170 void B15F::abort(std::string msg)
171 {
172  DriverException ex(msg);
173  abort(ex);
174 }
175 
176 void B15F::abort(std::exception &ex)
177 {
178  if (errorhandler)
179  errorhandler(ex);
180  else
181  {
182  std::cout << ex.what() << std::endl;
183  throw DriverException(ex.what());
184  }
185 }
186 
187 void B15F::setAbortHandler(errorhandler_t func)
188 {
189  errorhandler = func;
190 }
191 
192 /*************************************/
193 
194 
195 
196 /*************************
197  * Steuerbefehle für B15 *
198  *************************/
199 
201 {
202  uint8_t rq[] =
203  {
204  RQ_SELF_TEST
205  };
206 
207  assertRequestLength(rq, RQ_SELF_TEST);
208  usart.transmit(&rq[0], 0, sizeof(rq));
209 
210  uint8_t aw;
211  usart.receive(&aw, 0, sizeof(aw));
212  assertCode(aw, MSG_OK);
213 }
214 
215 void B15F::digitalWrite0(uint8_t port)
216 {
217  uint8_t rq[] =
218  {
219  RQ_DIGITAL_WRITE_0,
220  port
221  };
222 
223  assertRequestLength(rq, RQ_DIGITAL_WRITE_0);
224  usart.transmit(&rq[0], 0, sizeof(rq));
225 
226  uint8_t aw;
227  usart.receive(&aw, 0, sizeof(aw));
228  assertCode(aw, MSG_OK);
229 }
230 
231 void B15F::digitalWrite1(uint8_t port)
232 {
233  uint8_t rq[] =
234  {
235  RQ_DIGITAL_WRITE_1,
236  port
237  };
238 
239  assertRequestLength(rq, RQ_DIGITAL_WRITE_1);
240  usart.transmit(&rq[0], 0, sizeof(rq));
241 
242  uint8_t aw;
243  usart.receive(&aw, 0, sizeof(aw));
244  assertCode(aw, MSG_OK);
245 }
246 
247 uint8_t B15F::digitalRead0()
248 {
249  usart.clearInputBuffer();
250  uint8_t rq[] =
251  {
252  RQ_DIGITAL_READ_0
253  };
254 
255  assertRequestLength(rq, RQ_DIGITAL_READ_0);
256  usart.transmit(&rq[0], 0, sizeof(rq));
257 
258  uint8_t aw;
259  usart.receive(&aw, 0, sizeof(aw));
260  return aw;
261 }
262 
263 uint8_t B15F::digitalRead1()
264 {
265  usart.clearInputBuffer();
266  uint8_t rq[] =
267  {
268  RQ_DIGITAL_READ_1
269  };
270 
271  assertRequestLength(rq, RQ_DIGITAL_READ_1);
272  usart.transmit(&rq[0], 0, sizeof(rq));
273 
274  uint8_t aw;
275  usart.receive(&aw, 0, sizeof(aw));
276  return aw;
277 }
278 
279 uint8_t B15F::readDipSwitch()
280 {
281  usart.clearInputBuffer();
282  uint8_t rq[] =
283  {
284  RQ_READ_DIP_SWITCH
285  };
286 
287  assertRequestLength(rq, RQ_READ_DIP_SWITCH);
288  usart.transmit(&rq[0], 0, sizeof(rq));
289 
290  uint8_t aw;
291  usart.receive(&aw, 0, sizeof(aw));
292 
293  reverse(aw); // DIP Schalter muss invertiert werden!
294 
295  return aw;
296 }
297 
298 void B15F::analogWrite0(uint16_t value)
299 {
300  uint8_t rq[] =
301  {
302  RQ_ANALOG_WRITE_0,
303  static_cast<uint8_t >(value & 0xFF),
304  static_cast<uint8_t >(value >> 8)
305  };
306 
307  assertRequestLength(rq, RQ_ANALOG_WRITE_0);
308  usart.transmit(&rq[0], 0, sizeof(rq));
309 
310  uint8_t aw;
311  usart.receive(&aw, 0, sizeof(aw));
312  assertCode(aw, MSG_OK);
313 }
314 
315 void B15F::analogWrite1(uint16_t value)
316 {
317  uint8_t rq[] =
318  {
319  RQ_ANALOG_WRITE_1,
320  static_cast<uint8_t >(value & 0xFF),
321  static_cast<uint8_t >(value >> 8)
322  };
323 
324  assertRequestLength(rq, RQ_ANALOG_WRITE_1);
325  usart.transmit(&rq[0], 0, sizeof(rq));
326 
327  uint8_t aw;
328  usart.receive(&aw, 0, sizeof(aw));
329  assertCode(aw, MSG_OK);
330 }
331 
332 uint16_t B15F::analogRead(uint8_t channel)
333 {
334  usart.clearInputBuffer();
335  if (channel > 7)
336  abort("Bad ADC channel: " + std::to_string(channel));
337 
338  uint8_t rq[] =
339  {
340  RQ_ANALOG_READ,
341  channel
342  };
343 
344  assertRequestLength(rq, RQ_ANALOG_READ);
345  usart.transmit(&rq[0], 0, sizeof(rq));
346 
347  uint16_t aw;
348  usart.receive(reinterpret_cast<uint8_t *>(&aw), 0, sizeof(aw));
349 
350  if (aw > 1023)
351  abort("Bad ADC data detected (1)");
352  return aw;
353 }
354 
355 void B15F::analogSequence(uint8_t channel_a, uint16_t *buffer_a, uint32_t offset_a, uint8_t channel_b, uint16_t *buffer_b,
356  uint32_t offset_b, uint16_t start, int16_t delta, uint16_t count)
357 {
358  // prepare pointers
359  buffer_a += offset_a;
360  buffer_b += offset_b;
361 
362 
363  usart.clearInputBuffer();
364  uint8_t rq[] =
365  {
366  RQ_ADC_DAC_STROKE,
367  channel_a,
368  channel_b,
369  static_cast<uint8_t >(start & 0xFF),
370  static_cast<uint8_t >(start >> 8),
371  static_cast<uint8_t >(delta & 0xFF),
372  static_cast<uint8_t >(delta >> 8),
373  static_cast<uint8_t >(count & 0xFF),
374  static_cast<uint8_t >(count >> 8)
375  };
376 
377  assertRequestLength(rq, RQ_ADC_DAC_STROKE);
378  usart.transmit(&rq[0], 0, sizeof(rq));
379 
380  for (uint16_t i = 0; i < count; i++)
381  {
382  if (buffer_a)
383  {
384  usart.receive(reinterpret_cast<uint8_t *>(&buffer_a[i]), 0, 2);
385 
386  if (buffer_a[i] > 1023) // check for broken usart connection
387  abort("Bad ADC data detected (2)");
388  }
389  else
390  {
391  usart.drop(2);
392  }
393 
394  if (buffer_b)
395  {
396  usart.receive(reinterpret_cast<uint8_t *>(&buffer_b[i]), 0, 2);
397 
398  if (buffer_b[i] > 1023) // check for broken usart connection
399  abort("Bad ADC data detected (3)");
400  }
401  else
402  {
403  usart.drop(2);
404  }
405  }
406 
407  uint8_t aw;
408  usart.receive(&aw, 0, sizeof(aw));
409  assertCode(aw, MSG_OK);
410 }
411 
412 uint8_t B15F::pwmSetFrequency(uint32_t freq)
413 {
414  usart.clearInputBuffer();
415 
416  uint8_t rq[] =
417  {
418  RQ_PWM_SET_FREQ,
419  static_cast<uint8_t>((freq >> 0) & 0xFF),
420  static_cast<uint8_t>((freq >> 8) & 0xFF),
421  static_cast<uint8_t>((freq >> 16) & 0xFF),
422  static_cast<uint8_t>((freq >> 24) & 0xFF)
423  };
424 
425  assertRequestLength(rq, RQ_PWM_SET_FREQ);
426  usart.transmit(&rq[0], 0, sizeof(rq));
427 
428  uint8_t aw;
429  usart.receive(&aw, 0, sizeof(aw));
430  return aw;
431 }
432 
433 void B15F::pwmSetValue(uint8_t value)
434 {
435  usart.clearInputBuffer();
436 
437  uint8_t rq[] =
438  {
439  RQ_PWM_SET_VALUE,
440  value
441  };
442 
443  assertRequestLength(rq, RQ_PWM_SET_VALUE);
444  usart.transmit(&rq[0], 0, sizeof(rq));
445 
446  uint8_t aw;
447  usart.receive(&aw, 0, sizeof(aw));
448  assertCode(aw, MSG_OK);
449 }
450 
451 void B15F::setMem8(volatile uint8_t* adr, uint8_t val)
452 {
453  usart.clearInputBuffer();
454 
455  uint8_t rq[] =
456  {
457  RQ_SET_MEM_8,
458  static_cast<uint8_t >(reinterpret_cast<size_t>(adr) & 0xFF),
459  static_cast<uint8_t >(reinterpret_cast<size_t>(adr) >> 8),
460  val
461  };
462 
463  assertRequestLength(rq, RQ_SET_MEM_8);
464  usart.transmit(&rq[0], 0, sizeof(rq));
465 
466  uint8_t aw;
467  usart.receive(&aw, 0, sizeof(aw));
468  assertCode(aw, MSG_OK);
469 }
470 
471 uint8_t B15F::getMem8(volatile uint8_t* adr)
472 {
473  usart.clearInputBuffer();
474 
475  uint8_t rq[] =
476  {
477  RQ_GET_MEM_8,
478  static_cast<uint8_t >(reinterpret_cast<size_t>(adr) & 0xFF),
479  static_cast<uint8_t >(reinterpret_cast<size_t>(adr) >> 8)
480  };
481 
482  assertRequestLength(rq, RQ_GET_MEM_8);
483  usart.transmit(&rq[0], 0, sizeof(rq));
484 
485  uint8_t aw;
486  usart.receive(&aw, 0, sizeof(aw));
487  return aw;
488 }
489 
490 void B15F::setMem16(volatile uint16_t* adr, uint16_t val)
491 {
492  usart.clearInputBuffer();
493 
494  uint8_t rq[] =
495  {
496  RQ_SET_MEM_16,
497  static_cast<uint8_t >(reinterpret_cast<size_t>(adr) & 0xFF),
498  static_cast<uint8_t >(reinterpret_cast<size_t>(adr) >> 8),
499  static_cast<uint8_t >(val & 0xFF),
500  static_cast<uint8_t >(val >> 8)
501  };
502 
503  assertRequestLength(rq, RQ_SET_MEM_16);
504  usart.transmit(&rq[0], 0, sizeof(rq));
505 
506  uint16_t aw;
507  usart.receive(reinterpret_cast<uint8_t *>(&aw), 0, sizeof(aw));
508  assertCode(aw, MSG_OK);
509 }
510 
511 uint16_t B15F::getMem16(volatile uint16_t* adr)
512 {
513  usart.clearInputBuffer();
514 
515  uint8_t rq[] =
516  {
517  RQ_GET_MEM_16,
518  static_cast<uint8_t >(reinterpret_cast<size_t>(adr) & 0xFF),
519  static_cast<uint8_t >(reinterpret_cast<size_t>(adr) >> 8)
520  };
521 
522  assertRequestLength(rq, RQ_GET_MEM_16);
523  usart.transmit(&rq[0], 0, sizeof(rq));
524 
525  uint16_t aw;
526  usart.receive(reinterpret_cast<uint8_t *>(&aw), 0, sizeof(aw));
527  return aw;
528 }
529 
530 void B15F::setRegister(volatile uint8_t* adr, uint8_t val)
531 {
532  setMem8(adr, val);
533 }
534 
535 uint8_t B15F::getRegister(volatile uint8_t* adr)
536 {
537  return getMem8(adr);
538 }
539 
541 {
542  usart.clearInputBuffer();
543 
544  uint8_t rq[] =
545  {
546  RQ_COUNTER_OFFSET
547  };
548 
549  assertRequestLength(rq, RQ_COUNTER_OFFSET);
550  usart.transmit(&rq[0], 0, sizeof(rq));
551 
552  uint16_t aw;
553  usart.receive(reinterpret_cast<uint8_t *>(&aw), 0, sizeof(aw));
554  return reinterpret_cast<uint16_t*>(aw);
555 }
556 
557 void B15F::setServoEnabled(void)
558 {
559  usart.clearInputBuffer();
560 
561  uint8_t rq[] =
562  {
563  RQ_SERVO_ENABLE
564  };
565 
566  assertRequestLength(rq, RQ_SERVO_ENABLE);
567  usart.transmit(&rq[0], 0, sizeof(rq));
568 
569  uint8_t aw;
570  usart.receive(&aw, 0, sizeof(aw));
571  assertCode(aw, MSG_OK);
572 }
573 
574 void B15F::setServoDisabled(void)
575 {
576  usart.clearInputBuffer();
577 
578  uint8_t rq[] =
579  {
580  RQ_SERVO_DISABLE
581  };
582 
583  assertRequestLength(rq, RQ_SERVO_DISABLE);
584  usart.transmit(&rq[0], 0, sizeof(rq));
585 
586  uint8_t aw;
587  usart.receive(&aw, 0, sizeof(aw));
588  assertCode(aw, MSG_OK);
589 }
590 
591 void B15F::setServoPosition(uint16_t pos)
592 {
593  if(pos > 19000)
594  throw DriverException("Impulslänge ist zu lang: " + std::to_string(pos));
595 
596  usart.clearInputBuffer();
597 
598  uint8_t rq[] =
599  {
600  RQ_SERVO_SET_POS,
601  static_cast<uint8_t >(pos & 0xFF),
602  static_cast<uint8_t >(pos >> 8)
603  };
604 
605  assertRequestLength(rq, RQ_SERVO_SET_POS);
606  usart.transmit(&rq[0], 0, sizeof(rq));
607 
608  uint8_t aw;
609  usart.receive(&aw, 0, sizeof(aw));
610  assertCode(aw, MSG_OK);
611 }
612 
613 /*************************/
614 
615 
616 /**********************
617  * Private Funktionen *
618  **********************/
619 
620 B15F::B15F()
621 {
622  init();
623 }
624 
625 
626 void B15F::init()
627 {
628 
629 #ifdef __arm__
630  // Raspberry Pi serial interface
631  std::string device = exec("bash -c 'ls /dev/ttyAMA* 2> /dev/null'");
632 #else
633  // normal PC serial interface
634  std::string device = exec("bash -c 'ls /dev/ttyUSB* 2> /dev/null'");
635 #endif
636 
637  while (device.find(' ') != std::string::npos || device.find('\n') != std::string::npos ||
638  device.find('\t') != std::string::npos)
639  device.pop_back();
640 
641  if (device.length() == 0)
642  abort("Adapter nicht gefunden");
643 
644  std::cout << PRE << "Verwende Adapter: " << device << std::endl;
645 
646 
647  std::cout << PRE << "Stelle Verbindung mit Adapter her... " << std::flush;
648  usart.setBaudrate(BAUDRATE);
649  usart.openDevice(device);
650  std::cout << "OK" << std::endl;
651 
652 
653  std::cout << PRE << "Teste Verbindung... " << std::flush;
654  int tries = 4;
655  while (--tries)
656  {
657  discard();
658 
659  try
660  {
661  testConnection();
662  }
663  catch(DriverException& eDE)
664  {
665  continue;
666  }
667 
668  try
669  {
670  testIntConv();
671  }
672  catch(DriverException& eDE)
673  {
674  continue;
675  }
676 
677  break;
678  }
679  if (!tries)
680  abort("Verbindungstest fehlgeschlagen. Neueste Version im Einsatz?");
681 
682  std::cout << "OK" << std::endl;
683 
684 
685  // Gib board info aus
686  std::vector<std::string> info = getBoardInfo();
687  std::cout << PRE << "AVR Firmware Version: " << info[0] << " um " << info[1] << " Uhr (" << info[2] << ")"
688  << std::endl;
689 }
+
void testIntConv(void)
Definition: b15f.cpp:83
+
void pwmSetValue(uint8_t value)
Definition: b15f.cpp:431
+
static std::string exec(std::string cmd)
Definition: b15f.cpp:153
+
void analogWrite0(uint16_t port)
Definition: b15f.cpp:296
+
void setServoPosition(uint16_t pos)
Definition: b15f.cpp:589
+
void analogWrite1(uint16_t port)
Definition: b15f.cpp:313
+
uint16_t getMem16(volatile uint16_t *adr)
Definition: b15f.cpp:509
+
void delay_us(uint16_t us)
Definition: b15f.cpp:140
+
uint8_t digitalRead0(void)
Definition: b15f.cpp:245
+
uint8_t pwmSetFrequency(uint32_t freq)
Definition: b15f.cpp:410
+
void digitalWrite0(uint8_t)
Definition: b15f.cpp:213
+
void analogSequence(uint8_t channel_a, uint16_t *buffer_a, uint32_t offset_a, uint8_t channel_b, uint16_t *buffer_b, uint32_t offset_b, uint16_t start, int16_t delta, uint16_t count)
Definition: b15f.cpp:353
+
uint8_t readDipSwitch(void)
Definition: b15f.cpp:277
+
uint8_t getRegister(volatile uint8_t *adr)
Definition: b15f.cpp:533
+
uint8_t getMem8(volatile uint8_t *adr)
Definition: b15f.cpp:469
+
void delay_ms(uint16_t ms)
Definition: b15f.cpp:135
+
void testConnection(void)
Definition: b15f.cpp:63
static B15F & getInstance(void)
Definition: b15f.cpp:10
-
Definition: b15f.h:33
+
Definition: b15f.h:37
void transmit(uint8_t *buffer, uint16_t offset, uint8_t len)
Definition: usart.cpp:75
-
static void abort(std::string msg)
Definition: b15f.cpp:161
+
static void abort(std::string msg)
Definition: b15f.cpp:169
void receive(uint8_t *buffer, uint16_t offset, uint8_t len)
Definition: usart.cpp:84
void clearInputBuffer(void)
Definition: usart.cpp:54
-
uint16_t * getInterruptCounterOffset(void)
Definition: b15f.cpp:530
-
void setMem16(volatile uint16_t *adr, uint16_t val)
Definition: b15f.cpp:480
+
uint16_t * getInterruptCounterOffset(void)
Definition: b15f.cpp:538
+
void setMem16(volatile uint16_t *adr, uint16_t val)
Definition: b15f.cpp:488
void clearOutputBuffer(void)
Definition: usart.cpp:61
-
uint16_t analogRead(uint8_t channel)
Definition: b15f.cpp:322
-
void activateSelfTestMode(void)
Definition: b15f.cpp:190
-
const std::string PRE
B15F stdout prefix.
Definition: b15f.h:305
-
void reverse(uint8_t &b)
Definition: b15f.cpp:137
+
uint16_t analogRead(uint8_t channel)
Definition: b15f.cpp:330
+
void activateSelfTestMode(void)
Definition: b15f.cpp:198
+
const std::string PRE
B15F stdout prefix.
Definition: b15f.h:309
+
void reverse(uint8_t &b)
Definition: b15f.cpp:145
void setBaudrate(uint32_t baudrate)
Definition: usart.cpp:131
-
std::vector< std::string > getBoardInfo(void)
Definition: b15f.cpp:95
-
constexpr static uint16_t RECONNECT_TIMEOUT
Time in ms after which a reconnect attempt aborts.
Definition: b15f.h:308
-
void discard(void)
Definition: b15f.cpp:33
-
void setRegister(volatile uint8_t *adr, uint8_t val)
Definition: b15f.cpp:520
-
constexpr static uint8_t MSG_OK
Value to acknowledge a received command.
Definition: b15f.h:306
+
std::vector< std::string > getBoardInfo(void)
Definition: b15f.cpp:103
+
constexpr static uint16_t RECONNECT_TIMEOUT
Time in ms after which a reconnect attempt aborts.
Definition: b15f.h:312
+
void discard(void)
Definition: b15f.cpp:40
+
void setRegister(volatile uint8_t *adr, uint8_t val)
Definition: b15f.cpp:528
+
constexpr static uint8_t MSG_OK
Value to acknowledge a received command.
Definition: b15f.h:310
void openDevice(std::string device)
Definition: usart.cpp:9
-
uint8_t digitalRead1(void)
Definition: b15f.cpp:253
+
uint8_t digitalRead1(void)
Definition: b15f.cpp:261
void reconnect(void)
Definition: b15f.cpp:18
-
constexpr static uint32_t BAUDRATE
USART baudrate for communication with the MCU.
Definition: b15f.h:311
-
static void setAbortHandler(errorhandler_t func)
Definition: b15f.cpp:178
+
constexpr static uint32_t BAUDRATE
USART baudrate for communication with the MCU.
Definition: b15f.h:315
+
static void setAbortHandler(errorhandler_t func)
Definition: b15f.cpp:186
void drop(uint8_t len)
Definition: usart.cpp:114
-
void digitalWrite1(uint8_t)
Definition: b15f.cpp:221
-
void setServoEnabled(void)
Definition: b15f.cpp:547
-
constexpr static uint8_t RECONNECT_TRIES
Maximum count of reconnect attempts after which the driver stops.
Definition: b15f.h:310
-
void setMem8(volatile uint8_t *adr, uint8_t val)
Definition: b15f.cpp:441
-
void setServoDisabled(void)
Definition: b15f.cpp:564
-
bool testIntConv(void)
Definition: b15f.cpp:75
+
void digitalWrite1(uint8_t)
Definition: b15f.cpp:229
+
void setServoEnabled(void)
Definition: b15f.cpp:555
+
constexpr static uint8_t RECONNECT_TRIES
Maximum count of reconnect attempts after which the driver stops.
Definition: b15f.h:314
+
void setMem8(volatile uint8_t *adr, uint8_t val)
Definition: b15f.cpp:449
+
void setServoDisabled(void)
Definition: b15f.cpp:572
diff --git a/docs/html/b15f_8h_source.html b/docs/html/b15f_8h_source.html index 0b91531..eea1c74 100644 --- a/docs/html/b15f_8h_source.html +++ b/docs/html/b15f_8h_source.html @@ -70,54 +70,54 @@ $(function() {
b15f.h
-
1 #ifndef B15F_H
2 #define B15F_H
3 
4 #include <iostream>
5 #include <bits/stdc++.h>
6 #include <string>
7 #include <fstream>
8 #include <cstdlib>
9 #include <chrono>
10 #include <cstdint>
11 #include <vector>
12 
13 #include <unistd.h>
14 #include <fcntl.h>
15 #include <sys/ioctl.h>
16 #include <termios.h>
17 
18 #include "requests.h"
19 #include "usart.h"
20 #include "driverexception.h"
21 #include "timeoutexception.h"
22 
23 // wichtig für die Register-Zugriffe
24 #define _AVR_IO_H_ 1 // Erzwinge die Inklusion
25 #include "/usr/lib/avr/include/avr/sfr_defs.h"
26 #include "/usr/lib/avr/include/avr/iom1284p.h"
27 
28 typedef std::function<void(std::exception&)> errorhandler_t;
29 
30 
33 class B15F
34 {
35 public:
36 
37  /*************************************
38  * Grundfunktionen des B15F Treibers *
39  *************************************/
40 
45  static B15F& getInstance(void);
46 
51  void reconnect(void);
52 
57  void discard(void);
58 
63  bool testConnection(void);
64 
69  bool testIntConv(void);
70 
75  std::vector<std::string> getBoardInfo(void);
76 
81  void delay_ms(uint16_t ms);
82 
87  void delay_us(uint16_t us);
88 
94  void reverse(uint8_t& b);
95 
100  static std::string exec(std::string cmd);
101 
106  static void abort(std::string msg);
107 
112  static void abort(std::exception& ex);
113 
118  static void setAbortHandler(errorhandler_t func);
119 
120  /*************************************/
121 
122 
123 
124  /*************************
125  * Steuerbefehle für B15 *
126  *************************/
127 
133  void activateSelfTestMode(void);
134 
140  void digitalWrite0(uint8_t);
141 
147  void digitalWrite1(uint8_t);
148 
154  uint8_t digitalRead0(void);
155 
161  uint8_t digitalRead1(void);
162 
168  uint8_t readDipSwitch(void);
169 
175  void analogWrite0(uint16_t port);
176 
182  void analogWrite1(uint16_t port);
183 
189  uint16_t analogRead(uint8_t channel);
190 
206  void analogSequence(uint8_t channel_a, uint16_t* buffer_a, uint32_t offset_a, uint8_t channel_b, uint16_t* buffer_b, uint32_t offset_b, uint16_t start, int16_t delta, uint16_t count);
207 
217  uint8_t pwmSetFrequency(uint32_t freq);
218 
224  void pwmSetValue(uint8_t value);
225 
234  void setMem8(volatile uint8_t* adr, uint8_t val);
235 
242  uint8_t getMem8(volatile uint8_t* adr);
243 
252  void setMem16(volatile uint16_t* adr, uint16_t val);
253 
260  uint16_t getMem16(volatile uint16_t* adr);
261 
269  void setRegister(volatile uint8_t* adr, uint8_t val);
270 
276  uint8_t getRegister(volatile uint8_t* adr);
277 
282  uint16_t* getInterruptCounterOffset(void);
283 
288  void setServoEnabled(void);
289 
294  void setServoDisabled(void);
295 
301  void setServoPosition(uint16_t pos);
302 
303  /*************************/
304 
305 
306  // CONSTANTS
307  const std::string PRE = "[B15F] ";
308  constexpr static uint8_t MSG_OK = 0xFF;
309  constexpr static uint8_t MSG_FAIL = 0xFE;
310  constexpr static uint16_t RECONNECT_TIMEOUT = 64;
311  constexpr static uint16_t WDT_TIMEOUT = 15;
312  constexpr static uint8_t RECONNECT_TRIES = 3;
313  constexpr static uint32_t BAUDRATE = 57600;
314 
315 private:
316 
320  B15F(void);
321 
326  void init(void);
327 
332  template<typename CodeType, typename ExpectationType>
333  void assertCode(CodeType& code, ExpectationType expectation) const
334  {
335  if(code != static_cast<CodeType>(expectation))
336  throw DriverException("Ungültige Antwort erhalten: " + std::to_string((int) code) + " (erwartet: " + std::to_string((int) expectation) + ")");
337  }
338 
343  template<size_t RequestLength>
344  void assertRequestLength(uint8_t (&)[RequestLength], uint8_t rq_num)
345  {
346  if(RequestLength != rq_len[rq_num])
347  throw DriverException("Ungültige Request Länge: " + std::to_string(RequestLength) + " (erwartet: " + std::to_string(rq_len[rq_num]) + ")");
348  }
349 
350  USART usart;
351  static B15F* instance;
352  static errorhandler_t errorhandler;
353 };
354 
355 #endif // B15F_H
-
void pwmSetValue(uint8_t value)
Definition: b15f.cpp:423
-
static std::string exec(std::string cmd)
Definition: b15f.cpp:145
-
constexpr static uint8_t MSG_FAIL
Value to reject a received command.
Definition: b15f.h:307
-
void analogWrite0(uint16_t port)
Definition: b15f.cpp:288
-
void setServoPosition(uint16_t pos)
Definition: b15f.cpp:581
-
void analogWrite1(uint16_t port)
Definition: b15f.cpp:305
-
uint16_t getMem16(volatile uint16_t *adr)
Definition: b15f.cpp:501
-
void delay_us(uint16_t us)
Definition: b15f.cpp:132
-
uint8_t digitalRead0(void)
Definition: b15f.cpp:237
-
uint8_t pwmSetFrequency(uint32_t freq)
Definition: b15f.cpp:402
-
void digitalWrite0(uint8_t)
Definition: b15f.cpp:205
-
void analogSequence(uint8_t channel_a, uint16_t *buffer_a, uint32_t offset_a, uint8_t channel_b, uint16_t *buffer_b, uint32_t offset_b, uint16_t start, int16_t delta, uint16_t count)
Definition: b15f.cpp:345
-
bool testConnection(void)
Definition: b15f.cpp:56
-
uint8_t readDipSwitch(void)
Definition: b15f.cpp:269
-
uint8_t getRegister(volatile uint8_t *adr)
Definition: b15f.cpp:525
-
uint8_t getMem8(volatile uint8_t *adr)
Definition: b15f.cpp:461
-
void delay_ms(uint16_t ms)
Definition: b15f.cpp:127
+
1 #ifndef B15F_H
2 #define B15F_H
3 
4 #include <iostream>
5 #include <bits/stdc++.h>
6 #include <string>
7 #include <fstream>
8 #include <cstdlib>
9 #include <chrono>
10 #include <cstdint>
11 #include <vector>
12 
13 #include <unistd.h>
14 #include <fcntl.h>
15 #include <sys/ioctl.h>
16 #include <termios.h>
17 
18 #include "requests.h"
19 #include "usart.h"
20 #include "driverexception.h"
21 #include "timeoutexception.h"
22 
23 // wichtig für die Register-Zugriffe
24 #define _AVR_IO_H_ 1 // Erzwinge die Inklusion
25 #include "/usr/lib/avr/include/avr/sfr_defs.h"
26 #include "/usr/lib/avr/include/avr/iom1284p.h"
27 
28 typedef std::function<void(std::exception&)> errorhandler_t;
29 
30 // Wrapper für Codeposition-Ersetzung
31 #define assertCode(code, expectation) assertCodeFunc(code, expectation, &__FUNCTION__[0], &__FILE__[0], __LINE__)
32 #define assertRequestLength(rq, rq_num) assertRequestLengthFunc(rq, rq_num,& __FUNCTION__[0], &__FILE__[0], __LINE__)
33 
34 
37 class B15F
38 {
39 public:
40 
41  /*************************************
42  * Grundfunktionen des B15F Treibers *
43  *************************************/
44 
49  static B15F& getInstance(void);
50 
55  void reconnect(void);
56 
61  void discard(void);
62 
67  void testConnection(void);
68 
73  void testIntConv(void);
74 
79  std::vector<std::string> getBoardInfo(void);
80 
85  void delay_ms(uint16_t ms);
86 
91  void delay_us(uint16_t us);
92 
98  void reverse(uint8_t& b);
99 
104  static std::string exec(std::string cmd);
105 
110  static void abort(std::string msg);
111 
116  static void abort(std::exception& ex);
117 
122  static void setAbortHandler(errorhandler_t func);
123 
124  /*************************************/
125 
126 
127 
128  /*************************
129  * Steuerbefehle für B15 *
130  *************************/
131 
137  void activateSelfTestMode(void);
138 
144  void digitalWrite0(uint8_t);
145 
151  void digitalWrite1(uint8_t);
152 
158  uint8_t digitalRead0(void);
159 
165  uint8_t digitalRead1(void);
166 
172  uint8_t readDipSwitch(void);
173 
179  void analogWrite0(uint16_t port);
180 
186  void analogWrite1(uint16_t port);
187 
193  uint16_t analogRead(uint8_t channel);
194 
210  void analogSequence(uint8_t channel_a, uint16_t* buffer_a, uint32_t offset_a, uint8_t channel_b, uint16_t* buffer_b, uint32_t offset_b, uint16_t start, int16_t delta, uint16_t count);
211 
221  uint8_t pwmSetFrequency(uint32_t freq);
222 
228  void pwmSetValue(uint8_t value);
229 
238  void setMem8(volatile uint8_t* adr, uint8_t val);
239 
246  uint8_t getMem8(volatile uint8_t* adr);
247 
256  void setMem16(volatile uint16_t* adr, uint16_t val);
257 
264  uint16_t getMem16(volatile uint16_t* adr);
265 
273  void setRegister(volatile uint8_t* adr, uint8_t val);
274 
280  uint8_t getRegister(volatile uint8_t* adr);
281 
286  uint16_t* getInterruptCounterOffset(void);
287 
292  void setServoEnabled(void);
293 
298  void setServoDisabled(void);
299 
305  void setServoPosition(uint16_t pos);
306 
307  /*************************/
308 
309 
310  // CONSTANTS
311  const std::string PRE = "[B15F] ";
312  constexpr static uint8_t MSG_OK = 0xFF;
313  constexpr static uint8_t MSG_FAIL = 0xFE;
314  constexpr static uint16_t RECONNECT_TIMEOUT = 64;
315  constexpr static uint16_t WDT_TIMEOUT = 15;
316  constexpr static uint8_t RECONNECT_TRIES = 3;
317  constexpr static uint32_t BAUDRATE = 57600;
318 
319 private:
320 
324  B15F(void);
325 
330  void init(void);
331 
336  template<typename CodeType, typename ExpectationType>
337  void assertCodeFunc(CodeType& code, ExpectationType expectation, const char* func, const char* file, int line) const
338  {
339  if(code != static_cast<CodeType>(expectation))
340  throw DriverException("Ungültige Antwort erhalten: " + std::to_string((int) code) + " (erwartet: " + std::to_string((int) expectation) + ") in " + std::string(func) + ": " + std::string(file) + "#" + std::to_string(line));
341  }
342 
347  template<size_t RequestLength>
348  void assertRequestLengthFunc(uint8_t (&)[RequestLength], uint8_t rq_num, const char* func, const char* file, int line)
349  {
350  if(RequestLength != rq_len[rq_num])
351  throw DriverException("Ungültige Request Länge: " + std::to_string(RequestLength) + " (erwartet: " + std::to_string(rq_len[rq_num]) + ") in " + std::string(func) + ": " + std::string(file) + "#" + std::to_string(line));
352  }
353 
354  USART usart;
355  static B15F* instance;
356  static errorhandler_t errorhandler;
357 };
358 
359 #endif // B15F_H
+
void testIntConv(void)
Definition: b15f.cpp:83
+
void pwmSetValue(uint8_t value)
Definition: b15f.cpp:431
+
static std::string exec(std::string cmd)
Definition: b15f.cpp:153
+
constexpr static uint8_t MSG_FAIL
Value to reject a received command.
Definition: b15f.h:311
+
void analogWrite0(uint16_t port)
Definition: b15f.cpp:296
+
void setServoPosition(uint16_t pos)
Definition: b15f.cpp:589
+
void analogWrite1(uint16_t port)
Definition: b15f.cpp:313
+
uint16_t getMem16(volatile uint16_t *adr)
Definition: b15f.cpp:509
+
void delay_us(uint16_t us)
Definition: b15f.cpp:140
+
uint8_t digitalRead0(void)
Definition: b15f.cpp:245
+
uint8_t pwmSetFrequency(uint32_t freq)
Definition: b15f.cpp:410
+
void digitalWrite0(uint8_t)
Definition: b15f.cpp:213
+
void analogSequence(uint8_t channel_a, uint16_t *buffer_a, uint32_t offset_a, uint8_t channel_b, uint16_t *buffer_b, uint32_t offset_b, uint16_t start, int16_t delta, uint16_t count)
Definition: b15f.cpp:353
+
uint8_t readDipSwitch(void)
Definition: b15f.cpp:277
+
uint8_t getRegister(volatile uint8_t *adr)
Definition: b15f.cpp:533
+
uint8_t getMem8(volatile uint8_t *adr)
Definition: b15f.cpp:469
+
void delay_ms(uint16_t ms)
Definition: b15f.cpp:135
+
void testConnection(void)
Definition: b15f.cpp:63
static B15F & getInstance(void)
Definition: b15f.cpp:10
-
Definition: b15f.h:33
-
static void abort(std::string msg)
Definition: b15f.cpp:161
-
uint16_t * getInterruptCounterOffset(void)
Definition: b15f.cpp:530
+
Definition: b15f.h:37
+
static void abort(std::string msg)
Definition: b15f.cpp:169
+
uint16_t * getInterruptCounterOffset(void)
Definition: b15f.cpp:538
Definition: usart.h:16
-
void setMem16(volatile uint16_t *adr, uint16_t val)
Definition: b15f.cpp:480
-
uint16_t analogRead(uint8_t channel)
Definition: b15f.cpp:322
-
void activateSelfTestMode(void)
Definition: b15f.cpp:190
-
const std::string PRE
B15F stdout prefix.
Definition: b15f.h:305
-
void reverse(uint8_t &b)
Definition: b15f.cpp:137
-
std::vector< std::string > getBoardInfo(void)
Definition: b15f.cpp:95
-
constexpr static uint16_t RECONNECT_TIMEOUT
Time in ms after which a reconnect attempt aborts.
Definition: b15f.h:308
-
void discard(void)
Definition: b15f.cpp:33
-
void setRegister(volatile uint8_t *adr, uint8_t val)
Definition: b15f.cpp:520
-
constexpr static uint8_t MSG_OK
Value to acknowledge a received command.
Definition: b15f.h:306
-
uint8_t digitalRead1(void)
Definition: b15f.cpp:253
-
constexpr static uint16_t WDT_TIMEOUT
Time in ms after which the watch dog timer resets the MCU.
Definition: b15f.h:309
+
void setMem16(volatile uint16_t *adr, uint16_t val)
Definition: b15f.cpp:488
+
uint16_t analogRead(uint8_t channel)
Definition: b15f.cpp:330
+
void activateSelfTestMode(void)
Definition: b15f.cpp:198
+
const std::string PRE
B15F stdout prefix.
Definition: b15f.h:309
+
void reverse(uint8_t &b)
Definition: b15f.cpp:145
+
std::vector< std::string > getBoardInfo(void)
Definition: b15f.cpp:103
+
constexpr static uint16_t RECONNECT_TIMEOUT
Time in ms after which a reconnect attempt aborts.
Definition: b15f.h:312
+
void discard(void)
Definition: b15f.cpp:40
+
void setRegister(volatile uint8_t *adr, uint8_t val)
Definition: b15f.cpp:528
+
constexpr static uint8_t MSG_OK
Value to acknowledge a received command.
Definition: b15f.h:310
+
uint8_t digitalRead1(void)
Definition: b15f.cpp:261
+
constexpr static uint16_t WDT_TIMEOUT
Time in ms after which the watch dog timer resets the MCU.
Definition: b15f.h:313
void reconnect(void)
Definition: b15f.cpp:18
-
constexpr static uint32_t BAUDRATE
USART baudrate for communication with the MCU.
Definition: b15f.h:311
-
static void setAbortHandler(errorhandler_t func)
Definition: b15f.cpp:178
-
void digitalWrite1(uint8_t)
Definition: b15f.cpp:221
-
void setServoEnabled(void)
Definition: b15f.cpp:547
-
constexpr static uint8_t RECONNECT_TRIES
Maximum count of reconnect attempts after which the driver stops.
Definition: b15f.h:310
-
void setMem8(volatile uint8_t *adr, uint8_t val)
Definition: b15f.cpp:441
-
void setServoDisabled(void)
Definition: b15f.cpp:564
-
bool testIntConv(void)
Definition: b15f.cpp:75
+
constexpr static uint32_t BAUDRATE
USART baudrate for communication with the MCU.
Definition: b15f.h:315
+
static void setAbortHandler(errorhandler_t func)
Definition: b15f.cpp:186
+
void digitalWrite1(uint8_t)
Definition: b15f.cpp:229
+
void setServoEnabled(void)
Definition: b15f.cpp:555
+
constexpr static uint8_t RECONNECT_TRIES
Maximum count of reconnect attempts after which the driver stops.
Definition: b15f.h:314
+
void setMem8(volatile uint8_t *adr, uint8_t val)
Definition: b15f.cpp:449
+
void setServoDisabled(void)
Definition: b15f.cpp:572
diff --git a/docs/html/classB15F-members.html b/docs/html/classB15F-members.html index 7ee494e..79a8d50 100644 --- a/docs/html/classB15F-members.html +++ b/docs/html/classB15F-members.html @@ -108,13 +108,13 @@ $(function() { setServoDisabled(void)B15F setServoEnabled(void)B15F setServoPosition(uint16_t pos)B15F - testConnection(void)B15F - testIntConv(void)B15F + testConnection(void)B15F + testIntConv(void)B15F WDT_TIMEOUTB15Fstatic diff --git a/docs/html/classB15F.html b/docs/html/classB15F.html index 71f654b..56a856e 100644 --- a/docs/html/classB15F.html +++ b/docs/html/classB15F.html @@ -81,10 +81,10 @@ Public Member Functions   void discard (void)   -bool testConnection (void) -  -bool testIntConv (void) -  +void testConnection (void) +  +void testIntConv (void) +  std::vector< std::string > getBoardInfo (void)   void delay_ms (uint16_t ms) @@ -188,7 +188,7 @@ constexpr static uint32_t 

Detailed Description

main driver class

-

Definition at line 33 of file b15f.h.

+

Definition at line 37 of file b15f.h.

Member Function Documentation

◆ abort() [1/2]

@@ -220,7 +220,7 @@ constexpr static uint32_t  -

Definition at line 167 of file b15f.cpp.

+

Definition at line 175 of file b15f.cpp.

@@ -254,7 +254,7 @@ constexpr static uint32_t  -

Definition at line 161 of file b15f.cpp.

+

Definition at line 169 of file b15f.cpp.

@@ -280,7 +280,7 @@ constexpr static uint32_t  -

Definition at line 190 of file b15f.cpp.

+

Definition at line 198 of file b15f.cpp.

@@ -312,7 +312,7 @@ constexpr static uint32_t  -

Definition at line 322 of file b15f.cpp.

+

Definition at line 330 of file b15f.cpp.

@@ -404,7 +404,7 @@ constexpr static uint32_t  -

Definition at line 345 of file b15f.cpp.

+

Definition at line 353 of file b15f.cpp.

@@ -436,7 +436,7 @@ constexpr static uint32_t  -

Definition at line 288 of file b15f.cpp.

+

Definition at line 296 of file b15f.cpp.

@@ -468,7 +468,7 @@ constexpr static uint32_t  -

Definition at line 305 of file b15f.cpp.

+

Definition at line 313 of file b15f.cpp.

@@ -494,7 +494,7 @@ constexpr static uint32_t  -

Definition at line 127 of file b15f.cpp.

+

Definition at line 135 of file b15f.cpp.

@@ -520,7 +520,7 @@ constexpr static uint32_t  -

Definition at line 132 of file b15f.cpp.

+

Definition at line 140 of file b15f.cpp.

@@ -547,7 +547,7 @@ constexpr static uint32_t  -

Definition at line 237 of file b15f.cpp.

+

Definition at line 245 of file b15f.cpp.

@@ -574,7 +574,7 @@ constexpr static uint32_t  -

Definition at line 253 of file b15f.cpp.

+

Definition at line 261 of file b15f.cpp.

@@ -606,7 +606,7 @@ constexpr static uint32_t  -

Definition at line 205 of file b15f.cpp.

+

Definition at line 213 of file b15f.cpp.

@@ -638,7 +638,7 @@ constexpr static uint32_t  -

Definition at line 221 of file b15f.cpp.

+

Definition at line 229 of file b15f.cpp.

@@ -664,7 +664,7 @@ constexpr static uint32_t  -

Definition at line 33 of file b15f.cpp.

+

Definition at line 40 of file b15f.cpp.

@@ -698,7 +698,7 @@ constexpr static uint32_t  -

Definition at line 145 of file b15f.cpp.

+

Definition at line 153 of file b15f.cpp.

@@ -724,7 +724,7 @@ constexpr static uint32_t  -

Definition at line 95 of file b15f.cpp.

+

Definition at line 103 of file b15f.cpp.

@@ -779,7 +779,7 @@ constexpr static uint32_t  @@ -806,7 +806,7 @@ constexpr static uint32_t 
Returns
Wert der Speicherzelle
-

Definition at line 501 of file b15f.cpp.

+

Definition at line 509 of file b15f.cpp.

@@ -833,7 +833,7 @@ constexpr static uint32_t 
Returns
Wert der Speicherzelle
-

Definition at line 461 of file b15f.cpp.

+

Definition at line 469 of file b15f.cpp.

@@ -860,7 +860,7 @@ constexpr static uint32_t 
Returns
Wert des Registers
-

Definition at line 525 of file b15f.cpp.

+

Definition at line 533 of file b15f.cpp.

@@ -893,7 +893,7 @@ constexpr static uint32_t  -

Definition at line 402 of file b15f.cpp.

+

Definition at line 410 of file b15f.cpp.

@@ -925,7 +925,7 @@ constexpr static uint32_t  -

Definition at line 423 of file b15f.cpp.

+

Definition at line 431 of file b15f.cpp.

@@ -952,7 +952,7 @@ constexpr static uint32_t  -

Definition at line 269 of file b15f.cpp.

+

Definition at line 277 of file b15f.cpp.

@@ -1004,7 +1004,7 @@ constexpr static uint32_t  -

Definition at line 137 of file b15f.cpp.

+

Definition at line 145 of file b15f.cpp.

@@ -1038,7 +1038,7 @@ constexpr static uint32_t  -

Definition at line 178 of file b15f.cpp.

+

Definition at line 186 of file b15f.cpp.

@@ -1081,7 +1081,7 @@ constexpr static uint32_t  -

Definition at line 480 of file b15f.cpp.

+

Definition at line 488 of file b15f.cpp.

@@ -1119,7 +1119,7 @@ constexpr static uint32_t 
Returns
true, falls Vorgang erfolgreich
-

Definition at line 441 of file b15f.cpp.

+

Definition at line 449 of file b15f.cpp.

@@ -1162,7 +1162,7 @@ constexpr static uint32_t  -

Definition at line 520 of file b15f.cpp.

+

Definition at line 528 of file b15f.cpp.

@@ -1188,7 +1188,7 @@ constexpr static uint32_t  -

Definition at line 564 of file b15f.cpp.

+

Definition at line 572 of file b15f.cpp.

@@ -1214,7 +1214,7 @@ constexpr static uint32_t  -

Definition at line 547 of file b15f.cpp.

+

Definition at line 555 of file b15f.cpp.

@@ -1246,18 +1246,18 @@ constexpr static uint32_t  -

Definition at line 581 of file b15f.cpp.

+

Definition at line 589 of file b15f.cpp.

- -

◆ testConnection()

+ +

◆ testConnection()

- + @@ -1272,18 +1272,18 @@ constexpr static uint32_t  diff --git a/docs/html/classDriverException-members.html b/docs/html/classDriverException-members.html index 791afe8..bba03b8 100644 --- a/docs/html/classDriverException-members.html +++ b/docs/html/classDriverException-members.html @@ -77,7 +77,7 @@ $(function() {
bool B15F::testConnection void B15F::testConnection ( void  ) -

Definition at line 56 of file b15f.cpp.

+

Definition at line 63 of file b15f.cpp.

- -

◆ testIntConv()

+ +

◆ testIntConv()

- + @@ -1298,7 +1298,7 @@ constexpr static uint32_t 
bool B15F::testIntConv void B15F::testIntConv ( void  ) -

Definition at line 75 of file b15f.cpp.

+

Definition at line 83 of file b15f.cpp.

@@ -1309,7 +1309,7 @@ constexpr static uint32_t 
diff --git a/docs/html/classDot-members.html b/docs/html/classDot-members.html index 9c7e094..fca0216 100644 --- a/docs/html/classDot-members.html +++ b/docs/html/classDot-members.html @@ -76,7 +76,7 @@ $(function() {
diff --git a/docs/html/classDot.html b/docs/html/classDot.html index 7d1744d..7be4ec3 100644 --- a/docs/html/classDot.html +++ b/docs/html/classDot.html @@ -196,7 +196,7 @@ Public Member Functions
diff --git a/docs/html/classDriverException.html b/docs/html/classDriverException.html index 4bda33a..6a4fede 100644 --- a/docs/html/classDriverException.html +++ b/docs/html/classDriverException.html @@ -109,7 +109,7 @@ std::string msg_<
diff --git a/docs/html/classPlottyFile-members.html b/docs/html/classPlottyFile-members.html index b797b9b..0e9a3f4 100644 --- a/docs/html/classPlottyFile-members.html +++ b/docs/html/classPlottyFile-members.html @@ -100,7 +100,7 @@ $(function() { diff --git a/docs/html/classPlottyFile.html b/docs/html/classPlottyFile.html index 3723d9d..d0e67ea 100644 --- a/docs/html/classPlottyFile.html +++ b/docs/html/classPlottyFile.html @@ -811,7 +811,7 @@ Public Member Functions diff --git a/docs/html/classTimeoutException-members.html b/docs/html/classTimeoutException-members.html index 622abcb..1843817 100644 --- a/docs/html/classTimeoutException-members.html +++ b/docs/html/classTimeoutException-members.html @@ -77,7 +77,7 @@ $(function() { diff --git a/docs/html/classTimeoutException.html b/docs/html/classTimeoutException.html index 30d3af2..571bb8c 100644 --- a/docs/html/classTimeoutException.html +++ b/docs/html/classTimeoutException.html @@ -239,7 +239,7 @@ std::string  diff --git a/docs/html/classUSART-members.html b/docs/html/classUSART-members.html index 8a02d38..5664e4b 100644 --- a/docs/html/classUSART-members.html +++ b/docs/html/classUSART-members.html @@ -86,7 +86,7 @@ $(function() { diff --git a/docs/html/classUSART.html b/docs/html/classUSART.html index 468f0b7..e2e827e 100644 --- a/docs/html/classUSART.html +++ b/docs/html/classUSART.html @@ -523,7 +523,7 @@ Public Member Functions diff --git a/docs/html/classUSARTException-members.html b/docs/html/classUSARTException-members.html index fe0ce1b..942feb6 100644 --- a/docs/html/classUSARTException-members.html +++ b/docs/html/classUSARTException-members.html @@ -77,7 +77,7 @@ $(function() { diff --git a/docs/html/classUSARTException.html b/docs/html/classUSARTException.html index f863fa3..482b8fc 100644 --- a/docs/html/classUSARTException.html +++ b/docs/html/classUSARTException.html @@ -239,7 +239,7 @@ std::string  diff --git a/docs/html/classView-members.html b/docs/html/classView-members.html index d978970..04d43af 100644 --- a/docs/html/classView-members.html +++ b/docs/html/classView-members.html @@ -89,7 +89,7 @@ $(function() { diff --git a/docs/html/classView.html b/docs/html/classView.html index 840003d..4d2c87f 100644 --- a/docs/html/classView.html +++ b/docs/html/classView.html @@ -157,7 +157,7 @@ constexpr static int KEY_E diff --git a/docs/html/classViewInfo-members.html b/docs/html/classViewInfo-members.html index 904ec53..b7c6952 100644 --- a/docs/html/classViewInfo-members.html +++ b/docs/html/classViewInfo-members.html @@ -99,7 +99,7 @@ $(function() { diff --git a/docs/html/classViewInfo.html b/docs/html/classViewInfo.html index 6f4053a..2459ec8 100644 --- a/docs/html/classViewInfo.html +++ b/docs/html/classViewInfo.html @@ -185,7 +185,7 @@ static std::vector< std::string >  diff --git a/docs/html/classViewMonitor-members.html b/docs/html/classViewMonitor-members.html index e1cafbe..65370ff 100644 --- a/docs/html/classViewMonitor-members.html +++ b/docs/html/classViewMonitor-members.html @@ -103,7 +103,7 @@ $(function() { diff --git a/docs/html/classViewMonitor.html b/docs/html/classViewMonitor.html index 99a2f95..2e53d43 100644 --- a/docs/html/classViewMonitor.html +++ b/docs/html/classViewMonitor.html @@ -197,7 +197,7 @@ constexpr static int KEY_E diff --git a/docs/html/classViewPromt-members.html b/docs/html/classViewPromt-members.html index 010f14d..e01d2aa 100644 --- a/docs/html/classViewPromt-members.html +++ b/docs/html/classViewPromt-members.html @@ -105,7 +105,7 @@ $(function() { diff --git a/docs/html/classViewPromt.html b/docs/html/classViewPromt.html index b5712d9..9fdbd62 100644 --- a/docs/html/classViewPromt.html +++ b/docs/html/classViewPromt.html @@ -205,7 +205,7 @@ static std::vector< std::string >  diff --git a/docs/html/classViewSelection-members.html b/docs/html/classViewSelection-members.html index 373b6f6..9800ab4 100644 --- a/docs/html/classViewSelection-members.html +++ b/docs/html/classViewSelection-members.html @@ -94,7 +94,7 @@ $(function() { diff --git a/docs/html/classViewSelection.html b/docs/html/classViewSelection.html index b716df5..e415859 100644 --- a/docs/html/classViewSelection.html +++ b/docs/html/classViewSelection.html @@ -172,7 +172,7 @@ static std::vector< std::string >  diff --git a/docs/html/classes.html b/docs/html/classes.html index 8c46379..d92d5c8 100644 --- a/docs/html/classes.html +++ b/docs/html/classes.html @@ -105,7 +105,7 @@ $(function() { diff --git a/docs/html/cli_8cpp_source.html b/docs/html/cli_8cpp_source.html index eb94b8a..39bb28e 100644 --- a/docs/html/cli_8cpp_source.html +++ b/docs/html/cli_8cpp_source.html @@ -69,10 +69,10 @@ $(function() {
1 //#define B15F_CLI_DEBUG
2 
3 #include <stdio.h>
4 #include <ncurses.h> // sudo apt-get install libncurses5-dev
5 #include <vector>
6 #include <string>
7 #include <iostream>
8 #include <signal.h>
9 #include <sys/ioctl.h>
10 #include <unistd.h>
11 #include <signal.h>
12 #include <future>
13 #include <thread>
14 #include <chrono>
15 #include "drv/b15f.h"
16 #include "ui/ui.h"
17 #include "ui/view_selection.h"
18 #include "ui/view_info.h"
19 #include "ui/view_monitor.h"
20 #include "ui/view_promt.h"
21 
22 constexpr uint8_t WIN_WIDTH = 80;
23 constexpr uint8_t WIN_HEIGHT = 24;
24 
25 volatile int win_changed_cooldown = 0;
26 volatile bool t_refresh_active = false;
27 
28 void signal_handler(int signal)
29 {
30  if(signal == SIGWINCH)
31  {
32  win_changed_cooldown = 10; // 100ms
33 
34  if (!t_refresh_active)
35  {
36  if(t_refresh.joinable())
37  t_refresh.join();
38  t_refresh_active = true;
39  t_refresh = std::thread([]()
40  {
41 
42  while(win_changed_cooldown--)
43  std::this_thread::sleep_for(std::chrono::milliseconds(10));
44 
45  t_refresh_active = false;
46 
47  if(win_stack.size())
48  win_stack.back()->repaint();
49 
50  });
51  }
52 
53  }
54  else if(signal == SIGINT)
55  {
56  cleanup();
57  std::cout << "SIGINT - Abbruch." << std::endl;
58  exit(EXIT_FAILURE);
59  }
60 }
61 
62 void abort_handler(std::exception& ex)
63 {
64  ViewInfo* view = new ViewInfo();
65  view->setTitle("Fehler");
66  std::string msg(ex.what());
67  msg += "\n\nBeende in 5 Sekunden.";
68  view->setText(msg.c_str());
69  view->setLabelClose("");
70  view->repaint();
71 
72  std::this_thread::sleep_for(std::chrono::milliseconds(5000));
73 
74  cleanup();
75  std::cerr << std::endl << "*** EXCEPTION ***" << std::endl << ex.what() << std::endl;
76  exit(EXIT_FAILURE);
77 }
78 
79 void init()
80 {
81  // init b15 driver
83 #ifndef B15F_CLI_DEBUG
84  std::cout << std::endl << "Starte in 3s ..." << std::endl;
85  sleep(3);
86 #endif
87 
88  // init all ncurses stuff
89  initscr();
90  start_color();
91  curs_set(0); // 0: invisible, 1: normal, 2: very visible
92  clear();
93  noecho();
94  cbreak(); // Line buffering disabled. pass on everything
95  mousemask(ALL_MOUSE_EVENTS, NULL);
96 
97  // connect signals to handler
98  signal(SIGWINCH, signal_handler);
99  signal(SIGINT, signal_handler);
100 
101  // set view context
102  View::setWinContext(newwin(WIN_HEIGHT, WIN_WIDTH, 0, 0));
103 
104  // set graphical error handler
105  B15F::setAbortHandler(&abort_handler);
106 }
107 
108 
109 int main()
110 {
111  init();
112 
113  int exit_code = EXIT_SUCCESS;
114 
115  show_main(0);
116 
117  cleanup();
118 
119  return exit_code;
120 }
static B15F & getInstance(void)
Definition: b15f.cpp:10
-
static void setAbortHandler(errorhandler_t func)
Definition: b15f.cpp:178
+
static void setAbortHandler(errorhandler_t func)
Definition: b15f.cpp:186
diff --git a/docs/html/dir_1788f8309b1a812dcb800a185471cf6c.html b/docs/html/dir_1788f8309b1a812dcb800a185471cf6c.html index add7c75..e5adedc 100644 --- a/docs/html/dir_1788f8309b1a812dcb800a185471cf6c.html +++ b/docs/html/dir_1788f8309b1a812dcb800a185471cf6c.html @@ -73,7 +73,7 @@ $(function() { diff --git a/docs/html/dir_587c94d866dbb2f408f78cf41f9b2f8d.html b/docs/html/dir_587c94d866dbb2f408f78cf41f9b2f8d.html index babfe9e..97b1c33 100644 --- a/docs/html/dir_587c94d866dbb2f408f78cf41f9b2f8d.html +++ b/docs/html/dir_587c94d866dbb2f408f78cf41f9b2f8d.html @@ -73,7 +73,7 @@ $(function() { diff --git a/docs/html/dot_8cpp_source.html b/docs/html/dot_8cpp_source.html index cbf6c54..2edbd0d 100644 --- a/docs/html/dot_8cpp_source.html +++ b/docs/html/dot_8cpp_source.html @@ -77,7 +77,7 @@ $(function() {
Dot(uint16_t x, uint16_t y, uint8_t curve)
Definition: dot.cpp:3
diff --git a/docs/html/dot_8h_source.html b/docs/html/dot_8h_source.html index 94edb8f..8e0ddf8 100644 --- a/docs/html/dot_8h_source.html +++ b/docs/html/dot_8h_source.html @@ -78,7 +78,7 @@ $(function() {
Dot(uint16_t x, uint16_t y, uint8_t curve)
Definition: dot.cpp:3
diff --git a/docs/html/driverexception_8h_source.html b/docs/html/driverexception_8h_source.html index 836a526..d409a92 100644 --- a/docs/html/driverexception_8h_source.html +++ b/docs/html/driverexception_8h_source.html @@ -74,7 +74,7 @@ $(function() { diff --git a/docs/html/files.html b/docs/html/files.html index 230abed..d71382d 100644 --- a/docs/html/files.html +++ b/docs/html/files.html @@ -100,7 +100,7 @@ $(function() { diff --git a/docs/html/functions.html b/docs/html/functions.html index c16a9de..4f26cec 100644 --- a/docs/html/functions.html +++ b/docs/html/functions.html @@ -355,10 +355,10 @@ $(function() {

- t -

  • testConnection() -: B15F +: B15F
  • testIntConv() -: B15F +: B15F
  • TimeoutException() : TimeoutException @@ -407,7 +407,7 @@ $(function() { diff --git a/docs/html/functions_func.html b/docs/html/functions_func.html index ad264b8..28f4c88 100644 --- a/docs/html/functions_func.html +++ b/docs/html/functions_func.html @@ -325,10 +325,10 @@ $(function() {

    - t -

    • testConnection() -: B15F +: B15F
    • testIntConv() -: B15F +: B15F
    • TimeoutException() : TimeoutException @@ -374,7 +374,7 @@ $(function() { diff --git a/docs/html/functions_vars.html b/docs/html/functions_vars.html index 93c6c7e..e849599 100644 --- a/docs/html/functions_vars.html +++ b/docs/html/functions_vars.html @@ -92,7 +92,7 @@ $(function() { diff --git a/docs/html/hierarchy.html b/docs/html/hierarchy.html index 94b0aa1..9faa656 100644 --- a/docs/html/hierarchy.html +++ b/docs/html/hierarchy.html @@ -86,7 +86,7 @@ $(function() { diff --git a/docs/html/index.html b/docs/html/index.html index db64c40..ae3b8d9 100644 --- a/docs/html/index.html +++ b/docs/html/index.html @@ -170,7 +170,7 @@ Dabei gehören Punkte mit dem gleichen Index für curve (uint8_ diff --git a/docs/html/plottyfile_8cpp_source.html b/docs/html/plottyfile_8cpp_source.html index 4c1c5af..a5959d1 100644 --- a/docs/html/plottyfile_8cpp_source.html +++ b/docs/html/plottyfile_8cpp_source.html @@ -101,7 +101,7 @@ $(function() {
      std::string getUnitX(void) const
      Definition: plottyfile.cpp:105
      diff --git a/docs/html/plottyfile_8h_source.html b/docs/html/plottyfile_8h_source.html index ca366eb..5e4addf 100644 --- a/docs/html/plottyfile_8h_source.html +++ b/docs/html/plottyfile_8h_source.html @@ -102,7 +102,7 @@ $(function() {
      std::string getUnitX(void) const
      Definition: plottyfile.cpp:105
      diff --git a/docs/html/requests_8h_source.html b/docs/html/requests_8h_source.html index 5af1eb3..4cf0758 100644 --- a/docs/html/requests_8h_source.html +++ b/docs/html/requests_8h_source.html @@ -73,7 +73,7 @@ $(function() {
      1 #ifndef REQUESTS_H
      2 #define REQUESTS_H
      3 
      4 constexpr static uint8_t RQ_DISCARD = 0;
      5 constexpr static uint8_t RQ_TEST = 1;
      6 constexpr static uint8_t RQ_INFO = 2;
      7 constexpr static uint8_t RQ_INT_TEST = 3;
      8 constexpr static uint8_t RQ_SELF_TEST = 4;
      9 constexpr static uint8_t RQ_DIGITAL_WRITE_0 = 5;
      10 constexpr static uint8_t RQ_DIGITAL_WRITE_1 = 6;
      11 constexpr static uint8_t RQ_DIGITAL_READ_0 = 7;
      12 constexpr static uint8_t RQ_DIGITAL_READ_1 = 8;
      13 constexpr static uint8_t RQ_READ_DIP_SWITCH = 9;
      14 constexpr static uint8_t RQ_ANALOG_WRITE_0 = 10;
      15 constexpr static uint8_t RQ_ANALOG_WRITE_1 = 11;
      16 constexpr static uint8_t RQ_ANALOG_READ = 12;
      17 constexpr static uint8_t RQ_ADC_DAC_STROKE = 13;
      18 constexpr static uint8_t RQ_PWM_SET_FREQ = 14;
      19 constexpr static uint8_t RQ_PWM_SET_VALUE = 15;
      20 constexpr static uint8_t RQ_SET_MEM_8 = 16;
      21 constexpr static uint8_t RQ_GET_MEM_8 = 17;
      22 constexpr static uint8_t RQ_SET_MEM_16 = 18;
      23 constexpr static uint8_t RQ_GET_MEM_16 = 19;
      24 constexpr static uint8_t RQ_COUNTER_OFFSET = 20;
      25 constexpr static uint8_t RQ_SERVO_ENABLE = 21;
      26 constexpr static uint8_t RQ_SERVO_DISABLE = 22;
      27 constexpr static uint8_t RQ_SERVO_SET_POS = 23;
      28 
      29 uint8_t const rq_len[] =
      30 {
      31  1 /* RQ_DISCARD */,
      32  1 /* RQ_TEST */ + 1 /* test byte */,
      33  1 /* RQ_INFO */,
      34  1 /* RQ_INT_TEST */ + 1 /* test int high low */ + 1 /* test int high high */,
      35  1 /* RQ_SELF_TEST */,
      36  1 /* RQ_DIGITAL_WRITE_0 */ + 1 /* port value */,
      37  1 /* RQ_DIGITAL_WRITE_1 */ + 1 /* port value */,
      38  1 /* RQ_DIGITAL_READ_0 */,
      39  1 /* RQ_DIGITAL_READ_1 */,
      40  1 /* RQ_READ_DIP_SWITCH */,
      41  1 /* RQ_ANALOG_WRITE_0 */ + 1 /* test int high low */ + 1 /* test int high high */,
      42  1 /* RQ_ANALOG_WRITE_1 */ + 1 /* test int high low */ + 1 /* test int high high */,
      43  1 /* RQ_ANALOG_READ */ + 1 /* adc channel */,
      44  1 /* RQ_ADC_DAC_STROKE */ + 1 /* channel a */ + 1 /* channel b */ + 1 /* start low */ + 1 /* start high */ + 1 /* delta low */ + 1 /* delta high */ + 1 /* count low */ + 1 /* count high */,
      45  1 /* RQ_PWM_SET_FREQ */ + 1 /* freq low low */ + 1 /* freq low high */ + 1 /* freq high low */ + 1 /* freq high high */,
      46  1 /* RQ_PWM_SET_VALUE */ + 1 /* pwm value */,
      47  1 /* RQ_SET_MEM_8 */ + 1 /* memory address low */ + 1 /* memory address high */ + 1 /* memory value (8-bit) */,
      48  1 /* RQ_GET_MEM_8 */ + 1 /* memory address low */ + 1 /* memory address high */,
      49  1 /* RQ_SET_MEM_16 */ + 1 /* memory address low */ + 1 /* memory address high */ + 1 /* memory value low */ + 1 /* memory value high */,
      50  1 /* RQ_GET_MEM_16 */ + 1 /* memory address low */ + 1 /* memory address high */,
      51  1 /* RQ_COUNTER_OFFSET */,
      52  1 /* RQ_SERVO_ENABLE */,
      53  1 /* RQ_SERVO_DISABLE */,
      54  1 /* RQ_SERVO_SET_POS */ + 1 /* pulse length low */ + 1 /* pulse length high */,
      55 };
      56 
      57 #endif // REQUESTS_H
      diff --git a/docs/html/search/all_c.js b/docs/html/search/all_c.js index 37e3d29..ad39cf2 100644 --- a/docs/html/search/all_c.js +++ b/docs/html/search/all_c.js @@ -1,7 +1,7 @@ var searchData= [ - ['testconnection',['testConnection',['../classB15F.html#af01983594f2af98ab2b1e514aa036a5d',1,'B15F']]], - ['testintconv',['testIntConv',['../classB15F.html#a7b8a0e2a9156f7dcb05d097f23666a78',1,'B15F']]], + ['testconnection',['testConnection',['../classB15F.html#a6b8c7da1fb9b619543844e0ce7597d83',1,'B15F']]], + ['testintconv',['testIntConv',['../classB15F.html#ac2c7b6d84da5239ee7cc3d44e689d9db',1,'B15F']]], ['timeoutexception',['TimeoutException',['../classTimeoutException.html',1,'TimeoutException'],['../classTimeoutException.html#aa45912234da11ffc9dd3594a1bbc0218',1,'TimeoutException::TimeoutException(const char *message)'],['../classTimeoutException.html#ad6e5c200fbfd276f48a6c1163e2d2988',1,'TimeoutException::TimeoutException(const std::string &message)']]], ['transmit',['transmit',['../classUSART.html#a41b19dd58f307015b73e154048cd74ca',1,'USART']]] ]; diff --git a/docs/html/search/functions_a.js b/docs/html/search/functions_a.js index c417073..190df1c 100644 --- a/docs/html/search/functions_a.js +++ b/docs/html/search/functions_a.js @@ -1,7 +1,7 @@ var searchData= [ - ['testconnection',['testConnection',['../classB15F.html#af01983594f2af98ab2b1e514aa036a5d',1,'B15F']]], - ['testintconv',['testIntConv',['../classB15F.html#a7b8a0e2a9156f7dcb05d097f23666a78',1,'B15F']]], + ['testconnection',['testConnection',['../classB15F.html#a6b8c7da1fb9b619543844e0ce7597d83',1,'B15F']]], + ['testintconv',['testIntConv',['../classB15F.html#ac2c7b6d84da5239ee7cc3d44e689d9db',1,'B15F']]], ['timeoutexception',['TimeoutException',['../classTimeoutException.html#aa45912234da11ffc9dd3594a1bbc0218',1,'TimeoutException::TimeoutException(const char *message)'],['../classTimeoutException.html#ad6e5c200fbfd276f48a6c1163e2d2988',1,'TimeoutException::TimeoutException(const std::string &message)']]], ['transmit',['transmit',['../classUSART.html#a41b19dd58f307015b73e154048cd74ca',1,'USART']]] ]; diff --git a/docs/html/timeoutexception_8h_source.html b/docs/html/timeoutexception_8h_source.html index b7363c1..8b358d5 100644 --- a/docs/html/timeoutexception_8h_source.html +++ b/docs/html/timeoutexception_8h_source.html @@ -79,7 +79,7 @@ $(function() {
      TimeoutException(const std::string &message)
      diff --git a/docs/html/ui_8cpp_source.html b/docs/html/ui_8cpp_source.html index fe95567..0109508 100644 --- a/docs/html/ui_8cpp_source.html +++ b/docs/html/ui_8cpp_source.html @@ -72,23 +72,23 @@ $(function() {
      1 #include "ui.h"
      2 #include "../drv/b15f.h"
      3 
      4 std::vector<View*> win_stack;
      5 std::thread t_refresh;
      6 
      7 void show_main(int)
      8 {
      9  ViewSelection* view = new ViewSelection();
      10  view->setTitle("B15F - Command Line Interface");
      11  view->addChoice("[ Monitor - Eingaben beobachten ]", &show_monitor);
      12  view->addChoice("[ Digitale Ausgabe BA0 ]", &show_digital_output0);
      13  view->addChoice("[ Digitale Ausgabe BA1 ]", &show_digital_output1);
      14  view->addChoice("[ Analoge Ausgabe AA0 ]", &show_analog_output0);
      15  view->addChoice("[ Analoge Ausgabe AA1 ]", &show_analog_output1);
      16  view->addChoice("[ Selbsttest des B15 ]", &show_selftest_info);
      17  view->addChoice("[ Informationen ]", &show_info);
      18  view->addChoice("", nullptr);
      19  view->addChoice("[ Beenden ]", &finish);
      20  view->repaint();
      21 
      22  win_stack.push_back(view);
      23  input(0);
      24 }
      25 
      26 void input(int)
      27 {
      28  call_t nextCall;
      29  int key;
      30  do
      31  {
      32  key = wgetch(View::getWinContext());
      33  win_stack.back()->repaint();
      34  nextCall = win_stack.back()->keypress(key);
      35 
      36  if(key == -1)
      37  view_back(key);
      38 
      39  if(nextCall)
      40  nextCall(key);
      41  }
      42  while(win_stack.size());
      43 }
      44 
      45 void view_back(int)
      46 {
      47  if(win_stack.size())
      48  {
      49  delete win_stack.back();
      50  win_stack.pop_back();
      51  }
      52  if(win_stack.size())
      53  win_stack.back()->repaint();
      54 }
      55 
      56 void finish(int)
      57 {
      58  cleanup();
      59  exit(EXIT_SUCCESS);
      60 }
      61 
      62 void cleanup()
      63 {
      64  if(t_refresh.joinable())
      65  t_refresh.join();
      66  clrtoeol();
      67  refresh();
      68  endwin();
      69 }
      70 
      71 void show_info(int)
      72 {
      73  ViewInfo* view = new ViewInfo();
      74  view->setTitle("Info");
      75  view->setText("Informationen zu Board 15 Famulus Edition\n \nProjektseite: https://github.com/devfix/b15f/\nDokumentation: https://devfix.github.io/b15f/\n \nB15F Software entwickelt von Tristan Krause für das Hardware-Labor.\nKontakt: tristan.krause@stud.htwk-leipzig.de");
      76  view->setLabelClose("[ Zurueck ]");
      77  view->repaint();
      78 
      79  win_stack.push_back(view);
      80  input(0);
      81 }
      82 
      83 void show_monitor(int)
      84 {
      85  ViewMonitor* view = new ViewMonitor();
      86  view->setTitle("Monitor");
      87  view->setText("\nErfasse Messwerte...");
      88  view->setLabelClose("[ Zurueck ]");
      89  view->repaint();
      90 
      91  win_stack.push_back(view);
      92  input(0);
      93 }
      94 
      95 void show_invalid_port_input(int)
      96 {
      97  ViewInfo* view = new ViewInfo();
      98  view->setTitle("Falsche Eingabe");
      99  view->setText("Bitte geben Sie einen Wert aus dem Intervall [0, FF] an.");
      100  view->setLabelClose("[ Schliessen ]");
      101  view->repaint();
      102 
      103  win_stack.push_back(view);
      104  input(0);
      105 }
      106 
      107 void show_invalid_dac_input(int)
      108 {
      109  ViewInfo* view = new ViewInfo();
      110  view->setTitle("Falsche Eingabe");
      111  view->setText("Bitte geben Sie einen Wert aus dem Intervall [0, 1023] an.");
      112  view->setLabelClose("[ Schliessen ]");
      113  view->repaint();
      114 
      115  win_stack.push_back(view);
      116  input(0);
      117 }
      118 
      119 void write_digital_output0(int)
      120 {
      121  try
      122  {
      123  int d = std::stoi(static_cast<ViewPromt*>(win_stack.back())->getInput(), 0, 16);
      124  if(d > 255 || 0 > d)
      125  throw std::invalid_argument("bad value");
      126  uint8_t port = static_cast<uint8_t>(d);
      127 
      128  B15F& drv = B15F::getInstance();
      129  drv.digitalWrite0(port);
      130  view_back(0);
      131  }
      132  catch(std::invalid_argument& ex)
      133  {
      134  show_invalid_port_input(0);
      135  }
      136 }
      137 
      138 void write_digital_output1(int)
      139 {
      140  try
      141  {
      142  int d = std::stoi(static_cast<ViewPromt*>(win_stack.back())->getInput(), 0, 16);
      143  if(d > 255 || 0 > d)
      144  throw std::invalid_argument("bad value");
      145  uint8_t port = static_cast<uint8_t>(d);
      146 
      147  B15F& drv = B15F::getInstance();
      148  drv.digitalWrite1(port);
      149  view_back(0);
      150  }
      151  catch(std::invalid_argument& ex)
      152  {
      153  show_invalid_port_input(0);
      154  }
      155 }
      156 
      157 void write_analog_output0(int)
      158 {
      159  try
      160  {
      161  uint16_t port = std::stoi(static_cast<ViewPromt*>(win_stack.back())->getInput());
      162  if(port > 1023)
      163  throw std::invalid_argument("bad value");
      164 
      165  B15F& drv = B15F::getInstance();
      166  drv.analogWrite0(port);
      167  view_back(0);
      168  }
      169  catch(std::invalid_argument& ex)
      170  {
      171  show_invalid_dac_input(0);
      172  }
      173 }
      174 
      175 void write_analog_output1(int)
      176 {
      177  try
      178  {
      179  uint16_t port = std::stoi(static_cast<ViewPromt*>(win_stack.back())->getInput());
      180  if(port > 1023)
      181  throw std::invalid_argument("bad value");
      182 
      183  B15F& drv = B15F::getInstance();
      184  drv.analogWrite1(port);
      185  view_back(0);
      186  }
      187  catch(std::invalid_argument& ex)
      188  {
      189  show_invalid_dac_input(0);
      190  }
      191 }
      192 
      193 void show_digital_output0(int)
      194 {
      195  ViewPromt* view = new ViewPromt();
      196  view->setTitle("Digitale Ausgabe BE0");
      197  view->setMessage("\nAusgabe Port-Wert (hex): 0x");
      198  view->setCancel("[ Zurueck ]", true);
      199  view->setConfirm("[ OK ]", &write_digital_output0);
      200  view->repaint();
      201 
      202  win_stack.push_back(view);
      203  input(0);
      204 }
      205 
      206 void show_digital_output1(int)
      207 {
      208  ViewPromt* view = new ViewPromt();
      209  view->setTitle("Digitale Ausgabe BE1");
      210  view->setMessage("\nAusgabe Port-Wert (hex): 0x");
      211  view->setCancel("[ Zurueck ]", true);
      212  view->setConfirm("[ OK ]", &write_digital_output1);
      213  view->repaint();
      214 
      215  win_stack.push_back(view);
      216  input(0);
      217 }
      218 
      219 void show_analog_output0(int)
      220 {
      221  ViewPromt* view = new ViewPromt();
      222  view->setTitle("Analoge Ausgabe AA0");
      223  view->setMessage("\nAusgabe 10-Bit-Wert (0...1023): ");
      224  view->setCancel("[ Zurueck ]", true);
      225  view->setConfirm("[ OK ]", &write_analog_output0);
      226  view->repaint();
      227 
      228  win_stack.push_back(view);
      229  input(0);
      230 }
      231 
      232 void show_analog_output1(int)
      233 {
      234  ViewPromt* view = new ViewPromt();
      235  view->setTitle("Analoge Ausgabe AA1");
      236  view->setMessage("\nAusgabe 10-Bit-Wert (0...1023): ");
      237  view->setCancel("[ Zurueck ]", true);
      238  view->setConfirm("[ OK ]", &write_analog_output1);
      239  view->repaint();
      240 
      241  win_stack.push_back(view);
      242  input(0);
      243 }
      244 
      245 void start_selftest(int)
      246 {
      247  B15F& drv = B15F::getInstance();
      248  drv.activateSelfTestMode();
      249 
      250  ViewInfo* view = new ViewInfo();
      251  view->setTitle("Selbsttest aktiv");
      252  view->setText("Das B15 befindet sich jetzt im Selbsttestmodus.\n \nSelbsttest:\nZu Beginn geht der Reihe nach jede LED von BA0 bis BA1 an.\nDanach leuchten die LEDs an AA0 und AA1 kurz auf.\nZum Schluss spiegelt in einer Endlosschleife:\n* BA0 Port BE0\n* BA1 die DIP-Schalter S7\n* AA0 ADC0\n* AA1 ADC1");
      253  view->setLabelClose("[ Selbsttest Beenden ]");
      254  view->setCall(&stop_selftest);
      255  view->repaint();
      256 
      257  win_stack.push_back(view);
      258  input(0);
      259 }
      260 
      261 void stop_selftest(int)
      262 {
      263  B15F& drv = B15F::getInstance();
      264  drv.discard();
      266  drv.reconnect();
      267  drv.digitalWrite0(0);
      268  drv.digitalWrite1(0);
      269 }
      270 
      271 void show_selftest_info(int)
      272 {
      273  ViewInfo* view = new ViewInfo();
      274  view->setTitle("Selbsttest");
      275  view->setText("Bitte entfernen Sie jetzt alle Draehte von den Anschlussklemmen und\nbestätigen mit Enter.");
      276  view->setLabelClose("[ Weiter ]");
      277  view->setCall(&start_selftest);
      278  view->repaint();
      279 
      280  win_stack.push_back(view);
      281  input(0);
      282 }
      -
      void analogWrite0(uint16_t port)
      Definition: b15f.cpp:288
      -
      void analogWrite1(uint16_t port)
      Definition: b15f.cpp:305
      -
      void digitalWrite0(uint8_t)
      Definition: b15f.cpp:205
      +
      void analogWrite0(uint16_t port)
      Definition: b15f.cpp:296
      +
      void analogWrite1(uint16_t port)
      Definition: b15f.cpp:313
      +
      void digitalWrite0(uint8_t)
      Definition: b15f.cpp:213
      -
      void delay_ms(uint16_t ms)
      Definition: b15f.cpp:127
      +
      void delay_ms(uint16_t ms)
      Definition: b15f.cpp:135
      static B15F & getInstance(void)
      Definition: b15f.cpp:10
      -
      Definition: b15f.h:33
      -
      void activateSelfTestMode(void)
      Definition: b15f.cpp:190
      +
      Definition: b15f.h:37
      +
      void activateSelfTestMode(void)
      Definition: b15f.cpp:198
      -
      void discard(void)
      Definition: b15f.cpp:33
      -
      constexpr static uint16_t WDT_TIMEOUT
      Time in ms after which the watch dog timer resets the MCU.
      Definition: b15f.h:309
      +
      void discard(void)
      Definition: b15f.cpp:40
      +
      constexpr static uint16_t WDT_TIMEOUT
      Time in ms after which the watch dog timer resets the MCU.
      Definition: b15f.h:313
      void reconnect(void)
      Definition: b15f.cpp:18
      -
      void digitalWrite1(uint8_t)
      Definition: b15f.cpp:221
      +
      void digitalWrite1(uint8_t)
      Definition: b15f.cpp:229
      diff --git a/docs/html/ui_8h_source.html b/docs/html/ui_8h_source.html index d9c78bf..890bb4d 100644 --- a/docs/html/ui_8h_source.html +++ b/docs/html/ui_8h_source.html @@ -73,7 +73,7 @@ $(function() {
      1 #ifndef UI_H
      2 #define UI_H
      3 
      4 #include <vector>
      5 #include "view_selection.h"
      6 #include "view_info.h"
      7 #include "view_monitor.h"
      8 #include "view_promt.h"
      9 
      10 void show_main(int);
      11 void input(int);
      12 void view_back(int);
      13 void finish(int);
      14 void cleanup();
      15 
      16 void show_info(int);
      17 void show_monitor(int);
      18 void show_invalid_port_input(int);
      19 void show_invalid_dac_input(int);
      20 void write_digital_output0(int);
      21 void write_digital_output1(int);
      22 void write_analog_output0(int);
      23 void write_analog_output1(int);
      24 void show_digital_output0(int);
      25 void show_digital_output1(int);
      26 void show_analog_output0(int);
      27 void show_analog_output1(int);
      28 
      29 // selftest group
      30 void show_selftest_info(int);
      31 void start_selftest(int);
      32 void stop_selftest(int);
      33 
      34 
      35 extern std::vector<View*> win_stack;
      36 extern std::thread t_refresh;
      37 
      38 #endif // UI_H
      diff --git a/docs/html/usart_8cpp_source.html b/docs/html/usart_8cpp_source.html index c616b0a..1cc26b2 100644 --- a/docs/html/usart_8cpp_source.html +++ b/docs/html/usart_8cpp_source.html @@ -88,7 +88,7 @@ $(function() { diff --git a/docs/html/usart_8h_source.html b/docs/html/usart_8h_source.html index 3b8bcc9..b847786 100644 --- a/docs/html/usart_8h_source.html +++ b/docs/html/usart_8h_source.html @@ -88,7 +88,7 @@ $(function() {
      void flushOutputBuffer(void)
      Definition: usart.cpp:68
      diff --git a/docs/html/usartexception_8h_source.html b/docs/html/usartexception_8h_source.html index 7d55a87..bf102da 100644 --- a/docs/html/usartexception_8h_source.html +++ b/docs/html/usartexception_8h_source.html @@ -79,7 +79,7 @@ $(function() {
      virtual ~USARTException()=default
      diff --git a/docs/html/view_8cpp_source.html b/docs/html/view_8cpp_source.html index 25938c6..14d6b2b 100644 --- a/docs/html/view_8cpp_source.html +++ b/docs/html/view_8cpp_source.html @@ -71,10 +71,10 @@ $(function() {
      1 #include "view.h"
      2 
      3 WINDOW* View::win = nullptr;
      4 
      5 View::View()
      6 {
      7  if(!win)
      8  {
      9  B15F::abort("View::win not initialized, missing context");
      10  }
      11  getmaxyx(win, height, width); // init width and height
      12  keypad(win, TRUE);
      13 }
      14 
      15 View::~View()
      16 {
      17 }
      18 
      19 void View::setWinContext(WINDOW* win)
      20 {
      21  View::win = win;
      22 }
      23 
      24 WINDOW* View::getWinContext()
      25 {
      26  return win;
      27 }
      28 
      29 // from: https://stackoverflow.com/a/37454181
      30 std::vector<std::string> View::str_split(const std::string& str, const std::string delim)
      31 {
      32  std::vector<std::string> tokens;
      33  size_t prev = 0, pos = 0;
      34  do
      35  {
      36  pos = str.find(delim, prev);
      37  if (pos == std::string::npos) pos = str.length();
      38  std::string token = str.substr(prev, pos-prev);
      39  if (!token.empty()) tokens.push_back(token);
      40  prev = pos + delim.length();
      41  }
      42  while (pos < str.length() && prev < str.length());
      43  return tokens;
      44 }
      45 
      46 
      47 void View::setTitle(std::string title)
      48 {
      49  this->title = title;
      50 }
      51 
      52 void View::repaint()
      53 {
      54  // get screen size
      55  struct winsize size;
      56  if (ioctl(0, TIOCGWINSZ, (char *) &size) < 0)
      57  throw std::runtime_error("TIOCGWINSZ error");
      58 
      59 
      60  start_x = floor((size.ws_col - width) / 2.);
      61  start_y = floor((size.ws_row - height) / 2.);
      62 
      63  curs_set(0); // hide cursor
      64  mvwin(win, start_y, start_x);
      65  clear();
      66  wclear(win);
      67 
      68  // generic draw
      69  box(win, 0, 0);
      70  int offset_x = (width - title.length()) / 2;
      71  mvwprintw(win, 1, offset_x, "%s", title.c_str());
      72 
      73  // specific draw
      74  draw();
      75 
      76  refresh();
      77  wrefresh(win);
      78 }
      -
      static void abort(std::string msg)
      Definition: b15f.cpp:161
      +
      static void abort(std::string msg)
      Definition: b15f.cpp:169
      diff --git a/docs/html/view_8h_source.html b/docs/html/view_8h_source.html index baeef4a..1e5c0bb 100644 --- a/docs/html/view_8h_source.html +++ b/docs/html/view_8h_source.html @@ -74,7 +74,7 @@ $(function() {
      Definition: view.h:19
      diff --git a/docs/html/view__info_8cpp_source.html b/docs/html/view__info_8cpp_source.html index 8f431f0..2d56171 100644 --- a/docs/html/view__info_8cpp_source.html +++ b/docs/html/view__info_8cpp_source.html @@ -73,7 +73,7 @@ $(function() {
      1 #include "view_info.h"
      2 
      3 ViewInfo::ViewInfo()
      4 {
      5  calls.push_back(nullptr);
      6 }
      7 
      8 void ViewInfo::setText(std::string text)
      9 {
      10  this->text = text;
      11 }
      12 
      13 void ViewInfo::setLabelClose(std::string label)
      14 {
      15  this->label_close = label;
      16 }
      17 
      18 void ViewInfo::setCall(call_t call)
      19 {
      20  calls[0] = call;
      21 }
      22 
      23 void ViewInfo::draw()
      24 {
      25  int li = 0;
      26  for(std::string line : str_split(text, "\n"))
      27  mvwprintw(win, text_offset_y + li++, text_offset_x, "%s", line.c_str());
      28 
      29  close_offset_x = (width - label_close.length()) / 2;
      30  close_offset_y = height - 2;
      31 
      32  wattron(win, A_REVERSE);
      33  mvwprintw(win, close_offset_y, close_offset_x, "%s", label_close.c_str());
      34  wattroff(win, A_REVERSE);
      35 }
      36 
      37 call_t ViewInfo::keypress(int& key)
      38 {
      39  switch(key)
      40  {
      41 
      42  case KEY_MOUSE:
      43  {
      44  // http://pronix.linuxdelta.de/C/Linuxprogrammierung/Linuxsystemprogrammieren_C_Kurs_Kapitel10b.shtml
      45  MEVENT event;
      46  if(getmouse(&event) == OK && event.bstate & (BUTTON1_CLICKED | BUTTON1_DOUBLE_CLICKED))
      47  {
      48  size_t column = start_x + close_offset_x;
      49  size_t row = start_y + close_offset_y;
      50  size_t mouse_x = event.x, mouse_y = event.y;
      51  if(mouse_y == row && mouse_x >= column && mouse_x < column + label_close.length())
      52  key = -1; // do return from view
      53  }
      54  break;
      55  }
      56  case KEY_ENT:
      57  key = -1; // do return from view
      58  break;
      59  default:
      60  break;
      61  }
      62  return calls[0];
      63 }
      diff --git a/docs/html/view__info_8h_source.html b/docs/html/view__info_8h_source.html index 8dbd93a..1403ab3 100644 --- a/docs/html/view__info_8h_source.html +++ b/docs/html/view__info_8h_source.html @@ -75,7 +75,7 @@ $(function() {
      Definition: view.h:19
      diff --git a/docs/html/view__monitor_8cpp_source.html b/docs/html/view__monitor_8cpp_source.html index c17409a..17571f0 100644 --- a/docs/html/view__monitor_8cpp_source.html +++ b/docs/html/view__monitor_8cpp_source.html @@ -72,19 +72,19 @@ $(function() {
      1 #include "view_monitor.h"
      2 
      3 ViewMonitor::ViewMonitor() : t_worker(&ViewMonitor::worker, this)
      4 {
      5 }
      6 
      7 call_t ViewMonitor::keypress(int& key)
      8 {
      9  switch(key)
      10  {
      11 
      12  case KEY_MOUSE:
      13  {
      14  // http://pronix.linuxdelta.de/C/Linuxprogrammierung/Linuxsystemprogrammieren_C_Kurs_Kapitel10b.shtml
      15  MEVENT event;
      16  bool hit = false;
      17  if(getmouse(&event) == OK && event.bstate & (BUTTON1_CLICKED | BUTTON1_DOUBLE_CLICKED))
      18  {
      19  size_t column = start_x + close_offset_x;
      20  size_t row = start_y + close_offset_y;
      21  size_t mouse_x = event.x, mouse_y = event.y;
      22  if(mouse_y == row && mouse_x >= column && mouse_x < column + label_close.length())
      23  hit = true;
      24  }
      25  if(!hit)
      26  break;
      27 
      28  // fall through to next case
      29  [[fallthrough]];
      30  }
      31  case KEY_ENT:
      32  run_worker = false;
      33  key = -1; // do return from view
      34  wclear(win);
      35  wrefresh(win);
      36  t_worker.join();
      37  break;
      38  default:
      39  break;
      40  }
      41  return calls[0];
      42 }
      43 
      44 std::string ViewMonitor::fancyDigitalString(uint8_t& b)
      45 {
      46  std::string bitstring(std::bitset<8>(b).to_string());
      47  std::reverse(bitstring.begin(), bitstring.end());
      48 
      49  std::stringstream str;
      50  str << bitstring;
      51  str << " ";
      52  str << "0x" << std::setfill ('0') << std::setw(2) << std::hex << (int) b << std::dec;
      53  return str.str();
      54 }
      55 
      56 std::string ViewMonitor::fancyAnalogString(uint16_t& v)
      57 {
      58  std::stringstream str;
      59  double volt = round(v * 100.0 * 5.0 / 1023.0) / 100.0;
      60 
      61  str << std::setfill ('0') << std::setw(4) << (int) v << " " << std::fixed << std::setprecision(2) << volt << " V ";
      62 
      63  str << "[";
      64  uint8_t p = round(v * 40.0 / 1023.0);
      65  for(uint8_t i = 0; i < p; i++)
      66  str << "X";
      67  for(uint8_t i = 0; i < 40 - p; i++)
      68  str << " ";
      69  str << "]" << std::endl;
      70 
      71  return str.str();
      72 }
      73 
      74 void ViewMonitor::worker()
      75 {
      76  B15F& drv = B15F::getInstance();
      77  while(run_worker)
      78  {
      79  try
      80  {
      81  std::this_thread::sleep_for(std::chrono::milliseconds(100));
      82 
      83  uint8_t be0 = drv.digitalRead0();
      84  uint8_t be1 = drv.digitalRead1();
      85  uint8_t dsw = drv.readDipSwitch();
      86  uint16_t adc[8];
      87  for(uint8_t i = 0; i < sizeof(adc) / sizeof(adc[0]); i++)
      88  adc[i] = drv.analogRead(i);
      89 
      90 
      91  std::stringstream str;
      92 
      93  // hline
      94  for(uint8_t i = 0; i < width - 2 * text_offset_x; i++)
      95  if(i % 2 == 0)
      96  str << "-";
      97  else
      98  str << " ";
      99  str << std::endl;
      100 
      101  str << "Digitale Enigaenge:" << std::endl;
      102  str << "Binaere Eingabe 0: " << fancyDigitalString(be0) << std::endl;
      103  str << "Binaere Eingabe 1: " << fancyDigitalString(be1) << std::endl;
      104  str << "Dip Schalter (S7): " << fancyDigitalString(dsw) << std::endl;
      105 
      106  // hline
      107  for(uint8_t i = 0; i < width - 2 * text_offset_x; i++)
      108  if(i % 2 == 0)
      109  str << "-";
      110  else
      111  str << " ";
      112  str << std::endl;
      113 
      114  str << "Analoge Eingaenge:" << std::endl;
      115  for(uint8_t i = 0; i < sizeof(adc) / sizeof(adc[0]); i++)
      116  {
      117  str << "Kanal " << std::to_string((int) i) << ": ";
      118  str << fancyAnalogString(adc[i]) << std::endl;
      119  }
      120 
      121  text = str.str();
      122  repaint();
      123  }
      124  catch(DriverException& ex)
      125  {
      126  std::cout << "DriverException: " << ex.what() << std::endl;
      127  drv.delay_ms(1000);
      128  }
      129  catch(...)
      130  {
      131  try
      132  {
      133  drv.reconnect();
      134  }
      135  catch(...)
      136  {
      137  B15F::abort("Die Verbindung ist unterbrochen worden. Wurde ein Stecker gezogen? :D");
      138  return;
      139  }
      140  }
      141  }
      142 }
      -
      uint8_t digitalRead0(void)
      Definition: b15f.cpp:237
      -
      uint8_t readDipSwitch(void)
      Definition: b15f.cpp:269
      -
      void delay_ms(uint16_t ms)
      Definition: b15f.cpp:127
      +
      uint8_t digitalRead0(void)
      Definition: b15f.cpp:245
      +
      uint8_t readDipSwitch(void)
      Definition: b15f.cpp:277
      +
      void delay_ms(uint16_t ms)
      Definition: b15f.cpp:135
      static B15F & getInstance(void)
      Definition: b15f.cpp:10
      -
      Definition: b15f.h:33
      -
      static void abort(std::string msg)
      Definition: b15f.cpp:161
      -
      uint16_t analogRead(uint8_t channel)
      Definition: b15f.cpp:322
      -
      uint8_t digitalRead1(void)
      Definition: b15f.cpp:253
      +
      Definition: b15f.h:37
      +
      static void abort(std::string msg)
      Definition: b15f.cpp:169
      +
      uint16_t analogRead(uint8_t channel)
      Definition: b15f.cpp:330
      +
      uint8_t digitalRead1(void)
      Definition: b15f.cpp:261
      void reconnect(void)
      Definition: b15f.cpp:18
      diff --git a/docs/html/view__monitor_8h_source.html b/docs/html/view__monitor_8h_source.html index 0f16d3c..f324039 100644 --- a/docs/html/view__monitor_8h_source.html +++ b/docs/html/view__monitor_8h_source.html @@ -75,7 +75,7 @@ $(function() { diff --git a/docs/html/view__promt_8cpp_source.html b/docs/html/view__promt_8cpp_source.html index 6af2b6b..ab046ac 100644 --- a/docs/html/view__promt_8cpp_source.html +++ b/docs/html/view__promt_8cpp_source.html @@ -73,7 +73,7 @@ $(function() {
      1 #include "view_promt.h"
      2 
      3 void ViewPromt::draw()
      4 {
      5  curs_set(1); // show cursor
      6 
      7  int li = text_offset_y;
      8  int ci = 0;
      9  for(std::string line : str_split(message + input, "\n"))
      10  {
      11  mvwprintw(win, ++li, text_offset_x, "%s", line.c_str());
      12  ci = line.length() + text_offset_x;
      13  }
      14 
      15  button_offset_x = (width - label_cancel.length() - sep.length() - label_confirm.length()) / 2;
      16  button_offset_y = height - text_offset_y;
      17 
      18  if(selection == 0)
      19  {
      20  wattron(win, A_REVERSE);
      21  mvwprintw(win, button_offset_y, button_offset_x, "%s", label_cancel.c_str());
      22  wattroff(win, A_REVERSE);
      23  mvwprintw(win, button_offset_y, button_offset_x + label_cancel.length(), "%s", sep.c_str());
      24  mvwprintw(win, button_offset_y, button_offset_x + label_cancel.length() + sep.length(), "%s", label_confirm.c_str());
      25  }
      26  else
      27  {
      28  mvwprintw(win, button_offset_y, button_offset_x, "%s", label_cancel.c_str());
      29  mvwprintw(win, button_offset_y, button_offset_x + label_cancel.length(), "%s", sep.c_str());
      30  wattron(win, A_REVERSE);
      31  mvwprintw(win, button_offset_y, button_offset_x + label_cancel.length() + sep.length(), "%s", label_confirm.c_str());
      32  wattroff(win, A_REVERSE);
      33  }
      34  wmove(win, li, ci);
      35 }
      36 
      37 void ViewPromt::setMessage(std::string message)
      38 {
      39  this->message = message;
      40 }
      41 
      42 void ViewPromt::setConfirm(std::string name, std::function<void(int)> call)
      43 {
      44  label_confirm = name;
      45  call_confirm = call;
      46 }
      47 
      48 void ViewPromt::setCancel(std::string name, bool cancelable)
      49 {
      50  label_cancel = name;
      51  this->cancelable = cancelable;
      52 }
      53 
      54 std::string ViewPromt::getInput()
      55 {
      56  return input;
      57 }
      58 
      59 std::function<void(int)> ViewPromt::keypress(int& key)
      60 {
      61  std::function<void(int)> ret = nullptr;
      62  switch(key)
      63  {
      64  case KEY_BACKSPACE:
      65  if(input.length())
      66  input.pop_back();
      67  break;
      68  case '\t':
      69  case KEY_LEFT:
      70  case KEY_RIGHT:
      71  selection = (selection + 1 ) % 2;
      72  break;
      73  case KEY_MOUSE:
      74  {
      75  // http://pronix.linuxdelta.de/C/Linuxprogrammierung/Linuxsystemprogrammieren_C_Kurs_Kapitel10b.shtml
      76  MEVENT event;
      77  bool hit = false;
      78  if(getmouse(&event) == OK && event.bstate & (BUTTON1_CLICKED | BUTTON1_DOUBLE_CLICKED))
      79  {
      80  size_t column_start = start_x + button_offset_x;
      81  size_t row_start = start_y + button_offset_y;
      82  size_t mouse_x = event.x, mouse_y = event.y;
      83  if(mouse_y == row_start)
      84  {
      85  if(cancelable && mouse_x >= column_start && mouse_x < column_start + label_cancel.length())
      86  {
      87  if(selection == 0 || event.bstate & BUTTON1_DOUBLE_CLICKED)
      88  hit = true;
      89  selection = 0;
      90  }
      91  if(mouse_x >= column_start + label_cancel.length() + sep.length() && mouse_x < column_start + label_cancel.length() + sep.length() + label_confirm.length())
      92  {
      93  if(selection == 1 || event.bstate & BUTTON1_DOUBLE_CLICKED)
      94  hit = true;
      95  selection = 1;
      96  }
      97  }
      98  }
      99  if(!hit)
      100  break;
      101 
      102  // fall through to next case
      103  [[fallthrough]];
      104  }
      105  case KEY_ENT:
      106  if(selection == 0) // exit
      107  key = -1; // do return from view
      108  else
      109  ret = call_confirm;
      110  break;
      111  default:
      112  break;
      113  }
      114 
      115  if(key >= ' ' && key <= '~')
      116  input += (char) key;
      117 
      118  if(key != KEY_ENT)
      119  repaint();
      120  return ret;
      121 }
      diff --git a/docs/html/view__promt_8h_source.html b/docs/html/view__promt_8h_source.html index 46e5728..408c19a 100644 --- a/docs/html/view__promt_8h_source.html +++ b/docs/html/view__promt_8h_source.html @@ -75,7 +75,7 @@ $(function() { diff --git a/docs/html/view__selection_8cpp_source.html b/docs/html/view__selection_8cpp_source.html index fe26602..786df89 100644 --- a/docs/html/view__selection_8cpp_source.html +++ b/docs/html/view__selection_8cpp_source.html @@ -73,7 +73,7 @@ $(function() {
      1 #include "view_selection.h"
      2 
      3 void ViewSelection::draw()
      4 {
      5  //curs_set(0); // hide cursor
      6  for(size_t i = 0; i < choices.size(); i++)
      7  {
      8  if(selection == i)
      9  wattron(win, A_REVERSE);
      10  mvwprintw(win, i + choice_offset_y, choice_offset_x, "%s", choices[i].c_str());
      11  if(selection == i)
      12  wattroff(win, A_REVERSE);
      13  }
      14 }
      15 
      16 void ViewSelection::addChoice(std::string name, call_t call)
      17 {
      18  choices.push_back(name);
      19  calls.push_back(call);
      20 }
      21 
      22 call_t ViewSelection::keypress(int& key)
      23 {
      24  call_t ret = nullptr;
      25  switch(key)
      26  {
      27  case KEY_UP:
      28  do
      29  selection = (selection - 1 + choices.size()) % choices.size();
      30  while(!choices[selection].length() && choices.size());
      31  break;
      32 
      33  case '\t':
      34  case KEY_DOWN:
      35  do
      36  selection = (selection + 1) % choices.size();
      37  while(!choices[selection].length() && choices.size());
      38  break;
      39 
      40  case KEY_MOUSE:
      41  {
      42  // http://pronix.linuxdelta.de/C/Linuxprogrammierung/Linuxsystemprogrammieren_C_Kurs_Kapitel10b.shtml
      43  MEVENT event;
      44  bool hit = false;
      45  if(getmouse(&event) == OK && event.bstate & (BUTTON1_CLICKED | BUTTON1_DOUBLE_CLICKED))
      46  {
      47  size_t column_start = start_x + choice_offset_x;
      48  size_t row_start = start_y + choice_offset_y;
      49  size_t mouse_x = event.x, mouse_y = event.y;
      50  for(size_t i = 0; i < choices.size(); i++)
      51  if(choices[i].length() && mouse_y == row_start + i && mouse_x >= column_start && mouse_x < column_start + choices[i].length())
      52  {
      53  if(selection == i || event.bstate & BUTTON1_DOUBLE_CLICKED)
      54  hit = true;
      55  selection = i;
      56  }
      57  }
      58  if(!hit)
      59  break;
      60 
      61  // fall through to next case
      62  [[fallthrough]];
      63  }
      64 
      65  case KEY_ENT:
      66  if(selection == choices.size() - 1) // exit
      67  key = -1; // do return from view
      68  else
      69  ret = calls[selection];
      70  break;
      71  default:
      72  break;
      73  }
      74  repaint();
      75  return ret;
      76 }
      diff --git a/docs/html/view__selection_8h_source.html b/docs/html/view__selection_8h_source.html index 695c04a..5853202 100644 --- a/docs/html/view__selection_8h_source.html +++ b/docs/html/view__selection_8h_source.html @@ -75,7 +75,7 @@ $(function() {