You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

218 lines
5.8 KiB

#include "lib_epaper_2in9.h"
// Constants
const uint8_t lut_full_update[] = {
0x50, 0xAA, 0x55, 0xAA, 0x11, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xFF, 0xFF, 0x1F, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
const uint8_t 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
};
// Basic functions
void _epaper_spiinit()
{
// Enable clocks to relevant peripherals
LPC_SYSCON->SYSAHBCLKCTRL[0] |= (SPI0|SWM);
// Configure the SWM (see peripherals_lib and swm.h)
ConfigSWM(SPI0_SCK, SCK_PIN);
ConfigSWM(SPI0_MOSI, MOSI_PIN);
ConfigSWM(SPI0_SSEL0, CS_PIN);
// Give SPI0 a reset
LPC_SYSCON->PRESETCTRL[0] &= (SPI0_RST_N);
LPC_SYSCON->PRESETCTRL[0] |= ~(SPI0_RST_N);
// Enable main_clk as function clock to SPI
LPC_SYSCON->SPI0CLKSEL = FCLKSEL_MAIN_CLK;
// Get main_clk frequency
SystemCoreClockUpdate();
// Configure the SPI master's clock divider (value written to DIV divides by value+1)
LPC_SPI0->DIV = (main_clk/SPIBAUD) - 1;
// Configure the CFG register:
// Enable=true, master, no LSB first, CPHA=0, CPOL=0, no loop-back, SSEL active low
LPC_SPI0->CFG = SPI_CFG_ENABLE | SPI_CFG_MASTER;
// Configure the SPI delay register (DLY)
// Pre-delay = 0 clocks, post-delay = 0 clocks, frame-delay = 0 clocks, transfer-delay = 0 clocks
LPC_SPI0->DLY = 0x0000;
// Configure the SPI control register
// Master: End-of-frame true, End-of-transfer true, RXIGNORE true, LEN 8 bits.
LPC_SPI0->TXCTL = SPI_CTL_EOF | SPI_CTL_EOT | SPI_CTL_RXIGNORE | SPI_CTL_LEN(8);
}
void _epaper_spitransfer(uint8_t data)
{
WaitSPIReady();
LPC_SPI0->TXDAT = data;
}
uint8_t _epaper_digitalread(uint8_t pin)
{
return LPC_GPIO_PORT->B0[pin];
}
void _epaper_digitalwrite(uint8_t pin, uint8_t value)
{
LPC_GPIO_PORT->B0[pin] = value;
}
void _epaper_setlut(const uint8_t* lut)
{
epaper_sendcommand(WRITE_LUT_REGISTER);
/* the length of look-up table is 30 bytes */
for (int i = 0; i < 30; i++) {
epaper_senddata(lut[i]);
}
}
void _epaper_setmemoryarea(uint16_t x_start, uint16_t y_start, uint16_t x_stop, uint16_t y_stop)
{
epaper_sendcommand(SET_RAM_X_ADDRESS_START_END_POSITION);
/* x point must be the multiple of 8 or the last 3 bits will be ignored */
epaper_senddata((x_start >> 3) & 0xFF);
epaper_senddata((x_stop >> 3) & 0xFF);
epaper_sendcommand(SET_RAM_Y_ADDRESS_START_END_POSITION);
epaper_senddata(y_start & 0xFF);
epaper_senddata((y_start >> 8) & 0xFF);
epaper_senddata(y_stop & 0xFF);
epaper_senddata((y_stop >> 8) & 0xFF);
}
void _epaper_setmemorypointer(uint16_t x, uint16_t y)
{
epaper_sendcommand(SET_RAM_X_ADDRESS_COUNTER);
/* x point must be the multiple of 8 or the last 3 bits will be ignored */
epaper_senddata((x >> 3) & 0xFF);
epaper_sendcommand(SET_RAM_Y_ADDRESS_COUNTER);
epaper_senddata(y & 0xFF);
epaper_senddata((y >> 8) & 0xFF);
WaitEpaperReady();
}
// User functions
uint8_t epaper_init()
{
// Configuration des sorties
LPC_SYSCON->SYSAHBCLKCTRL0 |= IOCON | GPIO0;
LPC_GPIO_PORT->DIR0 |= (1<<RST_PIN) | (1<<DC_PIN);
// Configuration de la liaison SPI
_epaper_spiinit();
/* EPD hardware init start */
epaper_reset();
epaper_sendcommand(DRIVER_OUTPUT_CONTROL);
epaper_senddata((EPD_HEIGHT - 1) & 0xFF);
epaper_senddata(((EPD_HEIGHT - 1) >> 8) & 0xFF);
epaper_senddata(0x00); // GD = 0; SM = 0; TB = 0;
epaper_sendcommand(BOOSTER_SOFT_START_CONTROL);
epaper_senddata(0xD7);
epaper_senddata(0xD6);
epaper_senddata(0x9D);
epaper_sendcommand(WRITE_VCOM_REGISTER);
epaper_senddata(0xA8); // VCOM 7C
epaper_sendcommand(SET_DUMMY_LINE_PERIOD);
epaper_senddata(0x1A); // 4 dummy lines per gate
epaper_sendcommand(SET_GATE_TIME);
epaper_senddata(0x08); // 2us per line
epaper_sendcommand(DATA_ENTRY_MODE_SETTING);
epaper_senddata(0x03); // X increment; Y increment
_epaper_setlut(lut_full_update);
/* EPD hardware init end */
return 0;
}
void epaper_sendcommand(uint8_t command)
{
_epaper_digitalwrite(DC_PIN, 0);
_epaper_spitransfer(command);
}
void epaper_senddata(uint8_t data)
{
_epaper_digitalwrite(DC_PIN, 1);
_epaper_spitransfer(data);
}
void epaper_reset()
{
_epaper_digitalwrite(RST_PIN, 0);
for(uint32_t i = 0; i<10000; i++);
_epaper_digitalwrite(RST_PIN, 1);
for(uint32_t i = 0; i<10000; i++);
}
void epaper_setframe(uint8_t* image_buffer, uint16_t x, uint16_t y, uint16_t w, uint16_t h)
{
int x_end;
int y_end;
if (image_buffer == 0 || x < 0 || w < 0 || y < 0 || h < 0) return;
/* x point must be the multiple of 8 or the last 3 bits will be ignored */
x &= 0xF8;
w &= 0xF8;
if (x + w >= EPD_WIDTH) {
x_end = EPD_WIDTH - 1;
} else {
x_end = x + EPD_WIDTH - 1;
}
if (y + h >= EPD_HEIGHT) {
y_end = EPD_HEIGHT - 1;
} else {
y_end = y + EPD_HEIGHT - 1;
}
_epaper_setmemoryarea(x, y, x_end, y_end);
_epaper_setmemorypointer(x, y);
epaper_sendcommand(WRITE_RAM);
/* send the image data */
for (int j = 0; j < y_end - y + 1; j++) {
for (int i = 0; i < (x_end - x + 1) / 8; i++) {
epaper_senddata(image_buffer[i + j * (w / 8)]);
}
}
}
void epaper_clearframe(uint8_t color)
{
_epaper_setmemoryarea(0, 0, EPD_WIDTH - 1, EPD_HEIGHT - 1);
_epaper_setmemorypointer(0, 0);
epaper_sendcommand(WRITE_RAM);
/* send the color data */
for (int i = 0; i < EPD_WIDTH / 8 * EPD_HEIGHT; i++) {
epaper_senddata(color);
}
}
void epaper_display()
{
WaitEpaperReady();
epaper_sendcommand(DISPLAY_UPDATE_CONTROL_2);
epaper_senddata(0xC4);
epaper_sendcommand(MASTER_ACTIVATION);
epaper_sendcommand(TERMINATE_FRAME_READ_WRITE);
WaitEpaperReady();
}
void epaper_sleep()
{
epaper_sendcommand(DEEP_SLEEP_MODE);
epaper_senddata(0x01);
}