copy the 2.6 incode code

This commit is contained in:
muyuchl
2025-04-26 15:58:00 +08:00
parent 2c9b333b97
commit ca12f0757b
8 changed files with 1970 additions and 63 deletions

645
epd/epd_ses_266.c Normal file
View File

@@ -0,0 +1,645 @@
#include "epd_ses_266.h"
uint8 part_flag=0;
const unsigned char CODE lut_20_vcom0_full[] =
{
0x00, 0x08, 0x00, 0x00, 0x00, 0x02,
0x60, 0x28, 0x28, 0x00, 0x00, 0x01,
0x00, 0x14, 0x00, 0x00, 0x00, 0x01,
0x00, 0x12, 0x12, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00};
const unsigned char CODE lut_21_ww_full[] =
{
0x40, 0x08, 0x00, 0x00, 0x00, 0x02,
0x90, 0x28, 0x28, 0x00, 0x00, 0x01,
0x40, 0x14, 0x00, 0x00, 0x00, 0x01,
0xA0, 0x12, 0x12, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
const unsigned char CODE lut_22_bw_full[] =
{
0x40, 0x08, 0x00, 0x00, 0x00, 0x02,
0x90, 0x28, 0x28, 0x00, 0x00, 0x01,
0x40, 0x14, 0x00, 0x00, 0x00, 0x01,
0xA0, 0x12, 0x12, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
const unsigned char CODE lut_23_wb_full[] =
{
0x80, 0x08, 0x00, 0x00, 0x00, 0x02,
0x90, 0x28, 0x28, 0x00, 0x00, 0x01,
0x80, 0x14, 0x00, 0x00, 0x00, 0x01,
0x50, 0x12, 0x12, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
const unsigned char CODE lut_24_bb_full[] =
{
0x80, 0x08, 0x00, 0x00, 0x00, 0x02,
0x90, 0x28, 0x28, 0x00, 0x00, 0x01,
0x80, 0x14, 0x00, 0x00, 0x00, 0x01,
0x50, 0x12, 0x12, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
/******************************partial screen update LUT*********************************/
const unsigned char CODE lut_20_vcom0_partial[] =
{
0x00,
0x19,
0x01,
0x00,
0x00,
0x01,
};
const unsigned char CODE lut_21_ww_partial[] =
{
// 10 w
0x00,
0x19,
0x01,
0x00,
0x00,
0x01,
};
const unsigned char CODE lut_22_bw_partial[] =
{
// 10 w
0x80,
0x19,
0x01,
0x00,
0x00,
0x01,
};
const unsigned char CODE lut_23_wb_partial[] =
{
// 01 b
0x40,
0x19,
0x01,
0x00,
0x00,
0x01,
};
const unsigned char CODE lut_24_bb_partial[] =
{
// 01 b
0x00,
0x19,
0x01,
0x00,
0x00,
0x01,
};
void DelayMS(uint msec)
{
uint i,j;
for (i=0; i<msec; i++)
for (j=0; j<535; j++);
}
void SendByte_softSPI(uint8 sdbyte)
{
uint8 i;
for (i = 0; i < 8; i++)
{
EPD_SCLK_L;
if (sdbyte & 0x80)
{
EPD_SDI_H;
}
else
{
EPD_SDI_L;
}
sdbyte <<= 1;
EPD_SCLK_H;
}
EPD_SCLK_L;
}
void EPD_2IN66_SendCommand(uint8 cmd)
{
EPD_DC_L;
EPD_CS_L;
SendByte_softSPI(cmd);
EPD_CS_H;
EPD_DC_H;
}
void EPD_2IN66_SendData(uint8 data)
{
EPD_DC_H;
EPD_CS_L;
SendByte_softSPI(data);
EPD_CS_H;
}
void EPD_2IN66_SendData_Multi(const uint8 *data, uint16 data_size)
{
// EPD_DC_H;
// EPD_CS_L;
while (data_size)
{
EPD_2IN66_SendData((*data++));
data_size--;
}
// EPD_CS_H;
}
void _writeDataPGM(const uint8 *data, uint16 n, uint16 fill_with_zeroes)
{
for (uint16_t i = 0; i < n; i++)
{
EPD_2IN66_SendData(*data++);
}
while (fill_with_zeroes > 0)
{
EPD_2IN66_SendData(0x00);
fill_with_zeroes--;
}
}
void EPD_2IN66_ReadBusy(void)
{
while(!EPD_READ_BUSY){
}
}
void EPD_2IN66_Reset(void)
{
EPD_RST_L;
DelayMS(10);
EPD_RST_H;
DelayMS(10);
}
void EPD_2IN66_TurnOnDisplay(void)
{
if (part_flag)
{
EPD_2IN66_SendCommand(0x92);
}
EPD_2IN66_SendCommand(0x12);
EPD_2IN66_ReadBusy();
}
void EPD_2IN66_TurnOnDisplayEX(void)
{
if (part_flag)
{
EPD_2IN66_SendCommand(0x92);
}
EPD_2IN66_SendCommand(0x12);
}
void _InitDisplay()
{
EPD_2IN66_Reset();
EPD_2IN66_ReadBusy();
EPD_2IN66_SendCommand(0x01); // POWER SETTING
EPD_2IN66_SendData(0x03);
EPD_2IN66_SendData(0x00);
EPD_2IN66_SendData(0x2b);
EPD_2IN66_SendData(0x2b);
EPD_2IN66_SendData(0x03);
EPD_2IN66_SendCommand(0x06); // boost soft start
EPD_2IN66_SendData(0x17); // A
EPD_2IN66_SendData(0x17); // B
EPD_2IN66_SendData(0x17); // C
EPD_2IN66_SendCommand(0x00); // panel setting
EPD_2IN66_SendData(0xbf&(~(1<<3))); // LUT from REG 128x296
// EPD_2IN66_SendData(0x8b); // LUT from REG 128x296
EPD_2IN66_SendData(0x0d); // VCOM to 0V fast
EPD_2IN66_SendCommand(0x30); // PLL setting
EPD_2IN66_SendData(0x3a); // 3a 100HZ 29 150Hz 39 200HZ 31 171HZ
EPD_2IN66_SendCommand(0x61); // resolution setting
EPD_2IN66_SendData(EPD_2IN66_WIDTH);
EPD_2IN66_SendData(EPD_2IN66_HEIGHT / 256);
EPD_2IN66_SendData(EPD_2IN66_HEIGHT % 256);
EPD_2IN66_SendCommand(0x82); // vcom_DC setting
// EPD_2IN66_SendData (0x00); // -0.1
// EPD_2IN66_SendData (0x08); // -0.1 + 8 * -0.05 = -0.5V from demo
// EPD_2IN66_SendData (0x12); // -0.1 + 18 * -0.05 = -1.0V from OTP, slightly better
EPD_2IN66_SendData(0x1c); // -0.1 + 28 * -0.05 = -1.5V test, better
// EPD_2IN66_SendData (0x26); // -0.1 + 38 * -0.05 = -2.0V test, same
// EPD_2IN66_SendData (0x30); // -0.1 + 48 * -0.05 = -2.5V test, darker
// EPD_2IN66_SendCommand(0xe0); // resolution setting
// EPD_2IN66_SendData(0x02);
// EPD_2IN66_SendCommand(0xe5); // resolution setting
// EPD_2IN66_SendData(0x32);
EPD_2IN66_SendCommand(0x50); // VCOM AND DATA INTERVAL SETTING
EPD_2IN66_SendData(0x17); // WBmode:VBDF 17|D7 VBDW 97 VBDB 57 WBRmode:VBDF F7 VBDW 77 VBDB 37 VBDR B7
}
static void EPD_2IN66_SetLUA(const uint8_t *data, uint16_t n)
{
uint16_t count;
for (count = 0; count < n; count++)
{
EPD_2IN66_SendData(*(data + count));
}
}
void EPD_2IN66_Init(void)
{
part_flag = 0;
_InitDisplay();
EPD_2IN66_SendCommand(0x20);
EPD_2IN66_SetLUA((const uint8 *)lut_20_vcom0_full, sizeof(lut_20_vcom0_full));
EPD_2IN66_SendCommand(0x21);
EPD_2IN66_SetLUA((const uint8 *)lut_21_ww_full, sizeof(lut_21_ww_full));
EPD_2IN66_SendCommand(0x22);
EPD_2IN66_SetLUA((const uint8 *)lut_22_bw_full, sizeof(lut_22_bw_full));
EPD_2IN66_SendCommand(0x23);
EPD_2IN66_SetLUA((const uint8 *)lut_23_wb_full, sizeof(lut_23_wb_full));
EPD_2IN66_SendCommand(0x24);
EPD_2IN66_SetLUA((const uint8 *)lut_24_bb_full, sizeof(lut_24_bb_full));
EPD_2IN66_SendCommand(0x04); // POWER ON
EPD_2IN66_ReadBusy();
}
void EPD_2IN66_Init_Partial(void)
{
part_flag = 1;
_InitDisplay();
EPD_2IN66_SendCommand(0x20);
_writeDataPGM((const uint8 *)lut_20_vcom0_partial, sizeof(lut_20_vcom0_partial), 44 - sizeof(lut_20_vcom0_partial));
EPD_2IN66_SendCommand(0x21);
_writeDataPGM((const uint8 *)lut_21_ww_partial, sizeof(lut_21_ww_partial), 42 - sizeof(lut_21_ww_partial));
EPD_2IN66_SendCommand(0x22);
_writeDataPGM((const uint8 *)lut_22_bw_partial, sizeof(lut_22_bw_partial), 42 - sizeof(lut_22_bw_partial));
EPD_2IN66_SendCommand(0x23);
_writeDataPGM((const uint8 *)lut_23_wb_partial, sizeof(lut_23_wb_partial), 42 - sizeof(lut_23_wb_partial));
EPD_2IN66_SendCommand(0x24);
_writeDataPGM((const uint8 *)lut_24_bb_partial, sizeof(lut_24_bb_partial), 42 - sizeof(lut_24_bb_partial));
EPD_2IN66_SendCommand(0x04); // POWER ON
EPD_2IN66_ReadBusy();
EPD_2IN66_SendCommand(0x91); // This command makes the display enter partial mode
EPD_2IN66_SendCommand(0x90); // resolution setting
EPD_2IN66_SendData(0); // x-start
EPD_2IN66_SendData(EPD_2IN66_WIDTH - 1); // x-end
EPD_2IN66_SendData(0);
EPD_2IN66_SendData(0); // y-start
EPD_2IN66_SendData(EPD_2IN66_HEIGHT / 256);
EPD_2IN66_SendData(EPD_2IN66_HEIGHT % 256 - 1); // y-end
EPD_2IN66_SendData(0x28);
}
void EPD_2IN66_Clear(void)
{
unsigned int i;
// Write Data
EPD_2IN66_SendCommand(0x10); // Transfer old data
for (i = 0; i < (EPD_2IN66_WIDTH / 8) * EPD_2IN66_HEIGHT; i++)
{
EPD_2IN66_SendData(0x00);
}
EPD_2IN66_SendCommand(0x13); // Transfer new data
for (i = 0; i < (EPD_2IN66_WIDTH / 8) * EPD_2IN66_HEIGHT; i++)
{
EPD_2IN66_SendData(0xFF); // Transfer the actual displayed data
}
// Refresh
EPD_2IN66_TurnOnDisplay();
}
/*
* Image 为NULL发送0xFF isold 1发送OLD RAM 0发送NEW RAM
*/
void EPD_2IN66_part_Display(const uint8 *Image, uint8_t isold)
{
uint16 Width, Height;
Width = (EPD_2IN66_WIDTH % 8 == 0) ? (EPD_2IN66_WIDTH / 8) : (EPD_2IN66_WIDTH / 8 + 1);
Height = EPD_2IN66_HEIGHT;
volatile uint16 Addr = 0;
EPD_2IN66_SendCommand(isold == 1 ? 0x10 : 0x13);
if (Image != NULL)
{
EPD_2IN66_SendData_Multi(Image, Height * Width);
}
else
{
for (int j = 0; j < Height; j++)
{
for (int i = 0; i < Width; i++)
{
Addr = i + j * Width;
EPD_2IN66_SendData(0xFF);
}
}
}
}
/******************************************************************************
function : Sends the image buffer in RAM to e-Paper and displays
parameter:
******************************************************************************/
void EPD_2IN66_Display(uint8 *Image)
{
EPD_2IN66_part_Display(NULL, 1);
EPD_2IN66_part_Display(Image, 0);
EPD_2IN66_SendCommand(0x11);
}
/******************************************************************************
function : Enter sleep mode
parameter:
******************************************************************************/
void EPD_2IN66_Sleep(void)
{
EPD_2IN66_SendCommand(0X50);
EPD_2IN66_SendData(0xf7);
EPD_2IN66_SendCommand(0X02);
EPD_2IN66_ReadBusy();
EPD_2IN66_SendCommand(0x07);
EPD_2IN66_SendData(0xA5);
}
/**
* @brief 向EPD控制器发送指定大小的显示数据。
* @param data 要发送数据的指针。
* @param data_size 要发送数据的大小。
*/
void EPD_SendData_Multi(const uint8 *data, uint16 data_size, uint8 Inverse)
{
EPD_DC_H;
EPD_CS_L;
if (data == NULL)
{
for (uint i = 0; i < data_size; i++)
{
SendByte_softSPI(Inverse == 1 ? 0x00 : 0xff);
}
}
else
{
for (uint i = 0; i < data_size; i++)
{
SendByte_softSPI(Inverse == 1 ? ~data[i] : data[i]);
}
}
EPD_CS_H;
}
/**
* @brief 设置EPD显示窗口位置和大小。
* @param x 显示窗口起始X位置。
* @param y_x8 显示窗口起始Y位置设置1等于8像素。
* @param x_size 显示窗口X方向大小。
* @param y_size_x8 显示窗口Y方向大小设置1等于8像素。
* @note 指针已被自动设置至窗口的左上角。
*/
void EPD_SetWindow(uint16 x, uint8 y_x8, uint16 x_size, uint8 y_size_x8)
{
}
/**
* @brief 绘制UTF8字符串。
* @param x 绘制起始X位置。
* @param y_x8 绘制起始Y位置设置1等于8像素。
* @param gap 字符间额外间距。
* @param str 要绘制的字符串指针。
* @param ascii_font ASCII字符字模指针。
* @param utf8_font UTF8字符字模指针。
* @param ramX 写ram选择 1新 2旧 。
* @note 调用的文件必须是utf-8编码 否则中文会错误
*/
#define Interval_Ascii_Utf8 0 //ASCII字符与UTF8的间隔
void EPD_DrawFonts(uint16 x, uint8 y_x8, uint8 gap, const char *str, const epdFONT_ascii *ascii_font,
const epdFONT_utf8 *utf8_font,uint8 ramX)
{
uint8 i = 0, utf8_size = 0;
uint16 x_count = 0, font_size = 0;
const uint8 *ascii_base_addr = NULL;
uint32 unicode = 0, unicodeemp = 0;
x_count = 0;
while (*str != '\0')
{
if ((*str & 0x80) == 0x00) /* 普通ASCII字符 */
{
if (ascii_font != NULL)
{
font_size = ascii_font->Width * ascii_font->Hight / 8;
ascii_base_addr = ascii_font->fp + (*str - ascii_font->StartChar) * font_size;
if ((*str - ascii_font->StartChar) >= 0
&& ascii_base_addr + font_size <= ascii_font->fp + font_size * ascii_font->num) /* 限制数组范围 */
{
EPD_draw(x + x_count, y_x8, ascii_font->Width, ascii_font->Hight / 8,ascii_base_addr,ramX);
// EPD_SetWindow(x + x_count, y_x8, ascii_font->Width, ascii_font->Hight / 8);
// EPD_SendRAM(ascii_base_addr, font_size);
}
else
{
EPD_draw(x + x_count, y_x8, ascii_font->Width, ascii_font->Hight / 8,NULL,ramX);
// font_size = (ascii_font->Width) * (ascii_font->Hight / 8);
// EPD_SetWindow(x + x_count, y_x8, ascii_font->Width, ascii_font->Hight / 8);
// for (i = 0; i < font_size; i++)
// {
// utf8_size = 0xFF; /* 借用变量 */
// EPD_SendRAM(&utf8_size, 1);
// }
}
x_count += ascii_font->Width + gap;
}
else if (*str == ' ' && utf8_font != NULL) /* 未指定ASCII字体时空格为UTF8字体宽度除2 */
{
EPD_draw(x + x_count, y_x8, ascii_font->Width, ascii_font->Hight / 8,NULL,ramX);
// font_size = (utf8_font->Width / 2) * (utf8_font->Hight / 8);
// EPD_SetWindow(x + x_count, y_x8, utf8_font->Width / 2, utf8_font->Hight / 8);
// for (i = 0; i < font_size; i++)
// {
// utf8_size = 0xFF; /* 借用变量 */
// EPD_SendRAM(&utf8_size, 1);
// }
x_count += utf8_font->Width / 2 + gap;
}
}
else if (utf8_font != NULL) /* UTF8字符 */
{
unicode = 0x000000;
utf8_size = 0;
for (i = 0; i < 5; i++)
{
if (*str & (0x80 >> i))
{
utf8_size += 1;
}
else
{
break;
}
}
switch (utf8_size)
{
case 2:
if (*(str + 1) != '\0')
{
unicode = ((uint32) (*str & 0x1F)) << 6;
str += 1;
unicode |= (uint32) *str & 0x3F;
}
break;
case 3:
if (*(str + 1) != '\0' && *(str + 2) != '\0')
{
unicode = ((uint32) (*str & 0x0F)) << 12;
str += 1;
unicode |= ((uint32) (*str & 0x3F)) << 6;
str += 1;
unicode |= (uint32) *str & 0x3F;
}
break;
case 4:
if (*(str + 1) != '\0' && *(str + 2) != '\0' && *(str + 3) != '\0')
{
unicode = ((uint32) (*str & 0x07)) << 18;
str += 1;
unicode |= ((uint32) (*str & 0x3F)) << 12;
str += 1;
unicode |= ((uint32) (*str & 0x3F)) << 6;
str += 1;
unicode |= (uint32) *str & 0x3F;
}
break;
}
if (unicode != 0)
{
font_size = utf8_font->Width * utf8_font->Hight / 8;
for (i = 0; i < utf8_font->num; i++) /* 限制数组范围 */
{
unicodeemp = (uint32) utf8_font->fp[0 + (font_size + 3) * i] << 16;
unicodeemp |= (uint32) utf8_font->fp[1 + (font_size + 3) * i] << 8;
unicodeemp |= (uint32) utf8_font->fp[2 + (font_size + 3) * i];
if (unicodeemp == unicode)
{
EPD_draw(x + x_count + Interval_Ascii_Utf8, y_x8, utf8_font->Width, utf8_font->Hight / 8,utf8_font->fp + 3 + (font_size + 3) * i,ramX);
// EPD_SetWindow(x + x_count + Interval_Ascii_Utf8, y_x8, utf8_font->Width, utf8_font->Hight / 8);
// EPD_SendRAM(utf8_font->fp + 3 + (font_size + 3) * i, font_size);
break;
}
}
}
x_count += utf8_font->Width + gap;
}
str += 1;
}
}
void EPD_draw(uint16 x, uint8 y_x8, uint16 x_size, uint8 y_size_x8, const uint8 *dat, uint8 ramX)
{
uint16 data_size = x_size * y_size_x8;
EPD_2IN66_SendCommand(0x90);
EPD_2IN66_SendData(y_x8 << 3);
EPD_2IN66_SendData(((y_x8 + y_size_x8) << 3) - 1);
EPD_2IN66_SendData((x >> 8) & 0xff);
EPD_2IN66_SendData(x & 0xff);
EPD_2IN66_SendData(((x + x_size) >> 8) & 0xff);
EPD_2IN66_SendData((x + x_size) & 0xff);
if (dat == NULL)
{
if (ramX & 1)
{
EPD_2IN66_SendCommand(0x10);
EPD_SendData_Multi(dat, data_size, 1);
}
if (ramX & 2)
{
EPD_2IN66_SendCommand(0x13);
EPD_SendData_Multi(dat, data_size, 0);
}
}
else
{
if (ramX & 1)
{
EPD_2IN66_SendCommand(0x10);
EPD_SendData_Multi(dat, data_size, 1);
}
if (ramX & 2)
{
EPD_2IN66_SendCommand(0x13);
EPD_SendData_Multi(dat, data_size,0);
}
}
}
const uint8_t CODE *Battery_ICON[] = {Bitmap_bat0, Bitmap_bat20, Bitmap_bat40, Bitmap_bat60, Bitmap_bat80, Bitmap_bat100};
void Draw_Battery(uint16_t x, uint8_t y, uint16_t max_voltage, uint16_t min_voltage, uint16_t voltage)
{
const uint8_t * battery = NULL;
uint16_t voltage_size =0;
if (voltage <= min_voltage)
{
battery =(const uint8_t *) Bitmap_bat0;
goto END;
}
if (voltage >= max_voltage)
{
battery = (const uint8_t *)Bitmap_bat100;
goto END;
}
voltage_size = (uint16_t)(max_voltage - min_voltage);
for (int i = 1; i < sizeof(Battery_ICON); i++)
{
if ((voltage_size * i / 5 + min_voltage) >= voltage)
{
battery = (const uint8_t *)Battery_ICON[i];
break;
}
}
END:
EPD_draw(x, y, 27, 2, battery,3);
}