version as in use on hackaday Berlin 2023

This commit is contained in:
Jelmer
2023-03-23 11:09:22 +01:00
parent a8934dd1a0
commit 48539ef1ad
9 changed files with 198 additions and 39 deletions

View File

@@ -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);

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

@@ -63,6 +63,39 @@
<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">

View File

@@ -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);
}

View File

@@ -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", "-");

View File

@@ -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();
}
}

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

View File

@@ -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);

View File

@@ -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();