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: +
+ ID:
+
+ Rebroadcast
+ +
+
+
+
+
+Do command: +
+ ID:
+
+ Rebroadcast
+ +
+
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();