Added support for 3 Color ESL BWR

This commit is contained in:
atc1441
2022-04-29 18:46:35 +02:00
parent 4c2f621e95
commit c7f4054abc
12 changed files with 648 additions and 240 deletions

1
.gitignore vendored
View File

@@ -4,3 +4,4 @@ Firmware/tc32_windows
flashing
flash.bat
Firmware_test_gpio
.vscode

Binary file not shown.

View File

@@ -1,7 +1,7 @@
TEL_CHIP := -DCHIP_TYPE=CHIP_TYPE_8258
ifeq ($(OS), Windows_NT)
TC32_COMPILER_PATH := tc32_windows\\bin\\
TC32_COMPILER_PATH := "tc32_windows\\bin\\"
WINDOWS_PREFIX :=$(TC32_COMPILER_PATH)
LINUX_CHMOD :=
else

View File

@@ -2,6 +2,9 @@
#include "tl_common.h"
#include "main.h"
#include "epd.h"
#include "epd_spi.h"
#include "epd_bw.h"
#include "epd_bwr.h"
#include "drivers.h"
#include "stack/ble/ble.h"
@@ -15,8 +18,11 @@ extern const uint8_t ucMirror[];
#include "font16.h"
#include "font30.h"
RAM uint8_t epd_model = 0; // 0 = Undetected, 1 = BW, 2 = BWR
const char* epd_model_string[] = {"NC","BW","BWR"};
RAM uint8_t epd_update_state = 0;
const char* BLE_conn_string[] = {"", "B"};
RAM uint8_t epd_temperature_is_read = 0;
RAM uint8_t epd_temperature = 0;
@@ -25,279 +31,101 @@ uint8_t epd_temp[epd_buffer_size]; // for OneBitDisplay to draw into
OBDISP obd; // virtual display structure
TIFFIMAGE tiff;
#define _refresh_time 10
uint8_t lut_20_part[] =
{
0x20, 0x00, _refresh_time, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
uint8_t lut_21_part[] =
{
0x21, 0x00, _refresh_time, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
uint8_t lut_22_part[] =
{
0x22, 0x80, _refresh_time, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
uint8_t lut_23_part[] =
{
0x23, 0x40, _refresh_time, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
uint8_t lut_24_part[] =
{
0x24, 0x00, _refresh_time, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
#define EPD_POWER_ON() gpio_write(EPD_ENABLE, 0)
#define EPD_POWER_OFF() gpio_write(EPD_ENABLE, 1)
#define EPD_ENABLE_WRITE_CMD() gpio_write(EPD_DC, 0)
#define EPD_ENABLE_WRITE_DATA() gpio_write(EPD_DC, 1)
#define EPD_IS_BUSY() (!gpio_read(EPD_BUSY))
_attribute_ram_code_ void EPD_SPI_Write(unsigned char value)
// Here we detect what E-Paper display is connected
_attribute_ram_code_ void EPD_detect_model(void)
{
unsigned char i;
EPD_init();
// system power
EPD_POWER_ON();
WaitUs(10);
for (i = 0; i < 8; i++)
WaitMs(10);
// Reset the EPD driver IC
gpio_write(EPD_RESET, 0);
WaitMs(10);
gpio_write(EPD_RESET, 1);
WaitMs(10);
// Here we neeed to detect it
if (EPD_BWR_detect())
{
gpio_write(EPD_CLK, 0);
if (value & 0x80)
{
gpio_write(EPD_MOSI, 1);
}
else
{
gpio_write(EPD_MOSI, 0);
}
value = (value << 1);
gpio_write(EPD_CLK, 1);
epd_model = 2;
}
}
_attribute_ram_code_ uint8_t EPD_SPI_read(void)
{
unsigned char i;
uint8_t value = 0;
gpio_shutdown(EPD_MOSI);
gpio_set_output_en(EPD_MOSI, 0);
gpio_set_input_en(EPD_MOSI, 1);
gpio_write(EPD_CS, 0);
EPD_ENABLE_WRITE_DATA();
WaitUs(10);
for (i = 0; i < 8; i++)
else
{
value <<= 1;
if (gpio_read(EPD_MOSI) != 0)
{
value |= 1;
}
gpio_write(EPD_CLK, 1);
gpio_write(EPD_CLK, 0);
epd_model = 1;
}
gpio_set_output_en(EPD_MOSI, 1);
gpio_set_input_en(EPD_MOSI, 0);
gpio_write(EPD_CS, 1);
return value;
}
_attribute_ram_code_ void EPD_WriteCmd(unsigned char cmd)
{
gpio_write(EPD_CS, 0);
EPD_ENABLE_WRITE_CMD();
EPD_SPI_Write(cmd);
gpio_write(EPD_CS, 1);
}
_attribute_ram_code_ void EPD_WriteData(unsigned char data)
{
gpio_write(EPD_CS, 0);
EPD_ENABLE_WRITE_DATA();
EPD_SPI_Write(data);
gpio_write(EPD_CS, 1);
}
_attribute_ram_code_ void EPD_CheckStatus(void)
{
while (EPD_IS_BUSY())
{
}
}
_attribute_ram_code_ void _send_lut(uint8_t lut[])
{
EPD_WriteCmd(lut[0]);
for (int r = 1; r <= sizeof(lut_20_part); r++)
{
EPD_WriteData(lut[r]);
}
}
_attribute_ram_code_ void _send_empty_lut(uint8_t lut)
{
EPD_WriteCmd(lut);
for (int r = 0; r <= 260; r++)
EPD_WriteData(0x00);
}
_attribute_ram_code_ void EPD_LoadImage(unsigned char *image, int size)
{
int i;
EPD_WriteCmd(0x13);
for (i = 0; i < size; i++)
{
EPD_WriteData(image[i]);
}
WaitMs(2);
}
_attribute_ram_code_ void init_epd(void)
{
gpio_set_func(EPD_RESET, AS_GPIO);
gpio_set_output_en(EPD_RESET, 1);
gpio_setup_up_down_resistor(EPD_RESET, PM_PIN_PULLUP_1M);
gpio_set_func(EPD_DC, AS_GPIO);
gpio_set_output_en(EPD_DC, 1);
gpio_setup_up_down_resistor(EPD_DC, PM_PIN_PULLUP_1M);
gpio_set_func(EPD_BUSY, AS_GPIO);
gpio_set_output_en(EPD_BUSY, 0);
gpio_set_input_en(EPD_BUSY, 1);
gpio_setup_up_down_resistor(EPD_BUSY, PM_PIN_PULLUP_1M);
gpio_set_func(EPD_CS, AS_GPIO);
gpio_set_output_en(EPD_CS, 1);
gpio_setup_up_down_resistor(EPD_CS, PM_PIN_PULLUP_1M);
gpio_set_func(EPD_CLK, AS_GPIO);
gpio_set_output_en(EPD_CLK, 1);
gpio_setup_up_down_resistor(EPD_CLK, PM_PIN_PULLUP_1M);
gpio_set_func(EPD_MOSI, AS_GPIO);
gpio_set_output_en(EPD_MOSI, 1);
gpio_setup_up_down_resistor(EPD_MOSI, PM_PIN_PULLUP_1M);
gpio_set_output_en(EPD_ENABLE, 0);
gpio_set_input_en(EPD_ENABLE, 1);
gpio_setup_up_down_resistor(EPD_ENABLE, PM_PIN_PULLUP_1M);
EPD_POWER_OFF();
}
_attribute_ram_code_ uint8_t EPD_read_temp(void)
{
if (epd_temperature_is_read)
return epd_temperature;
if (!epd_model)
{
EPD_detect_model();
}
init_epd();
EPD_init();
// system power
EPD_POWER_ON();
WaitMs(5);
// Reset the EPD driver IC
gpio_write(EPD_RESET, 0);
WaitMs(10);
gpio_write(EPD_RESET, 1);
WaitMs(10);
// power on
EPD_WriteCmd(0x04);
// check BUSY pin
EPD_CheckStatus();
EPD_WriteCmd(0x40);
epd_temperature = EPD_SPI_read();
EPD_SPI_read();
epd_temperature_is_read = 1;
// power off
EPD_WriteCmd(0x02);
// deep sleep
EPD_WriteCmd(0x07);
EPD_WriteData(0xa5);
if (epd_model == 1)
epd_temperature = EPD_BW_read_temp();
else if (epd_model == 2)
epd_temperature = EPD_BWR_read_temp();
EPD_POWER_OFF();
epd_temperature_is_read = 1;
return epd_temperature;
}
_attribute_ram_code_ void EPD_Display(unsigned char *image, int size, uint8_t full_or_partial)
{
if (!epd_model)
{
EPD_detect_model();
}
init_epd();
EPD_init();
// system power
EPD_POWER_ON();
WaitMs(5);
// Reset the EPD driver IC
gpio_write(EPD_RESET, 0);
WaitMs(10);
gpio_write(EPD_RESET, 1);
WaitMs(10);
// Booster soft start
EPD_WriteCmd(0x06);
EPD_WriteData(0x17);
EPD_WriteData(0x17);
EPD_WriteData(0x17);
// power on
EPD_WriteCmd(0x04);
// check BUSY pin
EPD_CheckStatus();
if (epd_model == 1)
epd_temperature = EPD_BW_Display(image, size, full_or_partial);
else if (epd_model == 2)
epd_temperature = EPD_BWR_Display(image, size, full_or_partial);
EPD_WriteCmd(0x40);
epd_temperature = EPD_SPI_read();
EPD_SPI_read();
epd_temperature_is_read = 1;
// panel setting
EPD_WriteCmd(0x00);
if (full_or_partial)
EPD_WriteData(0b00011111);
else
EPD_WriteData(0b00111111);
EPD_WriteData(0x0f);
// resolution setting
EPD_WriteCmd(0x61);
EPD_WriteData(0x80);
EPD_WriteData(0x01);
EPD_WriteData(0x28);
// Vcom and data interval setting
EPD_WriteCmd(0X50);
EPD_WriteData(0x97);
if (!full_or_partial)
{
_send_lut(lut_20_part);
_send_empty_lut(0x21); //_send_lut(lut_21_part);
_send_lut(lut_22_part);
_send_lut(lut_23_part);
_send_empty_lut(0x24); //_send_lut(lut_24_part);
EPD_WriteCmd(0x10);
int i;
for (i = 0; i < size; i++)
{
EPD_WriteData(~epd_buffer[i]);
}
}
// load image data to EPD
EPD_LoadImage(image, size);
// trigger display refresh
EPD_WriteCmd(0x12);
epd_update_state = 1;
}
_attribute_ram_code_ void epd_set_sleep(void)
{
// Vcom and data interval setting
EPD_WriteCmd(0x50);
EPD_WriteData(0xf7);
if (!epd_model)
{
EPD_detect_model();
}
// power off
EPD_WriteCmd(0x02);
// deep sleep
EPD_WriteCmd(0x07);
EPD_WriteData(0xa5);
if (epd_model == 1)
EPD_BW_set_sleep();
else if (epd_model == 2)
EPD_BWR_set_sleep();
EPD_POWER_OFF();
epd_update_state = 0;
@@ -311,8 +139,16 @@ _attribute_ram_code_ uint8_t epd_state_handler(void)
// Nothing todo
break;
case 1: // check if refresh is done and sleep epd if so
if (!EPD_IS_BUSY())
epd_set_sleep();
if (epd_model == 1)
{
if (!EPD_IS_BUSY())
epd_set_sleep();
}
else
{
if (EPD_IS_BUSY())
epd_set_sleep();
}
break;
}
return epd_update_state;
@@ -358,7 +194,7 @@ _attribute_ram_code_ void TIFFDraw(TIFFDRAW *pDraw)
}
ucSrcMask >>= 1;
}
} /* TIFFDraw() */
}
_attribute_ram_code_ void epd_display_tiff(uint8_t *pData, int iSize)
{
@@ -369,7 +205,7 @@ _attribute_ram_code_ void epd_display_tiff(uint8_t *pData, int iSize)
TIFF_decode(&tiff);
TIFF_close(&tiff);
EPD_Display(epd_buffer, epd_buffer_size, 1);
} /* epd_display_tiff() */
}
extern uint8_t mac_public[6];
_attribute_ram_code_ void epd_display(uint32_t time_is, uint16_t battery_mv, int16_t temperature, uint8_t full_or_partial)
@@ -380,8 +216,10 @@ _attribute_ram_code_ void epd_display(uint32_t time_is, uint16_t battery_mv, int
obdFill(&obd, 0, 0); // fill with white
char buff[100];
sprintf(buff, "ESL_%02X%02X%02X", mac_public[2],mac_public[1],mac_public[0]);
sprintf(buff, "ESL_%02X%02X%02X - %s", mac_public[2], mac_public[1], mac_public[0], epd_model_string[epd_model]);
obdWriteStringCustom(&obd, (GFXfont *)&Dialog_plain_16, 1, 17, (char *)buff, 1);
sprintf(buff, "%s", BLE_conn_string[ble_get_connected()]);
obdWriteStringCustom(&obd, (GFXfont *)&Dialog_plain_16, 232, 20, (char *)buff, 1);
sprintf(buff, "%02d:%02d", ((time_is / 60) / 60) % 24, (time_is / 60) % 60);
obdWriteStringCustom(&obd, (GFXfont *)&DSEG14_Classic_Mini_Regular_40, 50, 65, (char *)buff, 1);
sprintf(buff, "%d'C", EPD_read_temp());
@@ -390,7 +228,7 @@ _attribute_ram_code_ void epd_display(uint32_t time_is, uint16_t battery_mv, int
obdWriteStringCustom(&obd, (GFXfont *)&Dialog_plain_16, 10, 120, (char *)buff, 1);
FixBuffer(epd_temp, epd_buffer);
EPD_Display(epd_buffer, epd_buffer_size, full_or_partial);
} /* epd_display() */
}
_attribute_ram_code_ void epd_display_char(uint8_t data)
{

View File

@@ -4,13 +4,6 @@
#define epd_width 250
#define epd_buffer_size ((epd_height/8) * epd_width)
void EPD_DLY_LP(unsigned int ms);
void EPD_SPI_Write(unsigned char value);
uint8_t EPD_SPI_read(void);
void EPD_WriteCmd(unsigned char cmd);
void EPD_WriteData(unsigned char data);
void EPD_CheckStatus(void);
void EPD_LoadImage(unsigned char *image, int size);
void init_epd(void);
uint8_t EPD_read_temp(void);
void EPD_Display(unsigned char *image, int size, uint8_t full_or_partial);

123
Firmware/src/epd_bw.c Normal file
View File

@@ -0,0 +1,123 @@
#include <stdint.h>
#include "tl_common.h"
#include "main.h"
#include "epd.h"
#include "epd_spi.h"
#include "epd_bw.h"
#include "drivers.h"
#include "stack/ble/ble.h"
// UC8151C or similar EPD Controller
#define _refresh_time 10
uint8_t lut_20_part[] =
{
0x20, 0x00, _refresh_time, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
uint8_t lut_22_part[] =
{
0x22, 0x80, _refresh_time, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
uint8_t lut_23_part[] =
{
0x23, 0x40, _refresh_time, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
_attribute_ram_code_ uint8_t EPD_BW_read_temp(void)
{
uint8_t epd_temperature = 0 ;
EPD_WriteCmd(0x04);
// check BUSY pin
EPD_CheckStatus(100);
EPD_WriteCmd(0x40);
epd_temperature = EPD_SPI_read();
EPD_SPI_read();
// power off
EPD_WriteCmd(0x02);
// deep sleep
EPD_WriteCmd(0x07);
EPD_WriteData(0xa5);
return epd_temperature;
}
_attribute_ram_code_ uint8_t EPD_BW_Display(unsigned char *image, int size, uint8_t full_or_partial)
{
uint8_t epd_temperature = 0 ;
// Booster soft start
EPD_WriteCmd(0x06);
EPD_WriteData(0x17);
EPD_WriteData(0x17);
EPD_WriteData(0x17);
// power on
EPD_WriteCmd(0x04);
// check BUSY pin
EPD_CheckStatus(100);
EPD_WriteCmd(0x40);
epd_temperature = EPD_SPI_read();
EPD_SPI_read();
// panel setting
EPD_WriteCmd(0x00);
if (full_or_partial)
EPD_WriteData(0b00011111);
else
EPD_WriteData(0b00111111);
EPD_WriteData(0x0f);
// resolution setting
EPD_WriteCmd(0x61);
EPD_WriteData(0x80);
EPD_WriteData(0x01);
EPD_WriteData(0x28);
// Vcom and data interval setting
EPD_WriteCmd(0X50);
EPD_WriteData(0x97);
if (!full_or_partial)
{
EPD_send_lut(lut_20_part, sizeof(lut_20_part));
EPD_send_empty_lut(0x21, 260);
EPD_send_lut(lut_22_part, sizeof(lut_22_part));
EPD_send_lut(lut_23_part, sizeof(lut_23_part));
EPD_send_empty_lut(0x24, 260);
EPD_WriteCmd(0x10);
int i;
for (i = 0; i < size; i++)
{
EPD_WriteData(~image[i]);
}
}
// load image data to EPD
EPD_LoadImage(image, size, 0x13);
// trigger display refresh
EPD_WriteCmd(0x12);
return epd_temperature;
}
_attribute_ram_code_ void EPD_BW_set_sleep(void)
{
// Vcom and data interval setting
EPD_WriteCmd(0x50);
EPD_WriteData(0xf7);
// power off
EPD_WriteCmd(0x02);
// deep sleep
EPD_WriteCmd(0x07);
EPD_WriteData(0xa5);
}

5
Firmware/src/epd_bw.h Normal file
View File

@@ -0,0 +1,5 @@
#pragma once
uint8_t EPD_BW_read_temp(void);
uint8_t EPD_BW_Display(unsigned char *image, int size, uint8_t full_or_partial);
void EPD_BW_set_sleep(void);

267
Firmware/src/epd_bwr.c Normal file
View File

@@ -0,0 +1,267 @@
#include <stdint.h>
#include "tl_common.h"
#include "main.h"
#include "epd.h"
#include "epd_spi.h"
#include "epd_bwr.h"
#include "drivers.h"
#include "stack/ble/ble.h"
// SSD1675 mixed with SSD1680 EPD Controller
#define BWR_Len 50
uint8_t LUT_bwr_part[] = {
0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
BWR_Len, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
0x00, 0x00, 0x00,
};
#define EPD_BWR_test_pattern 0xA5
_attribute_ram_code_ uint8_t EPD_BWR_detect(void)
{
// SW Reset
EPD_WriteCmd(0x12);
WaitMs(10);
EPD_WriteCmd(0x32);
int i;
for (i = 0; i < 10; i++)
{
EPD_WriteData(EPD_BWR_test_pattern);
}
EPD_WriteCmd(0x33);
for (i = 0; i < 10; i++)
{
if(EPD_SPI_read() != EPD_BWR_test_pattern)
return 0;
}
return 1;
}
_attribute_ram_code_ uint8_t EPD_BWR_read_temp(void)
{
uint8_t epd_temperature = 0 ;
// SW Reset
EPD_WriteCmd(0x12);
EPD_CheckStatus_inverted(100);
// Set Analog Block control
EPD_WriteCmd(0x74);
EPD_WriteData(0x54);
// Set Digital Block control
EPD_WriteCmd(0x7E);
EPD_WriteData(0x3B);
// Booster soft start
EPD_WriteCmd(0x0C);
EPD_WriteData(0x8B);
EPD_WriteData(0x9C);
EPD_WriteData(0x96);
EPD_WriteData(0x0F);
// Driver output control
EPD_WriteCmd(0x01);
EPD_WriteData(0x28);
EPD_WriteData(0x01);
EPD_WriteData(0x01);
// Data entry mode setting
EPD_WriteCmd(0x11);
EPD_WriteData(0x01);
// Set RAM X- Address Start/End
EPD_WriteCmd(0x44);
EPD_WriteData(0x00);
EPD_WriteData(0x0F);
// Set RAM Y- Address Start/End
EPD_WriteCmd(0x45);
EPD_WriteData(0x28);
EPD_WriteData(0x01);
EPD_WriteData(0x2E);
EPD_WriteData(0x00);
// Border waveform control
EPD_WriteCmd(0x3C);
EPD_WriteData(0x05);
// Display update control
EPD_WriteCmd(0x21);
EPD_WriteData(0x00);
EPD_WriteData(0x80);
// Temperature sensor control
EPD_WriteCmd(0x18);
EPD_WriteData(0x80);
// Display update control
EPD_WriteCmd(0x22);
EPD_WriteData(0xB1);
// Master Activation
EPD_WriteCmd(0x20);
EPD_CheckStatus_inverted(100);
// Temperature sensor read from register
EPD_WriteCmd(0x1B);
epd_temperature = EPD_SPI_read();
EPD_SPI_read();
WaitMs(5);
// deep sleep
EPD_WriteCmd(0x10);
EPD_WriteData(0x01);
return epd_temperature;
}
_attribute_ram_code_ uint8_t EPD_BWR_Display(unsigned char *image, int size, uint8_t full_or_partial)
{
uint8_t epd_temperature = 0 ;
// SW Reset
EPD_WriteCmd(0x12);
EPD_CheckStatus_inverted(100);
// Set Analog Block control
EPD_WriteCmd(0x74);
EPD_WriteData(0x54);
// Set Digital Block control
EPD_WriteCmd(0x7E);
EPD_WriteData(0x3B);
// Booster soft start
EPD_WriteCmd(0x0C);
EPD_WriteData(0x8B);
EPD_WriteData(0x9C);
EPD_WriteData(0x96);
EPD_WriteData(0x0F);
// Driver output control
EPD_WriteCmd(0x01);
EPD_WriteData(0x28);
EPD_WriteData(0x01);
EPD_WriteData(0x01);
// Data entry mode setting
EPD_WriteCmd(0x11);
EPD_WriteData(0x01);
// Set RAM X- Address Start/End
EPD_WriteCmd(0x44);
EPD_WriteData(0x00);
EPD_WriteData(0x0F);
// Set RAM Y- Address Start/End
EPD_WriteCmd(0x45);
EPD_WriteData(0x28);
EPD_WriteData(0x01);
EPD_WriteData(0x2E);
EPD_WriteData(0x00);
// Border waveform control
EPD_WriteCmd(0x3C);
EPD_WriteData(0x05);
// Display update control
EPD_WriteCmd(0x21);
EPD_WriteData(0x00);
EPD_WriteData(0x80);
// Temperature sensor control
EPD_WriteCmd(0x18);
EPD_WriteData(0x80);
// Display update control
EPD_WriteCmd(0x22);
EPD_WriteData(0xB1);
// Master Activation
EPD_WriteCmd(0x20);
EPD_CheckStatus_inverted(100);
// Temperature sensor read from register
EPD_WriteCmd(0x1B);
epd_temperature = EPD_SPI_read();
EPD_SPI_read();
WaitMs(5);
// Set RAM X address
EPD_WriteCmd(0x4E);
EPD_WriteData(0x00);
// Set RAM Y address
EPD_WriteCmd(0x4F);
EPD_WriteData(0x28);
EPD_WriteData(0x01);
EPD_LoadImage(image, size, 0x24);
// Set RAM X address
EPD_WriteCmd(0x4E);
EPD_WriteData(0x00);
// Set RAM Y address
EPD_WriteCmd(0x4F);
EPD_WriteData(0x28);
EPD_WriteData(0x01);
EPD_WriteCmd(0x26);// RED Color TODO make something out of it :)
int i;
for (i = 0; i < size; i++)
{
EPD_WriteData(0x00);
}
if (!full_or_partial)
{
EPD_WriteCmd(0x32);
for (i = 0; i < sizeof(LUT_bwr_part); i++)
{
EPD_WriteData(LUT_bwr_part[i]);
}
}
// Display update control
EPD_WriteCmd(0x22);
EPD_WriteData(0xC7);
// Master Activation
EPD_WriteCmd(0x20);
return epd_temperature;
}
_attribute_ram_code_ void EPD_BWR_set_sleep(void)
{
// deep sleep
EPD_WriteCmd(0x10);
EPD_WriteData(0x01);
}

6
Firmware/src/epd_bwr.h Normal file
View File

@@ -0,0 +1,6 @@
#pragma once
uint8_t EPD_BWR_detect(void);
uint8_t EPD_BWR_read_temp(void);
uint8_t EPD_BWR_Display(unsigned char *image, int size, uint8_t full_or_partial);
void EPD_BWR_set_sleep(void);

150
Firmware/src/epd_spi.c Normal file
View File

@@ -0,0 +1,150 @@
#include <stdint.h>
#include "tl_common.h"
#include "main.h"
#include "epd.h"
#include "epd_spi.h"
#include "drivers.h"
#include "stack/ble/ble.h"
_attribute_ram_code_ void EPD_init(void)
{
gpio_set_func(EPD_RESET, AS_GPIO);
gpio_set_output_en(EPD_RESET, 1);
gpio_setup_up_down_resistor(EPD_RESET, PM_PIN_PULLUP_1M);
gpio_set_func(EPD_DC, AS_GPIO);
gpio_set_output_en(EPD_DC, 1);
gpio_setup_up_down_resistor(EPD_DC, PM_PIN_PULLUP_1M);
gpio_set_func(EPD_BUSY, AS_GPIO);
gpio_set_output_en(EPD_BUSY, 0);
gpio_set_input_en(EPD_BUSY, 1);
gpio_setup_up_down_resistor(EPD_BUSY, PM_PIN_PULLUP_1M);
gpio_set_func(EPD_CS, AS_GPIO);
gpio_set_output_en(EPD_CS, 1);
gpio_setup_up_down_resistor(EPD_CS, PM_PIN_PULLUP_1M);
gpio_set_func(EPD_CLK, AS_GPIO);
gpio_set_output_en(EPD_CLK, 1);
gpio_setup_up_down_resistor(EPD_CLK, PM_PIN_PULLUP_1M);
gpio_set_func(EPD_MOSI, AS_GPIO);
gpio_set_output_en(EPD_MOSI, 1);
gpio_setup_up_down_resistor(EPD_MOSI, PM_PIN_PULLUP_1M);
gpio_set_output_en(EPD_ENABLE, 0);
gpio_set_input_en(EPD_ENABLE, 1);
gpio_setup_up_down_resistor(EPD_ENABLE, PM_PIN_PULLUP_1M);
}
_attribute_ram_code_ void EPD_SPI_Write(unsigned char value)
{
unsigned char i;
WaitUs(10);
for (i = 0; i < 8; i++)
{
gpio_write(EPD_CLK, 0);
if (value & 0x80)
{
gpio_write(EPD_MOSI, 1);
}
else
{
gpio_write(EPD_MOSI, 0);
}
value = (value << 1);
gpio_write(EPD_CLK, 1);
}
}
_attribute_ram_code_ uint8_t EPD_SPI_read(void)
{
unsigned char i;
uint8_t value = 0;
gpio_shutdown(EPD_MOSI);
gpio_set_output_en(EPD_MOSI, 0);
gpio_set_input_en(EPD_MOSI, 1);
gpio_write(EPD_CS, 0);
EPD_ENABLE_WRITE_DATA();
WaitUs(10);
for (i = 0; i < 8; i++)
{
gpio_write(EPD_CLK, 0);
gpio_write(EPD_CLK, 1);
value <<= 1;
if (gpio_read(EPD_MOSI) != 0)
{
value |= 1;
}
}
gpio_set_output_en(EPD_MOSI, 1);
gpio_set_input_en(EPD_MOSI, 0);
gpio_write(EPD_CS, 1);
return value;
}
_attribute_ram_code_ void EPD_WriteCmd(unsigned char cmd)
{
gpio_write(EPD_CS, 0);
EPD_ENABLE_WRITE_CMD();
EPD_SPI_Write(cmd);
gpio_write(EPD_CS, 1);
}
_attribute_ram_code_ void EPD_WriteData(unsigned char data)
{
gpio_write(EPD_CS, 0);
EPD_ENABLE_WRITE_DATA();
EPD_SPI_Write(data);
gpio_write(EPD_CS, 1);
}
_attribute_ram_code_ void EPD_CheckStatus(int max_ms)
{
// TODO implement timout to prevent endless blocking
WaitMs(1);
while (EPD_IS_BUSY())
{
}
}
_attribute_ram_code_ void EPD_CheckStatus_inverted(int max_ms)
{
// TODO implement timout to prevent endless blocking
WaitMs(1);
while (!EPD_IS_BUSY())
{
}
}
_attribute_ram_code_ void EPD_send_lut(uint8_t lut[], int len)
{
EPD_WriteCmd(lut[0]);
for (int r = 1; r <= len; r++)
{
EPD_WriteData(lut[r]);
}
}
_attribute_ram_code_ void EPD_send_empty_lut(uint8_t lut, int len)
{
EPD_WriteCmd(lut);
for (int r = 0; r <= len; r++)
EPD_WriteData(0x00);
}
_attribute_ram_code_ void EPD_LoadImage(unsigned char *image, int size, uint8_t cmd)
{
int i;
EPD_WriteCmd(cmd);
for (i = 0; i < size; i++)
{
EPD_WriteData(image[i]);
}
WaitMs(2);
}

22
Firmware/src/epd_spi.h Normal file
View File

@@ -0,0 +1,22 @@
#pragma once
#define EPD_POWER_ON() gpio_write(EPD_ENABLE, 0)
#define EPD_POWER_OFF() gpio_write(EPD_ENABLE, 1)
#define EPD_ENABLE_WRITE_CMD() gpio_write(EPD_DC, 0)
#define EPD_ENABLE_WRITE_DATA() gpio_write(EPD_DC, 1)
#define EPD_IS_BUSY() (!gpio_read(EPD_BUSY))
void EPD_init(void);
void EPD_SPI_Write(unsigned char value);
uint8_t EPD_SPI_read(void);
void EPD_WriteCmd(unsigned char cmd);
void EPD_WriteData(unsigned char data);
void EPD_CheckStatus(int max_ms);
void EPD_CheckStatus_inverted(int max_ms);
void EPD_send_lut(uint8_t lut[], int len);
void EPD_send_empty_lut(uint8_t lut, int len);
void EPD_LoadImage(unsigned char *image, int size, uint8_t cmd);

View File

@@ -8,7 +8,10 @@ $(OUT_PATH)/i2c.o \
$(OUT_PATH)/cmd_parser.o \
$(OUT_PATH)/flash.o \
$(OUT_PATH)/time.o \
$(OUT_PATH)/epd_spi.o \
$(OUT_PATH)/epd.o \
$(OUT_PATH)/epd_bw.o \
$(OUT_PATH)/epd_bwr.o \
$(OUT_PATH)/ota.o \
$(OUT_PATH)/led.o \
$(OUT_PATH)/uart.o \