mirror of
https://github.com/OpenEPaperLink/OpenEPaperLink.git
synced 2026-03-21 03:04:25 +01:00
Fixed M2 0024 issue->0025
This commit is contained in:
BIN
binaries/Tag/SOLUM_154_SSD1619-00-0025.bin
Normal file
BIN
binaries/Tag/SOLUM_154_SSD1619-00-0025.bin
Normal file
Binary file not shown.
BIN
binaries/Tag/SOLUM_29_BW_LOWTEMP-21-0025.bin
Normal file
BIN
binaries/Tag/SOLUM_29_BW_LOWTEMP-21-0025.bin
Normal file
Binary file not shown.
BIN
binaries/Tag/SOLUM_29_SSD1619-01-0025.bin
Normal file
BIN
binaries/Tag/SOLUM_29_SSD1619-01-0025.bin
Normal file
Binary file not shown.
BIN
binaries/Tag/SOLUM_29_UC8151-11-0025.bin
Normal file
BIN
binaries/Tag/SOLUM_29_UC8151-11-0025.bin
Normal file
Binary file not shown.
BIN
binaries/Tag/SOLUM_42_SSD1619-02-0025.bin
Normal file
BIN
binaries/Tag/SOLUM_42_SSD1619-02-0025.bin
Normal file
Binary file not shown.
@@ -12,30 +12,18 @@
|
||||
#include "screen.h"
|
||||
#include "timer.h"
|
||||
#include "userinterface.h" // for addIcons
|
||||
#include <stdlib.h>
|
||||
|
||||
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();
|
||||
}
|
||||
@@ -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();
|
||||
|
||||
@@ -3,15 +3,15 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#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
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -8,9 +8,7 @@
|
||||
#include "cpu.h"
|
||||
#include "wdt.h"
|
||||
#include "i2c.h"
|
||||
|
||||
//extern uint8_t __xdata* tempBuffer;
|
||||
uint8_t __xdata tempBuffer[320];
|
||||
#include <stdlib.h>
|
||||
|
||||
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++;
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
#include "timer.h"
|
||||
#include "wdt.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#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();
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -4,321 +4,299 @@
|
||||
#include "printf.h"
|
||||
#include "board.h"
|
||||
#include "cpu.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
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;
|
||||
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);
|
||||
eepromPrvSelect();
|
||||
eepromByte(0x03);
|
||||
eepromByte(addr >> 16);
|
||||
eepromByte(addr >> 8);
|
||||
eepromByte(addr & 0xff);
|
||||
|
||||
while (len--)
|
||||
*dst++ = eepromByte(0);
|
||||
eepromPrvDeselect();
|
||||
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;
|
||||
static bool eepromPrvBusyWait(void) {
|
||||
uint8_t val;
|
||||
|
||||
eepromPrvSelect();
|
||||
eepromByte(0x05);
|
||||
while ((val = eepromByte(0x00)) & 1);
|
||||
eepromPrvDeselect();
|
||||
eepromPrvSelect();
|
||||
eepromByte(0x05);
|
||||
while ((val = eepromByte(0x00)) & 1)
|
||||
;
|
||||
eepromPrvDeselect();
|
||||
|
||||
return true;
|
||||
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;
|
||||
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);
|
||||
eepromPrvSimpleCmd(0x06);
|
||||
|
||||
eepromPrvSelect();
|
||||
eepromByte(0x02);
|
||||
eepromByte(addr >> 16);
|
||||
eepromByte(addr >> 8);
|
||||
eepromByte(addr & 0xff);
|
||||
eepromPrvSelect();
|
||||
eepromByte(0x02);
|
||||
eepromByte(addr >> 16);
|
||||
eepromByte(addr >> 8);
|
||||
eepromByte(addr & 0xff);
|
||||
|
||||
while (len--)
|
||||
eepromByte(*src++);
|
||||
eepromPrvDeselect();
|
||||
while (len--)
|
||||
eepromByte(*src++);
|
||||
eepromPrvDeselect();
|
||||
|
||||
return eepromPrvBusyWait();
|
||||
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;
|
||||
__bit eepromInit(void) {
|
||||
uint8_t __xdata buf[8];
|
||||
uint8_t i, nParamHdrs;
|
||||
uint8_t __xdata *tempBufferE = malloc(320);
|
||||
|
||||
eepromPrvWakeFromPowerdown();
|
||||
eepromPrvWakeFromPowerdown();
|
||||
|
||||
//process SFDP
|
||||
// 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");
|
||||
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;
|
||||
__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;
|
||||
// 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;
|
||||
case 0x12: // MX25V4005
|
||||
mEepromSize = 0x00080000ul;
|
||||
break;
|
||||
|
||||
default:
|
||||
valid = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
eepromPrvDeselect();
|
||||
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--;
|
||||
|
||||
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;
|
||||
|
||||
//now we need to find the JEDEC parameter table header
|
||||
for (i = 0; i <= nParamHdrs; i++) {
|
||||
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;
|
||||
}
|
||||
|
||||
eepromPrvSfdpRead(mathPrvMul8x8(i, 8) + 8, buf, 8);
|
||||
if (buf[0] == 0x00 && buf[2] == 0x01 && buf[3] >= 9) {
|
||||
if (!tempBufferE[1] || tempBufferE[1] == 0xff) {
|
||||
pr("SFDP: 4K ERZ opcode invalid\n");
|
||||
break;
|
||||
}
|
||||
mOpcodeErz4K = tempBufferE[1];
|
||||
|
||||
uint8_t j;
|
||||
if (tempBufferE[7] & 0x80) {
|
||||
pr("SFDP: device too big\n");
|
||||
break;
|
||||
} else {
|
||||
uint8_t t;
|
||||
|
||||
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 (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;
|
||||
}
|
||||
|
||||
if (!tempBufferE[1] || tempBufferE[1] == 0xff) {
|
||||
pr("SFDP: 4K ERZ opcode invalid\n");
|
||||
break;
|
||||
}
|
||||
mOpcodeErz4K = tempBufferE[1];
|
||||
while (t) {
|
||||
mEepromSize <<= 1;
|
||||
t >>= 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (tempBufferE[7] & 0x80) {
|
||||
// get erase opcodes
|
||||
for (j = 0x1c; j < 0x24; j += 2) {
|
||||
uint8_t instr = tempBufferE[j + 1];
|
||||
|
||||
pr("SFDP: device too big\n");
|
||||
break;
|
||||
}
|
||||
else {
|
||||
if (!instr || instr == 0xff)
|
||||
continue;
|
||||
|
||||
uint8_t t;
|
||||
switch (tempBufferE[j]) {
|
||||
case 0x0c:
|
||||
if (mOpcodeErz4K != instr) {
|
||||
pr("4K ERZ opcode disagreement\n");
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
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;
|
||||
}
|
||||
case 0x0f: // 32K erase
|
||||
mOpcodeErz32K = instr;
|
||||
break;
|
||||
|
||||
while (t) {
|
||||
mEepromSize <<= 1;
|
||||
t >>= 1;
|
||||
}
|
||||
}
|
||||
case 0x10: // 64K erase
|
||||
mOpcodeErz64K = instr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//get erase opcodes
|
||||
for (j = 0x1c; j < 0x24; j += 2) {
|
||||
uint8_t instr = tempBufferE[j + 1];
|
||||
/*
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
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;
|
||||
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) {
|
||||
while (len) {
|
||||
uint16_t lenNow = EEPROM_WRITE_PAGE_SZ - (addr & (EEPROM_WRITE_PAGE_SZ - 1));
|
||||
|
||||
uint16_t lenNow = EEPROM_WRITE_PAGE_SZ - (addr & (EEPROM_WRITE_PAGE_SZ - 1));
|
||||
if (lenNow > len)
|
||||
lenNow = len;
|
||||
|
||||
if (lenNow > len)
|
||||
lenNow = len;
|
||||
if (!eepromWriteLL(addr, src, lenNow))
|
||||
return false;
|
||||
|
||||
if (!eepromWriteLL(addr, src, lenNow))
|
||||
return false;
|
||||
|
||||
addr += lenNow;
|
||||
src += lenNow;
|
||||
len -= lenNow;
|
||||
}
|
||||
return true;
|
||||
addr += lenNow;
|
||||
src += lenNow;
|
||||
len -= lenNow;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool eepromErase(uint32_t addr, uint16_t nSec) __reentrant
|
||||
{
|
||||
uint8_t now;
|
||||
bool eepromErase(uint32_t addr, uint16_t nSec) __reentrant {
|
||||
uint8_t now;
|
||||
|
||||
if (((uint16_t)addr) & 0x0fff)
|
||||
return false;
|
||||
if (((uint16_t)addr) & 0x0fff)
|
||||
return false;
|
||||
|
||||
for (;nSec; nSec -= now) {
|
||||
for (; nSec; nSec -= now) {
|
||||
eepromPrvSimpleCmd(0x06);
|
||||
eepromPrvSelect();
|
||||
|
||||
eepromPrvSimpleCmd(0x06);
|
||||
eepromPrvSelect();
|
||||
if (nSec >= 16 && !(uint16_t)addr && mOpcodeErz64K) { // erase 64K
|
||||
|
||||
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(mOpcodeErz64K);
|
||||
now = 16;
|
||||
}
|
||||
else if (nSec >= 8 && !(((uint16_t)addr) & 0x7fff) && mOpcodeErz32K) { //erase 32K
|
||||
eepromByte(mOpcodeErz32K);
|
||||
now = 8;
|
||||
} else { // erase 4K
|
||||
|
||||
eepromByte(mOpcodeErz32K);
|
||||
now = 8;
|
||||
}
|
||||
else { //erase 4K
|
||||
eepromByte(mOpcodeErz4K);
|
||||
now = 1;
|
||||
}
|
||||
|
||||
eepromByte(mOpcodeErz4K);
|
||||
now = 1;
|
||||
}
|
||||
eepromByte(addr >> 16);
|
||||
eepromByte(addr >> 8);
|
||||
eepromByte(addr);
|
||||
eepromPrvDeselect();
|
||||
|
||||
eepromByte(addr >> 16);
|
||||
eepromByte(addr >> 8);
|
||||
eepromByte(addr);
|
||||
eepromPrvDeselect();
|
||||
if (!eepromPrvBusyWait())
|
||||
return false;
|
||||
|
||||
if (!eepromPrvBusyWait())
|
||||
return false;
|
||||
addr += mathPrvMul16x8(EEPROM_ERZ_SECTOR_SZ, now);
|
||||
}
|
||||
|
||||
addr += mathPrvMul16x8(EEPROM_ERZ_SECTOR_SZ, now);
|
||||
}
|
||||
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
void eepromOtpModeEnter(void)
|
||||
{
|
||||
eepromPrvSimpleCmd(0xb1);
|
||||
void eepromOtpModeEnter(void) {
|
||||
eepromPrvSimpleCmd(0xb1);
|
||||
}
|
||||
|
||||
void eepromOtpModeExit(void)
|
||||
{
|
||||
eepromPrvSimpleCmd(0xc1);
|
||||
void eepromOtpModeExit(void) {
|
||||
eepromPrvSimpleCmd(0xc1);
|
||||
}
|
||||
Reference in New Issue
Block a user