diff --git a/binaries/Tag/SOLUM_154_SSD1619-00-0025.bin b/binaries/Tag/SOLUM_154_SSD1619-00-0025.bin new file mode 100644 index 00000000..ff0928dd Binary files /dev/null and b/binaries/Tag/SOLUM_154_SSD1619-00-0025.bin differ diff --git a/binaries/Tag/SOLUM_29_BW_LOWTEMP-21-0025.bin b/binaries/Tag/SOLUM_29_BW_LOWTEMP-21-0025.bin new file mode 100644 index 00000000..71c50c79 Binary files /dev/null and b/binaries/Tag/SOLUM_29_BW_LOWTEMP-21-0025.bin differ diff --git a/binaries/Tag/SOLUM_29_SSD1619-01-0025.bin b/binaries/Tag/SOLUM_29_SSD1619-01-0025.bin new file mode 100644 index 00000000..12a55c87 Binary files /dev/null and b/binaries/Tag/SOLUM_29_SSD1619-01-0025.bin differ diff --git a/binaries/Tag/SOLUM_29_UC8151-11-0025.bin b/binaries/Tag/SOLUM_29_UC8151-11-0025.bin new file mode 100644 index 00000000..97925a7d Binary files /dev/null and b/binaries/Tag/SOLUM_29_UC8151-11-0025.bin differ diff --git a/binaries/Tag/SOLUM_42_SSD1619-02-0025.bin b/binaries/Tag/SOLUM_42_SSD1619-02-0025.bin new file mode 100644 index 00000000..b487cb45 Binary files /dev/null and b/binaries/Tag/SOLUM_42_SSD1619-02-0025.bin differ diff --git a/zbs243_Tag_FW/drawing.c b/zbs243_Tag_FW/drawing.c index 09cf0027..5443ddea 100755 --- a/zbs243_Tag_FW/drawing.c +++ b/zbs243_Tag_FW/drawing.c @@ -12,30 +12,18 @@ #include "screen.h" #include "timer.h" #include "userinterface.h" // for addIcons +#include -extern uint8_t blockbuffer[]; +uint8_t __xdata* drawBuffer; -#if (SCREEN_WIDTH == 152) -void drawImageFromBuffer(uint8_t* buffer, const uint8_t lut) { - 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++) { - epdSend(buffer[c]); - } - epdDeselect(); - endWriteFramebuffer(); - addOverlay(); - drawWithSleep(); -} -#endif void drawImageAtAddress(uint32_t addr, uint8_t lut) { - struct EepromImageHeader* __xdata eih = (struct EepromImageHeader*)blockbuffer; - eepromRead(addr, blockbuffer, sizeof(struct EepromImageHeader)); + drawBuffer = malloc(512); + if (!drawBuffer) { + pr("malloc during draw failed..\n"); + return; + } + struct EepromImageHeader* __xdata eih = (struct EepromImageHeader*)drawBuffer; + eepromRead(addr, drawBuffer, sizeof(struct EepromImageHeader)); switch (eih->dataType) { case DATATYPE_IMG_RAW_1BPP: pr("Doing raw 1bpp\n"); @@ -46,12 +34,12 @@ void drawImageAtAddress(uint32_t addr, uint8_t lut) { beginWriteFramebuffer(EPD_COLOR_BLACK); epdSelect(); for (uint16_t c = 0; c < (SCREEN_HEIGHT * (SCREEN_WIDTH / 8)); c++) { - if (c % 256 == 0) { + if (c % 512 == 0) { epdDeselect(); - eepromRead(addr + sizeof(struct EepromImageHeader) + c, blockbuffer, 256); + eepromRead(addr + sizeof(struct EepromImageHeader) + c, drawBuffer, 512); epdSelect(); } - epdSend(blockbuffer[c % 256]); + epdSend(drawBuffer[c % 512]); } epdDeselect(); endWriteFramebuffer(); @@ -64,12 +52,12 @@ void drawImageAtAddress(uint32_t addr, uint8_t lut) { beginWriteFramebuffer(EPD_COLOR_BLACK); epdSelect(); for (uint16_t c = 0; c < (SCREEN_HEIGHT * (SCREEN_WIDTH / 8)); c++) { - if (c % 256 == 0) { + if (c % 512 == 0) { epdDeselect(); - eepromRead(addr + sizeof(struct EepromImageHeader) + c, blockbuffer, 256); + eepromRead(addr + sizeof(struct EepromImageHeader) + c, drawBuffer, 512); epdSelect(); } - epdSend(blockbuffer[c % 256]); + epdSend(drawBuffer[c % 512]); } epdDeselect(); endWriteFramebuffer(); @@ -77,20 +65,22 @@ void drawImageAtAddress(uint32_t addr, uint8_t lut) { beginWriteFramebuffer(EPD_COLOR_RED); epdSelect(); for (uint16_t c = 0; c < (SCREEN_HEIGHT * (SCREEN_WIDTH / 8)); c++) { - if (c % 256 == 0) { + if (c % 512 == 0) { epdDeselect(); - eepromRead(addr + sizeof(struct EepromImageHeader) + (SCREEN_HEIGHT * (SCREEN_WIDTH / 8)) + c, blockbuffer, 256); + eepromRead(addr + sizeof(struct EepromImageHeader) + (SCREEN_HEIGHT * (SCREEN_WIDTH / 8)) + c, drawBuffer, 512); epdSelect(); } - epdSend(blockbuffer[c % 256]); + epdSend(drawBuffer[c % 512]); } epdDeselect(); endWriteFramebuffer(); break; default: // prevent drawing from an unknown file image type pr("Image with type 0x%02X was requested, but we don't know what to do with that currently...\n", eih->dataType); + free(drawBuffer); return; } + free(drawBuffer); addOverlay(); drawWithSleep(); } \ No newline at end of file diff --git a/zbs243_Tag_FW/main.c b/zbs243_Tag_FW/main.c index 74bfb701..9ea75dd9 100755 --- a/zbs243_Tag_FW/main.c +++ b/zbs243_Tag_FW/main.c @@ -41,7 +41,7 @@ uint8_t __xdata slideShowCurrentImg = 0; uint8_t __xdata slideShowRefreshCount = 1; extern uint8_t *__idata blockp; -extern uint8_t blockbuffer[]; +extern uint8_t __xdata blockbuffer[]; uint8_t *rebootP; #ifdef ENABLE_EEPROM_LOADER @@ -673,14 +673,24 @@ void main() { pr("%02X%02X", mSelfMac[4], mSelfMac[5]); pr("%02X%02X\n", mSelfMac[6], mSelfMac[7]); + for (uint16_t c = 0; c < 4096; c++) { + blockbuffer[c] = (c % 256) & 0xFF; + } + // do a little sleep, this prevents a partial boot during battery insertion - doSleep(200UL); - powerUp(INIT_EEPROM); + doSleep(2000UL); + powerUp(INIT_EEPROM | INIT_UART); + + uint8_t __idata dati; + pr("blockbuffer @%d, idata@%d\n",&blockbuffer[0], &dati); + dump(blockbuffer, 4096); + // load settings from infopage loadSettings(); // invalidate the settings, and write them back in a later state invalidateSettingsEEPROM(); + #ifdef WRITE_MAC_FROM_FLASH if (mSelfMac[7] == 0xFF && mSelfMac[6] == 0xFF) { wdt10s(); diff --git a/zbs243_Tag_FW/settings.h b/zbs243_Tag_FW/settings.h index a5114263..362d62ab 100755 --- a/zbs243_Tag_FW/settings.h +++ b/zbs243_Tag_FW/settings.h @@ -3,15 +3,15 @@ #include -#define FW_VERSION 0x0024 // version number -#define FW_VERSION_SUFFIX "-SET" // suffix, like -RC1 or whatever. +#define FW_VERSION 0x0025 // version number +#define FW_VERSION_SUFFIX "-FIX3" // suffix, like -RC1 or whatever. // #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 // #define ENABLE_EEPROM_LOADER // uncomment if you want to load eeprom images via the serial interface -#define ENABLE_GPIO_WAKE // uncomment to enable GPIO wake -// #define ENABLE_RETURN_DATA // enables the tag to send blocks of data back. Enabling this costs about 4 IRAM bytes -// #define LEAN_VERSION // makes a smaller version, leaving extra flash space for other things -// #define WRITE_MAC_FROM_FLASH // takes mac address from flash if none is set in the infopage +// #define ENABLE_GPIO_WAKE // uncomment to enable GPIO wake +// #define ENABLE_RETURN_DATA // enables the tag to send blocks of data back. Enabling this costs about 4 IRAM bytes +// #define LEAN_VERSION // makes a smaller version, leaving extra flash space for other things +// #define WRITE_MAC_FROM_FLASH // takes mac address from flash if none is set in the infopage #define SETTINGS_STRUCT_VERSION 0x01 diff --git a/zbs243_Tag_FW/syncedproto.c b/zbs243_Tag_FW/syncedproto.c index 2867524b..d07b14e3 100755 --- a/zbs243_Tag_FW/syncedproto.c +++ b/zbs243_Tag_FW/syncedproto.c @@ -25,9 +25,10 @@ #include "timer.h" #include "userinterface.h" #include "wdt.h" +#include "uart.h" // download-stuff -uint8_t __xdata blockbuffer[BLOCK_XFER_BUFFER_SIZE]; +uint8_t __xdata blockbuffer[BLOCK_XFER_BUFFER_SIZE] = {0}; static struct blockRequest __xdata curBlock = {0}; // used by the block-requester, contains the next request that we'll send static uint8_t __xdata curDispDataVer[8] = {0}; static struct AvailDataInfo __xdata xferDataInfo = {0}; // holds the AvailDataInfo during the transfer @@ -98,6 +99,7 @@ void dump(const uint8_t *__xdata a, const uint16_t __xdata l) { pr("\n0x%04X | ", c); } pr("%02X ", a[c]); + UartTxWait(); } pr("\n--------"); for (uint8_t c = 0; c < ROWS; c++) { @@ -314,6 +316,10 @@ static bool processBlockPart(const struct blockPart *bp) { if ((start + size) > sizeof(blockbuffer)) { size = sizeof(blockbuffer) - start; } + + // check if we already processed this blockpart + if (!(curBlock.requestedParts[bp->blockPart / 8] & (1 << (bp->blockPart % 8)))) return false; + if (checkCRC(bp, sizeof(struct blockPart) + BLOCK_PART_DATA_SIZE)) { // copy block data to buffer xMemCopy((void *)(blockbuffer + start), (const void *)bp->data, size); @@ -620,7 +626,7 @@ static bool getDataBlock(const uint16_t blockSize) { } else { // immediately start with the reception of the block data } - blockRxLoop(270); // BLOCK RX LOOP - receive a block, until the timeout has passed + blockRxLoop(290); // BLOCK RX LOOP - receive a block, until the timeout has passed powerDown(INIT_RADIO); #ifdef DEBUGBLOCKS @@ -784,10 +790,12 @@ static bool downloadImageDataToEEPROM(const struct AvailDataInfo *__xdata avail) if (getDataBlock(dataRequestSize)) { // succesfully downloaded datablock, save to eeprom powerUp(INIT_EEPROM); + timerDelay(TIMER_TICKS_PER_MS * 100); #ifdef DEBUGBLOCKS pr("Saving block %d to slot %d\n", curBlock.blockId, xferImgSlot); #endif saveImgBlockData(xferImgSlot, curBlock.blockId); + timerDelay(TIMER_TICKS_PER_MS * 100); powerDown(INIT_EEPROM); curBlock.blockId++; xferDataInfo.dataSize -= dataRequestSize; @@ -895,10 +903,6 @@ inline bool processImageDataAvail(struct AvailDataInfo *__xdata avail) { powerUp(INIT_EPD | INIT_EEPROM); drawImageFromEeprom(findImgSlot, arg.lut); powerDown(INIT_EPD | INIT_EEPROM); - - //powerUp(INIT_EEPROM | INIT_EPD); - //powerDown(INIT_EEPROM | INIT_EPD); - } else { // not found in cache, prepare to download pr("downloading image...\n"); @@ -915,8 +919,6 @@ inline bool processImageDataAvail(struct AvailDataInfo *__xdata avail) { powerUp(INIT_EPD | INIT_EEPROM); drawImageFromEeprom(xferImgSlot, arg.lut); powerDown(INIT_EPD | INIT_EEPROM); - //powerUp(INIT_EEPROM | INIT_EPD); - //powerDown(INIT_EEPROM | INIT_EPD); } else { return false; } diff --git a/zbs243_Tag_FW/userinterface.c b/zbs243_Tag_FW/userinterface.c index 8c7bc43c..9a4e7882 100755 --- a/zbs243_Tag_FW/userinterface.c +++ b/zbs243_Tag_FW/userinterface.c @@ -24,11 +24,6 @@ #include "syncedproto.h" // for APmac / Channel #include "timer.h" -// extern uint8_t __xdata mSelfMac[8]; -// extern uint8_t __xdata currentChannel; -// extern uint8_t __xdata APmac[]; -// extern uint16_t __xdata batteryVoltage; - const uint16_t __code fwVersion = FW_VERSION; const char __code fwVersionSuffix[] = FW_VERSION_SUFFIX; @@ -156,8 +151,11 @@ void afterFlashScreenSaver() { epdPrintBegin(112, 293, EPD_DIRECTION_Y, EPD_SIZE_SINGLE, EPD_COLOR_BLACK); epdpr("openepaperlink.de"); epdPrintEnd(); - +#if (HW_TYPE == SOLUM_M2_BW_29_LOWTEMP) + epdPrintBegin(110, 155, EPD_DIRECTION_Y, EPD_SIZE_SINGLE, EPD_COLOR_BLACK); +#else epdPrintBegin(110, 155, EPD_DIRECTION_Y, EPD_SIZE_SINGLE, EPD_COLOR_RED); +#endif epdpr("%02X:%02X", mSelfMac[7], mSelfMac[6]); epdpr(":%02X:%02X", mSelfMac[5], mSelfMac[4]); epdpr(":%02X:%02X", mSelfMac[3], mSelfMac[2]); @@ -204,7 +202,11 @@ void afterFlashScreenSaver() { void showSplashScreen() { if (displayCustomImage(CUSTOM_IMAGE_SPLASHSCREEN)) return; powerUp(INIT_EPD); + + #if (HW_TYPE != SOLUM_M2_BW_29_LOWTEMP) selectLUT(EPD_LUT_NO_REPEATS); +#endif + clearScreen(); setColorMode(EPD_MODE_NORMAL, EPD_MODE_INVERT); @@ -335,7 +337,10 @@ void showAPFound() { clearScreen(); setColorMode(EPD_MODE_NORMAL, EPD_MODE_INVERT); + #if (HW_TYPE != SOLUM_M2_BW_29_LOWTEMP) selectLUT(1); +#endif + #if (SCREEN_WIDTH == 128) epdPrintBegin(0, 285, EPD_DIRECTION_Y, EPD_SIZE_DOUBLE, EPD_COLOR_BLACK); epdpr("Waiting for data..."); @@ -446,8 +451,10 @@ void showAPFound() { void showNoAP() { if (displayCustomImage(CUSTOM_IMAGE_NOAPFOUND)) return; powerUp(INIT_EPD | INIT_EEPROM); - + #if (HW_TYPE != SOLUM_M2_BW_29_LOWTEMP) selectLUT(EPD_LUT_NO_REPEATS); +#endif + setColorMode(EPD_MODE_NORMAL, EPD_MODE_INVERT); clearScreen(); #if (SCREEN_WIDTH == 128) // 2,9" @@ -604,8 +611,7 @@ bool displayCustomImage(uint8_t imagetype) { powerUp(INIT_EEPROM); uint8_t slot = findSlotDataTypeArg(imagetype << 3); if (slot != 0xFF) { - // found a slot for gpio button 1 - + // found a slot for a custom image type uint8_t lut = getEepromImageDataArgument(slot); lut &= 0x03; powerUp(INIT_EPD); diff --git a/zbs243_shared/board/boardZBS29common.c b/zbs243_shared/board/boardZBS29common.c index 80667c6c..a6a8b6ef 100644 --- a/zbs243_shared/board/boardZBS29common.c +++ b/zbs243_shared/board/boardZBS29common.c @@ -8,9 +8,7 @@ #include "cpu.h" #include "wdt.h" #include "i2c.h" - -//extern uint8_t __xdata* tempBuffer; -uint8_t __xdata tempBuffer[320]; +#include void powerPortsDownForSleep(void) { @@ -139,10 +137,14 @@ static uint32_t prvUpdateApplierGet(void) __naked void selfUpdate(void) { + + uint8_t __xdata *tempBuffer; + tempBuffer = malloc(320); uint32_t updaterInfo = prvUpdateApplierGet(); uint8_t __code *src = (uint8_t __code*)updaterInfo; uint8_t i, len = updaterInfo >> 16; uint8_t __xdata *dst = tempBuffer; + if(!tempBuffer)wdtDeviceReset(); for (i = len; i ; i--) *dst++ = *src++; diff --git a/zbs243_shared/board/ssd1619.c b/zbs243_shared/board/ssd1619.c index 7eb0275b..23e53e1e 100755 --- a/zbs243_shared/board/ssd1619.c +++ b/zbs243_shared/board/ssd1619.c @@ -17,6 +17,8 @@ #include "timer.h" #include "wdt.h" +#include + #define CMD_DRV_OUTPUT_CTRL 0x01 #define CMD_SOFT_START_CTRL 0x0C #define CMD_ENTER_SLEEP 0x10 @@ -72,8 +74,6 @@ P2_2 = 1; \ } while (0) -extern void dump(uint8_t* __xdata a, uint16_t __xdata l); // remove me when done - static uint8_t __xdata epdCharSize = 1; // character size, 1 or 2 (doubled) static bool __xdata directionY = true; // print direction, X or Y (true) static uint8_t __xdata rbuffer[32]; // used to rotate bits around @@ -87,11 +87,11 @@ static bool __xdata isInited = false; bool __xdata epdGPIOActive = false; #define LUT_BUFFER_SIZE 128 -static uint8_t waveformbuffer[LUT_BUFFER_SIZE]; uint8_t __xdata customLUT[LUT_BUFFER_SIZE] = {0}; -struct waveform10* __xdata waveform10 = (struct waveform10*)waveformbuffer; // holds the LUT/waveform -struct waveform* __xdata waveform7 = (struct waveform*)waveformbuffer; // holds the LUT/waveform +static uint8_t* waveformbuffer; +static struct waveform10* __xdata waveform10; +static struct waveform* __xdata waveform7; #pragma callee_saves epdBusySleep #pragma callee_saves epdBusyWait @@ -309,13 +309,6 @@ uint16_t epdGetBattery(void) { return voltage; } -void loadFixedTempOTPLUT() { - shortCommand1(0x18, 0x48); // external temp sensor - shortCommand2(0x1A, 0x05, 0x00); // < temp register - shortCommand1(CMD_DISP_UPDATE_CTRL2, 0xB1); // mode 1 (i2C) - shortCommand(CMD_ACTIVATION); - epdBusyWait(TIMER_TICKS_PER_SECOND); -} static void writeLut() { commandBegin(CMD_WRITE_LUT); for (uint8_t i = 0; i < (dispLutSize * 10); i++) @@ -397,6 +390,10 @@ void selectLUT(uint8_t lut) { return; } + waveformbuffer = malloc(150); + waveform10 = (struct waveform10*)waveformbuffer; // holds the LUT/waveform + waveform7 = (struct waveform*)waveformbuffer; // holds the LUT/waveform + // download the current LUT from the waveform buffer readLut(); @@ -444,7 +441,7 @@ void selectLUT(uint8_t lut) { break; } - // Handling if we received an OTA LUT + // Handling if we received an OTA LUT if (lut == EPD_LUT_OTA) { memcpy(waveformbuffer, customLUT, dispLutSize * 10); writeLut(); @@ -457,6 +454,7 @@ void selectLUT(uint8_t lut) { shortCommand1(CMD_DUMMY_PERIOD, customLUT[74]); shortCommand1(CMD_GATE_LINE_WIDTH, customLUT[75]); currentLut = lut; + free(waveformbuffer); return; } @@ -467,6 +465,7 @@ void selectLUT(uint8_t lut) { lutGroupDisable(LUTGROUP_UNUSED4); } writeLut(); + free(waveformbuffer); } void setWindowX(uint16_t start, uint16_t end) { @@ -474,7 +473,7 @@ void setWindowX(uint16_t start, uint16_t end) { } void setWindowY(uint16_t start, uint16_t end) { commandBegin(CMD_WINDOW_Y_SIZE); - epdSend((start)&0xff); + epdSend((start) & 0xff); epdSend((start) >> 8); epdSend((end - 1) & 0xff); epdSend((end - 1) >> 8); @@ -483,7 +482,7 @@ void setWindowY(uint16_t start, uint16_t end) { void setPosXY(uint16_t x, uint16_t y) { shortCommand1(CMD_XSTART_POS, (uint8_t)(x / 8)); commandBegin(CMD_YSTART_POS); - epdSend((y)&0xff); + epdSend((y) & 0xff); epdSend((y) >> 8); commandEnd(); } diff --git a/zbs243_shared/board/zbs29_BW_ssd1619/screen.c b/zbs243_shared/board/zbs29_BW_ssd1619/screen.c index 821ccb80..8cee3e06 100644 --- a/zbs243_shared/board/zbs29_BW_ssd1619/screen.c +++ b/zbs243_shared/board/zbs29_BW_ssd1619/screen.c @@ -233,6 +233,7 @@ void epdEnterSleep() { timerDelay(10); P2_0 = 1; timerDelay(50); + epdReset(); shortCommand(CMD_SOFT_RESET2); epdBusyWait(TIMER_TICKS_PER_MS * 15); shortCommand1(CMD_ENTER_SLEEP, 0x03); diff --git a/zbs243_shared/eeprom.c b/zbs243_shared/eeprom.c index ab01bbc7..0aeb77c1 100755 --- a/zbs243_shared/eeprom.c +++ b/zbs243_shared/eeprom.c @@ -4,321 +4,299 @@ #include "printf.h" #include "board.h" #include "cpu.h" +#include static uint32_t __xdata mEepromSize; static uint8_t __xdata mOpcodeErz4K = 0, mOpcodeErz32K = 0, mOpcodeErz64K = 0; -//extern uint8_t __xdata* tempBuffer; -uint8_t __xdata tempBufferE[320] = {0}; - -uint32_t eepromGetSize(void) -{ - return mEepromSize; +uint32_t eepromGetSize(void) { + return mEepromSize; } -void eepromReadStart(uint32_t addr) __reentrant -{ - eepromPrvSelect(); - eepromByte(0x03); - eepromByte(addr >> 16); - eepromByte(addr >> 8); - eepromByte(addr & 0xff); +void eepromReadStart(uint32_t addr) __reentrant { + eepromPrvSelect(); + eepromByte(0x03); + eepromByte(addr >> 16); + eepromByte(addr >> 8); + eepromByte(addr & 0xff); } -void eepromRead(uint32_t addr, void __xdata *dstP, uint16_t len) __reentrant -{ - uint8_t __xdata *dst = (uint8_t __xdata*)dstP; - - eepromPrvSelect(); - eepromByte(0x03); - eepromByte(addr >> 16); - eepromByte(addr >> 8); - eepromByte(addr & 0xff); - - while (len--) - *dst++ = eepromByte(0); - eepromPrvDeselect(); +void eepromRead(uint32_t addr, void __xdata *dstP, uint16_t len) __reentrant { + uint8_t __xdata *dst = (uint8_t __xdata *)dstP; + + eepromPrvSelect(); + eepromByte(0x03); + eepromByte(addr >> 16); + eepromByte(addr >> 8); + eepromByte(addr & 0xff); + + while (len--) + *dst++ = eepromByte(0); + eepromPrvDeselect(); } -static void eepromPrvSimpleCmd(uint8_t cmd) -{ - eepromPrvSelect(); - eepromByte(cmd); - eepromPrvDeselect(); +static void eepromPrvSimpleCmd(uint8_t cmd) { + eepromPrvSelect(); + eepromByte(cmd); + eepromPrvDeselect(); } -static bool eepromPrvBusyWait(void) -{ - uint8_t val; - - eepromPrvSelect(); - eepromByte(0x05); - while ((val = eepromByte(0x00)) & 1); - eepromPrvDeselect(); - - return true; +static bool eepromPrvBusyWait(void) { + uint8_t val; + + eepromPrvSelect(); + eepromByte(0x05); + while ((val = eepromByte(0x00)) & 1) + ; + eepromPrvDeselect(); + + return true; } -static bool eepromWriteLL(uint32_t addr, const void __xdata *srcP, uint16_t len) -{ - const uint8_t __xdata *src = (const uint8_t __xdata*)srcP; - - eepromPrvSimpleCmd(0x06); - - eepromPrvSelect(); - eepromByte(0x02); - eepromByte(addr >> 16); - eepromByte(addr >> 8); - eepromByte(addr & 0xff); - - while (len--) - eepromByte(*src++); - eepromPrvDeselect(); - - return eepromPrvBusyWait(); +static bool eepromWriteLL(uint32_t addr, const void __xdata *srcP, uint16_t len) { + const uint8_t __xdata *src = (const uint8_t __xdata *)srcP; + + eepromPrvSimpleCmd(0x06); + + eepromPrvSelect(); + eepromByte(0x02); + eepromByte(addr >> 16); + eepromByte(addr >> 8); + eepromByte(addr & 0xff); + + while (len--) + eepromByte(*src++); + eepromPrvDeselect(); + + return eepromPrvBusyWait(); } -void eepromDeepPowerDown(void) -{ - eepromPrvSimpleCmd(0xb9); +void eepromDeepPowerDown(void) { + eepromPrvSimpleCmd(0xb9); } -static void eepromPrvWakeFromPowerdown(void) -{ - eepromPrvSimpleCmd(0xab); +static void eepromPrvWakeFromPowerdown(void) { + eepromPrvSimpleCmd(0xab); } #pragma callee_saves eepromPrvSfdpRead -static void eepromPrvSfdpRead(uint16_t ofst, uint8_t __xdata *dst, uint8_t len) -{ - eepromPrvSelect(); - eepromByte(0x5a); //cmd - eepromByte(0); //addr - eepromByte(ofst >> 8); - eepromByte(ofst); - eepromByte(0x00); //dummy - while(len--) - *dst++ = eepromByte(0); - eepromPrvDeselect(); +static void eepromPrvSfdpRead(uint16_t ofst, uint8_t __xdata *dst, uint8_t len) { + eepromPrvSelect(); + eepromByte(0x5a); // cmd + eepromByte(0); // addr + eepromByte(ofst >> 8); + eepromByte(ofst); + eepromByte(0x00); // dummy + while (len--) + *dst++ = eepromByte(0); + eepromPrvDeselect(); } -__bit eepromInit(void) -{ - uint8_t __xdata buf[8]; - uint8_t i, nParamHdrs; - - eepromPrvWakeFromPowerdown(); - - //process SFDP - - eepromPrvSfdpRead(0, buf, 8); - if (buf[0] != 0x53 || buf[1] != 0x46 || buf[2] != 0x44 || buf[3] != 0x50 || buf[7] != 0xff) { - pr("SFDP: header not found\n"); - - __bit valid = false; - - //try manual ID for chips we know of - eepromPrvSelect(); - eepromByte(0x90); - eepromByte(0x00); - eepromByte(0x00); - eepromByte(0x00); - if (eepromByte(0) == 0xc2) { //old macronix chips - valid = true; - mOpcodeErz4K = 0x20; - switch (eepromByte(0)) { - case 0x05: //MX25V512 - mEepromSize = 0x00010000ul; - break; - - case 0x12: //MX25V4005 - mEepromSize = 0x00080000ul; - break; - - default: - valid = false; - break; - } - } - eepromPrvDeselect(); - - return valid; - } - if (buf[5] != 0x01) { - pr("SFDP: version wrong: %u.%d\n", buf[5], buf[4]); - return false; - } - nParamHdrs = buf[6]; - if (nParamHdrs == 0xff) //that case is very unlikely and we just do not care - nParamHdrs--; - - //now we need to find the JEDEC parameter table header - for (i = 0; i <= nParamHdrs; i++) { - - eepromPrvSfdpRead(mathPrvMul8x8(i, 8) + 8, buf, 8); - if (buf[0] == 0x00 && buf[2] == 0x01 && buf[3] >= 9) { - - uint8_t j; - - eepromPrvSfdpRead(*(uint16_t __xdata*)(buf + 4), tempBufferE, 9 * 4); - if ((tempBufferE[0] & 3) != 1) { - pr("SFDP: no 4K ERZ\n"); - break; - } - if (!(tempBufferE[0] & 0x04)) { - pr("SFDP: no large write buf\n"); - break; - } - if ((tempBufferE[2] & 0x06)) { - pr("SFDP: addr.len != 3\n"); - break; - } - - if (!tempBufferE[1] || tempBufferE[1] == 0xff) { - pr("SFDP: 4K ERZ opcode invalid\n"); - break; - } - mOpcodeErz4K = tempBufferE[1]; - - if (tempBufferE[7] & 0x80) { - - pr("SFDP: device too big\n"); - break; - } - else { - - uint8_t t; - - if (t = tempBufferE[7]) - mEepromSize = 0x00200000UL; - else if (t = tempBufferE[6]) - mEepromSize = 0x00002000UL; - else if (t = tempBufferE[5]) - mEepromSize = 0x00000020UL; - else { - pr("SFDP: device so small?!\n"); - break; - } - - while (t) { - mEepromSize <<= 1; - t >>= 1; - } - } - - //get erase opcodes - for (j = 0x1c; j < 0x24; j += 2) { - uint8_t instr = tempBufferE[j + 1]; - - if (!instr || instr == 0xff) - continue; - - switch (tempBufferE[j]) { - case 0x0c: - if (mOpcodeErz4K != instr) { - pr("4K ERZ opcode disagreement\n"); - return false; - } - break; - - case 0x0f: //32K erase - mOpcodeErz32K = instr; - break; - - case 0x10: //64K erase - mOpcodeErz64K = instr; - break; - } - } - - /* - pr("EEPROM accepted\n"); - pr(" ERZ opcodes: \n"); - if (mOpcodeErz4K) - pr(" 4K: %02xh\n", mOpcodeErz4K); - if (mOpcodeErz32K) - pr(" 32K: %02xh\n", mOpcodeErz32K); - if (mOpcodeErz64K) - pr(" 64K: %02xh\n", mOpcodeErz64K); - pr(" Size: 0x%*08lx\n", (uint16_t)&mEepromSize); - */ - return true; - } - } - - pr("SFDP: no JEDEC table of expected version found\n"); - return false; +__bit eepromInit(void) { + uint8_t __xdata buf[8]; + uint8_t i, nParamHdrs; + uint8_t __xdata *tempBufferE = malloc(320); + + eepromPrvWakeFromPowerdown(); + + // process SFDP + + eepromPrvSfdpRead(0, buf, 8); + if (buf[0] != 0x53 || buf[1] != 0x46 || buf[2] != 0x44 || buf[3] != 0x50 || buf[7] != 0xff) { + pr("SFDP: header not found\n"); + + __bit valid = false; + + // try manual ID for chips we know of + eepromPrvSelect(); + eepromByte(0x90); + eepromByte(0x00); + eepromByte(0x00); + eepromByte(0x00); + if (eepromByte(0) == 0xc2) { // old macronix chips + valid = true; + mOpcodeErz4K = 0x20; + switch (eepromByte(0)) { + case 0x05: // MX25V512 + mEepromSize = 0x00010000ul; + break; + + case 0x12: // MX25V4005 + mEepromSize = 0x00080000ul; + break; + + default: + valid = false; + break; + } + } + eepromPrvDeselect(); + free(tempBufferE); + return valid; + } + if (buf[5] != 0x01) { + pr("SFDP: version wrong: %u.%d\n", buf[5], buf[4]); + return false; + } + nParamHdrs = buf[6]; + if (nParamHdrs == 0xff) // that case is very unlikely and we just do not care + nParamHdrs--; + + // now we need to find the JEDEC parameter table header + for (i = 0; i <= nParamHdrs; i++) { + eepromPrvSfdpRead(mathPrvMul8x8(i, 8) + 8, buf, 8); + if (buf[0] == 0x00 && buf[2] == 0x01 && buf[3] >= 9) { + uint8_t j; + + eepromPrvSfdpRead(*(uint16_t __xdata *)(buf + 4), tempBufferE, 9 * 4); + if ((tempBufferE[0] & 3) != 1) { + pr("SFDP: no 4K ERZ\n"); + break; + } + if (!(tempBufferE[0] & 0x04)) { + pr("SFDP: no large write buf\n"); + break; + } + if ((tempBufferE[2] & 0x06)) { + pr("SFDP: addr.len != 3\n"); + break; + } + + if (!tempBufferE[1] || tempBufferE[1] == 0xff) { + pr("SFDP: 4K ERZ opcode invalid\n"); + break; + } + mOpcodeErz4K = tempBufferE[1]; + + if (tempBufferE[7] & 0x80) { + pr("SFDP: device too big\n"); + break; + } else { + uint8_t t; + + if (t = tempBufferE[7]) + mEepromSize = 0x00200000UL; + else if (t = tempBufferE[6]) + mEepromSize = 0x00002000UL; + else if (t = tempBufferE[5]) + mEepromSize = 0x00000020UL; + else { + pr("SFDP: device so small?!\n"); + break; + } + + while (t) { + mEepromSize <<= 1; + t >>= 1; + } + } + + // get erase opcodes + for (j = 0x1c; j < 0x24; j += 2) { + uint8_t instr = tempBufferE[j + 1]; + + if (!instr || instr == 0xff) + continue; + + switch (tempBufferE[j]) { + case 0x0c: + if (mOpcodeErz4K != instr) { + pr("4K ERZ opcode disagreement\n"); + return false; + } + break; + + case 0x0f: // 32K erase + mOpcodeErz32K = instr; + break; + + case 0x10: // 64K erase + mOpcodeErz64K = instr; + break; + } + } + + /* + pr("EEPROM accepted\n"); + pr(" ERZ opcodes: \n"); + if (mOpcodeErz4K) + pr(" 4K: %02xh\n", mOpcodeErz4K); + if (mOpcodeErz32K) + pr(" 32K: %02xh\n", mOpcodeErz32K); + if (mOpcodeErz64K) + pr(" 64K: %02xh\n", mOpcodeErz64K); + pr(" Size: 0x%*08lx\n", (uint16_t)&mEepromSize); + */ + free(tempBufferE); + return true; + } + } + + pr("SFDP: no JEDEC table of expected version found\n"); + return false; } -bool eepromWrite(uint32_t addr, const void __xdata *srcP, uint16_t len) __reentrant -{ - const uint8_t __xdata *src = (const uint8_t __xdata*)srcP; - - while (len) { - - uint16_t lenNow = EEPROM_WRITE_PAGE_SZ - (addr & (EEPROM_WRITE_PAGE_SZ - 1)); - - if (lenNow > len) - lenNow = len; - - if (!eepromWriteLL(addr, src, lenNow)) - return false; +bool eepromWrite(uint32_t addr, const void __xdata *srcP, uint16_t len) __reentrant { + const uint8_t __xdata *src = (const uint8_t __xdata *)srcP; - addr += lenNow; - src += lenNow; - len -= lenNow; - } - return true; + while (len) { + uint16_t lenNow = EEPROM_WRITE_PAGE_SZ - (addr & (EEPROM_WRITE_PAGE_SZ - 1)); + + if (lenNow > len) + lenNow = len; + + if (!eepromWriteLL(addr, src, lenNow)) + return false; + + addr += lenNow; + src += lenNow; + len -= lenNow; + } + return true; } -bool eepromErase(uint32_t addr, uint16_t nSec) __reentrant -{ - uint8_t now; - - if (((uint16_t)addr) & 0x0fff) - return false; - - for (;nSec; nSec -= now) { - - eepromPrvSimpleCmd(0x06); - eepromPrvSelect(); - - if (nSec >= 16 && !(uint16_t)addr && mOpcodeErz64K) { //erase 64K - - eepromByte(mOpcodeErz64K); - now = 16; - } - else if (nSec >= 8 && !(((uint16_t)addr) & 0x7fff) && mOpcodeErz32K) { //erase 32K - - eepromByte(mOpcodeErz32K); - now = 8; - } - else { //erase 4K - - eepromByte(mOpcodeErz4K); - now = 1; - } +bool eepromErase(uint32_t addr, uint16_t nSec) __reentrant { + uint8_t now; - eepromByte(addr >> 16); - eepromByte(addr >> 8); - eepromByte(addr); - eepromPrvDeselect(); - - if (!eepromPrvBusyWait()) - return false; - - addr += mathPrvMul16x8(EEPROM_ERZ_SECTOR_SZ, now); - } - - return true; + if (((uint16_t)addr) & 0x0fff) + return false; + + for (; nSec; nSec -= now) { + eepromPrvSimpleCmd(0x06); + eepromPrvSelect(); + + if (nSec >= 16 && !(uint16_t)addr && mOpcodeErz64K) { // erase 64K + + eepromByte(mOpcodeErz64K); + now = 16; + } else if (nSec >= 8 && !(((uint16_t)addr) & 0x7fff) && mOpcodeErz32K) { // erase 32K + + eepromByte(mOpcodeErz32K); + now = 8; + } else { // erase 4K + + eepromByte(mOpcodeErz4K); + now = 1; + } + + eepromByte(addr >> 16); + eepromByte(addr >> 8); + eepromByte(addr); + eepromPrvDeselect(); + + if (!eepromPrvBusyWait()) + return false; + + addr += mathPrvMul16x8(EEPROM_ERZ_SECTOR_SZ, now); + } + + return true; } -void eepromOtpModeEnter(void) -{ - eepromPrvSimpleCmd(0xb1); +void eepromOtpModeEnter(void) { + eepromPrvSimpleCmd(0xb1); } -void eepromOtpModeExit(void) -{ - eepromPrvSimpleCmd(0xc1); +void eepromOtpModeExit(void) { + eepromPrvSimpleCmd(0xc1); } \ No newline at end of file