From 7be1d18fd685bfe4356b1637a448bbe92e5415a8 Mon Sep 17 00:00:00 2001 From: Jelmer Date: Thu, 2 Feb 2023 13:56:10 +0100 Subject: [PATCH 1/3] new structs for tag --- ap_fw/zigbeebase0006.bin | Bin 18962 -> 0 bytes tag_fw/powermgt.c | 10 ++- tag_fw/powermgt.h | 9 +++ tag_fw/proto.h | 131 +++++++++++++++++++-------------------- tag_fw/syncedproto.c | 13 ++-- 5 files changed, 87 insertions(+), 76 deletions(-) delete mode 100644 ap_fw/zigbeebase0006.bin diff --git a/ap_fw/zigbeebase0006.bin b/ap_fw/zigbeebase0006.bin deleted file mode 100644 index 882ed032487b57c37dba3be80662db1344afa7ca..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18962 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 W=glD{OA?tl=D&XbC4v7X3H%QVPg2zY diff --git a/tag_fw/powermgt.c b/tag_fw/powermgt.c index df441448..68306d43 100644 --- a/tag_fw/powermgt.c +++ b/tag_fw/powermgt.c @@ -17,18 +17,18 @@ #include "printf.h" #include "proto.h" #include "radio.h" +#include "settings.h" #include "sleep.h" #include "syncedproto.h" #include "timer.h" #include "userinterface.h" #include "wdt.h" -#include "settings.h" - uint16_t __xdata dataReqAttemptArr[POWER_SAVING_SMOOTHING] = {0}; // Holds the amount of attempts required per data_req/check-in uint8_t __xdata dataReqAttemptArrayIndex = 0; uint8_t __xdata dataReqLastAttempt = 0; uint16_t __xdata nextCheckInFromAP = 0; +uint8_t __xdata wakeUpReason = 0; void initPowerSaving() { for (uint8_t c = 0; c < POWER_SAVING_SMOOTHING; c++) { @@ -63,9 +63,15 @@ void doSleep(uint32_t __xdata t) { // sleepy sleepForMsec(t); + wakeUpReason = WAKEUP_REASON_TIMED; #ifdef HAS_BUTTON P1INTEN = 0; + if (P1CHSTA && (1 << 0)) { + wakeUpReason = WAKEUP_REASON_GPIO; + pr("button pressed\n"); + P1CHSTA &= ~(1 << 0); + } #endif initAfterWake(); diff --git a/tag_fw/powermgt.h b/tag_fw/powermgt.h index 7f641671..1b55562a 100644 --- a/tag_fw/powermgt.h +++ b/tag_fw/powermgt.h @@ -2,6 +2,13 @@ #define _POWERMGT_H_ #include + +#define WAKEUP_REASON_TIMED 0 +#define WAKEUP_REASON_BOOTUP 1 +#define WAKEUP_REASON_GPIO 2 +#define WAKEUP_REASON_NFC 3 + + // power saving algorithm #define INTERVAL_BASE 40 // interval (in seconds) (when 1 packet is sent/received) for target current (7.2µA) #define INTERVAL_AT_MAX_ATTEMPTS 600 // interval (in seconds) (at max attempts) for target average current @@ -13,10 +20,12 @@ #define POWER_SAVING_SMOOTHING 8 // How many samples we should use to smooth the data request interval #define MINIMUM_INTERVAL 45 // IMPORTANT: Minimum interval for check-in; this determines overal battery life! + extern void initAfterWake(); extern void doSleep(uint32_t __xdata t); extern uint16_t getNextSleep(); extern void initPowerSaving(); +extern uint8_t __xdata wakeUpReason; extern uint16_t __xdata nextCheckInFromAP; extern uint8_t __xdata dataReqLastAttempt; diff --git a/tag_fw/proto.h b/tag_fw/proto.h index e817e08a..3f46b0eb 100644 --- a/tag_fw/proto.h +++ b/tag_fw/proto.h @@ -4,69 +4,66 @@ #include enum TagScreenType { - TagScreenEink_BW_1bpp, - TagScreenEink_BW_2bpp, - TagScreenEink_BW_4bpp, - TagScreenEink_BWY_only, //2bpp, but only 3 colors (BW?Y) - TagScreenEink_BWY_2bpp, - TagScreenEink_BWY_4bpp, - TagScreenEink_BWR_only, //2bpp, but only 3 colors (BW?R) - TagScreenEink_BWR_2bpp, - TagScreenEink_BWR_4bpp, - - TagScreenEink_BWY_3bpp, - TagScreenEink_BWR_3bpp, - TagScreenEink_BW_3bpp, - - TagScreenPersistentLcd_1bpp, - - TagScreenEink_BWY_5colors, - TagScreenEink_BWR_5colors, - - TagScreenEink_BWY_6colors, - TagScreenEink_BWR_6colors, - - TagScreenTypeOther = 0x7f, + TagScreenEink_BW_1bpp, + TagScreenEink_BW_2bpp, + TagScreenEink_BW_4bpp, + TagScreenEink_BWY_only, // 2bpp, but only 3 colors (BW?Y) + TagScreenEink_BWY_2bpp, + TagScreenEink_BWY_4bpp, + TagScreenEink_BWR_only, // 2bpp, but only 3 colors (BW?R) + TagScreenEink_BWR_2bpp, + TagScreenEink_BWR_4bpp, + + TagScreenEink_BWY_3bpp, + TagScreenEink_BWR_3bpp, + TagScreenEink_BW_3bpp, + + TagScreenPersistentLcd_1bpp, + + TagScreenEink_BWY_5colors, + TagScreenEink_BWR_5colors, + + TagScreenEink_BWY_6colors, + TagScreenEink_BWR_6colors, + + TagScreenTypeOther = 0x7f, }; -#define SOLUM_154_033 0 -#define SOLUM_29_033 1 -#define SOLUM_42_033 2 +#define SOLUM_154_033 0 +#define SOLUM_29_033 1 +#define SOLUM_42_033 2 #ifndef __packed -#define __packed __attribute__((packed)) +#define __packed __attribute__((packed)) #endif -#define PROTO_PAN_ID (0x4447) //PAN ID compression shall be used +#define PROTO_PAN_ID (0x4447) // PAN ID compression shall be used +#define RADIO_MAX_PACKET_LEN (125) // useful payload, not including the crc -#define RADIO_MAX_PACKET_LEN (125) //useful payload, not including the crc - -#define ADDR_MODE_NONE (0) -#define ADDR_MODE_SHORT (2) -#define ADDR_MODE_LONG (3) - -#define FRAME_TYPE_BEACON (0) -#define FRAME_TYPE_DATA (1) -#define FRAME_TYPE_ACK (2) -#define FRAME_TYPE_MAC_CMD (3) - -#define SHORT_MAC_UNUSED (0x10000000UL) //for radioRxFilterCfg's myShortMac +#define ADDR_MODE_NONE (0) +#define ADDR_MODE_SHORT (2) +#define ADDR_MODE_LONG (3) +#define FRAME_TYPE_BEACON (0) +#define FRAME_TYPE_DATA (1) +#define FRAME_TYPE_ACK (2) +#define FRAME_TYPE_MAC_CMD (3) +#define SHORT_MAC_UNUSED (0x10000000UL) // for radioRxFilterCfg's myShortMac struct MacFcs { - uint8_t frameType : 3; - uint8_t secure : 1; - uint8_t framePending : 1; - uint8_t ackReqd : 1; - uint8_t panIdCompressed : 1; - uint8_t rfu1 : 1; - uint8_t rfu2 : 2; - uint8_t destAddrType : 2; - uint8_t frameVer : 2; - uint8_t srcAddrType : 2; -} __packed ; + uint8_t frameType : 3; + uint8_t secure : 1; + uint8_t framePending : 1; + uint8_t ackReqd : 1; + uint8_t panIdCompressed : 1; + uint8_t rfu1 : 1; + uint8_t rfu2 : 2; + uint8_t destAddrType : 2; + uint8_t frameVer : 2; + uint8_t srcAddrType : 2; +} __packed; struct MacFrameFromMaster { struct MacFcs fcs; @@ -102,18 +99,19 @@ struct MacFrameBcast { #define PKT_XFER_COMPLETE 0xEA #define PKT_XFER_COMPLETE_ACK 0xEB #define PKT_CANCEL_XFER 0xEC +#define PKT_PING 0xED +#define PKT_PONG 0xEE struct AvailDataReq { uint8_t checksum; - uint8_t lastPacketLQI; // zero if not reported/not supported to be reported - int8_t lastPacketRSSI; // zero if not reported/not supported to be reported - uint8_t temperature; // zero if not reported/not supported to be reported. else, this minus CHECKIN_TEMP_OFFSET is temp in degrees C - uint16_t batteryMv; - uint8_t softVer; - uint8_t hwType; - uint8_t protoVer; - uint8_t buttonState; -} __packed; + uint8_t lastPacketLQI : 7; + uint8_t lastPacketRSSI : 7; // is negative + int8_t temperature : 7; // zero if not reported/not supported to be reported. else, this minus CHECKIN_TEMP_OFFSET is temp in degrees C + uint16_t batteryMv : 12; + uint8_t hwType : 5; // 32 types of tags supported + uint8_t wakeupReason : 2; // supports 4 types of wakeup reasons + uint8_t capabilities; +} __packed; // 7 bytes #define DATATYPE_NOUPDATE 0 #define DATATYPE_IMG 1 @@ -122,10 +120,11 @@ struct AvailDataReq { struct AvailDataInfo { uint8_t checksum; - uint64_t dataVer; - uint32_t dataSize; - uint8_t dataType; - uint16_t nextCheckIn; + uint64_t dataVer; // MD5 of potential traffic + uint32_t dataSize; + uint8_t dataType : 4; // allows for 16 different datatypes + uint8_t dataTypeArgument : 4; // 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 } __packed; struct blockPart { @@ -165,7 +164,7 @@ struct blockRequestAck { uint16_t pleaseWaitMs; } __packed; -#define MACFMT "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x" -#define MACCVT(x) ((const uint8_t*)(x))[7], ((const uint8_t*)(x))[6], ((const uint8_t*)(x))[5], ((const uint8_t*)(x))[4], ((const uint8_t*)(x))[3], ((const uint8_t*)(x))[2], ((const uint8_t*)(x))[1], ((const uint8_t*)(x))[0] +#define MACFMT "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x" +#define MACCVT(x) ((const uint8_t*)(x))[7], ((const uint8_t*)(x))[6], ((const uint8_t*)(x))[5], ((const uint8_t*)(x))[4], ((const uint8_t*)(x))[3], ((const uint8_t*)(x))[2], ((const uint8_t*)(x))[1], ((const uint8_t*)(x))[0] #endif \ No newline at end of file diff --git a/tag_fw/syncedproto.c b/tag_fw/syncedproto.c index 787950f8..371c3f0f 100644 --- a/tag_fw/syncedproto.c +++ b/tag_fw/syncedproto.c @@ -28,7 +28,7 @@ bool __xdata dataPending = true; uint8_t __xdata blockXferBuffer[BLOCK_XFER_BUFFER_SIZE] = {0}; struct blockRequest __xdata curBlock = {0}; struct AvailDataInfo __xdata curDataInfo = {0}; -uint16_t __xdata dataRemaining = 0; +uint16_t __xdata dataRemaining = 0; // since the targeted solum tags don't have more than 64k progmem, this is fine. bool __xdata curXferComplete = false; bool __xdata requestPartialBlock = false; @@ -156,14 +156,11 @@ void sendAvailDataReq() { txframe->dstPan = 0xFFFF; txframe->dstAddr = 0xFFFF; txframe->srcPan = PROTO_PAN_ID; - // TODO: send some meaningful data - availreq->softVer = 1; + // TODO: send some (more) meaningful data availreq->hwType = HW_TYPE; - if (P1CHSTA && (1 << 0)) { - availreq->buttonState = 1; - pr("button pressed\n"); - P1CHSTA &= ~(1 << 0); - } + availreq->wakeupReason = wakeUpReason; + + addCRC(availreq, sizeof(struct AvailDataReq)); commsTxNoCpy(outBuffer); } From aad868ef1a5bf1fa24ad2fc5fa4a3a8087b30b06 Mon Sep 17 00:00:00 2001 From: Jelmer Date: Thu, 2 Feb 2023 14:52:33 +0100 Subject: [PATCH 2/3] new structs for AP + ping-pong --- ap_fw/main.c | 52 ++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 38 insertions(+), 14 deletions(-) diff --git a/ap_fw/main.c b/ap_fw/main.c index 2d3453c6..6a1f9288 100644 --- a/ap_fw/main.c +++ b/ap_fw/main.c @@ -50,18 +50,19 @@ struct MacFrameBcast { #define PKT_XFER_COMPLETE 0xEA #define PKT_XFER_COMPLETE_ACK 0xEB #define PKT_CANCEL_XFER 0xEC +#define PKT_PING 0xED +#define PKT_PONG 0xEE struct AvailDataReq { uint8_t checksum; - uint8_t lastPacketLQI; // zero if not reported/not supported to be reported - int8_t lastPacketRSSI; // zero if not reported/not supported to be reported - uint8_t temperature; // zero if not reported/not supported to be reported. else, this minus CHECKIN_TEMP_OFFSET is temp in degrees C - uint16_t batteryMv; - uint8_t softVer; - uint8_t hwType; - uint8_t protoVer; - uint8_t buttonState; -} __packed; + uint8_t lastPacketLQI : 7; + uint8_t lastPacketRSSI : 7; // is negative + int8_t temperature : 7; // zero if not reported/not supported to be reported. else, this minus CHECKIN_TEMP_OFFSET is temp in degrees C + uint16_t batteryMv : 12; + uint8_t hwType : 5; // 32 types of tags supported + uint8_t wakeupReason : 2; // supports 4 types of wakeup reasons + uint8_t capabilities; +} __packed; // 7 bytes #define DATATYPE_NOUPDATE 0 #define DATATYPE_IMG 1 @@ -70,12 +71,14 @@ struct AvailDataReq { struct AvailDataInfo { uint8_t checksum; - uint64_t dataVer; - uint32_t dataSize; - uint8_t dataType; - uint16_t nextCheckIn; + uint64_t dataVer; // MD5 of potential traffic + uint32_t dataSize; + uint8_t dataType : 4; // allows for 16 different datatypes + uint8_t dataTypeArgument : 4; // 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 } __packed; + struct blockPart { uint8_t checksum; uint8_t blockId; @@ -625,6 +628,25 @@ void sendCancelXfer(uint8_t *dst) { frameHeader->pan = dstPan; radioTx(radiotxbuffer); } +void sendPong(void *__xdata buf) { + struct MacFrameBcast *rxframe = (struct MacFrameBcast *)buf; + struct MacFrameNormal *frameHeader = (struct MacFrameNormal *)(radiotxbuffer + 1); + memset(radiotxbuffer, 0, sizeof(struct MacFrameNormal) + 2); + + 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); + + frameHeader->fcs.frameType = 1; + frameHeader->fcs.panIdCompressed = 1; + frameHeader->fcs.destAddrType = 3; + frameHeader->fcs.srcAddrType = 3; + frameHeader->seq = seq++; + frameHeader->pan = rxframe->srcPan; + + radioTx(radiotxbuffer); +} // main loop void main(void) { @@ -689,7 +711,9 @@ void main(void) { case PKT_XFER_COMPLETE: processXferComplete(radiorxbuffer); break; - // + case PKT_PING: + sendPong(radiorxbuffer); + break; default: pr("t=%02X\n", getPacketType(radiorxbuffer)); break; From ad2e769c8393aa60bb3ca242d14e260cbc8c60be Mon Sep 17 00:00:00 2001 From: Jelmer Date: Thu, 2 Feb 2023 16:30:11 +0100 Subject: [PATCH 3/3] ping-based AP scanning --- tag_fw/main.c | 2 +- tag_fw/powermgt.h | 3 +++ tag_fw/syncedproto.c | 56 +++++++++++++++++++++++++++++++++++++------- tag_fw/syncedproto.h | 3 ++- 4 files changed, 54 insertions(+), 10 deletions(-) diff --git a/tag_fw/main.c b/tag_fw/main.c index 920d94d6..86d989e7 100644 --- a/tag_fw/main.c +++ b/tag_fw/main.c @@ -26,7 +26,7 @@ uint8_t showChannelSelect() { showScanningWindow(); for (uint8_t i = 0; i < 8; i++) { for (uint8_t c = 11; c < 27; c++) { - if (probeChannel(c)) { + if (detectAP(c)) { if (mLastLqi > result[c - 11]) result[c - 11] = mLastLqi; pr("Channel: %d - LQI: %d RSSI %d\n", c, mLastLqi, mLastRSSI); } diff --git a/tag_fw/powermgt.h b/tag_fw/powermgt.h index 1b55562a..65889c0c 100644 --- a/tag_fw/powermgt.h +++ b/tag_fw/powermgt.h @@ -20,6 +20,9 @@ #define POWER_SAVING_SMOOTHING 8 // How many samples we should use to smooth the data request interval #define MINIMUM_INTERVAL 45 // IMPORTANT: Minimum interval for check-in; this determines overal battery life! +#define MAXIMUM_PING_ATTEMPTS 20 // How many attempts to discover an AP the tag should do +#define PING_REPLY_WINDOW 2UL + extern void initAfterWake(); extern void doSleep(uint32_t __xdata t); diff --git a/tag_fw/syncedproto.c b/tag_fw/syncedproto.c index 371c3f0f..5e6d72d3 100644 --- a/tag_fw/syncedproto.c +++ b/tag_fw/syncedproto.c @@ -28,7 +28,7 @@ bool __xdata dataPending = true; uint8_t __xdata blockXferBuffer[BLOCK_XFER_BUFFER_SIZE] = {0}; struct blockRequest __xdata curBlock = {0}; struct AvailDataInfo __xdata curDataInfo = {0}; -uint16_t __xdata dataRemaining = 0; // since the targeted solum tags don't have more than 64k progmem, this is fine. +uint16_t __xdata dataRemaining = 0; // since the targeted solum tags don't have more than 64k progmem, this is fine. bool __xdata curXferComplete = false; bool __xdata requestPartialBlock = false; @@ -70,6 +70,17 @@ uint8_t __xdata getPacketType(void *__xdata buffer) { } return 0; } +bool pktIsUnicast(void *__xdata buffer) { + struct MacFcs *__xdata fcs = buffer; + if ((fcs->frameType == 1) && (fcs->destAddrType == 2) && (fcs->srcAddrType == 3) && (fcs->panIdCompressed == 0)) { + return false; + } else if ((fcs->frameType == 1) && (fcs->destAddrType == 3) && (fcs->srcAddrType == 3) && (fcs->panIdCompressed == 1)) { + // normal frame + return true; + } + // unknown type... + return false; +} void dump(uint8_t *__xdata a, uint16_t __xdata l) { pr("\n "); #define ROWS 16 @@ -130,14 +141,46 @@ void killRadio() { RADIO_command = 0xC5; CFGPAGE = cfgPg; } -bool probeChannel(uint8_t channel) { +void sendPing() { + struct MacFrameBcast __xdata *txframe = (struct MacFrameBcast *)(outBuffer + 1); + memset(outBuffer, 0, sizeof(struct MacFrameBcast) + 2 + 4); + outBuffer[0] = sizeof(struct MacFrameBcast) + 1 + 2; + outBuffer[sizeof(struct MacFrameBcast) + 1] = PKT_PING; + 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 = 0xFFFF; + txframe->dstAddr = 0xFFFF; + txframe->srcPan = PROTO_PAN_ID; + commsTxNoCpy(outBuffer); +} +uint8_t detectAP(uint8_t channel) { + uint32_t __xdata t; radioRxEnable(false, true); radioRxFlush(); radioSetChannel(channel); radioRxEnable(true, true); - getAvailDataInfo(); - return(dataReqLastAttempt != DATA_REQ_MAX_ATTEMPTS); - + for (uint8_t c = 1; c <= MAXIMUM_PING_ATTEMPTS; c++) { + sendPing(); + t = timerGet() + (TIMER_TICKS_PER_MS * PING_REPLY_WINDOW); + while (timerGet() < t) { + int8_t __xdata ret = commsRxUnencrypted(inBuffer); + if (ret > 1) { + if (getPacketType(inBuffer) == PKT_PONG) { + if (pktIsUnicast(inBuffer)) { + struct MacFrameNormal *__xdata f = (struct MacFrameNormal *)inBuffer; + memcpy(APmac, f->src, 8); + APsrcPan = f->pan; + return c; + } + } + } + } + } + return 0; } // data xfer stuff @@ -160,7 +203,6 @@ void sendAvailDataReq() { availreq->hwType = HW_TYPE; availreq->wakeupReason = wakeUpReason; - addCRC(availreq, sizeof(struct AvailDataReq)); commsTxNoCpy(outBuffer); } @@ -177,8 +219,6 @@ struct AvailDataInfo *__xdata getAvailDataInfo() { struct MacFrameNormal *__xdata f = (struct MacFrameNormal *)inBuffer; memcpy(APmac, f->src, 8); APsrcPan = f->pan; - // pr("RSSI: %d\n", commsGetLastPacketRSSI()); - // pr("LQI: %d\n", commsGetLastPacketLQI()); dataReqLastAttempt = c; return (struct AvailDataInfo *)(inBuffer + sizeof(struct MacFrameNormal) + 1); } diff --git a/tag_fw/syncedproto.h b/tag_fw/syncedproto.h index 583296dc..a78a2b94 100644 --- a/tag_fw/syncedproto.h +++ b/tag_fw/syncedproto.h @@ -16,5 +16,6 @@ extern struct AvailDataInfo *__xdata getAvailDataInfo(); extern bool doDataDownload(struct AvailDataInfo *__xdata avail); extern void initializeProto(); extern struct AvailDataInfo *__xdata getAvailDataInfo(); -bool probeChannel(uint8_t channel); +uint8_t detectAP(uint8_t channel); + #endif \ No newline at end of file