Instantly share code, notes, and snippets.
Last active
June 26, 2023 02:57
-
Star
9
(9)
You must be signed in to star a gist -
Fork
0
(0)
You must be signed in to fork a gist
-
Save urish/e98390e30457587cb89f4e6f50c2049d to your computer and use it in GitHub Desktop.
Driver for Waveshare 2.9inch e-Paper Module
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Copyright (C) 2017, Uri Shaked | |
// Loosely based on code samples provided by waveshare | |
// License: MIT | |
const DIN_PIN = 11; | |
const CLK_PIN = 12; | |
const CS_PIN = 13; | |
const DC_PIN = 14; | |
const RST_PIN = 15; | |
const BUSY_PIN = 16; | |
const EPD_WIDTH = 128; | |
const EPD_HEIGHT = 296; | |
const DRIVER_OUTPUT_CONTROL = 0x01; | |
const BOOSTER_SOFT_START_CONTROL = 0x0C; | |
const GATE_SCAN_START_POSITION = 0x0F; | |
const DEEP_SLEEP_MODE = 0x10; | |
const DATA_ENTRY_MODE_SETTING = 0x11; | |
const SW_RESET = 0x12; | |
const TEMPERATURE_SENSOR_CONTROL = 0x1A; | |
const MASTER_ACTIVATION = 0x20; | |
const DISPLAY_UPDATE_CONTROL_1 = 0x21; | |
const DISPLAY_UPDATE_CONTROL_2 = 0x22; | |
const WRITE_RAM = 0x24; | |
const WRITE_VCOM_REGISTER = 0x2C; | |
const WRITE_LUT_REGISTER = 0x32; | |
const SET_DUMMY_LINE_PERIOD = 0x3A; | |
const SET_GATE_TIME = 0x3B; | |
const BORDER_WAVEFORM_CONTROL = 0x3C; | |
const SET_RAM_X_ADDRESS_START_END_POSITION = 0x44; | |
const SET_RAM_Y_ADDRESS_START_END_POSITION = 0x45; | |
const SET_RAM_X_ADDRESS_COUNTER = 0x4E; | |
const SET_RAM_Y_ADDRESS_COUNTER = 0x4F; | |
const TERMINATE_FRAME_READ_WRITE = 0xFF; | |
const LUT_FULL_UPDATE = [ | |
0x02, 0x02, 0x01, 0x11, 0x12, 0x12, 0x22, 0x22, | |
0x66, 0x69, 0x69, 0x59, 0x58, 0x99, 0x99, 0x88, | |
0x00, 0x00, 0x00, 0x00, 0xF8, 0xB4, 0x13, 0x51, | |
0x35, 0x51, 0x51, 0x19, 0x01, 0x00 | |
]; | |
const LUT_PARTIAL_UPDATE = [ | |
0x10, 0x18, 0x18, 0x08, 0x18, 0x18, 0x08, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x13, 0x14, 0x44, 0x12, | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00 | |
]; | |
function start() { | |
SPI1.setup({mosi: DIN_PIN , sck: CLK_PIN, baud: 2000000}); | |
pinMode(BUSY_PIN, 'input'); | |
} | |
function sendCommand(cmd) { | |
digitalWrite(DC_PIN, LOW); | |
SPI1.send(cmd, CS_PIN); | |
} | |
function sendData(data) { | |
digitalWrite(DC_PIN, HIGH); | |
SPI1.send(data, CS_PIN); | |
} | |
function resetModule() { | |
return new Promise(resolve => { | |
digitalWrite(RST_PIN, LOW); | |
setTimeout(() => { | |
digitalWrite(RST_PIN, HIGH); | |
setTimeout(resolve, 200); | |
}, 200); | |
}); | |
} | |
function sendLut(lut) { | |
sendCommand(WRITE_LUT_REGISTER); | |
for (let i = 0; i < lut.length; i++) { | |
sendData(lut[i]); | |
} | |
} | |
function initModule(lut) { | |
return resetModule().then(() => { | |
sendCommand(DRIVER_OUTPUT_CONTROL); | |
sendData((EPD_HEIGHT - 1) & 0xFF); | |
sendData(((EPD_HEIGHT - 1) >> 8) & 0xFF); | |
sendData(0x00); // GD = 0 SM = 0 TB = 0 | |
sendCommand(BOOSTER_SOFT_START_CONTROL); | |
sendData(0xD7); | |
sendData(0xD6); | |
sendData(0x9D); | |
sendCommand(WRITE_VCOM_REGISTER); | |
sendData(0xA8); // VCOM 7C | |
sendCommand(SET_DUMMY_LINE_PERIOD); | |
sendData(0x1A); // 4 dummy lines per gate | |
sendCommand(SET_GATE_TIME); | |
sendData(0x08); // 2us per line | |
sendCommand(DATA_ENTRY_MODE_SETTING); | |
sendData(0x03); // X increment Y increment | |
sendLut(lut); | |
}); | |
} | |
function waitReady() { | |
while(digitalRead(BUSY_PIN)); | |
} | |
function displayFrame() { | |
sendCommand(DISPLAY_UPDATE_CONTROL_2); | |
sendData(0xC4); | |
sendCommand(MASTER_ACTIVATION); | |
sendCommand(TERMINATE_FRAME_READ_WRITE); | |
waitReady(); | |
} | |
function setMemoryArea(x, y, xEnd, yEnd) { | |
sendCommand(SET_RAM_X_ADDRESS_START_END_POSITION); | |
sendData((x >> 3) & 0xFF); | |
sendData((xEnd >> 3) & 0xFF); | |
sendCommand(SET_RAM_Y_ADDRESS_START_END_POSITION); | |
sendData(y & 0xFF); | |
sendData((y >> 8) & 0xFF); | |
sendData(yEnd & 0xFF); | |
sendData((yEnd >> 8) & 0xFF); | |
} | |
function setMemoryPointer(x, y) { | |
sendCommand(SET_RAM_X_ADDRESS_COUNTER); | |
sendData((x >> 3) & 0xFF); | |
sendCommand(SET_RAM_Y_ADDRESS_COUNTER); | |
sendData(y & 0xFF); | |
sendData((y >> 8) & 0xFF); | |
} | |
function fillMemory(value) { | |
value = value || 0; | |
setMemoryArea(0, 0, EPD_WIDTH - 1, EPD_HEIGHT - 1); | |
setMemoryPointer(0, 0); | |
sendCommand(WRITE_RAM); | |
let buf = new Uint8Array(EPD_WIDTH / 8 * EPD_HEIGHT); | |
buf.fill(value, 0, buf.length); | |
sendData(buf); | |
} | |
function cls() { | |
fillMemory(0); | |
displayFrame(); | |
fillMemory(0xff); | |
displayFrame(); | |
} | |
function clsw() { | |
fillMemory(0xff); | |
displayFrame(); | |
fillMemory(0xff); | |
displayFrame(); | |
} | |
function writeChar(buf, w, h, offs, x) { | |
setMemoryArea(0, offs|0, (w+x-8)||16, h||16); | |
setMemoryPointer(0, offs|0); | |
sendCommand(WRITE_RAM); | |
sendData(buf); | |
} | |
function expand(n) { | |
let shift = (n & 0x1) | ((n & 0x2) << 1) | ((n & 0x4) << 2) | ((n & 0x8) << 3); | |
return shift | (shift << 1); | |
} | |
function drawRow2(buf, ofs, w) { | |
for (let x = 0; x < w / 8; x++) { | |
let b1 = buf[ofs+x] & 0xf; | |
let b2 = buf[ofs+x] >> 4; | |
SPI1.send([expand(b2),expand(b1)], CS_PIN); | |
} | |
} | |
function writeChar2(buf, w, h, offs, x) { | |
setMemoryArea(0, offs|0, (w*2+x-8)||16, h*2||16); | |
setMemoryPointer(0, offs|0); | |
sendCommand(WRITE_RAM); | |
digitalWrite(DC_PIN, HIGH); | |
for (let y = 0; y < h; y++) { | |
drawRow2(buf, y*w/8, w); | |
drawRow2(buf, y*w/8, w); | |
} | |
} | |
function drawRow3(buf, y, ofs, w, xStart) { | |
if (y===121) { | |
setMemoryPointer(xStart, y); | |
sendCommand(WRITE_RAM); | |
digitalWrite(DC_PIN, HIGH); | |
} | |
for (let x = 0; x < w / 8; x++) { | |
let bin = buf[ofs+x].toString(2); | |
let triple = ''; | |
for (let i = 0; i < bin.length; i++) { | |
triple += bin[i] + bin[i] + bin[i]; | |
} | |
triple = parseInt(triple, 2); | |
SPI1.send([triple >> 16, (triple >> 8) & 0xff, triple & 0xff], CS_PIN); | |
} | |
} | |
function writeChar3(buf, w, h, x, y) { | |
setMemoryArea(x||0, y||0, (w*3+x-8)||16, h*3||16); | |
const yStart = y||0; | |
setMemoryPointer(x||0, yStart); | |
sendCommand(WRITE_RAM); | |
digitalWrite(DC_PIN, HIGH); | |
for (let y = 0; y < h; y++) { | |
drawRow3(buf, yStart+y*3, y*w/8, w, x || 0); | |
drawRow3(buf, yStart+y*3+1, y*w/8, w, x || 0); | |
drawRow3(buf, yStart+y*3+2, y*w/8, w, x || 0); | |
} | |
} | |
function writeComp(buf, w, h, offs) { | |
setMemoryArea(0, offs||0, w||16, h||16); | |
setMemoryPointer(0, offs||0); | |
sendCommand(WRITE_RAM); | |
for (let i = 0; i < buf.length; i += 2) { | |
for (let c = 0; c < buf[i+1]; c++) { | |
sendData(buf[i]); | |
} | |
} | |
displayFrame(); | |
} | |
// 24x19 | |
const zero = new Uint8Array([255,0,127,255,0,127,248,0,15,248,0,15,248,0,15,199,255,129,199,255,129,199,255,129,199,255,241,199,255,241,192,255,241,192,255,241,192,0,1,248,0,15,248,0,15,255,0,127,255,0,127,255,0,127,255,255,255]); | |
const one = new Uint8Array([255,255,255,255,255,255,255,255,241,255,255,241,255,255,241,255,255,241,255,255,241,192,0,1,192,0,1,192,0,1,192,0,1,192,0,1,192,0,1,248,255,241,248,255,241,255,255,241,255,255,241,255,255,241,255,255,255]); | |
const two = new Uint8Array([255,255,255,248,31,241,248,31,241,248,31,241,192,3,241,192,3,241,192,0,113,199,0,113,199,0,113,199,224,113,199,224,113,199,224,1,199,224,1,199,224,1,192,252,1,192,252,1,192,252,1,248,255,129,248,255,129]); | |
const three = new Uint8Array([255,255,255,199,252,15,199,252,15,199,252,15,192,224,1,192,224,1,192,0,1,192,3,241,192,3,241,199,3,241,199,3,241,199,3,241,199,227,241,199,227,241,199,255,129,199,255,129,199,255,129,255,255,143,255,255,143]); | |
const four = new Uint8Array([255,255,255,255,252,127,255,252,127,255,252,127,192,0,1,192,0,1,192,0,1,192,0,1,192,0,1,192,252,127,192,252,127,192,28,127,248,28,127,248,28,127,255,0,127,255,0,127,255,0,127,255,224,127,255,224,127]); | |
const five = new Uint8Array([255,255,255,255,224,15,255,224,15,255,224,15,199,0,1,199,0,1,199,0,1,199,31,241,199,31,241,199,31,241,199,31,241,199,31,241,199,31,241,199,31,241,192,31,129,192,31,129,192,31,129,192,31,143,192,31,143]); | |
const six = new Uint8Array([255,255,255,255,252,15,255,252,15,255,252,15,199,224,1,199,224,1,199,224,1,199,227,241,199,227,241,199,227,241,199,227,241,192,227,241,192,227,241,192,227,241,248,0,1,248,0,1,248,0,1,255,0,15,255,0,15]); | |
const seven = new Uint8Array([255,255,255,192,255,255,192,255,255,192,255,255,192,31,255,192,31,255,192,3,255,199,3,255,199,3,255,199,224,1,199,224,1,199,224,1,199,252,1,199,252,1,192,255,255,192,255,255,192,255,255,192,255,255,192,255,255]); | |
const eight = new Uint8Array([255,255,255,255,252,15,255,252,15,255,252,15,248,28,1,248,28,1,192,0,1,199,224,113,199,224,113,199,224,113,199,224,113,199,0,113,199,3,241,199,3,241,192,3,241,192,3,241,192,0,1,248,28,15,248,28,15]); | |
const nine = new Uint8Array([255,255,255,248,0,127,248,0,127,248,0,127,192,0,15,192,0,15,192,0,1,199,227,129,199,227,129,199,227,241,199,227,241,199,227,241,199,227,241,199,227,241,192,3,241,192,3,241,192,3,241,248,31,255,248,31,255]); | |
// 40x35 | |
const trex = new Uint8Array([255,252,0,255,255,255,255,128,255,255,255,255,192,63,255,255,255,224,63,255,255,255,224,15,255,255,255,248,3,255,255,255,248,3,255,255,255,248,1,255,255,255,248,1,255,255,255,224,0,3,255,255,224,0,27,255,255,192,0,27,255,255,192,0,127,255,255,0,0,127,255,255,0,1,255,255,255,0,1,255,255,252,0,0,127,255,252,0,0,127,192,0,0,0,3,192,0,0,3,251,128,0,0,3,251,152,0,0,15,255,152,0,0,15,255,128,0,0,127,255,128,0,0,127,255,128,3,223,255,255,128,51,223,255,255,128,51,199,255,255,128,51,255,255,255,128,51,255,255,255,128,51,255,255,255,128,51,255,255,255,128,63,255,255,255,192,63,255,255,255,192,63,255,255,255]); | |
start(); | |
initModule(LUT_PARTIAL_UPDATE).then(() => { | |
console.log('module ready!'); | |
cls(); | |
displayFrame(); | |
writeChar3(trex, 40, 35, 10, 120); | |
displayFrame(); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment