Fork of https://os.mbed.com/users/sebastiken/code/Adafruit_RA8875/ ; Adapted for use with K64F and in the process of adding more functions.
Diff: RA8875.cpp
- Revision:
- 0:66c1aa3d198e
- Child:
- 1:ac22f0f36d6b
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/RA8875.cpp Fri Sep 08 14:05:04 2017 +0000 @@ -0,0 +1,1300 @@ +/**************************************************************************/ +/*! + @file Adafruit_RA8875.cpp + @author Limor Friend/Ladyada, K.Townsend/KTOWN for Adafruit Industries + @license BSD license, all text above and below must be included in + any redistribution + + This is the library for the Adafruit RA8875 Driver board for TFT displays + ---------------> http://www.adafruit.com/products/1590 + The RA8875 is a TFT driver for up to 800x480 dotclock'd displays + It is tested to work with displays in the Adafruit shop. Other displays + may need timing adjustments and are not guanteed to work. + + Adafruit invests time and resources providing this open + source code, please support Adafruit and open-source hardware + by purchasing products from Adafruit! + + Written by Limor Fried/Ladyada for Adafruit Industries. + BSD license, check license.txt for more information. + All text above must be included in any redistribution. + + @section HISTORY + + v1.0 - First release + + Code migrated to Mbed. +*/ +/**************************************************************************/ +#include "RA8875.h" + +#if defined (ARDUINO_ARCH_ARC32) + uint32_t spi_speed = 12000000; +#else + uint32_t spi_speed = 4000000; +#endif + +// NOTE: MBed use transactions inside SPI class itself +//// If the SPI library has transaction support, these functions +//// establish settings and protect from interference from other +//// libraries. Otherwise, they simply do nothing. +//#ifdef SPI_HAS_TRANSACTION +// static inline void spi_begin(void) __attribute__((always_inline)); +// static inline void spi_begin(void) { +// // max speed! +// SPI.beginTransaction(SPISettings(spi_speed, MSBFIRST, SPI_MODE0)); +// } +// static inline void spi_end(void) __attribute__((always_inline)); +// static inline void spi_end(void) { +// SPI.endTransaction(); +// } +//#else +// #define spi_begin() +// #define spi_end() +//#endif + + +/**************************************************************************/ +/*! + Constructor for a new RA8875 instance + + @args CS[in] Location of the SPI chip select pin + @args RST[in] Location of the reset pin +*/ +/**************************************************************************/ +Adafruit_RA8875::Adafruit_RA8875(PinName MOSI, PinName MISO, PinName SCLK, + PinName CS, PinName RST) + : //Adafruit_GFX(800, 480) + _cs(CS) + , _rst(RST) + , spi(MOSI, MISO, SCLK) +{ +} + +/**************************************************************************/ +/*! + Initialises the LCD driver and any HW required by the display + + @args s[in] The display size, which can be either: + 'RA8875_480x272' (4.3" displays) r + 'RA8875_800x480' (5" and 7" displays) +*/ +/**************************************************************************/ +bool Adafruit_RA8875::begin(enum RA8875sizes s) { + _size = s; + + if (_size == RA8875_480x272) { + _width = 480; + _height = 272; + } + else if (_size == RA8875_800x480) { + _width = 800; + _height = 480; + } + else { + return false; + } + + _cs = 1; + + _rst = 0; + wait_ms(100); + _rst = 1; + wait_ms(100); + + // Setting format + spi.format(8, 0); + + // Configure SPI frequency + spi_speed = 2000000; + spi.frequency(spi_speed); + + uint8_t x = readReg(0); +// Serial.print("x = 0x"); Serial.println(x,HEX); + if (x != 0x75) { + return false; + } + + + + initialize(); + +#ifdef SPI_HAS_TRANSACTION + #if defined (ARDUINO_ARCH_ARC32) + spi_speed = 12000000L; + #else + spi_speed = 4000000L; + #endif +#else + #ifdef __AVR__ + SPI.setClockDivider(SPI_CLOCK_DIV4); + #endif +#endif + + return true; +} + +/************************* Initialization *********************************/ + +/**************************************************************************/ +/*! + Performs a SW-based reset of the RA8875 +*/ +/**************************************************************************/ +void Adafruit_RA8875::softReset(void) { + writeCommand(RA8875_PWRR); + writeData(RA8875_PWRR_SOFTRESET); + writeData(RA8875_PWRR_NORMAL); + wait_ms(1); +} + +/**************************************************************************/ +/*! + Initialise the PLL +*/ +/**************************************************************************/ +void Adafruit_RA8875::PLLinit(void) { + if (_size == RA8875_480x272) { + writeReg(RA8875_PLLC1, RA8875_PLLC1_PLLDIV1 + 10); + wait_ms(1); + writeReg(RA8875_PLLC2, RA8875_PLLC2_DIV4); + wait_ms(1); + } + else /* (_size == RA8875_800x480) */ { + writeReg(RA8875_PLLC1, RA8875_PLLC1_PLLDIV1 + 10); + wait_ms(1); + writeReg(RA8875_PLLC2, RA8875_PLLC2_DIV4); + wait_ms(1); + } +} + +/**************************************************************************/ +/*! + Initialises the driver IC (clock setup, etc.) +*/ +/**************************************************************************/ +void Adafruit_RA8875::initialize(void) { + PLLinit(); + writeReg(RA8875_SYSR, RA8875_SYSR_16BPP | RA8875_SYSR_MCU8); + + /* Timing values */ + uint8_t pixclk; + uint8_t hsync_start; + uint8_t hsync_pw; + uint8_t hsync_finetune; + uint8_t hsync_nondisp; + uint8_t vsync_pw; + uint16_t vsync_nondisp; + uint16_t vsync_start; + + /* Set the correct values for the display being used */ + if (_size == RA8875_480x272) + { + pixclk = RA8875_PCSR_PDATL | RA8875_PCSR_4CLK; + hsync_nondisp = 10; + hsync_start = 8; + hsync_pw = 48; + hsync_finetune = 0; + vsync_nondisp = 3; + vsync_start = 8; + vsync_pw = 10; + } + else // (_size == RA8875_800x480) + { + pixclk = RA8875_PCSR_PDATL | RA8875_PCSR_2CLK; + hsync_nondisp = 26; + hsync_start = 32; + hsync_pw = 96; + hsync_finetune = 0; + vsync_nondisp = 32; + vsync_start = 23; + vsync_pw = 2; + } + + writeReg(RA8875_PCSR, pixclk); + wait_ms(1); + + /* Horizontal settings registers */ + writeReg(RA8875_HDWR, (_width / 8) - 1); // H width: (HDWR + 1) * 8 = 480 + writeReg(RA8875_HNDFTR, RA8875_HNDFTR_DE_HIGH + hsync_finetune); + writeReg(RA8875_HNDR, (hsync_nondisp - hsync_finetune - 2)/8); // H non-display: HNDR * 8 + HNDFTR + 2 = 10 + writeReg(RA8875_HSTR, hsync_start/8 - 1); // Hsync start: (HSTR + 1)*8 + writeReg(RA8875_HPWR, RA8875_HPWR_LOW + (hsync_pw/8 - 1)); // HSync pulse width = (HPWR+1) * 8 + + /* Vertical settings registers */ + writeReg(RA8875_VDHR0, (uint16_t)(_height - 1) & 0xFF); + writeReg(RA8875_VDHR1, (uint16_t)(_height - 1) >> 8); + writeReg(RA8875_VNDR0, vsync_nondisp-1); // V non-display period = VNDR + 1 + writeReg(RA8875_VNDR1, vsync_nondisp >> 8); + writeReg(RA8875_VSTR0, vsync_start-1); // Vsync start position = VSTR + 1 + writeReg(RA8875_VSTR1, vsync_start >> 8); + writeReg(RA8875_VPWR, RA8875_VPWR_LOW + vsync_pw - 1); // Vsync pulse width = VPWR + 1 + + /* Set active window X */ + writeReg(RA8875_HSAW0, 0); // horizontal start point + writeReg(RA8875_HSAW1, 0); + writeReg(RA8875_HEAW0, (uint16_t)(_width - 1) & 0xFF); // horizontal end point + writeReg(RA8875_HEAW1, (uint16_t)(_width - 1) >> 8); + + /* Set active window Y */ + writeReg(RA8875_VSAW0, 0); // vertical start point + writeReg(RA8875_VSAW1, 0); + writeReg(RA8875_VEAW0, (uint16_t)(_height - 1) & 0xFF); // horizontal end point + writeReg(RA8875_VEAW1, (uint16_t)(_height - 1) >> 8); + + /* ToDo: Setup touch panel? */ + + /* Clear the entire window */ + writeReg(RA8875_MCLR, RA8875_MCLR_START | RA8875_MCLR_FULL); + wait_ms(500); +} + +/**************************************************************************/ +/*! + Returns the display width in pixels + + @returns The 1-based display width in pixels +*/ +/**************************************************************************/ +uint16_t Adafruit_RA8875::width(void) { return _width; } + +/**************************************************************************/ +/*! + Returns the display height in pixels + + @returns The 1-based display height in pixels +*/ +/**************************************************************************/ +uint16_t Adafruit_RA8875::height(void) { return _height; } + +/************************* Text Mode ***********************************/ + +/**************************************************************************/ +/*! + Sets the display in text mode (as opposed to graphics mode) +*/ +/**************************************************************************/ +void Adafruit_RA8875::textMode(void) +{ + /* Set text mode */ + writeCommand(RA8875_MWCR0); + uint8_t temp = readData(); + temp |= RA8875_MWCR0_TXTMODE; // Set bit 7 + writeData(temp); + + /* Select the internal (ROM) font */ + writeCommand(0x21); + temp = readData(); + temp &= ~((1<<7) | (1<<5)); // Clear bits 7 and 5 + writeData(temp); +} + +/**************************************************************************/ +/*! + Sets the display in text mode (as opposed to graphics mode) + + @args x[in] The x position of the cursor (in pixels, 0..1023) + @args y[in] The y position of the cursor (in pixels, 0..511) +*/ +/**************************************************************************/ +void Adafruit_RA8875::textSetCursor(uint16_t x, uint16_t y) +{ + /* Set cursor location */ + writeCommand(0x2A); + writeData(x & 0xFF); + writeCommand(0x2B); + writeData(x >> 8); + writeCommand(0x2C); + writeData(y & 0xFF); + writeCommand(0x2D); + writeData(y >> 8); +} + +/**************************************************************************/ +/*! + Sets the fore and background color when rendering text + + @args foreColor[in] The RGB565 color to use when rendering the text + @args bgColor[in] The RGB565 colot to use for the background +*/ +/**************************************************************************/ +void Adafruit_RA8875::textColor(uint16_t foreColor, uint16_t bgColor) +{ + /* Set Fore Color */ + writeCommand(0x63); + writeData((foreColor & 0xf800) >> 11); + writeCommand(0x64); + writeData((foreColor & 0x07e0) >> 5); + writeCommand(0x65); + writeData((foreColor & 0x001f)); + + /* Set Background Color */ + writeCommand(0x60); + writeData((bgColor & 0xf800) >> 11); + writeCommand(0x61); + writeData((bgColor & 0x07e0) >> 5); + writeCommand(0x62); + writeData((bgColor & 0x001f)); + + /* Clear transparency flag */ + writeCommand(0x22); + uint8_t temp = readData(); + temp &= ~(1<<6); // Clear bit 6 + writeData(temp); +} + +/**************************************************************************/ +/*! + Sets the fore color when rendering text with a transparent bg + + @args foreColor[in] The RGB565 color to use when rendering the text +*/ +/**************************************************************************/ +void Adafruit_RA8875::textTransparent(uint16_t foreColor) +{ + /* Set Fore Color */ + writeCommand(0x63); + writeData((foreColor & 0xf800) >> 11); + writeCommand(0x64); + writeData((foreColor & 0x07e0) >> 5); + writeCommand(0x65); + writeData((foreColor & 0x001f)); + + /* Set transparency flag */ + writeCommand(0x22); + uint8_t temp = readData(); + temp |= (1<<6); // Set bit 6 + writeData(temp); +} + +/**************************************************************************/ +/*! + Sets the text enlarge settings, using one of the following values: + + 0 = 1x zoom + 1 = 2x zoom + 2 = 3x zoom + 3 = 4x zoom + + @args scale[in] The zoom factor (0..3 for 1-4x zoom) +*/ +/**************************************************************************/ +void Adafruit_RA8875::textEnlarge(uint8_t scale) +{ + if (scale > 3) scale = 3; + + /* Set font size flags */ + writeCommand(0x22); + uint8_t temp = readData(); + temp &= ~(0xF); // Clears bits 0..3 + temp |= scale << 2; + temp |= scale; + writeData(temp); + + _textScale = scale; +} + +/**************************************************************************/ +/*! + Renders some text on the screen when in text mode + + @args buffer[in] The buffer containing the characters to render + @args len[in] The size of the buffer in bytes +*/ +/**************************************************************************/ +void Adafruit_RA8875::textWrite(const char* buffer, uint16_t len) +{ + if (len == 0) len = strlen(buffer); + writeCommand(RA8875_MRWC); + for (uint16_t i=0;i<len;i++) + { + writeData(buffer[i]); +#if defined(__AVR__) + if (_textScale > 1) wait_ms(1); +#elif defined(__arm__) + // This wait_ms is needed with textEnlarge(1) because + // Teensy 3.X is much faster than Arduino Uno + if (_textScale > 0) wait_ms(1); +#endif + } +} + +/************************* Graphics ***********************************/ + +/**************************************************************************/ +/*! + Sets the display in graphics mode (as opposed to text mode) +*/ +/**************************************************************************/ +void Adafruit_RA8875::graphicsMode(void) { + writeCommand(RA8875_MWCR0); + uint8_t temp = readData(); + temp &= ~RA8875_MWCR0_TXTMODE; // bit #7 + writeData(temp); +} + +/**************************************************************************/ +/*! + Waits for screen to finish by polling the status! +*/ +/**************************************************************************/ +bool Adafruit_RA8875::waitPoll(uint8_t regname, uint8_t waitflag) { + /* Wait for the command to finish */ + while (1) + { + uint8_t temp = readReg(regname); + if (!(temp & waitflag)) + return true; + } + //return false; // MEMEFIX: yeah i know, unreached! - add timeout? +} + + +/**************************************************************************/ +/*! + Sets the current X/Y position on the display before drawing + + @args x[in] The 0-based x location + @args y[in] The 0-base y location +*/ +/**************************************************************************/ +void Adafruit_RA8875::setXY(uint16_t x, uint16_t y) { + writeReg(RA8875_CURH0, x); + writeReg(RA8875_CURH1, x >> 8); + writeReg(RA8875_CURV0, y); + writeReg(RA8875_CURV1, y >> 8); +} + +/**************************************************************************/ +/*! + HW accelerated function to push a chunk of raw pixel data + + @args num[in] The number of pixels to push + @args p[in] The pixel color to use +*/ +/**************************************************************************/ +void Adafruit_RA8875::pushPixels(uint32_t num, uint16_t p) { + _cs = 0; + + spi.write(RA8875_DATAWRITE); + while (num--) { + spi.write(p >> 8); + spi.write(p); + } + _cs = 1; +} + +/**************************************************************************/ +/*! + +*/ +/**************************************************************************/ +void Adafruit_RA8875::fillRect(void) { + writeCommand(RA8875_DCR); + writeData(RA8875_DCR_LINESQUTRI_STOP | RA8875_DCR_DRAWSQUARE); + writeData(RA8875_DCR_LINESQUTRI_START | RA8875_DCR_FILL | RA8875_DCR_DRAWSQUARE); +} + +/**************************************************************************/ +/*! + Draws a single pixel at the specified location + + @args x[in] The 0-based x location + @args y[in] The 0-base y location + @args color[in] The RGB565 color to use when drawing the pixel +*/ +/**************************************************************************/ +void Adafruit_RA8875::drawPixel(int16_t x, int16_t y, uint16_t color) +{ + writeReg(RA8875_CURH0, x); + writeReg(RA8875_CURH1, x >> 8); + writeReg(RA8875_CURV0, y); + writeReg(RA8875_CURV1, y >> 8); + writeCommand(RA8875_MRWC); + _cs = 0; + spi.write(RA8875_DATAWRITE); + spi.write(color >> 8); + spi.write(color); + _cs = 1; +} + +/**************************************************************************/ +/*! + Draws a HW accelerated line on the display + + @args x0[in] The 0-based starting x location + @args y0[in] The 0-base starting y location + @args x1[in] The 0-based ending x location + @args y1[in] The 0-base ending y location + @args color[in] The RGB565 color to use when drawing the pixel +*/ +/**************************************************************************/ +void Adafruit_RA8875::drawLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1, uint16_t color) +{ + /* Set X */ + writeCommand(0x91); + writeData(x0); + writeCommand(0x92); + writeData(x0 >> 8); + + /* Set Y */ + writeCommand(0x93); + writeData(y0); + writeCommand(0x94); + writeData(y0 >> 8); + + /* Set X1 */ + writeCommand(0x95); + writeData(x1); + writeCommand(0x96); + writeData((x1) >> 8); + + /* Set Y1 */ + writeCommand(0x97); + writeData(y1); + writeCommand(0x98); + writeData((y1) >> 8); + + /* Set Color */ + writeCommand(0x63); + writeData((color & 0xf800) >> 11); + writeCommand(0x64); + writeData((color & 0x07e0) >> 5); + writeCommand(0x65); + writeData((color & 0x001f)); + + /* Draw! */ + writeCommand(RA8875_DCR); + writeData(0x80); + + /* Wait for the command to finish */ + waitPoll(RA8875_DCR, RA8875_DCR_LINESQUTRI_STATUS); +} + +/**************************************************************************/ +/*! + +*/ +/**************************************************************************/ +void Adafruit_RA8875::drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color) +{ + drawLine(x, y, x, y+h, color); +} + +/**************************************************************************/ +/*! + +*/ +/**************************************************************************/ +void Adafruit_RA8875::drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color) +{ + drawLine(x, y, x+w, y, color); +} + +/**************************************************************************/ +/*! + Draws a HW accelerated rectangle on the display + + @args x[in] The 0-based x location of the top-right corner + @args y[in] The 0-based y location of the top-right corner + @args w[in] The rectangle width + @args h[in] The rectangle height + @args color[in] The RGB565 color to use when drawing the pixel +*/ +/**************************************************************************/ +/* +void Adafruit_RA8875::drawRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color) +{ + rectHelper(x, y, x+w, y+h, color, false); +} +*/ +/**************************************************************************/ +/*! + Draws a HW accelerated filled rectangle on the display + + @args x[in] The 0-based x location of the top-right corner + @args y[in] The 0-based y location of the top-right corner + @args w[in] The rectangle width + @args h[in] The rectangle height + @args color[in] The RGB565 color to use when drawing the pixel +*/ +/**************************************************************************/ +/* +void Adafruit_RA8875::fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color) +{ + rectHelper(x, y, x+w, y+h, color, true); +} +*/ +/**************************************************************************/ +/*! + Fills the screen with the spefied RGB565 color + + @args color[in] The RGB565 color to use when drawing the pixel +*/ +/**************************************************************************/ + +void Adafruit_RA8875::fillScreen(uint16_t color) +{ + rectHelper(0, 0, _width-1, _height-1, color, true); +} + +/**************************************************************************/ +/*! + Draws a HW accelerated circle on the display + + @args x[in] The 0-based x location of the center of the circle + @args y[in] The 0-based y location of the center of the circle + @args w[in] The circle's radius + @args color[in] The RGB565 color to use when drawing the pixel +*/ +/**************************************************************************/ +/* +void Adafruit_RA8875::drawCircle(int16_t x0, int16_t y0, int16_t r, uint16_t color) +{ + circleHelper(x0, y0, r, color, false); +} +*/ +/**************************************************************************/ +/*! + Draws a HW accelerated filled circle on the display + + @args x[in] The 0-based x location of the center of the circle + @args y[in] The 0-based y location of the center of the circle + @args w[in] The circle's radius + @args color[in] The RGB565 color to use when drawing the pixel +*/ +/**************************************************************************/ +/* +void Adafruit_RA8875::fillCircle(int16_t x0, int16_t y0, int16_t r, uint16_t color) +{ + circleHelper(x0, y0, r, color, true); +} +*/ +/**************************************************************************/ +/*! + Draws a HW accelerated triangle on the display + + @args x0[in] The 0-based x location of point 0 on the triangle + @args y0[in] The 0-based y location of point 0 on the triangle + @args x1[in] The 0-based x location of point 1 on the triangle + @args y1[in] The 0-based y location of point 1 on the triangle + @args x2[in] The 0-based x location of point 2 on the triangle + @args y2[in] The 0-based y location of point 2 on the triangle + @args color[in] The RGB565 color to use when drawing the pixel +*/ +/**************************************************************************/ +/* +void Adafruit_RA8875::drawTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2, int16_t y2, uint16_t color) +{ + triangleHelper(x0, y0, x1, y1, x2, y2, color, false); +} +*/ +/**************************************************************************/ +/*! + Draws a HW accelerated filled triangle on the display + + @args x0[in] The 0-based x location of point 0 on the triangle + @args y0[in] The 0-based y location of point 0 on the triangle + @args x1[in] The 0-based x location of point 1 on the triangle + @args y1[in] The 0-based y location of point 1 on the triangle + @args x2[in] The 0-based x location of point 2 on the triangle + @args y2[in] The 0-based y location of point 2 on the triangle + @args color[in] The RGB565 color to use when drawing the pixel +*/ +/**************************************************************************/ +/* +void Adafruit_RA8875::fillTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2, int16_t y2, uint16_t color) +{ + triangleHelper(x0, y0, x1, y1, x2, y2, color, true); +} +*/ +/**************************************************************************/ +/*! + Draws a HW accelerated ellipse on the display + + @args xCenter[in] The 0-based x location of the ellipse's center + @args yCenter[in] The 0-based y location of the ellipse's center + @args longAxis[in] The size in pixels of the ellipse's long axis + @args shortAxis[in] The size in pixels of the ellipse's short axis + @args color[in] The RGB565 color to use when drawing the pixel +*/ +/**************************************************************************/ +/* +void Adafruit_RA8875::drawEllipse(int16_t xCenter, int16_t yCenter, int16_t longAxis, int16_t shortAxis, uint16_t color) +{ + ellipseHelper(xCenter, yCenter, longAxis, shortAxis, color, false); +} +*/ +/**************************************************************************/ +/*! + Draws a HW accelerated filled ellipse on the display + + @args xCenter[in] The 0-based x location of the ellipse's center + @args yCenter[in] The 0-based y location of the ellipse's center + @args longAxis[in] The size in pixels of the ellipse's long axis + @args shortAxis[in] The size in pixels of the ellipse's short axis + @args color[in] The RGB565 color to use when drawing the pixel +*/ +/**************************************************************************/ +/* +void Adafruit_RA8875::fillEllipse(int16_t xCenter, int16_t yCenter, int16_t longAxis, int16_t shortAxis, uint16_t color) +{ + ellipseHelper(xCenter, yCenter, longAxis, shortAxis, color, true); +} +*/ +/**************************************************************************/ +/*! + Draws a HW accelerated curve on the display + + @args xCenter[in] The 0-based x location of the ellipse's center + @args yCenter[in] The 0-based y location of the ellipse's center + @args longAxis[in] The size in pixels of the ellipse's long axis + @args shortAxis[in] The size in pixels of the ellipse's short axis + @args curvePart[in] The corner to draw, where in clock-wise motion: + 0 = 180-270° + 1 = 270-0° + 2 = 0-90° + 3 = 90-180° + @args color[in] The RGB565 color to use when drawing the pixel +*/ +/**************************************************************************/ +/* +void Adafruit_RA8875::drawCurve(int16_t xCenter, int16_t yCenter, int16_t longAxis, int16_t shortAxis, uint8_t curvePart, uint16_t color) +{ + curveHelper(xCenter, yCenter, longAxis, shortAxis, curvePart, color, false); +} +*/ +/**************************************************************************/ +/*! + Draws a HW accelerated filled curve on the display + + @args xCenter[in] The 0-based x location of the ellipse's center + @args yCenter[in] The 0-based y location of the ellipse's center + @args longAxis[in] The size in pixels of the ellipse's long axis + @args shortAxis[in] The size in pixels of the ellipse's short axis + @args curvePart[in] The corner to draw, where in clock-wise motion: + 0 = 180-270° + 1 = 270-0° + 2 = 0-90° + 3 = 90-180° + @args color[in] The RGB565 color to use when drawing the pixel +*/ +/**************************************************************************/ +/* +void Adafruit_RA8875::fillCurve(int16_t xCenter, int16_t yCenter, int16_t longAxis, int16_t shortAxis, uint8_t curvePart, uint16_t color) +{ + curveHelper(xCenter, yCenter, longAxis, shortAxis, curvePart, color, true); +} +*/ +/**************************************************************************/ +/*! + Helper function for higher level circle drawing code +*/ +/**************************************************************************/ + +void Adafruit_RA8875::circleHelper(int16_t x0, int16_t y0, int16_t r, uint16_t color, bool filled) +{ + /* Set X */ + writeCommand(0x99); + writeData(x0); + writeCommand(0x9a); + writeData(x0 >> 8); + + /* Set Y */ + writeCommand(0x9b); + writeData(y0); + writeCommand(0x9c); + writeData(y0 >> 8); + + /* Set Radius */ + writeCommand(0x9d); + writeData(r); + + /* Set Color */ + writeCommand(0x63); + writeData((color & 0xf800) >> 11); + writeCommand(0x64); + writeData((color & 0x07e0) >> 5); + writeCommand(0x65); + writeData((color & 0x001f)); + + /* Draw! */ + writeCommand(RA8875_DCR); + if (filled) + { + writeData(RA8875_DCR_CIRCLE_START | RA8875_DCR_FILL); + } + else + { + writeData(RA8875_DCR_CIRCLE_START | RA8875_DCR_NOFILL); + } + + /* Wait for the command to finish */ + waitPoll(RA8875_DCR, RA8875_DCR_CIRCLE_STATUS); +} + +/**************************************************************************/ +/*! + Helper function for higher level rectangle drawing code +*/ +/**************************************************************************/ +void Adafruit_RA8875::rectHelper(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color, bool filled) +{ + /* Set X */ + writeCommand(0x91); + writeData(x); + writeCommand(0x92); + writeData(x >> 8); + + /* Set Y */ + writeCommand(0x93); + writeData(y); + writeCommand(0x94); + writeData(y >> 8); + + /* Set X1 */ + writeCommand(0x95); + writeData(w); + writeCommand(0x96); + writeData((w) >> 8); + + /* Set Y1 */ + writeCommand(0x97); + writeData(h); + writeCommand(0x98); + writeData((h) >> 8); + + /* Set Color */ + writeCommand(0x63); + writeData((color & 0xf800) >> 11); + writeCommand(0x64); + writeData((color & 0x07e0) >> 5); + writeCommand(0x65); + writeData((color & 0x001f)); + + /* Draw! */ + writeCommand(RA8875_DCR); + if (filled) + { + writeData(0xB0); + } + else + { + writeData(0x90); + } + + /* Wait for the command to finish */ + waitPoll(RA8875_DCR, RA8875_DCR_LINESQUTRI_STATUS); +} + +/**************************************************************************/ +/*! + Helper function for higher level triangle drawing code +*/ +/**************************************************************************/ +void Adafruit_RA8875::triangleHelper(int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2, int16_t y2, uint16_t color, bool filled) +{ + /* Set Point 0 */ + writeCommand(0x91); + writeData(x0); + writeCommand(0x92); + writeData(x0 >> 8); + writeCommand(0x93); + writeData(y0); + writeCommand(0x94); + writeData(y0 >> 8); + + /* Set Point 1 */ + writeCommand(0x95); + writeData(x1); + writeCommand(0x96); + writeData(x1 >> 8); + writeCommand(0x97); + writeData(y1); + writeCommand(0x98); + writeData(y1 >> 8); + + /* Set Point 2 */ + writeCommand(0xA9); + writeData(x2); + writeCommand(0xAA); + writeData(x2 >> 8); + writeCommand(0xAB); + writeData(y2); + writeCommand(0xAC); + writeData(y2 >> 8); + + /* Set Color */ + writeCommand(0x63); + writeData((color & 0xf800) >> 11); + writeCommand(0x64); + writeData((color & 0x07e0) >> 5); + writeCommand(0x65); + writeData((color & 0x001f)); + + /* Draw! */ + writeCommand(RA8875_DCR); + if (filled) + { + writeData(0xA1); + } + else + { + writeData(0x81); + } + + /* Wait for the command to finish */ + waitPoll(RA8875_DCR, RA8875_DCR_LINESQUTRI_STATUS); +} + +/**************************************************************************/ +/*! + Helper function for higher level ellipse drawing code +*/ +/**************************************************************************/ +void Adafruit_RA8875::ellipseHelper(int16_t xCenter, int16_t yCenter, int16_t longAxis, int16_t shortAxis, uint16_t color, bool filled) +{ + /* Set Center Point */ + writeCommand(0xA5); + writeData(xCenter); + writeCommand(0xA6); + writeData(xCenter >> 8); + writeCommand(0xA7); + writeData(yCenter); + writeCommand(0xA8); + writeData(yCenter >> 8); + + /* Set Long and Short Axis */ + writeCommand(0xA1); + writeData(longAxis); + writeCommand(0xA2); + writeData(longAxis >> 8); + writeCommand(0xA3); + writeData(shortAxis); + writeCommand(0xA4); + writeData(shortAxis >> 8); + + /* Set Color */ + writeCommand(0x63); + writeData((color & 0xf800) >> 11); + writeCommand(0x64); + writeData((color & 0x07e0) >> 5); + writeCommand(0x65); + writeData((color & 0x001f)); + + /* Draw! */ + writeCommand(0xA0); + if (filled) + { + writeData(0xC0); + } + else + { + writeData(0x80); + } + + /* Wait for the command to finish */ + waitPoll(RA8875_ELLIPSE, RA8875_ELLIPSE_STATUS); +} + +/**************************************************************************/ +/*! + Helper function for higher level curve drawing code +*/ +/**************************************************************************/ +void Adafruit_RA8875::curveHelper(int16_t xCenter, int16_t yCenter, int16_t longAxis, int16_t shortAxis, uint8_t curvePart, uint16_t color, bool filled) +{ + /* Set Center Point */ + writeCommand(0xA5); + writeData(xCenter); + writeCommand(0xA6); + writeData(xCenter >> 8); + writeCommand(0xA7); + writeData(yCenter); + writeCommand(0xA8); + writeData(yCenter >> 8); + + /* Set Long and Short Axis */ + writeCommand(0xA1); + writeData(longAxis); + writeCommand(0xA2); + writeData(longAxis >> 8); + writeCommand(0xA3); + writeData(shortAxis); + writeCommand(0xA4); + writeData(shortAxis >> 8); + + /* Set Color */ + writeCommand(0x63); + writeData((color & 0xf800) >> 11); + writeCommand(0x64); + writeData((color & 0x07e0) >> 5); + writeCommand(0x65); + writeData((color & 0x001f)); + + /* Draw! */ + writeCommand(0xA0); + if (filled) + { + writeData(0xD0 | (curvePart & 0x03)); + } + else + { + writeData(0x90 | (curvePart & 0x03)); + } + + /* Wait for the command to finish */ + waitPoll(RA8875_ELLIPSE, RA8875_ELLIPSE_STATUS); +} + +/************************* Mid Level ***********************************/ + +/**************************************************************************/ +/*! + +*/ +/**************************************************************************/ +void Adafruit_RA8875::GPIOX(bool on) { + if (on) + writeReg(RA8875_GPIOX, 1); + else + writeReg(RA8875_GPIOX, 0); +} + +/**************************************************************************/ +/*! + +*/ +/**************************************************************************/ +void Adafruit_RA8875::PWM1out(uint8_t p) { + writeReg(RA8875_P1DCR, p); +} + +/**************************************************************************/ +/*! + +*/ +/**************************************************************************/ +void Adafruit_RA8875::PWM2out(uint8_t p) { + writeReg(RA8875_P2DCR, p); +} + +/**************************************************************************/ +/*! + +*/ +/**************************************************************************/ +void Adafruit_RA8875::PWM1config(bool on, uint8_t clock) { + if (on) { + writeReg(RA8875_P1CR, RA8875_P1CR_ENABLE | (clock & 0xF)); + } else { + writeReg(RA8875_P1CR, RA8875_P1CR_DISABLE | (clock & 0xF)); + } +} + +/**************************************************************************/ +/*! + +*/ +/**************************************************************************/ +void Adafruit_RA8875::PWM2config(bool on, uint8_t clock) { + if (on) { + writeReg(RA8875_P2CR, RA8875_P2CR_ENABLE | (clock & 0xF)); + } else { + writeReg(RA8875_P2CR, RA8875_P2CR_DISABLE | (clock & 0xF)); + } +} + +/**************************************************************************/ +/*! + Enables or disables the on-chip touch screen controller +*/ +/**************************************************************************/ +void Adafruit_RA8875::touchEnable(bool on) +{ + uint8_t adcClk = (uint8_t) RA8875_TPCR0_ADCCLK_DIV4; + + if ( _size == RA8875_800x480 ) //match up touch size with LCD size + adcClk = (uint8_t) RA8875_TPCR0_ADCCLK_DIV16; + + if (on) + { + /* Enable Touch Panel (Reg 0x70) */ + writeReg(RA8875_TPCR0, RA8875_TPCR0_ENABLE | + RA8875_TPCR0_WAIT_4096CLK | + RA8875_TPCR0_WAKEENABLE | + adcClk); // 10mhz max! + /* Set Auto Mode (Reg 0x71) */ + writeReg(RA8875_TPCR1, RA8875_TPCR1_AUTO | + // RA8875_TPCR1_VREFEXT | + RA8875_TPCR1_DEBOUNCE); + /* Enable TP INT */ + writeReg(RA8875_INTC1, readReg(RA8875_INTC1) | RA8875_INTC1_TP); + } + else + { + /* Disable TP INT */ + writeReg(RA8875_INTC1, readReg(RA8875_INTC1) & ~RA8875_INTC1_TP); + /* Disable Touch Panel (Reg 0x70) */ + writeReg(RA8875_TPCR0, RA8875_TPCR0_DISABLE); + } +} + +/**************************************************************************/ +/*! + Checks if a touch event has occured + + @returns True is a touch event has occured (reading it via + touchRead() will clear the interrupt in memory) +*/ +/**************************************************************************/ +bool Adafruit_RA8875::touched(void) +{ + if (readReg(RA8875_INTC2) & RA8875_INTC2_TP) return true; + return false; +} + +/**************************************************************************/ +/*! + Reads the last touch event + + @args x[out] Pointer to the uint16_t field to assign the raw X value + @args y[out] Pointer to the uint16_t field to assign the raw Y value + + @note Calling this function will clear the touch panel interrupt on + the RA8875, resetting the flag used by the 'touched' function +*/ +/**************************************************************************/ +bool Adafruit_RA8875::touchRead(uint16_t *x, uint16_t *y) +{ + uint16_t tx, ty; + uint8_t temp; + + tx = readReg(RA8875_TPXH); + ty = readReg(RA8875_TPYH); + temp = readReg(RA8875_TPXYL); + tx <<= 2; + ty <<= 2; + tx |= temp & 0x03; // get the bottom x bits + ty |= (temp >> 2) & 0x03; // get the bottom y bits + + *x = tx; + *y = ty; + + /* Clear TP INT Status */ + writeReg(RA8875_INTC2, RA8875_INTC2_TP); + + return true; +} + +/**************************************************************************/ +/*! + Turns the display on or off +*/ +/**************************************************************************/ +void Adafruit_RA8875::displayOn(bool on) +{ + if (on) + writeReg(RA8875_PWRR, RA8875_PWRR_NORMAL | RA8875_PWRR_DISPON); + else + writeReg(RA8875_PWRR, RA8875_PWRR_NORMAL | RA8875_PWRR_DISPOFF); +} + +/**************************************************************************/ +/*! + Puts the display in sleep mode, or disables sleep mode if enabled +*/ +/**************************************************************************/ +void Adafruit_RA8875::sleep(bool sleep) +{ + if (sleep) + writeReg(RA8875_PWRR, RA8875_PWRR_DISPOFF | RA8875_PWRR_SLEEP); + else + writeReg(RA8875_PWRR, RA8875_PWRR_DISPOFF); +} + +/************************* Low Level ***********************************/ + +/**************************************************************************/ +/*! + +*/ +/**************************************************************************/ +void Adafruit_RA8875::writeReg(uint8_t reg, uint8_t val) +{ + writeCommand(reg); + writeData(val); +} + +/**************************************************************************/ +/*! + +*/ +/**************************************************************************/ +uint8_t Adafruit_RA8875::readReg(uint8_t reg) +{ + writeCommand(reg); + return readData(); +} + +/**************************************************************************/ +/*! + +*/ +/**************************************************************************/ +void Adafruit_RA8875::writeData(uint8_t d) +{ + _cs = 0; + + spi.write(RA8875_DATAWRITE); + spi.write(d); + _cs = 1; + +} + +/**************************************************************************/ +/*! + +*/ +/**************************************************************************/ +uint8_t Adafruit_RA8875::readData(void) +{ + _cs = 0; + + spi.write(RA8875_DATAREAD); + uint8_t x = spi.write(0x0); + + _cs = 1; + return x; +} + +/**************************************************************************/ +/*! + +*/ +/**************************************************************************/ +void Adafruit_RA8875::writeCommand(uint8_t d) +{ + _cs = 0; + + spi.write(RA8875_CMDWRITE); + spi.write(d); + + _cs = 1; +} + +/**************************************************************************/ +/*! + +*/ +/**************************************************************************/ +uint8_t Adafruit_RA8875::readStatus(void) +{ + _cs = 0; + + spi.write(RA8875_CMDREAD); + uint8_t x = spi.write(0x0); + + _cs = 1; + return x; +}