Compare commits
6 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9c63ee9bd9 | ||
|
|
1d0c5a4a73 | ||
|
|
7097afb14a | ||
|
|
521daecd91 | ||
|
|
47c83e929a | ||
|
|
cd4ff4fd25 |
4 changed files with 604 additions and 868 deletions
|
|
@ -14,308 +14,60 @@
|
|||
BSD license, all text above must be included in any redistribution
|
||||
****************************************************/
|
||||
|
||||
#include "Adafruit_GFX.h"
|
||||
#include "Adafruit_SSD1331.h"
|
||||
#include "glcdfont.c"
|
||||
|
||||
#ifdef __AVR
|
||||
#include <avr/pgmspace.h>
|
||||
#elif defined(ESP8266)
|
||||
#include <pgmspace.h>
|
||||
#endif
|
||||
|
||||
#include "pins_arduino.h"
|
||||
#include "wiring_private.h"
|
||||
#include <SPI.h>
|
||||
|
||||
/********************************** low level pin interface */
|
||||
|
||||
inline void Adafruit_SSD1331::spiwrite(uint8_t c) {
|
||||
|
||||
if (!_sid) {
|
||||
SPI.transfer(c);
|
||||
return;
|
||||
}
|
||||
|
||||
int8_t i;
|
||||
|
||||
*sclkportreg |= sclkpin;
|
||||
|
||||
for (i=7; i>=0; i--) {
|
||||
*sclkportreg &= ~sclkpin;
|
||||
//SCLK_PORT &= ~_BV(SCLK);
|
||||
|
||||
if (c & _BV(i)) {
|
||||
*sidportreg |= sidpin;
|
||||
//digitalWrite(_sid, HIGH);
|
||||
//SID_PORT |= _BV(SID);
|
||||
} else {
|
||||
*sidportreg &= ~sidpin;
|
||||
//digitalWrite(_sid, LOW);
|
||||
//SID_PORT &= ~_BV(SID);
|
||||
}
|
||||
|
||||
*sclkportreg |= sclkpin;
|
||||
//SCLK_PORT |= _BV(SCLK);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Adafruit_SSD1331::writeCommand(uint8_t c) {
|
||||
*rsportreg &= ~ rspin;
|
||||
//digitalWrite(_rs, LOW);
|
||||
|
||||
*csportreg &= ~ cspin;
|
||||
//digitalWrite(_cs, LOW);
|
||||
|
||||
//Serial.print("C ");
|
||||
spiwrite(c);
|
||||
|
||||
*csportreg |= cspin;
|
||||
//digitalWrite(_cs, HIGH);
|
||||
}
|
||||
|
||||
|
||||
void Adafruit_SSD1331::writeData(uint8_t c) {
|
||||
*rsportreg |= rspin;
|
||||
//digitalWrite(_rs, HIGH);
|
||||
|
||||
*csportreg &= ~ cspin;
|
||||
//digitalWrite(_cs, LOW);
|
||||
|
||||
//Serial.print("D ");
|
||||
spiwrite(c);
|
||||
|
||||
*csportreg |= cspin;
|
||||
//digitalWrite(_cs, HIGH);
|
||||
}
|
||||
|
||||
/***********************************/
|
||||
|
||||
void Adafruit_SSD1331::goHome(void) {
|
||||
goTo(0,0);
|
||||
}
|
||||
|
||||
void Adafruit_SSD1331::goTo(int x, int y) {
|
||||
if ((x >= WIDTH) || (y >= HEIGHT)) return;
|
||||
void Adafruit_SSD1331::setAddrWindow(uint16_t x, uint16_t y, uint16_t w, uint16_t h) {
|
||||
|
||||
// set x and y coordinate
|
||||
writeCommand(SSD1331_CMD_SETCOLUMN);
|
||||
writeCommand(x);
|
||||
writeCommand(WIDTH-1);
|
||||
uint8_t x1 = x;
|
||||
uint8_t y1 = y;
|
||||
if (x1 > 95) x1 = 95;
|
||||
if (y1 > 63) y1 = 63;
|
||||
|
||||
writeCommand(SSD1331_CMD_SETROW);
|
||||
writeCommand(y);
|
||||
writeCommand(HEIGHT-1);
|
||||
}
|
||||
uint8_t x2 = (x+w-1);
|
||||
uint8_t y2 = (y+h-1);
|
||||
if (x2 > 95) x2 = 95;
|
||||
if (y2 > 63) y2 = 63;
|
||||
|
||||
uint16_t Adafruit_SSD1331::Color565(uint8_t r, uint8_t g, uint8_t b) {
|
||||
uint16_t c;
|
||||
c = r >> 3;
|
||||
c <<= 6;
|
||||
c |= g >> 2;
|
||||
c <<= 5;
|
||||
c |= b >> 3;
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Draws a filled rectangle using HW acceleration
|
||||
*/
|
||||
/**************************************************************************/
|
||||
/*
|
||||
void Adafruit_SSD1331::fillRect(uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint16_t fillcolor)
|
||||
{
|
||||
//Serial.println("fillRect");
|
||||
// check rotation, move rect around if necessary
|
||||
switch (getRotation()) {
|
||||
case 1:
|
||||
swap(x, y);
|
||||
swap(w, h);
|
||||
x = WIDTH - x - 1;
|
||||
break;
|
||||
case 2:
|
||||
x = WIDTH - x - 1;
|
||||
y = HEIGHT - y - 1;
|
||||
break;
|
||||
case 3:
|
||||
swap(x, y);
|
||||
swap(w, h);
|
||||
y = HEIGHT - y - 1;
|
||||
break;
|
||||
if (x1 > x2) {
|
||||
uint8_t t = x2;
|
||||
x2 = x1;
|
||||
x1 = t;
|
||||
}
|
||||
if (y1 > y2) {
|
||||
uint8_t t = y2;
|
||||
y2 = y1;
|
||||
y1 = t;
|
||||
}
|
||||
|
||||
// Bounds check
|
||||
if ((x >= TFTWIDTH) || (y >= TFTHEIGHT))
|
||||
return;
|
||||
|
||||
// Y bounds check
|
||||
if (y+h > TFTHEIGHT)
|
||||
{
|
||||
h = TFTHEIGHT - y;
|
||||
}
|
||||
|
||||
// X bounds check
|
||||
if (x+w > TFTWIDTH)
|
||||
{
|
||||
w = TFTWIDTH - x;
|
||||
}
|
||||
|
||||
// fill!
|
||||
writeCommand(SSD1331_CMD_FILL);
|
||||
writeCommand(0x01);
|
||||
|
||||
writeCommand(SSD1331_CMD_DRAWRECT);
|
||||
writeCommand(x & 0xFF); // Starting column
|
||||
writeCommand(y & 0xFF); // Starting row
|
||||
writeCommand((x+w-1) & 0xFF); // End column
|
||||
writeCommand((y+h-1) & 0xFF); // End row
|
||||
|
||||
// Outline color
|
||||
writeCommand((uint8_t)((fillcolor >> 11) << 1));
|
||||
writeCommand((uint8_t)((fillcolor >> 5) & 0x3F));
|
||||
writeCommand((uint8_t)((fillcolor << 1) & 0x3F));
|
||||
// Fill color
|
||||
writeCommand((uint8_t)((fillcolor >> 11) << 1));
|
||||
writeCommand((uint8_t)((fillcolor >> 5) & 0x3F));
|
||||
writeCommand((uint8_t)((fillcolor << 1) & 0x3F));
|
||||
|
||||
// Delay while the fill completes
|
||||
delay(SSD1331_DELAYS_HWFILL);
|
||||
}
|
||||
*/
|
||||
|
||||
void Adafruit_SSD1331::drawLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1, uint16_t color) {
|
||||
// check rotation, move pixel around if necessary
|
||||
switch (getRotation()) {
|
||||
case 1:
|
||||
gfx_swap(x0, y0);
|
||||
gfx_swap(x1, y1);
|
||||
x0 = WIDTH - x0 - 1;
|
||||
x1 = WIDTH - x1 - 1;
|
||||
break;
|
||||
case 2:
|
||||
x0 = WIDTH - x0 - 1;
|
||||
y0 = HEIGHT - y0 - 1;
|
||||
x1 = WIDTH - x1 - 1;
|
||||
y1 = HEIGHT - y1 - 1;
|
||||
break;
|
||||
case 3:
|
||||
gfx_swap(x0, y0);
|
||||
gfx_swap(x1, y1);
|
||||
y0 = HEIGHT - y0 - 1;
|
||||
y1 = HEIGHT - y1 - 1;
|
||||
break;
|
||||
}
|
||||
|
||||
// Boundary check
|
||||
if ((y0 >= TFTHEIGHT) && (y1 >= TFTHEIGHT))
|
||||
return;
|
||||
if ((x0 >= TFTWIDTH) && (x1 >= TFTWIDTH))
|
||||
return;
|
||||
if (x0 >= TFTWIDTH)
|
||||
x0 = TFTWIDTH - 1;
|
||||
if (y0 >= TFTHEIGHT)
|
||||
y0 = TFTHEIGHT - 1;
|
||||
if (x1 >= TFTWIDTH)
|
||||
x1 = TFTWIDTH - 1;
|
||||
if (y1 >= TFTHEIGHT)
|
||||
y1 = TFTHEIGHT - 1;
|
||||
|
||||
writeCommand(SSD1331_CMD_DRAWLINE);
|
||||
writeCommand(x0);
|
||||
writeCommand(y0);
|
||||
startWrite();
|
||||
writeCommand(0x15); // Column addr set
|
||||
writeCommand(x1);
|
||||
writeCommand(x2);
|
||||
endWrite();
|
||||
|
||||
startWrite();
|
||||
writeCommand(0x75); // Column addr set
|
||||
writeCommand(y1);
|
||||
delay(SSD1331_DELAYS_HWLINE);
|
||||
writeCommand((uint8_t)((color >> 11) << 1));
|
||||
writeCommand((uint8_t)((color >> 5) & 0x3F));
|
||||
writeCommand((uint8_t)((color << 1) & 0x3F));
|
||||
delay(SSD1331_DELAYS_HWLINE);
|
||||
}
|
||||
writeCommand(y2);
|
||||
endWrite();
|
||||
|
||||
void Adafruit_SSD1331::drawPixel(int16_t x, int16_t y, uint16_t color)
|
||||
{
|
||||
if ((x < 0) || (x >= width()) || (y < 0) || (y >= height())) return;
|
||||
startWrite();
|
||||
|
||||
// check rotation, move pixel around if necessary
|
||||
switch (getRotation()) {
|
||||
case 1:
|
||||
gfx_swap(x, y);
|
||||
x = WIDTH - x - 1;
|
||||
break;
|
||||
case 2:
|
||||
x = WIDTH - x - 1;
|
||||
y = HEIGHT - y - 1;
|
||||
break;
|
||||
case 3:
|
||||
gfx_swap(x, y);
|
||||
y = HEIGHT - y - 1;
|
||||
break;
|
||||
}
|
||||
|
||||
goTo(x, y);
|
||||
|
||||
// setup for data
|
||||
*rsportreg |= rspin;
|
||||
*csportreg &= ~ cspin;
|
||||
|
||||
spiwrite(color >> 8);
|
||||
spiwrite(color);
|
||||
|
||||
*csportreg |= cspin;
|
||||
}
|
||||
|
||||
void Adafruit_SSD1331::pushColor(uint16_t color) {
|
||||
// setup for data
|
||||
*rsportreg |= rspin;
|
||||
*csportreg &= ~ cspin;
|
||||
|
||||
spiwrite(color >> 8);
|
||||
spiwrite(color);
|
||||
|
||||
*csportreg |= cspin;
|
||||
}
|
||||
|
||||
|
||||
void Adafruit_SSD1331::begin(void) {
|
||||
// set pin directions
|
||||
pinMode(_rs, OUTPUT);
|
||||
|
||||
if (_sclk) {
|
||||
pinMode(_sclk, OUTPUT);
|
||||
sclkportreg = portOutputRegister(digitalPinToPort(_sclk));
|
||||
sclkpin = digitalPinToBitMask(_sclk);
|
||||
void Adafruit_SSD1331::begin(uint32_t freq) {
|
||||
initSPI(freq);
|
||||
|
||||
pinMode(_sid, OUTPUT);
|
||||
sidportreg = portOutputRegister(digitalPinToPort(_sid));
|
||||
sidpin = digitalPinToBitMask(_sid);
|
||||
} else {
|
||||
// using the hardware SPI
|
||||
SPI.begin();
|
||||
SPI.setDataMode(SPI_MODE3);
|
||||
}
|
||||
startWrite();
|
||||
|
||||
// Toggle RST low to reset; CS low so it'll listen to us
|
||||
pinMode(_cs, OUTPUT);
|
||||
digitalWrite(_cs, LOW);
|
||||
cspin = digitalPinToBitMask(_cs);
|
||||
csportreg = portOutputRegister(digitalPinToPort(_cs));
|
||||
|
||||
rspin = digitalPinToBitMask(_rs);
|
||||
rsportreg = portOutputRegister(digitalPinToPort(_rs));
|
||||
|
||||
if (_rst) {
|
||||
pinMode(_rst, OUTPUT);
|
||||
digitalWrite(_rst, HIGH);
|
||||
delay(500);
|
||||
digitalWrite(_rst, LOW);
|
||||
delay(500);
|
||||
digitalWrite(_rst, HIGH);
|
||||
delay(500);
|
||||
}
|
||||
// Initialization Sequence
|
||||
writeCommand(SSD1331_CMD_DISPLAYOFF); // 0xAE
|
||||
writeCommand(SSD1331_CMD_SETREMAP); // 0xA0
|
||||
|
|
@ -358,22 +110,17 @@ void Adafruit_SSD1331::begin(void) {
|
|||
writeCommand(SSD1331_CMD_CONTRASTC); // 0x83
|
||||
writeCommand(0x7D);
|
||||
writeCommand(SSD1331_CMD_DISPLAYON); //--turn on oled panel
|
||||
|
||||
endWrite();
|
||||
_width = TFTWIDTH;
|
||||
_height = TFTHEIGHT;
|
||||
}
|
||||
|
||||
/********************************* low level pin initialization */
|
||||
|
||||
Adafruit_SSD1331::Adafruit_SSD1331(uint8_t cs, uint8_t rs, uint8_t sid, uint8_t sclk, uint8_t rst) : Adafruit_GFX(TFTWIDTH, TFTHEIGHT) {
|
||||
_cs = cs;
|
||||
_rs = rs;
|
||||
_sid = sid;
|
||||
_sclk = sclk;
|
||||
_rst = rst;
|
||||
Adafruit_SSD1331::Adafruit_SSD1331(uint8_t cs, uint8_t dc, uint8_t mosi, uint8_t sclk, uint8_t rst) : Adafruit_SPITFT(TFTWIDTH, TFTHEIGHT, cs, dc, mosi, sclk, rst, -1) {
|
||||
}
|
||||
|
||||
Adafruit_SSD1331::Adafruit_SSD1331(uint8_t cs, uint8_t rs, uint8_t rst) : Adafruit_GFX(TFTWIDTH, TFTHEIGHT) {
|
||||
_cs = cs;
|
||||
_rs = rs;
|
||||
_sid = 0;
|
||||
_sclk = 0;
|
||||
_rst = rst;
|
||||
Adafruit_SSD1331::Adafruit_SSD1331(uint8_t cs, uint8_t dc, uint8_t rst) : Adafruit_SPITFT(TFTWIDTH, TFTHEIGHT, cs, dc, rst) {
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,22 +14,12 @@
|
|||
BSD license, all text above must be included in any redistribution
|
||||
****************************************************/
|
||||
|
||||
#if defined(ARDUINO) && ARDUINO >= 100
|
||||
#include "Arduino.h"
|
||||
#else
|
||||
#include "WProgram.h"
|
||||
#endif
|
||||
#include <SPI.h>
|
||||
#include <Adafruit_GFX.h>
|
||||
#include <Adafruit_SPITFT.h>
|
||||
#include <Adafruit_SPITFT_Macros.h>
|
||||
|
||||
#define gfx_swap(a, b) { uint16_t t = a; a = b; b = t; }
|
||||
|
||||
#ifdef __SAM3X8E__
|
||||
typedef volatile RwReg PortReg;
|
||||
typedef uint32_t PortMask;
|
||||
#define _BV(b) (1<<(b))
|
||||
#else
|
||||
typedef volatile uint8_t PortReg;
|
||||
typedef uint8_t PortMask;
|
||||
#endif
|
||||
|
||||
// Select one of these defines to set the pixel color order
|
||||
#define SSD1331_COLORORDER_RGB
|
||||
|
|
@ -73,43 +63,19 @@ typedef uint8_t PortMask;
|
|||
#define SSD1331_CMD_PRECHARGELEVEL 0xBB
|
||||
#define SSD1331_CMD_VCOMH 0xBE
|
||||
|
||||
class Adafruit_SSD1331 : public virtual Adafruit_GFX {
|
||||
class Adafruit_SSD1331 : public Adafruit_SPITFT {
|
||||
public:
|
||||
Adafruit_SSD1331(uint8_t CS, uint8_t RS, uint8_t SID, uint8_t SCLK, uint8_t RST);
|
||||
Adafruit_SSD1331(uint8_t CS, uint8_t RS, uint8_t RST);
|
||||
|
||||
uint16_t Color565(uint8_t r, uint8_t g, uint8_t b);
|
||||
|
||||
// drawing primitives!
|
||||
void drawPixel(int16_t x, int16_t y, uint16_t color);
|
||||
void drawLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1, uint16_t color);
|
||||
//void fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t fillcolor);
|
||||
void pushColor(uint16_t c);
|
||||
Adafruit_SSD1331(uint8_t _CS, uint8_t _DC, uint8_t _MOSI, uint8_t _SCLK, uint8_t _RST);
|
||||
Adafruit_SSD1331(uint8_t _CS, uint8_t _DC, uint8_t _RST);
|
||||
|
||||
// commands
|
||||
void begin(void);
|
||||
void goHome(void);
|
||||
void goTo(int x, int y);
|
||||
void begin(uint32_t begin=8000000);
|
||||
|
||||
void reset(void);
|
||||
|
||||
/* low level */
|
||||
|
||||
void writeData(uint8_t d);
|
||||
void writeCommand(uint8_t c);
|
||||
void setAddrWindow(uint16_t x, uint16_t y, uint16_t w, uint16_t h);
|
||||
uint8_t readcommand8(uint8_t reg, uint8_t index = 0);
|
||||
|
||||
static const int16_t TFTWIDTH = 96;
|
||||
static const int16_t TFTHEIGHT = 64;
|
||||
|
||||
void writeData_unsafe(uint16_t d);
|
||||
|
||||
void setWriteDir(void);
|
||||
void write8(uint8_t d);
|
||||
|
||||
private:
|
||||
void spiwrite(uint8_t);
|
||||
|
||||
uint8_t _cs, _rs, _rst, _sid, _sclk;
|
||||
PortReg *csportreg, *rsportreg, *sidportreg, *sclkportreg;
|
||||
PortMask cspin, rspin, sidpin, sclkpin;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -77,7 +77,7 @@ void setup(void) {
|
|||
|
||||
if (!SD.begin(SD_CS)) {
|
||||
Serial.println("failed!");
|
||||
return;
|
||||
while(1);
|
||||
}
|
||||
Serial.println("SD OK!");
|
||||
|
||||
|
|
@ -87,6 +87,7 @@ void setup(void) {
|
|||
void loop() {
|
||||
}
|
||||
|
||||
|
||||
// This function opens a Windows Bitmap (BMP) file and
|
||||
// displays it at the given coordinates. It's sped up
|
||||
// by reading many pixels worth of data at a time
|
||||
|
|
@ -97,7 +98,7 @@ void loop() {
|
|||
|
||||
#define BUFFPIXEL 20
|
||||
|
||||
void bmpDraw(char *filename, uint8_t x, uint8_t y) {
|
||||
void bmpDraw(char *filename, int16_t x, int16_t y) {
|
||||
|
||||
File bmpFile;
|
||||
int bmpWidth, bmpHeight; // W+H in pixels
|
||||
|
|
@ -108,40 +109,40 @@ void bmpDraw(char *filename, uint8_t x, uint8_t y) {
|
|||
uint8_t buffidx = sizeof(sdbuffer); // Current position in sdbuffer
|
||||
boolean goodBmp = false; // Set to true on valid header parse
|
||||
boolean flip = true; // BMP is stored bottom-to-top
|
||||
int w, h, row, col;
|
||||
int w, h, row, col, x2, y2, bx1, by1;
|
||||
uint8_t r, g, b;
|
||||
uint32_t pos = 0, startTime = millis();
|
||||
|
||||
if((x >= tft.width()) || (y >= tft.height())) return;
|
||||
|
||||
Serial.println();
|
||||
Serial.print("Loading image '");
|
||||
Serial.print(F("Loading image '"));
|
||||
Serial.print(filename);
|
||||
Serial.println('\'');
|
||||
|
||||
// Open requested file on SD card
|
||||
if ((bmpFile = SD.open(filename)) == NULL) {
|
||||
Serial.print("File not found");
|
||||
Serial.print(F("File not found"));
|
||||
return;
|
||||
}
|
||||
|
||||
// Parse BMP header
|
||||
if(read16(bmpFile) == 0x4D42) { // BMP signature
|
||||
Serial.print("File size: "); Serial.println(read32(bmpFile));
|
||||
Serial.print(F("File size: ")); Serial.println(read32(bmpFile));
|
||||
(void)read32(bmpFile); // Read & ignore creator bytes
|
||||
bmpImageoffset = read32(bmpFile); // Start of image data
|
||||
Serial.print("Image Offset: "); Serial.println(bmpImageoffset, DEC);
|
||||
Serial.print(F("Image Offset: ")); Serial.println(bmpImageoffset, DEC);
|
||||
// Read DIB header
|
||||
Serial.print("Header size: "); Serial.println(read32(bmpFile));
|
||||
Serial.print(F("Header size: ")); Serial.println(read32(bmpFile));
|
||||
bmpWidth = read32(bmpFile);
|
||||
bmpHeight = read32(bmpFile);
|
||||
if(read16(bmpFile) == 1) { // # planes -- must be '1'
|
||||
bmpDepth = read16(bmpFile); // bits per pixel
|
||||
Serial.print("Bit Depth: "); Serial.println(bmpDepth);
|
||||
Serial.print(F("Bit Depth: ")); Serial.println(bmpDepth);
|
||||
if((bmpDepth == 24) && (read32(bmpFile) == 0)) { // 0 = uncompressed
|
||||
|
||||
goodBmp = true; // Supported BMP format -- proceed!
|
||||
Serial.print("Image size: ");
|
||||
Serial.print(F("Image size: "));
|
||||
Serial.print(bmpWidth);
|
||||
Serial.print('x');
|
||||
Serial.println(bmpHeight);
|
||||
|
|
@ -157,48 +158,66 @@ void bmpDraw(char *filename, uint8_t x, uint8_t y) {
|
|||
}
|
||||
|
||||
// Crop area to be loaded
|
||||
w = bmpWidth;
|
||||
h = bmpHeight;
|
||||
if((x+w-1) >= tft.width()) w = tft.width() - x;
|
||||
if((y+h-1) >= tft.height()) h = tft.height() - y;
|
||||
|
||||
for (row=0; row<h; row++) { // For each scanline...
|
||||
tft.goTo(x, y+row);
|
||||
|
||||
// Seek to start of scan line. It might seem labor-
|
||||
// intensive to be doing this on every line, but this
|
||||
// method covers a lot of gritty details like cropping
|
||||
// and scanline padding. Also, the seek only takes
|
||||
// place if the file position actually needs to change
|
||||
// (avoids a lot of cluster math in SD library).
|
||||
if(flip) // Bitmap is stored bottom-to-top order (normal BMP)
|
||||
pos = bmpImageoffset + (bmpHeight - 1 - row) * rowSize;
|
||||
else // Bitmap is stored top-to-bottom
|
||||
pos = bmpImageoffset + row * rowSize;
|
||||
if(bmpFile.position() != pos) { // Need seek?
|
||||
bmpFile.seek(pos);
|
||||
buffidx = sizeof(sdbuffer); // Force buffer reload
|
||||
x2 = x + bmpWidth - 1; // Lower-right corner
|
||||
y2 = y + bmpHeight - 1;
|
||||
if((x2 >= 0) && (y2 >= 0)) { // On screen?
|
||||
w = bmpWidth; // Width/height of section to load/display
|
||||
h = bmpHeight;
|
||||
bx1 = by1 = 0; // UL coordinate in BMP file
|
||||
if(x < 0) { // Clip left
|
||||
bx1 = -x;
|
||||
x = 0;
|
||||
w = x2 + 1;
|
||||
}
|
||||
if(y < 0) { // Clip top
|
||||
by1 = -y;
|
||||
y = 0;
|
||||
h = y2 + 1;
|
||||
}
|
||||
if(x2 >= tft.width()) w = tft.width() - x; // Clip right
|
||||
if(y2 >= tft.height()) h = tft.height() - y; // Clip bottom
|
||||
|
||||
// optimize by setting pins now
|
||||
for (col=0; col<w; col++) { // For each pixel...
|
||||
// Time to read more pixel data?
|
||||
if (buffidx >= sizeof(sdbuffer)) { // Indeed
|
||||
bmpFile.read(sdbuffer, sizeof(sdbuffer));
|
||||
buffidx = 0; // Set index to beginning
|
||||
// Set TFT address window to clipped image bounds
|
||||
tft.startWrite(); // Requires start/end transaction now
|
||||
tft.setAddrWindow(x, y, w, h);
|
||||
|
||||
for (row=0; row<h; row++) { // For each scanline...
|
||||
|
||||
// Seek to start of scan line. It might seem labor-
|
||||
// intensive to be doing this on every line, but this
|
||||
// method covers a lot of gritty details like cropping
|
||||
// and scanline padding. Also, the seek only takes
|
||||
// place if the file position actually needs to change
|
||||
// (avoids a lot of cluster math in SD library).
|
||||
if(flip) // Bitmap is stored bottom-to-top order (normal BMP)
|
||||
pos = bmpImageoffset + (bmpHeight - 1 - (row + by1)) * rowSize;
|
||||
else // Bitmap is stored top-to-bottom
|
||||
pos = bmpImageoffset + (row + by1) * rowSize;
|
||||
pos += bx1 * 3; // Factor in starting column (bx1)
|
||||
if(bmpFile.position() != pos) { // Need seek?
|
||||
tft.endWrite(); // End TFT transaction
|
||||
bmpFile.seek(pos);
|
||||
buffidx = sizeof(sdbuffer); // Force buffer reload
|
||||
tft.startWrite(); // Start new TFT transaction
|
||||
}
|
||||
|
||||
// Convert pixel from BMP to TFT format, push to display
|
||||
b = sdbuffer[buffidx++];
|
||||
g = sdbuffer[buffidx++];
|
||||
r = sdbuffer[buffidx++];
|
||||
|
||||
//tft.drawPixel(x+col, y+row, tft.Color565(r,g,b));
|
||||
// optimized!
|
||||
tft.pushColor(tft.Color565(r,g,b));
|
||||
} // end pixel
|
||||
} // end scanline
|
||||
Serial.print("Loaded in ");
|
||||
for (col=0; col<w; col++) { // For each pixel...
|
||||
// Time to read more pixel data?
|
||||
if (buffidx >= sizeof(sdbuffer)) { // Indeed
|
||||
tft.endWrite(); // End TFT transaction
|
||||
bmpFile.read(sdbuffer, sizeof(sdbuffer));
|
||||
buffidx = 0; // Set index to beginning
|
||||
tft.startWrite(); // Start new TFT transaction
|
||||
}
|
||||
// Convert pixel from BMP to TFT format, push to display
|
||||
b = sdbuffer[buffidx++];
|
||||
g = sdbuffer[buffidx++];
|
||||
r = sdbuffer[buffidx++];
|
||||
tft.writePixel(tft.color565(r,g,b));
|
||||
} // end pixel
|
||||
} // end scanline
|
||||
tft.endWrite(); // End last TFT transaction
|
||||
} // end onscreen
|
||||
Serial.print(F("Loaded in "));
|
||||
Serial.print(millis() - startTime);
|
||||
Serial.println(" ms");
|
||||
} // end goodBmp
|
||||
|
|
@ -206,21 +225,21 @@ void bmpDraw(char *filename, uint8_t x, uint8_t y) {
|
|||
}
|
||||
|
||||
bmpFile.close();
|
||||
if(!goodBmp) Serial.println("BMP format not recognized.");
|
||||
if(!goodBmp) Serial.println(F("BMP format not recognized."));
|
||||
}
|
||||
|
||||
// These read 16- and 32-bit types from the SD card file.
|
||||
// BMP data is stored little-endian, Arduino is little-endian too.
|
||||
// May need to reverse subscript order if porting elsewhere.
|
||||
|
||||
uint16_t read16(File f) {
|
||||
uint16_t read16(File &f) {
|
||||
uint16_t result;
|
||||
((uint8_t *)&result)[0] = f.read(); // LSB
|
||||
((uint8_t *)&result)[1] = f.read(); // MSB
|
||||
return result;
|
||||
}
|
||||
|
||||
uint32_t read32(File f) {
|
||||
uint32_t read32(File &f) {
|
||||
uint32_t result;
|
||||
((uint8_t *)&result)[0] = f.read(); // LSB
|
||||
((uint8_t *)&result)[1] = f.read();
|
||||
|
|
@ -16,6 +16,10 @@
|
|||
BSD license, all text above must be included in any redistribution
|
||||
****************************************************/
|
||||
|
||||
#include <Adafruit_GFX.h>
|
||||
#include <Adafruit_SSD1331.h>
|
||||
#include <SPI.h>
|
||||
|
||||
|
||||
// You can use any (4 or) 5 pins
|
||||
#define sclk 13
|
||||
|
|
@ -35,18 +39,14 @@
|
|||
#define YELLOW 0xFFE0
|
||||
#define WHITE 0xFFFF
|
||||
|
||||
#include <Adafruit_GFX.h>
|
||||
#include <Adafruit_SSD1331.h>
|
||||
#include <SPI.h>
|
||||
|
||||
// Option 1: use any pins but a little slower
|
||||
Adafruit_SSD1331 display = Adafruit_SSD1331(cs, dc, mosi, sclk, rst);
|
||||
//Adafruit_SSD1331 display = Adafruit_SSD1331(cs, dc, mosi, sclk, rst);
|
||||
|
||||
// Option 2: must use the hardware SPI pins
|
||||
// (for UNO thats sclk = 13 and sid = 11) and pin 10 must be
|
||||
// an output. This is much faster - also required if you want
|
||||
// to use the microSD card (see the image drawing example)
|
||||
//Adafruit_SSD1331 display = Adafruit_SSD1331(cs, dc, rst);
|
||||
Adafruit_SSD1331 display = Adafruit_SSD1331(cs, dc, rst);
|
||||
|
||||
float p = 3.1415926;
|
||||
|
||||
|
|
@ -128,6 +128,9 @@ void testlines(uint16_t color) {
|
|||
display.drawLine(display.width()-1, 0, 0, y, color);
|
||||
}
|
||||
|
||||
// To avoid ESP8266 watchdog timer resets when not using the hardware SPI pins
|
||||
delay(0);
|
||||
|
||||
display.fillScreen(BLACK);
|
||||
for (int16_t x=0; x < display.width()-1; x+=6) {
|
||||
display.drawLine(0, display.height()-1, x, 0, color);
|
||||
|
|
@ -223,19 +226,19 @@ void testroundrects() {
|
|||
int i;
|
||||
int t;
|
||||
for(t = 0 ; t <= 4; t+=1) {
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
int w = display.width();
|
||||
int h = display.height();
|
||||
for(i = 0 ; i <= 24; i+=1) {
|
||||
display.drawRoundRect(x, y, w, h, 5, color);
|
||||
x+=2;
|
||||
y+=3;
|
||||
w-=4;
|
||||
h-=6;
|
||||
color+=1100;
|
||||
}
|
||||
color+=100;
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
int w = display.width();
|
||||
int h = display.height();
|
||||
for(i = 0 ; i <= 8; i+=1) {
|
||||
display.drawRoundRect(x, y, w, h, 5, color);
|
||||
x+=2;
|
||||
y+=3;
|
||||
w-=4;
|
||||
h-=6;
|
||||
color+=1100;
|
||||
}
|
||||
color+=100;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -300,21 +303,22 @@ void mediabuttons() {
|
|||
/**************************************************************************/
|
||||
void lcdTestPattern(void)
|
||||
{
|
||||
uint32_t i,j;
|
||||
display.goTo(0, 0);
|
||||
uint8_t w,h;
|
||||
display.setAddrWindow(0, 0, 96, 64);
|
||||
|
||||
for(i=0;i<64;i++)
|
||||
for(h=0; h<64; h++)
|
||||
{
|
||||
for(j=0;j<96;j++)
|
||||
for(w=0; w<96; w++)
|
||||
{
|
||||
if(i>55){display.writeData(WHITE>>8);display.writeData(WHITE);}
|
||||
else if(i>47){display.writeData(BLUE>>8);display.writeData(BLUE);}
|
||||
else if(i>39){display.writeData(GREEN>>8);display.writeData(GREEN);}
|
||||
else if(i>31){display.writeData(CYAN>>8);display.writeData(CYAN);}
|
||||
else if(i>23){display.writeData(RED>>8);display.writeData(RED);}
|
||||
else if(i>15){display.writeData(MAGENTA>>8);display.writeData(MAGENTA);}
|
||||
else if(i>7){display.writeData(YELLOW>>8);display.writeData(YELLOW);}
|
||||
else {display.writeData(BLACK>>8);display.writeData(BLACK);}
|
||||
if(w>83){display.writePixel(WHITE);}
|
||||
else if(w>71){display.writePixel(BLUE);}
|
||||
else if(w>59){display.writePixel(GREEN);}
|
||||
else if(w>47){display.writePixel(CYAN);}
|
||||
else if(w>35){display.writePixel(RED);}
|
||||
else if(w>23){display.writePixel(MAGENTA);}
|
||||
else if(w>11){display.writePixel(YELLOW);}
|
||||
else {display.writePixel(BLACK);}
|
||||
}
|
||||
}
|
||||
display.endWrite();
|
||||
}
|
||||
Loading…
Reference in a new issue