From abcfb06b0b21ff71ebce63282a8bd69f534002b2 Mon Sep 17 00:00:00 2001 From: Serge Vakulenko Date: Sat, 31 Oct 2015 21:12:50 -0700 Subject: [PATCH] Merge gpanel branch. --- sys/pic32/gpanel/Adafruit_ILI9341_8bit_AS.cpp | 579 ----------- sys/pic32/gpanel/Adafruit_ILI9341_8bit_AS.h | 105 -- sys/pic32/gpanel/pin_magic_MEGA.h | 126 --- sys/pic32/gpanel/pin_magic_UNO.h | 117 --- sys/pic32/gpanel/registers.h | 30 - sys/pic32/gpanel/st7781-landscape.c | 928 ------------------ 6 files changed, 1885 deletions(-) delete mode 100644 sys/pic32/gpanel/Adafruit_ILI9341_8bit_AS.cpp delete mode 100644 sys/pic32/gpanel/Adafruit_ILI9341_8bit_AS.h delete mode 100644 sys/pic32/gpanel/pin_magic_MEGA.h delete mode 100644 sys/pic32/gpanel/pin_magic_UNO.h delete mode 100644 sys/pic32/gpanel/registers.h delete mode 100644 sys/pic32/gpanel/st7781-landscape.c diff --git a/sys/pic32/gpanel/Adafruit_ILI9341_8bit_AS.cpp b/sys/pic32/gpanel/Adafruit_ILI9341_8bit_AS.cpp deleted file mode 100644 index fcd22ea..0000000 --- a/sys/pic32/gpanel/Adafruit_ILI9341_8bit_AS.cpp +++ /dev/null @@ -1,579 +0,0 @@ -// IMPORTANT: LIBRARY MUST BE SPECIFICALLY CONFIGURED FOR EITHER TFT SHIELD -// OR BREAKOUT BOARD USAGE. SEE RELEVANT COMMENTS IN Adafruit_ILI9341_8bit_AS.h - -// Graphics library by ladyada/adafruit with init code from Rossum -// MIT license - -#include - -#include "pins_arduino.h" - -#include "wiring_private.h" -#include "Adafruit_ILI9341_8bit_AS.h" - -#if defined __AVR_ATmega328P__ - #include "pin_magic_UNO.h" -#endif - -#if defined __AVR_ATmega2560__ - #include "pin_magic_MEGA.h" -#endif - - -//#define TFTWIDTH 320 -//#define TFTHEIGHT 480 - -#define TFTWIDTH 240 -#define TFTHEIGHT 320 - -// LCD controller chip identifiers -#define ID_9341 2 - -#include "registers.h" - -// Constructor for breakout board (configurable LCD control lines). -// Can still use this w/shield, but parameters are ignored. - -Adafruit_ILI9341_8bit_AS::Adafruit_ILI9341_8bit_AS(uint8_t cs, uint8_t cd, uint8_t wr, uint8_t rd, uint8_t reset) : Adafruit_GFX_AS(TFTWIDTH, TFTHEIGHT) { - -#ifndef USE_ADAFRUIT_SHIELD_PINOUT - // Convert pin numbers to registers and bitmasks - _reset = reset; - - csPort = portOutputRegister(digitalPinToPort(cs)); - cdPort = portOutputRegister(digitalPinToPort(cd)); - wrPort = portOutputRegister(digitalPinToPort(wr)); - rdPort = portOutputRegister(digitalPinToPort(rd)); - - csPinSet = digitalPinToBitMask(cs); - cdPinSet = digitalPinToBitMask(cd); - wrPinSet = digitalPinToBitMask(wr); - rdPinSet = digitalPinToBitMask(rd); - csPinUnset = ~csPinSet; - cdPinUnset = ~cdPinSet; - wrPinUnset = ~wrPinSet; - rdPinUnset = ~rdPinSet; - - *csPort |= csPinSet; // Set all control bits to HIGH (idle) - *cdPort |= cdPinSet; // Signals are ACTIVE LOW - *wrPort |= wrPinSet; - *rdPort |= rdPinSet; - - pinMode(cs, OUTPUT); // Enable outputs - pinMode(cd, OUTPUT); - pinMode(wr, OUTPUT); - pinMode(rd, OUTPUT); - - if(reset) { - digitalWrite(reset, HIGH); - pinMode(reset, OUTPUT); - } -#endif - - init(); -} - -// Constructor for shield (fixed LCD control lines) -Adafruit_ILI9341_8bit_AS::Adafruit_ILI9341_8bit_AS(void) : Adafruit_GFX_AS(TFTWIDTH, TFTHEIGHT) { - init(); -} - -// Initialization common to both shield & breakout configs -void Adafruit_ILI9341_8bit_AS::init(void) { - -#ifdef USE_ADAFRUIT_SHIELD_PINOUT - CS_IDLE; // Set all control bits to idle state - WR_IDLE; - RD_IDLE; - CD_DATA; - digitalWrite(5, HIGH); // Reset line - pinMode(A3, OUTPUT); // Enable outputs - pinMode(A2, OUTPUT); - pinMode(A1, OUTPUT); - pinMode(A0, OUTPUT); - pinMode( 5, OUTPUT); -#endif - - setWriteDir(); // Set up LCD data port(s) for WRITE operations - - rotation = 0; - cursor_y = cursor_x = 0; - textsize = 1; - textcolor = 0xFFFF; - _width = TFTWIDTH; - _height = TFTHEIGHT; -} - -// Initialization command tables for different LCD controllers -#define ILI9341_8bit_AS_DELAY 0xFF -static const uint8_t HX8347G_regValues[] PROGMEM = { - 0x2E , 0x89, - 0x29 , 0x8F, - 0x2B , 0x02, - 0xE2 , 0x00, - 0xE4 , 0x01, - 0xE5 , 0x10, - 0xE6 , 0x01, - 0xE7 , 0x10, - 0xE8 , 0x70, - 0xF2 , 0x00, - 0xEA , 0x00, - 0xEB , 0x20, - 0xEC , 0x3C, - 0xED , 0xC8, - 0xE9 , 0x38, - 0xF1 , 0x01, - - // skip gamma, do later - - 0x1B , 0x1A, - 0x1A , 0x02, - 0x24 , 0x61, - 0x25 , 0x5C, - - 0x18 , 0x36, - 0x19 , 0x01, - 0x1F , 0x88, - ILI9341_8bit_AS_DELAY , 5 , // delay 5 ms - 0x1F , 0x80, - ILI9341_8bit_AS_DELAY , 5 , - 0x1F , 0x90, - ILI9341_8bit_AS_DELAY , 5 , - 0x1F , 0xD4, - ILI9341_8bit_AS_DELAY , 5 , - 0x17 , 0x05, - - 0x36 , 0x09, - 0x28 , 0x38, - ILI9341_8bit_AS_DELAY , 40 , - 0x28 , 0x3C, - - 0x02 , 0x00, - 0x03 , 0x00, - 0x04 , 0x00, - 0x05 , 0xEF, - 0x06 , 0x00, - 0x07 , 0x00, - 0x08 , 0x01, - 0x09 , 0x3F -}; - -void Adafruit_ILI9341_8bit_AS::begin(uint16_t id) { - uint8_t i = 0; - - reset(); - - delay(200); - - uint16_t a, d; - driver = ID_9341; - CS_ACTIVE; - writeRegister8(ILI9341_SOFTRESET, 0); - delay(50); - writeRegister8(ILI9341_DISPLAYOFF, 0); - - writeRegister8(ILI9341_POWERCONTROL1, 0x23); - writeRegister8(ILI9341_POWERCONTROL2, 0x10); - writeRegister16(ILI9341_VCOMCONTROL1, 0x2B2B); - writeRegister8(ILI9341_VCOMCONTROL2, 0xC0); - writeRegister8(ILI9341_MEMCONTROL, ILI9341_MADCTL_MY | ILI9341_MADCTL_BGR); - writeRegister8(ILI9341_PIXELFORMAT, 0x55); - writeRegister16(ILI9341_FRAMECONTROL, 0x001B); - - writeRegister8(ILI9341_ENTRYMODE, 0x07); - /* writeRegister32(ILI9341_DISPLAYFUNC, 0x0A822700);*/ - - writeRegister8(ILI9341_SLEEPOUT, 0); - delay(150); - writeRegister8(ILI9341_DISPLAYON, 0); - delay(500); - setAddrWindow(0, 0, TFTWIDTH-1, TFTHEIGHT-1); - return; -} - -void Adafruit_ILI9341_8bit_AS::reset(void) { - - CS_IDLE; -// CD_DATA; - WR_IDLE; - RD_IDLE; - -#ifdef USE_ADAFRUIT_SHIELD_PINOUT - digitalWrite(5, LOW); - delay(2); - digitalWrite(5, HIGH); -#else - // if we have a reset pin defined ( _reset ) - if(_reset) { - digitalWrite(_reset, LOW); - delay(2); - digitalWrite(_reset, HIGH); - } -#endif - - // Data transfer sync - CS_ACTIVE; - CD_COMMAND; - write8(0x00); - for(uint8_t i=0; i<3; i++) WR_STROBE; // Three extra 0x00s - CS_IDLE; - - // let the display recover from the reset - delay(500); - -} - -// Sets the LCD address window (and address counter, on 932X). -// Relevant to rect/screen fills and H/V lines. Input coordinates are -// assumed pre-sorted (e.g. x2 >= x1). -void Adafruit_ILI9341_8bit_AS::setAddrWindow(int x1, int y1, int x2, int y2) { - CS_ACTIVE; - uint32_t t; - t = x1; - t <<= 16; - t |= x2; - writeRegister32(ILI9341_COLADDRSET, t); // HX8357D uses same registers! - t = y1; - t <<= 16; - t |= y2; - writeRegister32(ILI9341_PAGEADDRSET, t); // HX8357D uses same registers! - CS_IDLE; -} - -// Fast block fill operation for fillScreen, fillRect, H/V line, etc. -// Requires setAddrWindow() has previously been called to set the fill -// bounds. 'len' is inclusive, MUST be >= 1. -void Adafruit_ILI9341_8bit_AS::flood(uint16_t color, uint32_t len) { - uint16_t blocks; - uint8_t i, hi = color >> 8, - lo = color; - - CS_ACTIVE; - CD_COMMAND; - write8(0x2C); - - // Write first pixel normally, decrement counter by 1 - CD_DATA; - write8(hi); - write8(lo); - len--; - - blocks = (uint16_t)(len / 64); // 64 pixels/block - if(hi == lo) { - // High and low bytes are identical. Leave prior data - // on the port(s) and just toggle the write strobe. - while(blocks--) { - i = 16; // 64 pixels/block / 4 pixels/pass - do { - WR_STROBE; WR_STROBE; WR_STROBE; WR_STROBE; // 2 bytes/pixel - WR_STROBE; WR_STROBE; WR_STROBE; WR_STROBE; // x 4 pixels - } while(--i); - } - // Fill any remaining pixels (1 to 64) - for(i = (uint8_t)len & 63; i--; ) { - WR_STROBE; - WR_STROBE; - } - } else { - while(blocks--) { - i = 16; // 64 pixels/block / 4 pixels/pass - do { - write8(hi); write8(lo); write8(hi); write8(lo); - write8(hi); write8(lo); write8(hi); write8(lo); - } while(--i); - } - for(i = (uint8_t)len & 63; i--; ) { - write8(hi); - write8(lo); - } - } - CS_IDLE; -} - -void Adafruit_ILI9341_8bit_AS::drawFastHLine(int16_t x, int16_t y, int16_t length, - uint16_t color) -{ - int16_t x2; - - // Initial off-screen clipping - if((length <= 0 ) || - (y < 0 ) || ( y >= _height) || - (x >= _width) || ((x2 = (x+length-1)) < 0 )) return; - - if(x < 0) { // Clip left - length += x; - x = 0; - } - if(x2 >= _width) { // Clip right - x2 = _width - 1; - length = x2 - x + 1; - } - - setAddrWindow(x, y, x2, y); - flood(color, length); -} - -void Adafruit_ILI9341_8bit_AS::drawFastVLine(int16_t x, int16_t y, int16_t length, - uint16_t color) -{ - int16_t y2; - - // Initial off-screen clipping - if((length <= 0 ) || - (x < 0 ) || ( x >= _width) || - (y >= _height) || ((y2 = (y+length-1)) < 0 )) return; - if(y < 0) { // Clip top - length += y; - y = 0; - } - if(y2 >= _height) { // Clip bottom - y2 = _height - 1; - length = y2 - y + 1; - } - - setAddrWindow(x, y, x, y2); - flood(color, length); -} - -void Adafruit_ILI9341_8bit_AS::fillRect(int16_t x1, int16_t y1, int16_t w, int16_t h, - uint16_t fillcolor) { - int16_t x2, y2; - - // Initial off-screen clipping - if( (w <= 0 ) || (h <= 0 ) || - (x1 >= _width) || (y1 >= _height) || - ((x2 = x1+w-1) < 0 ) || ((y2 = y1+h-1) < 0 )) return; - if(x1 < 0) { // Clip left - w += x1; - x1 = 0; - } - if(y1 < 0) { // Clip top - h += y1; - y1 = 0; - } - if(x2 >= _width) { // Clip right - x2 = _width - 1; - w = x2 - x1 + 1; - } - if(y2 >= _height) { // Clip bottom - y2 = _height - 1; - h = y2 - y1 + 1; - } - - setAddrWindow(x1, y1, x2, y2); - flood(fillcolor, (uint32_t)w * (uint32_t)h); -} - -void Adafruit_ILI9341_8bit_AS::fillScreen(uint16_t color) { - - // For these, there is no settable address pointer, instead the - // address window must be set for each drawing operation. However, - // this display takes rotation into account for the parameters, no - // need to do extra rotation math here. - setAddrWindow(0, 0, _width - 1, _height - 1); - flood(color, (long)TFTWIDTH * (long)TFTHEIGHT); -} - -void Adafruit_ILI9341_8bit_AS::drawPixel(int16_t x, int16_t y, uint16_t color) { - - // Clip - if((x < 0) || (y < 0) || (x >= _width) || (y >= _height)) return; - - CS_ACTIVE; - setAddrWindow(x, y, _width-1, _height-1); - CS_ACTIVE; - CD_COMMAND; - write8(0x2C); - CD_DATA; - write8(color >> 8); write8(color); - CS_IDLE; -} - -// Issues 'raw' an array of 16-bit color values to the LCD; used -// externally by BMP examples. Assumes that setWindowAddr() has -// previously been set to define the bounds. Max 255 pixels at -// a time (BMP examples read in small chunks due to limited RAM). -void Adafruit_ILI9341_8bit_AS::pushColors(uint16_t *data, uint8_t len, boolean first) { - uint16_t color; - uint8_t hi, lo; - CS_ACTIVE; - if(first == true) { // Issue GRAM write command only on first call - CD_COMMAND; - - write8(0x2C); - } - CD_DATA; - while(len--) { - color = *data++; - hi = color >> 8; // Don't simplify or merge these - lo = color; // lines, there's macro shenanigans - write8(hi); // going on. - write8(lo); - } - CS_IDLE; -} - -void Adafruit_ILI9341_8bit_AS::setRotation(uint8_t x) { - - // Call parent rotation func first -- sets up rotation flags, etc. - Adafruit_GFX_AS::setRotation(x); - // Then perform hardware-specific rotation operations... - - CS_ACTIVE; - uint16_t t; - - switch (rotation) { - case 2: - t = ILI9341_MADCTL_MX | ILI9341_MADCTL_BGR; - break; - case 3: - t = ILI9341_MADCTL_MV | ILI9341_MADCTL_BGR; - break; - case 0: - t = ILI9341_MADCTL_MY | ILI9341_MADCTL_BGR; - break; - case 1: - t = ILI9341_MADCTL_MX | ILI9341_MADCTL_MY | ILI9341_MADCTL_MV | ILI9341_MADCTL_BGR; - break; - } - writeRegister8(ILI9341_MADCTL, t ); // MADCTL - // For 9341, init default full-screen address window: - setAddrWindow(0, 0, _width - 1, _height - 1); // CS_IDLE happens here - - writeRegister8(ILI9341_MADCTL, t ); // MADCTL - // For 8357, init default full-screen address window: - setAddrWindow(0, 0, _width - 1, _height - 1); // CS_IDLE happens here - } - -#ifdef read8isFunctionalized - #define read8(x) x=read8fn() -#endif - -// Because this function is used infrequently, it configures the ports for -// the read operation, reads the data, then restores the ports to the write -// configuration. Write operations happen a LOT, so it's advantageous to -// leave the ports in that state as a default. -uint16_t Adafruit_ILI9341_8bit_AS::readPixel(int16_t x, int16_t y) { - -return 0; -} - -// Ditto with the read/write port directions, as above. -uint16_t Adafruit_ILI9341_8bit_AS::readID(void) { - uint16_t id = readReg(0xD3); - return id; -} - -uint32_t Adafruit_ILI9341_8bit_AS::readReg(uint8_t r) { - uint32_t id; - uint8_t x; - - // try reading register #4 - CS_ACTIVE; - CD_COMMAND; - write8(r); - setReadDir(); // Set up LCD data port(s) for READ operations - CD_DATA; - delayMicroseconds(50); - read8(x); - id = x; // Do not merge or otherwise simplify - id <<= 8; // these lines. It's an unfortunate - read8(x); - id |= x; // shenanigans that are going on. - id <<= 8; // these lines. It's an unfortunate - read8(x); - id |= x; // shenanigans that are going on. - id <<= 8; // these lines. It's an unfortunate - read8(x); - id |= x; // shenanigans that are going on. - CS_IDLE; - setWriteDir(); // Restore LCD data port(s) to WRITE configuration - - return id; -} - -// Pass 8-bit (each) R,G,B, get back 16-bit packed color -uint16_t Adafruit_ILI9341_8bit_AS::color565(uint8_t r, uint8_t g, uint8_t b) { - return ((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3); -} - -// For I/O macros that were left undefined, declare function -// versions that reference the inline macros just once: - -#ifndef write8 -void Adafruit_ILI9341_8bit_AS::write8(uint8_t value) { - write8inline(value); -} -#endif - -#ifdef read8isFunctionalized -uint8_t Adafruit_ILI9341_8bit_AS::read8fn(void) { - uint8_t result; - read8inline(result); - return result; -} -#endif - -#ifndef setWriteDir -void Adafruit_ILI9341_8bit_AS::setWriteDir(void) { - setWriteDirInline(); -} -#endif - -#ifndef setReadDir -void Adafruit_ILI9341_8bit_AS::setReadDir(void) { - setReadDirInline(); -} -#endif - -#ifndef writeRegister8 -void Adafruit_ILI9341_8bit_AS::writeRegister8(uint8_t a, uint8_t d) { - writeRegister8inline(a, d); -} -#endif - -#ifndef writeRegister16 -void Adafruit_ILI9341_8bit_AS::writeRegister16(uint16_t a, uint16_t d) { - writeRegister16inline(a, d); -} -#endif - -#ifndef writeRegisterPair -void Adafruit_ILI9341_8bit_AS::writeRegisterPair(uint8_t aH, uint8_t aL, uint16_t d) { - writeRegisterPairInline(aH, aL, d); -} -#endif - - -void Adafruit_ILI9341_8bit_AS::writeRegister24(uint8_t r, uint32_t d) { - CS_ACTIVE; - CD_COMMAND; - write8(r); - CD_DATA; - delayMicroseconds(10); - write8(d >> 16); - delayMicroseconds(10); - write8(d >> 8); - delayMicroseconds(10); - write8(d); - CS_IDLE; - -} - - -void Adafruit_ILI9341_8bit_AS::writeRegister32(uint8_t r, uint32_t d) { - CS_ACTIVE; - CD_COMMAND; - write8(r); - CD_DATA; - delayMicroseconds(10); - write8(d >> 24); - delayMicroseconds(10); - write8(d >> 16); - delayMicroseconds(10); - write8(d >> 8); - delayMicroseconds(10); - write8(d); - CS_IDLE; - -} diff --git a/sys/pic32/gpanel/Adafruit_ILI9341_8bit_AS.h b/sys/pic32/gpanel/Adafruit_ILI9341_8bit_AS.h deleted file mode 100644 index ec1f8b8..0000000 --- a/sys/pic32/gpanel/Adafruit_ILI9341_8bit_AS.h +++ /dev/null @@ -1,105 +0,0 @@ -// IMPORTANT: SEE COMMENTS @ LINE 15 REGARDING SHIELD VS BREAKOUT BOARD USAGE. - -// Graphics library by ladyada/adafruit with init code from Rossum -// MIT license - -#ifndef _ADAFRUIT_ILI9341_8bit_AS_H_ -#define _ADAFRUIT_ILI9341_8bit_AS_H_ - -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif - -#include "Adafruit_GFX_AS.h" - -// **** IF USING THE LCD BREAKOUT BOARD, COMMENT OUT THIS NEXT LINE. **** -// **** IF USING THE LCD SHIELD, LEAVE THE LINE ENABLED: **** - -//#define USE_ADAFRUIT_SHIELD_PINOUT 1 - -class Adafruit_ILI9341_8bit_AS : public Adafruit_GFX_AS { - - public: - - Adafruit_ILI9341_8bit_AS(uint8_t cs, uint8_t cd, uint8_t wr, uint8_t rd, uint8_t rst); - Adafruit_ILI9341_8bit_AS(void); - - void begin(uint16_t id = 0x9325); - void drawPixel(int16_t x, int16_t y, uint16_t color); - void drawFastHLine(int16_t x0, int16_t y0, int16_t w, uint16_t color); - void drawFastVLine(int16_t x0, int16_t y0, int16_t h, uint16_t color); - void fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t c); - void fillScreen(uint16_t color); - void reset(void); - void setRegisters8(uint8_t *ptr, uint8_t n); - void setRegisters16(uint16_t *ptr, uint8_t n); - void setRotation(uint8_t x); - // These methods are public in order for BMP examples to work: - void setAddrWindow(int x1, int y1, int x2, int y2); - void pushColors(uint16_t *data, uint8_t len, boolean first); - - uint16_t color565(uint8_t r, uint8_t g, uint8_t b), - readPixel(int16_t x, int16_t y), - readID(void); - uint32_t readReg(uint8_t r); - - private: - - void init(), - // These items may have previously been defined as macros - // in pin_magic.h. If not, function versions are declared: -#ifndef write8 - write8(uint8_t value), -#endif -#ifndef setWriteDir - setWriteDir(void), -#endif -#ifndef setReadDir - setReadDir(void), -#endif -#ifndef writeRegister8 - writeRegister8(uint8_t a, uint8_t d), -#endif -#ifndef writeRegister16 - writeRegister16(uint16_t a, uint16_t d), -#endif - writeRegister24(uint8_t a, uint32_t d), - writeRegister32(uint8_t a, uint32_t d), -#ifndef writeRegisterPair - writeRegisterPair(uint8_t aH, uint8_t aL, uint16_t d), -#endif - setLR(void), - flood(uint16_t color, uint32_t len); - uint8_t driver; - -#ifndef read8 - uint8_t read8fn(void); - #define read8isFunctionalized -#endif - -#ifndef USE_ADAFRUIT_SHIELD_PINOUT - - #ifdef __AVR__ - volatile uint8_t *csPort , *cdPort , *wrPort , *rdPort; - uint8_t csPinSet , cdPinSet , wrPinSet , rdPinSet , - csPinUnset, cdPinUnset, wrPinUnset, rdPinUnset, - _reset; - #endif - #if defined(__SAM3X8E__) - Pio *csPort , *cdPort , *wrPort , *rdPort; - uint32_t csPinSet , cdPinSet , wrPinSet , rdPinSet , - csPinUnset, cdPinUnset, wrPinUnset, rdPinUnset, - _reset; -#endif - -#endif -}; - -// For compatibility with sketches written for older versions of library. -// Color function name was changed to 'color565' for parity with 2.2" LCD -// library. -#define Color565 color565 - -#endif diff --git a/sys/pic32/gpanel/pin_magic_MEGA.h b/sys/pic32/gpanel/pin_magic_MEGA.h deleted file mode 100644 index e7c07fc..0000000 --- a/sys/pic32/gpanel/pin_magic_MEGA.h +++ /dev/null @@ -1,126 +0,0 @@ -#ifndef _pin_magic_ -#define _pin_magic_ -// This header file serves two purposes: -// -// 1) Isolate non-portable MCU port- and pin-specific identifiers and -// operations so the library code itself remains somewhat agnostic -// (PORTs and pin numbers are always referenced through macros). -// -// 2) GCC doesn't always respect the "inline" keyword, so this is a -// ham-fisted manner of forcing the issue to minimize function calls. -// This sometimes makes the library a bit bigger than before, but fast++. -// However, because they're macros, we need to be SUPER CAREFUL about -// parameters -- for example, write8(x) may expand to multiple PORT -// writes that all refer to x, so it needs to be a constant or fixed -// variable and not something like *ptr++ (which, after macro -// expansion, may increment the pointer repeatedly and run off into -// la-la land). Macros also give us fine-grained control over which -// operations are inlined on which boards (balancing speed against -// available program space). -// When using the TFT shield, control and data pins exist in set physical -// locations, but the ports and bitmasks corresponding to each vary among -// boards. A separate set of pin definitions is given for each supported -// board type. -// When using the TFT breakout board, control pins are configurable but -// the data pins are still fixed -- making every data pin configurable -// would be much too slow. The data pin layouts are not the same between -// the shield and breakout configurations -- for the latter, pins were -// chosen to keep the tutorial wiring manageable more than making optimal -// use of ports and bitmasks. So there's a second set of pin definitions -// given for each supported board. -// Shield pin usage: - -// Breakout pin usage: -// LCD Data Bit : 7 6 5 4 3 2 1 0 -// Uno dig. pin : 7 6 5 4 3 2 9 8 -// Uno port/pin : PD7 PD6 PD5 PD4 PD3 PD2 PB1 PB0 -// Mega dig. pin: 27 6 5 4 3 2 9 8 -// Mega port/pin: PH4 PH3 PE3 PG5 PE5 PE4 PH6 PH5 - -// Pixel read operations require a minimum 400 nS delay from RD_ACTIVE -// to polling the input pins. At 16 MHz, one machine cycle is 62.5 nS. -// This code burns 7 cycles (437.5 nS) doing nothing; the RJMPs are -// equivalent to two NOPs each, final NOP burns the 7th cycle, and the -// last line is a radioactive mutant emoticon. -#define DELAY7 \ -asm volatile( \ -"rjmp .+0" "\n\t" \ -"rjmp .+0" "\n\t" \ -"rjmp .+0" "\n\t" \ -"nop" "\n" \ -::); - - -// As part of the inline control, macros reference other macros...if any -// of these are left undefined, an equivalent function version (non-inline) -// is declared later. The Uno has a moderate amount of program space, so -// only write8() is inlined -- that one provides the most performance -// benefit, but unfortunately also generates the most bloat. This is -// why only certain cases are inlined for each board. - - -// Arduino Mega, ADK, etc. -// Mega port/pin: PH4 PH3 PE3 PG5 PE5 PE4 PH6 PH5 -// Because the MEGA port to pin mapping is very messy it is necessary to shift the data bits around a lot. - #define write8inline(d) { \ - PORTE = (PORTE & B11001111) | ((d << 2) & B00110000); \ - PORTE = (PORTE & B11110111) | ((d >> 2) & B00001000); \ - PORTG = (PORTG & B11011111) | ((d << 1) & B00100000); \ - PORTH = (PORTH & B11100111) | ((d >> 3) & B00011000); \ - PORTH = (PORTH & B10011111) | ((d << 5) & B01100000); \ - WR_STROBE; } - #define read8inline(result) { \ - RD_ACTIVE; \ - DELAY7; \ - result = ((PINH & B00011000) << 3) | ((PINE & B00001000) << 2) | ((PING & B00100000) >> 1) |((PINE & B00110000) >> 2) | ((PINH & B01100000) >> 5); \ - RD_IDLE; } - - // // These set the PORT directions as required before the write and read - // // operations. - #define setWriteDirInline() { DDRE |= B00111000; DDRG |= B00100000; DDRH |= B01111000;} - #define setReadDirInline() { DDRE &= ~B00111000; DDRG &= ~B00100000; DDRH &= ~B01111000;} - - -// All of the functions are inlined on the Arduino Mega. When using the -// breakout board, the macro versions aren't appreciably larger than the -// function equivalents, and they're super simple and fast. When using -// the shield, the macros become pretty complicated...but this board has -// so much code space, the macros are used anyway. If you need to free -// up program space, some macros can be removed, at a minor cost in speed. -#define write8 write8inline -#define read8 read8inline -#define setWriteDir setWriteDirInline -#define setReadDir setReadDirInline -#define writeRegister8 writeRegister8inline -#define writeRegister16 writeRegister16inline -#define writeRegisterPair writeRegisterPairInline -// When using the TFT breakout board, control pins are configurable. -#define RD_ACTIVE *rdPort &= rdPinUnset -#define RD_IDLE *rdPort |= rdPinSet -#define WR_ACTIVE *wrPort &= wrPinUnset -#define WR_IDLE *wrPort |= wrPinSet -#define CD_COMMAND *cdPort &= cdPinUnset -#define CD_DATA *cdPort |= cdPinSet -#define CS_ACTIVE *csPort &= csPinUnset -#define CS_IDLE *csPort |= csPinSet -#endif -// Data read and write strobes, ~2 instructions and always inline -#define RD_STROBE { RD_ACTIVE; RD_IDLE; } -#define WR_STROBE { WR_ACTIVE; WR_IDLE; } -// These higher-level operations are usually functionalized, -// except on Mega where's there's gobs and gobs of program space. -// Set value of TFT register: 8-bit address, 8-bit value -#define writeRegister8inline(a, d) { \ -CD_COMMAND; write8(a); CD_DATA; write8(d); } -// Set value of TFT register: 16-bit address, 16-bit value -// See notes at top about macro expansion, hence hi & lo temp vars -#define writeRegister16inline(a, d) { \ -uint8_t hi, lo; \ -hi = (a) >> 8; lo = (a); CD_COMMAND; write8(hi); write8(lo); \ -hi = (d) >> 8; lo = (d); CD_DATA ; write8(hi); write8(lo); } -// Set value of 2 TFT registers: Two 8-bit addresses (hi & lo), 16-bit value -#define writeRegisterPairInline(aH, aL, d) { \ -uint8_t hi = (d) >> 8, lo = (d); \ -CD_COMMAND; write8(aH); CD_DATA; write8(hi); \ -CD_COMMAND; write8(aL); CD_DATA; write8(lo); } - diff --git a/sys/pic32/gpanel/pin_magic_UNO.h b/sys/pic32/gpanel/pin_magic_UNO.h deleted file mode 100644 index d631e6b..0000000 --- a/sys/pic32/gpanel/pin_magic_UNO.h +++ /dev/null @@ -1,117 +0,0 @@ -#ifndef _pin_magic_ -#define _pin_magic_ -// This header file serves two purposes: -// -// 1) Isolate non-portable MCU port- and pin-specific identifiers and -// operations so the library code itself remains somewhat agnostic -// (PORTs and pin numbers are always referenced through macros). -// -// 2) GCC doesn't always respect the "inline" keyword, so this is a -// ham-fisted manner of forcing the issue to minimize function calls. -// This sometimes makes the library a bit bigger than before, but fast++. -// However, because they're macros, we need to be SUPER CAREFUL about -// parameters -- for example, write8(x) may expand to multiple PORT -// writes that all refer to x, so it needs to be a constant or fixed -// variable and not something like *ptr++ (which, after macro -// expansion, may increment the pointer repeatedly and run off into -// la-la land). Macros also give us fine-grained control over which -// operations are inlined on which boards (balancing speed against -// available program space). -// When using the TFT shield, control and data pins exist in set physical -// locations, but the ports and bitmasks corresponding to each vary among -// boards. A separate set of pin definitions is given for each supported -// board type. -// When using the TFT breakout board, control pins are configurable but -// the data pins are still fixed -- making every data pin configurable -// would be much too slow. The data pin layouts are not the same between -// the shield and breakout configurations -- for the latter, pins were -// chosen to keep the tutorial wiring manageable more than making optimal -// use of ports and bitmasks. So there's a second set of pin definitions -// given for each supported board. -// Shield pin usage: - -// Breakout pin usage: -// LCD Data Bit : 7 6 5 4 3 2 1 0 -// Uno dig. pin : 7 6 5 4 3 2 9 8 -// Uno port/pin : PD7 PD6 PD5 PD4 PD3 PD2 PB1 PB0 -// Mega dig. pin: 27 6 5 4 3 2 9 8 -// Mega port/pin: PH4 PH3 PE3 PG5 PE5 PE4 PH6 PH5 - -// Pixel read operations require a minimum 400 nS delay from RD_ACTIVE -// to polling the input pins. At 16 MHz, one machine cycle is 62.5 nS. -// This code burns 7 cycles (437.5 nS) doing nothing; the RJMPs are -// equivalent to two NOPs each, final NOP burns the 7th cycle, and the -// last line is a radioactive mutant emoticon. -#define DELAY7 \ -asm volatile( \ -"rjmp .+0" "\n\t" \ -"rjmp .+0" "\n\t" \ -"rjmp .+0" "\n\t" \ -"nop" "\n" \ -::); -// As part of the inline control, macros reference other macros...if any -// of these are left undefined, an equivalent function version (non-inline) -// is declared later. The Uno has a moderate amount of program space, so -// only write8() is inlined -- that one provides the most performance -// benefit, but unfortunately also generates the most bloat. This is -// why only certain cases are inlined for each board. -//Uno w/Breakout board -// Uno dig. pin : 7 6 5 4 3 2 9 8 -// Uno port/pin : PD7 PD6 PD5 PD4 PD3 PD2 PB1 PB0 -#define write8inline(d) { \ -PORTD = (PORTD & B00000011) | ((d) & B11111100); \ -PORTB = (PORTB & B11111100) | ((d) & B00000011); \ -WR_STROBE; } -#define read8inline(result) { \ -RD_ACTIVE; \ -DELAY7; \ -result = (PIND & B11111100) | (PINB & B00000011); \ -RD_IDLE; } -#define setWriteDirInline() { DDRD |= B11111100; DDRB |= B00000011; } -#define setReadDirInline() { DDRD &= ~B11111100; DDRB &= ~B00000011; } - - - -// All of the functions are inlined on the Arduino Mega. When using the -// breakout board, the macro versions aren't appreciably larger than the -// function equivalents, and they're super simple and fast. When using -// the shield, the macros become pretty complicated...but this board has -// so much code space, the macros are used anyway. If you need to free -// up program space, some macros can be removed, at a minor cost in speed. -#define write8 write8inline -#define read8 read8inline -#define setWriteDir setWriteDirInline -#define setReadDir setReadDirInline -#define writeRegister8 writeRegister8inline -#define writeRegister16 writeRegister16inline -#define writeRegisterPair writeRegisterPairInline -// When using the TFT breakout board, control pins are configurable. -#define RD_ACTIVE *rdPort &= rdPinUnset -#define RD_IDLE *rdPort |= rdPinSet -#define WR_ACTIVE *wrPort &= wrPinUnset -#define WR_IDLE *wrPort |= wrPinSet -#define CD_COMMAND *cdPort &= cdPinUnset -#define CD_DATA *cdPort |= cdPinSet -#define CS_ACTIVE *csPort &= csPinUnset -#define CS_IDLE *csPort |= csPinSet -#endif -// Data read and write strobes, ~2 instructions and always inline -#define RD_STROBE { RD_ACTIVE; RD_IDLE; } -#define WR_STROBE { WR_ACTIVE; WR_IDLE; } -// These higher-level operations are usually functionalized, -// except on Mega where's there's gobs and gobs of program space. -// Set value of TFT register: 8-bit address, 8-bit value -#define writeRegister8inline(a, d) { \ -CD_COMMAND; write8(a); CD_DATA; write8(d); } -// Set value of TFT register: 16-bit address, 16-bit value -// See notes at top about macro expansion, hence hi & lo temp vars -#define writeRegister16inline(a, d) { \ -uint8_t hi, lo; \ -hi = (a) >> 8; lo = (a); CD_COMMAND; write8(hi); write8(lo); \ -hi = (d) >> 8; lo = (d); CD_DATA ; write8(hi); write8(lo); } -// Set value of 2 TFT registers: Two 8-bit addresses (hi & lo), 16-bit value -#define writeRegisterPairInline(aH, aL, d) { \ -uint8_t hi = (d) >> 8, lo = (d); \ -CD_COMMAND; write8(aH); CD_DATA; write8(hi); \ -CD_COMMAND; write8(aL); CD_DATA; write8(lo); } - diff --git a/sys/pic32/gpanel/registers.h b/sys/pic32/gpanel/registers.h deleted file mode 100644 index 4ad78de..0000000 --- a/sys/pic32/gpanel/registers.h +++ /dev/null @@ -1,30 +0,0 @@ -#define ILI9341_SOFTRESET 0x01 -#define ILI9341_SLEEPIN 0x10 -#define ILI9341_SLEEPOUT 0x11 -#define ILI9341_NORMALDISP 0x13 -#define ILI9341_INVERTOFF 0x20 -#define ILI9341_INVERTON 0x21 -#define ILI9341_GAMMASET 0x26 -#define ILI9341_DISPLAYOFF 0x28 -#define ILI9341_DISPLAYON 0x29 -#define ILI9341_COLADDRSET 0x2A -#define ILI9341_PAGEADDRSET 0x2B -#define ILI9341_MEMORYWRITE 0x2C -#define ILI9341_MEMCONTROL 0x36 -#define ILI9341_MADCTL 0x36 -#define ILI9341_PIXELFORMAT 0x3A -#define ILI9341_FRAMECONTROL 0xB1 -#define ILI9341_DISPLAYFUNC 0xB6 -#define ILI9341_ENTRYMODE 0xB7 -#define ILI9341_POWERCONTROL1 0xC0 -#define ILI9341_POWERCONTROL2 0xC1 -#define ILI9341_VCOMCONTROL1 0xC5 -#define ILI9341_VCOMCONTROL2 0xC7 - -#define ILI9341_MADCTL_MY 0x80 -#define ILI9341_MADCTL_MX 0x40 -#define ILI9341_MADCTL_MV 0x20 -#define ILI9341_MADCTL_ML 0x10 -#define ILI9341_MADCTL_BGR 0x08 -#define ILI9341_MADCTL_MH 0x04 -#define ILI9341_MADCTL_RGB 0x00 diff --git a/sys/pic32/gpanel/st7781-landscape.c b/sys/pic32/gpanel/st7781-landscape.c deleted file mode 100644 index 27ed9ec..0000000 --- a/sys/pic32/gpanel/st7781-landscape.c +++ /dev/null @@ -1,928 +0,0 @@ -/* - * ST7781 TFT LCD driver for PIC32. - * - * Based on code provided by Smoke And Wires - * https://github.com/Smoke-And-Wires/TFT-Shield-Example-Code - * - * Copyright (C) 2015 Serge Vakulenko - * - * Permission to use, copy, modify, and distribute this software - * and its documentation for any purpose and without fee is hereby - * granted, provided that the above copyright notice appear in all - * copies and that both that the copyright notice and this - * permission notice and warranty disclaimer appear in supporting - * documentation, and that the name of the author not be used in - * advertising or publicity pertaining to distribution of the - * software without specific, written prior permission. - * - * The author disclaim all warranties with regard to this - * software, including all implied warranties of merchantability - * and fitness. In no event shall the author be liable for any - * special, indirect or consequential damages or any damages - * whatsoever resulting from loss of use, data or profits, whether - * in an action of contract, negligence or other tortious action, - * arising out of or in connection with the use or performance of - * this software. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * Display size. - */ -//#define WIDTH 240 -//#define HEIGHT 320 -#define WIDTH 320 -#define HEIGHT 240 - -/* - * Cursor position for text output. - */ -static int _col, _row; - -/* - * ID of the LCD controller chip. - */ -static int _chip_id; - -/* - * Delay for 100 nanoseconds. - * Needed to match the /WR and /RD timing requirements. - */ -#if CPU_KHZ <= 10000 -# define delay100ns() /* empty */ -#elif CPU_KHZ <= 20000 -# define delay100ns() asm volatile("nop") -#elif CPU_KHZ <= 30000 -# define delay100ns() asm volatile("nop; nop") -#elif CPU_KHZ <= 40000 -# define delay100ns() asm volatile("nop; nop; nop") -#elif CPU_KHZ <= 50000 -# define delay100ns() asm volatile("nop; nop; nop; nop") -#elif CPU_KHZ <= 60000 -# define delay100ns() asm volatile("nop; nop; nop; nop; nop") -#elif CPU_KHZ <= 70000 -# define delay100ns() asm volatile("nop; nop; nop; nop; nop; nop") -#else -# define delay100ns() asm volatile("nop; nop; nop; nop; nop; nop; nop; nop") -#endif - -/* - * Signal mappings: - * /RESET - reset and initialize the chip. - * /CS - chip select when low. - * /RD - read operation enable. - * /WR - write operation enable. - * RS - command or data mode selection. - * D0-D7 - data bus, bidirectional. - */ -#define RST_IDLE() LAT_SET(LCD_RST_PORT) = 1<> 8); - writeByte(reg); - RS_DATA(); - writeByte(value >> 8); - writeByte(value); -} - -/* - * Read device ID code. - */ -static unsigned readDeviceId() -{ - unsigned value; - - CS_ACTIVE(); - RS_COMMAND(); - writeByte(ST7781_Driver_ID_Code_Read); - delay100ns(); - WR_STROBE(); // Repeat prior byte - setReadDir(); // Switch data bus as input - RS_DATA(); - value = readByte() << 8; - value |= readByte(); - setWriteDir(); // Restore data bus as output - CS_IDLE(); - return value; -} - -/* - * Detect the type of the LCD controller, and initialize it. - * Return -1 in case of unknown chip. - */ -static int initDisplay() -{ - /* - * Set all control bits to high (idle). - * Signals are active low. - */ - CS_IDLE(); - WR_IDLE(); - RD_IDLE(); - RST_IDLE(); - - /* Enable outputs. */ - TRIS_CLR(LCD_CS_PORT) = 1 << LCD_CS_PIN; - TRIS_CLR(LCD_RS_PORT) = 1 << LCD_RS_PIN; - TRIS_CLR(LCD_WR_PORT) = 1 << LCD_WR_PIN; - TRIS_CLR(LCD_RD_PORT) = 1 << LCD_RD_PIN; - TRIS_CLR(LCD_RST_PORT) = 1 << LCD_RST_PIN; - setWriteDir(); - - /* Reset the chip. */ - RST_ACTIVE(); - udelay(1000); - RST_IDLE(); - udelay(1000); - - /* Read the the chip ID register. */ - _chip_id = readDeviceId(); - switch (_chip_id) { - case 0x7783: - printf("swtft0: \n"); - break; - - default: - /* Disable outputs. */ - setReadDir(); - TRIS_SET(LCD_CS_PORT) = 1 << LCD_CS_PIN; - TRIS_SET(LCD_RS_PORT) = 1 << LCD_RS_PIN; - TRIS_SET(LCD_WR_PORT) = 1 << LCD_WR_PIN; - TRIS_SET(LCD_RD_PORT) = 1 << LCD_RD_PIN; - TRIS_SET(LCD_RST_PORT) = 1 << LCD_RST_PIN; - printf("swtft0: Unknown chip ID = 0x%x\n", _chip_id); - return -1; - } - - /* Initialization of LCD controller. */ - CS_ACTIVE(); - writeReg(ST7781_Driver_Output_Control, 0x0100); - writeReg(ST7781_LCD_Driving_Wave_Control, 0x0700); - //writeReg(ST7781_Entry_Mode, 0x1030); - writeReg(ST7781_Entry_Mode, 0x1028); - writeReg(ST7781_Display_control_2, 0x0302); - writeReg(ST7781_Display_Control_3, 0x0000); - writeReg(ST7781_Display_Control_4, 0x0008); - - /* Power control registers. */ - writeReg(ST7781_Power_Control_1, 0x0790); - writeReg(ST7781_Power_Control_2, 0x0005); - writeReg(ST7781_Power_Control_3, 0x0000); - writeReg(ST7781_Power_Control_4, 0x0000); - - /* Power supply startup 1 settings. */ - writeReg(ST7781_Power_Control_1, 0x12B0); - writeReg(ST7781_Power_Control_2, 0x0007); - - /* Power supply startup 2 settings. */ - writeReg(ST7781_Power_Control_3, 0x008C); - writeReg(ST7781_Power_Control_4, 0x1700); - writeReg(ST7781_VCOMH_Control, 0x0022); - - /* Gamma cluster settings. */ - writeReg(ST7781_Gamma_Control_1, 0x0000); - writeReg(ST7781_Gamma_Control_2, 0x0505); - writeReg(ST7781_Gamma_Control_3, 0x0205); - writeReg(ST7781_Gamma_Control_4, 0x0206); - writeReg(ST7781_Gamma_Control_5, 0x0408); - writeReg(ST7781_Gamma_Control_6, 0x0000); - writeReg(ST7781_Gamma_Control_7, 0x0504); - writeReg(ST7781_Gamma_Control_8, 0x0206); - writeReg(ST7781_Gamma_Control_9, 0x0206); - writeReg(ST7781_Gamma_Control_10, 0x0408); - - /* Frame rate settings. */ - writeReg(ST7781_Gate_Scan_Control_1, 0xA700); - writeReg(ST7781_Gate_Scan_Control_2, 0x0001); - writeReg(ST7781_Panel_Interface_Control_1, 0x0033); // RTNI setting - - /* Display on. */ - writeReg(ST7781_Display_Control_1, 0x0133); - return 0; -} - -static void setAddrWindow(int x0, int y0, int x1, int y1) -{ - if (WIDTH > HEIGHT) { - /* Landscape mode. */ - int t; - t = x0; - x0 = HEIGHT-1 - y1; - y1 = x1; - x1 = HEIGHT-1 - y0; - y0 = t; - } - /* Set address window. */ - CS_ACTIVE(); - writeReg(ST7781_Horizontal_Address_Start_Position, x0); - writeReg(ST7781_Horizontal_Address_End_Position, x1); - writeReg(ST7781_Vertical_Address_Start_Position, y0); - writeReg(ST7781_Vertical_Address_End_Position, y1); - - /* Set address counter to top left. */ - //writeReg(ST7781_DRAM_Horizontal_Address_Set, (WIDTH > HEIGHT) ? x1 : x0); - writeReg(ST7781_DRAM_Horizontal_Address_Set, x0); - writeReg(ST7781_DRAM_Vertical_Address_Set, y0); - CS_IDLE(); -} - -/* - * Draw a pixel. - */ -static void setPixel(int x, int y, int color) -{ - if (x < 0 || x >= WIDTH || y < 0 || y >= HEIGHT) - return; - CS_ACTIVE(); - if (WIDTH > HEIGHT) { - /* Landscape mode. */ - writeReg(ST7781_DRAM_Horizontal_Address_Set, HEIGHT-1 - y); - writeReg(ST7781_DRAM_Vertical_Address_Set, x); - } else { - /* Portrait mode. */ - writeReg(ST7781_DRAM_Horizontal_Address_Set, x); - writeReg(ST7781_DRAM_Vertical_Address_Set, y); - } - writeReg(ST7781_Write_Data_to_DRAM, color); - CS_IDLE(); -} - -/* - * Fast block fill operation. - * Requires setAddrWindow() has previously been called to set - * the fill bounds. - * 'npixels' is inclusive, MUST be >= 1. - */ -static void flood(int color, int npixels) -{ - unsigned blocks, i; - unsigned hi = color >> 8, - lo = color; - - CS_ACTIVE(); - RS_COMMAND(); - writeByte(0x00); /* High address byte */ - writeByte(ST7781_Write_Data_to_DRAM); - - /* Write first pixel normally, decrement counter by 1. */ - RS_DATA(); - writeByte(hi); - writeByte(lo); - npixels--; - - /* 64 pixels/block. */ - blocks = npixels >> 6; - if (hi == lo) { - /* High and low bytes are identical. Leave prior data - * on the port(s) and just toggle the write strobe. */ - while (blocks--) { - /* 64 pixels/block / 4 pixels/pass. */ - for (i = 16; i > 0; i--) { - /* 2 bytes/pixel x 4 pixels. */ - delay100ns(); WR_STROBE(); - delay100ns(); WR_STROBE(); - delay100ns(); WR_STROBE(); - delay100ns(); WR_STROBE(); - delay100ns(); WR_STROBE(); - delay100ns(); WR_STROBE(); - delay100ns(); WR_STROBE(); - delay100ns(); WR_STROBE(); - } - } - /* Fill any remaining pixels (1 to 64). */ - for (i = npixels & 63; i > 0; i--) { - delay100ns(); WR_STROBE(); - delay100ns(); WR_STROBE(); - } - } else { - while (blocks--) { - /* 64 pixels/block / 4 pixels/pass. */ - for (i = 16; i > 0; i--) { - writeByte(hi); writeByte(lo); writeByte(hi); writeByte(lo); - writeByte(hi); writeByte(lo); writeByte(hi); writeByte(lo); - } - } - for (i = npixels & 63; i > 0; i--) { - writeByte(hi); - writeByte(lo); - } - } - CS_IDLE(); -} - -/* - * Fill a rectangle with specified color. - */ -static void fillRectangle(int x0, int y0, int x1, int y1, int color) -{ - if (x0 < 0) x0 = 0; - if (y0 < 0) x0 = 0; - if (x1 < 0) x1 = 0; - if (y1 < 0) x1 = 0; - if (x0 >= WIDTH) x0 = WIDTH-1; - if (x1 >= WIDTH) x1 = WIDTH-1; - if (y0 >= HEIGHT) y0 = HEIGHT-1; - if (y1 >= HEIGHT) y1 = HEIGHT-1; - - if (x1 < x0) { - int t = x0; - x0 = x1; - x1 = t; - } - if (y1 < y0) { - int t = y0; - y0 = y1; - y1 = t; - } - setAddrWindow(x0, y0, x1, y1); - flood(color, (x1 - x0 + 1) * (y1 - y0 + 1)); - setAddrWindow(0, 0, WIDTH-1, HEIGHT-1); -} - -/* - * Fill a rectangle with user data. - */ -static void drawImage(int x, int y, int width, int height, - const unsigned short *data) -{ - unsigned cnt = width * height; - int color; - - setAddrWindow(x, y, x + width - 1, y + height - 1); - CS_ACTIVE(); - RS_COMMAND(); - writeByte(0x00); /* High address byte */ - writeByte(ST7781_Write_Data_to_DRAM); - RS_DATA(); - while (cnt--) { - color = *data++; - writeByte(color >> 8); - writeByte(color); - } - CS_IDLE(); - if (WIDTH > HEIGHT) - setAddrWindow(0, 0, WIDTH-1, HEIGHT-1); -} - -/* - * Draw a line. - */ -static void drawLine(int x0, int y0, int x1, int y1, int color) -{ - int dx, dy, stepx, stepy, fraction; - - if (x0 == x1 || y0 == y1) { - fillRectangle(x0, y0, x1, y1, color); - return; - } - - /* Use Bresenham's line algorithm. */ - dy = y1 - y0; - if (dy < 0) { - dy = -dy; - stepy = -1; - } else { - stepy = 1; - } - dx = x1 - x0; - if (dx < 0) { - dx = -dx; - stepx = -1; - } else { - stepx = 1; - } - dy <<= 1; /* dy is now 2*dy */ - dx <<= 1; /* dx is now 2*dx */ - setPixel(x0, y0, color); - if (dx > dy) { - fraction = dy - (dx >> 1); /* same as 2*dy - dx */ - while (x0 != x1) { - if (fraction >= 0) { - y0 += stepy; - fraction -= dx; /* same as fraction -= 2*dx */ - } - x0 += stepx; - fraction += dy; /* same as fraction -= 2*dy */ - setPixel(x0, y0, color); - } - } else { - fraction = dx - (dy >> 1); - while (y0 != y1) { - if (fraction >= 0) { - x0 += stepx; - fraction -= dy; - } - y0 += stepy; - fraction += dx; - setPixel(x0, y0, color); - } - } -} - -/* - * Draw a rectangular frame. - */ -static void drawFrame(int x0, int y0, int x1, int y1, int color) -{ - fillRectangle(x0, y0, x1, y0, color); - fillRectangle(x0, y1, x1, y1, color); - fillRectangle(x0, y0, x0, y1, color); - fillRectangle(x1, y0, x1, y1, color); -} - -/* - * Draw a circle. - */ -static void drawCircle(int x0, int y0, int radius, int color) -{ - int f = 1 - radius; - int ddF_x = 0; - int ddF_y = -2 * radius; - int x = 0; - int y = radius; - - setPixel(x0, y0 + radius, color); - setPixel(x0, y0 - radius, color); - setPixel(x0 + radius, y0, color); - setPixel(x0 - radius, y0, color); - while (x < y) { - if (f >= 0) { - y--; - ddF_y += 2; - f += ddF_y; - } - x++; - ddF_x += 2; - f += ddF_x + 1; - setPixel(x0 + x, y0 + y, color); - setPixel(x0 - x, y0 + y, color); - setPixel(x0 + x, y0 - y, color); - setPixel(x0 - x, y0 - y, color); - setPixel(x0 + y, y0 + x, color); - setPixel(x0 - y, y0 + x, color); - setPixel(x0 + y, y0 - x, color); - setPixel(x0 - y, y0 - x, color); - } -} - -/* - * Start a new line: increase row. - */ -static void newLine(const struct gpanel_font_t *font) -{ - _col = 0; - _row += font->height; - if (_row > HEIGHT - font->height) - _row = 0; -} - -/* - * Draw a glyph of one symbol. - */ -static void drawGlyph(const struct gpanel_font_t *font, - int color, int background, int width, const unsigned short *bits) -{ - int h, w, c; - unsigned bitmask = 0; - - if (background >= 0) { - /* - * Clear background. - */ - setAddrWindow(_col, _row, _col + width - 1, _row + font->height - 1); - CS_ACTIVE(); - RS_COMMAND(); - writeByte(0x00); /* High address byte */ - writeByte(ST7781_Write_Data_to_DRAM); - RS_DATA(); - - /* Loop on each glyph row. */ - for (h=0; hheight; h++) { - /* Loop on every pixel in the row (left to right). */ - for (w=0; w> 8); - writeByte(c); - } - } - CS_IDLE(); - } else { - /* - * Transparent background. - */ - /* Loop on each glyph row. */ - for (h=0; hheight; h++) { - /* Loop on every pixel in the row (left to right). */ - for (w=0; wfirstchar || sym >= font->firstchar + font->size) - sym = font->defaultchar; - cindex = sym - font->firstchar; - - /* Get font bitmap depending on fixed pitch or not. */ - if (font->width) { - /* Proportional font. */ - width = font->width[cindex]; - } else { - /* Fixed width font. */ - width = font->maxwidth; - } - if (font->offset) { - bits = font->bits + font->offset[cindex]; - } else { - bits = font->bits + cindex * font->height; - } - - /* Draw a character. */ - if (_col < WIDTH) - drawGlyph(font, color, background, width, bits); - _col += width; -} - -/* - * Draw a string of characters. - * TODO: Decode UTF-8. - */ -static void drawText(const struct gpanel_font_t *font, - int color, int background, int x, int y, const char *text) -{ - int sym; - - _col = x; - _row = y; - for (;;) { - sym = *text++; - if (! sym) - break; - - drawChar(font, color, background, sym); - } - if (WIDTH > HEIGHT) - setAddrWindow(0, 0, WIDTH-1, HEIGHT-1); -} - -int gpanel_open(dev_t dev, int flag, int mode) -{ - if (minor(dev) != 0) - return ENODEV; - return 0; -} - -int gpanel_close(dev_t dev, int flag, int mode) -{ - return 0; -} - -int gpanel_read(dev_t dev, struct uio *uio, int flag) -{ - return ENODEV; -} - -int gpanel_write(dev_t dev, struct uio *uio, int flag) -{ - return ENODEV; -} - -/* - * TODO: check whether user pointers are valid. - */ -int gpanel_ioctl(dev_t dev, register u_int cmd, caddr_t addr, int flag) -{ - switch (cmd) { - /* - * Clear the whole screen with a given color. - */ - case GPANEL_CLEAR: { - struct gpanel_clear_t *param = (struct gpanel_clear_t*) addr; - - setAddrWindow(0, 0, WIDTH-1, HEIGHT-1); - flood(param->color, WIDTH * HEIGHT); - if (WIDTH > HEIGHT) - setAddrWindow(0, 0, WIDTH-1, HEIGHT-1); - param->xsize = WIDTH; - param->ysize = HEIGHT; - break; - } - - /* - * Draw a single pixel. - */ - case GPANEL_PIXEL: { - struct gpanel_pixel_t *param = (struct gpanel_pixel_t*) addr; - - setPixel(param->x, param->y, param->color); - break; - } - - /* - * Draw a line. - */ - case GPANEL_LINE: { - struct gpanel_line_t *param = (struct gpanel_line_t*) addr; - - drawLine(param->x0, param->y0, param->x1, param->y1, param->color); - break; - } - - /* - * Draw a rectangle frame. - */ - case GPANEL_RECT: { - struct gpanel_rect_t *param = (struct gpanel_rect_t*) addr; - - drawFrame(param->x0, param->y0, param->x1, param->y1, param->color); - break; - } - - /* - * Fill a rectangle with color. - */ - case GPANEL_FILL: { - struct gpanel_rect_t *param = (struct gpanel_rect_t*) addr; - - fillRectangle(param->x0, param->y0, param->x1, param->y1, param->color); - break; - } - - /* - * Draw a circle. - */ - case GPANEL_CIRCLE: { - struct gpanel_circle_t *param = (struct gpanel_circle_t*) addr; - - drawCircle(param->x, param->y, param->radius, param->color); - break; - } - - /* - * Fill a rectangular area with the user-supplied data. - */ - case GPANEL_IMAGE: { - struct gpanel_image_t *param = (struct gpanel_image_t*) addr; - - drawImage(param->x, param->y, param->width, param->height, - param->image); - break; - } - - /* - * Draw a character. - */ - case GPANEL_CHAR: { - struct gpanel_char_t *param = (struct gpanel_char_t*) addr; - - _col = param->x; - _row = param->y; - drawChar(param->font, param->color, param->background, param->sym); - if (WIDTH > HEIGHT) - setAddrWindow(0, 0, WIDTH-1, HEIGHT-1); - break; - } - - /* - * Draw a string of characters. - */ - case GPANEL_TEXT: { - struct gpanel_text_t *param = (struct gpanel_text_t*) addr; - - drawText(param->font, param->color, param->background, - param->x, param->y, param->text); - break; - } - } - return 0; -} - -/* - * Test to see if device is present. - * Return true if found and initialized ok. - */ -static int -swtftprobe(config) - struct conf_device *config; -{ - if (initDisplay() < 0) - return 0; - - printf("swtft0: display %ux%u\n", WIDTH, HEIGHT); - setAddrWindow(0, 0, WIDTH-1, HEIGHT-1); - return 1; -} - -struct driver swtftdriver = { - "swtft", swtftprobe, -};