6 Commits
2.71 ... had

Author SHA1 Message Date
Jelmer
2204af5d49 Changed AP channel back to 11 2023-03-26 00:31:55 +01:00
Jelmer
48539ef1ad version as in use on hackaday Berlin 2023 2023-03-23 11:09:22 +01:00
Jelmer
a8934dd1a0 no commands yet 2023-03-18 12:04:50 +01:00
Jelmer
046d08cd18 added start/stop event mode 2023-03-11 15:24:13 +01:00
Jelmer
e5c06b39b4 working mesh 2023-03-11 13:39:22 +01:00
Jelmer
daea208c50 bitmaps 2023-03-10 18:57:09 +01:00
23 changed files with 1235 additions and 66 deletions

3
.vscode/settings.json vendored Normal file
View File

@@ -0,0 +1,3 @@
{
"cmake.sourceDirectory": "${workspaceFolder}/esp32_fw/.pio/libdeps/lolin32_lite/ESP Async WebServer"
}

View File

@@ -53,6 +53,16 @@ struct MacFrameBcast {
#define PKT_PING 0xED
#define PKT_PONG 0xEE
#define PKT_EVENT_PONG 0xC1
#define PKT_EVENT_DATA_REQ 0xC2
#define PKT_EVENT_DATA 0xC3
struct eventData {
uint8_t checksum;
uint8_t eventDataID;
uint8_t data[];
} __packed;
struct AvailDataReq {
uint8_t checksum;
uint8_t lastPacketLQI;
@@ -138,7 +148,7 @@ struct espAvailDataReq {
} __packed;
#define TIMER_TICKS_PER_MS 1333UL
uint16_t __xdata version = 0x0007;
uint16_t __xdata version = 0x000A;
#define RAW_PKT_PADDING 2
static uint8_t __xdata mRxBuf[COMMS_MAX_PACKET_SZ];
@@ -169,6 +179,10 @@ uint8_t seq = 0; // holds current sequence
uint8_t __xdata blockbuffer[BLOCK_XFER_BUFFER_SIZE]; // block transfer buffer
uint8_t lastAckMac[8] = {0};
#define EVENT_PKT_SIZE 100
uint8_t *eventDataBuffer = blockbuffer + 1024;
bool __xdata eventMode = false;
// these variables hold the current mac were talking to
#define CONCURRENT_REQUEST_DELAY 1200UL * TIMER_TICKS_PER_MS
uint32_t __xdata lastBlockRequest = 0;
@@ -283,6 +297,7 @@ void deleteAllPendingDataForVer(const uint8_t *ver) {
#define ZBS_RX_WAIT_HEADER 0
#define ZBS_RX_WAIT_SDA 1
#define ZBS_RX_WAIT_CANCEL 2
#define ZBS_RX_WAIT_EVENTD 3
void processSerial(uint8_t lastchar) {
// uartTx(lastchar); echo
switch (RXState) {
@@ -292,12 +307,34 @@ void processSerial(uint8_t lastchar) {
cmdbuffer[c] = cmdbuffer[c + 1];
}
cmdbuffer[3] = lastchar;
if (strncmp(cmdbuffer, "SDA>", 4) == 0) {
if ((strncmp(cmdbuffer, "SDA>", 4) == 0) && (eventMode == false)) {
RXState = ZBS_RX_WAIT_SDA;
bytesRemain = sizeof(struct pendingData);
serialbufferp = serialbuffer;
break;
}
if (strncmp(cmdbuffer, "UED>", 4) == 0) {
RXState = ZBS_RX_WAIT_EVENTD;
bytesRemain = sizeof(struct eventData) + EVENT_PKT_SIZE;
serialbufferp = blockbuffer;
break;
}
if (strncmp(cmdbuffer, "EEM>", 4) == 0) {
// enter event mode
eventMode = true;
pr("ACK>");
break;
}
if (strncmp(cmdbuffer, "SEM>", 4) == 0) {
// disable event mode
eventMode = false;
pr("ACK>");
break;
}
if (strncmp(cmdbuffer, "CXD>", 4) == 0) {
RXState = ZBS_RX_WAIT_CANCEL;
bytesRemain = sizeof(struct pendingData);
@@ -314,7 +351,20 @@ void processSerial(uint8_t lastchar) {
wdtDeviceReset();
}
break;
case ZBS_RX_WAIT_EVENTD:
*serialbufferp = lastchar;
serialbufferp++;
bytesRemain--;
if (bytesRemain == 0) {
if (checkCRC(blockbuffer, sizeof(struct eventData) + EVENT_PKT_SIZE)) {
xMemCopyShort((void *)eventDataBuffer, blockbuffer, sizeof(struct eventData) + EVENT_PKT_SIZE);
pr("ACK>\n");
} else {
pr("NOK>\n");
}
RXState = ZBS_RX_WAIT_HEADER;
}
break;
case ZBS_RX_WAIT_SDA:
*serialbufferp = lastchar;
serialbufferp++;
@@ -643,7 +693,11 @@ void sendCancelXfer(uint8_t *dst) {
void sendPong(void *__xdata buf) {
struct MacFrameBcast *rxframe = (struct MacFrameBcast *)buf;
struct MacFrameNormal *frameHeader = (struct MacFrameNormal *)(radiotxbuffer + 1);
radiotxbuffer[sizeof(struct MacFrameNormal) + 1] = PKT_PONG;
if (eventMode) {
radiotxbuffer[sizeof(struct MacFrameNormal) + 1] = PKT_EVENT_PONG;
} else {
radiotxbuffer[sizeof(struct MacFrameNormal) + 1] = PKT_PONG;
}
radiotxbuffer[0] = sizeof(struct MacFrameNormal) + 1 + RAW_PKT_PADDING;
memcpy(frameHeader->src, mSelfMac, 8);
memcpy(frameHeader->dst, rxframe->src, 8);
@@ -654,6 +708,23 @@ void sendPong(void *__xdata buf) {
radioTx(radiotxbuffer);
}
void sendEventData(void *__xdata buf) {
struct MacFrameBcast *rxframe = (struct MacFrameBcast *)buf;
struct MacFrameNormal *frameHeader = (struct MacFrameNormal *)(radiotxbuffer + 1);
struct eventData *ed = (struct eventData *)(radiotxbuffer + sizeof(struct MacFrameNormal) + 2);
radiotxbuffer[sizeof(struct MacFrameNormal) + 1] = PKT_EVENT_DATA;
radiotxbuffer[0] = sizeof(struct MacFrameNormal) + 1 + sizeof(struct eventData) + EVENT_PKT_SIZE + RAW_PKT_PADDING;
memcpy(ed, eventDataBuffer, sizeof(struct eventData) + EVENT_PKT_SIZE);
addCRC(ed, sizeof(struct eventData) + EVENT_PKT_SIZE);
memcpy(frameHeader->src, mSelfMac, 8);
memcpy(frameHeader->dst, rxframe->src, 8);
radiotxbuffer[1] = 0x41; // fast way to set the appropriate bits
radiotxbuffer[2] = 0xCC; // normal frame
frameHeader->seq = seq++;
frameHeader->pan = rxframe->srcPan;
radioTx(radiotxbuffer);
}
// main loop
void main(void) {
clockingAndIntsInit();
@@ -682,7 +753,7 @@ void main(void) {
rndSeed(mSelfMac[0] ^ (uint8_t)timerGetLowBits(), mSelfMac[1]);
// wdtSetResetVal(0xFD0DCF);
// wdtOn();
radioSetChannel(RADIO_FIRST_CHANNEL);
radioSetChannel(11);
radioSetTxPower(10);
radioRxEnable(true, true);
@@ -715,10 +786,17 @@ void main(void) {
case PKT_XFER_COMPLETE:
processXferComplete(radiorxbuffer);
break;
case PKT_EVENT_DATA_REQ:
if (eventMode == true) sendEventData(radiorxbuffer);
break;
case PKT_PING:
sendPong(radiorxbuffer);
break;
case PKT_AVAIL_DATA_SHORTREQ:
if (eventMode == true) {
sendPong(radiorxbuffer);
break;
}
// a short AvailDataReq is basically a very short (1 byte payload) packet that requires little preparation on the tx side, for optimal battery use
// bytes of the struct are set 0, so it passes the checksum test, and the ESP32 can detect that no interesting payload is sent
if (ret == 18) {

View File

@@ -217,8 +217,8 @@ void radioSetChannel(uint8_t ch) {
static const uint8_t perChannelSetting1[] = {0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x22, 0x22, 0x22, 0x22, 0x33, 0x33, 0x33, 0x33, 0x33};
static const uint8_t perChannelSetting2[] = {4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 2, 2, 2};
if (ch < RADIO_FIRST_CHANNEL || ch >= RADIO_FIRST_CHANNEL + RADIO_NUM_CHANNELS)
return;
//if (ch < RADIO_FIRST_CHANNEL || ch >= RADIO_FIRST_CHANNEL + RADIO_NUM_CHANNELS)
// return;
RADIO_channel = ch; // configmed to be at least RX channel
RADIO_command = RADIO_CMD_RECEIVE;

View File

@@ -8,7 +8,10 @@
void RF_IRQ1(void) __interrupt (4);
void RF_IRQ2(void) __interrupt (5);
#define RADIO_PAD_LEN_BY 2
extern bool radioChannelClear();
#include "../radioCommon.h"

View File

@@ -0,0 +1,115 @@
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0"/>
<title>Event Mesh - messages</title>
<link rel="stylesheet" href="main.css" type="text/css"/>
</head>
<body>
<header>
<div class="logo">Event Mesh - messages</div>
</header>
<div class="container">
<div class="blocks"><ul></ul></div>
<div class="window">
<iframe name="empty" style="border:1px solid darkgrey; width:100%; height:4em;"></iframe>
<div class="actionbox">
<form action="event_start" method="POST" target="empty">
<input type="submit" value="Enable Event Ping">
</form>
<form action="event_stop" method="POST" target="empty">
<input type="submit" value="Disable Event Ping">
</form>
</div>
<br/>
<div class="actionbox">
<form action="event_dataNowNext" method="POST" target="empty">
ID:<input name="id" size=3 maxlength=3 placeholder="1"/><br/>
Now:<input name="nowStart" size=5 maxlength=5 type="text" placeholder="10:00">-
<input name="nowEnd" size=5 maxlength=5 type="text" placeholder="10:30"><br/>
<input name="Row1" type="text" placeholder="Row1" size=20 maxlength=25><br/>
<input name="Row2" type="text" placeholder="Row2" size=20 maxlength=25><br/>
Next:<input name="nextStart" size=5 maxlength=5 type="text" placeholder="10:35">-
<input name="nextEnd" size=5 maxlength=5 type="text" placeholder="11:00"><br/>
<input name="Row3" type="text" placeholder="Row3" size=20 maxlength=25><br/>
<input name="Row4" type="text" placeholder="Row4" size=20 maxlength=25><br/>
<input type="submit" value="Send EventData Update">
</form>
</div>
<br/>
<br/>
<div class="actionbox">
<form action="event_dataGeneric" method="POST" target="empty">
ID:<input name="id" size=3 maxlength=3 placeholder="1"/><br/>
<input name="Row1" type="text" placeholder="Row1" size=20 maxlength=25><br/>
<input name="Row2" type="text" placeholder="Row2" size=20 maxlength=25><br/>
<input name="Row3" type="text" placeholder="Row3" size=20 maxlength=25><br/>
<input name="Row4" type="text" placeholder="Row4" size=20 maxlength=25><br/>
<input name="Row5" type="text" placeholder="Row5" size=20 maxlength=25><br/>
<input name="Row6" type="text" placeholder="Row6" size=20 maxlength=25><br/>
<input type="submit" value="Send EventData Update">
</form>
</div>
<br/>
<br/>
<div class="actionbox">
Show screen:
<form action="event_showScreen" method="POST" target="empty">
ID:<input name="id" size=3 maxlength=3 placeholder="1"/><br/>
<select name="screen">
<option value="0">Event Begin</option>
<option value="1">Event End</option>
<option value="2">Update Screen</option>
</select><br/>
<input type="checkbox" name="mesh" value="Rebroadcast">Rebroadcast<br/>
<input type="submit" value="Send EventData Update">
</form>
</div>
<br/>
<br/>
<div class="actionbox">
Do command:
<form action="event_doCmd" method="POST" target="empty">
ID:<input name="id" size=3 maxlength=3 placeholder="1"/><br/>
<select name="cmd">
<option value="0">Reset</option>
<option value="1">Go To EventEnd</option>
<option value="2">Cmd 2</option>
<option value="3">Cmd 1</option>
<option value="4">Cmd 2</option>
</select><br/>
<input type="checkbox" name="mesh" value="Rebroadcast">Rebroadcast<br/>
<input type="submit" value="Send EventData Update">
</form>
</div>
<div id="messages">
<ul class="messages">
</ul>
</div>
</div>
</div>
<script src="jquery.js"></script>
<script src="main.js"></script>
</body>
</html>

View File

@@ -18,6 +18,14 @@ struct blockData {
uint8_t data[];
} __packed;
#define EVENT_PKT_SIZE 100
struct eventData {
uint8_t checksum;
uint8_t eventDataID;
uint8_t data[100];
} __packed;
#define SOLUM_154_033 0
#define SOLUM_29_033 1
#define SOLUM_42_033 2

View File

@@ -3,6 +3,9 @@
void zbsTx(uint8_t* packetdata, uint8_t len);
void zbsRxTask(void* parameter);
void setEventMode(bool on);
bool sendEventData(struct eventData* ed);
void sendCancelPending(struct pendingData* pending);
void sendDataAvail(struct pendingData* pending);
void Ping();

View File

@@ -21,6 +21,8 @@
#define ZBS_RX_WAIT_JOINNETWORK 10
#define ZBS_RX_WAIT_XFERTIMEOUT 11
static SemaphoreHandle_t serialWait;
uint8_t restartBlockRequest = 0;
uint16_t sendBlock(const void* data, const uint16_t len) {
@@ -89,7 +91,7 @@ uint8_t pktlen = 0;
uint8_t pktindex = 0;
char lastchar = 0;
uint8_t charindex = 0;
uint64_t waitingForVersion = 0;
uint64_t waitingForVersion = 0;
uint16_t version;
void ShortRXWaitLoop() {
@@ -103,16 +105,86 @@ void ShortRXWaitLoop() {
cmdbuffer[3] = lastchar;
}
}
int8_t serialWaitReply() {
uint32_t start = millis();
int8_t ret = -1;
while ((millis() - start) < 100) {
ShortRXWaitLoop();
if ((strncmp(cmdbuffer, "ACK>", 4) == 0)) {
memset(cmdbuffer, 0x00, 4);
return 1;
}
if ((strncmp(cmdbuffer, "NOK>", 4) == 0)) {
memset(cmdbuffer, 0x00, 4);
return 0;
}
if ((strncmp(cmdbuffer, "NOQ>", 4) == 0)) {
memset(cmdbuffer, 0x00, 4);
return 2;
}
}
Serial.println(cmdbuffer);
return -1;
}
bool sendEventData(struct eventData* ed) {
addCRC(ed, sizeof(struct eventData));
uint8_t attempts = 5;
xSemaphoreTake(serialWait, portMAX_DELAY);
while (attempts--) {
uint8_t len = sizeof(struct eventData) + 5;
uint8_t* sendp = (uint8_t*)ed;
Serial1.print("U");
delayMicroseconds(200);
Serial1.print("E");
delayMicroseconds(200);
Serial1.print("D");
delayMicroseconds(200);
Serial1.print(">");
delayMicroseconds(200);
while (len--) {
Serial1.write(*(sendp++));
delayMicroseconds(200);
}
if (serialWaitReply() == 1) {
Serial.println("Event Data Sent");
xSemaphoreGive(serialWait);
return true;
}
vTaskDelay(3 / portTICK_PERIOD_MS);
}
xSemaphoreGive(serialWait);
Serial.println("Failed to send event data");
return false;
}
void Ping() {
Serial1.print("VER?");
waitingForVersion = esp_timer_get_time();
}
void setEventMode(bool on) {
uint8_t attempts = 5;
xSemaphoreTake(serialWait, portMAX_DELAY);
while (attempts--) {
if (on) {
Serial1.print("EEM>");
} else {
Serial1.print("SEM>");
}
if (serialWaitReply() == 1) {
xSemaphoreGive(serialWait);
return;
}
}
xSemaphoreGive(serialWait);
Serial.println("Failed to set mode...");
}
void SerialRXLoop() {
if (Serial1.available()) {
lastchar = Serial1.read();
//Serial.write(lastchar);
// Serial.write(lastchar);
switch (RXState) {
case ZBS_RX_WAIT_HEADER:
Serial.write(lastchar);
@@ -227,7 +299,6 @@ void SerialRXLoop() {
}
extern uint8_t* getDataForFile(File* file);
void zbsRxTask(void* parameter) {
Serial1.begin(230400, SERIAL_8N1, RXD1, TXD1);
@@ -236,7 +307,9 @@ void zbsRxTask(void* parameter) {
Serial1.print("VER?");
waitingForVersion = esp_timer_get_time();
serialWait = xSemaphoreCreateMutex();
while (1) {
xSemaphoreTake(serialWait, portMAX_DELAY);
SerialRXLoop();
if (Serial.available()) {
@@ -245,9 +318,9 @@ void zbsRxTask(void* parameter) {
vTaskDelay(1 / portTICK_PERIOD_MS);
if (waitingForVersion) {
if (esp_timer_get_time() - waitingForVersion > 10000*1000ULL) {
if (esp_timer_get_time() - waitingForVersion > 10000 * 1000ULL) {
waitingForVersion = 0;
//performDeviceFlash();
// performDeviceFlash();
Serial.println("I wasn't able to connect to a ZBS tag, trying to reboot the tag.");
Serial.println("If this problem persists, please check wiring and definitions in the settings.h file, and presence of the right firmware");
simplePowerOn();
@@ -255,7 +328,7 @@ void zbsRxTask(void* parameter) {
refreshAllPending();
}
}
if (version && firstrun) {
Serial.printf("ZBS/Zigbee FW version: %04X\n", version);
uint16_t fsversion;
@@ -270,5 +343,6 @@ void zbsRxTask(void* parameter) {
}
firstrun = false;
}
xSemaphoreGive(serialWait);
}
}

View File

@@ -2,7 +2,6 @@
#include <Arduino.h>
#include <ArduinoJson.h>
#include <AsyncTCP.h>
#include <ESPAsyncWebServer.h>
#include <ESPmDNS.h>
@@ -14,6 +13,7 @@
#include "commstructs.h"
#include "newproto.h"
#include "serial.h"
#include "settings.h"
#include "tag_db.h"
@@ -157,16 +157,32 @@ void wsSendSysteminfo() {
}
void wsSendTaginfo(uint8_t mac[6]) {
String json = "";
json = tagDBtoJson(mac);
xSemaphoreTake(wsMutex, portMAX_DELAY);
ws.textAll(json);
xSemaphoreGive(wsMutex);
}
struct eventNowNext {
uint8_t type;
uint8_t nowStartHour;
uint8_t nowStartMinutes;
uint8_t nowEndHour;
uint8_t nowEndMinutes;
uint8_t nextStartHour;
uint8_t nextStartMinutes;
uint8_t nextEndHour;
uint8_t nextEndMinutes;
uint8_t data[];
};
struct eventGeneric {
uint8_t type;
uint8_t data[];
};
void init_web() {
LittleFS.begin(true);
@@ -206,7 +222,7 @@ void init_web() {
server.serveStatic("/current", LittleFS, "/current/");
server.serveStatic("/", LittleFS, "/www/").setDefaultFile("index.html");
server.on(
"/imgupload", HTTP_POST, [](AsyncWebServerRequest *request) {
request->send(200);
@@ -218,15 +234,15 @@ void init_web() {
if (request->hasParam("mac")) {
String dst = request->getParam("mac")->value();
uint8_t mac[6];
if (sscanf(dst.c_str(), "%02X%02X%02X%02X%02X%02X", &mac[0], &mac[1], &mac[2], &mac[3], &mac[4], &mac[5])==6) {
if (sscanf(dst.c_str(), "%02X%02X%02X%02X%02X%02X", &mac[0], &mac[1], &mac[2], &mac[3], &mac[4], &mac[5]) == 6) {
json = tagDBtoJson(mac);
}
} else {
uint8_t startPos=0;
uint8_t startPos = 0;
if (request->hasParam("pos")) {
startPos = atoi(request->getParam("pos")->value().c_str());
}
json = tagDBtoJson(nullptr,startPos);
json = tagDBtoJson(nullptr, startPos);
}
request->send(200, "application/json", json);
});
@@ -243,8 +259,8 @@ void init_web() {
taginfo->modeConfigJson = request->getParam("modecfgjson", true)->value();
taginfo->contentMode = atoi(request->getParam("contentmode", true)->value().c_str());
taginfo->nextupdate = 0;
//memset(taginfo->md5, 0, 16 * sizeof(uint8_t));
//memset(taginfo->md5pending, 0, 16 * sizeof(uint8_t));
// memset(taginfo->md5, 0, 16 * sizeof(uint8_t));
// memset(taginfo->md5pending, 0, 16 * sizeof(uint8_t));
wsSendTaginfo(mac);
saveDB("/current/tagDB.json");
request->send(200, "text/plain", "Ok, saved");
@@ -272,6 +288,124 @@ void init_web() {
}
});
server.on("/event_start", HTTP_POST, [](AsyncWebServerRequest *request) {
setEventMode(true);
request->send(200, "text/plain", "Mode set");
});
server.on("/event_stop", HTTP_POST, [](AsyncWebServerRequest *request) {
setEventMode(false);
request->send(200, "text/plain", "Mode set");
});
server.on("/event_dataNowNext", HTTP_POST, [](AsyncWebServerRequest *request) {
struct eventData ed;
struct eventNowNext *nownext = (struct eventNowNext *)ed.data;
sscanf(request->getParam("id", true)->value().c_str(), "%d", &ed.eventDataID);
sscanf(request->getParam("nowStart", true)->value().c_str(), "%d:%d", &nownext->nowStartHour, &nownext->nowStartMinutes);
sscanf(request->getParam("nowEnd", true)->value().c_str(), "%d:%d", &nownext->nowEndHour, &nownext->nowEndMinutes);
sscanf(request->getParam("nextStart", true)->value().c_str(), "%d:%d", &nownext->nextStartHour, &nownext->nextStartMinutes);
sscanf(request->getParam("nextEnd", true)->value().c_str(), "%d:%d", &nownext->nextEndHour, &nownext->nextEndMinutes);
String data = request->getParam("Row1", true)->value();
data += "\n";
data += request->getParam("Row2", true)->value();
data += "\n";
data += request->getParam("Row3", true)->value();
data += "\n";
data += request->getParam("Row4", true)->value();
data += "\0";
nownext->type = 0xB1;
strncpy((char *)nownext->data, data.c_str(), 100 - sizeof(struct eventNowNext));
bool ret = sendEventData(&ed);
if (ret) {
request->send(200, "text/plain", "event data sent");
} else {
request->send(200, "text/plain", "Failed sending event data, please try again");
}
});
server.on("/event_dataGeneric", HTTP_POST, [](AsyncWebServerRequest *request) {
struct eventData ed;
struct eventGeneric *generic = (struct eventGeneric *)ed.data;
sscanf(request->getParam("id", true)->value().c_str(), "%d", &ed.eventDataID);
String data = request->getParam("Row1", true)->value();
data += "\n";
data += request->getParam("Row2", true)->value();
data += "\n";
data += request->getParam("Row3", true)->value();
data += "\n";
data += request->getParam("Row4", true)->value();
data += "\n";
data += request->getParam("Row5", true)->value();
data += "\n";
data += request->getParam("Row6", true)->value();
data += "\0";
generic->type = 0xB2;
strncpy((char *)generic->data, data.c_str(), 100 - sizeof(struct eventGeneric));
bool ret = sendEventData(&ed);
if (ret) {
request->send(200, "text/plain", "Event data sent");
} else {
request->send(200, "text/plain", "Failed sending event data, please try again");
}
});
server.on("/event_showScreen", HTTP_POST, [](AsyncWebServerRequest *request) {
struct eventData ed;
struct eventGeneric *generic = (struct eventGeneric *)ed.data;
uint8_t id[4];
sscanf(request->getParam("id", true)->value().c_str(), "%d", &id[0]);
uint8_t screenShow[4];
sscanf(request->getParam("screen", true)->value().c_str(), "%d", &screenShow[0]);
ed.eventDataID = id[0];
generic->type = 0x20;
generic->type |= (screenShow[0] & 0x0F);
if (request->hasParam("mesh", true)) {
generic->type |= 0x80;
}
bool ret = sendEventData(&ed);
if (ret) {
request->send(200, "text/plain", "Event data sent");
} else {
request->send(200, "text/plain", "Failed sending event data, please try again");
}
});
server.on("/event_doCmd", HTTP_POST, [](AsyncWebServerRequest *request) {
struct eventData ed;
struct eventGeneric *generic = (struct eventGeneric *)ed.data;
uint8_t id[4];
sscanf(request->getParam("id", true)->value().c_str(), "%d", &id[0]);
uint8_t cmd[4];
sscanf(request->getParam("cmd", true)->value().c_str(), "%d", &cmd[0]);
ed.eventDataID = id[0];
generic->type = 0x10;
generic->type |= (cmd[0] & 0x0F);
if (request->hasParam("mesh", true)) {
generic->type |= 0x80;
}
bool ret = sendEventData(&ed);
if (ret) {
request->send(200, "text/plain", "Event data sent");
} else {
request->send(200, "text/plain", "Failed sending event data, please try again");
}
});
server.onNotFound([](AsyncWebServerRequest *request) {
if (request->url() == "/" || request->url() == "index.htm") {
request->send(200, "text/html", "-");

View File

@@ -3,9 +3,293 @@
// images generated by https://lvgl.io/tools/imageconverter, prepended with width, height. "CF_INDEXED_1_BIT"-mode, little-endian
#include <stdint.h>
#include "screen.h"
static const uint8_t __code atc1441[] = {
112,9,
0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x10, 0x00, 0x04, 0x7c, 0xe2, 0x30, 0xc4,
0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x10, 0x00, 0x0a, 0x11, 0x16, 0x51, 0x4c,
0x20, 0xb1, 0xcb, 0x1e, 0x72, 0xce, 0x34, 0x16, 0x44, 0x0a, 0x11, 0x02, 0x51, 0x44,
0x1c, 0xca, 0x2c, 0xa0, 0x8b, 0x11, 0x4c, 0x19, 0x44, 0x11, 0x11, 0x02, 0x92, 0x44,
0x02, 0x8a, 0x28, 0x9c, 0x8a, 0x1f, 0x44, 0x11, 0x44, 0x1f, 0x11, 0x02, 0xfb, 0xe4,
0x22, 0x8a, 0x28, 0x82, 0x8a, 0x10, 0x44, 0x11, 0x28, 0x11, 0x11, 0x12, 0x10, 0x44,
0x1c, 0xf1, 0xc8, 0xbc, 0x72, 0x0e, 0x3c, 0x1e, 0x10, 0x11, 0x10, 0xe2, 0x10, 0x44,
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
};
static const uint8_t __code openepaperlink[] = {
136,9,
0x78, 0x00, 0x00, 0x00, 0x00, 0x88, 0x00, 0x1c, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x04, 0x10, 0x10,
0x44, 0x00, 0x00, 0x00, 0x00, 0x88, 0x00, 0x22, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x04, 0x00, 0x10,
0x44, 0xe4, 0x4e, 0x59, 0xc6, 0x8b, 0x22, 0x22, 0xb1, 0xcb, 0x20, 0xb1, 0xcb, 0x1c, 0xb4, 0x15, 0x92,
0x79, 0x15, 0x51, 0x62, 0x29, 0x8c, 0xa2, 0x22, 0xca, 0x2c, 0xbc, 0xc8, 0x2c, 0xa2, 0xc4, 0x16, 0x54,
0x41, 0x15, 0x5f, 0x43, 0xe8, 0x88, 0xa2, 0x22, 0x8b, 0xe8, 0xa0, 0x89, 0xe8, 0xbe, 0x84, 0x14, 0x58,
0x41, 0x12, 0x90, 0x42, 0x08, 0x88, 0x94, 0x22, 0x8a, 0x08, 0xa0, 0x8a, 0x28, 0xa0, 0x84, 0x14, 0x54,
0x40, 0xe2, 0x8e, 0x41, 0xc7, 0x8f, 0x08, 0x1c, 0xf1, 0xc8, 0xbe, 0xf1, 0xef, 0x1c, 0x87, 0xd4, 0x52,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0x80, 0x08, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x80, 0x00, 0x00, 0x80, 0x08, 0x00, 0x00, 0x00, 0x00,
};
static const uint8_t __code hadberlin[] = {
152,21,
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, 0x00, 0x01, 0xc0, 0x00, 0x00, 0x00, 0x07, 0x70, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xc0, 0x00, 0x00, 0x00, 0x07, 0x70, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xc0, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xc0, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
0x30, 0xc7, 0x0f, 0xcc, 0x61, 0x87, 0xf0, 0xcc, 0x31, 0xff, 0xe0, 0xff, 0x07, 0xf7, 0x70, 0xff, 0x3f, 0xff, 0xfc,
0x30, 0xc7, 0x1f, 0xec, 0xc3, 0xc6, 0x31, 0xe6, 0x31, 0xff, 0xe1, 0xff, 0x8f, 0xf7, 0x71, 0xff, 0xb3, 0xb9, 0x9c,
0x30, 0xcd, 0x9c, 0x0d, 0x83, 0xc6, 0x19, 0xe3, 0x61, 0xc0, 0x62, 0x03, 0x90, 0x07, 0x73, 0x03, 0xad, 0x56, 0xec,
0x3f, 0xcd, 0x98, 0x0f, 0x86, 0x66, 0x19, 0xb3, 0xc1, 0xc0, 0x66, 0x03, 0xb0, 0x07, 0x76, 0x03, 0xbb, 0x5d, 0x8c,
0x3f, 0xd9, 0x98, 0x0f, 0xc6, 0x66, 0x1b, 0x31, 0x81, 0xc0, 0x66, 0x1f, 0x30, 0x07, 0x76, 0x03, 0xb7, 0x5b, 0xec,
0x30, 0xdf, 0xd8, 0x0c, 0xc7, 0xe6, 0x1b, 0xf9, 0x81, 0xc0, 0x66, 0x3f, 0x30, 0x07, 0x76, 0x03, 0xaf, 0x57, 0xec,
0x30, 0xd8, 0xdc, 0x0c, 0x6c, 0x36, 0x3b, 0x19, 0x81, 0xff, 0xc7, 0x40, 0x30, 0x07, 0x76, 0x03, 0xa1, 0xb0, 0x98,
0x30, 0xf0, 0x6f, 0xec, 0x6c, 0x37, 0xf6, 0x0d, 0x80, 0xff, 0x87, 0xc0, 0x30, 0x07, 0x76, 0x03, 0xbf, 0xff, 0xf0,
0x30, 0xf0, 0x67, 0xcc, 0x2c, 0x37, 0xc6, 0x0d, 0x80, 0x7f, 0x03, 0xc0, 0x30, 0x07, 0x76, 0x03, 0xbf, 0xff, 0xe0,
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,
};
static const uint8_t __code hackaday[] = {
152,152,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x01, 0xff, 0xff,
0xff, 0xff, 0x80, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x03, 0xff, 0xff,
0xff, 0xff, 0xc0, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x07, 0xff, 0xff,
0xff, 0xff, 0xe0, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x0f, 0xff, 0xff,
0xff, 0xff, 0xf8, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x1f, 0xff, 0xff,
0xff, 0xff, 0xfc, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x3f, 0xff, 0xff,
0xff, 0xff, 0xfe, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x7f, 0xff, 0xff,
0xff, 0xff, 0xff, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0x80, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x01, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xc0, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x07, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xe0, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x0f, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xe0, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x07, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xc0, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x03, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0x80, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x03, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x01, 0xff, 0xff, 0xff,
0xdf, 0xff, 0xfe, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xf7,
0xcf, 0xff, 0xfc, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x7f, 0xff, 0xe7,
0xc3, 0xff, 0xfc, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x3f, 0xff, 0xc3,
0xc1, 0xff, 0xf8, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x1f, 0xff, 0x83,
0xc0, 0xff, 0xf0, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x0f, 0xff, 0x03,
0xc0, 0x7f, 0xe0, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x07, 0xfe, 0x07,
0xc0, 0x3f, 0xc0, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x03, 0xfc, 0x07,
0xe0, 0x1f, 0x80, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x01, 0xf0, 0x07,
0xe0, 0x0f, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x01, 0xe0, 0x07,
0xe0, 0x06, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0xc0, 0x07,
0xe0, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x0f,
0xf0, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x0f,
0xf0, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x1f,
0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f,
0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f,
0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xfc, 0x00, 0x3f, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f,
0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xc0, 0x00, 0x03, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xfe, 0x00, 0x00, 0x00, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff,
0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x07, 0xf8, 0x00, 0x00, 0x00, 0x1f, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff,
0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x03, 0xe0, 0x00, 0x00, 0x00, 0x0f, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff,
0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x07, 0xc0, 0x00, 0x00, 0x00, 0x03, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff,
0xff, 0xff, 0x00, 0x20, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x01, 0xf0, 0x00, 0x00, 0x04, 0x00, 0xff, 0xff,
0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x01, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xc0, 0x03, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xc0, 0x03, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xe0, 0x07, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xc0, 0x07, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xf0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xe0, 0x0f, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xf8, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x1f, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xfc, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x3f, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xfe, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x39, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x7f, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x01, 0xff, 0xc0, 0x00, 0x07, 0xff, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x03, 0xff, 0xe0, 0x00, 0x0f, 0xff, 0x80, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x07, 0xff, 0xf0, 0x00, 0x1f, 0xff, 0xc0, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x07, 0xff, 0xf8, 0x00, 0x1f, 0xff, 0xe0, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x0f, 0xff, 0xfc, 0x00, 0x3f, 0xff, 0xf0, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x1f, 0xff, 0xfc, 0x00, 0x3f, 0xff, 0xf0, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x1f, 0xff, 0xfc, 0x00, 0x3f, 0xff, 0xf8, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x1f, 0xff, 0xfc, 0x00, 0x3f, 0xff, 0xf8, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x3f, 0xff, 0xf8, 0x00, 0x3f, 0xff, 0xf8, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x3f, 0xff, 0xf0, 0x00, 0x1f, 0xff, 0xf8, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x3f, 0xff, 0xe0, 0x00, 0x0f, 0xff, 0xf8, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x1f, 0xff, 0xc0, 0x00, 0x03, 0xff, 0xf8, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x1f, 0xfe, 0x00, 0x00, 0x00, 0xff, 0xf8, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x1f, 0xf8, 0x00, 0x00, 0x00, 0x1f, 0xf8, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x1f, 0xe0, 0x00, 0x00, 0x00, 0x07, 0xf8, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x0f, 0xc0, 0x00, 0x00, 0x00, 0x03, 0xf0, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x0f, 0xc0, 0x00, 0x00, 0x00, 0x03, 0xe0, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x07, 0x80, 0x00, 0x00, 0x00, 0x03, 0xe0, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x03, 0x80, 0x00, 0x00, 0x00, 0x03, 0x80, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xfe, 0x70, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x0e, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xfc, 0x78, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x1c, 0x7f, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xf8, 0x38, 0x00, 0x00, 0x00, 0xe6, 0x00, 0x00, 0x00, 0x1c, 0x3f, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xf0, 0x3c, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x00, 0x00, 0x3c, 0x0f, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xe0, 0x1c, 0x00, 0x00, 0x00, 0xc2, 0x00, 0x00, 0x00, 0x38, 0x07, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xc0, 0x1e, 0x00, 0x00, 0x00, 0x42, 0x00, 0x00, 0x00, 0x70, 0x03, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0x80, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x01, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xfc, 0x00, 0x07, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x7f, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xf8, 0x00, 0x03, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x3f, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xf0, 0x00, 0x03, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x00, 0x1f, 0xff, 0xff, 0xff,
0xff, 0xff, 0xe1, 0xe0, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x07, 0x8f, 0xff, 0xff,
0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff,
0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff,
0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff,
0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff,
0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f,
0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f,
0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x08, 0x00, 0x30, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f,
0xf8, 0x00, 0x00, 0x00, 0x00, 0x01, 0xfe, 0x00, 0x08, 0x00, 0x30, 0x00, 0x7f, 0x80, 0x00, 0x00, 0x00, 0x00, 0x1f,
0xf0, 0x00, 0x00, 0x00, 0x00, 0x03, 0xfe, 0x00, 0x0c, 0x00, 0x30, 0x00, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x1f,
0xf0, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0x00, 0x0c, 0x00, 0x30, 0x00, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x0f,
0xe0, 0x02, 0x00, 0x00, 0x00, 0x0f, 0xff, 0x00, 0x1c, 0x00, 0x78, 0x01, 0xff, 0xf0, 0x00, 0x00, 0x00, 0xc0, 0x0f,
0xe0, 0x07, 0x00, 0x00, 0x00, 0x3f, 0xff, 0x80, 0x3e, 0x00, 0xfc, 0x01, 0xff, 0xf8, 0x00, 0x00, 0x00, 0xe0, 0x07,
0xe0, 0x0f, 0x80, 0x00, 0x00, 0x7f, 0xff, 0xe0, 0x7f, 0x81, 0xfe, 0x07, 0xff, 0xfc, 0x00, 0x00, 0x01, 0xf0, 0x07,
0xc0, 0x3f, 0xc0, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x03, 0xf8, 0x07,
0xc0, 0x7f, 0xe0, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x07, 0xfc, 0x07,
0xc0, 0xff, 0xf0, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x0f, 0xfe, 0x07,
0xc1, 0xff, 0xf8, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x1f, 0xff, 0x83,
0xc3, 0xff, 0xfc, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x3f, 0xff, 0xc3,
0xc7, 0xff, 0xfc, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x7f, 0xff, 0xe3,
0xcf, 0xff, 0xfe, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xf7,
0xff, 0xff, 0xff, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x01, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0x80, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x01, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xc0, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x03, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xe0, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x07, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xe0, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x0f, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xc0, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x07, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0x80, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x03, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x01, 0xff, 0xff, 0xff,
0xff, 0xff, 0xfe, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x7f, 0xff, 0xff,
0xff, 0xff, 0xfc, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x3f, 0xff, 0xff,
0xff, 0xff, 0xf8, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x1f, 0xff, 0xff,
0xff, 0xff, 0xf0, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x0f, 0xff, 0xff,
0xff, 0xff, 0xe0, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x07, 0xff, 0xff,
0xff, 0xff, 0x80, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x03, 0xff, 0xff,
0xff, 0xff, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x01, 0xff, 0xff,
0xff, 0xff, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x01, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
};
static const uint8_t __code hackadaysmall[] = {
80, 71,
0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00,
0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xf8, 0x00,
0x00, 0x3f, 0x80, 0x00, 0x00, 0x00, 0x00, 0x07, 0xf0, 0x00,
0x00, 0x1f, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xe0, 0x00,
0x00, 0x0f, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xc0, 0x00,
0x00, 0x07, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x80, 0x00,
0x00, 0x0f, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xc0, 0x00,
0x00, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xc0, 0x00,
0x80, 0x1f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xe0, 0x04,
0xc0, 0x3f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xf0, 0x0c,
0xe0, 0x7f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xf8, 0x1c,
0xf0, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xfc, 0x7c,
0xfd, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xfe, 0xfc,
0x7f, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xf8,
0x7f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xf8,
0x3f, 0xff, 0xff, 0x80, 0x00, 0x00, 0x07, 0xff, 0xff, 0xf0,
0x1f, 0xff, 0xff, 0xc0, 0x7f, 0xf0, 0x0f, 0xff, 0xff, 0xe0,
0x0f, 0xff, 0xff, 0xe1, 0xff, 0xfe, 0x1f, 0xff, 0xff, 0xc0,
0x03, 0xff, 0xff, 0xe7, 0xff, 0xff, 0x9f, 0xff, 0xff, 0x00,
0x00, 0x03, 0xff, 0x8f, 0xff, 0xff, 0xcf, 0xff, 0x00, 0x00,
0x00, 0x01, 0xff, 0x9f, 0xff, 0xff, 0xe7, 0xfe, 0x00, 0x00,
0x00, 0x00, 0xff, 0x3f, 0xff, 0xff, 0xf3, 0xfc, 0x00, 0x00,
0x00, 0x00, 0x7e, 0x7f, 0xff, 0xff, 0xf9, 0xf8, 0x00, 0x00,
0x00, 0x00, 0x3c, 0xff, 0xff, 0xff, 0xfc, 0xf0, 0x00, 0x00,
0x00, 0x00, 0x1c, 0xff, 0xff, 0xff, 0xfc, 0xe0, 0x00, 0x00,
0x00, 0x00, 0x09, 0xff, 0xff, 0xff, 0xfe, 0x40, 0x00, 0x00,
0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00,
0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00,
0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00,
0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00,
0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00,
0x00, 0x00, 0x07, 0xf8, 0x7f, 0xf8, 0x7f, 0x80, 0x00, 0x00,
0x00, 0x00, 0x07, 0xe0, 0x1f, 0xe0, 0x1f, 0x80, 0x00, 0x00,
0x00, 0x00, 0x07, 0xc0, 0x0f, 0xc0, 0x1f, 0x80, 0x00, 0x00,
0x00, 0x00, 0x0f, 0xc0, 0x0f, 0xc0, 0x0f, 0xc0, 0x00, 0x00,
0x00, 0x00, 0x0f, 0xc0, 0x0f, 0xc0, 0x0f, 0xc0, 0x00, 0x00,
0x00, 0x00, 0x0f, 0x80, 0x1f, 0xe0, 0x0f, 0xc0, 0x00, 0x00,
0x00, 0x00, 0x0f, 0x80, 0x3f, 0xf0, 0x0f, 0xc0, 0x00, 0x00,
0x00, 0x00, 0x07, 0xc0, 0xff, 0xfc, 0x0f, 0x80, 0x00, 0x00,
0x00, 0x00, 0x07, 0xc3, 0xff, 0xff, 0x0f, 0x80, 0x00, 0x00,
0x00, 0x00, 0x07, 0xe7, 0xff, 0xff, 0x9f, 0x80, 0x00, 0x00,
0x00, 0x00, 0x07, 0xf7, 0xff, 0xff, 0xbf, 0x80, 0x00, 0x00,
0x00, 0x00, 0x07, 0xff, 0xfc, 0xff, 0xff, 0x80, 0x00, 0x00,
0x00, 0x00, 0x03, 0xff, 0xfc, 0xff, 0xff, 0x00, 0x00, 0x00,
0x00, 0x00, 0x03, 0xff, 0xf8, 0x7f, 0xff, 0x00, 0x00, 0x00,
0x00, 0x00, 0x1b, 0xff, 0xf8, 0x7f, 0xff, 0x60, 0x00, 0x00,
0x00, 0x00, 0x39, 0xff, 0xfb, 0x7f, 0xfe, 0x70, 0x00, 0x00,
0x00, 0x00, 0x79, 0xff, 0xfb, 0x7f, 0xfe, 0xf8, 0x00, 0x00,
0x00, 0x00, 0xfc, 0xff, 0xff, 0xff, 0xfc, 0xfc, 0x00, 0x00,
0x00, 0x01, 0xfe, 0x7f, 0xff, 0xff, 0xf9, 0xfe, 0x00, 0x00,
0x00, 0x03, 0xfe, 0x3f, 0xff, 0xff, 0xf1, 0xff, 0x00, 0x00,
0x03, 0xff, 0xff, 0x3f, 0xff, 0xff, 0xe3, 0xff, 0xff, 0x00,
0x0f, 0xff, 0xff, 0x8f, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xc0,
0x1f, 0xff, 0xff, 0xcf, 0xff, 0xff, 0xcf, 0xff, 0xff, 0xe0,
0x3f, 0xff, 0xff, 0x8f, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xf0,
0x7f, 0xff, 0xff, 0x0f, 0xef, 0xdf, 0xc3, 0xff, 0xff, 0xf8,
0x7f, 0xff, 0xfe, 0x0f, 0xef, 0xdf, 0xc1, 0xff, 0xff, 0xf8,
0xfd, 0xff, 0xfc, 0x07, 0xcf, 0xcf, 0x80, 0xff, 0xfe, 0xf8,
0xf8, 0xff, 0xf0, 0x03, 0x83, 0x07, 0x00, 0x3f, 0xfc, 0x7c,
0xf0, 0x7f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xf8, 0x3c,
0xc0, 0x3f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xf0, 0x0c,
0x80, 0x1f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xe0, 0x04,
0x00, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xc0, 0x00,
0x00, 0x07, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x80, 0x00,
0x00, 0x07, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x80, 0x00,
0x00, 0x0f, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xc0, 0x00,
0x00, 0x1f, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xe0, 0x00,
0x00, 0x3f, 0x80, 0x00, 0x00, 0x00, 0x00, 0x07, 0xf0, 0x00,
0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xf8, 0x00,
0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xfc, 0x00,
0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00,
};
static const uint8_t __code oepli[] = {
128, 26,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,

View File

@@ -701,7 +701,7 @@ void writeCharEPD(uint8_t c) {
if (font[c][i]) empty = false;
}
if (empty) {
for (uint8_t i = 0; i < 8; i++) {
for (uint8_t i = 0; i < 5; i++) {
if (directionY) {
pushYFontBytesToEPD(0x00, 0x00);
} else {

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -8,11 +8,11 @@
#include "asmUtil.h"
#include "comms.h" // for mLastLqi and mLastRSSI
#include "eeprom.h"
#include "screen.h"
#include "powermgt.h"
#include "printf.h"
#include "proto.h"
#include "radio.h"
#include "screen.h"
#include "settings.h"
#include "syncedproto.h"
#include "timer.h"
@@ -21,8 +21,26 @@
// #define DEBUG_MODE
void eventMode();
void displayLoop() {
powerUp(INIT_BASE | INIT_UART | INIT_GPIO);
while (1) {
wdt120s();
pr("Splash screen\n");
powerUp(INIT_EPD);
showSplashScreen();
timerDelay(TIMER_TICKS_PER_SECOND * 4);
wdt120s();
pr("Event screen1\n");
powerUp(INIT_EPD);
eventUpdateScreen();
timerDelay(TIMER_TICKS_PER_SECOND * 4);
wdt120s();
pr("Event screen2\n");
powerUp(INIT_EPD);
eventScreen();
timerDelay(TIMER_TICKS_PER_SECOND * 4);
}
pr("Splash screen\n");
powerUp(INIT_EPD);
@@ -98,6 +116,13 @@ uint8_t showChannelSelect() { // returns 0 if no accesspoints were found
if (mLastLqi > result[c - 11]) result[c - 11] = mLastLqi;
pr("Channel: %d - LQI: %d RSSI %d\n", c, mLastLqi, mLastRSSI);
}
if (eventModeActive) {
// if event mode became active, skip the rest of the scan and go straight to event mode
epdWaitRdy();
powerDown(INIT_RADIO);
// skip the rest of the scan if
return c;
}
}
epdWaitRdy();
for (uint8_t c = 0; c < 16; c++) {
@@ -142,10 +167,11 @@ uint8_t channelSelect() { // returns 0 if no accesspoints were found
}
void main() {
// displayLoop(); // remove me
setupPortsInitial();
powerUp(INIT_BASE | INIT_UART);
// displayLoop(); // remove me
if (RESET & 0x01) {
wakeUpReason = WAKEUP_REASON_WDT_RESET;
pr("WDT reset!\n");
@@ -194,6 +220,7 @@ void main() {
// show the splashscreen
powerUp(INIT_EPD);
showSplashScreen();
powerUp(INIT_EPD);
@@ -202,6 +229,11 @@ void main() {
wdt10s();
if (eventModeActive) {
// skip straight to event mode
eventMode();
}
if (currentChannel) {
showAPFound();
initPowerSaving(INTERVAL_BASE);
@@ -220,7 +252,7 @@ void main() {
if (currentChannel) {
// associated
struct AvailDataInfo *__xdata avail;
struct AvailDataInfo* __xdata avail;
// Is there any reason why we should do a long (full) get data request (including reason, status)?
if ((longDataReqCounter > LONG_DATAREQ_INTERVAL) || wakeUpReason != WAKEUP_REASON_TIMED) {
// check if we should do a voltage measurement (those are pretty expensive)
@@ -341,3 +373,132 @@ void main() {
}
}
}
extern void dump(uint8_t* __xdata a, uint16_t __xdata l); // remove me when done
void doMeshIfNeeded(uint8_t cmddata) {
wdt30s();
if (!(cmddata & 0x40)) {
powerUp(INIT_EPD);
eventUpdateScreen();
}
if (cmddata & 0x80) {
wdt30s();
// enter AP mode
pr("AP enabled\n");
powerUp(INIT_RADIO);
eventAPMode();
powerDown(INIT_RADIO);
pr("AP disabled\n");
epdWaitRdy();
}
if (!(cmddata & 0x40)) {
powerDown(INIT_EPD);
}
}
#define EVENT_POLL_INTERVAL 3000
uint8_t __xdata eventDataID = 0;
uint16_t __xdata failedCount = 0;
void eventMode() {
powerUp(INIT_EPD);
setColorMode(EPD_MODE_NORMAL, EPD_MODE_INVERT);
selectLUT(EPD_LUT_FAST_NO_REDS);
clearScreen();
epdPrintBegin(2, 60, EPD_DIRECTION_X, EPD_SIZE_DOUBLE, EPD_COLOR_BLACK);
epdpr("EventMode");
epdPrintEnd();
drawWithSleep();
powerDown(INIT_EPD);
doSleep(1000);
powerUp(INIT_EPD);
eventStartScreen();
powerDown(INIT_EPD);
doSleep(5000);
while (failedCount < 28800) { // 24 hours at 3 second intervals
wdt10s();
powerUp(INIT_RADIO);
powerUp(INIT_UART);
struct eventData* __xdata ed = getEventData();
powerDown(INIT_RADIO);
if (ed == NULL) {
failedCount++;
} else {
failedCount = 0;
uint8_t cmddata = ed->data[0];
uint8_t newEventDataID = ed->eventDataID;
switch ((cmddata >> 4) & 0x03) {
case EVENT_CMD_EVENTSCREEN:
if (!((newEventDataID > eventDataID) || (eventDataID - newEventDataID > 128))) break; // ignore this message, its probably a mesh echo/reflection
doMeshIfNeeded(cmddata);
eventDataID = newEventDataID;
wdt10s();
powerUp(INIT_EPD);
eventScreen();
powerDown(INIT_EPD);
break;
case EVENT_CMD_DRAWSCREEN:
if (!((newEventDataID > eventDataID) || (eventDataID - newEventDataID > 128))) break; // ignore this message, its probably a mesh echo/reflection
doMeshIfNeeded(cmddata);
eventDataID = newEventDataID;
wdt30s();
powerUp(INIT_EPD);
switch (cmddata & 0x0F) {
case 0:
eventStartScreen();
break;
case 1:
wdt60s();
eventEndScreen();
break;
case 2:
eventUpdateScreen();
epdWaitRdy();
break;
}
powerDown(INIT_EPD);
break;
case EVENT_CMD_CMD:
if (!((newEventDataID > eventDataID) || (eventDataID - newEventDataID > 128))) break; // ignore this message, its probably a mesh echo/reflection
switch (cmddata & 0x0F) {
case 0: // reset
if (eventDataID != 0) {
doMeshIfNeeded(cmddata);
wdtDeviceReset();
}
break;
case 1: // go to event end
doMeshIfNeeded(cmddata);
failedCount = -1;
break;
}
eventDataID = newEventDataID;
break;
}
}
doSleep(EVENT_POLL_INTERVAL);
}
wdt60s();
// display thank you blah
powerUp(INIT_EPD);
eventEndScreen();
powerDown(INIT_EPD);
// sleep, wake every 10 minutes to see if an event has started;
while (1) {
doSleep(600000);
wdt10s();
powerUp(INIT_RADIO);
struct eventData* __xdata ed = getEventData();
powerDown(INIT_RADIO);
if (ed != NULL) wdtDeviceReset();
}
}

View File

@@ -90,6 +90,22 @@ struct MacFrameBcast {
uint8_t src[8];
} __packed;
#define EVENT_CMD_EVENTSCREEN 3
#define EVENT_CMD_DRAWSCREEN 2
#define EVENT_CMD_CMD 1
#define EVENT_CMD_GETIMGBLOCKDATA 0
struct eventCmd{
uint8_t mesh : 1;
uint8_t noMeshScreen : 1;
uint8_t cmd : 2;
uint8_t cmdArg: 4;
} __packed;
#define EVENT_CMD_RESET 0
#define EVENT_CMD_NO_MESH_SCREEN 0x40
#define PKT_AVAIL_DATA_SHORTREQ 0xE3
#define PKT_AVAIL_DATA_REQ 0xE5
#define PKT_AVAIL_DATA_INFO 0xE6
@@ -103,6 +119,10 @@ struct MacFrameBcast {
#define PKT_PING 0xED
#define PKT_PONG 0xEE
#define PKT_EVENT_PONG 0xC1
#define PKT_EVENT_DATA_REQ 0xC2
#define PKT_EVENT_DATA 0xC3
struct AvailDataReq {
uint8_t checksum;
uint8_t lastPacketLQI;
@@ -111,28 +131,26 @@ struct AvailDataReq {
uint16_t batteryMv;
uint8_t hwType;
uint8_t wakeupReason;
uint8_t capabilities; // undefined, as of now
uint8_t capabilities; // undefined, as of now
} __packed;
#define DATATYPE_NOUPDATE 0
#define DATATYPE_IMG_BMP 2
#define DATATYPE_FW_UPDATE 3
#define DATATYPE_IMG_DIFF 0x10 // always 1BPP
#define DATATYPE_IMG_RAW_1BPP 0x20 // 2888 bytes for 1.54" / 4736 2.9" / 15000 4.2"
#define DATATYPE_IMG_RAW_2BPP 0x21 // 5776 bytes for 1.54" / 9472 2.9" / 30000 4.2"
#define DATATYPE_IMG_RAW_1BPP_DIRECT 0x3F // only for 1.54", don't write to EEPROM, but straightaway to the EPD
#define DATATYPE_IMG_DIFF 0x10 // always 1BPP
#define DATATYPE_IMG_RAW_1BPP 0x20 // 2888 bytes for 1.54" / 4736 2.9" / 15000 4.2"
#define DATATYPE_IMG_RAW_2BPP 0x21 // 5776 bytes for 1.54" / 9472 2.9" / 30000 4.2"
#define DATATYPE_IMG_RAW_1BPP_DIRECT 0x3F // only for 1.54", don't write to EEPROM, but straightaway to the EPD
struct AvailDataInfo {
uint8_t checksum;
uint64_t dataVer; // MD5 of potential traffic
uint32_t dataSize;
uint8_t dataType;
uint64_t dataVer; // MD5 of potential traffic
uint32_t dataSize;
uint8_t dataType;
uint8_t dataTypeArgument; // extra specification or instruction for the tag (LUT to be used for drawing image)
uint16_t nextCheckIn; // when should the tag check-in again? Measured in minutes
uint16_t nextCheckIn; // when should the tag check-in again? Measured in minutes
} __packed;
struct blockPart {
uint8_t checksum;
uint8_t blockId;
@@ -151,6 +169,12 @@ struct burstMacData {
uint8_t targetMac[8];
} __packed;
struct eventData {
uint8_t checksum;
uint8_t eventDataID;
uint8_t data[];
} __packed;
#define BLOCK_PART_DATA_SIZE 99
#define BLOCK_MAX_PARTS 42
#define BLOCK_DATA_SIZE 4096UL

View File

@@ -111,19 +111,14 @@ bool radioTx(const void __xdata *packetP) // waits for tx end
uint16_t bkp, wait;
__bit irqs;
// this is how to do CCA. we do not bother because fuck it
// this is how WE do CCA. 'Fuck it' still somewhat applies if we don't get a clear channel in a reasonable amount of time
// okay fuck it.
/*
// this is how to do CCA.
for (uint8_t i = 0; i < 0x80; i++) {
if (!(RADIO_curRfState & 1)) {
//pr("radio CCA fail\n");
timerDelay(TIMER_TICKS_PER_SECOND / 2000);
//return;
pr("-");
return false;
}
}
*/
mAckTimePassed = false;
mGotAck = false;
mLastTxedSeq = packet[3];

View File

@@ -12,9 +12,6 @@ void RF_IRQ2(void) __interrupt (5);
#include "../radioCommon.h"
#endif

View File

@@ -18,12 +18,12 @@
#include "printf.h"
#include "proto.h"
#include "radio.h"
#include "screen.h"
#include "settings.h"
#include "sleep.h"
#include "timer.h"
#include "userinterface.h"
#include "wdt.h"
#include "screen.h"
// download-stuff
uint8_t __xdata blockXferBuffer[BLOCK_XFER_BUFFER_SIZE] = {0};
@@ -46,6 +46,9 @@ uint8_t __xdata mSelfMac[8] = {0};
static uint8_t __xdata seq = 0;
uint8_t __xdata currentChannel = 0;
// check if we're in event mode
bool __xdata eventModeActive = false;
// buffer we use to prepare/read packets
static uint8_t __xdata inBuffer[128] = {0};
static uint8_t __xdata outBuffer[128] = {0};
@@ -150,6 +153,12 @@ uint8_t detectAP(const uint8_t channel) {
return c;
}
}
if (getPacketType(inBuffer) == PKT_EVENT_PONG) {
if (pktIsUnicast(inBuffer)) {
eventModeActive = true;
return c;
}
}
}
}
}
@@ -238,6 +247,9 @@ struct AvailDataInfo *__xdata getShortAvailDataInfo() {
return (struct AvailDataInfo *)(inBuffer + sizeof(struct MacFrameNormal) + 1);
}
}
if (getPacketType(inBuffer) == PKT_EVENT_PONG) {
wdtDeviceReset();
}
}
}
}
@@ -479,7 +491,7 @@ static bool getDataBlock(const uint16_t blockSize) {
partsThisBlock = BLOCK_MAX_PARTS;
memset(curBlock.requestedParts, 0xFF, BLOCK_REQ_PARTS_BYTES);
} else {
partsThisBlock = (sizeof(struct blockData)+blockSize) / BLOCK_PART_DATA_SIZE;
partsThisBlock = (sizeof(struct blockData) + blockSize) / BLOCK_PART_DATA_SIZE;
if (blockSize % BLOCK_PART_DATA_SIZE) partsThisBlock++;
memset(curBlock.requestedParts, 0x00, BLOCK_REQ_PARTS_BYTES);
for (uint8_t c = 0; c < partsThisBlock; c++) {
@@ -698,7 +710,7 @@ bool processAvailDataInfo(struct AvailDataInfo *__xdata avail) {
}
xMemCopyShort(&curDataInfo, (void *)avail, sizeof(struct AvailDataInfo));
if (avail->dataSize > 4096) avail->dataSize = 4096;
if (getDataBlock(avail->dataSize)) {
powerUp(INIT_RADIO);
sendXferComplete();
@@ -799,4 +811,105 @@ bool processAvailDataInfo(struct AvailDataInfo *__xdata avail) {
void initializeProto() {
getNumSlots();
curHighSlotId = getHighSlotId();
}
// event mode
#define EVENT_AP_TIME 10
#define RAW_PKT_PADDING 2
#define EVENT_PKT_SIZE 100
#define EVENT_DATA_REQ_RX_WINDOW_SIZE 8
static void sendEventPong(const void *__xdata buf) {
struct MacFrameBcast *rxframe = (struct MacFrameBcast *)buf;
struct MacFrameNormal *frameHeader = (struct MacFrameNormal *)(outBuffer + 1);
outBuffer[sizeof(struct MacFrameNormal) + 1] = PKT_EVENT_PONG;
outBuffer[0] = sizeof(struct MacFrameNormal) + 1 + RAW_PKT_PADDING;
memcpy(frameHeader->src, mSelfMac, 8);
memcpy(frameHeader->dst, rxframe->src, 8);
outBuffer[1] = 0x41; // fast way to set the appropriate bits
outBuffer[2] = 0xCC; // normal frame
frameHeader->seq = seq++;
frameHeader->pan = rxframe->srcPan;
radioTx(outBuffer);
}
static void sendEventDataReply(const void *__xdata buf) {
struct MacFrameBcast *rxframe = (struct MacFrameBcast *)buf;
struct MacFrameNormal *frameHeader = (struct MacFrameNormal *)(outBuffer + 1);
struct eventData *eventData = (struct eventData *)(outBuffer + sizeof(struct MacFrameNormal) + 2);
memset(outBuffer + 1, 0, sizeof(struct eventData) + sizeof(struct MacFrameNormal));
outBuffer[sizeof(struct MacFrameNormal) + 1] = PKT_EVENT_DATA;
outBuffer[0] = sizeof(struct MacFrameNormal) + sizeof(struct eventData) + EVENT_PKT_SIZE + 1 + RAW_PKT_PADDING;
memcpy(frameHeader->src, mSelfMac, 8);
memcpy(frameHeader->dst, rxframe->src, 8);
memcpy(eventData, blockXferBuffer, sizeof(struct eventData) + EVENT_PKT_SIZE);
addCRC(eventData, sizeof(struct eventData) + EVENT_PKT_SIZE);
frameHeader->fcs.frameType = 1;
frameHeader->fcs.panIdCompressed = 1;
frameHeader->fcs.destAddrType = 3;
frameHeader->fcs.srcAddrType = 3;
frameHeader->seq = seq++;
frameHeader->pan = rxframe->srcPan;
radioTx(outBuffer);
}
void eventAPMode() {
radioRxEnable(true, true);
uint32_t __xdata APTime = timerGet();
while ((timerGet() - APTime) < (TIMER_TICKS_PER_SECOND * EVENT_AP_TIME)) {
int8_t ret = commsRxUnencrypted(inBuffer);
if (ret > 1) {
// received a packet, lets see what it is
switch (getPacketType(inBuffer)) {
case PKT_PING:
timerDelay(13 * (100 - mLastLqi));
sendEventPong(inBuffer);
break;
case PKT_EVENT_DATA_REQ:
timerDelay(13 * (100 - mLastLqi));
sendEventDataReply(inBuffer);
break;
}
}
}
}
bool sendEventDataReq() {
struct MacFrameBcast __xdata *txframe = (struct MacFrameBcast *)(outBuffer + 1);
memset(outBuffer, 0, sizeof(struct MacFrameBcast) + sizeof(struct AvailDataReq) + 2 + 4);
outBuffer[0] = sizeof(struct MacFrameBcast) + 2 + 2 + 10; // added some random extra bytes, seems to reduce crashes. Probably some timing issue
outBuffer[sizeof(struct MacFrameBcast) + 1] = PKT_EVENT_DATA_REQ;
memcpy(txframe->src, mSelfMac, 8);
txframe->fcs.frameType = 1;
txframe->fcs.ackReqd = 1;
txframe->fcs.destAddrType = 2;
txframe->fcs.srcAddrType = 3;
txframe->seq = seq++;
txframe->dstPan = PROTO_PAN_ID;
txframe->dstAddr = 0xFFFF;
txframe->srcPan = PROTO_PAN_ID;
return commsTxNoCpy(outBuffer);
}
struct eventData *__xdata getEventData() {
radioRxEnable(true, true);
uint32_t __xdata t;
bool timeExtended = false;
timerDelay(100);
for (uint8_t c = 0; c < 2; c++) {
if (!sendEventDataReq()) return NULL;
t = timerGet() + (TIMER_TICKS_PER_MS * EVENT_DATA_REQ_RX_WINDOW_SIZE);
while (timerGet() < t) {
int8_t __xdata ret = commsRxUnencrypted(inBuffer);
if (ret > 1) {
if ((getPacketType(inBuffer) == PKT_EVENT_DATA) && (pktIsUnicast(inBuffer))) {
if (checkCRC(inBuffer + sizeof(struct MacFrameNormal) + 1, sizeof(struct eventData) + EVENT_PKT_SIZE)) {
struct MacFrameNormal *__xdata f = (struct MacFrameNormal *)inBuffer;
memcpy(blockXferBuffer, inBuffer + sizeof(struct MacFrameNormal) + 1, 128);
return (struct eventData *)(inBuffer + sizeof(struct MacFrameNormal) + 1);
}
}
}
}
}
return NULL;
}

View File

@@ -21,4 +21,10 @@ extern bool processAvailDataInfo(struct AvailDataInfo *__xdata avail);
extern void initializeProto();
extern uint8_t detectAP(const uint8_t channel);
extern uint8_t __xdata eventDataID;
extern bool __xdata eventModeActive;
struct eventData *__xdata getEventData();
void eventAPMode();
#endif

View File

@@ -63,6 +63,177 @@ void addOverlay() {
}
}
extern uint8_t __xdata blockXferBuffer[];
struct eventNowNext {
uint8_t type;
uint8_t nowStartHour;
uint8_t nowStartMinutes;
uint8_t nowEndHour;
uint8_t nowEndMinutes;
uint8_t nextStartHour;
uint8_t nextStartMinutes;
uint8_t nextEndHour;
uint8_t nextEndMinutes;
uint8_t data[];
};
static void eventNowNext() {
struct eventNowNext* enn = (struct eventNowNext*)(blockXferBuffer + sizeof(struct eventData));
selectLUT(EPD_LUT_NO_REPEATS);
clearScreen();
setColorMode(EPD_MODE_NORMAL, EPD_MODE_INVERT);
loadRawBitmap(hadberlin, 0, 0, EPD_COLOR_BLACK);
if (blockXferBuffer[1] & 0x01) {
loadRawBitmap(atc1441, 20, 143, EPD_COLOR_BLACK);
} else {
loadRawBitmap(openepaperlink, 8, 143, EPD_COLOR_BLACK);
}
epdPrintBegin(2, 22, EPD_DIRECTION_X, EPD_SIZE_DOUBLE, EPD_COLOR_RED);
epdpr("Now:");
epdPrintEnd();
epdPrintBegin(2, 86, EPD_DIRECTION_X, EPD_SIZE_SINGLE, EPD_COLOR_RED);
epdpr("Next:");
epdPrintEnd();
epdPrintBegin(73, 33, EPD_DIRECTION_X, EPD_SIZE_SINGLE, EPD_COLOR_BLACK);
epdpr("%02d:%02d-%02d:%02d", enn->nowStartHour, enn->nowStartMinutes, enn->nowEndHour, enn->nowEndMinutes);
epdPrintEnd();
epdPrintBegin(73, 86, EPD_DIRECTION_X, EPD_SIZE_SINGLE, EPD_COLOR_BLACK);
epdpr("%02d:%02d-%02d:%02d", enn->nextStartHour, enn->nextStartMinutes, enn->nextEndHour, enn->nextEndMinutes);
epdPrintEnd();
char* readp = enn->data;
uint8_t row = 0;
uint8_t currow = 0;
epdPrintBegin(2, 54, EPD_DIRECTION_X, EPD_SIZE_SINGLE, EPD_COLOR_BLACK);
while (*readp) {
if (*readp == '\n') row++;
if (row != currow) {
readp++;
currow = row;
epdPrintEnd();
switch (row) {
case 1:
epdPrintBegin(2, 70, EPD_DIRECTION_X, EPD_SIZE_SINGLE, EPD_COLOR_BLACK);
break;
case 2:
epdPrintBegin(2, 102, EPD_DIRECTION_X, EPD_SIZE_SINGLE, EPD_COLOR_BLACK);
break;
case 3:
epdPrintBegin(2, 118, EPD_DIRECTION_X, EPD_SIZE_SINGLE, EPD_COLOR_BLACK);
break;
}
} else {
writeCharEPD(*(readp++));
}
}
epdPrintEnd();
drawWithSleep();
}
static void eventGeneric() {
selectLUT(EPD_LUT_NO_REPEATS);
clearScreen();
setColorMode(EPD_MODE_NORMAL, EPD_MODE_INVERT);
loadRawBitmap(hadberlin, 0, 0, EPD_COLOR_BLACK);
if (blockXferBuffer[1] & 0x01) {
loadRawBitmap(atc1441, 20, 143, EPD_COLOR_BLACK);
} else {
loadRawBitmap(openepaperlink, 8, 143, EPD_COLOR_BLACK);
}
char* readp = &blockXferBuffer[3];
uint8_t row = 0;
uint8_t currow = 0;
epdPrintBegin(2, 38, EPD_DIRECTION_X, EPD_SIZE_SINGLE, EPD_COLOR_BLACK);
while (*readp) {
if (*readp == '\n') row++;
if (row != currow) {
readp++;
currow = row;
epdPrintEnd();
switch (row) {
case 1:
epdPrintBegin(2, 54, EPD_DIRECTION_X, EPD_SIZE_SINGLE, EPD_COLOR_BLACK);
break;
case 2:
epdPrintBegin(2, 70, EPD_DIRECTION_X, EPD_SIZE_SINGLE, EPD_COLOR_BLACK);
break;
case 3:
epdPrintBegin(2, 86, EPD_DIRECTION_X, EPD_SIZE_SINGLE, EPD_COLOR_BLACK);
break;
case 4:
epdPrintBegin(2, 102, EPD_DIRECTION_X, EPD_SIZE_SINGLE, EPD_COLOR_BLACK);
break;
case 5:
epdPrintBegin(2, 118, EPD_DIRECTION_X, EPD_SIZE_SINGLE, EPD_COLOR_BLACK);
break;
}
} else {
writeCharEPD(*(readp++));
}
}
epdPrintEnd();
drawWithSleep();
}
void eventUpdateScreen() {
selectLUT(EPD_LUT_FAST_NO_REDS);
clearScreen();
setColorMode(EPD_MODE_NORMAL, EPD_MODE_INVERT);
loadRawBitmap(hackaday, 0, 0, EPD_COLOR_BLACK);
drawNoWait();
}
void eventStartScreen() {
selectLUT(EPD_LUT_NO_REPEATS);
clearScreen();
setColorMode(EPD_MODE_NORMAL, EPD_MODE_INVERT);
loadRawBitmap(hackadaysmall, 40, 37, EPD_COLOR_BLACK);
epdPrintBegin(20, 0, EPD_DIRECTION_X, EPD_SIZE_DOUBLE, EPD_COLOR_RED);
epdpr("Welcome");
epdPrintEnd();
epdPrintBegin(10, 117, EPD_DIRECTION_X, EPD_SIZE_SINGLE, EPD_COLOR_BLACK);
epdpr("to Hackaday Berlin");
epdPrintEnd();
epdPrintBegin(66, 133, EPD_DIRECTION_X, EPD_SIZE_SINGLE, EPD_COLOR_BLACK);
epdpr("2023");
epdPrintEnd();
drawWithSleep();
}
void eventEndScreen() {
selectLUT(EPD_LUT_DEFAULT);
clearScreen();
setColorMode(EPD_MODE_NORMAL, EPD_MODE_INVERT);
loadRawBitmap(hadberlin, 0, 131, EPD_COLOR_BLACK);
loadRawBitmap(hackadaysmall, 40, 37, EPD_COLOR_BLACK);
epdPrintBegin(4, 0, EPD_DIRECTION_X, EPD_SIZE_DOUBLE, EPD_COLOR_RED);
epdpr("Thank you");
epdPrintEnd();
epdPrintBegin(36, 117, EPD_DIRECTION_X, EPD_SIZE_SINGLE, EPD_COLOR_BLACK);
epdpr("for visiting");
epdPrintEnd();
drawWithSleep();
}
void eventScreen() {
switch (blockXferBuffer[2]) {
case 0xB1:
eventNowNext();
break;
case 0xB2:
eventGeneric();
break;
default:
pr("type=%d\n", blockXferBuffer[2]);
break;
}
}
void showSplashScreen() {
selectLUT(EPD_LUT_NO_REPEATS);
clearScreen();
@@ -84,7 +255,8 @@ void showSplashScreen() {
epdPrintEnd();
epdPrintBegin(2, 120, EPD_DIRECTION_X, EPD_SIZE_SINGLE, EPD_COLOR_BLACK);
epdpr("zbs154v033 %d.%d.%d%s", fwVersion / 100, (fwVersion % 100) / 10, (fwVersion % 10), fwVersionSuffix);
epdpr("Hackaday Berlin 2023-");
//epdpr("zbs154v033 %d.%d.%d%s", fwVersion / 100, (fwVersion % 100) / 10, (fwVersion % 10), fwVersionSuffix);
epdPrintEnd();
#endif
@@ -150,7 +322,6 @@ void showSplashScreen() {
#endif
drawWithSleep();
}
void showApplyUpdate() {
setColorMode(EPD_MODE_NORMAL, EPD_MODE_INVERT);
selectLUT(1);
@@ -172,9 +343,7 @@ void showApplyUpdate() {
epdPrintEnd();
drawNoWait();
}
uint8_t __xdata resultcounter = 0;
void showScanningWindow() {
setColorMode(EPD_MODE_NORMAL, EPD_MODE_INVERT);
selectLUT(EPD_LUT_FAST_NO_REDS);
@@ -209,7 +378,6 @@ void showScanningWindow() {
selectLUT(EPD_LUT_FAST);
resultcounter = 0;
}
void addScanResult(uint8_t channel, uint8_t lqi) {
if (channel == 11) resultcounter = 0;
#if (SCREEN_WIDTH == 128) // 2.9"
@@ -225,7 +393,6 @@ void addScanResult(uint8_t channel, uint8_t lqi) {
epdPrintEnd();
resultcounter++;
}
void showAPFound() {
clearScreen();
setColorMode(EPD_MODE_NORMAL, EPD_MODE_INVERT);
@@ -331,7 +498,6 @@ void showAPFound() {
addOverlay();
drawWithSleep();
}
void showNoAP() {
selectLUT(EPD_LUT_NO_REPEATS);
setColorMode(EPD_MODE_NORMAL, EPD_MODE_INVERT);
@@ -377,7 +543,6 @@ void showNoAP() {
addOverlay();
drawWithSleep();
}
void showLongTermSleep() {
selectLUT(EPD_LUT_NO_REPEATS);
setColorMode(EPD_MODE_NORMAL, EPD_MODE_INVERT);
@@ -421,7 +586,7 @@ void showNoEEPROM() {
epdPrintEnd();
#endif
#if (SCREEN_WIDTH == 400) // 4.2"
epdPrintBegin(50 , 3, EPD_DIRECTION_X, EPD_SIZE_DOUBLE, EPD_COLOR_BLACK);
epdPrintBegin(50, 3, EPD_DIRECTION_X, EPD_SIZE_DOUBLE, EPD_COLOR_BLACK);
epdpr("EEPROM FAILED :(");
epdPrintEnd();
loadRawBitmap(failed, 176, 126, EPD_COLOR_RED);
@@ -431,7 +596,6 @@ void showNoEEPROM() {
#endif
drawWithSleep();
}
void showNoMAC() {
selectLUT(EPD_LUT_NO_REPEATS);
clearScreen();

View File

@@ -14,6 +14,13 @@ void showLongTermSleep();
void showNoEEPROM();
void showNoMAC();
void eventStartScreen();
void eventUpdateScreen();
void eventScreen();
void eventEndScreen();
extern const uint8_t __code fwVersion;
extern const char __code fwVersionSuffix[];
extern bool __xdata lowBatteryShown;