mirror of
https://github.com/RoCry/blozi-etag.git
synced 2025-12-06 09:02:49 +08:00
247 lines
6.3 KiB
C
Executable File
247 lines
6.3 KiB
C
Executable File
#include <stdint.h>
|
|
#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"
|
|
|
|
#include "battery.h"
|
|
|
|
#include "OneBitDisplay.h"
|
|
#include "TIFF_G4.h"
|
|
extern const uint8_t ucMirror[];
|
|
#include "Roboto_Black_80.h"
|
|
#include "font_60.h"
|
|
#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;
|
|
|
|
uint8_t epd_buffer[epd_buffer_size];
|
|
uint8_t epd_temp[epd_buffer_size]; // for OneBitDisplay to draw into
|
|
OBDISP obd; // virtual display structure
|
|
TIFFIMAGE tiff;
|
|
|
|
// Here we detect what E-Paper display is connected
|
|
_attribute_ram_code_ void EPD_detect_model(void)
|
|
{
|
|
EPD_init();
|
|
// system power
|
|
EPD_POWER_ON();
|
|
|
|
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())
|
|
{
|
|
epd_model = 2;
|
|
}
|
|
else
|
|
{
|
|
epd_model = 1;
|
|
}
|
|
|
|
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();
|
|
}
|
|
|
|
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);
|
|
|
|
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();
|
|
}
|
|
|
|
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);
|
|
|
|
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_temperature_is_read = 1;
|
|
epd_update_state = 1;
|
|
}
|
|
|
|
_attribute_ram_code_ void epd_set_sleep(void)
|
|
{
|
|
if (!epd_model)
|
|
{
|
|
EPD_detect_model();
|
|
}
|
|
|
|
if (epd_model == 1)
|
|
EPD_BW_set_sleep();
|
|
else if (epd_model == 2)
|
|
EPD_BWR_set_sleep();
|
|
|
|
EPD_POWER_OFF();
|
|
epd_update_state = 0;
|
|
}
|
|
|
|
_attribute_ram_code_ uint8_t epd_state_handler(void)
|
|
{
|
|
switch (epd_update_state)
|
|
{
|
|
case 0:
|
|
// Nothing todo
|
|
break;
|
|
case 1: // check if refresh is done and sleep epd if so
|
|
if (epd_model == 1)
|
|
{
|
|
if (!EPD_IS_BUSY())
|
|
epd_set_sleep();
|
|
}
|
|
else
|
|
{
|
|
if (EPD_IS_BUSY())
|
|
epd_set_sleep();
|
|
}
|
|
break;
|
|
}
|
|
return epd_update_state;
|
|
}
|
|
|
|
_attribute_ram_code_ void FixBuffer(uint8_t *pSrc, uint8_t *pDst)
|
|
{
|
|
int x, y;
|
|
uint8_t *s, *d;
|
|
for (y = 0; y < 16; y++)
|
|
{ // byte rows
|
|
d = &pDst[y];
|
|
s = &pSrc[y * 250];
|
|
for (x = 0; x < 250; x++)
|
|
{
|
|
d[x * 16] = ~ucMirror[s[249 - x]]; // invert and flip
|
|
} // for x
|
|
} // for y
|
|
}
|
|
|
|
_attribute_ram_code_ void TIFFDraw(TIFFDRAW *pDraw)
|
|
{
|
|
uint8_t uc = 0, ucSrcMask, ucDstMask, *s, *d;
|
|
int x, y;
|
|
|
|
s = pDraw->pPixels;
|
|
y = pDraw->y; // current line
|
|
d = &epd_buffer[(249 * 16) + (y / 8)]; // rotated 90 deg clockwise
|
|
ucDstMask = 0x80 >> (y & 7); // destination mask
|
|
ucSrcMask = 0; // src mask
|
|
for (x = 0; x < pDraw->iWidth; x++)
|
|
{
|
|
// Slower to draw this way, but it allows us to use a single buffer
|
|
// instead of drawing and then converting the pixels to be the EPD format
|
|
if (ucSrcMask == 0)
|
|
{ // load next source byte
|
|
ucSrcMask = 0x80;
|
|
uc = *s++;
|
|
}
|
|
if (!(uc & ucSrcMask))
|
|
{ // black pixel
|
|
d[-(x * 16)] &= ~ucDstMask;
|
|
}
|
|
ucSrcMask >>= 1;
|
|
}
|
|
}
|
|
|
|
_attribute_ram_code_ void epd_display_tiff(uint8_t *pData, int iSize)
|
|
{
|
|
// test G4 decoder
|
|
memset(epd_buffer, 0xff, epd_buffer_size); // clear to white
|
|
TIFF_openRAW(&tiff, 250, 122, BITDIR_MSB_FIRST, pData, iSize, TIFFDraw);
|
|
TIFF_setDrawParameters(&tiff, 65536, TIFF_PIXEL_1BPP, 0, 0, 250, 122, NULL);
|
|
TIFF_decode(&tiff);
|
|
TIFF_close(&tiff);
|
|
EPD_Display(epd_buffer, epd_buffer_size, 1);
|
|
}
|
|
|
|
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)
|
|
{
|
|
if (epd_update_state)
|
|
return;
|
|
obdCreateVirtualDisplay(&obd, 250, 122, epd_temp);
|
|
obdFill(&obd, 0, 0); // fill with white
|
|
|
|
char buff[100];
|
|
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());
|
|
obdWriteStringCustom(&obd, (GFXfont *)&Special_Elite_Regular_30, 10, 95, (char *)buff, 1);
|
|
sprintf(buff, "Battery %dmV", battery_mv);
|
|
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);
|
|
}
|
|
|
|
_attribute_ram_code_ void epd_display_char(uint8_t data)
|
|
{
|
|
int i;
|
|
for (i = 0; i < epd_buffer_size; i++)
|
|
{
|
|
epd_buffer[i] = data;
|
|
}
|
|
EPD_Display(epd_buffer, epd_buffer_size, 1);
|
|
}
|
|
|
|
_attribute_ram_code_ void epd_clear(void)
|
|
{
|
|
memset(epd_buffer, 0x00, epd_buffer_size);
|
|
}
|