diff --git a/ap_fw/main.c b/ap_fw/main.c index 105394c8..30380800 100644 --- a/ap_fw/main.c +++ b/ap_fw/main.c @@ -133,7 +133,6 @@ struct blockRequest { struct blockRequestAck { uint8_t checksum; - uint16_t blockSizeMs; uint16_t pleaseWaitMs; uint8_t cancelXfer; } __packed; @@ -159,7 +158,6 @@ struct espJoinNetwork { uint8_t src[8]; } __packed; - // used to transmit AP update information - flashing the firmware struct espSaveUpdateBlock { uint8_t checksum; @@ -168,7 +166,7 @@ struct espSaveUpdateBlock { } __packed; #define TIMER_TICKS_PER_MS 1333UL -uint16_t __xdata version = 0x0015; +uint16_t __xdata version = 0x0006; #define RAW_PKT_PADDING 2 static uint8_t __xdata mRxBuf[COMMS_MAX_PACKET_SZ]; @@ -244,22 +242,6 @@ void dump(uint8_t *__xdata a, uint16_t __xdata l) { } pr("\n"); } -uint8_t getBlockDataLength() { - uint8_t partNo = 0; - uint8_t rounds = 0; - while (partNo < BLOCK_MAX_PARTS) { - for (uint8_t c = 0; (c < BLOCK_MAX_PARTS) && (partNo < BLOCK_MAX_PARTS); c++) { - if (requestedData.requestedParts[c / 8] & (1 << (c % 8))) { - partNo++; - } - } - rounds++; - if (rounds == 4) { - return partNo; - } - } - return partNo; -} uint8_t __xdata getPacketType(void *__xdata buffer) { struct MacFcs *__xdata fcs = buffer; if ((fcs->frameType == 1) && (fcs->destAddrType == 2) && (fcs->srcAddrType == 3) && (fcs->panIdCompressed == 0)) { @@ -279,32 +261,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 +307,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 +329,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,35 +386,31 @@ 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); if (!checkCRC(blockReq, sizeof(struct blockRequest))) return; // todo: actually do something with the block request - // uint32_t __xdata curTimerValue = *t; bool __xdata requestDataDownload = false; - // if ((blockReq->blockId != requestedData.blockId) || (blockReq->ver != requestedData.ver)) { if ((blockReq->blockId != requestedData.blockId) || (!u64_isEq((const uint64_t __xdata *)&blockReq->ver, (const uint64_t __xdata *)&requestedData.ver))) { // requested block isn't already in the buffer 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 ((timerGet() - nextBlockAttempt) > (380 * TIMER_TICKS_PER_MS)) { requestDataDownload = true; + pr("FORCED\n"); } 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("IGNORED\n"); } } } + // copy blockrequest into requested data memcpy(&requestedData, blockReq, sizeof(struct blockRequest)); struct MacFrameNormal *txHeader = (struct MacFrameNormal *)(radiotxbuffer + 1); @@ -507,7 +418,6 @@ 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 @@ -516,21 +426,16 @@ void processBlockRequest(const uint8_t *buffer, uint8_t forceBlockDownload) { } else { blockRequestAck->pleaseWaitMs = 100; } - blockStartTimer = timerGet() + blockRequestAck->pleaseWaitMs * TIMER_TICKS_PER_MS; } else { - blockRequestAck->pleaseWaitMs = 30; - blockStartTimer = timerGet() + blockRequestAck->pleaseWaitMs * TIMER_TICKS_PER_MS; + // block is already in buffer + blockRequestAck->pleaseWaitMs = 50; } } 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->pleaseWaitMs = 50; } - blockRequestAck->blockSizeMs = 15 + 15 + (getBlockDataLength() * 245) / BLOCK_MAX_PARTS; + blockStartTimer = timerGet() + blockRequestAck->pleaseWaitMs * TIMER_TICKS_PER_MS; + blockRequestAck->cancelXfer = 0; - // pr("s=%d\n", blockRequestAck->blockSizeMs); memcpy(txHeader->src, mSelfMac, 8); memcpy(txHeader->dst, rxHeader->src, 8); @@ -547,14 +452,14 @@ void processBlockRequest(const uint8_t *buffer, uint8_t forceBlockDownload) { addCRC((void *)blockRequestAck, sizeof(struct blockRequestAck)); 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); + serialBypassActive = false; espBlockRequest(&requestedData); + nextBlockAttempt = timerGet(); } /* @@ -609,6 +514,7 @@ void processAvailDataReq(uint8_t *buffer) { txHeader->seq = seq++; addCRC(availDataInfo, sizeof(struct AvailDataInfo)); radioTx(radiotxbuffer); + espNotifyAvailDataReq(availDataReq); } void processXferComplete(uint8_t *buffer) { @@ -742,26 +648,15 @@ void sendPart(uint8_t partNo) { } void sendBlockData() { uint8_t partNo = 0; - uint8_t rounds = 0; while (partNo < BLOCK_MAX_PARTS) { 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; - } } - // 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); } void sendXferCompleteAck(uint8_t *dst) { struct MacFrameNormal *frameHeader = (struct MacFrameNormal *)(radiotxbuffer + 1); @@ -794,13 +689,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)); @@ -870,6 +765,7 @@ void main(void) { if (timerGet() > blockStartTimer) { sendBlockData(); blockStartTimer = 0; + radioRxFlush(); } } } diff --git a/ap_fw/soc/zbs243/radio.c b/ap_fw/soc/zbs243/radio.c index 802f2561..4fb70e9b 100644 --- a/ap_fw/soc/zbs243/radio.c +++ b/ap_fw/soc/zbs243/radio.c @@ -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) { diff --git a/ap_fw/soc/zbs243/uart.c b/ap_fw/soc/zbs243/uart.c index 708347c3..45d33b5a 100644 --- a/ap_fw/soc/zbs243/uart.c +++ b/ap_fw/soc/zbs243/uart.c @@ -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 { diff --git a/tag_fw/syncedproto.c b/tag_fw/syncedproto.c index dcf6d90d..bb020f7a 100644 --- a/tag_fw/syncedproto.c +++ b/tag_fw/syncedproto.c @@ -128,14 +128,13 @@ struct blockRequest { struct blockRequestAck { uint8_t checksum; - uint16_t blockSizeMs; uint16_t pleaseWaitMs; uint8_t cancelXfer; } __packed; #define TIMER_TICKS_PER_MS 1333UL #define RX_WINDOW_SIZE 10UL // ms -//#define DEBUGBLOCKS +// #define DEBUGBLOCKS // download-stuff bool __xdata dataPending = true; @@ -288,9 +287,9 @@ const struct timingResponse *__xdata getTimingInfo() { radioRxFlush(); uint32_t __xdata mTimerWaitStart; radioRxEnable(true, true); - for (uint8_t c = 0; c < 3; c++) { + for (uint8_t c = 0; c < 5; c++) { sendTimingInfoReq(); - mTimerWaitStart = timerGet() + TIMER_TICKS_PER_MS * 3; + mTimerWaitStart = timerGet() + TIMER_TICKS_PER_MS * 4; while (timerGet() < mTimerWaitStart) { int8_t ret = commsRxUnencrypted(inBuffer); if (ret > 1) { @@ -396,9 +395,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) { @@ -425,9 +424,7 @@ void processBlockPart(struct blockPart *bp) { if ((start + size) > sizeof(blockXferBuffer)) { size = sizeof(blockXferBuffer) - start; } - if (!checkCRC(bp, sizeof(struct blockPart) + BLOCK_PART_DATA_SIZE)) { - pr("CHKSUM FAILED!\n"); - } else { + if (checkCRC(bp, sizeof(struct blockPart) + BLOCK_PART_DATA_SIZE)) { // copy block data to buffer xMemCopy((void *)(blockXferBuffer + start), (const void *)bp->data, size); // we don't need this block anymore, set bit to 0 so we don't request it again @@ -456,19 +453,15 @@ 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->cancelXfer = 0; return ack; } void sendBlockRequest() { - /* commsRxUnencrypted(mRxBuf); - commsRxUnencrypted(mRxBuf); - commsRxUnencrypted(mRxBuf); - commsRxUnencrypted(mRxBuf);*/ memset(outBuffer, 0, sizeof(struct MacFrameNormal) + sizeof(struct blockRequest) + 2 + 2); 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; @@ -493,9 +486,10 @@ void sendBlockRequest() { struct blockRequestAck *__xdata performBlockRequest() { uint32_t __xdata t; radioRxEnable(true, true); - for (uint8_t c = 0; c < 5; c++) { + radioRxFlush(); + for (uint8_t c = 0; c < 30; c++) { sendBlockRequest(); - t = timerGet() + (TIMER_TICKS_PER_MS * 10UL); + t = timerGet() + (TIMER_TICKS_PER_MS * (7UL + c / 10)); do { int8_t __xdata ret = commsRxUnencrypted(inBuffer); if (ret > 1) { @@ -505,17 +499,21 @@ struct blockRequestAck *__xdata performBlockRequest() { return (struct blockRequestAck *)(inBuffer + sizeof(struct MacFrameNormal) + 1); break; case PKT_BLOCK_PART: - // pr("packet instead of ack"); - processBlockPart((struct blockPart *)(inBuffer + sizeof(struct MacFrameNormal) + 1)); + // block already started while we were waiting for a get block reply + //pr("!"); + //processBlockPart((struct blockPart *)(inBuffer + sizeof(struct MacFrameNormal) + 1)); return continueToRX(); + break; default: - pr("got a packet w/ type %02X during block download?\n", getPacketType(inBuffer)); + pr("pkt w/type %02X\n", getPacketType(inBuffer)); + break; } } } while (timerGet() < t); } - return NULL; + return continueToRX(); + //return NULL; } void sendXferCompletePacket() { memset(outBuffer, 0, sizeof(struct MacFrameNormal) + 2 + 4); @@ -613,7 +611,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 +640,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(); @@ -787,6 +784,9 @@ void doDataDownload() { } pr("]\n"); #endif + + //timerDelay(TIMER_TICKS_PER_MS*100); + // DO BLOCK REQUEST - request a block, get an ack with timing info (hopefully) struct blockRequestAck *__xdata ack = performBlockRequest(); if (ack == NULL) { @@ -802,23 +802,27 @@ void doDataDownload() { } // SLEEP - until the AP is ready with the data - if (ack->pleaseWaitMs) { - if (ack->pleaseWaitMs < 35) - ack->pleaseWaitMs = 35; - doSleep(ack->pleaseWaitMs - 30); - radioRxEnable(true, true); + ack->pleaseWaitMs -= 10; + if (ack->pleaseWaitMs < 35) { + timerDelay(ack->pleaseWaitMs * TIMER_TICKS_PER_MS); + } else { + doSleep(ack->pleaseWaitMs - 30); + radioRxEnable(true, true); + } + } else { + // immediately start with the reception of the block data } // BLOCK RX LOOP - receive a block, until the timeout has passed - if (!blockRxLoop(ack->blockSizeMs)) { + if (!blockRxLoop(440)) { // was 340 // didn't receive packets blockRequestAttempt++; - if (blockRequestAttempt > 4) { + if (blockRequestAttempt > 5) { pr("bailing on download, 0 blockparts rx'd\n"); return; } else { - goto startdownload; + //goto startdownload; } } else { // successfull block RX loop @@ -915,7 +919,9 @@ void doDataDownload() { sendXferComplete(); killRadio(); eepromReadStart(EEPROM_UPDATA_AREA_START); + //wdtDeviceReset(); selfUpdate(); + break; } }