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

Revision:
0:e7a39129f419
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/EpdGDE021A1.cpp	Wed Apr 15 11:16:20 2015 +0000
@@ -0,0 +1,170 @@
+#include "EpdGDE021A1.h"
+#include "GraphicUtil/Graphic.h"
+
+using namespace mbed;
+
+//const unsigned char init_data[] = { 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, 0x55,
+//      0x55, 0x00, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x15, 0x15, 0x15,
+//      0x15, 0x05, 0x05, 0x05, 0x05, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00,
+//      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+//      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+//      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+//      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+//      0x00, 0x44, 0xF7, 0x44, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; //waveform
+const unsigned char init_data[] = { 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, 0x55,
+        0x55, 0x00, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xAA, 0x55,
+        0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x05, 0x05, 0x05, 0x05, 0x15, 0x15, 0x15,
+        0x15, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x34, 0x32, 0xF1, 0x74, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, };
+
+EpdGDE021A1::EpdGDE021A1(PinName mosi, PinName sclk, PinName cs, PinName dc,
+        PinName reset) :
+        Graphic(_buf,
+        GED021A1_WIDH, GED021A1_HIGHT, GED021A1_BITS), //graphic
+        _spi(mosi, NC, sclk), // spi
+        _spi_ncs(cs), //cs
+        _spi_ndc(dc), //d/c
+        _reset(reset) // reset
+{
+    _reset = 1;
+    _spi_ncs = 1;
+    if (dc == NC) {
+//          _spi.format(9);
+        _spi3w = 1;
+    } else
+        _spi3w = 0;
+//      _spi.frequency(100000); //default 1M
+
+    memset(_buf, 0xff, GED021A1_BUF_SIZE);
+}
+
+void EpdGDE021A1::reset() {
+    _reset = 0;
+    wait_ms(1); //1ms
+    _reset = 1;
+    wait_ms(1); //1ms
+}
+
+void EpdGDE021A1::spi_write(int cmd, unsigned char val) {
+    int v;
+//  _spi_ncs = 0;
+//  DELAY_100nS(1);
+//  wait_ms(3);
+//  wait_us(100);
+
+    _spi_ncs = 0;
+
+    if (_spi3w == 1) { //SPI 3-wire mode, bit-9 = !cmd
+        v = ((!cmd) << 7) | (val >> 1);
+        _spi.write(v);
+        _spi.write(val << 7);
+//      v = ((!cmd) << 8) | (val);
+//      _spi.write(v);
+    } else {
+        _spi_ndc = !cmd;
+        _spi.write(val);
+    }
+
+    //DELAY_100nS(1);
+//  wait_ms(3);
+//  wait_us(100);
+    _spi_ncs = 1;
+    wait_us(1);
+//  wait_us(100);
+//  wait_ms(3);
+}
+
+void EpdGDE021A1::spi_cmd(unsigned char cmd) {
+    spi_write(1, cmd);
+}
+void EpdGDE021A1::spi_data(unsigned char val) {
+    spi_write(0, val);
+}
+
+void EpdGDE021A1::write_lut() {
+    unsigned char i;
+    spi_cmd(0x32); //write LUT register
+    for (i = 0; i < 90; i++)
+        spi_data(init_data[i]); //write LUT register
+}
+void EpdGDE021A1::init() {
+    //initial code
+    spi_cmd(0x10); //set no deep sleep mode
+    spi_data(0x00);
+
+    /* controller layout (x:y):
+     *  0:172  0:0
+     *  72:172 72:0
+     * To refresh EPD from left to right, x increase then y decrease
+     */
+    spi_cmd(0x11); //data enter mode
+    spi_data(0x01); //x inc then y dec
+
+    spi_cmd(0x44); //set window x
+    spi_data(0x00); //start at 00h;
+    spi_data(0x11); //end at 11h(17)->72
+
+    spi_cmd(0x45); //set window y
+    spi_data(0xAB); //start at ABh(171)->172
+    spi_data(0x00); //end at 00h
+
+    spi_cmd(0x4E); //set RAM x address count to 0;
+    spi_data(0x00);
+    spi_cmd(0x4F); //set RAM y address count to 0;
+    spi_data(0xAB);
+
+    spi_cmd(0x21); //bypass RAM data
+    spi_data(0x81); //only content
+
+    spi_cmd(0xF0); //booster feedback used
+    spi_data(0x1F);
+    spi_cmd(0x2C); //vcom voltage
+    spi_data(0xA0);
+    spi_cmd(0x3C); //board voltage
+    spi_data(0x63);
+    spi_cmd(0x22); //display update sequence option ,in page 33
+    spi_data(0xc4); //0xc4 //enable sequence: clk -> CP -> LUT ->  pattern display
+    write_lut();
+}
+
+void EpdGDE021A1::wait_busy() {
+//      while (1) {
+//          for (unsigned int i = 5; i > 0; i--)
+//              ;
+//          if (digitalRead(BUSY_GDE021A1) == 0)
+//              break;
+//      }
+    wait(2);
+}
+
+void EpdGDE021A1::sleep() {
+    spi_cmd(0x22); //display updata sequence option
+    spi_data(0x03);
+    spi_cmd(0x20);
+}
+
+void EpdGDE021A1::draw(unsigned char *data) {
+    int i;
+    spi_cmd(0x24);
+    for (i = 0; i < GED021A1_BUF_SIZE; i++) {
+        spi_data(data[i]);
+    }
+    spi_cmd(0x20);
+    wait_ms(1);
+    wait_busy();
+    wait(1.5);
+    sleep();
+}
+
+void EpdGDE021A1::setup() {
+    reset();
+    init();
+}
+
+void EpdGDE021A1::update() {
+    setup();
+    draw(_buf);
+}