mirror of
https://github.com/OpenEPaperLink/OpenEPaperLink.git
synced 2026-03-21 08:06:46 +01:00
testing - power not checked!
This commit is contained in:
108
tag_fw/drawing.c
108
tag_fw/drawing.c
@@ -8,10 +8,11 @@
|
||||
#include "eeprom.h"
|
||||
#include "epd.h"
|
||||
#include "printf.h"
|
||||
#include "proto.h"
|
||||
#include "screen.h"
|
||||
#include "timer.h"
|
||||
#include "userinterface.h" // for addIcons
|
||||
|
||||
#include "userinterface.h" // for addIcons
|
||||
#define COMPRESSION_BITPACKED_3x5_to_7 0x62700357 // 3 pixels of 5 possible colors in 7 bits
|
||||
#define COMPRESSION_BITPACKED_5x3_to_8 0x62700538 // 5 pixels of 3 possible colors in 8 bits
|
||||
#define COMPRESSION_BITPACKED_3x6_to_8 0x62700368 // 3 pixels of 6 possible colors in 8 bits
|
||||
@@ -335,31 +336,88 @@ void ByteDecode(uint8_t byte) {
|
||||
}
|
||||
|
||||
void drawImageAtAddress(uint32_t addr, uint8_t lut) {
|
||||
uint32_t __xdata clutAddr;
|
||||
pr("sending to EPD - ");
|
||||
clutAddr = drawPrvParseHeader(addr);
|
||||
if (!clutAddr)
|
||||
return;
|
||||
drawPrvLoadAndMapClut(clutAddr);
|
||||
struct EepromImageHeader* __xdata eih = (struct EepromImageHeader*)mClutMap;
|
||||
eepromRead(addr, mClutMap, sizeof(struct EepromImageHeader));
|
||||
|
||||
epdSetup();
|
||||
if(lut)selectLUT(lut);
|
||||
mPassNo = 0;
|
||||
beginFullscreenImage();
|
||||
beginWriteFramebuffer(EPD_COLOR_BLACK);
|
||||
prev = 0;
|
||||
step = 0;
|
||||
drawPrvDecodeImageOnce();
|
||||
endWriteFramebuffer();
|
||||
mPassNo++;
|
||||
beginFullscreenImage();
|
||||
beginWriteFramebuffer(EPD_COLOR_RED);
|
||||
prev = 0;
|
||||
step = 0;
|
||||
drawPrvDecodeImageOnce();
|
||||
endWriteFramebuffer();
|
||||
switch (eih->dataType) {
|
||||
case DATATYPE_IMG_RAW_1BPP:
|
||||
pr("Doing raw 1bpp\n");
|
||||
epdSetup();
|
||||
if (lut) selectLUT(lut);
|
||||
beginFullscreenImage();
|
||||
clearScreen();
|
||||
beginWriteFramebuffer(EPD_COLOR_BLACK);
|
||||
epdSelect();
|
||||
for (uint16_t c = 0; c < (SCREEN_HEIGHT * SCREEN_WIDTH / 8); c++) {
|
||||
if (c % 256 == 0) {
|
||||
epdDeselect();
|
||||
eepromRead(addr + sizeof(struct EepromImageHeader) + c, mClutMap, 256);
|
||||
epdSelect();
|
||||
}
|
||||
epdSend(mClutMap[c % 256]);
|
||||
}
|
||||
epdDeselect();
|
||||
endWriteFramebuffer();
|
||||
break;
|
||||
case DATATYPE_IMG_RAW_2BPP:
|
||||
pr("Doing raw 2bpp\n");
|
||||
epdSetup();
|
||||
if (lut) selectLUT(lut);
|
||||
beginFullscreenImage();
|
||||
beginWriteFramebuffer(EPD_COLOR_BLACK);
|
||||
epdSelect();
|
||||
for (uint16_t c = 0; c < (SCREEN_HEIGHT * SCREEN_WIDTH / 8); c++) {
|
||||
if (c % 256 == 0) {
|
||||
epdDeselect();
|
||||
eepromRead(addr + sizeof(struct EepromImageHeader) + c, mClutMap, 256);
|
||||
epdSelect();
|
||||
}
|
||||
epdSend(mClutMap[c % 256]);
|
||||
}
|
||||
epdDeselect();
|
||||
endWriteFramebuffer();
|
||||
|
||||
pr(" complete.\n");
|
||||
beginWriteFramebuffer(EPD_COLOR_RED);
|
||||
epdSelect();
|
||||
for (uint16_t c = 0; c < (SCREEN_HEIGHT * SCREEN_WIDTH / 8); c++) {
|
||||
if (c % 256 == 0) {
|
||||
epdDeselect();
|
||||
eepromRead(addr + sizeof(struct EepromImageHeader) + (SCREEN_HEIGHT * SCREEN_WIDTH / 8) + c, mClutMap, 256);
|
||||
epdSelect();
|
||||
}
|
||||
epdSend(mClutMap[c % 256]);
|
||||
}
|
||||
epdDeselect();
|
||||
endWriteFramebuffer();
|
||||
break;
|
||||
case DATATYPE_IMG_BMP:;
|
||||
uint32_t __xdata clutAddr;
|
||||
pr("sending to EPD - ");
|
||||
clutAddr = drawPrvParseHeader(addr);
|
||||
if (!clutAddr)
|
||||
return;
|
||||
drawPrvLoadAndMapClut(clutAddr);
|
||||
|
||||
epdSetup();
|
||||
if (lut) selectLUT(lut);
|
||||
mPassNo = 0;
|
||||
beginFullscreenImage();
|
||||
beginWriteFramebuffer(EPD_COLOR_BLACK);
|
||||
prev = 0;
|
||||
step = 0;
|
||||
drawPrvDecodeImageOnce();
|
||||
endWriteFramebuffer();
|
||||
mPassNo++;
|
||||
beginFullscreenImage();
|
||||
beginWriteFramebuffer(EPD_COLOR_RED);
|
||||
prev = 0;
|
||||
step = 0;
|
||||
drawPrvDecodeImageOnce();
|
||||
endWriteFramebuffer();
|
||||
|
||||
pr(" complete.\n");
|
||||
break;
|
||||
}
|
||||
addOverlay();
|
||||
drawWithSleep();
|
||||
}
|
||||
}
|
||||
@@ -32,17 +32,14 @@ void eepromReadStart(uint32_t addr) __reentrant;
|
||||
|
||||
//structures
|
||||
#define EEPROM_IMG_INPROGRESS (0x7fffffffUL)
|
||||
#define EEPROM_IMG_VALID (0x494d4722UL)
|
||||
|
||||
#define EEPROM_IMG_VALID (0x494d4721UL)
|
||||
#include "board.h"
|
||||
|
||||
#define EEPROM_PIECE_SZ (88)
|
||||
struct EepromImageHeader { //each image space is 0x17000 bytes, we have space for ten of them
|
||||
uint64_t version;
|
||||
uint32_t validMarker;
|
||||
uint32_t size;
|
||||
uint32_t rfu[8]; //zero-filled for now
|
||||
uint8_t piecesMissing[EEPROM_PROGRESS_BYTES]; //each bit represents a EEPROM_PIECE_SZ-byte piece
|
||||
uint8_t dataType;
|
||||
uint32_t id;
|
||||
|
||||
//image data here
|
||||
|
||||
BIN
tag_fw/fw154.bin
BIN
tag_fw/fw154.bin
Binary file not shown.
BIN
tag_fw/fw29.bin
BIN
tag_fw/fw29.bin
Binary file not shown.
BIN
tag_fw/fw42.bin
BIN
tag_fw/fw42.bin
Binary file not shown.
@@ -235,7 +235,7 @@ void mainProtocolLoop(void) {
|
||||
// Check if we were already displaying an image
|
||||
if (curImgSlot != 0xFF) {
|
||||
powerUp(INIT_EEPROM);
|
||||
drawImageFromEeprom();
|
||||
drawImageFromEeprom(curImgSlot);
|
||||
powerDown(INIT_EEPROM);
|
||||
} else {
|
||||
showAPFound();
|
||||
@@ -267,7 +267,7 @@ void mainProtocolLoop(void) {
|
||||
if (avail->dataType != DATATYPE_NOUPDATE) {
|
||||
// data transfer
|
||||
powerUp(INIT_GPIO | INIT_UART);
|
||||
if (doDataDownload(avail)) {
|
||||
if (processAvailDataInfo(avail)) {
|
||||
// succesful transfer, next wake time is determined by the NextCheckin;
|
||||
} else {
|
||||
// failed transfer, let the algorithm determine next sleep interval (not the AP)
|
||||
@@ -311,7 +311,7 @@ void mainProtocolLoop(void) {
|
||||
powerUp(INIT_EPD);
|
||||
if (curImgSlot != 0xFF) {
|
||||
powerUp(INIT_EEPROM);
|
||||
drawImageFromEeprom();
|
||||
drawImageFromEeprom(curImgSlot);
|
||||
powerDown(INIT_EEPROM);
|
||||
} else if ((scanAttempts >= (INTERVAL_1_ATTEMPTS + INTERVAL_2_ATTEMPTS - 1))) {
|
||||
showLongTermSleep();
|
||||
|
||||
@@ -116,9 +116,11 @@ struct AvailDataReq {
|
||||
|
||||
|
||||
#define DATATYPE_NOUPDATE 0
|
||||
#define DATATYPE_IMG 1
|
||||
#define DATATYPE_IMGRAW 2
|
||||
#define DATATYPE_UPDATE 3
|
||||
#define DATATYPE_IMG_BMP 2
|
||||
#define DATATYPE_FW_UPDATE 3
|
||||
#define DATATYPE_IMG_DIFF 0x10 // always 1BPP
|
||||
#define DATATYPE_IMG_RAW_1BPP 0x20 // 2888 bytes for 1.54" / 4736 2.9" / 15000 4.2"
|
||||
#define DATATYPE_IMG_RAW_2BPP 0x21 // 5776 bytes for 1.54" / 9472 2.9" / 30000 4.2"
|
||||
|
||||
struct AvailDataInfo {
|
||||
uint8_t checksum;
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#include <stdint.h>
|
||||
|
||||
#define FW_VERSION 014 // version number (max 2.5.5 :) )
|
||||
#define FW_VERSION_SUFFIX "-lutje" // suffix, like -RC1 or whatever.
|
||||
#define FW_VERSION_SUFFIX "-RE" // suffix, like -RC1 or whatever.
|
||||
#define HAS_BUTTON // uncomment to enable reading a push button (connect between 'TEST' en 'GND' on the tag, along with a 100nF capacitor in parallel).
|
||||
#define DEBUGBLOCKS // uncomment to enable extra debug information on the block transfers
|
||||
//#define PRINT_LUT // uncomment if you want the tag to print the LUT for the current temperature bracket
|
||||
|
||||
@@ -25,26 +25,19 @@
|
||||
#include "wdt.h"
|
||||
|
||||
// download-stuff
|
||||
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.
|
||||
bool __xdata curXferComplete = false;
|
||||
struct blockRequest __xdata curBlock = {0}; // used by the block-requester, contains the next request that we'll send
|
||||
struct AvailDataInfo __xdata curDataInfo = {0}; // last 'AvailDataInfo' we received from the AP
|
||||
bool __xdata requestPartialBlock = false;
|
||||
#define BLOCK_TRANSFER_ATTEMPTS 5
|
||||
|
||||
uint8_t __xdata prevImgSlot = 0xFF;
|
||||
uint8_t __xdata curImgSlot = 0xFF;
|
||||
uint32_t __xdata curHighSlotId = 0;
|
||||
uint8_t __xdata nextImgSlot = 0;
|
||||
uint8_t __xdata imgSlots = 0;
|
||||
uint8_t __xdata drawWithLut = 0;
|
||||
|
||||
// doDownload persistent variables
|
||||
bool __xdata lastBlock = false;
|
||||
uint8_t __xdata partsThisBlock = 0;
|
||||
uint8_t __xdata blockRequestAttempt = 0;
|
||||
uint8_t __xdata blockValidateAttempt = 0;
|
||||
|
||||
// stuff we need to keep track of related to the network/AP
|
||||
uint8_t __xdata APmac[8] = {0};
|
||||
uint16_t __xdata APsrcPan = 0;
|
||||
@@ -441,19 +434,22 @@ uint8_t findSlot(uint8_t *__xdata ver) {
|
||||
void eraseUpdateBlock() {
|
||||
eepromErase(EEPROM_UPDATA_AREA_START, EEPROM_UPDATE_AREA_LEN / EEPROM_ERZ_SECTOR_SZ);
|
||||
}
|
||||
void eraseImageBlock(uint8_t c) {
|
||||
eepromErase(getAddressForSlot(c), EEPROM_IMG_EACH / EEPROM_ERZ_SECTOR_SZ);
|
||||
}
|
||||
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) {
|
||||
void saveImgBlockData(uint8_t imgSlot, uint8_t blockId) {
|
||||
uint16_t length = EEPROM_IMG_EACH - (sizeof(struct EepromImageHeader) + (blockId * BLOCK_DATA_SIZE));
|
||||
if (length > 4096) length = 4096;
|
||||
|
||||
if (!eepromWrite(getAddressForSlot(curImgSlot) + sizeof(struct EepromImageHeader) + (blockId * BLOCK_DATA_SIZE), blockXferBuffer + sizeof(struct blockData), length))
|
||||
if (!eepromWrite(getAddressForSlot(imgSlot) + sizeof(struct EepromImageHeader) + (blockId * BLOCK_DATA_SIZE), blockXferBuffer + sizeof(struct blockData), length))
|
||||
pr("EEPROM write failed\n");
|
||||
}
|
||||
void drawImageFromEeprom() {
|
||||
drawImageAtAddress(getAddressForSlot(curImgSlot), drawWithLut);
|
||||
void drawImageFromEeprom(uint8_t imgSlot) {
|
||||
drawImageAtAddress(getAddressForSlot(imgSlot), drawWithLut);
|
||||
drawWithLut = 0; // default back to the regular ol' stock/OTP LUT
|
||||
powerDown(INIT_EPD);
|
||||
}
|
||||
@@ -474,110 +470,30 @@ uint32_t getHighSlotId() {
|
||||
return temp;
|
||||
}
|
||||
|
||||
// Main download function
|
||||
bool doDataDownload(struct AvailDataInfo *__xdata avail) {
|
||||
// this is the main function for the download process
|
||||
bool getDataBlock(uint16_t blockSize) {
|
||||
static uint8_t __xdata partsThisBlock = 0;
|
||||
static uint8_t __xdata blockAttempts = 0;
|
||||
blockAttempts = BLOCK_TRANSFER_ATTEMPTS;
|
||||
|
||||
if (!eepromInit()) { // we'll need the eeprom here, init it.
|
||||
pr("failed to init eeprom\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
// GET AVAIL DATA INFO - enable the radio and get data
|
||||
if (avail == NULL) { // didn't receive a reply to get info about the data, we'll resync and try again later
|
||||
#ifdef DEBUGBLOCKS
|
||||
pr("didn't receive getavaildatainfo");
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
// did receive available data info (avail struct)
|
||||
switch (avail->dataType) {
|
||||
case DATATYPE_IMG:
|
||||
case DATATYPE_IMGRAW:
|
||||
// check if this download is currently displayed or active
|
||||
if (curXferComplete && xMemEqual((const void *__xdata) & avail->dataVer, (const void *__xdata) & curDataInfo.dataVer, 8)) {
|
||||
// we've downloaded this already, we're guessing it's already displayed
|
||||
pr("old ver, already downloaded!\n");
|
||||
powerUp(INIT_RADIO);
|
||||
sendXferComplete();
|
||||
powerDown(INIT_RADIO);
|
||||
return true;
|
||||
} else {
|
||||
// check if we've seen this version before
|
||||
curImgSlot = findSlot(&(avail->dataVer));
|
||||
if (curImgSlot != 0xFF) {
|
||||
// found a (complete)valid image slot for this version
|
||||
powerDown(INIT_RADIO);
|
||||
sendXferComplete();
|
||||
powerDown(INIT_RADIO);
|
||||
|
||||
pr("already seen, drawing from eeprom slot %d\n", curImgSlot);
|
||||
|
||||
// mark as completed and draw from EEPROM
|
||||
curXferComplete = true;
|
||||
xMemCopyShort(&curDataInfo, (void *)avail, sizeof(struct AvailDataInfo));
|
||||
drawWithLut = avail->dataTypeArgument;
|
||||
wdt60s();
|
||||
drawImageFromEeprom();
|
||||
return true;
|
||||
} else {
|
||||
// not found in cache, prepare to download
|
||||
// go to the next image slot
|
||||
nextImgSlot++;
|
||||
if (nextImgSlot >= imgSlots) nextImgSlot = 0;
|
||||
curImgSlot = nextImgSlot;
|
||||
drawWithLut = avail->dataTypeArgument;
|
||||
eepromErase(getAddressForSlot(curImgSlot), EEPROM_IMG_EACH / EEPROM_ERZ_SECTOR_SZ);
|
||||
pr("new download, writing to slot %d\n", curImgSlot);
|
||||
// continue!
|
||||
}
|
||||
}
|
||||
break;
|
||||
case DATATYPE_UPDATE:
|
||||
pr("received firmware!\n");
|
||||
eepromErase(EEPROM_UPDATA_AREA_START, EEPROM_UPDATE_AREA_LEN / EEPROM_ERZ_SECTOR_SZ);
|
||||
break;
|
||||
}
|
||||
|
||||
// prepare for download
|
||||
curXferComplete = false;
|
||||
curBlock.blockId = 0;
|
||||
xMemCopy8(&(curBlock.ver), &(avail->dataVer));
|
||||
curBlock.type = avail->dataType;
|
||||
xMemCopyShort(&curDataInfo, (void *)avail, sizeof(struct AvailDataInfo));
|
||||
dataRemaining = curDataInfo.dataSize; // this was + 2, and I can't remember why. It works fine without it, so I don't know....
|
||||
|
||||
// set requested parts - check if the transfer is contained in this block
|
||||
if (dataRemaining > BLOCK_DATA_SIZE) {
|
||||
// full block, not last
|
||||
lastBlock = false;
|
||||
if (blockSize == BLOCK_DATA_SIZE) {
|
||||
partsThisBlock = BLOCK_MAX_PARTS;
|
||||
memset(curBlock.requestedParts, 0xFF, BLOCK_REQ_PARTS_BYTES);
|
||||
} else {
|
||||
// final block, probably partial
|
||||
lastBlock = true;
|
||||
partsThisBlock = dataRemaining / BLOCK_PART_DATA_SIZE;
|
||||
if (dataRemaining % BLOCK_PART_DATA_SIZE) partsThisBlock++;
|
||||
partsThisBlock = blockSize / BLOCK_PART_DATA_SIZE;
|
||||
if (blockSize % BLOCK_PART_DATA_SIZE) partsThisBlock++;
|
||||
memset(curBlock.requestedParts, 0x00, BLOCK_REQ_PARTS_BYTES);
|
||||
for (uint8_t c = 0; c < partsThisBlock; c++) {
|
||||
curBlock.requestedParts[c / 8] |= (1 << (c % 8));
|
||||
}
|
||||
}
|
||||
|
||||
// do transfer!
|
||||
blockRequestAttempt = 0;
|
||||
blockValidateAttempt = 0;
|
||||
while (!curXferComplete) {
|
||||
// this while loop loops until the transfer has been completed, or we get tired for other reasons
|
||||
startdownload:;
|
||||
wdt10s();
|
||||
requestPartialBlock = false; // this forces the AP to request the block data from the host
|
||||
|
||||
while (blockAttempts--) {
|
||||
#ifndef DEBUGBLOCKS
|
||||
pr("REQ %d ", curBlock.blockId);
|
||||
#endif
|
||||
#ifdef DEBUGBLOCKS
|
||||
#else
|
||||
pr("REQ %d[", curBlock.blockId);
|
||||
|
||||
for (uint8_t c = 0; c < BLOCK_MAX_PARTS; c++) {
|
||||
if ((c != 0) && (c % 8 == 0)) pr("][");
|
||||
if (curBlock.requestedParts[c / 8] & (1 << (c % 8))) {
|
||||
@@ -588,20 +504,13 @@ bool doDataDownload(struct AvailDataInfo *__xdata avail) {
|
||||
}
|
||||
pr("]\n");
|
||||
#endif
|
||||
|
||||
// timerDelay(TIMER_TICKS_PER_MS*100);
|
||||
|
||||
// DO BLOCK REQUEST - request a block, get an ack with timing info (hopefully)
|
||||
powerUp(INIT_RADIO);
|
||||
struct blockRequestAck *__xdata ack = performBlockRequest();
|
||||
if (ack == NULL) {
|
||||
pr("Cancelled request\n");
|
||||
return false;
|
||||
} else {
|
||||
// got an ack!
|
||||
}
|
||||
// SLEEP - until the AP is ready with the data
|
||||
if (ack->pleaseWaitMs) {
|
||||
if (ack->pleaseWaitMs) { // SLEEP - until the AP is ready with the data
|
||||
if (ack->pleaseWaitMs < 35) {
|
||||
timerDelay(ack->pleaseWaitMs * TIMER_TICKS_PER_MS);
|
||||
} else {
|
||||
@@ -613,20 +522,10 @@ bool doDataDownload(struct AvailDataInfo *__xdata avail) {
|
||||
} else {
|
||||
// immediately start with the reception of the block data
|
||||
}
|
||||
// BLOCK RX LOOP - receive a block, until the timeout has passed
|
||||
if (!blockRxLoop(270)) { // was 300
|
||||
// didn't receive packets
|
||||
blockRequestAttempt++;
|
||||
if (blockRequestAttempt > 5) {
|
||||
powerDown(INIT_RADIO);
|
||||
pr("bailing on download, 0 blockparts rx'd\n");
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
// successfull block RX loop
|
||||
blockRequestAttempt = 0;
|
||||
}
|
||||
|
||||
blockRxLoop(270); // BLOCK RX LOOP - receive a block, until the timeout has passed
|
||||
powerDown(INIT_RADIO);
|
||||
|
||||
#ifdef DEBUGBLOCKS
|
||||
pr("RX %d[", curBlock.blockId);
|
||||
for (uint8_t c = 0; c < BLOCK_MAX_PARTS; c++) {
|
||||
@@ -639,7 +538,6 @@ bool doDataDownload(struct AvailDataInfo *__xdata avail) {
|
||||
}
|
||||
pr("]\n");
|
||||
#endif
|
||||
|
||||
// check if we got all the parts we needed, e.g: has the block been completed?
|
||||
bool blockComplete = true;
|
||||
for (uint8_t c = 0; c < partsThisBlock; c++) {
|
||||
@@ -651,31 +549,14 @@ bool doDataDownload(struct AvailDataInfo *__xdata avail) {
|
||||
pr("- COMPLETE\n");
|
||||
#endif
|
||||
if (validateBlockData()) {
|
||||
// checked and found okay
|
||||
requestPartialBlock = false; // next block is going to be requested from the ESP32 by the AP
|
||||
blockValidateAttempt = 0;
|
||||
switch (curBlock.type) {
|
||||
case DATATYPE_IMG:
|
||||
case DATATYPE_IMGRAW:
|
||||
saveImgBlockData(curBlock.blockId);
|
||||
break;
|
||||
case DATATYPE_UPDATE:
|
||||
saveUpdateBlockData(curBlock.blockId);
|
||||
break;
|
||||
}
|
||||
// block download complete, validated
|
||||
return true;
|
||||
} else {
|
||||
// block checked, but failed validation. Mark all parts for this block as 'request'
|
||||
blockValidateAttempt++;
|
||||
if (blockValidateAttempt > 5) {
|
||||
pr("bailing on download, 0 blockparts rx'd\n");
|
||||
return false;
|
||||
}
|
||||
for (uint8_t c = 0; c < partsThisBlock; c++) {
|
||||
curBlock.requestedParts[c / 8] |= (1 << (c % 8));
|
||||
}
|
||||
blockComplete = false;
|
||||
requestPartialBlock = false;
|
||||
pr("block failed validation!\n");
|
||||
pr("blk failed validation!\n");
|
||||
}
|
||||
} else {
|
||||
#ifndef DEBUGBLOCKS
|
||||
@@ -684,67 +565,174 @@ bool doDataDownload(struct AvailDataInfo *__xdata avail) {
|
||||
// block incomplete, re-request a partial block
|
||||
requestPartialBlock = true;
|
||||
}
|
||||
}
|
||||
pr("failed getting block\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (blockComplete) {
|
||||
if (!lastBlock) {
|
||||
// Not the last block! check what the next block is going to be
|
||||
curBlock.blockId++;
|
||||
dataRemaining -= BLOCK_DATA_SIZE;
|
||||
if (dataRemaining > BLOCK_DATA_SIZE) {
|
||||
// full block-size
|
||||
partsThisBlock = BLOCK_MAX_PARTS;
|
||||
memset(curBlock.requestedParts, 0xFF, BLOCK_REQ_PARTS_BYTES);
|
||||
lastBlock = false;
|
||||
} else {
|
||||
// final block, probably partial
|
||||
partsThisBlock = dataRemaining / BLOCK_PART_DATA_SIZE;
|
||||
if (dataRemaining % BLOCK_PART_DATA_SIZE) partsThisBlock++;
|
||||
memset(curBlock.requestedParts, 0x00, BLOCK_REQ_PARTS_BYTES);
|
||||
for (uint8_t c = 0; c < partsThisBlock; c++) {
|
||||
curBlock.requestedParts[c / 8] |= (1 << (c % 8));
|
||||
}
|
||||
lastBlock = true;
|
||||
}
|
||||
bool downloadFWUpdate(struct AvailDataInfo *__xdata avail) {
|
||||
// check if we already started the transfer of this information & haven't completed it
|
||||
if (xMemEqual((const void *__xdata) & avail->dataVer, (const void *__xdata) & curDataInfo.dataVer, 8) && curDataInfo.dataSize) {
|
||||
// looks like we did. We'll carry on where we left off.
|
||||
} else {
|
||||
// start, or restart the transfer from 0. Copy data from the AvailDataInfo struct, and the struct intself. This forces a new transfer
|
||||
curBlock.blockId = 0;
|
||||
xMemCopy8(&(curBlock.ver), &(avail->dataVer));
|
||||
curBlock.type = avail->dataType;
|
||||
xMemCopyShort(&curDataInfo, (void *)avail, sizeof(struct AvailDataInfo));
|
||||
eraseUpdateBlock();
|
||||
}
|
||||
|
||||
} else {
|
||||
// this was the last block. What should we do next?
|
||||
switch (curBlock.type) {
|
||||
case DATATYPE_IMG:
|
||||
case DATATYPE_IMGRAW:;
|
||||
// transfer complete. Save data info and mark data in image slot as 'valid'
|
||||
struct EepromImageHeader __xdata *eih = (struct EepromImageHeader __xdata *)blockXferBuffer;
|
||||
xMemCopy8(&eih->version, &curDataInfo.dataVer);
|
||||
eih->size = curDataInfo.dataSize;
|
||||
eih->validMarker = EEPROM_IMG_VALID;
|
||||
eih->id = ++curHighSlotId;
|
||||
eepromWrite(getAddressForSlot(curImgSlot), eih, sizeof(struct EepromImageHeader));
|
||||
// pr("transfer complete!");
|
||||
curXferComplete = true;
|
||||
powerUp(INIT_RADIO);
|
||||
sendXferComplete();
|
||||
powerDown(INIT_RADIO);
|
||||
wdt60s();
|
||||
drawImageFromEeprom();
|
||||
curDataInfo.dataVer = 0xAA;
|
||||
break;
|
||||
case DATATYPE_UPDATE:
|
||||
pr("firmware download complete, doing update.\n");
|
||||
powerUp(INIT_EPD);
|
||||
showApplyUpdate();
|
||||
curXferComplete = true;
|
||||
powerUp(INIT_RADIO);
|
||||
sendXferComplete();
|
||||
powerDown(INIT_RADIO);
|
||||
wdt60s();
|
||||
eepromReadStart(EEPROM_UPDATA_AREA_START);
|
||||
selfUpdate();
|
||||
break;
|
||||
}
|
||||
}
|
||||
while (curDataInfo.dataSize) {
|
||||
wdt10s();
|
||||
static uint16_t __xdata dataRequestSize;
|
||||
if (curDataInfo.dataSize > BLOCK_DATA_SIZE) {
|
||||
// more than one block remaining
|
||||
dataRequestSize = BLOCK_DATA_SIZE;
|
||||
} else {
|
||||
// incomplete block, wrap around and get the rest of the block...
|
||||
// only one block remains
|
||||
dataRequestSize = curDataInfo.dataSize;
|
||||
}
|
||||
} // end download while loop
|
||||
if (getDataBlock(dataRequestSize)) {
|
||||
// succesfully downloaded datablock, save to eeprom
|
||||
powerUp(INIT_EEPROM);
|
||||
saveUpdateBlockData(curBlock.blockId);
|
||||
powerDown(INIT_EEPROM);
|
||||
curBlock.blockId++;
|
||||
curDataInfo.dataSize -= dataRequestSize;
|
||||
} else {
|
||||
// failed to get the block we wanted, we'll stop for now, maybe resume later
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// no more data, download complete
|
||||
return true;
|
||||
}
|
||||
bool downloadImageData(struct AvailDataInfo *__xdata avail) {
|
||||
static uint16_t __xdata imageSize = 0;
|
||||
// check if we already started the transfer of this information & haven't completed it
|
||||
if (xMemEqual((const void *__xdata) & avail->dataVer, (const void *__xdata) & curDataInfo.dataVer, 8) && curDataInfo.dataSize) {
|
||||
// looks like we did. We'll carry on where we left off.
|
||||
pr("restarting image download");
|
||||
} else {
|
||||
// go to the next image slot
|
||||
nextImgSlot++;
|
||||
if (nextImgSlot >= imgSlots) nextImgSlot = 0;
|
||||
curImgSlot = nextImgSlot;
|
||||
drawWithLut = avail->dataTypeArgument;
|
||||
eepromErase(getAddressForSlot(curImgSlot), EEPROM_IMG_EACH / EEPROM_ERZ_SECTOR_SZ);
|
||||
pr("new download, writing to slot %d\n", curImgSlot);
|
||||
|
||||
// start, or restart the transfer. Copy data from the AvailDataInfo struct, and the struct intself. This forces a new transfer
|
||||
curBlock.blockId = 0;
|
||||
xMemCopy8(&(curBlock.ver), &(avail->dataVer));
|
||||
curBlock.type = avail->dataType;
|
||||
xMemCopyShort(&curDataInfo, (void *)avail, sizeof(struct AvailDataInfo));
|
||||
imageSize = curDataInfo.dataSize;
|
||||
}
|
||||
|
||||
while (curDataInfo.dataSize) {
|
||||
wdt10s();
|
||||
static uint16_t __xdata dataRequestSize;
|
||||
if (curDataInfo.dataSize > BLOCK_DATA_SIZE) {
|
||||
// more than one block remaining
|
||||
dataRequestSize = BLOCK_DATA_SIZE;
|
||||
} else {
|
||||
// only one block remains
|
||||
dataRequestSize = curDataInfo.dataSize;
|
||||
}
|
||||
if (getDataBlock(dataRequestSize)) {
|
||||
// succesfully downloaded datablock, save to eeprom
|
||||
powerUp(INIT_EEPROM);
|
||||
saveImgBlockData(curImgSlot, curBlock.blockId);
|
||||
curBlock.blockId++;
|
||||
curDataInfo.dataSize -= dataRequestSize;
|
||||
} else {
|
||||
// failed to get the block we wanted, we'll stop for now, probably resume later
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// borrow the blockXferBuffer temporarily
|
||||
struct EepromImageHeader __xdata *eih = (struct EepromImageHeader __xdata *)blockXferBuffer;
|
||||
xMemCopy8(&eih->version, &curDataInfo.dataVer);
|
||||
eih->validMarker = EEPROM_IMG_VALID;
|
||||
eih->id = ++curHighSlotId;
|
||||
eih->size = imageSize;
|
||||
eih->dataType = curDataInfo.dataType;
|
||||
eepromWrite(getAddressForSlot(curImgSlot), eih, sizeof(struct EepromImageHeader));
|
||||
|
||||
powerUp(INIT_RADIO);
|
||||
sendXferComplete();
|
||||
powerDown(INIT_RADIO);
|
||||
// no more data, download complete
|
||||
return true;
|
||||
}
|
||||
|
||||
bool processAvailDataInfo(struct AvailDataInfo *__xdata avail) {
|
||||
powerUp(INIT_EEPROM | INIT_UART | INIT_GPIO);
|
||||
switch (avail->dataType) {
|
||||
case DATATYPE_IMG_BMP:
|
||||
case DATATYPE_IMG_DIFF:
|
||||
case DATATYPE_IMG_RAW_1BPP:
|
||||
case DATATYPE_IMG_RAW_2BPP:
|
||||
// check if this download is currently displayed or active
|
||||
if (curDataInfo.dataSize == 0 && xMemEqual((const void *__xdata) & avail->dataVer, (const void *__xdata) & curDataInfo.dataVer, 8)) {
|
||||
// we've downloaded this already, we're guessing it's already displayed
|
||||
pr("currently shown image, send xfc\n");
|
||||
powerUp(INIT_RADIO);
|
||||
sendXferComplete();
|
||||
powerDown(INIT_RADIO);
|
||||
return true;
|
||||
}
|
||||
|
||||
// check if we've seen this version before
|
||||
powerUp(INIT_EEPROM);
|
||||
curImgSlot = findSlot(&(avail->dataVer));
|
||||
if (curImgSlot != 0xFF) {
|
||||
// found a (complete)valid image slot for this version
|
||||
powerUp(INIT_RADIO);
|
||||
sendXferComplete();
|
||||
powerDown(INIT_RADIO);
|
||||
|
||||
pr("already seen, drawing from eeprom slot %d\n", curImgSlot);
|
||||
|
||||
// mark as completed and draw from EEPROM
|
||||
xMemCopyShort(&curDataInfo, (void *)avail, sizeof(struct AvailDataInfo));
|
||||
curDataInfo.dataSize = 0; // mark as transfer not pending
|
||||
|
||||
drawWithLut = avail->dataTypeArgument;
|
||||
wdt60s();
|
||||
drawImageFromEeprom(curImgSlot);
|
||||
return true;
|
||||
} else {
|
||||
drawWithLut = avail->dataTypeArgument;
|
||||
// not found in cache, prepare to download
|
||||
downloadImageData(avail);
|
||||
drawImageFromEeprom(curImgSlot);
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case DATATYPE_FW_UPDATE:
|
||||
powerUp(INIT_EEPROM);
|
||||
if (downloadFWUpdate(avail)) {
|
||||
pr("firmware download complete, doing update.\n");
|
||||
|
||||
powerUp(INIT_EPD);
|
||||
showApplyUpdate();
|
||||
|
||||
powerUp(INIT_RADIO);
|
||||
sendXferComplete();
|
||||
powerDown(INIT_RADIO);
|
||||
|
||||
wdt60s();
|
||||
eepromReadStart(EEPROM_UPDATA_AREA_START);
|
||||
selfUpdate();
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -16,8 +16,8 @@ extern void killRadio(void);
|
||||
|
||||
extern struct AvailDataInfo *__xdata getAvailDataInfo();
|
||||
extern struct AvailDataInfo *__xdata getShortAvailDataInfo();
|
||||
extern void drawImageFromEeprom();
|
||||
extern bool doDataDownload(struct AvailDataInfo *__xdata avail);
|
||||
extern void drawImageFromEeprom(uint8_t imgSlot);
|
||||
extern bool processAvailDataInfo(struct AvailDataInfo *__xdata avail);
|
||||
extern void initializeProto();
|
||||
extern uint8_t detectAP(uint8_t channel);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user