From a2e7686c755c7dd6d5cf4c2a9dd0b1619a9fdaec Mon Sep 17 00:00:00 2001 From: "gael.pongnot" Date: Mon, 12 Sep 2022 11:32:48 +0200 Subject: [PATCH] =?UTF-8?q?Portage=20fait,=20=C3=A0=20tester?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- inc/lib_epaper_2in9.h | 66 +++++++++++++ src/lib_epaper_2in9.c | 220 ++++++++++++++++++++++++++++++++++++++++++ src/main.c | 41 +------- 3 files changed, 291 insertions(+), 36 deletions(-) diff --git a/inc/lib_epaper_2in9.h b/inc/lib_epaper_2in9.h index e69de29..0cf6916 100644 --- a/inc/lib_epaper_2in9.h +++ b/inc/lib_epaper_2in9.h @@ -0,0 +1,66 @@ +#ifndef LIB_EPAPER_2IN9_H_ +#define LIB_EPAPER_2IN9_H_ + +#include "LPC8xx.h" + +// Pin definition - à modifier +#define SPIBAUD 115200 +#define SCK_PIN P0_1 +#define MOSI_PIN P0_8 +#define CS_PIN P0_16 +#define RST_PIN P0_11 +#define DC_PIN P0_21 +#define BUSY_PIN P0_17 + +// Display resolution +#define EPD_WIDTH 128 +#define EPD_HEIGHT 296 + +// EPD2IN9 commands +#define DRIVER_OUTPUT_CONTROL 0x01 +#define BOOSTER_SOFT_START_CONTROL 0x0C +#define GATE_SCAN_START_POSITION 0x0F +#define DEEP_SLEEP_MODE 0x10 +#define DATA_ENTRY_MODE_SETTING 0x11 +#define SW_RESET 0x12 +#define TEMPERATURE_SENSOR_CONTROL 0x1A +#define MASTER_ACTIVATION 0x20 +#define DISPLAY_UPDATE_CONTROL_1 0x21 +#define DISPLAY_UPDATE_CONTROL_2 0x22 +#define WRITE_RAM 0x24 +#define WRITE_VCOM_REGISTER 0x2C +#define WRITE_LUT_REGISTER 0x32 +#define SET_DUMMY_LINE_PERIOD 0x3A +#define SET_GATE_TIME 0x3B +#define BORDER_WAVEFORM_CONTROL 0x3C +#define SET_RAM_X_ADDRESS_START_END_POSITION 0x44 +#define SET_RAM_Y_ADDRESS_START_END_POSITION 0x45 +#define SET_RAM_X_ADDRESS_COUNTER 0x4E +#define SET_RAM_Y_ADDRESS_COUNTER 0x4F +#define TERMINATE_FRAME_READ_WRITE 0xFF + +// Macro functions +#define WaitEpaperReady() while(LPC_GPIO_PORT->B0[BUSY_PIN]) // à modifier +#define WaitSPIReady() while(!(LPC_SPI0->STAT & SPI_TXRDY)); + +// Basic functions +void _epaper_spiinit(); +void _epaper_spitransfer(uint8_t data); +uint8_t _epaper_digitalread(uint8_t pin); +uint8_t _epaper_digitalwrite(uint8_t pin, uint8_t value); +void _epaper_setlut(const uint8_t* lut); +void _epaper_setmemoryarea(uint8_t x_start, uint8_t y_start, uint8_t x_stop, uint8_t y_stop); +void _epaper_setmemorypointer(uint8_t x, uint8_t y); + +// User functions +uint8_t epaper_init(); +void epaper_sendcommand(uint8_t command); +void epaper_senddata(uint8_t data); +void epaper_reset(); +void epaper_setframe(uint8_t* image_buffer, uint8_t x, uint8_t y, uint8_t w, uint8_t h); +void epaper_clearframe(uint8_t color); +void epaper_display(); +void epaper_sleep(); + + +#endif /* LIB_EPAPER_2IN9_H_ */ diff --git a/src/lib_epaper_2in9.c b/src/lib_epaper_2in9.c index e69de29..c2043e9 100644 --- a/src/lib_epaper_2in9.c +++ b/src/lib_epaper_2in9.c @@ -0,0 +1,220 @@ +#include "lib_epaper_2in9.h" + +// 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]; +} + +uint8_t _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++) { + SendData(lut[i]); + } +} + +void _epaper_setmemoryarea(uint8_t x_start, uint8_t y_start, uint8_t x_stop, uint8_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_end >> 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_end & 0xFF); + epaper_senddata((y_end >> 8) & 0xFF); +} + +void _epaper_setmemorypointer(uint8_t x, uint8_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(command); +} + +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, uint8_t x, uint8_t y, uint8_t w, uint8_t h) +{ + int x_end; + int y_end; + + if ( + image_buffer == NULL || + x < 0 || image_width < 0 || + y < 0 || image_height < 0 + ) { + return; + } + /* x point must be the multiple of 8 or the last 3 bits will be ignored */ + x &= 0xF8; + image_width &= 0xF8; + if (x + image_width >= this->width) { + x_end = this->width - 1; + } else { + x_end = x + image_width - 1; + } + if (y + image_height >= this->height) { + y_end = this->height - 1; + } else { + y_end = y + image_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++) { + SendData(image_buffer[i + j * (image_width / 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 < this->width / 8 * this->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); +} + +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 +}; diff --git a/src/main.c b/src/main.c index 5208822..fea7393 100644 --- a/src/main.c +++ b/src/main.c @@ -6,50 +6,19 @@ #include "utilities.h" #include "chip_setup.h" #include "lib_ENS_II1_lcd.h" +#include "lib_epaper_2in9.h" -#define SPIBAUD 115200 -#define SCK_PIN P0_19 -#define MOSI_PIN P0_18 -#define SSEL_PIN P0_21 +#define SCK_PIN P0_19 + // // Main routine // int main(void) { - // 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, SSEL_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); + // Init e-paper + epaper_init(); // Init LCD Screen init_lcd();