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

EpdGDE021A1.cpp

Committer:
steeven
Date:
2015-04-15
Revision:
0:e7a39129f419

File content as of revision 0:e7a39129f419:

#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);
}