mirror of
https://github.com/OpenEPaperLink/OpenEPaperLink.git
synced 2026-03-21 08:06:46 +01:00
Improved power consumption
This commit is contained in:
15
ap_fw/main.c
15
ap_fw/main.c
@@ -168,7 +168,7 @@ extern bool __idata serialBypassActive; // if the serial bypass is
|
||||
uint32_t __xdata nextBlockAttempt = 0; // reference time for when the AP can request a new block from the ESP32
|
||||
uint8_t seq = 0; // holds current sequence number for transmission
|
||||
uint8_t __xdata blockbuffer[BLOCK_XFER_BUFFER_SIZE]; // block transfer buffer
|
||||
|
||||
uint8_t lastAckMac[8] = {0};
|
||||
void sendXferCompleteAck(uint8_t *dst);
|
||||
|
||||
// tools
|
||||
@@ -437,7 +437,7 @@ void processAvailDataReq(uint8_t *buffer) {
|
||||
return;
|
||||
|
||||
// prepare tx buffer to send a response
|
||||
memset(radiotxbuffer, 0, sizeof(struct MacFrameNormal)+sizeof(struct AvailDataInfo)+2);//120);
|
||||
memset(radiotxbuffer, 0, sizeof(struct MacFrameNormal) + sizeof(struct AvailDataInfo) + 2); // 120);
|
||||
struct MacFrameNormal *txHeader = (struct MacFrameNormal *)(radiotxbuffer + 1);
|
||||
struct AvailDataInfo *availDataInfo = (struct AvailDataInfo *)(radiotxbuffer + sizeof(struct MacFrameNormal) + 2);
|
||||
radiotxbuffer[0] = sizeof(struct MacFrameNormal) + 1 + sizeof(struct AvailDataInfo) + RAW_PKT_PADDING;
|
||||
@@ -468,14 +468,19 @@ void processAvailDataReq(uint8_t *buffer) {
|
||||
txHeader->seq = seq++;
|
||||
addCRC(availDataInfo, sizeof(struct AvailDataInfo));
|
||||
radioTx(radiotxbuffer);
|
||||
memset(lastAckMac, 0, 8); // reset lastAckMac, so we can record if we've received exactly one ack packet
|
||||
espNotifyAvailDataReq(availDataReq, rxHeader->src);
|
||||
}
|
||||
|
||||
void processXferComplete(uint8_t *buffer) {
|
||||
struct MacFrameNormal *rxHeader = (struct MacFrameNormal *)buffer;
|
||||
sendXferCompleteAck(rxHeader->src);
|
||||
espNotifyXferComplete(rxHeader->src);
|
||||
int8_t slot = findSlotForMac(rxHeader->src);
|
||||
if (slot != -1) pendingDataArr[slot].attemptsLeft = 0;
|
||||
if (memcmp(lastAckMac, rxHeader->src, 8) != 0) {
|
||||
xMemCopyShort((void *__xdata)lastAckMac, (void *__xdata)rxHeader->src, 8);
|
||||
espNotifyXferComplete(rxHeader->src);
|
||||
int8_t slot = findSlotForMac(rxHeader->src);
|
||||
if (slot != -1) pendingDataArr[slot].attemptsLeft = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// send block data to the tag
|
||||
|
||||
@@ -21,7 +21,6 @@ void uartInit(void) {
|
||||
}
|
||||
|
||||
extern uint8_t __xdata blockbuffer[];
|
||||
extern bool __xdata blockRequestInProgress;
|
||||
|
||||
volatile uint8_t txtail = 0;
|
||||
volatile uint8_t txhead = 0;
|
||||
@@ -79,7 +78,6 @@ void UART_IRQ1(void) __interrupt(0) {
|
||||
*blockp++ = UARTBUF;
|
||||
if (blockp == (blockbuffer+4100)) {
|
||||
serialBypassActive = false;
|
||||
blockRequestInProgress = false;
|
||||
}
|
||||
} else {
|
||||
rxbuf[rxhead] = UARTBUF;
|
||||
|
||||
BIN
tag_fw/fw154.bin
Normal file
BIN
tag_fw/fw154.bin
Normal file
Binary file not shown.
BIN
tag_fw/fw29.bin
Normal file
BIN
tag_fw/fw29.bin
Normal file
Binary file not shown.
BIN
tag_fw/fw42.bin
Normal file
BIN
tag_fw/fw42.bin
Normal file
Binary file not shown.
@@ -133,7 +133,6 @@ struct blockRequestAck {
|
||||
} __packed;
|
||||
|
||||
#define TIMER_TICKS_PER_MS 1333UL
|
||||
#define RX_WINDOW_SIZE 10UL // ms
|
||||
// #define DEBUGBLOCKS
|
||||
|
||||
// download-stuff
|
||||
@@ -149,26 +148,27 @@ uint32_t __xdata curHighSlotId = 0;
|
||||
uint8_t __xdata nextImgSlot = 0;
|
||||
uint8_t __xdata imgSlots = 0;
|
||||
|
||||
// stuff we need to keep track of because of the network
|
||||
// stuff we need to keep track of related to the network/AP
|
||||
uint8_t __xdata APmac[8] = {0};
|
||||
uint16_t __xdata APsrcPan = 0;
|
||||
uint8_t __xdata mSelfMac[8] = {0};
|
||||
uint8_t __xdata seq = 0;
|
||||
|
||||
// timing stuff
|
||||
bool __xdata isSynced = false; // are we synced to the network?
|
||||
#define SYNC_CALIB_TIME 10000UL
|
||||
#define MAX_NEXT_ATTEMPT_DELAY_MS 300000UL
|
||||
#define MIN_NEXT_ATTEMPT_DELAY_MS 1000UL // wait at least this time
|
||||
uint32_t __xdata nextAttempt = 1000; // delay before next attempt;
|
||||
bool __xdata isCalibrated = false; // is the RC oscillator calibrated against the AP?
|
||||
uint16_t __xdata calib = SYNC_CALIB_TIME; // RC oscillator calibration value
|
||||
uint32_t __xdata APburstInterval = 0;
|
||||
int8_t __xdata calibVector = 0;
|
||||
uint16_t __xdata APburstLengthMs = 0; // burst length in ms
|
||||
uint8_t __xdata APburstLength = 0;
|
||||
// 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
|
||||
#define INTERVAL_NO_SIGNAL 1800 // interval (in seconds) when no answer for POWER_SAVING_SMOOTHING attempts,
|
||||
// (INTERVAL_AT_MAX_ATTEMPTS * POWER_SAVING_SMOOTHING) seconds
|
||||
#define DATA_REQ_RX_WINDOW_SIZE 5UL // How many milliseconds we should wait for a packet during the data_request.
|
||||
// If the AP holds a long list of data for tags, it may need a little more time to lookup the mac address
|
||||
#define DATA_REQ_MAX_ATTEMPTS 14 // How many attempts (at most) we should do to get something back from the AP
|
||||
#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!
|
||||
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;
|
||||
|
||||
// buffer we use to prepare packets
|
||||
// buffer we use to prepare/read packets
|
||||
// static uint8_t __xdata mRxBuf[130];
|
||||
static uint8_t __xdata inBuffer[128] = {0};
|
||||
static uint8_t __xdata outBuffer[128] = {0};
|
||||
@@ -187,13 +187,6 @@ uint8_t __xdata getPacketType(void *__xdata buffer) {
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
uint32_t __xdata getNextAttemptDelay() {
|
||||
nextAttempt *= 2;
|
||||
if (nextAttempt > MAX_NEXT_ATTEMPT_DELAY_MS) {
|
||||
nextAttempt = MAX_NEXT_ATTEMPT_DELAY_MS;
|
||||
}
|
||||
return nextAttempt;
|
||||
}
|
||||
void dump(uint8_t *__xdata a, uint16_t __xdata l) {
|
||||
pr("\n ");
|
||||
#define ROWS 16
|
||||
@@ -261,15 +254,36 @@ void initAfterWake() {
|
||||
initRadio();
|
||||
}
|
||||
void doSleep(uint32_t __xdata t) {
|
||||
pr("s=%lu\n ", t/1000);
|
||||
powerPortsDownForSleep();
|
||||
// sleepy
|
||||
sleepForMsec(t * SYNC_CALIB_TIME / (uint32_t)calib);
|
||||
sleepForMsec(t);
|
||||
initAfterWake();
|
||||
}
|
||||
uint16_t getNextSleep() {
|
||||
uint16_t __xdata curval = INTERVAL_AT_MAX_ATTEMPTS - INTERVAL_BASE;
|
||||
curval *= dataReqLastAttempt;
|
||||
curval /= DATA_REQ_MAX_ATTEMPTS;
|
||||
curval += INTERVAL_BASE;
|
||||
dataReqAttemptArr[dataReqAttemptArrayIndex % POWER_SAVING_SMOOTHING] = curval;
|
||||
dataReqAttemptArrayIndex++;
|
||||
|
||||
uint16_t avg = 0;
|
||||
bool noNetwork = true;
|
||||
for (uint8_t c = 0; c < POWER_SAVING_SMOOTHING; c++) {
|
||||
avg += dataReqAttemptArr[c];
|
||||
if (dataReqAttemptArr[c] != INTERVAL_AT_MAX_ATTEMPTS) {
|
||||
noNetwork = false;
|
||||
}
|
||||
}
|
||||
if (noNetwork == true) return INTERVAL_NO_SIGNAL;
|
||||
avg /= POWER_SAVING_SMOOTHING;
|
||||
return avg;
|
||||
}
|
||||
|
||||
// data xfer stuff
|
||||
void sendAvailDataReq() {
|
||||
struct MacFrameBcast __xdata *txframe = (struct MacFrameBcast *)(outBuffer+1);
|
||||
struct MacFrameBcast __xdata *txframe = (struct MacFrameBcast *)(outBuffer + 1);
|
||||
memset(outBuffer, 0, sizeof(struct MacFrameBcast) + sizeof(struct AvailDataReq) + 2 + 4);
|
||||
struct AvailDataReq *__xdata availreq = (struct AvailDataReq *)(outBuffer + 2 + sizeof(struct MacFrameBcast));
|
||||
outBuffer[0] = sizeof(struct MacFrameBcast) + sizeof(struct AvailDataReq) + 2 + 2;
|
||||
@@ -290,9 +304,9 @@ void sendAvailDataReq() {
|
||||
}
|
||||
struct AvailDataInfo *__xdata getAvailDataInfo() {
|
||||
uint32_t __xdata t;
|
||||
for (uint8_t c = 0; c < 15; c++) {
|
||||
for (uint8_t c = 0; c < DATA_REQ_MAX_ATTEMPTS; c++) {
|
||||
sendAvailDataReq();
|
||||
t = timerGet() + (TIMER_TICKS_PER_MS * 10UL);
|
||||
t = timerGet() + (TIMER_TICKS_PER_MS * DATA_REQ_RX_WINDOW_SIZE);
|
||||
while (timerGet() < t) {
|
||||
int8_t __xdata ret = commsRxUnencrypted(inBuffer);
|
||||
if (ret > 1) {
|
||||
@@ -301,12 +315,16 @@ 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
dataReqLastAttempt = DATA_REQ_MAX_ATTEMPTS;
|
||||
return NULL;
|
||||
}
|
||||
void processBlockPart(struct blockPart *bp) {
|
||||
@@ -359,7 +377,8 @@ void sendBlockRequest() {
|
||||
struct MacFrameNormal *__xdata f = (struct MacFrameNormal *)(outBuffer + 1);
|
||||
struct blockRequest *__xdata blockreq = (struct blockRequest *)(outBuffer + 2 + sizeof(struct MacFrameNormal));
|
||||
outBuffer[0] = sizeof(struct MacFrameNormal) + sizeof(struct blockRequest) + 2 + 2;
|
||||
if (requestPartialBlock) {;
|
||||
if (requestPartialBlock) {
|
||||
;
|
||||
outBuffer[sizeof(struct MacFrameNormal) + 1] = PKT_BLOCK_PARTIAL_REQUEST;
|
||||
} else {
|
||||
outBuffer[sizeof(struct MacFrameNormal) + 1] = PKT_BLOCK_REQUEST;
|
||||
@@ -398,8 +417,8 @@ struct blockRequestAck *__xdata performBlockRequest() {
|
||||
break;
|
||||
case PKT_BLOCK_PART:
|
||||
// block already started while we were waiting for a get block reply
|
||||
//pr("!");
|
||||
//processBlockPart((struct blockPart *)(inBuffer + sizeof(struct MacFrameNormal) + 1));
|
||||
// pr("!");
|
||||
// processBlockPart((struct blockPart *)(inBuffer + sizeof(struct MacFrameNormal) + 1));
|
||||
return continueToRX();
|
||||
break;
|
||||
default:
|
||||
@@ -411,7 +430,7 @@ struct blockRequestAck *__xdata performBlockRequest() {
|
||||
} while (timerGet() < t);
|
||||
}
|
||||
return continueToRX();
|
||||
//return NULL;
|
||||
// return NULL;
|
||||
}
|
||||
void sendXferCompletePacket() {
|
||||
memset(outBuffer, 0, sizeof(struct MacFrameNormal) + 2 + 4);
|
||||
@@ -451,6 +470,15 @@ void sendXferComplete() {
|
||||
pr("XFC NACK!\n");
|
||||
return;
|
||||
}
|
||||
bool validateBlockData() {
|
||||
struct blockData *bd = (struct blockData *)blockXferBuffer;
|
||||
// pr("expected len = %04X, checksum=%04X\n", bd->size, bd->checksum);
|
||||
uint16_t t = 0;
|
||||
for (uint16_t c = 0; c < bd->size; c++) {
|
||||
t += bd->data[c];
|
||||
}
|
||||
return bd->checksum == t;
|
||||
}
|
||||
|
||||
const uint8_t epd_bitmap_ant[] = {
|
||||
0xff, 0xbf, 0xfd, 0xdf, 0xfe, 0xdf, 0xee, 0xdf, 0xee, 0xdf, 0xed, 0xdf, 0xd7, 0xbf, 0xd7, 0xff,
|
||||
@@ -529,7 +557,6 @@ void saveUpdateBlockData(uint8_t blockId) {
|
||||
if (!eepromWrite(EEPROM_UPDATA_AREA_START + (blockId * BLOCK_DATA_SIZE), blockXferBuffer + sizeof(struct blockData), BLOCK_DATA_SIZE))
|
||||
pr("EEPROM write failed\n");
|
||||
}
|
||||
|
||||
void saveImgBlockData(uint8_t blockId) {
|
||||
uint16_t length = EEPROM_IMG_EACH - (sizeof(struct EepromImageHeader) + (blockId * BLOCK_DATA_SIZE));
|
||||
if (length > 4096) length = 4096;
|
||||
@@ -562,19 +589,9 @@ uint32_t getHighSlotId() {
|
||||
return temp;
|
||||
}
|
||||
|
||||
bool validateBlockData() {
|
||||
struct blockData *bd = (struct blockData *)blockXferBuffer;
|
||||
// pr("expected len = %04X, checksum=%04X\n", bd->size, bd->checksum);
|
||||
uint16_t t = 0;
|
||||
for (uint16_t c = 0; c < bd->size; c++) {
|
||||
t += bd->data[c];
|
||||
}
|
||||
return bd->checksum == t;
|
||||
}
|
||||
|
||||
#define DEBUGBLOCKS
|
||||
// Main download function
|
||||
void doDataDownload(struct AvailDataInfo* __xdata avail){
|
||||
void doDataDownload(struct AvailDataInfo *__xdata avail) {
|
||||
// this is the main function for the download process
|
||||
|
||||
if (!eepromInit()) { // we'll need the eeprom here, init it.
|
||||
@@ -681,7 +698,7 @@ void doDataDownload(struct AvailDataInfo* __xdata avail){
|
||||
pr("]\n");
|
||||
#endif
|
||||
|
||||
//timerDelay(TIMER_TICKS_PER_MS*100);
|
||||
// timerDelay(TIMER_TICKS_PER_MS*100);
|
||||
|
||||
// DO BLOCK REQUEST - request a block, get an ack with timing info (hopefully)
|
||||
struct blockRequestAck *__xdata ack = performBlockRequest();
|
||||
@@ -711,14 +728,14 @@ void doDataDownload(struct AvailDataInfo* __xdata avail){
|
||||
}
|
||||
|
||||
// BLOCK RX LOOP - receive a block, until the timeout has passed
|
||||
if (!blockRxLoop(440)) { // was 340
|
||||
if (!blockRxLoop(440)) { // was 340
|
||||
// didn't receive packets
|
||||
blockRequestAttempt++;
|
||||
if (blockRequestAttempt > 5) {
|
||||
pr("bailing on download, 0 blockparts rx'd\n");
|
||||
return;
|
||||
} else {
|
||||
//goto startdownload;
|
||||
// goto startdownload;
|
||||
}
|
||||
} else {
|
||||
// successfull block RX loop
|
||||
@@ -815,7 +832,7 @@ void doDataDownload(struct AvailDataInfo* __xdata avail){
|
||||
sendXferComplete();
|
||||
killRadio();
|
||||
eepromReadStart(EEPROM_UPDATA_AREA_START);
|
||||
//wdtDeviceReset();
|
||||
// wdtDeviceReset();
|
||||
selfUpdate();
|
||||
|
||||
break;
|
||||
@@ -856,8 +873,6 @@ void mainProtocolLoop(void) {
|
||||
// i2ctest();
|
||||
|
||||
pr("BOOTED> (new version!)\n\n");
|
||||
isSynced = false;
|
||||
isCalibrated = false;
|
||||
|
||||
if (!eepromInit()) {
|
||||
pr("failed to init eeprom\n");
|
||||
@@ -869,20 +884,27 @@ void mainProtocolLoop(void) {
|
||||
curHighSlotId = getHighSlotId();
|
||||
}
|
||||
|
||||
// initialize attempt-array with the default value;
|
||||
for (uint8_t c = 0; c < POWER_SAVING_SMOOTHING; c++) {
|
||||
dataReqAttemptArr[c] = INTERVAL_BASE;
|
||||
}
|
||||
|
||||
screenSleep();
|
||||
eepromDeepPowerDown();
|
||||
initRadio();
|
||||
// drawPartial();
|
||||
// i2ctest();
|
||||
|
||||
// doSleep(10000);
|
||||
while (1) {
|
||||
radioRxEnable(true, true);
|
||||
struct AvailDataInfo *__xdata avail = getAvailDataInfo();
|
||||
if(avail->dataType!=DATATYPE_NOUPDATE){
|
||||
doDataDownload(avail);
|
||||
if (avail == NULL) {
|
||||
} else {
|
||||
pr("nothing.\n");
|
||||
if (avail->dataType != DATATYPE_NOUPDATE) {
|
||||
doDataDownload(avail);
|
||||
} else {
|
||||
}
|
||||
}
|
||||
doSleep(10000);
|
||||
doSleep(getNextSleep()*1000UL);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user