diff --git a/ap_fw/main.c b/ap_fw/main.c
index 43c52926..f1d697e9 100644
--- a/ap_fw/main.c
+++ b/ap_fw/main.c
@@ -753,7 +753,7 @@ void main(void) {
rndSeed(mSelfMac[0] ^ (uint8_t)timerGetLowBits(), mSelfMac[1]);
// wdtSetResetVal(0xFD0DCF);
// wdtOn();
- radioSetChannel(RADIO_FIRST_CHANNEL);
+ radioSetChannel(26);
radioSetTxPower(10);
radioRxEnable(true, true);
diff --git a/ap_fw/soc/zbs243/radio.c b/ap_fw/soc/zbs243/radio.c
index 055527ce..88d8e656 100644
--- a/ap_fw/soc/zbs243/radio.c
+++ b/ap_fw/soc/zbs243/radio.c
@@ -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;
diff --git a/esp32_fw/data/www/event.html b/esp32_fw/data/www/event.html
index 2f8edc45..36411921 100644
--- a/esp32_fw/data/www/event.html
+++ b/esp32_fw/data/www/event.html
@@ -63,6 +63,39 @@
+
+
+
+
+ Show screen:
+
+
+
+
+
+Do command:
+
+
diff --git a/esp32_fw/src/serial.cpp b/esp32_fw/src/serial.cpp
index da48c4ba..087c0c3d 100644
--- a/esp32_fw/src/serial.cpp
+++ b/esp32_fw/src/serial.cpp
@@ -131,10 +131,21 @@ bool sendEventData(struct eventData* ed) {
uint8_t attempts = 5;
xSemaphoreTake(serialWait, portMAX_DELAY);
while (attempts--) {
- uint8_t len = sizeof(struct eventData)+5;
+ uint8_t len = sizeof(struct eventData) + 5;
uint8_t* sendp = (uint8_t*)ed;
- Serial1.print("UED>");
- while(len--){
+ 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);
}
diff --git a/esp32_fw/src/web.cpp b/esp32_fw/src/web.cpp
index d0e4b49e..c040669d 100644
--- a/esp32_fw/src/web.cpp
+++ b/esp32_fw/src/web.cpp
@@ -354,6 +354,58 @@ void init_web() {
}
});
+ 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", "-");
diff --git a/tag_fw/main.c b/tag_fw/main.c
index 34ed9ed3..d5eceff3 100644
--- a/tag_fw/main.c
+++ b/tag_fw/main.c
@@ -374,6 +374,29 @@ 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;
@@ -407,34 +430,57 @@ void eventMode() {
if (ed == NULL) {
failedCount++;
} else {
- // eventdata is copied to blockXferBuffer, gets picked up from there
failedCount = 0;
+ uint8_t cmddata = ed->data[0];
+ uint8_t newEventDataID = ed->eventDataID;
- // check if should display this data, and make it available to other tags
- 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)
- powerUp(INIT_EPD);
- eventUpdateScreen();
-
- wdt30s();
- // enter AP mode
- pr("AP enabled\n");
- powerUp(INIT_RADIO);
- eventAPMode();
- powerDown(INIT_RADIO);
- pr("AP disabled\n");
-
- // for good measure, check if the EPD was ready with the picture
- epdWaitRdy();
-
- wdt10s();
- // display new data
- eventScreen();
- powerDown(INIT_EPD);
- } else {
- // ignore
+ 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);
@@ -446,13 +492,13 @@ void eventMode() {
eventEndScreen();
powerDown(INIT_EPD);
- // sleep, wake every 10 minutes to see if an event has started;
+ // 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();
+ if (ed != NULL) wdtDeviceReset();
}
}
\ No newline at end of file
diff --git a/tag_fw/proto.h b/tag_fw/proto.h
index 8eb6209e..fb9d6ba1 100644
--- a/tag_fw/proto.h
+++ b/tag_fw/proto.h
@@ -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
diff --git a/tag_fw/syncedproto.c b/tag_fw/syncedproto.c
index 8b0f1cbd..cb7747e6 100644
--- a/tag_fw/syncedproto.c
+++ b/tag_fw/syncedproto.c
@@ -817,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 7
+#define EVENT_DATA_REQ_RX_WINDOW_SIZE 8
static void sendEventPong(const void *__xdata buf) {
struct MacFrameBcast *rxframe = (struct MacFrameBcast *)buf;
@@ -860,9 +860,11 @@ void eventAPMode() {
// 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;
}
@@ -891,8 +893,7 @@ struct eventData *__xdata getEventData() {
bool timeExtended = false;
timerDelay(100);
for (uint8_t c = 0; c < 2; c++) {
-
- if(!sendEventDataReq()) return NULL;
+ if (!sendEventDataReq()) return NULL;
t = timerGet() + (TIMER_TICKS_PER_MS * EVENT_DATA_REQ_RX_WINDOW_SIZE);
@@ -900,7 +901,7 @@ struct eventData *__xdata getEventData() {
int8_t __xdata ret = commsRxUnencrypted(inBuffer);
if (ret > 1) {
- if (getPacketType(inBuffer) == PKT_EVENT_DATA) {
+ 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);
diff --git a/tag_fw/userinterface.c b/tag_fw/userinterface.c
index dee9a153..0c988142 100644
--- a/tag_fw/userinterface.c
+++ b/tag_fw/userinterface.c
@@ -255,7 +255,7 @@ void showSplashScreen() {
epdPrintEnd();
epdPrintBegin(2, 120, EPD_DIRECTION_X, EPD_SIZE_SINGLE, EPD_COLOR_BLACK);
- epdpr("Hackaday Berlin 2023");
+ epdpr("Hackaday Berlin 2023-");
//epdpr("zbs154v033 %d.%d.%d%s", fwVersion / 100, (fwVersion % 100) / 10, (fwVersion % 10), fwVersionSuffix);
epdPrintEnd();