From 9410c4787508bfd3b32a194b8dd3b6a34fab4002 Mon Sep 17 00:00:00 2001
From: VstudioLAB <57193516+VstudioLAB@users.noreply.github.com>
Date: Wed, 22 Nov 2023 00:25:17 +0100
Subject: [PATCH 1/2] Added French
Added french langage as an option for tag content
---
ESP32_AP-Flasher/data/www/index.html.gz | Bin 4834 -> 4843 bytes
ESP32_AP-Flasher/platformio.ini | 5 +++--
ESP32_AP-Flasher/src/language.cpp | 14 ++++++++++----
ESP32_AP-Flasher/wwwroot/index.html | 1 +
4 files changed, 14 insertions(+), 6 deletions(-)
diff --git a/ESP32_AP-Flasher/data/www/index.html.gz b/ESP32_AP-Flasher/data/www/index.html.gz
index feffb6d4574d5c3086fd023bef556a82c65cb1ec..e76fb1fa7efc1019ebbffe0249630388b1f02f26 100644
GIT binary patch
delta 4714
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
C*cE*M
diff --git a/ESP32_AP-Flasher/platformio.ini b/ESP32_AP-Flasher/platformio.ini
index 7e4a9ae3..e0759d1c 100644
--- a/ESP32_AP-Flasher/platformio.ini
+++ b/ESP32_AP-Flasher/platformio.ini
@@ -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
diff --git a/ESP32_AP-Flasher/src/language.cpp b/ESP32_AP-Flasher/src/language.cpp
index 7d5b9923..61eabf54 100644
--- a/ESP32_AP-Flasher/src/language.cpp
+++ b/ESP32_AP-Flasher/src/language.cpp
@@ -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;
diff --git a/ESP32_AP-Flasher/wwwroot/index.html b/ESP32_AP-Flasher/wwwroot/index.html
index 3d2fa76a..88ea06d1 100644
--- a/ESP32_AP-Flasher/wwwroot/index.html
+++ b/ESP32_AP-Flasher/wwwroot/index.html
@@ -287,6 +287,7 @@
+
From 66c7ad6140969de1fd0538643d56d4b0fa0f54b1 Mon Sep 17 00:00:00 2001
From: VstudioLAB <57193516+VstudioLAB@users.noreply.github.com>
Date: Wed, 29 Nov 2023 00:26:15 +0100
Subject: [PATCH 2/2] =?UTF-8?q?Added=20ST=E2=80=90GM29XXF=202.9"=20Support?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
added ST‐GM29XXF 2.9" support
---
ESP32_AP-Flasher/data/tagtypes/21.json | 74 ++
.../data/www/content_cards.json.gz | Bin 3260 -> 3284 bytes
ESP32_AP-Flasher/wwwroot/content_cards.json | 57 +-
oepl-definitions.h | 1 +
zbs243_Tag_FW/powermgt.c | 6 +-
zbs243_Tag_FW/syncedproto.c | 4 +-
zbs243_shared/board/zbs29_BW_ssd1619/board.c | 163 ++++
zbs243_shared/board/zbs29_BW_ssd1619/board.h | 36 +
zbs243_shared/board/zbs29_BW_ssd1619/make.mk | 7 +
.../board/zbs29_BW_ssd1619/old_screen.c | 1 +
zbs243_shared/board/zbs29_BW_ssd1619/screen.c | 834 ++++++++++++++++++
zbs243_shared/board/zbs29_BW_ssd1619/screen.h | 26 +
12 files changed, 1186 insertions(+), 23 deletions(-)
create mode 100644 ESP32_AP-Flasher/data/tagtypes/21.json
create mode 100644 zbs243_shared/board/zbs29_BW_ssd1619/board.c
create mode 100644 zbs243_shared/board/zbs29_BW_ssd1619/board.h
create mode 100644 zbs243_shared/board/zbs29_BW_ssd1619/make.mk
create mode 100644 zbs243_shared/board/zbs29_BW_ssd1619/old_screen.c
create mode 100644 zbs243_shared/board/zbs29_BW_ssd1619/screen.c
create mode 100644 zbs243_shared/board/zbs29_BW_ssd1619/screen.h
diff --git a/ESP32_AP-Flasher/data/tagtypes/21.json b/ESP32_AP-Flasher/data/tagtypes/21.json
new file mode 100644
index 00000000..e380a7f4
--- /dev/null
+++ b/ESP32_AP-Flasher/data/tagtypes/21.json
@@ -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 ] }
+ ]
+ }
+}
diff --git a/ESP32_AP-Flasher/data/www/content_cards.json.gz b/ESP32_AP-Flasher/data/www/content_cards.json.gz
index 263bdfb2be2caf4681dd5def77f004a76c6f9caf..982947461dd2cabd8928780eae43614aa105d514 100644
GIT binary patch
delta 3191
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
delta 3149
zcmV-T46^go8N3;gJpt>HJ|BPWC^M0H+$D)!?DsBy`t}<_e!)M4tnqm5d$QRpe+il~
z_`NnV)bNP#j852^2gXcC7C4nNO(@Ydq#j9>%t*phM)X`8mi0(ZxiCx-sR+A)3qez&
zWuYS0C#UoZ5DUeKkwh`g{{>f5=3a*P@JA$-Vv#|(Obf%M=vRxG&dh&2$F=_CZjg!y
zLbj@_L3OoTUG2PC++1L8y>eGS`w!$)(X9UdU;G6Cuh<+pf#h12^=dHB!=n(;^YBDQ
zzzzRAk-`$3a${1KXc8-az5HNF?b_#jf={h^(67B))@OLej7*#F@+-Uq@TELyg8dqY
znJk1M>lqh?VfrO3ks5#a!*#h$GoGd>1#@yuQy%xpCD35#gk*d&HAG0eb-5HV$ru&0
zDK0!j6v)Zl2#PtdNd<{{Ye8I0g0x%~N{}f{6C(v9vByQmgLuj$fyE;VH+X9{Wde|N
zp3*sD-?vo?HH6Y8nN9M91V`fmkQ%0{raua+_kUY&&5aUrLkjzn>H9%`r!u?Ie
zZ@dR?Z`s>oZE^G0JMk-5ER{6wV3?&3=|2ykdCqw>A!mqMzL6wwol+#f(CksDECq4YO}u7c7|_(yNv|ePVDf32
z_E6Y#&LR$W^07qhOsb5gA+~-v{+^6rH}#Z^BE^^paTk$JByc#ALcoXNLm?(3+VC8V
zMIqt_e8;I@!YoKzSP#9bGU$3r;{_E0N9_U%GgW^m9%$wzmAu8@-PoV?GO*f?c|$$liWrz^H8q`}QFs^Y>)272}@x^gI9
z5jDnRh=0b=bflmv+Um^4qc4Bb7
z8~Fbvgu~d+f$yT3+ECI^!{RJS#GUZ2Kqr
z50&Yymbv|l#twfr%knf-vTq6Y=Q{fTw}3B^+9xB%Y_4^f)10XjF0Melu6QM=PJ-=2
zPWIsuY=R{aX%JWod4B;H!MTI`OXBL|3rE%9!tX^TK798BsTFMzeIodKN;!#Q*A^NJxC+XQj2Z`@Oig1pfD266muQ^}6F%4SqCP@3SJ0%(JS*onBL
z#I8?1qIS3$n93#g$3POgwLg#_0cy>L;?b4U34DJMPZrNnGE-QXzz6zIx5@JuQ>y)h83Pn|jFC&slZ07gI*cO7
zRLHrkwIXX9)47&bhkOJERkMjT#I2Qlz+x4~R52SDlL^Q>WHMlQi7oWGZ0Q!USg~ct
z1>1iLZY4sN2aKwfzJ~uEXfW{YgYNGRI==e|U)}Eh>h?pZ{eoQXgk<6D=pa}-7tUi7CkMqNegaaiyv7;6i5B8`3$F4%t!
ziy$`m6Zj6S4@r!`3vV)k3>>yA>=by+u30Mcj0y9EM|`sISk1xdTf)OLHN&XWOWr5R
zd>yhxm%!u$%)uvtJptC@CX|gdXMoBdW%yE#ZV`;2(453>OyV_Q{6;So?kZ0-YRL~EjX^~R=~
zjwa2;E_#^oNejI10J%zL5cCEaaB)OFHepriC27*G3&=~AA@CHw(J{c3vO;6*N0QC{
zoB#ZKxEKyrboMyxfh>)VQx=DKb0{3>zMKKtl%!en)Jl~y0_hh4c#T8MeYt;EvC3Af
zbEdeAIS$g#iN-VnZQk(wg)R%{SO9`#8??z<%thoHO{owpMbD2XyfD9j$UyUnZAf58
zxG}Q+JrtCl){q_9z?J#+VFoo>IKiztj0e)O8{nh+|`K&d$f;^Ux8T7v#|`P=p)Ar
zFOv1{>I*dbWA};|j$g~v*s~;l&J+0$9)saTD8+*66Xzk=3SCPeg1mp*w;{z0E3Ww7*+E*@#_YFHTAbQM-6x3+?3qu_6YV~$^&t(~#A
zTiEvS6#Q-6wg;x*@BM#gwg#})axY$#Vt-G~7s_moy>Vq@xL92l@tbd$~M0U535Q?<`
nlnOeAFsj~EO6UHlBvuM)FTI
+#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"
+ );
+}
\ No newline at end of file
diff --git a/zbs243_shared/board/zbs29_BW_ssd1619/board.h b/zbs243_shared/board/zbs29_BW_ssd1619/board.h
new file mode 100644
index 00000000..4684a303
--- /dev/null
+++ b/zbs243_shared/board/zbs29_BW_ssd1619/board.h
@@ -0,0 +1,36 @@
+#ifndef _BOARD_H_
+#define _BOARD_H_
+
+#include
+
+#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
diff --git a/zbs243_shared/board/zbs29_BW_ssd1619/make.mk b/zbs243_shared/board/zbs29_BW_ssd1619/make.mk
new file mode 100644
index 00000000..d1083181
--- /dev/null
+++ b/zbs243_shared/board/zbs29_BW_ssd1619/make.mk
@@ -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
\ No newline at end of file
diff --git a/zbs243_shared/board/zbs29_BW_ssd1619/old_screen.c b/zbs243_shared/board/zbs29_BW_ssd1619/old_screen.c
new file mode 100644
index 00000000..9494884c
--- /dev/null
+++ b/zbs243_shared/board/zbs29_BW_ssd1619/old_screen.c
@@ -0,0 +1 @@
+#include "../ssd1619.c"
diff --git a/zbs243_shared/board/zbs29_BW_ssd1619/screen.c b/zbs243_shared/board/zbs29_BW_ssd1619/screen.c
new file mode 100644
index 00000000..abc290f3
--- /dev/null
+++ b/zbs243_shared/board/zbs29_BW_ssd1619/screen.c
@@ -0,0 +1,834 @@
+#include "../ssd1619.h"
+
+#include
+#include
+
+#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();
+}
diff --git a/zbs243_shared/board/zbs29_BW_ssd1619/screen.h b/zbs243_shared/board/zbs29_BW_ssd1619/screen.h
new file mode 100644
index 00000000..e724816e
--- /dev/null
+++ b/zbs243_shared/board/zbs29_BW_ssd1619/screen.h
@@ -0,0 +1,26 @@
+#ifndef _SCREEN_H_
+#define _SCREEN_H_
+
+#include
+#include
+#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