From aabc61dc3b33116e0daabb6c22f78de8b8d205da Mon Sep 17 00:00:00 2001 From: nanosonde <2073569+nanosonde@users.noreply.github.com> Date: Fri, 11 Sep 2020 13:32:29 +0200 Subject: [PATCH] Add UART support for Linux platform to use TP1 KNX transceivers (#88) * Add inital serial port support for Linux platform * Add missing print implementation for uint64_t and enable mask 07B0 for Linux platform using TPUART * Create executable per mask * Add one executable per mask for coupler --- examples/knx-linux-coupler/CMakeLists.txt | 20 ++- examples/knx-linux/CMakeLists.txt | 23 +++- examples/knx-linux/main.cpp | 2 + src/linux_platform.cpp | 143 +++++++++++++++++++++- src/linux_platform.h | 14 ++- 5 files changed, 190 insertions(+), 12 deletions(-) diff --git a/examples/knx-linux-coupler/CMakeLists.txt b/examples/knx-linux-coupler/CMakeLists.txt index 6fad30a..dfbb21a 100644 --- a/examples/knx-linux-coupler/CMakeLists.txt +++ b/examples/knx-linux-coupler/CMakeLists.txt @@ -1,8 +1,9 @@ cmake_minimum_required(VERSION 2.7) project(knx-linux-coupler) set(LIBRARIES_FROM_REFERENCES "") -add_executable(knx-linux - ../../src/knx/address_table_object.cpp + +set(SOURCES + ../../src/knx/address_table_object.cpp ../../src/knx/address_table_object.h ../../src/knx/aes.c ../../src/knx/aes.h @@ -130,9 +131,18 @@ add_executable(knx-linux fdsk.cpp fdsk.h main.cpp) -target_link_libraries(knx-linux "${LIBRARIES_FROM_REFERENCES}") + include_directories(../../src) + set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -Wall -Wno-unknown-pragmas -g -O0") set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Wall -Wno-unknown-pragmas -g -O0") -set_property(TARGET knx-linux PROPERTY CXX_STANDARD 11) -add_definitions(-DMASK_VERSION=0x091A) + +add_executable(knx-linux-iptp ${SOURCES}) +target_link_libraries(knx-linux-iptp "${LIBRARIES_FROM_REFERENCES}") +set_property(TARGET knx-linux-iptp PROPERTY CXX_STANDARD 11) +target_compile_definitions(knx-linux-iptp PUBLIC -DMASK_VERSION=0x091A) + +add_executable(knx-linux-tprf ${SOURCES}) +target_link_libraries(knx-linux-tprf "${LIBRARIES_FROM_REFERENCES}") +set_property(TARGET knx-linux-tprf PROPERTY CXX_STANDARD 11) +target_compile_definitions(knx-linux-tprf PUBLIC -DMASK_VERSION=0x2920) diff --git a/examples/knx-linux/CMakeLists.txt b/examples/knx-linux/CMakeLists.txt index b84d7b7..40d21c8 100644 --- a/examples/knx-linux/CMakeLists.txt +++ b/examples/knx-linux/CMakeLists.txt @@ -1,7 +1,8 @@ cmake_minimum_required(VERSION 2.7) project(knx-linux) set(LIBRARIES_FROM_REFERENCES "") -add_executable(knx-linux + +set(SOURCES ../../src/knx/address_table_object.cpp ../../src/knx/address_table_object.h ../../src/knx/aes.c @@ -130,9 +131,23 @@ add_executable(knx-linux fdsk.cpp fdsk.h main.cpp) -target_link_libraries(knx-linux "${LIBRARIES_FROM_REFERENCES}") + include_directories(../../src) + set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -Wall -Wno-unknown-pragmas -g -O0") set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Wall -Wno-unknown-pragmas -g -O0") -set_property(TARGET knx-linux PROPERTY CXX_STANDARD 11) -add_definitions(-DMASK_VERSION=0x57B0) + +add_executable(knx-linux-tp ${SOURCES}) +target_link_libraries(knx-linux-tp "${LIBRARIES_FROM_REFERENCES}") +set_property(TARGET knx-linux-tp PROPERTY CXX_STANDARD 11) +target_compile_definitions(knx-linux-tp PUBLIC -DMASK_VERSION=0x07B0) + +add_executable(knx-linux-rf ${SOURCES}) +target_link_libraries(knx-linux-rf "${LIBRARIES_FROM_REFERENCES}") +set_property(TARGET knx-linux-rf PROPERTY CXX_STANDARD 11) +target_compile_definitions(knx-linux-rf PUBLIC -DMASK_VERSION=0x27B0) + +add_executable(knx-linux-ip ${SOURCES}) +target_link_libraries(knx-linux-ip "${LIBRARIES_FROM_REFERENCES}") +set_property(TARGET knx-linux-ip PROPERTY CXX_STANDARD 11) +target_compile_definitions(knx-linux-ip PUBLIC -DMASK_VERSION=0x57B0) diff --git a/examples/knx-linux/main.cpp b/examples/knx-linux/main.cpp index 9c17954..a416220 100644 --- a/examples/knx-linux/main.cpp +++ b/examples/knx-linux/main.cpp @@ -38,6 +38,8 @@ bool isSendHidReportPossible() KnxFacade knx; #elif MASK_VERSION == 0x27B0 KnxFacade knx; +#elif MASK_VERSION == 0x07B0 +KnxFacade knx; #else #error Mask version not supported yet! #endif diff --git a/src/linux_platform.cpp b/src/linux_platform.cpp index 2dfd2e3..6501730 100644 --- a/src/linux_platform.cpp +++ b/src/linux_platform.cpp @@ -21,6 +21,7 @@ #include #include #include +#include #include // Needed for SPI port #include // Needed for SPI port @@ -400,6 +401,124 @@ std::string LinuxPlatform::flashFilePath() return _flashFilePath; } + + +size_t LinuxPlatform::readBytesUart(uint8_t *buffer, size_t length) +{ + return read(_uartFd, buffer, length); +} + +int LinuxPlatform::readUart() +{ + uint8_t x ; + + if (read(_uartFd, &x, 1) != 1) + { + return -1; + } + + return ((int)x) & 0xFF ; +} + +size_t LinuxPlatform::writeUart(const uint8_t *buffer, size_t size) +{ + return write(_uartFd, buffer, size) ; +} + +size_t LinuxPlatform::writeUart(const uint8_t data) +{ + return write(_uartFd, &data, 1) ; +} + +int LinuxPlatform::uartAvailable() +{ + int result ; + + if (ioctl(_uartFd, FIONREAD, &result) == -1) + { + return -1; + } + + return result ; +} + +void LinuxPlatform::closeUart() +{ + if (_uartFd >= 0) + { + close(_uartFd); + } +} + +void LinuxPlatform::setupUart() +{ + /* + * 19200,8E1, no handshake + */ + struct termios options; /* Schnittstellenoptionen */ + + /* Port oeffnen - read/write, kein "controlling tty", Status von DCD ignorieren */ + _uartFd = open("/dev/ttyUSB0", O_RDWR | O_NOCTTY | O_NDELAY); + if (_uartFd >= 0) + { + /* get the current options */ + fcntl(_uartFd, F_SETFL, 0); + if (tcgetattr(_uartFd, &options) != 0) + { + close(_uartFd); + _uartFd = -1; + return; + } + memset(&options, 0, sizeof(options)); /* Structur loeschen, ggf. vorher sichern + und bei Programmende wieder restaurieren */ + /* Baudrate setzen */ + cfsetispeed(&options, B19200); + cfsetospeed(&options, B19200); + + /* setze Optionen */ + options.c_cflag |= PARENB; /* Enable Paritybit */ + options.c_cflag &= ~PARODD; /* Even parity */ + options.c_cflag &= ~CSTOPB; /* 1 Stoppbit */ + options.c_cflag &= ~CSIZE; /* 8 Datenbits */ + options.c_cflag |= CS8; + + /* 19200 bps, 8 Datenbits, CD-Signal ignorieren, Lesen erlauben */ + options.c_cflag |= (CLOCAL | CREAD); + + /* Kein Echo, keine Steuerzeichen, keine Interrupts */ + options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); + options.c_iflag = IGNPAR; /* Parity-Fehler ignorieren */ + options.c_oflag &= ~OPOST; /* setze "raw" Input */ + options.c_cc[VMIN] = 0; /* warten auf min. 0 Zeichen */ + options.c_cc[VTIME] = 10; /* Timeout 1 Sekunde */ + tcflush(_uartFd,TCIOFLUSH); /* Puffer leeren */ + + if (tcsetattr(_uartFd, TCSAFLUSH, &options) != 0) + { + close(_uartFd); + _uartFd = -1; + return; + } + } +} + +void printUint64(uint64_t value, int base = DEC) + { + char buf[8 * sizeof(uint64_t) + 1]; + char* str = &buf[sizeof(buf) - 1]; + *str = '\0'; + + uint64_t n = value; + do { + char c = n % base; + n /= base; + + *--str = c < 10 ? c + '0' : c + 'A' - 10; + } while (n > 0); + + print(str); +} + void print(const char* s) { printf("%s", s); @@ -474,6 +593,16 @@ void print(unsigned long num, int base) printf("%ld", num); } +void print(unsigned long long num) +{ + printUint64(num); +} + +void print(unsigned long long num, int base) +{ + printUint64(num, base); +} + void print(double num) { printf("%f", num); @@ -553,6 +682,18 @@ void println(unsigned long num, int base) printf("%ld\n", num); } +void println(unsigned long long num) +{ + printUint64(num); + println(""); +} + +void println(unsigned long long num, int base) +{ + printUint64(num, base); + println(""); +} + void println(double num) { printf("%f\n", num); @@ -1031,4 +1172,4 @@ uint32_t LinuxPlatform::currentDefaultGateway() { return _defaultGateway; } -#endif \ No newline at end of file +#endif diff --git a/src/linux_platform.h b/src/linux_platform.h index b82d3f8..0ec9bb9 100644 --- a/src/linux_platform.h +++ b/src/linux_platform.h @@ -39,7 +39,16 @@ public: bool sendBytesMultiCast(uint8_t* buffer, uint16_t len) override; int readBytesMultiCast(uint8_t* buffer, uint16_t maxLen) override; bool sendBytesUniCast(uint32_t addr, uint16_t port, uint8_t* buffer, uint16_t len) override; - + + //UART + void setupUart() override; + void closeUart() override; + int uartAvailable() override; + size_t writeUart(const uint8_t data) override; + size_t writeUart(const uint8_t* buffer, size_t size) override; + int readUart() override; + size_t readBytesUart(uint8_t* buffer, size_t length) override; + //spi void setupSpi() override; void closeSpi() override; @@ -59,6 +68,7 @@ public: uint8_t* _mappedFile = 0; int _fd = -1; int _spiFd = -1; + int _uartFd = -1; std::string _flashFilePath = "flash.bin"; char** _args = 0; @@ -68,4 +78,4 @@ public: uint32_t _defaultGateway = 0; }; -#endif \ No newline at end of file +#endif