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

This E-ink display can be found from here, Factory datasheet, Controller: SSD1606

/media/uploads/steeven/image1.jpg

Committer:
steeven
Date:
Wed Apr 15 11:16:20 2015 +0000
Revision:
0:e7a39129f419
GDE021A1 initial

Who changed what in which revision?

UserRevisionLine numberNew contents of line
steeven 0:e7a39129f419 1 #include "EpdGDE021A1.h"
steeven 0:e7a39129f419 2 #include "GraphicUtil/Graphic.h"
steeven 0:e7a39129f419 3
steeven 0:e7a39129f419 4 using namespace mbed;
steeven 0:e7a39129f419 5
steeven 0:e7a39129f419 6 //const unsigned char init_data[] = { 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, 0x55,
steeven 0:e7a39129f419 7 // 0x55, 0x00, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x15, 0x15, 0x15,
steeven 0:e7a39129f419 8 // 0x15, 0x05, 0x05, 0x05, 0x05, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00,
steeven 0:e7a39129f419 9 // 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
steeven 0:e7a39129f419 10 // 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
steeven 0:e7a39129f419 11 // 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
steeven 0:e7a39129f419 12 // 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
steeven 0:e7a39129f419 13 // 0x00, 0x44, 0xF7, 0x44, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; //waveform
steeven 0:e7a39129f419 14 const unsigned char init_data[] = { 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, 0x55,
steeven 0:e7a39129f419 15 0x55, 0x00, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xAA, 0x55,
steeven 0:e7a39129f419 16 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x05, 0x05, 0x05, 0x05, 0x15, 0x15, 0x15,
steeven 0:e7a39129f419 17 0x15, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
steeven 0:e7a39129f419 18 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
steeven 0:e7a39129f419 19 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
steeven 0:e7a39129f419 20 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
steeven 0:e7a39129f419 21 0x00, 0x34, 0x32, 0xF1, 0x74, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, };
steeven 0:e7a39129f419 22
steeven 0:e7a39129f419 23 EpdGDE021A1::EpdGDE021A1(PinName mosi, PinName sclk, PinName cs, PinName dc,
steeven 0:e7a39129f419 24 PinName reset) :
steeven 0:e7a39129f419 25 Graphic(_buf,
steeven 0:e7a39129f419 26 GED021A1_WIDH, GED021A1_HIGHT, GED021A1_BITS), //graphic
steeven 0:e7a39129f419 27 _spi(mosi, NC, sclk), // spi
steeven 0:e7a39129f419 28 _spi_ncs(cs), //cs
steeven 0:e7a39129f419 29 _spi_ndc(dc), //d/c
steeven 0:e7a39129f419 30 _reset(reset) // reset
steeven 0:e7a39129f419 31 {
steeven 0:e7a39129f419 32 _reset = 1;
steeven 0:e7a39129f419 33 _spi_ncs = 1;
steeven 0:e7a39129f419 34 if (dc == NC) {
steeven 0:e7a39129f419 35 // _spi.format(9);
steeven 0:e7a39129f419 36 _spi3w = 1;
steeven 0:e7a39129f419 37 } else
steeven 0:e7a39129f419 38 _spi3w = 0;
steeven 0:e7a39129f419 39 // _spi.frequency(100000); //default 1M
steeven 0:e7a39129f419 40
steeven 0:e7a39129f419 41 memset(_buf, 0xff, GED021A1_BUF_SIZE);
steeven 0:e7a39129f419 42 }
steeven 0:e7a39129f419 43
steeven 0:e7a39129f419 44 void EpdGDE021A1::reset() {
steeven 0:e7a39129f419 45 _reset = 0;
steeven 0:e7a39129f419 46 wait_ms(1); //1ms
steeven 0:e7a39129f419 47 _reset = 1;
steeven 0:e7a39129f419 48 wait_ms(1); //1ms
steeven 0:e7a39129f419 49 }
steeven 0:e7a39129f419 50
steeven 0:e7a39129f419 51 void EpdGDE021A1::spi_write(int cmd, unsigned char val) {
steeven 0:e7a39129f419 52 int v;
steeven 0:e7a39129f419 53 // _spi_ncs = 0;
steeven 0:e7a39129f419 54 // DELAY_100nS(1);
steeven 0:e7a39129f419 55 // wait_ms(3);
steeven 0:e7a39129f419 56 // wait_us(100);
steeven 0:e7a39129f419 57
steeven 0:e7a39129f419 58 _spi_ncs = 0;
steeven 0:e7a39129f419 59
steeven 0:e7a39129f419 60 if (_spi3w == 1) { //SPI 3-wire mode, bit-9 = !cmd
steeven 0:e7a39129f419 61 v = ((!cmd) << 7) | (val >> 1);
steeven 0:e7a39129f419 62 _spi.write(v);
steeven 0:e7a39129f419 63 _spi.write(val << 7);
steeven 0:e7a39129f419 64 // v = ((!cmd) << 8) | (val);
steeven 0:e7a39129f419 65 // _spi.write(v);
steeven 0:e7a39129f419 66 } else {
steeven 0:e7a39129f419 67 _spi_ndc = !cmd;
steeven 0:e7a39129f419 68 _spi.write(val);
steeven 0:e7a39129f419 69 }
steeven 0:e7a39129f419 70
steeven 0:e7a39129f419 71 //DELAY_100nS(1);
steeven 0:e7a39129f419 72 // wait_ms(3);
steeven 0:e7a39129f419 73 // wait_us(100);
steeven 0:e7a39129f419 74 _spi_ncs = 1;
steeven 0:e7a39129f419 75 wait_us(1);
steeven 0:e7a39129f419 76 // wait_us(100);
steeven 0:e7a39129f419 77 // wait_ms(3);
steeven 0:e7a39129f419 78 }
steeven 0:e7a39129f419 79
steeven 0:e7a39129f419 80 void EpdGDE021A1::spi_cmd(unsigned char cmd) {
steeven 0:e7a39129f419 81 spi_write(1, cmd);
steeven 0:e7a39129f419 82 }
steeven 0:e7a39129f419 83 void EpdGDE021A1::spi_data(unsigned char val) {
steeven 0:e7a39129f419 84 spi_write(0, val);
steeven 0:e7a39129f419 85 }
steeven 0:e7a39129f419 86
steeven 0:e7a39129f419 87 void EpdGDE021A1::write_lut() {
steeven 0:e7a39129f419 88 unsigned char i;
steeven 0:e7a39129f419 89 spi_cmd(0x32); //write LUT register
steeven 0:e7a39129f419 90 for (i = 0; i < 90; i++)
steeven 0:e7a39129f419 91 spi_data(init_data[i]); //write LUT register
steeven 0:e7a39129f419 92 }
steeven 0:e7a39129f419 93 void EpdGDE021A1::init() {
steeven 0:e7a39129f419 94 //initial code
steeven 0:e7a39129f419 95 spi_cmd(0x10); //set no deep sleep mode
steeven 0:e7a39129f419 96 spi_data(0x00);
steeven 0:e7a39129f419 97
steeven 0:e7a39129f419 98 /* controller layout (x:y):
steeven 0:e7a39129f419 99 * 0:172 0:0
steeven 0:e7a39129f419 100 * 72:172 72:0
steeven 0:e7a39129f419 101 * To refresh EPD from left to right, x increase then y decrease
steeven 0:e7a39129f419 102 */
steeven 0:e7a39129f419 103 spi_cmd(0x11); //data enter mode
steeven 0:e7a39129f419 104 spi_data(0x01); //x inc then y dec
steeven 0:e7a39129f419 105
steeven 0:e7a39129f419 106 spi_cmd(0x44); //set window x
steeven 0:e7a39129f419 107 spi_data(0x00); //start at 00h;
steeven 0:e7a39129f419 108 spi_data(0x11); //end at 11h(17)->72
steeven 0:e7a39129f419 109
steeven 0:e7a39129f419 110 spi_cmd(0x45); //set window y
steeven 0:e7a39129f419 111 spi_data(0xAB); //start at ABh(171)->172
steeven 0:e7a39129f419 112 spi_data(0x00); //end at 00h
steeven 0:e7a39129f419 113
steeven 0:e7a39129f419 114 spi_cmd(0x4E); //set RAM x address count to 0;
steeven 0:e7a39129f419 115 spi_data(0x00);
steeven 0:e7a39129f419 116 spi_cmd(0x4F); //set RAM y address count to 0;
steeven 0:e7a39129f419 117 spi_data(0xAB);
steeven 0:e7a39129f419 118
steeven 0:e7a39129f419 119 spi_cmd(0x21); //bypass RAM data
steeven 0:e7a39129f419 120 spi_data(0x81); //only content
steeven 0:e7a39129f419 121
steeven 0:e7a39129f419 122 spi_cmd(0xF0); //booster feedback used
steeven 0:e7a39129f419 123 spi_data(0x1F);
steeven 0:e7a39129f419 124 spi_cmd(0x2C); //vcom voltage
steeven 0:e7a39129f419 125 spi_data(0xA0);
steeven 0:e7a39129f419 126 spi_cmd(0x3C); //board voltage
steeven 0:e7a39129f419 127 spi_data(0x63);
steeven 0:e7a39129f419 128 spi_cmd(0x22); //display update sequence option ,in page 33
steeven 0:e7a39129f419 129 spi_data(0xc4); //0xc4 //enable sequence: clk -> CP -> LUT -> pattern display
steeven 0:e7a39129f419 130 write_lut();
steeven 0:e7a39129f419 131 }
steeven 0:e7a39129f419 132
steeven 0:e7a39129f419 133 void EpdGDE021A1::wait_busy() {
steeven 0:e7a39129f419 134 // while (1) {
steeven 0:e7a39129f419 135 // for (unsigned int i = 5; i > 0; i--)
steeven 0:e7a39129f419 136 // ;
steeven 0:e7a39129f419 137 // if (digitalRead(BUSY_GDE021A1) == 0)
steeven 0:e7a39129f419 138 // break;
steeven 0:e7a39129f419 139 // }
steeven 0:e7a39129f419 140 wait(2);
steeven 0:e7a39129f419 141 }
steeven 0:e7a39129f419 142
steeven 0:e7a39129f419 143 void EpdGDE021A1::sleep() {
steeven 0:e7a39129f419 144 spi_cmd(0x22); //display updata sequence option
steeven 0:e7a39129f419 145 spi_data(0x03);
steeven 0:e7a39129f419 146 spi_cmd(0x20);
steeven 0:e7a39129f419 147 }
steeven 0:e7a39129f419 148
steeven 0:e7a39129f419 149 void EpdGDE021A1::draw(unsigned char *data) {
steeven 0:e7a39129f419 150 int i;
steeven 0:e7a39129f419 151 spi_cmd(0x24);
steeven 0:e7a39129f419 152 for (i = 0; i < GED021A1_BUF_SIZE; i++) {
steeven 0:e7a39129f419 153 spi_data(data[i]);
steeven 0:e7a39129f419 154 }
steeven 0:e7a39129f419 155 spi_cmd(0x20);
steeven 0:e7a39129f419 156 wait_ms(1);
steeven 0:e7a39129f419 157 wait_busy();
steeven 0:e7a39129f419 158 wait(1.5);
steeven 0:e7a39129f419 159 sleep();
steeven 0:e7a39129f419 160 }
steeven 0:e7a39129f419 161
steeven 0:e7a39129f419 162 void EpdGDE021A1::setup() {
steeven 0:e7a39129f419 163 reset();
steeven 0:e7a39129f419 164 init();
steeven 0:e7a39129f419 165 }
steeven 0:e7a39129f419 166
steeven 0:e7a39129f419 167 void EpdGDE021A1::update() {
steeven 0:e7a39129f419 168 setup();
steeven 0:e7a39129f419 169 draw(_buf);
steeven 0:e7a39129f419 170 }