Adafruit_EPD/Adafruit_SSD1608.cpp
Limor "Ladyada" Fried 918c98aba3
Actions (#17)
2019-12-27 18:18:06 -05:00

255 lines
7.1 KiB
C++

#include "Adafruit_SSD1608.h"
#include "Adafruit_EPD.h"
#define BUSY_WAIT 500
const unsigned char LUT_DATA[30] = {
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};
/**************************************************************************/
/*!
@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_SSD1608::Adafruit_SSD1608(int width, int height, int8_t SID,
int8_t SCLK, int8_t DC, int8_t RST,
int8_t CS, int8_t SRCS, int8_t MISO,
int8_t BUSY)
: Adafruit_EPD(width, height, SID, SCLK, DC, RST, CS, SRCS, MISO, BUSY) {
if ((width % 8) != 0) {
width += 8 - (width % 8);
}
buffer1_size = (uint16_t)width * (uint16_t)height / 8;
buffer2_size = 0;
if (SRCS >= 0) {
use_sram = true;
buffer1_addr = 0;
buffer2_addr = 0;
} else {
buffer1 = (uint8_t *)malloc(buffer1_size);
buffer2 = NULL;
}
}
// 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_SSD1608::Adafruit_SSD1608(int width, int height, int8_t DC, int8_t RST,
int8_t CS, int8_t SRCS, int8_t BUSY)
: Adafruit_EPD(width, height, DC, RST, CS, SRCS, BUSY) {
if ((height % 8) != 0) {
height += 8 - (height % 8);
}
buffer1_size = (uint16_t)width * (uint16_t)height / 8;
buffer2_size = 0;
if (SRCS >= 0) {
use_sram = true;
buffer1_addr = 0;
buffer2_addr = 0;
} else {
buffer1 = (uint8_t *)malloc(buffer1_size);
buffer2 = buffer1;
}
}
/**************************************************************************/
/*!
@brief wait for busy signal to end
*/
/**************************************************************************/
void Adafruit_SSD1608::busy_wait(void) {
if (_busy_pin >= 0) {
while (digitalRead(_busy_pin)) { // wait for busy low
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_SSD1608::begin(bool reset) {
Adafruit_EPD::begin(reset);
setBlackBuffer(0, true); // black defaults to inverted
setColorBuffer(0, true); // no secondary buffer, so we'll just reuse index 0
delay(100);
powerDown();
}
/**************************************************************************/
/*!
@brief signal the display to update
*/
/**************************************************************************/
void Adafruit_SSD1608::update() {
uint8_t buf[1];
// display update sequence
buf[0] = 0xC7;
EPD_command(SSD1608_DISP_CTRL2, buf, 1);
EPD_command(SSD1608_MASTER_ACTIVATE);
busy_wait();
}
/**************************************************************************/
/*!
@brief start up the display
*/
/**************************************************************************/
void Adafruit_SSD1608::powerUp() {
uint8_t buf[5];
hardwareReset();
busy_wait();
// soft reset
EPD_command(SSD1608_SW_RESET);
busy_wait();
// driver output control
buf[0] = HEIGHT - 1;
buf[1] = (HEIGHT - 1) >> 8;
buf[2] = 0x00;
EPD_command(SSD1608_DRIVER_CONTROL, buf, 3);
// Set dummy line period
buf[0] = 0x1B;
EPD_command(SSD1608_WRITE_DUMMY, buf, 1);
// Set gate line width
buf[0] = 0x0B;
EPD_command(SSD1608_WRITE_GATELINE, buf, 1);
// Data entry sequence
buf[0] = 0x03;
EPD_command(SSD1608_DATA_MODE, buf, 1);
// Set ram X start/end postion
buf[0] = 0x00;
buf[1] = WIDTH / 8 - 1;
EPD_command(SSD1608_SET_RAMXPOS, buf, 2);
// Set ram Y start/end postion
buf[0] = 0x00;
buf[1] = 0x00;
buf[2] = HEIGHT - 1;
buf[3] = (HEIGHT - 1) >> 8;
EPD_command(SSD1608_SET_RAMYPOS, buf, 4);
// Vcom Voltage
buf[0] = 0x70;
EPD_command(SSD1608_WRITE_VCOM, buf, 1);
EPD_command(SSD1608_WRITE_LUT, LUT_DATA, 30);
/*
// border color
buf[0] = 0x03;
EPD_command(SSD1608_WRITE_BORDER, buf, 1);
// Set gate voltage
buf[0] = LUT_DATA[70];
EPD_command(SSD1608_GATE_VOLTAGE, buf, 1);
// Set source voltage
buf[0] = LUT_DATA[71];
buf[1] = LUT_DATA[72];
buf[2] = LUT_DATA[73];
EPD_command(SSD1608_SOURCE_VOLTAGE, buf, 3);
*/
/*
// set RAM x address count ;
buf[0] = 0;
EPD_command(SSD1608_SET_RAMXCOUNT, buf, 1);
// set RAM y address count;
buf[0] = HEIGHT - 1;
buf[1] = (HEIGHT - 1) >> 8;
EPD_command(SSD1608_SET_RAMYCOUNT, buf, 2);
*/
busy_wait();
}
/**************************************************************************/
/*!
@brief wind down the display
*/
/**************************************************************************/
void Adafruit_SSD1608::powerDown(void) {
uint8_t buf[2];
// deep sleep
buf[0] = 0x01;
EPD_command(SSD1608_DEEP_SLEEP, buf, 1);
delay(100);
}
/**************************************************************************/
/*!
@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_SSD1608::writeRAMCommand(uint8_t index) {
return EPD_command(SSD1608_WRITE_RAM, false);
}
/**************************************************************************/
/*!
@brief Some displays require setting the RAM address pointer
@param x X address counter value
@param y Y address counter value
*/
/**************************************************************************/
void Adafruit_SSD1608::setRAMAddress(uint16_t x, uint16_t y) {
uint8_t buf[2];
// Set RAM X address counter
buf[0] = x;
EPD_command(SSD1608_SET_RAMXCOUNT, buf, 1);
// Set RAM Y address counter
buf[0] = y >> 8;
buf[1] = y;
EPD_command(SSD1608_SET_RAMYCOUNT, buf, 2);
}