A lib to handle a E-Paper display from Jiaxian Displays. The lib can handle graphic and text drawing and is using external fonts. SPI interface.

Dependents:   EPD_GDE021A1_demo

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers EpdGDE021A1.cpp Source File

EpdGDE021A1.cpp

00001 #include "EpdGDE021A1.h"
00002 #include "GraphicUtil/Graphic.h"
00003 
00004 using namespace mbed;
00005 
00006 //const unsigned char init_data[] = { 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, 0x55,
00007 //      0x55, 0x00, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x15, 0x15, 0x15,
00008 //      0x15, 0x05, 0x05, 0x05, 0x05, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00,
00009 //      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00010 //      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00011 //      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00012 //      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00013 //      0x00, 0x44, 0xF7, 0x44, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; //waveform
00014 const unsigned char init_data[] = { 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, 0x55,
00015         0x55, 0x00, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xAA, 0x55,
00016         0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x05, 0x05, 0x05, 0x05, 0x15, 0x15, 0x15,
00017         0x15, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00018         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00019         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00020         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00021         0x00, 0x34, 0x32, 0xF1, 0x74, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, };
00022 
00023 EpdGDE021A1::EpdGDE021A1(PinName mosi, PinName sclk, PinName cs, PinName dc,
00024         PinName reset) :
00025         Graphic(_buf,
00026         GED021A1_WIDH, GED021A1_HIGHT, GED021A1_BITS), //graphic
00027         _spi(mosi, NC, sclk), // spi
00028         _spi_ncs(cs), //cs
00029         _spi_ndc(dc), //d/c
00030         _reset(reset) // reset
00031 {
00032     _reset = 1;
00033     _spi_ncs = 1;
00034     if (dc == NC) {
00035 //          _spi.format(9);
00036         _spi3w = 1;
00037     } else
00038         _spi3w = 0;
00039 //      _spi.frequency(100000); //default 1M
00040 
00041     memset(_buf, 0xff, GED021A1_BUF_SIZE);
00042 }
00043 
00044 void EpdGDE021A1::reset() {
00045     _reset = 0;
00046     wait_ms(1); //1ms
00047     _reset = 1;
00048     wait_ms(1); //1ms
00049 }
00050 
00051 void EpdGDE021A1::spi_write(int cmd, unsigned char val) {
00052     int v;
00053 //  _spi_ncs = 0;
00054 //  DELAY_100nS(1);
00055 //  wait_ms(3);
00056 //  wait_us(100);
00057 
00058     _spi_ncs = 0;
00059 
00060     if (_spi3w == 1) { //SPI 3-wire mode, bit-9 = !cmd
00061         v = ((!cmd) << 7) | (val >> 1);
00062         _spi.write(v);
00063         _spi.write(val << 7);
00064 //      v = ((!cmd) << 8) | (val);
00065 //      _spi.write(v);
00066     } else {
00067         _spi_ndc = !cmd;
00068         _spi.write(val);
00069     }
00070 
00071     //DELAY_100nS(1);
00072 //  wait_ms(3);
00073 //  wait_us(100);
00074     _spi_ncs = 1;
00075     wait_us(1);
00076 //  wait_us(100);
00077 //  wait_ms(3);
00078 }
00079 
00080 void EpdGDE021A1::spi_cmd(unsigned char cmd) {
00081     spi_write(1, cmd);
00082 }
00083 void EpdGDE021A1::spi_data(unsigned char val) {
00084     spi_write(0, val);
00085 }
00086 
00087 void EpdGDE021A1::write_lut() {
00088     unsigned char i;
00089     spi_cmd(0x32); //write LUT register
00090     for (i = 0; i < 90; i++)
00091         spi_data(init_data[i]); //write LUT register
00092 }
00093 void EpdGDE021A1::init() {
00094     //initial code
00095     spi_cmd(0x10); //set no deep sleep mode
00096     spi_data(0x00);
00097 
00098     /* controller layout (x:y):
00099      *  0:172  0:0
00100      *  72:172 72:0
00101      * To refresh EPD from left to right, x increase then y decrease
00102      */
00103     spi_cmd(0x11); //data enter mode
00104     spi_data(0x01); //x inc then y dec
00105 
00106     spi_cmd(0x44); //set window x
00107     spi_data(0x00); //start at 00h;
00108     spi_data(0x11); //end at 11h(17)->72
00109 
00110     spi_cmd(0x45); //set window y
00111     spi_data(0xAB); //start at ABh(171)->172
00112     spi_data(0x00); //end at 00h
00113 
00114     spi_cmd(0x4E); //set RAM x address count to 0;
00115     spi_data(0x00);
00116     spi_cmd(0x4F); //set RAM y address count to 0;
00117     spi_data(0xAB);
00118 
00119     spi_cmd(0x21); //bypass RAM data
00120     spi_data(0x81); //only content
00121 
00122     spi_cmd(0xF0); //booster feedback used
00123     spi_data(0x1F);
00124     spi_cmd(0x2C); //vcom voltage
00125     spi_data(0xA0);
00126     spi_cmd(0x3C); //board voltage
00127     spi_data(0x63);
00128     spi_cmd(0x22); //display update sequence option ,in page 33
00129     spi_data(0xc4); //0xc4 //enable sequence: clk -> CP -> LUT ->  pattern display
00130     write_lut();
00131 }
00132 
00133 void EpdGDE021A1::wait_busy() {
00134 //      while (1) {
00135 //          for (unsigned int i = 5; i > 0; i--)
00136 //              ;
00137 //          if (digitalRead(BUSY_GDE021A1) == 0)
00138 //              break;
00139 //      }
00140     wait(2);
00141 }
00142 
00143 void EpdGDE021A1::sleep() {
00144     spi_cmd(0x22); //display updata sequence option
00145     spi_data(0x03);
00146     spi_cmd(0x20);
00147 }
00148 
00149 void EpdGDE021A1::draw(unsigned char *data) {
00150     int i;
00151     spi_cmd(0x24);
00152     for (i = 0; i < GED021A1_BUF_SIZE; i++) {
00153         spi_data(data[i]);
00154     }
00155     spi_cmd(0x20);
00156     wait_ms(1);
00157     wait_busy();
00158     wait(1.5);
00159     sleep();
00160 }
00161 
00162 void EpdGDE021A1::setup() {
00163     reset();
00164     init();
00165 }
00166 
00167 void EpdGDE021A1::update() {
00168     setup();
00169     draw(_buf);
00170 }