M2 tag firmware v0024

This commit is contained in:
jjwbruijn
2023-12-09 01:07:27 +01:00
parent bb73069097
commit 60f9454bb2
20 changed files with 251 additions and 512 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -1,26 +1,30 @@
// TAG TYPES
// The 'OG' tags in OEPL (mostly M2 tags)
#define SOLUM_154_SSD1619 0
#define SOLUM_29_SSD1619 0x01
#define SOLUM_29_BW_SSD1619 0x21
#define SOLUM_29_UC8151 0x11
#define SOLUM_M2_BWR_29_UC8151 0x11
#define SOLUM_42_SSD1619 0x02
#define SOLUM_SEG_UK 0xF0
#define SOLUM_SEG_EU 0xF1
#define SOLUM_NODISPLAY 0xFF
#define ESP32_C6 0xC6
// M2 Tags, overflow
#define SOLUM_M2_BWR_16 0x20
#define SOLUM_M2_BW_29L 0x21
#define SOLUM_M2_BW_29_LOWTEMP 0x21 // low temperature version of the 2.9 M2 tag
#define SOLUM_M2_BWR_29 0x23
#define SOLUM_M2_BWR_42 0x24
#define SOLUM_M2_BWR_75 0x26
// M3 Tags
#define SOLUM_M3_BWR_16 0x30
#define SOLUM_M3_BWY_16 0x38
#define SOLUM_M3_BWR_22 0x31
#define SOLUM_M3_BWY_22 0x39
#define SOLUM_M3_BWR_26 0x32
#define SOLUM_M3_BWY_26 0x3A
#define SOLUM_M3_BWR_29 0x33
#define SOLUM_M3_BWR_29 0x33 // the 'standard' SSD1619 version
#define SOLUM_M3_BWY_29 0x3B
#define SOLUM_M3_BWR_42 0x34
#define SOLUM_M3_BWY_42 0x3C
@@ -31,10 +35,15 @@
#define SOLUM_M3_BWR_116 0x37
#define SOLUM_M3_BWY_116 0x3F
// M3 Tags overflow
#define SOLUM_M3_BWR_29_UC8151 0x40 // the UC8151 version of this M3 tag
// Hanshow Nebular types
#define HS_NEBULAR_BWY_35 0x60
#define HS_NEBULAR_BWR_35 0x61
#define HS_NEBULAR_BW_35 0x62
#define CAPABILITY_SUPPORTS_COMPRESSION 0x02
#define CAPABILITY_SUPPORTS_CUSTOM_LUTS 0x04
#define CAPABILITY_ALT_LUT_SIZE 0x08
@@ -44,12 +53,12 @@
#define CAPABILITY_NFC_WAKE 0x80
#define DATATYPE_NOUPDATE 0
#define DATATYPE_IMG_BMP 2
#define DATATYPE_IMG_BMP 2 // ** deprecated
#define DATATYPE_FW_UPDATE 3
#define DATATYPE_IMG_DIFF 0x10 // always 1BPP
#define DATATYPE_IMG_DIFF 0x10 // always 1BPP ** deprecated
#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"
#define DATATYPE_IMG_RAW_1BPP_DIRECT 0x3F // only for 1.54", don't write to EEPROM, but straightaway to the EPD
#define DATATYPE_IMG_RAW_1BPP_DIRECT 0x3F // only for 1.54", don't write to EEPROM, but straightaway to the EPD ** deprecated
#define DATATYPE_UK_SEGMENTED 0x51 // Segmented data for the UK Segmented display type (contained in availableData Reply)
#define DATATYPE_EU_SEGMENTED 0x52 // Segmented data for the EU/DE Segmented display type (contained in availableData Reply)
#define DATATYPE_NFC_RAW_CONTENT 0xA0 // raw memory content for the NT3H1101
@@ -81,7 +90,6 @@
#define WAKEUP_REASON_NETWORK_SCAN 0xFD
#define WAKEUP_REASON_WDT_RESET 0xFE
#define EPD_LUT_DEFAULT 0
#define EPD_LUT_NO_REPEATS 1
#define EPD_LUT_FAST_NO_REDS 2

View File

@@ -1,24 +1,34 @@
#!/bin/bash
make clean > /dev/null
VER=$(grep "#define FW_VERSION" settings.h | grep -v "suffix" | awk '{print $3}' | cut -c 3-)
echo "Building ZBS version ${VER}"
BINDIR="../binaries/Tag"
echo -e "\nBuilding 1.54 version..."
make BUILD=zbs154_ssd1619 CPU=8051 SOC=zbs243 > /dev/null
mv main.bin ../binaries/Tag_FW_1.54.bin -v
mv main.bin ${BINDIR}/SOLUM_154_SSD1619-00-${VER}.bin -v
make clean > /dev/null
echo -e "\n\nBuilding 2.9 (SSD1619) version..."
make BUILD=zbs29_ssd1619 CPU=8051 SOC=zbs243 > /dev/null
mv main.bin ../binaries/Tag_FW_2.9.bin -v
mv main.bin ${BINDIR}/SOLUM_29_SSD1619-01-${VER}.bin -v
make clean > /dev/null
echo -e "\n\nBuilding 4.2 version..."
make BUILD=zbs42_ssd1619 CPU=8051 SOC=zbs243 > /dev/null
mv main.bin ../binaries/Tag_FW_4.2.bin -v
mv main.bin ${BINDIR}/SOLUM_42_SSD1619-02-${VER}.bin -v
make clean > /dev/null
echo -e "\n\nBuilding 2.9 (UC8151) version..."
make BUILD=zbs29_uc8151 CPU=8051 SOC=zbs243 > /dev/null
mv main.bin ../binaries/Tag_FW_2.9-uc8151.bin -v
mv main.bin ${BINDIR}/SOLUM_29_UC8151-11-${VER}.bin -v
make clean > /dev/null
echo -e "\n\nBuilding 2.9 BW (SSD1619 - freezer) version..."
make BUILD=zbs29_BW_ssd1619 CPU=8051 SOC=zbs243 > /dev/null
mv main.bin ${BINDIR}/SOLUM_29_BW_LOWTEMP-21-${VER}.bin -v
make clean > /dev/null
php packagebinaries.php

View File

@@ -13,327 +13,8 @@
#include "timer.h"
#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
extern uint8_t blockbuffer[];
struct BitmapFileHeader {
uint8_t sig[2];
uint32_t fileSz;
uint8_t rfu[4];
uint32_t dataOfst;
uint32_t headerSz; // 40
int32_t width;
int32_t height;
uint16_t colorplanes; // must be one
uint16_t bpp;
uint32_t compression;
uint32_t dataLen; // may be 0
uint32_t pixelsPerMeterX;
uint32_t pixelsPerMeterY;
uint32_t numColors; // if zero, assume 2^bpp
uint32_t numImportantColors;
};
struct BitmapClutEntry {
uint8_t b, g, r, x;
};
struct BitmapDrawInfo {
// dimensions
uint16_t w, h, effectiveW, effectiveH, stride /* 0 -> 1, 5 - >7, 255 -> 256 */;
uint8_t numColorsM1;
// data start
uint32_t dataAddr;
// compression state
uint8_t packetPixelDivVal;
uint8_t packetNumPixels;
uint8_t packetBitSz;
uint8_t packetBitMask; // derived from the above
// flags
uint8_t bpp : 4;
uint8_t bottomUp : 1;
};
uint8_t __xdata mPassNo = 0;
static const uint8_t __code mColorMap[][6] = {
// colors are: B, DG, G, LG, W, R
// phase 0 (LUTS: B:W:R:G, purpose: BWR, prepare greys)
{1, 1, 1, 1, 0, 0}, // lo plane (B)
{0, 0, 0, 0, 0, 1} // hi plane (R)
};
static uint8_t __xdata mClutMap[256];
static struct BitmapDrawInfo __xdata mDrawInfo;
#pragma callee_saves drawPrvParseHeader
static uint32_t drawPrvParseHeader(uint32_t addr) // return clut addr or zero on error
{
struct BitmapFileHeader __xdata bmph;
uint16_t __xdata packetsPerRow;
addr += sizeof(struct EepromImageHeader);
eepromRead(addr, &bmph, sizeof(bmph));
if (bmph.sig[0] != 'B' || bmph.sig[1] != 'M')
goto fail;
if (bmph.colorplanes != 1)
goto fail;
if (u32minusU16(&bmph.headerSz, 40)) // < 40
goto fail;
if (bmph.bpp > 8)
goto fail;
mDrawInfo.bpp = bmph.bpp;
if (!u32minusU16(&bmph.headerSz, 257)) // >= 257
goto fail;
if (u32Nonzero(&bmph.numColors))
mDrawInfo.numColorsM1 = (uint8_t)bmph.numColors - (uint8_t)1;
else
mDrawInfo.numColorsM1 = (uint8_t)((uint8_t)1 << (uint8_t)mDrawInfo.bpp) - (uint8_t)1;
if (!u32Nonzero(&bmph.height))
goto fail;
if (u32minusU16(&bmph.width, 1) || !u32minusU16(&bmph.width, 0xffff))
goto fail;
mDrawInfo.w = bmph.width;
if (i32Negative(&bmph.height)) {
if (u32plusU16(&bmph.height, 0xffff)) // carries if val too negative
goto fail;
mDrawInfo.h = -bmph.height;
mDrawInfo.bottomUp = false;
} else {
if (!u32minusU16(&bmph.headerSz, 0xffff)) // no carry if val too big
goto fail;
mDrawInfo.h = bmph.height;
mDrawInfo.bottomUp = true;
}
if (bmph.compression) {
pr("compression is not supported ;(");
goto fail;
}
mDrawInfo.packetPixelDivVal = 0;
mDrawInfo.packetNumPixels = 1;
if (mDrawInfo.bpp > 1) {
mDrawInfo.packetBitSz = 2;
} else {
mDrawInfo.packetBitSz = 1; // mDrawInfo.bpp;
}
// mDrawInfo.stride = mathPrvDiv32x8(mathPrvMul16x8((mDrawInfo.w + mDrawInfo.packetNumPixels - 1), mDrawInfo.packetBitSz) + 31, 32) * 4UL;
// mDrawInfo.packetBitMask = (uint8_t)(((uint8_t)1) << (uint8_t)mDrawInfo.packetBitSz) - (uint8_t)1;
packetsPerRow = mathPrvDiv16x8(mDrawInfo.w + mDrawInfo.packetNumPixels - 1, mDrawInfo.packetNumPixels);
mDrawInfo.stride = mathPrvDiv32x8(mathPrvMul16x8(packetsPerRow, mDrawInfo.packetBitSz) + 31, 32) * 4UL;
mDrawInfo.packetBitMask = (uint8_t)(((uint8_t)1) << (uint8_t)mDrawInfo.packetBitSz) - (uint8_t)1;
// calc effective size
mDrawInfo.effectiveH = (mDrawInfo.h > SCREEN_HEIGHT) ? SCREEN_HEIGHT : mDrawInfo.h;
mDrawInfo.effectiveW = (mDrawInfo.w > SCREEN_WIDTH) ? SCREEN_WIDTH : mDrawInfo.w;
// calc addrs
mDrawInfo.dataAddr = addr + bmph.dataOfst;
return addr + bmph.dataOfst - sizeof(struct BitmapClutEntry) * (1 + mDrawInfo.numColorsM1);
// seriously, fuck SDCC
fail:
pr("Tried to parse the bmp header, didn't work...");
return 0;
}
#pragma callee_saves drawPrvLoadAndMapClut
static void drawPrvLoadAndMapClut(uint32_t clutAddr) {
struct BitmapClutEntry __xdata clut;
uint8_t __xdata i;
// convert clut to our understanding of color
i = 0;
do {
uint8_t __xdata entry;
eepromRead(clutAddr, &clut, sizeof(clut));
clutAddr += sizeof(struct BitmapClutEntry);
if (SCREEN_EXTRA_COLOR_INDEX >= 0 && clut.r == 0xff && (clut.g == 0xff || clut.g == 0) && clut.b == 0) // yellow/red
entry = SCREEN_EXTRA_COLOR_INDEX;
else {
uint16_t intensity = 0;
intensity += mathPrvMul8x8(0x37, clut.r);
intensity += mathPrvMul8x8(0xB7, clut.g);
intensity += mathPrvMul8x8(0x12, clut.b);
// adds up to 0xff00 -> fix it
intensity += (uint8_t)(intensity >> 8);
entry = mathPrvMul16x8(intensity, SCREEN_NUM_GREYS) >> 16;
entry += SCREEN_FIRST_GREY_IDX;
}
// pr("mapped clut %u (%d %d %d) -> %d\n", i, clut.r, clut.g, clut.b, entry);
mClutMap[i] = entry;
} while (i++ != mDrawInfo.numColorsM1);
// replicate clut down if not a full 256-entry clut
if (mDrawInfo.bpp != 8) {
uint8_t num = (uint8_t)((uint8_t)1 << (uint8_t)mDrawInfo.bpp);
// we can use the fact that our memcpy always copies forward
xMemCopyShort(mClutMap + num, mClutMap, (uint8_t)256 - (uint8_t)num);
}
}
#pragma callee_saves drawPrvDecodeImageOnce
static void drawPrvDecodeImageOnce(void) {
uint8_t __xdata rowBuf[SCREEN_WIDTH];
uint16_t __xdata er, c;
if (mDrawInfo.bottomUp)
er = mDrawInfo.effectiveH - 1;
else
er = 0;
while (1) { // we account differently for loop gets compiled worse
uint8_t __xdata inIdx = 0, bitpoolInUsed = 0, bitpoolIn = 0;
uint16_t __xdata nBytesOut = 0;
#if SCREEN_TX_BPP == 4
uint8_t __xdata txPrev = 0;
__bit emit = false;
#else
uint8_t __xdata bitpoolOutUsedUsed = 0;
uint16_t __xdata bitpoolOut = 0;
#endif
// get a row
epdDeselect();
eepromRead(mathPrvMul16x16(er, mDrawInfo.stride) + mDrawInfo.dataAddr, rowBuf, mDrawInfo.stride);
epdSelect();
// convert to our format
c = mDrawInfo.effectiveW;
do {
// uartTx('.');
uint8_t packet, packetIdx, packetMembers = mDrawInfo.packetNumPixels;
if (bitpoolInUsed >= mDrawInfo.packetBitSz) {
bitpoolInUsed -= mDrawInfo.packetBitSz;
packet = bitpoolIn >> bitpoolInUsed;
} else {
uint8_t __xdata packetBitSz = mDrawInfo.packetBitSz;
uint8_t __xdata t = rowBuf[inIdx++];
packet = (bitpoolIn << (packetBitSz - bitpoolInUsed)) | (t >> (8 - (packetBitSz - bitpoolInUsed)));
bitpoolInUsed += 8 - packetBitSz;
bitpoolIn = t;
}
packet &= mDrawInfo.packetBitMask;
// val is now a packet - unpack it
if (packetMembers > c)
packetMembers = c;
for (packetIdx = 0; packetIdx < packetMembers; packetIdx++) {
uint8_t __xdata val;
// extract
if (mDrawInfo.packetPixelDivVal) {
val = packet % mDrawInfo.packetPixelDivVal;
packet /= mDrawInfo.packetPixelDivVal;
} else
val = packet;
// map
val = mClutMap[val];
// get bits out
#if SCREEN_TX_BPP == 4
if (emit) {
emit = false;
ByteDecode(txPrev | val);
nBytesOut++;
txPrev = 0;
} else {
emit = true;
txPrev = val << 4;
}
#else
bitpoolOut <<= SCREEN_TX_BPP;
bitpoolOut |= val;
bitpoolOutUsedUsed += SCREEN_TX_BPP;
if (bitpoolOutUsedUsed >= 8) {
ByteDecode(bitpoolOut >> (bitpoolOutUsedUsed -= 8));
bitpoolOut &= (1 << bitpoolOutUsedUsed) - 1;
nBytesOut++;
}
#endif
}
c -= packetMembers;
} while (c);
#if SCREEN_TX_BPP == 4
if (emit) {
ByteDecode(txPrev);
nBytesOut++;
}
#else
if (bitpoolOutUsedUsed) {
ByteDecode(bitpoolOut);
nBytesOut++;
}
#endif
// if we did not produce enough bytes, do so
nBytesOut = ((long)SCREEN_WIDTH * SCREEN_TX_BPP + 7) / 8 - nBytesOut;
while (nBytesOut--)
ByteDecode(SCREEN_BYTE_FILL);
// update row
if (mDrawInfo.bottomUp) {
if (er)
er--;
else
break;
} else {
er++;
if (er == mDrawInfo.effectiveH)
break;
}
}
// fill the rest of the screen
for (er = mDrawInfo.effectiveH - SCREEN_HEIGHT; er; er--) {
for (c = ((long)SCREEN_WIDTH * SCREEN_TX_BPP + 7) / 8; c; c--) {
ByteDecode(SCREEN_BYTE_FILL);
}
}
}
static uint8_t __xdata prev, step = 0;
void ByteDecode(uint8_t byte) {
prev <<= 2;
prev |= (mColorMap[mPassNo][byte >> 4] << 1) | mColorMap[mPassNo][byte & 0x0f];
if (++step == 4) {
step = 0;
epdSend(prev);
}
}
#if (SCREEN_WIDTH == 152)
void drawImageFromBuffer(uint8_t* buffer, const uint8_t lut) {
pr("Doing raw 1bpp\n");
@@ -353,8 +34,8 @@ void drawImageFromBuffer(uint8_t* buffer, const uint8_t lut) {
}
#endif
void drawImageAtAddress(uint32_t addr, uint8_t lut) {
struct EepromImageHeader* __xdata eih = (struct EepromImageHeader*)mClutMap;
eepromRead(addr, mClutMap, sizeof(struct EepromImageHeader));
struct EepromImageHeader* __xdata eih = (struct EepromImageHeader*)blockbuffer;
eepromRead(addr, blockbuffer, sizeof(struct EepromImageHeader));
switch (eih->dataType) {
case DATATYPE_IMG_RAW_1BPP:
pr("Doing raw 1bpp\n");
@@ -367,10 +48,10 @@ void drawImageAtAddress(uint32_t addr, uint8_t lut) {
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);
eepromRead(addr + sizeof(struct EepromImageHeader) + c, blockbuffer, 256);
epdSelect();
}
epdSend(mClutMap[c % 256]);
epdSend(blockbuffer[c % 256]);
}
epdDeselect();
endWriteFramebuffer();
@@ -385,10 +66,10 @@ void drawImageAtAddress(uint32_t addr, uint8_t lut) {
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);
eepromRead(addr + sizeof(struct EepromImageHeader) + c, blockbuffer, 256);
epdSelect();
}
epdSend(mClutMap[c % 256]);
epdSend(blockbuffer[c % 256]);
}
epdDeselect();
endWriteFramebuffer();
@@ -398,41 +79,14 @@ void drawImageAtAddress(uint32_t addr, uint8_t lut) {
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);
eepromRead(addr + sizeof(struct EepromImageHeader) + (SCREEN_HEIGHT * (SCREEN_WIDTH / 8)) + c, blockbuffer, 256);
epdSelect();
}
epdSend(mClutMap[c % 256]);
epdSend(blockbuffer[c % 256]);
}
epdDeselect();
endWriteFramebuffer();
break;
case DATATYPE_IMG_BMP:;
uint32_t __xdata clutAddr;
pr("sending BMP 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;
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);
return;

View File

@@ -21,6 +21,8 @@
#include "userinterface.h"
#include "wdt.h"
#include "flash.h"
#include "uart.h"
#include "../oepl-definitions.h"
@@ -28,7 +30,7 @@
// #define DEBUG_MODE
static const uint64_t __code __at(0x008b) mVersionRom = 0x1000011300000000ull;
// static const uint64_t __code __at(0x008b) mVersionRom = 0x1000011300000000ull;
#define TAG_MODE_CHANSEARCH 0
#define TAG_MODE_ASSOCIATED 1
@@ -41,6 +43,7 @@ uint8_t __xdata slideShowRefreshCount = 1;
extern uint8_t *__idata blockp;
extern uint8_t blockbuffer[];
uint8_t *rebootP;
#ifdef ENABLE_EEPROM_LOADER
extern bool __idata serialBypassActive;
bool __xdata serialActive = false;
@@ -158,6 +161,51 @@ void displayLoop() {
wdtDeviceReset();
}
#ifdef WRITE_MAC_FROM_FLASH
void writeInfoPageWithMac() {
uint8_t *settemp = blockbuffer + 2048;
flashRead(FLASH_INFOPAGE_ADDR, (void *)blockbuffer, 1024);
flashRead(0xFC06, (void *)(settemp + 8), 4);
settemp[7] = 0x00;
settemp[6] = 0x00;
settemp[5] = settemp[8];
settemp[4] = settemp[9];
settemp[3] = settemp[10];
settemp[2] = settemp[11];
#if (HW_TYPE == SOLUM_29_SSD1619)
settemp[1] = 0x3B;
settemp[0] = 0x10;
#endif
#if (HW_TYPE == SOLUM_M2_BWR_29_UC8151)
settemp[1] = 0x3B;
settemp[0] = 0x30;
#endif
#if (HW_TYPE == SOLUM_154_SSD1619)
settemp[1] = 0x34;
settemp[0] = 0x10;
#endif
#if (HW_TYPE == SOLUM_42_SSD1619)
settemp[1] = 0x48;
settemp[0] = 0x10;
#endif
#if (HW_TYPE == SOLUM_M2_BW_29_LOWTEMP)
settemp[1] = 0x2D;
settemp[0] = 0x10;
#endif
uint8_t cksum = 0;
for (uint8_t c = 0; c < 8; c++) {
cksum ^= settemp[c];
cksum ^= settemp[c] >> 4;
}
settemp[0] += cksum & 0x0F;
memcpy((void *)(blockbuffer + 0x0010), (void *)settemp, 8);
flashErase(FLASH_INFOPAGE_ADDR + 1);
flashWrite(FLASH_INFOPAGE_ADDR, (void *)blockbuffer, 1024, false);
}
#endif
uint8_t channelSelect(uint8_t rounds) { // returns 0 if no accesspoints were found
powerUp(INIT_RADIO);
uint8_t __xdata result[16];
@@ -430,6 +478,7 @@ void TagChanSearch() {
}
}
#ifndef LEAN_VERSION
void TagSlideShow() {
currentChannel = 11; // suppress the no-rf image thing
displayCustomImage(CUSTOM_IMAGE_SPLASHSCREEN);
@@ -515,6 +564,7 @@ void TagShowWaitRFWake() {
powerDown(INIT_EEPROM);
wdtDeviceReset();
}
#endif
void executeCommand(uint8_t cmd) {
switch (cmd) {
@@ -543,6 +593,7 @@ void executeCommand(uint8_t cmd) {
eraseImageBlocks();
powerDown(INIT_EEPROM);
break;
#ifndef LEAN_VERSION
case CMD_ENTER_SLIDESHOW_FAST:
powerUp(INIT_EEPROM);
if (findSlotDataTypeArg(CUSTOM_IMAGE_SLIDESHOW << 3) == 0xFF) {
@@ -601,6 +652,7 @@ void executeCommand(uint8_t cmd) {
powerDown(INIT_EEPROM);
wdtDeviceReset();
break;
#endif
}
}
@@ -613,16 +665,45 @@ void main() {
// Find the reason why we're booting; is this a WDT?
wakeUpReason = getFirstWakeUpReason();
// get our own mac address. this is stored in Infopage at offset 0x10-onwards
// dump(blockbuffer, 1024);
// get our own mac address. this is stored in Infopage at offset 0x10-onwards
boardGetOwnMac(mSelfMac);
pr("MAC>%02X%02X", mSelfMac[0], mSelfMac[1]);
pr("%02X%02X", mSelfMac[2], mSelfMac[3]);
pr("%02X%02X", mSelfMac[4], mSelfMac[5]);
pr("%02X%02X\n", mSelfMac[6], mSelfMac[7]);
// do a little sleep, this prevents a partial boot during battery insertion
doSleep(200UL);
powerUp(INIT_EEPROM);
// 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();
timerDelay(TIMER_TICKS_PER_SECOND * 2);
writeInfoPageWithMac();
for (uint16_t c = 0xE800; c != 0; c += 1024) {
flashErase(c);
}
boardGetOwnMac(mSelfMac);
powerUp(INIT_UART | INIT_EEPROM | INIT_RADIO);
wdt120s();
powerDown(INIT_EEPROM | INIT_RADIO);
wdt120s();
powerUp(INIT_EPD);
afterFlashScreenSaver();
powerDown(INIT_EPD | INIT_UART);
while (1) {
doSleep(-1);
}
}
#endif
// get the highest slot number, number of slots
initializeProto();
powerDown(INIT_EEPROM);
@@ -630,6 +711,7 @@ void main() {
// detect button or jig
detectButtonOrJig();
#ifndef LEAN_VERSION
switch (tagSettings.customMode) {
case TAG_CUSTOM_MODE_WAIT_RFWAKE:
TagShowWaitRFWake();
@@ -643,6 +725,7 @@ void main() {
default:
break;
}
#endif
if (tagSettings.enableFastBoot) {
// Fastboot
@@ -682,9 +765,6 @@ void main() {
tagSettings.fastBootCapabilities = capabilities;
// now that we've collected all possible capabilities, save it to settings
powerUp(INIT_EEPROM);
writeSettings();
powerDown(INIT_EEPROM);
// scan for channels
wdt30s();
@@ -697,14 +777,25 @@ void main() {
// end of the fastboot option split
wdt10s();
powerUp(INIT_EPD);
if (currentChannel) {
showAPFound();
// write the settings to the eeprom
powerUp(INIT_EEPROM);
writeSettings();
powerDown(INIT_EEPROM);
initPowerSaving(INTERVAL_BASE);
currentTagMode = TAG_MODE_ASSOCIATED;
doSleep(5000UL);
} else {
showNoAP();
// write the settings to the eeprom
powerUp(INIT_EEPROM);
writeSettings();
powerDown(INIT_EEPROM);
initPowerSaving(INTERVAL_AT_MAX_ATTEMPTS);
currentTagMode = TAG_MODE_CHANSEARCH;
doSleep(120000UL);

View File

@@ -119,13 +119,13 @@ static void configSPI(const bool setup) {
static void configUART(const bool setup) {
if (uartActive == setup) return;
if (setup) {
P0FUNC |= (1 << 6)|(1<<7);
P0FUNC |= (1 << 6) | (1 << 7);
P0DIR &= ~(1 << 6);
P0DIR |= (1<<7);
P0DIR |= (1 << 7);
uartInit();
} else {
P0DIR |= (1 << 6);
P0FUNC &= ~((1 << 6)|(1<<7));
P0FUNC &= ~((1 << 6) | (1 << 7));
CLKEN &= ~(0x20);
}
uartActive = setup;
@@ -134,10 +134,15 @@ static void configUART(const bool setup) {
static void configEEPROM(const bool setup) {
if (setup == eepromActive) return;
if (setup) {
#ifdef EXTRA_EEPROM_LINES
P1FUNC &= ~(1 << 1) | (1 << 2) | (1 << 6);
P1DIR &= ~(1 << 1) | (1 << 2) | (1 << 6);
P1_6 = 1;
P1_2 = 1;
P1_2 = 1;
#else
P1FUNC &= ~(1 << 1);
P1DIR &= ~(1 << 1);
#endif
if (!eepromInit()) {
powerDown(INIT_RADIO);
powerUp(INIT_EPD);
@@ -289,7 +294,7 @@ void doSleep(const uint32_t __xdata t) {
uartActive = false;
eepromActive = false;
capabilities |= CAPABILITY_HAS_WAKE_BUTTON;
//capabilities |= CAPABILITY_HAS_WAKE_BUTTON;
if (capabilities & CAPABILITY_HAS_WAKE_BUTTON) {
// Button setup on TEST pin 1.0 (input pullup)
@@ -339,19 +344,18 @@ void doSleep(const uint32_t __xdata t) {
P0INTEN = 0;
switch (RADIO_Wake_Reason) {
case RADIO_WAKE_REASON_TIMER:
case RADIO_WAKE_REASON_RF:
wakeUpReason = WAKEUP_REASON_RF;
break;
case RADIO_WAKE_REASON_EXT:
if ((P1CHSTA & (1 << 0)) && (capabilities & CAPABILITY_HAS_WAKE_BUTTON)) {
wakeUpReason = WAKEUP_REASON_BUTTON1;
P1CHSTA &= ~(1 << 0);
}
if ((P0CHSTA & (1 << 7)) && (capabilities & CAPABILITY_HAS_WAKE_BUTTON)) {
wakeUpReason = WAKEUP_REASON_BUTTON2;
P0CHSTA &= ~(1 << 7);
}
if ((P1CHSTA & (1 << 3)) && (capabilities & CAPABILITY_NFC_WAKE)) {
wakeUpReason = WAKEUP_REASON_NFC;
P1CHSTA &= ~(1 << 3);
@@ -363,8 +367,9 @@ void doSleep(const uint32_t __xdata t) {
}
#endif
break;
case RADIO_WAKE_REASON_RF:
wakeUpReason = WAKEUP_REASON_RF;
case RADIO_WAKE_REASON_TIMER:
// this stops the compiler from whining about a conditional flow optimization
wakeUpReason = wakeUpReason;
break;
}
}

View File

@@ -1,14 +1,13 @@
#define __packed
#include "settings.h"
//#include <flash.h>
// #include <flash.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include "asmUtil.h"
#include "powermgt.h"
#include "printf.h"
@@ -17,6 +16,8 @@
#include "../oepl-definitions.h"
#include "../oepl-proto.h"
#define SETTINGS_MAGIC 0xABBA5AA5
struct tagsettings __xdata tagSettings = {0};
extern uint8_t __xdata blockbuffer[];
uint8_t* __xdata settingsTempBuffer = 1024 + blockbuffer;
@@ -44,7 +45,7 @@ void loadSettingsFromBuffer(uint8_t* p) {
break;
default:
pr("SETTINGS: received something we couldn't really process, version %d\n");
break;
break;
}
tagSettings.fastBootCapabilities = capabilities;
writeSettings();
@@ -66,9 +67,12 @@ static void upgradeSettings() {
}
void loadSettings() {
eepromRead(EEPROM_SETTINGS_AREA_START, (void*)settingsTempBuffer, sizeof(struct tagsettings));
eepromRead(EEPROM_SETTINGS_AREA_START + 4, (void*)settingsTempBuffer, sizeof(struct tagsettings));
memcpy((void*)&tagSettings, (void*)settingsTempBuffer, sizeof(struct tagsettings));
uint32_t __xdata valid = 0;
eepromRead(EEPROM_SETTINGS_AREA_START, (void*)&valid, 4);
xMemCopy((void*)tagSettings, (void*)settingsTempBuffer, sizeof(struct tagsettings));
if (tagSettings.settingsVer == 0xFF) {
if (tagSettings.settingsVer == 0xFF || valid != SETTINGS_MAGIC) {
// settings not set. load the defaults
loadDefaultSettings();
pr("SETTINGS: Loaded default settings\n");
@@ -90,6 +94,13 @@ void writeSettings() {
return;
}
eepromErase(EEPROM_SETTINGS_AREA_START, 1);
eepromWrite(EEPROM_SETTINGS_AREA_START, (void*)tagSettings, sizeof(tagSettings));
uint32_t __xdata valid = SETTINGS_MAGIC;
eepromWrite(EEPROM_SETTINGS_AREA_START, (void*)&valid, 4);
eepromWrite(EEPROM_SETTINGS_AREA_START + 4, (void*)&tagSettings, sizeof(tagSettings));
pr("SETTINGS: Updated settings in EEPROM\n");
}
void invalidateSettingsEEPROM() {
int32_t __xdata valid = 0x0000;
eepromWrite(EEPROM_SETTINGS_AREA_START, (void*)&valid, 4);
}

View File

@@ -3,13 +3,15 @@
#include <stdint.h>
#define FW_VERSION 23 // version number (max 2.5.5 :) )
#define FW_VERSION_SUFFIX "-HWI" // 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 FW_VERSION 0x0024 // version number
#define FW_VERSION_SUFFIX "-SET" // 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 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
@@ -43,4 +45,5 @@ void loadDefaultSettings();
void writeSettings();
void loadSettings();
void loadSettingsFromBuffer(uint8_t* p);
void invalidateSettingsEEPROM();
#endif

View File

@@ -27,7 +27,7 @@
#include "wdt.h"
// download-stuff
uint8_t __xdata blockbuffer[BLOCK_XFER_BUFFER_SIZE] = {0};
uint8_t __xdata blockbuffer[BLOCK_XFER_BUFFER_SIZE];
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
@@ -578,7 +578,7 @@ static bool getDataBlock(const uint16_t blockSize) {
memset(curBlock.requestedParts, 0xFF, BLOCK_REQ_PARTS_BYTES);
} else {
partsThisBlock = (sizeof(struct blockData) + blockSize) / BLOCK_PART_DATA_SIZE;
if (blockSize % BLOCK_PART_DATA_SIZE) partsThisBlock++;
if ((sizeof(struct blockData) + 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));
@@ -896,6 +896,9 @@ inline bool processImageDataAvail(struct AvailDataInfo *__xdata avail) {
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");
@@ -912,7 +915,8 @@ 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;
}
@@ -967,8 +971,7 @@ bool processAvailDataInfo(struct AvailDataInfo *__xdata avail) {
}
pr("NFC URL received\n");
/*
if (curDataInfo.dataSize == 0 && xMemEqual((const void *__xdata) & avail->dataVer, (const void *__xdata) & curDataInfo.dataVer, 8)) {
if (xferDataInfo.dataSize == 0 && xMemEqual((const void *__xdata) & avail->dataVer, (const void *__xdata) & xferDataInfo.dataVer, 8)) {
// we've already downloaded this NFC data, disregard and send XFC
pr("this was the same as the last transfer, disregard\n");
powerUp(INIT_RADIO);
@@ -979,11 +982,11 @@ bool processAvailDataInfo(struct AvailDataInfo *__xdata avail) {
curBlock.blockId = 0;
xMemCopy8(&(curBlock.ver), &(avail->dataVer));
curBlock.type = avail->dataType;
xMemCopyShort(&curDataInfo, (void *)avail, sizeof(struct AvailDataInfo));
xMemCopyShort(&xferDataInfo, (void *)avail, sizeof(struct AvailDataInfo));
uint16_t __xdata nfcsize = avail->dataSize;
wdt10s();
if (getDataBlock(avail->dataSize)) {
curDataInfo.dataSize = 0; // mark as transfer not pending
xferDataInfo.dataSize = 0; // mark as transfer not pending
powerUp(INIT_I2C);
if (avail->dataType == DATATYPE_NFC_URL_DIRECT) {
// only one URL (handle NDEF records on the tag)
@@ -992,7 +995,7 @@ bool processAvailDataInfo(struct AvailDataInfo *__xdata avail) {
// raw NFC data upload to the NFC IC
loadRawNTag(nfcsize);
}
timerDelay(13330);
timerDelay(39990);
powerDown(INIT_I2C);
powerUp(INIT_RADIO);
sendXferComplete();
@@ -1001,7 +1004,6 @@ bool processAvailDataInfo(struct AvailDataInfo *__xdata avail) {
}
return false;
break;
*/
case DATATYPE_TAG_CONFIG_DATA:
if (xferDataInfo.dataSize == 0 && xMemEqual((const void *__xdata) & avail->dataVer, (const void *__xdata) & xferDataInfo.dataVer, 8)) {
pr("this was the same as the last transfer, disregard\n");

View File

@@ -6,7 +6,7 @@
#include <string.h>
#include "asmUtil.h"
#include "bitmaps.h"
#include "board.h"
#include "comms.h"
#include "cpu.h"
@@ -18,6 +18,7 @@
#include "../oepl-proto.h"
#include "screen.h"
#include "settings.h"
#include "bitmaps.h"
#include "sleep.h"
#include "spi.h"
#include "syncedproto.h" // for APmac / Channel
@@ -94,7 +95,7 @@ void afterFlashScreenSaver() {
epdPrintEnd();
epdPrintBegin(100, 32, EPD_DIRECTION_X, EPD_SIZE_SINGLE, EPD_COLOR_RED);
epdpr("v%d.%d.%d", fwVersion / 100, (fwVersion % 100) / 10, (fwVersion % 10));
epdpr("v%04X", fwVersion);
epdPrintEnd();
epdPrintBegin(0, 16, EPD_DIRECTION_X, EPD_SIZE_SINGLE, EPD_COLOR_BLACK);
@@ -136,7 +137,7 @@ void afterFlashScreenSaver() {
epdPrintEnd();
epdPrintBegin(8, 40, EPD_DIRECTION_Y, EPD_SIZE_SINGLE, EPD_COLOR_BLACK);
epdpr("v%d.%d.%d", fwVersion / 100, (fwVersion % 100) / 10, (fwVersion % 10));
epdpr("v%04X", fwVersion);
epdPrintEnd();
epdPrintBegin(32, 290, EPD_DIRECTION_Y, EPD_SIZE_SINGLE, EPD_COLOR_BLACK);
@@ -169,7 +170,7 @@ void afterFlashScreenSaver() {
epdPrintEnd();
epdPrintBegin(360, 8, EPD_DIRECTION_X, EPD_SIZE_SINGLE, EPD_COLOR_BLACK);
epdpr("v%d.%d.%d", fwVersion / 100, (fwVersion % 100) / 10, (fwVersion % 10));
epdpr("v%04X", fwVersion);
epdPrintEnd();
epdPrintBegin(10, 48, EPD_DIRECTION_X, EPD_SIZE_SINGLE, EPD_COLOR_BLACK);
@@ -212,8 +213,10 @@ void showSplashScreen() {
epdpr("Starting");
epdPrintEnd();
#ifndef LEAN_VERSION
loadRawBitmap(oepli, 12, 12, EPD_COLOR_BLACK);
loadRawBitmap(cloud, 12, 0, EPD_COLOR_RED);
#endif
epdPrintBegin(5, 136, EPD_DIRECTION_X, EPD_SIZE_SINGLE, EPD_COLOR_RED);
epdpr("%02X%02X", mSelfMac[7], mSelfMac[6]);
@@ -227,7 +230,7 @@ void showSplashScreen() {
epdPrintEnd();
epdPrintBegin(2, 120, EPD_DIRECTION_X, EPD_SIZE_SINGLE, EPD_COLOR_BLACK);
epdpr("zbs154v033 %d.%d.%d%s", fwVersion / 100, (fwVersion % 100) / 10, (fwVersion % 10), fwVersionSuffix);
epdpr("zbs154 %04X%s", fwVersion, fwVersionSuffix);
epdPrintEnd();
#endif
@@ -243,7 +246,7 @@ void showSplashScreen() {
epdPrintEnd();
epdPrintBegin(80, 295, EPD_DIRECTION_Y, EPD_SIZE_SINGLE, EPD_COLOR_BLACK);
epdpr("zbs29v033 %d.%d.%d%s", fwVersion / 100, (fwVersion % 100) / 10, (fwVersion % 10), fwVersionSuffix);
epdpr("zbs29 %04X%s", fwVersion, fwVersionSuffix);
epdPrintEnd();
epdPrintBegin(105, 270, EPD_DIRECTION_Y, EPD_SIZE_SINGLE, EPD_COLOR_RED);
@@ -259,9 +262,10 @@ void showSplashScreen() {
spr(buffer + 8, "%02X%02X", mSelfMac[3], mSelfMac[2]);
spr(buffer + 12, "%02X%02X", mSelfMac[1], mSelfMac[0]);
printBarcode(buffer, 120, 284);
#ifndef LEAN_VERSION
loadRawBitmap(oepli, 0, 12, EPD_COLOR_BLACK);
loadRawBitmap(cloud, 0, 0, EPD_COLOR_RED);
#endif
// lutTest();
// drawLineVertical(EPD_COLOR_RED, 64, 10, 286);
// drawLineVertical(EPD_COLOR_BLACK, 65, 10, 286);
@@ -278,7 +282,7 @@ void showSplashScreen() {
epdPrintEnd();
epdPrintBegin(3, 268, EPD_DIRECTION_X, EPD_SIZE_SINGLE, EPD_COLOR_BLACK);
epdpr("zbs42v033 %d.%d.%d%s", fwVersion / 100, (fwVersion % 100) / 10, (fwVersion % 10), fwVersionSuffix);
epdpr("zbs42 %04X%s", fwVersion, fwVersionSuffix);
epdPrintEnd();
epdPrintBegin(3, 284, EPD_DIRECTION_X, EPD_SIZE_SINGLE, EPD_COLOR_RED);
epdpr("MAC: %02X:%02X", mSelfMac[7], mSelfMac[6]);
@@ -286,10 +290,10 @@ void showSplashScreen() {
epdpr(":%02X:%02X", mSelfMac[3], mSelfMac[2]);
epdpr(":%02X:%02X", mSelfMac[1], mSelfMac[0]);
epdPrintEnd();
#ifndef LEAN_VERSION
loadRawBitmap(oepli, 136, 22, EPD_COLOR_BLACK);
loadRawBitmap(cloud, 136, 10, EPD_COLOR_RED);
#endif
uint8_t __xdata buffer[17];
spr(buffer, "%02X%02X", mSelfMac[7], mSelfMac[6]);
spr(buffer + 4, "%02X%02X", mSelfMac[5], mSelfMac[4]);
@@ -362,8 +366,10 @@ void showAPFound() {
spr(buffer + 8, "%02X%02X", mSelfMac[3], mSelfMac[2]);
spr(buffer + 12, "%02X%02X", mSelfMac[1], mSelfMac[0]);
printBarcode(buffer, 120, 253);
#ifndef LEAN_VERSION
loadRawBitmap(receive, 36, 14, EPD_COLOR_BLACK);
#endif
#endif
#if (SCREEN_WIDTH == 152) // 1.54"
epdPrintBegin(25, 0, EPD_DIRECTION_X, EPD_SIZE_DOUBLE, EPD_COLOR_BLACK);
epdpr("Waiting");
@@ -428,7 +434,9 @@ void showAPFound() {
spr(buffer + 12, "%02X%02X", mSelfMac[1], mSelfMac[0]);
printBarcode(buffer, 392, 253);
printBarcode(buffer, 384, 253);
#ifndef LEAN_VERSION
loadRawBitmap(receive, 100, 170, EPD_COLOR_BLACK);
#endif
#endif
addOverlay();
drawWithSleep();
@@ -452,9 +460,11 @@ void showNoAP() {
epdPrintBegin(64, 285, EPD_DIRECTION_Y, EPD_SIZE_SINGLE, EPD_COLOR_BLACK);
epdpr("little while...");
epdPrintEnd();
#ifndef LEAN_VERSION
loadRawBitmap(receive, 36, 24, EPD_COLOR_BLACK);
loadRawBitmap(failed, 42, 26, EPD_COLOR_RED);
#endif
#endif
#if (SCREEN_WIDTH == 152) // 1.54"
epdPrintBegin(40, 0, EPD_DIRECTION_X, EPD_SIZE_DOUBLE, EPD_COLOR_BLACK);
epdpr("No AP");
@@ -477,8 +487,10 @@ void showNoAP() {
epdPrintBegin(10, 274, EPD_DIRECTION_X, EPD_SIZE_SINGLE, EPD_COLOR_BLACK);
epdpr("We'll try again in a little while");
epdPrintEnd();
#ifndef LEAN_VERSION
loadRawBitmap(receive, 76, 120, EPD_COLOR_BLACK);
loadRawBitmap(failed, 82, 122, EPD_COLOR_RED);
#endif
#endif
addOverlay();
drawWithSleep();
@@ -513,8 +525,10 @@ void showNoEEPROM() {
epdPrintBegin(64, 285, EPD_DIRECTION_Y, EPD_SIZE_SINGLE, EPD_COLOR_BLACK);
epdpr("Sleeping forever :'(");
epdPrintEnd();
#ifndef LEAN_VERSION
loadRawBitmap(failed, 42, 26, EPD_COLOR_RED);
#endif
#endif
#if (SCREEN_WIDTH == 152) // 1.54"
epdPrintBegin(26, 0, EPD_DIRECTION_X, EPD_SIZE_DOUBLE, EPD_COLOR_BLACK);
epdpr("EEPROM ");
@@ -522,8 +536,9 @@ void showNoEEPROM() {
epdPrintBegin(8, 32, EPD_DIRECTION_X, EPD_SIZE_DOUBLE, EPD_COLOR_BLACK);
epdpr("FAILED :(");
epdPrintEnd();
#ifndef LEAN_VERSION
loadRawBitmap(failed, 60, 72, EPD_COLOR_RED);
#endif
epdPrintBegin(3, 136, EPD_DIRECTION_X, EPD_SIZE_SINGLE, EPD_COLOR_BLACK);
epdpr("Sleeping forever :'(");
epdPrintEnd();
@@ -532,7 +547,9 @@ void showNoEEPROM() {
epdPrintBegin(50, 3, EPD_DIRECTION_X, EPD_SIZE_DOUBLE, EPD_COLOR_BLACK);
epdpr("EEPROM FAILED :(");
epdPrintEnd();
#ifndef LEAN_VERSION
loadRawBitmap(failed, 176, 126, EPD_COLOR_RED);
#endif
epdPrintBegin(100, 284, EPD_DIRECTION_X, EPD_SIZE_SINGLE, EPD_COLOR_BLACK);
epdpr("Sleeping forever :'(");
epdPrintEnd();
@@ -551,8 +568,10 @@ void showNoMAC() {
epdPrintBegin(64, 285, EPD_DIRECTION_Y, EPD_SIZE_SINGLE, EPD_COLOR_BLACK);
epdpr("Sleeping forever :'(");
epdPrintEnd();
#ifndef LEAN_VERSION
loadRawBitmap(failed, 42, 26, EPD_COLOR_RED);
#endif
#endif
#if (SCREEN_WIDTH == 152) // 1.54"
epdPrintBegin(20, 0, EPD_DIRECTION_X, EPD_SIZE_DOUBLE, EPD_COLOR_BLACK);
epdpr("NO MAC");
@@ -560,7 +579,9 @@ void showNoMAC() {
epdPrintBegin(30, 32, EPD_DIRECTION_X, EPD_SIZE_DOUBLE, EPD_COLOR_BLACK);
epdpr("SET :(");
epdPrintEnd();
#ifndef LEAN_VERSION
loadRawBitmap(failed, 60, 72, EPD_COLOR_RED);
#endif
epdPrintBegin(3, 136, EPD_DIRECTION_X, EPD_SIZE_SINGLE, EPD_COLOR_BLACK);
epdpr("Sleeping forever :'(");
epdPrintEnd();
@@ -569,7 +590,9 @@ void showNoMAC() {
epdPrintBegin(100, 3, EPD_DIRECTION_X, EPD_SIZE_DOUBLE, EPD_COLOR_BLACK);
epdpr("NO MAC SET :(");
epdPrintEnd();
#ifndef LEAN_VERSION
loadRawBitmap(failed, 176, 126, EPD_COLOR_RED);
#endif
epdPrintBegin(100, 284, EPD_DIRECTION_X, EPD_SIZE_SINGLE, EPD_COLOR_BLACK);
epdpr("Sleeping forever :'(");
epdPrintEnd();

View File

@@ -16,7 +16,6 @@ void showNoEEPROM();
void showNoMAC();
// wakeups from external stimuli
void externalWakeHandler(uint8_t type);

View File

@@ -6,6 +6,8 @@
#include "screen.h"
#ifndef LEAN_VERSION
static const uint8_t __code oepli[] = {
128, 26,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
@@ -202,6 +204,7 @@ static const uint8_t __code failed[] = {
0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
0x00, 0x00, 0x1f, 0xf8, 0x00, 0x00,
};
#endif
#if (SCREEN_WIDTH != 128)
static const uint8_t __code ant[] = {

View File

@@ -327,10 +327,13 @@ void epdConfigGPIO(bool setup) {
epdGPIOActive = setup;
}
void epdEnterSleep() {
timerDelay(20 * TIMER_TICKS_PER_MS);
epdReset();
timerDelay(20 * TIMER_TICKS_PER_MS);
shortCommand1(CMD_VCOM_INTERVAL, 0x17);
shortCommand1(CMD_VCOM_DC_SETTING, 0x00);
// shortCommand(CMD_POWER_OFF);
// epdWaitRdy();
// epdWaitRdy();
shortCommand1(CMD_DEEP_SLEEP, 0xA5);
isInited = false;
}
@@ -395,69 +398,19 @@ static uint8_t epdGetStatus() {
return sta;
}
uint16_t epdGetBattery(void) {
return 0;
uint8_t sta;
commandReadBegin(0x51);
sta = epdReadByte();
commandReadEnd();
if (sta) return 3000;
return 2100;
}
static void readLut() {
commandReadBegin(0x33);
uint16_t checksum = 0;
uint16_t ident = 0;
uint16_t shortl = 0;
for (uint16_t c = 0; c < LUT_BUFFER_SIZE; c++) {
waveformbuffer[c] = epdReadByte();
}
commandReadEnd();
}
static uint8_t getLutSize() {
uint8_t ref = 0;
for (uint8_t c = (LUT_BUFFER_SIZE - 4); c > 16; c--) {
uint8_t check = waveformbuffer[c];
for (uint8_t d = 1; d < 4; d++) {
if (waveformbuffer[c + d] != check) {
ref = c;
goto end;
}
}
}
end:;
return ref + 1;
}
static void lutGroupDisable(uint8_t group) {
if (dispLutSize == 7) {
memset(&(waveform7->group[group]), 0x00, 5);
} else {
memset(&(waveform10->group[group]), 0x00, 5);
}
}
static void lutGroupSpeedup(uint8_t group, uint8_t speed) {
if (dispLutSize == 7) {
for (uint8_t i = 0; i < 4; i++) {
waveform7->group[group].phaselength[i] = 1 + (waveform7->group[group].phaselength[i] / speed);
}
} else {
for (uint8_t i = 0; i < 4; i++) {
waveform10->group[group].phaselength[i] = 1 + (waveform10->group[group].phaselength[i] / speed);
}
}
}
static void lutGroupRepeat(uint8_t group, uint8_t repeat) {
if (dispLutSize == 7) {
waveform7->group[group].repeat = repeat;
} else {
waveform10->group[group].repeat = repeat;
}
}
static void lutGroupRepeatReduce(uint8_t group, uint8_t factor) {
if (dispLutSize == 7) {
waveform7->group[group].repeat = waveform7->group[group].repeat / factor;
} else {
waveform10->group[group].repeat = waveform10->group[group].repeat / factor;
}
}
void selectLUT(uint8_t lut) {
// implement alternative LUTs here. Currently just reset the watchdog to two minutes,
// to ensure it doesn't reset during the much longer bootup procedure
lut+=1; // make the compiler a happy camper
lut += 1; // make the compiler a happy camper
wdtSetResetVal(0xFF8E797F); // 120 s
wdtOn();
return;
@@ -478,8 +431,8 @@ void setWindowXY(uint16_t xstart, uint16_t xend, uint16_t ystart, uint16_t yend)
void setColorMode(uint8_t red, uint8_t bw) {
// this does exactly nothing, just keeps the compiler from barking
red=1;
bw=0;
red = 1;
bw = 0;
return;
}
void clearScreen() {

View File

@@ -8,27 +8,26 @@
#include "../oepl-definitions.h"
#include "spi.h"
#define eepromByte spiByte
#define eepromPrvSelect() do { __asm__("nop\nnop\nnop\n"); P1_1 = 0; __asm__("nop\nnop\nnop\n"); } while(0)
#define eepromPrvDeselect() do { __asm__("nop\nnop\nnop\n"); P1_1 = 1; __asm__("nop\nnop\nnop\n"); } while(0)
#define eepromByte spiByte
#define eepromPrvSelect() do { __asm__("nop\nnop\nnop\n"); P1_1 = 0; __asm__("nop\nnop\nnop\n"); } while(0)
#define eepromPrvDeselect() do { __asm__("nop\nnop\nnop\n"); P1_1 = 1; __asm__("nop\nnop\nnop\n"); } while(0)
//eeprom map
#define EEPROM_SETTINGS_AREA_START (0x01000UL)
#define EEPROM_SETTINGS_AREA_LEN (0x03000UL)
#define EEPROM_UPDATA_AREA_START (0x04000UL)
#define EEPROM_UPDATE_AREA_LEN (0x10000UL)
#define EEPROM_IMG_START (0x14000UL)
#define EEPROM_IMG_EACH (0x04000UL)
#define EEPROM_SETTINGS_AREA_START (0x00000UL)
#define EEPROM_SETTINGS_AREA_LEN (0x01000UL)
#define EEPROM_IMG_START (0x01000UL)
#define EEPROM_IMG_EACH (0x03000UL)
//till end of eeprom really. do not put anything after - it will be erased at pairing time!!!
#define EEPROM_PROGRESS_BYTES (128)
#define EEPROM_PROGRESS_BYTES (128)
#define HAS_EEPROM 1
#define HAS_SCREEN 1
#define NFC_TYPE -1
#define AP_EMULATE_TAG 1
#define EXTRA_EEPROM_LINES // this tag has extra eeprom lines that need to be driven
//hw types
#define HW_TYPE SOLUM_29_BW_SSD1619
#define HW_TYPE SOLUM_M2_BW_29_LOWTEMP
#include "../boardCommon.h"

View File

@@ -810,25 +810,3 @@ void epdPrintEnd() {
}
commandEnd();
}
extern uint8_t __xdata blockXferBuffer[];
void readRam() {
setWindowY(296, 0);
setWindowX(0, 8);
setPosXY(0, 296);
shortCommand1(CMD_DATA_ENTRY_MODE, 1); // was 3
shortCommand1(0x41, 0x00);
commandReadBegin(0x27);
epdReadByte();
for (uint16_t c = 0; c < 293; c++) {
blockXferBuffer[c] = epdReadByte() | 0x10;
}
commandReadEnd();
commandBegin(CMD_WRITE_FB_BW);
for (uint16_t c = 0; c < 296; c++) {
epdSend(blockXferBuffer[c]);
}
commandEnd();
}

View File

@@ -24,7 +24,7 @@
#define AP_EMULATE_TAG 1
//hw types
#define HW_TYPE SOLUM_29_UC8151
#define HW_TYPE SOLUM_M2_BWR_29_UC8151
#include "../boardCommon.h"