From 7c96d9fe88737b213a884107e5d6c6e541b66d3c Mon Sep 17 00:00:00 2001 From: delphi Date: Sat, 19 Sep 2020 18:50:37 +0200 Subject: [PATCH] [examples] Add ILI9341 display example --- examples/stm32_f4ve/gui/.gitignore | 2 + examples/stm32_f4ve/gui/images/bake.pbm | 16 + .../stm32_f4ve/gui/images/battery_empty.pbm | 9 + .../stm32_f4ve/gui/images/battery_full.pbm | 9 + .../stm32_f4ve/gui/images/battery_good.pbm | 9 + .../stm32_f4ve/gui/images/battery_low.pbm | 9 + .../gui/images/battery_not_connected.pbm | 9 + .../stm32_f4ve/gui/images/bluetooth_12x16.pbm | 6 + .../stm32_f4ve/gui/images/bluetooth_24x32.pbm | 14 + examples/stm32_f4ve/gui/images/charge.pbm | 7 + examples/stm32_f4ve/gui/images/discharge.pbm | 7 + examples/stm32_f4ve/gui/images/plug.pbm | 7 + examples/stm32_f4ve/gui/images/warning.pbm | 62 +++ .../stm32_f4ve/gui/images/warning_32x32.pbm | 18 + examples/stm32_f4ve/gui/main.cpp | 506 ++++++++++++++++++ examples/stm32_f4ve/gui/project.xml | 22 + .../stm32_f4ve/gui/touchscreen_calibrator.hpp | 105 ++++ 17 files changed, 817 insertions(+) create mode 100644 examples/stm32_f4ve/gui/.gitignore create mode 100644 examples/stm32_f4ve/gui/images/bake.pbm create mode 100644 examples/stm32_f4ve/gui/images/battery_empty.pbm create mode 100644 examples/stm32_f4ve/gui/images/battery_full.pbm create mode 100644 examples/stm32_f4ve/gui/images/battery_good.pbm create mode 100644 examples/stm32_f4ve/gui/images/battery_low.pbm create mode 100644 examples/stm32_f4ve/gui/images/battery_not_connected.pbm create mode 100644 examples/stm32_f4ve/gui/images/bluetooth_12x16.pbm create mode 100644 examples/stm32_f4ve/gui/images/bluetooth_24x32.pbm create mode 100644 examples/stm32_f4ve/gui/images/charge.pbm create mode 100644 examples/stm32_f4ve/gui/images/discharge.pbm create mode 100644 examples/stm32_f4ve/gui/images/plug.pbm create mode 100644 examples/stm32_f4ve/gui/images/warning.pbm create mode 100644 examples/stm32_f4ve/gui/images/warning_32x32.pbm create mode 100644 examples/stm32_f4ve/gui/main.cpp create mode 100644 examples/stm32_f4ve/gui/project.xml create mode 100644 examples/stm32_f4ve/gui/touchscreen_calibrator.hpp diff --git a/examples/stm32_f4ve/gui/.gitignore b/examples/stm32_f4ve/gui/.gitignore new file mode 100644 index 0000000000..a251fc8669 --- /dev/null +++ b/examples/stm32_f4ve/gui/.gitignore @@ -0,0 +1,2 @@ +images/*.hpp +images/*.cpp diff --git a/examples/stm32_f4ve/gui/images/bake.pbm b/examples/stm32_f4ve/gui/images/bake.pbm new file mode 100644 index 0000000000..dbee414ca0 --- /dev/null +++ b/examples/stm32_f4ve/gui/images/bake.pbm @@ -0,0 +1,16 @@ +P1 +# CREATOR: GIMP PNM Filter Version 1.1 +30 30 +0000000000000000000000000000000011111111111111111111111111100011111111 +1111111111111111111000111111111111111111111111111000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000000000 +0000000001110000000111000000000000000001111111111111000000000000000001 +1111111111110000000000000000001111111111100000000000000000000011111110 +0000000000000000000000011111000000000000000000000000011111000000000000 +0000000000000011100000000000000000000000000011100000000000000011111111 +1111111111111111111000111111111111111111111111111000111111111111111111 +1111111110001110000000000000000000001110001110000000000000000000001110 +0011100000000000000000000011100011100000000000000000000011100011100000 +0000000000000000111000111000000000000000000000111000111000000000000000 +0000001110001111111111111111111111111110001111111111111111111111111110 +001111111111111111111111111110000000000000000000000000000000 \ No newline at end of file diff --git a/examples/stm32_f4ve/gui/images/battery_empty.pbm b/examples/stm32_f4ve/gui/images/battery_empty.pbm new file mode 100644 index 0000000000..829b7bff0e --- /dev/null +++ b/examples/stm32_f4ve/gui/images/battery_empty.pbm @@ -0,0 +1,9 @@ +P1 +# CREATOR: GIMP PNM Filter Version 1.1 +25 16 +0000000000000000000000000000000000000000000000000000001111111111111111 +1110000010000000000000000000100001000000000000000001010001100000000000 +0000001010010100000000000000001101001010000000000000000110100101000000 +0000000000110100101000000000000000111010001100000000000000011101000010 +0000000000000011101000010000000000000000000100000111111111111111111100 +00000000000000000000000000000000000000000000000000 \ No newline at end of file diff --git a/examples/stm32_f4ve/gui/images/battery_full.pbm b/examples/stm32_f4ve/gui/images/battery_full.pbm new file mode 100644 index 0000000000..2b5eff03ee --- /dev/null +++ b/examples/stm32_f4ve/gui/images/battery_full.pbm @@ -0,0 +1,9 @@ +P1 +# CREATOR: GIMP PNM Filter Version 1.1 +25 16 +0000000000000000000000000000000000000000000000000000001111111111111111 +1110000010000000000000000000100001011111011111011111010001101111101111 +1011111010010101111101111101111101001010111110111110111110100101011111 +0111110111110100101011111011111011111010001101111101111101111101000010 +1111101111101111101000010000000000000000000100000111111111111111111100 +00000000000000000000000000000000000000000000000000 \ No newline at end of file diff --git a/examples/stm32_f4ve/gui/images/battery_good.pbm b/examples/stm32_f4ve/gui/images/battery_good.pbm new file mode 100644 index 0000000000..786663c960 --- /dev/null +++ b/examples/stm32_f4ve/gui/images/battery_good.pbm @@ -0,0 +1,9 @@ +P1 +# CREATOR: GIMP PNM Filter Version 1.1 +25 16 +0000000000000000000000000000000000000000000000000000001111111111111111 +1110000010000000000000000000100001000001011111011111010001100000101111 +1011111010010100001101111101111101001010000110111110111110100101000111 +0111110111110100101000111011111011111010001100111101111101111101000010 +0111101111101111101000010000000000000000000100000111111111111111111100 +00000000000000000000000000000000000000000000000000 \ No newline at end of file diff --git a/examples/stm32_f4ve/gui/images/battery_low.pbm b/examples/stm32_f4ve/gui/images/battery_low.pbm new file mode 100644 index 0000000000..9e94ea1b31 --- /dev/null +++ b/examples/stm32_f4ve/gui/images/battery_low.pbm @@ -0,0 +1,9 @@ +P1 +# CREATOR: GIMP PNM Filter Version 1.1 +25 16 +0000000000000000000000000000000000000000000000000000001111111111111111 +1110000010000000000000000000100001000000000000011111010001100000000000 +0011111010010100000000000001111101001010000000000000111110100101000000 +0000000111110100101000000000000011111010001100000000000001111101000010 +0000000000001111101000010000000000000000000100000111111111111111111100 +00000000000000000000000000000000000000000000000000 \ No newline at end of file diff --git a/examples/stm32_f4ve/gui/images/battery_not_connected.pbm b/examples/stm32_f4ve/gui/images/battery_not_connected.pbm new file mode 100644 index 0000000000..4b5eb456ad --- /dev/null +++ b/examples/stm32_f4ve/gui/images/battery_not_connected.pbm @@ -0,0 +1,9 @@ +P1 +# CREATOR: GIMP PNM Filter Version 1.1 +25 16 +0000000000000000000000000000000000000000000000000000001111111111111111 +1110000010000000000000000000100001000000001110000000010001100000001000 +1000000010010100000000000100000001001010000000000100000000100101000000 +0001000000000100101000000000100000000010001100000000000000000001000010 +0000000010000000001000010000000000000000000100000111111111111111111100 +00000000000000000000000000000000000000000000000000 \ No newline at end of file diff --git a/examples/stm32_f4ve/gui/images/bluetooth_12x16.pbm b/examples/stm32_f4ve/gui/images/bluetooth_12x16.pbm new file mode 100644 index 0000000000..f91742d0b1 --- /dev/null +++ b/examples/stm32_f4ve/gui/images/bluetooth_12x16.pbm @@ -0,0 +1,6 @@ +P1 +# CREATOR: GIMP PNM Filter Version 1.1 +12 16 +0000000000000001111110000011111111000111100111100111101011100110101101 +1001110010111001111001111001111001111001110010111001101011011001111010 +1110011110011110001111111100000111111000000000000000 \ No newline at end of file diff --git a/examples/stm32_f4ve/gui/images/bluetooth_24x32.pbm b/examples/stm32_f4ve/gui/images/bluetooth_24x32.pbm new file mode 100644 index 0000000000..9fa77741f5 --- /dev/null +++ b/examples/stm32_f4ve/gui/images/bluetooth_24x32.pbm @@ -0,0 +1,14 @@ +P1 +# CREATOR: GIMP PNM Filter Version 1.1 +24 32 +0000000000000000000000000000000001111110000000000000001111111111110000 +0000000111111111111110000000001111111001111111000000011111111000111111 +1000001111111110000111111100001111111110000011111100001111111110010001 +1111000111111111100110001111100111100011100111000111100111110001100110 +0011111001111110001001000111111001111111000000001111111001111111100000 +0111111110011111111100001111111110011111111100001111111110011111111000 +0001111111100111111100000000111111100111111000100100011111100111110001 +1001100011111001111000111001110001111001111111111001100011111001111111 +1110010001111110001111111110000011111100001111111110000111111100000111 +1111100011111110000000111111100111111100000000011111111111111000000000 +00111111111111000000000000000111111000000000000000000000000000000000 \ No newline at end of file diff --git a/examples/stm32_f4ve/gui/images/charge.pbm b/examples/stm32_f4ve/gui/images/charge.pbm new file mode 100644 index 0000000000..f1245a19ce --- /dev/null +++ b/examples/stm32_f4ve/gui/images/charge.pbm @@ -0,0 +1,7 @@ +P1 +# CREATOR: GIMP PNM Filter Version 1.1 +16 16 +0000000000000000000100000000000000010000000000000001000000000000000100 +0100000000000100110000000000010111000000000001111111111100000111111111 +1100000101110000000000010011000000000001000100000000000100000000000000 +0100000000000000010000000000000000000000000000 \ No newline at end of file diff --git a/examples/stm32_f4ve/gui/images/discharge.pbm b/examples/stm32_f4ve/gui/images/discharge.pbm new file mode 100644 index 0000000000..c47d2515f1 --- /dev/null +++ b/examples/stm32_f4ve/gui/images/discharge.pbm @@ -0,0 +1,7 @@ +P1 +# CREATOR: GIMP PNM Filter Version 1.1 +16 16 +0000000000000000000100000000000000010000000000000001000000000000000100 +0000100000000100000011000000010000001110000001111111111100000111111111 +1100000100000011100000010000001100000001000000100000000100000000000000 +0100000000000000010000000000000000000000000000 \ No newline at end of file diff --git a/examples/stm32_f4ve/gui/images/plug.pbm b/examples/stm32_f4ve/gui/images/plug.pbm new file mode 100644 index 0000000000..1c832d4a66 --- /dev/null +++ b/examples/stm32_f4ve/gui/images/plug.pbm @@ -0,0 +1,7 @@ +P1 +# CREATOR: GIMP PNM Filter Version 1.1 +16 16 +0000000000000000000011100000000000001111111000000000111111110000011111 +1111111000011111111111100000001111111110000000111111111111000011111111 +1111000011111111100001111111111110000111111111111000000011111111000000 +0011111110000000001110000000000000000000000000 \ No newline at end of file diff --git a/examples/stm32_f4ve/gui/images/warning.pbm b/examples/stm32_f4ve/gui/images/warning.pbm new file mode 100644 index 0000000000..e2d772ebc4 --- /dev/null +++ b/examples/stm32_f4ve/gui/images/warning.pbm @@ -0,0 +1,62 @@ +P1 +# CREATOR: GIMP PNM Filter Version 1.1 +64 64 +0000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000000000 +0000000000011111100000000000000000000000000000000000000000000000000000 +0001111111111000000000000000000000000000000000000000000000000000001111 +1111111100000000000000000000000000000000000000000000000000011110000001 +1110000000000000000000000000000000000000000000000000011100000000111000 +0000000000000000000000000000000000000000000000111000000000011100000000 +0000000000000000000000000000000000000000111000000000011100000000000000 +0000000000000000000000000000000001110000000000001110000000000000000000 +0000000000000000000000000001110000000000001110000000000000000000000000 +0000000000000000000011100000000000000111000000000000000000000000000000 +0000000000000011100000000000000111000000000000000000000000000000000000 +0000000111000000000000000011100000000000000000000000000000000000000000 +0111000000000000000011100000000000000000000000000000000000000000111000 +0000111100000001110000000000000000000000000000000000000000111000000111 +1110000001110000000000000000000000000000000000000001110000001100111100 +0000111000000000000000000000000000000000000001110000011011111110000011 +1000000000000000000000000000000000000011100000011011111110000001110000 +0000000000000000000000000000000011100000011011111110000001110000000000 +0000000000000000000000000111000000011011111110000000111000000000000000 +0000000000000000000111000000011011111110000000111000000000000000000000 +0000000000001110000000011011111110000000011100000000000000000000000000 +0000001110000000011011111110000000011100000000000000000000000000000001 +1100000000011011111110000000001110000000000000000000000000000001110000 +0000011011111110000000001110000000000000000000000000000011100000000001 +1011111110000000000111000000000000000000000000000011100000000001101111 +1110000000000111000000000000000000000000000111000000000001101111111000 +0000000011100000000000000000000000000111000000000001101111111000000000 +0011100000000000000000000000001110000000000001101111111000000000000111 +0000000000000000000000001110000000000001101111111000000000000111000000 +0000000000000000011100000000000001101111111000000000000011100000000000 +0000000000011100000000000001101111111000000000000011100000000000000000 +0000111000000000000001111111111000000000000001110000000000000000000011 +1000000000000000111111110000000000000001110000000000000000000111000000 +0000000000011111100000000000000000111000000000000000000111000000000000 +0000001111000000000000000000111000000000000000001110000000000000000000 +0000000000000000000000011100000000000000001110000000000000000000000000 +0000000000000000011100000000000000011100000000000000000000000000000000 +0000000000001110000000000000011100000000000000000000000000000000000000 +0000001110000000000000111000000000000000000000111100000000000000000000 +0111000000000000111000000000000000000011111111000000000000000000011100 +0000000001110000000000000000000111000111100000000000000000001110000000 +0001110000000000000000000110111111100000000000000000001110000000001110 +0000000000000000001101111111110000000000000000000111000000001110000000 +0000000000001101111111110000000000000000000111000000011110000000000000 +0000001101111111110000000000000000000111100000011100000000000000000000 +1111111111110000000000000000000011100000011100000000000000000000011111 +1111100000000000000000000011100000011100000000000000000000011111111110 +0000000000000000000011100000011100000000000000000000001111111100000000 +0000000000000011100000011110000000000000000000000011110000000000000000 +0000000111100000001110000000000000000000000000000000000000000000000000 +0111000000001111000000000000000000000000000000000000000000000000111100 +0000000111110000000000000000000000000000000000000000000011111000000000 +0011111111111111111111111111111111111111111111111111110000000000000111 +1111111111111111111111111111111111111111111111100000000000000001111111 +1111111111111111111111111111111111111110000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000 \ No newline at end of file diff --git a/examples/stm32_f4ve/gui/images/warning_32x32.pbm b/examples/stm32_f4ve/gui/images/warning_32x32.pbm new file mode 100644 index 0000000000..8779c7d69d --- /dev/null +++ b/examples/stm32_f4ve/gui/images/warning_32x32.pbm @@ -0,0 +1,18 @@ +P1 +# CREATOR: GIMP PNM Filter Version 1.1 +32 32 +0000000000000000000000000000000000000000000000111100000000000000000000 +0000000111111000000000000000000000000011100111000000000000000000000000 +1100001100000000000000000000000110000001100000000000000000000001100000 +0110000000000000000000001100000000110000000000000000000011000110001100 +0000000000000000011000101100011000000000000000000110001111000110000000 +0000000000110000111100001100000000000000001100001111000011000000000000 +0001100000111100000110000000000000011000001111000001100000000000001100 +0000111100000011000000000000110000001111000000110000000000011000000011 +1100000001100000000001100000001111000000011000000000110000000001100000 +0000110000000011000000000000000000001100000001100000000000000000000001 +1000000110000000000110000000000110000011000000000010110000000000110000 +1100000000010111100000000011000110000000000111111000000000011001100000 +0000001111000000000001100110000000000001100000000000011001110000000000 +0000000000000011100011111111111111111111111111110000011111111111111111 +11111111100000000000000000000000000000000000 \ No newline at end of file diff --git a/examples/stm32_f4ve/gui/main.cpp b/examples/stm32_f4ve/gui/main.cpp new file mode 100644 index 0000000000..f0e9a1c09a --- /dev/null +++ b/examples/stm32_f4ve/gui/main.cpp @@ -0,0 +1,506 @@ +/* + * Copyright (c) 2011, Georgi Grinshpun + * Copyright (c) 2011-2013, Fabian Greif + * Copyright (c) 2012-2014, 2017, Sascha Schade + * Copyright (c) 2013, Kevin Läufer + * Copyright (c) 2013-2014, Daniel Krebs + * Copyright (c) 2013-2018, Niklas Hauser + * Copyright (c) 2020, Pavel Pletenev + * + * This file is part of the modm project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +// ---------------------------------------------------------------------------- + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "touchscreen_calibrator.hpp" + +#include "images/bluetooth_12x16.hpp" + + + +// ---------------------------------------------------------------------------- +/* + * Setup UART Logger + */ + +// Set the log level +#undef MODM_LOG_LEVEL +#define MODM_LOG_LEVEL modm::log::DEBUG + +// ---------------------------------------------------------------------------- + +/* FSMC + * + * * Use A18 as Command / Data pin + * 0x60000000 is the base address for FSMC's first memory bank. + * When accessing 0x60000000 A16 is low. + * + * But the TftMemoryBus16Bit uses the FSMC in 16 bit mode. + * Then, according to Table 184 (External memory address) of + * reference manual (p1317) address HADDR[25:1] >> 1 are issued to + * the address pins A24:A0. + * So when writing to offset +((1 << 18) << 1) pin A16 is high. + */ +constexpr std::uintptr_t offset = 0x60000000; +constexpr std::uintptr_t offsetCmd = offset + ((1 << 18) << 1); +modm::TftMemoryBus16Bit parallelBus( + (volatile uint16_t *) offset, + (volatile uint16_t *) offsetCmd); + +using Display = modm::Ili9341Parallel< + modm::TftMemoryBus16Bit, Board::display::Reset, Board::display::Backlight>; +Display tft(parallelBus); + +// ---------------------------------------------------------------------------- + +constexpr uint8_t TP_TOLERANCE = 30; // in pixels +constexpr uint16_t TOUCH_REPEAT_RATE = 600; // in ms, 0 to disable + + +modm::gui::inputQueue input_queue; +modm::gui::AsyncEventList async_events; +modm::glcd::Point last_point; + +// ---------------------------------------------------------------------------- +// Touchscreen + +typedef GpioOutputC4 CsTouchscreen; +typedef GpioInputC5 IntTouchscreen; + +modm::Ads7843 ads7843; +modm::TouchscreenCalibrator touchscreen; + +typedef GpioOutputD7 CS; + + + + +static void +initDisplay() +{ + MODM_LOG_DEBUG << __PRETTY_FUNCTION__ << modm::endl; + Fsmc::initialize(); + GpioConnector::connect(); + + + CS::setOutput(); + CS::reset(); + + fsmc::NorSram::AsynchronousTiming timing = { + // read + 15, 0, 15, + // write + 15, 0, 15, + // bus turn around + 15 + }; + + fsmc::NorSram::configureAsynchronousRegion( + fsmc::NorSram::CHIP_SELECT_1, + fsmc::NorSram::NO_MULTIPLEX_16BIT, + fsmc::NorSram::SRAM_ROM, + fsmc::NorSram::MODE_A, + timing); + + fsmc::NorSram::enableRegion(fsmc::NorSram::CHIP_SELECT_1); + + + tft.initialize(); + tft.enableBacklight(true); + tft.setRotation(Display::Rotation::Rotate90); +} + + + +static void +initTouchscreen() +{ + MODM_LOG_DEBUG << __PRETTY_FUNCTION__ << modm::endl; + CsTouchscreen::setOutput(); + CsTouchscreen::set(); + + IntTouchscreen::setInput(Gpio::InputType::PullUp); + using namespace Board::display::touch; + + SpiMaster2::connect(); + SpiMaster2::initialize(); + SpiMaster2::setDataMode(SpiMaster2::DataMode::Mode0); + +} + +// ---------------------------------------------------------------------------- +/* screen calibration */ +static void +drawCross(modm::GraphicDisplay& display, modm::glcd::Point center) +{ + display.setColor(modm::glcd::Color::red()); + display.drawLine(center.x - 15, center.y, center.x - 2, center.y); + display.drawLine(center.x + 2, center.y, center.x + 15, center.y); + display.drawLine(center.x, center.y - 15, center.x, center.y - 2); + display.drawLine(center.x, center.y + 2, center.x, center.y + 15); + + display.setColor(modm::glcd::Color::white()); + display.drawLine(center.x - 15, center.y + 15, center.x - 7, center.y + 15); + display.drawLine(center.x - 15, center.y + 7, center.x - 15, center.y + 15); + + display.drawLine(center.x - 15, center.y - 15, center.x - 7, center.y - 15); + display.drawLine(center.x - 15, center.y - 7, center.x - 15, center.y - 15); + + display.drawLine(center.x + 7, center.y + 15, center.x + 15, center.y + 15); + display.drawLine(center.x + 15, center.y + 7, center.x + 15, center.y + 15); + + display.drawLine(center.x + 7, center.y - 15, center.x + 15, center.y - 15); + display.drawLine(center.x + 15, center.y - 15, center.x + 15, center.y - 7); +} + +static void +calibrateTouchscreen(modm::GraphicDisplay& display, modm::glcd::Point *fixed_samples = NULL) +{ + MODM_LOG_DEBUG << __PRETTY_FUNCTION__ << modm::endl; + modm::glcd::Point calibrationPoint[3] = { { 45, 45 }, { 270, 90 }, { 100, 190 } }; + modm::glcd::Point sample[3]; + + if(!fixed_samples) { + for (uint8_t i = 0; i < 3; i++) + { + display.clear(); + + display.setColor(modm::glcd::Color::yellow()); + display.setCursor(50, 5); + display << "Touch crosshair to calibrate"; + + drawCross(display, calibrationPoint[i]); + modm::delay(500ms); + + while (!ads7843.read(&sample[i])) { + // wait until a valid sample can be taken + } + + MODM_LOG_DEBUG << "calibration point: (" << sample[i].x << " | " << sample[i].y << ")" << modm::endl; + } + + touchscreen.calibrate(calibrationPoint, sample); + + } else { + touchscreen.calibrate(calibrationPoint, fixed_samples); + } + + display.clear(); +} + +void +drawPoint(modm::GraphicDisplay& display, modm::glcd::Point point) +{ + MODM_LOG_DEBUG << __PRETTY_FUNCTION__ << modm::endl; + if (point.x < 0 || point.y < 0) { + return; + } + + display.drawPixel(point.x, point.y); + display.drawPixel(point.x + 1, point.y); + display.drawPixel(point.x, point.y + 1); + display.drawPixel(point.x + 1, point.y + 1); +} + +// ---------------------------------------------------------------------------- +/* catch touch input */ +bool +touchActive() +{ + /* + * XPT2046: + * + * !PENIRQ when not touched: + * _____ _ __________ _ _______ + * \_/ \_/ \_/ \_/ + * |<----->| + * ~120us + * + * !PENIRQ when touched: + * + * _____|____|______|__|_|_____|___ + * + * random ~100ns peaks + * + */ + + bool m1, m2; + + m1 = !IntTouchscreen::read(); + modm::delay(130us); + m2 = !IntTouchscreen::read(); + + return (m1 || m2); +} + +void +resetTouchLock(void* /* data */) +{ + last_point = modm::glcd::Point(-400, -400); +} + +bool +debounceTouch(modm::glcd::Point *out, modm::glcd::Point *old) +{ + modm::glcd::Point raw, point; + + if(touchActive()) { + + if (ads7843.read(&raw)) { + + // translate point according to calibration + touchscreen.translate(&raw, &point); + + if(abs(point.x - old->x) < TP_TOLERANCE && + abs(point.y - old->y) < TP_TOLERANCE + ) + { + // point is within area of last touch + *old = point; + return false; + } + + // new touch point + *old = point; + *out = point; + + // schedule a reset for debounce lock, so that holding the finger fires repeated touch events + if(TOUCH_REPEAT_RATE) + { + async_events.append(new modm::gui::AsyncEvent(TOUCH_REPEAT_RATE, &resetTouchLock, NULL)); + } + + return true; + } + } else { + // reset old point so that when touched again you can touch the same spot + *old = modm::glcd::Point(-400, -400); + } + return false; +} + +void +touchUp(void* data) +{ + MODM_LOG_DEBUG << __PRETTY_FUNCTION__ << modm::endl; + modm::gui::InputEvent* ev = static_cast(data); + + MODM_LOG_DEBUG << "asynchronous UP-event:" << modm::endl; + MODM_LOG_DEBUG << "x: " << ev->coord.x << modm::endl; + MODM_LOG_DEBUG << "y: " << ev->coord.y << modm::endl; + + // queue UP-event as new input event + input_queue.push(ev); +} + + +void +gatherInput() +{ + modm::glcd::Point point; + + if (debounceTouch(&point, &last_point)) { + + auto ev_down = new modm::gui::InputEvent(point, + modm::gui::InputEvent::Type::TOUCH, + modm::gui::InputEvent::Direction::DOWN); + + auto ev_up = new modm::gui::InputEvent( point, + modm::gui::InputEvent::Type::TOUCH, + modm::gui::InputEvent::Direction::UP); + + // queue down event + input_queue.push(ev_down); + + // create an asynchronous event with Direction::UP and 200ms delay + auto async_ev = new modm::gui::AsyncEvent(500, &touchUp, (void*)(ev_up)); + async_events.append(async_ev); + + MODM_LOG_DEBUG << "touch down x: " << point.x << modm::endl; + MODM_LOG_DEBUG << "touch down y: " << point.y << modm::endl; + + } +} + +inline void +updateAsyncEvents() +{ + auto iter = async_events.begin(); + + while(iter != async_events.end()) + { + if((*iter)->is_expired()) { + iter = async_events.erase(iter); + } else + { + ++iter; + } + } +} + + +// ---------------------------------------------------------------------------- + +void +test_callback(const modm::gui::InputEvent& ev, modm::gui::Widget* w, void* data) +{ + // avoid warnings + (void) ev; + (void) w; + (void) data; + + Board::LedGreen2::toggle(); +} + + +modm::glcd::Color colors[modm::gui::Color::PALETTE_SIZE] { + modm::glcd::Color::black(), + modm::glcd::Color::white(), + modm::glcd::Color::gray(), + modm::glcd::Color::red(), + modm::glcd::Color::green(), + modm::glcd::Color::blue(), + modm::glcd::Color::blue(), // BORDER + modm::glcd::Color::red(), // TEXT + modm::glcd::Color::black(), // BACKGROUND + modm::glcd::Color::red(), // ACTIVATED + modm::glcd::Color::blue(), // DEACTIVATED + +}; +modm::gui::ColorPalette colorpalette{colors}; +/* + * empirically found calibration points + */ +// modm::glcd::Point calibration[] = {{3339, 3046},{931, 2428},{2740, 982}}; +modm::glcd::Point* calibration = nullptr; +// ---------------------------------------------------------------------------- + +class MyView : public modm::gui::View{ +public: + MyView(modm::gui::GuiViewStack* stack, uint8_t identifier, modm::gui::Dimension dimension) + : View(stack, identifier, dimension){ + + } + ~MyView() override{} +protected: + virtual bool hasChanged() override { + return true; + } +}; + +int +main() +{ + + Board::initialize(); + + + MODM_LOG_DEBUG << "Hello from modm gui example!" << modm::endl; + + initDisplay(); + initTouchscreen(); + + /* + * calibrate touchscreen with already found calibration points + */ + + calibrateTouchscreen(tft, calibration); + + + /* + * manipulate the color palette + */ + + colorpalette.setColor(modm::gui::Color::TEXT, modm::glcd::Color::yellow()); + + + /* + * Create a view and some widgets + */ + modm::gui::GuiViewStack stack(&tft, &input_queue); + MyView myView(&stack, 1, modm::gui::Dimension(320, 240)); + + modm::gui::ButtonWidget toggleLedButton((char*)"Toggle Green", modm::gui::Dimension(100, 50)); + modm::gui::ButtonWidget doNothingButton((char*)"Do nothing", modm::gui::Dimension(100, 50)); + + modm::gui::IntegerRocker rocker1(100, 50, modm::gui::Dimension(200, 30)); + + + /* + * connect callbacks to widgets + */ + + toggleLedButton.cb_activate = &test_callback; + + + /* + * place widgets in view + */ + + myView.pack(&toggleLedButton, modm::glcd::Point(110, 10)); + myView.pack(&doNothingButton, modm::glcd::Point(110, 80)); + myView.pack(&rocker1, modm::glcd::Point(60, 200)); + stack.push(&myView); + + // modm::glcd::Point pixPos(10, 200); + // modm::glcd::Point pixDeltaPos(1, 1); + // auto pix = modm::accessor::asFlash(bitmap::bluetooth_12x16); + while(true) { + + gatherInput(); + + // process asynchronous events + updateAsyncEvents(); + + // update view + stack.update(); + + + /* + * display an arbitrary image + */ + // if(pixPos.x < 0 || (pixPos.x + pix[0]) > tft.getWidth()){ + // pixDeltaPos.x *= -1; + // } + // if(pixPos.y < 0 || (pixPos.y + pix[1]) > tft.getHeight()){ + // pixDeltaPos.y *= -1; + // } + // pixPos += pixDeltaPos; + // tft.drawImage(pixPos, pix); + } + + return 0; +} diff --git a/examples/stm32_f4ve/gui/project.xml b/examples/stm32_f4ve/gui/project.xml new file mode 100644 index 0000000000..eff4dfff36 --- /dev/null +++ b/examples/stm32_f4ve/gui/project.xml @@ -0,0 +1,22 @@ + + modm:stm32_f4ve + + + + + + modm:container + modm:debug + modm:driver:ads7843 + modm:driver:ili9341 + modm:driver:memory_bus + modm:platform:fsmc + modm:platform:spi:2 + modm:platform:uart:2 + modm:platform:heap + modm:ui:display + modm:ui:gui + modm:utils + modm:build:scons + + diff --git a/examples/stm32_f4ve/gui/touchscreen_calibrator.hpp b/examples/stm32_f4ve/gui/touchscreen_calibrator.hpp new file mode 100644 index 0000000000..9fe858941a --- /dev/null +++ b/examples/stm32_f4ve/gui/touchscreen_calibrator.hpp @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2009, Martin Rosekeit + * Copyright (c) 2009-2010, 2012-2013, Fabian Greif + * Copyright (c) 2012, Niklas Hauser + * Copyright (c) 2012, Sascha Schade + * Copyright (c) 2014, Daniel Krebs + * + * This file is part of the modm project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +// ---------------------------------------------------------------------------- + +#ifndef MODM_TOUCHSCREEN_CALIBRATOR_HPP +#define MODM_TOUCHSCREEN_CALIBRATOR_HPP + +namespace modm +{ + class TouchscreenCalibrator + { + public: + TouchscreenCalibrator(); + + bool + calibrate(modm::glcd::Point * display, modm::glcd::Point * sample); + + void + translate(modm::glcd::Point * raw, modm::glcd::Point * translated); + + private: + float An; + float Bn; + float Cn; + float Dn; + float En; + float Fn; + float scale; + }; +} + +#endif // MODM_TOUCHSCREEN_CALIBRATOR_HPP + +#ifndef MODM_TOUCHSCREEN_CALIBRATOR_HPP +# error "Don't include this file directly, use touchscreen_calibrator.hpp instead!" +#endif + +modm::TouchscreenCalibrator::TouchscreenCalibrator() : + scale(0.f) +{ +} + +bool +modm::TouchscreenCalibrator::calibrate( + modm::glcd::Point * display, modm::glcd::Point * sample) +{ + // K��(X0��X2) (Y1��Y2)��(X1��X2) (Y0��Y2) + scale = ((sample[0].x - sample[2].x) * (sample[1].y - sample[2].y)) - + ((sample[1].x - sample[2].x) * (sample[0].y - sample[2].y)); + + if (scale == 0) { + return false; + } + + // A��((XD0��XD2) (Y1��Y2)��(XD1��XD2) (Y0��Y2))��K + An = ((display[0].x - display[2].x) * (sample[1].y - sample[2].y)) - + ((display[1].x - display[2].x) * (sample[0].y - sample[2].y)); + // B��((X0��X2) (XD1��XD2)��(XD0��XD2) (X1��X2))��K */ + Bn = ((sample[0].x - sample[2].x) * (display[1].x - display[2].x)) - + ((display[0].x - display[2].x) * (sample[1].x - sample[2].x)); + // C��(Y0(X2XD1��X1XD2)+Y1(X0XD2��X2XD0)+Y2(X1XD0��X0XD1))��K */ + Cn = (sample[2].x * display[1].x - sample[1].x * display[2].x) * sample[0].y + + (sample[0].x * display[2].x - sample[2].x * display[0].x) * sample[1].y + + (sample[1].x * display[0].x - sample[0].x * display[1].x) * sample[2].y; + + // D��((YD0��YD2) (Y1��Y2)��(YD1��YD2) (Y0��Y2))��K */ + Dn = ((display[0].y - display[2].y) * (sample[1].y - sample[2].y)) - + ((display[1].y - display[2].y) * (sample[0].y - sample[2].y)); + // E��((X0��X2) (YD1��YD2)��(YD0��YD2) (X1��X2))��K */ + En = ((sample[0].x - sample[2].x) * (display[1].y - display[2].y)) - + ((display[0].y - display[2].y) * (sample[1].x - sample[2].x)); + // F��(Y0(X2YD1��X1YD2)+Y1(X0YD2��X2YD0)+Y2(X1YD0��X0YD1))��K */ + Fn = (sample[2].x * display[1].y - sample[1].x * display[2].y) * sample[0].y + + (sample[0].x * display[2].y - sample[2].x * display[0].y) * sample[1].y + + (sample[1].x * display[0].y - sample[0].x * display[1].y) * sample[2].y; + + return true; +} + +void +modm::TouchscreenCalibrator::translate(modm::glcd::Point * raw, modm::glcd::Point * translated) +{ + if (scale != 0) + { + /* XD = AX+BY+C */ + translated->x = + ((An * raw->x) + + (Bn * raw->y) + Cn) / scale; + /* YD = DX+EY+F */ + translated->y = + ((Dn * raw->x) + + (En * raw->y) + Fn) / scale; + } +}