diff --git a/IO_TFTDisplay.h b/IO_TFTDisplay.h deleted file mode 100644 index 1de7b85..0000000 --- a/IO_TFTDisplay.h +++ /dev/null @@ -1,256 +0,0 @@ -/* - * © 2023, Neil McKechnie. All rights reserved. - * - * This file is part of DCC++EX API - * - * This is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * It is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with CommandStation. If not, see . - */ - -/* - * This driver provides a way of driving a ST7735 TFT display through SCREEN(disp,line,"text"). - * If the line specified is off the screen then the text in the bottom line will be - * overwritten. There is however a special case that if line 255 is specified, - * the existing text will scroll up and the new line added to the bottom - * line of the screen. - * - * To install, use the following command in myHal.cpp: - - * TFTDisplay::create(address, width, height); - * - * where address is the I2C address (0x3c or 0x3d), - * width is the width in pixels of the display, and - * height is the height in pixels of the display. - * - */ - - -#ifndef IO_TFTDISPLAY_H -#define IO_TFTDDISPLAY_H - -#include "IODevice.h" -#include "DisplayInterface.h" -#include "version.h" - - -template -class TFTDisplay : public IODevice, public DisplayInterface { -private: - uint8_t _displayNo = 0; - // Here we define the device-specific variables. - uint8_t _height; // in pixels - uint8_t _width; // in pixels - T *_displayDriver; - uint8_t _rowNo = 0; // Row number being written by caller - uint8_t _colNo = 0; // Position in line being written by caller - uint8_t _numRows; - uint8_t _numCols; - char *_buffer = NULL; - uint8_t *_rowGeneration = NULL; - uint8_t *_lastRowGeneration = NULL; - uint8_t _rowNoToScreen = 0; - uint8_t _charPosToScreen = 0; - DisplayInterface *_nextDisplay = NULL; - uint8_t _selectedDisplayNo = 0; - -public: - // Static function to handle "TFTDisplay::create(...)" calls. - static void create(I2CAddress i2cAddress, int width = 128, int height=64) { - /* if (checkNoOverlap(i2cAddress)) */ new TFTDisplay(0, i2cAddress, width, height); - } - static void create(uint8_t displayNo, I2CAddress i2cAddress, int width = 128, int height=64) { - /* if (checkNoOverlap(i2cAddress)) */ new TFTDisplay(displayNo, i2cAddress, width, height); - } - -protected: - // Constructor - TFTDisplay(uint8_t displayNo, I2CAddress i2cAddress, int width, int height) { - _displayDriver = new T(i2cAddress, width, height); - _displayNo = displayNo; - _I2CAddress = i2cAddress; - _width = width; - _height = height; - _numCols = (_width+5) / 6; // character block 6 x 8, round up - _numRows = _height / 8; // Round down - - _charPosToScreen = _numCols; - - // Allocate arrays - _buffer = (char *)calloc(_numRows*_numCols, sizeof(char)); - _rowGeneration = (uint8_t *)calloc(_numRows, sizeof(uint8_t)); - _lastRowGeneration = (uint8_t *)calloc(_numRows, sizeof(uint8_t)); - // Fill buffer with spaces - memset(_buffer, ' ', _numCols*_numRows); - - _displayDriver->clearNative(); - - // Is this the main display? - if (_displayNo == 0) { - // Set first two lines on screen - this->setRow(0, 0); - print(F("DCC-EX v")); - print(F(VERSION)); - setRow(0, 1); - print(F("Lic GPLv3")); - } - - // Store pointer to this object into CS display hook, so that we - // will intercept any subsequent calls to displayHandler methods. - // Make a note of the existing display reference, to that we can - // pass on anything we're not interested in. - _nextDisplay = DisplayInterface::displayHandler; - DisplayInterface::displayHandler = this; - - addDevice(this); - } - - - void screenUpdate() { - // Loop through the buffer and if a row has changed - // (rowGeneration[row] is changed) then start writing the - // characters from the buffer, one character per entry, - // to the screen until that row has been refreshed. - - // First check if the OLED driver is still busy from a previous - // call. If so, don't to anything until the next entry. - if (!_displayDriver->isBusy()) { - // Check if we've just done the end of a row or just started - if (_charPosToScreen >= _numCols) { - // Move to next line - if (++_rowNoToScreen >= _numRows) - _rowNoToScreen = 0; // Wrap to first row - - if (_rowGeneration[_rowNoToScreen] != _lastRowGeneration[_rowNoToScreen]) { - // Row content has changed, so start outputting it - _lastRowGeneration[_rowNoToScreen] = _rowGeneration[_rowNoToScreen]; - _displayDriver->setRowNative(_rowNoToScreen); - _charPosToScreen = 0; // Prepare to output first character on next entry - } else { - // Row not changed, don't bother writing it. - } - } else { - // output character at current position - _displayDriver->writeNative(_buffer[_rowNoToScreen*_numCols+_charPosToScreen++]); - } - } - return; - } - - ///////////////////////////////////////////////// - // IODevice Class Member Overrides - ///////////////////////////////////////////////// - - // Device-specific initialisation - void _begin() override { - // Initialise device - if (_displayDriver->begin()) { - - DIAG(F("TFTDisplay installed on address %s as screen %d"), - _I2CAddress.toString(), _displayNo); - - // Force all rows to be redrawn - for (uint8_t row=0; row<_numRows; row++) - _rowGeneration[row]++; - - // Start with top line (looks better) - _rowNoToScreen = _numRows; - _charPosToScreen = _numCols; - } - } - - void _loop(unsigned long) override { - screenUpdate(); - } - - ///////////////////////////////////////////////// - // DisplayInterface functions - // - ///////////////////////////////////////////////// - -public: - void loop() override { - screenUpdate(); - if (_nextDisplay) - _nextDisplay->loop(); // continue to next display - return; - } - - // Position on nominated line number (0 to number of lines -1) - // Clear the line in the buffer ready for updating - // The displayNo referenced here is remembered and any following - // calls to write() will be directed to that display. - void setRow(uint8_t displayNo, byte line) override { - _selectedDisplayNo = displayNo; - if (displayNo == _displayNo) { - if (line == 255) { - // LCD(255,"xxx") or SCREEN(displayNo,255, "xxx") - - // scroll the contents of the buffer and put the new line - // at the bottom of the screen - for (int row=1; row<_numRows; row++) { - strncpy(&_buffer[(row-1)*_numCols], &_buffer[row*_numCols], _numCols); - _rowGeneration[row-1]++; - } - line = _numRows-1; - } else if (line >= _numRows) - line = _numRows - 1; // Overwrite bottom line. - - _rowNo = line; - // Fill line with blanks - for (_colNo = 0; _colNo < _numCols; _colNo++) - _buffer[_rowNo*_numCols+_colNo] = ' '; - _colNo = 0; - // Mark that the buffer has been touched. It will be - // sent to the screen on the next loop entry, by which time - // the line should have been written to the buffer. - _rowGeneration[_rowNo]++; - - } - if (_nextDisplay) - _nextDisplay->setRow(displayNo, line); // Pass to next display - - } - - // Write one character to the screen referenced in the last setRow() call. - size_t write(uint8_t c) override { - if (_selectedDisplayNo == _displayNo) { - // Write character to buffer (if there's space) - if (_colNo < _numCols) { - _buffer[_rowNo*_numCols+_colNo++] = c; - } - } - if (_nextDisplay) - _nextDisplay->write(c); - return 1; - } - - // Write blanks to all of the screen (blocks until complete) - void clear (uint8_t displayNo) override { - if (displayNo == _displayNo) { - // Clear buffer - for (_rowNo = 0; _rowNo < _numRows; _rowNo++) { - setRow(displayNo, _rowNo); - } - _rowNo = 0; - } - if (_nextDisplay) - _nextDisplay->clear(displayNo); // Pass to next display - } - - // Display information about the device. - void _display() { - DIAG(F("TFTDisplay %d Configured addr %s"), _displayNo, _I2CAddress.toString()); - } - -}; - -#endif // IO_TFTDDISPLAY_H \ No newline at end of file diff --git a/IO_Wire.h b/IO_Wire.h deleted file mode 100644 index 624c911..0000000 --- a/IO_Wire.h +++ /dev/null @@ -1,136 +0,0 @@ -/* - * © 2023, Neil McKechnie. All rights reserved. - * - * This file is part of DCC++EX API - * - * This is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * It is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with CommandStation. If not, see . - */ - -/* - * The purpose of this module is to provide an interface to the DCC - * I2CManager that is compatible with code written for the Arduino - * 'Wire' interface. - * - * To use it, just replace - * #include "Wire.h" or #include - * with - * #include "IO_Wire.h" - * - * Note that the CS only supports I2C master mode, so the calls related to - * slave mode are not implemented here. - * - */ - -#ifndef IO_WIRE -#define IO_WIRE - -#include "IODevice.h" - -#ifndef I2C_USE_WIRE - -class IO_Wire : public IODevice, public Stream { -public: - IO_Wire() { - addDevice(this); - }; - void begin() { - I2CManager.begin(); - } - void setClock(uint32_t speed) { - I2CManager.setClock(speed); - } - void beginTransmission(uint8_t address) { - i2cAddress = address; - outputLength = 0; - } - size_t write(byte value) override { - if (outputLength < sizeof(outputBuffer)) { - outputBuffer[outputLength++] = value; - return 1; - } else - return 0; - } - size_t write(const uint8_t *buffer, size_t size) override { - for (size_t i=0; i -#endif -#endif \ No newline at end of file diff --git a/ST7735-TFT.h b/ST7735-TFT.h deleted file mode 100644 index 5893d3c..0000000 --- a/ST7735-TFT.h +++ /dev/null @@ -1,517 +0,0 @@ -/* Tiny TFT Graphics Library v5 - see http://www.technoblogy.com/show?3WAI - David Johnson-Davies - www.technoblogy.com - 26th October 2022 - - CC BY 4.0 - Licensed under a Creative Commons Attribution 4.0 International license: - http://creativecommons.org/licenses/by/4.0/ -*/ - -#include "FSH.h" -#include "DisplayInterface.h" - - -#if defined(MEGATINYCORE) -// ATtiny402/412 PORTA positions. Change these for the chip you're using -int const dc = 7; -int const mosi = 1; -int const sck = 3; -int const cs = 6; - -// ATtiny 0-, 1-, and 2-series port manipulations - assumes all pins in same port -#define PORT_TOGGLE(x) PORTA.OUTTGL = (x) -#define PORT_LOW(x) PORTA.OUTCLR = (x) -#define PORT_HIGH(x) PORTA.OUTSET = (x) -#define PORT_OUTPUT(x) PORTA.DIRSET = (x) - -#else -// ATtiny45/85 PORTB positions. Change these for the chip you're using -int const dc = 0; -int const mosi = 1; -int const sck = 2; -int const cs = 3; - -// Classic ATtiny port manipulations - assumes all pins in same port -#define PORT_TOGGLE(x) PINB = (x) -#define PORT_LOW(x) PORTB = PORTB & ~((x)); -#define PORT_HIGH(x) PORTB = PORTB | ((x)) -#define PORT_OUTPUT(x) DDRB = (x) - -#endif - -// Display parameters - uncomment the line for the one you want to use - -// Adafruit 1.44" 128x128 display -// int const xsize = 128, ysize = 128, xoff = 2, yoff = 1, invert = 0, rotate = 3, bgr = 1; - -// AliExpress 1.44" 128x128 display -// int const xsize = 128, ysize = 128, xoff = 2, yoff = 1, invert = 0, rotate = 3, bgr = 1; - -// Adafruit 0.96" 160x80 display -// int const xsize = 160, ysize = 80, xoff = 0, yoff = 24, invert = 0, rotate = 6, bgr = 0; - -// AliExpress 0.96" 160x80 display -// int const xsize = 160, ysize = 80, xoff = 1, yoff = 26, invert = 1, rotate = 0, bgr = 1; - -// Adafruit 1.8" 160x128 display -// int const xsize = 160, ysize = 128, xoff = 0, yoff = 0, invert = 0, rotate = 0, bgr = 1; - -// AliExpress 1.8" 160x128 display (red PCB) -int const xsize = 160, ysize = 128, xoff = 0, yoff = 0, invert = 0, rotate = 0, bgr = 1; - -// AliExpress 1.8" 160x128 display (blue PCB) -// int const xsize = 160, ysize = 128, xoff = 0, yoff = 0, invert = 0, rotate = 6, bgr = 0; - -// Adafruit 1.14" 240x135 display -// int const xsize = 240, ysize = 135, xoff = 40, yoff = 53, invert = 1, rotate = 6, bgr = 0; - -// AliExpress 1.14" 240x135 display -// int const xsize = 240, ysize = 135, xoff = 40, yoff = 52, invert = 1, rotate = 0, bgr = 0; - -// Adafruit 1.3" 240x240 display -// int const xsize = 240, ysize = 240, xoff = 0, yoff = 80, invert = 1, rotate = 5, bgr = 0; - -// Adafruit 1.54" 240x240 display -// int const xsize = 240, ysize = 240, xoff = 0, yoff = 80, invert = 1, rotate = 5, bgr = 0; - -// AliExpress 1.54" 240x240 display -// int const xsize = 240, ysize = 240, xoff = 0, yoff = 80, invert = 1, rotate = 5, bgr = 0; - -// Adafruit 1.9" 320x170 display -// int const xsize = 320, ysize = 170, xoff = 0, yoff = 35, invert = 1, rotate = 0, bgr = 0; - -// AliExpress 1.9" 320x170 display -// int const xsize = 320, ysize = 170, xoff = 0, yoff = 35, invert = 1, rotate = 0, bgr = 0; - -// Adafruit 1.47" 320x172 rounded rectangle display -// int const xsize = 320, ysize = 172, xoff = 0, yoff = 34, invert = 1, rotate = 0, bgr = 0; - -// AliExpress 1.47" 320x172 rounded rectangle display -// int const xsize = 320, ysize = 172, xoff = 0, yoff = 34, invert = 1, rotate = 0, bgr = 0; - -// Adafruit 2.0" 320x240 display -// int const xsize = 320, ysize = 240, xoff = 0, yoff = 0, invert = 1, rotate = 6, bgr = 0; - -// AliExpress 2.0" 320x240 display -// int const xsize = 320, ysize = 240, xoff = 0, yoff = 0, invert = 1, rotate = 0, bgr = 0; - -// Adafruit 2.2" 320x240 display -// int const xsize = 320, ysize = 240, xoff = 0, yoff = 0, invert = 0, rotate = 4, bgr = 1; - -// AliExpress 2.4" 320x240 display -// int const xsize = 320, ysize = 240, xoff = 0, yoff = 0, invert = 0, rotate = 2, bgr = 1; - -// Character set for text - stored in program memory -const uint8_t CharMap[96][6] FLASH = { -{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, -{ 0x00, 0x00, 0x5F, 0x00, 0x00, 0x00 }, -{ 0x00, 0x07, 0x00, 0x07, 0x00, 0x00 }, -{ 0x14, 0x7F, 0x14, 0x7F, 0x14, 0x00 }, -{ 0x24, 0x2A, 0x7F, 0x2A, 0x12, 0x00 }, -{ 0x23, 0x13, 0x08, 0x64, 0x62, 0x00 }, -{ 0x36, 0x49, 0x56, 0x20, 0x50, 0x00 }, -{ 0x00, 0x08, 0x07, 0x03, 0x00, 0x00 }, -{ 0x00, 0x1C, 0x22, 0x41, 0x00, 0x00 }, -{ 0x00, 0x41, 0x22, 0x1C, 0x00, 0x00 }, -{ 0x2A, 0x1C, 0x7F, 0x1C, 0x2A, 0x00 }, -{ 0x08, 0x08, 0x3E, 0x08, 0x08, 0x00 }, -{ 0x00, 0x80, 0x70, 0x30, 0x00, 0x00 }, -{ 0x08, 0x08, 0x08, 0x08, 0x08, 0x00 }, -{ 0x00, 0x00, 0x60, 0x60, 0x00, 0x00 }, -{ 0x20, 0x10, 0x08, 0x04, 0x02, 0x00 }, -{ 0x3E, 0x51, 0x49, 0x45, 0x3E, 0x00 }, -{ 0x00, 0x42, 0x7F, 0x40, 0x00, 0x00 }, -{ 0x72, 0x49, 0x49, 0x49, 0x46, 0x00 }, -{ 0x21, 0x41, 0x49, 0x4D, 0x33, 0x00 }, -{ 0x18, 0x14, 0x12, 0x7F, 0x10, 0x00 }, -{ 0x27, 0x45, 0x45, 0x45, 0x39, 0x00 }, -{ 0x3C, 0x4A, 0x49, 0x49, 0x31, 0x00 }, -{ 0x41, 0x21, 0x11, 0x09, 0x07, 0x00 }, -{ 0x36, 0x49, 0x49, 0x49, 0x36, 0x00 }, -{ 0x46, 0x49, 0x49, 0x29, 0x1E, 0x00 }, -{ 0x00, 0x00, 0x14, 0x00, 0x00, 0x00 }, -{ 0x00, 0x40, 0x34, 0x00, 0x00, 0x00 }, -{ 0x00, 0x08, 0x14, 0x22, 0x41, 0x00 }, -{ 0x14, 0x14, 0x14, 0x14, 0x14, 0x00 }, -{ 0x00, 0x41, 0x22, 0x14, 0x08, 0x00 }, -{ 0x02, 0x01, 0x59, 0x09, 0x06, 0x00 }, -{ 0x3E, 0x41, 0x5D, 0x59, 0x4E, 0x00 }, -{ 0x7C, 0x12, 0x11, 0x12, 0x7C, 0x00 }, -{ 0x7F, 0x49, 0x49, 0x49, 0x36, 0x00 }, -{ 0x3E, 0x41, 0x41, 0x41, 0x22, 0x00 }, -{ 0x7F, 0x41, 0x41, 0x41, 0x3E, 0x00 }, -{ 0x7F, 0x49, 0x49, 0x49, 0x41, 0x00 }, -{ 0x7F, 0x09, 0x09, 0x09, 0x01, 0x00 }, -{ 0x3E, 0x41, 0x41, 0x51, 0x73, 0x00 }, -{ 0x7F, 0x08, 0x08, 0x08, 0x7F, 0x00 }, -{ 0x00, 0x41, 0x7F, 0x41, 0x00, 0x00 }, -{ 0x20, 0x40, 0x41, 0x3F, 0x01, 0x00 }, -{ 0x7F, 0x08, 0x14, 0x22, 0x41, 0x00 }, -{ 0x7F, 0x40, 0x40, 0x40, 0x40, 0x00 }, -{ 0x7F, 0x02, 0x1C, 0x02, 0x7F, 0x00 }, -{ 0x7F, 0x04, 0x08, 0x10, 0x7F, 0x00 }, -{ 0x3E, 0x41, 0x41, 0x41, 0x3E, 0x00 }, -{ 0x7F, 0x09, 0x09, 0x09, 0x06, 0x00 }, -{ 0x3E, 0x41, 0x51, 0x21, 0x5E, 0x00 }, -{ 0x7F, 0x09, 0x19, 0x29, 0x46, 0x00 }, -{ 0x26, 0x49, 0x49, 0x49, 0x32, 0x00 }, -{ 0x03, 0x01, 0x7F, 0x01, 0x03, 0x00 }, -{ 0x3F, 0x40, 0x40, 0x40, 0x3F, 0x00 }, -{ 0x1F, 0x20, 0x40, 0x20, 0x1F, 0x00 }, -{ 0x3F, 0x40, 0x38, 0x40, 0x3F, 0x00 }, -{ 0x63, 0x14, 0x08, 0x14, 0x63, 0x00 }, -{ 0x03, 0x04, 0x78, 0x04, 0x03, 0x00 }, -{ 0x61, 0x59, 0x49, 0x4D, 0x43, 0x00 }, -{ 0x00, 0x7F, 0x41, 0x41, 0x41, 0x00 }, -{ 0x02, 0x04, 0x08, 0x10, 0x20, 0x00 }, -{ 0x00, 0x41, 0x41, 0x41, 0x7F, 0x00 }, -{ 0x04, 0x02, 0x01, 0x02, 0x04, 0x00 }, -{ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00 }, -{ 0x00, 0x03, 0x07, 0x08, 0x00, 0x00 }, -{ 0x20, 0x54, 0x54, 0x78, 0x40, 0x00 }, -{ 0x7F, 0x28, 0x44, 0x44, 0x38, 0x00 }, -{ 0x38, 0x44, 0x44, 0x44, 0x28, 0x00 }, -{ 0x38, 0x44, 0x44, 0x28, 0x7F, 0x00 }, -{ 0x38, 0x54, 0x54, 0x54, 0x18, 0x00 }, -{ 0x00, 0x08, 0x7E, 0x09, 0x02, 0x00 }, -{ 0x18, 0xA4, 0xA4, 0x9C, 0x78, 0x00 }, -{ 0x7F, 0x08, 0x04, 0x04, 0x78, 0x00 }, -{ 0x00, 0x44, 0x7D, 0x40, 0x00, 0x00 }, -{ 0x20, 0x40, 0x40, 0x3D, 0x00, 0x00 }, -{ 0x7F, 0x10, 0x28, 0x44, 0x00, 0x00 }, -{ 0x00, 0x41, 0x7F, 0x40, 0x00, 0x00 }, -{ 0x7C, 0x04, 0x78, 0x04, 0x78, 0x00 }, -{ 0x7C, 0x08, 0x04, 0x04, 0x78, 0x00 }, -{ 0x38, 0x44, 0x44, 0x44, 0x38, 0x00 }, -{ 0xFC, 0x18, 0x24, 0x24, 0x18, 0x00 }, -{ 0x18, 0x24, 0x24, 0x18, 0xFC, 0x00 }, -{ 0x7C, 0x08, 0x04, 0x04, 0x08, 0x00 }, -{ 0x48, 0x54, 0x54, 0x54, 0x24, 0x00 }, -{ 0x04, 0x04, 0x3F, 0x44, 0x24, 0x00 }, -{ 0x3C, 0x40, 0x40, 0x20, 0x7C, 0x00 }, -{ 0x1C, 0x20, 0x40, 0x20, 0x1C, 0x00 }, -{ 0x3C, 0x40, 0x30, 0x40, 0x3C, 0x00 }, -{ 0x44, 0x28, 0x10, 0x28, 0x44, 0x00 }, -{ 0x4C, 0x90, 0x90, 0x90, 0x7C, 0x00 }, -{ 0x44, 0x64, 0x54, 0x4C, 0x44, 0x00 }, -{ 0x00, 0x08, 0x36, 0x41, 0x00, 0x00 }, -{ 0x00, 0x00, 0x77, 0x00, 0x00, 0x00 }, -{ 0x00, 0x41, 0x36, 0x08, 0x00, 0x00 }, -{ 0x00, 0x06, 0x09, 0x06, 0x00, 0x00 }, // degree symbol = '~' -{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00 } -}; - -// TFT colour display ********************************************** - -int const CASET = 0x2A; // Define column address -int const RASET = 0x2B; // Define row address -int const RAMWR = 0x2C; // Write to display RAM - -int const White = 0xFFFF; -int const Black = 0; - -// Current plot position and colours -int xpos, ypos; -int fore = White; -int back = Black; -int scale = 1; // Text scale - -// Send a byte to the display - -void Data (uint8_t d) { - for (uint8_t bit = 0x80; bit; bit >>= 1) { - PORT_TOGGLE(1<>8); Data(d1); Data(d2>>8); Data(d2); -} - -void InitDisplay () { - PORT_OUTPUT(1<>3; -} - -// Move current plot position to x,y -void MoveTo (int x, int y) { - xpos = x; ypos = y; -} - -// Plot point at x,y -void PlotPoint (int x, int y) { - PORT_TOGGLE(1<>8); Data(fore & 0xff); - PORT_TOGGLE(1< -dy) { err = err - dy; xpos = xpos + sx; } - if (e2 < dx) { err = err + dx; ypos = ypos + sy; } - } -} - -void FillRect (int w, int h) { - PORT_TOGGLE(1<>8; - uint8_t lo = fore & 0xff; - for (int i=0; i= y) { - MoveTo(x1-x, y1+y); FillRect(x<<1, 1); - MoveTo(x1-y, y1+x); FillRect(y<<1, 1); - MoveTo(x1-y, y1-x); FillRect(y<<1, 1); - MoveTo(x1-x, y1-y); FillRect(x<<1, 1); - if (err > 0) { - x = x - 1; dx = dx + 2; - err = err - (radius<<1) + dx; - } else { - y = y + 1; err = err + dy; - dy = dy + 2; - } - } - xpos = x1; ypos = y1; -} - -void DrawCircle (int radius) { - int x1 = xpos, y1 = ypos, dx = 1, dy = 1; - int x = radius - 1, y = 0; - int err = dx - (radius<<1); - while (x >= y) { - PlotPoint(x1-x, y1+y); PlotPoint(x1+x, y1+y); - PlotPoint(x1-y, y1+x); PlotPoint(x1+y, y1+x); - PlotPoint(x1-y, y1-x); PlotPoint(x1+y, y1-x); - PlotPoint(x1-x, y1-y); PlotPoint(x1+x, y1-y); - if (err > 0) { - x = x - 1; dx = dx + 2; - err = err - (radius<<1) + dx; - } else { - y = y + 1; err = err + dy; - dy = dy + 2; - } - } -} - -// Plot an ASCII character with bottom left corner at x,y -void PlotChar (char c) { - int colour; - PORT_TOGGLE(1<>(7-yy) & 1) colour = fore; else colour = back; - for (int yr=0; yr>8); Data(colour & 0xFF); - } - } - } - } - PORT_TOGGLE(1<0; d = d/10) { - char j = (n/d) % 10; - if (j!=0 || lead || d==1) { PlotChar(j + '0'); lead = true; } - } -} - -void TestChart () { - DrawRect(xsize, ysize); - scale = 8; - fore = Colour(255, 0, 0); - MoveTo((xsize-40)/2, (ysize-64)/2); PlotChar('F'); - scale = 1; -} - -// Demos ********************************************** - -void BarChart () { - int x0 = 0, y0 = 0, w = xsize, h = ysize, x1 = 15, y1 = 11; - MoveTo(x0+(w-x1-90)/2+x1, y0+h-8); PlotText(PSTR("Sensor Readings")); - // Horizontal axis - int xinc = (w-x1)/20; - MoveTo(x0+x1, y0+y1); DrawTo(x0+w-1, y0+y1); - for (int i=0; i<=20; i=i+4) { - int mark = x1+i*xinc; - MoveTo(x0+mark, y0+y1); DrawTo(x0+mark, y0+y1-2); - // Draw histogram - if (i != 20) { - int bar = xinc*4/3; - for (int b=2; b>=0; b--) { - fore = Colour(255, 127*b, 0); // Red, Orange, Yellow - MoveTo(x0+mark+bar*b-b+1, y0+y1+1); FillRect(bar, 5+random(h-y1-20)); - } - fore = White; - } - if (i > 9) MoveTo(x0+mark-7, y0+y1-11); else MoveTo(x0+mark-3, y0+y1-11); - PlotInt(i); - } - // Vertical axis - int yinc = (h-y1)/20; - MoveTo(x0+x1, y0+y1); DrawTo(x0+x1, y0+h-1); - for (int i=0; i<=20; i=i+5) { - int mark = y1+i*yinc; - MoveTo(x0+x1, y0+mark); DrawTo(x0+x1-2, y0+mark); - if (i > 9) MoveTo(x0+x1-15, y0+mark-4); else MoveTo(x0+x1-9, y0+mark-4); - PlotInt(i); - } -} - -void Waterfall () { - int x0 = 0, y0 = 0, w = xsize, h = ysize, x1 = 15, y1 = 11; - int factor = 5160/h*10; - MoveTo(x0+(w-x1-60)/2+x1, y0+h-8); PlotText(PSTR("Luminance")); - // Horizontal axis - int xinc = (w-x1-15)/30; - MoveTo(x0+x1, y0+y1); DrawTo(x0+x1+xinc*20, y0+y1); - for (int i=0; i<=20; i=i+5) { - int mark = x1+i*xinc; - MoveTo(x0+mark, y0+y1); DrawTo(x0+mark, y0+y1-2); - if (i > 9) MoveTo(x0+mark-7, y0+y1-11); else MoveTo(x0+mark-3, y0+y1-11); - PlotInt(i); - } - // Vertical axis - int yinc = (h-y1)/20; - MoveTo(x0+x1, y0+y1); DrawTo(x0+x1, y0+h-1); - for (int i=0; i<=20; i=i+5) { - int mark = y1+i*yinc; - MoveTo(x0+x1, y0+mark); DrawTo(x0+x1-2, y0+mark); - if (i > 9) MoveTo(x0+x1-15, y0+mark-4); else MoveTo(x0+x1-9, y0+mark-4); - PlotInt(i); - } - // Diagonal axis - yinc = xinc/2; - // MoveTo(x0+x1, y0+y1); DrawTo(x0+x1+10*xinc, y0+y1+10*xinc); - MoveTo(x0+x1+20*xinc, y0+y1); DrawTo(x0+x1+30*xinc, y0+y1+10*xinc); - for (int i=0; i<=20; i=i+5) { - MoveTo(x0+x1+20*xinc+i*xinc/2, y0+y1+i*xinc/2); - DrawTo(x0+x1+20*xinc+i*xinc/2+3, y0+y1+i*xinc/2); - MoveTo(x0+x1+20*xinc+i*xinc/2+6, y0+y1+i*xinc/2-4); PlotInt(i); - } - // Plot data - for (int y=20; y>=0; y--) { - for (int i=0; i<=20; i++) { - int fn0 = 180-(i-10)*(i-10)-(y-10)*(y-10); - int fn1 = 180-(i+1-10)*(i+1-10)-(y-10)*(y-10); - fore = Colour(255, 255, 0); - MoveTo(x0+x1+y*yinc+i*xinc, y0+y1+y*yinc+fn0*fn0/factor); - DrawTo(x0+x1+y*yinc+(i+1)*xinc, y0+y1+y*yinc+fn1*fn1/factor); - fore = White; - } - } -} - -// Setup ********************************************** - -void setup() { - InitDisplay(); - ClearDisplay(); - DisplayOn(); - MoveTo(0,0); - // TestChart(); -} - -void loop () { - BarChart(); - // Waterfall(); - for (;;); -} \ No newline at end of file