414 lines
11 KiB
C++
414 lines
11 KiB
C++
#ifndef LCD_SSD1306
|
|
#define LCD_SSD1306
|
|
|
|
#include "../../io/SoftSPI.h"
|
|
|
|
|
|
/**
|
|
* https://www.displayfuture.com/Display/datasheet/controller/ST7735.pdf
|
|
* https://www.aliexpress.com/item/1-8-inch-TFT-color-screen-module-ST7735-SPI-at-least-4IO-support-C51-STM32-with/32809505663.html?spm=2114.search0302.3.266.14d83b8cQXOxfz&ws_ab_test=searchweb0_0,searchweb201602_0_450_452_532_533_534_10618_535_317_318_319_10059_10696_10084_100031_10083_10547_10304_10546_10843_10887_320_10307_10548_204_448_10065_449_10068_10320_10103_10884_10820,searchweb201603_0,ppcSwitch_0&algo_pvid=7cf0bb24-ac60-4e97-9878-8716f61a79f3&algo_expid=7cf0bb24-ac60-4e97-9878-8716f61a79f3-33
|
|
* https://sites.google.com/site/arduinomega2560projects/microchip-pic/level-3/st7735-1-8-tft (!!!!)
|
|
*
|
|
* display is SPI
|
|
* CLK = clock
|
|
* SDA = mosi
|
|
* RS = data/command
|
|
* RST = reset
|
|
* CS = chip-select
|
|
*/
|
|
|
|
class ST7735 {
|
|
|
|
private:
|
|
|
|
static constexpr const char* NAME = "ST7735";
|
|
|
|
bool inited = false;
|
|
|
|
/** switch D/C line low */
|
|
inline void modeCommand() {
|
|
GPIO5_OUTPUT_SET;
|
|
GPIO5_L;
|
|
}
|
|
|
|
/** switch D/C line high */
|
|
inline void modeData() {
|
|
GPIO5_OUTPUT_SET;
|
|
GPIO5_H;
|
|
}
|
|
|
|
/** set CS = low */
|
|
inline void select() {
|
|
spi::chipSelect();
|
|
}
|
|
|
|
/** set CS = high */
|
|
inline void deselect() {
|
|
spi::chipDeselect();
|
|
}
|
|
|
|
|
|
public:
|
|
|
|
|
|
void initOnce() {
|
|
if (inited) {return;}
|
|
init();
|
|
inited = true;
|
|
}
|
|
|
|
//#define ST77XX_NOP 0x00
|
|
//#define ST77XX_SWRESET 0x01
|
|
//#define ST77XX_RDDID 0x04
|
|
//#define ST77XX_RDDST 0x09
|
|
|
|
//#define ST77XX_SLPIN 0x10
|
|
//#define ST77XX_SLPOUT 0x11
|
|
//#define ST77XX_PTLON 0x12
|
|
//#define ST77XX_NORON 0x13
|
|
|
|
//#define ST77XX_INVOFF 0x20
|
|
//#define ST77XX_INVON 0x21
|
|
//#define ST77XX_DISPOFF 0x28
|
|
//#define ST77XX_DISPON 0x29
|
|
//#define ST77XX_CASET 0x2A
|
|
//#define ST77XX_RASET 0x2B
|
|
//#define ST77XX_RAMWR 0x2C
|
|
//#define ST77XX_RAMRD 0x2E
|
|
|
|
//#define ST77XX_PTLAR 0x30
|
|
//#define ST77XX_COLMOD 0x3A
|
|
//#define ST77XX_MADCTL 0x36
|
|
|
|
//#define ST77XX_MADCTL_MY 0x80
|
|
//#define ST77XX_MADCTL_MX 0x40
|
|
//#define ST77XX_MADCTL_MV 0x20
|
|
//#define ST77XX_MADCTL_ML 0x10
|
|
//#define ST77XX_MADCTL_RGB 0x00
|
|
|
|
//#define ST77XX_RDID1 0xDA
|
|
//#define ST77XX_RDID2 0xDB
|
|
//#define ST77XX_RDID3 0xDC
|
|
//#define ST77XX_RDID4 0xDD
|
|
|
|
//#define ST7735_MADCTL_BGR 0x08
|
|
//#define ST7735_MADCTL_MH 0x04
|
|
|
|
//#define ST7735_FRMCTR1 0xB1
|
|
//#define ST7735_FRMCTR2 0xB2
|
|
//#define ST7735_FRMCTR3 0xB3
|
|
//#define ST7735_INVCTR 0xB4
|
|
//#define ST7735_DISSET5 0xB6
|
|
|
|
//#define ST7735_PWCTR1 0xC0
|
|
//#define ST7735_PWCTR2 0xC1
|
|
//#define ST7735_PWCTR3 0xC2
|
|
//#define ST7735_PWCTR4 0xC3
|
|
//#define ST7735_PWCTR5 0xC4
|
|
//#define ST7735_VMCTR1 0xC5
|
|
|
|
//#define ST7735_PWCTR6 0xFC
|
|
|
|
//#define ST7735_GMCTRP1 0xE0
|
|
//#define ST7735_GMCTRN1 0xE1
|
|
|
|
|
|
|
|
#define ST7735_NOP 0x00
|
|
#define ST7735_SWRESET 0x01
|
|
#define ST7735_RDDID 0x04
|
|
#define ST7735_RDDST 0x09
|
|
|
|
#define ST7735_SLPIN 0x10
|
|
#define ST7735_SLPOUT 0x11
|
|
#define ST7735_PTLON 0x12
|
|
#define ST7735_NORON 0x13
|
|
|
|
#define ST7735_INVOFF 0x20
|
|
#define ST7735_INVON 0x21
|
|
#define ST7735_DISPOFF 0x28
|
|
#define ST7735_DISPON 0x29
|
|
#define ST7735_CASET 0x2A
|
|
#define ST7735_RASET 0x2B
|
|
#define ST7735_RAMWR 0x2C
|
|
#define ST7735_RAMRD 0x2E
|
|
|
|
#define ST7735_PTLAR 0x30
|
|
#define ST7735_COLMOD 0x3A
|
|
#define ST7735_MADCTL 0x36
|
|
|
|
#define ST7735_FRMCTR1 0xB1
|
|
#define ST7735_FRMCTR2 0xB2
|
|
#define ST7735_FRMCTR3 0xB3
|
|
#define ST7735_INVCTR 0xB4
|
|
#define ST7735_DISSET5 0xB6
|
|
|
|
#define ST7735_PWCTR1 0xC0
|
|
#define ST7735_PWCTR2 0xC1
|
|
#define ST7735_PWCTR3 0xC2
|
|
#define ST7735_PWCTR4 0xC3
|
|
#define ST7735_PWCTR5 0xC4
|
|
#define ST7735_VMCTR1 0xC5
|
|
|
|
#define ST7735_RDID1 0xDA
|
|
#define ST7735_RDID2 0xDB
|
|
#define ST7735_RDID3 0xDC
|
|
#define ST7735_RDID4 0xDD
|
|
|
|
#define ST7735_PWCTR6 0xFC
|
|
|
|
#define ST7735_GMCTRP1 0xE0
|
|
#define ST7735_GMCTRN1 0xE1
|
|
|
|
|
|
private:
|
|
|
|
#define V 128
|
|
#define H 160
|
|
|
|
void waitLong() {
|
|
for (int i = 0; i < 50; ++i) {
|
|
os_delay_us(10*1000);
|
|
}
|
|
}
|
|
|
|
void waitShort() {
|
|
os_delay_us(10*1000);
|
|
}
|
|
|
|
void init() {
|
|
|
|
spi::init();
|
|
|
|
debugMod(NAME, "init()");
|
|
|
|
// sendCommand(ST77XX_SWRESET); waitLong();
|
|
// sendCommand(ST77XX_SLPOUT); waitLong();
|
|
// sendCommand(ST77XX_COLMOD, 0x05); waitShort();
|
|
|
|
// sendCommand(ST7735_FRMCTR1, 0x00, 0x06, 0x03); waitShort();
|
|
// sendCommand(ST77XX_MADCTL, 0x08);
|
|
// sendCommand(ST7735_DISSET5, 0x15, 0x02);
|
|
// sendCommand(ST7735_INVCTR, 0x0);
|
|
|
|
// sendCommand(ST7735_PWCTR1, 0x02, 0x70); waitShort();
|
|
|
|
// sendCommand(ST7735_PWCTR2, 0x05);
|
|
// sendCommand(ST7735_PWCTR3, 0x01, 0x02);
|
|
// sendCommand(ST7735_VMCTR1, 0x3C, 0x38); waitShort();
|
|
// sendCommand(ST7735_PWCTR6, 0x11, 0x15);
|
|
|
|
// sendCommand(ST7735_GMCTRP1,
|
|
// 0x09, 0x16, 0x09, 0x20,
|
|
// 0x21, 0x1B, 0x13, 0x19,
|
|
// 0x17, 0x15, 0x1E, 0x2B,
|
|
// 0x04, 0x05, 0x02, 0x0E);
|
|
// sendCommand(ST7735_GMCTRN1,
|
|
// 0x0B, 0x14, 0x08, 0x1E,
|
|
// 0x22, 0x1D, 0x18, 0x1E,
|
|
// 0x1B, 0x1A, 0x24, 0x2B,
|
|
// 0x06, 0x06, 0x02, 0x0F);
|
|
// waitShort();
|
|
|
|
// sendCommand(ST77XX_CASET, 0x00, 0x02, 0x00, 0x81);
|
|
// sendCommand(ST77XX_RASET, 0x00, 0x02, 0x00, 0x81);
|
|
// sendCommand(ST77XX_NORON); waitShort();
|
|
// sendCommand(ST77XX_DISPON); waitLong();
|
|
|
|
|
|
sendCommand(ST7735_SWRESET); // 1: Software reset, 0 args, w/delay 150ms 0x01
|
|
waitLong();
|
|
sendCommand(ST7735_SLPOUT); // 2: Out of sleep mode, 0 args, w/delay 500ms 0x11
|
|
waitLong();
|
|
sendCommand(ST7735_FRMCTR1); // 3: Frame rate ctrl - normal mode) 3 args: 0xb1
|
|
sendData(0x01); sendData(0x2C); sendData(0x2D); // Rate = fosc/(1x2+40) * (LINE+2C+2D)
|
|
sendCommand(ST7735_FRMCTR2); // 4: Frame rate control - idle mode) 3 args: 0xb2
|
|
sendData(0x01); sendData(0x2C); sendData(0x2D); // Rate = fosc/(1x2+40) * (LINE+2C+2D)
|
|
sendCommand(ST7735_FRMCTR3); // 5: Frame rate ctrl - partial mode) 6 args: 0xb3
|
|
sendData(0x01); sendData(0x2C); sendData(0x2D); // Dot inversion mode
|
|
sendData(0x01); sendData(0x2C); sendData(0x2D); // Line inversion mode
|
|
sendCommand(ST7735_INVCTR); // 6: Display inversion ctrl) 1 arg) no delay: 0xb4
|
|
sendData(0x07); // No inversion
|
|
sendCommand(ST7735_PWCTR1); // 7: Power control) 3 args) no delay: 0xc0
|
|
sendData(0xA2);
|
|
sendData(0x02); // -4.6V
|
|
sendData(0x84); // AUTO mode
|
|
sendCommand(ST7735_PWCTR2); // 8: Power control) 1 arg) no delay: 0xc1
|
|
sendData(0xC5); // VGH25 = 2.4C VGSEL = -10 VGH = 3 * AVDD
|
|
sendCommand(ST7735_PWCTR3); // 9: Power control) 2 args) no delay: 0xc2
|
|
sendData(0x0A); // Opamp current small
|
|
sendData(0x00); // Boost frequency
|
|
sendCommand(ST7735_PWCTR4); // 10: Power control) 2 args) no delay:
|
|
sendData(0x8A); // BCLK/2) Opamp current small & Medium low
|
|
sendData(0x2A);
|
|
sendCommand(ST7735_PWCTR5); // 11: Power control) 2 args) no delay:
|
|
sendData(0x8A); sendData(0xEE);
|
|
sendCommand(ST7735_VMCTR1); // 12: Power control) 1 arg) no delay:
|
|
sendData(0x0E);
|
|
sendCommand(ST7735_INVOFF); // 13: Don't invert display) no args) no delay 0x20
|
|
sendCommand(ST7735_MADCTL); // 14: Memory access control (directions)) 1 arg:
|
|
sendData(0xC8); // row addr/col addr); bottom to top refresh
|
|
sendCommand(ST7735_COLMOD); // 15: set color mode); 1 arg); no delay:
|
|
sendData(0x05); // 16-bit color
|
|
sendCommand(ST7735_NORON); // 3: Normal display on, no args, w/delay 10ms 0x13
|
|
waitShort();
|
|
sendCommand(ST7735_DISPON); // 4: Main screen turn on, no args w/delay 100ms 0x29
|
|
waitLong();
|
|
|
|
|
|
|
|
debugMod(NAME, "init() done");
|
|
|
|
clean(0x1111110000001111);
|
|
|
|
}
|
|
|
|
|
|
void clean(uint16_t color){
|
|
|
|
uint8_t lo = color & 0xFF;
|
|
uint8_t hi = color >> 8;
|
|
|
|
sendCommand(ST7735_CASET); // Column addr set
|
|
sendData(0x00);
|
|
sendData(0); // XSTART
|
|
sendData(0x00);
|
|
sendData(V); // XEND
|
|
|
|
sendCommand(ST7735_RASET); // Row addr set
|
|
sendData(0x00);
|
|
sendData(0); // YSTART
|
|
sendData(0x00);
|
|
sendData(H); // YEND
|
|
|
|
sendCommand(ST7735_RAMWR);
|
|
|
|
for(char x=0;x<V;x++){
|
|
for(char y=0;y<H;y++){
|
|
sendData(lo);
|
|
sendData(hi);
|
|
}
|
|
}
|
|
}
|
|
|
|
public:
|
|
|
|
void flush(uint16_t* data) {
|
|
|
|
sendCommand(ST7735_CASET); // Column addr set
|
|
sendData(0x00);
|
|
sendData(0); // XSTART
|
|
sendData(0x00);
|
|
sendData(V); // XEND
|
|
|
|
sendCommand(ST7735_RASET); // Row addr set
|
|
sendData(0x00);
|
|
sendData(0); // YSTART
|
|
sendData(0x00);
|
|
sendData(H); // YEND
|
|
|
|
sendCommand(ST7735_RAMWR);
|
|
|
|
for (int i = 0; i < (V*H); ++i) {
|
|
uint16_t color = data[i];
|
|
uint8_t lo = color & 0xFF;
|
|
uint8_t hi = color >> 8;
|
|
sendData(lo);
|
|
sendData(hi);
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
void sendData(uint8_t data) {
|
|
modeData();
|
|
select();
|
|
spi::writeByte(data);
|
|
deselect();
|
|
}
|
|
|
|
void sendCommand(uint8_t cmd) {
|
|
modeCommand();
|
|
select();
|
|
spi::writeByte(cmd);
|
|
deselect();
|
|
}
|
|
|
|
// void sendCommand(uint8_t cmd, uint8_t arg1) {
|
|
// modeCommand();
|
|
// select();
|
|
// spi::writeByte(cmd);
|
|
// deselect();
|
|
// sendData(arg1);
|
|
// }
|
|
|
|
// void sendCommand(uint8_t cmd, uint8_t arg1, uint8_t arg2) {
|
|
// modeCommand();
|
|
// select();
|
|
// spi::writeByte(cmd);
|
|
// deselect();
|
|
// sendData(arg1);
|
|
// sendData(arg2);
|
|
// }
|
|
|
|
// void sendCommand(uint8_t cmd, uint8_t arg1, uint8_t arg2, uint8_t arg3) {
|
|
// modeCommand();
|
|
// select();
|
|
// spi::writeByte(cmd);
|
|
// deselect();
|
|
// sendData(arg1);
|
|
// sendData(arg2);
|
|
// sendData(arg3);
|
|
// }
|
|
|
|
// void sendCommand(uint8_t cmd, uint8_t arg1, uint8_t arg2, uint8_t arg3, uint8_t arg4) {
|
|
// modeCommand();
|
|
// select();
|
|
// spi::writeByte(cmd);
|
|
// deselect();
|
|
// sendData(arg1);
|
|
// sendData(arg2);
|
|
// sendData(arg3);
|
|
// sendData(arg4);
|
|
// }
|
|
|
|
// void sendCommand(uint8_t cmd,
|
|
// uint8_t a1, uint8_t a2, uint8_t a3, uint8_t a4,
|
|
// uint8_t a5, uint8_t a6, uint8_t a7, uint8_t a8,
|
|
// uint8_t a9, uint8_t a10, uint8_t a11, uint8_t a12,
|
|
// uint8_t a13, uint8_t a14, uint8_t a15, uint8_t a16) {
|
|
// modeCommand();
|
|
// select();
|
|
// spi::writeByte(cmd);
|
|
// deselect();
|
|
|
|
// sendData(a1);
|
|
// sendData(a2);
|
|
// sendData(a3);
|
|
// sendData(a4);
|
|
|
|
// sendData(a5);
|
|
// sendData(a6);
|
|
// sendData(a7);
|
|
// sendData(a8);
|
|
|
|
// sendData(a9);
|
|
// sendData(a10);
|
|
// sendData(a11);
|
|
// sendData(a12);
|
|
|
|
// sendData(a13);
|
|
// sendData(a14);
|
|
// sendData(a15);
|
|
// sendData(a16);
|
|
|
|
// }
|
|
|
|
};
|
|
|
|
|
|
#endif
|