Tasmota/lib/libesp32_eink/epdiy/src/epd4in7.cpp

207 lines
5.2 KiB
C++

/**
* @filename : epd4in2.cpp
* @brief : Implements for Dual-color e-paper library
* @author : Yehui from Waveshare
*
* Copyright (C) Waveshare August 10 2017
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documnetation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <stdlib.h>
#include <epd4in7.h>
#include <freertos/FreeRTOS.h>
#include <freertos/queue.h>
#include <freertos/semphr.h>
#include <freertos/task.h>
#include <esp_attr.h>
#include <esp_assert.h>
#include <esp_heap_caps.h>
#include <esp_log.h>
#include <esp_types.h>
#include <xtensa/core-macros.h>
#include <driver/gpio.h>
#include "epd_driver.h"
#include "epd_highlevel.h"
#define WAVEFORM EPD_BUILTIN_WAVEFORM
uint8_t *epd47_buffer;
int temperature = 25;
EpdiyHighlevelState hl;
uint16_t Epd47::GetColorFromIndex(uint8_t index) {
return index & 0xf;
}
Epd47::Epd47(int16_t dwidth, int16_t dheight) : Renderer(dwidth, dheight) {
width = dwidth;
height = dheight;
disp_bpp = 4;
}
int32_t Epd47::Init(void) {
epd_init(EPD_LUT_1K);
hl = epd_hl_init(WAVEFORM);
epd47_buffer = epd_hl_get_framebuffer(&hl);
framebuffer = epd47_buffer;
lvgl_param.flushlines = 10;
return 0;
}
void Epd47::DisplayInit(int8_t p, int8_t size, int8_t rot, int8_t font) {
if (p == DISPLAY_INIT_MODE) {
epd_poweron();
epd_clear();
epd_poweroff();
}
if (p == DISPLAY_INIT_FULL) {
memset(hl.back_fb, 0xff, width * height / 2);
epd_poweron();
epd_clear();
epd_hl_update_screen(&hl, MODE_GC16, temperature);
epd_poweroff();
return;
}
if (p == DISPLAY_INIT_PARTIAL) {
memset(hl.back_fb, 0xff, width * height / 2);
epd_poweron();
epd_hl_update_screen(&hl, MODE_GL16, temperature);
epd_poweroff();
return;
}
setRotation(rot);
setTextWrap(false);
cp437(true);
setTextFont(font);
setTextSize(size);
setCursor(0,0);
fillScreen(15);
}
void Epd47::Updateframe() {
epd_poweron();
epd_hl_update_screen(&hl, MODE_GL16, temperature);
epd_poweroff();
}
void Epd47::fillScreen(uint16_t color) {
color &= 0xf;
uint8_t icol = (color << 4) | color;
memset(epd47_buffer, icol, width * height / 2);
}
#define _swap(a, b) { uint16_t t = a; a = b; b = t; }
void Epd47::drawPixel(int16_t x, int16_t y, uint16_t color) {
uint16_t xp = x;
uint16_t yp = y;
uint8_t *buf_ptr;
switch (getRotation()) {
case 1:
_swap(xp, yp);
xp = width - xp - 1;
break;
case 2:
xp = width - xp - 1;
yp = height - yp - 1;
break;
case 3:
_swap(xp, yp);
yp = height - yp - 1;
break;
}
if (xp >= width) return;
if (yp >= height) return;
buf_ptr = &epd47_buffer[yp * width / 2 + xp / 2];
if (xp % 2) {
*buf_ptr = (*buf_ptr & 0x0F) | (color << 4);
} else {
*buf_ptr = (*buf_ptr & 0xF0) | (color & 0xf);
}
}
void Epd47::drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color) {
while (h--) {
drawPixel(x , y , color);
y++;
}
}
void Epd47::drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color) {
while (w--) {
drawPixel(x , y , color);
x++;
}
}
void Epd47::setAddrWindow(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1) {
// just save params or update frame
if (!x0 && !y0 && !x1 && !y1) {
//Updateframe();
} else {
seta_xp1 = x0;
seta_xp2 = x1;
seta_yp1 = y0;
seta_yp2 = y1;
}
}
static inline void lvgl_color_swap2(uint16_t *data, uint16_t len) { for (uint32_t i = 0; i < len; i++) (data[i] = data[i] << 8 | data[i] >> 8); }
void Epd47::pushColors(uint16_t *data, uint16_t len, boolean not_swapped) {
if (not_swapped == false) {
lvgl_color_swap2(data, len);
}
// stupid bw version
uint16_t x1 = seta_xp1;
uint16_t x2 = seta_xp2;
uint16_t y1 = seta_yp1;
uint16_t y2 = seta_yp2;
for (uint32_t y = y1; y < y2; y++) {
for (uint32_t x = x1; x < x2; x++) {
uint16_t color = *data++;
uint8_t red = ((color >> 11) & 0x1f) << 3;
uint8_t green = ((color >> 5) & 0x3f) << 2;
uint8_t blue = (color & 0x1f) << 3;
color = (red + green + blue) / 3;
color >>= 4;
drawPixel(x, y, color);
len--;
if (!len) {
seta_yp1 = y + 1;
return;
}
}
}
}
/* END OF FILE */