This commit is contained in:
Jelmer
2023-02-02 16:31:31 +01:00
8 changed files with 177 additions and 98 deletions

View File

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

Binary file not shown.

View File

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

View File

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

View File

@@ -2,6 +2,13 @@
#define _POWERMGT_H_
#include <stdint.h>
#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,15 @@
#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);
extern uint16_t getNextSleep();
extern void initPowerSaving();
extern uint8_t __xdata wakeUpReason;
extern uint16_t __xdata nextCheckInFromAP;
extern uint8_t __xdata dataReqLastAttempt;

View File

@@ -4,69 +4,66 @@
#include <stdint.h>
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

View File

@@ -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;
@@ -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
@@ -156,14 +199,10 @@ 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);
}
@@ -180,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);
}

View File

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