diff --git a/examples/nucleo_f042k6/spi_dma/main.cpp b/examples/nucleo_f042k6/spi_dma/main.cpp index 611068fe38..bfbd24f662 100644 --- a/examples/nucleo_f042k6/spi_dma/main.cpp +++ b/examples/nucleo_f042k6/spi_dma/main.cpp @@ -33,7 +33,7 @@ int main() uint8_t receiveBuffer[13]; // send out 12 bytes, don't care about response - Spi::transferBlocking(sendBuffer, nullptr, 12); + Spi::transferBlocking(sendBuffer, (uint8_t*)(nullptr), 12); // send out 12 bytes, read in 12 bytes Spi::transferBlocking(sendBuffer, receiveBuffer, 12); diff --git a/examples/nucleo_f303re/spi_dma/main.cpp b/examples/nucleo_f303re/spi_dma/main.cpp index 5e60bf438f..b300c9c6ae 100644 --- a/examples/nucleo_f303re/spi_dma/main.cpp +++ b/examples/nucleo_f303re/spi_dma/main.cpp @@ -33,7 +33,7 @@ int main() uint8_t receiveBuffer[13]; // send out 12 bytes, don't care about response - Spi::transferBlocking(sendBuffer, nullptr, 12); + Spi::transferBlocking(sendBuffer, (uint8_t*)(nullptr), 12); // send out 12 bytes, read in 12 bytes Spi::transferBlocking(sendBuffer, receiveBuffer, 12); diff --git a/examples/nucleo_l432kc/spi_dma/main.cpp b/examples/nucleo_l432kc/spi_dma/main.cpp index 3c5b45d0f1..754459e269 100644 --- a/examples/nucleo_l432kc/spi_dma/main.cpp +++ b/examples/nucleo_l432kc/spi_dma/main.cpp @@ -34,7 +34,7 @@ int main() uint8_t receiveBuffer[13]; // send out 12 bytes, don't care about response - Spi::transferBlocking(sendBuffer, nullptr, 12); + Spi::transferBlocking(sendBuffer, (uint8_t*)(nullptr), 12); // send out 12 bytes, read in 12 bytes Spi::transferBlocking(sendBuffer, receiveBuffer, 12); diff --git a/examples/nucleo_l452re/graphics_touch/main.cpp b/examples/nucleo_l452re/graphics_touch/main.cpp index f71ed9b5d5..d59206d16a 100644 --- a/examples/nucleo_l452re/graphics_touch/main.cpp +++ b/examples/nucleo_l452re/graphics_touch/main.cpp @@ -51,7 +51,7 @@ namespace touch //using Interrupt = modm::platform::GpioA10; } -modm::Touch2046 touchController; +modm::Touch2046 touchController; int @@ -75,12 +75,10 @@ main() touch::Mosi::Mosi>(); touch::Spi::initialize(); modm::touch2046::Calibration cal{ - .OffsetX = -11, - .OffsetY = 335, .FactorX = 22018, + .OffsetX = -11, .FactorY = -29358, - .MaxX = 240, - .MaxY = 320, + .OffsetY = 335, .ThresholdZ = 500, }; touchController.setCalibration(cal); @@ -107,13 +105,13 @@ main() int16_t X = 0; int16_t Y = 0; - int16_t Z = 0; + // int16_t Z = 0; while (true) { LedGreen::set(); - std::tie(X, Y, Z) = RF_CALL_BLOCKING(touchController.getRawValues()); + std::tie(X, Y) = RF_CALL_BLOCKING(touchController.getTouchPosition()); tftController.setColor(Red); tftController.fillRectangle({30, 50}, 90, 115); tftController.setColor(Black); @@ -121,8 +119,8 @@ main() tftController << "X=" << X; tftController.setCursor(0, 90); tftController << "Y=" << Y; - tftController.setCursor(0, 130); - tftController << "Z=" << Z; + // tftController.setCursor(0, 130); + // tftController << "Z=" << Z; tftController.setColor(Red); tftController.fillRectangle({30, 220}, 120, 35); diff --git a/examples/nucleo_l452re/lvgl/main.cpp b/examples/nucleo_l452re/lvgl/main.cpp index 84e430b86b..8aec17dd5a 100644 --- a/examples/nucleo_l452re/lvgl/main.cpp +++ b/examples/nucleo_l452re/lvgl/main.cpp @@ -59,7 +59,7 @@ namespace touch //using Interrupt = modm::platform::GpioA10; } -modm::Touch2046 touchController; +modm::Touch2046 touchController; static lv_disp_draw_buf_t disp_buf; diff --git a/src/modm/architecture/interface/accessor_flash.hpp b/src/modm/architecture/interface/accessor_flash.hpp index 38bfe8642e..470c6a2672 100644 --- a/src/modm/architecture/interface/accessor_flash.hpp +++ b/src/modm/architecture/interface/accessor_flash.hpp @@ -162,7 +162,7 @@ class Flash return address; } -private: +protected: const T* address; #if MODM_HAS_IOSTREAM private: diff --git a/src/modm/architecture/interface/accessor_ram.hpp b/src/modm/architecture/interface/accessor_ram.hpp index 897ca61785..980a5d1674 100644 --- a/src/modm/architecture/interface/accessor_ram.hpp +++ b/src/modm/architecture/interface/accessor_ram.hpp @@ -117,7 +117,7 @@ class Ram return address; } -private: +protected: const T* address; }; diff --git a/src/modm/architecture/interface/spi_master.hpp b/src/modm/architecture/interface/spi_master.hpp index 0bcbe52ccc..0626bf0b36 100644 --- a/src/modm/architecture/interface/spi_master.hpp +++ b/src/modm/architecture/interface/spi_master.hpp @@ -3,6 +3,7 @@ * Copyright (c) 2010, Martin Rosekeit * Copyright (c) 2012-2017, Niklas Hauser * Copyright (c) 2013, Sascha Schade + * Copyright (c) 2021, Thomas Sommer * * This file is part of the modm project. * @@ -96,14 +97,28 @@ class SpiMaster : public ::modm::PeripheralDriver, public Spi release(void *ctx); /** - * Swap a single byte and wait for completion. + * Swap a single byte or word or word and wait for completion. * * @param data * data to be sent * @return received data */ - static uint8_t - transferBlocking(uint8_t data); + template + static T + transferBlocking(T data); + + /** + * Swap a single byte or word or word multiple times and wait for completion non-blocking! + * This may be hardware accelerated (DMA or Interrupt), but not guaranteed. + * + * @param[in] tx + * pointer to transmit data + * @param repeat + * number of repetitions for same byte or word or word + */ + template + static modm::ResumableResult + transfer(const T *tx, const std::size_t repeat); /** * Set the data buffers and length with options and starts a transfer. @@ -116,11 +131,12 @@ class SpiMaster : public ::modm::PeripheralDriver, public Spi * @param length * number of bytes to be shifted out */ + template static void - transferBlocking(const uint8_t *tx, uint8_t *rx, std::size_t length); + transferBlocking(const T *tx, T *rx, const std::size_t length); /** - * Swap a single byte and wait for completion non-blocking!. + * Swap a single byte or word and wait for completion non-blocking! * * You must call this inside a Protothread or Resumable * using `PT_CALL` or `RF_CALL` respectively. @@ -132,8 +148,28 @@ class SpiMaster : public ::modm::PeripheralDriver, public Spi * data to be sent * @return received data */ - static modm::ResumableResult - transfer(uint8_t data); + template + static modm::ResumableResult + transfer(T data); + + /** + * Swap a single byte or word multiple times and wait for completion non-blocking! + * This may be hardware accelerated (DMA or Interrupt), but not guaranteed. + * + * You must call this inside a Protothread or Resumable + * using `PT_CALL` or `RF_CALL` respectively. + * @warning These methods differ from Resumables by lacking context protection! + * You must ensure that only one driver is accessing this resumable function + * by using `acquire(ctx)` and `release(ctx)`. + * + * @param[in] tx + * pointer to transmit data + * @param repeat + * number of repetitions for same byte or word + */ + template + static modm::ResumableResult + transfer(const T *tx, const std::size_t repeat); /** * Set the data buffers and length with options and @@ -153,8 +189,9 @@ class SpiMaster : public ::modm::PeripheralDriver, public Spi * @param length * number of bytes to be shifted out */ + template static modm::ResumableResult - transfer(const uint8_t *tx, uint8_t *rx, std::size_t length); + transfer(const T *tx, T *rx, const std::size_t length); #endif }; diff --git a/src/modm/driver/can/mcp2515_impl.hpp b/src/modm/driver/can/mcp2515_impl.hpp index 9b705897b5..32673f18b3 100644 --- a/src/modm/driver/can/mcp2515_impl.hpp +++ b/src/modm/driver/can/mcp2515_impl.hpp @@ -70,7 +70,7 @@ modm::Mcp2515::initializeWithPrescaler( // software reset for the mcp2515, after this the chip is back in the // configuration mode chipSelect.reset(); - spi.transferBlocking(RESET); + spi.transferBlocking(uint8_t(RESET)); modm::delay_ms(1); chipSelect.set(); @@ -78,14 +78,14 @@ modm::Mcp2515::initializeWithPrescaler( modm::delay_ms(30); chipSelect.reset(); - spi.transferBlocking(WRITE); - spi.transferBlocking(CNF3); + spi.transferBlocking(uint8_t(WRITE)); + spi.transferBlocking(uint8_t(CNF3)); // load CNF1..3 - spi.transferBlocking(cnf, nullptr, 3); + spi.transferBlocking(cnf, (uint8_t*)(nullptr), 3); // enable interrupts - spi.transferBlocking(RX1IE | RX0IE); + spi.transferBlocking(uint8_t(RX1IE | RX0IE)); chipSelect.set(); // set TXnRTS pins as inwrites @@ -146,7 +146,7 @@ modm::Mcp2515::setFilter(accessor::Flash filter) for (i = 0; i < 0x30; i += 0x10) { chipSelect.reset(); - spi.transferBlocking(WRITE); + spi.transferBlocking(uint8_t(WRITE)); spi.transferBlocking(i); for (j = 0; j < 12; j++) @@ -222,10 +222,10 @@ modm::Mcp2515::getMessage(can::Message& message) else { message.flags.rtr = false; } - message.length = spi.transferBlocking(0xff) & 0x0f; + message.length = spi.transferBlocking(uint8_t(0xff)) & 0x0f; for (uint8_t i = 0; i < message.length; ++i) { - message.data[i] = spi.transferBlocking(0xff); + message.data[i] = spi.transferBlocking(uint8_t(0xff)); } chipSelect.set(); @@ -279,12 +279,12 @@ modm::Mcp2515::sendMessage(const can::Message& message) } chipSelect.reset(); - spi.transferBlocking(WRITE_TX | address); + spi.transferBlocking(uint8_t(WRITE_TX | address)); writeIdentifier(message.identifier, message.flags.extended); // if the message is a rtr-frame, is has a length but no attached data if (message.flags.rtr) { - spi.transferBlocking(MCP2515_RTR | message.length); + spi.transferBlocking(uint8_t(MCP2515_RTR | message.length)); } else { spi.transferBlocking(message.length); @@ -300,7 +300,7 @@ modm::Mcp2515::sendMessage(const can::Message& message) // send message via RTS command chipSelect.reset(); address = (address == 0) ? 1 : address; // 0 2 4 => 1 2 4 - spi.transferBlocking(RTS | address); + spi.transferBlocking(uint8_t(RTS | address)); chipSelect.set(); return address; @@ -314,7 +314,7 @@ modm::Mcp2515::writeRegister(uint8_t address, uint8_t data) { chipSelect.reset(); - spi.transferBlocking(WRITE); + spi.transferBlocking(uint8_t(WRITE)); spi.transferBlocking(address); spi.transferBlocking(data); @@ -327,9 +327,9 @@ modm::Mcp2515::readRegister(uint8_t address) { chipSelect.reset(); - spi.transferBlocking(READ); + spi.transferBlocking(uint8_t(READ)); spi.transferBlocking(address); - uint8_t data = spi.transferBlocking(0xff); + uint8_t data = spi.transferBlocking(uint8_t(0xff)); chipSelect.set(); @@ -342,7 +342,7 @@ modm::Mcp2515::bitModify(uint8_t address, uint8_t mask, uint8_t da { chipSelect.reset(); - spi.transferBlocking(BIT_MODIFY); + spi.transferBlocking(uint8_t(BIT_MODIFY)); spi.transferBlocking(address); spi.transferBlocking(mask); spi.transferBlocking(data); @@ -357,7 +357,7 @@ modm::Mcp2515::readStatus(uint8_t type) chipSelect.reset(); spi.transferBlocking(type); - uint8_t data = spi.transferBlocking(0xff); + uint8_t data = spi.transferBlocking(uint8_t(0xff)); chipSelect.set(); @@ -391,10 +391,11 @@ modm::Mcp2515::writeIdentifier(const uint32_t& identifier, } else { - spi.transferBlocking(*((uint16_t *) ptr) >> 3); - spi.transferBlocking(*((uint8_t *) ptr) << 5); - spi.transferBlocking(0); - spi.transferBlocking(0); + spi.transferBlocking(uint8_t(*((uint16_t *) ptr) >> 3)); + spi.transferBlocking(uint8_t(*((uint8_t *) ptr) << 5)); + + spi.transferBlocking(uint8_t(0)); + spi.transferBlocking(uint8_t(0)); } } @@ -406,31 +407,31 @@ modm::Mcp2515::readIdentifier(uint32_t& identifier) uint32_t *ptr = &identifier; - uint8_t first = spi.transferBlocking(0xff); - uint8_t second = spi.transferBlocking(0xff); + uint8_t first = spi.transferBlocking(uint8_t(0xff)); + uint8_t second = spi.transferBlocking(uint8_t(0xff)); if (second & MCP2515_IDE) { *((uint16_t *) ptr + 1) = (uint16_t) first << 5; - *((uint8_t *) ptr + 1) = spi.transferBlocking(0xff); + *((uint8_t *) ptr + 1) = spi.transferBlocking(uint8_t(0xff)); *((uint8_t *) ptr + 2) |= (second >> 3) & 0x1C; *((uint8_t *) ptr + 2) |= second & 0x03; - *((uint8_t *) ptr) = spi.transferBlocking(0xff); + *((uint8_t *) ptr) = spi.transferBlocking(uint8_t(0xff)); return true; } else { - spi.transferBlocking(0xff); + spi.transferBlocking(uint8_t(0xff)); *((uint8_t *) ptr + 3) = 0; *((uint8_t *) ptr + 2) = 0; *((uint16_t *) ptr) = (uint16_t) first << 3; - spi.transferBlocking(0xff); + spi.transferBlocking(uint8_t(0xff)); *((uint8_t *) ptr) |= second >> 5; diff --git a/src/modm/driver/display/ili9341.hpp b/src/modm/driver/display/ili9341.hpp index b5cbc2e4de..f16f9dfc20 100644 --- a/src/modm/driver/display/ili9341.hpp +++ b/src/modm/driver/display/ili9341.hpp @@ -1,5 +1,6 @@ /* * Copyright (c) 2019, Mike Wolfram + * Copyright (c) 2021, Thomas Sommer * * This file is part of the modm project. * @@ -11,297 +12,174 @@ #ifndef MODM_ILI9341_HPP #define MODM_ILI9341_HPP +#include + #include #include -#include -#include -#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "ili9341_interface_parallel.hpp" +#include "ili9341_interface_spi.hpp" namespace modm { /// @ingroup modm_driver_ili9341 -struct ili9341 -{ -protected: - /// @cond - enum class - Command : uint8_t - { - // common commands - Nop = 0x00, - SwReset = 0x01, - ReadID = 0x04, - ReadStatus = 0x09, - ReadPowerMode = 0x0a, - ReadMemoryAccessCtrl = 0x0b, - ReadPixelFormat = 0x0c, - ReadImageFormat = 0x0d, - ReadSignalMode = 0x0e, - ReadSelfDiagnostic = 0x0f, - EnterSleep = 0x10, - LeaveSleep = 0x11, - PartialMode = 0x12, - NormalMode = 0x13, - InversionOff = 0x20, - InversionOn = 0x21, - GammaSet = 0x26, - DisplayOff = 0x28, - DisplayOn = 0x29, - ColumnAddressSet = 0x2a, - PageAddressSet = 0x2b, - MemoryWrite = 0x2c, - ColorSet = 0x2d, - MemoryRead = 0x2e, - PartialArea = 0x30, - VerticalScrollDefinition = 0x33, - TearingEffectOff = 0x34, - TearingEffectOn = 0x35, - MemoryAccessCtrl = 0x36, - VerticalScrollStartAddr = 0x37, - IdleModeOff = 0x38, - IdleModeOn = 0x39, - PixelFormatSet = 0x3a, - WriteMemoryContinue = 0x3c, - ReadMemoryContinue = 0x3e, - SetTearScanLine = 0x44, - GetScanLine = 0x45, - WriteBrightness = 0x51, - ReadBrightness = 0x52, - WriteCtrlDisplay = 0x53, - ReadCtrlDisplay = 0x54, - WriteContentAdaptiveBrightnessCtrl = 0x55, - ReadContentAdaptiveBrightnessCtrl = 0x56, - WriteCabcMinimumBrightness = 0x5e, - ReadCabcMinimumBrightness = 0x5f, - ReadId1 = 0xda, - ReadId2 = 0xdb, - ReadId3 = 0xdc, - // extended commands - RgbInterfaceSignalCtrl = 0xb0, - FrameCtrlNormalMode = 0xb1, - FrameCtrlIdleMode = 0xb2, - FrameCtrlPartialMode = 0xb3, - InversionCtrl = 0xb4, - BlankingPorchCtrl = 0xb5, - DisplayFunctionCtrl = 0xb6, - EntryModeSet = 0xb7, - BacklightCtrl1 = 0xb8, - BacklightCtrl2 = 0xb9, - BacklightCtrl3 = 0xba, - BacklightCtrl4 = 0xbb, - BacklightCtrl5 = 0xbc, - BacklightCtrl7 = 0xbe, - BacklightCtrl8 = 0xbf, - PowerCtrl1 = 0xc0, - PowerCtrl2 = 0xc1, - VComCtrl1 = 0xc5, - VComCtrl2 = 0xc7, - PowerCtrlA = 0xcb, - PowerCtrlB = 0xcf, - NvMemoryWrite = 0xd0, - NvMemoryProtectionKey = 0xd1, - NvMemoryStatus = 0xd2, - ReadId4 = 0xd3, - PositiveGammaCorrection = 0xe0, - NegativeGammaCorrection = 0xe1, - DigitalGammaCtrl = 0xe2, - TimingCtrlA = 0xe8, - TimingCtrlB = 0xea, - PowerOnSequenceCtrl = 0xed, - Enable3Gamma = 0xf2, - InterfaceCtrl = 0xf6, - PumpRatioCtrl = 0xf7, - }; - static constexpr uint8_t i(Command command) { return uint8_t(command); } - - enum class - MemoryAccessCtrl : uint8_t - { - MY = modm::Bit7, - MX = modm::Bit6, - MV = modm::Bit5, - ML = modm::Bit4, - BGR = modm::Bit3, - MH = modm::Bit2 - }; - MODM_FLAGS8(MemoryAccessCtrl); - /// @endcond - -public: - enum class - DisplayMode : uint8_t - { - Normal = uint8_t(Command::InversionOff), - Inverted = uint8_t(Command::InversionOn) - }; -}; -/// @ingroup modm_driver_ili9341 -template -class Ili9341 : public Interface, public modm::ColorGraphicDisplay +template +// requires std::derived_from> +class Ili9341 : public Transport, public graphic::Display { - static_assert(BufferSize >= 16, "at least a small buffer is required"); + // OPTIMIZE determine good contraints + static_assert(BC >= 32, "Conversion Buffer < 64 pixels produces too much overhead."); + static_assert(BC <= 2048, "Conversion Buffer > 2048 pixels doesn't make it any better."); + + using Toggle = ili9341_register::Toggle; + using ReadWrite = ili9341_register::ReadWrite; + using Command = ili9341_register::Command; + using ReadCommand = ili9341_register::ReadCommand; - static constexpr uint16_t Width = 240; - static constexpr uint16_t Height = 320; - using BatchHandle = typename Interface::BatchHandle; - using Command = ili9341::Command; public: - using Orientation = glcd::Orientation; - using DisplayMode = ili9341::DisplayMode; + using ColorType = color::Rgb565; + using BufferLandscape = graphic::Buffer; + using BufferPortrait = graphic::Buffer; template - Ili9341(Args&&... args): Interface(std::forward(args)...) - { - Reset::setOutput(modm::Gpio::High); - Backlight::setOutput(modm::Gpio::Low); - } + Ili9341(Args &&...args) + : Transport(std::forward(args)...) + { Reset::setOutput(modm::Gpio::High); } + + ~Ili9341(){}; - void + ResumableResult initialize(); - void + ResumableResult reset(bool hardReset = false); - uint16_t + ResumableResult getIcModel(); - void - turnOn(); + /* ResumableResult + getStatus(); // 5 bytes, Datasheet P92 - void - turnOff(); + ResumableResult + getPowerMode(); // 2 bytes, Datasheet P94 - void - enableBacklight(bool enable) - { Backlight::set(enable); } + ResumableResult + getMadCtl(); // 2 bytes, Datasheet P95 - void - setBrightness(uint8_t level); + ResumableResult + getPixelFormat(); // 2 bytes, Datasheet P96 */ - void - setInvert(bool invert); + ResumableResult + set(Toggle toggle, bool state); - void - setIdle(bool enable); + ResumableResult + set(ReadWrite reg, uint8_t value); - void - enableSleep(bool enable); + ResumableResult + get(ReadWrite reg); - uint16_t - getWidth() const final - { - switch (orientation) - { - case Orientation::Portrait90: - case Orientation::Portrait270: - return Height; - default: - return Width; - } - } - - uint16_t - getHeight() const final - { - switch (orientation) - { - case Orientation::Portrait90: - case Orientation::Portrait270: - return Width; - default: - return Height; - } - } - - inline std::size_t - getBufferWidth() const final - { - return Width; - } - - inline std::size_t - getBufferHeight() const final - { - return Height; - } - - void - setPixel(int16_t x, int16_t y) final - { setColoredPixel(x, y, foregroundColor); } - - void - clearPixel(int16_t x, int16_t y) final - { setColoredPixel(x, y, backgroundColor); } - - // TODO implement getPixel for ili9341 - color::Rgb565 - getPixel(int16_t x, int16_t y) const final - { - (void) x; - (void) y; - return modm::color::html::White; - } - - void - clear() final; - - inline void - update() final - { /* nothing to do, data is directly written to TFT RAM */ } - - inline void - setOrientation(glcd::Orientation orientation); - - void - fillRectangle(glcd::Point upperLeft, uint16_t width, uint16_t height); - - inline void - fillRectangle(int16_t x, int16_t y, uint16_t width, uint16_t height) - { fillRectangle(glcd::Point(x, y), width, height); } - - void - fillCircle(glcd::Point center, uint16_t radius); - - void - drawImageRaw(glcd::Point upperLeft, - uint16_t width, uint16_t height, - modm::accessor::Flash data) final; - - void - drawRaw(glcd::Point upperLeft, uint16_t width, uint16_t height, color::Rgb565* data); - - void - setScrollArea(uint16_t topFixedRows, uint16_t bottomFixedRows, uint16_t firstRow); - - void + ResumableResult + setOrientation(graphic::Orientation orientation); + + ResumableResult + setScrollArea(uint16_t topFixedRows, uint16_t firstRow, uint16_t bottomFixedRows); + + ResumableResult scrollTo(uint16_t row); - void - drawBitmap(glcd::Point upperLeft, uint16_t width, uint16_t height, modm::accessor::Flash data); + template + ResumableResult + writePattern(shape::Rectangle rectangle, P pattern); -protected: - void - drawHorizontalLine(glcd::Point start, uint16_t length) final; + // Clear whole display with colormap index + ResumableResult + clear(const std::size_t color_idx); + + // Clear whole display with color + ResumableResult + clear(const ColorType color = 0); +private: + // Static variables for resumable functions + shape::Section section; + shape::Point cursor; + // ################################################################## - void - drawVerticalLine(glcd::Point start, uint16_t length) final; +protected: + ResumableResult + updateClipping(); + + ResumableResult + setClipping(shape::Point point); + + /** + * Write Image with foreign Color + * + * @param accessor ImageAccessor with underlying Flash or Ram Accessor + * @param placement Placement for the image + */ + template class Accessor> + ResumableResult + writeImage(graphic::ImageAccessor accessor); + + /** + * Write Image with same Color + * + * @param accessor ImageAccessor with underlying Flash or Ram Accessor + * @param placement Placement for the image + */ + template class Accessor> + ResumableResult + writeImage(graphic::ImageAccessor accessor); + + ResumableResult drawBlind(const shape::Point& point); + ResumableResult drawBlind(const shape::Section& section); + ResumableResult drawBlind(const shape::HLine& hline); + ResumableResult drawBlind(const shape::VLine& vline); + + ResumableResult + getBlind(const shape::Point& point) const; private: - void - setColoredPixel(int16_t x, int16_t y, color::Rgb565 const &color); + // Static variables for resumable functions + // OPTIMIZE Closing check if the union is well formed + union { + modm::ShortTimeout timeout; + + std::array array_u8; + std::array array_u16; + + ili9341_register::MemoryAccessCtrl_t madCtrl; + + // Static variables for resumable functions with parallel application + struct + { + std::array array_color; + std::array array_u16; - void - setClipping(uint16_t x, uint16_t y, uint16_t width, uint16_t height); + size_t i; // index in conversion array_color + Point scanner; // index on display - Orientation orientation{Orientation::Landscape0}; + uint64_t pixels; // Must fit Total number of pixels: R.x * R.y = 76800 + size_t pixels_bulk; // Number of pixels of current bulk - uint8_t buffer[BufferSize * 2]{0}; + ColorType temp_color; // Temporary storage for a color + } p; // [p]arallel + }; }; -} // namespace modm +} // namespace modm #include "ili9341_impl.hpp" -#endif // MODM_ILI9341_HPP +#endif // MODM_ILI9341_HPP diff --git a/src/modm/driver/display/ili9341.lb b/src/modm/driver/display/ili9341.lb index 63333894e3..7576703c77 100644 --- a/src/modm/driver/display/ili9341.lb +++ b/src/modm/driver/display/ili9341.lb @@ -2,6 +2,7 @@ # -*- coding: utf-8 -*- # # Copyright (c) 2020, Mike Wolfram +# Copyright (c) 2021, Thomas Sommer # # This file is part of the modm project. # @@ -10,21 +11,25 @@ # file, You can obtain one at http://mozilla.org/MPL/2.0/. # ----------------------------------------------------------------------------- - def init(module): module.name = ":driver:ili9341" module.description = "ILI9341 Display with parallel and SPI bus transports" + def prepare(module, options): module.depends( ":architecture:delay", ":architecture:spi.device", - ":ui:display") + ":ui:graphic") return True + def build(env): env.outbasepath = "modm/src/modm/driver/display" + env.copy("ili9341_defines.hpp") env.copy("ili9341.hpp") env.copy("ili9341_impl.hpp") - env.copy("ili9341_spi.hpp") - env.copy("ili9341_parallel.hpp") + env.copy("ili9341_interface_parallel.hpp") + + env.substitutions = {'spi_16bit_hardware': env[":target"].has_driver("spi:stm32")} + env.template("ili9341_interface_spi.hpp.in") diff --git a/src/modm/driver/display/ili9341_defines.hpp b/src/modm/driver/display/ili9341_defines.hpp new file mode 100644 index 0000000000..43fb786c27 --- /dev/null +++ b/src/modm/driver/display/ili9341_defines.hpp @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2019, Mike Wolfram + * Copyright (c) 2021, Thomas Sommer + * + * 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/. + */ + +#pragma once +#ifndef MODM_ILI9341_HPP +#error "Don't include this file directly, use 'ili9341.hpp' instead!" +#endif + +#include + +namespace modm { + +/// @ingroup modm_driver_ili9341 +struct ili9341_register +{ +public: + // Bit0 => false: Off, true: On + enum Toggle : uint8_t { + SleepDisable = 0x10, + Inversion = 0x20, + Enable = 0x28, + TearingEffect = 0x34, + Idle = 0x38, + }; + + // Bit0 => false: Write, true: Read + enum class ReadWrite : uint8_t { + Brightness = 0x51, + CtrlDisplay = 0x53, + ContentAdaptiveBrightnessCtrl = 0x55, + CabcMinimumBrightness = 0x5E, + }; + +// protected: + enum class Command : uint8_t + { + Nop = 0x00, + SwReset = 0x01, + + GammaSet = 0x26, + ColumnAddressSet = 0x2A, + PageAddressSet = 0x2B, + MemoryWrite = 0x2C, + ColorSet = 0x2D, + MemoryRead = 0x2E, + + PartialMode = 0x12, + NormalMode = 0x13, + + PartialArea = 0x30, + VerticalScrollDefinition = 0x33, + MemoryAccessCtrl = 0x36, + VerticalScrollStartAddr = 0x37, + + PixelFormatSet = 0x3A, + WriteMemoryContinue = 0x3C, + ReadMemoryContinue = 0x3E, + SetTearScanLine = 0x44, + GetScanLine = 0x45, + + // Extended + RgbInterfaceSignalCtrl = 0xB0, + FrameCtrlNormalMode = 0xB1, + FrameCtrlIdleMode = 0xB2, + FrameCtrlPartialMode = 0xB3, + InversionCtrl = 0xB4, + BlankingPorchCtrl = 0xB5, + DisplayFunctionCtrl = 0xB6, + EntryModeSet = 0xB7, + BacklightCtrl1 = 0xB8, + BacklightCtrl2 = 0xB9, + BacklightCtrl3 = 0xBA, + BacklightCtrl4 = 0xBB, + BacklightCtrl5 = 0xBC, + BacklightCtrl7 = 0xBE, + BacklightCtrl8 = 0xBF, + PowerCtrl1 = 0xC0, + PowerCtrl2 = 0xC1, + VComCtrl1 = 0xC5, + VComCtrl2 = 0xC7, + PowerCtrlA = 0xCB, + PowerCtrlB = 0xCF, + NvMemoryWrite = 0xD0, + NvMemoryProtectionKey = 0xD1, + NvMemoryStatus = 0xD2, + PositiveGammaCorrection = 0xE0, + NegativeGammaCorrection = 0xE1, + DigitalGammaCtrl = 0xE2, + TimingCtrlA = 0xE8, + TimingCtrlB = 0xEA, + PowerOnSequenceCtrl = 0xED, + Enable3Gamma = 0xF2, + InterfaceCtrl = 0xF6, + PumpRatioCtrl = 0xF7, + }; + + enum class ReadCommand : uint8_t { + // TODO got 0s only for each of ReadId* + Id = 0x04, // returns 4 bytes + Id1 = 0xDA, + Id2 = 0xDB, + Id3 = 0xDC, + Id4 = 0xD3, + + Status = 0x09, // returns 5 bytes + PowerMode = 0x0A, // returns 2 bytes + MemoryAccessCtrl = 0x0B,// returns 2 bytes + PixelFormat = 0x0C, // returns 2 bytes + ImageFormat = 0x0D, // returns 2 bytes + SignalMode = 0x0E, // returns 2 bytes + SelfDiagnostic = 0x0F, // returns 2 bytes + }; + + enum class MemoryAccessCtrl : uint8_t + { + // Rgb565 bits-order + PIXEL_DIR = Bit3, // 0: RGB, 1: BGR + // LCD Refresh + REFRESH_DIR_X = Bit2, // 0: Left->Right, 1: Right->Left + REFRESH_DIR_Y = Bit4, // 0: Top->Bottom, 1: Bottom->Top + // Memory Access + MEMORY_MODE = Bit5, // 0: Normal, 1: Reverse + MEMORY_DIR_X = Bit6, // 0: Left->Right, 1: Right->Left + MEMORY_DIR_Y = Bit7 // 0: Top->Bottom, 1: Bottom->Top + }; + MODM_FLAGS8(MemoryAccessCtrl); +}; +} \ No newline at end of file diff --git a/src/modm/driver/display/ili9341_impl.hpp b/src/modm/driver/display/ili9341_impl.hpp index d44ce85c69..4a59335462 100644 --- a/src/modm/driver/display/ili9341_impl.hpp +++ b/src/modm/driver/display/ili9341_impl.hpp @@ -1,5 +1,6 @@ /* * Copyright (c) 2019, Mike Wolfram + * Copyright (c) 2021, Thomas Sommer * * This file is part of the modm project. * @@ -8,433 +9,419 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef MODM_ILI9341_HPP -# error "Don't include this file directly, use 'ili9341.hpp' instead!" -#endif +#pragma once +#include "ili9341.hpp" -namespace modm -{ +#include + +using namespace modm::shape; +using namespace modm::color; +using namespace modm::graphic; -template -void -Ili9341::initialize() +#define MODM_INIT_BUFFER(...) {\ + constexpr uint8_t data[]__VA_ARGS__;\ + std::copy(std::begin(data), std::end(data), std::begin(array_u8));\ + } + +template +modm::ResumableResult +modm::Ili9341::initialize() { - constexpr uint8_t pwrCtrlA[] { 0x39, 0x2c, 0x00, 0x34, 0x02 }; - constexpr uint8_t pwrCtrlB[] { 0x00, 0xc1, 0x30 }; - constexpr uint8_t timCtrlA[] { 0x85, 0x10, 0x7a }; - constexpr uint8_t timCtrlB[] { 0x00, 0x00 }; - constexpr uint8_t pwrOnSeqCtrl[] { 0x64, 0x03, 0x12, 0x81 }; - constexpr uint8_t pwrCtrl1[] { 0x1b }; - constexpr uint8_t pwrCtrl2[] { 0x12 }; - constexpr uint8_t vcomCtrl1[] { 0x08, 0x26 };//0x3e, 0x28 }; - constexpr uint8_t vcomCtrl2[] { 0xb7 }; + RF_BEGIN(); + RF_CALL(reset()); + RF_CALL(set(Toggle::Enable, false)); + + MODM_INIT_BUFFER({0x39, 0x2c, 0x00, 0x34, 0x02}) + RF_CALL(this->writeCommand(Command::PowerCtrlA, array_u8.begin(), array_u8.begin() + 5)); + + MODM_INIT_BUFFER({0x00, 0xc1, 0x30}) + RF_CALL(this->writeCommand(Command::PowerCtrlB, array_u8.begin(), array_u8.begin() + 3)); + + MODM_INIT_BUFFER({0x85, 0x10, 0x7a}) + RF_CALL(this->writeCommand(Command::TimingCtrlA, array_u8.begin(), array_u8.begin() + 3)); + + MODM_INIT_BUFFER({0x00, 0x00}) + RF_CALL(this->writeCommand(Command::TimingCtrlB, array_u8.begin(), array_u8.begin() + 2)); + + MODM_INIT_BUFFER({0x64, 0x03, 0x12, 0x81}) + RF_CALL(this->writeCommand(Command::PowerOnSequenceCtrl, array_u8.begin(), array_u8.begin() + 4)); + + RF_CALL(this->writeCommand(Command::PowerCtrl1, uint8_t(0x1b))); + RF_CALL(this->writeCommand(Command::PowerCtrl2, uint8_t(0x12))); + + MODM_INIT_BUFFER({0x08, 0x26}) // 0x3e, 0x28 }; + RF_CALL(this->writeCommand(Command::VComCtrl1, array_u8.begin(), array_u8.begin() + 2)); + + RF_CALL(this->writeCommand(Command::VComCtrl2, uint8_t(0xb7))); // constexpr uint8_t pumpRatioCtrl[] { 0x20 }; - constexpr uint8_t pixelFormat[] { 0x55 }; - constexpr uint8_t frameCtrl[] { 0x00, 0x1a }; - constexpr uint8_t dispFuncCtrl[] { 0x0a, 0xa2, 0x27, 00 };//{ 0x08, 0x82, 0x27, 0x00 }; - constexpr uint8_t enable3G[] { 0x00 }; - constexpr uint8_t gammaSet[] { 0x01 }; -// constexpr uint8_t positiveGammaCorr[] { 0x0f, 0x31, 0x2b, 0x0c, 0x0e, 0x08, -// 0xe4, 0xf1, 0x37, 0x07, 0x10, 0x03, 0x0e, 0x09, 0x00 }; -// constexpr uint8_t negativeGammaCorr[] { 0x00, 0x0e, 0x14, 0x03, 0x11, 0x07, -// 0x31, 0xc1, 0x48, 0x08, 0x0f, 0x0c, 0x31, 0x36, 0x0f }; - constexpr uint8_t positiveGammaCorr[] { 0x0f, 0x1d, 0x1a, 0x0a, 0x0d, 0x07, - 0x49, 0x66, 0x3b, 0x07, 0x11, 0x01, 0x09, 0x05, 0x04 }; - constexpr uint8_t negativeGammaCorr[] { 0x00, 0x18, 0x1d, 0x02, 0x0f, 0x04, - 0x36, 0x13, 0x4c, 0x07, 0x13, 0x0f, 0x2e, 0x2f, 0x05 }; - - reset(); + RF_CALL(this->writeCommand(Command::PixelFormatSet, uint8_t(0x55))); + + MODM_INIT_BUFFER({0x00, 0x1a}) + RF_CALL(this->writeCommand(Command::FrameCtrlNormalMode, array_u8.begin(), array_u8.begin() + 2)); - { - BatchHandle h(*this); - - this->writeCommand(Command::DisplayOff); - - this->writeCommand(Command::PowerCtrlA, pwrCtrlA, sizeof(pwrCtrlA)); - this->writeCommand(Command::PowerCtrlB, pwrCtrlB, sizeof(pwrCtrlB)); - this->writeCommand(Command::TimingCtrlA, timCtrlA, sizeof(timCtrlA)); - this->writeCommand(Command::TimingCtrlB, timCtrlB, sizeof(timCtrlB)); - this->writeCommand(Command::PowerOnSequenceCtrl, pwrOnSeqCtrl, sizeof(pwrOnSeqCtrl)); - this->writeCommand(Command::PowerCtrl1, pwrCtrl1, sizeof(pwrCtrl1)); - this->writeCommand(Command::PowerCtrl2, pwrCtrl2, sizeof(pwrCtrl2)); - this->writeCommand(Command::VComCtrl1, vcomCtrl1, sizeof(vcomCtrl1)); - this->writeCommand(Command::VComCtrl2, vcomCtrl2, sizeof(vcomCtrl2)); - this->writeCommand(Command::PixelFormatSet, pixelFormat, sizeof(pixelFormat)); - this->writeCommand(Command::FrameCtrlNormalMode, frameCtrl, sizeof(frameCtrl)); - this->writeCommand(Command::DisplayFunctionCtrl, dispFuncCtrl, sizeof(dispFuncCtrl)); - this->writeCommand(Command::Enable3Gamma, enable3G, sizeof(enable3G)); - this->writeCommand(Command::GammaSet, gammaSet, sizeof(gammaSet)); - this->writeCommand(Command::PositiveGammaCorrection, positiveGammaCorr, - sizeof(positiveGammaCorr)); - this->writeCommand(Command::NegativeGammaCorrection, negativeGammaCorr, - sizeof(negativeGammaCorr)); - - this->writeCommand(Command::LeaveSleep); - modm::delay_ms(120); - this->writeCommand(Command::InversionOff); - this->writeCommand(Command::DisplayOn); - - setOrientation(orientation); - } + MODM_INIT_BUFFER({0x0a, 0xa2, 0x27, 0x00}) //{ 0x08, 0x82, 0x27, 0x00 }; + RF_CALL(this->writeCommand(Command::DisplayFunctionCtrl, array_u8.begin(), array_u8.begin() + 4)); + + RF_CALL(this->writeCommand(Command::Enable3Gamma, uint8_t(0x00))); + RF_CALL(this->writeCommand(Command::GammaSet, uint8_t(0x01))); + + // MODM_INIT_BUFFER({ 0x0f, 0x31, 0x2b, 0x0c, 0x0e, 0x08, 0xe4, 0xf1, 0x37, 0x07, 0x10, 0x03, 0x0e, 0x09, 0x00}); + MODM_INIT_BUFFER({0x0f, 0x1d, 0x1a, 0x0a, 0x0d, 0x07, 0x49, 0x66, 0x3b, 0x07, 0x11, 0x01, 0x09, 0x05, 0x04}) + RF_CALL(this->writeCommand(Command::PositiveGammaCorrection, array_u8.begin(), array_u8.begin() + 15)); + + // MODM_INIT_BUFFER({ 0x00, 0x0e, 0x14, 0x03, 0x11, 0x07, 0x31, 0xc1, 0x48, 0x08, 0x0f, 0x0c, 0x31, 0x36, 0x0f}); + MODM_INIT_BUFFER({0x00, 0x18, 0x1d, 0x02, 0x0f, 0x04, 0x36, 0x13, 0x4c, 0x07, 0x13, 0x0f, 0x2e, 0x2f, 0x05}) + RF_CALL(this->writeCommand(Command::NegativeGammaCorrection, array_u8.begin(), array_u8.begin() + 15)); + + RF_CALL(set(Toggle::SleepDisable, true)); + timeout.restart(120ms); + RF_WAIT_UNTIL(timeout.isExpired()); + RF_CALL(set(Toggle::Inversion, false)); + RF_CALL(setOrientation(orientation)); + RF_CALL(set(Toggle::Enable, true)); + + RF_END(); } -template -void -Ili9341::reset(bool hardReset /* = false */) +#undef MODM_INIT_BUFFER + +template +modm::ResumableResult +modm::Ili9341::reset(bool hardReset /* = false */) { + RF_BEGIN(); + if (hardReset) { Reset::set(); - modm::delay_ms(5); + timeout.restart(5ms); + RF_WAIT_UNTIL(timeout.isExpired()); Reset::reset(); - modm::delay_ms(5); + timeout.restart(); + RF_WAIT_UNTIL(timeout.isExpired()); Reset::set(); - modm::delay_ms(5); - } - else { - BatchHandle h(*this); - this->writeCommand(Command::SwReset); - modm::delay_ms(5); + timeout.restart(); + RF_WAIT_UNTIL(timeout.isExpired()); + } else + { + RF_CALL(this->writeCommand(Command::SwReset)); + timeout.restart(5ms); + RF_WAIT_UNTIL(timeout.isExpired()); } + RF_END(); } -template -uint16_t -Ili9341::getIcModel() +template +modm::ResumableResult +modm::Ili9341::getIcModel() { - BatchHandle h(*this); - - uint8_t buffer[4] { 0 }; - this->readData(Command::ReadId4, buffer, 4); - return (buffer[2] << 8) | buffer[3]; + RF_BEGIN(); + // TODO Need function testing + RF_CALL(this->readData(ReadCommand::Id, array_u16, 2)); + RF_END_RETURN(array_u16[1]); } -template -inline void -Ili9341::setOrientation(glcd::Orientation orientation) +template +modm::ResumableResult +modm::Ili9341::set(Toggle toggle, bool state) { - using MemoryAccessCtrl_t = ili9341::MemoryAccessCtrl_t; - using MemoryAccessCtrl = ili9341::MemoryAccessCtrl; - MemoryAccessCtrl_t madCtrl { MemoryAccessCtrl::BGR }; - - switch (orientation) - { - case glcd::Orientation::Portrait90: - madCtrl |= MemoryAccessCtrl::MV | MemoryAccessCtrl::MX; - break; - case glcd::Orientation::Landscape180: - madCtrl |= MemoryAccessCtrl::MX | MemoryAccessCtrl::MY; - break; - case glcd::Orientation::Portrait270: - madCtrl |= MemoryAccessCtrl::MV | MemoryAccessCtrl::MY; - break; - default: -// madCtrl |= MemoryAccessCtrl::ML; - break; - } - - this->orientation = orientation; - - BatchHandle h(*this); - this->writeCommandValue8(Command::MemoryAccessCtrl, madCtrl.value); + RF_BEGIN(); + RF_CALL(this->writeCommand(Command(uint8_t(toggle) | uint8_t(state)))); + RF_END(); } -template -void -Ili9341::turnOn() +template +modm::ResumableResult +modm::Ili9341::set(ReadWrite reg, uint8_t value) { - BatchHandle h(*this); - this->writeCommand(Command::DisplayOn); + RF_BEGIN(); + RF_CALL(this->writeCommand(Command(reg), value)); + RF_END(); } -template -void -Ili9341::turnOff() +template +modm::ResumableResult +modm::Ili9341::get(ReadWrite reg) { - BatchHandle h(*this); - this->writeCommand(Command::DisplayOff); + RF_BEGIN(); + RF_END_RETURN_CALL(this->readData(Command(uint8_t(reg) | uint8_t(Bit0)))); } -template -void -Ili9341::setIdle(bool enable) +template +modm::ResumableResult +modm::Ili9341::setOrientation( + Orientation orientation) { - BatchHandle h(*this); - this->writeCommand(enable ? Command::IdleModeOn : Command::IdleModeOff); -} + RF_BEGIN(); + this->orientation = orientation; -template -void -Ili9341::enableSleep(bool enable) -{ - BatchHandle h(*this); - this->writeCommand(enable ? Command::EnterSleep : Command::LeaveSleep); -} + using MemoryAccessCtrl = ili9341_register::MemoryAccessCtrl; + using OrientationFlags = graphic::OrientationFlags; -template -void -Ili9341::setBrightness(uint8_t level) -{ - BatchHandle h(*this); - this->writeCommand(Command::WriteBrightness, &level, 1); -} + madCtrl = MemoryAccessCtrl::PIXEL_DIR; -template -void -Ili9341::setInvert(bool invert) -{ - BatchHandle h(*this); - this->writeCommand(invert ? Command::InversionOn : Command::InversionOff); -} + // FIXME adjust for flipped x-y in Buffer + if (orientation & OrientationFlags::Portrait) + madCtrl |= MemoryAccessCtrl::MEMORY_MODE; -template -void -Ili9341::clear() -{ - auto const saveForegroundColor { foregroundColor }; - foregroundColor = backgroundColor; - fillRectangle(glcd::Point(0, 0), Width, Height); - foregroundColor = saveForegroundColor; -} + if (orientation & OrientationFlags::TopDown) + madCtrl |= MemoryAccessCtrl::MEMORY_DIR_Y; -template -void -Ili9341::drawHorizontalLine( - glcd::Point start, uint16_t length) -{ - uint16_t const pixelValue { modm::toBigEndian(foregroundColor.color) }; - auto minLength { std::min(std::size_t(length), BufferSize) }; - uint16_t *buffer16 { reinterpret_cast(buffer) }; - std::fill(buffer16, buffer16+minLength, pixelValue); + if (bool(orientation & OrientationFlags::Portrait) == bool(orientation & OrientationFlags::TopDown)) + madCtrl |= MemoryAccessCtrl::MEMORY_DIR_X; - BatchHandle h(*this); + RF_CALL(this->writeCommand(Command::MemoryAccessCtrl, madCtrl.value)); - setClipping(start.getX(), start.getY(), length, 1); - while (length > BufferSize) - { - this->writeData(buffer, BufferSize * 2); - length -= BufferSize; - } - this->writeData(buffer, length * 2); + RF_END(); } -template -void -Ili9341::drawVerticalLine( - glcd::Point start, uint16_t length) +template +modm::ResumableResult +modm::Ili9341::setScrollArea(uint16_t topFixedRows, uint16_t firstRow, uint16_t bottomFixedRows) { - uint16_t const pixelValue { modm::toBigEndian(foregroundColor.color) }; - auto minLength { std::min(std::size_t(length), BufferSize) }; - uint16_t *buffer16 { reinterpret_cast(buffer) }; - std::fill(buffer16, buffer16+minLength, pixelValue); + RF_BEGIN(); - BatchHandle h(*this); + array_u16[0] = topFixedRows; + array_u16[1] = firstRow; + array_u16[2] = bottomFixedRows; - setClipping(start.getX(), start.getY(), 1, length); - while (length > BufferSize) - { - this->writeData(buffer, BufferSize * 2); - length -= BufferSize; - } - this->writeData(buffer, length * 2); + RF_CALL(this->writeCommand(Command::VerticalScrollDefinition, array_u16.begin(), array_u16.begin() + 3)); + RF_END(); } -template -void -Ili9341::fillRectangle( - glcd::Point upperLeft, uint16_t width, uint16_t height) +template +modm::ResumableResult +modm::Ili9341::scrollTo(uint16_t row) +{ + RF_BEGIN(); + RF_CALL(this->writeCommand(Command::VerticalScrollStartAddr, row)); + RF_END(); +} + +// --------------------------------------------------------------------------- + +template +modm::ResumableResult +modm::Ili9341::updateClipping() { - auto const x { upperLeft.getX() }; - auto const y { upperLeft.getY() }; - std::size_t pixelCount { std::size_t(width) * std::size_t(height) }; + RF_BEGIN(); - uint16_t const pixelValue { modm::toBigEndian(foregroundColor.color) }; - auto minLength { std::min(std::size_t(pixelCount), BufferSize) }; - uint16_t *buffer16 { reinterpret_cast(buffer) }; - std::fill(buffer16, buffer16+minLength, pixelValue); + p.array_u16[0] = this->clipping.topLeft.y; + p.array_u16[1] = this->clipping.bottomRight.y - 1; + RF_CALL(this->writeCommand(Command::ColumnAddressSet, p.array_u16.begin(), p.array_u16.begin() + 2)); - BatchHandle h(*this); + p.array_u16[0] = this->clipping.topLeft.x; + p.array_u16[1] = this->clipping.bottomRight.x - 1; + RF_CALL(this->writeCommand(Command::PageAddressSet, p.array_u16.begin(), p.array_u16.begin() + 2)); - setClipping(x, y, width, height); - while (pixelCount > BufferSize) + RF_CALL(this->writeCommand(Command::MemoryWrite)); + p.pixels = uint64_t(this->clipping.getWidth()) * this->clipping.getHeight(); + + RF_END(); +} + +template +template class Accessor> +modm::ResumableResult +modm::Ili9341::writeImage(ImageAccessor accessor) { + // Found no cast for a share the memory between all of the writeImage()-methods. + // This waste of RAM will be history once Resumable Functions become history. + static ImageAccessor a; + + RF_BEGIN(); + + a = accessor; + + this->clipping = this->getIntersection(a.getSection()); + RF_CALL(updateClipping()); + + a.incrementRow_preparePixel(); + p.scanner = this->clipping.topLeft; + + while (p.pixels) { - this->writeData(buffer, BufferSize * 2); - pixelCount -= BufferSize; + // Fill array_color + for(p.i = 0; p.i < std::min(p.pixels, BC); p.i++) { + if constexpr (ColorPalletized) { + // Apply colormap + p.array_color[p.i] = colormap[ a.nextPixel().getValue() ]; + } else { + // convert color + p.array_color[p.i] = a.nextPixel(); + } + + if (++p.scanner.y == this->clipping.bottomRight.y) { + p.scanner.x++; + p.scanner.y = this->clipping.topLeft.y; + a.incrementRow_preparePixel(); + } + } + + // Transfer array_color + RF_CALL(this->writePixels(p.array_color.begin(), p.array_color.begin() + p.i)); + p.pixels -= p.i; } - if (pixelCount) - this->writeData(buffer, pixelCount * 2); + + RF_END(); } -template -void -Ili9341::fillCircle( - glcd::Point center, uint16_t radius) +template +template class Accessor> +modm::ResumableResult +modm::Ili9341::writeImage(ImageAccessor accessor) { - uint8_t const setColor[] { uint8_t((foregroundColor.color >> 8) & 0xff), - uint8_t(foregroundColor.color & 0xff) }; - - int16_t f = 1 - radius; - int16_t ddF_x = 0; - int16_t ddF_y = -2 * radius; - uint16_t x = 0; - uint16_t y = radius; + // Found no cast for a share the memory between all of the writeImage()-methods. + // This waste of RAM will be history once Resumable Functions become history. + static ImageAccessor a; - BatchHandle h(*this); + RF_BEGIN(); + + a = accessor; - setClipping(center.getX() - radius, center.getY(), 2 * radius, 1); - for (std::size_t i = 0; i < 2 * radius; ++i) - this->writeData(setColor, 2); + this->clipping = this->getIntersection(a.getSection()); + RF_CALL(updateClipping()); - while(x < y) + // Buffer is clipped? + // REIMPLEMENT clipped array_color detection + if (true /* placement.y < 0 or placement.y + a.getSize().y >= this->getHeight() */) { - if (f >= 0) - { - y--; - ddF_y += 2; - f += ddF_y; + // Transfer array_color row by row + p.pixels_bulk = this->clipping.getHeight(); + while(p.pixels >= p.pixels_bulk) { + RF_CALL(this->writeData(a.getPointer() + 1, p.pixels_bulk)); + a.incrementRow(); + p.pixels -= p.pixels_bulk; } - x++; - ddF_x += 2; - f += ddF_x + 1; - - setClipping(center.getX() - x, center.getY() - y, 2 * x, 1); - for (std::size_t i = 0; i < 2 * x; ++i) - this->writeData(setColor, 2); - setClipping(center.getX() - y, center.getY() - x, 2 * y, 1); - for (std::size_t i = 0; i < 2 * y; ++i) - this->writeData(setColor, 2); - setClipping(center.getX() - x, center.getY() + y, 2 * x, 1); - for (std::size_t i = 0; i < 2 * x; ++i) - this->writeData(setColor, 2); - setClipping(center.getX() - y, center.getY() + x, 2 * y, 1); - for (std::size_t i = 0; i < 2 * y; ++i) - this->writeData(setColor, 2); + } else + { + // Transfer array_color in one turn + // TODO Why +1 ??? + RF_CALL(this->writePixels(a.getPointer() + 1, a.getPointer() + p.pixels + 1)); } + RF_END(); } -template -void -Ili9341::drawImageRaw(glcd::Point upperLeft, - uint16_t width, uint16_t height, modm::accessor::Flash data) -{ - uint8_t const setColor[] { uint8_t((foregroundColor.color >> 8) & 0xff), - uint8_t(foregroundColor.color & 0xff) }; - uint8_t const clearColor[] { uint8_t((backgroundColor.color >> 8) & 0xff), - uint8_t(backgroundColor.color & 0xff) }; +template +template +modm::ResumableResult +modm::Ili9341::writePattern(Rectangle rectangle, P pattern) { + RF_BEGIN(); - BatchHandle h(*this); + this->clipping = this->getIntersection(rectangle); + RF_CALL(updateClipping()); - setClipping(upperLeft.getX(), upperLeft.getY(), width, height); + p.scanner = this->clipping.topLeft; - uint8_t bit = 0x01; - for (uint16_t r = 0; r < height; ++r) + while (p.pixels) { - for (uint16_t w = 0; w < width; ++w) - { - uint8_t byte = data[(r / 8) * width + w]; - if (byte & bit) - this->writeData(setColor, 2); - else - this->writeData(clearColor, 2); + // Fill array_color + for(p.i = 0; p.i < std::min(p.pixels, BC); p.i++) { + p.array_color[p.i] = pattern(p.scanner); + if (++p.scanner.y == this->clipping.bottomRight.y) { + p.scanner.x++; + p.scanner.y = this->clipping.topLeft.y; + } } - // TODO: optimize, use ROL (rotate left) - bit <<= 1; - if (bit == 0) - bit = 0x01; + // Transfer array_color + RF_CALL(this->writePixels(p.array_color.begin(), p.array_color.begin() + p.i)); + p.pixels-= p.i; } + + RF_END(); } -template -void -Ili9341::drawRaw(glcd::Point upperLeft, - uint16_t width, uint16_t height, color::Rgb565* data) +// Fundamental drawing of shapes +template +modm::ResumableResult +modm::Ili9341::drawBlind(const Point& point) { - BatchHandle h(*this); - - uint16_t* buffer = (uint16_t*)data; - for(size_t i = 0; i < size_t(width*height); i++) { - buffer[i] = modm::fromBigEndian(buffer[i]); - } - - setClipping(upperLeft.getX(), upperLeft.getY(), width, height); - this->writeData((uint8_t*)buffer, width * height * 2); + RF_BEGIN(); + // This snipers single pixels and is quite heavy because anytime + // the clipping and thus the DataCommand-line is modulated. + // + // OPTIMIZE Modulate DC with hardware: Timer connected with a DMA. + // 1. An array contains periods for modulation of the DC-Line: [1, 2, 1, 2, 1] => 1cmd, 2data, 1cmd, 1cmd, 2data + // 2. A DMA sequences these periods into a Timers compare-register + // 3. The timers clock is connected to Spi-transfer-complete. + // 4. Compare match toggles the DC-Line and triggers the DMA + // OPTIMIZE Now it's possible to array_color remote drawing-instructions and do efficient DMA transfers + // without CPU intervention. + p.array_u16[0] = point.y; + p.array_u16[1] = p.array_u16[0]; + RF_CALL(this->writeCommand(Command::ColumnAddressSet, p.array_u16, 2)); + + p.array_u16[0] = point.x; + p.array_u16[1] = p.array_u16[0]; + RF_CALL(this->writeCommand(Command::PageAddressSet, p.array_u16, 2)); + + RF_CALL(this->writeCommand(Command::MemoryWrite)); + + RF_END_RETURN_CALL(this->writeData(this->color.getValue())); } -template -void -Ili9341::setScrollArea( - uint16_t topFixedRows, uint16_t bottomFixedRows, uint16_t firstRow) +template +modm::ResumableResult +modm::Ili9341::drawBlind(const HLine& hline) { - BatchHandle h(*this); + RF_BEGIN(); + RF_END_RETURN_CALL(drawBlind(Section(hline.start, {hline.end_x, hline.start.y + 1}))); +} - uint8_t arg[] - { - uint8_t((topFixedRows >> 8) & 0xff), uint8_t(topFixedRows & 0xff), - uint8_t((firstRow >> 8) & 0xff), uint8_t(firstRow & 0xff), - uint8_t((bottomFixedRows >> 8) & 0xff), uint8_t(bottomFixedRows & 0xff) - }; - this->writeCommand(Command::VerticalScrollDefinition, arg, 6); +template +modm::ResumableResult +modm::Ili9341::drawBlind(const VLine& vline) +{ + RF_BEGIN(); + RF_END_RETURN_CALL(drawBlind(Section(vline.start, {vline.start.x + 1, vline.end_y}))); } -template -void -Ili9341::scrollTo(uint16_t row) +template +modm::ResumableResult +modm::Ili9341::drawBlind(const Section& section) { - BatchHandle h(*this); + RF_BEGIN(); + + this->clipping = section; + RF_CALL(updateClipping()); + + while(p.pixels) { + // DMAs DataLenght register is limited to uint16_t, thus can be max 2^16-1 + p.pixels_bulk = std::min(p.pixels, std::numeric_limits::max()); + RF_CALL(this->writePixels(this->color, p.pixels_bulk)); + p.pixels -= p.pixels_bulk; + } - uint8_t arg[] { uint8_t((row >> 8) & 0xff), uint8_t(row & 0xff) }; - this->writeCommand(Command::VerticalScrollStartAddr, arg, 2); + RF_END(); } -template -void -Ili9341::setColoredPixel( - int16_t x, int16_t y, color::Rgb565 const &color) +template +modm::ResumableResult +modm::Ili9341::clear(const std::size_t color_idx) { - auto const pixelColor { color }; - uint8_t const setColor[] { uint8_t((pixelColor.color >> 8) & 0xff), uint8_t(pixelColor.color & 0xff) }; + RF_BEGIN(); - BatchHandle h(*this); + p.temp_color = this->color; + this->color = colormap[color_idx]; - this->setClipping(x, y, 1, 1); - this->writeData(setColor, 2); -} + RF_CALL(this->drawBlind(this->asSection())); + + this->color = p.temp_color; -template -void -Ili9341::setClipping( - uint16_t x, uint16_t y, uint16_t width, uint16_t height) -{ - uint8_t buffer[4]; - - buffer[0] = uint8_t((x >> 8) & 0xff); - buffer[1] = uint8_t(x & 0xff); - buffer[2] = uint8_t(((x + width - 1) >> 8) & 0xff); - buffer[3] = uint8_t((x + width - 1) & 0xff); - this->writeCommand(Command::ColumnAddressSet, buffer, 4); - - buffer[0] = uint8_t((y >> 8) & 0xff); - buffer[1] = uint8_t(y & 0xff); - buffer[2] = uint8_t(((y + height - 1) >> 8) & 0xff); - buffer[3] = uint8_t((y + height - 1) & 0xff); - this->writeCommand(Command::PageAddressSet, buffer, 4); - this->writeCommand(Command::MemoryWrite); + RF_END(); } -template -void -Ili9341::drawBitmap(glcd::Point upperLeft, - uint16_t width, uint16_t height, modm::accessor::Flash data) +template +modm::ResumableResult +modm::Ili9341::clear(const ColorType color) { - BatchHandle h(*this); + RF_BEGIN(); - setClipping(upperLeft.getX(), upperLeft.getY(), width, height); - for (int i = 0; i < width * height; ++i) { - buffer[0] = data[i*2+1]; - buffer[1] = data[i*2]; - this->writeData(buffer, 2); - } -// this->writeData(data.getPointer(), width * height * 2); -} + p.temp_color = this->color; + this->color = color; + + RF_CALL(this->drawBlind(this->asSection())); + + this->color = p.temp_color; -} // namespace modm + RF_END(); +} \ No newline at end of file diff --git a/src/modm/driver/display/ili9341_interface_parallel.hpp b/src/modm/driver/display/ili9341_interface_parallel.hpp new file mode 100644 index 0000000000..5644a16ecf --- /dev/null +++ b/src/modm/driver/display/ili9341_interface_parallel.hpp @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2020, Pavel Pletenev + * Copyright (c) 2020, Thomas Sommer + * + * 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/. + */ +#pragma once +#include "ili9341.hpp" + +#include + +#include "ili9341_defines.hpp" + +namespace modm +{ + +/// @ingroup modm_driver_ili9341 +template +class Ili9341InterfaceParallel: public ili9341_register +{ + Interface& interface; +public: + Ili9341InterfaceParallel(Interface& interface) + : interface(interface) {} + + void + writeCommand(Command command) + { + interface.writeIndex(uint8_t(command)); + } + void + writeCommand(Command command, uint8_t const *args, std::size_t length) + { + interface.writeIndex(uint8_t(command)); + for(std::size_t i=0; i +#include + +#include "ili9341_defines.hpp" + +namespace modm +{ + +// TODO Forward Nesting Level from PainterRemote: template +/// @ingroup modm_driver_ili9341 +template +class Ili9341InterfaceSpi : public ili9341_register, public modm::SpiDevice< Spi >, protected modm::NestedResumable<5> +{ + uint8_t read; + +protected: + Ili9341InterfaceSpi() + { + this->attachConfigurationHandler([]() { + Spi::setDataMode(Spi::DataMode::Mode0); + Spi::setDataOrder(Spi::DataOrder::MsbFirst); + }); + + Cs::setOutput(modm::Gpio::High); + Dc::setOutput(); + } + +// - Configure display controller -------------------------------- + + modm::ResumableResult + writeCommand(Command command) + { + RF_BEGIN(); + + RF_WAIT_UNTIL(this->acquireMaster()); + Cs::reset(); + + %% if spi_16bit_hardware + Spi::setDataSize(Spi::DataSize::Bit8); + %% endif + + Dc::reset(); + RF_CALL(Spi::transmit(uint8_t(command))); + Dc::set(); + + if (this->releaseMaster()) + Cs::set(); + + RF_END(); + } + + template + modm::ResumableResult + writeCommand(Command command, const T data) + { + RF_BEGIN(); + + RF_WAIT_UNTIL(this->acquireMaster()); + Cs::reset(); + + %% if spi_16bit_hardware + Spi::setDataSize(Spi::DataSize::Bit8); + %% endif + + Dc::reset(); + RF_CALL(Spi::transmit(uint8_t(command))); + Dc::set(); + + %% if spi_16bit_hardware + if constexpr(std::is_same::value) + Spi::setDataSize(Spi::DataSize::Bit16); + %% endif + + RF_CALL(Spi::transmit(data)); + + if (this->releaseMaster()) + Cs::set(); + + RF_END(); + } + + template + modm::ResumableResult + writeCommand(Command command, const T *data_first, const T *data_last) + { + RF_BEGIN(); + + RF_WAIT_UNTIL(this->acquireMaster()); + Cs::reset(); + + %% if spi_16bit_hardware + Spi::setDataSize(Spi::DataSize::Bit8); + %% endif + + Dc::reset(); + RF_CALL(Spi::transmit(uint8_t(command))); + Dc::set(); + + %% if spi_16bit_hardware + if constexpr(std::is_same::value) + Spi::setDataSize(Spi::DataSize::Bit16); + %% endif + + RF_CALL(Spi::transmit(data_first, data_last)); + + if (this->releaseMaster()) + Cs::set(); + + RF_END(); + } + + modm::ResumableResult + writeCommand(Command command, const uint16_t *data, uint16_t length) + { + RF_BEGIN(); + + RF_WAIT_UNTIL(this->acquireMaster()); + Cs::reset(); + + %% if spi_16bit_hardware + Spi::setDataSize(Spi::DataSize::Bit8); + %% endif + + Dc::reset(); + RF_CALL(Spi::transmit(uint8_t(command))); + Dc::set(); + + %% if spi_16bit_hardware + Spi::setDataSize(Spi::DataSize::Bit16); + %% endif + + RF_CALL(Spi::transfer16(data, nullptr, length)); + + if (this->releaseMaster()) + Cs::set(); + + RF_END(); + } + + modm::ResumableResult + readData(Command command) + { + RF_BEGIN(); + + RF_WAIT_UNTIL(this->acquireMaster()); + Cs::reset(); + + %% if spi_16bit_hardware + Spi::setDataSize(Spi::DataSize::Bit8); + %% endif + + Dc::reset(); + RF_CALL(Spi::transmit(uint8_t(command))); + Dc::set(); + + // REIMPLEMENT + // read = RF_CALL(Spi::transmit(0)).getResult(); + + if (this->releaseMaster()) + Cs::set(); + + RF_END_RETURN(read); + } + + template + modm::ResumableResult + readData(Command command, T *data_first, T *data_last) + { + RF_BEGIN(); + + RF_WAIT_UNTIL(this->acquireMaster()); + Cs::reset(); + + %% if spi_16bit_hardware + Spi::setDataSize(Spi::DataSize::Bit8); + %% endif + + Dc::reset(); + RF_CALL(Spi::transmit(uint8_t(command))); + Dc::set(); + + %% if spi_16bit_hardware + if constexpr(std::is_same::value) + Spi::setDataSize(Spi::DataSize::Bit16); + %% endif + + // REIMPLEMENT + // RF_CALL(Spi::receive(data_first, data_last)); + + if (this->releaseMaster()) + Cs::set(); + + RF_END(); + } + +// - Write / Read CGRAM ---------------------------------------- + + + modm::ResumableResult + writePixel(color::Rgb565 pixel) + { + RF_BEGIN(); + + RF_WAIT_UNTIL(this->acquireMaster()); + Cs::reset(); + + %% if spi_16bit_hardware + Spi::setDataSize(Spi::DataSize::Bit8); + %% endif + + RF_CALL(Spi::transmit(pixel.getValue())); + + if (this->releaseMaster()) + Cs::set(); + + RF_END(); + } + + modm::ResumableResult + writePixels(color::Rgb565 pixel, uint16_t repeat) + { + RF_BEGIN(); + + RF_WAIT_UNTIL(this->acquireMaster()); + Cs::reset(); + + %% if spi_16bit_hardware + Spi::setDataSize(Spi::DataSize::Bit16); + %% endif + + RF_CALL(Spi::transmit(pixel.getValue(), repeat)); + + if (this->releaseMaster()) + Cs::set(); + + RF_END(); + } + + modm::ResumableResult + writePixels(const color::Rgb565 *pixel_first, const color::Rgb565 *pixel_last) + { + RF_BEGIN(); + + RF_WAIT_UNTIL(this->acquireMaster()); + Cs::reset(); + + %% if spi_16bit_hardware + Spi::setDataSize(Spi::DataSize::Bit16); + %% endif + + RF_CALL(Spi::transmit((uint16_t*)(pixel_first), (uint16_t*)(pixel_last))); + + if (this->releaseMaster()) + Cs::set(); + + RF_END(); + } +}; + +} // namespace modm \ No newline at end of file diff --git a/src/modm/driver/display/ili9341_parallel.hpp b/src/modm/driver/display/ili9341_parallel.hpp deleted file mode 100644 index 4a282e32a3..0000000000 --- a/src/modm/driver/display/ili9341_parallel.hpp +++ /dev/null @@ -1,85 +0,0 @@ -/* - * 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/. - */ -#ifndef MODM_ILI9341_PARALLEL_HPP -#define MODM_ILI9341_PARALLEL_HPP - -#include "ili9341.hpp" - -namespace modm -{ - -/// @ingroup modm_driver_ili9341 -template -class Ili9341ParallelInterface: public ili9341 -{ - INTERFACE& interface; -public: - Ili9341ParallelInterface(INTERFACE& interface) - : interface(interface) {} - - __attribute__((noinline)) void - writeCommand(Command command) - { - interface.writeIndex(i(command)); - } - __attribute__((noinline)) void - writeCommand(Command command, uint8_t const *args, std::size_t length) - { - interface.writeIndex(i(command)); - for(std::size_t i=0; i(data); - size_t const length16 = length / 2; - for(std::size_t i=0; i -using Ili9341Parallel = Ili9341< - Ili9341ParallelInterface, - Reset, Backlight, BufferSize>; - -} // namespace modm - -#endif // MODM_ILI9341_PARALLEL_HPP diff --git a/src/modm/driver/display/ili9341_spi.hpp b/src/modm/driver/display/ili9341_spi.hpp deleted file mode 100644 index 7f145dde49..0000000000 --- a/src/modm/driver/display/ili9341_spi.hpp +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright (c) 2019, Mike Wolfram - * - * 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_ILI9341_SPI_HPP -#define MODM_ILI9341_SPI_HPP - -#include "ili9341.hpp" -#include -#include - -namespace modm -{ - -/// @ingroup modm_driver_ili9341 -template -class Ili9341SPIInterface: public ili9341, public modm::SpiDevice -{ -public: - Ili9341SPIInterface() - { - this->attachConfigurationHandler([]() { - SPI::setDataMode(SPI::DataMode::Mode0); - SPI::setDataOrder(SPI::DataOrder::MsbFirst); - }); - Cs::setOutput(modm::Gpio::High); - Dc::setOutput(); - } - - __attribute__((noinline)) void - writeCommand(Command command) - { - Dc::reset(); // enable command - SPI::transferBlocking(i(command)); - Dc::set(); // reset to data - } - __attribute__((noinline)) void - writeCommand(Command command, uint8_t const *args, std::size_t length) - { - Dc::reset(); // enable command - SPI::transferBlocking(i(command)); - Dc::set(); // reset to data - if (length != 0) - { - SPI::transferBlocking(const_cast(args), nullptr, length); - } - } - void - writeData(uint8_t const *data, std::size_t length) - { - SPI::transferBlocking(const_cast(data), nullptr, length); - } - void - writeCommandValue8(Command command, uint8_t value) - { - writeCommand(command, &value, 1); - } - - void - readData(Command command, uint8_t *buffer, std::size_t length) - { - using modm::platform::SpiBase; - uint8_t b[4]; - - Dc::reset(); // enable command - // SPI::Hal::setDataSize(SpiBase::DataSize::Bit9); - SPI::transferBlocking(i(command) << 1); - SPI::Hal::setDataSize(SpiBase::DataSize::Bit8); - Dc::set(); // reset to data - SPI::transferBlocking(b /*nullptr*/, buffer, length); - } - uint8_t - readData(Command command) - { - writeCommand(command); - return SPI::transferBlocking(0x00); - } - -public: - struct BatchHandle - { - Ili9341SPIInterface& i; - BatchHandle(Ili9341SPIInterface& iface) - : i(iface) - { - i.acquireMaster(); - Cs::reset(); - } - ~BatchHandle() - { - if (i.releaseMaster()) - Cs::set(); - } - }; -}; - -/// @ingroup modm_driver_ili9341 -template -using Ili9341Spi = Ili9341< - Ili9341SPIInterface, - Reset, Backlight, BufferSize>; - -} // namespace modm - -#endif // MODM_ILI9341_SPI_HPP diff --git a/src/modm/driver/display/sh1106.hpp b/src/modm/driver/display/sh1106.hpp index 92120d7c80..6c8fb8f293 100644 --- a/src/modm/driver/display/sh1106.hpp +++ b/src/modm/driver/display/sh1106.hpp @@ -10,6 +10,8 @@ // ---------------------------------------------------------------------------- #pragma once +#ifndef MODM_SH1106_HPP +#define MODM_SH1106_HPP #include "ssd1306.hpp" @@ -25,51 +27,54 @@ namespace modm * * @ingroup modm_driver_sh1106 */ -template -class Sh1106 : public Ssd1306 + +template +class Sh1106 : public Ssd1306 { public: - Sh1106(uint8_t address = 0x3C) : Ssd1306(address) {} - -protected: - modm::ResumableResult - startWriteDisplay() override - { - RF_BEGIN(); - - this->transaction_success = true; - - this->commandBuffer[0] = ssd1306::AdressingCommands::HigherColumnStartAddress; - this->commandBuffer[1] = 0x02; - - for (page = 0; page < Height / 8; page++) - { - this->commandBuffer[2] = 0xB0 | page; - this->transaction_success &= RF_CALL(this->writeCommands(3)); + using ColorType = Ssd1306::ColorType; + using Buffer = Ssd1306::Buffer; - RF_WAIT_UNTIL( - this->transaction.configureDisplayWrite((uint8_t*)&this->buffer[page], 128)); - RF_WAIT_UNTIL(this->startTransaction()); - RF_WAIT_WHILE(this->isTransactionRunning()); - this->transaction_success &= this->wasTransactionSuccessful(); - }; + Sh1106(uint8_t address = 0x3C) : Ssd1306(address) {} - RF_END_RETURN(this->transaction_success); + // TODO Abstract these write(...) cause is common to all I2c Displays! + // Write BufferInterface + modm::ResumableResult + write(graphic::BufferInterface &buffer, shape::Point placement = {0, 0}) { + RF_BEGIN(); + RF_END_RETURN_CALL(writeImage(graphic::ImageAccessor(&buffer, placement))); } - modm::ResumableResult - initializeMemoryMode() override - { + // Write Flash Image + modm::ResumableResult + write(const uint8_t *addr, shape::Point placement = {0, 0}) { RF_BEGIN(); - // Default on Power-up - can be omitted - this->commandBuffer[0] = ssd1306::AdressingCommands::MemoryMode; - this->commandBuffer[1] = ssd1306::MemoryMode::PAGE; - this->transaction_success &= RF_CALL(this->writeCommands(2)); - RF_END(); + // TODO Support other than ColorType + RF_END_RETURN_CALL(writeImage(graphic::ImageAccessor(addr, placement))); } -private: - size_t page; +protected: + modm::ResumableResult + initializeMemoryMode() override; + + modm::ResumableResult + updateClipping() final; + + // Write monochrome Image + // Caution: placement.y rounds to multiples of 8 + template class Accessor> + modm::ResumableResult + writeImage(graphic::ImageAccessor accessor); + + // Static variables for Resumable Functions + size_t yd; // vertical index in display (page) + size_t yd_start; // first vertical index in display + size_t yd_end; // last vertical index in display + size_t yb; // vertical position in buffer }; } // namespace modm + +#include "sh1106_impl.hpp" + +#endif // MODM_SH1106_HPP \ No newline at end of file diff --git a/src/modm/driver/display/sh1106.lb b/src/modm/driver/display/sh1106.lb index 4222f45849..4362da26dd 100644 --- a/src/modm/driver/display/sh1106.lb +++ b/src/modm/driver/display/sh1106.lb @@ -22,3 +22,4 @@ def prepare(module, options): def build(env): env.outbasepath = "modm/src/modm/driver/display" env.copy("sh1106.hpp") + env.copy("sh1106_impl.hpp") diff --git a/src/modm/driver/display/sh1106_impl.hpp b/src/modm/driver/display/sh1106_impl.hpp new file mode 100644 index 0000000000..0a0310d4d4 --- /dev/null +++ b/src/modm/driver/display/sh1106_impl.hpp @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2021, Thomas Sommer + * + * 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/. + */ +// ---------------------------------------------------------------------------- + +#pragma once +#include "sh1106.hpp" + +template +modm::ResumableResult +modm::Sh1106::initializeMemoryMode() +{ + RF_BEGIN(); + // Default on Power-up - can be omitted + this->commandBuffer[0] = ssd1306::AdressingCommands::MemoryMode; + this->commandBuffer[1] = ssd1306::MemoryMode::PAGE; + RF_END_RETURN_CALL(this->writeCommands(2)); +} + +template +modm::ResumableResult +modm::Sh1106::updateClipping() +{ + RF_BEGIN(); + + // SH1106-Screen wiring has 2 pixels offset on left + this->commandBuffer[0] = + ssd1306::AdressingCommands::HigherColumnStartAddress | ((this->clipping.topLeft.x + 2) >> 4); + this->commandBuffer[1] = + ssd1306::AdressingCommands::LowerColumnStartAddress | ((this->clipping.topLeft.x + 2) & 0x0F); + + yd_start = this->clipping.topLeft.y / 8; + yd_end = (this->clipping.bottomRight.y / 8) - 1; + + RF_END_RETURN(true); +} + +template +template class Accessor> +modm::ResumableResult +modm::Sh1106::writeImage(graphic::ImageAccessor accessor) { + RF_BEGIN(); + this->clipping = this->getIntersection(accessor.getSection()); + + if (this->pointInCanvas(this->clipping.bottomRight - Point(1, 1))) + { + RF_CALL(updateClipping()); + + this->transaction_success = true; + yb = 0; + + for (yd = yd_start; yd <= yd_end; yd++) + { + this->commandBuffer[2] = ssd1306::AdressingCommands::PageStartAddress | yd; + this->transaction_success &= RF_CALL(this->writeCommands(3)); + + RF_WAIT_UNTIL(this->transaction.configureDisplayWrite(accessor.getPointer() + (this->clipping.getWidth() * yb++), this->clipping.getWidth())); + RF_WAIT_UNTIL(this->startTransaction()); + RF_WAIT_WHILE(this->isTransactionRunning()); + this->transaction_success &= this->wasTransactionSuccessful(); + }; + } else { + MODM_LOG_ERROR << "buffer exceeds display border in " << __FUNCTION__ << modm::endl; + this->transaction_success = false; + } + RF_END_RETURN(this->transaction_success); +} \ No newline at end of file diff --git a/src/modm/driver/display/siemens_s65_impl.hpp b/src/modm/driver/display/siemens_s65_impl.hpp index 94eeddc200..a7adcd011e 100644 --- a/src/modm/driver/display/siemens_s65_impl.hpp +++ b/src/modm/driver/display/siemens_s65_impl.hpp @@ -280,7 +280,7 @@ modm::SiemensS65Portrait::update() { } // pix // use transfer() of SPI to transfer spiBuffer - SPI::transferBlocking(spiBuffer, nullptr, 16); + SPI::transferBlocking(spiBuffer, (uint8_t*)(nullptr), 16); } // y } // x #endif @@ -383,7 +383,7 @@ modm::SiemensS65Landscape::update() { } // pix // use transfer() of SPI to transfer spiBuffer - SPI::transferBlocking(spiBuffer, nullptr, bufSize); + SPI::transferBlocking(spiBuffer, (uint8_t*)(nullptr), bufSize); } // y } // x #endif diff --git a/src/modm/driver/display/ssd1306.hpp b/src/modm/driver/display/ssd1306.hpp index e62881d154..2549afb412 100644 --- a/src/modm/driver/display/ssd1306.hpp +++ b/src/modm/driver/display/ssd1306.hpp @@ -11,15 +11,19 @@ */ // ---------------------------------------------------------------------------- +#pragma once #ifndef MODM_SSD1306_HPP #define MODM_SSD1306_HPP #include #include #include -#include -#include "ssd1306_register.hpp" +#include +#include +#include + +#include "ssd1306_defines.hpp" namespace modm { @@ -50,13 +54,6 @@ struct ssd1306 : public ssd1306_register // LeftBottom = VerticalAndHorizontalScrollLeft, }; - enum class - DisplayMode : uint8_t - { - Normal = NormalDisplay, - Inverted = InvertedDisplay - }; - public: /// @cond class Ssd1306_I2cWriteTransaction : public modm::I2cWriteTransaction @@ -94,15 +91,19 @@ struct ssd1306 : public ssd1306_register * @author Thomas Sommer * @ingroup modm_driver_ssd1306 */ -template +template class Ssd1306 : public ssd1306, - public MonochromeGraphicDisplayVertical<128, Height>, + public graphic::Display, public I2cDevice { - static_assert((Height == 64) or (Height == 32), "Display height must be either 32 or 64 pixel!"); - + static_assert((H == 64) or (H == 32), "Display height must be either 32 or 64 pixel!"); public: - Ssd1306(uint8_t address = 0x3C); + using ColorType = Monochrome; + using Buffer = graphic::Buffer; + + Ssd1306(uint8_t address = 0x3C) + : graphic::Display(true), I2cDevice(address) + {} /// Pings the display bool inline pingBlocking() @@ -112,10 +113,6 @@ class Ssd1306 : public ssd1306, bool inline initializeBlocking() { return RF_CALL_BLOCKING(initialize()); } - /// Update the display with the content of the RAM buffer. - void - update() override - { RF_CALL_BLOCKING(startWriteDisplay()); } /// Use this method to synchronize writing to the displays buffer /// to avoid tearing. @@ -128,16 +125,8 @@ class Ssd1306 : public ssd1306, modm::ResumableResult initialize(); - // starts a frame transfer and waits for completion - virtual modm::ResumableResult - writeDisplay(); - modm::ResumableResult - setDisplayMode(DisplayMode mode = DisplayMode::Normal) - { - commandBuffer[0] = mode; - return writeCommands(1); - } + set(ssd1306_register::Toggle toggle, bool state); modm::ResumableResult setContrast(uint8_t contrast = 0xCE) @@ -148,13 +137,13 @@ class Ssd1306 : public ssd1306, } /** - * \param orientation glcd::Orientation::Landscape0 or glcd::Orientation::Landscape180 + * @param orientation display::Orientation::Landscape0 or display::Orientation::Landscape180 */ modm::ResumableResult - setOrientation(glcd::Orientation orientation); + setOrientation(graphic::Orientation orientation); modm::ResumableResult - configureScroll(uint8_t origin, uint8_t size, ScrollDirection direction, ScrollStep steps); + configureScroll(uint8_t placement, uint8_t size, ScrollDirection direction, ScrollStep steps); modm::ResumableResult enableScroll() @@ -170,16 +159,46 @@ class Ssd1306 : public ssd1306, return writeCommands(1); } + // TODO Abstract these write(...) cause is common to all I2c Displays! + // Write BufferInterface + // Caution: placement.y rounds to multiples of 8 + modm::ResumableResult + write(graphic::BufferInterface &buffer, shape::Point placement = {0, 0}) { + RF_BEGIN(); + RF_END_RETURN_CALL(writeImage(graphic::ImageAccessor(&buffer, placement))); + } + + // Write Flash Image + modm::ResumableResult + write(const uint8_t *addr, shape::Point placement = {0, 0}) { + RF_BEGIN(); + RF_END_RETURN_CALL(writeImage(graphic::ImageAccessor(addr, placement))); + } + + // Clear whole screen with color + modm::ResumableResult + clear(ColorType color = 0); + protected: + virtual modm::ResumableResult + updateClipping(); + + // Write monochrome Image + template class Accessor> + modm::ResumableResult + writeImage(graphic::ImageAccessor accessor); + modm::ResumableResult writeCommands(std::size_t length); - virtual modm::ResumableResult + /** + * MemoryMode::HORIZONTAL and MemoryMode::VERTICAL have the best performance + * because the whole buffer is send in one transaction. + */ + virtual modm::ResumableResult initializeMemoryMode(); - virtual modm::ResumableResult - startWriteDisplay(); - + // Static variables for resumable functions uint8_t commandBuffer[7]; bool transaction_success; }; diff --git a/src/modm/driver/display/ssd1306.lb b/src/modm/driver/display/ssd1306.lb index 0b138e8811..547f0629aa 100644 --- a/src/modm/driver/display/ssd1306.lb +++ b/src/modm/driver/display/ssd1306.lb @@ -19,12 +19,12 @@ def prepare(module, options): module.depends( ":architecture:i2c.device", ":processing:timer", - ":ui:display") + ":ui:graphic") return True def build(env): env.outbasepath = "modm/src/modm/driver/display" + env.copy("ssd1306_defines.hpp") env.copy("ssd1306.hpp") env.copy("ssd1306_impl.hpp") - env.copy("ssd1306_register.hpp") env.copy("ssd1306_i2c_transaction_impl.cpp") diff --git a/src/modm/driver/display/ssd1306_register.hpp b/src/modm/driver/display/ssd1306_defines.hpp similarity index 71% rename from src/modm/driver/display/ssd1306_register.hpp rename to src/modm/driver/display/ssd1306_defines.hpp index 37d8ea0e5b..e0ab5e5719 100644 --- a/src/modm/driver/display/ssd1306_register.hpp +++ b/src/modm/driver/display/ssd1306_defines.hpp @@ -16,6 +16,12 @@ namespace modm struct ssd1306_register { +public: + // Bit0 => false: Off, true: On + enum Toggle : uint8_t { + Inversion = 0xA6, + Enable = 0xAE + }; protected: enum Transfer : uint8_t { @@ -27,23 +33,19 @@ struct ssd1306_register enum FundamentalCommands : uint8_t { - ContrastControl = 0x81, // Range 1-255 + ContrastControl = 0x81, // Range 1-255 EntireDisplayResumeToRam = 0xA4, EntireDisplayIgnoreRam = 0xA5, - NormalDisplay = 0xA6, - InvertedDisplay = 0xA7, - DisplayOff = 0xAE, - DisplayOn = 0xAF, }; enum AdressingCommands : uint8_t { - MemoryMode = 0x20, // enum MemoryMode + MemoryMode = 0x20, // enum MemoryMode // HORIZONTAL and VERTICAL addressing only - ColumnAddress = 0x21, // Range 0-127 - PageAddress = 0x22, // Range 0-7 + ColumnAddress = 0x21, // Range 0-127 + PageAddress = 0x22, // Range 0-7 // PAGE addressing only - PageStartAddress = 0xB0, // Range 0-7 + PageStartAddress = 0xB0, // Range 0-7 LowerColumnStartAddress = 0x00, HigherColumnStartAddress = 0x10, }; @@ -53,11 +55,11 @@ struct ssd1306_register DisplayStartLine = 0x40, SegmentRemap0 = 0xA0, SegmentRemap127 = 0xA1, - MultiplexRatio = 0xA8, // Range 16-64 + MultiplexRatio = 0xA8, // Range 16-64 ComOutputScanDirectionIncrement = 0xC0, ComOutputScanDirectionDecrement = 0xC8, - DisplayOffset = 0xD3, // Range 0-63 - ComPinsOrder = 0xDA, // enum ComPinsOrder + DisplayOffset = 0xD3, // Range 0-63 + ComPinsOrder = 0xDA, }; enum ScrollingCommands : uint8_t @@ -71,6 +73,15 @@ struct ssd1306_register EnableScroll = 0x2F, }; + enum TimingAndDrivingCommands : uint8_t + { + ChargePump = 0x8D, // enum ChargePump + DisplayClockDivideRatio = 0xD5, // [7:4] Frequency [3:0] Prescaler + PreChargePeriod = 0xD9, + V_DeselectLevel = 0xDB, // 0: ~0.65 x VCC, 1: 0.71 x VCC, 2: 0.77 x VCC, 3: 0.83 x VCC + Nop = 0xE3 + }; + enum MemoryMode : uint8_t { HORIZONTAL = 0, @@ -78,15 +89,6 @@ struct ssd1306_register PAGE = 2 }; - enum TimingAndDrivingCommands : uint8_t - { - ChargePump = 0x8D, // enum ChargePump - DisplayClockDivideRatio = 0xD5, // [7:4] Frequency [3:0] Prescaler - PreChargePeriod = 0xD9, - V_DeselectLevel = 0xDB, // 0: ~0.65 x VCC, 1: 0.71 x VCC, 2: 0.77 x VCC, 3: 0.83 x VCC - Nop = 0xE3 - }; - enum ChargePump : uint8_t { DISABLE = 0x00, diff --git a/src/modm/driver/display/ssd1306_impl.hpp b/src/modm/driver/display/ssd1306_impl.hpp index cde8634f40..c022ec9760 100644 --- a/src/modm/driver/display/ssd1306_impl.hpp +++ b/src/modm/driver/display/ssd1306_impl.hpp @@ -9,153 +9,117 @@ */ // ---------------------------------------------------------------------------- -#ifndef MODM_SSD1306_HPP -#error "Don't include this file directly, use 'ssd1306.hpp' instead!" -#endif +#pragma once +#include "ssd1306.hpp" -template -modm::Ssd1306::Ssd1306(uint8_t address) - : I2cDevice(address) -{} - -// ---------------------------------------------------------------------------- -// MARK: - Tasks -template +template modm::ResumableResult -modm::Ssd1306::initialize() +modm::Ssd1306::initialize() { RF_BEGIN(); transaction_success = true; - commandBuffer[0] = FundamentalCommands::DisplayOff; - commandBuffer[1] = TimingAndDrivingCommands::DisplayClockDivideRatio; - commandBuffer[2] = 8 << 4; // Frequency (influences scrolling speed too) - commandBuffer[2] |= 0; // Prescaler - commandBuffer[3] = HardwareConfigCommands::MultiplexRatio; - commandBuffer[4] = 63; // Range 0-63 - commandBuffer[5] = HardwareConfigCommands::DisplayOffset; - commandBuffer[6] = 0; // Range 0-63 - transaction_success &= RF_CALL(writeCommands(7)); + transaction_success &= RF_CALL(set(Toggle::Enable, false)); - RF_CALL(initializeMemoryMode()); + commandBuffer[0] = TimingAndDrivingCommands::DisplayClockDivideRatio; + commandBuffer[1] = 8 << 4; // Frequency (influences scrolling speed too) + commandBuffer[1] |= 0; // Prescaler + commandBuffer[2] = HardwareConfigCommands::MultiplexRatio; + commandBuffer[3] = 63; // Range 0-63 + commandBuffer[4] = HardwareConfigCommands::DisplayOffset; + commandBuffer[5] = 0; // Range 0-63 + transaction_success &= RF_CALL(writeCommands(6)); + + transaction_success &= RF_CALL(initializeMemoryMode()); commandBuffer[0] = TimingAndDrivingCommands::ChargePump; commandBuffer[1] = ChargePump::V7_5; commandBuffer[2] = HardwareConfigCommands::SegmentRemap127; commandBuffer[3] = HardwareConfigCommands::ComOutputScanDirectionDecrement; commandBuffer[4] = HardwareConfigCommands::DisplayStartLine; - commandBuffer[4] |= 0; // Range 0-63 + commandBuffer[4] |= 0; // Range 0-63 transaction_success &= RF_CALL(writeCommands(5)); commandBuffer[0] = HardwareConfigCommands::ComPinsOrder; - commandBuffer[1] = Height == 64 ? 0x12 : 0x02; + commandBuffer[1] = H == 64 ? 0x12 : 0x02; commandBuffer[2] = FundamentalCommands::ContrastControl; - commandBuffer[3] = 0xCF; // Strange non-linear beahaviour + commandBuffer[3] = 0xCF; // Strange non-linear beahaviour commandBuffer[4] = TimingAndDrivingCommands::PreChargePeriod; - commandBuffer[5] = 1; // [3:0] Phase 1 period - commandBuffer[5] |= 15 << 4;// [7:4] Phase 2 period + commandBuffer[5] = 1; // [3:0] Phase 1 period + commandBuffer[5] |= 15 << 4; // [7:4] Phase 2 period transaction_success &= RF_CALL(writeCommands(6)); commandBuffer[0] = TimingAndDrivingCommands::V_DeselectLevel; - commandBuffer[1] = 4 << 4; // [7:4] See Datasheet + commandBuffer[1] = 4 << 4; // [7:4] See Datasheet commandBuffer[2] = ScrollingCommands::DisableScroll; commandBuffer[3] = FundamentalCommands::EntireDisplayResumeToRam; - commandBuffer[4] = FundamentalCommands::NormalDisplay; - transaction_success &= RF_CALL(writeCommands(5)); + transaction_success &= RF_CALL(writeCommands(4)); - commandBuffer[0] = FundamentalCommands::DisplayOn; - transaction_success &= RF_CALL(writeCommands(1)); + transaction_success &= RF_CALL(set(Toggle::Inversion, false)); + transaction_success &= RF_CALL(set(Toggle::Enable, true)); RF_END_RETURN(transaction_success); } -/** - * @brief MemoryMode::HORIZONTAL and MemoryMode::VERTICAL - * have the best performance cause the whole buffer - * is send in one transaction. - */ -template -modm::ResumableResult -modm::Ssd1306::initializeMemoryMode() +template +modm::ResumableResult +modm::Ssd1306::initializeMemoryMode() { RF_BEGIN(); commandBuffer[0] = AdressingCommands::MemoryMode; commandBuffer[1] = MemoryMode::HORIZONTAL; - transaction_success &= RF_CALL(writeCommands(2)); - - // Default on Power-up - can be omitted - commandBuffer[0] = AdressingCommands::ColumnAddress; - commandBuffer[1] = 0; - commandBuffer[2] = 127; - commandBuffer[3] = AdressingCommands::PageAddress; - commandBuffer[4] = 0; - commandBuffer[5] = 7; - transaction_success &= RF_CALL(writeCommands(6)); - - RF_END(); -} - -// ---------------------------------------------------------------------------- -template -modm::ResumableResult -modm::Ssd1306::startWriteDisplay() -{ - RF_BEGIN(); - - RF_WAIT_UNTIL( - this->transaction.configureDisplayWrite((uint8_t*)(&this->buffer), sizeof(this->buffer)) and - this->startTransaction()); - - RF_END(); + RF_END_RETURN_CALL(writeCommands(2)); } -template +template modm::ResumableResult -modm::Ssd1306::writeDisplay() +modm::Ssd1306::setOrientation(graphic::Orientation orientation) { RF_BEGIN(); - RF_CALL(startWriteDisplay()); + // No support for Portrait + if(orientation & graphic::OrientationFlags::Portrait) + RF_RETURN(false); - RF_WAIT_WHILE(this->isTransactionRunning()); + switch (orientation) + { + case graphic::Orientation::Landscape0: + commandBuffer[0] = HardwareConfigCommands::SegmentRemap127; + commandBuffer[1] = HardwareConfigCommands::ComOutputScanDirectionDecrement; + break; + case graphic::Orientation::Landscape180: + commandBuffer[0] = HardwareConfigCommands::SegmentRemap0; + commandBuffer[1] = HardwareConfigCommands::ComOutputScanDirectionIncrement; + break; + } - RF_END_RETURN(this->wasTransactionSuccessful()); + RF_CALL(writeCommands(2)); + RF_END_RETURN_CALL(clear()); } -template +template modm::ResumableResult -modm::Ssd1306::setOrientation(glcd::Orientation orientation) -{ +modm::Ssd1306::set(Toggle toggle, bool state) { RF_BEGIN(); - if (orientation == glcd::Orientation::Landscape0) - { - commandBuffer[0] = HardwareConfigCommands::SegmentRemap127; - commandBuffer[1] = HardwareConfigCommands::ComOutputScanDirectionDecrement; - } - else if (orientation == glcd::Orientation::Landscape180) - { - commandBuffer[0] = HardwareConfigCommands::SegmentRemap0; - commandBuffer[1] = HardwareConfigCommands::ComOutputScanDirectionIncrement; - } + commandBuffer[0] = uint8_t(toggle) | uint8_t(state); - RF_END_RETURN_CALL(writeCommands(2)); + RF_END_RETURN_CALL(writeCommands(1)); } -template +template modm::ResumableResult -modm::Ssd1306::configureScroll(uint8_t origin, uint8_t size, +modm::Ssd1306::configureScroll(uint8_t placement, uint8_t size, ScrollDirection direction, ScrollStep steps) { RF_BEGIN(); - if (!RF_CALL(disableScroll())) - RF_RETURN(false); + if (!RF_CALL(disableScroll())) RF_RETURN(false); { - uint8_t beginY = (origin > 7) ? 7 : origin; + uint8_t beginY = (placement > 7) ? 7 : placement; - uint8_t endY = ((origin + size) > 7) ? 7 : (origin + size); + uint8_t endY = ((placement + size) > 7) ? 7 : (placement + size); if (endY < beginY) endY = beginY; commandBuffer[0] = uint8_t(direction); @@ -170,11 +134,9 @@ modm::Ssd1306::configureScroll(uint8_t origin, uint8_t size, RF_END_RETURN_CALL(writeCommands(7)); } -// ---------------------------------------------------------------------------- -// MARK: write command -template +template modm::ResumableResult -modm::Ssd1306::writeCommands(std::size_t length) +modm::Ssd1306::writeCommands(std::size_t length) { RF_BEGIN(); @@ -184,3 +146,73 @@ modm::Ssd1306::writeCommands(std::size_t length) RF_END_RETURN(this->wasTransactionSuccessful()); } + +template +modm::ResumableResult +modm::Ssd1306::updateClipping() +{ + RF_BEGIN(); + + commandBuffer[0] = AdressingCommands::ColumnAddress; + commandBuffer[1] = this->clipping.topLeft.x; + commandBuffer[2] = this->clipping.bottomRight.x - 1; + commandBuffer[3] = AdressingCommands::PageAddress; + commandBuffer[4] = this->clipping.topLeft.y / 8; + commandBuffer[5] = (this->clipping.bottomRight.y / 8) - 1; + + RF_END_RETURN_CALL(writeCommands(6)); +} + +#include + +template +template class Accessor> +modm::ResumableResult +modm::Ssd1306::writeImage(graphic::ImageAccessor accessor) { + RF_BEGIN(); + + this->clipping = this->getIntersection(accessor.getSection()); + + if(!this->pointInCanvas(this->clipping.bottomRight - Point(1, 1))) { + MODM_LOG_ERROR << "buffer exceeds display border in " << __FUNCTION__ << modm::endl; + RF_RETURN(false); + } + + RF_CALL(updateClipping()); + + // FIXME Integrate this->clipping results + RF_WAIT_UNTIL(this->transaction.configureDisplayWrite(accessor.getPointer(), this->clipping.getPixels() / 8)); + + this->startTransaction(); + RF_WAIT_WHILE(this->isTransactionRunning()); + + RF_END_RETURN(this->wasTransactionSuccessful()); +} + +// TODO Test in Hardware +template +modm::ResumableResult +modm::Ssd1306::clear(ColorType color) +{ + // OPTIMIZE Make this impossible fast through use of DMA + // See https://github.com/modm-io/modm/issues/666 + RF_BEGIN(); + + // FIXME Gray8(color).value is not very accurate + std::fill(commandBuffer[0], commandBuffer[7], Gray8(color).value); + transaction_success = true; + + this->clipping = Section({0, 0}, {128, H}); + RF_CALL(updateClipping()); + + while(true) { + RF_WAIT_UNTIL(this->transaction.configureDisplayWrite(commandBuffer, 7)); + this->startTransaction(); + RF_WAIT_WHILE(this->isTransactionRunning()); + transaction_success &= this->wasTransactionSuccessful(); + + // TODO Needs end condition + } + + RF_END_RETURN(true); +} \ No newline at end of file diff --git a/src/modm/driver/display/st7586s.hpp b/src/modm/driver/display/st7586s.hpp index a4fb666d6d..84755b3df8 100644 --- a/src/modm/driver/display/st7586s.hpp +++ b/src/modm/driver/display/st7586s.hpp @@ -26,6 +26,7 @@ class St7586s : public MonochromeGraphicDisplayHorizontal static constexpr uint8_t pixelsPerByte = 3; void sendCommand(Command cmd, const void *data = nullptr, size_t len = 0); + template void sendCommand(Command cmd, Data data) { sendCommand(cmd, &data, sizeof(data)); diff --git a/src/modm/driver/display/st7586s_impl.hpp b/src/modm/driver/display/st7586s_impl.hpp index e29336c6d2..acdf953eee 100644 --- a/src/modm/driver/display/st7586s_impl.hpp +++ b/src/modm/driver/display/st7586s_impl.hpp @@ -27,7 +27,7 @@ St7586s::sendCommand(Command cmd, const void *d SPI::transferBlocking(static_cast(cmd)); DC::set(); // data mode if (len > 0) { - SPI::transferBlocking(reinterpret_cast(data), nullptr, len); + SPI::transferBlocking(reinterpret_cast(data), (uint8_t*)(nullptr), len); } CS::set(); // exit with data mode on diff --git a/src/modm/driver/gpio/mcp23_transport_impl.hpp b/src/modm/driver/gpio/mcp23_transport_impl.hpp index 4c9ee8e411..9de3ac89cf 100644 --- a/src/modm/driver/gpio/mcp23_transport_impl.hpp +++ b/src/modm/driver/gpio/mcp23_transport_impl.hpp @@ -136,7 +136,7 @@ modm::Mcp23TransportSpi::read(uint8_t reg, uint8_t *buffer, uint8 RF_CALL(SpiMaster::transfer(address | Read)); RF_CALL(SpiMaster::transfer(reg)); - RF_CALL(SpiMaster::transfer(nullptr, buffer, length)); + RF_CALL(SpiMaster::transfer((uint8_t*)(nullptr), buffer, length)); if (this->releaseMaster()) Cs::set(); diff --git a/src/modm/driver/inertial/lis3_transport_impl.hpp b/src/modm/driver/inertial/lis3_transport_impl.hpp index d68ca82c6a..7f7f826522 100644 --- a/src/modm/driver/inertial/lis3_transport_impl.hpp +++ b/src/modm/driver/inertial/lis3_transport_impl.hpp @@ -84,7 +84,7 @@ modm::Lis3TransportSpi::write(uint8_t reg, uint8_t value) RF_WAIT_UNTIL(this->acquireMaster()); Cs::reset(); - RF_CALL(SpiMaster::transfer(reg | Write)); + RF_CALL(SpiMaster::transfer(uint8_t(reg | Write))); RF_CALL(SpiMaster::transfer(value)); if (this->releaseMaster()) @@ -103,9 +103,9 @@ modm::Lis3TransportSpi::read(uint8_t reg, uint8_t *buffer, uint8_ RF_WAIT_UNTIL(this->acquireMaster()); Cs::reset(); - RF_CALL(SpiMaster::transfer(reg | Read)); + RF_CALL(SpiMaster::transfer(uint8_t(reg | Read))); - RF_CALL(SpiMaster::transfer(nullptr, buffer, length)); + RF_CALL(SpiMaster::transfer((uint8_t*)(nullptr), buffer, length)); if (this->releaseMaster()) Cs::set(); diff --git a/src/modm/driver/pwm/apa102.hpp b/src/modm/driver/pwm/apa102.hpp index b9b5e79d32..f09b2a4070 100644 --- a/src/modm/driver/pwm/apa102.hpp +++ b/src/modm/driver/pwm/apa102.hpp @@ -90,7 +90,7 @@ class Apa102 modm::ResumableResult write() { - return SpiMaster::transfer(data, nullptr, length); + return SpiMaster::transfer(data, (uint8_t*)(nullptr), length); } }; diff --git a/src/modm/driver/pwm/tlc594x_impl.hpp b/src/modm/driver/pwm/tlc594x_impl.hpp index ea20a410f5..538a42a12d 100644 --- a/src/modm/driver/pwm/tlc594x_impl.hpp +++ b/src/modm/driver/pwm/tlc594x_impl.hpp @@ -225,7 +225,7 @@ modm::TLC594X::writeDotCorrection(bool Vprog::set(); // transfer - RF_CALL(Spi::transfer(dc, nullptr, CHANNELS*3/4)); + RF_CALL(Spi::transfer(dc, (uint8_t*)(nullptr), CHANNELS*3/4)); if (flush) latch(); Vprog::reset(); diff --git a/src/modm/driver/radio/sx1276_impl.hpp b/src/modm/driver/radio/sx1276_impl.hpp index ef41310150..ff8fbf3a5f 100644 --- a/src/modm/driver/radio/sx1276_impl.hpp +++ b/src/modm/driver/radio/sx1276_impl.hpp @@ -173,8 +173,8 @@ Sx1276::transmit(uint8_t* data, uint8_t length) Cs::reset(); - RF_CALL(SpiMaster::transfer(buffer,nullptr,1)); - RF_CALL(SpiMaster::transfer(data,nullptr,length)); + RF_CALL(SpiMaster::transfer(buffer, (uint8_t*)(nullptr), 1)); + RF_CALL(SpiMaster::transfer(data, (uint8_t*)(nullptr), length)); if(this->releaseMaster()) { @@ -251,16 +251,16 @@ Sx1276::readPacket(uint8_t* data, uint8_t maxLength) Cs::reset(); - RF_CALL(SpiMaster::transfer(buffer,nullptr,1)); + RF_CALL(SpiMaster::transfer(buffer, (uint8_t*)(nullptr), 1)); if(lastPacketSize > maxLength) { MODM_LOG_ERROR<<"SX1276: Read buffer is too small, packet discarded!"<releaseMaster()) diff --git a/src/modm/driver/storage/block_device_spiflash_impl.hpp b/src/modm/driver/storage/block_device_spiflash_impl.hpp index 3e4a3431f0..6c33babab4 100644 --- a/src/modm/driver/storage/block_device_spiflash_impl.hpp +++ b/src/modm/driver/storage/block_device_spiflash_impl.hpp @@ -202,7 +202,7 @@ modm::BdSpiFlash::spiOperation(Instruction instruction, size RF_WAIT_UNTIL(this->acquireMaster()); Cs::reset(); - RF_CALL(Spi::transfer(instructionBuffer, nullptr, i)); + RF_CALL(Spi::transfer(instructionBuffer, (uint8_t*)(nullptr), i)); if(dataLength > 0) { RF_CALL(Spi::transfer(const_cast(txData), rxData, dataLength)); diff --git a/src/modm/driver/temperature/ltc2984_impl.hpp b/src/modm/driver/temperature/ltc2984_impl.hpp index 9b83a3f517..6092e7e220 100644 --- a/src/modm/driver/temperature/ltc2984_impl.hpp +++ b/src/modm/driver/temperature/ltc2984_impl.hpp @@ -140,7 +140,7 @@ modm::Ltc2984::writeData(Register address, uint8_t* data, size_t buffer[3+i] = data[length-1-i]; } - RF_CALL(SpiMaster::transfer(buffer, nullptr, length+3)); + RF_CALL(SpiMaster::transfer(buffer, (uint8_t*)(nullptr), length+3)); if (this->releaseMaster()) { Cs::set(); @@ -170,8 +170,8 @@ modm::Ltc2984::readFourBytes(Register address, uint8_t* data) buffer[1] = static_cast(address) >> 8; buffer[2] = static_cast(address); - RF_CALL(SpiMaster::transfer(buffer, nullptr, 3)); - RF_CALL(SpiMaster::transfer(nullptr, buffer, 4)); + RF_CALL(SpiMaster::transfer(buffer, (uint8_t*)(nullptr), 3)); + RF_CALL(SpiMaster::transfer((uint8_t*)(nullptr), buffer, 4)); // swap byte order data[0] = buffer[3]; @@ -200,8 +200,8 @@ modm::Ltc2984::readByte(Register address, uint8_t& command) buffer[1] = static_cast(address) >> 8; buffer[2] = static_cast(address); - RF_CALL(SpiMaster::transfer(buffer, nullptr, 3)); - RF_CALL(SpiMaster::transfer(nullptr, &command, 1)); + RF_CALL(SpiMaster::transfer(buffer, (uint8_t*)(nullptr), 3)); + RF_CALL(SpiMaster::transfer((uint8_t*)(nullptr), &command, 1)); if (this->releaseMaster()) { Cs::set(); diff --git a/src/modm/driver/touch/ads7843_impl.hpp b/src/modm/driver/touch/ads7843_impl.hpp index a8f1ef47fa..8607af6126 100644 --- a/src/modm/driver/touch/ads7843_impl.hpp +++ b/src/modm/driver/touch/ads7843_impl.hpp @@ -98,14 +98,9 @@ modm::Ads7843::readData(uint8_t command) Spi::transferBlocking(command); modm::delay_us(1); - uint16_t temp = Spi::transferBlocking(0x00); - temp <<= 8; - modm::delay_us(1); - - temp |= Spi::transferBlocking(0x00); - temp >>= 3; + uint16_t temp = Spi::transferBlocking(uint16_t(0)); Cs::set(); - return (temp & 0xfff); + return (temp >> 3 & 0xfff); } diff --git a/src/modm/driver/touch/touch2046.hpp b/src/modm/driver/touch/touch2046.hpp index 97f75ce12b..c844dd3f3f 100644 --- a/src/modm/driver/touch/touch2046.hpp +++ b/src/modm/driver/touch/touch2046.hpp @@ -1,6 +1,7 @@ // coding: utf-8 /* * Copyright (c) 2021, Raphael Lehmann + * Copyright (c) 2021, Thomas Sommer * * This file is part of the modm project. * @@ -10,67 +11,120 @@ */ // ---------------------------------------------------------------------------- -#ifndef MODM_TOUCH2046_HPP -#define MODM_TOUCH2046_HPP +#pragma once + +#include +#include #include #include #include - -#include -#include +#include namespace modm { /// \ingroup modm_driver_touch2046 struct touch2046 { - enum class Orientation { - Normal, - //... + enum class Control : uint8_t + { + START = Bit7, // 1: Marks the control byte + + A2 = Bit6, // see enum class ChDiff / ChSingleEnd + A1 = Bit5, + A0 = Bit4, + MODE = Bit3, // see enum class Mode + REF = Bit2, // see enum class Reference + + PD1 = Bit1, // see enum class PowerDown + PD0 = Bit0, + }; + MODM_FLAGS8(Control); + + // Valid when Control::MODE is 0 + enum class ChDiff : uint8_t + { + Z1 = int(Control::A0) | int(Control::A1), + Z2 = int(Control::A2), + X = int(Control::A0) | int(Control::A2), + Y = int(Control::A0) }; + typedef Configuration ChDiff_t; + + // Valid when Control::MODE is 1 + enum class ChSingleEnd : uint8_t + { + TEMP0 = 0, + Y = int(Control::A0), + VBAT = int(Control::A1), + Z1 = int(Control::A0) | int(Control::A1), + Z2 = int(Control::A2), + X = int(Control::A0) | int(Control::A2), + AUX = int(Control::A0) | int(Control::A1), + TEMP1 = int(Control::A0) | int(Control::A1) | int(Control::A2) + }; + typedef Configuration ChSingleEnd_t; + + enum class Mode : uint8_t + { + Res_12Bit = 0, + Res_8Bit = int(Control::MODE) + }; + typedef Configuration Mode_t; + + enum class Reference : uint8_t + { + Differential = 0, + SingleEnded = int(Control::REF) + }; + typedef Configuration Reference_t; + + enum class PowerDown : uint8_t + { + Auto = 0, + RefOff_AdcOn = int(Control::PD0), + RefOn_AdcOff = int(Control::PD1), + AlwaysOn = int(Control::PD0) | int(Control::PD1) + }; + typedef Configuration PowerDown_t; + /** * Calibration values are used to calculate touch point * from raw values. * - * \ref FactorX and \ref FactorY scaled by 1000000 to avoid float - * arithmetic. E.g. to get a factor of 0.75 \ref FactorX has to be - * set to 750'000. - * * isTouched() = bool(Z > ThresholdZ) * * X = (rawX * FactorX / 1000000) + OffsetX * limited to [0, MaxX] * Y = (rawY * FactorY / 1000000) + OffsetY * limited to [0, MaxY] - * - * Orientation (rotation, mirror) are applied after the - * above operations. */ + struct Calibration { + int32_t FactorX = 24; int16_t OffsetX = 0; + int32_t FactorY = 24; int16_t OffsetY = 0; - int32_t FactorX = 1'000'000; - int32_t FactorY = 1'000'000; - uint16_t MaxX = 240; - uint16_t MaxY = 320; - uint16_t ThresholdZ = 1500; - Orientation orientation = Orientation::Normal; + uint16_t ThresholdZ = 1000; }; }; /** * \ingroup modm_driver_touch2046 - * \author Raphael Lehmann + * \author Raphael Lehmann, Thomas Sommer * * Datasheet TSC2046: https://www.ti.com/lit/ds/symlink/tsc2046.pdf */ -template < class SpiMaster, class Cs> +template < class SpiMaster, class Cs, Size R> class Touch2046 : public touch2046, public modm::SpiDevice< SpiMaster >, protected modm::NestedResumable<3> { public: + Touch2046(); + + using Orientation = modm::graphic::Orientation; + /** * Set calibration data * @@ -81,14 +135,6 @@ class Touch2046 : public touch2046, public modm::SpiDevice< SpiMaster >, protect cal = calibration; } - /** - * Get raw X, Y and Z values - * - * \return Position and intensity of touch point. Full int16_t range. - */ - modm::ResumableResult> - getRawValues(); - /** * Is screen touched? * @@ -98,40 +144,57 @@ class Touch2046 : public touch2046, public modm::SpiDevice< SpiMaster >, protect isTouched(); /** - * Get touch position + * Get touch position as tuple * * \return Position (X, Y) of touch point. */ modm::ResumableResult> getTouchPosition(); + /** + * Get touch position as modm::shape::Point + * + * \return Point of touch point. + */ + modm::ResumableResult + getTouchPoint(); + + void setOrientation(Orientation orientation) + { this->orientation = orientation; } + + Orientation getOrientation() const + { return orientation; } + private: - static constexpr uint8_t MeasureZ1 = 0xB1; - static constexpr uint8_t MeasureZ2 = 0xC1; - static constexpr uint8_t MeasureX = 0xD1; - static constexpr uint8_t MeasureY = 0x91; - static constexpr uint8_t Powerdown = 0b1111'1100; - static constexpr std::array bufferWrite = { - MeasureZ1, 0x00, - MeasureZ2, 0x00, - MeasureY, 0x00, - MeasureX, 0x00, - MeasureY, 0x00, - MeasureX, 0x00, - MeasureY, 0x00, - (MeasureX & Powerdown), 0x00, - 0x00}; - std::array bufferRead = {}; + modm::ResumableResult + updateZ(); + + modm::ResumableResult + updateXY(); + + static constexpr Control_t Measure = Control::START | Mode_t(Mode::Res_12Bit) + | Reference_t(Reference::Differential) | PowerDown_t(PowerDown::RefOff_AdcOn); + static constexpr std::array bufferWrite = { + (Measure | ChDiff_t(ChDiff::Z1)).value, + ((Measure | ChDiff_t(ChDiff::Z2)) & ~PowerDown_t::mask()).value, + (Measure | ChDiff_t(ChDiff::X)).value, + (Measure | ChDiff_t(ChDiff::Y)).value, + (Measure | ChDiff_t(ChDiff::X)).value, + (Measure | ChDiff_t(ChDiff::Y)).value, + (Measure | ChDiff_t(ChDiff::X)).value, + ((Measure | ChDiff_t(ChDiff::Y)) & ~PowerDown_t::mask()).value + }; + std::array bufferRead = {}; +public: uint16_t x = 0; uint16_t y = 0; uint16_t z = 0; Calibration cal; -}; -} // modm namespace - -#include "touch2046_impl.hpp" + Orientation orientation = Orientation::Portrait90; +}; +} // namespace modm -#endif // MODM_TOUCH2046_HPP +#include "touch2046_impl.hpp" \ No newline at end of file diff --git a/src/modm/driver/touch/touch2046.lb b/src/modm/driver/touch/touch2046.lb index 56d09b40d6..d419f1dd63 100644 --- a/src/modm/driver/touch/touch2046.lb +++ b/src/modm/driver/touch/touch2046.lb @@ -35,4 +35,6 @@ def prepare(module, options): def build(env): env.outbasepath = "modm/src/modm/driver/touch" env.copy("touch2046.hpp") - env.copy("touch2046_impl.hpp") + + env.substitutions = {'spi_16bit_hardware': env[":target"].has_driver("spi:stm32")} + env.template("touch2046_impl.hpp.in") diff --git a/src/modm/driver/touch/touch2046_impl.hpp b/src/modm/driver/touch/touch2046_impl.hpp deleted file mode 100644 index c5f9718363..0000000000 --- a/src/modm/driver/touch/touch2046_impl.hpp +++ /dev/null @@ -1,79 +0,0 @@ -// coding: utf-8 -/* - * Copyright (c) 2021, Raphael Lehmann - * - * 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_TOUCH2046_HPP - #error "Don't include this file directly, use 'touch2046.hpp' instead!" -#endif - - -template < class SpiMaster, class Cs > -modm::ResumableResult> -modm::Touch2046::getRawValues() -{ - RF_BEGIN(); - - RF_WAIT_UNTIL(this->acquireMaster()); - Cs::reset(); - - RF_CALL(SpiMaster::transfer( - bufferWrite.data(), - reinterpret_cast(bufferRead.data()) + 1, - 17)); - - z = 4095 + (modm::fromBigEndian(bufferRead[1]) >> 3) - - (modm::fromBigEndian(bufferRead[2]) >> 3); - - y = (modm::fromBigEndian(bufferRead[3]) >> 3) - + (modm::fromBigEndian(bufferRead[5]) >> 3) - + (modm::fromBigEndian(bufferRead[7]) >> 3); - - x = (modm::fromBigEndian(bufferRead[4]) >> 3) - + (modm::fromBigEndian(bufferRead[6]) >> 3) - + (modm::fromBigEndian(bufferRead[8]) >> 3); - - if (this->releaseMaster()) { - Cs::set(); - } - - RF_END_RETURN(std::make_tuple(x, y, z)); -} - -template < class SpiMaster, class Cs > -modm::ResumableResult -modm::Touch2046::isTouched() -{ - RF_BEGIN(); - std::tie(std::ignore, std::ignore, z) = RF_CALL(getRawValues()); - RF_END_RETURN(z > cal.ThresholdZ); -} - -template < class SpiMaster, class Cs > -modm::ResumableResult> -modm::Touch2046::getTouchPosition() -{ - RF_BEGIN(); - - std::tie(x, y, std::ignore) = RF_CALL(getRawValues()); - - x = std::min( - ((static_cast(x * cal.FactorX) / 1'000'000) - + cal.OffsetX), - cal.MaxX); - y = std::min( - ((static_cast(y * cal.FactorY) / 1'000'000) - + cal.OffsetY), - cal.MaxY); - - // todo: orientation processing - - RF_END_RETURN(std::make_tuple(x, y)); -} diff --git a/src/modm/driver/touch/touch2046_impl.hpp.in b/src/modm/driver/touch/touch2046_impl.hpp.in new file mode 100644 index 0000000000..060603178b --- /dev/null +++ b/src/modm/driver/touch/touch2046_impl.hpp.in @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2021, Raphael Lehmann + * Copyright (c) 2021, Thomas Sommer + * + * 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/. + */ +// ---------------------------------------------------------------------------- + +#pragma once +#include "touch2046.hpp" + +#include + +template +modm::Touch2046::Touch2046() +{ + this->attachConfigurationHandler([]() { + SpiMaster::setDataMode(SpiMaster::DataMode::Mode0); + SpiMaster::setDataOrder(SpiMaster::DataOrder::MsbFirst); + %% if spi_16bit_hardware + SpiMaster::setDataSize(SpiMaster::DataSize::Bit16); + %% endif + }); + + Cs::setOutput(true); +} + +template +modm::ResumableResult +modm::Touch2046::updateZ() +{ + RF_BEGIN(); + + RF_WAIT_UNTIL(this->acquireMaster()); + Cs::reset(); + + RF_CALL(SpiMaster::transfer16(&bufferWrite[0], &bufferRead[0], 3)); + + z = 4095 + (bufferRead[1] >> 3) - (bufferRead[2] >> 3); + + if (this->releaseMaster()) + Cs::set(); + + RF_END_RETURN(); +} + +template +modm::ResumableResult +modm::Touch2046::updateXY() +{ + RF_BEGIN(); + + RF_WAIT_UNTIL(this->acquireMaster()); + Cs::reset(); + + RF_CALL(SpiMaster::transfer16(&bufferWrite[2], &bufferRead[0], bufferRead.size())); + + if (this->releaseMaster()) + Cs::set(); + + x = (bufferRead[1] >> 3) + (bufferRead[3] >> 3) + (bufferRead[5] >> 3); + y = (bufferRead[2] >> 3) + (bufferRead[4] >> 3) + (bufferRead[6] >> 3); + + static constexpr int scale_shift = 10; + x = std::clamp((((uint32_t)(x * cal.FactorX) >> scale_shift) + cal.OffsetX), 0, R.x); + y = std::clamp((((uint32_t)(y * cal.FactorY) >> scale_shift) + cal.OffsetY), 0, R.y); + + RF_END_RETURN(); +} + +template +modm::ResumableResult +modm::Touch2046::isTouched() +{ + RF_BEGIN(); + RF_CALL(updateZ()); + RF_END_RETURN(z > cal.ThresholdZ); +} + +template +modm::ResumableResult +modm::Touch2046::getTouchPoint() +{ + RF_BEGIN(); + RF_CALL(updateXY()); + + switch(orientation) { + case Orientation::Landscape0: RF_RETURN(Point(R.y - y, R.x - x)); + case Orientation::Portrait90: RF_RETURN(Point(x, R.y - y)); + case Orientation::Landscape180: RF_RETURN(Point(y, x)); + case Orientation::Portrait270: RF_RETURN(Point(R.x - x, y)); + } + + RF_END(); +} + +template +modm::ResumableResult> +modm::Touch2046::getTouchPosition() +{ + RF_BEGIN(); + RF_CALL(updateXY()); + // TODO evaluate orientation & modm::graphic::OrientationFlags::TopDown + if (orientation & modm::graphic::OrientationFlags::Portrait) { + RF_RETURN(std::make_tuple(x, y)); + } else { + RF_RETURN(std::make_tuple(y, x)); + } + RF_END(); +} \ No newline at end of file diff --git a/src/modm/math/filter/s_curve_controller_impl.hpp b/src/modm/math/filter/s_curve_controller_impl.hpp index e2bd72fe5a..898b43cb3c 100644 --- a/src/modm/math/filter/s_curve_controller_impl.hpp +++ b/src/modm/math/filter/s_curve_controller_impl.hpp @@ -113,9 +113,9 @@ modm::SCurveController::update(T error, const T& speed) outputDecrement = std::sqrt(error * parameter.decreaseFactor * 2); } - output = modm::min(outputIncrement, outputDecrement); + output = std::min(outputIncrement, outputDecrement); // TODO smooth breaking if the speedMaximum has changed to a lower value - output = modm::min(output, parameter.speedMaximum); + output = std::min(output, parameter.speedMaximum); if (output < parameter.speedMinimum) { output = parameter.speedMinimum; diff --git a/src/modm/math/geometry/vector2.hpp b/src/modm/math/geometry/vector2.hpp index 7cb06624e9..c5b1daa740 100644 --- a/src/modm/math/geometry/vector2.hpp +++ b/src/modm/math/geometry/vector2.hpp @@ -62,18 +62,11 @@ namespace modm typedef typename GeometricTraits::FloatType FloatType; public: - /** - * \brief Default-Constructor - * - * Creates a Vector with coordinates (0, 0). - */ - Vector(); - - Vector(const T& inX, const T& inY); - - Vector(const Vector &inX, const Vector &inY); - Vector(const T &inX, const Vector &inY); - Vector(const Vector &inX, const T &inY); + constexpr Vector() = default; + constexpr Vector(const T& inX, const T& inY); + constexpr Vector(const Vector &inX, const Vector &inY); + constexpr Vector(const T &inX, const Vector &inY); + constexpr Vector(const Vector &inX, const T &inY); explicit Vector(T inVal); Vector(const Matrix &rhs); @@ -246,8 +239,8 @@ namespace modm const T* ptr() const; Vector operator - () const; - Vector operator - (const Vector &rhs) const; - Vector operator + (const Vector &rhs) const; + constexpr Vector operator - (const Vector &rhs) const; + constexpr Vector operator + (const Vector &rhs) const; T operator * (const Vector &rhs) const; T operator ^ (const Vector &rhs) const; Vector operator * (float rhs) const; diff --git a/src/modm/math/geometry/vector2_impl.hpp b/src/modm/math/geometry/vector2_impl.hpp index b30f16be8e..4c4c57064a 100644 --- a/src/modm/math/geometry/vector2_impl.hpp +++ b/src/modm/math/geometry/vector2_impl.hpp @@ -18,15 +18,7 @@ // ---------------------------------------------------------------------------- template -modm::Vector::Vector() : - x(), - y() -{ -} - -// ---------------------------------------------------------------------------- -template -modm::Vector::Vector(const T& inX, const T& inY) : +constexpr modm::Vector::Vector(const T& inX, const T& inY) : x(inX), y(inY) { @@ -34,7 +26,7 @@ modm::Vector::Vector(const T& inX, const T& inY) : // ---------------------------------------------------------------------------- template -modm::Vector::Vector( +constexpr modm::Vector::Vector( const modm::Vector &inX, const modm::Vector &inY) : x(inX.x), @@ -44,7 +36,7 @@ modm::Vector::Vector( // ---------------------------------------------------------------------------- template -modm::Vector::Vector(const T &inX, const modm::Vector &inY) : +constexpr modm::Vector::Vector(const T &inX, const modm::Vector &inY) : x(inX), y(inY.x) { @@ -52,7 +44,7 @@ modm::Vector::Vector(const T &inX, const modm::Vector &inY) : // ---------------------------------------------------------------------------- template -modm::Vector::Vector(const modm::Vector &inX, const T &inY) : +constexpr modm::Vector::Vector(const modm::Vector &inX, const T &inY) : x(inX.x), y(inY) { @@ -406,7 +398,7 @@ modm::Vector::operator - () const // ---------------------------------------------------------------------------- template -modm::Vector +constexpr modm::Vector modm::Vector::operator - (const modm::Vector &rhs) const { return modm::Vector(x - rhs.x, y - rhs.y); @@ -414,7 +406,7 @@ modm::Vector::operator - (const modm::Vector &rhs) const // ---------------------------------------------------------------------------- template -modm::Vector +constexpr modm::Vector modm::Vector::operator + (const modm::Vector &rhs) const { return modm::Vector(x + rhs.x, y + rhs.y); diff --git a/src/modm/math/saturated/saturated.hpp b/src/modm/math/saturated/saturated.hpp deleted file mode 100644 index 7bd74a6def..0000000000 --- a/src/modm/math/saturated/saturated.hpp +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright (c) 2009-2010, Fabian Greif - * Copyright (c) 2009-2010, Martin Rosekeit - * Copyright (c) 2012, Niklas Hauser - * - * 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_SATURATED_HPP -#define MODM_SATURATED_HPP - -#include - -namespace modm -{ - /** - * \brief Saturated arithmetics - * - * \see http://www.mikrocontroller.net/articles/AVR_Arithmetik/Saturierung - * - * \author Fabian Greif - * - * \todo extend implementation (multiplication etc.) - * \todo add 16-bit datetype assembler implementations for AVRs - * \todo documentation - * \ingroup modm_math_saturated - */ - template - class Saturated - { - typedef modm::SignedType SignedType; - typedef modm::WideType WideType; - - public: - Saturated(); - - Saturated(const T& initialValue); - - inline const T& - getValue() const - { - return value; - } - - Saturated& - operator += (const Saturated& other); - - Saturated& - operator -= (const Saturated& other); - - void - absolute(); - - public: - template - friend Saturated - operator - (const Saturated& x); - - template - friend Saturated - abs(const Saturated& x); - - template - friend Saturated - operator - (const Saturated& a, const Saturated& b); - - template - friend Saturated - operator + (const Saturated& a, const Saturated& b); - - template - friend bool - operator == (const Saturated& a, const Saturated& b); - - template - friend bool - operator != (const Saturated& a, const Saturated& b); - - // TODO > >= < <= - - private: - void - setValue(WideType value); - - T value; - }; - - // ------------------------------------------------------------------------ - - /// \brief Invert value - template - Saturated - operator - (const Saturated& x); - - /// \brief Calculate the absolute value - template - Saturated - abs(const Saturated& x); - - template - Saturated - operator - (const Saturated& a, const Saturated& b); - - template - Saturated - operator + (const Saturated& a, const Saturated& b); - - template - inline bool - operator == (const Saturated& a, const Saturated& b); - - template - inline bool - operator != (const Saturated& a, const Saturated& b); -} - -#include "saturated_impl.hpp" - -#endif // MODM_SATURATED_HPP diff --git a/src/modm/math/saturated/saturated__avr_s8_impl.hpp b/src/modm/math/saturated/saturated__avr_s8_impl.hpp deleted file mode 100644 index b408a901e9..0000000000 --- a/src/modm/math/saturated/saturated__avr_s8_impl.hpp +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Copyright (c) 2009, Fabian Greif - * Copyright (c) 2010, Martin Rosekeit - * Copyright (c) 2012, Niklas Hauser - * - * 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_SATURATED_HPP - #error "Don't include this file directly use 'math/saturated.hpp' instead!" -#endif - -namespace modm -{ - // ------------------------------------------------------------------------ - template<> - Saturated& - Saturated::operator+=(const Saturated& other) { - asm ( - "add %[x], %[y]" "\n\t" - "brvc 0f" "\n\t" // Falls es einen signed Überlauf gab - // (V=1) Maximalwert laden - "ldi %[x], 0x7f" "\n\t" - "sbrc %[y], 7" "\n\t" // y ist negativ, daher muss der - // Minimalwert geladen werden - "ldi %[x], 0x80" "\n\t" - "0:" - : [x] "+d" (this->value) - : [y] "r" (other.value) - ); - - return *this; - } - - // ------------------------------------------------------------------------ - // TODO testen - /*template<> - Saturated& - Saturated::operator+=(const Saturated& other) { - asm ( - "add %[x], %[y]" "\n\t" - "brvc 0f" "\n\t" // Falls es einen signed Überlauf gab - // (V=1) Maximalwert laden - "ldi %[x], 0xff" "\n\t" - "0:" - : [x] "+d" (this->value) - : [y] "r" (other.value) - ); - - return *this; - }*/ - - // ------------------------------------------------------------------------ - template<> - Saturated& - Saturated::operator-=(const Saturated& other) { - asm ( - "sub %[x], %[y]" "\n\t" - "brvc 0f" "\n\t" // Falls es einen signed Überlauf gab - // (V=1) Minimalwert laden - "ldi %[x], 0x80" "\n\t" - "sbrc %[y], 7" "\n\t" // y ist negativ, daher muss der - // Maximalwert geladen werden - "ldi %[x], 0x7f" "\n\t" - "0:" - : [x] "+d" (this->value) - : [y] "r" (other.value) - ); - - return *this; - } - - // ------------------------------------------------------------------------ - // TODO testen - /*template<> - Saturated& - Saturated::operator-=(const Saturated& other) { - asm ( - "sub %[x], %[y]" "\n\t" - "brvc 0f" "\n\t" // Falls es einen signed Überlauf gab - // (V=1) Minimalwert laden - "ldi %[x], 0x80" "\n\t" - "0:" - : [x] "+d" (this->value) - : [y] "r" (other.value) - ); - - return *this; - }*/ - - // ------------------------------------------------------------------------ - // FIXME warum funktioniert das nicht??? - template<> - Saturated - operator - (const Saturated& a) { - Saturated temp(a); - asm ( - "neg %[x]" "\n\t" - "brvc 0f" "\n\t" // Signed Überlauf (V=1): Das Ergebnis - // ist 0x80 und wird verändert zu 0x7f - "dec %[x]" "\n\t" - "0:" - : [x] "+d" (temp.value) - ); - return temp; - } - - // ------------------------------------------------------------------------ - template<> - Saturated - abs(const Saturated& a) { - Saturated temp(a); - asm ( - "sbrc %[x], 7" "\n\t" - "neg %[x]" "\n\t" // x < 0: negieren - "sbrc %[x], 7" "\n\t" - "dec %[x]" "\n\t" // R0 ist immer noch < 0 (also 0x80), - // lade 0x7f - : [x] "+d" (temp.value) - ); - return temp; - } -} diff --git a/src/modm/math/saturated/saturated__avr_u8_impl.hpp b/src/modm/math/saturated/saturated__avr_u8_impl.hpp deleted file mode 100644 index a192fc86bd..0000000000 --- a/src/modm/math/saturated/saturated__avr_u8_impl.hpp +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright (c) 2009, Fabian Greif - * Copyright (c) 2010, Martin Rosekeit - * Copyright (c) 2012, Niklas Hauser - * - * 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_SATURATED_HPP - #error "Don't include this file directly use 'math/saturated.hpp' instead!" -#endif - -namespace modm -{ - // ------------------------------------------------------------------------ - template<> - Saturated& - Saturated::operator += (const Saturated& other) { - asm ( - "add %[x], %[y]" "\n\t" - "brcc 0f" "\n\t" // Falls es einen unsigned Überlauf gab - // (C=1) Maximalwert laden - "ldi %[x], 0xff" "\n" - "0:" "\n\t" - : [x] "+d" (this->value) - : [y] "r" (other.value) - ); - - return *this; - } - - // ------------------------------------------------------------------------ - // Diese Kombination ist am aufwändigsten in der Behandlung und geschieht - // am einfachsten durch Umskalierung auf zwei signed-Werte, - // signed-saturierter Operation und nachfolgender Rückskalierung. Zu - // beachten ist, daß dieser Operator nicht kommutativ ist, d.h. a+b - // liefert i.A. ein anderes Ergebnis als b+a. - /*template<> - Saturated& - Saturated::operator += (const Saturated& other) { - asm ( - "subi %[x], 0x80" "\n\t" // Transformation - // [0x00, 0xff] -> [0x80, 0x7f] - "add %[x], %[y]" "\n\t" - "brvc 0f" "\n\t" // Falls es einen signed Überlauf gab - // (V=1) Maximalwert laden - "ldi %[x], 0x7f" "\n\t" - "sbrc %[y], 7" "\n\t" // R0 ist negativ, daher muss der - // Minimalwert geladen werden - "ldi %[x], 0x80" "\n" - "0:" "\n\t" - "subi %[x], 0x80" "\n\t" // Rücktransformation - // [0x80, 0x7f] -> [0x00, 0xff] - : [x] "+d" (this->value) - : [y] "r" (other.value) - ); - - return *this; - }*/ - - // ------------------------------------------------------------------------ - template<> - Saturated& - Saturated::operator -= (const Saturated& other) { - asm ( - "sub %[x], %[y]" "\n\t" - "brcc 0f" "\n\t" // Falls es einen unsigned Unterlauf - // gab (C=1) Minimalwert laden - "clr %[x]" "\n\t" - "0:" - : [x] "+r" (this->value) - : [y] "r" (other.value) - ); - - return *this; - } - - // ------------------------------------------------------------------------ - /*template<> - Saturated& - Saturated::operator-=(const Saturated& other) { - asm ( - "subi %[x], 0x80" "\n\t" // Transformation - // [0x00, 0xff] -> [0x80, 0x7f] - "sub %[x], %[y]" "\n\t" - "brvc 0f" "\n\t" // Falls es einen signed Überlauf gab - // (V=1) Minimalwert laden - "ldi %[x], 0x80" "\n\t" - "sbrc %[y], 7" "\n\t" // R0 ist negativ, daher muss der - // Maximalwert geladen werden - "ldi %[x], 0x7f" "\n" - "0:" "\n\t" - "subi %[x], 0x80" "\n\t" // Rücktransformation - // [0x80, 0x7f] -> [0x00, 0xff] - : [x] "+d" (this->value) - : [y] "r" (other.value) - ); - - return *this; - }*/ -} diff --git a/src/modm/math/saturated/saturated_impl.hpp b/src/modm/math/saturated/saturated_impl.hpp deleted file mode 100644 index edc402336f..0000000000 --- a/src/modm/math/saturated/saturated_impl.hpp +++ /dev/null @@ -1,169 +0,0 @@ -/* - * Copyright (c) 2009-2010, Fabian Greif - * Copyright (c) 2010, Martin Rosekeit - * Copyright (c) 2012, 2014, Niklas Hauser - * - * 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_SATURATED_HPP - #error "Don't include this file directly use 'math/saturated.hpp' instead!" -#endif - -#ifdef __AVR__ - // include faster implementations written in assembler - #include "saturated__avr_u8_impl.hpp" - #include "saturated__avr_s8_impl.hpp" -#endif - -namespace modm -{ - template - Saturated::Saturated() : - value() - { - } - - template - Saturated::Saturated(const T& initialValue) : - value(initialValue) - { - } - - template - void - Saturated::setValue(WideType in) - { - if (in > std::numeric_limits::max()) { - value = std::numeric_limits::max(); - } - else if (in < std::numeric_limits::min()) { - value = std::numeric_limits::min(); - } - else { - value = static_cast(in); - } - } - - template - Saturated& - Saturated::operator += (const Saturated& other) - { - WideType temp = static_cast(this->value) + - static_cast(other.value); - setValue(temp); - - return *this; - } - - template - Saturated& - Saturated::operator -= (const Saturated& other) - { - WideType temp = static_cast(value) - - static_cast(other.value); - setValue(temp); - - return *this; - } - - template - void - Saturated::absolute() - { - if (std::is_signed_v) - { - if (value < 0) { - value = -value; - } - } - } - - // ---------------------------------------------------------------------------- - template - Saturated - operator - (const Saturated& x) - { - using WideType = modm::WideType; - - WideType temp = - static_cast(x.value); - - Saturated result; - result.setValue(temp); - return result; - } - - // ---------------------------------------------------------------------------- - template - Saturated - abs(const Saturated& x) - { - Saturated result(x); - - if (std::is_signed_v) { - result.absolute(); - } - return result; - } - - // ---------------------------------------------------------------------------- - template - Saturated - operator - (const Saturated& a, const Saturated& b) - { - Saturated t(a); - t -= b; - return t; - } - - // ---------------------------------------------------------------------------- - template - Saturated - operator + (const Saturated& a, const Saturated& b) - { - Saturated t(a); - t += b; - return t; - } - - // ---------------------------------------------------------------------------- - template - inline bool - operator == (const Saturated& a, const Saturated& b) - { - return (a.value == b.value); - } - - // ---------------------------------------------------------------------------- - template - inline bool - operator != (const Saturated& a, const Saturated& b) - { - return (a.value != b.value); - } - - // ---------------------------------------------------------------------------- - - template<> - void - Saturated::absolute() - { - } - - template<> - void - Saturated::absolute() - { - } - - template<> - void - Saturated::absolute() - { - } -} diff --git a/src/modm/math/saturation/saturated.hpp b/src/modm/math/saturation/saturated.hpp new file mode 100644 index 0000000000..181850473f --- /dev/null +++ b/src/modm/math/saturation/saturated.hpp @@ -0,0 +1,308 @@ +/* + * Copyright (c) 2021, Thomas Sommer + * + * 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/. + */ +// ---------------------------------------------------------------------------- + +#pragma once + +#include +#include +#include +#include +#include +#include +#include + +#include +using namespace std; + +namespace modm +{ +/** + * @brief Saturated arithmetics + * @see https://en.wikipedia.org/wiki/Saturation_arithmetic + * + * @author Thomas Sommer + * + * @ingroup modm_math_saturated + */ + +template +requires integral> +class Saturated +{ +protected: + T value; + + using TP = remove_reference_t; + using TS = conditional_t, T, make_signed_t>>; + +private: + static constexpr TP min = numeric_limits::min(); + static constexpr TP max = numeric_limits::max(); + +public: + // Constructors + Saturated() = default; + + // ### Construct from T + constexpr Saturated(const T& value) : value(value){}; + constexpr Saturated(const Saturated& other) : value(other.value){}; + + // ### Construct from U + template + requires integral> + constexpr Saturated(const U& v) + { + value = clamp< modm::fits_any_t >(v, min, max); + } + + template + requires floating_point> + constexpr Saturated(const U& v) + { + value = clamp(v, min, max); + } + + template + requires integral> + constexpr Saturated(const Saturated& other) + { + value = clamp< modm::fits_any_t >(other.value, min, max); + } + + // ### operator++, operator-- [Post] + Saturated& + operator++() + { + if (value < max) value++; + return *this; + } + + Saturated& + operator--() + { + if (value > min) value--; + return *this; + } + + // operator++(int), operator--(int) [Pre] + Saturated + operator++(int) + { + Saturated tmp(*this); + if (value < max) value++; + return tmp; + } + + Saturated + operator--(int) + { + Saturated tmp(*this); + if (value > min) value--; + return tmp; + } + + // ### operator- [Negate] + TS + operator-() + { + // Dump negation. Does not clamp. + return -TS(value); + } + + // ### operator= + + // Unrequired. generic version below is equivalent + /* void + operator=(const T& v) { + value = clamp(v, min, max); + } */ + + template + requires integral> + void + operator=(const U& v) + { + value = clamp< modm::fits_any_t >(v, min, max); + } + + void + operator=(const Saturated& other) + { + value = other.value; + } + + template + requires integral> + void + operator=(const Saturated& other) + { + value = clamp< modm::fits_any_t >(other.value, min, max); + } + + // ### operator+=, operator-=, operator*= + template + requires unsigned_integral> + Saturated& + operator+=(const U& v) + { + if (__builtin_add_overflow(value, v, &value)) value = max; + return *this; + } + + template + requires signed_integral> + Saturated& + operator+=(const U& v) + { + if (v < 0) + { + if (__builtin_sub_overflow(value, -v, &value)) value = min; + } else + { + if (__builtin_add_overflow(value, v, &value)) value = max; + } + return *this; + } + + template + requires unsigned_integral> + Saturated& + operator-=(const U& v) + { + if (__builtin_sub_overflow(value, v, &value)) { value = min; } + return *this; + } + + template + requires signed_integral> + Saturated& + operator-=(const U& v) + { + if (v < 0) + { + if (__builtin_add_overflow(value, -v, &value)) value = max; + } else + { + if (__builtin_sub_overflow(value, v, &value)) value = min; + } + return *this; + } + + template + requires unsigned_integral> + Saturated& + operator*=(const U& v) + { + if (__builtin_mul_overflow(value, v, &value)) { value = max; } + return *this; + } + + template + requires signed_integral> + Saturated& + operator*=(const U& v) + { + if (v < 0) + { + // FIXME unfinished business !? + if (__builtin_mul_overflow(value, -v, &value)) value = max; + value = -value; + } else + { + if (__builtin_mul_overflow(value, v, &value)) value = max; + } + return *this; + } + + // ### operator+, operator-, operator* + template + requires unsigned_integral> + TP + operator+(const U& v) + { + Saturated tmp; + + if (__builtin_add_overflow(value, v, &tmp.value)) tmp.value = max; + + return tmp.value; + } + + template + requires signed_integral> + TP + operator+(const U& v) + { + Saturated tmp; + + if (v < 0) + { + if (__builtin_sub_overflow(value, -v, &tmp.value)) tmp.value = min; + } else + { + if (__builtin_add_overflow(value, v, &tmp.value)) tmp.value = max; + } + + return tmp.value; + } + + template + requires unsigned_integral> + TP + operator-(const U& v) + { + Saturated tmp; + + if (__builtin_sub_overflow(value, v, &tmp.value)) tmp.value = min; + + return tmp.value; + } + + template + requires signed_integral> + TP + operator-(const U& v) + { + Saturated tmp; + + if (v < 0) + { + if (__builtin_add_overflow(value, -v, &tmp.value)) tmp.value = max; + } else + { + if (__builtin_sub_overflow(value, v, &tmp.value)) tmp.value = min; + } + + return tmp.value; + } + + TP + operator*(const T& v) + { + Saturated tmp; + + if (__builtin_mul_overflow(value, v, &tmp.value)) tmp.value = max; + + return tmp.value; + } + + TP + getValue() const + { + return value; + } + + constexpr auto + operator<=>(const Saturated&) const = default; + + template + friend class Saturated; +}; +} // namespace modm \ No newline at end of file diff --git a/src/modm/math/saturation/saturated_limited.hpp b/src/modm/math/saturation/saturated_limited.hpp new file mode 100644 index 0000000000..3b6e422865 --- /dev/null +++ b/src/modm/math/saturation/saturated_limited.hpp @@ -0,0 +1,205 @@ +#pragma once + +#include + +#include "saturated.hpp" + +using namespace std; + +namespace modm +{ +/** + * @brief Saturated type with custom boundaries. + * + * @tparam T Type of saturated. plain or reference + * @tparam LimitsConst true: max and min are const, false: max and min can be adjusted + */ +template +class SaturatedLimited : public Saturated +{ +protected: + using TP = Saturated::TP; + using TB = conditional_t; + +public: + TB min = numeric_limits::min(); + TB max = numeric_limits::max(); + + constexpr SaturatedLimited() = default; + + constexpr SaturatedLimited(T value, TB min, TB max) : Saturated(value), min(min), max(max) {} + + // ### operator++, operator-- [Post] + SaturatedLimited& + operator++() + { + if (Saturated::value < max) Saturated::value++; + return *this; + } + + SaturatedLimited& + operator--() + { + if (Saturated::value > min) Saturated::value--; + return *this; + } + + // operator++(int), operator--(int) [Pre] + SaturatedLimited + operator++(int) + { + SaturatedLimited tmp(*this); + if (Saturated::value < max) Saturated::value++; + return tmp; + } + + SaturatedLimited + operator--(int) + { + SaturatedLimited tmp(*this); + if (Saturated::value > min) Saturated::value--; + return tmp; + } + + // ### operator= + + // Unrequired. generic version below is equivalent + void + operator=(const T& v) { + Saturated::value = clamp(v, min, max); + } + + template + requires integral> + void + operator=(const U& v) + { + Saturated::value = clamp< modm::fits_any_t >(v, min, max); + } + + template + requires integral> + void + operator=(const Saturated& other) + { + Saturated::value = clamp< modm::fits_any_t >(other.getValue(), min, max); + } + + template + requires integral> + void + operator=(const SaturatedLimited& other) + { + if constexpr(LimitsConst) { + Saturated::value = clamp< modm::fits_any_t >(other.value, min, max); + } else { + Saturated::value = other.value; + min = other.min; + max = other.max; + } + } + + // ### operator+=, operator-=, operator*= + template + requires integral> + SaturatedLimited& + operator+=(const U& v) + { + Saturated::template operator+=(v); + Saturated::value = clamp(Saturated::value, min, max); + return *this; + } + + template + requires integral> + SaturatedLimited& + operator-=(const U& v) + { + Saturated::template operator-=(v); + Saturated::value = clamp(Saturated::value, min, max); + return *this; + } + + template + requires integral> + SaturatedLimited& + operator*=(const U& v) + { + Saturated::template operator*=(v); + Saturated::value = clamp(Saturated::value, min, max); + return *this; + } + + // ### operator+, operator-, operator* + template + requires integral> + TP + operator+(const U& v) + { + SaturatedLimited tmp(*this); + tmp += v; + return tmp.value; + } + + template + requires integral> + TP + operator-(const U& v) + { + SaturatedLimited tmp(*this); + tmp -= v; + return tmp.value; + } + + template + requires integral> + TP + operator*(const U& v) + { + SaturatedLimited tmp(*this); + tmp *= v; + return tmp.value; + } + + TB& + getMin() + { + return min; + } + + TB& + getMax() + { + return max; + } + +private: + template + friend class SaturatedLimited; + + template + friend modm::IOStream& + operator<<(modm::IOStream&, const SaturatedLimited&); +}; + +#if __has_include() +#include + +template +modm::IOStream& +operator<<(modm::IOStream& os, const SaturatedLimited& sl) +{ + // An illustrative asci-slider + const T_ step = std::max((sl.max - sl.min) / 32, 1); + T_ i = sl.min; + while(i < sl.value) { os << '-'; i += step; } + os << '|'; + while(i < sl.max) { os << '-'; i += step; } + os << modm::endl; + + os << "min: " << sl.min << "\tval: " << sl.value << "\tmax: " << sl.max; + return os; +} +#endif + +} // namespace modm \ No newline at end of file diff --git a/src/modm/math/saturated/module.lb b/src/modm/math/saturation/saturation.lb similarity index 79% rename from src/modm/math/saturated/module.lb rename to src/modm/math/saturation/saturation.lb index 460f61732e..f3be8be6c3 100644 --- a/src/modm/math/saturated/module.lb +++ b/src/modm/math/saturation/saturation.lb @@ -11,13 +11,13 @@ # ----------------------------------------------------------------------------- def init(module): - module.name = ":math:saturated" - module.description = "Saturated Arithmetics" + module.name = ":math:saturation" + module.description = "Saturation Arithmetics" def prepare(module, options): module.depends(":math:utils") return True def build(env): - env.outbasepath = "modm/src/modm/math/saturated" + env.outbasepath = "modm/src/modm/math/saturation" env.copy(".") diff --git a/src/modm/math/scaling_unsigned.hpp b/src/modm/math/scaling_unsigned.hpp new file mode 100644 index 0000000000..7c0a816843 --- /dev/null +++ b/src/modm/math/scaling_unsigned.hpp @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2021, Thomas Sommer + * + * 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/. + */ +// ---------------------------------------------------------------------------- + +#pragma once + +#include + +#include +// #include + +namespace modm { + +/** + * @brief Unsigned integer with arbitrary digits and scaling value on conversion + * between instances with different digits. + * + * @tparam D Digits + * + * @author Thomas Sommer + */ +template +class ScalingUnsigned { +public: + static constexpr int Digits = D; + using ValueType = uint_t::least; + + static constexpr ValueType min = 0; + static constexpr ValueType max = bitmask(); + + constexpr ScalingUnsigned() = default; + + // FIXME want both: + // COMPTIME: static_assert(value <= max, "value out of range") + // RUNTIME: std::min(value, max) or modm_assert(value <= max, ...) + constexpr ScalingUnsigned(ValueType value) : value(std::min(value, max)) { + // TODO disable via lbuild option + // modm_assert_continue_fail_debug(value <= max, "ScalingUnsigned", "constructor", "value out of range"); + } + + // Construct from bigger or equal ColorGray + template = nullptr> + constexpr ScalingUnsigned(const ScalingUnsigned& other) + : value(other.value >> (E - D)) {} + + template = nullptr> + constexpr ScalingUnsigned(ScalingUnsigned &&other) + : value(other.value >> (E - D)) {} + + // Construct from smaller ColorGray + template E), void*> = nullptr> + constexpr ScalingUnsigned(const ScalingUnsigned& other) + : value(other.value * max / other.max) + {} + + template E), void*> = nullptr> + constexpr ScalingUnsigned(ScalingUnsigned &&other) + : value(other.value * max / other.max) + {} + + /* // Faster construction from from single digit + constexpr ScalingUnsigned(const ScalingUnsigned<1> &other) : value(other.value ? bitmask() : 0){} + + // constexpr ScalingUnsigned(ScalingUnsigned<1> &&other) : value(other.value ? bitmask() : 0){} + constexpr ScalingUnsigned& operator=(const ScalingUnsigned<1> &other) { + value = other.value ? bitmask() : 0; + return *this; + } */ + + // Assign ScalingUnsigned with more or equal Depth + template = nullptr> + void operator=(const ScalingUnsigned& other) { + value = other.value >> (E - D); + } + + // Assign ScalingUnsigned with less Depth + template E), void*> = nullptr> + void operator=(const ScalingUnsigned& other) { + value = other.value * max / other.max; + } + + // FIXME want both: + // COMPTIME: static_assert(value <= max, "value out of range") + // RUNTIME: std::min(value, max) or modm_assert(value <= max, ...) + void setValue(ValueType value) { + this->value = std::min(value, max); + // TODO disable via lbuild option + // modm_assert_continue_fail_debug(value <= max, "modm::ScalingUnsigned", "setValue()", "value out of range"); + } + + ValueType getValue() const { return value; } + + bool isSaturated() const { + return value == max; + } + + constexpr auto operator<=>(const ScalingUnsigned &) const = default; + +protected: + ValueType value = 0; + + inline void max_cutoff() { value = std::min(value, max); } +private: + template + friend class ScalingUnsigned; +}; + +} \ No newline at end of file diff --git a/src/modm/math/scaling_unsigned.lb b/src/modm/math/scaling_unsigned.lb new file mode 100644 index 0000000000..08d89574cc --- /dev/null +++ b/src/modm/math/scaling_unsigned.lb @@ -0,0 +1,32 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# +# Copyright (c) 2021, Thomas Sommer +# +# 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/. +# ----------------------------------------------------------------------------- + +def init(module): + module.name = ":math:scaling_unsigned" + module.description = """ +# Scaling Unsigned + +Unsigned integer with arbitrary digits and scaling value on conversion between +instances with different digits. F.e. a 2bit scaling unsigned of 0b11 becomes +0b1111 when converted to a 4bit scaling unsigned. + +It's the baseclass to all in modm::color::* but may have wider applications. + +""" + +def prepare(module, options): + module.depends(":utils") + return True + +def build(env): + env.outbasepath = "modm/src/modm/math" + env.copy("scaling_unsigned.hpp") diff --git a/src/modm/math/utils/binary.hpp b/src/modm/math/utils/binary.hpp new file mode 100644 index 0000000000..b0334870a9 --- /dev/null +++ b/src/modm/math/utils/binary.hpp @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2021, Thomas Sommer + * + * 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 + +namespace modm { + template + concept unsigned_integral_max8 = std::unsigned_integral and std::numeric_limits::digits <= 8; + + template + concept unsigned_integral_max16 = std::unsigned_integral and std::numeric_limits::digits <= 16; + + template + concept unsigned_integral_max32 = std::unsigned_integral and std::numeric_limits::digits <= 32; + + template + concept unsigned_integral_max64 = std::unsigned_integral and std::numeric_limits::digits <= 64; +} \ No newline at end of file diff --git a/src/modm/math/utils/integer_traits.hpp b/src/modm/math/utils/integer_traits.hpp new file mode 100644 index 0000000000..0864af40b3 --- /dev/null +++ b/src/modm/math/utils/integer_traits.hpp @@ -0,0 +1,58 @@ +#pragma once + +#include +#include + +#include +namespace modm +{ + template + struct uint_t + { + using least = std::conditional_t< + (Bits <= 8),uint8_t, std::conditional_t< + (Bits <= 16), uint16_t, std::conditional_t< + (Bits <= 32), uint32_t, std::enable_if_t< + (Bits <= 64), uint64_t>>>>; + }; + + template + using least_uint = typename modm::uint_t::least; + + template + constexpr int most_digits() { + return std::numeric_limits::digits; + } + + template + constexpr std::enable_if_t + most_digits() { + return std::max(std::numeric_limits::digits, most_digits()); + } + + // Trait the smallest integral - signed or unsigned - fitting any Ts + template + struct fits_any { + static constexpr int most_dig = most_digits(); + + using type = std::conditional_t< + std::conjunction_v...>, + typename uint_t::least, + // An odd most_dig means: type with most digits is signed integral + std::make_signed_t::least> + >; + }; + + template + using fits_any_t = typename fits_any::type; + + template + struct bitmask { + using value_type = uint_t::least; + static constexpr value_type value = std::pow(2, N) - 1; + constexpr operator value_type() const noexcept { return value; } + }; + + template + using bitmask_t = typename bitmask::value_type; +} diff --git a/src/modm/math/utils/misc.hpp b/src/modm/math/utils/misc.hpp index 2af1b97608..1c7bdb438d 100644 --- a/src/modm/math/utils/misc.hpp +++ b/src/modm/math/utils/misc.hpp @@ -4,6 +4,7 @@ * Copyright (c) 2011-2012, 2014-2015, Niklas Hauser * Copyright (c) 2015, Sascha Schade * Copyright (c) 2020, Christopher Durand + * Copyright (c) 2021, Thomas Sommer * * This file is part of the modm project. * @@ -16,10 +17,12 @@ #ifndef MODM_MATH_UTILS_MISC_HPP #define MODM_MATH_UTILS_MISC_HPP -#include -#include #include + +#include +#include #include +#include #include @@ -60,65 +63,51 @@ pow(uint32_t base, uint8_t exponent) } /** - * @brief This does what you think it does. + * @brief Variadic min for 2-∞ objects * - * @param a A thing of arbitrary type. - * @param b Another thing of arbitrary type. - * @return The lesser of the parameters. + * @param a first object to compare + * @param b second object to compare + * @param cs More optional objects to compare + * @return The smallest object * - * This is the simple classic generic implementation. It will work on - * temporary expressions, since they are only evaluated once, unlike a - * preprocessor macro. + * @see https://stackoverflow.com/questions/23815138/implementing-variadic-min-max-functions */ template -inline const T& -min(const T& a, const T& b) +constexpr T vmin(T a, T b) { - if (b < a) - return b; - else - return a; + return a < b ? a : b; } -/** - * @brief This does what you think it does. - * - * @param a A thing of arbitrary type. - * @param b Another thing of arbitrary type. - * @return The greater of the parameters. - * - * This is the simple classic generic implementation. It will work on - * temporary expressions, since they are only evaluated once, unlike a - * preprocessor macro. - */ -template -inline const T& -max(const T& a, const T& b) +template +constexpr T vmin(T a, T b, Ts&&... cs) { - if (a < b) - return b; - else - return a; + return a < b ? + vmin(a, std::forward(cs)...) : + vmin(b, std::forward(cs)...); } /** - * @brief This does what you think it does. + * @brief Variadic max for 2-∞ objects * - * @param a A thing of arbitrary type. - * @param b Another thing of arbitrary type. - * @param c Something else of arbitrary type. - * @return The greater of the three parameters. + * @param a first object to compare + * @param b second object to compare + * @param cs More optional objects to compare + * @return The greatest object * - * This is the simple classic generic implementation. It will work on - * temporary expressions, since they are only evaluated once, unlike a - * preprocessor macro. + * @see https://stackoverflow.com/questions/23815138/implementing-variadic-min-max-functions */ template -constexpr T -max(const T a, const T b, const T c) +constexpr T vmax(T& a, T& b) +{ + return a > b ? a : b; +} + +template +constexpr T vmax(T& a, T& b, Ts&... cs) { - return ( ( (b > c) ? b : c ) > a ) ? - ( (b > c) ? b : c) : a; + return a > b ? + vmax(a, std::forward(cs)...) : + vmax(b, std::forward(cs)...); } /** @@ -136,10 +125,7 @@ template inline const T& min(const T& a, const T& b, Compare compare) { - if (compare(b, a)) - return b; - else - return a; + return compare(b, a) ? b : a; } /** @@ -157,24 +143,16 @@ template inline const T& max(const T& a, const T& b, Compare compare) { - if (compare(a, b)) - return b; - else - return a; + return compare(a, b) ? b : a; } /** * @brief constexpr implementation of fabs */ -template - requires std::is_floating_point_v +template constexpr Float constexpr_fabs(Float number) { - if (number >= 0) { - return number; - } else { - return -number; - } + return number >= 0 ? number : -number; } /// @} diff --git a/src/modm/platform/dma/stm32/dma.hpp.in b/src/modm/platform/dma/stm32/dma.hpp.in index 4bc02ff703..88151f7add 100644 --- a/src/modm/platform/dma/stm32/dma.hpp.in +++ b/src/modm/platform/dma/stm32/dma.hpp.in @@ -190,6 +190,18 @@ public: ChannelHal::setPeripheralAddress(address); } + static void + setMemoryDataSize(MemoryDataSize memoryDataSize) + { + ChannelHal::setMemoryDataSize(memoryDataSize); + } + + static void + setPeripheralDataSize(PeripheralDataSize peripheralDataSize) + { + ChannelHal::setPeripheralDataSize(peripheralDataSize); + } + /** * Enable/disable memory increment * diff --git a/src/modm/platform/dma/stm32/dma_base.hpp.in b/src/modm/platform/dma/stm32/dma_base.hpp.in index 2dcb0e7a4f..aab2f99b23 100644 --- a/src/modm/platform/dma/stm32/dma_base.hpp.in +++ b/src/modm/platform/dma/stm32/dma_base.hpp.in @@ -155,6 +155,7 @@ public: Bit16 = HalfWord, Word = {{ reg_prefix }}_MSIZE_1, Bit32 = Word, + All = DMA_CCR_MSIZE_0 | DMA_CCR_MSIZE_1 }; enum class @@ -166,6 +167,7 @@ public: Bit16 = HalfWord, Word = {{ reg_prefix }}_PSIZE_1, Bit32 = Word, + All = DMA_CCR_PSIZE_0 | DMA_CCR_PSIZE_1 }; enum class diff --git a/src/modm/platform/dma/stm32/dma_hal.hpp.in b/src/modm/platform/dma/stm32/dma_hal.hpp.in index dc23e234a3..80042a641d 100644 --- a/src/modm/platform/dma/stm32/dma_hal.hpp.in +++ b/src/modm/platform/dma/stm32/dma_hal.hpp.in @@ -250,6 +250,22 @@ public: %% endif } + static void + setMemoryDataSize(MemoryDataSize memoryDataSize) + { + DMA_Channel_TypeDef *Base = (DMA_Channel_TypeDef *) CHANNEL_BASE; + Base->CCR &= ~uint32_t(MemoryDataSize::All); + Base->CCR |= uint32_t(memoryDataSize); + } + + static void + setPeripheralDataSize(PeripheralDataSize peripheralDataSize) + { + DMA_Channel_TypeDef *Base = (DMA_Channel_TypeDef *) CHANNEL_BASE; + Base->CCR &= ~uint32_t(PeripheralDataSize::All); + Base->CCR |= uint32_t(peripheralDataSize); + } + /** * Enable/disable memory increment * @@ -290,9 +306,11 @@ public: /** * Set length of data to transfer + * + * @param lenght range: 0-65535 */ static void - setDataLength(std::size_t length) + setDataLength(uint16_t length) { DMA_Channel_TypeDef *Base = (DMA_Channel_TypeDef *) CHANNEL_BASE; %% if dmaType in ["stm32-channel-request", "stm32-channel", "stm32-mux"] diff --git a/src/modm/platform/spi/at90_tiny_mega/module.lb b/src/modm/platform/spi/at90_tiny_mega/module.lb index 46fa67ee62..7f6cad2a31 100644 --- a/src/modm/platform/spi/at90_tiny_mega/module.lb +++ b/src/modm/platform/spi/at90_tiny_mega/module.lb @@ -20,6 +20,7 @@ def get_properties(env): properties["driver"] = driver return properties + def load_options(module): module.add_option( BooleanOption( @@ -50,12 +51,14 @@ class Instance(Module): env.template("spi.hpp.in", "spi{}.hpp".format(self.instance)) env.template("spi_master.hpp.in", "spi_master{}.hpp".format(self.instance)) + env.template("spi_master_impl.hpp.in", "spi_master{}_impl.hpp".format(self.instance)) env.template("spi_master.cpp.in", "spi_master{}.cpp".format(self.instance)) def init(module): module.name = ":platform:spi" module.description = "Serial Peripheral Interface (SPI)" + def prepare(module, options): device = options[":target"] if not device.has_driver("spi:avr"): @@ -76,6 +79,7 @@ def prepare(module, options): ":math:utils") return True + def build(env): properties = get_properties(env) driver = properties["driver"] @@ -87,6 +91,7 @@ def build(env): env.outbasepath = "modm/src/modm/platform/spi" if "instance" not in driver: + env.template("spi.hpp.in") env.template("spi_master.hpp.in") + env.template("spi_master_impl.hpp.in") env.template("spi_master.cpp.in") - env.template("spi.hpp.in") diff --git a/src/modm/platform/spi/at90_tiny_mega/spi.hpp.in b/src/modm/platform/spi/at90_tiny_mega/spi.hpp.in index 4eec7ada92..592379ded1 100644 --- a/src/modm/platform/spi/at90_tiny_mega/spi.hpp.in +++ b/src/modm/platform/spi/at90_tiny_mega/spi.hpp.in @@ -71,6 +71,20 @@ struct Spi Div64 = (1 << SPR1{{ id }}), Div128 = (1 << SPR1{{ id }}) | (1 << SPR0{{ id }}), }; + + enum State : uint8_t { + Idle = Bit6, // Transaction is running + AutoIncr = Bit7, // Increment index in tx/rx after each value transmission + }; + MODM_FLAGS8(State); + + enum ByteCount : uint8_t { + Byte = 0, // 1 byte + HalfWord = 1, // 2 bytes + Word = 2, // 4 bytes + // WordWord = 3 // 8 bytes + }; + typedef Configuration TxByteCount_t; // Right-aligned cause of highest access-rate }; } // namespace platform diff --git a/src/modm/platform/spi/at90_tiny_mega/spi_master.cpp.in b/src/modm/platform/spi/at90_tiny_mega/spi_master.cpp.in index 685ad7afc5..d131fc980a 100644 --- a/src/modm/platform/spi/at90_tiny_mega/spi_master.cpp.in +++ b/src/modm/platform/spi/at90_tiny_mega/spi_master.cpp.in @@ -2,6 +2,7 @@ * Copyright (c) 2013-2018, Niklas Hauser * Copyright (c) 2014, Sascha Schade * Copyright (c) 2017, Fabian Greif + * Copyright (c) 2021, Thomas Sommer * * This file is part of the modm project. * @@ -11,37 +12,140 @@ */ // ---------------------------------------------------------------------------- -#include "spi_master{{ id }}.hpp" +#include "spi_master.hpp" #include #include #include #include +#include -// bit 7 (0x80) is used for transfer 1 byte -// bit 6 (0x40) is used for transfer multiple byte -// bit 5-0 (0x3f) are used to store the acquire count -uint8_t -modm::platform::SpiMaster{{ id }}::state(0); +uint8_t modm::platform::SpiMaster{{ id }}::count(0); -void * -modm::platform::SpiMaster{{ id }}::context(nullptr); +void* modm::platform::SpiMaster{{ id }}::context(nullptr); modm::Spi::ConfigurationHandler -modm::platform::SpiMaster{{ id }}::configuration(nullptr); + modm::platform::SpiMaster{{ id }}::configuration(nullptr); + +// ---------------------------------------------------------------------------- + +modm::platform::Spi::State_t + modm::platform::SpiMaster{{ id }}::state(0); +uint8_t modm::platform::SpiMaster{{ id }}::bytes_left(0); + +std::size_t modm::platform::SpiMaster{{ id }}::size(0); +std::size_t modm::platform::SpiMaster{{ id }}::index(0); +modm::platform::SpiMaster{{ id }}::unsigned_data_u + modm::platform::SpiMaster{{ id }}::tx{nullptr}; +modm::platform::SpiMaster{{ id }}::unsigned_data_u + modm::platform::SpiMaster{{ id }}::rx{nullptr}; + +uint32_t modm::platform::SpiMaster{{ id }}::temp(0); + // ---------------------------------------------------------------------------- -void -modm::platform::SpiMaster{{ id }}::initialize(Prescaler prescaler) +using State = modm::platform::Spi::State; +using ByteCount = modm::platform::Spi::ByteCount; + +MODM_ISR(SPI_STC) { + modm::platform::SpiMaster{{ id }}::isr_handler(); +} + +void modm::platform::SpiMaster{{ id }}::isr_handler() { + // Unpack state + const int tx_byte_count = TxByteCount_t::get(state); + const bool auto_incr = state.all(State::AutoIncr); + + // Transmit further byte(s) + if(bytes_left) { + const std::size_t i = auto_incr ? index : 0; + switch(tx_byte_count) { + case ByteCount::HalfWord: + // Store received byte + if(rx.u8) rx.u16[index] = uint16_t(SPDR{{ id }}) << 8; // << bytes_left + // Transmit next byte + bytes_left = 0; + SPDR{{ id }} = tx.u16[i]; + return; + case ByteCount::Word: + // Store received byte + if(rx.u8) rx.u32[index] |= uint32_t(SPDR{{ id }}) << bytes_left; + // Transmit next byte + bytes_left -= 8; + SPDR{{ id }} = tx.u32[i] >> bytes_left; + return; + } + } + + // Store received byte + switch(tx_byte_count) { + case ByteCount::Byte: + if(rx.u8) rx.u8[index] = SPDR{{ id }}; + break; + case ByteCount::HalfWord: + if(rx.u8) rx.u16[index] |= SPDR{{ id }}; + break; + case ByteCount::Word: + if(rx.u8) rx.u32[index] |= SPDR{{ id }}; + break; + } + + // Increment index + if (++index == size) { + // Job done, disable Interrupt. + SPCR{{ id }} &= ~(1 << SPIE); + return; + } + + // Transmit next byte + const std::size_t i = auto_incr ? index : 0; + + switch(tx_byte_count) { + case ByteCount::Byte: + SPDR{{ id }} = tx.u8[i]; + return; + case ByteCount::HalfWord: + bytes_left = 1 * 8; + SPDR{{ id }} = tx.u16[i] >> 8; // >> bytes_left + return; + case ByteCount::Word: + bytes_left = 3 * 8; + SPDR{{ id }} = tx.u32[i] >> 24; // >> bytes_left + + if(rx.u32) rx.u32[index] = 0; // Need reset, because received bytes are | (ored) + return; + } +} + +modm::ResumableResult +modm::platform::SpiMaster{{ id }}::transmit(const uint8_t data) { + // FIXME does not yet work when called before a regular transmit() + // cause interrupt is not enabled here, witch signales a running condition + // ot the regular transmit. + + // Interrupt enabled? transmission in progress! + if(SPCR{{ id }} & (1 << SPIE)) + return {modm::rf::Running}; + + SPDR{{ id }} = data; + // wait for transfer to finish + if (!(SPSR & (1 << SPIF))) + return {modm::rf::Running}; + + return {modm::rf::Stop, SPDR{{ id }}}; +} + +// --------------------------------------------------------------------------- + +void modm::platform::SpiMaster{{ id }}::initialize(Prescaler prescaler) { modm::atomic::Lock lock; - SPCR{{ id }} = (1 << SPE{{ id }}) | (1 << MSTR{{ id }}) | (static_cast(prescaler) & ~0x80); - SPSR{{ id }} = (static_cast(prescaler) & 0x80) ? (1 << SPI2X{{ id }}) : 0; - state &= 0x3f; + SPCR{{ id }} = (1 << SPE) | (1 << MSTR) | (static_cast(prescaler) & ~0x80); + SPSR{{ id }} = (static_cast(prescaler) & 0x80) ? (1 << SPI2X) : 0; + state = State(0); } -// ---------------------------------------------------------------------------- uint8_t modm::platform::SpiMaster{{ id }}::acquire(void *ctx, ConfigurationHandler handler) @@ -49,9 +153,10 @@ modm::platform::SpiMaster{{ id }}::acquire(void *ctx, ConfigurationHandler handl if (context == nullptr) { context = ctx; - state = (state & ~0x3f) | 1; + count = 1; // if handler is not nullptr and is different from previous configuration - if (handler and configuration != handler) { + if (handler and configuration != handler) + { configuration = handler; configuration(); } @@ -59,7 +164,7 @@ modm::platform::SpiMaster{{ id }}::acquire(void *ctx, ConfigurationHandler handl } if (ctx == context) - return (++state & 0x3f); + return ++count; return 0; } @@ -67,103 +172,8 @@ modm::platform::SpiMaster{{ id }}::acquire(void *ctx, ConfigurationHandler handl uint8_t modm::platform::SpiMaster{{ id }}::release(void *ctx) { - if (ctx == context) - { - if ((--state & 0x3f) == 0) - context = nullptr; - } - return (state & 0x3f); -} -// ---------------------------------------------------------------------------- - -modm::ResumableResult -modm::platform::SpiMaster{{ id }}::transfer(uint8_t data) -{ -%% if options["busywait"] - SPDR{{ id }} = data; - - // wait for transfer to finish - while (!(SPSR{{ id }} & (1 << SPIF{{ id }}))) - ; - - data = SPDR{{ id }}; - return {modm::rf::Stop, data}; -%% else - // this is a manually implemented "fast resumable function" - // there is no context or nesting protection, since we don't need it. - // there are only two states encoded into 1 bit (LSB of state): - // 1. waiting to start, and - // 2. waiting to finish. - - // MSB != Bit7 ? - if ( !(state & Bit7) ) - { - // start transfer by copying data into register - SPDR{{ id }} = data; - - // set MSB = Bit7 - state |= Bit7; - } + if (ctx == context and --count == 0) + context = nullptr; - // wait for transfer to finish - if (!(SPSR{{ id }} & (1 << SPIF{{ id }}))) - return {modm::rf::Running}; - - data = SPDR{{ id }}; - state &= ~Bit7; - return {modm::rf::Stop, data}; -%% endif -} - -modm::ResumableResult -modm::platform::SpiMaster{{ id }}::transfer(const uint8_t *tx, uint8_t *rx, std::size_t length) -{ -%% if options["busywait"] - for (std::size_t index = 0; index < length; index++) - { - modm::ResumableResult result = transfer(tx ? tx[index] : 0); - if (rx) rx[index] = result.getResult(); - } - return {modm::rf::Stop}; -%% else - // this is a manually implemented "fast resumable function" - // there is no context or nesting protection, since we don't need it. - // there are only two states encoded into 1 bit (Bit6 of state): - // 1. initialize index, and - // 2. wait for 1-byte transfer to finish. - - // we need to globally remember which byte we are currently transferring - static std::size_t index = 0; - - // we are only interested in Bit6 - switch(state & Bit6) - { - case 0: - // we will only visit this state once - state |= Bit6; - - // initialize index and check range - index = 0; - while (index < length) - { - default: - { - // call the resumable function - modm::ResumableResult result = transfer(tx ? tx[index] : 0); - - // if the resumable function is still running, so are we - if (result.getState() > modm::rf::NestingError) - return {modm::rf::Running}; - - // if rx != 0, we copy the result into the array - if (rx) rx[index] = result.getResult(); - } - index++; - } - - // clear the state - state &= ~Bit6; - return {modm::rf::Stop}; - } -%% endif -} + return count; +} \ No newline at end of file diff --git a/src/modm/platform/spi/at90_tiny_mega/spi_master.hpp.in b/src/modm/platform/spi/at90_tiny_mega/spi_master.hpp.in index c7339d22be..aa73b32fb0 100644 --- a/src/modm/platform/spi/at90_tiny_mega/spi_master.hpp.in +++ b/src/modm/platform/spi/at90_tiny_mega/spi_master.hpp.in @@ -2,6 +2,7 @@ * Copyright (c) 2013-2017, Niklas Hauser * Copyright (c) 2014, Sascha Schade * Copyright (c) 2017, Fabian Greif + * Copyright (c) 2021, Thomas Sommer * * This file is part of the modm project. * @@ -14,11 +15,13 @@ #ifndef MODM_AVR_SPI_MASTER{{ id }}_HPP #define MODM_AVR_SPI_MASTER{{ id }}_HPP +#include #include #include #include #include +#include %% set sck = "Sck" %% if target["type"] in ["u2"] @@ -52,9 +55,28 @@ namespace platform */ class SpiMaster{{ id }} : public ::modm::SpiMaster, private Spi { - static uint8_t state; + static uint8_t count; static void *context; static ConfigurationHandler configuration; + + static Spi::State_t state; + + // static uint8_t byte_count; + static uint8_t bytes_left; + // static bool auto_incr; + + static std::size_t size; + static std::size_t index; + + union unsigned_data_u { + uint8_t *u8; + uint16_t *u16; + uint32_t *u32; + }; + static unsigned_data_u tx; + static unsigned_data_u rx; + + static uint32_t temp; public: /// Spi Data Mode, Mode0 is the most common mode enum class @@ -114,11 +136,10 @@ public: static void setDataOrder(DataOrder order) { - if (order == DataOrder::LsbFirst) { + if (order == DataOrder::LsbFirst) SPCR{{ id }} |= (1 << DORD{{ id }}); - } else { + else SPCR{{ id }} &= ~(1 << DORD{{ id }}); - } } @@ -128,42 +149,221 @@ public: static uint8_t release(void *ctx); + // TODO Complete the docs - static uint8_t - transferBlocking(uint8_t data) - { + /** + * @brief + * + * @param data + * @return modm::ResumableResult + */ + template + static modm::ResumableResult + transmit(const T data); + + static modm::ResumableResult + transmit(const uint8_t data); + + /** + * @brief + * + * @param data + * @return modm::ResumableResult + */ + template + static modm::ResumableResult + transmit(const T data, std::size_t repeat); + + /** + * @brief Send and optional receive data in range begin()->end(). + * Works with C-array or std::array for tx / rx + * + * @param tx_first Pointer to first element to send. f.e. tx.begin() OR tx.begin() + 1 + * @param tx_first Pointer to one after last element to send: f.e. tx.end() OR tx.end() - 4 + * @param rx_first Pointer to first element to receive: f.e. rx_data.begin() OR rx_data.begin() + 1 + */ + template + static modm::ResumableResult + transmit(const T *tx_first, const T *tx_last, T *rx_first = nullptr); + + /** + * @brief Send a std::array + * + * @param tx_array std::array with data to send + */ + template + static modm::ResumableResult + transmit(const C &tx_arr) + { return transmit(tx_arr.begin(), tx_arr.end()); }; + + /** + * @brief Transmit and receive a std::array + * + * @param tx_arr std::array with data to send + * @param rx_arr std::array for received data + */ + template + static modm::ResumableResult + transmit(const C &tx_arr, C &rx_arr) + { return transmit(tx_arr.begin(), tx_arr.end(), rx_arr.begin()); }; + +// -- Backwards compatible API -------------------------------------------------------- + + // Backwards compatible API %% if options["busywait"] - return transfer(data).getResult(); -%% else - return RF_CALL_BLOCKING(transfer(data)); -%% endif - } + static uint8_t + transferBlocking(const uint8_t data) + { return transmit(data).getResult(); } + + static uint16_t + transferBlocking16(const uint16_t data) + { return transmit(data).getResult(); } + + static uint32_t + transferBlocking32(const uint32_t data) + { return transmit(data).getResult(); } + + static void + transferBlocking(const uint8_t data, std::size_t repeat) + { transmit(data, repeat); } + + static void + transferBlocking16(const uint16_t data, std::size_t repeat) + { transmit(data, repeat); } + + static void + transferBlocking32(const uint32_t data, std::size_t repeat) + { transmit(data, repeat); } static void transferBlocking(const uint8_t *tx, uint8_t *rx, std::size_t length) - { -%% if options["busywait"] - transfer(tx, rx, length); + { transmit(tx, tx + length, rx); } + + static void + transferBlocking16(const uint16_t *tx, uint16_t *rx, std::size_t length) + { transmit(tx, tx + length, rx); } + + static void + transferBlocking32(const uint32_t *tx, uint32_t *rx, std::size_t length) + { transmit(tx, tx + length, rx); } %% else - RF_CALL_BLOCKING(transfer(tx, rx, length)); + static uint8_t + transferBlocking(const uint8_t data) + { return RF_CALL_BLOCKING(transmit(data)); } + + static uint16_t + transferBlocking16(const uint16_t data) + { return RF_CALL_BLOCKING(transmit(data)); } + + static uint32_t + transferBlocking32(const uint32_t data) + { return RF_CALL_BLOCKING(transmit(data)); } + + static void + transferBlocking(const uint8_t data, std::size_t repeat) + { RF_CALL_BLOCKING(transmit(data, repeat)); } + + static void + transferBlocking16(const uint16_t data, std::size_t repeat) + { RF_CALL_BLOCKING(transmit(data, repeat)); } + + static void + transferBlocking32(const uint32_t data, std::size_t repeat) + { RF_CALL_BLOCKING(transmit(data, repeat)); } + + static void + transferBlocking(const uint8_t *tx, uint8_t *rx, std::size_t length) + { RF_CALL_BLOCKING(transmit(tx, tx + length, rx)); } + + static void + transferBlocking16(const uint16_t *tx, uint16_t *rx, std::size_t length) + { RF_CALL_BLOCKING(transmit(tx, tx + length, rx)); } + + static void + transferBlocking32(const uint32_t *tx, uint32_t *rx, std::size_t length) + { RF_CALL_BLOCKING(transmit(tx, tx + length, rx)); } %% endif + + static modm::ResumableResult + transfer(const uint8_t data) { + return transmit(data); } + static modm::ResumableResult + transfer16(const uint16_t data) { + return transmit(data); + } - static modm::ResumableResult - transfer(uint8_t data); + static modm::ResumableResult + transfer32(const uint32_t data) { + return transmit(data); + } + + static modm::ResumableResult + transfer(const uint8_t tx, const std::size_t repeat) { + return transmit(tx, repeat); + } + + static modm::ResumableResult + transfer16(const uint16_t tx, const std::size_t repeat) { + return transmit(tx, repeat); + } + template static modm::ResumableResult - transfer(const uint8_t *tx, uint8_t *rx, std::size_t length); + transfer32(const uint32_t tx, const std::size_t repeat) { + return transmit(tx, repeat); + } + + static modm::ResumableResult + transfer(const uint8_t *tx, uint8_t *rx, const std::size_t length) { + return transmit(tx, tx + length, rx); + } + + static modm::ResumableResult + transfer16(const uint16_t *tx, uint16_t *rx, const std::size_t length) { + return transmit(tx, tx + length, rx); + } + + static modm::ResumableResult + transfer32(const uint32_t *tx, uint32_t *rx, const std::size_t length) { + return transmit(tx, tx + length, rx); + } // end documentation inherited + // TODO friend with MODM_ISR(SPI_STC) possible? + static void isr_handler(); + +private: + template + static void + transmit_begin(); + protected: + template + static modm::ResumableResult + transmit(const T data); + + template + static modm::ResumableResult + transmit(const T *tx, const std::size_t repeat); + + template + static modm::ResumableResult + transmit(const T *tx, T *rx, const std::size_t length); + static void initialize(Prescaler prescaler); + + template + static void + begin(); }; } // namespace platform } // namespace modm +#include "spi_master_impl.hpp" + #endif // MODM_AVR_SPI_MASTER_HPP diff --git a/src/modm/platform/spi/at90_tiny_mega/spi_master_impl.hpp.in b/src/modm/platform/spi/at90_tiny_mega/spi_master_impl.hpp.in new file mode 100644 index 0000000000..2bcf7ec6cc --- /dev/null +++ b/src/modm/platform/spi/at90_tiny_mega/spi_master_impl.hpp.in @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2013-2018, Niklas Hauser + * Copyright (c) 2014, Sascha Schade + * Copyright (c) 2017, Fabian Greif + * Copyright (c) 2021, Thomas Sommer + * + * 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/. + */ +// ---------------------------------------------------------------------------- + +#pragma once + +#include + +template +modm::ResumableResult +modm::platform::SpiMaster{{ id }}::transmit(const T data) +{ + // Interrupt enabled? transmission in progress! + if(SPCR{{ id }} & (1 << SPIE)) { + return {modm::rf::Running}; + } else if(!state.all(State::Idle)) { + temp = data; + // TODO cleaner way to assign tx? + tx.u8 = (uint8_t*)(&temp); + size = 1; + + transmit_begin(); + return {modm::rf::Running}; + } + + state.reset(State::Idle); + + return {modm::rf::Stop, T(temp | SPDR{{ id }})}; +} + +template +modm::ResumableResult +modm::platform::SpiMaster{{ id }}::transmit(const T data, std::size_t repeat) +{ + // Interrupt enabled? transmission in progress! + if(SPCR{{ id }} & (1 << SPIE)) { + return {modm::rf::Running}; + } else if(!state.all(State::Idle)) { + temp = data; + // TODO cleaner way to assign tx? + tx.u8 = (uint8_t*)(&temp); + size = repeat; + + state.reset(State::AutoIncr); + transmit_begin(); + return {modm::rf::Running}; + } + + state.reset(State::Idle); + return {modm::rf::Stop}; +} + +template +modm::ResumableResult +modm::platform::SpiMaster{{ id }}::transmit(const T *tx_first, const T *tx_last, T *rx_first) +{ + modm_assert_continue_fail_debug(tx_first < tx_last, "SpiMaster{{ id }}::transmit", "tx_first > tx_last"); + modm_assert_continue_fail_debug( + tx_last < rx_first + || rx_first + (tx_last - tx_first) <= tx_first, + "SpiMaster{{ id }}::transmit", "rx overlaps tx" + ); + + // Interrupt enabled? transmission in progress! + if(SPCR{{ id }} & (1 << SPIE)) { + return {modm::rf::Running}; + } else if(!state.all(State::Idle)) { + // TODO cleaner way to assign tx and rx? + tx.u8 = (uint8_t*)(tx_first); + rx.u8 = (uint8_t*)(rx_first); + size = tx_last - tx_first; + + state.set(State::AutoIncr); + transmit_begin(); + return {modm::rf::Running}; + } + + state.reset(State::Idle); + return {modm::rf::Stop}; +} + +template +void +modm::platform::SpiMaster{{ id }}::SpiMaster{{ id }}::transmit_begin() { + state.set(State::Idle); + index = 0; + + if constexpr(std::is_same::value) { + TxByteCount_t::set(state, ByteCount::Byte); + SPDR{{ id }} = tx.u8[0]; + } else if constexpr(std::is_same::value) { + TxByteCount_t::set(state, ByteCount::HalfWord); + bytes_left = 1 * 8; + SPDR{{ id }} = tx.u16[0] >> 8; // >> bytes_left + } else if constexpr(std::is_same::value) { + TxByteCount_t::set(state, ByteCount::Word); + bytes_left = 3 * 8; + SPDR{{ id }} = tx.u32[0] >> 24; // >> bytes_left + + if(rx.u32) rx.u32[index] = 0; // Need reset, because received bytes are | (ored) + } + + // enable Interrupt + SPCR{{ id }} |= (1 << SPIE); +} diff --git a/src/modm/platform/spi/stm32/module.lb b/src/modm/platform/spi/stm32/module.lb index 783b3eb8a3..bc786c79de 100644 --- a/src/modm/platform/spi/stm32/module.lb +++ b/src/modm/platform/spi/stm32/module.lb @@ -29,7 +29,10 @@ class Instance(Module): module.description = "Instance {}".format(self.instance) def prepare(self, module, options): - module.depends(":platform:spi") + module.depends( + ":platform:spi", + ":math:utils" + ) return True def build(self, env): @@ -42,6 +45,7 @@ class Instance(Module): env.template("spi_hal.hpp.in", "spi_hal_{}.hpp".format(self.instance)) env.template("spi_hal_impl.hpp.in", "spi_hal_{}_impl.hpp".format(self.instance)) env.template("spi_master.hpp.in", "spi_master_{}.hpp".format(self.instance)) + env.template("spi_master_impl.hpp.in", "spi_master_{}_impl.hpp".format(self.instance)) env.template("spi_master.cpp.in", "spi_master_{}.cpp".format(self.instance)) if env.has_module(":platform:dma"): env.template("spi_master_dma.hpp.in", "spi_master_{}_dma.hpp".format(self.instance)) diff --git a/src/modm/platform/spi/stm32/spi_base.hpp.in b/src/modm/platform/spi/stm32/spi_base.hpp.in index 875fb3ac03..a42135e057 100644 --- a/src/modm/platform/spi/stm32/spi_base.hpp.in +++ b/src/modm/platform/spi/stm32/spi_base.hpp.in @@ -139,6 +139,14 @@ public: QuarterFull = SPI_CR2_FRXTH, }; %% endif + enum State : uint8_t { + // Word = Bit0, // 0: Byte (uint8_t) transaction, 1: Word (uint16_t) transaction + // AutoIncr = Bit1, // 0: Always send first data of tx, 1: Send consecutive data of tx + Idle = Bit2, // 1: Transaction is Running + LowByte = Bit3, // 1: Low byte has been transmitted + ByteHigh = Bit4, // 1: High byte of word has been transmitted + }; + MODM_FLAGS8(State); }; } // namespace platform diff --git a/src/modm/platform/spi/stm32/spi_hal.hpp.in b/src/modm/platform/spi/stm32/spi_hal.hpp.in index cac0022289..b4cf90ea9d 100644 --- a/src/modm/platform/spi/stm32/spi_hal.hpp.in +++ b/src/modm/platform/spi/stm32/spi_hal.hpp.in @@ -3,6 +3,7 @@ * Copyright (c) 2013-2018, Niklas Hauser * Copyright (c) 2014, Daniel Krebs * Copyright (c) 2020, Mike Wolfram + * Copyright (c) 2021, Thomas Sommer * * This file is part of the modm project. * @@ -82,24 +83,24 @@ public: isTransmitRegisterEmpty(); /** - * Write up to 16 Bit to the data register + * Write up to 8 Bit to the data register * * @warning This method does NOT do any sanity checks!! * It is your responsibility to check if the register * is empty! */ static void - write(uint16_t data); + write(uint8_t data); /** - * Write 8 Bit to the data register + * Write up to 16 Bit to the data register * * @warning This method does NOT do any sanity checks!! * It is your responsibility to check if the register * is empty! */ static void - write(uint8_t data); + write(uint16_t data); /** * Returns the value of the data register diff --git a/src/modm/platform/spi/stm32/spi_hal_impl.hpp.in b/src/modm/platform/spi/stm32/spi_hal_impl.hpp.in index c75a7667c7..d854eef83e 100644 --- a/src/modm/platform/spi/stm32/spi_hal_impl.hpp.in +++ b/src/modm/platform/spi/stm32/spi_hal_impl.hpp.in @@ -3,6 +3,7 @@ * Copyright (c) 2013-2017, Niklas Hauser * Copyright (c) 2014, Daniel Krebs * Copyright (c) 2020, Mike Wolfram + * Copyright (c) 2021, Thomas Sommer * * This file is part of the modm project. * @@ -81,13 +82,8 @@ void inline modm::platform::SpiHal{{ id }}::setDataSize(DataSize dataSize) { // TODO: implement as set/reset bit -%% if "data-size" not in features - SPI{{ id }}->CR1 = (SPI{{ id }}->CR1 & ~static_cast(DataSize::All)) - | static_cast(dataSize); -%% else SPI{{ id }}->CR2 = (SPI{{ id }}->CR2 & ~static_cast(DataSize::All)) | static_cast(dataSize); -%% endif } void inline @@ -119,12 +115,6 @@ modm::platform::SpiHal{{ id }}::isTransmitRegisterEmpty() return static_cast(getInterruptFlags() & InterruptFlag::TxBufferEmpty); } -void inline -modm::platform::SpiHal{{ id }}::write(uint16_t data) -{ - SPI{{ id }}->DR = data; -} - void inline modm::platform::SpiHal{{ id }}::write(uint8_t data) { @@ -136,6 +126,12 @@ modm::platform::SpiHal{{ id }}::write(uint8_t data) } +void inline +modm::platform::SpiHal{{ id }}::write(uint16_t data) +{ + SPI{{ id }}->DR = data; +} + void inline modm::platform::SpiHal{{ id }}::read(uint8_t &data) { diff --git a/src/modm/platform/spi/stm32/spi_master.cpp.in b/src/modm/platform/spi/stm32/spi_master.cpp.in index b31a39c0de..4f6a87b7c9 100644 --- a/src/modm/platform/spi/stm32/spi_master.cpp.in +++ b/src/modm/platform/spi/stm32/spi_master.cpp.in @@ -5,6 +5,7 @@ * Copyright (c) 2012-2017, Niklas Hauser * Copyright (c) 2013, Kevin Läufer * Copyright (c) 2014, Sascha Schade + * Copyright (c) 2021, Thomas Sommer * * This file is part of the modm project. * @@ -18,9 +19,12 @@ // Bit0: single transfer state // Bit1: block transfer state -uint8_t +modm::platform::SpiBase::State_t modm::platform::SpiMaster{{ id }}::state(0); +std::size_t +modm::platform::SpiMaster{{ id }}::index(0); + uint8_t modm::platform::SpiMaster{{ id }}::count(0); @@ -61,85 +65,4 @@ modm::platform::SpiMaster{{ id }}::release(void *ctx) context = nullptr; } return count; -} -// ---------------------------------------------------------------------------- - -modm::ResumableResult -modm::platform::SpiMaster{{ id }}::transfer(uint8_t data) -{ - // this is a manually implemented "fast resumable function" - // there is no context or nesting protection, since we don't need it. - // there are only two states encoded into 1 bit (LSB of state): - // 1. waiting to start, and - // 2. waiting to finish. - - // LSB != Bit0 ? - if ( !(state & Bit0) ) - { - // wait for previous transfer to finish - if (!SpiHal{{ id }}::isTransmitRegisterEmpty()) - return {modm::rf::Running}; - - // start transfer by copying data into register - SpiHal{{ id }}::write(data); - - // set LSB = Bit0 - state |= Bit0; - } - - if (!SpiHal{{ id }}::isReceiveRegisterNotEmpty()) - return {modm::rf::Running}; - - SpiHal{{ id }}::read(data); - - // transfer finished - state &= ~Bit0; - return {modm::rf::Stop, data}; -} - -modm::ResumableResult -modm::platform::SpiMaster{{ id }}::transfer( - const uint8_t * tx, uint8_t * rx, std::size_t length) -{ - // this is a manually implemented "fast resumable function" - // there is no context or nesting protection, since we don't need it. - // there are only two states encoded into 1 bit (Bit1 of state): - // 1. initialize index, and - // 2. wait for 1-byte transfer to finish. - - // we need to globally remember which byte we are currently transferring - static std::size_t index = 0; - - // we are only interested in Bit1 - switch(state & Bit1) - { - case 0: - // we will only visit this state once - state |= Bit1; - - // initialize index and check range - index = 0; - while (index < length) - { - default: - { - // if tx == 0, we use a dummy byte 0x00 - // else we copy it from the array - // call the resumable function - modm::ResumableResult result = transfer(tx ? tx[index] : 0); - - // if the resumable function is still running, so are we - if (result.getState() > modm::rf::NestingError) - return {modm::rf::Running}; - - // if rx != 0, we copy the result into the array - if (rx) rx[index] = result.getResult(); - } - index++; - } - - // clear the state - state &= ~Bit1; - return {modm::rf::Stop}; - } -} +} \ No newline at end of file diff --git a/src/modm/platform/spi/stm32/spi_master.hpp.in b/src/modm/platform/spi/stm32/spi_master.hpp.in index 94bd6887f4..2c9759695f 100644 --- a/src/modm/platform/spi/stm32/spi_master.hpp.in +++ b/src/modm/platform/spi/stm32/spi_master.hpp.in @@ -5,6 +5,7 @@ * Copyright (c) 2012, Georgi Grinshpun * Copyright (c) 2013, Kevin Läufer * Copyright (c) 2014, Sascha Schade + * Copyright (c) 2021, Thomas Sommer * * This file is part of the modm project. * @@ -38,7 +39,9 @@ namespace platform */ class SpiMaster{{ id }} : public modm::SpiMaster { - static uint8_t state; + static SpiBase::State_t state; + static std::size_t index; + static uint8_t count; static void *context; static ConfigurationHandler configuration; @@ -96,7 +99,7 @@ public: // initialize the Spi SpiHal{{ id }}::initialize(prescaler); - state = 0; + state = SpiBase::State(0); } static modm_always_inline void @@ -110,13 +113,13 @@ public: { SpiHal{{ id }}::setDataOrder(static_cast(order)); } + static modm_always_inline void setDataSize(DataSize size) { SpiHal{{ id }}::setDataSize(static_cast(size)); } - static uint8_t acquire(void *ctx, ConfigurationHandler handler = nullptr); @@ -125,28 +128,103 @@ public: static uint8_t - transferBlocking(uint8_t data) + transferBlocking(const uint8_t data) + { + return RF_CALL_BLOCKING(transmit(data)); + } + + static uint16_t + transferBlocking16(const uint16_t data) { - return RF_CALL_BLOCKING(transfer(data)); + return RF_CALL_BLOCKING(transmit(data)); } static void - transferBlocking(const uint8_t *tx, uint8_t *rx, std::size_t length) + transferBlocking(const uint8_t *tx, std::size_t repeat) { - RF_CALL_BLOCKING(transfer(tx, rx, length)); + RF_CALL_BLOCKING(transmit(tx, repeat)); } + static void + transferBlocking16(const uint16_t *tx, std::size_t repeat) + { + RF_CALL_BLOCKING(transmit(tx, repeat)); + } + + static void + transferBlocking16(const uint16_t *tx, std::size_t repeat) + { + RF_CALL_BLOCKING(transmit(tx, rx, length)); + } + + static void + transferBlocking16(const uint16_t *tx, uint16_t *rx, std::size_t length) + { + RF_CALL_BLOCKING(transmit(tx, rx, length)); + } static modm::ResumableResult - transfer(uint8_t data); + transfer(const uint8_t data) { + return transmit(data); + } + + static modm::ResumableResult + transfer16(const uint16_t data) { + return transmit(data); + } static modm::ResumableResult - transfer(const uint8_t *tx, uint8_t *rx, std::size_t length); + transfer(const uint8_t *tx, const std::size_t repeat) { + return transmit(tx, repeat); + } + + static modm::ResumableResult + transfer16(const uint16_t *tx, const std::size_t repeat) { + return transmit(tx, repeat); + } + + static modm::ResumableResult + transfer(const uint8_t *tx, uint8_t *rx, const std::size_t length) { + return transmit(tx, rx, length); + } + + static modm::ResumableResult + transfer16(const uint16_t *tx, uint16_t *rx, const std::size_t length) { + return transmit(tx, rx, length); + } + + // TODO "transmit" == good? + template + static modm::ResumableResult + transmit(const T data); + + template + static modm::ResumableResult + transmit(const T *tx, const std::size_t repeat); + + template + static modm::ResumableResult + transmit(const T *tx, T *rx, const std::size_t length); // end documentation inherited + +protected: + template + static modm::ResumableResult + transmit(const T data); + + template + static modm::ResumableResult + transmit(const T *tx, const std::size_t repeat); + + template + static modm::ResumableResult + transmit(const T *tx, T *rx, const std::size_t length); }; } // namespace platform } // namespace modm +#include "spi_master_{{ id }}_impl.hpp" + #endif // MODM_STM32_SPI_MASTER{{ id }}_HPP diff --git a/src/modm/platform/spi/stm32/spi_master_dma.hpp.in b/src/modm/platform/spi/stm32/spi_master_dma.hpp.in index 1f53b2eb1c..5a73b00191 100644 --- a/src/modm/platform/spi/stm32/spi_master_dma.hpp.in +++ b/src/modm/platform/spi/stm32/spi_master_dma.hpp.in @@ -1,5 +1,6 @@ /* * Copyright (c) 2020, Mike Wolfram + * Copyright (c) 2021, Thomas Sommer * * This file is part of the modm project. * @@ -56,23 +57,100 @@ public: static void initialize(); + static void + setDataSize(DataSize size) + { + SpiMaster{{ id }}::setDataSize(size); + + if(size < DataSize::Bit9) { + Dma::TxChannel::setPeripheralDataSize(DmaBase::PeripheralDataSize::Byte); + Dma::RxChannel::setMemoryDataSize(DmaBase::MemoryDataSize::Byte); + } + else { + Dma::TxChannel::setPeripheralDataSize(DmaBase::PeripheralDataSize::HalfWord); + Dma::RxChannel::setMemoryDataSize(DmaBase::MemoryDataSize::HalfWord); + } + } + static uint8_t - transferBlocking(uint8_t data) + transferBlocking(const uint8_t data) + { + return RF_CALL_BLOCKING(transmit(data)); + } + + static uint16_t + transferBlocking16(const uint16_t data) + { + return RF_CALL_BLOCKING(transmit(data)); + } + + static void + transferBlocking(const uint8_t *tx, uint16_t repeat) + { + RF_CALL_BLOCKING(transmit(tx, repeat)); + } + + static void + transferBlocking16(const uint16_t *tx, uint16_t repeat) + { + RF_CALL_BLOCKING(transmit(tx, repeat)); + } + + static void + transferBlocking(const uint8_t *tx, uint8_t *rx, uint16_t length) { - return RF_CALL_BLOCKING(transfer(data)); + RF_CALL_BLOCKING(transmit(tx, rx, length)); } + template static void - transferBlocking(const uint8_t *tx, uint8_t *rx, std::size_t length) + transferBlocking16(const uint16_t *tx, uint16_t *rx, uint16_t length) { - RF_CALL_BLOCKING(transfer(tx, rx, length)); + RF_CALL_BLOCKING(transmit(tx, rx, length)); } static modm::ResumableResult - transfer(uint8_t data); + transfer(const uint8_t data) { + return transmit(data); + } + + static modm::ResumableResult + transfer16(const uint16_t data) { + return transmit(data); + } + + static modm::ResumableResult + transfer(const uint8_t *tx, const uint16_t repeat) { + return transmit(tx, repeat); + } + + static modm::ResumableResult + transfer16(const uint16_t *tx, const uint16_t repeat) { + return transmit(tx, repeat); + } + + static modm::ResumableResult + transfer(const uint8_t *tx, uint8_t *rx, const uint16_t length) { + return transmit(tx, rx, length); + } + + static modm::ResumableResult + transfer16(const uint16_t *tx, uint16_t *rx, const uint16_t length) { + return transmit(tx, rx, length); + } + + // TODO "transmit" == good? + template + static modm::ResumableResult + transmit(const T data); + + template + static modm::ResumableResult + transmit(const T *tx, const uint16_t repeat); + template static modm::ResumableResult - transfer(const uint8_t *tx, uint8_t *rx, std::size_t length); + transmit(const T *tx, T *rx, const uint16_t length); private: static void diff --git a/src/modm/platform/spi/stm32/spi_master_dma_impl.hpp.in b/src/modm/platform/spi/stm32/spi_master_dma_impl.hpp.in index aa89e933bf..533830127d 100644 --- a/src/modm/platform/spi/stm32/spi_master_dma_impl.hpp.in +++ b/src/modm/platform/spi/stm32/spi_master_dma_impl.hpp.in @@ -1,5 +1,6 @@ /* * Copyright (c) 2020, Mike Wolfram + * Copyright (c) 2021, Thomas Sommer * * This file is part of the modm project. * @@ -45,24 +46,23 @@ modm::platform::SpiMaster{{ id }}_Dma::initialize() SpiMaster{{ id }}::initialize(); -%% if "fifo" in features SpiHal{{ id }}::setRxFifoThreshold(SpiHal{{ id }}::RxFifoThreshold::QuarterFull); -%% endif } template -modm::ResumableResult -modm::platform::SpiMaster{{ id }}_Dma::transfer(uint8_t data) +template +modm::ResumableResult +modm::platform::SpiMaster{{ id }}_Dma::transmit(T data) { // this is a manually implemented "fast resumable function" // there is no context or nesting protection, since we don't need it. // there are only two states encoded into 1 bit (LSB of state): // 1. waiting to start, and // 2. waiting to finish. - // LSB != Bit0 ? - if ( !(state & Bit0) ) + + if (!state.all(SpiBase::LowByte)) { - // disable DMA for single byte transfer + // disable DMA for single transfer SpiHal{{ id }}::disableInterrupt(SpiBase::Interrupt::TxDmaEnable | SpiBase::Interrupt::RxDmaEnable); @@ -74,7 +74,7 @@ modm::platform::SpiMaster{{ id }}_Dma::transfer(uint SpiHal{{ id }}::write(data); // set LSB = Bit0 - state |= Bit0; + state.set(SpiBase::LowByte); } if (!SpiHal{{ id }}::isReceiveRegisterNotEmpty()) @@ -83,28 +83,91 @@ modm::platform::SpiMaster{{ id }}_Dma::transfer(uint SpiHal{{ id }}::read(data); // transfer finished - state &= ~Bit0; + state.reset(SpiBase::LowByte); return {modm::rf::Stop, data}; } template +template modm::ResumableResult -modm::platform::SpiMaster{{ id }}_Dma::transfer(const uint8_t *tx, - uint8_t *rx, std::size_t length) +modm::platform::SpiMaster{{ id }}_Dma::transmit(const T *tx, + const uint16_t repeat) { // this is a manually implemented "fast resumable function" // there is no context or nesting protection, since we don't need it. // there are only two states encoded into 1 bit (Bit1 of state): // 1. initialize index, and - // 2. wait for 1-byte transfer to finish. + // 2. wait for transfer to finish. + + switch(int(state.all(SpiBase::Idle))) + { + case 0: + // we will only visit this state once + state.set(SpiBase::Idle); + dmaError = false; + + SpiHal{{ id }}::enableInterrupt(SpiBase::Interrupt::TxDmaEnable | + SpiBase::Interrupt::RxDmaEnable); + + Dma::TxChannel::setMemoryAddress(uint32_t(tx)); + Dma::TxChannel::setMemoryIncrementMode(false); + + // Althought not used, RxChannel must be treated to keep the (current) Spi-Dma logic alive + Dma::RxChannel::setMemoryAddress(uint32_t(&dmaDummy)); + Dma::RxChannel::setMemoryIncrementMode(false); + + Dma::TxChannel::setDataLength(repeat); + dmaTransmitComplete = false; + Dma::TxChannel::start(); + + Dma::RxChannel::setDataLength(repeat); + Dma::RxChannel::start(); + + [[fallthrough]]; + + default: + while (true) { + if (dmaError) + break; + if (not dmaTransmitComplete) + return { modm::rf::Running }; + if (SpiHal{{ id }}::getInterruptFlags() & SpiBase::InterruptFlag::Busy) + return { modm::rf::Running }; +%% if "fifo" in features + if (SpiHal{{ id }}::getInterruptFlags() & SpiBase::InterruptFlag::FifoTxLevel) + return { modm::rf::Running }; +%% endif + break; + } + + SpiHal{{ id }}::disableInterrupt(SpiBase::Interrupt::TxDmaEnable | + SpiBase::Interrupt::RxDmaEnable); + + state.reset(SpiBase::Idle); + return {modm::rf::Stop}; + } +} + +template +template +modm::ResumableResult +modm::platform::SpiMaster{{ id }}_Dma::transmit(const T *tx, + T *rx, const uint16_t length) +{ + // this is a manually implemented "fast resumable function" + // there is no context or nesting protection, since we don't need it. + // there are only two states encoded into 1 bit (Bit1 of state): + // 1. initialize index, and + // 2. wait for transfer to finish. // we are only interested in Bit1 - switch(state & Bit1) + switch(int(state.all(SpiBase::Idle))) { case 0: // we will only visit this state once - state |= Bit1; + state.set(SpiBase::Idle); dmaError = false; + SpiHal{{ id }}::enableInterrupt(SpiBase::Interrupt::TxDmaEnable | SpiBase::Interrupt::RxDmaEnable); @@ -115,6 +178,7 @@ modm::platform::SpiMaster{{ id }}_Dma::transfer(cons Dma::TxChannel::setMemoryAddress(uint32_t(&dmaDummy)); Dma::TxChannel::setMemoryIncrementMode(false); } + if (rx) { Dma::RxChannel::setMemoryAddress(uint32_t(rx)); Dma::RxChannel::setMemoryIncrementMode(true); @@ -123,14 +187,14 @@ modm::platform::SpiMaster{{ id }}_Dma::transfer(cons Dma::RxChannel::setMemoryIncrementMode(false); } - Dma::RxChannel::setDataLength(length); - dmaReceiveComplete = false; - Dma::RxChannel::start(); - Dma::TxChannel::setDataLength(length); dmaTransmitComplete = false; Dma::TxChannel::start(); + Dma::RxChannel::setDataLength(length); + dmaReceiveComplete = false; + Dma::RxChannel::start(); + [[fallthrough]]; default: @@ -141,19 +205,17 @@ modm::platform::SpiMaster{{ id }}_Dma::transfer(cons return { modm::rf::Running }; if (SpiHal{{ id }}::getInterruptFlags() & SpiBase::InterruptFlag::Busy) return { modm::rf::Running }; -%% if "fifo" in features if (SpiHal{{ id }}::getInterruptFlags() & SpiBase::InterruptFlag::FifoTxLevel) return { modm::rf::Running }; if (SpiHal{{ id }}::getInterruptFlags() & SpiBase::InterruptFlag::FifoRxLevel) return { modm::rf::Running }; -%% endif break; } SpiHal{{ id }}::disableInterrupt(SpiBase::Interrupt::TxDmaEnable | SpiBase::Interrupt::RxDmaEnable); - // clear the state - state &= ~Bit1; + + state.reset(SpiBase::Idle); return {modm::rf::Stop}; } } @@ -164,23 +226,23 @@ modm::platform::SpiMaster{{ id }}_Dma::handleDmaTran { SpiHal{{ id }}::disableInterrupt(SpiBase::Interrupt::TxDmaEnable | SpiBase::Interrupt::RxDmaEnable); - Dma::RxChannel::stop(); Dma::TxChannel::stop(); + Dma::RxChannel::stop(); dmaError = true; } template void -modm::platform::SpiMaster{{ id }}_Dma::handleDmaReceiveComplete() +modm::platform::SpiMaster{{ id }}_Dma::handleDmaTransmitComplete() { - Dma::RxChannel::stop(); - dmaReceiveComplete = true; + Dma::TxChannel::stop(); + dmaTransmitComplete = true; } template void -modm::platform::SpiMaster{{ id }}_Dma::handleDmaTransmitComplete() +modm::platform::SpiMaster{{ id }}_Dma::handleDmaReceiveComplete() { - Dma::TxChannel::stop(); - dmaTransmitComplete = true; -} + Dma::RxChannel::stop(); + dmaReceiveComplete = true; +} \ No newline at end of file diff --git a/src/modm/platform/spi/stm32/spi_master_impl.hpp.in b/src/modm/platform/spi/stm32/spi_master_impl.hpp.in new file mode 100644 index 0000000000..ba8f63fd2b --- /dev/null +++ b/src/modm/platform/spi/stm32/spi_master_impl.hpp.in @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2009-2011, Fabian Greif + * Copyright (c) 2010, Martin Rosekeit + * Copyright (c) 2011-2017, Niklas Hauser + * Copyright (c) 2012, Georgi Grinshpun + * Copyright (c) 2013, Kevin Läufer + * Copyright (c) 2014, Sascha Schade + * Copyright (c) 2021, Thomas Sommer + * + * 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/. + */ +// ---------------------------------------------------------------------------- + +#pragma once +#include "spi_master_{{ id }}.hpp" + +template +modm::ResumableResult +modm::platform::SpiMaster{{ id }}::transmit(T data) +{ + // this is a manually implemented "fast resumable function" + // there is no context or nesting protection, since we don't need it. + // there are only two states encoded into 1 bit (LSB of state): + // 1. waiting to start, and + // 2. waiting to finish. + + if (!state.all(SpiBase::LowByte)) + { + // wait for previous transfer to finish + if (!SpiHal{{ id }}::isTransmitRegisterEmpty()) + return {modm::rf::Running}; + + // start transfer by copying data into register + SpiHal{{ id }}::write(data); + + state.set(SpiBase::LowByte); + } + + if (!SpiHal{{ id }}::isReceiveRegisterNotEmpty()) + return {modm::rf::Running}; + + SpiHal{{ id }}::read(data); + + // transfer finished + state.reset(SpiBase::LowByte); + return {modm::rf::Stop, data}; +} + +template +modm::ResumableResult +modm::platform::SpiMaster{{ id }}::transmit(const T *tx, const std::size_t repeat) +{ + // this is a manually implemented "fast resumable function" + // there is no context or nesting protection, since we don't need it. + // there are only two states encoded into 1 bit (Bit1 of state): + // 1. initialize index, and + // 2. wait for transfer to finish. + + // we are only interested in Bit1 + switch(int(state.all(SpiBase::Idle))) + { + case 0: + // we will only visit this state once + state.set(SpiBase::Idle); + + // initialize index and check range + index = 0; + + while (index < repeat) + { + default: + { + // call the resumable function + modm::ResumableResult result = transmit(tx[0]); + + // if the resumable function is still running, so are we + if (result.getState() > modm::rf::NestingError) + return {modm::rf::Running}; + } + index++; + } + + state.reset(SpiBase::Idle); + return {modm::rf::Stop}; + } +} + +template +modm::ResumableResult +modm::platform::SpiMaster{{ id }}::transmit(const T * tx, T * rx, const std::size_t length) +{ + // this is a manually implemented "fast resumable function" + // there is no context or nesting protection, since we don't need it. + // there are only two states encoded into 1 bit (Bit1 of state): + // 1. initialize index, and + // 2. wait for transfer to finish. + + switch(int(state.all(SpiBase::Idle))) + { + case 0: + // we will only visit this state once + state.set(SpiBase::Idle); + + // initialize index and check range + index = 0; + while (index < length) + { + default: + { + // if tx == 0, we use a dummy byte 0x00 + // else we copy it from the array + // call the resumable function + modm::ResumableResult result = transmit(tx ? tx[index] : 0); + + // if the resumable function is still running, so are we + if (result.getState() > modm::rf::NestingError) + return {modm::rf::Running}; + + // if rx != 0, we copy the result into the array + if (rx) rx[index] = result.getResult(); + } + index++; + } + + // clear the state + state.reset(SpiBase::Idle); + return {modm::rf::Stop}; + } +} \ No newline at end of file diff --git a/src/modm/ui/display/character_display.cpp b/src/modm/ui/character_display.cpp similarity index 100% rename from src/modm/ui/display/character_display.cpp rename to src/modm/ui/character_display.cpp diff --git a/src/modm/ui/display/character_display.hpp b/src/modm/ui/character_display.hpp similarity index 100% rename from src/modm/ui/display/character_display.hpp rename to src/modm/ui/character_display.hpp diff --git a/src/modm/ui/color.cpp b/src/modm/ui/color.cpp deleted file mode 100644 index 7e19a0655f..0000000000 --- a/src/modm/ui/color.cpp +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2009-2010, 2012, Fabian Greif - * Copyright (c) 2010, Martin Rosekeit - * Copyright (c) 2012-2013, Niklas Hauser - * Copyright (c) 2013, David Hebbeker - * - * 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 "color.hpp" - -// ---------------------------------------------------------------------------- -namespace modm { -namespace color { -template<> template<> -void -HsvT::toRgb(RgbT* color) const -{ - uint16_t vs = value * saturation; - uint16_t h6 = 6 * hue; - - uint8_t p = ((value << 8) - vs) >> 8; - uint8_t i = h6 >> 8; - uint16_t f = ((i | 1) << 8) - h6; - if (i & 1) { - f = -f; - } - - uint8_t u = (((uint32_t) value << 16) - (uint32_t) vs * f) >> 16; - uint8_t r = value; - uint8_t g = value; - uint8_t b = value; - switch(i) - { - case 0: g = u; b = p; break; - case 1: r = u; b = p; break; - case 2: r = p; b = u; break; - case 3: r = p; g = u; break; - case 4: r = u; g = p; break; - case 5: g = p; b = u; break; - } - - color->red = r; - color->green = g; - color->blue = b; -} -} // namespace color -} // namespace modm diff --git a/src/modm/ui/color.hpp b/src/modm/ui/color.hpp index 64e4ef53ce..7df13298a2 100644 --- a/src/modm/ui/color.hpp +++ b/src/modm/ui/color.hpp @@ -1,8 +1,4 @@ /* - * Copyright (c) 2009, Martin Rosekeit - * Copyright (c) 2009-2013, Fabian Greif - * Copyright (c) 2012-2013, 2015, Niklas Hauser - * Copyright (c) 2013, David Hebbeker * Copyright (c) 2021, Thomas Sommer * * This file is part of the modm project. @@ -12,10 +8,11 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ // ---------------------------------------------------------------------------- +#pragma once +#include "color/gray.hpp" #include "color/rgb.hpp" #include "color/hsv.hpp" -#include "color/brightness.hpp" -#include "color/rgb565.hpp" -#include "color/rgbhtml.hpp" +#include "color/rgb_html.hpp" +#include "color/rgb_stacked.hpp" \ No newline at end of file diff --git a/src/modm/ui/color/brightness.hpp b/src/modm/ui/color/brightness.hpp deleted file mode 100644 index bc5e961cb5..0000000000 --- a/src/modm/ui/color/brightness.hpp +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright (c) 2021, Thomas Sommer - * - * 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/. - */ -// ---------------------------------------------------------------------------- - -#pragma once - -#include - -#include - -#include "hsv.hpp" -#include "rgb.hpp" -#include "rgb565.hpp" - -namespace modm::color -{ - -// forward declarations for convertion constructors -template -class RgbT; - -template -class HsvT; - -class Rgb565; - -/** - * @brief Brightness as unsigned integral. Add's the math for conversion to and from - * Color-Types. Use with: Grayscale Buffers, Dimmed LEDs, Brightness sensors - * - * @author Thomas Sommer - * - * @tparam T Unsigned integral for the brightness-value - * @ingroup modm_ui_color - */ -template -class BrightnessT -{ -public: - T value{0}; - - constexpr BrightnessT() = default; - - constexpr BrightnessT(T value) : value(value) {} - - /** - * Copy Constructor 8bit->16bit - */ - template - requires std::is_same_v && std::is_same_v - constexpr BrightnessT(const BrightnessT &brightness_other) - : value(brightness_other.value << 8) - {} - - /** - * Copy Constructor 16bit->8bit - */ - template - requires std::is_same_v && std::is_same_v - constexpr BrightnessT(const BrightnessT &brightness_other) - : value(brightness_other.value >> 8) - {} - - /** - * Convertion Constructor for RGB Color - * - * @param rgb RGB Color - */ - template - constexpr BrightnessT(RgbT rgb) - : value((0.2125 * float(rgb.red)) + (0.7154 * float(rgb.green)) + - (0.0721 * float(rgb.blue))) - {} - - /** - * Convertion Constructor for HSV Color - * - * @param hsv HSV Color - */ - template - constexpr BrightnessT(HsvT hsv) : value(hsv.value) - {} - - /** - * Convertion Constructor for RGB565 Color - * - * @param rgb565 RGB565 Color - */ - constexpr BrightnessT(Rgb565 rgb565) : BrightnessT(RgbT(rgb565)) {} - - constexpr bool - operator==(const BrightnessT &other) const = default; -}; - -/// @ingroup modm_ui_color -using Brightness = BrightnessT; - -} // namespace modm::color diff --git a/src/modm/ui/color/color.lb b/src/modm/ui/color/color.lb index f0d4dcf5f1..daa5742fe1 100644 --- a/src/modm/ui/color/color.lb +++ b/src/modm/ui/color/color.lb @@ -18,11 +18,20 @@ def init(module): Color containers and converters in various formats: RGB, HSV, Brightness, Rgb565 """ + def prepare(module, options): - module.depends(":math:utils") + module.depends( + ":math:utils", + ":math:scaling_unsigned", + ":math:saturation" + ) return True + def build(env): env.outbasepath = "modm/src/modm/ui/color" - env.copy(".") + + ignore = ["*pattern*"] + env.copy(".", ignore=env.ignore_paths(*ignore)) + env.copy("../color.hpp") diff --git a/src/modm/ui/color/concepts.hpp b/src/modm/ui/color/concepts.hpp new file mode 100644 index 0000000000..cd3f4e068e --- /dev/null +++ b/src/modm/ui/color/concepts.hpp @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2021, Thomas Sommer + * + * 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/. + */ +// ---------------------------------------------------------------------------- + +#pragma once + +#include + +/** + * @brief Concepts for colortypes and groups of colortypes. + * Key applications: + * - Color conversion constructors + * - Specialisation of buffer manipulation algorithms + * + * @author Thomas Sommer + * @ingroup modm_ui_color + */ +namespace modm::color { + +template +class GrayD; + +template +class RgbD; + +template +class RgbStackedD; + +template +class HsvD; + +/** + * @brief Identify template class instance + * @see: https://stackoverflow.com/questions/44012938/how-to-tell-if-template-type-is-an-instance-of-a-template-class + */ +template class> +struct is_instance : public std::false_type {}; + +template class U> +struct is_instance, U> : public std::true_type {}; + +/** + * @brief Concepts to ident specific colortype instance + */ +template +concept ColorGray = is_instance::value; + +template +concept ColorRgb = is_instance::value; + +template +concept ColorRgbStacked = is_instance::value; + +template +concept ColorHsv = is_instance::value; + +/** + * @brief Concept to ident any colortype instance + */ +template +concept Color = ColorGray || ColorRgb || ColorHsv || ColorRgbStacked; // conjunction +// concept Color = std::convertible_to >; // more tolerant alternative: convertability + +/** + * @brief Concept to ident palettizing (stacking) colortype instances + * + * @see: https://en.wikipedia.org/wiki/Framebuffer#Memory_access + */ +template +concept ColorPalletized = ColorGray and C::Digits < 8 and std::popcount(unsigned(C::Digits)) == 1; + +/** + * @brief Concept to ident non-palettizing (planar) colortype instances + * + * @see: https://en.wikipedia.org/wiki/Framebuffer#Memory_access + */ +template +concept ColorPlanar = !ColorPalletized; + +/** + * @brief Concept to ident monochrome colortype + */ +template +concept ColorMonochrome = std::is_same_v>; +// concept ColorMonochrome = ColorGray and C::Digits == 1; Alternative implementation as reference + +} \ No newline at end of file diff --git a/src/modm/ui/color/gray.hpp b/src/modm/ui/color/gray.hpp new file mode 100644 index 0000000000..7a72ed12e2 --- /dev/null +++ b/src/modm/ui/color/gray.hpp @@ -0,0 +1,195 @@ +/* + * Copyright (c) 2021, Thomas Sommer + * + * 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/. + */ +// ---------------------------------------------------------------------------- + +#pragma once + +#include +#include +#include + +#include +#include + +#include +#include + +#include "concepts.hpp" + +namespace modm::color { +/** + * @brief Unsigned integer with arbitrary number of digits, symetric conversion + * and saturating arithemtics. Used for grayscale + * + * @tparam D Digits + * @tparam P When forming a Buffer with this color, this would be the internal storage. + * Should be MCUs fastest unsigned int -> just keep the default. + * Some Displays require a specific type therefore it's a template argument. + * + * + * @author Thomas Sommer + * @ingroup modm_color_gray + */ +template +// template // TODO +class GrayD : public modm::ScalingUnsigned +{ + static_assert(D > 0, "Positive number of digits required for grayscale / colorchannel type."); +public: + using ValueType = ScalingUnsigned::ValueType; + + // using PalletType = uint32_t; // Best performance on STM32 + // using PalletType = uint16_t; + using PalletType = uint8_t; // Must for Ssd1306, Sh1106 + // using PalletType = P; // TODO PalletType from template argument + + using ScalingUnsigned::ScalingUnsigned; + + template + constexpr GrayD(const C& rgb) + : ScalingUnsigned(( + 2125 * (modm::WideType)(GrayD(rgb.getRed()).value) + + 7154 * (modm::WideType)(GrayD(rgb.getGreen()).value) + + 0721 * (modm::WideType)(GrayD(rgb.getBlue()).value) + ) / 10000 + ) + {} + + template + constexpr GrayD(const C& hsv) : ScalingUnsigned(hsv.getValue()) + {} + + GrayD& operator+=(const ValueType& value) { + modm::Saturated result(this->value); + result+=value; + this->max_cutoff(); + + return *this; + } + + GrayD& operator+=(const GrayD& other) { + modm::Saturated result(this->value); + result+=other.value; + this->max_cutoff(); + + return *this; + } + + GrayD& operator-=(const ValueType& value) { + modm::Saturated result(this->value); + result-=value; + this->max_cutoff(); + + return *this; + } + + GrayD& operator-=(const GrayD& other) { + modm::Saturated result(this->value); + result-=other.value; + this->max_cutoff(); + + return *this; + } + + // IMPLEMENT missing operators + // operator*=() {} + + template + GrayD operator+(const U value) const { + modm::Saturated result(this->value); + result+=value; + + // When all digits of ValueType are used, std::min should optimize away + return {std::min(result.getValue(), this->max)}; + } + + GrayD operator+(const GrayD& other) const { + modm::Saturated result(this->value); + result+=other.value; + + // When all digits of ValueType are used, std::min should optimize away + return {std::min(result.getValue(), this->max)}; + } + + template + GrayD operator-(const U value) const { + modm::Saturated result(this->value); + result-=value; + + // When all digits of ValueType are used, std::min should optimize away + return {std::min(result.getValue(), this->max)}; + } + + GrayD operator-(const GrayD& other) const { + modm::Saturated result(this->value); + result -= other.value; + + return result.getValue(); + } + + template + GrayD operator*(const ScaleType &scale) const { + modm::Saturated result(this->value); + result *= scale; + + // When all digits of ValueType are used, std::min should optimize away + return {std::min(result.getValue(), this->max)}; + } + + template + GrayD + operator*(const ScaleType &scale) const + { + // OPTIMIZE develop optimal decimals from D + static constexpr int decimals = 10; + using WideType = modm::WideType; + WideType result = this->value * ValueType(scale * decimals) / decimals; + return {ValueType(std::min(result, max))}; + } + + void invert() { + this->value ^= bitmask(); + // alterantive: this->value ^= D - this->value; + // alternative: this->value ^= this->max; + } + +private: + + // template // TODO + template + friend class GrayD; + + template + friend modm::IOStream & + operator<<(modm::IOStream &, const GrayD &); +}; + +template +using GrayT = GrayD::digits>; + +using Monochrome = GrayD<1>; +using Gray2 = GrayD<2>; +using Gray4 = GrayD<4>; +using Gray8 = GrayT; +using Gray16 = GrayT; + +#if __has_include() +#include + +template +modm::IOStream & +operator<<(modm::IOStream &os, const GrayD &color) +{ + os << color.value; + return os; +} +#endif + +} \ No newline at end of file diff --git a/src/modm/ui/color/hsv.hpp b/src/modm/ui/color/hsv.hpp index 57fada273b..35a2ce0eeb 100644 --- a/src/modm/ui/color/hsv.hpp +++ b/src/modm/ui/color/hsv.hpp @@ -1,8 +1,4 @@ /* - * Copyright (c) 2009, Martin Rosekeit - * Copyright (c) 2009-2013, Fabian Greif - * Copyright (c) 2012-2013, 2015, Niklas Hauser - * Copyright (c) 2013, David Hebbeker * Copyright (c) 2021, Thomas Sommer * * This file is part of the modm project. @@ -13,109 +9,116 @@ */ // ---------------------------------------------------------------------------- -#ifndef MODM_COLOR_HSV_HPP -#define MODM_COLOR_HSV_HPP +#pragma once #include #include -#include "brightness.hpp" -#include "rgb.hpp" -#include "rgb565.hpp" +#include "concepts.hpp" +#include "gray.hpp" + +#include namespace modm::color { - -// forward declarations for convertion constructors -template -class RgbT; - -template -class BrightnessT; - -class Rgb565; - /** - * @brief Color in HSV Colorspace + * @brief Color in HSV space. Each channel has it's own Memoryaddress. * - * @author Martin Rosekeit, Fabian Greif, Niklas Hauser, David Hebbeker, Thomas Sommer - * @ingroup modm_ui_color + * @tparam DH Digits for hue + * @tparam DS Digits for saturation + * @tparam DV Digits for value + * + * @author Thomas Sommer + * @ingroup modm_ui_color */ -template -class HsvT +template +class HsvD { public: - T hue{0}; - T saturation{0}; - T value{0}; - - constexpr HsvT() = default; + // TODO HueType should wrap rather than saturate + using HueType = GrayD; + using SaturationType = GrayD; + using ValueType = GrayD; - constexpr HsvT(T hue, T saturation, T value) : hue(hue), saturation(saturation), value(value) {} + constexpr HsvD() = default; - /** - * Copy Constructor 8bit->16bit - */ - template - requires std::is_same_v && std::is_same_v - constexpr HsvT(const HsvT &hsv_other) - : hue(hsv_other.hue << 8), saturation(hsv_other.saturation << 8), value(hsv_other.value << 8) + constexpr HsvD(HueType hue, SaturationType saturation, ValueType value) + : hue(hue), saturation(saturation), value(value) {} - /** - * Copy Constructor 16bit->8bit - */ - template - requires std::is_same_v && std::is_same_v - constexpr HsvT(const HsvT &hsv_other) - : hue(hsv_other.hue >> 8), saturation(hsv_other.saturation >> 8), value(hsv_other.value >> 8) + template + constexpr HsvD(const C &other) + : hue(other.hue), saturation(other.saturation), value(other.value) {} - /** - * Convertion Constructor for RGB Color - * - * @param rgb RGB Color - */ - template - constexpr HsvT(const RgbT& rgb); - - /** - * Convertion Constructor for Brightness - * - * @param brightness Brightness 'Color'-object - */ - template - constexpr HsvT(const BrightnessT gray) : hue(0), saturation(0), value(gray.value) - {} + template + constexpr HsvD(const C& rgb); + + template + constexpr HsvD(const CS& rgbstacked) : HsvD(RgbD(rgbstacked)) {} + + void setHue(HueType hue) { this->hue = hue;} + void setSaturation(SaturationType saturation) { this->saturation = saturation;} + void setValue(ValueType value) { this->value = value;} - /** - * Convertion Constructor for RGB565 Color - * - * @param rgb565 RGB565 Color - */ - constexpr HsvT(const Rgb565& rgb565) : HsvT(RgbT(rgb565)) {} + HueType getHue() const { return hue; } + + SaturationType getSaturation() const { return saturation; } + ValueType getValue() const { return value; } constexpr bool - operator==(const HsvT& other) const = default; + operator==(const HsvD& other) const = default; + + // IMPLEMENT missing operators + // operator+=() + // operator-=() + // operator*=() + + void invert() { + hue.invert(); + } + + // Output in human readable format + // Hue in deg, Sat in pct, Value in pct + void iostream_human_readable(IOStream& io) { + using CalcTypeHue = modm::WideType; + io << (CalcTypeHue(hue.getValue()) * 360 / hue.max) << "deg\t"; + + using CalcTypeSaturation = modm::WideType; + io << (CalcTypeSaturation(saturation.getValue()) * 100 / saturation.max) << "%\t"; + + using CalcTypeValue = modm::WideType; + io << (CalcTypeValue(value.getValue()) * 100 / value.max) << "%"; + } private: - template + HueType hue{0}; + SaturationType saturation{0}; + ValueType value{0}; + + template + friend class HsvD; + + template friend IOStream& - operator<<(IOStream&, const HsvT&); + operator<<(IOStream&, const C&); }; -/// @ingroup modm_ui_color -using Hsv = HsvT; +template +using HsvT = HsvD::digits>; +/// @ingroup modm_ui_color +using Hsv888 = HsvD<8>; // Alternative using Hsv888 = HsvT; +using Hsv161616 = HsvD<16>; // Alternative using Hsv888 = HsvT; #if __has_include() #include -template +template IOStream& -operator<<(IOStream& os, const color::HsvT& color) +operator<<(IOStream& os, const C& hsv) { - os << color.hue << "\t" << color.saturation << "\t" << color.value; + os << hsv.getHue() << "\t" << hsv.getSaturation() << "\t" << hsv.getValue(); return os; } #endif @@ -123,5 +126,3 @@ operator<<(IOStream& os, const color::HsvT& color) } // namespace modm::color #include "hsv_impl.hpp" - -#endif // MODM_COLOR_HSV_HPP diff --git a/src/modm/ui/color/hsv_impl.hpp b/src/modm/ui/color/hsv_impl.hpp index c9851b787f..7bc93c3d3b 100644 --- a/src/modm/ui/color/hsv_impl.hpp +++ b/src/modm/ui/color/hsv_impl.hpp @@ -13,59 +13,52 @@ */ // ---------------------------------------------------------------------------- -#ifndef MODM_COLOR_HSV_HPP -#error "Don't include this file directly, use 'hsv.hpp' instead!" -#endif +#pragma once +#include "hsv.hpp" #include /** - * @see http://de.wikipedia.org/wiki/HSV-Farbraum#Umrechnung_RGB_in_HSV.2FHSL - * @param rgb + * @see https://en.wikipedia.org/wiki/HSL_and_HSV */ -template -template -constexpr modm::color::HsvT::HsvT(const modm::color::RgbT &rgb) +template +template +constexpr modm::color::HsvD::HsvD(const C& rgb) { + // OPTIMIZE No need to calculate sharper than the output + // Develop CalcType from target types: HueType, SaturationType and ValueType using CalcType = float; - const CalcType maxValue = std::numeric_limits::max(); - const CalcType _red = CalcType(rgb.red) / maxValue; - const CalcType _blue = CalcType(rgb.blue) / maxValue; - const CalcType _green = CalcType(rgb.green) / maxValue; - const CalcType _max = std::max(_red, std::max(_green, _blue)); - const CalcType _min = std::min(_red, std::min(_green, _blue)); - const CalcType _diff = _max - _min; + + const CalcType maxValue = ValueType::max; + + const CalcType red = CalcType(ValueType(rgb.getRed()).getValue()) / maxValue; + const CalcType green = CalcType(ValueType(rgb.getGreen()).getValue()) / maxValue; + const CalcType blue = CalcType(ValueType(rgb.getBlue()).getValue()) / maxValue; + const CalcType max = modm::vmax(red, green, blue); + const CalcType min = modm::vmin(red, green, blue); + const CalcType diff = max - min; CalcType hue_temp; - // CALCULATE HUE - if (_max == _min) + if (max == min) { // all three color values are the same hue_temp = 0; - value = _max * maxValue; - } else if (_max == _red) + value = max * maxValue; + } else if (max == red) { - hue_temp = 60 * (0 + (_green - _blue) / _diff); - value = rgb.red; - } else if (_max == _green) + hue_temp = 60 * (0 + (green - blue) / diff); + value = rgb.getRed(); + } else if (max == green) { - hue_temp = 60 * (2 + (_blue - _red) / _diff); - value = rgb.green; - } else /*if(_max == _blue)*/ + hue_temp = 60 * (2 + (blue - red) / diff); + value = rgb.getGreen(); + } else // max == blue { - hue_temp = 60 * (4 + (_red - _green) / _diff); - value = rgb.blue; + hue_temp = 60 * (4 + (red - green) / diff); + value = rgb.getBlue(); } - if (hue_temp < 0) - hue = (hue_temp + 360) * (maxValue / 360); - else - hue = (hue_temp) * (maxValue / 360); - - // CALCULATE SATURATION - if (_max == 0) - saturation = 0; - else - saturation = _diff / _max * maxValue; -} + hue = hue_temp < 0 ? (hue_temp + 360) * (maxValue / 360) : (hue_temp) * (maxValue / 360); + saturation = max ? diff / max * maxValue : 0; +} \ No newline at end of file diff --git a/src/modm/ui/color/rgb.hpp b/src/modm/ui/color/rgb.hpp index cb5df9f00a..82d67c1c81 100644 --- a/src/modm/ui/color/rgb.hpp +++ b/src/modm/ui/color/rgb.hpp @@ -1,8 +1,4 @@ /* - * Copyright (c) 2009, Martin Rosekeit - * Copyright (c) 2009-2013, Fabian Greif - * Copyright (c) 2012-2013, 2015, Niklas Hauser - * Copyright (c) 2013, David Hebbeker * Copyright (c) 2021, Thomas Sommer * * This file is part of the modm project. @@ -13,8 +9,7 @@ */ // ---------------------------------------------------------------------------- -#ifndef MODM_COLOR_RGB_HPP -#define MODM_COLOR_RGB_HPP +#pragma once #include #include @@ -24,102 +19,95 @@ #include #include -#include "brightness.hpp" -#include "hsv.hpp" -#include "rgb565.hpp" +#include "concepts.hpp" +#include "gray.hpp" namespace modm::color { - -// forward declarations for convertion constructors -template -class HsvT; - -template -class BrightnessT; - -class Rgb565; - /** - * Color in HSV Colorspace + * @brief Color in RGB space. Each channel has it's own Memoryaddress. + * + * @tparam DR Digits for red channel + * @tparam DG Digits for green channel + * @tparam DB Digits for blue channel * - * @author Martin Rosekeit, Fabian Greif, Niklas Hauser, David Hebbeker, Thomas Sommer - * @ingroup modm_ui_color + * @author Thomas Sommer + * @ingroup modm_ui_color */ -template -class RgbT +template +class RgbD { public: - T red{0}; - T green{0}; - T blue{0}; + using RedType = GrayD; + using GreenType = GrayD; + using BlueType = GrayD; - using TSum = modm::WideType; + // using RgbSumValueType = modm::fits_any_t; - constexpr RgbT() = default; + constexpr RgbD() = default; - constexpr RgbT(T red, T green, T blue) : red(red), green(green), blue(blue) {} - - /** - * Copy Constructor 8bit->16bit - */ - template - requires std::is_same_v && std::is_same_v - constexpr RgbT(const RgbT &rgb_other) - : red(rgb_other.red << 8), green(rgb_other.green << 8), blue(rgb_other.blue << 8) + constexpr RgbD(RedType red, GreenType green, BlueType blue) + : red(red), green(green), blue(blue) {} - /** - * Copy Constructor 16bit->8bit - */ - template - requires std::is_same_v && std::is_same_v - constexpr RgbT(const RgbT &rgb_other) - : red(rgb_other.red >> 8), green(rgb_other.green >> 8), blue(rgb_other.blue >> 8) + template + constexpr RgbD(const C& rgb_other) + : red(rgb_other.red), green(rgb_other.green), blue(rgb_other.blue) {} - /** - * Convertion Constructor for HSV Color - * - * @param hsv HSV Color - */ - template - constexpr RgbT(const HsvT& hsv); - - /** - * Convertion Constructor for Brightness - * - * @param brightness Brightness 'Color'-object - */ - // TODO Plump conversion, implement the right way - template - constexpr RgbT(const BrightnessT brightness) - : red(brightness), green(brightness), blue(brightness) - {} + template + constexpr RgbD(const C &gray) + : red(gray), green(gray), blue(gray) {} - /** - * Convertion Constructor for RGB565 Color - * - * @param rgb565 RGB565 Color - */ - constexpr RgbT(const Rgb565& rgb565) - : red((rgb565.color >> 8) & 0xF8), - green((rgb565.color >> 3) & 0xFC), - blue(rgb565.color << 3) + template + constexpr RgbD(const C& rgbs) + : red(rgbs.getRed()), green(rgbs.getGreen()), blue(rgbs.getBlue()) {} + template + constexpr RgbD(const C& hsv); + + void setRed(RedType red) { this->red = red;} + void setGreen(GreenType green) { this->green = green;} + void setBlue(BlueType blue) { this->blue = blue;} + + RedType getRed() const { return red; } + GreenType getGreen() const { return green; } + BlueType getBlue() const { return blue; } + + // IMPLEMENT missing operators + // operator+=() + // operator-=() + // operator*=() + constexpr bool - operator==(const RgbT& other) const = default; + operator==(const RgbD& other) const = default; + + void invert() { + red.invert(); + green.invert(); + blue.invert(); + } private: - template + RedType red{0}; + GreenType green{0}; + BlueType blue{0}; + + template + friend class RgbD; + + template friend IOStream& - operator<<(IOStream&, const RgbT&); + operator<<(IOStream&, const C&); }; -/// @ingroup modm_ui_color -using Rgb = RgbT; +template +using RgbT = RgbD::digits>; +/// @ingroup modm_ui_color +using Rgb888 = RgbD<8>; // Alternative using Rgb888 = RgbT +using Rgb161616 = RgbD<16>; // Alternative using Rgb161616 = RgbT /** * Normalize color values based on a clear value @@ -133,32 +121,31 @@ using Rgb = RgbT; * * @ingroup modm_ui_color */ -template +template requires std::is_fundamental_v -constexpr RgbT -normalizeColor(RgbT rgb, IntermediateType multiplier = 1) +constexpr ReturnColor +normalizeColor(C rgb, IntermediateType multiplier = 1) { const IntermediateType sum = IntermediateType(rgb.red) + rgb.green + rgb.blue; - return RgbT(IntermediateType(rgb.red) * multiplier / sum, - IntermediateType(rgb.green) * multiplier / sum, - IntermediateType(rgb.blue) * multiplier / sum); + return { + IntermediateType(rgb.getRed()) * multiplier / sum, + IntermediateType(rgb.getGreen()) * multiplier / sum, + IntermediateType(rgb.getBlue()) * multiplier / sum + }; } - #if __has_include() #include -template +template IOStream& -operator<<(IOStream& os, const color::RgbT& color) +operator<<(IOStream& os, const C& rgb) { - os << color.red << "\t" << color.green << "\t" << color.blue; + os << rgb.getRed() << "\t" << rgb.getGreen() << "\t" << rgb.getBlue(); return os; } #endif } // namespace modm::color -#include "rgb_impl.hpp" - -#endif // MODM_COLOR_RGB_HPP +#include "rgb_impl.hpp" \ No newline at end of file diff --git a/src/modm/ui/color/rgb565.hpp b/src/modm/ui/color/rgb565.hpp deleted file mode 100644 index dbb19aba56..0000000000 --- a/src/modm/ui/color/rgb565.hpp +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright (c) 2021, Thomas Sommer - * - * 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/. - */ -// ---------------------------------------------------------------------------- - -#pragma once - -#include - -#include "brightness.hpp" -#include "hsv.hpp" -#include "rgb.hpp" - -namespace modm::color -{ - -// forward declarations for convertion constructors -template -class RgbT; - -template -class HsvT; - -template -class BrightnessT; - -/** - * Color in RGB Colorspace, 16 bits: RRRR RGGG GGGB BBBB - * - * @author Fabian Greif, Thomas Sommer - * @ingroup modm_ui_color - */ -class Rgb565 -{ -public: - uint16_t color{0x0000}; - - using RgbCalcType = RgbT; - - constexpr Rgb565() = default; - - /** - * Constructor for preformatted Rgb565 Color - * - * @param color Preformatted RGB-color in 565-format: RRRR RGGG GGGB BBBB - */ - constexpr Rgb565(uint16_t color) : color(color) {} - - /** - * Constructor for components: red, green, blue - * - * @param red Red color component - * @param green Green color component - * @param blue Blue color component - */ - constexpr Rgb565(uint8_t red, uint8_t green, uint8_t blue) - : color(uint16_t(red & 0xF8) << 8 | uint16_t(green & 0xFC) << 3 | uint16_t(blue >> 3)) - {} - - /** - * Convertion Constructor for RGB Color - * - * @param rgb RGB Color - */ - template - constexpr Rgb565(const RgbT &rgb) : Rgb565(rgb.red, rgb.green, rgb.blue) - {} - - /** - * Convertion Constructor for HSV Color - * - * @param hsv HSV Color - */ - template - constexpr Rgb565(const HsvT &hsv) : Rgb565(RgbCalcType(hsv)) - {} - - /** - * Convertion Constructor for Brightness - * - * @param brightness Brightness 'Color'-object - */ - template - constexpr Rgb565(const BrightnessT brightness) : Rgb565(RgbCalcType(brightness)) - {} - - constexpr bool - operator==(const Rgb565 &other) const = default; - - /// Saturated addition ⊕ - Rgb565 - operator+(const Rgb565 other) const - { - const int8_t red_raw = (color >> 11) + (other.color >> 11); - const uint16_t red = std::clamp(red_raw, 0, 31) << 11; - - const int8_t green_raw = (color >> 5 & 0x3F) + (other.color >> 5 & 0x3F); - const uint16_t green = std::clamp(green_raw, 0, 63) << 5; - - const int8_t blue_raw = (color & 0x1F) + (other.color & 0x1F); - const uint16_t blue = std::clamp(blue_raw, 0, 31); - - return Rgb565(red | green | blue); - } - - /// Saturated substraction ⊖ - Rgb565 - operator-(const Rgb565 other) const - { - const int8_t red_raw = (color >> 11) - (other.color >> 11); - const uint16_t red = std::clamp(red_raw, 0, 0x1F) << 11; - - const int8_t green_raw = (color >> 5 & 0x3F) - (other.color >> 5 & 0x3F); - const uint16_t green = std::clamp(green_raw, 0, 0x3F) << 5; - - const int8_t blue_raw = (color & 0x1F) - (other.color & 0x1F); - const uint16_t blue = std::clamp(blue_raw, 0, 0x1F); - - return Rgb565(red | green | blue); - } -}; - -} // namespace modm::color diff --git a/src/modm/ui/color/rgb_html.hpp b/src/modm/ui/color/rgb_html.hpp new file mode 100644 index 0000000000..681c73ef91 --- /dev/null +++ b/src/modm/ui/color/rgb_html.hpp @@ -0,0 +1,192 @@ +/* + * Copyright (c) 2021, Thomas Sommer + * + * 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/. + */ +// ---------------------------------------------------------------------------- + +#pragma once + +#include "rgb.hpp" + +namespace modm::color::html +{ + +/** + * Constant HTML Colornames in RGB Colorspace + * + * @see https://htmlcolorcodes.com/color-names/ + * @see modm:color:RgbD + * @author Thomas Sommer + * @ingroup modm_ui_color + * @{ + */ + +// Red HTML Color Names +static constexpr Rgb888 IndianRed(205, 92, 92); +static constexpr Rgb888 LightCoral(240, 128, 128); +static constexpr Rgb888 Salmon(250, 128, 114); +static constexpr Rgb888 DarkSalmon(233, 150, 122); +static constexpr Rgb888 LightSalmon(255, 160, 122); +static constexpr Rgb888 Crimson(220, 20, 60); +static constexpr Rgb888 Red(255, 0, 0); +static constexpr Rgb888 FireBrick(178, 34, 34); +static constexpr Rgb888 DarkRed(139, 0, 0); + +// Pink HTML Color Names +static constexpr Rgb888 Pink(255, 192, 203); +static constexpr Rgb888 LightPink(255, 182, 193); +static constexpr Rgb888 HotPink(255, 105, 180); +static constexpr Rgb888 DeepPink(255, 20, 147); +static constexpr Rgb888 MediumVioletRed(199, 21, 133); +static constexpr Rgb888 PaleVioletRed(219, 112, 147); + +// Orange HTML Color Names +static constexpr Rgb888 Coral(255, 127, 80); +static constexpr Rgb888 Tomato(255, 99, 71); +static constexpr Rgb888 OrangeRed(255, 69, 0); +static constexpr Rgb888 DarkOrange(255, 140, 0); +static constexpr Rgb888 Orange(25, 165, 0); + +// Yellow HTML Color Names +static constexpr Rgb888 Gold(255, 215, 0); +static constexpr Rgb888 Yellow(255, 255, 0); +static constexpr Rgb888 LightYellow(255, 255, 224); +static constexpr Rgb888 LemonChiffon(255, 250, 205); +static constexpr Rgb888 LightGoldenrodYellow(250, 250, 210); +static constexpr Rgb888 PapayaWhip(255, 239, 213); +static constexpr Rgb888 Moccasin(255, 228, 181); +static constexpr Rgb888 PeachPuff(255, 218, 185); +static constexpr Rgb888 PaleGoldenrod(238, 232, 170); +static constexpr Rgb888 Khaki(240, 230, 140); +static constexpr Rgb888 DarkKhaki(189, 183, 107); + +// Purple HTML Color Names +static constexpr Rgb888 Lavender(230, 230, 250); +static constexpr Rgb888 Thistle(216, 191, 216); +static constexpr Rgb888 Plum(221, 160, 221); +static constexpr Rgb888 Violet(238, 130, 238); +static constexpr Rgb888 Orchid(218, 112, 214); +static constexpr Rgb888 Fuchsia(255, 0, 255); +static constexpr Rgb888 Magenta(255, 0, 255); +static constexpr Rgb888 MediumOrchid(186, 85, 211); +static constexpr Rgb888 MediumPurple(147, 112, 219); +static constexpr Rgb888 RebeccaPurple(102, 51, 153); +static constexpr Rgb888 BlueViolet(138, 43, 226); +static constexpr Rgb888 DarkViolet(148, 0, 211); +static constexpr Rgb888 DarkOrchid(153, 50, 204); +static constexpr Rgb888 DarkMagenta(139, 0, 139); +static constexpr Rgb888 Purple(128, 0, 128); +static constexpr Rgb888 Indigo(75, 0, 130); +static constexpr Rgb888 SlateBlue(106, 90, 205); +static constexpr Rgb888 DarkSlateBlue(72, 61, 139); + +// Green HTML Color Names +static constexpr Rgb888 GreenYellow(173, 255, 47); +static constexpr Rgb888 Chartreuse(127, 255, 0); +static constexpr Rgb888 LawnGreen(124, 252, 0); +static constexpr Rgb888 Lime(0, 255, 0); +static constexpr Rgb888 LimeGreen(50, 205, 50); +static constexpr Rgb888 PaleGreen(152, 251, 152); +static constexpr Rgb888 LightGreen(144, 238, 144); +static constexpr Rgb888 MediumSpringGreen(0, 250, 154); +static constexpr Rgb888 SpringGreen(0, 255, 127); +static constexpr Rgb888 MediumSeaGreen(60, 179, 113); +static constexpr Rgb888 SeaGreen(46, 139, 87); +static constexpr Rgb888 ForestGreen(34, 139, 34); +static constexpr Rgb888 Green(0, 128, 0); +static constexpr Rgb888 DarkGreen(0, 100, 0); +static constexpr Rgb888 YellowGreen(154, 205, 50); +static constexpr Rgb888 OliveDrab(107, 142, 35); +static constexpr Rgb888 Olive(128, 128, 0); +static constexpr Rgb888 DarkOliveGreen(85, 107, 47); +static constexpr Rgb888 MediumAquamarine(102, 205, 170); +static constexpr Rgb888 DarkSeaGreen(143, 188, 139); +static constexpr Rgb888 LightSeaGreen(32, 178, 170); +static constexpr Rgb888 DarkCyan(0, 139, 139); +static constexpr Rgb888 Teal(0, 128, 128); + +// Blue HTML Color Names +static constexpr Rgb888 Aqua(0, 255, 255); +static constexpr Rgb888 Cyan(0, 255, 255); +static constexpr Rgb888 LightCyan(224, 255, 255); +static constexpr Rgb888 PaleTurquoise(175, 238, 238); +static constexpr Rgb888 Aquamarine(127, 255, 212); +static constexpr Rgb888 Turquoise(64, 224, 208); +static constexpr Rgb888 MediumTurquoise(72, 209, 204); +static constexpr Rgb888 DarkTurquoise(0, 206, 209); +static constexpr Rgb888 CadetBlue(95, 158, 160); +static constexpr Rgb888 SteelBlue(70, 130, 180); +static constexpr Rgb888 LightSteelBlue(176, 196, 222); +static constexpr Rgb888 PowderBlue(176, 224, 230); +static constexpr Rgb888 LightBlue(173, 216, 230); +static constexpr Rgb888 SkyBlue(135, 206, 235); +static constexpr Rgb888 LightSkyBlue(135, 206, 250); +static constexpr Rgb888 DeepSkyBlue(0, 191, 255); +static constexpr Rgb888 DodgerBlue(30, 144, 255); +static constexpr Rgb888 CornflowerBlue(100, 149, 237); +static constexpr Rgb888 MediumSlateBlue(123, 104, 238); +static constexpr Rgb888 RoyalBlue(65, 105, 225); +static constexpr Rgb888 Blue(0, 0, 255); +static constexpr Rgb888 MediumBlue(0, 0, 205); +static constexpr Rgb888 DarkBlue(0, 0, 139); +static constexpr Rgb888 Navy(0, 0, 128); +static constexpr Rgb888 MidnightBlue(25, 25, 112); + +// Brown HTML Color Names +static constexpr Rgb888 Cornsilk(255, 248, 220); +static constexpr Rgb888 BlanchedAlmond(255, 235, 205); +static constexpr Rgb888 Bisque(255, 228, 196); +static constexpr Rgb888 NavajoWhite(255, 222, 173); +static constexpr Rgb888 Wheat(245, 222, 179); +static constexpr Rgb888 BurlyWood(222, 184, 135); +static constexpr Rgb888 Tan(210, 180, 140); +static constexpr Rgb888 RosyBrown(188, 143, 143); +static constexpr Rgb888 SandyBrown(244, 164, 96); +static constexpr Rgb888 Goldenrod(218, 165, 32); +static constexpr Rgb888 DarkGoldenrod(184, 134, 11); +static constexpr Rgb888 Peru(205, 133, 63); +static constexpr Rgb888 Chocolate(210, 105, 30); +static constexpr Rgb888 SaddleBrown(139, 69, 19); +static constexpr Rgb888 Sienna(160, 82, 45); +static constexpr Rgb888 Brown(165, 42, 42); +static constexpr Rgb888 Maroon(128, 0, 0); + +// White HTML Color Names +static constexpr Rgb888 White(255, 255, 255); +static constexpr Rgb888 Snow(255, 250, 250); +static constexpr Rgb888 HoneyDew(240, 255, 240); +static constexpr Rgb888 MintCream(245, 255, 250); +static constexpr Rgb888 Azure(240, 255, 255); +static constexpr Rgb888 AliceBlue(240, 248, 255); +static constexpr Rgb888 GhostWhite(248, 248, 255); +static constexpr Rgb888 WhiteSmoke(245, 245, 245); +static constexpr Rgb888 SeaShell(255, 245, 238); +static constexpr Rgb888 Beige(245, 245, 220); +static constexpr Rgb888 OldLace(253, 245, 230); +static constexpr Rgb888 FloralWhite(255, 250, 230); +static constexpr Rgb888 Ivory(255, 255, 240); +static constexpr Rgb888 AntiqueWhite(250, 235, 215); +static constexpr Rgb888 Linen(250, 240, 230); +static constexpr Rgb888 LavenderBlush(255, 240, 245); +static constexpr Rgb888 MistyRose(255, 228, 225); + +// Gray HTML Color Names +static constexpr Rgb888 Gainsboro(220, 220, 220); +static constexpr Rgb888 LightGray(211, 211, 211); +static constexpr Rgb888 Silver(192, 192, 192); +static constexpr Rgb888 DarkGray(169, 169, 169); +static constexpr Rgb888 Gray(128, 128, 128); +static constexpr Rgb888 DimGray(105, 105, 105); +static constexpr Rgb888 LightSlateGray(119, 136, 153); +static constexpr Rgb888 SlateGray(112, 128, 144); +static constexpr Rgb888 DarkSlateGray(47, 79, 79); +static constexpr Rgb888 Black(0, 0, 0); + +/// @} + +} // namespace modm::color::html diff --git a/src/modm/ui/color/rgb_impl.hpp b/src/modm/ui/color/rgb_impl.hpp index b8b9a17841..c70299d6c2 100644 --- a/src/modm/ui/color/rgb_impl.hpp +++ b/src/modm/ui/color/rgb_impl.hpp @@ -13,38 +13,43 @@ */ // ---------------------------------------------------------------------------- -#ifndef MODM_COLOR_RGB_HPP -#error "Don't include this file directly, use 'rgb.hpp' instead!" -#endif +#pragma once +#include "rgb.hpp" -#include - -namespace modm::color +template +template +constexpr modm::color::RgbD::RgbD(const C& hsv) { + // OPTIMIZE No need to calculate sharper than the output + // Develop CalcType from types of conversion target: RedType, GreenType and BlueType. + using CalcType = C::ValueType; + using ValueType = CalcType::ValueType; -// TODO Finish generalisation for uint16_t -template -template -constexpr RgbT::RgbT(const HsvT &hsv) -{ - uint16_t vs = hsv.value * hsv.saturation; - uint16_t h6 = 6 * hsv.hue; + using WideType = modm::WideType; + using WideWideType = modm::WideType; + static_assert(!std::is_same_v, "C::ValueType too big"); + + const ValueType hue = CalcType(hsv.getHue()).getValue(); + const ValueType saturation = CalcType(hsv.getSaturation()).getValue(); + const ValueType value = CalcType(hsv.getValue()).getValue(); - T p = ((hsv.value << 8) - vs) >> 8; - T i = h6 >> 8; - uint16_t f = ((i | 1) << 8) - h6; - if (i & 1) { f = -f; } - T u = (((uint32_t)hsv.value << 16) - (uint32_t)vs * f) >> 16; + const WideType vs = value * saturation; + const WideType h6 = 6 * hue; + + ValueType i = h6 >> CalcType::Digits; + WideType f = ((i | 1) << CalcType::Digits) - h6; + if (i & 1) f = -f; + + CalcType p(((value << CalcType::Digits) - vs) >> CalcType::Digits); + CalcType u(((WideWideType(value) << 2 * CalcType::Digits) - WideWideType(vs) * f) >> 2 * CalcType::Digits); switch (i) { - case 0: red = hsv.value; green = u; blue = p; break; - case 1: red = u; green = hsv.value; blue = p; break; - case 2: red = p; green = hsv.value; blue = u; break; - case 3: red = p; green = u; blue = hsv.value; break; - case 4: red = u; green = p; blue = hsv.value; break; - case 5: red = hsv.value; green = p; blue = u; break; + case 0: red = hsv.getValue(); green = u; blue = p; break; + case 1: red = u; green = hsv.getValue(); blue = p; break; + case 2: red = p; green = hsv.getValue(); blue = u; break; + case 3: red = p; green = u; blue = hsv.getValue(); break; + case 4: red = u; green = p; blue = hsv.getValue(); break; + case 5: red = hsv.getValue(); green = p; blue = u; break; } -} - -} // namespace modm::color +} \ No newline at end of file diff --git a/src/modm/ui/color/rgb_stacked.hpp b/src/modm/ui/color/rgb_stacked.hpp new file mode 100644 index 0000000000..4fc181120b --- /dev/null +++ b/src/modm/ui/color/rgb_stacked.hpp @@ -0,0 +1,156 @@ +/* + * Copyright (c) 2021, Thomas Sommer + * + * 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/. + */ +// ---------------------------------------------------------------------------- + +#pragma once + +#include "concepts.hpp" + +namespace modm::color { +/** + * @brief Stores a RGB color in a stacked. Consumes potentialy less space but + * does not offer immediate access to each channel making it Inefficient + * to calc with. Primary application as display- or storage-format. + * + * @tparam DR Bits for red channel + * @tparam DG Bits for green channel + * @tparam DB Bits for blue channel + * + * @author Thomas Sommer + * @ingroup modm_ui_color + */ +template +class RgbStackedD +{ +public: + using RedType = GrayD; + using GreenType = GrayD; + using BlueType = GrayD; + + using ValueType = uint_t::least; + + constexpr RgbStackedD() = default; + + constexpr RgbStackedD(const ValueType value) : value(value){}; + + constexpr RgbStackedD(RedType red, GreenType green, BlueType blue) + : value(red.getValue() << (DG + DB) | green.getValue() << DB | blue.getValue()) {} + + template + constexpr RgbStackedD(const C &other) + : RgbStackedD(other.getRed(), other.getGreen(), other.getBlue()) {} + + template + constexpr RgbStackedD(C &&other) + : RgbStackedD(other.getRed(), other.getGreen(), other.getBlue()) {} + + template + constexpr RgbStackedD(const C &gray) + : RgbStackedD(RgbD(gray)) {} + + template + constexpr RgbStackedD(const C &rgb) + : RgbStackedD(rgb.getRed(), rgb.getGreen(), rgb.getBlue()) {} + + template + constexpr RgbStackedD(const C &hsv) + : RgbStackedD(RgbD<5,6,5>(hsv)) {} + + void setRed(RedType red) + { value = (value & ~(RedType::mask << (DG + DB))) | red.value << (DG + DB); } + void setGreen(GreenType green) + { value = (value & ~(GreenType::mask << DB)) | green.value << DB; } + void setBlue(BlueType blue) + { value = (value & ~BlueType::mask) | blue.value; } + + RedType getRed() const { return value >> (DG + DB); } + GreenType getGreen() const { return value >> DB & GreenType::max;} + BlueType getBlue() const { return value & BlueType::max; } + + ValueType getValue() const { return value; } + + template + constexpr RgbStackedD operator+(RgbStackedT_ &other) { + return { + getRed() + other.getRed(), + getGreen() + other.getGreen(), + getBlue() + other.getBlue() + }; + } + + // OPTIMIZE Do move semantics help for these operators? + template + constexpr RgbStackedD operator-(RgbStackedT_ &other) { + return { + getRed() - other.getRed(), + getGreen() - other.getGreen(), + getBlue() - other.getBlue() + }; + } + + template + RgbStackedD& operator+=(RgbStackedT_ &other) { + setRed(getRed() + other.getRed()); + setGreen(getGreen() + other.getGreen()); + setBlue(getBlue() + other.getBlue()); + return *this; + } + + template + RgbStackedD& operator-=(RgbStackedT_ &other) { + setRed(getRed() - other.getRed()); + setGreen(getGreen() - other.getGreen()); + setBlue(getBlue() - other.getBlue()); + return *this; + } + + // IMPLEMENT missing operators + // operator+ + // operator- + + constexpr bool + operator==(const RgbStackedD& other) const = default; + + void invert() { + value ^= bitmask(); + } + + template + constexpr RgbStackedD operator*(ScaleType &scale) { + return { + getRed() * scale, + getGreen() * scale, + getBlue() * scale + }; + } + +private: + ValueType value; + + template + friend IOStream& + operator<<(IOStream&, const C&); +}; + +using Rgb565 = RgbStackedD<5,6,5>; + +#if __has_include() +#include + +template +IOStream& +operator<<(IOStream& os, const C& rgb) +{ + os << rgb.getRed() << "\t" << rgb.getGreen() << "\t" << rgb.getBlue(); + return os; +} +#endif + +} \ No newline at end of file diff --git a/src/modm/ui/color/rgbhtml.hpp b/src/modm/ui/color/rgbhtml.hpp deleted file mode 100644 index 71d6c9dccd..0000000000 --- a/src/modm/ui/color/rgbhtml.hpp +++ /dev/null @@ -1,191 +0,0 @@ -/* - * Copyright (c) 2021, Thomas Sommer - * - * 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/. - */ -// ---------------------------------------------------------------------------- - -#pragma once - -#include "rgb.hpp" - -namespace modm::color::html -{ - -/** - * Constant HTML Colornames in RGB Colorspace - * - * @see https://htmlcolorcodes.com/color-names/ - * @see modm:color:RgbT - * @ingroup modm_ui_color - * @{ - */ - -// Red HTML Color Names -static constexpr Rgb IndianRed(205, 92, 92); -static constexpr Rgb LightCoral(240, 128, 128); -static constexpr Rgb Salmon(250, 128, 114); -static constexpr Rgb DarkSalmon(233, 150, 122); -static constexpr Rgb LightSalmon(255, 160, 122); -static constexpr Rgb Crimson(220, 20, 60); -static constexpr Rgb Red(255, 0, 0); -static constexpr Rgb FireBrick(178, 34, 34); -static constexpr Rgb DarkRed(139, 0, 0); - -// Pink HTML Color Names -static constexpr Rgb Pink(255, 192, 203); -static constexpr Rgb LightPink(255, 182, 193); -static constexpr Rgb HotPink(255, 105, 180); -static constexpr Rgb DeepPink(255, 20, 147); -static constexpr Rgb MediumVioletRed(199, 21, 133); -static constexpr Rgb PaleVioletRed(219, 112, 147); - -// Orange HTML Color Names -static constexpr Rgb Coral(255, 127, 80); -static constexpr Rgb Tomato(255, 99, 71); -static constexpr Rgb OrangeRed(255, 69, 0); -static constexpr Rgb DarkOrange(255, 140, 0); -static constexpr Rgb Orange(25, 165, 0); - -// Yellow HTML Color Names -static constexpr Rgb Gold(255, 215, 0); -static constexpr Rgb Yellow(255, 255, 0); -static constexpr Rgb LightYellow(255, 255, 224); -static constexpr Rgb LemonChiffon(255, 250, 205); -static constexpr Rgb LightGoldenrodYellow(250, 250, 210); -static constexpr Rgb PapayaWhip(255, 239, 213); -static constexpr Rgb Moccasin(255, 228, 181); -static constexpr Rgb PeachPuff(255, 218, 185); -static constexpr Rgb PaleGoldenrod(238, 232, 170); -static constexpr Rgb Khaki(240, 230, 140); -static constexpr Rgb DarkKhaki(189, 183, 107); - -// Purple HTML Color Names -static constexpr Rgb Lavender(230, 230, 250); -static constexpr Rgb Thistle(216, 191, 216); -static constexpr Rgb Plum(221, 160, 221); -static constexpr Rgb Violet(238, 130, 238); -static constexpr Rgb Orchid(218, 112, 214); -static constexpr Rgb Fuchsia(255, 0, 255); -static constexpr Rgb Magenta(255, 0, 255); -static constexpr Rgb MediumOrchid(186, 85, 211); -static constexpr Rgb MediumPurple(147, 112, 219); -static constexpr Rgb RebeccaPurple(102, 51, 153); -static constexpr Rgb BlueViolet(138, 43, 226); -static constexpr Rgb DarkViolet(148, 0, 211); -static constexpr Rgb DarkOrchid(153, 50, 204); -static constexpr Rgb DarkMagenta(139, 0, 139); -static constexpr Rgb Purple(128, 0, 128); -static constexpr Rgb Indigo(75, 0, 130); -static constexpr Rgb SlateBlue(106, 90, 205); -static constexpr Rgb DarkSlateBlue(72, 61, 139); - -// Green HTML Color Names -static constexpr Rgb GreenYellow(173, 255, 47); -static constexpr Rgb Chartreuse(127, 255, 0); -static constexpr Rgb LawnGreen(124, 252, 0); -static constexpr Rgb Lime(0, 255, 0); -static constexpr Rgb LimeGreen(50, 205, 50); -static constexpr Rgb PaleGreen(152, 251, 152); -static constexpr Rgb LightGreen(144, 238, 144); -static constexpr Rgb MediumSpringGreen(0, 250, 154); -static constexpr Rgb SpringGreen(0, 255, 127); -static constexpr Rgb MediumSeaGreen(60, 179, 113); -static constexpr Rgb SeaGreen(46, 139, 87); -static constexpr Rgb ForestGreen(34, 139, 34); -static constexpr Rgb Green(0, 128, 0); -static constexpr Rgb DarkGreen(0, 100, 0); -static constexpr Rgb YellowGreen(154, 205, 50); -static constexpr Rgb OliveDrab(107, 142, 35); -static constexpr Rgb Olive(128, 128, 0); -static constexpr Rgb DarkOliveGreen(85, 107, 47); -static constexpr Rgb MediumAquamarine(102, 205, 170); -static constexpr Rgb DarkSeaGreen(143, 188, 139); -static constexpr Rgb LightSeaGreen(32, 178, 170); -static constexpr Rgb DarkCyan(0, 139, 139); -static constexpr Rgb Teal(0, 128, 128); - -// Blue HTML Color Names -static constexpr Rgb Aqua(0, 255, 255); -static constexpr Rgb Cyan(0, 255, 255); -static constexpr Rgb LightCyan(224, 255, 255); -static constexpr Rgb PaleTurquoise(175, 238, 238); -static constexpr Rgb Aquamarine(127, 255, 212); -static constexpr Rgb Turquoise(64, 224, 208); -static constexpr Rgb MediumTurquoise(72, 209, 204); -static constexpr Rgb DarkTurquoise(0, 206, 209); -static constexpr Rgb CadetBlue(95, 158, 160); -static constexpr Rgb SteelBlue(70, 130, 180); -static constexpr Rgb LightSteelBlue(176, 196, 222); -static constexpr Rgb PowderBlue(176, 224, 230); -static constexpr Rgb LightBlue(173, 216, 230); -static constexpr Rgb SkyBlue(135, 206, 235); -static constexpr Rgb LightSkyBlue(135, 206, 250); -static constexpr Rgb DeepSkyBlue(0, 191, 255); -static constexpr Rgb DodgerBlue(30, 144, 255); -static constexpr Rgb CornflowerBlue(100, 149, 237); -static constexpr Rgb MediumSlateBlue(123, 104, 238); -static constexpr Rgb RoyalBlue(65, 105, 225); -static constexpr Rgb Blue(0, 0, 255); -static constexpr Rgb MediumBlue(0, 0, 205); -static constexpr Rgb DarkBlue(0, 0, 139); -static constexpr Rgb Navy(0, 0, 128); -static constexpr Rgb MidnightBlue(25, 25, 112); - -// Brown HTML Color Names -static constexpr Rgb Cornsilk(255, 248, 220); -static constexpr Rgb BlanchedAlmond(255, 235, 205); -static constexpr Rgb Bisque(255, 228, 196); -static constexpr Rgb NavajoWhite(255, 222, 173); -static constexpr Rgb Wheat(245, 222, 179); -static constexpr Rgb BurlyWood(222, 184, 135); -static constexpr Rgb Tan(210, 180, 140); -static constexpr Rgb RosyBrown(188, 143, 143); -static constexpr Rgb SandyBrown(244, 164, 96); -static constexpr Rgb Goldenrod(218, 165, 32); -static constexpr Rgb DarkGoldenrod(184, 134, 11); -static constexpr Rgb Peru(205, 133, 63); -static constexpr Rgb Chocolate(210, 105, 30); -static constexpr Rgb SaddleBrown(139, 69, 19); -static constexpr Rgb Sienna(160, 82, 45); -static constexpr Rgb Brown(165, 42, 42); -static constexpr Rgb Maroon(128, 0, 0); - -// White HTML Color Names -static constexpr Rgb White(255, 255, 255); -static constexpr Rgb Snow(255, 250, 250); -static constexpr Rgb HoneyDew(240, 255, 240); -static constexpr Rgb MintCream(245, 255, 250); -static constexpr Rgb Azure(240, 255, 255); -static constexpr Rgb AliceBlue(240, 248, 255); -static constexpr Rgb GhostWhite(248, 248, 255); -static constexpr Rgb WhiteSmoke(245, 245, 245); -static constexpr Rgb SeaShell(255, 245, 238); -static constexpr Rgb Beige(245, 245, 220); -static constexpr Rgb OldLace(253, 245, 230); -static constexpr Rgb FloralWhite(255, 250, 230); -static constexpr Rgb Ivory(255, 255, 240); -static constexpr Rgb AntiqueWhite(250, 235, 215); -static constexpr Rgb Linen(250, 240, 230); -static constexpr Rgb LavenderBlush(255, 240, 245); -static constexpr Rgb MistyRose(255, 228, 225); - -// Gray HTML Color Names -static constexpr Rgb Gainsboro(220, 220, 220); -static constexpr Rgb LightGray(211, 211, 211); -static constexpr Rgb Silver(192, 192, 192); -static constexpr Rgb DarkGray(169, 169, 169); -static constexpr Rgb Gray(128, 128, 128); -static constexpr Rgb DimGray(105, 105, 105); -static constexpr Rgb LightSlateGray(119, 136, 153); -static constexpr Rgb SlateGray(112, 128, 144); -static constexpr Rgb DarkSlateGray(47, 79, 79); -static constexpr Rgb Black(0, 0, 0); - -/// @} - -} // namespace modm::color::html diff --git a/src/modm/ui/color_impl.hpp b/src/modm/ui/color_impl.hpp deleted file mode 100644 index 5cf8aa4439..0000000000 --- a/src/modm/ui/color_impl.hpp +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (c) 2013-2015, Niklas Hauser - * - * 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_COLOR_HPP -# error "Don't include this file directly, use 'color.hpp' instead!" -#endif - -#include -#include - -/** - * @see http://de.wikipedia.org/wiki/HSV-Farbraum#Umrechnung_RGB_in_HSV.2FHSL - * @param color - */ -template template -inline void -modm::color::RgbT::toHsv(HsvT* color) const -{ - typedef float CalcType; - const CalcType maxValue = std::numeric_limits::max(); - const CalcType _red = static_cast(red) / maxValue; - const CalcType _blue = static_cast(blue) / maxValue; - const CalcType _green = static_cast(green) / maxValue; - const CalcType _max = std::max(_red, std::max(_green, _blue)); - const CalcType _min = std::min(_red, std::min(_green, _blue)); - const CalcType _diff = _max - _min; - - CalcType hue_temp; - - // CALCULATE HUE - if(_max == _min) { // all three color values are the same - hue_temp = 0; - color->value = _max * maxValue; - } - else if(_max == _red) { - hue_temp = 60 * (0 + (_green - _blue) / _diff ); - color->value = red; - } - else if(_max == _green) { - hue_temp = 60 * (2 + (_blue - _red) / _diff ); - color->value = green; - } - else /*if(_max == _blue)*/ { - hue_temp = 60 * (4 + (_red - _green) / _diff ); - color->value = blue; - } - - if(hue_temp < 0) { - color->hue = (hue_temp + 360 ) * (maxValue / 360); - } - else { - color->hue = (hue_temp ) * (maxValue / 360); - } - - // CALCULATE SATURATION - if(_max == 0) { - color->saturation = 0; - } else { - color->saturation = _diff / _max * maxValue; - } -} - -template -modm::IOStream& -modm::color::operator << ( modm::IOStream& os, const modm::color::RgbT& color) -{ - os << color.red << "\t" << color.green << "\t" << color.blue; - return os; -} - -template -modm::IOStream& -modm::color::operator << ( modm::IOStream& os, const modm::color::HsvT& color) -{ - os << color.hue << "\t" << color.saturation << "\t" << color.value; - return os; -} \ No newline at end of file diff --git a/src/modm/ui/display.hpp b/src/modm/ui/display.hpp deleted file mode 100644 index c54170c96d..0000000000 --- a/src/modm/ui/display.hpp +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright (c) 2009, Martin Rosekeit - * Copyright (c) 2009-2011, 2019, Fabian Greif - * Copyright (c) 2012, Sascha Schade - * Copyright (c) 2012-2014, Niklas Hauser - * Copyright (c) 2021, Thomas Sommer - * - * 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 "display/font.hpp" -#include "display/image.hpp" - -#include "display/character_display.hpp" -#include "display/color_graphic_display.hpp" -#include "display/monochrome_graphic_display.hpp" diff --git a/src/modm/ui/display/color_graphic_display.hpp b/src/modm/ui/display/color_graphic_display.hpp deleted file mode 100644 index c9a6cbf5ef..0000000000 --- a/src/modm/ui/display/color_graphic_display.hpp +++ /dev/null @@ -1,60 +0,0 @@ -#ifndef MODM_COLOR_GRAPHIC_DISPLAY_HPP -#define MODM_COLOR_GRAPHIC_DISPLAY_HPP - -#include - -#include "graphic_display.hpp" - -using namespace modm::platform; - -namespace modm -{ -class ColorGraphicDisplay : public GraphicDisplay -{ -public: - ColorGraphicDisplay() - : foregroundColor(color::html::White), backgroundColor(color::html::Black) - {} - - virtual color::Rgb565 - getPixel(int16_t x, int16_t y) const = 0; - - /** - * Set a new foreground color. - * Used for drawing operations. Default is white. - */ - inline void - setColor(const color::Rgb565 color) - { - foregroundColor = color; - } - - inline color::Rgb565 - getColor() const - { - return foregroundColor; - } - - /** - * Set background color. - * Used when clearing the screen. Default is black. - */ - inline void - setBackgroundColor(const color::Rgb565 color) - { - backgroundColor = color; - } - - inline color::Rgb565 - getBackgroundColor() const - { - return backgroundColor; - } - -protected: - color::Rgb565 foregroundColor; - color::Rgb565 backgroundColor; -}; -} // namespace modm - -#endif // MODM_COLOR_GRAPHIC_DISPLAY_HPP diff --git a/src/modm/ui/display/font/all_caps_3x5.font b/src/modm/ui/display/font/all_caps_3x5.font deleted file mode 100644 index 281d971d6a..0000000000 --- a/src/modm/ui/display/font/all_caps_3x5.font +++ /dev/null @@ -1,677 +0,0 @@ -#font : All Caps 3x5 -#width : 3 -#height : 5 -#hspace : 1 -#vspace : 1 - -#char : 32 ' ' -[ ] -[ ] -[ ] -[ ] -[ ] - -#char : 33 '!' -[#] -[#] -[#] -[ ] -[#] - -#char : 34 '"' -[##] -[##] -[ ] -[ ] -[ ] - -#char : 35 '#' -[# # ] -[####] -[# # ] -[####] -[# # ] - -#char : 36 '$' -[ # ] -[###] -[ # ] -[###] -[ # ] - -#char : 37 '%' -[ ] -[# #] -[ # ] -[# #] -[ ] - -#char : 38 '&' -[ ## ] -[# #] -[ ## ] -[# # ] -[## #] - -#char : 39 ''' -[#] -[#] -[ ] -[ ] -[ ] - -#char : 40 '(' -[ #] -[# ] -[# ] -[# ] -[ #] - -#char : 41 ')' -[# ] -[ #] -[ #] -[ #] -[# ] - -#char : 42 '*' -[ ] -[# #] -[ # ] -[# #] -[ ] - -#char : 43 '+' -[ ] -[ # ] -[###] -[ # ] -[ ] - -#char : 44 ',' -[ ] -[ ] -[ ] -[ #] -[# ] - -#char : 45 '-' -[ ] -[ ] -[###] -[ ] -[ ] - -#char : 46 '.' -[ ] -[ ] -[ ] -[ ] -[#] - -#char : 47 '/' -[ #] -[ # ] -[ # ] -[ # ] -[# ] - -#char : 48 '0' -[###] -[# #] -[# #] -[# #] -[###] - -#char : 49 '1' -[ # ] -[## ] -[ # ] -[ # ] -[###] - -#char : 50 '2' -[###] -[ #] -[###] -[# ] -[###] - -#char : 51 '3' -[###] -[ #] -[ ##] -[ #] -[###] - -#char : 52 '4' -[# ] -[# #] -[###] -[ #] -[ #] - -#char : 53 '5' -[###] -[# ] -[###] -[ #] -[###] - -#char : 54 '6' -[###] -[# ] -[###] -[# #] -[###] - -#char : 55 '7' -[###] -[ #] -[ # ] -[ # ] -[ # ] - -#char : 56 '8' -[###] -[# #] -[###] -[# #] -[###] - -#char : 57 '9' -[###] -[# #] -[###] -[ #] -[###] - -#char : 58 ':' -[ ] -[#] -[ ] -[#] -[ ] - -#char : 59 ';' -[ ] -[ #] -[ ] -[ #] -[# ] - -#char : 60 '<' -[ #] -[ # ] -[# ] -[ # ] -[ #] - -#char : 61 '=' -[ ] -[###] -[ ] -[###] -[ ] - -#char : 62 '>' -[# ] -[ # ] -[ #] -[ # ] -[# ] - -#char : 63 '?' -[###] -[ #] -[ # ] -[ ] -[ # ] - -#char : 64 '@' -[ ] -[ ##] -[# ] -[# #] -[###] - -#char : 65 'A' -[ # ] -[# #] -[###] -[# #] -[# #] - -#char : 66 'B' -[## ] -[# #] -[## ] -[# #] -[## ] - -#char : 67 'C' -[ ##] -[# ] -[# ] -[# ] -[ ##] - -#char : 68 'D' -[## ] -[# #] -[# #] -[# #] -[## ] - -#char : 69 'E' -[###] -[# ] -[## ] -[# ] -[###] - -#char : 70 'F' -[###] -[# ] -[## ] -[# ] -[# ] - -#char : 71 'G' -[ ##] -[# ] -[# #] -[# #] -[ ##] - -#char : 72 'H' -[# #] -[# #] -[###] -[# #] -[# #] - -#char : 73 'I' -[#] -[#] -[#] -[#] -[#] - -#char : 74 'J' -[ #] -[ #] -[ #] -[ #] -[# ] - -#char : 75 'K' -[# ] -[# #] -[## ] -[# #] -[# #] - -#char : 76 'L' -[# ] -[# ] -[# ] -[# ] -[###] - -#char : 77 'M' -[# #] -[###] -[# #] -[# #] -[# #] - -#char : 78 'N' -[## ] -[# #] -[# #] -[# #] -[# #] - -#char : 79 'O' -[ ##] -[# #] -[# #] -[# #] -[## ] - -#char : 80 'P' -[## ] -[# #] -[###] -[# ] -[# ] - -#char : 81 'Q' -[ # ] -[# #] -[# #] -[###] -[ ##] - -#char : 82 'R' -[## ] -[# #] -[## ] -[# #] -[# #] - -#char : 83 'S' -[ ##] -[# ] -[ # ] -[ #] -[## ] - -#char : 84 'T' -[###] -[ # ] -[ # ] -[ # ] -[ # ] - -#char : 85 'U' -[# #] -[# #] -[# #] -[# #] -[ ##] - -#char : 86 'V' -[# #] -[# #] -[# #] -[# #] -[ # ] - -#char : 87 'W' -[# #] -[# #] -[# #] -[###] -[# #] - -#char : 88 'X' -[# #] -[# #] -[ # ] -[# #] -[# #] - -#char : 89 'Y' -[# #] -[# #] -[###] -[ # ] -[ # ] - -#char : 90 'Z' -[###] -[ #] -[ # ] -[# ] -[###] - -#char : 91 '[' -[##] -[# ] -[# ] -[# ] -[##] - -#char : 92 '\' -[# ] -[ # ] -[ # ] -[ # ] -[ #] - -#char : 93 ']' -[##] -[ #] -[ #] -[ #] -[##] - -#char : 94 '^' -[ # ] -[# #] -[ ] -[ ] -[ ] - -#char : 95 '_' -[ ] -[ ] -[ ] -[ ] -[###] - -#char : 96 '`' -[# ] -[ #] -[ ] -[ ] -[ ] - -#char : 97 'a' -[ # ] -[# #] -[###] -[# #] -[# #] - -#char : 98 'b' -[## ] -[# #] -[## ] -[# #] -[## ] - -#char : 99 'c' -[ ##] -[# ] -[# ] -[# ] -[ ##] - -#char : 100 'd' -[## ] -[# #] -[# #] -[# #] -[## ] - -#char : 101 'e' -[###] -[# ] -[## ] -[# ] -[###] - -#char : 102 'f' -[###] -[# ] -[## ] -[# ] -[# ] - -#char : 103 'g' -[ ##] -[# ] -[# #] -[# #] -[ ##] - -#char : 104 'h' -[# #] -[# #] -[###] -[# #] -[# #] - -#char : 105 'i' -[#] -[#] -[#] -[#] -[#] - -#char : 106 'j' -[ #] -[ #] -[ #] -[ #] -[# ] - -#char : 107 'k' -[# ] -[# #] -[## ] -[# #] -[# #] - -#char : 108 'l' -[# ] -[# ] -[# ] -[# ] -[###] - -#char : 109 'm' -[# #] -[###] -[# #] -[# #] -[# #] - -#char : 110 'n' -[## ] -[# #] -[# #] -[# #] -[# #] - -#char : 111 'o' -[ ##] -[# #] -[# #] -[# #] -[## ] - -#char : 112 'p' -[## ] -[# #] -[###] -[# ] -[# ] - -#char : 113 'q' -[ # ] -[# #] -[# #] -[###] -[ ##] - -#char : 114 'r' -[## ] -[# #] -[## ] -[# #] -[# #] - -#char : 115 's' -[ ##] -[# ] -[ # ] -[ #] -[## ] - -#char : 116 't' -[###] -[ # ] -[ # ] -[ # ] -[ # ] - -#char : 117 'u' -[# #] -[# #] -[# #] -[# #] -[ ##] - -#char : 118 'v' -[# #] -[# #] -[# #] -[# #] -[ # ] - -#char : 119 'w' -[# #] -[# #] -[# #] -[###] -[# #] - -#char : 120 'x' -[# #] -[# #] -[ # ] -[# #] -[# #] - -#char : 121 'y' -[# #] -[# #] -[###] -[ # ] -[ # ] - -#char : 122 'z' -[###] -[ #] -[ # ] -[# ] -[###] - -#char : 123 '{' -[ #] -[ # ] -[## ] -[ # ] -[ #] - -#char : 124 '|' -[#] -[#] -[#] -[#] -[#] - -#char : 125 '}' -[# ] -[ # ] -[ ##] -[ # ] -[# ] - -#char : 126 '~' -[ ] -[ # ] -[###] -[ ] -[ ] - -#char : 127 -[ ] -[ ] -[ ] -[ ] -[ ] diff --git a/src/modm/ui/display/font/arcade_classic.font b/src/modm/ui/display/font/arcade_classic.font deleted file mode 100644 index 4bde9e6854..0000000000 --- a/src/modm/ui/display/font/arcade_classic.font +++ /dev/null @@ -1,965 +0,0 @@ -#font : Arcade Classic -#width : 7 -#height : 8 -#hspace : 0 -#vspace : 1 - -#char : 32 ' ' -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] - -#char : 33 '!' -[ ### ] -[ ### ] -[ ## ] -[ ## ] -[ # ] -[ ] -[ # ] -[ ] - -#char : 34 '"' -[ ## ## ] -[ ## ## ] -[ # # ] -[ # # ] -[ ] -[ ] -[ ] -[ ] - -#char : 35 '#' -[ ## ## ] -[ ## ## ] -[#######] -[ ## ## ] -[#######] -[ ## ## ] -[ ## ## ] -[ ] - -#char : 36 '$' -[ # ] -[ ##### ] -[## ] -[ ##### ] -[ ##] -[ ##### ] -[ # ] -[ ] - -#char : 37 '%' -[ ] -[## ##] -[## ## ] -[ ## ] -[ ## ] -[ ## ##] -[## ##] -[ ] - -#char : 38 '&' -[ #### ] -[## ## ] -[## ## ] -[ ### ] -[## ####] -[## ## ] -[ ### ##] -[ ] - -#char : 39 ''' -[ ## ] -[ ## ] -[ # ] -[ # ] -[ ] -[ ] -[ ] -[ ] - -#char : 40 '(' -[ ## ] -[ ## ] -[ ## ] -[ ## ] -[ ## ] -[ ## ] -[ ## ] -[ ] - -#char : 41 ')' -[ ## ] -[ ## ] -[ ## ] -[ ## ] -[ ## ] -[ ## ] -[ ## ] -[ ] - -#char : 42 '*' -[ ] -[ # ] -[ # # # ] -[ ### ] -[ # # # ] -[ # ] -[ ] -[ ] - -#char : 43 '+' -[ ] -[ # ] -[ # ] -[ ##### ] -[ # ] -[ # ] -[ ] -[ ] - -#char : 44 ',' -[ ] -[ ] -[ ] -[ ] -[ ## ] -[ ## ] -[ # ] -[ # ] - -#char : 45 '-' -[ ] -[ ] -[ ] -[ ##### ] -[ ] -[ ] -[ ] -[ ] - -#char : 46 '.' -[ ] -[ ] -[ ] -[ ] -[ ] -[ ## ] -[ ## ] -[ ] - -#char : 47 '/' -[ ] -[ ##] -[ ## ] -[ ## ] -[ ## ] -[ ## ] -[## ] -[ ] - -#char : 48 '0' -[ ### ] -[ # ## ] -[## ##] -[## ##] -[## ##] -[ ## # ] -[ ### ] -[ ] - -#char : 49 '1' -[ ## ] -[ ### ] -[ ## ] -[ ## ] -[ ## ] -[ ## ] -[###### ] -[ ] - -#char : 50 '2' -[ ##### ] -[## ##] -[ ###] -[ #### ] -[ ## ] -[## ] -[#######] -[ ] - -#char : 51 '3' -[ ######] -[ ## ] -[ ## ] -[ #### ] -[ ##] -[## ##] -[ ##### ] -[ ] - -#char : 52 '4' -[ ### ] -[ #### ] -[ ## ## ] -[## ## ] -[#######] -[ ## ] -[ ## ] -[ ] - -#char : 53 '5' -[###### ] -[## ] -[###### ] -[ ##] -[ ##] -[## ##] -[ ##### ] -[ ] - -#char : 54 '6' -[ #### ] -[ ## ] -[## ] -[###### ] -[## ##] -[## ##] -[ ##### ] -[ ] - -#char : 55 '7' -[#######] -[## ##] -[ ## ] -[ ## ] -[ ## ] -[ ## ] -[ ## ] -[ ] - -#char : 56 '8' -[ #### ] -[## # ] -[### # ] -[ #### ] -[# ####] -[# ##] -[ ##### ] -[ ] - -#char : 57 '9' -[ ##### ] -[## ##] -[## ##] -[ ######] -[ ##] -[ ## ] -[ #### ] -[ ] - -#char : 58 ':' -[ ] -[ ] -[ ## ] -[ ## ] -[ ] -[ ## ] -[ ## ] -[ ] - -#char : 59 ';' -[ ] -[ ] -[ ## ] -[ ## ] -[ ] -[ ## ] -[ # ] -[ # ] - -#char : 60 '<' -[ ## ] -[ ## ] -[ ## ] -[ ## ] -[ ## ] -[ ## ] -[ ## ] -[ ] - -#char : 61 '=' -[ ] -[ ] -[ ##### ] -[ ] -[ ##### ] -[ ] -[ ] -[ ] - -#char : 62 '>' -[ ## ] -[ ## ] -[ ## ] -[ ## ] -[ ## ] -[ ## ] -[ ## ] -[ ] - -#char : 63 '?' -[ ##### ] -[## ##] -[ ##] -[ ### ] -[ ## ] -[ ] -[ ## ] -[ ] - -#char : 64 '@' -[ ### ] -[ # # ] -[# # #] -[# # # #] -[# # ###] -[# # ] -[ # # ] -[ ### ] - -#char : 65 'A' -[ ### ] -[ ## ## ] -[## ##] -[## ##] -[#######] -[## ##] -[## ##] -[ ] - -#char : 66 'B' -[###### ] -[## ##] -[## ##] -[###### ] -[## ##] -[## ##] -[###### ] -[ ] - -#char : 67 'C' -[ #### ] -[ ## ##] -[## ] -[## ] -[## ] -[ ## ##] -[ #### ] -[ ] - -#char : 68 'D' -[##### ] -[## ## ] -[## ##] -[## ##] -[## ##] -[## ## ] -[##### ] -[ ] - -#char : 69 'E' -[###### ] -[## ] -[## ] -[##### ] -[## ] -[## ] -[#######] -[ ] - -#char : 70 'F' -[#######] -[## ] -[## ] -[###### ] -[## ] -[## ] -[## ] -[ ] - -#char : 71 'G' -[ #####] -[ ## ] -[## ] -[## ###] -[## ##] -[ ## ##] -[ #####] -[ ] - -#char : 72 'H' -[## ##] -[## ##] -[## ##] -[#######] -[## ##] -[## ##] -[## ##] -[ ] - -#char : 73 'I' -[###### ] -[ ## ] -[ ## ] -[ ## ] -[ ## ] -[ ## ] -[###### ] -[ ] - -#char : 74 'J' -[ ##] -[ ##] -[ ##] -[ ##] -[ ##] -[## ##] -[ ##### ] -[ ] - -#char : 75 'K' -[## ##] -[## ## ] -[## ## ] -[#### ] -[##### ] -[## ### ] -[## ###] -[ ] - -#char : 76 'L' -[## ] -[## ] -[## ] -[## ] -[## ] -[## ] -[#######] -[ ] - -#char : 77 'M' -[## ##] -[### ###] -[#######] -[## # ##] -[## ##] -[## ##] -[## ##] -[ ] - -#char : 78 'N' -[## ##] -[### ##] -[#### ##] -[## ####] -[## ###] -[## ##] -[## ##] -[ ] - -#char : 79 'O' -[ ##### ] -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[ ##### ] -[ ] - -#char : 80 'P' -[###### ] -[## ##] -[## ##] -[## ##] -[###### ] -[## ] -[## ] -[ ] - -#char : 81 'Q' -[ ##### ] -[## ##] -[## ##] -[## ##] -[## ####] -[## ## ] -[ #### #] -[ ] - -#char : 82 'R' -[###### ] -[## ##] -[## ##] -[## ## ] -[##### ] -[## ### ] -[## ###] -[ ] - -#char : 83 'S' -[ #### ] -[## ## ] -[## ] -[ ##### ] -[ ##] -[## ##] -[ ##### ] -[ ] - -#char : 84 'T' -[###### ] -[ ## ] -[ ## ] -[ ## ] -[ ## ] -[ ## ] -[ ## ] -[ ] - -#char : 85 'U' -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[ ##### ] -[ ] - -#char : 86 'V' -[## ##] -[## ##] -[## ##] -[## ##] -[ ## ## ] -[ ### ] -[ # ] -[ ] - -#char : 87 'W' -[## ##] -[## ##] -[## ##] -[## # ##] -[#######] -[### ###] -[## ##] -[ ] - -#char : 88 'X' -[## ##] -[### ###] -[ ##### ] -[ ### ] -[ ##### ] -[### ###] -[## ##] -[ ] - -#char : 89 'Y' -[## ## ] -[## ## ] -[## ## ] -[ #### ] -[ ## ] -[ ## ] -[ ## ] -[ ] - -#char : 90 'Z' -[#######] -[ ###] -[ ### ] -[ ### ] -[ ### ] -[### ] -[#######] -[ ] - -#char : 91 '[' -[ ### ] -[ ## ] -[ ## ] -[ ## ] -[ ## ] -[ ## ] -[ ### ] -[ ] - -#char : 92 '\' -[ ] -[## ] -[ ## ] -[ ## ] -[ ## ] -[ ## ] -[ ##] -[ ] - -#char : 93 ']' -[ ### ] -[ ## ] -[ ## ] -[ ## ] -[ ## ] -[ ## ] -[ ### ] -[ ] - -#char : 94 '^' -[ ] -[ # ] -[ ### ] -[ ] -[ ] -[ ] -[ ] -[ ] - -#char : 95 '_' -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[#######] - -#char : 96 '`' -[ ] -[ ## ] -[ ## ] -[ ] -[ ] -[ ] -[ ] -[ ] - -#char : 97 'a' -[ ### ] -[ ## ## ] -[## ##] -[## ##] -[#######] -[## ##] -[## ##] -[ ] - -#char : 98 'b' -[###### ] -[## ##] -[## ##] -[###### ] -[## ##] -[## ##] -[###### ] -[ ] - -#char : 99 'c' -[ #### ] -[ ## ##] -[## ] -[## ] -[## ] -[ ## ##] -[ #### ] -[ ] - -#char : 100 'd' -[##### ] -[## ## ] -[## ##] -[## ##] -[## ##] -[## ## ] -[##### ] -[ ] - -#char : 101 'e' -[###### ] -[## ] -[## ] -[##### ] -[## ] -[## ] -[#######] -[ ] - -#char : 102 'f' -[#######] -[## ] -[## ] -[###### ] -[## ] -[## ] -[## ] -[ ] - -#char : 103 'g' -[ #####] -[ ## ] -[## ] -[## ###] -[## ##] -[ ## ##] -[ #####] -[ ] - -#char : 104 'h' -[## ##] -[## ##] -[## ##] -[#######] -[## ##] -[## ##] -[## ##] -[ ] - -#char : 105 'i' -[###### ] -[ ## ] -[ ## ] -[ ## ] -[ ## ] -[ ## ] -[###### ] -[ ] - -#char : 106 'j' -[ ##] -[ ##] -[ ##] -[ ##] -[ ##] -[## ##] -[ ##### ] -[ ] - -#char : 107 'k' -[## ##] -[## ## ] -[## ## ] -[#### ] -[##### ] -[## ### ] -[## ###] -[ ] - -#char : 108 'l' -[## ] -[## ] -[## ] -[## ] -[## ] -[## ] -[#######] -[ ] - -#char : 109 'm' -[## ##] -[### ###] -[#######] -[## # ##] -[## ##] -[## ##] -[## ##] -[ ] - -#char : 110 'n' -[## ##] -[### ##] -[#### ##] -[## ####] -[## ###] -[## ##] -[## ##] -[ ] - -#char : 111 'o' -[ ##### ] -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[ ##### ] -[ ] - -#char : 112 'p' -[###### ] -[## ##] -[## ##] -[## ##] -[###### ] -[## ] -[## ] -[ ] - -#char : 113 'q' -[ ##### ] -[## ##] -[## ##] -[## ##] -[## ####] -[## ## ] -[ #### #] -[ ] - -#char : 114 'r' -[###### ] -[## ##] -[## ##] -[## ## ] -[##### ] -[## ### ] -[## ###] -[ ] - -#char : 115 's' -[ #### ] -[## ## ] -[## ] -[ ##### ] -[ ##] -[## ##] -[ ##### ] -[ ] - -#char : 116 't' -[###### ] -[ ## ] -[ ## ] -[ ## ] -[ ## ] -[ ## ] -[ ## ] -[ ] - -#char : 117 'u' -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[ ##### ] -[ ] - -#char : 118 'v' -[## ##] -[## ##] -[## ##] -[## ##] -[ ## ## ] -[ ### ] -[ # ] -[ ] - -#char : 119 'w' -[## ##] -[## ##] -[## ##] -[## # ##] -[#######] -[### ###] -[## ##] -[ ] - -#char : 120 'x' -[## ##] -[### ###] -[ ##### ] -[ ### ] -[ ##### ] -[### ###] -[## ##] -[ ] - -#char : 121 'y' -[## ## ] -[## ## ] -[## ## ] -[ #### ] -[ ## ] -[ ## ] -[ ## ] -[ ] - -#char : 122 'z' -[#######] -[ ###] -[ ### ] -[ ### ] -[ ### ] -[### ] -[#######] -[ ] - -#char : 123 '{' -[ ## ] -[ ## ] -[ ## ] -[ ## ] -[ ## ] -[ ## ] -[ ## ] -[ ] - -#char : 124 '|' -[ ## ] -[ ## ] -[ ## ] -[ ## ] -[ ## ] -[ ## ] -[ ## ] -[ ] - -#char : 125 '}' -[ ## ] -[ ## ] -[ ## ] -[ ## ] -[ ## ] -[ ## ] -[ ## ] -[ ] - -#char : 126 '~' -[ ] -[ ] -[ ## # ] -[ ##### ] -[ # ## ] -[ ] -[ ] -[ ] - -#char : 127 -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] diff --git a/src/modm/ui/display/font/assertion.font b/src/modm/ui/display/font/assertion.font deleted file mode 100644 index a4fe087ca6..0000000000 --- a/src/modm/ui/display/font/assertion.font +++ /dev/null @@ -1,1637 +0,0 @@ -#font : Assertion -#width : 7 -#height : 15 -#hspace : 0 -#vspace : 1 - -#char : 32 ' ' -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] - -#char : 33 '!' -[##] -[##] -[##] -[##] -[##] -[##] -[##] -[##] -[##] -[ ] -[##] -[##] -[ ] -[ ] -[ ] - -#char : 34 '"' -[## ##] -[## ##] -[## ##] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] - -#char : 35 '#' -[ ] -[ ## ## ] -[ ## ## ] -[ ## ## ] -[##########] -[ ## ## ] -[ ## ## ] -[ ## ## ] -[##########] -[ ## ## ] -[ ## ## ] -[ ## ## ] -[ ] -[ ] -[ ] - -#char : 36 '$' -[ # ] -[ # ] -[ ##### ] -[## ##] -[## ##] -[## ##] -[## ] -[ ##### ] -[ ##] -[## ##] -[## ##] -[## ##] -[ ##### ] -[ # ] -[ # ] - -#char : 37 '%' -[ ] -[ ### #] -[## ## ##] -[## ## ## ] -[## ## ## ] -[ ### ## ] -[ ## ] -[ ## ### ] -[ ## ## ##] -[ ## ## ##] -[## ## ##] -[# ### ] -[ ] -[ ] -[ ] - -#char : 38 '&' -[ ##### ] -[## ## ] -[## ## ] -[## ## ] -[## ] -[ # #####] -[## ## ] -[## ## ] -[## ## ] -[## ## ] -[## ## ] -[ ##### ] -[ ] -[ ] -[ ] - -#char : 39 ''' -[##] -[##] -[##] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] - -#char : 40 '(' -[ #] -[ # ] -[ # ] -[## ] -[## ] -[## ] -[## ] -[## ] -[## ] -[ # ] -[ # ] -[ #] -[ ] -[ ] -[ ] - -#char : 41 ')' -[# ] -[ # ] -[ # ] -[ ##] -[ ##] -[ ##] -[ ##] -[ ##] -[ ##] -[ # ] -[ # ] -[# ] -[ ] -[ ] -[ ] - -#char : 42 '*' -[ ] -[ ] -[ ## ] -[## ## ##] -[ ###### ] -[ #### ] -[ ###### ] -[## ## ##] -[ ## ] -[ ## ] -[ ] -[ ] -[ ] -[ ] -[ ] - -#char : 43 '+' -[ ] -[ ] -[ ] -[ ## ] -[ ## ] -[ ## ] -[######] -[ ## ] -[ ## ] -[ ## ] -[ ] -[ ] -[ ] -[ ] -[ ] - -#char : 44 ',' -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ##] -[ ##] -[ ##] -[## ] - -#char : 45 '-' -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[#####] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] - -#char : 46 '.' -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[##] -[##] -[##] -[ ] - -#char : 47 '/' -[ ##] -[ # ] -[ ## ] -[ ## ] -[ # ] -[ ## ] -[ ## ] -[ # ] -[ ## ] -[ ## ] -[ # ] -[## ] -[## ] -[ ] -[ ] - -#char : 48 '0' -[ ##### ] -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[ ##### ] -[ ] -[ ] -[ ] - -#char : 49 '1' -[####] -[ ##] -[ ##] -[ ##] -[ ##] -[ ##] -[ ##] -[ ##] -[ ##] -[ ##] -[ ##] -[ ##] -[ ] -[ ] -[ ] - -#char : 50 '2' -[ ##### ] -[## ##] -[## ##] -[## ##] -[ ##] -[ ##] -[ ##### ] -[## ] -[## ] -[## ] -[## ] -[#######] -[ ] -[ ] -[ ] - -#char : 51 '3' -[ ##### ] -[## ##] -[## ##] -[## ##] -[ ##] -[ #### ] -[ ##] -[ ##] -[## ##] -[## ##] -[## ##] -[ ##### ] -[ ] -[ ] -[ ] - -#char : 52 '4' -[## ## ] -[## ## ] -[## ## ] -[## ## ] -[## ## ] -[## ## ] -[## ## ] -[## ## ] -[#######] -[ ## ] -[ ## ] -[ ## ] -[ ] -[ ] -[ ] - -#char : 53 '5' -[#######] -[## ] -[## ] -[## ] -[###### ] -[ ##] -[ ##] -[## ##] -[## ##] -[## ##] -[## ##] -[ ##### ] -[ ] -[ ] -[ ] - -#char : 54 '6' -[ ##### ] -[## ##] -[## ##] -[## ##] -[## ] -[###### ] -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[ ##### ] -[ ] -[ ] -[ ] - -#char : 55 '7' -[######] -[ ##] -[ ##] -[ ##] -[ ###] -[ ### ] -[ ## ] -[ ## ] -[ ## ] -[ ## ] -[ ## ] -[ ## ] -[ ] -[ ] -[ ] - -#char : 56 '8' -[ ##### ] -[## ##] -[## ##] -[## ##] -[## ##] -[ ##### ] -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[ ##### ] -[ ] -[ ] -[ ] - -#char : 57 '9' -[ ##### ] -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[ ######] -[ ##] -[## ##] -[## ##] -[## ##] -[ ##### ] -[ ] -[ ] -[ ] - -#char : 58 ':' -[ ] -[ ] -[ ] -[ ] -[##] -[##] -[##] -[ ] -[##] -[##] -[##] -[ ] -[ ] -[ ] -[ ] - -#char : 59 ';' -[ ] -[ ] -[ ] -[ ] -[ ##] -[ ##] -[ ##] -[ ] -[ ##] -[ ##] -[ ##] -[## ] -[ ] -[ ] -[ ] - -#char : 60 '<' -[ ] -[ ] -[ ] -[ ##] -[ ## ] -[ ## ] -[## ] -[ ## ] -[ ## ] -[ ##] -[ ] -[ ] -[ ] -[ ] -[ ] - -#char : 61 '=' -[ ] -[ ] -[ ] -[ ] -[#####] -[ ] -[ ] -[#####] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] - -#char : 62 '>' -[ ] -[ ] -[ ] -[## ] -[ ## ] -[ ## ] -[ ##] -[ ## ] -[ ## ] -[## ] -[ ] -[ ] -[ ] -[ ] -[ ] - -#char : 63 '?' -[ ##### ] -[## ##] -[## ##] -[## ##] -[ ##] -[ ## ] -[ ## ] -[ ## ] -[ ## ] -[ ] -[ ## ] -[ ## ] -[ ] -[ ] -[ ] - -#char : 64 '@' -[ ##### ] -[ # # ] -[ # ### # ] -[## ## ## ##] -[## ## ## ##] -[## ## ## ##] -[## ## ## ##] -[## ## ## ##] -[## ## ## ##] -[ # ### ## ] -[ # ] -[ ####### ] -[ ] -[ ] -[ ] - -#char : 65 'A' -[ ##### ] -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[#######] -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[ ] -[ ] -[ ] - -#char : 66 'B' -[###### ] -[## ##] -[## ##] -[## ##] -[## ##] -[###### ] -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[###### ] -[ ] -[ ] -[ ] - -#char : 67 'C' -[ ##### ] -[## ##] -[## ##] -[## ##] -[## ##] -[## ] -[## ] -[## ##] -[## ##] -[## ##] -[## ##] -[ ##### ] -[ ] -[ ] -[ ] - -#char : 68 'D' -[###### ] -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[###### ] -[ ] -[ ] -[ ] - -#char : 69 'E' -[#######] -[## ] -[## ] -[## ] -[## ] -[###### ] -[## ] -[## ] -[## ] -[## ] -[## ] -[#######] -[ ] -[ ] -[ ] - -#char : 70 'F' -[#######] -[## ] -[## ] -[## ] -[## ] -[###### ] -[## ] -[## ] -[## ] -[## ] -[## ] -[## ] -[ ] -[ ] -[ ] - -#char : 71 'G' -[ ##### ] -[## ##] -[## ##] -[## ##] -[## ##] -[## ] -[## ####] -[## ##] -[## ##] -[## ##] -[## ##] -[ ##### ] -[ ] -[ ] -[ ] - -#char : 72 'H' -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[#######] -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[ ] -[ ] -[ ] - -#char : 73 'I' -[##] -[##] -[##] -[##] -[##] -[##] -[##] -[##] -[##] -[##] -[##] -[##] -[ ] -[ ] -[ ] - -#char : 74 'J' -[ ##] -[ ##] -[ ##] -[ ##] -[ ##] -[ ##] -[ ##] -[## ##] -[## ##] -[## ##] -[## ##] -[ ##### ] -[ ] -[ ] -[ ] - -#char : 75 'K' -[## ##] -[## ##] -[## ##] -[## ##] -[## ## ] -[##### ] -[## ## ] -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[ ] -[ ] -[ ] - -#char : 76 'L' -[## ] -[## ] -[## ] -[## ] -[## ] -[## ] -[## ] -[## ] -[## ] -[## ] -[## ] -[######] -[ ] -[ ] -[ ] - -#char : 77 'M' -[######### ] -[## ## ##] -[## ## ##] -[## ## ##] -[## ## ##] -[## ## ##] -[## ## ##] -[## ## ##] -[## ## ##] -[## ## ##] -[## ## ##] -[## ## ##] -[ ] -[ ] -[ ] - -#char : 78 'N' -[###### ] -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[ ] -[ ] -[ ] - -#char : 79 'O' -[ ##### ] -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[ ##### ] -[ ] -[ ] -[ ] - -#char : 80 'P' -[###### ] -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[###### ] -[## ] -[## ] -[## ] -[## ] -[## ] -[ ] -[ ] -[ ] - -#char : 81 'Q' -[ ##### ] -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[ ##### ] -[ ## ] -[ ##] -[ ] - -#char : 82 'R' -[###### ] -[## ##] -[## ##] -[## ##] -[## ##] -[###### ] -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[ ] -[ ] -[ ] - -#char : 83 'S' -[ ##### ] -[## ##] -[## ##] -[## ##] -[## ] -[ ##### ] -[ ##] -[## ##] -[## ##] -[## ##] -[## ##] -[ ##### ] -[ ] -[ ] -[ ] - -#char : 84 'T' -[######] -[ ## ] -[ ## ] -[ ## ] -[ ## ] -[ ## ] -[ ## ] -[ ## ] -[ ## ] -[ ## ] -[ ## ] -[ ## ] -[ ] -[ ] -[ ] - -#char : 85 'U' -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[ ##### ] -[ ] -[ ] -[ ] - -#char : 86 'V' -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[ ## ## ] -[ ### ] -[ # ] -[ ] -[ ] -[ ] - -#char : 87 'W' -[## ## ##] -[## ## ##] -[## ## ##] -[## ## ##] -[## ## ##] -[## ## ##] -[## ## ##] -[## ## ##] -[## ## ##] -[ ## #### ## ] -[ ### ### ] -[ # # ] -[ ] -[ ] -[ ] - -#char : 88 'X' -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[ ## ## ] -[ ### ] -[ ## ## ] -[## ##] -[## ##] -[## ##] -[## ##] -[ ] -[ ] -[ ] - -#char : 89 'Y' -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[ #### ] -[ ## ] -[ ## ] -[ ## ] -[ ## ] -[ ## ] -[ ] -[ ] -[ ] - -#char : 90 'Z' -[###### ] -[ ## ] -[ ## ] -[ ## ] -[ ## ] -[ ## ] -[ ## ] -[## ] -[## ] -[## ] -[## ] -[#######] -[ ] -[ ] -[ ] - -#char : 91 '[' -[####] -[## ] -[## ] -[## ] -[## ] -[## ] -[## ] -[## ] -[## ] -[## ] -[## ] -[####] -[ ] -[ ] -[ ] - -#char : 92 '\' -[## ] -[ # ] -[ ## ] -[ ## ] -[ # ] -[ ## ] -[ ## ] -[ # ] -[ ## ] -[ ## ] -[ # ] -[ ##] -[ ##] -[ ] -[ ] - -#char : 93 ']' -[####] -[ ##] -[ ##] -[ ##] -[ ##] -[ ##] -[ ##] -[ ##] -[ ##] -[ ##] -[ ##] -[####] -[ ] -[ ] -[ ] - -#char : 94 '^' -[ # ] -[ ### ] -[ # # ] -[ ## ## ] -[ # # ] -[## ##] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] - -#char : 95 '_' -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[#######] - -#char : 96 '`' -[# ] -[ # ] -[ #] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] - -#char : 97 'a' -[ ] -[ ] -[ ] -[ ######] -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[ ######] -[ ] -[ ] -[ ] - -#char : 98 'b' -[## ] -[## ] -[## ] -[###### ] -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[###### ] -[ ] -[ ] -[ ] - -#char : 99 'c' -[ ] -[ ] -[ ] -[ ##### ] -[## ##] -[## ##] -[## ] -[## ] -[## ] -[## ##] -[## ##] -[ ##### ] -[ ] -[ ] -[ ] - -#char : 100 'd' -[ ##] -[ ##] -[ ##] -[ ######] -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[ ######] -[ ] -[ ] -[ ] - -#char : 101 'e' -[ ] -[ ] -[ ] -[ ##### ] -[## ##] -[## ##] -[#######] -[## ] -[## ] -[## ##] -[## ##] -[ ##### ] -[ ] -[ ] -[ ] - -#char : 102 'f' -[ ###] -[ ## ] -[ ## ] -[#####] -[ ## ] -[ ## ] -[ ## ] -[ ## ] -[ ## ] -[ ## ] -[ ## ] -[ ## ] -[ ] -[ ] -[ ] - -#char : 103 'g' -[ ] -[ ] -[ ] -[ ######] -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[ ######] -[ ##] -[ ##] -[ ##### ] - -#char : 104 'h' -[## ] -[## ] -[## ] -[###### ] -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[ ] -[ ] -[ ] - -#char : 105 'i' -[##] -[##] -[ ] -[##] -[##] -[##] -[##] -[##] -[##] -[##] -[##] -[##] -[ ] -[ ] -[ ] - -#char : 106 'j' -[ ##] -[ ##] -[ ] -[ ##] -[ ##] -[ ##] -[ ##] -[ ##] -[ ##] -[ ##] -[ ##] -[ ##] -[ ##] -[ ##] -[### ] - -#char : 107 'k' -[## ] -[## ] -[## ] -[## ##] -[## ##] -[## ## ] -[##### ] -[## ## ] -[## ##] -[## ##] -[## ##] -[## ##] -[ ] -[ ] -[ ] - -#char : 108 'l' -[##] -[##] -[##] -[##] -[##] -[##] -[##] -[##] -[##] -[##] -[##] -[##] -[ ] -[ ] -[ ] - -#char : 109 'm' -[ ] -[ ] -[ ] -[######### ] -[## ## ##] -[## ## ##] -[## ## ##] -[## ## ##] -[## ## ##] -[## ## ##] -[## ## ##] -[## ## ##] -[ ] -[ ] -[ ] - -#char : 110 'n' -[ ] -[ ] -[ ] -[###### ] -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[ ] -[ ] -[ ] - -#char : 111 'o' -[ ] -[ ] -[ ] -[ ##### ] -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[ ##### ] -[ ] -[ ] -[ ] - -#char : 112 'p' -[ ] -[ ] -[ ] -[###### ] -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[###### ] -[## ] -[## ] -[## ] - -#char : 113 'q' -[ ] -[ ] -[ ] -[ ######] -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[ ######] -[ ##] -[ ##] -[ ##] - -#char : 114 'r' -[ ] -[ ] -[ ] -[## ##] -[#### ] -[### ] -[## ] -[## ] -[## ] -[## ] -[## ] -[## ] -[ ] -[ ] -[ ] - -#char : 115 's' -[ ] -[ ] -[ ] -[ ##### ] -[## ##] -[## ##] -[## ] -[ ##### ] -[ ##] -[## ##] -[## ##] -[ ##### ] -[ ] -[ ] -[ ] - -#char : 116 't' -[ # ] -[ ## ] -[ ## ] -[#####] -[ ## ] -[ ## ] -[ ## ] -[ ## ] -[ ## ] -[ ## ] -[ ## ] -[ ###] -[ ] -[ ] -[ ] - -#char : 117 'u' -[ ] -[ ] -[ ] -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[ ##### ] -[ ] -[ ] -[ ] - -#char : 118 'v' -[ ] -[ ] -[ ] -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[ ## ## ] -[ ### ] -[ ] -[ ] -[ ] - -#char : 119 'w' -[ ] -[ ] -[ ] -[## ## ##] -[## ## ##] -[## ## ##] -[## ## ##] -[## ## ##] -[## ## ##] -[## ## ##] -[ ## #### ## ] -[ ### ### ] -[ ] -[ ] -[ ] - -#char : 120 'x' -[ ] -[ ] -[ ] -[## ##] -[## ##] -[## ##] -[ ## ## ] -[ ### ] -[ ## ## ] -[## ##] -[## ##] -[## ##] -[ ] -[ ] -[ ] - -#char : 121 'y' -[ ] -[ ] -[ ] -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[ ######] -[ ##] -[ ##] -[ ##### ] - -#char : 122 'z' -[ ] -[ ] -[ ] -[#####] -[ ##] -[ ##] -[ ## ] -[ ## ] -[## ] -[## ] -[## ] -[#####] -[ ] -[ ] -[ ] - -#char : 123 '{' -[ ###] -[ ## ] -[ ## ] -[ ## ] -[ ## ] -[ ## ] -[## ] -[ ## ] -[ ## ] -[ ## ] -[ ## ] -[ ## ] -[ ###] -[ ] -[ ] - -#char : 124 '|' -[##] -[##] -[##] -[##] -[##] -[##] -[##] -[##] -[##] -[##] -[##] -[##] -[ ] -[ ] -[ ] - -#char : 125 '}' -[### ] -[ ## ] -[ ## ] -[ ## ] -[ ## ] -[ ## ] -[ ##] -[ ## ] -[ ## ] -[ ## ] -[ ## ] -[ ## ] -[### ] -[ ] -[ ] - -#char : 126 '~' -[ ] -[ ] -[ ] -[ ] -[ ] -[ ## #] -[#####] -[# ## ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] - -#char : 127 -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] diff --git a/src/modm/ui/display/font/fixed_width_5x8.font b/src/modm/ui/display/font/fixed_width_5x8.font deleted file mode 100644 index 2b87a30298..0000000000 --- a/src/modm/ui/display/font/fixed_width_5x8.font +++ /dev/null @@ -1,965 +0,0 @@ -#font : Fixed Width 5x8 -#width : 5 -#height : 8 -#hspace : 0 -#vspace : 1 - -#char : 32 ' ' -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] - -#char : 33 '!' -[ # ] -[ ### ] -[ ### ] -[ # ] -[ # ] -[ ] -[ # ] -[ ] - -#char : 34 '"' -[## ##] -[## ##] -[# # ] -[ ] -[ ] -[ ] -[ ] -[ ] - -#char : 35 '#' -[ ] -[ # # ] -[#####] -[ # # ] -[ # # ] -[#####] -[ # # ] -[ ] - -#char : 36 '$' -[ # ] -[ ####] -[# # ] -[ ### ] -[ # #] -[#### ] -[ # ] -[ ] - -#char : 37 '%' -[## ] -[## #] -[ # ] -[ # ] -[ # ] -[# ##] -[ ##] -[ ] - -#char : 38 '&' -[ # ] -[# # ] -[# # ] -[ # ] -[# # #] -[# # ] -[ ## #] -[ ] - -#char : 39 ''' -[ ## ] -[ ## ] -[ # ] -[ # ] -[ ] -[ ] -[ ] -[ ] - -#char : 40 '(' -[ # ] -[ # ] -[ # ] -[ # ] -[ # ] -[ # ] -[ # ] -[ ] - -#char : 41 ')' -[ # ] -[ # ] -[ # ] -[ # ] -[ # ] -[ # ] -[ # ] -[ ] - -#char : 42 '*' -[ ] -[ # # ] -[ ### ] -[#####] -[ ### ] -[ # # ] -[ ] -[ ] - -#char : 43 '+' -[ ] -[ # ] -[ # ] -[#####] -[ # ] -[ # ] -[ ] -[ ] - -#char : 44 ',' -[ ] -[ ] -[ ] -[ ] -[ ## ] -[ ## ] -[ # ] -[ # ] - -#char : 45 '-' -[ ] -[ ] -[ ] -[#####] -[ ] -[ ] -[ ] -[ ] - -#char : 46 '.' -[ ] -[ ] -[ ] -[ ] -[ ] -[ ## ] -[ ## ] -[ ] - -#char : 47 '/' -[ ] -[ #] -[ # ] -[ # ] -[ # ] -[# ] -[ ] -[ ] - -#char : 48 '0' -[ ### ] -[# #] -[# ##] -[# # #] -[## #] -[# #] -[ ### ] -[ ] - -#char : 49 '1' -[ # ] -[ ## ] -[ # ] -[ # ] -[ # ] -[ # ] -[ ### ] -[ ] - -#char : 50 '2' -[ ### ] -[# #] -[ #] -[ ## ] -[ # ] -[# ] -[#####] -[ ] - -#char : 51 '3' -[ ### ] -[# #] -[ #] -[ ### ] -[ #] -[# #] -[ ### ] -[ ] - -#char : 52 '4' -[ # ] -[ ## ] -[ # # ] -[# # ] -[#####] -[ # ] -[ # ] -[ ] - -#char : 53 '5' -[#####] -[# ] -[# ] -[#### ] -[ #] -[# #] -[ ### ] -[ ] - -#char : 54 '6' -[ ## ] -[ # ] -[# ] -[#### ] -[# #] -[# #] -[ ### ] -[ ] - -#char : 55 '7' -[#####] -[ #] -[ # ] -[ # ] -[ # ] -[ # ] -[ # ] -[ ] - -#char : 56 '8' -[ ### ] -[# #] -[# #] -[ ### ] -[# #] -[# #] -[ ### ] -[ ] - -#char : 57 '9' -[ ### ] -[# #] -[# #] -[ ####] -[ #] -[ # ] -[ ## ] -[ ] - -#char : 58 ':' -[ ] -[ ] -[ # ] -[ ] -[ # ] -[ ] -[ ] -[ ] - -#char : 59 ';' -[ ] -[ ] -[ # ] -[ ] -[ ] -[ # ] -[ # ] -[ # ] - -#char : 60 '<' -[ # ] -[ # ] -[ # ] -[# ] -[ # ] -[ # ] -[ # ] -[ ] - -#char : 61 '=' -[ ] -[ ] -[#####] -[ ] -[#####] -[ ] -[ ] -[ ] - -#char : 62 '>' -[ # ] -[ # ] -[ # ] -[ #] -[ # ] -[ # ] -[ # ] -[ ] - -#char : 63 '?' -[ ### ] -[# #] -[ #] -[ ## ] -[ # ] -[ ] -[ # ] -[ ] - -#char : 64 '@' -[ ### ] -[# #] -[# ###] -[# # #] -[# ###] -[# ] -[ ### ] -[ ] - -#char : 65 'A' -[ ### ] -[# #] -[# #] -[# #] -[#####] -[# #] -[# #] -[ ] - -#char : 66 'B' -[#### ] -[# #] -[# #] -[#### ] -[# #] -[# #] -[#### ] -[ ] - -#char : 67 'C' -[ ### ] -[# #] -[# ] -[# ] -[# ] -[# #] -[ ### ] -[ ] - -#char : 68 'D' -[#### ] -[# #] -[# #] -[# #] -[# #] -[# #] -[#### ] -[ ] - -#char : 69 'E' -[#####] -[# ] -[# ] -[#### ] -[# ] -[# ] -[#####] -[ ] - -#char : 70 'F' -[#####] -[# ] -[# ] -[#### ] -[# ] -[# ] -[# ] -[ ] - -#char : 71 'G' -[ ### ] -[# #] -[# ] -[# ###] -[# #] -[# #] -[ ####] -[ ] - -#char : 72 'H' -[# #] -[# #] -[# #] -[#####] -[# #] -[# #] -[# #] -[ ] - -#char : 73 'I' -[ ### ] -[ # ] -[ # ] -[ # ] -[ # ] -[ # ] -[ ### ] -[ ] - -#char : 74 'J' -[ #] -[ #] -[ #] -[ #] -[# #] -[# #] -[ ### ] -[ ] - -#char : 75 'K' -[# #] -[# # ] -[# # ] -[## ] -[# # ] -[# # ] -[# #] -[ ] - -#char : 76 'L' -[# ] -[# ] -[# ] -[# ] -[# ] -[# ] -[#####] -[ ] - -#char : 77 'M' -[# #] -[## ##] -[# # #] -[# #] -[# #] -[# #] -[# #] -[ ] - -#char : 78 'N' -[# #] -[## #] -[# # #] -[# ##] -[# #] -[# #] -[# #] -[ ] - -#char : 79 'O' -[ ### ] -[# #] -[# #] -[# #] -[# #] -[# #] -[ ### ] -[ ] - -#char : 80 'P' -[#### ] -[# #] -[# #] -[#### ] -[# ] -[# ] -[# ] -[ ] - -#char : 81 'Q' -[ ### ] -[# #] -[# #] -[# #] -[# # #] -[# # ] -[ ## #] -[ ] - -#char : 82 'R' -[#### ] -[# #] -[# #] -[#### ] -[# # ] -[# #] -[# #] -[ ] - -#char : 83 'S' -[ ### ] -[# #] -[# ] -[ ### ] -[ #] -[# #] -[ ### ] -[ ] - -#char : 84 'T' -[#####] -[ # ] -[ # ] -[ # ] -[ # ] -[ # ] -[ # ] -[ ] - -#char : 85 'U' -[# #] -[# #] -[# #] -[# #] -[# #] -[# #] -[ ### ] -[ ] - -#char : 86 'V' -[# #] -[# #] -[# #] -[# #] -[# #] -[ # # ] -[ # ] -[ ] - -#char : 87 'W' -[# #] -[# #] -[# #] -[# # #] -[# # #] -[# # #] -[ # # ] -[ ] - -#char : 88 'X' -[# #] -[# #] -[ # # ] -[ # ] -[ # # ] -[# #] -[# #] -[ ] - -#char : 89 'Y' -[# #] -[# #] -[# #] -[ # # ] -[ # ] -[ # ] -[ # ] -[ ] - -#char : 90 'Z' -[#####] -[ #] -[ # ] -[ # ] -[ # ] -[# ] -[#####] -[ ] - -#char : 91 '[' -[ ## ] -[ # ] -[ # ] -[ # ] -[ # ] -[ # ] -[ ## ] -[ ] - -#char : 92 '\' -[ ] -[# ] -[ # ] -[ # ] -[ # ] -[ #] -[ ] -[ ] - -#char : 93 ']' -[ ## ] -[ # ] -[ # ] -[ # ] -[ # ] -[ # ] -[ ## ] -[ ] - -#char : 94 '^' -[ # ] -[ # # ] -[# #] -[ ] -[ ] -[ ] -[ ] -[ ] - -#char : 95 '_' -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[#####] - -#char : 96 '`' -[ ## ] -[ ## ] -[ # ] -[ ] -[ ] -[ ] -[ ] -[ ] - -#char : 97 'a' -[ ] -[ ] -[ ### ] -[ #] -[ ####] -[# #] -[ ####] -[ ] - -#char : 98 'b' -[# ] -[# ] -[#### ] -[# #] -[# #] -[# #] -[#### ] -[ ] - -#char : 99 'c' -[ ] -[ ] -[ ### ] -[# #] -[# ] -[# #] -[ ### ] -[ ] - -#char : 100 'd' -[ #] -[ #] -[ ####] -[# #] -[# #] -[# #] -[ ####] -[ ] - -#char : 101 'e' -[ ] -[ ] -[ ### ] -[# #] -[#### ] -[# ] -[ ### ] -[ ] - -#char : 102 'f' -[ ## ] -[ # ] -[ # ] -[#### ] -[ # ] -[ # ] -[ # ] -[ ] - -#char : 103 'g' -[ ] -[ ] -[ ####] -[# #] -[# #] -[ ####] -[ #] -[ ### ] - -#char : 104 'h' -[# ] -[# ] -[# ] -[### ] -[# # ] -[# # ] -[# # ] -[ ] - -#char : 105 'i' -[ # ] -[ ] -[ # ] -[ # ] -[ # ] -[ # ] -[ ## ] -[ ] - -#char : 106 'j' -[ # ] -[ ] -[ ## ] -[ # ] -[ # ] -[ # ] -[# # ] -[ ## ] - -#char : 107 'k' -[# ] -[# ] -[# # ] -[# # ] -[## ] -[# # ] -[# # ] -[ ] - -#char : 108 'l' -[ # ] -[ # ] -[ # ] -[ # ] -[ # ] -[ # ] -[ ## ] -[ ] - -#char : 109 'm' -[ ] -[ ] -[## # ] -[# # #] -[# # #] -[# #] -[# #] -[ ] - -#char : 110 'n' -[ ] -[ ] -[### ] -[# # ] -[# # ] -[# # ] -[# # ] -[ ] - -#char : 111 'o' -[ ] -[ ] -[ ### ] -[# #] -[# #] -[# #] -[ ### ] -[ ] - -#char : 112 'p' -[ ] -[ ] -[#### ] -[# #] -[# #] -[#### ] -[# ] -[# ] - -#char : 113 'q' -[ ] -[ ] -[ ####] -[# #] -[# #] -[ ####] -[ #] -[ #] - -#char : 114 'r' -[ ] -[ ] -[# ## ] -[ # #] -[ # ] -[ # ] -[### ] -[ ] - -#char : 115 's' -[ ] -[ ] -[ ### ] -[# ] -[ ### ] -[ #] -[ ### ] -[ ] - -#char : 116 't' -[ # ] -[#### ] -[ # ] -[ # ] -[ # ] -[ # # ] -[ # ] -[ ] - -#char : 117 'u' -[ ] -[ ] -[# #] -[# #] -[# #] -[# #] -[ ### ] -[ ] - -#char : 118 'v' -[ ] -[ ] -[# #] -[# #] -[# #] -[ # # ] -[ # ] -[ ] - -#char : 119 'w' -[ ] -[ ] -[# #] -[# #] -[# # #] -[# # #] -[ # # ] -[ ] - -#char : 120 'x' -[ ] -[ ] -[# # ] -[# # ] -[ ## ] -[# # ] -[# # ] -[ ] - -#char : 121 'y' -[ ] -[ ] -[# #] -[# #] -[# #] -[ ####] -[ #] -[ ### ] - -#char : 122 'z' -[ ] -[ ] -[#### ] -[ # ] -[ ## ] -[# ] -[#### ] -[ ] - -#char : 123 '{' -[ ## ] -[ # ] -[ # ] -[## ] -[ # ] -[ # ] -[ ## ] -[ ] - -#char : 124 '|' -[ # ] -[ # ] -[ # ] -[ ] -[ # ] -[ # ] -[ # ] -[ ] - -#char : 125 '}' -[ ## ] -[ # ] -[ # ] -[ ##] -[ # ] -[ # ] -[ ## ] -[ ] - -#char : 126 '~' -[ ] -[ ] -[ ] -[ # # ] -[# # ] -[ ] -[ ] -[ ] - -#char : 127 -[ # ] -[ ### ] -[## ##] -[# #] -[# #] -[# #] -[#####] -[ ] diff --git a/src/modm/ui/display/font/matrix_8x8.font b/src/modm/ui/display/font/matrix_8x8.font deleted file mode 100644 index fab759dca9..0000000000 --- a/src/modm/ui/display/font/matrix_8x8.font +++ /dev/null @@ -1,105 +0,0 @@ -#font : Matrix 8x8 -#width : 8 -#height : 8 -#hspace : 0 -#vspace : 0 - -#char : 48 '0' -[ ##### ] -[## ## ] -[## ### ] -[## #### ] -[#### ## ] -[### ## ] -[ ##### ] -[ ] - -#char : 49 '1' -[ ## ] -[ ### ] -[ ## ] -[ ## ] -[ ## ] -[ ## ] -[###### ] -[ ] - -#char : 50 '2' -[ #### ] -[## ## ] -[ ## ] -[ ### ] -[ ## ] -[## ## ] -[###### ] -[ ] - -#char : 51 '3' -[ #### ] -[## ## ] -[ ## ] -[ ### ] -[ ## ] -[## ## ] -[ #### ] -[ ] - -#char : 52 '4' -[ ### ] -[ #### ] -[ ## ## ] -[## ## ] -[####### ] -[ ## ] -[ #### ] -[ ] - -#char : 53 '5' -[###### ] -[## ] -[##### ] -[ ## ] -[ ## ] -[## ## ] -[ #### ] -[ ] - -#char : 54 '6' -[ ### ] -[ ## ] -[## ] -[##### ] -[## ## ] -[## ## ] -[ #### ] -[ ] - -#char : 55 '7' -[###### ] -[## ## ] -[ ## ] -[ ## ] -[ ## ] -[ ## ] -[ ## ] -[ ] - -#char : 56 '8' -[ #### ] -[## ## ] -[## ## ] -[ #### ] -[## ## ] -[## ## ] -[ #### ] -[ ] - -#char : 57 '9' -[ #### ] -[## ## ] -[## ## ] -[ ##### ] -[ ## ] -[ ## ] -[ ### ] -[ ] diff --git a/src/modm/ui/display/font/numbers_14x32.font b/src/modm/ui/display/font/numbers_14x32.font deleted file mode 100644 index cc95d01289..0000000000 --- a/src/modm/ui/display/font/numbers_14x32.font +++ /dev/null @@ -1,345 +0,0 @@ -#font : Numbers 14x32 -#width : 14 -#height : 32 -#hspace : 3 -#vspace : 4 - -#char : 48 '0' -[ ###### ] -[ ########## ] -[ ############ ] -[ ############ ] -[##### #####] -[#### ####] -[#### ####] -[#### ####] -[#### ####] -[#### ####] -[#### #####] -[#### #####] -[#### ######] -[#### ######] -[#### #######] -[#### ### ####] -[#### ### ####] -[####### ####] -[###### ####] -[###### ####] -[##### ####] -[##### ####] -[#### ####] -[#### ####] -[#### ####] -[#### ####] -[#### ####] -[##### #####] -[ ############ ] -[ ############ ] -[ ########## ] -[ ###### ] - -#char : 49 '1' -[ ### ] -[ ##### ] -[ ###### ] -[ ###### ] -[ ####### ] -[ ######## ] -[ ######## ] -[ #### #### ] -[ #### #### ] -[ #### #### ] -[ #### #### ] -[ ### #### ] -[ #### ] -[ #### ] -[ #### ] -[ #### ] -[ #### ] -[ #### ] -[ #### ] -[ #### ] -[ #### ] -[ #### ] -[ #### ] -[ #### ] -[ #### ] -[ #### ] -[ #### ] -[ #### ] -[ #### ] -[ #### ] -[ #### ] -[ ## ] - -#char : 50 '2' -[ ###### ] -[ ########## ] -[ ############ ] -[ ############ ] -[##### #####] -[#### ####] -[ ## ####] -[ ####] -[ ####] -[ ####] -[ ####] -[ ####] -[ #####] -[ ##### ] -[ ###### ] -[ ###### ] -[ ###### ] -[ ###### ] -[ ###### ] -[ ###### ] -[ ###### ] -[ ##### ] -[##### ] -[#### ] -[#### ] -[#### ] -[#### ] -[#### ] -[############# ] -[##############] -[##############] -[ ############ ] - -#char : 51 '3' -[ ###### ] -[ ########## ] -[ ############ ] -[ ############ ] -[##### #####] -[#### ####] -[ ## ####] -[ ####] -[ ####] -[ ####] -[ ####] -[ ####] -[ ####] -[ #### ] -[ ####### ] -[ ####### ] -[ ####### ] -[ ####### ] -[ #### ] -[ ####] -[ ####] -[ ####] -[ ####] -[ ####] -[ ####] -[ ## ####] -[#### ####] -[##### #####] -[ ############ ] -[ ############ ] -[ ########## ] -[ ###### ] - -#char : 52 '4' -[ ### ] -[ ##### ] -[ ###### ] -[ ###### ] -[ ####### ] -[ ####### ] -[ ####### ] -[ ######## ] -[ ### #### ] -[ #### #### ] -[ #### #### ] -[ ### #### ] -[ #### #### ] -[ #### #### ] -[ ### #### ] -[ #### #### ] -[ ### #### ] -[#### #### ] -[#### #### ] -[### #### ] -[### #### ] -[##############] -[##############] -[##############] -[ #############] -[ #### ] -[ #### ] -[ #### ] -[ #### ] -[ #### ] -[ #### ] -[ ## ] - -#char : 53 '5' -[ ############ ] -[##############] -[##############] -[############# ] -[#### ] -[#### ] -[#### ] -[#### ] -[#### ] -[#### ] -[#### ] -[#### ] -[#### ###### ] -[############ ] -[############# ] -[##############] -[###### #####] -[ ### ####] -[ ####] -[ ####] -[ ####] -[ ####] -[ ####] -[ ####] -[ ####] -[ ## ####] -[#### #####] -[##### ##### ] -[ ############ ] -[ ########### ] -[ ######### ] -[ ###### ] - -#char : 54 '6' -[ ##### ] -[ ######### ] -[ ########### ] -[ ############ ] -[ #### #####] -[#### ####] -[#### ## ] -[#### ] -[#### ] -[#### ] -[#### ] -[#### ] -[#### ###### ] -[############ ] -[############# ] -[##############] -[##### #####] -[#### ####] -[#### ####] -[#### ####] -[#### ####] -[#### ####] -[#### ####] -[#### ####] -[#### ####] -[#### ####] -[#### ####] -[ #### #### ] -[ ############ ] -[ ########## ] -[ ######## ] -[ #### ] - -#char : 55 '7' -[ ############ ] -[##############] -[##############] -[ #############] -[ ####] -[ ####] -[ ####] -[ ####] -[ ####] -[ #####] -[ #### ] -[ ##### ] -[ #### ] -[ ##### ] -[ #### ] -[ ##### ] -[ #### ] -[ ##### ] -[ #### ] -[ #### ] -[ #### ] -[ #### ] -[ #### ] -[ #### ] -[ #### ] -[ #### ] -[ #### ] -[ #### ] -[ #### ] -[ #### ] -[ #### ] -[ ## ] - -#char : 56 '8' -[ #### ] -[ ######## ] -[ ########## ] -[ ############ ] -[ #### #### ] -[#### ####] -[#### ####] -[#### ####] -[#### ####] -[#### ####] -[#### ####] -[#### ####] -[ #### #### ] -[ ##### ##### ] -[ ########## ] -[ ######## ] -[ ######## ] -[ ########## ] -[ ##### ##### ] -[ #### #### ] -[#### ####] -[#### ####] -[#### ####] -[#### ####] -[#### ####] -[#### ####] -[#### ####] -[ #### #### ] -[ ############ ] -[ ########## ] -[ ######## ] -[ #### ] - -#char : 57 '9' -[ #### ] -[ ######## ] -[ ########## ] -[ ############ ] -[ #### #### ] -[#### ####] -[#### ####] -[#### ####] -[#### ####] -[#### ####] -[#### ####] -[#### ####] -[#### ####] -[##### #####] -[ ##### ######] -[ #############] -[ ############] -[ ###########] -[ #### ####] -[ ####] -[ ####] -[ ####] -[ ####] -[ ####] -[ ####] -[ ## ####] -[#### ####] -[##### #####] -[ ############ ] -[ ############ ] -[ ########## ] -[ ###### ] diff --git a/src/modm/ui/display/font/numbers_40x56.font b/src/modm/ui/display/font/numbers_40x56.font deleted file mode 100644 index 70a20c5d74..0000000000 --- a/src/modm/ui/display/font/numbers_40x56.font +++ /dev/null @@ -1,591 +0,0 @@ -#font : Numbers 40x57 -#width : 40 -#height : 56 -#hspace : 4 -#vspace : 0 - -#char : 48 '0' -[ ######### ] -[ ############### ] -[ ################### ] -[ ##################### ] -[ ####################### ] -[ ######################### ] -[ ########################### ] -[ ############################# ] -[ ############################## ] -[ ############################### ] -[ ############## ############## ] -[ ############# ############# ] -[ ############ ############ ] -[ ############ ############ ] -[ ############ ############ ] -[ ############ ############ ] -[ ############ ############ ] -[ ############ ############ ] -[ ############ ############ ] -[ ############ ############ ] -[ ########### ########### ] -[############ ############ ] -[############ ############ ] -[############ ############ ] -[############ ############ ] -[############ ############ ] -[############ ############ ] -[############ ############ ] -[############ ############ ] -[############ ############ ] -[############ ############ ] -[############ ############ ] -[############ ############ ] -[############ ############ ] -[############ ############ ] -[ ########### ########### ] -[ ############ ############ ] -[ ############ ############ ] -[ ############ ############ ] -[ ############ ############ ] -[ ############ ############ ] -[ ############ ############ ] -[ ############ ############ ] -[ ############# ############# ] -[ ############# ############# ] -[ ############## ############## ] -[ ############################### ] -[ ############################### ] -[ ############################# ] -[ ########################### ] -[ ######################### ] -[ ####################### ] -[ ##################### ] -[ ################### ] -[ ############### ] -[ ######### ] - -#char : 49 '1' -[ ######### ] -[ ########## ] -[ ########### ] -[ ############ ] -[ ############## ] -[ ############### ] -[ ################# ] -[ ################## ] -[ #################### ] -[ ###################### ] -[ ######################## ] -[ ########################## ] -[ ########################### ] -[ ########################## ] -[ ########################## ] -[ ######################### ] -[ ############ ############ ] -[ ########## ############ ] -[ ####### ############ ] -[ ##### ############ ] -[ # ############ ] -[ ############ ] -[ ############ ] -[ ############ ] -[ ############ ] -[ ############ ] -[ ############ ] -[ ############ ] -[ ############ ] -[ ############ ] -[ ############ ] -[ ############ ] -[ ############ ] -[ ############ ] -[ ############ ] -[ ############ ] -[ ############ ] -[ ############ ] -[ ############ ] -[ ############ ] -[ ############ ] -[ ############ ] -[ ############ ] -[ ############ ] -[ ############ ] -[ ############ ] -[ ############ ] -[ ############ ] -[ ############ ] -[ ############ ] -[ ############ ] -[ ############ ] -[ ############ ] -[ ############ ] -[ ############ ] -[ ############ ] - -#char : 50 '2' -[ ########## ] -[ ################# ] -[ ###################### ] -[ ########################## ] -[ ############################ ] -[ ############################### ] -[ ################################# ] -[ ################################## ] -[ ################################## ] -[ ################################## ] -[ ############ ############### ] -[ ######### ############## ] -[ ###### ############# ] -[ #### ############ ] -[ ## ############ ] -[ ############ ] -[ ############ ] -[ ############ ] -[ ############ ] -[ ############# ] -[ ############ ] -[ ############# ] -[ ############# ] -[ ############# ] -[ ############# ] -[ ############## ] -[ ############## ] -[ ############## ] -[ ############### ] -[ ################ ] -[ ################ ] -[ ################ ] -[ ################ ] -[ ################ ] -[ ################ ] -[ ################ ] -[ ################ ] -[ ############### ] -[ ############### ] -[ ############### ] -[ ############### ] -[ ############### ] -[ ############### ] -[ ############## ] -[ ############## ] -[ ############## ] -[ #################################### ] -[ ##################################### ] -[ ##################################### ] -[ ##################################### ] -[ ##################################### ] -[ ##################################### ] -[ ##################################### ] -[ ##################################### ] -[ ##################################### ] -[ ##################################### ] - -#char : 51 '3' -[ ########### ] -[ ################## ] -[ ####################### ] -[ ########################### ] -[ ############################## ] -[ ################################ ] -[ ############################### ] -[ ################################ ] -[ ############################### ] -[ ################################ ] -[ ######## ############### ] -[ ##### ############## ] -[ ## ############# ] -[ ############ ] -[ ############ ] -[ ############ ] -[ ############ ] -[ ############# ] -[ ############ ] -[ ############# ] -[ ############### ] -[ ######################## ] -[ ####################### ] -[ ###################### ] -[ ##################### ] -[ ################### ] -[ ##################### ] -[ ####################### ] -[ ######################## ] -[ ######################### ] -[ ########################## ] -[ ################ ] -[ ############### ] -[ ############# ] -[ ############ ] -[ ############# ] -[ ############ ] -[ ############ ] -[ ############ ] -[ ############ ] -[ ############ ] -[ ############# ] -[ ############# ] -[ # ############# ] -[ #### ############## ] -[ ######## ################# ] -[ ################################## ] -[ ################################### ] -[ ################################## ] -[ ################################# ] -[ ################################ ] -[ ################################ ] -[ ############################### ] -[ ############################ ] -[ ###################### ] -[ ############ ] - - -#char : 52 '4' -[ ############ ] -[ ############# ] -[ ############## ] -[ ############### ] -[ ################ ] -[ ################# ] -[ ################# ] -[ ################## ] -[ ################### ] -[ #################### ] -[ #################### ] -[ ##################### ] -[ ###################### ] -[ ####################### ] -[ ####################### ] -[ ########### ############ ] -[ ############ ############ ] -[ ########### ############ ] -[ ########### ############ ] -[ ########### ############ ] -[ ########### ############ ] -[ ########### ############ ] -[ ########### ############ ] -[ ########### ############ ] -[ ########### ############ ] -[ ########## ############ ] -[ ########### ############ ] -[ ########### ############ ] -[ ########### ############ ] -[ ########### ############ ] -[ ########### ############ ] -[ ########### ############ ] -[ ########### ############ ] -[########################################] -[########################################] -[########################################] -[########################################] -[########################################] -[########################################] -[########################################] -[########################################] -[########################################] -[########################################] -[ ############ ] -[ ############ ] -[ ############ ] -[ ############ ] -[ ############ ] -[ ############ ] -[ ############ ] -[ ############ ] -[ ############ ] -[ ############ ] -[ ############ ] -[ ############ ] -[ ############ ] - -#char : 53 '5' -[ ############################## ] -[ ############################## ] -[ ############################## ] -[ ############################## ] -[ ############################## ] -[ ############################## ] -[ ############################## ] -[ ############################## ] -[ ############################## ] -[ ############################### ] -[ ########### ] -[ ########### ] -[ ########### ] -[ ########### ] -[ ########### ] -[ ########### ] -[ ########### ] -[ ########## ] -[ ########## ] -[ ########## ] -[ ############### ] -[ ################### ] -[ ###################### ] -[ ######################### ] -[ ########################### ] -[ ############################# ] -[ ############################## ] -[ ############################## ] -[ ############################### ] -[ ################################ ] -[ ###################### ] -[ ################## ] -[ ############### ] -[ ############## ] -[ ############## ] -[ ############# ] -[ ############ ] -[ ############ ] -[ ############ ] -[ ############ ] -[ ############ ] -[ ############# ] -[ ############# ] -[ ############# ] -[ ### ############## ] -[ ####### ################# ] -[ ################################## ] -[ ################################## ] -[ ################################# ] -[ ################################ ] -[ ############################### ] -[ ############################### ] -[ ############################## ] -[ ########################### ] -[ ##################### ] -[ ############ ] - - -#char : 54 '6' -[ ###### ] -[ ########### ] -[ ################ ] -[ ################## ] -[ #################### ] -[ ###################### ] -[ ####################### ] -[ ######################### ] -[ ########################## ] -[ ########################### ] -[ ###################### ] -[ ################## ] -[ ################ ] -[ ############### ] -[ ############### ] -[ ############# ] -[ ############# ] -[ ############# ] -[ ############# ] -[ ############ ] -[ ############ ########## ] -[ ############################ ] -[ ############################## ] -[ ################################ ] -[ ################################# ] -[ ################################## ] -[#################################### ] -[##################################### ] -[##################################### ] -[###################################### ] -[############## ################ ] -[############ ############## ] -[############ ############# ] -[############ ############# ] -[############ ############ ] -[############ ############ ] -[############ ############ ] -[############ ############ ] -[############ ############ ] -[ ############ ############ ] -[ ############ ############ ] -[ ############ ############# ] -[ ############# ############ ] -[ ############ ############# ] -[ ############# ############## ] -[ ############### ############## ] -[ ################################## ] -[ ################################# ] -[ ############################### ] -[ ############################## ] -[ ############################ ] -[ ########################## ] -[ ####################### ] -[ ##################### ] -[ ################ ] -[ ########## ] - - -#char : 55 '7' -[####################################### ] -[####################################### ] -[####################################### ] -[####################################### ] -[####################################### ] -[####################################### ] -[####################################### ] -[####################################### ] -[####################################### ] -[####################################### ] -[ ############## ] -[ ############# ] -[ ############## ] -[ ############## ] -[ ############# ] -[ ############# ] -[ ############# ] -[ ############# ] -[ ############## ] -[ ############# ] -[ ############# ] -[ ############# ] -[ ############# ] -[ ############# ] -[ ############ ] -[ ############# ] -[ ############ ] -[ ############# ] -[ ############ ] -[ ############# ] -[ ############ ] -[ ############ ] -[ ############# ] -[ ############ ] -[ ############ ] -[ ############# ] -[ ############ ] -[ ############ ] -[ ############# ] -[ ############ ] -[ ############ ] -[ ############ ] -[ ############ ] -[ ############ ] -[ ############ ] -[ ############ ] -[ ############ ] -[ ############ ] -[ ############ ] -[ ############ ] -[ ############ ] -[ ############ ] -[ ############ ] -[ ############ ] -[ ############ ] -[ ############ ] - - -#char : 56 '8' -[ ########## ] -[ ################# ] -[ ##################### ] -[ ######################## ] -[ ########################### ] -[ ############################# ] -[ ############################### ] -[ ################################ ] -[ ################################# ] -[ ################################## ] -[ ############### ############### ] -[ ############# ############## ] -[ ############# ############# ] -[ ############# ############# ] -[ ############ ############ ] -[ ############ ############ ] -[ ############ ############ ] -[ ############# ############ ] -[ ############# ############ ] -[ ############# ############ ] -[ ############## ############ ] -[ ############### ############# ] -[ ################ ############# ] -[ ############################## ] -[ ############################# ] -[ ########################### ] -[ ######################### ] -[ ######################## ] -[ ########################### ] -[ ############################## ] -[ ################################ ] -[ ################################## ] -[ ############# ################# ] -[ ############# ################ ] -[ ############# ############## ] -[ ############ ############# ] -[ ############ ############# ] -[############ ############# ] -[############ ############ ] -[############ ############ ] -[############ ############ ] -[############ ############ ] -[############# ############# ] -[############# ############# ] -[ ############# ############# ] -[ ############### ############### ] -[ ##################################### ] -[ ################################### ] -[ ################################### ] -[ ################################# ] -[ ############################### ] -[ ############################# ] -[ ########################### ] -[ ####################### ] -[ ################### ] -[ ########### ] - - -#char : 57 '9' -[ ########## ] -[ ################# ] -[ ##################### ] -[ ######################## ] -[ ########################### ] -[ ############################# ] -[ ############################### ] -[ ################################ ] -[ ################################# ] -[ ################################### ] -[ ############### ############### ] -[ ############## ############## ] -[ ############# ############# ] -[ ############ ############# ] -[############# ############# ] -[############ ############ ] -[############ ############ ] -[############ ############ ] -[############ ############] -[############ ############] -[############ ############] -[############ ############] -[############# ############] -[############## ############] -[ ############## ############] -[ ################ ##############] -[ #######################################] -[ ######################################] -[ ######################################] -[ #####################################] -[ ####################################] -[ ################################## ] -[ ################################# ] -[ ############################### ] -[ ############################# ] -[ ########## ############ ] -[ ############ ] -[ ############ ] -[ ############# ] -[ ############# ] -[ ############## ] -[ ############## ] -[ ############### ] -[ ################ ] -[ ################## ] -[ ###################### ] -[ ############################# ] -[ ########################### ] -[ ########################## ] -[ ######################### ] -[ ####################### ] -[ ##################### ] -[ ################### ] -[ ################# ] -[ ############# ] -[ ######## ] - diff --git a/src/modm/ui/display/font/numbers_46x64.font b/src/modm/ui/display/font/numbers_46x64.font deleted file mode 100644 index c77b22c333..0000000000 --- a/src/modm/ui/display/font/numbers_46x64.font +++ /dev/null @@ -1,666 +0,0 @@ -#font : Numbers 46x64 -#width : 46 -#height : 64 -#hspace : 4 -#vspace : 4 - -#char : 48 '0' -[ ########## ] -[ ################# ] -[ ##################### ] -[ ######################## ] -[ ########################### ] -[ ############################# ] -[ ############################### ] -[ ################################ ] -[ ################################## ] -[ #################################### ] -[ #################################### ] -[ ################ ################ ] -[ ############## ############## ] -[ ############## ############## ] -[ ############# ############# ] -[ ############## ############## ] -[ ############# ############# ] -[ ############# ############# ] -[ ############# ############## ] -[ ############# ############# ] -[ ############# ############# ] -[ ############# ############# ] -[ ############# ############# ] -[ ############ ############ ] -[############# #############] -[############# #############] -[############# #############] -[############# #############] -[############# #############] -[############# #############] -[############# #############] -[############# #############] -[############# #############] -[############# #############] -[############# #############] -[############# #############] -[############# #############] -[############# #############] -[############# #############] -[############# #############] -[ ############ ############ ] -[ ############# ############# ] -[ ############# ############# ] -[ ############# ############# ] -[ ############# ############# ] -[ ############# ############## ] -[ ############# ############# ] -[ ############# ############# ] -[ ############## ############## ] -[ ############# ############# ] -[ ############## ############## ] -[ ############### ############## ] -[ ################ ################ ] -[ #################################### ] -[ #################################### ] -[ ################################## ] -[ ################################ ] -[ ################################ ] -[ ############################## ] -[ ############################ ] -[ ######################## ] -[ ###################### ] -[ ################## ] -[ ########## ] - -#char : 49 '1' -[ ######### ] -[ ########### ] -[ ############ ] -[ ############# ] -[ ############## ] -[ ################ ] -[ ################# ] -[ ################### ] -[ ##################### ] -[ ###################### ] -[ ######################## ] -[ ########################### ] -[ ############################# ] -[ ############################## ] -[ ############################## ] -[ ############################# ] -[ ############################# ] -[ ############## ############# ] -[ ############# ############# ] -[ ########## ############# ] -[ ####### ############# ] -[ ##### ############# ] -[ # ############# ] -[ ############# ] -[ ############# ] -[ ############# ] -[ ############# ] -[ ############# ] -[ ############# ] -[ ############# ] -[ ############# ] -[ ############# ] -[ ############# ] -[ ############# ] -[ ############# ] -[ ############# ] -[ ############# ] -[ ############# ] -[ ############# ] -[ ############# ] -[ ############# ] -[ ############# ] -[ ############# ] -[ ############# ] -[ ############# ] -[ ############# ] -[ ############# ] -[ ############# ] -[ ############# ] -[ ############# ] -[ ############# ] -[ ############# ] -[ ############# ] -[ ############# ] -[ ############# ] -[ ############# ] -[ ############# ] -[ ############# ] -[ ############# ] -[ ############# ] -[ ############# ] -[ ############# ] -[ ############# ] -[ ############# ] - -#char : 50 '2' -[ ########### ] -[ ################### ] -[ ######################## ] -[ ########################### ] -[ ############################### ] -[ ################################# ] -[ #################################### ] -[ ##################################### ] -[ ####################################### ] -[ ###################################### ] -[ ###################################### ] -[ ############## ################# ] -[ ########### ############## ] -[ ######## ############## ] -[ ##### ############## ] -[ #### ############# ] -[ ## ############# ] -[ ############# ] -[ ############# ] -[ ############# ] -[ ############# ] -[ ############# ] -[ ############## ] -[ ############# ] -[ ############## ] -[ ############### ] -[ ############## ] -[ ############### ] -[ ############### ] -[ ################ ] -[ ################ ] -[ ################ ] -[ ################# ] -[ ################# ] -[ ################# ] -[ ################# ] -[ ################# ] -[ ################# ] -[ ################# ] -[ ################# ] -[ ################# ] -[ ################# ] -[ ################# ] -[ ################# ] -[ ################# ] -[ ################ ] -[ ################# ] -[ ################# ] -[ ################ ] -[ ################ ] -[ ############### ] -[ ################ ] -[ ############### ] -[ ######################################## ] -[ ######################################### ] -[ ######################################### ] -[ ######################################### ] -[ ######################################### ] -[ ######################################### ] -[ ######################################### ] -[ ######################################### ] -[ ######################################### ] -[ ######################################### ] -[ ######################################### ] - -#char : 51 '3' -[ ########### ] -[ ################### ] -[ ######################## ] -[ ############################ ] -[ ############################### ] -[ ################################### ] -[ ################################### ] -[ ################################### ] -[ #################################### ] -[ ################################### ] -[ #################################### ] -[ ########## ################# ] -[ ####### ############### ] -[ #### ############### ] -[ ## ############## ] -[ ############# ] -[ ############# ] -[ ############# ] -[ ############# ] -[ ############# ] -[ ############## ] -[ ############# ] -[ ############## ] -[ ############## ] -[ ################# ] -[ ########################## ] -[ ######################### ] -[ ######################## ] -[ ####################### ] -[ ##################### ] -[ ####################### ] -[ ######################### ] -[ ########################## ] -[ ############################ ] -[ ############################ ] -[ ############################# ] -[ ################### ] -[ ################ ] -[ ############### ] -[ ############## ] -[ ############## ] -[ ############## ] -[ ############# ] -[ ############# ] -[ ############# ] -[ ############# ] -[ ############# ] -[ ############## ] -[ ############## ] -[ ############## ] -[ # ############### ] -[ ##### ################ ] -[ ######### ################## ] -[ ####################################### ] -[ ###################################### ] -[ ####################################### ] -[ ###################################### ] -[ ##################################### ] -[ #################################### ] -[ #################################### ] -[ ################################## ] -[ ############################## ] -[ ####################### ] -[ ############# ] - -#char : 52 '4' -[ ############ ] -[ ############# ] -[ ############## ] -[ ############### ] -[ ################ ] -[ ################# ] -[ ################## ] -[ ################## ] -[ ################### ] -[ #################### ] -[ ##################### ] -[ ###################### ] -[ ###################### ] -[ ####################### ] -[ ######################## ] -[ ######################### ] -[ ######################### ] -[ ########################## ] -[ ############# ############# ] -[ ############ ############# ] -[ ############# ############# ] -[ ############# ############# ] -[ ############ ############# ] -[ ############# ############# ] -[ ############# ############# ] -[ ############ ############# ] -[ ############ ############# ] -[ ############# ############# ] -[ ############ ############# ] -[ ############ ############# ] -[ ############ ############# ] -[ ############ ############# ] -[ ############# ############# ] -[ ############ ############# ] -[ ############# ############# ] -[ ############ ############# ] -[ ############# ############# ] -[ ############ ############# ] -[##############################################] -[##############################################] -[##############################################] -[##############################################] -[##############################################] -[##############################################] -[##############################################] -[##############################################] -[##############################################] -[##############################################] -[##############################################] -[ ############# ] -[ ############# ] -[ ############# ] -[ ############# ] -[ ############# ] -[ ############# ] -[ ############# ] -[ ############# ] -[ ############# ] -[ ############# ] -[ ############# ] -[ ############# ] -[ ############# ] -[ ############# ] -[ ############# ] - -#char : 53 '5' -[ ################################## ] -[ ################################## ] -[ ################################## ] -[ ################################## ] -[ ################################## ] -[ ################################## ] -[ ################################## ] -[ ################################## ] -[ ################################### ] -[ ################################### ] -[ ################################### ] -[ ############ ] -[ ############ ] -[ ############ ] -[ ############ ] -[ ############ ] -[ ############ ] -[ ############ ] -[ ############ ] -[ ############ ] -[ ########### ] -[ ############ ] -[ ############ ] -[ ############ ] -[ ################# ] -[ ###################### ] -[ ######################### ] -[ ############################ ] -[ ############################# ] -[ ############################### ] -[ ################################ ] -[ ################################## ] -[ ################################### ] -[ #################################### ] -[ ##################################### ] -[ ########################## ] -[ ##################### ] -[ ################## ] -[ ################ ] -[ ############## ] -[ ############## ] -[ ############## ] -[ ############# ] -[ ############# ] -[ ############# ] -[ ############# ] -[ ############# ] -[ ############# ] -[ ############## ] -[ ############## ] -[ # ############### ] -[ #### ################ ] -[ ######### ################## ] -[ ####################################### ] -[ ####################################### ] -[ ###################################### ] -[ ###################################### ] -[ ##################################### ] -[ #################################### ] -[ ################################### ] -[ ################################## ] -[ ############################## ] -[ ####################### ] -[ ############## ] - -#char : 54 '6' -[ ] -[ ####### ] -[ ############# ] -[ ################ ] -[ ################### ] -[ ###################### ] -[ ######################## ] -[ ########################## ] -[ ########################### ] -[ ############################# ] -[ ############################## ] -[ ############################### ] -[ ######################### ] -[ ##################### ] -[ ################### ] -[ ################## ] -[ ################ ] -[ ################ ] -[ ############### ] -[ ############## ] -[ ############## ] -[ ############## ] -[ ############# ] -[ ############## ] -[ ############# ############ ] -[ ################################ ] -[ ################################### ] -[ ##################################### ] -[ ###################################### ] -[ ######################################## ] -[ ######################################### ] -[########################################## ] -[########################################### ] -[############################################ ] -[############################################ ] -[################ ################## ] -[############# ################ ] -[############# ############## ] -[############# ##############] -[############# ##############] -[############# #############] -[############# #############] -[############# #############] -[############# #############] -[ ############# #############] -[ ############# #############] -[ ############# #############] -[ ############# ##############] -[ ############## ############# ] -[ ############## ############## ] -[ ############## ############### ] -[ ################ ############### ] -[ ################# ################# ] -[ ######################################## ] -[ ####################################### ] -[ ##################################### ] -[ #################################### ] -[ ################################## ] -[ ################################ ] -[ ############################## ] -[ ########################### ] -[ ######################## ] -[ ################### ] -[ ############ ] - -#char : 55 '7' -[ ########################################### ] -[ ########################################### ] -[ ########################################### ] -[ ########################################### ] -[ ########################################### ] -[ ########################################### ] -[ ########################################### ] -[ ########################################### ] -[ ########################################### ] -[ ########################################### ] -[ ########################################## ] -[ ############## ] -[ ############### ] -[ ############### ] -[ ############## ] -[ ############### ] -[ ############### ] -[ ############## ] -[ ############### ] -[ ############## ] -[ ############## ] -[ ############## ] -[ ############## ] -[ ############## ] -[ ############## ] -[ ############## ] -[ ############## ] -[ ############## ] -[ ############# ] -[ ############## ] -[ ############# ] -[ ############## ] -[ ############# ] -[ ############# ] -[ ############## ] -[ ############# ] -[ ############# ] -[ ############## ] -[ ############# ] -[ ############# ] -[ ############# ] -[ ############# ] -[ ############# ] -[ ############## ] -[ ############# ] -[ ############# ] -[ ############# ] -[ ############# ] -[ ############# ] -[ ############# ] -[ ############# ] -[ ############# ] -[ ############# ] -[ ############# ] -[ ############# ] -[ ############# ] -[ ############# ] -[ ############# ] -[ ############# ] -[ ############# ] -[ ############# ] -[ ############# ] -[ ############# ] -[ ############# ] - -#char : 56 '8' -[ ########## ] -[ ################## ] -[ ###################### ] -[ ########################## ] -[ ############################ ] -[ ############################### ] -[ ################################# ] -[ ################################## ] -[ #################################### ] -[ ##################################### ] -[ ###################################### ] -[ ################# ################# ] -[ ############### ############### ] -[ ############## ############### ] -[ ############## ############## ] -[ ############# ############# ] -[ ############# ############# ] -[ ############# ############# ] -[ ############# ############# ] -[ ############# ############# ] -[ ############## ############# ] -[ ############## ############# ] -[ ############## ############# ] -[ ############### ############# ] -[ ################ ############## ] -[ ################# ############## ] -[ ################### ############## ] -[ ################################## ] -[ ################################ ] -[ ############################# ] -[ ########################### ] -[ ########################### ] -[ ############################# ] -[ ################################ ] -[ ################################## ] -[ #################################### ] -[ ############### ##################### ] -[ ############## ################### ] -[ ############## ################# ] -[ ############## ################ ] -[ ############## ############### ] -[ ############# ############## ] -[ ############## ############## ] -[ ############# ############# ] -[ ############# ############# ] -[ ############# ############# ] -[ ############# ############# ] -[ ############# ############# ] -[ ############## ############## ] -[ ############## ############## ] -[ ############### ############## ] -[ ############### ############### ] -[ ################# ################# ] -[ ######################################## ] -[ ######################################## ] -[ ###################################### ] -[ ###################################### ] -[ #################################### ] -[ ################################## ] -[ ################################ ] -[ ############################ ] -[ ######################## ] -[ #################### ] -[ ############ ] - -#char : 57 '9' -[ ########### ] -[ ################# ] -[ ###################### ] -[ ######################### ] -[ ############################ ] -[ ############################### ] -[ ################################# ] -[ ################################## ] -[ ################################### ] -[ ##################################### ] -[ ##################################### ] -[ ################ ################ ] -[ ############### ############### ] -[ ############## ############## ] -[ ############## ############## ] -[ ############# ############## ] -[ ############## ############## ] -[ ############# ############# ] -[ ############# ############# ] -[ ############# ############# ] -[ ############# ############# ] -[ ############# ############# ] -[ ############# ############# ] -[ ############# ############# ] -[ ############# ############# ] -[ ############## ############# ] -[ ############## ############# ] -[ ############## ############# ] -[ ############### ############# ] -[ ################## ################ ] -[ ########################################## ] -[ ########################################## ] -[ ######################################### ] -[ ######################################### ] -[ ######################################## ] -[ ####################################### ] -[ ##################################### ] -[ #################################### ] -[ ################################## ] -[ ################## ############# ] -[ ########### ############## ] -[ ############# ] -[ ############# ] -[ ############## ] -[ ############## ] -[ ############## ] -[ ############### ] -[ ############### ] -[ ################# ] -[ ################# ] -[ ################## ] -[ ##################### ] -[ ######################### ] -[ ################################ ] -[ ############################### ] -[ ############################# ] -[ ############################ ] -[ ########################## ] -[ ######################### ] -[ ####################### ] -[ ##################### ] -[ ################## ] -[ ############## ] -[ ######## ] - diff --git a/src/modm/ui/display/font/scripto_narrow.font b/src/modm/ui/display/font/scripto_narrow.font deleted file mode 100644 index fec1ea913c..0000000000 --- a/src/modm/ui/display/font/scripto_narrow.font +++ /dev/null @@ -1,860 +0,0 @@ -#font : Scripto Narrow -#width : 5 -#height : 7 -#vspace : 1 -#hspace : 0 - -#char : 32 ' ' -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] - -#char : 33 '!' -[#] -[#] -[#] -[#] -[ ] -[#] -[ ] - -#char : 34 '"' -[# #] -[# #] -[ ] -[ ] -[ ] -[ ] -[ ] - -#char : 35 '#' -[ # # ] -[#####] -[ # # ] -[ # # ] -[#####] -[ # # ] -[ ] - -#char : 36 '$' -[ # ] -[ ####] -[# # ] -[ ### ] -[ # #] -[#### ] -[ # ] - -#char : 37 '%' -[ ## #] -[# # # ] -[## # ] -[ # ##] -[ # # #] -[# ## ] -[ ] - -#char : 38 '&' -[ ## ] -[# # ] -[ # ] -[## ] -[# # ] -[## #] -[ ] - -#char : 39 ''' -[#] -[#] -[ ] -[ ] -[ ] -[ ] -[ ] - -#char : 40 '(' -[ #] -[# ] -[# ] -[# ] -[# ] -[ #] -[ ] - -#char : 41 ')' -[# ] -[ #] -[ #] -[ #] -[ #] -[# ] -[ ] - -#char : 42 '*' -[ ] -[# #] -[ ## ] -[####] -[ ## ] -[# #] -[ ] - -#char : 43 '+' -[ ] -[ ] -[ # ] -[###] -[ # ] -[ ] -[ ] - -#char : 44 ',' -[ ] -[ ] -[ ] -[ ] -[ ] -[ #] -[# ] - -#char : 45 '-' -[ ] -[ ] -[ ] -[ ] -[###] -[ ] -[ ] - -#char : 46 '.' -[ ] -[ ] -[ ] -[ ] -[ ] -[ #] -[# ] - -#char : 47 '/' -[ #] -[ #] -[ #] -[# ] -[# ] -[# ] -[ ] - -#char : 48 '0' -[ ##] -[# #] -[# #] -[# #] -[# #] -[## ] -[ ] - -#char : 49 '1' -[ #] -[##] -[ #] -[ #] -[ #] -[ #] -[ ] - -#char : 50 '2' -[## ] -[ #] -[ # ] -[# ] -[# ] -[###] -[ ] - -#char : 51 '3' -[## ] -[ #] -[ # ] -[ #] -[ #] -[###] -[ ] - -#char : 52 '4' -[ #] -[ ##] -[# #] -[###] -[ #] -[ #] -[ ] - -#char : 53 '5' -[###] -[# ] -[## ] -[ #] -[ #] -[###] -[ ] - -#char : 54 '6' -[ ##] -[# ] -[###] -[# #] -[# #] -[ # ] -[ ] - -#char : 55 '7' -[###] -[ #] -[ #] -[ # ] -[ # ] -[ # ] -[ ] - -#char : 56 '8' -[ ##] -[# #] -[ # ] -[# #] -[# #] -[## ] -[ ] - -#char : 57 '9' -[ # ] -[# #] -[# #] -[###] -[ #] -[## ] -[ ] - -#char : 58 ':' -[ ] -[ ] -[#] -[ ] -[#] -[ ] -[ ] - -#char : 59 ';' -[ ] -[ ] -[ #] -[ ] -[ ] -[ #] -[# ] - -#char : 60 '<' -[ ] -[ #] -[ # ] -[# ] -[ # ] -[ #] -[ ] - -#char : 61 '=' -[ ] -[ ] -[###] -[ ] -[###] -[ ] -[ ] - -#char : 62 '>' -[ ] -[# ] -[ # ] -[ #] -[ # ] -[# ] -[ ] - -#char : 63 '?' -[ ## ] -[# #] -[ # ] -[ # ] -[ ] -[ # ] -[ ] - -#char : 64 '@' -[###] -[# #] -[# #] -[# #] -[# ] -[###] -[ ] - -#char : 65 'A' -[## ] -[# #] -[# #] -[###] -[# #] -[# #] -[ ] - -#char : 66 'B' -[## ] -[# #] -[## ] -[# #] -[# #] -[###] -[ ] - -#char : 67 'C' -[ ##] -[# ] -[# ] -[# ] -[# ] -[###] -[ ] - -#char : 68 'D' -[## ] -[# #] -[# #] -[# #] -[# #] -[###] -[ ] - -#char : 69 'E' -[###] -[# ] -[## ] -[# ] -[# ] -[###] -[ ] - -#char : 70 'F' -[###] -[# ] -[## ] -[# ] -[# ] -[# ] -[ ] - -#char : 71 'G' -[ ##] -[# ] -[# ] -[###] -[# #] -[###] -[ ] - -#char : 72 'H' -[# #] -[# #] -[###] -[# #] -[# #] -[# #] -[ ] - -#char : 73 'I' -[#] -[#] -[#] -[#] -[#] -[#] -[ ] - -#char : 74 'J' -[ #] -[ #] -[ #] -[ #] -[ #] -[## ] -[ ] - -#char : 75 'K' -[# #] -[# #] -[## ] -[# #] -[# #] -[# #] -[ ] - -#char : 76 'L' -[# ] -[# ] -[# ] -[# ] -[# ] -[###] -[ ] - -#char : 77 'M' -[# #] -[####] -[# #] -[# #] -[# #] -[# #] -[ ] - -#char : 78 'N' -[# #] -[###] -[# #] -[# #] -[# #] -[# #] -[ ] - -#char : 79 'O' -[ ##] -[# #] -[# #] -[# #] -[# #] -[## ] -[ ] - -#char : 80 'P' -[## ] -[# #] -[# #] -[###] -[# ] -[# ] -[ ] - -#char : 81 'Q' -[ # ] -[# #] -[# #] -[# #] -[###] -[ ##] -[ ] - -#char : 82 'R' -[## ] -[# #] -[# #] -[## ] -[# #] -[# #] -[ ] - -#char : 83 'S' -[ ##] -[# ] -[ # ] -[ #] -[ #] -[## ] -[ ] - -#char : 84 'T' -[###] -[ # ] -[ # ] -[ # ] -[ # ] -[ # ] -[ ] - -#char : 85 'U' -[# #] -[# #] -[# #] -[# #] -[# #] -[ ##] -[ ] - -#char : 86 'V' -[# #] -[# #] -[# #] -[# #] -[# #] -[ # ] -[ ] - -#char : 87 'W' -[# #] -[# #] -[# #] -[# #] -[####] -[# #] -[ ] - -#char : 88 'X' -[# #] -[ ## ] -[ ## ] -[ ## ] -[ ## ] -[# #] -[ ] - -#char : 89 'Y' -[# #] -[# #] -[# #] -[ # ] -[ # ] -[ # ] -[ ] - -#char : 90 'Z' -[###] -[ #] -[ # ] -[# ] -[# ] -[###] -[ ] - -#char : 91 '[' -[##] -[# ] -[# ] -[# ] -[# ] -[##] -[ ] - -#char : 92 '\' -[# ] -[# ] -[# ] -[ #] -[ #] -[ #] -[ ] - -#char : 93 ']' -[##] -[ #] -[ #] -[ #] -[ #] -[##] -[ ] - -#char : 94 '^' -[ # ] -[# #] -[ ] -[ ] -[ ] -[ ] -[ ] - -#char : 95 '_' -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[###] - -#char : 96 '`' -[# ] -[ #] -[ ] -[ ] -[ ] -[ ] -[ ] - -#char : 97 'a' -[ ] -[ ] -[ ##] -[# #] -[# #] -[###] -[ ] - -#char : 98 'b' -[# ] -[# ] -[## ] -[# #] -[# #] -[###] -[ ] - -#char : 99 'c' -[ ] -[ ] -[ ##] -[# ] -[# ] -[###] -[ ] - -#char : 100 'd' -[ #] -[ #] -[ ##] -[# #] -[# #] -[###] -[ ] - -#char : 101 'e' -[ ] -[ ] -[ # ] -[###] -[# ] -[###] -[ ] - -#char : 102 'f' -[ #] -[# ] -[##] -[# ] -[# ] -[# ] -[ ] - -#char : 103 'g' -[ ] -[ ##] -[# #] -[# #] -[###] -[ #] -[## ] - -#char : 104 'h' -[# ] -[# ] -[## ] -[# #] -[# #] -[# #] -[ ] - -#char : 105 'i' -[#] -[ ] -[#] -[#] -[#] -[#] -[ ] - -#char : 106 'j' -[ #] -[ ] -[ #] -[ #] -[ #] -[ #] -[# ] - -#char : 107 'k' -[# ] -[# ] -[###] -[## ] -[# #] -[# #] -[ ] - -#char : 108 'l' -[#] -[#] -[#] -[#] -[#] -[#] -[ ] - -#char : 109 'm' -[ ] -[ ] -[## # ] -[# # #] -[# # #] -[# # #] -[ ] - -#char : 110 'n' -[ ] -[ ] -[## ] -[# #] -[# #] -[# #] -[ ] - -#char : 111 'o' -[ ] -[ ] -[ ##] -[# #] -[# #] -[## ] -[ ] - -#char : 112 'p' -[ ] -[## ] -[# #] -[# #] -[###] -[# ] -[# ] - -#char : 113 'q' -[ ] -[ ##] -[# #] -[# #] -[###] -[ #] -[ #] - -#char : 114 'r' -[ ] -[ ] -[# #] -[## ] -[# ] -[# ] -[ ] - -#char : 115 's' -[ ] -[ ] -[ ###] -[## ] -[ ##] -[### ] -[ ] - -#char : 116 't' -[ # ] -[ # ] -[###] -[ # ] -[ # ] -[ # ] -[ ] - -#char : 117 'u' -[ ] -[ ] -[# #] -[# #] -[# #] -[ ##] -[ ] - -#char : 118 'v' -[ ] -[ ] -[# #] -[# #] -[# #] -[ # ] -[ ] - -#char : 119 'w' -[ ] -[ ] -[# # #] -[# # #] -[# # #] -[## # ] -[ ] - -#char : 120 'x' -[ ] -[ ] -[# #] -[ # ] -[ # ] -[# #] -[ ] - -#char : 121 'y' -[ ] -[# #] -[# #] -[# #] -[###] -[ #] -[## ] - -#char : 122 'z' -[ ] -[ ] -[####] -[ # ] -[ # ] -[####] -[ ] - -#char : 123 '{' -[ #] -[ # ] -[ # ] -[# ] -[ # ] -[ # ] -[ #] - -#char : 124 '|' -[#] -[#] -[ ] -[ ] -[#] -[#] -[ ] - -#char : 125 '}' -[# ] -[ # ] -[ # ] -[ #] -[ # ] -[ # ] -[# ] - -#char : 126 '~' -[ ] -[ ] -[ ## #] -[# ## ] -[ ] -[ ] -[ ] diff --git a/src/modm/ui/display/font/ubuntu_36.font b/src/modm/ui/display/font/ubuntu_36.font deleted file mode 100644 index f2973b8a3f..0000000000 --- a/src/modm/ui/display/font/ubuntu_36.font +++ /dev/null @@ -1,3557 +0,0 @@ -#font : Ubuntu_36 -#width : 10 -#height : 35 -#hspace : 1 -#vspace : 0 - -#char : 32 ' ' -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] - -#char : 33 '!' -[ ] -[ ] -[ ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ # ] -[ # ] -[ ] -[ ] -[ ] -[ ### ] -[#####] -[#####] -[#####] -[ ### ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] - -#char : 34 '"' -[### ###] -[### ###] -[### ###] -[### ###] -[### ###] -[### ###] -[### ###] -[### ###] -[ # # ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] - -#char : 35 '#' -[ ] -[ ] -[ ] -[ ### ### ] -[ ### ### ] -[ #### ### ] -[ ### ### ] -[ ### ### ] -[ ### ### ] -[ ### ### ] -[####################] -[####################] -[####################] -[ ### ### ] -[ ### ### ] -[ ### ### ] -[ ### ### ] -[ ### ### ] -[####################] -[####################] -[####################] -[ ### ### ] -[ ### ### ] -[ ### ### ] -[ ### ### ] -[ #### ### ] -[ ### ### ] -[ ### ### ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] - -#char : 36 '$' -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ######## ] -[ ############ ] -[ ############# ] -[ #### # ] -[ #### ] -[ ### ] -[ ### ] -[ ### ] -[ #### ] -[ ##### ] -[ ###### ] -[ ####### ] -[ ###### ] -[ ##### ] -[ #### ] -[ ### ] -[ ###] -[ ###] -[ ###] -[ ####] -[ ## #####] -[############### ] -[############## ] -[ ######### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ] -[ ] - -#char : 37 '%' -[ ] -[ ] -[ ] -[ ###### ### ] -[ ######## ### ] -[ ### ### ### ] -[#### #### ### ] -[### ### ### ] -[### ### ### ] -[### ### ### ] -[### ### ### ] -[#### #### ### ] -[ ### ### ### ] -[ ######## ### ] -[ ###### ### ] -[ ### ] -[ ### ###### ] -[ ### ######## ] -[ ### ### ### ] -[ ### #### ####] -[ ### ### ###] -[ ### ### ###] -[ ### ### ###] -[ ### ### ###] -[ ### #### ####] -[ ### ### ### ] -[ ### ######## ] -[ ### ###### ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] - -#char : 38 '&' -[ ] -[ ] -[ ] -[ ##### ] -[ ######## ] -[ ########## ] -[ #### #### ] -[ ### ### ] -[ ### ### ] -[ ### ### ] -[ ### #### ] -[ #### ### ] -[ ### #### ] -[ ######## ] -[ ###### ] -[ ###### ] -[ ######### ## ] -[ #### #### ### ] -[ ### #### ## ] -[### #### ### ] -[### ####### ] -[### ###### ] -[### #### ] -[#### #### ] -[ #### ####### ] -[ ################## ] -[ ########### #### ] -[ ###### ####] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] - -#char : 39 ''' -[###] -[###] -[###] -[###] -[###] -[###] -[###] -[###] -[ # ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] - -#char : 40 '(' -[ # ] -[ ###] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ###] -[ # ] - -#char : 41 ')' -[ # ] -[### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ###] -[ ###] -[ ###] -[ ###] -[ ###] -[ ###] -[ ###] -[ ###] -[ ###] -[ ###] -[ ###] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[### ] -[ # ] - -#char : 42 '*' -[ ] -[ ] -[ ] -[ ### ] -[ ### ] -[ ### ] -[ # ### # ] -[#### ### ####] -[ ##### # ##### ] -[ ######### ] -[ ### ] -[ ## ## ] -[ ### ### ] -[ ### ### ] -[ #### #### ] -[ ### ### ] -[ # # ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] - -#char : 43 '+' -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[#################] -[#################] -[#################] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] - -#char : 44 ',' -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ###] -[ ###] -[ ###] -[ ###] -[ ###] -[ ## ] -[ ## ] -[### ] -[## ] -[ # ] -[ ] - -#char : 45 '-' -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[#########] -[#########] -[#########] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] - -#char : 46 '.' -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ### ] -[#####] -[#####] -[#####] -[ ### ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] - -#char : 47 '/' -[ ##] -[ ###] -[ ###] -[ ###] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ #### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[### ] -[### ] -[### ] -[## ] - -#char : 48 '0' -[ ] -[ ] -[ ] -[ ###### ] -[ ######## ] -[ ########## ] -[ #### #### ] -[ #### #### ] -[ ### ### ] -[ ### ### ] -[#### ###] -[### ###] -[### ###] -[### ###] -[### ###] -[### ###] -[### ###] -[### ###] -[### ###] -[### ###] -[#### ###] -[ ### ### ] -[ ### ### ] -[ #### #### ] -[ #### #### ] -[ ########## ] -[ ######## ] -[ ###### ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] - -#char : 49 '1' -[ ] -[ ] -[ ] -[ ###] -[ ####] -[ #####] -[ #######] -[ #########] -[###### ###] -[ #### ###] -[ # ###] -[ ###] -[ ###] -[ ###] -[ ###] -[ ###] -[ ###] -[ ###] -[ ###] -[ ###] -[ ###] -[ ###] -[ ###] -[ ###] -[ ###] -[ ###] -[ ###] -[ ###] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] - -#char : 50 '2' -[ ] -[ ] -[ ] -[ ####### ] -[ ########### ] -[ ############# ] -[##### #### ] -[ ## #### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ #### ] -[ #### ] -[ #### ] -[ #### ] -[ #### ] -[ #### ] -[ #### ] -[ #### ] -[ #### ] -[ #### ] -[ ### ] -[### ] -[################] -[################] -[################] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] - -#char : 51 '3' -[ ] -[ ] -[ ] -[ ####### ] -[ ########### ] -[############# ] -[ ## #### ] -[ #### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ####### ] -[ ####### ] -[ ######### ] -[ ##### ] -[ ### ] -[ ####] -[ ###] -[ ###] -[ ###] -[ ###] -[ ### ] -[### ##### ] -[############# ] -[############ ] -[ ######## ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] - -#char : 52 '4' -[ ] -[ ] -[ ] -[ ### ] -[ #### ] -[ ##### ] -[ ###### ] -[ ####### ] -[ #### ### ] -[ ### ### ] -[ #### ### ] -[ #### ### ] -[ ### ### ] -[ ### ### ] -[ ### ### ] -[ ### ### ] -[ ### ### ] -[ ### ### ] -[### ### ] -[#################] -[#################] -[#################] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] - -#char : 53 '5' -[ ] -[ ] -[ ] -[ ############ ] -[ ############ ] -[ ############ ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ####### ] -[ ########## ] -[ ############ ] -[ ####### ] -[ #### ] -[ ####] -[ ###] -[ ###] -[ ###] -[ ###] -[ ###] -[ ### ] -[### ##### ] -[############# ] -[############ ] -[ ######## ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] - -#char : 54 '6' -[ ] -[ ] -[ ] -[ #### ] -[ ####### ] -[ ######### ] -[ ###### ] -[ #### ] -[ #### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ###### ] -[############# ] -[############## ] -[#### #### ] -[### ### ] -[### ###] -[### ###] -[### ###] -[### ###] -[#### ###] -[ ### ####] -[ #### ### ] -[ #### ##### ] -[ ############ ] -[ ########## ] -[ ###### ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] - -#char : 55 '7' -[ ] -[ ] -[ ] -[################] -[################] -[################] -[ ## ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ## ] -[ ### ] -[ ### ] -[ ## ] -[ ### ] -[ ### ] -[ ### ] -[ ## ] -[ ### ] -[ ### ] -[ ### ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] - -#char : 56 '8' -[ ] -[ ] -[ ] -[ ###### ] -[ ########## ] -[ ############ ] -[ #### #### ] -[ #### #### ] -[ ### ### ] -[ ### ### ] -[ ### ### ] -[ #### ### ] -[ ### ### ] -[ ##### #### ] -[ ########## ] -[ ######## ] -[ ########### ] -[ ### ###### ] -[ ### #### ] -[### ####] -[### ###] -[### ###] -[### ###] -[#### ####] -[ #### #### ] -[ ############## ] -[ ########### ] -[ ###### ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] - -#char : 57 '9' -[ ] -[ ] -[ ] -[ ###### ] -[ ########## ] -[ ############ ] -[ #### #### ] -[ ### ### ] -[### ### ] -[### ###] -[### ###] -[### ###] -[### ###] -[#### ###] -[ #### ####] -[ ##############] -[ #############] -[ ###### ###] -[ ### ] -[ ### ] -[ #### ] -[ ### ] -[ #### ] -[ #### ] -[ ###### ] -[ ######### ] -[ ####### ] -[ ##### ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] - -#char : 58 ':' -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ### ] -[#####] -[#####] -[#####] -[ ### ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ### ] -[#####] -[#####] -[#####] -[ ### ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] - -#char : 59 ';' -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ### ] -[#####] -[#####] -[#####] -[ ### ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ## ] -[ ## ] -[### ] -[## ] -[ # ] -[ ] - -#char : 60 '<' -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ # ] -[ ####] -[ ######] -[ ###### ] -[ ###### ] -[ ###### ] -[ ###### ] -[###### ] -[#### ] -[###### ] -[ ###### ] -[ ###### ] -[ ###### ] -[ ###### ] -[ ######] -[ ####] -[ # ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] - -#char : 61 '=' -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[################] -[################] -[################] -[ ] -[ ] -[ ] -[ ] -[ ] -[################] -[################] -[################] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] - -#char : 62 '>' -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ # ] -[#### ] -[###### ] -[ ####### ] -[ ####### ] -[ ####### ] -[ ###### ] -[ ######] -[ ####] -[ ######] -[ ###### ] -[ ####### ] -[ ####### ] -[ ####### ] -[###### ] -[#### ] -[ # ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] - -#char : 63 '?' -[ ] -[ ] -[ ] -[ ####### ] -[########### ] -[############ ] -[ ## #####] -[ ####] -[ ###] -[ ###] -[ ###] -[ ### ] -[ ### ] -[ #### ] -[ ### ] -[ #### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ] -[ ] -[ ] -[ # ] -[ ### ] -[ ### ] -[ ### ] -[ # ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] - -#char : 64 '@' -[ ] -[ ] -[ ] -[ ######### ] -[ ############## ] -[ ################## ] -[ ###### ####### ] -[ ##### ##### ] -[ #### #### ] -[ #### #### ] -[ ### ######### #### ] -[ #### ############ ### ] -[ ### ############# ### ] -[ ### ##### ### ###] -[### ### ### ###] -[### #### ### ###] -[### ### ### ###] -[### ### ### ###] -[### ### ### ###] -[### ### ### ###] -[### #### ### ### ] -[### ### ### ### ] -[ ### ##### ### #### ] -[ ### ################### ] -[ #### ################# ] -[ ### ####### ##### ] -[ #### ] -[ #### ] -[ ##### ] -[ ####### # ] -[ ################ ] -[ ############## ] -[ ########## ] -[ ] -[ ] - -#char : 65 'A' -[ ] -[ ] -[ ] -[ ### ] -[ ##### ] -[ ##### ] -[ ###### ] -[ ### ### ] -[ ### ### ] -[ #### ### ] -[ ### ### ] -[ ### #### ] -[ ### ### ] -[ ### #### ] -[ #### ### ] -[ ### ### ] -[ ### ### ] -[ ### ### ] -[ ### ### ] -[ ################# ] -[ ################## ] -[ ################## ] -[ ### #### ] -[ ### ### ] -[ #### ### ] -[ ### ### ] -[ ### ### ] -[### ###] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] - -#char : 66 'B' -[ ] -[ ] -[ ] -[ ########### ] -[############## ] -[################ ] -[### ##### ] -[### #### ] -[### ### ] -[### ### ] -[### ### ] -[### #### ] -[### ##### ] -[############### ] -[############## ] -[################ ] -[### ##### ] -[### ### ] -[### ###] -[### ###] -[### ###] -[### ###] -[### ####] -[### #### ] -[### ###### ] -[################ ] -[############### ] -[ ########### ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] - -#char : 67 'C' -[ ] -[ ] -[ ] -[ ######## ] -[ #############] -[ ###############] -[ ###### ### ] -[ ##### ] -[ ### ] -[ #### ] -[ ### ] -[ ### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[#### ] -[ ### ] -[ #### ] -[ ### ] -[ #### ] -[ ##### ## ] -[ ###############] -[ ##############] -[ ######## ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] - -#char : 68 'D' -[ ] -[ ] -[ ] -[ ########### ] -[############### ] -[################ ] -[### ####### ] -[### #### ] -[### #### ] -[### #### ] -[### ### ] -[### ### ] -[### ###] -[### ###] -[### ###] -[### ###] -[### ###] -[### ###] -[### ###] -[### ### ] -[### ### ] -[### #### ] -[### #### ] -[### #### ] -[### ####### ] -[################ ] -[############### ] -[ ########## ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] - -#char : 69 'E' -[ ] -[ ] -[ ] -[################ ] -[################ ] -[################ ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[############### ] -[############### ] -[############### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[#################] -[#################] -[#################] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] - -#char : 70 'F' -[ ] -[ ] -[ ] -[###############] -[###############] -[###############] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[############## ] -[############## ] -[############## ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] - -#char : 71 'G' -[ ] -[ ] -[ ] -[ ######## ] -[ #############] -[ ###############] -[ ##### ### ] -[ #### ] -[ ### ] -[ #### ] -[ ### ] -[#### ] -[### ] -[### ] -[### ] -[### ] -[### ###] -[### ###] -[### ###] -[#### ###] -[ ### ###] -[ #### ###] -[ ### ###] -[ #### ###] -[ ##### ###] -[ ###############] -[ ##############] -[ ######## ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] - -#char : 72 'H' -[ ] -[ ] -[ ] -[### ###] -[### ###] -[### ###] -[### ###] -[### ###] -[### ###] -[### ###] -[### ###] -[### ###] -[### ###] -[###################] -[###################] -[###################] -[### ###] -[### ###] -[### ###] -[### ###] -[### ###] -[### ###] -[### ###] -[### ###] -[### ###] -[### ###] -[### ###] -[### ###] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] - -#char : 73 'I' -[ ] -[ ] -[ ] -[###] -[###] -[###] -[###] -[###] -[###] -[###] -[###] -[###] -[###] -[###] -[###] -[###] -[###] -[###] -[###] -[###] -[###] -[###] -[###] -[###] -[###] -[###] -[###] -[###] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] - -#char : 74 'J' -[ ] -[ ] -[ ] -[ ###] -[ ###] -[ ###] -[ ###] -[ ###] -[ ###] -[ ###] -[ ###] -[ ###] -[ ###] -[ ###] -[ ###] -[ ###] -[ ###] -[ ###] -[ ###] -[ ###] -[ ###] -[ ###] -[ ####] -[ # ### ] -[ ### #### ] -[############# ] -[ ########### ] -[ ####### ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] - -#char : 75 'K' -[ ] -[ ] -[ ] -[### #### ] -[### #### ] -[### #### ] -[### #### ] -[### #### ] -[### #### ] -[### #### ] -[### #### ] -[### #### ] -[### #### ] -[### #### ] -[###### ] -[######## ] -[### ##### ] -[### ##### ] -[### #### ] -[### #### ] -[### ##### ] -[### ##### ] -[### ##### ] -[### ##### ] -[### #### ] -[### #### ] -[### #### ] -[### ####] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] - -#char : 76 'L' -[ ] -[ ] -[ ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[###############] -[###############] -[###############] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] - -#char : 77 'M' -[ ] -[ ] -[ ] -[ ### ### ] -[ #### #### ] -[ #### #### ] -[ ##### ##### ] -[ ###### ##### ] -[ ####### ####### ] -[ ####### ####### ] -[ ### #### #### ### ] -[ ### ### ### ### ] -[ ### #### #### ### ] -[ ### ### ### ### ] -[ ### ### ### ### ] -[ ### ### ### ### ] -[ ### ### ### ### ] -[ ### ### ### ### ] -[ ### ### ### ### ] -[#### ## ## ### ] -[### ### ### ###] -[### ## ### ###] -[### ##### ###] -[### ##### ###] -[### ### ###] -[### ###] -[### ###] -[### ###] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] - -#char : 78 'N' -[ ] -[ ] -[ ] -[### ###] -[#### ###] -[##### ###] -[###### ###] -[###### ###] -[####### ###] -[### #### ###] -[### #### ###] -[### #### ###] -[### #### ###] -[### #### ###] -[### #### ###] -[### #### ###] -[### #### ###] -[### ### ###] -[### ### ###] -[### #### ###] -[### ### ###] -[### ######] -[### #####] -[### #####] -[### ####] -[### ###] -[### ###] -[### ##] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] - -#char : 79 'O' -[ ] -[ ] -[ ] -[ ######## ] -[ ############ ] -[ ################ ] -[ ###### ###### ] -[ ##### ##### ] -[ #### #### ] -[ #### #### ] -[ ### ### ] -[ ### ####] -[### ###] -[### ###] -[### ###] -[### ###] -[### ###] -[### ###] -[### ###] -[ ### ####] -[ ### ### ] -[ #### #### ] -[ #### #### ] -[ ##### ##### ] -[ ###### ###### ] -[ ################ ] -[ ############ ] -[ ######## ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] - -#char : 80 'P' -[ ] -[ ] -[ ] -[ ########### ] -[############## ] -[################ ] -[### ###### ] -[### #### ] -[### ####] -[### ###] -[### ###] -[### ###] -[### ###] -[### ####] -[### #### ] -[### ###### ] -[################ ] -[############## ] -[########### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] - -#char : 81 'Q' -[ ] -[ ] -[ ] -[ ######## ] -[ ############ ] -[ ################ ] -[ ###### ###### ] -[ ##### ##### ] -[ #### #### ] -[ #### #### ] -[ ### ### ] -[ ### ####] -[### ###] -[### ###] -[### ###] -[### ###] -[### ###] -[### ###] -[### ###] -[#### ### ] -[ ### ### ] -[ #### #### ] -[ #### #### ] -[ ##### #### ] -[ ###### ###### ] -[ ############### ] -[ ############ ] -[ ####### ] -[ ### ] -[ #### ] -[ #### ] -[ ###### ] -[ ######## ] -[ ##### ] -[ ## ] - -#char : 82 'R' -[ ] -[ ] -[ ] -[ ########## ] -[############## ] -[############### ] -[### ##### ] -[### ### ] -[### ### ] -[### ### ] -[### ### ] -[### ### ] -[### ### ] -[### ### ] -[### ##### ] -[############### ] -[############## ] -[############ ] -[### #### ] -[### #### ] -[### ### ] -[### #### ] -[### #### ] -[### ### ] -[### #### ] -[### ### ] -[### #### ] -[### ####] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] - -#char : 83 'S' -[ ] -[ ] -[ ] -[ ####### ] -[ ############ ] -[ ############## ] -[ #### ## ] -[ #### ] -[ ### ] -[ ### ] -[ ### ] -[ #### ] -[ #### ] -[ ###### ] -[ ####### ] -[ ######## ] -[ ####### ] -[ ###### ] -[ #### ] -[ ####] -[ ###] -[ ###] -[ ###] -[ ####] -[ ### #### ] -[################ ] -[ ############# ] -[ ######## ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] - -#char : 84 'T' -[ ] -[ ] -[ ] -[###################] -[###################] -[###################] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] - -#char : 85 'U' -[ ] -[ ] -[ ] -[### ###] -[### ###] -[### ###] -[### ###] -[### ###] -[### ###] -[### ###] -[### ###] -[### ###] -[### ###] -[### ###] -[### ###] -[### ###] -[### ###] -[### ###] -[### ###] -[### ###] -[### ###] -[#### ####] -[ ### ### ] -[ #### #### ] -[ ##### ##### ] -[ ############# ] -[ ########### ] -[ ####### ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] - -#char : 86 'V' -[ ] -[ ] -[ ] -[### ###] -[ ### ### ] -[ ### ### ] -[ ### ### ] -[ ### ### ] -[ ### ### ] -[ #### #### ] -[ ### ### ] -[ ### ### ] -[ #### #### ] -[ ### ### ] -[ #### #### ] -[ ### ### ] -[ ### ### ] -[ #### #### ] -[ ### ### ] -[ #### #### ] -[ ### ### ] -[ ### ### ] -[ ### ### ] -[ ### ### ] -[ ####### ] -[ ##### ] -[ ##### ] -[ ### ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] - -#char : 87 'W' -[ ] -[ ] -[ ] -[### ###] -[### ###] -[#### ####] -[ ### ### ### ] -[ ### #### ### ] -[ ### #### ### ] -[ #### ##### ### ] -[ ### ##### ### ] -[ ### ### ### #### ] -[ ### ### ### ### ] -[ #### ### #### ### ] -[ #### ### ### ### ] -[ ### ### ### #### ] -[ ### #### #### #### ] -[ #### ### ### ### ] -[ ### ### ### ### ] -[ ### ### #### ### ] -[ ### ### ### #### ] -[ #### #### #### ### ] -[ ### ### ### ### ] -[ ### ### ### ### ] -[ ###### ####### ] -[ ##### ##### ] -[ ##### ##### ] -[ #### #### ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] - -#char : 88 'X' -[ ] -[ ] -[ ] -[#### #### ] -[ ### ### ] -[ ### ### ] -[ #### #### ] -[ #### ### ] -[ ### ### ] -[ #### #### ] -[ #### ### ] -[ ### ### ] -[ ####### ] -[ ###### ] -[ #### ] -[ #### ] -[ ##### ] -[ ####### ] -[ #### ### ] -[ #### ### ] -[ ### #### ] -[ #### #### ] -[ #### ### ] -[ ### ### ] -[ #### #### ] -[ #### ### ] -[ ### ### ] -[#### ####] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] - -#char : 89 'Y' -[ ] -[ ] -[ ] -[#### ####] -[ ### ### ] -[ #### #### ] -[ ### ### ] -[ ### ### ] -[ ### ### ] -[ ### ### ] -[ #### #### ] -[ ### ### ] -[ ### ### ] -[ #### #### ] -[ ### ### ] -[ ####### ] -[ ##### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] - -#char : 90 'Z' -[ ] -[ ] -[ ] -[ ##################] -[ ##################] -[ ##################] -[ ####] -[ #### ] -[ #### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ #### ] -[ #### ] -[ ### ] -[ ### ] -[ ### ] -[ #### ] -[ ### ] -[ ### ] -[ #### ] -[ ### ] -[ ### ] -[ #### ] -[###################] -[###################] -[###################] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] - -#char : 91 '[' -[#########] -[#########] -[#########] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[#########] -[#########] -[#########] - -#char : 92 '\' -[## ] -[### ] -[### ] -[### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ #### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ###] -[ ###] -[ ###] -[ ##] - -#char : 93 ']' -[#########] -[#########] -[#########] -[ ###] -[ ###] -[ ###] -[ ###] -[ ###] -[ ###] -[ ###] -[ ###] -[ ###] -[ ###] -[ ###] -[ ###] -[ ###] -[ ###] -[ ###] -[ ###] -[ ###] -[ ###] -[ ###] -[ ###] -[ ###] -[ ###] -[ ###] -[ ###] -[ ###] -[ ###] -[ ###] -[ ###] -[ ###] -[#########] -[#########] -[#########] - -#char : 94 '^' -[ ] -[ ] -[ ] -[ ### ] -[ ##### ] -[ ##### ] -[ ### ### ] -[ #### #### ] -[ ### ### ] -[ #### #### ] -[ ### ### ] -[ #### #### ] -[ ### ### ] -[ #### #### ] -[ ### ### ] -[#### ####] -[ # # ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] - -#char : 95 '_' -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[##################] -[##################] -[##################] - -#char : 96 '`' -[ # ] -[### ] -[#### ] -[ #### ] -[ ####] -[ ###] -[ # ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] - -#char : 97 'a' -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ####### ] -[ ########## ] -[ ########### ] -[ # #### ] -[ ####] -[ ###] -[ ###] -[ ##########] -[ ############] -[ #############] -[##### ###] -[### ###] -[### ###] -[### ###] -[### ###] -[##### ###] -[ #############] -[ ############] -[ ######### ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] - -#char : 98 'b' -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ###### ] -[############# ] -[############## ] -[##### #### ] -[### #### ] -[### ### ] -[### ###] -[### ###] -[### ###] -[### ###] -[### ###] -[### ###] -[### ####] -[### ### ] -[### #### ] -[### #### ] -[############# ] -[############ ] -[ ######## ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] - -#char : 99 'c' -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ####### ] -[ ##########] -[ ###########] -[ #### # ] -[ #### ] -[ ### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[ ### ] -[ #### ] -[ #### #] -[ ############] -[ ##########] -[ ####### ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] - -#char : 100 'd' -[ ###] -[ ###] -[ ###] -[ ###] -[ ###] -[ ###] -[ ###] -[ ###] -[ ###] -[ ###### ###] -[ #############] -[ ##############] -[ #### #####] -[ #### ###] -[ ### ###] -[### ###] -[### ###] -[### ###] -[### ###] -[### ###] -[### ###] -[#### ###] -[ ### ###] -[ #### ###] -[ #### ###] -[ #############] -[ ############] -[ ######## ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] - -#char : 101 'e' -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ##### ] -[ ######### ] -[ ############ ] -[ #### #### ] -[ ### ### ] -[ ### ###] -[### ###] -[################] -[################] -[################] -[### ] -[### ] -[#### ] -[ ### ] -[ #### ] -[ #### ## ] -[ ############# ] -[ ########### ] -[ ####### ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] - -#char : 102 'f' -[ #######] -[ #########] -[ ##########] -[ #### ] -[#### ] -[### ] -[### ] -[### ] -[### ] -[########## ] -[########## ] -[########## ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] - -#char : 103 'g' -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ######## ] -[ ############] -[ ##############] -[ #### ###] -[ #### ###] -[ ### ###] -[### ###] -[### ###] -[### ###] -[### ###] -[### ###] -[### ###] -[#### ###] -[ #### ###] -[ ##### #####] -[ ##############] -[ #############] -[ ###### ###] -[ ###] -[ ###] -[ ####] -[ ### ] -[ # ##### ] -[ ############# ] -[ ############ ] -[ ######## ] - -#char : 104 'h' -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ####### ] -[############ ] -[############# ] -[### #### ] -[### ### ] -[### ###] -[### ###] -[### ###] -[### ###] -[### ###] -[### ###] -[### ###] -[### ###] -[### ###] -[### ###] -[### ###] -[### ###] -[### ###] -[### ###] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] - -#char : 105 'i' -[ ] -[###] -[###] -[###] -[###] -[ ] -[ ] -[ ] -[ ] -[###] -[###] -[###] -[###] -[###] -[###] -[###] -[###] -[###] -[###] -[###] -[###] -[###] -[###] -[###] -[###] -[###] -[###] -[###] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] - -#char : 106 'j' -[ ] -[ ###] -[ ###] -[ ###] -[ ###] -[ ] -[ ] -[ ] -[ ] -[ ###] -[ ###] -[ ###] -[ ###] -[ ###] -[ ###] -[ ###] -[ ###] -[ ###] -[ ###] -[ ###] -[ ###] -[ ###] -[ ###] -[ ###] -[ ###] -[ ###] -[ ###] -[ ###] -[ ###] -[ ###] -[ ###] -[ ### ] -[##### ] -[#### ] -[### ] - -#char : 107 'k' -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### #### ] -[### #### ] -[### #### ] -[### #### ] -[### #### ] -[### #### ] -[### #### ] -[####### ] -[###### ] -[####### ] -[### #### ] -[### #### ] -[### #### ] -[### #### ] -[### #### ] -[### #### ] -[### #### ] -[### #### ] -[### ####] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] - -#char : 108 'l' -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[#### ] -[######] -[ #####] -[ ###] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] - -#char : 109 'm' -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ######## ###### ] -[############ ########## ] -[######################## ] -[### ###### #### ] -[### ### ####] -[### ### ###] -[### ### ###] -[### ### ###] -[### ### ###] -[### ### ###] -[### ### ###] -[### ### ###] -[### ### ###] -[### ### ###] -[### ### ###] -[### ### ###] -[### ### ###] -[### ### ###] -[### ### ###] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] - -#char : 110 'n' -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ######### ] -[############# ] -[############# ] -[### #### ] -[### ### ] -[### ###] -[### ###] -[### ###] -[### ###] -[### ###] -[### ###] -[### ###] -[### ###] -[### ###] -[### ###] -[### ###] -[### ###] -[### ###] -[### ###] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] - -#char : 111 'o' -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ##### ] -[ ######### ] -[ ############# ] -[ #### #### ] -[ #### #### ] -[ ### ### ] -[### ###] -[### ###] -[### ###] -[### ###] -[### ###] -[### ###] -[### ###] -[ ### ### ] -[ #### #### ] -[ #### #### ] -[ ############# ] -[ ######### ] -[ ##### ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] - -#char : 112 'p' -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ######## ] -[############ ] -[############# ] -[### #### ] -[### #### ] -[### ### ] -[### ####] -[### ###] -[### ###] -[### ###] -[### ###] -[### ###] -[### ###] -[### ### ] -[### #### ] -[##### #### ] -[############## ] -[############# ] -[### ###### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] - -#char : 113 'q' -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ######## ] -[ ############] -[ #############] -[ #### ###] -[ #### ###] -[ ### ###] -[#### ###] -[### ###] -[### ###] -[### ###] -[### ###] -[### ###] -[### ###] -[ ### ###] -[ #### ###] -[ #### #####] -[ ##############] -[ #############] -[ ###### ###] -[ ###] -[ ###] -[ ###] -[ ###] -[ ###] -[ ###] -[ ###] - -#char : 114 'r' -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ #########] -[###########] -[###########] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] - -#char : 115 's' -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ####### ] -[ ########## ] -[ ########### ] -[#### # ] -[### ] -[### ] -[#### ] -[ #### ] -[ ####### ] -[ ######## ] -[ ####### ] -[ #####] -[ ####] -[ ###] -[ ###] -[ # ####] -[############ ] -[########### ] -[ ####### ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] - -#char : 116 't' -[ ] -[ ] -[ ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[######### ] -[######### ] -[######### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[### ] -[#### ] -[ #########] -[ ########] -[ ###### ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] - -#char : 117 'u' -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[### ###] -[### ###] -[### ###] -[### ###] -[### ###] -[### ###] -[### ###] -[### ###] -[### ###] -[### ###] -[### ###] -[### ###] -[### ###] -[#### ###] -[ ### ###] -[ #### ###] -[ #############] -[ ############] -[ ######### ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] - -#char : 118 'v' -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[### ###] -[#### ####] -[ ### ### ] -[ ### ### ] -[ #### #### ] -[ ### ### ] -[ ### ### ] -[ #### #### ] -[ ### ### ] -[ ### ### ] -[ #### #### ] -[ ### ### ] -[ #### #### ] -[ ### ### ] -[ ####### ] -[ ####### ] -[ ##### ] -[ ##### ] -[ ### ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] - -#char : 119 'w' -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[### ### ###] -[### ### ###] -[ ### ##### ### ] -[ ### ##### ### ] -[ ### ##### ### ] -[ ### ##### #### ] -[ ### ### ### ### ] -[ ### ### ### ### ] -[ ### ### ### ### ] -[ ### ### #### ### ] -[ ### ### ### ### ] -[ ### ### ### ### ] -[ ### #### #### ### ] -[ ### ### ### ### ] -[ ### ### ### ### ] -[ ##### ###### ] -[ ##### ##### ] -[ ##### ##### ] -[ ### #### ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] - -#char : 120 'x' -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[#### #### ] -[ ### ### ] -[ ### ### ] -[ #### #### ] -[ ### ### ] -[ ### #### ] -[ ####### ] -[ ##### ] -[ ##### ] -[ #### ] -[ ##### ] -[ ####### ] -[ ### #### ] -[ #### #### ] -[ #### ### ] -[ ### #### ] -[ #### #### ] -[ ### ### ] -[#### ####] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] - -#char : 121 'y' -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ### ###] -[ ### ####] -[ ### ### ] -[ ### ### ] -[ ### ### ] -[ ### ### ] -[ ### ### ] -[ ### ### ] -[ ### ### ] -[ ### ### ] -[ ### ### ] -[ ### ### ] -[ ### ### ] -[ ### ### ] -[ ### ## ] -[ ###### ] -[ ##### ] -[ #### ] -[ #### ] -[ ### ] -[ #### ] -[ ### ] -[ #### ] -[######### ] -[######## ] -[###### ] - -#char : 122 'z' -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ##############] -[ ##############] -[ ##############] -[ ####] -[ #### ] -[ #### ] -[ #### ] -[ #### ] -[ #### ] -[ ### ] -[ ### ] -[ #### ] -[ #### ] -[ #### ] -[ ### ] -[ #### ] -[###############] -[###############] -[###############] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] - -#char : 123 '{' -[ ####] -[ #####] -[ ######] -[ #### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[##### ] -[#### ] -[##### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ #### ] -[ ######] -[ #####] -[ ####] - -#char : 124 '|' -[###] -[###] -[###] -[###] -[###] -[###] -[###] -[###] -[###] -[###] -[###] -[###] -[###] -[###] -[###] -[###] -[###] -[###] -[###] -[###] -[###] -[###] -[###] -[###] -[###] -[###] -[###] -[###] -[###] -[###] -[###] -[###] -[###] -[###] -[###] - -#char : 125 '}' -[#### ] -[##### ] -[###### ] -[ #### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ #####] -[ ####] -[ #####] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ ### ] -[ #### ] -[###### ] -[##### ] -[#### ] - -#char : 126 '~' -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ #### ## ] -[ ###### ###] -[ ######### ####] -[ ### ######### ] -[### ###### ] -[ ## #### ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] - -#char : 127 -[ ] -[##############] -[##############] -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[## ##] -[##############] -[##############] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] -[ ] diff --git a/src/modm/ui/display/graphic_display.cpp b/src/modm/ui/display/graphic_display.cpp deleted file mode 100644 index 1c5727e66e..0000000000 --- a/src/modm/ui/display/graphic_display.cpp +++ /dev/null @@ -1,292 +0,0 @@ -/* - * Copyright (c) 2009, Martin Rosekeit - * Copyright (c) 2009-2011, 2013, Fabian Greif - * Copyright (c) 2010, Georgi Grinshpun - * Copyright (c) 2012, Sascha Schade - * Copyright (c) 2012-2014, 2017, Niklas Hauser - * Copyright (c) 2014, Daniel Krebs - * Copyright (c) 2016, Antal Szabó - * Copyright (c) 2017, Christopher Durand - * - * 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 "graphic_display.hpp" - -#include -#include - -#include "font/fixed_width_5x8.hpp" - -// ---------------------------------------------------------------------------- -modm::GraphicDisplay::GraphicDisplay() - : IOStream(writer), writer(this), font(modm::accessor::asFlash(modm::font::FixedWidth5x8)) -{} - -// ---------------------------------------------------------------------------- -void -modm::GraphicDisplay::drawLine(int16_t x1, int16_t y1, int16_t x2, int16_t y2) -{ - if (x1 == x2) - { - // x1|y1 must be the upper point - if (y1 > y2) { modm::swap(y1, y2); } - this->drawVerticalLine(glcd::Point(x1, y1), y2 - y1 + 1); - } else if (y1 == y2) - { - // x1|y1 must be the left point - if (x1 > x2) { modm::swap(x1, x2); } - this->drawHorizontalLine(glcd::Point(x1, y1), x2 - x1 + 1); - } else - { - // bresenham algorithm - bool steep = abs(y2 - y1) > abs(x2 - x1); - if (steep) - { - modm::swap(x1, y1); - modm::swap(x2, y2); - } - - if (x1 > x2) - { - modm::swap(x1, x2); - modm::swap(y1, y2); - } - - int16_t deltaX = x2 - x1; - int16_t deltaY = abs(y2 - y1); - int16_t error = deltaX / 2; - - int16_t yStep; - int16_t y = y1; - - if (y1 < y2) - yStep = 1; - else - yStep = -1; - - for (int_fast16_t x = x1; x <= x2; ++x) - { - if (steep) - this->setPixel(y, x); - else - this->setPixel(x, y); - - error = error - deltaY; - - if (error < 0) - { - y += yStep; - error += deltaX; - } - } - } -} - -void -modm::GraphicDisplay::drawHorizontalLine(glcd::Point start, uint16_t length) -{ - for (int_fast16_t i = start.x; i < static_cast(start.x + length); ++i) - { - this->setPixel(i, start.y); - } -} - -void -modm::GraphicDisplay::drawVerticalLine(glcd::Point start, uint16_t length) -{ - for (int_fast16_t i = start.y; i < static_cast(start.y + length); ++i) - { - this->setPixel(start.x, i); - } -} - -void -modm::GraphicDisplay::drawRectangle(glcd::Point start, uint16_t width, uint16_t height) -{ - uint16_t x2 = start.x + width - 1; - uint16_t y2 = start.y + height - 1; - - this->drawHorizontalLine(start, width); - this->drawHorizontalLine(glcd::Point(start.x, y2), width); - this->drawVerticalLine(start, height); - this->drawVerticalLine(glcd::Point(x2, start.y), height); -} - -void -modm::GraphicDisplay::drawRoundedRectangle(glcd::Point start, uint16_t width, uint16_t height, - uint16_t radius) -{ - if (radius == 0) { this->drawRectangle(start, width, height); } - - const int16_t x = start.x; - const int16_t y = start.y; - - int16_t x1 = 0; - int16_t y1 = radius; - int16_t f = 3 - 2 * radius; - - while (x1 <= y1) - { - this->setPixel(x + radius - x1, y + radius - y1); - this->setPixel(x + radius - x1, y + height - radius + y1); - this->setPixel(x + radius - y1, y + radius - x1); - this->setPixel(x + radius - y1, y + height - radius + x1); - - this->setPixel(x + width - radius + x1, y + radius - y1); - this->setPixel(x + width - radius + x1, y + height - radius + y1); - this->setPixel(x + width - radius + y1, y + radius - x1); - this->setPixel(x + width - radius + y1, y + height - radius + x1); - - if (f < 0) - { - f += (4 * x1 + 6); - } else - { - f += (4 * (x1 - y1) + 10); - y1--; - } - x1++; - } - - this->drawHorizontalLine(glcd::Point(x + radius, y), width - (2 * radius)); - this->drawHorizontalLine(glcd::Point(x + radius, y + height), width - (2 * radius)); - this->drawVerticalLine(glcd::Point(x, y + radius), height - (2 * radius)); - this->drawVerticalLine(glcd::Point(x + width, y + radius), height - (2 * radius)); -} - -void -modm::GraphicDisplay::drawCircle(glcd::Point center, uint16_t radius) -{ - if (radius == 0) { return; } - - int16_t error = -radius; - int16_t x = radius; - int16_t y = 0; - - while (x > y) - { - this->drawCircle4(center, x, y); - this->drawCircle4(center, y, x); - - error += y; - ++y; - error += y; - - if (error >= 0) - { - --x; - error -= x; - error -= x; - } - } - this->drawCircle4(center, x, y); -} - -void -modm::GraphicDisplay::drawCircle4(glcd::Point center, int16_t x, int16_t y) -{ - const int16_t cx = center.x; - const int16_t cy = center.y; - - this->setPixel(cx + x, cy + y); - this->setPixel(cx - x, cy - y); - if (x != 0) { this->setPixel(cx - x, cy + y); } - if (y != 0) { this->setPixel(cx + x, cy - y); } -} - -void -modm::GraphicDisplay::drawEllipse(glcd::Point center, int16_t rx, int16_t ry) -{ - int32_t rx_2 = rx * rx; - int32_t ry_2 = ry * ry; - - int16_t x = 0; - int16_t y = ry; - - int32_t fx = 0; - int32_t fy = rx_2 * 2 * ry; - - int32_t p = ry_2 - (rx_2 * ry) + (rx_2 + 2) / 4; - - drawCircle4(center, x, y); - while (fx < fy) - { - x++; - fx += ry_2 * 2; - - if (p < 0) - { - p += (fx + ry_2); - } else - { - y--; - fy -= rx_2 * 2; - p += (fx + ry_2 - fy); - } - - drawCircle4(center, x, y); - } - - p = ((ry_2 * (4 * x * x + 4 * x + 1) / 2) + 2 * (rx_2 * (y - 1) * (y - 1)) - 2 * (rx_2 * ry_2) + - 1) / - 2; - - while (y > 0) - { - y--; - fy -= rx_2 * 2; - - if (p >= 0) - { - p += (rx_2 - fy); - } else - { - x++; - fx += ry_2 * 2; - p += (fx + rx_2 - fy); - } - - drawCircle4(center, x, y); - } -} - -// ---------------------------------------------------------------------------- -void -modm::GraphicDisplay::drawImage(glcd::Point start, modm::accessor::Flash image) -{ - uint8_t width = image[0]; - uint8_t height = image[1]; - - drawImageRaw(start, width, height, modm::accessor::Flash(image.getPointer() + 2)); -} - -void -modm::GraphicDisplay::drawImageRaw(glcd::Point start, uint16_t width, uint16_t height, - modm::accessor::Flash data) -{ - uint16_t rows = (height + 7) / 8; - for (uint16_t i = 0; i < width; i++) - { - for (uint16_t k = 0; k < rows; k++) - { - uint16_t byte = data[i + k * width]; - uint16_t rowHeight = height - k * 8; - if (rowHeight > 8) { rowHeight = 8; } - for (uint16_t j = 0; j < rowHeight; j++) - { - if (byte & 0x01) - this->setPixel(start.x + i, start.y + k * 8 + j); - else - this->clearPixel(start.x + i, start.y + k * 8 + j); - - byte >>= 1; - } - } - } -} diff --git a/src/modm/ui/display/graphic_display.hpp b/src/modm/ui/display/graphic_display.hpp deleted file mode 100644 index a1c708f21c..0000000000 --- a/src/modm/ui/display/graphic_display.hpp +++ /dev/null @@ -1,459 +0,0 @@ -/* - * Copyright (c) 2009-2010, Martin Rosekeit - * Copyright (c) 2009-2011, 2013, Fabian Greif - * Copyright (c) 2011, 2013, Thorsten Lajewski - * Copyright (c) 2012-2014, 2016, Niklas Hauser - * Copyright (c) 2013, Hans Schily - * Copyright (c) 2014, Daniel Krebs - * Copyright (c) 2015, Niclas Rohrer - * Copyright (c) 2021, Thomas Sommer - * - * 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_GRAPHIC_DISPLAY_HPP -#define MODM_GRAPHIC_DISPLAY_HPP - -#include -#include -#include -#include - -#include -#include "font.hpp" - -namespace modm -{ - -/// @ingroup modm_ui_display -namespace glcd -{ - -/// @ingroup modm_ui_display -using Point = Vector; - -enum Orientation : uint8_t -{ - Landscape0, - Portrait90, - Landscape180, - Portrait270, -}; - -} // namespace glcd - -/** - * Base class for graphical displays. - * - * \ingroup modm_ui_display - */ - -/* - * - * Text mode: - * - left adjusted (default) - * - right adjusted - * - centered - * - * All modes relative to the current viewport. This would make - * drawing a menu system easier. - */ -class GraphicDisplay : public IOStream -{ -public: - friend class VirtualGraphicDisplay; - - GraphicDisplay(); - - virtual ~GraphicDisplay() {} - - /** - * Number of pixel in horizontal direction. - */ - virtual uint16_t - getWidth() const = 0; - - /** - * Number of pixel in vertical direction. - */ - virtual uint16_t - getHeight() const = 0; - - // TODO Requires all inherited drivers work with resumable functions - // virtual modm::ResumableResult - // setOrientation() = 0; - - /** - * Buffer-array size of first dimension - */ - virtual std::size_t - getBufferWidth() const = 0; - - /** - * Buffer-array size of second dimension - */ - virtual std::size_t - getBufferHeight() const = 0; - - /** - * Set a pixel to foregroundColor - * - * \param x x-position - * \param y y-position - */ - virtual void - setPixel(int16_t x, int16_t y) = 0; - - /** - * Set a pixel to foregroundColor - * - * \param p point - */ - inline void - setPixel(glcd::Point p) - { - this->setPixel(p.x, p.y); - } - - /** - * Set a pixel to backgroundColor - * - * \param x x-position - * \param y y-position - */ - virtual void - clearPixel(int16_t x, int16_t y) = 0; - - /** - * Set a pixel to backgroundColor - * - * \param p point - */ - inline void - clearPixel(glcd::Point p) - { - this->setPixel(p.x, p.y); - } - - /** - * Set whole screen to backgroundColor - */ - virtual void - clear() = 0; - - /** - * Transfer the content of the RAM buffer to the real display. - */ - virtual void - update() = 0; - - // TODO Requires all inherited drivers work with resumable functions - // modm::ResumableResult - // writeDisplay(); - - // TODO Set a clipping area - // Everything drawn outside this area will be discarded. - // inline void - // setClippingWindow(glcd::Point start, glcd::Point end); - - /** - * Draw a line. - * - * Uses the faster drawHorizontalLine() or drawVerticalLine() if - * possible, otherwise the line is rastered with the Bresenham line - * algorithm. - * - * \param start first point - * \param end second point - */ - inline void - drawLine(glcd::Point start, glcd::Point end) - { - this->drawLine(start.x, start.y, end.x, end.y); - } - - /** - * Draw a line - * - * \param x1 Start x-position - * \param y1 Start y-position - * \param x2 End x-position - * \param y3 End y-position - */ - void - drawLine(int16_t x1, int16_t y1, int16_t x2, int16_t y2); - - /** - * Draw a rectangle. - * - * \param start Upper left corner - * \param width Width of rectangle - * \param height Height of rectangle - */ - void - drawRectangle(glcd::Point start, uint16_t width, uint16_t height); - - /** - * Draw a rectangle. - * - * \param x Upper left corner x-position - * \param y Upper left corner y-position - * \param width Width of rectangle - * \param height Height of rectangle - */ - inline void - drawRectangle(int16_t x, int16_t y, uint16_t width, uint16_t height) - { - drawRectangle(glcd::Point(x, y), width, height); - } - - /** - * Draw a filled rectangle. - * - * \param start Upper left corner - * \param width Width of rectangle - * \param height Height of rectangle - */ - void - fillRectangle(glcd::Point start, uint16_t width, uint16_t height); - - /** - * Draw a rectangle. - * - * \param x Upper left corner x-position - * \param y Upper left corner y-position - * \param width Width of rectangle - * \param height Height of rectangle - */ - inline void - fillRectangle(int16_t x, int16_t y, uint16_t width, uint16_t height) - { - fillRectangle(glcd::Point(x, y), width, height); - } - - /** - * Draw a rectangle with rounded corners - * - * \param start Upper left corner - * \param width Width of rectangle - * \param height Height of rectangle - * \param radius Rounding radius - */ - void - drawRoundedRectangle(glcd::Point start, uint16_t width, uint16_t height, uint16_t radius); - - /** - * Draw a filled rectangle with rounded corners - * - * \param start Upper left corner - * \param width Width of rectangle - * \param height Height of rectangle - * \param radius Rounding radius - */ - // TODO Not yet implemented - // void - // fillRoundedRectangle(glcd::Point start, uint16_t width, uint16_t height, uint16_t radius); - - /** - * Draw a circle - * - * Uses the midpoint circle algorithm. - * - * \param center Center of the circle - * \param radius Radius of the circle - */ - void - drawCircle(glcd::Point center, uint16_t radius); - - /** - * Draw a filled circle. - * - * \param center Center of the circle - * \param radius Radius of the circle - */ - virtual void - fillCircle(glcd::Point center, uint16_t radius); - - /** - * Draw an ellipse. - * - * Uses a variation of the midpoint algorithm. May be improved through - * simplification of the used formula. - * - * \param center Center of the ellipse - * \param rx Radius in x-direction - * \param ry Radius in y-direction - */ - void - drawEllipse(glcd::Point center, int16_t rx, int16_t ry); - - /** - * Draw an image. - * - * The first byte in the image data specifies the with, the second - * byte the height. Afterwards the actual image data. - * - * \param start Upper left corner - * \param image Image data in Flash - * - * \see drawImage() - */ - void - drawImage(glcd::Point start, modm::accessor::Flash image); - - /** - * Draw an image. - * - * \param start Upper left corner - * \param width Image width - * \param height Image height - * \param data Image data in Flash without any size information. - */ - virtual void - drawImageRaw(glcd::Point start, uint16_t width, uint16_t height, - modm::accessor::Flash data); - - /** - * Set the cursor for text drawing. - * - * \param position Cursor position - */ - inline void - setCursor(glcd::Point position) - { - this->cursor = position; - } - - /** - * Set the cursor for text drawing. - * - * \param x Cursor x-position - * \param y Cursor y-position - */ - inline void - setCursor(int16_t x, int16_t y) - { - this->cursor = glcd::Point(x, y); - } - - /** - * Set the cursor x-position for text drawing. - * - * \param x Cursor x-position - */ - inline void - setCursorX(int16_t x) - { - this->cursor.x = x; - } - - /** - * Set the cursor y-position for text drawing. - * - * \param y Cursor y-position - */ - inline void - setCursorY(int16_t y) - { - this->cursor.y = y; - } - - inline glcd::Point - getCursor() const - { - return this->cursor; - } - - /** - * Set a new font. - * - * Default font is modm::font::FixedWidth5x8. - * - * \param newFont Active font - * \see modm::font - */ - inline void - setFont(const uint8_t *newFont) - { - this->font = modm::accessor::asFlash(newFont); - } - - inline void - setFont(const modm::accessor::Flash *font) - { - this->font = *font; - } - - /** - * Get the height of a character. - */ - uint8_t - getFontHeight() const; - - static uint8_t - getFontHeight(const modm::accessor::Flash *font); - - /** - * Get the width of (null terminated) string. - */ - uint16_t - getStringWidth(const char *s) const; - - static uint16_t - getStringWidth(const char *s, const modm::accessor::Flash *font); - - /** - * Write a single character. - */ - void - write(char c); - -protected: - /// helper method for drawCircle() and drawEllipse() - void - drawCircle4(glcd::Point center, int16_t x, int16_t y); - - virtual void - drawHorizontalLine(glcd::Point start, uint16_t length); - - virtual void - drawVerticalLine(glcd::Point start, uint16_t length); - -protected: - // Interface class for the IOStream - class Writer : public IODevice - { - public: - Writer(GraphicDisplay *parent) : parent(parent) {} - - /// Draw a single character - virtual void - write(char c); - - using IODevice::write; - - // unused - virtual void - flush(); - - // unused, returns always `false` - virtual bool - read(char &c); - - private: - GraphicDisplay *parent; - }; - -protected: - Writer writer; - modm::accessor::Flash font; - glcd::Point cursor; -}; -} // namespace modm - -#endif // MODM_GRAPHIC_DISPLAY_HPP diff --git a/src/modm/ui/display/graphic_display_fill.cpp b/src/modm/ui/display/graphic_display_fill.cpp deleted file mode 100644 index 389f8e8564..0000000000 --- a/src/modm/ui/display/graphic_display_fill.cpp +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (c) 2010-2011, 2013, Fabian Greif - * Copyright (c) 2012-2013, Niklas Hauser - * Copyright (c) 2013, Hans Schily - * Copyright (c) 2013, Thorsten Lajewski - * - * 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 "graphic_display.hpp" - -// ---------------------------------------------------------------------------- -void -modm::GraphicDisplay::fillRectangle(glcd::Point start, - uint16_t width, uint16_t height) -{ - for (uint16_t i = start.x; (i < start.x + width) && (i < getWidth()); ++i) - for (uint16_t k = start.y; (k < start.y + height) && (k < getHeight()); ++k) - this->setPixel(i, k); -} - -void -modm::GraphicDisplay::fillCircle(glcd::Point center, uint16_t radius) -{ - int16_t f = 1 - radius; - int16_t ddF_x = 0; - int16_t ddF_y = -2 * radius; - uint16_t x = 0; - uint16_t y = radius; - - this->drawVerticalLine(glcd::Point(center.x, center.y - radius), 2 * radius); - - while(x < y) - { - if (f >= 0) - { - y--; - ddF_y += 2; - f += ddF_y; - } - x++; - ddF_x += 2; - f += ddF_x + 1; - - this->drawVerticalLine(glcd::Point(center.x + x, center.y - y), 2 * y); - this->drawVerticalLine(glcd::Point(center.x + y, center.y - x), 2 * x); - this->drawVerticalLine(glcd::Point(center.x - x, center.y - y), 2 * y); - this->drawVerticalLine(glcd::Point(center.x - y, center.y - x), 2 * x); - } -} diff --git a/src/modm/ui/display/graphic_display_text.cpp b/src/modm/ui/display/graphic_display_text.cpp deleted file mode 100644 index f1e6d1d68d..0000000000 --- a/src/modm/ui/display/graphic_display_text.cpp +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Copyright (c) 2010-2011, 2013, Fabian Greif - * Copyright (c) 2012-2013, Niklas Hauser - * 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/. - */ -// ---------------------------------------------------------------------------- - -#include "graphic_display.hpp" - -// ---------------------------------------------------------------------------- -uint8_t -modm::GraphicDisplay::getFontHeight() const -{ - return modm::GraphicDisplay::getFontHeight(&(this->font)); -} - -uint8_t -modm::GraphicDisplay::getFontHeight(const modm::accessor::Flash *font) -{ - if (!font->isValid()) - return 0; - - return (*font)[3]; -} - -// ---------------------------------------------------------------------------- -uint16_t -modm::GraphicDisplay::getStringWidth(const char* s) const -{ - return modm::GraphicDisplay::getStringWidth(s, &(this->font)); -} - - -uint16_t -modm::GraphicDisplay::getStringWidth(const char* s, const modm::accessor::Flash *font) -{ - if (!font->isValid()) - return 0; - - const uint8_t offsetWidthTable = 8; - const uint8_t vspace = (*font)[5]; - const uint8_t first = (*font)[6]; - - uint16_t width = 0; - - while(*s) { - width += (*font)[offsetWidthTable + (static_cast(*s) - first)]; - width += vspace; - s++; - } - - return width; -} - -// ---------------------------------------------------------------------------- -void -modm::GraphicDisplay::write(char c) -{ - if (!this->font.isValid()) - return; - - const uint8_t character = static_cast(c); - const uint8_t height = font[3]; - const uint8_t hspace = font[4]; - const uint8_t vspace = font[5]; - - if (character == '\n') { - this->cursor.set(0, this->cursor.y + height + hspace); - return; - } - - const uint8_t first = font[6]; - const uint8_t count = font[7]; - - if (character >= (first + count) || character < first) { - // character is not contained in this font set - return; - } - - const uint8_t offsetWidthTable = 8; - - uint16_t offset = count + offsetWidthTable; - uint8_t position = character - first + offsetWidthTable; - const uint8_t usedRows = (height + 7) / 8; // round up - for (uint8_t i = offsetWidthTable; i < position; i++) - { - offset += font[i] * usedRows; - } - uint8_t width = font[position]; - - this->drawImageRaw(cursor, width, height, - accessor::asFlash(font.getPointer() + offset)); - - cursor.setX(cursor.x + width); - - // all characters below 128 have whitespace afterwards (number given - // by vspace). - if (character < 128) { - //color::Rgb565 oldColor = this->color; - - //this->setColor(color::html::White); - for (uint_fast8_t i = 0; i < vspace; ++i) { - //this->drawVerticalLine(cursor, height); - cursor.setX(cursor.x + 1); - } - - // restore color - //this->setColor(oldColor); - } -} - -// ---------------------------------------------------------------------------- -void -modm::GraphicDisplay::Writer::write(char c) -{ - this->parent->write(c); -} - -void -modm::GraphicDisplay::Writer::flush() -{ -} - -bool -modm::GraphicDisplay::Writer::read(char&) -{ - return false; -} diff --git a/src/modm/ui/display/image/home_16x16.pbm b/src/modm/ui/display/image/home_16x16.pbm deleted file mode 100644 index 8c559dc943..0000000000 --- a/src/modm/ui/display/image/home_16x16.pbm +++ /dev/null @@ -1,7 +0,0 @@ -P1 -# CREATOR: GIMP PNM Filter Version 1.1 -16 16 -0000000000000000000111111111100000100000000001000100000110000010010000 -1111000010010001111110001001001111111100100101100000011010010010000001 -0010010010011101001001001001110100100100100111010010010011111111001000 -1000000000010000011111111110000000000000000000 \ No newline at end of file diff --git a/src/modm/ui/display/image/logo_eurobot_90x64.pbm b/src/modm/ui/display/image/logo_eurobot_90x64.pbm deleted file mode 100644 index 897eb60614..0000000000 --- a/src/modm/ui/display/image/logo_eurobot_90x64.pbm +++ /dev/null @@ -1,86 +0,0 @@ -P1 -# CREATOR: GIMP PNM Filter Version 1.1 -90 64 -0000000000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000000000 -0000111111000000000000000000000000000000000000000000000000000000000000 -0000000000011111111111100000001111100000000000000000000000000000000000 -0000000000000000000000001111111111111111111111111100011111000000000000 -0000000000000000000000000000000000000000111111111111111111111111111111 -1110001111100000000000000000000000000000000000000000000001111111111111 -1110111111111111111111111110011110000000000000000000000000000000000000 -0000111111111111111111000111111111111101111111111001111000000000000000 -0000000000000000000000111111111111111111111011111111111110001111111111 -1001110000000000000000000000000000000000111111111101111111111111111111 -1111111101111111111111100111000000000000000000000000000000111111111110 -0011111111111111111111111111111111111111111110111000000000000000000000 -0000000111111111111101111111111111111111111111111111111111111111110111 -0000000000000000000000000111111111111111111111111111001111111111111111 -1111111101111111111110000000000000000000000011111111111111111111111111 -1100111111111111110011111100000111111111110000000000000000000001111111 -1111111111111111111111001111111111111100111111101011111111111110000000 -0000000000001111000011001100100100110000110000011110000110000011111111 -1111111111111100000000000000000111100110010011001000001000000100000011 -0000001000001111111111111111111111100000000000000011111001100100110010 -0011001110010011001001110011001111111111111111111111111000000000000001 -1111100000010011001001110011100100110010011100110011111111111111101111 -1111110000000000001111111001111100110010011100111001001100100111001100 -1111111111110000000111111100000000000011111110011111001000100111001110 -0100110010011100110011111111111111000111111111100000000001111111110000 -0110001010011110000011000001110000011100001111111111100100111111111000 -0000001111111111111111111111111111111111111111111111111111111111111111 -1101111011111111100000000011111111111111111111111111111111111111111111 -1111111111111111111111111111111111111000000000111111111111111111111111 -1111111111111111111111111111111111111111111111111111111110000000011111 -1111111111111111111111111111111111111111111111111111111111111110111111 -1111111000000001111111111111111111110111111111111111110000001111111111 -1111111111111001111111111110000000011111111111111111111100111111111111 -1110000000011111111111111111110000000001111111100000000111111111111111 -1111110001111111111111101000000111111111111111111111000001111111111000 -0000111111111111111111111100001111111111111011000001111111111111111111 -1101110111111111100000001111100011111111111111000001111111111110111000 -0011111111111111111110111110111111111000000011000000111111111111110000 -0011111111111001100000111111111111110111111111111111111110000000110000 -0011111111111111000000000000000000011000001111111111111000111111111111 -1111110000000111000000011111111111110000000000000000001110000011111111 -1000000000001111111111111100000001110000000111111111000000000000000000 -0001010000011111111111110000011111111111111110000000011110000001100000 -0000000000000000000000110000000111111111111000100011111111111111100000 -0001111000000000000000000000000000000000011110001111111111111100111110 -0111111111111100000000011110000001110000000000000000000000001111111111 -1111111111111111111111111111111101000000000111100000001111100000000000 -0000000000111111111111111111111111111111111111111110100000000000111000 -0000111111110000000000000000000111111110000001111111111111111111111111 -0100000000000011110000001111111111100000000000000000111111000000001111 -1111111111111111111010000000000000111100000011111111111100000000000000 -0001110000000000011111111111111111111101000000000000001111000011111111 -1111110000000000000000001100000000000011111111111111111110100000000000 -0000011111111111111111111100000000000000000001001110000000111111111111 -1111100100000000000000000111111111111111111110000000001111000000000111 -1110000011111111111111110010000000000000000001110001111111111111100000 -0001111111100000001111100000111111111111110011000000000000000000000000 -0011111111111110000000111111111110000000011100001111111111110011000000 -0000000000000000000000001111100011100000011111111111111100000111000011 -1111111100111000000000000000000000000000000001100000011000001111111111 -1111111001111100011111111000111000000000000000000000000000000000000000 -0000100001100111111111111111000110001111100001111000000000000000000000 -0000000000000000000000000000111110000001111111111100000100000111111000 -0000000000000000000000000000000000000000000000001111111111100000000000 -0000001111111110000000000000000000000000000000000000010000000000000111 -1111111111111111111111111111111100000000000000000000000000000000000000 -0011001100000000011111111111111111111111111111110000000000000000000000 -0000000000000000000000111011100000000000011111111111111111111111000000 -0000000000000000000000000000000000000000000110111100000000000000000001 -1111100000000000000000000000000000000000000000000000000000000001110111 -1000000000000000000000000000000000000000000000000000000000000000000000 -0000000000000011011110000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000111011110000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000111011100000000 -0000000000000000000000000000000000000000000000000000000000000000000000 -0000011110000001000000000000000000000000000000000000000000000000000000 -0000000000000000000000000011110000100000000000000000000000000000000000 -0000000000000000000000000000000000000000000000011111110000000000000000 -0000000000000000000000000000000000000000000000000000000000000000000001 -1110000000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000000000 -00000000000000000000 \ No newline at end of file diff --git a/src/modm/ui/display/image/logo_rca_90x64.pbm b/src/modm/ui/display/image/logo_rca_90x64.pbm deleted file mode 100644 index 8235011dc6..0000000000 --- a/src/modm/ui/display/image/logo_rca_90x64.pbm +++ /dev/null @@ -1,86 +0,0 @@ -P1 -# CREATOR: GIMP PNM Filter Version 1.1 -90 64 -0000111111111111111111111111111111111111111111111111111111111111111111 -1111111111111111000000111111111111111111111111111111111111111111111111 -1111111111111111111111111111111111111100011110000000000000000000000000 -0000000000000000000000000000000000000000000000000000000111100110000000 -0001111111111100000000000000001111111111000000000000011111111110000000 -0000000110111000000000011111111111111000000000001111111111111100000000 -0001111111111000000000000001111100000000000111111111111111000000000111 -1111111111111000000000011111111110000000000000001111000000000001111111 -1111111110000000011111111111111110000000001111111111110000000000000011 -1100000000000111111100111111100000000111111100111111100000000011111111 -1111000000000000001111000000000001111111001111111000000001111111001111 -1110000000001111111111110000000000000011110000000000011111110011111110 -0000000111111100111111100000000011111111111100000000000000111100000000 -0001111111001111111000000001111111001111111000000001111111111111100000 -0000000011110000000000011111110011111110000000011111110011111110000000 -0111111111111110000000000000111100000000000111111100111111100000000111 -1111001111111000000001111111111111100000000000001111000000000001111111 -0011111110000000011111110011111110000000011111100111111000000000000011 -1100000000000111111111111111000000000111111100000000000000000111111001 -1111100000000000001111000000000001111111111111100000000001111111000000 -0000000000011111100111111000000000000011110000000000011111111111111100 -0000000111111100000000000000000111111001111110000000000000111100000000 -0001111111111111111000000001111111001111111000000011111110011111110000 -0000000011110000000000011111110011111110000000011111110011111110000000 -1111111111111111000000000000111100000000000111111100111111100000000111 -1111001111111000000011111111111111110000000000001111000000000001111111 -0011111110000000011111110011111110000000111111111111111100000000000011 -1100000000000111111100111111100000000111111100111111100000001111111111 -1111110000000000001111000000000001111111001111111000000001111111111111 -1110000000111111100111111100000000000011110000000000011111110011111110 -0000000111111111111111100000001111111001111111000000000000111100000000 -0001111111001111111000000000111111111111110000000011111110011111110000 -0000000011110000000000011111110011111110000000000011111111110000000000 -1111111001111111000000000000111100000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000001111111111111111111111 -1111111111111111111111111111111111111111111111111111111111111111111111 -1100000000000000000000000000000000000000000000000000000000000000000000 -0000000000000000001111000110000001000000010000000000000100000010000001 -0000000000100000000000000000010100000011110001010000010000000100000000 -0000010000001000001010000000001000000000000000000101000000111100010100 -1001100010011001001000110100101011000010101110011011000100010000010001 -0100000011110001100101010101010100101011010001001010101000111000101000 -1010101010100010100101000000111100010101010101010101001110100100010010 -1010100010101110100010101100101000110001010000001111000101010101010101 -0100100010010001001010101000101010101000101010001010001000010100000011 -1100010100100110001000100100100011001001101100001010111001101010010010 -1000010100100100001111000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000011111111111111111111111111111111 -1111111111111111111111111111111111111111111111111111111111111100000000 -0000000000000000000100000000000000000000000000000010000000000000000000 -0000000011110000000000000000000000000001000000000000000000000000000000 -1001111111111111111111111100111100000000000000000011110000010000000000 -0000000000000000000010010000000000000000000001001111000000000000000000 -1000100001000000000011111000000000000000100100110111001001100111010011 -1100000000000000000010000100010000000000111111000000000000001001010000 -1001010101001001001111111111111111111111100001000100000000000111111000 -0000000000100100100010010101100010010011110000000000000000001000010001 -0000000000001111110000000000001001000100100111010100100100111100111111 -1000000000100001111100000000000001111100000000000010010110001001010101 -0010010011110010000010001110001000010001000000000000001111000000000000 -1001000000000000000000000100111111100000111111111110000100010000000000 -0000111100000000000010011111111111111111111111001111001000001000111000 -1000010001000000000000001111000000000000100000000000001000000000000011 -1100111111100001000010001000010011000000000011110000000000001000000000 -0000100000000000001111000000000000010000111100000100111000000000111110 -0000000000100000000000110110000000000011110000000000000100000000000001 -0011110000000011111100000000001000000000110000011000000000111100000000 -0011111110000000000100111110000001111111100000000010000000110000000001 -1000000011110000000000000000000000000001001111111111111111111100000000 -1000001100100000010001100000111100000000001111111000000000010001111111 -1111111111111000000010001100000001101010000110001111000000000000010000 -0000000001000011111111111111111111000000101100000010000010100000011111 -1100000000000001000000000000010000011111111111100111111000001000110000 -1001101010000110001111000000000000010000000000000100000000000111111000 -1111110000100000110001000001000110000011110000000000001110000000000001 -0000000000001111110001111110001000000011000000000110000000111111111111 -1111111111111111111100000000000001111110001111110010000000001100000110 -0000000111011000000000001110000000000001000000000000001111110001111110 -1000000000001101100000000001100111100000000000000000000000010000000000 -0000011111100011111110000000000000100000000001111000111111111111111111 -1111111111111111111111111111111111111111111111111111111111111111111100 -0000111111111111111111111111111111111111111111111111111111111111111111 -11111111111111110000 \ No newline at end of file diff --git a/src/modm/ui/display/image/skull_64x64.pbm b/src/modm/ui/display/image/skull_64x64.pbm deleted file mode 100644 index d7493b9f75..0000000000 --- a/src/modm/ui/display/image/skull_64x64.pbm +++ /dev/null @@ -1,62 +0,0 @@ -P1 -# CREATOR: GIMP PNM Filter Version 1.1 -64 64 -0000000000000000000000000001111111111100000000000000000000000000000000 -0000000000000000011111111111111111110000000000000000000000000000000000 -0000000011111000000000000000111110000000000000000000000000000000000000 -1111000000000000000000000111100000000000000000000000000000000001100000 -0000000000000000000001110000000000000000000000000000000111000000000000 -0000000000000000011000000000000000000000000000000110000000000000000000 -0000000000001100000000000000000000000000001100000000000000000000000000 -0000000110000000000000000000000000011000000000000000000000000000000000 -0011000000000000000000000000110000000000000000000000000000000000001100 -0000000000000000000000110000000000000000000000000000000000000110000000 -0000000000000000100000000000000000000000000000000000000110000000000000 -0000000001100000000000000000000000000000000000000011000000000000000000 -0001100000000000000000000000000000000000000011000000000000000000000100 -0100000000000000000000000000000000010011000000000000000000000100010000 -0000000000000000000000000000010001000000000000000000000100110000000000 -0000000000000000000000011001000000000000000000000100110000000000000000 -0000000000000000011001000000000000000000000100010000000000000000000000 -0000000000010001000000000000000000000100010000000000000000000000000000 -0000010001000000000000000000000110011000000000000000000000000000000011 -0011000000000000000000000110011000000000000000000000000000000011001100 -0000000000000000000110001000000000000000000000000000000010001100000000 -0000000000000011001000000000000000000000000000000010011000000000000000 -0000000011001000011111111000000011111111000010011000000000000000000000 -0001101001111111111000000011111111100010110000000000000000000000000111 -1001111111111000000011111111110011110000000000000000000000000011100111 -1111111000000011111111110011100000000000000000000000000001100111111111 -1000000011111111110011000000000000000000000000000001100111111111000000 -0011111111110011000000000000000001111000000001100011111111000000000111 -1111100011000000001000000001101100000001000011111110000000000011111110 -0001000000111110000001000110000001000001111100000101000001111100000100 -0000110110000011000110000001000000011000001101100000110000000100000110 -0010000011000011000001100000000000011101100000000000001100001100001000 -0111000001110001100000000000011101110000000000001100001100001000111000 -0000111100110000000000011101110000000000011000111000001100110000000000 -1111111000000000011101110000000001111001100000000110100000000000001111 -1111100000011101110000000111111111000000000011111111110000000011111111 -0000011101110000011111111100000000000001011111111100000000011111100001 -1000110000111111110000000011111111000000000111000000011001100000000000 -0000101011000000001111111110000000000001111000001010110000000000000110 -1011000000111000000000000000000000011110001010110000000000000110111000 -0011100000000000000000000000000111101100011111000111111101011000111100 -0000000000000000000000000001111101001010111010100001011011110000000000 -0000000000000000000000011001011010101010100101011111000000000000000000 -0000000000000000001001001110101010111101011100000000000000000000000000 -0000000000011001101010111111101010011000000000000000000000000000000000 -0001111100111010101010000110011100000000000000000000000000000000011100 -1100001110101010111000011111000000000000000000000000000001111000110000 -0001111111000000011011110000000000000000000111111111000000011000000000 -0000000000110000011100000000000000001111111100000000111000000000000000 -0001111000000111111111000000001000000000000011111100000000000000001111 -1110000001111111100000001100000000000111000111000000000000011100011100 -0000000000100000000110000000011100000011110000000001111000000111000000 -0001100000000011000001110000000000111111111111100000000001110000001100 -0000000011000011000000000000000001110000000000000000011000011000000000 -0001000010000000000000000000000000000000000000001000010000000000000100 -0110000000000000000000000000000000000000001100010000000000000110110000 -0000000000000000000000000000000000000110110000000000000111100000000000 -0000000000000000000000000000000011100000000000000000000000000000000000 -000000000000000000000000000000000000 \ No newline at end of file diff --git a/src/modm/ui/display/module.lb b/src/modm/ui/display/module.lb deleted file mode 100644 index e4918ec448..0000000000 --- a/src/modm/ui/display/module.lb +++ /dev/null @@ -1,54 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- -# -# Copyright (c) 2018, Niklas Hauser -# -# 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/. -# ----------------------------------------------------------------------------- - -def init(module): - module.name = ":ui:display" - module.description = """\ -# Display Graphics - -Code for writing and drawing on character and graphical displays. - -## Coordinate System - -``` -(0, 0) - +---------------------+ - | ----> X | - | | | - | | | - | V Y | - | | - | | - | | - +---------------------+ - e.g. (127, 63) -``` - -The size (width and height) of a graphics primitive always correspond -to its mathematical model, ignoring the rendered with. As everything -is drawn one pixel wide, the pixels will be rendered to the right and -below the mathematically defined points. -""" - -def prepare(module, options): - module.depends( - ":architecture:accessor", - ":io", - ":math:geometry", - ":math:utils", - ":ui:color") - return True - -def build(env): - env.outbasepath = "modm/src/modm/ui/display" - env.copy(".", ignore=env.ignore_files("*.font", "*.pbm")) - env.copy("../display.hpp") diff --git a/src/modm/ui/display/monochrome_graphic_display.hpp b/src/modm/ui/display/monochrome_graphic_display.hpp deleted file mode 100644 index 599827de52..0000000000 --- a/src/modm/ui/display/monochrome_graphic_display.hpp +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (c) 2009, Georgi Grinshpun - * Copyright (c) 2009-2011, 2013, 2019, Fabian Greif - * Copyright (c) 2010, Martin Rosekeit - * Copyright (c) 2011, Thorsten Lajewski - * Copyright (c) 2012-2015, Niklas Hauser - * Copyright (c) 2021, Thomas Sommer - * - * 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_MONOCHROME_GRAPHIC_DISPLAY_HPP -#define MODM_MONOCHROME_GRAPHIC_DISPLAY_HPP - -#include - -#include "graphic_display.hpp" - -namespace modm -{ -/** - * Base class for monochrome graphical displays with a RAM buffer. - * - * Every operation works on the internal RAM buffer, therefore the content - * of the real display is not changed until a call of update(). - * - * \tparam Width Horizontal number of Pixels - * \tparam Height Vertical number of Pixels - * \tparam BufferWidth Horizontal (first) dimension of Buffer - * \tparam BufferHeight Vertical (first) dimension of Buffer - * - * \author Thomas Sommer - * \ingroup modm_ui_display - */ -template -class MonochromeGraphicDisplay : public GraphicDisplay -{ - static_assert(Width > 0, "width must be greater than 0"); - static_assert(Height > 0, "height must be greater than 0"); - -public: - virtual ~MonochromeGraphicDisplay() = default; - - inline uint16_t - getWidth() const final - { - return Width; - } - - inline uint16_t - getHeight() const final - { - return Height; - } - - inline std::size_t - getBufferWidth() const final - { - return BufferWidth; - } - - inline std::size_t - getBufferHeight() const final - { - return BufferHeight; - } - - virtual bool - getPixel(int16_t x, int16_t y) const = 0; - - void - clear() final; - -protected: - uint8_t buffer[BufferHeight][BufferWidth]; -}; -} // namespace modm - -#include "monochrome_graphic_display_impl.hpp" - -#endif // MODM_MONOCHROME_GRAPHIC_DISPLAY_HPP \ No newline at end of file diff --git a/src/modm/ui/display/monochrome_graphic_display_horizontal.hpp b/src/modm/ui/display/monochrome_graphic_display_horizontal.hpp deleted file mode 100644 index 43ce0be339..0000000000 --- a/src/modm/ui/display/monochrome_graphic_display_horizontal.hpp +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (c) 2019, Fabian Greif - * - * 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_MONOCHROME_GRAPHIC_DISPLAY_HORIZONTAL_HPP -#define MODM_MONOCHROME_GRAPHIC_DISPLAY_HORIZONTAL_HPP - -#include - -#include "monochrome_graphic_display.hpp" - -namespace modm -{ -/** - * Base class for monochrome graphical displays with a RAM buffer. - * - * The pixel are compressed horizontally, this means that 8 pixel in - * y-direction are combined into one byte in the RAM buffer. - * - * Every operation works on the internal RAM buffer, therefore the content - * of the real display is not changed until a call of update(). - * - * \tparam Width Width of the display. Must be a multiple of 8! - * \tparam Height Height of the display. - * - * \ingroup modm_ui_display - */ -template -class MonochromeGraphicDisplayHorizontal - : public MonochromeGraphicDisplay -{ - // Height must be a multiple of 8 - static_assert((Width % 8) == 0, "width must be a multiple of 8"); - -public: - virtual ~MonochromeGraphicDisplayHorizontal() = default; - -protected: - void - setPixel(int16_t x, int16_t y) final; - - void - clearPixel(int16_t x, int16_t y) final; - - bool - getPixel(int16_t x, int16_t y) const final; -}; -} // namespace modm - -#include "monochrome_graphic_display_horizontal_impl.hpp" - -#endif // MODM_MONOCHROME_GRAPHIC_DISPLAY_HORIZONTAL_HPP diff --git a/src/modm/ui/display/monochrome_graphic_display_horizontal_impl.hpp b/src/modm/ui/display/monochrome_graphic_display_horizontal_impl.hpp deleted file mode 100644 index a7aabf49e7..0000000000 --- a/src/modm/ui/display/monochrome_graphic_display_horizontal_impl.hpp +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2019, Fabian Greif - * - * 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_MONOCHROME_GRAPHIC_DISPLAY_HORIZONTAL_HPP -#error "Don't include this file directly, use 'monochrome_graphic_display_horizontal.hpp' instead!" -#endif - -namespace modm -{ -template -void -MonochromeGraphicDisplayHorizontal::setPixel(int16_t x, int16_t y) -{ - if ((x < Width) and (y < Height)) { this->buffer[y][x / 8] |= (1 << (x % 8)); } -} - -template -void -MonochromeGraphicDisplayHorizontal::clearPixel(int16_t x, int16_t y) -{ - if ((x < Width) and (y < Height)) { this->buffer[y][x / 8] &= ~(1 << (x % 8)); } -} - -template -bool -MonochromeGraphicDisplayHorizontal::getPixel(int16_t x, int16_t y) const -{ - if ((x < Width) and (y < Height)) - return (this->buffer[y][x / 8] & (1 << (x % 8))); - else - return false; -} -} // namespace modm diff --git a/src/modm/ui/display/monochrome_graphic_display_impl.hpp b/src/modm/ui/display/monochrome_graphic_display_impl.hpp deleted file mode 100644 index 14900c6944..0000000000 --- a/src/modm/ui/display/monochrome_graphic_display_impl.hpp +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (c) 2009-2011, 2013, 2019, Fabian Greif - * Copyright (c) 2011, Martin Rosekeit - * Copyright (c) 2012-2013, Niklas Hauser - * Copyright (c) 2016, Antal Szabó - * Copyright (c) 2021, Thomas Sommer - * - * 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 - -#ifndef MODM_MONOCHROME_GRAPHIC_DISPLAY_HPP -#error "Don't include this file directly, use 'monochrome_graphic_display.hpp' instead!" -#endif - -template -void -modm::MonochromeGraphicDisplay::clear() -{ - std::fill(&buffer[0][0], &buffer[0][0] + sizeof(buffer), 0); - this->cursor = {0, 0}; -} \ No newline at end of file diff --git a/src/modm/ui/display/monochrome_graphic_display_vertical.hpp b/src/modm/ui/display/monochrome_graphic_display_vertical.hpp deleted file mode 100644 index 3377d476b9..0000000000 --- a/src/modm/ui/display/monochrome_graphic_display_vertical.hpp +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (c) 2009, Georgi Grinshpun - * Copyright (c) 2009-2011, 2013, 2019, Fabian Greif - * Copyright (c) 2010, Martin Rosekeit - * Copyright (c) 2011, Thorsten Lajewski - * Copyright (c) 2012-2015, Niklas Hauser - * Copyright (c) 2021, Thomas Sommer - * - * 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_MONOCHROME_GRAPHIC_DISPLAY_VERTICAL_HPP -#define MODM_MONOCHROME_GRAPHIC_DISPLAY_VERTICAL_HPP - -#include - -#include "monochrome_graphic_display.hpp" - -namespace modm -{ -/** - * Base class for graphical displays with a RAM buffer. - * - * Every operation works on the internal RAM buffer, therefore the content - * of the real display is not changed until a call of update(). - * - * \tparam Width Width of the display. - * \tparam Height Height of the display. Must be a multiple of 8! - * - * \author Fabian Greif - * \ingroup modm_ui_display - */ -template -class MonochromeGraphicDisplayVertical - : public MonochromeGraphicDisplay -{ - static_assert((Height % 8) == 0, "height must be a multiple of 8"); - -public: - virtual ~MonochromeGraphicDisplayVertical() = default; - - // Faster version adapted for the RAM buffer - void - drawImageRaw(glcd::Point start, uint16_t width, uint16_t height, - modm::accessor::Flash data) final; - - void - setPixel(int16_t x, int16_t y) final; - - void - clearPixel(int16_t x, int16_t y) final; - - bool - getPixel(int16_t x, int16_t y) const final; - -protected: - // Faster version adapted for the RAM buffer - void - drawHorizontalLine(glcd::Point start, uint16_t length) final; - - // Faster version adapted for the RAM buffer - void - drawVerticalLine(glcd::Point start, uint16_t length) final; -}; -} // namespace modm - -#include "monochrome_graphic_display_vertical_impl.hpp" - -#endif // MODM_MONOCHROME_GRAPHIC_DISPLAY_VERTICAL_HPP diff --git a/src/modm/ui/display/monochrome_graphic_display_vertical_impl.hpp b/src/modm/ui/display/monochrome_graphic_display_vertical_impl.hpp deleted file mode 100644 index aefaeaec81..0000000000 --- a/src/modm/ui/display/monochrome_graphic_display_vertical_impl.hpp +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright (c) 2009-2011, 2013, 2019, Fabian Greif - * Copyright (c) 2011, Martin Rosekeit - * Copyright (c) 2012-2013, Niklas Hauser - * Copyright (c) 2016, Antal Szabó - * Copyright (c) 2021, Thomas Sommer - * - * 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_MONOCHROME_GRAPHIC_DISPLAY_VERTICAL_HPP -#error "Don't include this file directly, use 'monochrome_graphic_display_vertical.hpp' instead!" -#endif - -template -void -modm::MonochromeGraphicDisplayVertical::drawHorizontalLine(glcd::Point start, - uint16_t length) -{ - if (start.y >= 0 and start.y < Height) - { - const int16_t y = start.y / 8; - - const uint8_t byte = 1 << (start.y % 8); - for (int_fast16_t x = start.x; x < static_cast(start.x + length); ++x) - { - if (x < Width) { this->buffer[y][x] |= byte; } - } - } -} - -template -void -modm::MonochromeGraphicDisplayVertical::drawVerticalLine(glcd::Point start, - uint16_t length) -{ - if (start.x >= 0 and start.x < Width) - { - const int8_t end_y = start.y + length; - const uint8_t y_last = end_y / 8; - - uint_fast8_t y = start.y / 8; - // Mask out start - uint_fast8_t byte = 0xFF << start.y % 8; - while (y != y_last) - { - if (y < Height / 8) - { - this->buffer[y][start.x] |= byte; - byte = 0xFF; - } - y++; - } - // Mask out end - if (y < Height / 8) - { - byte &= 0xFF >> (8 - end_y % 8); - this->buffer[y][start.x] |= byte; - } - } -} - -template -void -modm::MonochromeGraphicDisplayVertical::drawImageRaw( - glcd::Point start, uint16_t width, uint16_t height, modm::accessor::Flash data) -{ - if ((start.y % 8) == 0) - { - uint16_t row = start.y / 8; - uint16_t rowCount = (height + 7) / 8; // always round up - - if ((height % 8) == 0) - { - for (uint_fast16_t i = 0; i < width; i++) - { - for (uint_fast16_t k = 0; k < rowCount; k++) - { - uint16_t x = start.x + i; - uint16_t y = k + row; - - if (x < Width and y < Height) - { - this->buffer[y][x] = data[i + k * width]; - } - } - } - return; - } - } - - GraphicDisplay::drawImageRaw(start, width, height, data); -} - -template -void -modm::MonochromeGraphicDisplayVertical::setPixel(int16_t x, int16_t y) -{ - if (x < Width and y < Height) { this->buffer[y / 8][x] |= (1 << y % 8); } -} - -template -void -modm::MonochromeGraphicDisplayVertical::clearPixel(int16_t x, int16_t y) -{ - if (x < Width and y < Height) { this->buffer[y / 8][x] &= ~(1 << y % 8); } -} - -template -bool -modm::MonochromeGraphicDisplayVertical::getPixel(int16_t x, int16_t y) const -{ - if (x < Width and y < Height) - { - return (this->buffer[y / 8][x] & (1 << y % 8)); - } else - { - return false; - } -} \ No newline at end of file diff --git a/src/modm/ui/display/virtual_graphic_display.cpp b/src/modm/ui/display/virtual_graphic_display.cpp deleted file mode 100644 index 936629c168..0000000000 --- a/src/modm/ui/display/virtual_graphic_display.cpp +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (c) 2013, Kevin Läufer - * Copyright (c) 2013, Thorsten Lajewski - * - * 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 "virtual_graphic_display.hpp" - -modm::VirtualGraphicDisplay::VirtualGraphicDisplay(modm::ColorGraphicDisplay* display, - modm::glcd::Point leftUpper, modm::glcd::Point rightLower): - display(display), leftUpper(leftUpper), rightLower(rightLower), - width(static_cast(this->rightLower[0] - this->leftUpper[0])), - height(static_cast(this->rightLower[1] - this->leftUpper[1])) -{ -} - -void -modm::VirtualGraphicDisplay::setDisplay(modm::ColorGraphicDisplay* display) -{ - this->display = display; - return; -} - -void -modm::VirtualGraphicDisplay::clear() -{ - //TODO switch black , white - this->display->setColor(color::Rgb(0, 0, 0)); - this->display->fillRectangle(this->leftUpper, width, height); - this->display->setColor(color::Rgb(255, 255, 255)); -} - -void -modm::VirtualGraphicDisplay::update() -{ - this->display->update(); - return; -} - -void -modm::VirtualGraphicDisplay::setPixel(int16_t x, int16_t y) -{ - this->display->setPixel(x + this->leftUpper[0], y + this->leftUpper[1]); -} - -void -modm::VirtualGraphicDisplay::clearPixel(int16_t x, int16_t y) -{ - this->display->clearPixel(x + this->leftUpper[0], y + this->leftUpper[1] ); -} - -modm::color::Rgb565 -modm::VirtualGraphicDisplay::getPixel(int16_t x, int16_t y) const -{ - return this->display->getPixel(x + this->leftUpper[0], y + this->leftUpper[1] ); -} \ No newline at end of file diff --git a/src/modm/ui/display/virtual_graphic_display.hpp b/src/modm/ui/display/virtual_graphic_display.hpp deleted file mode 100644 index 5d8b9d4b2d..0000000000 --- a/src/modm/ui/display/virtual_graphic_display.hpp +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (c) 2009-2010, Fabian Greif - * Copyright (c) 2009-2010, Martin Rosekeit - * Copyright (c) 2012, 2014, Niklas Hauser - * Copyright (c) 2013, Kevin Läufer - * Copyright (c) 2013, Thorsten Lajewski - * - * 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_VIRTUAL_GRAPHIC_DISPLAY -#define MODM_VIRTUAL_GRAPHIC_DISPLAY - -#include - -namespace modm -{ -/// @ingroup modm_ui_display -class VirtualGraphicDisplay : public modm::ColorGraphicDisplay -{ -public: - VirtualGraphicDisplay(modm::ColorGraphicDisplay* display, modm::glcd::Point leftUpper, - modm::glcd::Point rightLower); - - void - setDisplay(modm::ColorGraphicDisplay* display); - - virtual inline uint16_t - getWidth() const - { - return this->width; - } - - virtual inline uint16_t - getHeight() const - { - return this->height; - } - - virtual void - clear(); - - virtual void - update(); - -protected: - void - setPixel(int16_t x, int16_t y) final; - - void - clearPixel(int16_t x, int16_t y) final; - - color::Rgb565 - getPixel(int16_t x, int16_t y) const final; - -private: - modm::ColorGraphicDisplay* display; - modm::glcd::Point leftUpper; - modm::glcd::Point rightLower; - const uint16_t width; - const uint16_t height; -}; - -} // namespace modm - -#endif // MODM_VIRTUAL_GRAPHIC_DISPLAY diff --git a/src/modm/ui/display/font.hpp b/src/modm/ui/font.hpp similarity index 97% rename from src/modm/ui/display/font.hpp rename to src/modm/ui/font.hpp index bdc5a08377..b6d193d0ea 100644 --- a/src/modm/ui/display/font.hpp +++ b/src/modm/ui/font.hpp @@ -31,4 +31,4 @@ #include "font/numbers_14x32.hpp" #include "font/numbers_40x56.hpp" #include "font/numbers_46x64.hpp" -#include "font/matrix_8x8.hpp" +#include "font/matrix_8x8.hpp" \ No newline at end of file diff --git a/src/modm/ui/display/font/SConscript.generate b/src/modm/ui/font/SConscript.generate similarity index 100% rename from src/modm/ui/display/font/SConscript.generate rename to src/modm/ui/font/SConscript.generate diff --git a/src/modm/ui/display/font/all_caps_3x5.cpp b/src/modm/ui/font/all_caps_3x5.cpp similarity index 100% rename from src/modm/ui/display/font/all_caps_3x5.cpp rename to src/modm/ui/font/all_caps_3x5.cpp diff --git a/src/modm/ui/display/font/all_caps_3x5.hpp b/src/modm/ui/font/all_caps_3x5.hpp similarity index 100% rename from src/modm/ui/display/font/all_caps_3x5.hpp rename to src/modm/ui/font/all_caps_3x5.hpp diff --git a/src/modm/ui/display/font/arcade_classic.cpp b/src/modm/ui/font/arcade_classic.cpp similarity index 100% rename from src/modm/ui/display/font/arcade_classic.cpp rename to src/modm/ui/font/arcade_classic.cpp diff --git a/src/modm/ui/display/font/arcade_classic.hpp b/src/modm/ui/font/arcade_classic.hpp similarity index 100% rename from src/modm/ui/display/font/arcade_classic.hpp rename to src/modm/ui/font/arcade_classic.hpp diff --git a/src/modm/ui/display/font/assertion.cpp b/src/modm/ui/font/assertion.cpp similarity index 100% rename from src/modm/ui/display/font/assertion.cpp rename to src/modm/ui/font/assertion.cpp diff --git a/src/modm/ui/display/font/assertion.hpp b/src/modm/ui/font/assertion.hpp similarity index 100% rename from src/modm/ui/display/font/assertion.hpp rename to src/modm/ui/font/assertion.hpp diff --git a/src/modm/ui/display/font/fixed_width_5x8.cpp b/src/modm/ui/font/fixed_width_5x8.cpp similarity index 100% rename from src/modm/ui/display/font/fixed_width_5x8.cpp rename to src/modm/ui/font/fixed_width_5x8.cpp diff --git a/src/modm/ui/display/font/fixed_width_5x8.hpp b/src/modm/ui/font/fixed_width_5x8.hpp similarity index 100% rename from src/modm/ui/display/font/fixed_width_5x8.hpp rename to src/modm/ui/font/fixed_width_5x8.hpp diff --git a/src/modm/ui/font/font.lb b/src/modm/ui/font/font.lb new file mode 100644 index 0000000000..592c6ebc13 --- /dev/null +++ b/src/modm/ui/font/font.lb @@ -0,0 +1,27 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# +# Copyright (c) 2021, Thomas Sommer +# +# 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/. +# ----------------------------------------------------------------------------- + +def init(module): + module.name = ":ui:font" + module.description = """ +# Font + +Various Fonts to be written on graphic-displays +""" + +def prepare(module, options): + return True + +def build(env): + env.outbasepath = "modm/src/modm/ui/font" + env.copy(".") + env.copy("../font.hpp") diff --git a/src/modm/ui/display/font/matrix_8x8.cpp b/src/modm/ui/font/matrix_8x8.cpp similarity index 100% rename from src/modm/ui/display/font/matrix_8x8.cpp rename to src/modm/ui/font/matrix_8x8.cpp diff --git a/src/modm/ui/display/font/matrix_8x8.hpp b/src/modm/ui/font/matrix_8x8.hpp similarity index 100% rename from src/modm/ui/display/font/matrix_8x8.hpp rename to src/modm/ui/font/matrix_8x8.hpp diff --git a/src/modm/ui/display/font/numbers_14x32.cpp b/src/modm/ui/font/numbers_14x32.cpp similarity index 100% rename from src/modm/ui/display/font/numbers_14x32.cpp rename to src/modm/ui/font/numbers_14x32.cpp diff --git a/src/modm/ui/display/font/numbers_14x32.hpp b/src/modm/ui/font/numbers_14x32.hpp similarity index 100% rename from src/modm/ui/display/font/numbers_14x32.hpp rename to src/modm/ui/font/numbers_14x32.hpp diff --git a/src/modm/ui/display/font/numbers_40x56.cpp b/src/modm/ui/font/numbers_40x56.cpp similarity index 100% rename from src/modm/ui/display/font/numbers_40x56.cpp rename to src/modm/ui/font/numbers_40x56.cpp diff --git a/src/modm/ui/display/font/numbers_40x56.hpp b/src/modm/ui/font/numbers_40x56.hpp similarity index 100% rename from src/modm/ui/display/font/numbers_40x56.hpp rename to src/modm/ui/font/numbers_40x56.hpp diff --git a/src/modm/ui/display/font/numbers_46x64.cpp b/src/modm/ui/font/numbers_46x64.cpp similarity index 100% rename from src/modm/ui/display/font/numbers_46x64.cpp rename to src/modm/ui/font/numbers_46x64.cpp diff --git a/src/modm/ui/display/font/numbers_46x64.hpp b/src/modm/ui/font/numbers_46x64.hpp similarity index 100% rename from src/modm/ui/display/font/numbers_46x64.hpp rename to src/modm/ui/font/numbers_46x64.hpp diff --git a/src/modm/ui/display/font/scripto_narrow.cpp b/src/modm/ui/font/scripto_narrow.cpp similarity index 100% rename from src/modm/ui/display/font/scripto_narrow.cpp rename to src/modm/ui/font/scripto_narrow.cpp diff --git a/src/modm/ui/display/font/scripto_narrow.hpp b/src/modm/ui/font/scripto_narrow.hpp similarity index 100% rename from src/modm/ui/display/font/scripto_narrow.hpp rename to src/modm/ui/font/scripto_narrow.hpp diff --git a/src/modm/ui/display/font/ubuntu_36.cpp b/src/modm/ui/font/ubuntu_36.cpp similarity index 100% rename from src/modm/ui/display/font/ubuntu_36.cpp rename to src/modm/ui/font/ubuntu_36.cpp diff --git a/src/modm/ui/display/font/ubuntu_36.hpp b/src/modm/ui/font/ubuntu_36.hpp similarity index 100% rename from src/modm/ui/display/font/ubuntu_36.hpp rename to src/modm/ui/font/ubuntu_36.hpp diff --git a/src/modm/ui/graphic.hpp b/src/modm/ui/graphic.hpp new file mode 100644 index 0000000000..d2d5748f1c --- /dev/null +++ b/src/modm/ui/graphic.hpp @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2021, Thomas Sommer + * + * 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 "font.hpp" +#include "shape.hpp" +#include "color.hpp" + +#include "graphic/painter_local.hpp" +#include "graphic/buffer.hpp" + +#include "graphic/painter_remote.hpp" +#include "graphic/display.hpp" + +#include "graphic/pattern.hpp" \ No newline at end of file diff --git a/src/modm/ui/graphic/accessor_image.hpp b/src/modm/ui/graphic/accessor_image.hpp new file mode 100644 index 0000000000..872b268855 --- /dev/null +++ b/src/modm/ui/graphic/accessor_image.hpp @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2021, Thomas Sommer + * + * 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/. + */ +// ---------------------------------------------------------------------------- + +#pragma once + +#include + +#include +#include + +#include +#include + +namespace modm::graphic +{ + +/** + * @brief Sequential Accessor for images in RAM, Flash or SD-Card (later not yet implemented) + * Some image compressions or storages are very inefficient for random access. + * Also to fulfill the purpose of sequential reading an image, random access is not required. + * By consequently restricting the ImageAccessor to sequential access, intercompatibility + * is guaranteed. + */ +template class> +class ImageAccessor; + +/** + * @brief Sequential accessor for planar stored image with clipping support + * + * @tparam C Planar Colortype of image to access + * @tparam Accessor Any of modm::accessor::* + * + * @author Thomas Sommer + * @ingroup modm_ui_graphic + */ +template class Accessor> +class ImageAccessor : public Accessor +{ +public: + ImageAccessor() = default; + + ImageAccessor(const BufferInterface* buffer, shape::Point placement = {0, 0}) + : Accessor(buffer->getBuffer()), section(placement, placement + buffer->getSize()) + { + col_size = buffer->getSize().x; + initialize(placement); + } + + ImageAccessor(const C* addr, shape::Point placement = {0, 0}) + : Accessor(addr + 2) + { + auto flash = modm::accessor::asFlash(addr); + section = {placement, placement + shape::Point(flash[0], flash[1])}; + col_size = flash[0]; + initialize(placement); + } + + ImageAccessor(const C* addr, shape::Size size, shape::Point placement) + : Accessor(addr), section(placement, placement + size), col_size(size.x) + { + initialize(placement); + } + + shape::Size getSection() const + { return section; } + + void incrementRow() + { this->address = addr_top++; } + + void incrementCol() + { this->address += col_size; } + + C + nextPixel() + { + incrementCol(); + return Accessor::operator*(); + } + +private: + void + initialize(const shape::Point placement) + { + const shape::Point topLeft = {placement.x < 0 ? -placement.x : 0, placement.y < 0 ? -placement.y : 0}; + + // TODO Test functionality + addr_top = this->address + topLeft.y * col_size + topLeft.x; + this->address = addr_top; + } + + shape::Size section; + size_t col_size; + const C* addr_top; +}; + +} // namespace modm::graphic + +#include "accessor_image_palletized.hpp" \ No newline at end of file diff --git a/src/modm/ui/graphic/accessor_image_palletized.hpp b/src/modm/ui/graphic/accessor_image_palletized.hpp new file mode 100644 index 0000000000..fe03869486 --- /dev/null +++ b/src/modm/ui/graphic/accessor_image_palletized.hpp @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2021, Thomas Sommer + * + * 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/. + */ +// ---------------------------------------------------------------------------- + +#pragma once +#include "accessor_image.hpp" + +#include +#include + +namespace modm::graphic +{ + +/** + * @brief Sequential accessor for palettized stored image with clipping support + * +* @tparam C Palletized Colortype of image to access + * @tparam Accessor Any of modm::accessor::* + * + * @author Thomas Sommer + * @ingroup modm_ui_graphic + */ +template class Accessor> +class ImageAccessor : public Accessor +{ +public: + static constexpr int digits = std::numeric_limits::digits; + // OPTIMIZE confirm "inline" doesn't help + ImageAccessor() = default; + + ImageAccessor(const BufferInterface* buffer, shape::Point placement = {0, 0}) + : Accessor((typename C::PalletType*)(buffer->getBuffer())), section(placement, placement + buffer->getSize()) + { + col_size = buffer->getSize().x; + initialize(placement); + } + + ImageAccessor(const uint8_t* addr, shape::Point placement = {0, 0}) + : Accessor((typename C::PalletType*)(addr + 2)) + { + auto flash = modm::accessor::asFlash(addr); + section = {placement, placement + shape::Point(flash[0], flash[1])}; + col_size = flash[0]; + initialize(placement); + } + + ImageAccessor(const uint8_t* addr, shape::Point size, shape::Point placement) + : Accessor((typename C::PalletType*)(addr)), section(placement, placement + size), col_size(size.x) + { + initialize(placement); + } + + shape::Section getSection() const + { return section; } + + void incrementRow() + { this->address = addr_top++; } + + void incrementCol() + { this->address += col_size; } + + void + incrementRow_preparePixel() + { + incrementRow(); + // Reset reading head + rotr = rotr_top; + byte = std::rotr(Accessor::operator*(), rotr); + } + + C + nextPixel() + { + rotr += C::Digits; + if (rotr == digits) + { + rotr = 0; + incrementCol(); + // load next byte + byte = Accessor::operator*(); + } else { + // rotate to next pixel + byte = std::rotr(byte, C::Digits); + } + + return byte & C::max; + } +private: + void + initialize(const shape::Point placement) + { + const shape::Point topLeft = {placement.x < 0 ? -placement.x : 0, placement.y < 0 ? -placement.y : 0}; + + addr_top = this->address + topLeft.y * C::Digits / digits + topLeft.x * col_size; + // & (digits - 1) coresponds x % digits with support for negative int + rotr_top = ((topLeft.y * C::Digits) & (digits - 1)) - C::Digits; + } + + int + getYlshift(int16_t y) const + { return (y * C::Digits) % digits; } + + // Image properties + shape::Section section; + size_t col_size; + + // Start conditions for new row + const C::PalletType* addr_top; + int rotr_top; + + // Current byte + C::PalletType byte; + // Track current rotation + int rotr; +}; +} // namespace modm::graphic \ No newline at end of file diff --git a/src/modm/ui/graphic/buffer.hpp b/src/modm/ui/graphic/buffer.hpp new file mode 100644 index 0000000000..45dd81b251 --- /dev/null +++ b/src/modm/ui/graphic/buffer.hpp @@ -0,0 +1,278 @@ +/* + * Copyright (c) 2009-2010, Martin Rosekeit + * Copyright (c) 2009-2011, 2013, Fabian Greif + * Copyright (c) 2011, 2013, Thorsten Lajewski + * Copyright (c) 2012-2014, 2016, Niklas Hauser + * Copyright (c) 2013, Hans Schily + * Copyright (c) 2014, Daniel Krebs + * Copyright (c) 2015, Niclas Rohrer + * Copyright (c) 2021, Thomas Sommer + * + * 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/. + */ +// ---------------------------------------------------------------------------- + +#pragma once + +#include +#include +#include + +#include "buffer_interface.hpp" +#include "buffer_memory.hpp" + +#include "accessor_image.hpp" + +namespace modm::graphic +{ +template +class Buffer : public BufferMemory, public IOStream +{ +public: + using ColorType = C; + + Buffer(C* colormap) : BufferMemory(colormap), IOStream(writer), writer(this) + { setFont(modm::font::FixedWidth5x8); } + + // ################################################### + // # Same Color and Size: use std::copy or DMA + constexpr Buffer(const Buffer &other) + { + // OPTIMIZE support DMA + std::copy(other.buffer[0], other.buffer[0] + sizeof(other.buffer) / sizeof(C), this->buffer[0]); + + this->colormap = other.colormap; + this->font = other.font; + this->font_metadata = other.font_metadata; + } + + Buffer& operator=(const Buffer &other) + { + // OPTIMIZE support DMA + if(this != &other) + std::copy(other.buffer[0], other.buffer[0] + sizeof(other.buffer) / sizeof(C), this->buffer[0]); + + // this->colormap = other.colormap; + // this->font = other.font; + // this->font_metadata = other.font_metadata; + + return *this; + } + + constexpr Buffer(Buffer &&other) + { + this->buffer = other.buffer; + + this->colormap = other.colormap; + this->font = other.font; + this->font_metadata = other.font_metadata; + } + +/* constexpr Buffer& operator=(Buffer &&other) { + this->buffer = other.buffer; + + this->colormap = other.colormap; + this->font = other.font; + this->font_metadata = other.font_metadata; + return *this; + } */ + + // ########################################### + // Different color but same size: Copy-algorithm varies for planar and palettized colortype + // Thus the copying is deligated to BufferMemory + template + constexpr Buffer(const Buffer &other) : BufferMemory(other), IOStream(writer), writer(this) + { + this->colormap = other.colormap; + this->font = other.font; + this->font_metadata = other.font_metadata; + } + + template + Buffer& operator=(const Buffer &other) + { + BufferMemory::operator=(other); + // this->colormap = other.colormap; + // this->font = other.font; + // this->font_metadata = other.font_metadata; + return *this; + } + + // ########################################### + // Different color and size: always use writeImage + template + constexpr Buffer(const Buffer &other) : IOStream(writer), writer(this) + { + this->writeImage(ImageAccessor(&other)); + + this->colormap = other.colormap; + this->font = other.font; + this->font_metadata = other.font_metadata; + } + + // IMPLEMENT all operators + // using BufferMemory::operator=; + // using BufferMemory::operator+; + // using BufferMemory::operator-; + // using BufferMemory::operator+=; + // using BufferMemory::operator-=; + + // ############################################################# + // # General interface between Buffers + + /** + * @brief Writes another buffer to this buffer. If the other buffer is palettized, + * pixels will be mapped using the colormap. + * + * @tparam CO Colortype of other buffer + * + * @param buffer Other buffer + * @param placement Target position for other buffer + */ + template + void write(const BufferInterface &buffer, shape::Point placement) { + this->writeImage(ImageAccessor(&buffer, placement)); + } + + template + void write(const BufferInterface &buffer) { + // no placement passed? take a shortcut + this->operator=(buffer); + } + + /** + * @brief Writes an image from flash to this buffer. If the image is palettized, + * pixels will be mapped using the colormap. + * + * @tparam CO Colortype of image + * + * @param buffer Address of the image in flash + * @param placement Target position for image + */ + template + void write(const uint8_t *addr, shape::Point placement = {0, 0}) { + this->writeImage(ImageAccessor(addr, placement)); + } + + void clear(ColorType color = 0); + + // Idea for vertical and horizontal shift with <<= and >>= + // https://stackoverflow.com/questions/486099/can-inner-classes-access-private-variables + // class Horizontal { + // public: + void operator<<=(const size_t shift); + void operator>>=(const size_t shift); + // private: + // uint8_t& buffer; + // } + + // class Vertical { + // public: + // void operator<<=(const size_t shift); + // void operator>>=(const size_t shift); + // private: + // uint8_t& buffer; + // } + + // friend class Horizontal; + + // void rotateVertical(const size_t difference); + // void rotateHorizontal(const size_t difference); + + // Serve BufferInterface + const uint8_t* getBuffer() const final + { return (uint8_t*)(this->buffer); } + + shape::Size getSize() const final + { return R; } + +public: + shape::Point cursor; + bool auto_linebreak = true; + + void + writeChar(char c); + + void + setFont(const uint8_t *font); + + void + setFont(const modm::accessor::Flash *font) + { setFont(font->getPointer()); } + + // Move to font-object + uint8_t + getFontHeight() const { + return font_metadata.height; + } + + uint16_t + getStringWidth(const char *s) const; + + static uint16_t + getStringWidth(const char *s, const modm::accessor::Flash *font); + +private: + modm::accessor::Flash font; + static constexpr uint8_t offsetWidthTable = 8; + + void linebreak() + { + cursor.x = 0; + cursor.y += font_metadata.height + font_metadata.hspace; + } + + // Interface for IOStream + class Writer : public IODevice + { + Buffer *parent; + public: + Writer(Buffer *parent) : parent(parent) {} + + virtual void + write(char c) + { this->parent->writeChar(c); } + + using IODevice::write; + + // unused + virtual void + flush() {} + + // unused + virtual bool + read(char&) + { return false; } + }; + + Writer writer; + + struct + { + uint8_t height; + uint8_t hspace; + uint8_t vspace; + uint8_t first; + uint8_t count; + + inline void + update(modm::accessor::Flash font) { + height = font[3]; + hspace = font[4]; + vspace = font[5]; + first = font[6]; + count = font[7]; + } + } font_metadata; + + template + friend class Buffer; +}; +} // namespace modm::graphic + +#include "buffer_impl.hpp" +#include "buffer_text_impl.hpp" \ No newline at end of file diff --git a/src/modm/ui/graphic/buffer_impl.hpp b/src/modm/ui/graphic/buffer_impl.hpp new file mode 100644 index 0000000000..fd0c6e61a9 --- /dev/null +++ b/src/modm/ui/graphic/buffer_impl.hpp @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2021, Thomas Sommer + * + * 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/. + */ +// ---------------------------------------------------------------------------- + +#pragma once +#include "buffer.hpp" + +using namespace modm::shape; +using namespace modm::color; + +namespace modm::graphic { + +template +void +Buffer::clear(ColorType color) +{ + // OPTIMIZE support DMA + std::fill(this->buffer[0], this->buffer[0] + sizeof(this->buffer) / sizeof(decltype(this->clearValue(color))), this->clearValue(color)); + cursor = {0, 0}; +} + +template +void +Buffer::operator<<=(const size_t shift) +{ + for (size_t yb = 0; yb < Buffer::BY; yb++) + { + size_t x = 0; + while (x < R.x - shift) + { + this->buffer[yb][x] = this->buffer[yb][x + shift]; + x++; + } + const auto clear = this->clearValue(); + while (x < R.x) + this->buffer[yb][x++] = clear; + } +} + +template +void +Buffer::operator>>=(const size_t shift) +{ + for (size_t yb = 0; yb < Buffer::BY; yb++) + { + size_t x = R.x; + while (x > shift) + { + x--; + this->buffer[yb][x] = this->buffer[yb][x - shift]; + } + const auto clear = this->clearValue(); + while (x) + this->buffer[yb][--x] = clear; + } +} +} // namespace modm::graphic \ No newline at end of file diff --git a/src/modm/ui/graphic/buffer_interface.hpp b/src/modm/ui/graphic/buffer_interface.hpp new file mode 100644 index 0000000000..9b1402b6d1 --- /dev/null +++ b/src/modm/ui/graphic/buffer_interface.hpp @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2021, Thomas Sommer + * + * 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/. + */ +// ---------------------------------------------------------------------------- + +#pragma once + +#include +#include + +#include "canvas.hpp" + +namespace modm::graphic +{ + +/** + * @brief Interface to Buffer to serve graphic::ImageAccessor + * + * @tparam C ColorType. Althought it's an interface, the Variation over C is + * required for optimal performance. Anyways // TODO find a way to get rid of this C + */ + +// FIXME BufferMemory::UnderlyingType must pass T +template +class BufferInterface +{ +public: + virtual shape::Size + getSize() const = 0; + + virtual const T* + getBuffer() const = 0; + +protected: + BufferInterface() = default; +}; +} // namespace modm \ No newline at end of file diff --git a/src/modm/ui/graphic/buffer_memory.hpp b/src/modm/ui/graphic/buffer_memory.hpp new file mode 100644 index 0000000000..bf9039a950 --- /dev/null +++ b/src/modm/ui/graphic/buffer_memory.hpp @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2021, Thomas Sommer + * + * 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/. + */ +// ---------------------------------------------------------------------------- + +#pragma once + +#include +#include + +#include + +#include +#include "concepts.hpp" + +#include +#include +#include + +#include "accessor_image.hpp" + +namespace modm::graphic +{ + +template +class BufferMemory; + +/** + * @brief Framebuffer with random access and low-lvl drawing methods. Each pixel has it's own address + * + * @tparam C color::Gray{>= 8}, color::Rgb, color::Hsv or color::RgbStacked - to be expanded in the future + * @tparam R Resolution - R.x: horizontal, R.y: vertical + * + * @author Thomas Sommer + * @ingroup modm_ui_graphic + */ +template +class BufferMemory : public BufferInterface, public Canvas +{ +protected: + BufferMemory(C* colormap) : Canvas(colormap) {}; + + template + constexpr BufferMemory(const BufferMemory &other) + { + std::copy(other.buffer[0], other.buffer[0] + sizeof(other.buffer) / sizeof(C), buffer[0]); + } + + template + constexpr BufferMemory(const BufferMemory &other) + { + this->writeImage(ImageAccessor(&other)); + } + + template + void operator=(const BufferMemory &other) + { + std::copy(other.buffer[0], other.buffer[0] + sizeof(other.buffer) / sizeof(CO), buffer[0]); + } + + template + void operator=(const BufferMemory &other) + { + this->writeImage(ImageAccessor(&other)); + } + +protected: + static constexpr size_t BY = R.y; + C buffer[BY][R.x]; + + C::ValueType clearValue(C color = 0) const { + return color.getValue(); + } + + /** + * @brief Write Image with foreign Color + * + * @param accessor ImageAccessor inheriting an accessor::Flash or accessor::Ram + * @param placement Placement for the image + */ + template class Accessor> + void + writeImage(ImageAccessor accessor); + + /** + * @brief Write Image with same C + * + * @param accessor ImageAccessor inheriting an accessor::Flash or accessor::Ram + * @param placement Placement for the image + */ + template class Accessor> + void + writeImage(ImageAccessor accessor); + + /** + * @warning These methods do not check sanity! + * It is your responsibility to check if the shape + * is within buffer boundaries. + */ + void drawBlind(const shape::Point& point); + void drawBlind(const shape::HLine& hline); + void drawBlind(const shape::VLine& vline); + void drawBlind(const shape::Section& section); + + C getBlind(const shape::Point& point) const + { + return buffer[point.y][point.x]; + } + + C& operator()(const shape::Point& point) + { + return buffer[point.y][point.x]; + } + + template + friend class BufferMemory; +}; +} // namespace modm + +#include "buffer_memory_impl.hpp" +#include "buffer_memory_draw_impl.hpp" + +#include "buffer_memory_palletized.hpp" +// #include "buffer_memory_palletized_mono.hpp" \ No newline at end of file diff --git a/src/modm/ui/graphic/buffer_memory_draw_impl.hpp b/src/modm/ui/graphic/buffer_memory_draw_impl.hpp new file mode 100644 index 0000000000..b27dc7c980 --- /dev/null +++ b/src/modm/ui/graphic/buffer_memory_draw_impl.hpp @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2021, Thomas Sommer + * + * 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/. + */ +// ---------------------------------------------------------------------------- + +#pragma once +#include "buffer.hpp" + +using namespace modm::shape; +using namespace modm::color; + +namespace modm::graphic { + +template +void +BufferMemory::drawBlind(const Point& point) +{ + buffer[point.y][point.x] = this->color; +} + +template +void +// TODO make const HLine ... but benchmark with const and +BufferMemory::drawBlind(const HLine& hline) +{ + std::fill(&buffer[hline.start.y][hline.start.x], &buffer[hline.start.y][hline.end_x], this->color); +} + +template +void +BufferMemory::drawBlind(const VLine& vline) +{ + shape::Point scanner = vline.start; + while (scanner.y < vline.end_y) + { + drawBlind(scanner); + scanner.y++; + } +} + +template +void +BufferMemory::drawBlind(const Section& section) +{ + Point scanner = section.topLeft; + while (scanner.y < section.bottomRight.y) + { + this->drawBlind(HLine(scanner, section.bottomRight.x)); + scanner.y++; + } +} + +} \ No newline at end of file diff --git a/src/modm/ui/graphic/buffer_memory_impl.hpp b/src/modm/ui/graphic/buffer_memory_impl.hpp new file mode 100644 index 0000000000..2be7b75171 --- /dev/null +++ b/src/modm/ui/graphic/buffer_memory_impl.hpp @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2021, Thomas Sommer + * + * 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/. + */ +// ---------------------------------------------------------------------------- + +#pragma once +#include "buffer.hpp" + +using namespace modm::shape; +using namespace modm::color; + +namespace modm::graphic { + +template +template class Accessor> +void +BufferMemory::writeImage(ImageAccessor accessor) +{ + const Section clipping = this->getIntersection(accessor.getSection()); + + Point scanner = clipping.topLeft; + while (scanner.x < clipping.bottomRight.x) + { + accessor.incrementRow_preparePixel(); + while (scanner.y < clipping.bottomRight.y) + { + if constexpr (ColorPalletized) { + // Apply colormap + buffer[scanner.y][scanner.x] = this->colormap[ accessor.nextPixel().getValue() ]; + } else { + // convert color + buffer[scanner.y][scanner.x] = accessor.nextPixel(); + } + scanner.y++; + } + scanner.x++; + scanner.y = clipping.topLeft.y; + } +} + +template +template class Accessor> +void +BufferMemory::writeImage(ImageAccessor accessor) +{ + // IMPLEMENT. see ili9341 equivalent + + // std::copy +} + +} // namespace modm::graphic \ No newline at end of file diff --git a/src/modm/ui/graphic/buffer_memory_palletized.hpp b/src/modm/ui/graphic/buffer_memory_palletized.hpp new file mode 100644 index 0000000000..1759b5b50c --- /dev/null +++ b/src/modm/ui/graphic/buffer_memory_palletized.hpp @@ -0,0 +1,175 @@ +/* + * Copyright (c) 2021, Thomas Sommer + * + * 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/. + */ +// ---------------------------------------------------------------------------- + +#pragma once +#include "buffer.hpp" + +#include +#include + +#include + +namespace modm::graphic +{ + +template +class Buffer; + +/** + * @brief Framebuffer with random access and low-lvl drawing methods. Multiple pixels share one address + * + * @tparam C color::Monochrome, color::Gray2 or color::Gray4 - to be expanded in the future + * @tparam R Resolution - R.x: horizontal, R.y: vertical + * + * @author Thomas Sommer + * @ingroup modm_ui_graphic + */ +template +class BufferMemory : public BufferInterface, public Canvas +{ + // Manipulations + void invert(); + +protected: + using PalletType = C::PalletType; + + // TODO check if it works with uint16_t and uint32_t + static constexpr int digits = std::numeric_limits::digits; + static constexpr PalletType allBits = std::numeric_limits::max(); + static constexpr int ppb = digits / C::Digits; + static constexpr size_t BY = (R.y + digits - 1) / ppb; + + PalletType buffer[BY][R.x]; + + PalletType clearValue(C color = 0) const { + return GrayD(color).getValue(); + } + + // ------------------------------------------------------------------ + + BufferMemory(C* colormap) : Canvas(colormap) {}; + + template + constexpr BufferMemory(const BufferMemory& other) { + this->writeImage(ImageAccessor(&other)); + } + + template + void operator=(const BufferMemory &other) + { + this->writeImage(ImageAccessor(&other)); + } + + /** + * @brief Write Image with foreign Color + * + * @param accessor ImageAccessor inheriting an accessor::Flash or accessor::Ram + * @param placement Placement for the image + */ + template class Accessor> + void + writeImage(ImageAccessor accessor); + + /** + * @brief Write Image with same Color + * + * @param accessor ImageAccessor inheriting an accessor::Flash or accessor::Ram + * @param placement Placement for the image + */ + template class Accessor> + void + writeImage(ImageAccessor accessor); + + /** + * @warning These methods do not check sanity! + * It is your responsibility to check if the shape + * is within buffer boundaries. + */ + void drawBlind(const shape::Point& point); + void drawBlind(const shape::HLine& hline); + void drawBlind(const shape::VLine& vline); + void drawBlind(const shape::Section& section); + + C getBlind(const shape::Point& point) const; + +private: + static size_t + getY(int_fast16_t y) + { return y / ppb; } + + static int + getYlshift(int_fast16_t y) + { return (y * C::Digits) & (digits - 1); } // x & (digits - 1) coresponds x % digits with support for negative int + + PalletType& + getByte(const shape::Point& point) + { return buffer[getY(point.y)][point.x]; } + + PalletType + getByte(const shape::Point& point) const + { return buffer[getY(point.y)][point.x]; } + + /** + * @brief Calculates a ton of constants for + * looping palletized 2D memories (images) + */ + struct Looper { + const size_t yb_top, yb_bot; + const int lshift_top, lshift_bot; + const PalletType keepmask_top, keepmask_bot; + + // Maybe this is the beginning of a general service-class + // including the // Top End, Middle part, Bottom end code-blocks in various methods of BufferMemory + Looper(const shape::Section section) : + yb_top(getY(section.topLeft.y)), + yb_bot(getY(section.bottomRight.y - 1)), + lshift_top(getYlshift(section.topLeft.y)), + lshift_bot(getYlshift(section.bottomRight.y) ? getYlshift(section.bottomRight.y) : digits), + keepmask_top(~(allBits << lshift_top)), + keepmask_bot(yb_top == yb_bot ? keepmask_top | allBits << lshift_bot : allBits << lshift_bot) + {} + + Looper(const shape::VLine vline) : + yb_top(getY(vline.start.y)), + yb_bot(getY(vline.end_y - 1)), + lshift_top(getYlshift(vline.start.y)), + lshift_bot(getYlshift(vline.end_y) ? getYlshift(vline.end_y) : digits), + keepmask_top(~(allBits << lshift_top)), + keepmask_bot(yb_top == yb_bot ? keepmask_top | allBits << lshift_bot : allBits << lshift_bot) + {} + }; + + // OPTIMIZE confirm "inline" doesn't help + template class Accessor> + PalletType + palletizeByte(ImageAccessor& accessor, int lshift, const int lshift_max) { + PalletType byte(0); + + while(lshift < lshift_max) { + if constexpr (ColorPalletized) { + // Apply colormap + byte |= this->colormap[ accessor.nextPixel().getValue() ].getValue() << lshift; + } else { + // Convert color + byte |= C( accessor.nextPixel() ).getValue() << lshift; + } + lshift += C::Digits; + } + return byte; + } + + template + friend class BufferMemory; +}; +} // namespace modm + +#include "buffer_memory_palletized_impl.hpp" +#include "buffer_memory_palletized_draw_impl.hpp" \ No newline at end of file diff --git a/src/modm/ui/graphic/buffer_memory_palletized_draw_impl.hpp b/src/modm/ui/graphic/buffer_memory_palletized_draw_impl.hpp new file mode 100644 index 0000000000..2fc4548ca6 --- /dev/null +++ b/src/modm/ui/graphic/buffer_memory_palletized_draw_impl.hpp @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2021, Thomas Sommer + * + * 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/. + */ +// ---------------------------------------------------------------------------- + +#pragma once +#include "buffer_memory_palletized.hpp" + +using namespace modm::shape; +using namespace modm::color; + +namespace modm::graphic { + +template +void +BufferMemory::drawBlind(const Point& point) +{ + PalletType& byte = getByte(point); + const int lshift = getYlshift(point.y); + + byte = (byte & ~(C::max << lshift)) | this->color.getValue() << lshift; +} + +template +void +BufferMemory::drawBlind(const HLine& hline) +{ + const size_t yb = getY(hline.start.y); + const int lshift = getYlshift(hline.start.y); + + const PalletType keepmask = ~(C::max << lshift); + const typename C::ValueType value = this->color.getValue() << lshift; + + size_t x = hline.start.x; + while (x <= hline.end_x) { + buffer[yb][x] = (buffer[yb][x] & keepmask) | value; + x++; + } +} + +template +void +BufferMemory::drawBlind(const VLine& vline) +{ + const Looper looper(vline); + const PalletType byte_middle = clearValue(this->color); + + const size_t x = vline.start.x; + size_t yb = looper.yb_top; + + // Top end + if(yb < looper.yb_bot) { + buffer[yb][x] = (buffer[yb][x] & looper.keepmask_top) | (byte_middle & ~looper.keepmask_top); + yb++; + } + + // Middle part + while (yb < looper.yb_bot) + buffer[yb++][x] = byte_middle; + + // Bottom end + buffer[yb][x] = (buffer[yb][x] & looper.keepmask_bot) | (byte_middle & ~looper.keepmask_bot); +} + +template +void +BufferMemory::drawBlind(const Section& section) +{ + const Looper looper(section); + + const PalletType byte_middle = clearValue(this->color); + + for (int_fast16_t x = section.topLeft.x; x < section.bottomRight.x; x++) { + size_t yb = looper.yb_top; + + // Top end + if(yb < looper.yb_bot) { + buffer[yb][x] = (buffer[yb][x] & looper.keepmask_top) | (byte_middle & ~looper.keepmask_top); + yb++; + } + + // Middle part + while (yb < looper.yb_bot) + buffer[yb++][x] = byte_middle; // OPTIMIZE would std::fill be faster ? + + // Bottom end + buffer[yb][x] = (buffer[yb][x] & looper.keepmask_bot) | (byte_middle & ~looper.keepmask_bot); + } +} + +template +C +BufferMemory::getBlind(const Point& point) const +{ + return C(getByte(point) >> getYlshift(point.y) & C::max); +} + +} // namespace modm::graphic \ No newline at end of file diff --git a/src/modm/ui/graphic/buffer_memory_palletized_impl.hpp b/src/modm/ui/graphic/buffer_memory_palletized_impl.hpp new file mode 100644 index 0000000000..cb485839a6 --- /dev/null +++ b/src/modm/ui/graphic/buffer_memory_palletized_impl.hpp @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2021, Thomas Sommer + * + * 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/. + */ +// ---------------------------------------------------------------------------- + +#pragma once +#include "buffer_memory_palletized.hpp" + +using namespace modm::shape; +using namespace modm::color; + +namespace modm::graphic { + +template +template class Accessor> +void +BufferMemory::writeImage(ImageAccessor accessor) +{ + // FIXME buggy for placement.y < 0 + const Section clipping = this->getIntersection(accessor.getSection()); + const Looper looper(clipping); + + for (int_fast16_t x = clipping.topLeft.x; x < clipping.bottomRight.x; x++) + { + size_t yb = looper.yb_top; + int lshift = looper.lshift_top; + accessor.incrementRow_preparePixel(); + + // Top end + if(yb < looper.yb_bot) { + this->buffer[yb][x] = (this->buffer[yb][x] & looper.keepmask_top) | palletizeByte(accessor, lshift, digits); + lshift = 0; + yb++; + } + + // Middle part + while(yb < looper.yb_bot) + this->buffer[yb++][x] = palletizeByte(accessor, 0, digits); + + // Bottom end + this->buffer[yb][x] = (this->buffer[yb][x] & looper.keepmask_bot) | palletizeByte(accessor, lshift, looper.lshift_bot); + } +} + +template +template class Accessor> +void +BufferMemory::writeImage(ImageAccessor accessor) +{ + const Section clipping = this->getIntersection(accessor.getSection()); + const Looper looper(clipping); + + const int rshift_bot = digits - looper.lshift_top; + + // FIXME looper.lshift_top always 0 for placement.y < 0 + // Thus writeImage top offscreen is buggy + // MODM_LOG_VAR(looper.lshift_top); + + if (looper.lshift_top) { + // Split bytes, shift, reassemble + for (int_fast16_t x = clipping.topLeft.x; x < clipping.bottomRight.x; x++) + { + accessor.incrementRow(); + size_t yb = looper.yb_top; + + // Top end + if (clipping.topLeft.y > 0) + { + this->buffer[yb][x] = (this->buffer[yb][x] & looper.keepmask_top) | *accessor << looper.lshift_top; + yb++; + } + + // Middle part + while (yb < looper.yb_bot) + { + this->buffer[yb][x] = *accessor >> rshift_bot; + accessor.incrementCol(); // Byte + this->buffer[yb][x] |= *accessor << looper.lshift_top; + yb++; + } + + // Bottom end + if (clipping.bottomRight.y < int16_t(R.y)) + this->buffer[yb][x] = (this->buffer[yb][x] & looper.keepmask_bot) | *accessor >> rshift_bot; + } + } else if (clipping.topLeft.y < clipping.bottomRight.y) { + // Copy bytes + for (int_fast16_t x = clipping.topLeft.x; x < clipping.bottomRight.x; x++) + { + accessor.incrementRow(); + size_t yb = looper.yb_top; + + while (yb < looper.yb_bot) + { + // OPTIMIZE Concider std::copy for Accessor == modm::accessor::Ram + this->buffer[yb++][x] = *accessor; + accessor.incrementCol(); + } + + this->buffer[yb][x] = (this->buffer[yb][x] & looper.keepmask_bot) | *accessor; + } + } +} + +template +void +BufferMemory::invert() +{ + std::for_each(buffer[0], buffer[0] + R.x * BY, [](PalletType &value){ + value ^= allBits; + } ); +} + +} // namespace modm::graphic \ No newline at end of file diff --git a/src/modm/ui/graphic/buffer_memory_palletized_mono_impl.hpp b/src/modm/ui/graphic/buffer_memory_palletized_mono_impl.hpp new file mode 100644 index 0000000000..6dd6dbf963 --- /dev/null +++ b/src/modm/ui/graphic/buffer_memory_palletized_mono_impl.hpp @@ -0,0 +1,99 @@ +// OPTIMIZE BufferMemory for speed + +template +template class Accessor> +void +BufferMemory::writeImage(ImageAccessor accessor, Point placement) +{ + const Section clipping = this->getIntersection(Rectangle(placement, accessor.getSize())); + + const size_t yb_min = clipping.topLeft.y / 8; + size_t yb_max = (clipping.bottomRight.y - 1) / 8; + + Point dataTopLeft = this->getSourceOrigin(placement); + size_t i_start = (dataTopLeft.y / 8) * accessor.getSize().x + dataTopLeft.x; + const uint8_t lshift_upper = placement.y & (digits - 1); // x & (digits - 1) coresponds x % digits with support for negative int + + if (lshift_upper) + { + // Split bytes, shift and reassembly + if (clipping.bottomRight.y == int16_t(R.y)) yb_max++; + const uint8_t rshift_lower = 8 - lshift_upper; + + if(this->color.getValue()) { + for (int16_t x = clipping.topLeft.x; x < clipping.bottomRight.x; x++) + { + size_t i = i_start++; + size_t yb = yb_min; + + if (clipping.topLeft.y > 0) + { + this->buffer[yb][x] |= accessor[i] << lshift_upper; + yb++; + } + while (yb < yb_max) + { + this->buffer[yb][x] |= accessor[i] >> rshift_lower; + i += accessor.getSize().x; + this->buffer[yb][x] |= accessor[i] << lshift_upper; + yb++; + } + if (clipping.bottomRight.y < int16_t(R.y)) + this->buffer[yb][x] |= accessor[i] >> rshift_lower; + } + } else { + for (int16_t x = clipping.topLeft.x; x < clipping.bottomRight.x; x++) + { + size_t i = i_start++; + size_t yb = yb_min; + + if (clipping.topLeft.y > 0) + { + this->buffer[yb][x] &= ~(accessor[i] << lshift_upper); + yb++; + } + while (yb < yb_max) + { + this->buffer[yb][x] &= ~(accessor[i] >> rshift_lower); + i += accessor.getSize().x; + this->buffer[yb][x] &= ~(accessor[i] << lshift_upper); + yb++; + } + if (clipping.bottomRight.y < int16_t(R.y)) + this->buffer[yb][x] &= ~(accessor[i] >> rshift_lower); + } + } + } else if (clipping.topLeft.y < clipping.bottomRight.y) + { + // Copy bytes as they are + if(this->color.getValue()) { + for (int16_t x = clipping.topLeft.x; x < clipping.bottomRight.x; x++) + { + size_t i = i_start++; + size_t yb = yb_min; + + while (yb < yb_max) + { + this->buffer[yb][x] |= accessor[i]; + i += accessor.getSize().x; + yb++; + } + this->buffer[yb][x] |= accessor[i]; + } + } else { + for (int16_t x = clipping.topLeft.x; x < clipping.bottomRight.x; x++) + { + size_t i = i_start++; + size_t yb = yb_min; + + while (yb < yb_max) + { + this->buffer[yb][x] &= ~accessor[i]; + i += accessor.getSize().x; + yb++; + } + this->buffer[yb][x] &= ~accessor[i]; + } + } + } +} \ No newline at end of file diff --git a/src/modm/ui/graphic/buffer_text_impl.hpp b/src/modm/ui/graphic/buffer_text_impl.hpp new file mode 100644 index 0000000000..9ba7ba7c85 --- /dev/null +++ b/src/modm/ui/graphic/buffer_text_impl.hpp @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2010-2011, 2013, Fabian Greif + * Copyright (c) 2012-2013, Niklas Hauser + * Copyright (c) 2014, Daniel Krebs + * Copyright (c) 2021, Thomas Sommer + * + * 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/. + */ +// ---------------------------------------------------------------------------- + +#pragma once +#include "buffer.hpp" + +using namespace modm::color; +using namespace modm::shape; + +namespace modm::graphic { + +template +void +Buffer::setFont(const uint8_t* font) +{ + if (modm::accessor::asFlash(font).isValid()) + { + this->font = modm::accessor::asFlash(font); + font_metadata.update(this->font); + } +} + +template +uint16_t +Buffer::getStringWidth(const char* s) const +{ + uint16_t width = 0; + + while (*s) + { + width += (*font)[offsetWidthTable + (uint8_t(*s) - font_metadata.first)]; + width += font_metadata.vspace; + s++; + } + + return width; +} + +template +uint16_t +Buffer::getStringWidth( + const char* s, const modm::accessor::Flash* font) +{ + uint16_t width = 0; + + const uint8_t vspace = (*font)[5]; + const uint8_t first = (*font)[6]; + + while (*s) + { + width += (*font)[offsetWidthTable + (uint8_t(*s) - first)]; + width += vspace; + s++; + } + + return width; +} + +template +void +Buffer::writeChar(char character) +{ + if (character == '\n') + { + linebreak(); + return; + } + + if (character == '\t') + { + // TODO + const uint8_t tab_width = 2 * font_metadata.height; + if (cursor.x < R.x + tab_width) + cursor.x += tab_width; + else + linebreak(); + return; + } + + // Character not contained in this font? + if (character < font_metadata.first or character >= (font_metadata.first + font_metadata.count)) + return; + + const uint8_t usedRows = (font_metadata.height + 7) / 8; // round up + + const uint8_t position = character - font_metadata.first + offsetWidthTable; + const uint8_t width = font[position]; + + uint16_t offset = font_metadata.count + offsetWidthTable; + for (uint8_t i = offsetWidthTable; i < position; i++) { offset += font[i] * usedRows; } + + if (auto_linebreak and cursor.x > R.x - width) + linebreak(); + + this->writeImage(ImageAccessor(font.getPointer() + offset, {width, font_metadata.height}, cursor)); + + // Add Whitespace + cursor.x += character < 128 ? width + font_metadata.vspace : width; +} + +} // namespace modm::graphic \ No newline at end of file diff --git a/src/modm/ui/graphic/canvas.hpp b/src/modm/ui/graphic/canvas.hpp new file mode 100644 index 0000000000..44dba76e6a --- /dev/null +++ b/src/modm/ui/graphic/canvas.hpp @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2021, Thomas Sommer + * + * 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/. + */ +// ---------------------------------------------------------------------------- + +#pragma once + +#include +#include + +namespace modm::graphic +{ +/** + * Baseclass for 2D Graphic Objects like Display and BufferMemory + * + * @tparam R Resolution - R.x: horizontal, R.y: vertical + * + * @author Thomas Sommer + * @ingroup modm_ui_graphic + */ +template +class Canvas +{ +public: + static constexpr shape::Size ResolutionVector = R; + + constexpr uint32_t + getPixels() const { return R.x * R.y; } + + virtual constexpr int16_t + getWidth() const { return R.x; } + + virtual constexpr int16_t + getHeight() const { return R.y; } + + virtual constexpr shape::Size + getSize() const { return R; } + + constexpr shape::Section + asSection() const + { return {{0, 0}, getSize()}; } + + constexpr shape::Section + getIntersection(shape::Section section) { + return {{ + std::clamp(section.topLeft.x, 0, getWidth()), + std::clamp(section.topLeft.y, 0, getHeight()) + }, + { + std::clamp(section.bottomRight.x, 0, getWidth()), + std::clamp(section.bottomRight.y, 0, getHeight()) + }}; + } + + void + setColormap(C* colormap) + { this->colormap = colormap; } + + // Set drawing color form colormap + void + setColor(const std::size_t color_idx) + { this->color = colormap[color_idx]; } + + // Set drawing color + void + setColor(const C color) + { this->color = color; } + +protected: + Canvas(C* colormap = nullptr) : colormap(colormap) {} + + C* colormap; + C color; + + static constexpr shape::Point + getSourceOrigin(shape::Point placement) { + return { + placement.x < 0 ? -placement.x : 0, + placement.y < 0 ? -placement.y : 0 + }; + } + + constexpr bool + xInCanvas(int16_t x) const + { return x >= 0 and x < int16_t(getWidth()); } + + constexpr bool + yInCanvas(int16_t y) const + { return y >= 0 and y < int16_t(getHeight()); } + + constexpr bool + pointInCanvas(shape::Point position) const + { return xInCanvas(position.x) and yInCanvas(position.y); } +}; +} // namespace modm::graphic \ No newline at end of file diff --git a/src/modm/ui/graphic/concepts.hpp b/src/modm/ui/graphic/concepts.hpp new file mode 100644 index 0000000000..43e8d38a66 --- /dev/null +++ b/src/modm/ui/graphic/concepts.hpp @@ -0,0 +1,26 @@ +#pragma once +#include + +namespace modm::graphic +{ + +template +concept GraphicBuffer = color::Color; +// TODO check B for existence of ResolutionVector + +template +concept GraphicDisplay = color::Color; +// TODO check D for existence of ResolutionVector + +/** + * @brief Function or functor comcept, returning a Color for each Point you pass + * + * @author Thomas Sommer + */ +template +concept ColorPattern = requires(F p) +{ + { p.operator()(shape::Point()) } -> color::Color; // -> std::convertible_to; +}; + +} // namespace modm::graphic \ No newline at end of file diff --git a/src/modm/ui/graphic/display.hpp b/src/modm/ui/graphic/display.hpp new file mode 100644 index 0000000000..5d9eb1d115 --- /dev/null +++ b/src/modm/ui/graphic/display.hpp @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2021, Thomas Sommer + * + * 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/. + */ +// ---------------------------------------------------------------------------- + +#pragma once + +#include + +#include + +#include +#include + +#include "canvas.hpp" +#include "buffer.hpp" +#include "concepts.hpp" + +namespace modm::graphic +{ + +enum OrientationFlags : uint8_t +{ + Portrait = Bit0, + TopDown = Bit1 +}; + +enum Orientation : uint8_t +{ + Landscape0, + Portrait90 = Portrait, + Landscape180 = TopDown, + Portrait270 = Portrait | TopDown +}; + +/** + * Baseclass for Graphic Display + * + * @tparam C One of color::* or bool + * @tparam R Resolution - R.x: horizontal, R.y: vertical + * @tparam CanPortrait Wether the Display supports Portrait90 / Portrait270 Orientation + * + * @author Thomas Sommer + * @ingroup modm_ui_graphic + */ + +// TODO Replace <.., bool CanPortrait> with <.., Orientation Supported> +// so constexpr and runtime getWidth() / getHeight() can be enabled more cleverly +// May inherit on modm::Matrix<..> or provide a conversion constructor for modm::Matrix<..> +template +class Display : virtual public Canvas +{ +public: + Orientation getOrientation() const + { return orientation; } + + int16_t + getWidth() const override + { return (orientation & OrientationFlags::Portrait) ? R.y : R.x; } + + int16_t + getHeight() const override + { return (orientation & OrientationFlags::Portrait) ? R.x : R.y; } + + Size + getSize() const override + { return (orientation & OrientationFlags::Portrait) ? R.swapped() : R; } + +protected: + Display() = default; + + Orientation orientation = Orientation::Landscape0; + + // Static variables for Resumable Functions + shape::Section clipping; +}; + +// Same like Display but doesn't overwrite getWidth() and getHeight() +template +class Display : virtual public Canvas +{ +public: + C color; + + Orientation getOrientation() const + { return orientation; } + +protected: + Display(C color) : color(color) {}; + + Orientation orientation = Orientation::Landscape0; + + // Static variables for Resumable Functions + Section clipping; +}; + +} // namespace modm \ No newline at end of file diff --git a/src/modm/ui/graphic/graphic.lb b/src/modm/ui/graphic/graphic.lb new file mode 100644 index 0000000000..fbcc79966f --- /dev/null +++ b/src/modm/ui/graphic/graphic.lb @@ -0,0 +1,31 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# +# Copyright (c) 2018, Niklas Hauser +# Copyright (c) 2021, Thomas Sommer +# +# 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/. +# ----------------------------------------------------------------------------- + +def init(module): + module.name = ":ui:graphic" + module.description = FileReader("graphic.md") + +def prepare(module, options): + module.depends( + ":architecture:accessor", + ":io", + ":math:utils", + ":ui:color", + ":ui:shape", + ":ui:font") + return True + +def build(env): + env.outbasepath = "modm/src/modm/ui/graphic" + env.copy(".") + env.copy("../graphic.hpp") diff --git a/src/modm/ui/graphic/graphic.md b/src/modm/ui/graphic/graphic.md new file mode 100644 index 0000000000..d563961e12 --- /dev/null +++ b/src/modm/ui/graphic/graphic.md @@ -0,0 +1,33 @@ +# Graphic + +Code for writing and drawing on graphical displays + +## Coordinate System + +{0, 0} + ┌─────────────────────┐ + │ ┌───➤ X │ + │ │ │ + │ 🠛 Y │ + │ │ + │ │ + │ │ + │ │ + └─────────────────────┘ + e.g. {127, 63} + +The size (width and height) of a graphics primitive always correspond +to its mathematical model, ignoring the rendered width. As everything +is drawn one pixel wide, the pixels will be rendered to the right and +below the mathematically defined points. + +## Example + +```cpp +#include + +buffer = GraphicBuffer +buffer << "Hello World" +ssd1306.write(buffer); + +′′′ \ No newline at end of file diff --git a/src/modm/ui/gui.hpp b/src/modm/ui/graphic/layout.hpp similarity index 57% rename from src/modm/ui/gui.hpp rename to src/modm/ui/graphic/layout.hpp index 10da89d433..bd414959a3 100644 --- a/src/modm/ui/gui.hpp +++ b/src/modm/ui/graphic/layout.hpp @@ -1,7 +1,5 @@ /* - * Copyright (c) 2014, Daniel Krebs - * Copyright (c) 2014, Niklas Hauser - * Copyright (c) 2014, Sascha Schade + * Copyright (c) 2021, Thomas Sommer * * This file is part of the modm project. * @@ -11,8 +9,16 @@ */ // ---------------------------------------------------------------------------- -#include "gui/types.hpp" -#include "gui/colorpalette.hpp" -#include "gui/view_stack.hpp" -#include "gui/view.hpp" -#include "gui/widgets.hpp" +#pragma once + +#include "buffer.hpp" + +namespace modm::graphic +{ +template +class Layout +{ +private: + BufferInterface *buffers[N]; +} +} // namespace modm::graphic \ No newline at end of file diff --git a/src/modm/ui/graphic/painter_local.hpp b/src/modm/ui/graphic/painter_local.hpp new file mode 100644 index 0000000000..631cb731f4 --- /dev/null +++ b/src/modm/ui/graphic/painter_local.hpp @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2021, Thomas Sommer + * + * 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/. + */ +// ---------------------------------------------------------------------------- + +#pragma once + +#include + +#include + +#include "concepts.hpp" +#include "buffer.hpp" +#include "style.hpp" + +namespace modm::graphic +{ +/** + * @brief Painter for BufferMemory stored in local RAM + * Can draw fundamental shapes: Point, Line, Rectangle, Circle, Ellipse + * Can write other buffers from RAM and images from FLASH. + * + * @tparam GB GraphicBuffer in RAM + * + * @author Thomas Sommer + * @ingroup modm_ui_graphic + * + * @see graphic::RemotePainter (same with Resumable Functions) + */ + +template +class LocalPainter : public GB +{ +public: + LocalPainter(GB::ColorType* colormap = nullptr) : GB(colormap) {}; + + /** + * @brief Fundamental drawing routines. Should be self-explained. + */ + // OPTIMIZE check if pass-by-reference helps + void draw(shape::Point point); + void draw(shape::Line line); + void draw(shape::Polygon polygon, Style style = Style::Outline); + void draw(shape::Rectangle rectangle, Style style = Style::Outline); + void draw(shape::Rectangle rectangle, uint16_t radius, Style style = Style::Outline); + void draw(shape::Circle circle, Style style = Style::Outline); + void draw(shape::Ellipse ellipse, Style style = Style::Outline); + + GB::ColorType get(const shape::Point& point) const; + + template + LocalPainter& operator=(const Buffer &other) + { + GB::template operator=(other); + return *this; + } +private: + void drawQuadPoints(shape::Point center, shape::Point point); +}; + +} // namespace modm:: graphic + +#include "painter_local_impl.hpp" +#include "painter_local_mono.hpp" \ No newline at end of file diff --git a/src/modm/ui/graphic/painter_local_impl.hpp b/src/modm/ui/graphic/painter_local_impl.hpp new file mode 100644 index 0000000000..e2188a8305 --- /dev/null +++ b/src/modm/ui/graphic/painter_local_impl.hpp @@ -0,0 +1,358 @@ +/* + * Copyright (c) 2009, Martin Rosekeit + * Copyright (c) 2009-2011, 2013, Fabian Greif + * Copyright (c) 2010, Georgi Grinshpun + * Copyright (c) 2012, Sascha Schade + * Copyright (c) 2012-2014, 2017, Niklas Hauser + * Copyright (c) 2014, Daniel Krebs + * Copyright (c) 2016, Antal Szabó + * Copyright (c) 2017, Christopher Durand + * Copyright (c) 2021, Thomas Sommer + * + * 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/. + */ +// ---------------------------------------------------------------------------- + +#pragma once +#include "painter_local.hpp" + +#include +#include + +#include "../font/fixed_width_5x8.hpp" + +using namespace modm::shape; +using namespace modm::color; + +namespace modm::graphic { + +template +void +LocalPainter::draw(Point point) +{ + if (this->pointInCanvas(point)) this->drawBlind(point); +}; + +template +void +LocalPainter::draw(Line line) +{ + if (line.isHorizontal()) + { + if(this->yInCanvas(line.start.y)) { + if (line.start.x > line.end.x) std::swap(line.start.x, line.end.x); + HLine hline( + {std::max(line.start.x, 0), line.start.y}, + std::min(line.end.x, this->ResolutionVector.x) + ); + this->drawBlind(hline); + } + } else if (line.isVertical()) + { + if(this->xInCanvas(line.start.x)) { + if (line.start.y > line.end.y) std::swap(line.start.y, line.end.y); + VLine vline( + {line.start.x, std::max(line.start.y, 0)}, + std::min(line.end.y, this->ResolutionVector.y) + ); + this->drawBlind(vline); + } + } else + { + line.clip(Section({0,0}, this->ResolutionVector)); + + // Bresenham algorithm + const Point deltaSteep = line.end - line.start; + const bool steep = std::abs(deltaSteep.y) > std::abs(deltaSteep.x); + if (steep) + { + line.start.swap(); + line.end.swap(); + } + if (line.start.x > line.end.x) + std::swap(line.start, line.end); + + const Point delta = line.end - line.start; + const int16_t step = delta.y > 0 ? 1 : -1; + int16_t error = delta.x / 2; + + if (steep) + { + line.start.swap(); + while (line.start.y <= line.end.x) + { + this->drawBlind(line.start); + line.start.y++; + + error -= std::abs(delta.y); + if (error < 0) + { + line.start.x += step; + error += delta.x; + } + } + } else + { + while (line.start.x <= line.end.x) + { + this->drawBlind(line.start); + line.start.x++; + + error -= std::abs(delta.y); + if (error < 0) + { + line.start.y += step; + error += delta.x; + } + } + } + } +} + +template +void +LocalPainter::draw(Polygon polygon, Style style) +{ + // IMPLEMENT draw(Polygon) +} + +template +void +LocalPainter::draw(Rectangle rectangle, Style style) +{ + const Section section = this->getIntersection(rectangle); + + if(style == Style::Outline) { + const Point bottomRight = rectangle.getBottomRight(); + + if (this->yInCanvas(rectangle.origin.y)) + this->drawBlind(HLine(section.topLeft, section.bottomRight.x)); + + if (this->yInCanvas(bottomRight.y)) + this->drawBlind(HLine(section.getBottomLeft(), section.bottomRight.x)); + + if (this->xInCanvas(rectangle.origin.x)) + this->drawBlind(VLine(section.topLeft, section.bottomRight.y)); + + if (this->xInCanvas(bottomRight.x)) + this->drawBlind(VLine(section.getTopRight(), section.bottomRight.y)); + } + else if(style == Style::Filled) { + this->drawBlind(section); + } +} + +template +void +LocalPainter::draw(Rectangle rectangle, uint16_t radius, Style style) +{ + if (radius == 0) { + draw(rectangle, style); + return; + } + + if(style == Style::Outline) { + const Point center = rectangle.getCenter(); + const Point circle_off = rectangle.size / 2 - Point(radius, radius); + + int16_t error = -radius; + Point p(radius, 0); + + while (p.x > p.y) + { + drawQuadPoints(center, p + circle_off); + drawQuadPoints(center, p.swapped() + circle_off); + + error += p.y; + ++p.y; + error += p.y; + + if (error >= 0) + error -= 2 * --p.x; + } + drawQuadPoints(center, p + circle_off); + + // FIXME Crashes if one of these lines cross screen-border + // OPTIMIZE There's potential for more recycling + if (this->yInCanvas(rectangle.origin.y)) + this->drawBlind(HLine({center.x - circle_off.x, rectangle.origin.y}, center.x + circle_off.x)); + + if (this->yInCanvas(rectangle.getBottomRight().y)) + this->drawBlind(HLine({center.x - circle_off.x, rectangle.getBottomRight().y}, center.x + circle_off.x)); + + if (this->xInCanvas(rectangle.origin.x)) + this->drawBlind(VLine({rectangle.origin.x, center.y - circle_off.y}, center.y + circle_off.y)); + + if (this->xInCanvas(rectangle.getBottomRight().x)) + this->drawBlind(VLine({rectangle.getBottomRight().x, center.y - circle_off.y}, center.y + circle_off.y)); + } + else if(style == Style::Filled) { + // IMPLEMENT filled, rounded Rectangle + draw(rectangle, style); + } +} + +template +void +LocalPainter::draw(Circle circle, Style style) +{ + if (circle.radius == 0) { + draw(circle.center); + return; + } + + if(style == Style::Outline) { + int16_t error = -circle.radius; + Point p(circle.radius, 0); + + while (p.x > p.y) + { + drawQuadPoints(circle.center, p); + drawQuadPoints(circle.center, p.swapped()); + + error += p.y; + ++p.y; + error += p.y; + + if (error >= 0) + error -= 2 * --p.x; + } + drawQuadPoints(circle.center, p); + } + else if (style == Style::Filled) { + int16_t f = 1 - circle.radius; + int16_t ddF_x = 0; + int16_t ddF_y = -2 * circle.radius; + int16_t x = 0; + int16_t y = circle.radius; + + Point start(circle.center.x, circle.center.y - circle.radius); + this->drawBlind(VLine(start, start.y + 2 * circle.radius)); + + while (x < y) + { + if (f >= 0) + { + y--; + ddF_y += 2; + f += ddF_y; + } + x++; + ddF_x += 2; + f += ddF_x + 1; + + start = circle.center + Point(x, -y); + this->drawBlind(VLine(start, start.y + 2 * y)); + start = circle.center + Point(y, -x); + this->drawBlind(VLine(start, start.y + 2 * x)); + start = circle.center - Point(x, y); + this->drawBlind(VLine(start, start.y + 2 * y)); + start = circle.center - Point(y, x); + this->drawBlind(VLine(start, start.y + 2 * x)); + } + } +} + +template +void +LocalPainter::draw(Ellipse ellipse, Style style) +{ + if(style == Style::Outline) { + int32_t rx_2 = ellipse.radius_x * ellipse.radius_x; + int32_t ry_2 = ellipse.radius_y * ellipse.radius_y; + + int16_t x = 0; + int16_t y = ellipse.radius_y; + + int32_t fx = 0; + int32_t fy = rx_2 * 2 * ellipse.radius_y; + + int32_t p = ry_2 - (rx_2 * ellipse.radius_y) + (rx_2 + 2) / 4; + + drawQuadPoints(ellipse.center, {x, y}); + while (fx < fy) + { + x++; + fx += ry_2 * 2; + + if (p < 0) + { + p += (fx + ry_2); + } else + { + y--; + fy -= rx_2 * 2; + p += (fx + ry_2 - fy); + } + + drawQuadPoints(ellipse.center, {x, y}); + } + + p = ((ry_2 * (4 * x * x + 4 * x + 1) / 2) + 2 * (rx_2 * (y - 1) * (y - 1)) - 2 * (rx_2 * ry_2) + + 1) / + 2; + + while (y > 0) + { + y--; + fy -= rx_2 * 2; + + if (p >= 0) + p += (rx_2 - fy); + else { + x++; + fx += ry_2 * 2; + p += (fx + rx_2 - fy); + } + + drawQuadPoints(ellipse.center, {x, y}); + } + } + else if (style == Style::Filled) { + // IMPLEMENT Ellipse Style::Filled; + draw(ellipse, Style::Outline); + } +} + +template +void +LocalPainter::drawQuadPoints(Point center, Point point) +{ + Point qpoint = center + point; + bool drawXpos = this->xInCanvas(qpoint.x); + bool drawXneg = this->xInCanvas(center.x - point.x); + + if(this->yInCanvas(qpoint.y)) { + if(drawXpos) + this->drawBlind(qpoint); + if(point.x != 0 and drawXneg) { + qpoint.x = center.x - point.x; + this->drawBlind(qpoint); + } + } + if(point.y != 0) { + qpoint = center - point; + if(this->yInCanvas(qpoint.y)) { + if(drawXneg) + this->drawBlind(qpoint); + if(point.x != 0 and drawXpos) { + qpoint.x = center.x + point.x; + this->drawBlind(qpoint); + } + } + } +} + +template +GB::ColorType +LocalPainter::get(const Point& point) const +{ + modm_assert(this->pointInCanvas(point), "LocalPainter", "get(Point)", "value out of range"); + return this->pointInCanvas(point) ? this->getBlind(point) : 0; +}; + +} // namespace modm::graphic \ No newline at end of file diff --git a/src/modm/ui/graphic/painter_local_mono.hpp b/src/modm/ui/graphic/painter_local_mono.hpp new file mode 100644 index 0000000000..331f91e17f --- /dev/null +++ b/src/modm/ui/graphic/painter_local_mono.hpp @@ -0,0 +1 @@ +// OPTIMIZE PainterLocal for speed \ No newline at end of file diff --git a/src/modm/ui/graphic/painter_remote.hpp b/src/modm/ui/graphic/painter_remote.hpp new file mode 100644 index 0000000000..497ad55e6e --- /dev/null +++ b/src/modm/ui/graphic/painter_remote.hpp @@ -0,0 +1,156 @@ +/* + * Copyright (c) 2021, Thomas Sommer + * + * 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/. + */ +// ---------------------------------------------------------------------------- + +#pragma once + +#include +#include + +#include "canvas.hpp" +#include "style.hpp" +#include + +namespace modm::graphic +{ + +/** + * @brief Painter for external attached memory, e.g. a Display. + * Can draw fundamental shapes: shape::Point, Line, Rectangle, Circle, Ellipse + * Can write other buffers from RAM and images from FLASH. + * + * @tparam GD Recipient display for the paintings + * + * @author Thomas Sommer + * @ingroup modm_ui_graphic + * + * @see graphic::LocalPainter (same without Resumable Functions) + */ + +template +class RemotePainter : public GD +{ +public: + using ColorType = GD::ColorType; + + void drawBlocking(shape::Point point) + { RF_CALL_BLOCKING(draw(point)); } + + void drawBlocking(shape::Line line) + { RF_CALL_BLOCKING(draw(line)); } + + void drawBlocking(shape::Rectangle rectangle, Style style = Style::Outline) + { RF_CALL_BLOCKING(draw(rectangle, style)); } + + void drawBlocking(shape::Rectangle rectangle, uint16_t radius, Style style = Style::Outline) + { RF_CALL_BLOCKING(draw(rectangle, radius, style)); } + + void drawBlocking(shape::Circle circle, Style style = Style::Outline) + { RF_CALL_BLOCKING(draw(circle, style)); } + + void drawBlocking(shape::Ellipse ellipse, Style style = Style::Outline) + { RF_CALL_BLOCKING(draw(ellipse, style)); } + + ColorType getBlocking(shape::Point point) + { return RF_CALL_BLOCKING(get(point)); } + + // TODO Export these Interfaces + template + void writeBlocking(BufferInterface &buffer, shape::Point placement = {0, 0}) + { RF_CALL_BLOCKING(write(buffer, placement)); } + + template + void writeBlocking(const uint8_t *addr, shape::Point placement = {0, 0}) + { RF_CALL_BLOCKING(write(addr, placement)); } + + /** + * @brief Fundamental drawing routines. Should be self-explained. + */ + ResumableResult + draw(shape::Point point); + + ResumableResult + draw(shape::Line line); + + ResumableResult + draw(shape::Rectangle rectangle, Style style = Style::Outline); + + ResumableResult + draw(shape::Rectangle rectangle, uint16_t radius, Style style = Style::Outline); + + ResumableResult + draw(shape::Circle circle, Style style = Style::Outline); + + modm ::ResumableResult + draw(shape::Ellipse ellipse, Style style = Style::Outline); + + ResumableResult + get(Point point) const; + + /** + * @brief Writes a buffer to remote location. If the other buffer is grayscale, + * the colors will be mapped using the colormap. + * + * @tparam CO Colortype of buffer + * @param buffer Interface to Buffer + * @param placement Write buffer to this position + */ + template + ResumableResult + write(BufferInterface &buffer, shape::Point placement = {0, 0}); + + /** + * @brief Writes an image to remote location. If the image is grayscale, + * the colors will be mapped using the colormap. + * + * @tparam CO Colortype of image + * @param buffer Address of the image in flash + * @param placement Write image to this position + */ + template + ResumableResult + write(const uint8_t *addr, shape::Point placement = {0, 0}); +private: + ResumableResult + drawQuadPoints(shape::Point center, shape::Point point); + + // Static variables for resumable functions + shape::Section section; + + union { + struct { + Line line; + Point delta; + bool steep; + int16_t step, error; + } l; // Line bresenhem + + struct { + Point bottomRight; + } r; + struct { + shape::Point point; + int16_t error; + } co; // Circle Outline + + struct { + int16_t f, ddF_x, ddF_y, x, y; + shape::Point start; + } cf; // Circle Filled + }; + + // Quad Points + Point qpoint; + bool drawXpos, drawXneg; +}; + +} // namespace modm::graphic + +#include "painter_remote_impl.hpp" \ No newline at end of file diff --git a/src/modm/ui/graphic/painter_remote_impl.hpp b/src/modm/ui/graphic/painter_remote_impl.hpp new file mode 100644 index 0000000000..03c0aebdf7 --- /dev/null +++ b/src/modm/ui/graphic/painter_remote_impl.hpp @@ -0,0 +1,400 @@ +/* + * Copyright (c) 2009, Martin Rosekeit + * Copyright (c) 2009-2011, 2013, Fabian Greif + * Copyright (c) 2010, Georgi Grinshpun + * Copyright (c) 2012, Sascha Schade + * Copyright (c) 2012-2014, 2017, Niklas Hauser + * Copyright (c) 2014, Daniel Krebs + * Copyright (c) 2016, Antal Szabó + * Copyright (c) 2017, Christopher Durand + * Copyright (c) 2021, Thomas Sommer + * + * 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/. + */ +// ---------------------------------------------------------------------------- + +#pragma once +#include "painter_remote.hpp" + +#include +#include + +using namespace modm::shape; + +namespace modm::graphic { + +template +modm::ResumableResult +RemotePainter::draw(Point point) +{ + RF_BEGIN(); + if (this->pointInCanvas(point)) + RF_CALL(GD::drawBlind(point)); + RF_END(); +}; + +template +modm::ResumableResult +RemotePainter::draw(Line line) +{ + RF_BEGIN(); + + if (line.isHorizontal()) + { + if(this->yInCanvas(line.start.y)) { + if (line.start.x > line.end.x) std::swap(line.start.x, line.end.x); + + RF_RETURN_CALL(GD::drawBlind( + HLine( + {std::max(line.start.x, 0), line.start.y}, + std::min(line.end.x, this->ResolutionVector.x) + ) + )); + } + } else if (line.isVertical()) + { + if(this->xInCanvas(line.start.x)) { + if (line.start.y > line.end.y) std::swap(line.start.y, line.end.y); + + RF_RETURN_CALL(GD::drawBlind( + VLine( + {line.start.x, std::max(line.start.y, 0)}, + std::min(line.end.y, this->ResolutionVector.y) + ) + )); + } + } else + { + l.line = line; + + l.line.clip(this->asSection()); + + // Bresenham algorithm + l.delta = l.line.end - l.line.start; + l.steep = std::abs(l.delta.y) > std::abs(l.delta.x); + if (l.steep) + { + l.line.start.swap(); + l.line.end.swap(); + } + if (l.line.start.x > l.line.end.x) + std::swap(line.start, line.end); + + l.delta = l.line.end - l.line.start; + l.step = l.delta.y > 0 ? 1 : -1; + l.error = l.delta.x / 2; + + if (l.steep) + { + while (l.line.start.x <= l.line.end.x) + { + RF_CALL(GD::drawBlind(l.line.start.swapped())); + l.line.start.x++; + + l.error -= std::abs(l.delta.y); + if (l.error < 0) + { + l.line.start.y += l.step; + l.error += l.delta.x; + } + } + } else + { + while (l.line.start.x <= l.line.end.x) + { + RF_CALL(GD::drawBlind(l.line.start)); + l.line.start.x++; + + l.error -= std::abs(l.delta.y); + if (l.error < 0) + { + l.line.start.y += l.step; + l.error += l.delta.x; + } + } + } + } + + RF_END(); +} + +template +modm::ResumableResult +RemotePainter::draw(Rectangle rectangle, Style style) +{ + RF_BEGIN(); + + section = this->getIntersection(rectangle); + + if (style == Style::Outline) + { + r.bottomRight = rectangle.getBottomRight(); + if (this->yInCanvas(rectangle.origin.y)) + RF_CALL(GD::drawBlind(HLine(section.topLeft, section.bottomRight.x - 1))); + + if (this->yInCanvas(r.bottomRight.y)) + RF_CALL(GD::drawBlind(HLine(section.getBottomLeft(), section.bottomRight.x - 1))); + + if (this->xInCanvas(rectangle.origin.x)) + RF_CALL(GD::drawBlind(VLine(section.topLeft, section.bottomRight.y - 1))); + + if (this->xInCanvas(r.bottomRight.x)) + RF_CALL(GD::drawBlind(VLine(section.getTopRight(), section.bottomRight.y - 1))); + + } else /* if (style == Style::Filled) */ + RF_CALL(GD::drawBlind(section)); + + RF_END(); +} + +template +modm::ResumableResult +RemotePainter::draw(Rectangle rectangle, uint16_t radius, Style style) +{ + RF_BEGIN(); + + if (radius == 0) + RF_RETURN_CALL(draw(rectangle, style)); + + if(style == Style::Outline) { + const Point center = rectangle.getCenter(); + const Point circle_off = rectangle.size / 2 - Point(radius, radius); + + int16_t error = -radius; + Point p(radius, 0); + + while (p.x > p.y) + { + RF_CALL(drawQuadPoints(center, p + circle_off)); + RF_CALL(drawQuadPoints(center, Point(p.y, p.x) + circle_off)); + + error += p.y; + ++p.y; + error += p.y; + + if (error >= 0) + error -= 2 * --p.x; + } + RF_CALL(drawQuadPoints(center, p + circle_off)); + + // FIXME Crashes if one of these lines cross screen-border + // OPTIMIZE There's potential for more recycling + if (this->yInCanvas(rectangle.origin.y)) + RF_CALL(GD::drawBlind( + HLine({center.x - circle_off.x, rectangle.origin.y}, center.x + circle_off.x) + )); + + if (this->yInCanvas(rectangle.getBottomRight().y)) + RF_CALL(GD::drawBlind( + HLine({center.x - circle_off.x, rectangle.getBottomRight().y}, center.x + circle_off.x) + )); + + if (this->xInCanvas(rectangle.origin.x)) + RF_CALL(GD::drawBlind( + VLine({rectangle.origin.x, center.y - circle_off.y}, center.y + circle_off.y) + )); + + if (this->xInCanvas(rectangle.getBottomRight().x)) + RF_CALL(GD::drawBlind( + VLine({rectangle.getBottomRight().x, center.y - circle_off.y}, center.y + circle_off.y) + )); + } + else if(style == Style::Filled) { + // IMPLEMENT filled, rounded Rectangle + RF_CALL(draw(rectangle, style)); + } + + RF_END(); +} + +template +modm::ResumableResult +RemotePainter::draw(Circle circle, Style style) +{ + RF_BEGIN(); + + if (circle.radius == 0) + RF_RETURN_CALL(draw(circle.center)); + + if (style == Style::Outline) + { + co.error = -circle.radius; + co.point = {circle.radius, 0}; + + while (co.point.x > co.point.y) + { + RF_CALL(drawQuadPoints(circle.center, co.point)); + RF_CALL(drawQuadPoints(circle.center, co.point.swapped())); + + co.error += co.point.y; + ++co.point.y; + co.error += co.point.y; + + if (co.error >= 0) co.error -= 2 * --co.point.x; + } + RF_CALL(drawQuadPoints(circle.center, co.point)); + } + else if (style == Style::Filled) { + cf.f = 1 - circle.radius; + cf.ddF_x = 0; + cf.ddF_y = -2 * circle.radius; + cf.x = 0; + cf.y = circle.radius; + + cf.start = {circle.center.x, circle.center.y - circle.radius}; + RF_CALL(GD::drawBlind(VLine(cf.start, cf.start.y + 2 * circle.radius))); + + while (cf.x < cf.y) + { + if (cf.f >= 0) + { + cf.y--; + cf.ddF_y += 2; + cf.f += cf.ddF_y; + } + cf.x++; + cf.ddF_x += 2; + cf.f += cf.ddF_x + 1; + + cf.start = circle.center + Point(cf.x, -cf.y); + RF_CALL(GD::drawBlind(VLine(cf.start, cf.start.y + 2 * cf.y))); + cf.start = circle.center + Point(cf.y, -cf.x); + RF_CALL(GD::drawBlind(VLine(cf.start, cf.start.y + 2 * cf.x))); + cf.start = circle.center - Point(cf.x, cf.y); + RF_CALL(GD::drawBlind(VLine(cf.start, cf.start.y + 2 * cf.y))); + cf.start = circle.center - Point(cf.y, cf.x); + RF_CALL(GD::drawBlind(VLine(cf.start, cf.start.y + 2 * cf.x))); + } + } + + RF_END(); +} + +template +modm::ResumableResult +RemotePainter::draw(Ellipse ellipse, Style style) +{ + RF_BEGIN(); + + if(style == Style::Outline) { + // IMPLEMENT RemotePainter brensenham ellipse +/* int32_t rx_2 = ellipse.radius_x * ellipse.radius_x; + int32_t ry_2 = ellipse.radius_y * ellipse.radius_y; + + int16_t x = 0; + int16_t y = ellipse.radius_y; + + int32_t fx = 0; + int32_t fy = rx_2 * 2 * ellipse.radius_y; + + int32_t p = ry_2 - (rx_2 * ellipse.radius_y) + (rx_2 + 2) / 4; + + RF_CALL(drawQuadPoints(ellipse.center, x, y)); + while (fx < fy) + { + x++; + fx += ry_2 * 2; + + if (p < 0) + { + p += (fx + ry_2); + } else + { + y--; + fy -= rx_2 * 2; + p += (fx + ry_2 - fy); + } + + RF_CALL(drawQuadPoints(ellipse.center, x, y)); + } + + p = ((ry_2 * (4 * x * x + 4 * x + 1) / 2) + 2 * (rx_2 * (y - 1) * (y - 1)) - 2 * (rx_2 * ry_2) + + 1) / + 2; + + while (y > 0) + { + y--; + fy -= rx_2 * 2; + + if (p >= 0) + p += (rx_2 - fy); + else { + x++; + fx += ry_2 * 2; + p += (fx + rx_2 - fy); + } + + RF_CALL(drawQuadPoints(ellipse.center, x, y)); */ + } + else if(style == Style::Filled) { + // IMPLEMENT Ellipse Style::Filled; + RF_CALL(draw(ellipse, Style::Outline)); + } + + RF_END(); +} + +template +modm::ResumableResult +RemotePainter::drawQuadPoints(Point center, Point point) +{ + RF_BEGIN(); + + qpoint = center + point; + drawXpos = this->xInCanvas(qpoint.x); + drawXneg = this->xInCanvas(center.x - point.x); + + if(this->yInCanvas(qpoint.y)) { + if(drawXpos) + RF_CALL(GD::drawBlind(qpoint)); + if(point.x != 0 and drawXneg) { + qpoint.x = center.x - point.x; + RF_CALL(GD::drawBlind(qpoint)); + } + } + if(point.y != 0) { + qpoint = center - point; + if(this->yInCanvas(qpoint.y)) { + if(drawXneg) + RF_CALL(GD::drawBlind(qpoint)); + if(point.x != 0 and drawXpos) { + qpoint.x = center.x + point.x; + RF_CALL(GD::drawBlind(qpoint)); + } + } + } + + RF_END(); +} + +template +modm::ResumableResult +RemotePainter::get(Point point) const +{ + RF_BEGIN(); + if(this->pointInCanvas(point)) RF_RETURN_CALL(this->getBlind(point)); + RF_END_RETURN(0); +} + +template +template +modm::ResumableResult +RemotePainter::write(BufferInterface &buffer, Point placement) { + RF_BEGIN(); + RF_END_RETURN_CALL(this->writeImage(ImageAccessor(&buffer, placement))); +} + +template +template +modm::ResumableResult +RemotePainter::write(const uint8_t *addr, Point placement) { + RF_BEGIN(); + RF_END_RETURN_CALL(this->writeImage(ImageAccessor(addr, placement))); +} + +} // namespace modm::graphic \ No newline at end of file diff --git a/src/modm/ui/graphic/pattern.hpp b/src/modm/ui/graphic/pattern.hpp new file mode 100644 index 0000000000..3b34c72fcc --- /dev/null +++ b/src/modm/ui/graphic/pattern.hpp @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2021, Thomas Sommer + * + * 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/. + */ +// ---------------------------------------------------------------------------- + +#pragma once + +#include +#include + +using namespace modm::color; +using namespace modm::shape; + +namespace modm::graphic::pattern { + + // Small collection of common patterns for inspiration + // You can pass these to writePattern(...) methods as second argument + constexpr int width = 16; + + constexpr auto solid = [](Point) { return html::MediumSpringGreen; }; + constexpr auto stripes_horizontal = [](Point p) { return p.x % (2 * width) < width ? html::Yellow : html::Black; }; + constexpr auto stripes_vertical = [](Point p) { return p.y % (2 * width) < width ? html::Yellow : html::Black; }; + constexpr auto stripes_diag_left = [](Point p) { return (p.x + p.y) % (2 * width) < width ? html::Yellow : html::Black; }; + constexpr auto stripes_diag_right = [](Point p) { return (p.x - p.y) % (2 * width) < width ? html::Yellow : html::Black; }; + + constexpr auto gradient_hsv = [](Point p) { return Rgb888(Hsv888(p.x, p.y, 255)); }; + + constexpr auto gradient_red = [](Point p) { return Rgb888(p.x + p.y / width, 30, 30); }; + constexpr auto gradient_green = [](Point p) { return Rgb888(30, p.x + p.y / width, 30); }; + constexpr auto gradient_blue = [](Point p) { return Rgb888(30, 30, p.x + p.y / width); }; + + constexpr auto noize = [](Point) { return Rgb888(rand(), rand(), rand()); }; + constexpr auto white_noize = [](Point) { return GrayD<8>(rand()); }; + + // Rgb888 Mandelbrot(Point p) { + // return ... TODO + // } +} \ No newline at end of file diff --git a/src/modm/ui/graphic/style.hpp b/src/modm/ui/graphic/style.hpp new file mode 100644 index 0000000000..02ea5add02 --- /dev/null +++ b/src/modm/ui/graphic/style.hpp @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2021, Thomas Sommer + * + * 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/. + */ +// ---------------------------------------------------------------------------- + +#pragma once + +namespace modm::graphic +{ +enum class Style : uint8_t +{ + Outline, + Filled, + // Outline_Dotted, + // Outline_Dashed, +}; +} // namespace modm::graphic \ No newline at end of file diff --git a/src/modm/ui/display/image.hpp b/src/modm/ui/image.hpp similarity index 100% rename from src/modm/ui/display/image.hpp rename to src/modm/ui/image.hpp diff --git a/src/modm/ui/display/image/SConscript.generate b/src/modm/ui/image/SConscript.generate similarity index 100% rename from src/modm/ui/display/image/SConscript.generate rename to src/modm/ui/image/SConscript.generate diff --git a/src/modm/ui/display/image/home_16x16.cpp b/src/modm/ui/image/home_16x16.cpp similarity index 100% rename from src/modm/ui/display/image/home_16x16.cpp rename to src/modm/ui/image/home_16x16.cpp diff --git a/src/modm/ui/display/image/home_16x16.hpp b/src/modm/ui/image/home_16x16.hpp similarity index 100% rename from src/modm/ui/display/image/home_16x16.hpp rename to src/modm/ui/image/home_16x16.hpp diff --git a/src/modm/ui/image/image.lb b/src/modm/ui/image/image.lb new file mode 100644 index 0000000000..5f3f6447c4 --- /dev/null +++ b/src/modm/ui/image/image.lb @@ -0,0 +1,27 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# +# Copyright (c) 2021, Thomas Sommer +# +# 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/. +# ----------------------------------------------------------------------------- + +def init(module): + module.name = ":ui:image" + module.description = """ +# Image + +Image examples to be written on graphic-displays +""" + +def prepare(module, options): + return True + +def build(env): + env.outbasepath = "modm/src/modm/ui/image" + env.copy(".") + env.copy("../image.hpp") diff --git a/src/modm/ui/display/image/logo_eurobot_90x64.cpp b/src/modm/ui/image/logo_eurobot_90x64.cpp similarity index 100% rename from src/modm/ui/display/image/logo_eurobot_90x64.cpp rename to src/modm/ui/image/logo_eurobot_90x64.cpp diff --git a/src/modm/ui/display/image/logo_eurobot_90x64.hpp b/src/modm/ui/image/logo_eurobot_90x64.hpp similarity index 100% rename from src/modm/ui/display/image/logo_eurobot_90x64.hpp rename to src/modm/ui/image/logo_eurobot_90x64.hpp diff --git a/src/modm/ui/display/image/logo_rca_90x64.cpp b/src/modm/ui/image/logo_rca_90x64.cpp similarity index 100% rename from src/modm/ui/display/image/logo_rca_90x64.cpp rename to src/modm/ui/image/logo_rca_90x64.cpp diff --git a/src/modm/ui/display/image/logo_rca_90x64.hpp b/src/modm/ui/image/logo_rca_90x64.hpp similarity index 100% rename from src/modm/ui/display/image/logo_rca_90x64.hpp rename to src/modm/ui/image/logo_rca_90x64.hpp diff --git a/src/modm/ui/display/image/skull_64x64.cpp b/src/modm/ui/image/skull_64x64.cpp similarity index 100% rename from src/modm/ui/display/image/skull_64x64.cpp rename to src/modm/ui/image/skull_64x64.cpp diff --git a/src/modm/ui/display/image/skull_64x64.hpp b/src/modm/ui/image/skull_64x64.hpp similarity index 100% rename from src/modm/ui/display/image/skull_64x64.hpp rename to src/modm/ui/image/skull_64x64.hpp diff --git a/src/modm/ui/shape.hpp b/src/modm/ui/shape.hpp new file mode 100644 index 0000000000..2fc39c7a45 --- /dev/null +++ b/src/modm/ui/shape.hpp @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2021, Thomas Sommer + * + * 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 "shape/point.hpp" +#include "shape/line.hpp" +#include "shape/polygon.hpp" +#include "shape/rectangle.hpp" +#include "shape/circle.hpp" +#include "shape/ellipse.hpp" + +#include "shape/section.hpp" diff --git a/src/modm/ui/shape/circle.hpp b/src/modm/ui/shape/circle.hpp new file mode 100644 index 0000000000..d48b3aa9a4 --- /dev/null +++ b/src/modm/ui/shape/circle.hpp @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2021, Thomas Sommer + * + * 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/. + */ +// ---------------------------------------------------------------------------- + +#pragma once + +#include "point.hpp" +#include "rectangle.hpp" + +#include +namespace modm::shape +{ + +class Rectangle; +class Circle +{ +public: + Point center; + uint16_t radius; + + constexpr Circle() = default; + + /** + * @brief Construct a new Circle object + * + * @param center Center of the circle + * @param radius Radius of the circle + */ + constexpr Circle(Point center, uint16_t radius) + : center(center), radius(radius) + {} + + template + Circle(Circle2D &circle2d) : center(circle2d.center), radius(circle2d.radius) {} +}; +} // namespace modm::shape \ No newline at end of file diff --git a/src/modm/ui/shape/ellipse.hpp b/src/modm/ui/shape/ellipse.hpp new file mode 100644 index 0000000000..b5411c5de0 --- /dev/null +++ b/src/modm/ui/shape/ellipse.hpp @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2021, Thomas Sommer + * + * 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/. + */ +// ---------------------------------------------------------------------------- + +#pragma once + +#include "rectangle.hpp" +#include "section.hpp" + +namespace modm::shape +{ + +class Rectangle; +class Section; + +class Ellipse +{ +public: + Point center; + uint16_t radius_x, radius_y; + + constexpr Ellipse() = default; + + constexpr Ellipse(Point center, uint16_t radius_x, uint16_t radius_y) + : center(center), radius_x(radius_x), radius_y(radius_y) + {} +}; +} // namespace modm::shape \ No newline at end of file diff --git a/src/modm/ui/shape/line.hpp b/src/modm/ui/shape/line.hpp new file mode 100644 index 0000000000..c15d20abb9 --- /dev/null +++ b/src/modm/ui/shape/line.hpp @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2021, Thomas Sommer + * + * 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/. + */ +// ---------------------------------------------------------------------------- + +#pragma once + +#include "section.hpp" + +#include +namespace modm::shape +{ + +class Section; + +class Line +{ +public: + Point start, end; + + constexpr Line() = default; + + /** + * @brief Construct a new Line object + * + * @param start Start point of the line + * @param end End point of the line + */ + constexpr Line(Point start, Point end) : start(start), end(end) {} + + // Convertion + // template + // Line(Line2D &line2d) + + void + clip(Section section) { + // FIXME Not working when line doesn't intersect with section at all + + const Point axis = end - start; + start = clipPoint(start, section, axis); + end = clipPoint(end, section, axis); + } + + constexpr bool + isHorizontal() const + { return start.y == end.y; } + + constexpr bool + isVertical() const + { return start.x == end.x; } + +private: + // Moves point along axis to make it intersect with section + Point + clipPoint(Point point, const Section section, const Point axis) + { + if (point.x < section.topLeft.x) + { + point.y += (section.topLeft.x - point.x) * axis.y / axis.x; + point.x = section.topLeft.x; + } else if (point.x >= section.bottomRight.x) + { + point.y += (section.bottomRight.x - point.x) * axis.y / axis.x; + point.x = section.bottomRight.x - 1; + } + + if (point.y < section.topLeft.y) + { + point.x += (section.topLeft.y - point.y) * axis.x / axis.y; + point.y = section.topLeft.y; + } else if (point.y >= section.bottomRight.y) + { + point.x += (section.bottomRight.y - point.y) * axis.x / axis.y; + point.y = section.bottomRight.y - 1; + } + + return point; + } +}; + +class HLine +{ +public: + Point start; + uint16_t end_x; + + constexpr HLine() = default; + constexpr HLine(Point start, uint16_t end_x) : start(start), end_x(end_x) {} + + // Conversion constructor + constexpr HLine(Line line) : start(line.start), end_x(line.end.x) {} +}; + +class VLine +{ +public: + Point start; + uint16_t end_y; + + constexpr VLine() = default; + constexpr VLine(Point start, uint16_t end_y) : start(start), end_y(end_y) {} + + // Conversion constructor + constexpr VLine(Line line) : start(line.start), end_y(line.end.y) {} +}; +} // namespace modm \ No newline at end of file diff --git a/src/modm/ui/shape/point.hpp b/src/modm/ui/shape/point.hpp new file mode 100644 index 0000000000..3c524c038e --- /dev/null +++ b/src/modm/ui/shape/point.hpp @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2021, Thomas Sommer + * + * 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/. + */ +// ---------------------------------------------------------------------------- + +#pragma once + +#include + +namespace modm::shape +{ + +class Point : public Vector +{ +public: + constexpr Point() = default; + + // Allow arbitray arithmetic Types for Point-construction + // This suspresses "narrowing conversion" compiler warnings + template + requires std::is_arithmetic_v and std::is_arithmetic_v + constexpr Point(T x, U y) : Vector(x, y){}; + + template + requires std::is_arithmetic_v + constexpr Point(Vector vector) : Vector(vector){}; + + modm_always_inline + void swap() { + int16_t temp = x; + x = y; + y = temp; + } + + modm_always_inline + constexpr Point swapped() const { + return {y, x}; + } +}; + +using Size = Point; + +} // namespace modm::shape \ No newline at end of file diff --git a/test/modm/math/saturated/saturated_test.hpp b/src/modm/ui/shape/polygon.hpp similarity index 55% rename from test/modm/math/saturated/saturated_test.hpp rename to src/modm/ui/shape/polygon.hpp index e96ede3095..4e9d8d3742 100644 --- a/test/modm/math/saturated/saturated_test.hpp +++ b/src/modm/ui/shape/polygon.hpp @@ -1,7 +1,5 @@ /* - * Copyright (c) 2009, Martin Rosekeit - * Copyright (c) 2009-2010, Fabian Greif - * Copyright (c) 2012, Niklas Hauser + * Copyright (c) 2021, Thomas Sommer * * This file is part of the modm project. * @@ -11,15 +9,17 @@ */ // ---------------------------------------------------------------------------- -#include +#pragma once -/// @ingroup modm_test_test_math -class SaturatedTest : public unittest::TestSuite +namespace modm::shape +{ +class Polygon { public: - void - testSigned8bit(); + Point a, b, c; + + constexpr Polygon() = default; - void - testUnsigned8bit(); + constexpr Polygon(Point a, Point b, Point c) : a(a), b(b), c(c) {} }; +} // namespace modm \ No newline at end of file diff --git a/src/modm/ui/shape/rectangle.hpp b/src/modm/ui/shape/rectangle.hpp new file mode 100644 index 0000000000..2668c9cb14 --- /dev/null +++ b/src/modm/ui/shape/rectangle.hpp @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2021, Thomas Sommer + * + * 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/. + */ +// ---------------------------------------------------------------------------- + +#pragma once + +#include "point.hpp" + +namespace modm::shape +{ + +class Rectangle +{ +public: + Point origin; + Size size; + + constexpr Rectangle() = default; + + /** + * @brief Construct a new Rectangle object + * + * @param origin Top left corner of the Rectangle + * @param size Size x and y of the Rectangle + */ + constexpr Rectangle(Point origin, Size size) : origin(origin), size(size) {} + + Point + getBottomRight() const { + return origin + size; + } + + Point + getCenter() const { + return origin + size / 2; + } +}; +} // namespace modm::shape \ No newline at end of file diff --git a/src/modm/ui/shape/section.hpp b/src/modm/ui/shape/section.hpp new file mode 100644 index 0000000000..b098180eb6 --- /dev/null +++ b/src/modm/ui/shape/section.hpp @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2021, Thomas Sommer + * + * 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/. + */ +// ---------------------------------------------------------------------------- + +#pragma once + +#include "circle.hpp" +#include "point.hpp" +#include "rectangle.hpp" + +namespace modm::shape +{ + +// forward declarations for convertion constructors +class Rectangle; +class Circle; + +class Section +{ +public: + Point topLeft, bottomRight; + + constexpr Section() = default; + + constexpr Section(Point topLeft, Point bottomRight) : topLeft(topLeft), bottomRight(bottomRight) + {} + + // Conversion constructors + constexpr Section(Rectangle rectangle) + : topLeft(rectangle.origin), bottomRight(rectangle.origin + rectangle.size) + {} + +/* constexpr Section(Circle circle) + { + Point half_size(circle.radius, circle.radius); + topLeft = circle.center - half_size; + bottomRight = circle.center + half_size; + } */ + + constexpr Point + getTopRight() const { + return {bottomRight.x, topLeft.y}; + } + + constexpr Point + getBottomLeft() const { + return {topLeft.x, bottomRight.y}; + } + + constexpr uint16_t + getWidth() const + { return bottomRight.x - topLeft.x; } + + constexpr uint16_t + getHeight() const + { return bottomRight.y - topLeft.y; } +}; +} // namespace modm::shape \ No newline at end of file diff --git a/src/modm/ui/shape/shape.lb b/src/modm/ui/shape/shape.lb new file mode 100644 index 0000000000..c3622cbb10 --- /dev/null +++ b/src/modm/ui/shape/shape.lb @@ -0,0 +1,28 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# +# Copyright (c) 2021, Thomas Sommer +# +# 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/. +# ----------------------------------------------------------------------------- + +def init(module): + module.name = ":ui:shape" + module.description = """ +# Shape + +Primitive geometric shapes like Point, Line, Rectangle, Circle, Ellipse, ... +""" + +def prepare(module, options): + module.depends(":math:geometry") + return True + +def build(env): + env.outbasepath = "modm/src/modm/ui/shape" + env.copy(".") + env.copy("../shape.hpp") diff --git a/test/modm/math/module.lb b/test/modm/math/module.lb index 90f8744bff..fbb8799ef3 100644 --- a/test/modm/math/module.lb +++ b/test/modm/math/module.lb @@ -20,7 +20,7 @@ def prepare(module, options): "modm:math:filter", "modm:math:geometry", "modm:math:interpolation", - "modm:math:saturated", + "modm:math:saturation", "modm:math:matrix", "modm:math:algorithm", "modm:math:utils") diff --git a/test/modm/math/saturated/saturated_test.cpp b/test/modm/math/saturated/saturated_test.cpp deleted file mode 100644 index 52abe31590..0000000000 --- a/test/modm/math/saturated/saturated_test.cpp +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (c) 2009, Martin Rosekeit - * Copyright (c) 2009-2010, Fabian Greif - * Copyright (c) 2012, Niklas Hauser - * - * 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 "saturated_test.hpp" - -void -SaturatedTest::testSigned8bit() -{ - //TEST_FAIL("TODO"); - -} - -void -SaturatedTest::testUnsigned8bit() -{ - modm::Saturated x; - modm::Saturated y(100); - - TEST_ASSERT_EQUALS(x.getValue(), 0); - TEST_ASSERT_EQUALS(y.getValue(), 100); - - x = 200; - - TEST_ASSERT_EQUALS(x.getValue(), 200); - - x += y; - - TEST_ASSERT_EQUALS(x.getValue(), 255); - - x = 10; - y = 20; - x -= y; - - TEST_ASSERT_EQUALS(x.getValue(), 0); - - modm::Saturated z; - - x = 20; - y = 10; - - z = x + y; - - TEST_ASSERT_EQUALS(x.getValue(), 20); - TEST_ASSERT_EQUALS(y.getValue(), 10); - TEST_ASSERT_EQUALS(z.getValue(), 30); - - z = x - y; - - TEST_ASSERT_EQUALS(x.getValue(), 20); - TEST_ASSERT_EQUALS(y.getValue(), 10); - TEST_ASSERT_EQUALS(z.getValue(), 10); - - y = z - x; - - TEST_ASSERT_EQUALS(x.getValue(), 20); - TEST_ASSERT_EQUALS(y.getValue(), 0); - TEST_ASSERT_EQUALS(z.getValue(), 10); - - x = -z; - - TEST_ASSERT_EQUALS(x.getValue(), 0); - - y = 200; - //x = abs(y); - x = y; - x.absolute(); - - TEST_ASSERT_EQUALS(x.getValue(), 200); -} diff --git a/test/modm/math/saturation/saturation_test.hpp b/test/modm/math/saturation/saturation_test.hpp new file mode 100644 index 0000000000..d72f4483e1 --- /dev/null +++ b/test/modm/math/saturation/saturation_test.hpp @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2021, Thomas Sommer + * 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 + +#undef MODM_LOG_LEVEL +#define MODM_LOG_LEVEL modm::log::DEBUG + +/// @ingroup modm_test_test_math +class SaturatedTest : public unittest::TestSuite +{ +public: + template + void + testGeneric(); + + void + test_uint8_t__int16_t() { + MODM_LOG_INFO << __FUNCTION__ << modm::endl; + testGeneric(); + } + + test_reference_all_uint8_t() { + uint8_t u8; + Saturated<&uint8_t> a(u8); + } + +/* void + test_all_uint8_t() + { + MODM_LOG_INFO << __FUNCTION__ << modm::endl; + testGeneric(); + } + + void + test_all_int8_t() + { + MODM_LOG_INFO << __FUNCTION__ << modm::endl; + testGeneric(); + } + + void + test_all_uint16_t() + { + MODM_LOG_INFO << __FUNCTION__ << modm::endl; + testGeneric(); + } + + void + test_all_int16_t() + { + MODM_LOG_INFO << __FUNCTION__ << modm::endl; + testGeneric(); + } */ +}; + +#include "saturation_test_impl.hpp" \ No newline at end of file diff --git a/test/modm/math/saturation/saturation_test_impl.hpp b/test/modm/math/saturation/saturation_test_impl.hpp new file mode 100644 index 0000000000..e061cd36c3 --- /dev/null +++ b/test/modm/math/saturation/saturation_test_impl.hpp @@ -0,0 +1,72 @@ +#include +#include + +#include + +using namespace std; + +template +void +SaturatedTest::testGeneric() +{ + static constexpr A a_big = numeric_limits::max() - 23; + static constexpr A a_small = numeric_limits::min() + 21; + + static constexpr B b_big = numeric_limits::max() - 17; + static constexpr B b_small = numeric_limits::min() + 15; + + static constexpr C c_big = numeric_limits::max() - 7; + static constexpr C c_small = numeric_limits::min() + 5; + + modm::Saturated a; + modm::Saturated b(b_small); + // modm::Saturated c(b); + + TEST_ASSERT_EQUALS(a.getValue(), 0); + + // modm::Saturated a2(a); + // TEST_ASSERT_EQUALS(a, a2); // requires Saturated::operator<<() + TEST_ASSERT_EQUALS(b.getValue(), b_small); + // TEST_ASSERT_EQUALS(c.getValue(), max(numeric_limits::min(), b_small)); + + a = a_big; + + TEST_ASSERT_EQUALS(a.getValue(), a_big); + + // a += b; + + // TEST_ASSERT_EQUALS(a.getValue(), std::max(numeric_limits::max(), a_big + b_big)); + + /* x = 10; + y = 20; + x -= y; + + TEST_ASSERT_EQUALS(x.getValue(), 0); + + modm::Saturated z; + + x = 20; + y = 10; + + z = x + y; + + TEST_ASSERT_EQUALS(x.getValue(), 20); + TEST_ASSERT_EQUALS(y.getValue(), 10); + TEST_ASSERT_EQUALS(z.getValue(), 30); + + z = x - y; + + TEST_ASSERT_EQUALS(x.getValue(), 20); + TEST_ASSERT_EQUALS(y.getValue(), 10); + TEST_ASSERT_EQUALS(z.getValue(), 10); + + y = z - x; + + TEST_ASSERT_EQUALS(x.getValue(), 20); + TEST_ASSERT_EQUALS(y.getValue(), 0); + TEST_ASSERT_EQUALS(z.getValue(), 10); + + x = -z; + + TEST_ASSERT_EQUALS(x.getValue(), 0); */ +} \ No newline at end of file diff --git a/test/modm/ui/color/color_test.cpp b/test/modm/ui/color/color_test.cpp index ce4aca9a24..1cab7864d4 100644 --- a/test/modm/ui/color/color_test.cpp +++ b/test/modm/ui/color/color_test.cpp @@ -15,101 +15,110 @@ #include #include +using namespace modm; using namespace modm::color; -void ColorTest::testRgbCopyConstructors() { - RgbT rgb8(html::Orchid); - RgbT rgb8_b(rgb8); +void ColorTest::testGrayConstructors() { + Gray8 gray8(127); + Gray8 gray8_b(gray8); + TEST_ASSERT_EQUALS(gray8, gray8_b); + + Gray4 gray4(7); + gray4 += 3; + TEST_ASSERT_EQUALS(gray4.getValue(), 10); + gray4 -= 1; + TEST_ASSERT_EQUALS(gray4.getValue(), 9); + gray4 -= 42; // under-saturation + TEST_ASSERT_EQUALS(gray4.getValue(), 0); + gray4 += 66; // over-saturation + TEST_ASSERT_EQUALS(gray4.getValue(), 0b00001111); + gray4 -= 3; + TEST_ASSERT_EQUALS(gray4.getValue(), 0b00001100); + + // not supported + // gray4 -= -6; // another over-saturation + // TEST_ASSERT_EQUALS(gray4.getValue(), 0b00001111); + + + gray8 = gray4; // upscaling + TEST_ASSERT_EQUALS(gray8.getValue(), 0b11001100); + GrayD<13> gray13 = gray4; // more upscaling + TEST_ASSERT_EQUALS(gray13.getValue(), 0b0001100110011000); // last digit rounds down for odd D + gray4 = gray13; // downscaling + TEST_ASSERT_EQUALS(gray4.getValue(), 0b00001100); +} + +void ColorTest::testRgbConstructors() { + Rgb888 rgb8(html::Orchid); + Rgb888 rgb8_b(rgb8); TEST_ASSERT_EQUALS(rgb8, rgb8_b); - RgbT rgb16(rgb8); - TEST_ASSERT_EQUALS(uint16_t(rgb8.red) << 8, rgb16.red); - TEST_ASSERT_EQUALS(uint16_t(rgb8.green) << 8, rgb16.green); - TEST_ASSERT_EQUALS(uint16_t(rgb8.blue) << 8, rgb16.blue); + Rgb161616 rgb16(rgb8); - RgbT rgb8_c(rgb16); + Rgb888 rgb8_c(rgb16); TEST_ASSERT_EQUALS(rgb8, rgb8_c); } -void ColorTest::testHsvCopyConstructors() { - HsvT hsv8(html::Orchid); - HsvT hsv8_b(hsv8); +void ColorTest::testHsvConstructors() { + Hsv888 hsv8(html::Orchid); + Hsv888 hsv8_b(hsv8); TEST_ASSERT_EQUALS(hsv8, hsv8_b); - HsvT hsv16(hsv8); - TEST_ASSERT_EQUALS(uint16_t(hsv8.hue) << 8, hsv16.hue); - TEST_ASSERT_EQUALS(uint16_t(hsv8.saturation) << 8, hsv16.saturation); - TEST_ASSERT_EQUALS(uint16_t(hsv8.value) << 8, hsv16.value); + Hsv161616 hsv16(hsv8); - HsvT hsv8_c(hsv16); + Hsv888 hsv8_c(hsv16); TEST_ASSERT_EQUALS(hsv8, hsv8_c); } -void ColorTest::testBrightnessCopyConstructors() { - BrightnessT brightness8(127); - BrightnessT brightness8_b(brightness8); - TEST_ASSERT_EQUALS(brightness8.value, brightness8_b.value); - - BrightnessT brightness16(brightness8); - TEST_ASSERT_EQUALS(uint16_t(brightness8.value) << 8, brightness16.value); - - BrightnessT brightness8_c(brightness16); - TEST_ASSERT_EQUALS(brightness8.value, brightness8_c.value); -} - void ColorTest::testConvertion_8bit() { - RgbT rgb(124, 128, 10); + Rgb888 rgb(124, 128, 10); - HsvT hsv(rgb); - TEST_ASSERT_EQUALS(hsv.hue, 43); - TEST_ASSERT_EQUALS(hsv.saturation, 235); - TEST_ASSERT_EQUALS(hsv.value, 128); + Hsv888 hsv(rgb); + TEST_ASSERT_EQUALS(hsv.getHue(), 43); + TEST_ASSERT_EQUALS(hsv.getSaturation(), 235); + TEST_ASSERT_EQUALS(hsv.getValue(), 128); - BrightnessT brightness(rgb); - TEST_ASSERT_EQUALS(brightness.value, 118); + Gray8 gray(rgb); + TEST_ASSERT_EQUALS(gray.getValue(), 118); } -// TODO 16bit convertion not yet working -// see hsv_impl.hpp and rgb_impl.hpp -// void ColorTest::testConvertion_16bit() -// { -// RgbT rgb8(html::Orchid); -// HsvT hsv8(rgb8); -// HsvT hsv16(hsv8); -// RgbT rgb16(rgb8); -// HsvT hsv16_b(rgb16); +void ColorTest::testConvertion_16bit() +{ + Rgb888 rgb8(html::Orchid); + Hsv888 hsv8(rgb8); + Hsv161616 hsv16(hsv8); -// // Test, if rgb->hsv conversion produces the same result for 8 and 16bits -// TEST_ASSERT_EQUALS(hsv16, hsv16_b); -// } + Rgb161616 rgb16(rgb8); + Hsv161616 hsv16_b(rgb16); + + // Test, if rgb->hsv conversion produces the same result for 8 and 16bits + // FIXME test fails + // TEST_ASSERT_EQUALS(hsv16, hsv16_b); +} void ColorTest::testRgbHsvPingPongConvertion_8bit() { - RgbT rgb8(html::Orchid); - HsvT hsv8(rgb8); - RgbT rgb8_b(hsv8); - - // Convertion can distort - allow some tolerance. - using namespace modm; - TEST_ASSERT_TRUE(modm::Tolerance::isValueInTolerance(rgb8.red, rgb8_b.red, 1_pct)); - TEST_ASSERT_TRUE(modm::Tolerance::isValueInTolerance(rgb8.green, rgb8_b.green, 1_pct)); - TEST_ASSERT_TRUE(modm::Tolerance::isValueInTolerance(rgb8.blue, rgb8_b.blue, 1_pct)); + Rgb888 rgb8(html::Orchid); + Hsv888 hsv8(rgb8); + Rgb888 rgb8_b(hsv8); + + // Convertion may distort - allow some tolerance. + TEST_ASSERT_TRUE(modm::Tolerance::isValueInTolerance(rgb8.getRed().getValue(), rgb8_b.getRed().getValue(), 1_pct)); + TEST_ASSERT_TRUE(modm::Tolerance::isValueInTolerance(rgb8.getGreen().getValue(), rgb8_b.getGreen().getValue(), 1_pct)); + TEST_ASSERT_TRUE(modm::Tolerance::isValueInTolerance(rgb8.getBlue().getValue(), rgb8_b.getBlue().getValue(), 1_pct)); } -// TODO 16bit convertion not yet working -// see hsv_impl.hpp and rgb_impl.hpp -// void ColorTest::testRgbHsvPingPongConvertion_16bit() -// { -// // Rgb->Hsv->Rgb, both 16 bit -// RgbT rgb16(html::Orchid); -// HsvT hsv16(rgb16); -// RgbT rgb16_b(hsv16); - -// // Convertion can distort - allow some tolerance. -// using namespace modm; -// TEST_ASSERT_TRUE(modm::Tolerance::isValueInTolerance(rgb.red, rgb16_b.red, 1_pct)); -// TEST_ASSERT_TRUE(modm::Tolerance::isValueInTolerance(rgb.green, rgb16_b.green, 1_pct)); -// TEST_ASSERT_TRUE(modm::Tolerance::isValueInTolerance(rgb.blue, rgb16_b.blue, 1_pct)); -// } \ No newline at end of file +void ColorTest::testRgbHsvPingPongConvertion_16bit() +{ + // Rgb->Hsv->Rgb, both 16 bit + Rgb161616 rgb16(html::Orchid); + Hsv161616 hsv16(rgb16); + Rgb161616 rgb16_b(hsv16); + + // Convertion may distort - allow some tolerance. + TEST_ASSERT_TRUE(modm::Tolerance::isValueInTolerance(rgb16.getRed().getValue(), rgb16_b.getRed().getValue(), 1_pct)); + TEST_ASSERT_TRUE(modm::Tolerance::isValueInTolerance(rgb16.getGreen().getValue(), rgb16_b.getGreen().getValue(), 1_pct)); + TEST_ASSERT_TRUE(modm::Tolerance::isValueInTolerance(rgb16.getBlue().getValue(), rgb16_b.getBlue().getValue(), 1_pct)); +} \ No newline at end of file diff --git a/test/modm/ui/color/color_test.hpp b/test/modm/ui/color/color_test.hpp index bb9bb1cc0a..e37f26bd55 100644 --- a/test/modm/ui/color/color_test.hpp +++ b/test/modm/ui/color/color_test.hpp @@ -19,29 +19,25 @@ class ColorTest : public unittest::TestSuite { public: void - testRgbCopyConstructors(); + testGrayConstructors(); void - testHsvCopyConstructors(); + testRgbConstructors(); void - testBrightnessCopyConstructors(); + testHsvConstructors(); void testConvertion_8bit(); - // TODO 16bit convertion not yet working - // see hsv_impl.hpp and rgb_impl.hpp - // void - // testConvertion_16bit(); + void + testConvertion_16bit(); void testRgbHsvPingPongConvertion_8bit(); - // TODO 16bit convertion not yet working - // see hsv_impl.hpp and rgb_impl.hpp - // void - // testRgbHsvPingPongConvertion_16bit(); + void + testRgbHsvPingPongConvertion_16bit(); }; #endif // COLOR_TEST_HPP