mirror of
https://github.com/OpenEPaperLink/OpenEPaperLink.git
synced 2026-03-21 08:06:46 +01:00
changes for improved performance in poor rf env
This commit is contained in:
173
ap_fw/main.c
173
ap_fw/main.c
@@ -159,7 +159,6 @@ struct espJoinNetwork {
|
||||
uint8_t src[8];
|
||||
} __packed;
|
||||
|
||||
|
||||
// used to transmit AP update information - flashing the firmware
|
||||
struct espSaveUpdateBlock {
|
||||
uint8_t checksum;
|
||||
@@ -168,7 +167,7 @@ struct espSaveUpdateBlock {
|
||||
} __packed;
|
||||
|
||||
#define TIMER_TICKS_PER_MS 1333UL
|
||||
uint16_t __xdata version = 0x0015;
|
||||
uint16_t __xdata version = 0x001D;
|
||||
#define RAW_PKT_PADDING 2
|
||||
|
||||
static uint8_t __xdata mRxBuf[COMMS_MAX_PACKET_SZ];
|
||||
@@ -255,7 +254,7 @@ uint8_t getBlockDataLength() {
|
||||
}
|
||||
rounds++;
|
||||
if (rounds == 4) {
|
||||
return partNo;
|
||||
// return partNo; // REMOVE ME
|
||||
}
|
||||
}
|
||||
return partNo;
|
||||
@@ -279,32 +278,6 @@ uint16_t averageXmitDelay(uint16_t xfersize) {
|
||||
return (xfersize * 3) / 5;
|
||||
}
|
||||
|
||||
// serial update
|
||||
void eraseUpdateBlock() {
|
||||
eepromErase(EEPROM_UPDATA_AREA_START, EEPROM_UPDATE_AREA_LEN / EEPROM_ERZ_SECTOR_SZ);
|
||||
}
|
||||
bool validateBlockData() {
|
||||
struct blockData *bd = (struct blockData *)blockbuffer;
|
||||
// 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;
|
||||
}
|
||||
void saveBlock(uint8_t blockId) {
|
||||
if (!eepromWrite(EEPROM_UPDATA_AREA_START + (blockId * BLOCK_DATA_SIZE), blockbuffer + sizeof(struct blockData), BLOCK_DATA_SIZE))
|
||||
pr("EEPROM write failed\n");
|
||||
}
|
||||
void performUpdate() {
|
||||
eepromReadStart(EEPROM_UPDATA_AREA_START);
|
||||
selfUpdate();
|
||||
}
|
||||
uint16_t getBlockChecksum() {
|
||||
struct blockData *bd = (struct blockData *)blockbuffer;
|
||||
return bd->checksum;
|
||||
}
|
||||
|
||||
// pendingdata slot stuff
|
||||
int8_t findSlotForMac(const uint8_t *mac) {
|
||||
for (uint8_t __xdata c = 0; c < MAX_PENDING_MACS; c++) {
|
||||
@@ -351,23 +324,6 @@ void processSerial(uint8_t lastchar) {
|
||||
if (strncmp(cmdbuffer, "RSET", 4) == 0) {
|
||||
wdtDeviceReset();
|
||||
}
|
||||
if (strncmp(cmdbuffer, "ERAS", 4) == 0) {
|
||||
// erase update space
|
||||
eraseUpdateBlock();
|
||||
pr("EROK\n");
|
||||
}
|
||||
if (strncmp(cmdbuffer, "UPDA", 4) == 0) {
|
||||
// perform update!
|
||||
pr("OK>>\n");
|
||||
performUpdate();
|
||||
}
|
||||
if (strncmp(cmdbuffer, "SUBL", 4) == 0) {
|
||||
// save update block
|
||||
RXState = ZBS_RX_WAIT_UPDBLOCK;
|
||||
bytesRemain = sizeof(struct espSaveUpdateBlock);
|
||||
serialbufferp = serialbuffer;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case ZBS_RX_WAIT_SDA:
|
||||
@@ -390,30 +346,6 @@ void processSerial(uint8_t lastchar) {
|
||||
RXState = ZBS_RX_WAIT_HEADER;
|
||||
}
|
||||
break;
|
||||
case ZBS_RX_WAIT_UPDBLOCK:
|
||||
*serialbufferp = lastchar;
|
||||
serialbufferp++;
|
||||
bytesRemain--;
|
||||
if (bytesRemain == 0) {
|
||||
if (checkCRC(serialbuffer, sizeof(struct espSaveUpdateBlock))) {
|
||||
if (validateBlockData()) {
|
||||
const struct espSaveUpdateBlock *updb = (struct espSaveUpdateBlock *)serialbuffer;
|
||||
if (updb->blockChecksum == getBlockChecksum()) {
|
||||
saveBlock(updb->blockId);
|
||||
pr("BLOK\n");
|
||||
} else {
|
||||
pr("BLFL> - block checksum doesn't match\n");
|
||||
}
|
||||
} else {
|
||||
pr("BLFL> - block doesn't validate\n");
|
||||
}
|
||||
} else {
|
||||
// block failed download
|
||||
pr("BLFL> - update block data checksum failed\n");
|
||||
}
|
||||
RXState = ZBS_RX_WAIT_HEADER;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -471,6 +403,9 @@ void espNotifyJoinNetwork(const uint8_t *src) {
|
||||
}
|
||||
|
||||
// process data from tag
|
||||
uint8_t __xdata blockReqFailcount = 0;
|
||||
extern bool __idata serialBypassActive;
|
||||
uint32_t __xdata nextBlockAttempt = 0;
|
||||
void processBlockRequest(const uint8_t *buffer, uint8_t forceBlockDownload) {
|
||||
struct MacFrameNormal *__xdata rxHeader = (struct MacFrameNormal *)buffer;
|
||||
struct blockRequest *__xdata blockReq = (struct blockRequest *)(buffer + sizeof(struct MacFrameNormal) + 1);
|
||||
@@ -484,22 +419,17 @@ void processBlockRequest(const uint8_t *buffer, uint8_t forceBlockDownload) {
|
||||
requestDataDownload = true;
|
||||
} else {
|
||||
// requested block is already in the buffer
|
||||
if (forceBlockDownload) {
|
||||
// force a download anyway; probably some error in the transfer between ESP32->AP-tag
|
||||
if (!blockRequestInProgress) {
|
||||
// block download from ESP32 not in progress
|
||||
blockRequestInProgress = true;
|
||||
//if (forceBlockDownload) {
|
||||
if ((timerGet() - nextBlockAttempt) > (200 * TIMER_TICKS_PER_MS)) {
|
||||
requestDataDownload = true;
|
||||
serialBypassActive = false;
|
||||
} else {
|
||||
// block download from ESP32 requested, but already in progress. Maybe the transfer stalled for some reason; have the ESP32 send us some bytes.
|
||||
uartTx('R');
|
||||
uartTx('Q');
|
||||
uartTx('Q');
|
||||
uartTx('>');
|
||||
pr("NOT DOWNLOADING THIS BLOCK AGAIN\n");
|
||||
}
|
||||
}
|
||||
//}
|
||||
}
|
||||
|
||||
// copy blockrequest into requested data
|
||||
memcpy(&requestedData, blockReq, sizeof(struct blockRequest));
|
||||
|
||||
struct MacFrameNormal *txHeader = (struct MacFrameNormal *)(radiotxbuffer + 1);
|
||||
@@ -507,30 +437,38 @@ void processBlockRequest(const uint8_t *buffer, uint8_t forceBlockDownload) {
|
||||
radiotxbuffer[0] = sizeof(struct MacFrameNormal) + 1 + sizeof(struct blockRequestAck) + RAW_PKT_PADDING;
|
||||
radiotxbuffer[sizeof(struct MacFrameNormal) + 1] = PKT_BLOCK_REQUEST_ACK;
|
||||
|
||||
// TODO: get this data from somnewhere, dynamically. Depending on cache status we might need to return a longer or shorter wait period
|
||||
if (blockStartTimer == 0) {
|
||||
if (requestDataDownload) {
|
||||
// check if we need to download the first block; we need to give the ESP32 some additional time to cache the file
|
||||
if (blockReq->blockId == 0) {
|
||||
blockRequestAck->pleaseWaitMs = 200;
|
||||
/* // REMOVE ME!
|
||||
if (blockStartTimer == 0) {
|
||||
if (requestDataDownload) {
|
||||
// check if we need to download the first block; we need to give the ESP32 some additional time to cache the file
|
||||
if (blockReq->blockId == 0) {
|
||||
blockRequestAck->pleaseWaitMs = 200;
|
||||
} else {
|
||||
blockRequestAck->pleaseWaitMs = 100;
|
||||
}
|
||||
blockStartTimer = timerGet() + blockRequestAck->pleaseWaitMs * TIMER_TICKS_PER_MS;
|
||||
} else {
|
||||
blockRequestAck->pleaseWaitMs = 100;
|
||||
// block is already in buffer
|
||||
blockRequestAck->pleaseWaitMs = 50;
|
||||
blockStartTimer = timerGet() + blockRequestAck->pleaseWaitMs * TIMER_TICKS_PER_MS;
|
||||
}
|
||||
blockStartTimer = timerGet() + blockRequestAck->pleaseWaitMs * TIMER_TICKS_PER_MS;
|
||||
} else {
|
||||
blockRequestAck->pleaseWaitMs = 30;
|
||||
blockStartTimer = timerGet() + blockRequestAck->pleaseWaitMs * TIMER_TICKS_PER_MS;
|
||||
blockRequestAck->pleaseWaitMs = (blockStartTimer - timerGet()) / TIMER_TICKS_PER_MS;
|
||||
if (blockRequestAck->pleaseWaitMs < 50) {
|
||||
blockRequestAck->pleaseWaitMs = 50;
|
||||
blockStartTimer = timerGet() + blockRequestAck->pleaseWaitMs * TIMER_TICKS_PER_MS;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
blockRequestAck->pleaseWaitMs = (blockStartTimer - timerGet()) / TIMER_TICKS_PER_MS;
|
||||
if (blockRequestAck->pleaseWaitMs < 30) {
|
||||
blockRequestAck->pleaseWaitMs = 30;
|
||||
blockStartTimer = timerGet() + blockRequestAck->pleaseWaitMs * TIMER_TICKS_PER_MS;
|
||||
}
|
||||
}
|
||||
blockRequestAck->blockSizeMs = 15 + 15 + (getBlockDataLength() * 245) / BLOCK_MAX_PARTS;
|
||||
*/
|
||||
|
||||
// REMOVE THIS BLOCK
|
||||
blockRequestAck->pleaseWaitMs = 100;
|
||||
blockStartTimer = timerGet() + blockRequestAck->pleaseWaitMs * TIMER_TICKS_PER_MS;
|
||||
blockRequestAck->blockSizeMs = 500;
|
||||
// REMOVE ME!
|
||||
|
||||
// blockRequestAck->blockSizeMs = 15 + 15 + (getBlockDataLength() * 245) / BLOCK_MAX_PARTS; // uncomment me!
|
||||
blockRequestAck->cancelXfer = 0;
|
||||
// pr("s=%d\n", blockRequestAck->blockSizeMs);
|
||||
|
||||
memcpy(txHeader->src, mSelfMac, 8);
|
||||
memcpy(txHeader->dst, rxHeader->src, 8);
|
||||
@@ -547,14 +485,14 @@ void processBlockRequest(const uint8_t *buffer, uint8_t forceBlockDownload) {
|
||||
addCRC((void *)blockRequestAck, sizeof(struct blockRequestAck));
|
||||
|
||||
radioTx(radiotxbuffer);
|
||||
radioTx(radiotxbuffer);
|
||||
radioTx(radiotxbuffer);
|
||||
// radioTx(radiotxbuffer);
|
||||
// radioTx(radiotxbuffer);
|
||||
|
||||
// pr("req blockreq: %02X%02X%02X%02X%02X%02X%02X%02X\n", ((uint8_t *)&(blockReq->ver))[0], ((uint8_t *)&(blockReq->ver))[1], ((uint8_t *)&(blockReq->ver))[2], ((uint8_t *)&(blockReq->ver))[3], ((uint8_t *)&(blockReq->ver))[4], ((uint8_t *)&(blockReq->ver))[5], ((uint8_t *)&(blockReq->ver))[6], ((uint8_t *)&(blockReq->ver))[7]);
|
||||
|
||||
if (requestDataDownload) {
|
||||
// espBlockRequest(blockReq);
|
||||
espBlockRequest(&requestedData);
|
||||
nextBlockAttempt = timerGet();
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -718,6 +656,8 @@ void sendTimingReply(void *__xdata buf) {
|
||||
frameHeader->pan = rxframe->srcPan;
|
||||
addCRC(response, sizeof(struct timingResponse));
|
||||
radioTx(radiotxbuffer);
|
||||
radioTx(radiotxbuffer);
|
||||
radioTx(radiotxbuffer);
|
||||
espNotifyJoinNetwork(rxframe->src);
|
||||
}
|
||||
void sendPart(uint8_t partNo) {
|
||||
@@ -747,21 +687,24 @@ void sendBlockData() {
|
||||
for (uint8_t c = 0; (c < BLOCK_MAX_PARTS) && (partNo < BLOCK_MAX_PARTS); c++) {
|
||||
if (requestedData.requestedParts[c / 8] & (1 << (c % 8))) {
|
||||
sendPart(c);
|
||||
timerDelay(TIMER_TICKS_PER_MS);
|
||||
partNo++;
|
||||
}
|
||||
}
|
||||
rounds++;
|
||||
if (rounds == 4) {
|
||||
return;
|
||||
// return;
|
||||
}
|
||||
}
|
||||
// TODO: not sure if we need this, probably not. Not sure why I added it in the first place
|
||||
commsRxUnencrypted(radiorxbuffer);
|
||||
commsRxUnencrypted(radiorxbuffer);
|
||||
commsRxUnencrypted(radiorxbuffer);
|
||||
commsRxUnencrypted(radiorxbuffer);
|
||||
commsRxUnencrypted(radiorxbuffer);
|
||||
commsRxUnencrypted(radiorxbuffer);
|
||||
/*
|
||||
commsRxUnencrypted(radiorxbuffer);
|
||||
commsRxUnencrypted(radiorxbuffer);
|
||||
commsRxUnencrypted(radiorxbuffer);
|
||||
commsRxUnencrypted(radiorxbuffer);
|
||||
commsRxUnencrypted(radiorxbuffer);
|
||||
commsRxUnencrypted(radiorxbuffer);
|
||||
*/
|
||||
}
|
||||
void sendXferCompleteAck(uint8_t *dst) {
|
||||
struct MacFrameNormal *frameHeader = (struct MacFrameNormal *)(radiotxbuffer + 1);
|
||||
@@ -794,13 +737,13 @@ void main(void) {
|
||||
;
|
||||
}
|
||||
for (uint8_t c = 0; c < 8; c++) {
|
||||
// mSelfMac[c] = c;
|
||||
mSelfMac[c] = c;
|
||||
}
|
||||
|
||||
if (!eepromInit()) { // we'll need the eeprom here, init it.
|
||||
pr("failed to init eeprom\n");
|
||||
return;
|
||||
}
|
||||
// if (!eepromInit()) { // we'll need the eeprom here, init it.
|
||||
// pr("failed to init eeprom\n");
|
||||
// return;
|
||||
// }
|
||||
|
||||
// clear the array with pending information
|
||||
memset(pendingDataArr, 0, sizeof(pendingDataArr));
|
||||
|
||||
@@ -57,6 +57,7 @@ void RF_IRQ1(void) __interrupt(4) {
|
||||
CFGPAGE = bkp;
|
||||
}
|
||||
}
|
||||
/*
|
||||
if ((cause & 0x10) && !(RADIO_curRfState & 0x20)) { // radio got a valid preamble and is RXing a packet. this is our chance to sample some RSSI
|
||||
uint8_t i;
|
||||
|
||||
@@ -65,6 +66,7 @@ void RF_IRQ1(void) __interrupt(4) {
|
||||
for (i = 0; i < 0x3c; i++)
|
||||
mLastRSSI = RADIO_currentRSSI;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
void RF_IRQ2(void) __interrupt(5) {
|
||||
|
||||
@@ -59,7 +59,7 @@ uint8_t uartBytesAvail() {
|
||||
|
||||
uint8_t* __idata blockp;
|
||||
uint8_t __idata cmd[3];
|
||||
bool __idata bypass = false;
|
||||
volatile bool __idata serialBypassActive = false;
|
||||
|
||||
void checkcommand(uint8_t rx) {
|
||||
for (uint8_t c = 0; c < 2; c++) {
|
||||
@@ -68,17 +68,17 @@ void checkcommand(uint8_t rx) {
|
||||
cmd[2] = rx;
|
||||
if (strncmp(cmd, ">D>", 3) == 0) {
|
||||
blockp = blockbuffer;
|
||||
bypass = true;
|
||||
serialBypassActive = true;
|
||||
}
|
||||
}
|
||||
|
||||
void UART_IRQ1(void) __interrupt(0) {
|
||||
if (UARTSTA & 1) { // RXC
|
||||
UARTSTA &= 0xfe;
|
||||
if (bypass) {
|
||||
if (serialBypassActive) {
|
||||
*blockp++ = UARTBUF;
|
||||
if (blockp == (blockbuffer+4100)) {
|
||||
bypass = false;
|
||||
serialBypassActive = false;
|
||||
blockRequestInProgress = false;
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -135,7 +135,7 @@ struct blockRequestAck {
|
||||
|
||||
#define TIMER_TICKS_PER_MS 1333UL
|
||||
#define RX_WINDOW_SIZE 10UL // ms
|
||||
//#define DEBUGBLOCKS
|
||||
// #define DEBUGBLOCKS
|
||||
|
||||
// download-stuff
|
||||
bool __xdata dataPending = true;
|
||||
@@ -396,9 +396,9 @@ void sendAvailDataReq() {
|
||||
}
|
||||
struct AvailDataInfo *__xdata getAvailDataInfo() {
|
||||
uint32_t __xdata t;
|
||||
for (uint8_t c = 0; c < 4; c++) {
|
||||
for (uint8_t c = 0; c < 15; c++) {
|
||||
sendAvailDataReq();
|
||||
t = timerGet() + (TIMER_TICKS_PER_MS * 15UL);
|
||||
t = timerGet() + (TIMER_TICKS_PER_MS * 10UL);
|
||||
while (timerGet() < t) {
|
||||
int8_t __xdata ret = commsRxUnencrypted(inBuffer);
|
||||
if (ret > 1) {
|
||||
@@ -455,8 +455,8 @@ bool blockRxLoop(uint32_t timeout) {
|
||||
}
|
||||
struct blockRequestAck *__xdata continueToRX() {
|
||||
struct blockRequestAck *ack = (struct blockRequestAck *)(inBuffer + sizeof(struct MacFrameNormal) + 1);
|
||||
ack->pleaseWaitMs = 0;
|
||||
ack->blockSizeMs = 100;
|
||||
ack->pleaseWaitMs = 1;
|
||||
ack->blockSizeMs = 250;
|
||||
return ack;
|
||||
}
|
||||
void sendBlockRequest() {
|
||||
@@ -493,9 +493,9 @@ void sendBlockRequest() {
|
||||
struct blockRequestAck *__xdata performBlockRequest() {
|
||||
uint32_t __xdata t;
|
||||
radioRxEnable(true, true);
|
||||
for (uint8_t c = 0; c < 5; c++) {
|
||||
for (uint8_t c = 0; c < 10; c++) {
|
||||
sendBlockRequest();
|
||||
t = timerGet() + (TIMER_TICKS_PER_MS * 10UL);
|
||||
t = timerGet() + (TIMER_TICKS_PER_MS * 5UL);
|
||||
do {
|
||||
int8_t __xdata ret = commsRxUnencrypted(inBuffer);
|
||||
if (ret > 1) {
|
||||
@@ -504,12 +504,13 @@ struct blockRequestAck *__xdata performBlockRequest() {
|
||||
if (checkCRC((inBuffer + sizeof(struct MacFrameNormal) + 1), sizeof(struct blockRequestAck)))
|
||||
return (struct blockRequestAck *)(inBuffer + sizeof(struct MacFrameNormal) + 1);
|
||||
break;
|
||||
case PKT_BLOCK_PART:
|
||||
/* case PKT_BLOCK_PART:
|
||||
// pr("packet instead of ack");
|
||||
processBlockPart((struct blockPart *)(inBuffer + sizeof(struct MacFrameNormal) + 1));
|
||||
return continueToRX();
|
||||
*/
|
||||
default:
|
||||
pr("got a packet w/ type %02X during block download?\n", getPacketType(inBuffer));
|
||||
pr("pkt w/type %02X\n", getPacketType(inBuffer));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -613,7 +614,7 @@ void getNumSlots() {
|
||||
imgSlots = nSlots;
|
||||
}
|
||||
uint8_t findSlot(uint8_t *__xdata ver) {
|
||||
//return 0xFF; // remove me! This forces the tag to re-download each and every upload without checking if it's already in the eeprom somewhere
|
||||
// return 0xFF; // remove me! This forces the tag to re-download each and every upload without checking if it's already in the eeprom somewhere
|
||||
uint32_t __xdata markerValid = EEPROM_IMG_VALID;
|
||||
for (uint8_t __xdata c = 0; c < imgSlots; c++) {
|
||||
struct EepromImageHeader __xdata *eih = (struct EepromImageHeader __xdata *)mScreenRow;
|
||||
@@ -642,7 +643,6 @@ void saveImgBlockData(uint8_t blockId) {
|
||||
pr("EEPROM write failed\n");
|
||||
}
|
||||
void drawImageFromEeprom() {
|
||||
|
||||
// enable WDT, to make sure de tag resets if it's for some reason unable to draw the image
|
||||
wdtSetResetVal(0xFFFFFFFF - 0x38C340);
|
||||
wdtOn();
|
||||
@@ -802,12 +802,14 @@ void doDataDownload() {
|
||||
}
|
||||
|
||||
// SLEEP - until the AP is ready with the data
|
||||
|
||||
uint32_t temp1 = ack->pleaseWaitMs * 1UL;
|
||||
if (ack->pleaseWaitMs) {
|
||||
if (ack->pleaseWaitMs < 35)
|
||||
ack->pleaseWaitMs = 35;
|
||||
doSleep(ack->pleaseWaitMs - 30);
|
||||
radioRxEnable(true, true);
|
||||
if (ack->pleaseWaitMs < 35) {
|
||||
timerDelay(ack->pleaseWaitMs * TIMER_TICKS_PER_MS);
|
||||
} else {
|
||||
doSleep(ack->pleaseWaitMs - 30);
|
||||
radioRxEnable(true, true);
|
||||
}
|
||||
}
|
||||
|
||||
// BLOCK RX LOOP - receive a block, until the timeout has passed
|
||||
@@ -818,6 +820,7 @@ void doDataDownload() {
|
||||
pr("bailing on download, 0 blockparts rx'd\n");
|
||||
return;
|
||||
} else {
|
||||
pr("0 packets...\n");
|
||||
goto startdownload;
|
||||
}
|
||||
} else {
|
||||
@@ -915,7 +918,9 @@ void doDataDownload() {
|
||||
sendXferComplete();
|
||||
killRadio();
|
||||
eepromReadStart(EEPROM_UPDATA_AREA_START);
|
||||
selfUpdate();
|
||||
wdtDeviceReset();
|
||||
// selfUpdate();
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user