Merge pull request #68 from prenticedavid/test_9797

Test 9797
This commit is contained in:
prenticedavid
2018-10-28 08:20:24 +00:00
committed by GitHub
3 changed files with 239 additions and 21 deletions

View File

@@ -1,6 +1,6 @@
//#define SUPPORT_0139 //S6D0139 +280 bytes
#define SUPPORT_0154 //S6D0154 +320 bytes
//#define SUPPORT_1289 //costs about 408 bytes
#define SUPPORT_1289 //costs about 408 bytes
//#define SUPPORT_1580 //R61580 Untested
#define SUPPORT_1963 //only works with 16BIT bus anyway
//#define SUPPORT_4532 //LGDP4532 +120 bytes. thanks Leodino
@@ -59,13 +59,30 @@ MCUFRIEND_kbv::MCUFRIEND_kbv(int CS, int RS, int WR, int RD, int _RST):Adafruit_
// we can not access GPIO pins until AHB has been enabled.
}
static uint8_t done_reset, is8347, is555;
static uint8_t done_reset, is8347, is555, is9797;
static uint16_t color565_to_555(uint16_t color) {
return (color & 0xFFC0) | ((color & 0x1F) << 1) | ((color & 0x01)); //lose Green LSB, extend Blue LSB
}
static uint16_t color555_to_565(uint16_t color) {
return (color & 0xFFC0) | ((color & 0x0400) >> 5) | ((color & 0x3F) >> 1); //extend Green LSB
}
static uint8_t color565_to_r(uint16_t color) {
return ((color & 0xF800) >> 8); // transform to rrrrrxxx
}
static uint8_t color565_to_g(uint16_t color) {
return ((color & 0x07E0) >> 3); // transform to ggggggxx
}
static uint8_t color565_to_b(uint16_t color) {
return ((color & 0x001F) << 3); // transform to bbbbbxxx
}
static void write24(uint16_t color) {
uint8_t r = color565_to_r(color);
uint8_t g = color565_to_g(color);
uint8_t b = color565_to_b(color);
write8(r);
write8(g);
write8(b);
}
void MCUFRIEND_kbv::reset(void)
{
@@ -461,14 +478,15 @@ void MCUFRIEND_kbv::setRotation(uint8_t r)
_MC = 0x4E, _MP = 0x4F, _MW = 0x22, _SC = 0x44, _EC = 0x44, _SP = 0x45, _EP = 0x46;
if (rotation & 1)
val ^= 0xD0; // exchange Landscape modes
GS = (val & 0x80) ? (1 << 14) | (1 << 12) : 0; //called TB (top-bottom)
GS = (val & 0x80) ? (1 << 14) : 0; //called TB (top-bottom), CAD=0
SS_v = (val & 0x40) ? (1 << 9) : 0; //called RL (right-left)
ORG = (val & 0x20) ? (1 << 3) : 0; //called AM
_lcd_drivOut = GS | SS_v | (REV << 13) | 0x013F; //REV=0, BGR=0, MUX=319
if (val & 0x08)
_lcd_drivOut |= 0x0800; //BGR
WriteCmdData(0x01, _lcd_drivOut); // set Driver Output Control
WriteCmdData(0x11, ORG | 0x6070); // set GRAM write direction.
if (is9797) WriteCmdData(0x11, ORG | 0x4C30); else // DFM=2, DEN=1, WM=1, TY=0
WriteCmdData(0x11, ORG | 0x6070); // DFM=3, EN=0, TY=1
break;
#endif
}
@@ -493,6 +511,7 @@ void MCUFRIEND_kbv::drawPixel(int16_t x, int16_t y, uint16_t color)
#endif
setAddrWindow(x, y, x, y);
// CS_ACTIVE; WriteCmd(_MW); write16(color); CS_IDLE; //-0.01s +98B
if (is9797) { CS_ACTIVE; WriteCmd(_MW); write24(color); CS_IDLE;} else
WriteCmdData(_MW, color);
}
@@ -604,6 +623,18 @@ void MCUFRIEND_kbv::fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_
STROBE_16BIT;
}
#else
#if defined(SUPPORT_1289)
if (is9797) {
uint8_t r = color565_to_r(color);
uint8_t g = color565_to_g(color);
uint8_t b = color565_to_b(color);
do {
write8(r);
write8(g);
write8(b);
} while (--end != 0);
} else
#endif
do {
write8(hi);
write8(lo);
@@ -635,8 +666,9 @@ static void pushColors_any(uint16_t cmd, uint8_t * block, int16_t n, bool first,
}
color = (isbigend) ? (h << 8 | l) : (l << 8 | h);
#if defined(SUPPORT_9488_555)
if (is555) color = color565_to_555(color);
if (is555) color = color565_to_555(color);
#endif
if (is9797) write24(color); else
write16(color);
}
CS_IDLE;
@@ -973,20 +1005,28 @@ void MCUFRIEND_kbv::begin(uint16_t ID)
#endif
#ifdef SUPPORT_1289
case 0x9797:
is9797 = 1;
// _lcd_capable = 0 | XSA_XEA_16BIT | REV_SCREEN | AUTO_READINC | READ_24BITS;
// deliberately set READ_BGR to disable Software Scroll in graphictest_kbv example
_lcd_capable = 0 | XSA_XEA_16BIT | REV_SCREEN | AUTO_READINC | READ_24BITS | READ_BGR;
_lcd_ID = 0x1289;
goto common_1289;
case 0x1289:
_lcd_capable = 0 | XSA_XEA_16BIT | REV_SCREEN;
_lcd_capable = 0 | XSA_XEA_16BIT | REV_SCREEN | AUTO_READINC;
common_1289:
// came from MikroElektronika library http://www.hmsprojects.com/tft_lcd.html
static const uint16_t SSD1289_regValues[] PROGMEM = {
0x0000, 0x0001,
0x0003, 0xA8A4,
0x000C, 0x0000,
0x000D, 0x080C, // was 0x800C
0x000D, 0x000A, // VRH=10
0x000E, 0x2B00,
0x001E, 0x00B7,
0x0001, 0x2B3F, // was 0x2B3F,
0x0002, 0x0400, // was 0x0600
0x0001, 0x2B3F, // setRotation() alters
0x0002, 0x0600, // B_C=1, EOR=1
0x0010, 0x0000,
0x0011, 0x6070, // was 0x6070
0x0011, 0x6070, // setRotation() alters
0x0005, 0x0000,
0x0006, 0x0000,
0x0016, 0xEF1C,
@@ -994,15 +1034,6 @@ void MCUFRIEND_kbv::begin(uint16_t ID)
0x0007, 0x0233,
0x000B, 0x0000,
0x000F, 0x0000,
0x0041, 0x0000,
0x0042, 0x0000,
0x0048, 0x0000,
0x0049, 0x013F,
0x004A, 0x0000,
0x004B, 0x0000,
0x0044, 0xEF95,
0x0045, 0x0000,
0x0046, 0x013F,
0x0030, 0x0707,
0x0031, 0x0204,
0x0032, 0x0204,
@@ -1016,8 +1047,6 @@ void MCUFRIEND_kbv::begin(uint16_t ID)
0x0023, 0x0000,
0x0024, 0x0000,
0x0025, 0x8000,
0x004f, 0x0000,
0x004e, 0x0000,
};
init_table16(SSD1289_regValues, sizeof(SSD1289_regValues));
break;

View File

@@ -74,6 +74,7 @@ SPFD5408 240x320 ID=0x5408
SPFD5420 240x400 ID=0x5420 #define SUPPORT_9326_5420
SSD1963 800x480 ID=0x1963
SSD1289 240x320 ID=0x1289 #define SUPPORT_1289
SSD1297 240x320 ID=0x9797 #define SUPPORT_1289 (unstable readGRAM())
ST7781 240x320 ID=0x7783 #define SUPPORT_7781 (no Vertical Scroll)
ST7789V 240x320 ID=0x7789
ST7793 240x400 ID=0x7793 #define SUPPORT_B509_7793

View File

@@ -0,0 +1,188 @@
#define SSD1289_JUMPERS 2 //Uno Shield with VERY different pin-out to Mcufriend
//#define USE_SSD1289_SHIELD_UNO
//#define USE_SSD1289_SHIELD_MEGA
#define USE_SSD1289_SHIELD_DUE //Due only works with JUMPERS==2
#if 0
//################################# SSD1289 SHIELD #######################
// SSD1289 shield has LCD_D0 on RXD0. SD_CS=D8, T_IRQ=D9, T_CS=D10
// This is fine for write-only operations with NO Serial. A4, A5 are available for I2C
// NOTE THAT Serial.end() IS REQUIRED FOR NO JUMPERS
// Read operations, lose I2C (on Uno) but gain Serial, Bootloader etc
// jumper D0 to A4, D1 to A5, Switch #1 to OFF, #2 to OFF
#elif defined(__AVR_ATmega328P__) && defined(USE_SSD1289_SHIELD_UNO) //on UNO
#warning using SSD1289 Shield for mega328
#define RD_PORT PORTC
#define RD_PIN 3
#define WR_PORT PORTC
#define WR_PIN 2
#define CD_PORT PORTC
#define CD_PIN 1
#define CS_PORT PORTC
#define CS_PIN 0
#define RESET_PORT PORTB
#define RESET_PIN 1 //D9 actually T_IRQ
#if SSD1289_JUMPERS == 0 //data bus on D0..D7
#warning no jumpers. Switch #1=ON, #2=ON
#define BMASK 0x00 //0x00 for output, 0x01 for Read + Serial
#define CMASK 0x00 //0x20 for Read + Serial
#define DMASK 0xFF
#define write8(x) { PORTD = x; WR_STROBE; }
#define read_8() ( 0xAB ) //this shield is WRITE-ONLY
#elif SSD1289_JUMPERS == 2
#warning jumper D0 to A4, D1 to A5. Switch #1=OFF, #2=OFF
#define BMASK 0x00 //D8 is unused now
#define CMASK ((1<<4)|(1<<5)) //A4, A5
#define DMASK (0xFC)
#define write8(x) { PORTC = (PORTC & ~CMASK) | ((x<<4) & CMASK);\
PORTD = (PORTD & ~DMASK) | (x & DMASK); WR_STROBE; }
#define read_8() ( ((PINC & CMASK)>>4)|(PIND & DMASK) )
#endif
#define setWriteDir() { DDRC |= CMASK; DDRD |= DMASK; DDRB |= BMASK; }
#define setReadDir() { DDRC &= ~CMASK; DDRD &= ~DMASK; DDRB &= ~BMASK; }
#define write16(x) { uint8_t h = (x)>>8, l = x; write8(h); write8(l); }
#define READ_8(dst) { RD_STROBE; dst = read_8(); RD_IDLE; }
#define READ_16(dst) { uint8_t hi; READ_8(hi); READ_8(dst); dst |= (hi << 8); }
#define PIN_LOW(p, b) (p) &= ~(1<<(b))
#define PIN_HIGH(p, b) (p) |= (1<<(b))
#define PIN_OUTPUT(p, b) *(&p-1) |= (1<<(b))
#elif defined(__AVR_ATmega2560__) && defined(USE_SSD1289_SHIELD_MEGA)
#warning using SSD1289 Shield for mega2560
#define RD_PORT PORTF
#define RD_PIN 3 //A3
#define WR_PORT PORTF
#define WR_PIN 2 //A2
#define CD_PORT PORTF
#define CD_PIN 1 //A1
#define CS_PORT PORTF
#define CS_PIN 0 //A0
#define RESET_PORT PORTH
#define RESET_PIN 6 //D9 (D10=T_CS, D9=T_IRQ, D8=SD_CS)
#if (SSD1289_JUMPERS == 0) //data bus on D0..D7
#warning no jumpers Switch #1=ON, #2=ON
#define EMASK ((1<<0)|(1<<1)|(1<<4)|(1<<5)|(1<<3))
#define FMASK 0x00
#define HMASK ((1<<3)|(1<<4))
#define GMASK (1<<5)
#define write_8(x) { PORTH &= ~HMASK; PORTG &= ~GMASK; PORTF &= ~FMASK; PORTE &= ~EMASK; \
PORTE |= (((x) & (1<<0)) << 0); \
PORTE |= (((x) & (1<<1)) << 0); \
PORTE |= (((x) & (3<<2)) << 2); \
PORTG |= (((x) & (1<<4)) << 1); \
PORTE |= (((x) & (1<<5)) >> 2); \
PORTH |= (((x) & (3<<6)) >> 3); \
}
#define read_8() ( 0xBC ) //this shield is WRITE-ONLY
#elif (SSD1289_JUMPERS == 2) //jumper D0 to A4, D1 to A5. Switch #1=OFF, #2=OFF
#warning jumper D0 to A4, D1 to A5. Switch #1=OFF, #2=OFF
#define EMASK ((1<<4)|(1<<5)|(1<<3))
#define FMASK ((1<<4)|(1<<5))
#define HMASK ((1<<3)|(1<<4))
#define GMASK (1<<5)
#define write_8(x) { PORTH &= ~HMASK; PORTG &= ~GMASK; PORTF &= ~FMASK; PORTE &= ~EMASK; \
PORTF |= (((x) & (1<<0)) << 4); \
PORTF |= (((x) & (1<<1)) << 4); \
PORTE |= (((x) & (3<<2)) << 2); \
PORTG |= (((x) & (1<<4)) << 1); \
PORTE |= (((x) & (1<<5)) >> 2); \
PORTH |= (((x) & (3<<6)) >> 3); \
}
#define read_8() ( ((PINF & (1<<4)) >> 4)\
| ((PINF & (1<<5)) >> 4)\
| ((PINE & (3<<4)) >> 2)\
| ((PING & (1<<5)) >> 1)\
| ((PINE & (1<<3)) << 2)\
| ((PINH & (3<<3)) << 3)\
)
#endif
#define setWriteDir() { DDRH |= HMASK; DDRG |= GMASK; DDRF |= FMASK; DDRE |= EMASK; }
#define setReadDir() { DDRH &= ~HMASK; DDRG &= ~GMASK; DDRF &= ~FMASK; DDRE &= ~EMASK; }
#define write8(x) { write_8(x); WR_STROBE; }
#define write16(x) { uint8_t h = (x)>>8, l = x; write8(h); write8(l); }
#define READ_8(dst) { RD_STROBE; dst = read_8(); RD_IDLE; }
#define READ_16(dst) { RD_STROBE; dst = read_8(); RD_IDLE; RD_STROBE; dst = (dst<<8) | read_8(); RD_IDLE; }
#define PIN_LOW(p, b) (p) &= ~(1<<(b))
#define PIN_HIGH(p, b) (p) |= (1<<(b))
#define PIN_OUTPUT(p, b) *(&p-1) |= (1<<(b))
#elif defined(__SAM3X8E__) && defined(USE_SSD1289_SHIELD_DUE) // on DUE
#warning USE_SSD1289_SHIELD_DUE
// configure macros for the control pins
#define RD_PORT PIOA
#define RD_PIN 22 //A3
#define WR_PORT PIOA
#define WR_PIN 23 //A2
#define CD_PORT PIOA
#define CD_PIN 24 //A1
#define CS_PORT PIOA
#define CS_PIN 16 //A0
#define RESET_PORT PIOC
#define RESET_PIN 21 //D9 Touch_IRQ
// configure macros for data bus
#if SSD1289_JUMPERS == 0 //data bus on D0..D7
#warning no jumpers Switch #1=ON, #2=ON
#define AMASK ((1<<8)|(1<<9)) //D0, D1
#define BMASK (1<<25)
#define CMASK ((1<<28)|(1<<26)|(1<<25)|(1<<24)|(1<<23))
#define write_8(x) { PIOA->PIO_CODR = AMASK; PIOB->PIO_CODR = BMASK; PIOC->PIO_CODR = CMASK; \
PIOA->PIO_SODR = (((x) & (1<<0)) << 8); \
PIOA->PIO_SODR = (((x) & (1<<1)) << 8); \
PIOB->PIO_SODR = (((x) & (1<<2)) << 23); \
PIOC->PIO_SODR = (((x) & (1<<3)) << 25); \
PIOC->PIO_SODR = (((x) & (1<<4)) << 22); \
PIOC->PIO_SODR = (((x) & (1<<5)) << 20); \
PIOC->PIO_SODR = (((x) & (1<<6)) << 18); \
PIOC->PIO_SODR = (((x) & (1<<7)) << 16); \
}
#define read_8() ( 0xCD ) //this shield is WRITE-ONLY
#elif SSD1289_JUMPERS == 2 //jumper D0 to A4, D1 to A5. Switch #1=OFF, #2=OFF
#warning jumper D0 to A4, D1 to A5. Switch #1=OFF, #2=OFF
#define AMASK ((1<<6)|(1<<4)) //A4, A5
#define BMASK (1<<25)
#define CMASK ((1<<28)|(1<<26)|(1<<25)|(1<<24)|(1<<23))
#define write_8(x) { PIOA->PIO_CODR = AMASK; PIOB->PIO_CODR = BMASK; PIOC->PIO_CODR = CMASK; \
PIOA->PIO_SODR = (((x) & (1<<0)) << 6); \
PIOA->PIO_SODR = (((x) & (1<<1)) << 3); \
PIOB->PIO_SODR = (((x) & (1<<2)) << 23); \
PIOC->PIO_SODR = (((x) & (1<<3)) << 25); \
PIOC->PIO_SODR = (((x) & (1<<4)) << 22); \
PIOC->PIO_SODR = (((x) & (1<<5)) << 20); \
PIOC->PIO_SODR = (((x) & (1<<6)) << 18); \
PIOC->PIO_SODR = (((x) & (1<<7)) << 16); \
}
#define read_8() ( ((PIOA->PIO_PDSR & (1<<6)) >> 6)\
| ((PIOA->PIO_PDSR & (1<<4)) >> 3)\
| ((PIOB->PIO_PDSR & (1<<25)) >> 23)\
| ((PIOC->PIO_PDSR & (1<<28)) >> 25)\
| ((PIOC->PIO_PDSR & (1<<26)) >> 22)\
| ((PIOC->PIO_PDSR & (1<<25)) >> 20)\
| ((PIOC->PIO_PDSR & (1<<24)) >> 18)\
| ((PIOC->PIO_PDSR & (1<<23)) >> 16)\
)
#endif
#define setWriteDir() { PIOA->PIO_OER = AMASK; PIOB->PIO_OER = BMASK; PIOC->PIO_OER = CMASK; }
#define setReadDir() { \
PMC->PMC_PCER0 = (1 << ID_PIOA)|(1 << ID_PIOB)|(1 << ID_PIOC);\
PIOA->PIO_ODR = AMASK; PIOB->PIO_ODR = BMASK; PIOC->PIO_ODR = CMASK;\
}
#define write8(x) { write_8(x); WR_ACTIVE; WR_STROBE; WR_IDLE; }
#define write16(x) { uint8_t h = (x)>>8, l = x; write8(h); write8(l); }
#define READ_8(dst) { RD_STROBE; RD_ACTIVE4; dst = read_8(); RD_IDLE; RD_IDLE; RD_IDLE; }
#define READ_16(dst) { uint8_t hi; READ_8(hi); READ_8(dst); dst |= (hi << 8); }
// Shield Control macros.
#define PIN_LOW(port, pin) (port)->PIO_CODR = (1<<(pin))
#define PIN_HIGH(port, pin) (port)->PIO_SODR = (1<<(pin))
#define PIN_OUTPUT(port, pin) (port)->PIO_OER = (1<<(pin))