diff --git a/src/firmware/application/CMakeLists.txt b/src/firmware/application/CMakeLists.txt index 7ccb6e23b..2351b9cf5 100644 --- a/src/firmware/application/CMakeLists.txt +++ b/src/firmware/application/CMakeLists.txt @@ -50,6 +50,7 @@ if(NOT "PROJECT_TARGET_USB_OVER_SERIAL_HOST" IN_LIST PROJECT_TARGET_DEFINES) target_sources(application PRIVATE ${CMAKE_CURRENT_LIST_DIR}/io/buttons/Buttons.cpp + ${CMAKE_CURRENT_LIST_DIR}/io/touchscreen/model/viewtech/Viewtech.cpp ${CMAKE_CURRENT_LIST_DIR}/io/touchscreen/model/Builder.cpp ${CMAKE_CURRENT_LIST_DIR}/io/touchscreen/model/nextion/Nextion.cpp ${CMAKE_CURRENT_LIST_DIR}/io/touchscreen/Touchscreen.cpp diff --git a/src/firmware/application/io/touchscreen/Touchscreen.h b/src/firmware/application/io/touchscreen/Touchscreen.h index 9965f57fd..f99e19a25 100644 --- a/src/firmware/application/io/touchscreen/Touchscreen.h +++ b/src/firmware/application/io/touchscreen/Touchscreen.h @@ -102,6 +102,7 @@ namespace io enum class model_t : uint8_t { NEXTION, + VIEWTECH, AMOUNT }; diff --git a/src/firmware/application/io/touchscreen/model/Builder.cpp b/src/firmware/application/io/touchscreen/model/Builder.cpp index 6f1bea5e0..b5053ebc7 100644 --- a/src/firmware/application/io/touchscreen/model/Builder.cpp +++ b/src/firmware/application/io/touchscreen/model/Builder.cpp @@ -24,6 +24,7 @@ using namespace io; TouchscreenModelBuilder::TouchscreenModelBuilder(Touchscreen::HWA& hwa) : _nextion(hwa) + , _viewtech(hwa) {} uint8_t Touchscreen::Model::_rxBuffer[Touchscreen::Model::BUFFER_SIZE]; diff --git a/src/firmware/application/io/touchscreen/model/Builder.h b/src/firmware/application/io/touchscreen/model/Builder.h index a82bd2aa6..4eceb4454 100644 --- a/src/firmware/application/io/touchscreen/model/Builder.h +++ b/src/firmware/application/io/touchscreen/model/Builder.h @@ -23,6 +23,7 @@ limitations under the License. #ifdef PROJECT_TARGET_SUPPORT_TOUCHSCREEN #include "nextion/Nextion.h" +#include "viewtech/Viewtech.h" namespace io { @@ -32,7 +33,8 @@ namespace io TouchscreenModelBuilder(Touchscreen::HWA& hwa); private: - Nextion _nextion; + Nextion _nextion; + Viewtech _viewtech; }; } // namespace io #else diff --git a/src/firmware/application/io/touchscreen/model/viewtech/README.md b/src/firmware/application/io/touchscreen/model/viewtech/README.md new file mode 100644 index 000000000..e000baa75 --- /dev/null +++ b/src/firmware/application/io/touchscreen/model/viewtech/README.md @@ -0,0 +1,3 @@ +This directory contains code support for Viewtech SDWe displays. Currently tested displays: + +* SDWe101T09T (1024x600, 10", resistive touchscreen) \ No newline at end of file diff --git a/src/firmware/application/io/touchscreen/model/viewtech/Viewtech.cpp b/src/firmware/application/io/touchscreen/model/viewtech/Viewtech.cpp new file mode 100644 index 000000000..a98f8e391 --- /dev/null +++ b/src/firmware/application/io/touchscreen/model/viewtech/Viewtech.cpp @@ -0,0 +1,181 @@ +/* + +Copyright 2015-2022 Igor Petrovic + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +*/ + +#ifdef PROJECT_TARGET_SUPPORT_TOUCHSCREEN + +#include "Viewtech.h" +#include "core/MCU.h" +#include "core/util/Util.h" + +using namespace io; + +Viewtech::Viewtech(io::Touchscreen::HWA& hwa) + : _hwa(hwa) +{ + io::Touchscreen::registerModel(io::Touchscreen::model_t::VIEWTECH, this); +} + +bool Viewtech::init() +{ + Touchscreen::Model::_bufferCount = 0; + + if (_hwa.init()) + { + // add slight delay to ensure display can receive commands after power on + core::mcu::timing::waitMs(3000); + + return true; + } + + return false; +} + +bool Viewtech::deInit() +{ + return _hwa.deInit(); +} + +bool Viewtech::setScreen(size_t screenID) +{ + screenID &= 0xFF; + + _hwa.write(0xA5); + _hwa.write(0x5A); + _hwa.write(0x04); + _hwa.write(0x80); + _hwa.write(0x03); + _hwa.write(0x00); + _hwa.write(screenID); + + return true; +} + +Touchscreen::tsEvent_t Viewtech::update(Touchscreen::tsData_t& data) +{ + auto event = Touchscreen::tsEvent_t::NONE; + uint8_t value = 0; + + while (_hwa.read(value)) + { + Touchscreen::Model::_rxBuffer[Touchscreen::Model::_bufferCount++] = value; + } + + // assumption - only one response is received at the time + // if parsing fails, wipe the buffer + if (Touchscreen::Model::_bufferCount) + { + // verify header first + if (Touchscreen::Model::_rxBuffer[0] == 0xA5) + { + if (Touchscreen::Model::_bufferCount > 1) + { + if (Touchscreen::Model::_rxBuffer[1] == 0x5A) + { + if (Touchscreen::Model::_bufferCount > 2) + { + // byte at index 2 holds response length, without first two bytes and without byte at index 2 + if (Touchscreen::Model::_bufferCount >= static_cast(3 + Touchscreen::Model::_rxBuffer[2])) + { + uint32_t response = Touchscreen::Model::_rxBuffer[2]; + response <<= 8; + response |= Touchscreen::Model::_rxBuffer[3]; + response <<= 8; + response |= Touchscreen::Model::_rxBuffer[4]; + response <<= 8; + response |= Touchscreen::Model::_rxBuffer[5]; + + switch (response) + { + case static_cast(response_t::BUTTON_STATE_CHANGE): + { + data.buttonState = Touchscreen::Model::_rxBuffer[6]; + data.buttonID = Touchscreen::Model::_rxBuffer[7]; + + event = Touchscreen::tsEvent_t::BUTTON; + } + break; + + default: + break; + } + + Touchscreen::Model::_bufferCount = 0; + } + } + } + else + { + // header invalid - ignore the rest of the message + Touchscreen::Model::_bufferCount = 0; + } + } + } + else + { + // header invalid - ignore the rest of the message + Touchscreen::Model::_bufferCount = 0; + } + } + + return event; +} + +void Viewtech::setIconState(Touchscreen::icon_t& icon, bool state) +{ + // header + _hwa.write(0xA5); + _hwa.write(0x5A); + + // request size + _hwa.write(0x05); + + // write variable + _hwa.write(0x82); + + // icon address - for viewtech displays, address is stored in xPos element + _hwa.write(core::util::MSB_U16(icon.xPos)); + _hwa.write(core::util::LSB_U16(icon.xPos)); + + // value to set - 2 bytes are used, higher is always 0 + // inverted logic for setting state - 0 means on state, 1 is off + _hwa.write(0x00); + _hwa.write(state ? 0x00 : 0x01); +} + +bool Viewtech::setBrightness(Touchscreen::brightness_t brightness) +{ + // header + _hwa.write(0xA5); + _hwa.write(0x5A); + + // request size + _hwa.write(0x03); + + // register write + _hwa.write(0x80); + + // brightness settting + _hwa.write(0x01); + + // brightness value + _hwa.write(BRIGHTNESS_MAPPING[static_cast(brightness)]); + + return true; +} + +#endif \ No newline at end of file diff --git a/src/firmware/application/io/touchscreen/model/viewtech/Viewtech.h b/src/firmware/application/io/touchscreen/model/viewtech/Viewtech.h new file mode 100644 index 000000000..8515da2c4 --- /dev/null +++ b/src/firmware/application/io/touchscreen/model/viewtech/Viewtech.h @@ -0,0 +1,55 @@ +/* + +Copyright 2015-2022 Igor Petrovic + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +*/ + +#pragma once + +#include +#include "application/io/touchscreen/Touchscreen.h" +#include "core/util/RingBuffer.h" + +class Viewtech : public io::Touchscreen::Model +{ + public: + Viewtech(io::Touchscreen::HWA& hwa); + + bool init() override; + bool deInit() override; + bool setScreen(size_t screenID) override; + io::Touchscreen::tsEvent_t update(io::Touchscreen::tsData_t& data) override; + void setIconState(io::Touchscreen::icon_t& icon, bool state) override; + bool setBrightness(io::Touchscreen::brightness_t brightness) override; + + private: + enum class response_t : uint32_t + { + BUTTON_STATE_CHANGE = 0x05820002 + }; + + io::Touchscreen::HWA& _hwa; + + // there are 7 levels of brighness - scale them to available range (0-64) + static constexpr uint8_t BRIGHTNESS_MAPPING[7] = { + 6, + 16, + 32, + 48, + 51, + 58, + 64 + }; +}; \ No newline at end of file diff --git a/src/firmware/application/io/touchscreen/stub/Touchscreen.h b/src/firmware/application/io/touchscreen/stub/Touchscreen.h index 0fff7b0d0..bd3bd21b2 100644 --- a/src/firmware/application/io/touchscreen/stub/Touchscreen.h +++ b/src/firmware/application/io/touchscreen/stub/Touchscreen.h @@ -92,6 +92,7 @@ namespace io enum class model_t : uint8_t { NEXTION, + VIEWTECH, AMOUNT }; diff --git a/tests/src/system/CMakeLists.txt b/tests/src/system/CMakeLists.txt index 505a62b58..58d7368a4 100644 --- a/tests/src/system/CMakeLists.txt +++ b/tests/src/system/CMakeLists.txt @@ -20,6 +20,7 @@ if(NOT "PROJECT_TARGET_USB_OVER_SERIAL_HOST" IN_LIST PROJECT_TARGET_DEFINES) ${PROJECT_ROOT}/src/firmware/application/io/touchscreen/Touchscreen.cpp ${PROJECT_ROOT}/src/firmware/application/io/touchscreen/model/Builder.cpp ${PROJECT_ROOT}/src/firmware/application/io/touchscreen/model/nextion/Nextion.cpp + ${PROJECT_ROOT}/src/firmware/application/io/touchscreen/model/viewtech/Viewtech.cpp ) target_compile_definitions(system