no commands yet

This commit is contained in:
Jelmer
2023-03-18 12:04:50 +01:00
parent 046d08cd18
commit a8934dd1a0
20 changed files with 573 additions and 69 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

@@ -148,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];
@@ -307,7 +307,7 @@ 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;
@@ -793,6 +793,10 @@ void main(void) {
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

@@ -9,6 +9,9 @@ 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,82 @@
<!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>
<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,75 @@ 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("UED>");
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 +288,6 @@ void SerialRXLoop() {
}
extern uint8_t* getDataForFile(File* file);
void zbsRxTask(void* parameter) {
Serial1.begin(230400, SERIAL_8N1, RXD1, TXD1);
@@ -236,7 +296,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 +307,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();
@@ -270,5 +332,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);
@@ -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,72 @@ 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.onNotFound([](AsyncWebServerRequest *request) {
if (request->url() == "/" || request->url() == "index.htm") {
request->send(200, "text/html", "-");

View File

@@ -3,8 +3,36 @@
// 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,
@@ -187,7 +215,80 @@ static const uint8_t __code hackaday[] = {
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 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,

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

@@ -374,15 +374,15 @@ void main() {
}
}
#define EVENT_POLL_INTERVAL 5000
#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(0, 60, EPD_DIRECTION_X, EPD_SIZE_DOUBLE, EPD_COLOR_BLACK);
epdPrintBegin(2, 60, EPD_DIRECTION_X, EPD_SIZE_DOUBLE, EPD_COLOR_BLACK);
epdpr("EventMode");
epdPrintEnd();
drawWithSleep();
@@ -390,24 +390,28 @@ void eventMode() {
doSleep(1000);
uint16_t __xdata failedCount = 0;
powerUp(INIT_EPD);
eventStartScreen();
powerDown(INIT_EPD);
// display welcome!
doSleep(5000);
while (failedCount < 28800) { // 24 hours at 3 second intervals
while (failedCount < 17280) { // 24 hours at 5 second intervals
wdt10s();
powerUp(INIT_RADIO | INIT_UART);
powerUp(INIT_RADIO);
powerUp(INIT_UART);
struct eventData* __xdata ed = getEventData();
powerDown(INIT_RADIO);
if (ed == NULL) {
failedCount++;
} else {
// eventdata is copied to blockXferBuffer, gets picked up from
// eventdata is copied to blockXferBuffer, gets picked up from there
failedCount = 0;
// check if should display this data, and make it available to other tags
if ((ed->eventDataID > eventDataID) || (ed->eventDataID - eventDataID > 128)) {
if ((ed->eventDataID > eventDataID) || (eventDataID - ed->eventDataID > 128)) {
eventDataID = ed->eventDataID;
// display event logo while we run the AP (we could just skip straight to showing the data, but where's the fun in that)
@@ -436,10 +440,19 @@ void eventMode() {
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) {
// sleep forever
doSleep(-1);
doSleep(600000);
wdt10s();
powerUp(INIT_RADIO);
struct eventData* __xdata ed = getEventData();
powerDown(INIT_RADIO);
if(ed!=NULL)wdtDeviceReset();
}
}

View File

@@ -111,18 +111,13 @@ 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;

View File

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

View File

@@ -247,6 +247,9 @@ struct AvailDataInfo *__xdata getShortAvailDataInfo() {
return (struct AvailDataInfo *)(inBuffer + sizeof(struct MacFrameNormal) + 1);
}
}
if (getPacketType(inBuffer) == PKT_EVENT_PONG) {
wdtDeviceReset();
}
}
}
}
@@ -814,7 +817,7 @@ void initializeProto() {
#define EVENT_AP_TIME 10
#define RAW_PKT_PADDING 2
#define EVENT_PKT_SIZE 100
#define EVENT_DATA_REQ_RX_WINDOW_SIZE 10
#define EVENT_DATA_REQ_RX_WINDOW_SIZE 7
static void sendEventPong(const void *__xdata buf) {
struct MacFrameBcast *rxframe = (struct MacFrameBcast *)buf;
@@ -857,21 +860,19 @@ void eventAPMode() {
// received a packet, lets see what it is
switch (getPacketType(inBuffer)) {
case PKT_PING:
pr("pong rx\n");
sendEventPong(inBuffer);
break;
case PKT_EVENT_DATA_REQ:
pr("event data reply\n");
sendEventDataReply(inBuffer);
break;
}
}
}
}
static void sendEventDataReq() {
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;
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;
@@ -882,16 +883,22 @@ static void sendEventDataReq() {
txframe->dstPan = PROTO_PAN_ID;
txframe->dstAddr = 0xFFFF;
txframe->srcPan = PROTO_PAN_ID;
commsTxNoCpy(outBuffer);
return commsTxNoCpy(outBuffer);
}
struct eventData *__xdata getEventData() {
radioRxEnable(true, true);
uint32_t __xdata t;
for (uint8_t c = 0; c < DATA_REQ_MAX_ATTEMPTS; c++) {
sendEventDataReq();
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) {
if (checkCRC(inBuffer + sizeof(struct MacFrameNormal) + 1, sizeof(struct eventData) + EVENT_PKT_SIZE)) {

View File

@@ -63,6 +63,122 @@ 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();
@@ -71,20 +187,52 @@ void eventUpdateScreen() {
drawNoWait();
}
extern uint8_t __xdata blockXferBuffer[];
void eventScreen() {
void eventStartScreen() {
selectLUT(EPD_LUT_NO_REPEATS);
clearScreen();
setColorMode(EPD_MODE_NORMAL, EPD_MODE_INVERT);
loadRawBitmap(hadberlin, 0, 0, EPD_COLOR_BLACK);
loadRawBitmap(hackadaysmall, 40, 37, EPD_COLOR_BLACK);
epdPrintBegin(20, 0, EPD_DIRECTION_X, EPD_SIZE_DOUBLE, EPD_COLOR_RED);
epdpr("Welcome");
epdPrintEnd();
epdPrintBegin(2, 120, EPD_DIRECTION_X, EPD_SIZE_SINGLE, EPD_COLOR_BLACK);
epdpr("ID=%d",blockXferBuffer[1]);
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);
@@ -107,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
@@ -173,7 +322,6 @@ void showSplashScreen() {
#endif
drawWithSleep();
}
void showApplyUpdate() {
setColorMode(EPD_MODE_NORMAL, EPD_MODE_INVERT);
selectLUT(1);
@@ -195,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);
@@ -232,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"
@@ -248,7 +393,6 @@ void addScanResult(uint8_t channel, uint8_t lqi) {
epdPrintEnd();
resultcounter++;
}
void showAPFound() {
clearScreen();
setColorMode(EPD_MODE_NORMAL, EPD_MODE_INVERT);
@@ -354,7 +498,6 @@ void showAPFound() {
addOverlay();
drawWithSleep();
}
void showNoAP() {
selectLUT(EPD_LUT_NO_REPEATS);
setColorMode(EPD_MODE_NORMAL, EPD_MODE_INVERT);
@@ -400,7 +543,6 @@ void showNoAP() {
addOverlay();
drawWithSleep();
}
void showLongTermSleep() {
selectLUT(EPD_LUT_NO_REPEATS);
setColorMode(EPD_MODE_NORMAL, EPD_MODE_INVERT);
@@ -454,7 +596,6 @@ void showNoEEPROM() {
#endif
drawWithSleep();
}
void showNoMAC() {
selectLUT(EPD_LUT_NO_REPEATS);
clearScreen();

View File

@@ -14,8 +14,10 @@ void showLongTermSleep();
void showNoEEPROM();
void showNoMAC();
void eventStartScreen();
void eventUpdateScreen();
void eventScreen();
void eventEndScreen();