Merge pull request #41 from adafruit/acephacking
Add ACEP (7-color EPD) support
This commit is contained in:
commit
b51d8c3783
9 changed files with 476 additions and 45 deletions
8
.github/workflows/githubci.yml
vendored
8
.github/workflows/githubci.yml
vendored
|
|
@ -19,8 +19,14 @@ jobs:
|
|||
- name: pre-install
|
||||
run: bash ci/actions_install.sh
|
||||
|
||||
# manually install SDFat
|
||||
- name: extra libraries
|
||||
run: |
|
||||
git clone --quiet https://github.com/adafruit/SdFat.git /home/runner/Arduino/libraries/SdFat
|
||||
git clone --quiet https://github.com/adafruit/Adafruit_SPIFlash.git /home/runner/Arduino/libraries/Adafruit_SPIFlash
|
||||
|
||||
- name: test platforms
|
||||
run: python3 ci/build_platform.py main_platforms cpb cpx
|
||||
run: python3 ci/build_platform.py main_platforms metro_m4_tinyusb cpb cpx
|
||||
|
||||
- name: clang
|
||||
run: python3 ci/run-clang-format.py -e "ci/*" -e "bin/*" -r .
|
||||
|
|
|
|||
0
examples/acep_7ColorTest/.metro_m4_tinyusb.test.only
Normal file
0
examples/acep_7ColorTest/.metro_m4_tinyusb.test.only
Normal file
263
examples/acep_7ColorTest/acep_7ColorTest.ino
Normal file
263
examples/acep_7ColorTest/acep_7ColorTest.ino
Normal file
|
|
@ -0,0 +1,263 @@
|
|||
/***************************************************
|
||||
Adafruit invests time and resources providing this open source code,
|
||||
please support Adafruit and open-source hardware by purchasing
|
||||
products from Adafruit!
|
||||
|
||||
Written by Limor Fried/Ladyada for Adafruit Industries.
|
||||
MIT license, all text above must be included in any redistribution
|
||||
****************************************************/
|
||||
|
||||
|
||||
#include <SPI.h>
|
||||
#include <SdFat.h>
|
||||
#include <Adafruit_SPIFlash.h>
|
||||
#include "Adafruit_EPD.h"
|
||||
|
||||
|
||||
#define EPD_CS 9
|
||||
#define EPD_DC 10
|
||||
#define SRAM_CS -1 // Use the build in memory, we need 133KB!
|
||||
#define EPD_RESET 6 // can set to -1 and share with microcontroller Reset!
|
||||
#define EPD_BUSY 5 // can set to -1 to not use a pin (will wait a fixed delay)
|
||||
|
||||
// Uncomment the following line if you are using ACeP 7 color 5.65"
|
||||
Adafruit_ACEP display(600, 448, EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY);
|
||||
|
||||
Adafruit_FlashTransport_QSPI flashTransport;
|
||||
Adafruit_SPIFlash flash(&flashTransport);
|
||||
FatFileSystem fatfs;
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
while (!Serial) { delay(10); }
|
||||
|
||||
Serial.println("Adafruit ACeP EPD test");
|
||||
|
||||
if (!flash.begin()) {
|
||||
Serial.println("Error, failed to initialize flash chip!");
|
||||
while(1) delay(1);
|
||||
}
|
||||
Serial.print("Flash chip JEDEC ID: 0x"); Serial.println(flash.getJEDECID(), HEX);
|
||||
// First call begin to mount the filesystem. Check that it returns true
|
||||
// to make sure the filesystem was mounted.
|
||||
if (!fatfs.begin(&flash)) {
|
||||
Serial.println("Error, failed to mount newly formatted filesystem!");
|
||||
Serial.println("Was the flash chip formatted with the fatfs_format example?");
|
||||
while(1) delay(1);
|
||||
}
|
||||
Serial.println("Mounted filesystem!");
|
||||
File root = fatfs.open("/");
|
||||
printDirectory(root, 0);
|
||||
|
||||
display.begin();
|
||||
display.setRotation(0);
|
||||
display.clearBuffer();
|
||||
// draw 7 color bars
|
||||
for (uint8_t color=ACEP_COLOR_BLACK; color<=ACEP_COLOR_ORANGE; color++) {
|
||||
display.fillRect(display.width()*color/7, 0, display.width()/7, display.height(), color);
|
||||
}
|
||||
display.display();
|
||||
}
|
||||
|
||||
void loop() {
|
||||
bmpDraw("adafruit_characters.bmp", 0, 0);
|
||||
bmpDraw("adabot.bmp", 0, 0);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// This function opens a Windows Bitmap (BMP) file and
|
||||
// displays it at the given coordinates. It's sped up
|
||||
// by reading many pixels worth of data at a time
|
||||
// (rather than pixel by pixel). Increasing the buffer
|
||||
// size takes more of the Arduino's precious RAM but
|
||||
// makes loading a little faster. 20 pixels seems a
|
||||
// good balance.
|
||||
|
||||
#define BUFFPIXEL 20
|
||||
|
||||
bool bmpDraw(char *filename, int16_t x, int16_t y) {
|
||||
File bmpFile;
|
||||
int bmpWidth, bmpHeight; // W+H in pixels
|
||||
uint8_t bmpDepth; // Bit depth (currently must be 24)
|
||||
uint32_t bmpImageoffset; // Start of image data in file
|
||||
uint32_t rowSize; // Not always = bmpWidth; may have padding
|
||||
uint8_t sdbuffer[3*BUFFPIXEL]; // pixel buffer (R+G+B per pixel)
|
||||
uint8_t buffidx = sizeof(sdbuffer); // Current position in sdbuffer
|
||||
boolean goodBmp = false; // Set to true on valid header parse
|
||||
boolean flip = true; // BMP is stored bottom-to-top
|
||||
int w, h, row, col, x2, y2, bx1, by1;
|
||||
uint8_t r, g, b;
|
||||
uint32_t pos = 0, startTime = millis();
|
||||
|
||||
if((x >= display.width()) || (y >= display.height())) return false;
|
||||
|
||||
Serial.println();
|
||||
Serial.print(F("Loading image '"));
|
||||
Serial.print(filename);
|
||||
Serial.println('\'');
|
||||
|
||||
// Open requested file on SD card
|
||||
if ((bmpFile = fatfs.open(filename, FILE_READ)) == NULL) {
|
||||
Serial.print(F("File not found"));
|
||||
return false;
|
||||
}
|
||||
|
||||
// Parse BMP header
|
||||
if (read16(bmpFile) == 0x4D42) { // BMP signature
|
||||
Serial.print(F("File size: ")); Serial.println(read32(bmpFile));
|
||||
(void)read32(bmpFile); // Read & ignore creator bytes
|
||||
bmpImageoffset = read32(bmpFile); // Start of image data
|
||||
Serial.print(F("Image Offset: ")); Serial.println(bmpImageoffset, DEC);
|
||||
// Read DIB header
|
||||
Serial.print(F("Header size: ")); Serial.println(read32(bmpFile));
|
||||
bmpWidth = read32(bmpFile);
|
||||
bmpHeight = read32(bmpFile);
|
||||
if(read16(bmpFile) == 1) { // # planes -- must be '1'
|
||||
bmpDepth = read16(bmpFile); // bits per pixel
|
||||
Serial.print(F("Bit Depth: ")); Serial.println(bmpDepth);
|
||||
if((bmpDepth == 24) && (read32(bmpFile) == 0)) { // 0 = uncompressed
|
||||
|
||||
goodBmp = true; // Supported BMP format -- proceed!
|
||||
Serial.print(F("Image size: "));
|
||||
Serial.print(bmpWidth);
|
||||
Serial.print('x');
|
||||
Serial.println(bmpHeight);
|
||||
|
||||
// BMP rows are padded (if needed) to 4-byte boundary
|
||||
rowSize = (bmpWidth * 3 + 3) & ~3;
|
||||
|
||||
// If bmpHeight is negative, image is in top-down order.
|
||||
// This is not canon but has been observed in the wild.
|
||||
if(bmpHeight < 0) {
|
||||
bmpHeight = -bmpHeight;
|
||||
flip = false;
|
||||
}
|
||||
|
||||
// Crop area to be loaded
|
||||
x2 = x + bmpWidth - 1; // Lower-right corner
|
||||
y2 = y + bmpHeight - 1;
|
||||
if((x2 >= 0) && (y2 >= 0)) { // On screen?
|
||||
w = bmpWidth; // Width/height of section to load/display
|
||||
h = bmpHeight;
|
||||
bx1 = by1 = 0; // UL coordinate in BMP file
|
||||
|
||||
for (row=0; row<h; row++) { // For each scanline...
|
||||
|
||||
// Seek to start of scan line. It might seem labor-
|
||||
// intensive to be doing this on every line, but this
|
||||
// method covers a lot of gritty details like cropping
|
||||
// and scanline padding. Also, the seek only takes
|
||||
// place if the file position actually needs to change
|
||||
// (avoids a lot of cluster math in SD library).
|
||||
if(flip) // Bitmap is stored bottom-to-top order (normal BMP)
|
||||
pos = bmpImageoffset + (bmpHeight - 1 - (row + by1)) * rowSize;
|
||||
else // Bitmap is stored top-to-bottom
|
||||
pos = bmpImageoffset + (row + by1) * rowSize;
|
||||
pos += bx1 * 3; // Factor in starting column (bx1)
|
||||
if(bmpFile.position() != pos) { // Need seek?
|
||||
bmpFile.seek(pos);
|
||||
buffidx = sizeof(sdbuffer); // Force buffer reload
|
||||
}
|
||||
for (col=0; col<w; col++) { // For each pixel...
|
||||
// Time to read more pixel data?
|
||||
if (buffidx >= sizeof(sdbuffer)) { // Indeed
|
||||
bmpFile.read(sdbuffer, sizeof(sdbuffer));
|
||||
buffidx = 0; // Set index to beginning
|
||||
}
|
||||
// Convert pixel from BMP to EPD format, push to display
|
||||
b = sdbuffer[buffidx++];
|
||||
g = sdbuffer[buffidx++];
|
||||
r = sdbuffer[buffidx++];
|
||||
uint32_t color = r;
|
||||
color <<= 8;
|
||||
color |= g;
|
||||
color <<= 8;
|
||||
color |= b;
|
||||
|
||||
uint8_t c;
|
||||
switch (color) {
|
||||
case 0x000000: c = ACEP_COLOR_BLACK; break;
|
||||
case 0xFFFFFF: c = ACEP_COLOR_WHITE; break;
|
||||
case 0x00FF00: c = ACEP_COLOR_GREEN; break;
|
||||
case 0x0000FF: c = ACEP_COLOR_BLUE; break;
|
||||
case 0xFF0000: c = ACEP_COLOR_RED; break;
|
||||
case 0xFFFF00: c = ACEP_COLOR_YELLOW; break;
|
||||
case 0xFF8000: c = ACEP_COLOR_ORANGE; break;
|
||||
default: {
|
||||
Serial.print("Unknown color 0x");
|
||||
Serial.println(color, HEX);
|
||||
c = ACEP_COLOR_WHITE;
|
||||
}
|
||||
}
|
||||
display.writePixel(col, row, c);
|
||||
} // end pixel
|
||||
} // end scanline
|
||||
} // end onscreen
|
||||
display.display();
|
||||
Serial.print(F("Loaded in "));
|
||||
Serial.print(millis() - startTime);
|
||||
Serial.println(" ms");
|
||||
} // end goodBmp
|
||||
}
|
||||
}
|
||||
|
||||
bmpFile.close();
|
||||
if(!goodBmp) {
|
||||
Serial.println(F("BMP format not recognized."));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// These read 16- and 32-bit types from the SD card file.
|
||||
// BMP data is stored little-endian, Arduino is little-endian too.
|
||||
// May need to reverse subscript order if porting elsewhere.
|
||||
|
||||
uint16_t read16(File &f) {
|
||||
uint16_t result;
|
||||
((uint8_t *)&result)[0] = f.read(); // LSB
|
||||
((uint8_t *)&result)[1] = f.read(); // MSB
|
||||
return result;
|
||||
}
|
||||
|
||||
uint32_t read32(File &f) {
|
||||
uint32_t result;
|
||||
((uint8_t *)&result)[0] = f.read(); // LSB
|
||||
((uint8_t *)&result)[1] = f.read();
|
||||
((uint8_t *)&result)[2] = f.read();
|
||||
((uint8_t *)&result)[3] = f.read(); // MSB
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
void printDirectory(File dir, int numTabs) {
|
||||
char filename[80];
|
||||
|
||||
while (true) {
|
||||
File entry = dir.openNextFile();
|
||||
if (! entry) {
|
||||
// no more files
|
||||
break;
|
||||
}
|
||||
for (uint8_t i = 0; i < numTabs; i++) {
|
||||
Serial.print('\t');
|
||||
}
|
||||
entry.getName(filename, 80);
|
||||
Serial.print(filename);
|
||||
if (entry.isDirectory()) {
|
||||
Serial.println("/");
|
||||
printDirectory(entry, numTabs + 1);
|
||||
} else {
|
||||
// files have sizes, directories do not
|
||||
Serial.print("\t\t");
|
||||
Serial.println(entry.size(), DEC);
|
||||
}
|
||||
entry.close();
|
||||
}
|
||||
}
|
||||
BIN
examples/acep_7ColorTest/adabot.bmp
Normal file
BIN
examples/acep_7ColorTest/adabot.bmp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 788 KiB |
BIN
examples/acep_7ColorTest/adafruit_characters.bmp
Normal file
BIN
examples/acep_7ColorTest/adafruit_characters.bmp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 788 KiB |
|
|
@ -290,7 +290,7 @@ void Adafruit_EPD::writeRAMFramebufferToEPD(uint8_t *framebuffer,
|
|||
dcHigh();
|
||||
// Serial.printf("Writing from RAM location %04x: \n", &framebuffer);
|
||||
|
||||
for (uint16_t i = 0; i < framebuffer_size; i++) {
|
||||
for (uint32_t i = 0; i < framebuffer_size; i++) {
|
||||
uint8_t d = framebuffer[i];
|
||||
if (invertdata)
|
||||
d = ~d;
|
||||
|
|
|
|||
|
|
@ -155,8 +155,8 @@ protected:
|
|||
|
||||
uint8_t layer_colors[EPD_NUM_COLORS];
|
||||
|
||||
uint16_t buffer1_size; ///< size of the primary buffer
|
||||
uint16_t buffer2_size; ///< size of the secondary buffer
|
||||
uint32_t buffer1_size; ///< size of the primary buffer
|
||||
uint32_t buffer2_size; ///< size of the secondary buffer
|
||||
uint8_t *buffer1; ///< the pointer to the primary buffer if using on-chip ram
|
||||
uint8_t
|
||||
*buffer2; ///< the pointer to the secondary buffer if using on-chip ram
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
// clang-format off
|
||||
|
||||
const uint8_t acep_default_init_code[] {
|
||||
0xFF, 10, // wait a lil bit
|
||||
ACEP_PANEL_SETTING, 2, 0xEF, 0x08, // LUT from OTP
|
||||
ACEP_POWER_SETTING, 4, 0x37, 0x00, 0x23, 0x23, // 0x05&0x05?
|
||||
ACEP_POWER_OFF_SEQUENCE, 1, 0x00,
|
||||
|
|
@ -16,6 +17,8 @@ const uint8_t acep_default_init_code[] {
|
|||
ACEP_TCON, 1, 0x22,
|
||||
ACEP_RESOLUTION, 4, 0x02, 0x58, 0x01, 0xC0,
|
||||
ACEP_PWS, 1, 0xAA,
|
||||
0xFF, 100, // 100 ms delay
|
||||
ACEP_CDI, 1, 0x37,
|
||||
0xFE};
|
||||
|
||||
// clang-format on
|
||||
|
|
@ -79,7 +82,7 @@ Adafruit_ACEP::Adafruit_ACEP(int width, int height, int8_t DC, int8_t RST,
|
|||
if ((height % 8) != 0) {
|
||||
height += 8 - (height % 8);
|
||||
}
|
||||
buffer1_size = (uint16_t)width * (uint16_t)height / 2;
|
||||
buffer1_size = width * height / 2;
|
||||
buffer2_size = 0;
|
||||
|
||||
if (SRCS >= 0) {
|
||||
|
|
@ -94,6 +97,127 @@ Adafruit_ACEP::Adafruit_ACEP(int width, int height, int8_t DC, int8_t RST,
|
|||
singleByteTxns = true;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief clear all data buffers
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void Adafruit_ACEP::clearBuffer() {
|
||||
if (use_sram) {
|
||||
sram.erase(colorbuffer_addr, buffer1_size, 0x11);
|
||||
} else {
|
||||
memset(color_buffer, 0x11, buffer1_size);
|
||||
}
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief clear all data buffers
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void Adafruit_ACEP::deGhost() {
|
||||
uint8_t buf[4];
|
||||
|
||||
buf[0] = 0x02;
|
||||
buf[1] = 0x58;
|
||||
buf[2] = 0x01;
|
||||
buf[3] = 0xC0;
|
||||
EPD_command(ACEP_RESOLUTION, buf, 4);
|
||||
|
||||
EPD_command(ACEP_DTM);
|
||||
uint32_t remaining = (600UL * 448UL / 2);
|
||||
while (remaining) {
|
||||
uint8_t block[256];
|
||||
uint32_t numbytes = min(remaining, sizeof(block));
|
||||
memset(block, 0x77, numbytes);
|
||||
EPD_data(block, numbytes);
|
||||
remaining -= numbytes;
|
||||
}
|
||||
|
||||
EPD_command(ACEP_POWER_ON);
|
||||
busy_wait();
|
||||
EPD_command(ACEP_DISPLAY_REFRESH);
|
||||
busy_wait();
|
||||
EPD_command(ACEP_POWER_OFF);
|
||||
|
||||
if (_busy_pin >= 0) {
|
||||
while (digitalRead(_busy_pin)) { // wait for busy LOW
|
||||
delay(10);
|
||||
}
|
||||
} else {
|
||||
delay(BUSY_WAIT);
|
||||
}
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief clear the display twice to remove any spooky ghost images
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void Adafruit_ACEP::clearDisplay() {
|
||||
clearBuffer();
|
||||
display();
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief draw a single pixel on the screen
|
||||
@param x the x axis position
|
||||
@param y the y axis position
|
||||
@param color the color of the pixel
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void Adafruit_ACEP::drawPixel(int16_t x, int16_t y, uint16_t color) {
|
||||
if ((x < 0) || (x >= width()) || (y < 0) || (y >= height()))
|
||||
return;
|
||||
|
||||
uint8_t *pBuf;
|
||||
|
||||
// deal with non-8-bit heights
|
||||
uint16_t _HEIGHT = HEIGHT;
|
||||
if (_HEIGHT % 8 != 0) {
|
||||
_HEIGHT += 8 - (_HEIGHT % 8);
|
||||
}
|
||||
|
||||
// check rotation, move pixel around if necessary
|
||||
switch (getRotation()) {
|
||||
case 1:
|
||||
EPD_swap(x, y);
|
||||
x = WIDTH - x - 1;
|
||||
break;
|
||||
case 2:
|
||||
x = WIDTH - x - 1;
|
||||
y = _HEIGHT - y - 1;
|
||||
break;
|
||||
case 3:
|
||||
EPD_swap(x, y);
|
||||
y = _HEIGHT - y - 1;
|
||||
break;
|
||||
}
|
||||
uint32_t addr = ((uint32_t)x + (uint32_t)y * WIDTH) / 2;
|
||||
bool lower_nibble = x % 2;
|
||||
uint8_t color_c;
|
||||
|
||||
if (use_sram) {
|
||||
color_c = sram.read8(colorbuffer_addr + addr);
|
||||
pBuf = &color_c;
|
||||
} else {
|
||||
pBuf = color_buffer + addr;
|
||||
}
|
||||
|
||||
if (lower_nibble) {
|
||||
*pBuf &= 0xF0; // save higher nib
|
||||
*pBuf |= (color & 0xF);
|
||||
} else {
|
||||
*pBuf &= 0x0F; // save lower nib
|
||||
*pBuf |= (color & 0xF) << 4;
|
||||
}
|
||||
|
||||
if (use_sram) {
|
||||
sram.write8(colorbuffer_addr + addr, *pBuf);
|
||||
}
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief wait for busy signal to end
|
||||
|
|
@ -117,9 +241,58 @@ void Adafruit_ACEP::busy_wait(void) {
|
|||
/**************************************************************************/
|
||||
void Adafruit_ACEP::begin(bool reset) {
|
||||
Adafruit_EPD::begin(reset);
|
||||
|
||||
delay(100);
|
||||
powerDown();
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Transfer the data stored in the buffer(s) to the display
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void Adafruit_ACEP::display(bool sleep) {
|
||||
uint8_t c;
|
||||
|
||||
#ifdef EPD_DEBUG
|
||||
Serial.println(" Powering Up");
|
||||
#endif
|
||||
|
||||
powerUp();
|
||||
|
||||
#ifdef EPD_DEBUG
|
||||
Serial.println(" De Ghosting");
|
||||
#endif
|
||||
|
||||
deGhost();
|
||||
delay(500);
|
||||
|
||||
#ifdef EPD_DEBUG
|
||||
Serial.println(" Powering Up");
|
||||
#endif
|
||||
|
||||
powerUp();
|
||||
|
||||
#ifdef EPD_DEBUG
|
||||
Serial.println(" Write frame buffer");
|
||||
#endif
|
||||
|
||||
if (use_sram) {
|
||||
writeSRAMFramebufferToEPD(buffer1_addr, buffer1_size, 0);
|
||||
} else {
|
||||
writeRAMFramebufferToEPD(buffer1, buffer1_size, 0);
|
||||
}
|
||||
|
||||
#ifdef EPD_DEBUG
|
||||
Serial.println(" Update");
|
||||
#endif
|
||||
update();
|
||||
partialsSinceLastFullUpdate = 0;
|
||||
|
||||
if (sleep) {
|
||||
#ifdef EPD_DEBUG
|
||||
Serial.println(" Powering Down");
|
||||
#endif
|
||||
powerDown();
|
||||
}
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
|
|
@ -127,53 +300,22 @@ void Adafruit_ACEP::begin(bool reset) {
|
|||
@brief signal the display to update
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void Adafruit_ACEP::update() {
|
||||
void Adafruit_ACEP::update(void) {
|
||||
|
||||
uint8_t buf[4];
|
||||
/*
|
||||
// clear data
|
||||
buf[0] = 0x02;
|
||||
buf[1] = 0x58;
|
||||
buf[2] = 0x01;
|
||||
buf[3] = 0xC0;
|
||||
EPD_command(ACEP_RESOLUTION, buf, 4);
|
||||
EPD_command(ACEP_DTM);
|
||||
for (int i=0; i< 134400/256; i++) {
|
||||
uint8_t block[256];
|
||||
memset(block, 0x77, 256);
|
||||
EPD_data(block, 256);
|
||||
}
|
||||
|
||||
EPD_command(ACEP_POWER_ON);
|
||||
busy_wait();
|
||||
EPD_command(ACEP_DISPLAY_REFRESH);
|
||||
busy_wait();
|
||||
EPD_command(ACEP_POWER_OFF);
|
||||
|
||||
if (_busy_pin >= 0) {
|
||||
while (digitalRead(_busy_pin)) { // wait for busy LOW
|
||||
delay(10);
|
||||
}
|
||||
} else {
|
||||
delay(BUSY_WAIT);
|
||||
}*/
|
||||
|
||||
// actual data
|
||||
// clear data
|
||||
buf[0] = 0x02;
|
||||
buf[1] = 0x58;
|
||||
buf[2] = 0x01;
|
||||
buf[3] = 0xC0;
|
||||
EPD_command(ACEP_RESOLUTION, buf, 4);
|
||||
EPD_command(ACEP_DTM);
|
||||
for (int i = 0; i < 134400 / 256; i++) {
|
||||
uint8_t block[256];
|
||||
memset(block, ((i % 6) << 4) | (i % 6), 256);
|
||||
EPD_data(block, 256);
|
||||
}
|
||||
EPD_command(ACEP_POWER_ON);
|
||||
busy_wait();
|
||||
EPD_command(ACEP_DISPLAY_REFRESH);
|
||||
busy_wait();
|
||||
EPD_command(ACEP_POWER_OFF);
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
|
|
@ -193,9 +335,15 @@ void Adafruit_ACEP::powerUp() {
|
|||
init_code = _epd_init_code;
|
||||
}
|
||||
EPD_commandList(init_code);
|
||||
delay(1000);
|
||||
buf[0] = 0x37;
|
||||
EPD_command(ACEP_CDI, buf, 1);
|
||||
|
||||
// set resolution
|
||||
buf[0] = 0x02;
|
||||
buf[1] = 0x58;
|
||||
buf[2] = 0x01;
|
||||
buf[3] = 0xC0;
|
||||
EPD_command(ACEP_RESOLUTION, buf, 4);
|
||||
|
||||
delay(100);
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
|
|
|
|||
|
|
@ -14,12 +14,20 @@
|
|||
#define ACEP_DTM 0x10
|
||||
#define ACEP_DISPLAY_REFRESH 0x12
|
||||
#define ACEP_PLL 0x30
|
||||
#define ACEP_TSE 0x41
|
||||
#define ACEP_TSE 0x40
|
||||
#define ACEP_CDI 0x50
|
||||
#define ACEP_TCON 0x60
|
||||
#define ACEP_RESOLUTION 0x61
|
||||
#define ACEP_PWS 0xE3
|
||||
|
||||
#define ACEP_COLOR_BLACK 0x0 /// 000
|
||||
#define ACEP_COLOR_WHITE 0x1 /// 001
|
||||
#define ACEP_COLOR_GREEN 0x2 /// 010
|
||||
#define ACEP_COLOR_BLUE 0x3 /// 011
|
||||
#define ACEP_COLOR_RED 0x4 /// 100
|
||||
#define ACEP_COLOR_YELLOW 0x5 /// 101
|
||||
#define ACEP_COLOR_ORANGE 0x6 /// 110
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Class for interfacing with ACEP EPD drivers
|
||||
|
|
@ -37,6 +45,12 @@ public:
|
|||
void powerUp();
|
||||
void powerDown();
|
||||
void update();
|
||||
void display(bool sleep = true);
|
||||
|
||||
void clearBuffer();
|
||||
void clearDisplay();
|
||||
void deGhost();
|
||||
void drawPixel(int16_t x, int16_t y, uint16_t color);
|
||||
|
||||
protected:
|
||||
uint8_t writeRAMCommand(uint8_t index);
|
||||
|
|
|
|||
Loading…
Reference in a new issue