mirror of
https://github.com/OpenEPaperLink/OpenEPaperLink.git
synced 2026-03-21 03:04:25 +01:00
Merge branch 'VstudioLAB-master'
This commit is contained in:
74
ESP32_AP-Flasher/data/tagtypes/21.json
Normal file
74
ESP32_AP-Flasher/data/tagtypes/21.json
Normal file
@@ -0,0 +1,74 @@
|
||||
{
|
||||
"name": "ST‐GM29XXF 2.9\"",
|
||||
"width": 296,
|
||||
"height": 128,
|
||||
"rotatebuffer": 1,
|
||||
"bpp": 1,
|
||||
"colors": 2,
|
||||
"colortable": {
|
||||
"white": [255, 255, 255],
|
||||
"black": [0, 0, 0]
|
||||
},
|
||||
"shortlut": 0,
|
||||
"options": ["button", "customlut"],
|
||||
"contentids": [ 0, 1, 2, 3, 4, 8, 16, 9, 7, 19, 10, 11, 21 ],
|
||||
"usetemplate": 1,
|
||||
"template": {
|
||||
"1": {
|
||||
"weekday": [148, 10, "fonts/calibrib60"],
|
||||
"date": [148, 73, "fonts/calibrib50"]
|
||||
},
|
||||
"16": {
|
||||
"location": [ 5, 5, "fonts/bahnschrift30" ],
|
||||
"title": [ 247, 11, "glasstown_nbp_tf" ],
|
||||
"cols": [ 1, 125, 12, "glasstown_nbp_tf" ],
|
||||
"bars": [ 5, 111, 10 ]
|
||||
},
|
||||
"2": {
|
||||
"fonts": ["fonts/calibrib150", "fonts/calibrib150", "fonts/calibrib120", "fonts/calibrib100"],
|
||||
"xy": [148, 74]
|
||||
},
|
||||
"4": {
|
||||
"location": [5, 5, "fonts/bahnschrift30"],
|
||||
"wind": [280, 5, "fonts/bahnschrift30"],
|
||||
"temp": [5, 65, "fonts/bahnschrift70"],
|
||||
"icon": [285, 20, 70, 2],
|
||||
"dir": [235, -12, 40],
|
||||
"umbrella": [190, -50, 25]
|
||||
},
|
||||
"8": {
|
||||
"location": [5, 12, "t0_14b_tf"],
|
||||
"column": [5, 59],
|
||||
"day": [30, 18, "fonts/twcondensed20", 41, 108],
|
||||
"icon": [30, 55, 30],
|
||||
"wind": [18, 26],
|
||||
"line": [20, 128]
|
||||
},
|
||||
"9": {
|
||||
"title": [5, 3, "fonts/bahnschrift20"],
|
||||
"items": 8,
|
||||
"line": [5, 34, 13],
|
||||
"font": "glasstown_nbp_tf"
|
||||
},
|
||||
"10": {
|
||||
"title": [10, 5, "fonts/bahnschrift20"],
|
||||
"pos": [149, 25]
|
||||
},
|
||||
"11": {
|
||||
"title": [5, 2, "fonts/bahnschrift20"],
|
||||
"date": [290, 2],
|
||||
"items": 7,
|
||||
"red": [0, 21, 296, 14],
|
||||
"line": [5, 32, 15, "t0_14b_tf", 50]
|
||||
},
|
||||
"21": [
|
||||
{ "text": [ 5, 5, "OpenEpaperLink AP", "bahnschrift20", 1, 0, 0 ] },
|
||||
{ "text": [ 5, 50, "IP address:", "t0_14b_tf", 1, 0, 0 ] },
|
||||
{ "text": [ 120, 50, "{ap_ip}", "t0_14b_tf", 1, 0, 0 ] },
|
||||
{ "text": [ 5, 70, "Channel:", "t0_14b_tf", 1, 0, 0 ] },
|
||||
{ "text": [ 120, 70, "{ap_ch}", "t0_14b_tf", 1, 0, 0 ] },
|
||||
{ "text": [ 5, 90, "Tag count:", "t0_14b_tf", 1, 0, 0 ] },
|
||||
{ "text": [ 120, 90, "{ap_tagcount}", "t0_14b_tf", 1, 0, 0 ] }
|
||||
]
|
||||
}
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
@@ -37,8 +37,8 @@ build_flags =
|
||||
-D ILI9341_DRIVER
|
||||
-D SMOOTH_FONT
|
||||
|
||||
upload_port = COM11
|
||||
monitor_port = COM11
|
||||
;upload_port = COM11
|
||||
;monitor_port = COM11
|
||||
; ----------------------------------------------------------------------------------------
|
||||
; !!! this configuration expects the Mini_AP
|
||||
;
|
||||
@@ -325,6 +325,7 @@ build_src_filter =
|
||||
[env:ESP32_S3_16_8_YELLOW_AP]
|
||||
board = esp32-s3-devkitc-1
|
||||
board_build.partitions = large_spiffs_16MB.csv
|
||||
|
||||
build_unflags =
|
||||
-std=gnu++11
|
||||
-D ARDUINO_USB_MODE=1
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
int defaultLanguage = 0;
|
||||
|
||||
String languageList[] = {"EN - English", "NL - Nederlands", "DE - Deutsch", "NO - Norwegian"};
|
||||
String languageList[] = {"EN - English", "NL - Nederlands", "DE - Deutsch", "NO - Norwegian", "FR - French"};
|
||||
|
||||
/*EN English language section*/
|
||||
String languageEnDaysShort[] = {"SU", "MO", "TU", "WE", "TH", "FR", "SA"};
|
||||
@@ -33,9 +33,15 @@ String languageNoDays[] = {"Søndag", "Mandag", "Tirsdag", "Onsdag", "Torsdag",
|
||||
String languageNoMonth[] = {"Januar", "Februar", "Mars", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Desember"};
|
||||
/*END Norwegian language section END*/
|
||||
|
||||
String* languageDaysShort[] = {languageEnDaysShort, languageNlDaysShort, languageDeDaysShort, languageNoDaysShort};
|
||||
String* languageDays[] = {languageEnDays, languageNlDays, languageDeDays, languageNoDays};
|
||||
String* languageMonth[] = {languageEnMonth, languageNlMonth, languageDeMonth, languageNoMonth};
|
||||
/*FR French language section*/
|
||||
String languageFrDaysShort[] = {"DI", "LU", "MA", "ME", "JE", "VE", "SA"};
|
||||
String languageFrDays[] = {"Dimanche", "Lundi", "Mardi", "Mercredi", "Jeudi", "Vendredi", "Samedi"};
|
||||
String languageFrMonth[] = {"Janvier", "Fevrier", "Mars", "Avril", "Mai", "Juin", "Juillet", "Aout", "Septembre", "Octobre", "Novembre", "Decembre"};
|
||||
/*END French language section END*/
|
||||
|
||||
String* languageDaysShort[] = {languageEnDaysShort, languageNlDaysShort, languageDeDaysShort, languageNoDaysShort, languageFrDaysShort};
|
||||
String* languageDays[] = {languageEnDays, languageNlDays, languageDeDays, languageNoDays, languageFrDays};
|
||||
String* languageMonth[] = {languageEnMonth, languageNlMonth, languageDeMonth, languageNoMonth, languageFrMonth};
|
||||
|
||||
int currentLanguage = defaultLanguage;
|
||||
|
||||
|
||||
@@ -10,7 +10,8 @@
|
||||
5,
|
||||
49,
|
||||
51,
|
||||
17
|
||||
17,
|
||||
15
|
||||
],
|
||||
"param": [
|
||||
{
|
||||
@@ -90,7 +91,8 @@
|
||||
17,
|
||||
49,
|
||||
51,
|
||||
240
|
||||
240,
|
||||
15
|
||||
],
|
||||
"param": []
|
||||
},
|
||||
@@ -106,7 +108,8 @@
|
||||
17,
|
||||
49,
|
||||
51,
|
||||
240
|
||||
240,
|
||||
21
|
||||
],
|
||||
"param": [
|
||||
{
|
||||
@@ -126,7 +129,8 @@
|
||||
2,
|
||||
49,
|
||||
51,
|
||||
17
|
||||
17,
|
||||
15
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -143,7 +147,8 @@
|
||||
17,
|
||||
49,
|
||||
51,
|
||||
240
|
||||
240,
|
||||
15
|
||||
],
|
||||
"param": [
|
||||
{
|
||||
@@ -164,7 +169,8 @@
|
||||
5,
|
||||
49,
|
||||
51,
|
||||
17
|
||||
17,
|
||||
15
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -181,7 +187,8 @@
|
||||
17,
|
||||
49,
|
||||
51,
|
||||
240
|
||||
240,
|
||||
15
|
||||
],
|
||||
"param": [
|
||||
{
|
||||
@@ -224,7 +231,8 @@
|
||||
5,
|
||||
49,
|
||||
51,
|
||||
17
|
||||
17,
|
||||
15
|
||||
],
|
||||
"param": [
|
||||
{
|
||||
@@ -265,7 +273,8 @@
|
||||
1,
|
||||
49,
|
||||
51,
|
||||
17
|
||||
17,
|
||||
21
|
||||
],
|
||||
"param": [
|
||||
{
|
||||
@@ -298,7 +307,8 @@
|
||||
5,
|
||||
49,
|
||||
51,
|
||||
17
|
||||
17,
|
||||
15
|
||||
],
|
||||
"param": [
|
||||
{
|
||||
@@ -332,7 +342,8 @@
|
||||
5,
|
||||
49,
|
||||
51,
|
||||
17
|
||||
17,
|
||||
15
|
||||
],
|
||||
"param": [
|
||||
{
|
||||
@@ -360,7 +371,8 @@
|
||||
5,
|
||||
49,
|
||||
51,
|
||||
17
|
||||
17,
|
||||
15
|
||||
],
|
||||
"param": [
|
||||
{
|
||||
@@ -394,7 +406,8 @@
|
||||
5,
|
||||
17,
|
||||
49,
|
||||
51
|
||||
51,
|
||||
15
|
||||
],
|
||||
"param": [
|
||||
{
|
||||
@@ -421,7 +434,8 @@
|
||||
5,
|
||||
49,
|
||||
51,
|
||||
17
|
||||
17,
|
||||
15
|
||||
],
|
||||
"param": [
|
||||
{
|
||||
@@ -456,7 +470,8 @@
|
||||
17,
|
||||
49,
|
||||
51,
|
||||
240
|
||||
240,
|
||||
15
|
||||
],
|
||||
"param": [
|
||||
{
|
||||
@@ -548,7 +563,8 @@
|
||||
17,
|
||||
49,
|
||||
51,
|
||||
240
|
||||
240,
|
||||
15
|
||||
],
|
||||
"param": [
|
||||
{
|
||||
@@ -571,7 +587,8 @@
|
||||
17,
|
||||
49,
|
||||
51,
|
||||
240
|
||||
240,
|
||||
15
|
||||
],
|
||||
"param": [
|
||||
{
|
||||
@@ -675,7 +692,8 @@
|
||||
5,
|
||||
49,
|
||||
51,
|
||||
17
|
||||
17,
|
||||
15
|
||||
],
|
||||
"param": [
|
||||
{
|
||||
@@ -692,7 +710,8 @@
|
||||
"desc": "Displays information about the currently connected access point",
|
||||
"hwtype": [
|
||||
0,
|
||||
1
|
||||
1,
|
||||
15
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -287,6 +287,7 @@
|
||||
<option value="0" selected>EN English</option>
|
||||
<option value="1">NL Nederlands</option>
|
||||
<option value="2">DE Deutsch</option>
|
||||
<option value="4">FR French</option>
|
||||
<option value="3">NO Norwegian</option>
|
||||
</select>
|
||||
</p>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#define SOLUM_154_SSD1619 0
|
||||
#define SOLUM_29_SSD1619 0x01
|
||||
#define SOLUM_29_BW_SSD1619 0x21
|
||||
#define SOLUM_29_UC8151 0x11
|
||||
#define SOLUM_42_SSD1619 0x02
|
||||
#define SOLUM_SEG_UK 0xF0
|
||||
|
||||
@@ -133,8 +133,10 @@ static void configUART(const bool setup) {
|
||||
static void configEEPROM(const bool setup) {
|
||||
if (setup == eepromActive) return;
|
||||
if (setup) {
|
||||
P1FUNC &= ~(1 << 1);
|
||||
P1DIR &= ~(1 << 1);
|
||||
P1FUNC &= ~(1 << 1) | (1 << 2) | (1 << 6);
|
||||
P1DIR &= ~(1 << 1) | (1 << 2) | (1 << 6);
|
||||
P1_6 = 1;
|
||||
P1_2 = 1;
|
||||
if (!eepromInit()) {
|
||||
powerDown(INIT_RADIO);
|
||||
powerUp(INIT_EPD);
|
||||
|
||||
@@ -633,8 +633,8 @@ static bool getDataBlock(const uint16_t blockSize) {
|
||||
#endif
|
||||
// check if we got all the parts we needed, e.g: has the block been completed?
|
||||
bool blockComplete = true;
|
||||
for (uint8_t c = 0; c < partsThisBlock; c++) {
|
||||
if (curBlock.requestedParts[c / 8] & (1 << (c % 8))) blockComplete = false;
|
||||
for (uint8_t c1 = 0; c1 < partsThisBlock; c1++) {
|
||||
if (curBlock.requestedParts[c1 / 8] & (1 << (c1 % 8))) blockComplete = false;
|
||||
}
|
||||
|
||||
if (blockComplete) {
|
||||
|
||||
163
zbs243_shared/board/zbs29_BW_ssd1619/board.c
Normal file
163
zbs243_shared/board/zbs29_BW_ssd1619/board.c
Normal file
@@ -0,0 +1,163 @@
|
||||
#include <stdbool.h>
|
||||
#include "printf.h"
|
||||
#include "screen.h"
|
||||
#include "board.h"
|
||||
#include "flash.h"
|
||||
#include "uart.h"
|
||||
#include "spi.h"
|
||||
#include "cpu.h"
|
||||
#include "wdt.h"
|
||||
#include "i2c.h"
|
||||
|
||||
//extern uint8_t __xdata* tempBuffer;
|
||||
uint8_t __xdata tempBuffer[320];
|
||||
|
||||
void powerPortsDownForSleep(void)
|
||||
{
|
||||
P0FUNC = 0;
|
||||
P1FUNC = 0;
|
||||
P2FUNC = 0;
|
||||
P0DIR = 0;
|
||||
P0 = 0;
|
||||
P0PULL = 0;
|
||||
P1DIR = 0;
|
||||
P1 = 2;
|
||||
P1PULL = 0;
|
||||
P2DIR = 2;
|
||||
P2 =1;
|
||||
P2PULL = 0;
|
||||
}
|
||||
|
||||
void boardInit(void)
|
||||
{
|
||||
pr("board init\n");
|
||||
//set up pins for spi(0.0,0.1,0.2), UART (0.6)
|
||||
P0FUNC |= (1 << 0) | (1 << 1) | (1 << 2) | (1 << 6);
|
||||
P0DIR = (P0DIR &~ ((1 << 0) | (1 << 1) | (1 << 6))) | (1 << 2);
|
||||
|
||||
//pulls for spi in
|
||||
P0PULL = (P0PULL &~ ((1 << 0) | (1 << 1) | (1 << 6))) | (1 << 2);
|
||||
|
||||
//setup 1.1(eeprom_nCS), 1.2(eink_BS1), 1.6(flash write protect) 1.7(eink_nCS)
|
||||
P1FUNC &=~ ((1 << 1) | (1 << 2) | (1 << 5) | (1 << 6) | (1 << 7));
|
||||
P1DIR &= ~((1 << 1) | (1 << 2) | (1 << 5) | (1 << 6) | (1 << 7));
|
||||
|
||||
//setup 2.0(eink_nRST), 2.1(eink_BUSY), 2.2(eink_D/nC)
|
||||
P2FUNC &= ~((1 << 0) | (1 << 1) | (1 << 2));
|
||||
P2DIR = (P2DIR &~ ((1 << 0) | (1 << 2))) | (1 << 1);
|
||||
|
||||
//raise chip select(s)
|
||||
P1_1 = 1;
|
||||
P1_7 = 1;
|
||||
|
||||
//BS1 = low
|
||||
P1_2 = 1;
|
||||
P1_5 = 0;
|
||||
P1_6 = 1;
|
||||
|
||||
spiInit();
|
||||
}
|
||||
|
||||
|
||||
__bit boardGetOwnMac(uint8_t __xdata *mac)
|
||||
{
|
||||
return flashRead(FLASH_INFOPAGE_ADDR + 0x10, mac, 8);
|
||||
}
|
||||
|
||||
#pragma callee_saves prvUpdateApplierGet
|
||||
static uint32_t prvUpdateApplierGet(void) __naked
|
||||
{
|
||||
__asm__(
|
||||
" mov DPTR, #00098$ \n"
|
||||
" mov A, #00099$ \n"
|
||||
" clr C \n"
|
||||
" subb A, DPL \n"
|
||||
" mov B, A \n"
|
||||
" ret \n"
|
||||
|
||||
///actual updater code
|
||||
"00098$: \n"
|
||||
|
||||
|
||||
//copied to last page of flash for updating, called with ints off and eeprom ready to read update
|
||||
//flashes 63 flash pages, uses xram for buffer. uses combined erase+flash flash op
|
||||
|
||||
" mov _CLKSPEED, #0x21 \n"
|
||||
" mov _CFGPAGE, #0x04 \n"
|
||||
" mov R0, #0 \n"
|
||||
|
||||
"00001$: \n"
|
||||
|
||||
//read a page of update
|
||||
" mov DPTR, #0xe000 \n"
|
||||
" mov R1, #0x04 \n"
|
||||
" mov R2, #0x00 \n"
|
||||
"000010$: \n"
|
||||
" mov _SPITX, #0x00 \n"
|
||||
" mov _SPICFG, #0xa0 \n"
|
||||
"000011$: \n"
|
||||
" mov A, _SPICFG \n"
|
||||
" jb A.5, 000011$ \n"
|
||||
" mov A, _SPIRX \n"
|
||||
" movx @DPTR, A \n"
|
||||
" inc DPTR \n"
|
||||
" djnz R2, 000010$ \n"
|
||||
" djnz R1, 000010$ \n"
|
||||
|
||||
//flash it
|
||||
" clr A \n"
|
||||
" orl _SETTINGS, #0x38 \n"
|
||||
" mov _FWRTHREE, #0x03 \n"
|
||||
" mov _FPGNO, R0 \n"
|
||||
" mov _FWRDSTL, A \n"
|
||||
" mov _FWRDSTH, A \n"
|
||||
" mov _FWRLENL, #0xff \n"
|
||||
" mov _FWRLENH, #0x03 \n"
|
||||
" mov _FWRSRCL, A \n"
|
||||
" mov _FWRSRCH, #0xe0 \n"
|
||||
" orl _TRIGGER, #0x08 \n"
|
||||
"00050$: \n"
|
||||
" mov A, _TCON2 \n"
|
||||
" jnb A.3, 00050$ \n"
|
||||
" anl _TCON2, #~0x48 \n"
|
||||
" anl _SETTINGS, #~0x10 \n"
|
||||
|
||||
//go do next page
|
||||
" inc R0 \n"
|
||||
" cjne R0, #63, 00001$ \n"
|
||||
|
||||
//done? reset
|
||||
" mov _WDTCONF, #0x80 \n"
|
||||
" mov _WDTENA, #0x01 \n"
|
||||
" mov A, #0xff \n"
|
||||
" mov _WDTRSTVALH, A \n"
|
||||
" mov _WDTRSTVALM, A \n"
|
||||
" mov _WDTRSTVALL, A \n"
|
||||
"00090$: \n"
|
||||
" sjmp 00090$ \n"
|
||||
|
||||
"00099$: \n"
|
||||
);
|
||||
}
|
||||
|
||||
void selfUpdate(void)
|
||||
{
|
||||
uint32_t updaterInfo = prvUpdateApplierGet();
|
||||
uint8_t __code *src = (uint8_t __code*)updaterInfo;
|
||||
uint8_t i, len = updaterInfo >> 16;
|
||||
uint8_t __xdata *dst = tempBuffer;
|
||||
|
||||
for (i = len; i ; i--)
|
||||
*dst++ = *src++;
|
||||
|
||||
if (!flashWrite(0xfc00, tempBuffer, len, true))
|
||||
pr("failed to write updater\n");
|
||||
|
||||
IEN_EA = 0; //ints off
|
||||
|
||||
__asm__(
|
||||
" mov dptr, #0xfc00 \n"
|
||||
" clr a \n"
|
||||
" jmp @a+dptr \n"
|
||||
);
|
||||
}
|
||||
36
zbs243_shared/board/zbs29_BW_ssd1619/board.h
Normal file
36
zbs243_shared/board/zbs29_BW_ssd1619/board.h
Normal file
@@ -0,0 +1,36 @@
|
||||
#ifndef _BOARD_H_
|
||||
#define _BOARD_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define __packed
|
||||
|
||||
#include "../oepl-definitions.h"
|
||||
#include "spi.h"
|
||||
|
||||
#define eepromByte spiByte
|
||||
#define eepromPrvSelect() do { __asm__("nop\nnop\nnop\n"); P1_1 = 0; __asm__("nop\nnop\nnop\n"); } while(0)
|
||||
#define eepromPrvDeselect() do { __asm__("nop\nnop\nnop\n"); P1_1 = 1; __asm__("nop\nnop\nnop\n"); } while(0)
|
||||
|
||||
//eeprom map
|
||||
#define EEPROM_SETTINGS_AREA_START (0x01000UL)
|
||||
#define EEPROM_SETTINGS_AREA_LEN (0x03000UL)
|
||||
#define EEPROM_UPDATA_AREA_START (0x04000UL)
|
||||
#define EEPROM_UPDATE_AREA_LEN (0x10000UL)
|
||||
#define EEPROM_IMG_START (0x14000UL)
|
||||
#define EEPROM_IMG_EACH (0x04000UL)
|
||||
//till end of eeprom really. do not put anything after - it will be erased at pairing time!!!
|
||||
#define EEPROM_PROGRESS_BYTES (128)
|
||||
|
||||
#define HAS_EEPROM 1
|
||||
#define HAS_SCREEN 1
|
||||
#define NFC_TYPE -1
|
||||
#define AP_EMULATE_TAG 1
|
||||
|
||||
//hw types
|
||||
#define HW_TYPE SOLUM_29_BW_SSD1619
|
||||
|
||||
#include "../boardCommon.h"
|
||||
|
||||
|
||||
#endif
|
||||
7
zbs243_shared/board/zbs29_BW_ssd1619/make.mk
Normal file
7
zbs243_shared/board/zbs29_BW_ssd1619/make.mk
Normal file
@@ -0,0 +1,7 @@
|
||||
FLAGS += --code-size 0xfc00
|
||||
|
||||
SOC = zbs243
|
||||
|
||||
BARCODE = datamatrix
|
||||
|
||||
# 0xfc00 and not 0x10000 to leave some space for update header and updater in flash
|
||||
1
zbs243_shared/board/zbs29_BW_ssd1619/old_screen.c
Normal file
1
zbs243_shared/board/zbs29_BW_ssd1619/old_screen.c
Normal file
@@ -0,0 +1 @@
|
||||
#include "../ssd1619.c"
|
||||
834
zbs243_shared/board/zbs29_BW_ssd1619/screen.c
Normal file
834
zbs243_shared/board/zbs29_BW_ssd1619/screen.c
Normal file
@@ -0,0 +1,834 @@
|
||||
#include "../ssd1619.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "asmUtil.h"
|
||||
#include "barcode.h"
|
||||
#include "board.h"
|
||||
#include "cpu.h"
|
||||
#include "font.h"
|
||||
#include "lut.h"
|
||||
#include "printf.h"
|
||||
#include "screen.h"
|
||||
// #include "settings.h"
|
||||
#include "sleep.h"
|
||||
#include "spi.h"
|
||||
#include "timer.h"
|
||||
#include "wdt.h"
|
||||
|
||||
#define CMD_DRV_OUTPUT_CTRL 0x01
|
||||
#define CMD_SOFT_START_CTRL 0x0C
|
||||
#define CMD_ENTER_SLEEP 0x10
|
||||
#define CMD_DATA_ENTRY_MODE 0x11
|
||||
#define CMD_SOFT_RESET 0x12
|
||||
#define CMD_SOFT_RESET2 0x13
|
||||
#define CMD_SETUP_VOLT_DETECT 0x15
|
||||
#define CMD_TEMP_SENSOR_CONTROL 0x18
|
||||
#define CMD_ACTIVATION 0x20
|
||||
#define CMD_DISP_UPDATE_CTRL 0x21
|
||||
#define CMD_DISP_UPDATE_CTRL2 0x22
|
||||
#define CMD_WRITE_FB_BW 0x24
|
||||
#define CMD_WRITE_FB_RED 0x26
|
||||
#define CMD_UNKNOWN_1 0x2B
|
||||
#define CMD_LOAD_OTP_LUT 0x31
|
||||
#define CMD_WRITE_LUT 0x32
|
||||
#define CMD_BORDER_WAVEFORM_CTRL 0x3C
|
||||
#define CMD_WINDOW_X_SIZE 0x44
|
||||
#define CMD_WINDOW_Y_SIZE 0x45
|
||||
#define CMD_WRITE_PATTERN_RED 0x46
|
||||
#define CMD_WRITE_PATTERN_BW 0x47
|
||||
#define CMD_XSTART_POS 0x4E
|
||||
#define CMD_YSTART_POS 0x4F
|
||||
#define CMD_ANALOG_BLK_CTRL 0x74
|
||||
#define CMD_DIGITAL_BLK_CTRL 0x7E
|
||||
// added for OTA LUT-support
|
||||
#define CMD_GATE_LEVEL 0x03
|
||||
#define CMD_SOURCE_LEVEL 0x04
|
||||
#define CMD_DUMMY_PERIOD 0x3A
|
||||
#define CMD_GATE_LINE_WIDTH 0x3B
|
||||
|
||||
#define SCREEN_CMD_CLOCK_ON 0x80
|
||||
#define SCREEN_CMD_CLOCK_OFF 0x01
|
||||
#define SCREEN_CMD_ANALOG_ON 0x40
|
||||
#define SCREEN_CMD_ANALOG_OFF 0x02
|
||||
#define SCREEN_CMD_LATCH_TEMPERATURE_VAL 0x20
|
||||
#define SCREEN_CMD_LOAD_LUT 0x10
|
||||
#define SCREEN_CMD_USE_MODE_2 0x08 // modified commands 0x10 and 0x04
|
||||
#define SCREEN_CMD_REFRESH 0xC7
|
||||
|
||||
#define commandEnd() \
|
||||
do { \
|
||||
P1_7 = 1; \
|
||||
} while (0)
|
||||
|
||||
#define markCommand() \
|
||||
do { \
|
||||
P2_2 = 0; \
|
||||
} while (0)
|
||||
|
||||
#define markData() \
|
||||
do { \
|
||||
P2_2 = 1; \
|
||||
} while (0)
|
||||
|
||||
extern void dump(uint8_t* __xdata a, uint16_t __xdata l); // remove me when done
|
||||
|
||||
static uint8_t __xdata epdCharSize = 1; // character size, 1 or 2 (doubled)
|
||||
static bool __xdata directionY = true; // print direction, X or Y (true)
|
||||
static uint8_t __xdata rbuffer[32]; // used to rotate bits around
|
||||
static uint16_t __xdata fontCurXpos = 0; // current X value we're working with
|
||||
static uint16_t __xdata fontCurYpos = 0; // current Y value we're working with
|
||||
static uint8_t __xdata currentLut = 0;
|
||||
uint8_t __xdata dispLutSize = 0; // we'll need to expose this in the 'capabilities' flag
|
||||
|
||||
static bool __xdata isInited = false;
|
||||
|
||||
bool __xdata epdGPIOActive = false;
|
||||
|
||||
#define LUT_BUFFER_SIZE 128
|
||||
static uint8_t waveformbuffer[LUT_BUFFER_SIZE];
|
||||
uint8_t __xdata customLUT[LUT_BUFFER_SIZE] = {0};
|
||||
|
||||
struct waveform10* __xdata waveform10 = (struct waveform10*)waveformbuffer; // holds the LUT/waveform
|
||||
struct waveform* __xdata waveform7 = (struct waveform*)waveformbuffer; // holds the LUT/waveform
|
||||
|
||||
#pragma callee_saves epdBusySleep
|
||||
#pragma callee_saves epdBusyWait
|
||||
static void epdBusySleep(uint32_t timeout) {
|
||||
uint8_t tmp_P2FUNC = P2FUNC;
|
||||
uint8_t tmp_P2DIR = P2DIR;
|
||||
uint8_t tmp_P2PULL = P2PULL;
|
||||
uint8_t tmp_P2LVLSEL = P2LVLSEL;
|
||||
P2FUNC &= 0xfd;
|
||||
P2DIR |= 2;
|
||||
P2PULL |= 2;
|
||||
P2LVLSEL |= 2;
|
||||
|
||||
P2CHSTA &= 0xfd;
|
||||
P2INTEN |= 2;
|
||||
P2CHSTA &= 0xfd;
|
||||
sleepForMsec(timeout);
|
||||
wdtOn();
|
||||
P2CHSTA &= 0xfd;
|
||||
P2INTEN &= 0xfd;
|
||||
|
||||
P2FUNC = tmp_P2FUNC;
|
||||
P2DIR = tmp_P2DIR;
|
||||
P2PULL = tmp_P2PULL;
|
||||
P2LVLSEL = tmp_P2LVLSEL;
|
||||
eepromPrvDeselect();
|
||||
}
|
||||
static void epdBusyWait(uint32_t timeout) {
|
||||
uint32_t __xdata start = timerGet();
|
||||
|
||||
while (timerGet() - start < timeout) {
|
||||
if (!P2_1)
|
||||
return;
|
||||
}
|
||||
pr("screen timeout %lu ticks :(\n", timerGet() - start);
|
||||
while (1)
|
||||
;
|
||||
}
|
||||
static void commandReadBegin(uint8_t cmd) {
|
||||
epdSelect();
|
||||
markCommand();
|
||||
spiByte(cmd); // dump LUT
|
||||
|
||||
P0DIR = (P0DIR & ~(1 << 0)) | (1 << 1);
|
||||
P0 &= ~(1 << 0);
|
||||
P0FUNC &= ~((1 << 0) | (1 << 1));
|
||||
P2_2 = 1;
|
||||
}
|
||||
static void commandReadEnd() {
|
||||
// set up pins for spi (0.0,0.1,0.2)
|
||||
P0FUNC |= (1 << 0) | (1 << 1);
|
||||
epdDeselect();
|
||||
}
|
||||
#pragma callee_saves epdReadByte
|
||||
static uint8_t epdReadByte() {
|
||||
uint8_t val = 0, i;
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
P0_0 = 1;
|
||||
__asm__("nop\nnop\nnop\nnop\nnop\nnop\n");
|
||||
val <<= 1;
|
||||
if (P0_1)
|
||||
val++;
|
||||
P0_0 = 0;
|
||||
__asm__("nop\nnop\nnop\nnop\nnop\nnop\n");
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
static void shortCommand(uint8_t cmd) {
|
||||
epdSelect();
|
||||
markCommand();
|
||||
spiTXByte(cmd);
|
||||
epdDeselect();
|
||||
}
|
||||
static void shortCommand1(uint8_t cmd, uint8_t arg) {
|
||||
epdSelect();
|
||||
markCommand();
|
||||
spiTXByte(cmd);
|
||||
markData();
|
||||
spiTXByte(arg);
|
||||
epdDeselect();
|
||||
}
|
||||
static void shortCommand2(uint8_t cmd, uint8_t arg1, uint8_t arg2) {
|
||||
epdSelect();
|
||||
markCommand();
|
||||
spiTXByte(cmd);
|
||||
markData();
|
||||
spiTXByte(arg1);
|
||||
spiTXByte(arg2);
|
||||
epdDeselect();
|
||||
}
|
||||
static void commandBegin(uint8_t cmd) {
|
||||
epdSelect();
|
||||
markCommand();
|
||||
spiTXByte(cmd);
|
||||
markData();
|
||||
}
|
||||
static void epdReset() {
|
||||
timerDelay(TIMER_TICKS_PER_SECOND / 100);
|
||||
P2_0 = 0;
|
||||
timerDelay(TIMER_TICKS_PER_SECOND / 100);
|
||||
P2_0 = 1;
|
||||
timerDelay(TIMER_TICKS_PER_SECOND / 100);
|
||||
|
||||
shortCommand(CMD_SOFT_RESET); // software reset
|
||||
timerDelay(TIMER_TICKS_PER_SECOND / 100);
|
||||
//shortCommand(CMD_SOFT_RESET2);
|
||||
//timerDelay(TIMER_TICKS_PER_SECOND / 100);
|
||||
}
|
||||
void epdConfigGPIO(bool setup) {
|
||||
// data / _command: 2.2
|
||||
// busy 2.1
|
||||
// reset 2.0
|
||||
// _select 1.7
|
||||
// bs1 1.2
|
||||
|
||||
// GENERIC SPI BUS PINS
|
||||
// spi.clk 0.0
|
||||
// spi.mosi 0.1
|
||||
if (epdGPIOActive == setup) return;
|
||||
if (setup) {
|
||||
P2DIR |= (1 << 1); // busy as input
|
||||
P2DIR &= ~((1 << 2) | (1 << 0)); // D/C and Reset as output
|
||||
P1DIR &= ~((1 << 7) | (1 << 2) | (1 << 5)); // select and bs1 as output
|
||||
//P1_2 = 0; // select 4-wire SPI / BS1 = low
|
||||
P1_5 = 0;
|
||||
P1_7 = 1; // deselect EPD
|
||||
} else {
|
||||
P2DIR |= ((1 << 2) | (1 << 0)); // DC and Reset as input
|
||||
P2 &= ~((1 << 2) | (1 << 0));
|
||||
P1DIR |= ((1 << 7) | (1 << 2)); // Select and BS1 as input
|
||||
P2 &= ~((1 << 7));
|
||||
}
|
||||
epdGPIOActive = setup;
|
||||
}
|
||||
void epdEnterSleep() {
|
||||
P2_0 = 0;
|
||||
timerDelay(10);
|
||||
P2_0 = 1;
|
||||
timerDelay(50);
|
||||
shortCommand(CMD_SOFT_RESET2);
|
||||
epdBusyWait(TIMER_TICKS_PER_MS * 15);
|
||||
shortCommand1(CMD_ENTER_SLEEP, 0x03);
|
||||
isInited = false;
|
||||
}
|
||||
void epdSetup() {
|
||||
epdReset();
|
||||
shortCommand1(CMD_ANALOG_BLK_CTRL, 0x54);
|
||||
shortCommand1(CMD_DIGITAL_BLK_CTRL, 0x3B);
|
||||
shortCommand2(CMD_UNKNOWN_1, 0x04, 0x63);
|
||||
|
||||
commandBegin(CMD_SOFT_START_CTRL);
|
||||
epdSend(0x8f);
|
||||
epdSend(0x8f);
|
||||
epdSend(0x8f);
|
||||
epdSend(0x3f);
|
||||
commandEnd();
|
||||
|
||||
commandBegin(CMD_DRV_OUTPUT_CTRL);
|
||||
epdSend((SCREEN_HEIGHT - 1) & 0xff);
|
||||
epdSend((SCREEN_HEIGHT - 1) >> 8);
|
||||
epdSend(0x00);
|
||||
commandEnd();
|
||||
|
||||
// shortCommand1(CMD_DATA_ENTRY_MODE, 0x03);
|
||||
// shortCommand1(CMD_BORDER_WAVEFORM_CTRL, 0xC0); // blurry edges
|
||||
shortCommand1(CMD_BORDER_WAVEFORM_CTRL, 0x01);
|
||||
shortCommand1(CMD_TEMP_SENSOR_CONTROL, 0x80);
|
||||
shortCommand1(CMD_DISP_UPDATE_CTRL2, 0xB1); // mode 1 (i2C)
|
||||
// shortCommand1(CMD_DISP_UPDATE_CTRL2, 0xB9); // mode 2?
|
||||
shortCommand(CMD_ACTIVATION);
|
||||
epdBusyWait(TIMER_TICKS_PER_SECOND);
|
||||
isInited = true;
|
||||
currentLut = EPD_LUT_DEFAULT;
|
||||
}
|
||||
static uint8_t epdGetStatus() {
|
||||
uint8_t sta;
|
||||
commandReadBegin(0x2F);
|
||||
sta = epdReadByte();
|
||||
commandReadEnd();
|
||||
return sta;
|
||||
}
|
||||
uint16_t epdGetBattery(void) {
|
||||
uint16_t voltage = 2600;
|
||||
uint8_t val;
|
||||
|
||||
epdReset();
|
||||
|
||||
shortCommand1(CMD_DISP_UPDATE_CTRL2, SCREEN_CMD_CLOCK_ON | SCREEN_CMD_ANALOG_ON);
|
||||
shortCommand(CMD_ACTIVATION);
|
||||
epdBusyWait(TIMER_TICKS_PER_MS * 1000);
|
||||
|
||||
for (val = 3; val < 8; val++) {
|
||||
shortCommand1(CMD_SETUP_VOLT_DETECT, val);
|
||||
epdBusyWait(TIMER_TICKS_PER_MS * 1000);
|
||||
if (epdGetStatus() & 0x10) { // set if voltage is less than threshold ( == 1.9 + val / 10)
|
||||
voltage = 1850 + mathPrvMul8x8(val, 100);
|
||||
break;
|
||||
}
|
||||
}
|
||||
//shortCommand(CMD_SOFT_RESET2);
|
||||
//epdBusyWait(TIMER_TICKS_PER_MS * 1000);
|
||||
shortCommand1(CMD_ENTER_SLEEP, 0x03);
|
||||
return voltage;
|
||||
}
|
||||
|
||||
void loadFixedTempOTPLUT() {
|
||||
shortCommand1(0x18, 0x48); // external temp sensor
|
||||
shortCommand2(0x1A, 0x05, 0x00); // < temp register
|
||||
shortCommand1(CMD_DISP_UPDATE_CTRL2, 0xB1); // mode 1 (i2C)
|
||||
shortCommand(CMD_ACTIVATION);
|
||||
epdBusyWait(TIMER_TICKS_PER_SECOND);
|
||||
}
|
||||
static void writeLut() {
|
||||
commandBegin(CMD_WRITE_LUT);
|
||||
for (uint8_t i = 0; i < (dispLutSize * 10); i++)
|
||||
epdSend(waveformbuffer[i]);
|
||||
commandEnd();
|
||||
}
|
||||
static void readLut() {
|
||||
commandReadBegin(0x33);
|
||||
uint16_t checksum = 0;
|
||||
uint16_t ident = 0;
|
||||
uint16_t shortl = 0;
|
||||
for (uint16_t c = 0; c < LUT_BUFFER_SIZE; c++) {
|
||||
waveformbuffer[c] = epdReadByte();
|
||||
}
|
||||
commandReadEnd();
|
||||
}
|
||||
static uint8_t getLutSize() {
|
||||
uint8_t ref = 0;
|
||||
for (uint8_t c = (LUT_BUFFER_SIZE - 4); c > 16; c--) {
|
||||
uint8_t check = waveformbuffer[c];
|
||||
for (uint8_t d = 1; d < 4; d++) {
|
||||
if (waveformbuffer[c + d] != check) {
|
||||
ref = c;
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
}
|
||||
end:;
|
||||
return ref + 1;
|
||||
}
|
||||
static void lutGroupDisable(uint8_t group) {
|
||||
if (dispLutSize == 7) {
|
||||
memset(&(waveform7->group[group]), 0x00, 5);
|
||||
} else {
|
||||
memset(&(waveform10->group[group]), 0x00, 5);
|
||||
}
|
||||
}
|
||||
static void lutGroupSpeedup(uint8_t group, uint8_t speed) {
|
||||
if (dispLutSize == 7) {
|
||||
for (uint8_t i = 0; i < 4; i++) {
|
||||
waveform7->group[group].phaselength[i] = 1 + (waveform7->group[group].phaselength[i] / speed);
|
||||
}
|
||||
} else {
|
||||
for (uint8_t i = 0; i < 4; i++) {
|
||||
waveform10->group[group].phaselength[i] = 1 + (waveform10->group[group].phaselength[i] / speed);
|
||||
}
|
||||
}
|
||||
}
|
||||
static void lutGroupRepeat(uint8_t group, uint8_t repeat) {
|
||||
if (dispLutSize == 7) {
|
||||
waveform7->group[group].repeat = repeat;
|
||||
} else {
|
||||
waveform10->group[group].repeat = repeat;
|
||||
}
|
||||
}
|
||||
static void lutGroupRepeatReduce(uint8_t group, uint8_t factor) {
|
||||
if (dispLutSize == 7) {
|
||||
waveform7->group[group].repeat = waveform7->group[group].repeat / factor;
|
||||
} else {
|
||||
waveform10->group[group].repeat = waveform10->group[group].repeat / factor;
|
||||
}
|
||||
}
|
||||
void selectLUT(uint8_t lut) {
|
||||
if (currentLut == lut) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (currentLut != EPD_LUT_DEFAULT) {
|
||||
// load the 'default' LUT for the current temperature in the EPD lut register
|
||||
shortCommand1(CMD_DISP_UPDATE_CTRL2, 0xB1); // mode 1?
|
||||
shortCommand(CMD_ACTIVATION);
|
||||
epdBusyWait(TIMER_TICKS_PER_SECOND);
|
||||
}
|
||||
|
||||
currentLut = lut;
|
||||
|
||||
// if we're going to be using the default LUT, we're done here.
|
||||
if (lut == EPD_LUT_DEFAULT) {
|
||||
return;
|
||||
}
|
||||
|
||||
// download the current LUT from the waveform buffer
|
||||
readLut();
|
||||
|
||||
if (dispLutSize == 0) {
|
||||
dispLutSize = getLutSize();
|
||||
dispLutSize /= 10;
|
||||
pr("lut size = %d\n", dispLutSize);
|
||||
#ifdef PRINT_LUT
|
||||
dump(waveformbuffer, LUT_BUFFER_SIZE);
|
||||
#endif
|
||||
memcpy(customLUT, waveformbuffer, dispLutSize * 10);
|
||||
}
|
||||
|
||||
switch (lut) {
|
||||
default:
|
||||
case EPD_LUT_NO_REPEATS:
|
||||
lutGroupDisable(LUTGROUP_NEGATIVE);
|
||||
lutGroupDisable(LUTGROUP_FASTBLINK);
|
||||
lutGroupRepeat(LUTGROUP_SLOWBLINK, 0);
|
||||
lutGroupSpeedup(LUTGROUP_SET, 2);
|
||||
lutGroupSpeedup(LUTGROUP_IMPROVE_SHARPNESS, 2);
|
||||
lutGroupRepeatReduce(LUTGROUP_IMPROVE_SHARPNESS, 2);
|
||||
lutGroupSpeedup(LUTGROUP_IMPROVE_REDS, 2);
|
||||
lutGroupRepeatReduce(LUTGROUP_IMPROVE_REDS, 2);
|
||||
lutGroupDisable(LUTGROUP_UNUSED);
|
||||
break;
|
||||
case EPD_LUT_FAST_NO_REDS:
|
||||
lutGroupDisable(LUTGROUP_NEGATIVE);
|
||||
lutGroupDisable(LUTGROUP_FASTBLINK);
|
||||
lutGroupDisable(LUTGROUP_SLOWBLINK);
|
||||
lutGroupSpeedup(LUTGROUP_SET, 2);
|
||||
lutGroupDisable(LUTGROUP_IMPROVE_REDS);
|
||||
lutGroupDisable(LUTGROUP_IMPROVE_SHARPNESS);
|
||||
lutGroupDisable(LUTGROUP_UNUSED);
|
||||
break;
|
||||
case EPD_LUT_FAST:
|
||||
lutGroupDisable(LUTGROUP_NEGATIVE);
|
||||
lutGroupDisable(LUTGROUP_FASTBLINK);
|
||||
lutGroupDisable(LUTGROUP_SLOWBLINK);
|
||||
lutGroupRepeat(LUTGROUP_SET, 1);
|
||||
lutGroupSpeedup(LUTGROUP_SET, 2);
|
||||
lutGroupDisable(LUTGROUP_IMPROVE_SHARPNESS);
|
||||
lutGroupDisable(LUTGROUP_IMPROVE_REDS);
|
||||
lutGroupDisable(LUTGROUP_UNUSED);
|
||||
break;
|
||||
}
|
||||
|
||||
// Handling if we received an OTA LUT
|
||||
if (lut == EPD_LUT_OTA) {
|
||||
memcpy(waveformbuffer, customLUT, dispLutSize * 10);
|
||||
writeLut();
|
||||
shortCommand1(CMD_GATE_LEVEL, customLUT[70]);
|
||||
commandBegin(CMD_SOURCE_LEVEL);
|
||||
epdSend(customLUT[71]);
|
||||
epdSend(customLUT[72]);
|
||||
epdSend(customLUT[73]);
|
||||
commandEnd();
|
||||
shortCommand1(CMD_DUMMY_PERIOD, customLUT[74]);
|
||||
shortCommand1(CMD_GATE_LINE_WIDTH, customLUT[75]);
|
||||
currentLut = lut;
|
||||
return;
|
||||
}
|
||||
|
||||
if (dispLutSize == 10) {
|
||||
lutGroupDisable(LUTGROUP_UNUSED);
|
||||
lutGroupDisable(LUTGROUP_UNKNOWN);
|
||||
lutGroupDisable(LUTGROUP_UNUSED3);
|
||||
lutGroupDisable(LUTGROUP_UNUSED4);
|
||||
}
|
||||
writeLut();
|
||||
}
|
||||
|
||||
void setWindowX(uint16_t start, uint16_t end) {
|
||||
shortCommand2(CMD_WINDOW_X_SIZE, start / 8, end / 8 - 1);
|
||||
}
|
||||
void setWindowY(uint16_t start, uint16_t end) {
|
||||
commandBegin(CMD_WINDOW_Y_SIZE);
|
||||
epdSend((start)&0xff);
|
||||
epdSend((start) >> 8);
|
||||
epdSend((end - 1) & 0xff);
|
||||
epdSend((end - 1) >> 8);
|
||||
commandEnd();
|
||||
}
|
||||
void setPosXY(uint16_t x, uint16_t y) {
|
||||
shortCommand1(CMD_XSTART_POS, (uint8_t)(x / 8));
|
||||
commandBegin(CMD_YSTART_POS);
|
||||
epdSend((y)&0xff);
|
||||
epdSend((y) >> 8);
|
||||
commandEnd();
|
||||
}
|
||||
void setColorMode(uint8_t red, uint8_t bw) {
|
||||
shortCommand1(CMD_DISP_UPDATE_CTRL, (red << 4) | bw);
|
||||
}
|
||||
void fillWindowWithPattern(bool color) {
|
||||
if (color == EPD_COLOR_RED) {
|
||||
shortCommand1(CMD_WRITE_PATTERN_RED, 0x00);
|
||||
} else {
|
||||
shortCommand1(CMD_WRITE_PATTERN_BW, 0x00);
|
||||
}
|
||||
}
|
||||
void clearWindow(bool color) {
|
||||
if (color == EPD_COLOR_RED) {
|
||||
shortCommand1(CMD_WRITE_PATTERN_RED, 0x66);
|
||||
} else {
|
||||
shortCommand1(CMD_WRITE_PATTERN_BW, 0x66);
|
||||
}
|
||||
}
|
||||
void clearScreen() {
|
||||
setWindowX(0, SCREEN_WIDTH);
|
||||
setWindowY(0, SCREEN_HEIGHT);
|
||||
setPosXY(0, 0);
|
||||
shortCommand1(CMD_DATA_ENTRY_MODE, 3); // was 3
|
||||
shortCommand1(CMD_WRITE_PATTERN_BW, 0x66);
|
||||
epdBusyWait(TIMER_TICKS_PER_MS * 100);
|
||||
shortCommand1(CMD_WRITE_PATTERN_RED, 0x66);
|
||||
epdBusyWait(TIMER_TICKS_PER_MS * 100);
|
||||
}
|
||||
void draw() {
|
||||
shortCommand1(0x22, 0xCF);
|
||||
// shortCommand1(0x22, SCREEN_CMD_REFRESH);
|
||||
shortCommand(0x20);
|
||||
epdBusyWait(TIMER_TICKS_PER_SECOND * 120);
|
||||
}
|
||||
void drawNoWait() {
|
||||
shortCommand1(0x22, 0xCF);
|
||||
// shortCommand1(0x22, SCREEN_CMD_REFRESH);
|
||||
shortCommand(0x20);
|
||||
}
|
||||
void drawWithSleep() {
|
||||
shortCommand1(0x22, 0xCF);
|
||||
// shortCommand1(0x22, SCREEN_CMD_REFRESH);
|
||||
shortCommand(0x20);
|
||||
uint8_t tmp_P2FUNC = P2FUNC;
|
||||
uint8_t tmp_P2DIR = P2DIR;
|
||||
uint8_t tmp_P2PULL = P2PULL;
|
||||
uint8_t tmp_P2LVLSEL = P2LVLSEL;
|
||||
P2FUNC &= 0xfd;
|
||||
P2DIR |= 2;
|
||||
P2PULL |= 2;
|
||||
P2LVLSEL |= 2;
|
||||
|
||||
P2CHSTA &= 0xfd;
|
||||
P2INTEN |= 2;
|
||||
P2CHSTA &= 0xfd;
|
||||
sleepForMsec(TIMER_TICKS_PER_SECOND * 120);
|
||||
wdtOn();
|
||||
P2CHSTA &= 0xfd;
|
||||
P2INTEN &= 0xfd;
|
||||
|
||||
P2FUNC = tmp_P2FUNC;
|
||||
P2DIR = tmp_P2DIR;
|
||||
P2PULL = tmp_P2PULL;
|
||||
P2LVLSEL = tmp_P2LVLSEL;
|
||||
eepromPrvDeselect();
|
||||
}
|
||||
void epdWaitRdy() {
|
||||
epdBusyWait(TIMER_TICKS_PER_SECOND * 120);
|
||||
}
|
||||
void drawLineHorizontal(bool color, uint16_t x1, uint16_t x2, uint16_t y) {
|
||||
setWindowX(x1, x2);
|
||||
setWindowY(y, y + 1);
|
||||
if (color) {
|
||||
shortCommand1(CMD_WRITE_PATTERN_RED, 0xE6);
|
||||
} else {
|
||||
shortCommand1(CMD_WRITE_PATTERN_BW, 0xE6);
|
||||
}
|
||||
epdBusyWait(TIMER_TICKS_PER_MS * 100);
|
||||
}
|
||||
void drawLineVertical(bool color, uint16_t x, uint16_t y1, uint16_t y2) {
|
||||
setWindowY(y1, y2);
|
||||
setWindowX(x, x + 8);
|
||||
shortCommand1(CMD_DATA_ENTRY_MODE, 3);
|
||||
setPosXY(x, y1);
|
||||
if (color) {
|
||||
commandBegin(CMD_WRITE_FB_RED);
|
||||
} else {
|
||||
commandBegin(CMD_WRITE_FB_BW);
|
||||
}
|
||||
uint8_t __xdata c = 0x80;
|
||||
c >>= (x % 8);
|
||||
for (; y1 < y2; y1++) {
|
||||
epdSend(c);
|
||||
}
|
||||
commandEnd();
|
||||
}
|
||||
void beginFullscreenImage() {
|
||||
setColorMode(EPD_MODE_NORMAL, EPD_MODE_INVERT);
|
||||
setWindowX(0, SCREEN_WIDTH);
|
||||
setWindowY(0, SCREEN_HEIGHT);
|
||||
shortCommand1(CMD_DATA_ENTRY_MODE, 3);
|
||||
setPosXY(0, 0);
|
||||
}
|
||||
void beginWriteFramebuffer(bool color) {
|
||||
if (color == EPD_COLOR_RED) {
|
||||
commandBegin(CMD_WRITE_FB_RED);
|
||||
} else {
|
||||
commandBegin(CMD_WRITE_FB_BW);
|
||||
}
|
||||
epdDeselect();
|
||||
}
|
||||
void endWriteFramebuffer() {
|
||||
commandEnd();
|
||||
}
|
||||
void loadRawBitmap(uint8_t* bmp, uint16_t x, uint16_t y, bool color) {
|
||||
uint16_t xsize = bmp[0] / 8;
|
||||
if (bmp[0] % 8) xsize++;
|
||||
uint16_t size = xsize * bmp[1];
|
||||
setWindowX(x, x + (xsize * 8));
|
||||
setWindowY(y, bmp[1] + y);
|
||||
setPosXY(x, y);
|
||||
shortCommand1(CMD_DATA_ENTRY_MODE, 3);
|
||||
if (color) {
|
||||
commandBegin(CMD_WRITE_FB_RED);
|
||||
} else {
|
||||
commandBegin(CMD_WRITE_FB_BW);
|
||||
}
|
||||
bmp += 2;
|
||||
while (size--) {
|
||||
epdSend(*(bmp++));
|
||||
}
|
||||
commandEnd();
|
||||
}
|
||||
void printBarcode(const uint8_t* string, uint16_t x, uint16_t y) {
|
||||
setWindowY(y, 1);
|
||||
setWindowX(x, x + 8);
|
||||
setPosXY(x, y);
|
||||
shortCommand1(CMD_DATA_ENTRY_MODE, 1);
|
||||
commandBegin(CMD_WRITE_FB_BW);
|
||||
struct BarcodeInfo __xdata bci = {
|
||||
.str = string,
|
||||
};
|
||||
while (!barcodeIsDone(&bci)) {
|
||||
if (barcodeNextBar(&bci)) {
|
||||
epdSend(0xFF);
|
||||
} else {
|
||||
epdSend(0x00);
|
||||
}
|
||||
}
|
||||
commandEnd();
|
||||
}
|
||||
// stuff for printing text
|
||||
static void pushXFontBytesToEPD(uint8_t byte1, uint8_t byte2) {
|
||||
if (epdCharSize == 1) {
|
||||
uint8_t offset = 7 - (fontCurXpos % 8);
|
||||
for (uint8_t c = 0; c < 8; c++) {
|
||||
if (byte2 & (1 << (7 - c))) rbuffer[c] |= (1 << offset);
|
||||
}
|
||||
for (uint8_t c = 0; c < 8; c++) {
|
||||
if (byte1 & (1 << (7 - c))) rbuffer[8 + c] |= (1 << offset);
|
||||
}
|
||||
fontCurXpos++;
|
||||
} else {
|
||||
uint8_t offset = 6 - (fontCurXpos % 8);
|
||||
// double font size
|
||||
for (uint8_t c = 0; c < 8; c++) {
|
||||
if (byte2 & (1 << (7 - c))) {
|
||||
rbuffer[c * 2] |= (3 << offset);
|
||||
rbuffer[(c * 2) + 1] |= (3 << offset);
|
||||
}
|
||||
}
|
||||
for (uint8_t c = 0; c < 8; c++) {
|
||||
if (byte1 & (1 << (7 - c))) {
|
||||
rbuffer[(c * 2) + 16] |= (3 << offset);
|
||||
rbuffer[(c * 2) + 17] |= (3 << offset);
|
||||
}
|
||||
}
|
||||
fontCurXpos += 2;
|
||||
}
|
||||
if (fontCurXpos % 8 == 0) {
|
||||
// next byte, flush current byte to EPD
|
||||
for (uint8_t i = 0; i < (16 * epdCharSize); i++) {
|
||||
epdSend(rbuffer[i]);
|
||||
}
|
||||
memset(rbuffer, 0, 32);
|
||||
}
|
||||
}
|
||||
static void bufferByteShift(uint8_t byte) {
|
||||
/*
|
||||
rbuffer[0] = 0; // previous value
|
||||
rbuffer[1] = y%8; // offset
|
||||
rbuffer[2] = 0; // current byte counter;
|
||||
rbuffer[3] = 1+(epdCharsize*2);
|
||||
*/
|
||||
|
||||
if (rbuffer[1] == 0) {
|
||||
epdSend(byte);
|
||||
} else {
|
||||
uint8_t offset = rbuffer[1];
|
||||
rbuffer[0] |= (byte >> offset);
|
||||
epdSend(rbuffer[0]);
|
||||
// epdSend(byte);
|
||||
rbuffer[0] = (byte << (8 - offset));
|
||||
rbuffer[2]++;
|
||||
if (rbuffer[2] == rbuffer[3]) {
|
||||
epdSend(rbuffer[0]);
|
||||
rbuffer[0] = 0;
|
||||
rbuffer[2] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
static void pushYFontBytesToEPD(uint8_t byte1, uint8_t byte2) {
|
||||
if (epdCharSize == 2) {
|
||||
for (uint8_t j = 0; j < 2; j++) {
|
||||
uint8_t c = 0;
|
||||
for (uint8_t i = 7; i != 255; i--) {
|
||||
if (byte1 & (1 << i)) c |= (0x03 << ((i % 4) * 2));
|
||||
if ((i % 4) == 0) {
|
||||
bufferByteShift(c);
|
||||
c = 0;
|
||||
}
|
||||
}
|
||||
for (uint8_t i = 7; i != 255; i--) {
|
||||
if (byte2 & (1 << i)) c |= (0x03 << ((i % 4) * 2));
|
||||
if ((i % 4) == 0) {
|
||||
bufferByteShift(c);
|
||||
c = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
bufferByteShift(byte1);
|
||||
bufferByteShift(byte2);
|
||||
}
|
||||
}
|
||||
void writeCharEPD(uint8_t c) {
|
||||
// Writes a single character to the framebuffer
|
||||
bool empty = true;
|
||||
for (uint8_t i = 0; i < 20; i++) {
|
||||
if (font[c][i]) empty = false;
|
||||
}
|
||||
if (empty) {
|
||||
for (uint8_t i = 0; i < 8; i++) {
|
||||
if (directionY) {
|
||||
pushYFontBytesToEPD(0x00, 0x00);
|
||||
} else {
|
||||
pushXFontBytesToEPD(0x00, 0x00);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t begin = 0;
|
||||
while (font[c][begin] == 0x00 && font[c][begin + 1] == 0x00) {
|
||||
begin += 2;
|
||||
}
|
||||
|
||||
uint8_t end = 20;
|
||||
while (font[c][end - 1] == 0x00 && font[c][end - 2] == 0x00) {
|
||||
end -= 2;
|
||||
}
|
||||
|
||||
for (uint8_t pos = begin; pos < end; pos += 2) {
|
||||
if (directionY) {
|
||||
pushYFontBytesToEPD(font[c][pos + 1], font[c][pos]);
|
||||
} else {
|
||||
pushXFontBytesToEPD(font[c][pos], font[c][pos + 1]);
|
||||
}
|
||||
}
|
||||
|
||||
// spacing between characters
|
||||
if (directionY) {
|
||||
pushYFontBytesToEPD(0x00, 0x00);
|
||||
} else {
|
||||
pushXFontBytesToEPD(0x00, 0x00);
|
||||
}
|
||||
}
|
||||
|
||||
// Print text to the EPD. Origin is top-left
|
||||
void epdPrintBegin(uint16_t x, uint16_t y, bool direction, bool fontsize, bool color) {
|
||||
directionY = direction;
|
||||
epdCharSize = 1 + fontsize;
|
||||
if (directionY) {
|
||||
uint8_t extra = 0;
|
||||
|
||||
// provisions for dealing with font in Y direction, byte-unaligned
|
||||
if (x % 8) {
|
||||
extra = 8;
|
||||
rbuffer[0] = 0; // previous value
|
||||
rbuffer[1] = x % 8; // offset
|
||||
rbuffer[2] = 0; // current byte counter;
|
||||
rbuffer[3] = (epdCharSize * 2);
|
||||
} else {
|
||||
rbuffer[1] = 0;
|
||||
}
|
||||
|
||||
setWindowY(y, 1);
|
||||
if (epdCharSize == 2) {
|
||||
setWindowX(x, x + 32 + extra);
|
||||
setPosXY(x, y);
|
||||
} else {
|
||||
setWindowX(x, x + 16 + extra);
|
||||
setPosXY(x, y);
|
||||
}
|
||||
shortCommand1(CMD_DATA_ENTRY_MODE, 1); // was 3
|
||||
} else {
|
||||
if (epdCharSize == 2) {
|
||||
x /= 2;
|
||||
x *= 2;
|
||||
setWindowY(y, y + 32);
|
||||
} else {
|
||||
setWindowY(y, y + 16);
|
||||
}
|
||||
setPosXY(x, y);
|
||||
fontCurXpos = x;
|
||||
setWindowX(x, SCREEN_WIDTH);
|
||||
shortCommand1(CMD_DATA_ENTRY_MODE, 7);
|
||||
memset(rbuffer, 0, 32);
|
||||
}
|
||||
|
||||
if (color) {
|
||||
commandBegin(CMD_WRITE_FB_RED);
|
||||
} else {
|
||||
commandBegin(CMD_WRITE_FB_BW);
|
||||
}
|
||||
}
|
||||
void epdPrintEnd() {
|
||||
if (!directionY && ((fontCurXpos % 8) != 0)) {
|
||||
for (uint8_t i = 0; i < (16 * epdCharSize); i++) {
|
||||
epdSend(rbuffer[i]);
|
||||
}
|
||||
}
|
||||
commandEnd();
|
||||
}
|
||||
|
||||
extern uint8_t __xdata blockXferBuffer[];
|
||||
|
||||
void readRam() {
|
||||
setWindowY(296, 0);
|
||||
setWindowX(0, 8);
|
||||
setPosXY(0, 296);
|
||||
shortCommand1(CMD_DATA_ENTRY_MODE, 1); // was 3
|
||||
shortCommand1(0x41, 0x00);
|
||||
commandReadBegin(0x27);
|
||||
epdReadByte();
|
||||
|
||||
for (uint16_t c = 0; c < 293; c++) {
|
||||
blockXferBuffer[c] = epdReadByte() | 0x10;
|
||||
}
|
||||
commandReadEnd();
|
||||
commandBegin(CMD_WRITE_FB_BW);
|
||||
for (uint16_t c = 0; c < 296; c++) {
|
||||
epdSend(blockXferBuffer[c]);
|
||||
}
|
||||
commandEnd();
|
||||
}
|
||||
26
zbs243_shared/board/zbs29_BW_ssd1619/screen.h
Normal file
26
zbs243_shared/board/zbs29_BW_ssd1619/screen.h
Normal file
@@ -0,0 +1,26 @@
|
||||
#ifndef _SCREEN_H_
|
||||
#define _SCREEN_H_
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include "../ssd1619.h"
|
||||
|
||||
|
||||
#define SCREEN_WIDTH 128
|
||||
#define SCREEN_HEIGHT 296
|
||||
|
||||
#define SCREEN_NUM_GREYS 5
|
||||
#define SCREEN_FIRST_GREY_IDX 0
|
||||
#define SCREEN_EXTRA_COLOR_INDEX -1 //set to negative if nonexistent
|
||||
#define SCREEN_TX_BPP 4 //in transit
|
||||
|
||||
#define SCREEN_WIDTH_MM 29
|
||||
#define SCREEN_HEIGHT_MM 67
|
||||
|
||||
#define SCREEN_BYTE_FILL 0x44 //white
|
||||
|
||||
#define SCREEN_TYPE TagScreenEink_BW_1bpp
|
||||
|
||||
#define SCREEN_DATA_PASSES 2
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user