#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<> 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<1000; i++); _epaper_digitalwrite(RST_PIN, 1); for(uint32_t i = 0; i<1000; 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); }