add 3.52" quad color (note upside-down connector!)
This commit is contained in:
parent
a44b60d8f4
commit
308619ed00
6 changed files with 406 additions and 3 deletions
|
|
@ -30,6 +30,10 @@
|
|||
ThinkInk_213_Quadcolor_AJHE5 display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY,
|
||||
EPD_SPI);
|
||||
|
||||
// 3.52" Quadcolor EPD with JD79667 chipset
|
||||
ThinkInk_352_Quadcolor_AJHE5 display(EPD_DC, EPD_RESET, EPD_CS, SRAM_CS, EPD_BUSY,
|
||||
EPD_SPI);
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
while (!Serial) {
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@
|
|||
#include "panels/ThinkInk_290_Tricolor_Z10.h"
|
||||
#include "panels/ThinkInk_290_Tricolor_Z13.h"
|
||||
#include "panels/ThinkInk_290_Tricolor_Z94.h"
|
||||
#include "panels/ThinkInk_352_Quadcolor_AJHE5.h"
|
||||
#include "panels/ThinkInk_370_Mono_BAAMFGN.h"
|
||||
#include "panels/ThinkInk_370_Tricolor_BABMFGNR.h"
|
||||
#include "panels/ThinkInk_420_Grayscale4_MFGN.h"
|
||||
|
|
|
|||
|
|
@ -131,10 +131,10 @@ void Adafruit_JD79661::drawPixel(int16_t x, int16_t y, uint16_t color) {
|
|||
|
||||
uint8_t* pBuf;
|
||||
|
||||
// deal with non-8-bit heights
|
||||
// deal with non-4-bit heights
|
||||
uint16_t _WIDTH = WIDTH;
|
||||
if (_WIDTH % 8 != 0) {
|
||||
_WIDTH += 8 - (_WIDTH % 8);
|
||||
if (_WIDTH % 4 != 0) {
|
||||
_WIDTH += 4 - (_WIDTH % 4);
|
||||
}
|
||||
|
||||
// check rotation, move pixel around if necessary
|
||||
|
|
|
|||
315
src/drivers/Adafruit_JD79667.cpp
Normal file
315
src/drivers/Adafruit_JD79667.cpp
Normal file
|
|
@ -0,0 +1,315 @@
|
|||
#include "Adafruit_JD79667.h"
|
||||
|
||||
#include "Adafruit_EPD.h"
|
||||
|
||||
#define EPD_RAM_BW 0x10
|
||||
#define EPD_RAM_RED 0x13
|
||||
|
||||
#define BUSY_WAIT 500
|
||||
|
||||
// clang-format off
|
||||
|
||||
const uint8_t jd79667_default_init_code[] {
|
||||
0xFF, 10, // wait a lil bit
|
||||
0x4D, 1, 0x78,
|
||||
JD79667_PANEL_SETTING, 2, 0x0F, 0x29, // PSR, Display resolution is 180x384
|
||||
JD79667_POWER_SETTING, 2, 0x07, 0x00, // PWR
|
||||
0x03, 3, 0x10, 0x54, 0x44, // POFS
|
||||
JD79667_BOOSTER_SOFTSTART, 7, 0x05, 0x00, 0x3F, 0x0A, 0x25, 0x12, 0x1A,
|
||||
JD79667_CDI, 1, 0x37, // CDI
|
||||
0x60, 2, 0x02, 0x02, // TCON
|
||||
JD79667_RESOLUTION, 4, 0, 180, 1, 128, // TRES 180x384
|
||||
0xE7, 1, 0x1C,
|
||||
0xE3, 1, 0x22,
|
||||
0xB4, 1, 0xD0,
|
||||
0xB5, 1, 0x03,
|
||||
0xE9, 1, 0x01,
|
||||
JD79667_PLL_CONTROL, 1, 0x08,
|
||||
JD79667_POWER_ON, 0,
|
||||
0xFE};
|
||||
|
||||
// clang-format on
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief constructor if using external SRAM chip and software SPI
|
||||
@param width the width of the display in pixels
|
||||
@param height the height of the display in pixels
|
||||
@param SID the SID pin to use
|
||||
@param SCLK the SCLK pin to use
|
||||
@param DC the data/command pin to use
|
||||
@param RST the reset pin to use
|
||||
@param CS the chip select pin to use
|
||||
@param SRCS the SRAM chip select pin to use
|
||||
@param MISO the MISO pin to use
|
||||
@param BUSY the busy pin to use
|
||||
*/
|
||||
/**************************************************************************/
|
||||
Adafruit_JD79667::Adafruit_JD79667(int width, int height, int16_t SID,
|
||||
int16_t SCLK, int16_t DC, int16_t RST,
|
||||
int16_t CS, int16_t SRCS, int16_t MISO,
|
||||
int16_t BUSY)
|
||||
: Adafruit_EPD(width, height, SID, SCLK, DC, RST, CS, SRCS, MISO, BUSY) {
|
||||
if ((width % 8) != 0) {
|
||||
width += 8 - (width % 8);
|
||||
}
|
||||
buffer1_size = width * height / 4;
|
||||
buffer2_size = 0;
|
||||
|
||||
if (SRCS >= 0) {
|
||||
use_sram = true;
|
||||
buffer1_addr = 0;
|
||||
buffer2_addr = 0;
|
||||
} else {
|
||||
buffer1 = (uint8_t*)malloc(buffer1_size);
|
||||
buffer2 = buffer1;
|
||||
}
|
||||
singleByteTxns = true;
|
||||
}
|
||||
|
||||
// constructor for hardware SPI - we indicate DataCommand, ChipSelect, Reset
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief constructor if using on-chip RAM and hardware SPI
|
||||
@param width the width of the display in pixels
|
||||
@param height the height of the display in pixels
|
||||
@param DC the data/command pin to use
|
||||
@param RST the reset pin to use
|
||||
@param CS the chip select pin to use
|
||||
@param SRCS the SRAM chip select pin to use
|
||||
@param BUSY the busy pin to use
|
||||
*/
|
||||
/**************************************************************************/
|
||||
Adafruit_JD79667::Adafruit_JD79667(int width, int height, int16_t DC,
|
||||
int16_t RST, int16_t CS, int16_t SRCS,
|
||||
int16_t BUSY, SPIClass* spi)
|
||||
: Adafruit_EPD(width, height, DC, RST, CS, SRCS, BUSY, spi) {
|
||||
if ((width % 8) != 0) {
|
||||
width += 8 - (width % 8);
|
||||
}
|
||||
buffer1_size = width * height / 4;
|
||||
buffer2_size = 0;
|
||||
|
||||
if (SRCS >= 0) {
|
||||
use_sram = true;
|
||||
buffer1_addr = 0;
|
||||
buffer2_addr = 0;
|
||||
} else {
|
||||
buffer1 = (uint8_t*)malloc(buffer1_size);
|
||||
buffer2 = buffer1;
|
||||
}
|
||||
|
||||
|
||||
singleByteTxns = true;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief clear all data buffers
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void Adafruit_JD79667::clearBuffer() {
|
||||
if (use_sram) {
|
||||
sram.erase(colorbuffer_addr, buffer1_size, 0x55);
|
||||
} else {
|
||||
memset(buffer1, 0x55, buffer1_size);
|
||||
}
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@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_JD79667::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-4-bit heights
|
||||
uint16_t _WIDTH = WIDTH;
|
||||
if (_WIDTH % 4 != 0) {
|
||||
_WIDTH += 4 - (_WIDTH % 4);
|
||||
}
|
||||
|
||||
// check rotation, move pixel around if necessary
|
||||
switch (getRotation()) {
|
||||
case 1:
|
||||
EPD_swap(x, y);
|
||||
x = _WIDTH - x - 1;
|
||||
// remove the offset
|
||||
x -= _WIDTH - WIDTH;
|
||||
break;
|
||||
case 2:
|
||||
x = _WIDTH - x - 1;
|
||||
y = HEIGHT - y - 1;
|
||||
// re-add the offset
|
||||
x += _WIDTH - WIDTH;
|
||||
break;
|
||||
case 3:
|
||||
EPD_swap(x, y);
|
||||
y = HEIGHT - y - 1;
|
||||
break;
|
||||
}
|
||||
uint32_t addr = ((uint32_t)x + (uint32_t)y * _WIDTH) / 4;
|
||||
uint8_t color_c;
|
||||
|
||||
if (use_sram) {
|
||||
color_c = sram.read8(colorbuffer_addr + addr);
|
||||
pBuf = &color_c;
|
||||
} else {
|
||||
pBuf = color_buffer + addr;
|
||||
}
|
||||
|
||||
if (color == EPD_BLACK) {
|
||||
color = JD79667_BLACK;
|
||||
} else if (color == EPD_RED) {
|
||||
color = JD79667_RED;
|
||||
} else if (color == EPD_YELLOW) {
|
||||
color = JD79667_YELLOW;
|
||||
} else if (color == EPD_WHITE) {
|
||||
color = JD79667_WHITE;
|
||||
}
|
||||
|
||||
uint8_t byte_offset_mask = 0x3 << (3 - (x % 4)) * 2;
|
||||
uint8_t byte_offset_value = (color & 0x3) << (3 - (x % 4)) * 2;
|
||||
|
||||
*pBuf &= ~byte_offset_mask; // save reverse mask
|
||||
*pBuf |= byte_offset_value; // now add in the new color
|
||||
|
||||
if (use_sram) {
|
||||
sram.write8(colorbuffer_addr + addr, *pBuf);
|
||||
}
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief wait for busy signal to end
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void Adafruit_JD79667::busy_wait(void) {
|
||||
if (_busy_pin >= 0) {
|
||||
while (!digitalRead(_busy_pin)) { // wait for busy HIGH!
|
||||
delay(10);
|
||||
}
|
||||
} else {
|
||||
delay(BUSY_WAIT);
|
||||
}
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief begin communication with and set up the display.
|
||||
@param reset if true the reset pin will be toggled.
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void Adafruit_JD79667::begin(bool reset) {
|
||||
Adafruit_EPD::begin(reset);
|
||||
delay(100);
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief signal the display to update
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void Adafruit_JD79667::update() {
|
||||
uint8_t buf[1];
|
||||
|
||||
// display update sequence
|
||||
buf[0] = 0x00;
|
||||
EPD_command(JD79667_DISPLAY_REFRESH, buf, 1);
|
||||
|
||||
busy_wait();
|
||||
|
||||
if (_busy_pin <= -1) {
|
||||
delay(1000);
|
||||
}
|
||||
}
|
||||
|
||||
void Adafruit_JD79667::hardwareReset(void) {
|
||||
if (_reset_pin >= 0) {
|
||||
// Setup reset pin direction
|
||||
pinMode(_reset_pin, OUTPUT);
|
||||
// VDD (3.3V) goes high at start, lets just chill for a ms
|
||||
digitalWrite(_reset_pin, HIGH);
|
||||
delay(20);
|
||||
// bring reset low
|
||||
digitalWrite(_reset_pin, LOW);
|
||||
// wait 40ms
|
||||
delay(40);
|
||||
// bring out of reset
|
||||
digitalWrite(_reset_pin, HIGH);
|
||||
delay(50);
|
||||
}
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief start up the display
|
||||
*/
|
||||
/**************************************************************************/
|
||||
|
||||
void Adafruit_JD79667::powerUp() {
|
||||
hardwareReset();
|
||||
busy_wait();
|
||||
|
||||
const uint8_t* init_code = jd79667_default_init_code;
|
||||
if (_epd_init_code != NULL) {
|
||||
init_code = _epd_init_code;
|
||||
}
|
||||
EPD_commandList(init_code);
|
||||
|
||||
busy_wait();
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief wind down the display
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void Adafruit_JD79667::powerDown() {
|
||||
uint8_t buf[1];
|
||||
// Only deep sleep if we can get out of it
|
||||
if (_reset_pin >= 0) {
|
||||
// deep sleep
|
||||
buf[0] = 0x00;
|
||||
EPD_command(JD79667_POWER_OFF, buf, 1);
|
||||
busy_wait();
|
||||
delay(100);
|
||||
buf[0] = 0xA5;
|
||||
EPD_command(JD79667_DEEP_SLEEP, buf, 1);
|
||||
}
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Send the specific command to start writing to EPD display RAM
|
||||
@param index The index for which buffer to write (0 or 1 or tri-color
|
||||
displays) Ignored for monochrome displays.
|
||||
@returns The byte that is read from SPI at the same time as sending the
|
||||
command
|
||||
*/
|
||||
/**************************************************************************/
|
||||
uint8_t Adafruit_JD79667::writeRAMCommand(uint8_t index) {
|
||||
(void)index;
|
||||
EPD_command(JD79667_DATA_START_XMIT);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Some displays require setting the RAM address pointer
|
||||
@param x X address counter value
|
||||
@param y Y address counter value
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void Adafruit_JD79667::setRAMAddress(uint16_t x, uint16_t y) {
|
||||
(void)x;
|
||||
(void)y;
|
||||
}
|
||||
53
src/drivers/Adafruit_JD79667.h
Normal file
53
src/drivers/Adafruit_JD79667.h
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
#ifndef LIB_ADAFRUIT_JD79667
|
||||
#define LIB_ADAFRUIT_JD79667
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
#include "Adafruit_EPD.h"
|
||||
|
||||
#define JD79667_PANEL_SETTING 0x00
|
||||
#define JD79667_POWER_SETTING 0x01
|
||||
#define JD79667_POWER_OFF 0x02
|
||||
#define JD79667_POWER_ON 0x04
|
||||
#define JD79667_BOOSTER_SOFTSTART 0x06
|
||||
#define JD79667_DATA_START_XMIT 0x10
|
||||
#define JD79667_DISPLAY_REFRESH 0x12
|
||||
#define JD79667_DEEP_SLEEP 0x07
|
||||
#define JD79667_PLL_CONTROL 0x30
|
||||
#define JD79667_CDI 0x50
|
||||
#define JD79667_RESOLUTION 0x61
|
||||
|
||||
#define JD79667_BLACK 0b00
|
||||
#define JD79667_WHITE 0b01
|
||||
#define JD79667_YELLOW 0b10
|
||||
#define JD79667_RED 0b11
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Class for interfacing with JD79667 EPD drivers
|
||||
*/
|
||||
/**************************************************************************/
|
||||
class Adafruit_JD79667 : public Adafruit_EPD {
|
||||
public:
|
||||
Adafruit_JD79667(int width, int height, int16_t SID, int16_t SCLK, int16_t DC,
|
||||
int16_t RST, int16_t CS, int16_t SRCS, int16_t MISO,
|
||||
int16_t BUSY = -1);
|
||||
Adafruit_JD79667(int width, int height, int16_t DC, int16_t RST, int16_t CS,
|
||||
int16_t SRCS, int16_t BUSY = -1, SPIClass* spi = &SPI);
|
||||
|
||||
void begin(bool reset = true);
|
||||
void powerUp();
|
||||
void update(void);
|
||||
void powerDown();
|
||||
|
||||
void clearBuffer();
|
||||
void drawPixel(int16_t x, int16_t y, uint16_t color);
|
||||
void hardwareReset(void);
|
||||
|
||||
protected:
|
||||
void busy_wait();
|
||||
void setRAMAddress(uint16_t x, uint16_t y);
|
||||
uint8_t writeRAMCommand(uint8_t index);
|
||||
};
|
||||
|
||||
#endif
|
||||
30
src/panels/ThinkInk_352_Quadcolor_AJHE5.h
Normal file
30
src/panels/ThinkInk_352_Quadcolor_AJHE5.h
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
#ifndef _THINKINK_352_QUADCOLOR_AJHE5_H
|
||||
#define _THINKINK_352_QUADCOLOR_AJHE5_H
|
||||
|
||||
// This file is #included by Adafruit_ThinkInk.h and does not need to
|
||||
// #include anything else to pick up the EPD header or ink mode enum.
|
||||
|
||||
class ThinkInk_352_Quadcolor_AJHE5 : public Adafruit_JD79667 {
|
||||
public:
|
||||
ThinkInk_352_Quadcolor_AJHE5(int16_t SID, int16_t SCLK, int16_t DC,
|
||||
int16_t RST, int16_t CS, int16_t SRCS,
|
||||
int16_t MISO, int16_t BUSY = -1)
|
||||
: Adafruit_JD79667(180, 384, SID, SCLK, DC, RST, CS, SRCS, MISO, BUSY){};
|
||||
|
||||
ThinkInk_352_Quadcolor_AJHE5(int16_t DC, int16_t RST, int16_t CS,
|
||||
int16_t SRCS, int16_t BUSY = -1,
|
||||
SPIClass* spi = &SPI)
|
||||
: Adafruit_JD79667(180, 384, DC, RST, CS, SRCS, BUSY, spi){};
|
||||
|
||||
void begin(thinkinkmode_t mode = THINKINK_QUADCOLOR) {
|
||||
Adafruit_JD79667::begin(true);
|
||||
|
||||
inkmode = mode; // Preserve ink mode for ImageReader or others
|
||||
|
||||
default_refresh_delay = 13000;
|
||||
setRotation(1);
|
||||
powerDown();
|
||||
}
|
||||
};
|
||||
|
||||
#endif // _THINKINK_352_Quad
|
||||
Loading…
Reference in a new issue