diff --git a/tag_fw/Makefile b/tag_fw/Makefile index 7dcae7e6..5dec4173 100644 --- a/tag_fw/Makefile +++ b/tag_fw/Makefile @@ -3,8 +3,8 @@ BUILD ?= zbs29v033 #file containing main() must be first! SOURCES += main.c eeprom.c drawing.c -SOURCES += comms.c chars.c -SOURCES += syncedproto.c +SOURCES += comms.c +SOURCES += syncedproto.c epd.c userinterface.c all: #make sure it is the first target @@ -18,21 +18,7 @@ FLAGS += -Icpu/$(CPU) SOURCES += cpu/$(CPU)/cpu.c SOURCES += board/$(BUILD)/board.c -SOURCES += board/$(BUILD)/screen.c - - -ifeq ($(BARCODE),barcode) - FLAGS += -DBARCODE - SOURCES += barcode.c -else ifeq ($(BARCODE),datamatrix) - # FLAGS += -DDATAMATRIX - # SOURCES += datamatrix.c - #i might release this later, but for now, just use barcodes :P - FLAGS += -DBARCODE - SOURCES += barcode.c -else - SOURCES += $(warning "no barcode type set") -endif +#SOURCES += board/$(BUILD)/screen.c EEPROMDRV ?= eeprom.c diff --git a/tag_fw/adc.h b/tag_fw/adc.h deleted file mode 100644 index c495bc07..00000000 --- a/tag_fw/adc.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef _ADC_H_ -#define _ADC_H_ - -#include - -extern uint16_t __xdata mAdcSlope; -extern uint16_t __xdata mAdcIntercept; - - -uint16_t adcSampleBattery(void); //in mV -int8_t adcSampleTemperature(void); //in degrees C - - - - -#endif diff --git a/tag_fw/barcode.c b/tag_fw/barcode.c deleted file mode 100644 index c431d148..00000000 --- a/tag_fw/barcode.c +++ /dev/null @@ -1,101 +0,0 @@ -#include -#include "barcode.h" -#include "asmUtil.h" - -//code128 generator (c) 2021 Dmitry Grinberg https://dmitry.gr -//non-commercial use only, contact licensing@dmitry.gr for other options - -#pragma nogcse - -static const uint16_t __code mCode128[] = { - 0b00110011011, 0b00110110011, 0b01100110011, 0b00011001001, 0b00110001001, 0b00110010001, 0b00010011001, 0b00100011001, - 0b00100110001, 0b00010010011, 0b00100010011, 0b00100100011, 0b00111001101, 0b00111011001, 0b01110011001, 0b00110011101, - 0b00110111001, 0b01100111001, 0b01001110011, 0b00111010011, 0b01110010011, 0b00100111011, 0b00101110011, 0b01110110111, - 0b00110010111, 0b00110100111, 0b01100100111, 0b00100110111, 0b00101100111, 0b01001100111, 0b00011011011, 0b01100011011, - 0b01101100011, 0b00011000101, 0b00011010001, 0b01100010001, 0b00010001101, 0b00010110001, 0b01000110001, 0b00010001011, - 0b00010100011, 0b01000100011, 0b00011101101, 0b01110001101, 0b01110110001, 0b00011011101, 0b01100011101, 0b01101110001, - 0b01101110111, 0b01110001011, 0b01110100011, 0b00010111011, 0b01000111011, 0b01110111011, 0b00011010111, 0b01100010111, - 0b01101000111, 0b00010110111, 0b01000110111, 0b01011000111, 0b01011110111, 0b01000010011, 0b01010001111, 0b00001100101, - 0b00110000101, 0b00001101001, 0b01100001001, 0b00110100001, 0b01100100001, 0b00001001101, 0b00100001101, 0b00001011001, - 0b01000011001, 0b00101100001, 0b01001100001, 0b01001000011, 0b00001010011, 0b01011101111, 0b00101000011, 0b01011110001, - 0b00111100101, 0b00111101001, 0b01111001001, 0b00100111101, 0b00101111001, 0b01001111001, 0b00100101111, 0b00101001111, - 0b01001001111, 0b01111011011, 0b01101111011, 0b01101101111, 0b00011110101, 0b01111000101, 0b01111010001, 0b00010111101, - 0b01000111101, 0b00010101111, 0b01000101111, 0b01111011101, 0b01110111101, 0b01111010111, 0b01110101111 -}; - - -#define CODE128_START_B (0b00001001011) -#define CODE128_STOP (0b1101011100011) - -#define CODE128_IDX_START_A (103) -#define CODE128_IDX_START_B (104) -#define CODE128_IDX_START_C (105) -#define CODE128_IDX_CODE_STOP (106) - - -enum BarCodeState { - BarCodeInit, - BarCodeEmittingChar, - BarCodeEmittingChecksum, - BarCodeEmittingStop, - BarCodeDone, -}; - - - - -__bit barcodeIsDone(struct BarcodeInfo __xdata *bci) -{ - return bci->state == BarCodeDone; -} - -__bit barcodeNextBar(struct BarcodeInfo __xdata *bci) -{ - uint8_t t; - __bit ret; - - if (!bci->barsLeft) switch (bci->state) { - case BarCodeInit: - bci->curBars = CODE128_START_B; - bci->barsLeft = 11; - bci->state = BarCodeEmittingChar; - bci->csum = CODE128_IDX_START_B; - break; - - case BarCodeEmittingChar: - t = charsPrvDerefAndIncGenericPtr(&bci->str); - if (t) { - t -= 0x20; - if (t >= 0x60) - t = '?' - 0x20; - bci->csum = mathPrvMod16x8(mathPrvMul8x8(++bci->csumMul, t) + bci->csum, 103); - } - else { - - bci->state = BarCodeEmittingChecksum; - t = bci->csum; - } - bci->curBars = mCode128[t]; - bci->barsLeft = 11; - break; - - case BarCodeEmittingChecksum: - bci->state = BarCodeEmittingStop; - bci->curBars = CODE128_STOP; - bci->barsLeft = 13; - break; - - case BarCodeEmittingStop: - bci->state = BarCodeDone; - //fallthrough - - case BarCodeDone: - default: - return false; - } - - ret = bci->curBars & 1; - bci->curBars >>= 1; - bci->barsLeft--; - return ret; -} diff --git a/tag_fw/barcode.h b/tag_fw/barcode.h deleted file mode 100644 index f6d784b9..00000000 --- a/tag_fw/barcode.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef _BARCODE_H_ -#define _BARCODE_H_ - -#include - -//code128 generator (c) 2021 Dmitry Grinberg https://dmitry.gr -//non-commercial use only, contact licensing@dmitry.gr for other options - - -struct BarcodeInfo { //zero-init this except the string ptr - const char *str; - uint16_t curBars; - uint8_t barsLeft; - uint8_t state; - uint8_t csum; - uint8_t csumMul; -}; - -#define barcodeWidth(nChars) (11 * (nChars) + 11 /*start */+ 11 /*check sum */ + 13 /* stop */) - -#pragma callee_saves barcodeIsDone -__bit barcodeIsDone(struct BarcodeInfo __xdata *bci); - -#pragma callee_saves barcodeNextBar -__bit barcodeNextBar(struct BarcodeInfo __xdata *bci); - - - -#endif diff --git a/tag_fw/board/boardZBS29common.c b/tag_fw/board/boardZBS29common.c index ee41370c..7a662eed 100644 --- a/tag_fw/board/boardZBS29common.c +++ b/tag_fw/board/boardZBS29common.c @@ -7,9 +7,10 @@ #include "spi.h" #include "cpu.h" #include "wdt.h" -#include "adc.h" #include "i2c.h" +//extern uint8_t __xdata* tempBuffer; +uint8_t __xdata tempBuffer[320]; void powerPortsDownForSleep(void) { @@ -148,12 +149,12 @@ void selfUpdate(void) uint32_t updaterInfo = prvUpdateApplierGet(); uint8_t __code *src = (uint8_t __code*)updaterInfo; uint8_t i, len = updaterInfo >> 16; - uint8_t __xdata *dst = mScreenRow; + uint8_t __xdata *dst = tempBuffer; for (i = len; i ; i--) *dst++ = *src++; - if (!flashWrite(0xfc00, mScreenRow, len, true)) + if (!flashWrite(0xfc00, tempBuffer, len, true)) pr("failed to write updater\n"); IEN_EA = 0; //ints off diff --git a/tag_fw/board/zbs154v033/screen.c b/tag_fw/board/zbs154v033/screen.c deleted file mode 100644 index 2bd46f4d..00000000 --- a/tag_fw/board/zbs154v033/screen.c +++ /dev/null @@ -1,475 +0,0 @@ -#include "screen.h" - -#include - -#include "adc.h" -#include "asmUtil.h" -#include "board.h" -#include "cpu.h" -#include "printf.h" -#include "sleep.h" -#include "spi.h" -#include "timer.h" - -uint8_t __xdata mScreenRow[320]; - -static __bit mInited = false, mPartial; -static uint8_t __xdata mPassNo; - -#define SCREEN_CMD_CLOCK_ON 0x80 -#define SCREEN_CMD_CLOCK_OFF 0x01 - -#define SCREEN_CMD_ANALOG_ON 0x40 -#define SCREEN_CMD_ANALOG_OFF 0x02 - -#define SCREEN_CMD_LATCH_TEMPERATURE_VAL 0x20 - -#define SCREEN_CMD_LOAD_LUT 0x10 -#define SCREEN_CMD_USE_MODE_2 0x08 // modified commands 0x10 and 0x04 - -#define SCREEN_CMD_REFRESH 0xC7 - -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 const uint8_t __code partial_lut[] = { - // lut0 (KEEP) voltages - 0x40, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - // lut1 (W2B) voltages - 0x80, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - // lut2 (B2W) voltages - 0x40, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - // lut3 (unused) voltages - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - // lut4 (vcom) voltages - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - - // group0 phase lengths and repeat count - 45, - 0x00, - 0x00, - 0x00, - 0x00, - - // group1 not used - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - - // group2 not used - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - - // group3 phase lengths and repeat count - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - - // group4 phase lengths and repeat count - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - - // group5 phase lengths and repeat count - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - - // group6 phase lengths and repeat count - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, -}; - -#define einkPrvSelect() \ - do { \ - P1_7 = 0; \ - } while (0) - -#define einkPrvDeselect() \ - do { \ - P1_7 = 1; \ - } while (0) -// urx pin -#define einkPrvMarkCommand() \ - do { \ - P2_2 = 0; \ - } while (0) - -#define einkPrvMarkData() \ - do { \ - P2_2 = 1; \ - } while (0) - -#pragma callee_saves einkPrvCmd -static void einkPrvCmd(uint8_t cmd) // sets chip select -{ - einkPrvSelect(); - einkPrvMarkCommand(); - spiByte(cmd); -} - -#pragma callee_saves einkPrvData -static void einkPrvData(uint8_t byte) { - einkPrvMarkData(); - spiByte(byte); -} - -#pragma callee_saves einkPrvCmdWithOneByte -static void einkPrvCmdWithOneByte(uint16_t vals) // passing in one u16 is better than two params cause SDCC sucks -{ - einkPrvCmd(vals >> 8); - einkPrvData(vals); - einkPrvDeselect(); -} - -#pragma callee_saves einkPrvWaitWithTimeout -static void einkPrvWaitWithTimeout(uint32_t timeout) { - uint32_t __xdata start = timerGet(); - - while (timerGet() - start < timeout) { - if (!P2_1) - return; - } - pr("screen timeout %lu ticks\n", timerGet() - start); - while (1) - ; -} - -#pragma callee_saves einkPrvWaitWithTimeout -static void einkPrvWaitWithTimeoutSleep(uint32_t timeout) { - uint8_t tmp_P2FUNC = P2FUNC; - uint8_t tmp_P2DIR = P2DIR; - uint8_t tmp_P2PULL = P2PULL; - uint8_t tmp_P2LVLSEL = P2LVLSEL; - P2FUNC &= 0xfd; - P2DIR |= 2; - P2PULL |= 2; - P2LVLSEL |= 2; - - P2CHSTA &= 0xfd; - P2INTEN |= 2; - P2CHSTA &= 0xfd; - sleepForMsec(timeout); - P2CHSTA &= 0xfd; - P2INTEN &= 0xfd; - - P2FUNC = tmp_P2FUNC; - P2DIR = tmp_P2DIR; - P2PULL = tmp_P2PULL; - P2LVLSEL = tmp_P2LVLSEL; - /*if (!P2_1) - return; - - pr("screen timeout\n"); - while(1);*/ -} - -#pragma callee_saves einkPrvReadByte -static uint8_t einkPrvReadByte(void) { - uint8_t val = 0, i; - - P0DIR = (P0DIR & ~(1 << 0)) | (1 << 1); - P0 &= ~(1 << 0); - P0FUNC &= ~((1 << 0) | (1 << 1)); - - P2_2 = 1; - - for (i = 0; i < 8; i++) { - P0_0 = 1; - __asm__("nop\nnop\nnop\nnop\nnop\n"); - val <<= 1; - if (P0_1) - val++; - P0_0 = 0; - __asm__("nop\nnop\nnop\nnop\nnop\n"); - } - - // set up pins for spi (0.0,0.1,0.2) - P0FUNC |= (1 << 0) | (1 << 1); - - return val; -} - -#pragma callee_saves einkPrvReadStatus -static uint8_t einkPrvReadStatus(void) { - uint8_t sta; - einkPrvCmd(0x2f); - - sta = einkPrvReadByte(); - einkPrvDeselect(); - - return sta; -} - -#pragma callee_saves screenPrvStartSubPhase -static void screenPrvStartSubPhase(__bit redSubphase) { - einkPrvCmd(0x4e); - einkPrvData(0); - einkPrvDeselect(); - - einkPrvCmd(0x4f); - einkPrvData(0x00); - einkPrvData(0x00); - einkPrvDeselect(); - - einkPrvCmd(redSubphase ? 0x26 : 0x24); - - einkPrvDeselect(); -} - -void moveToXY(uint8_t x, uint16_t y, bool color) { - einkPrvCmd(0x4e); - einkPrvData(x); - einkPrvDeselect(); - einkPrvCmd(0x4f); - einkPrvData((uint8_t)(y & 0xFF)); - einkPrvData((uint8_t)(y >> 8)); - einkPrvDeselect(); - einkPrvCmd(color ? 0x26 : 0x24); - einkPrvDeselect(); -} - -#pragma callee_saves screenInitIfNeeded -static void screenInitIfNeeded(__bit forPartial) { - if (mInited) - return; - - mInited = true; - mPartial = forPartial; - - timerDelay(TIMER_TICKS_PER_SECOND / 1000); - P2_0 = 0; - timerDelay(TIMER_TICKS_PER_SECOND / 1000); - P2_0 = 1; - timerDelay(TIMER_TICKS_PER_SECOND / 1000); - - einkPrvCmd(0x12); // software reset - einkPrvDeselect(); - timerDelay(TIMER_TICKS_PER_SECOND / 1000); - - einkPrvCmdWithOneByte(0x7454); - - einkPrvCmdWithOneByte(0x7e3b); - - einkPrvCmd(0x2b); - einkPrvData(0x04); - einkPrvData(0x63); - einkPrvDeselect(); - - einkPrvCmd(0x0c); // they send 8f 8f 8f 3f - einkPrvData(0x8f); - einkPrvData(0x8f); - einkPrvData(0x8f); - einkPrvData(0x3f); - einkPrvDeselect(); - - einkPrvCmd(0x01); - einkPrvData(0x97); - einkPrvData(0x00); - einkPrvData(0x00); - einkPrvDeselect(); - - einkPrvCmdWithOneByte(0x1103); - einkPrvDeselect(); - - einkPrvCmdWithOneByte(0x2200 | SCREEN_CMD_CLOCK_ON | SCREEN_CMD_ANALOG_ON); - einkPrvCmd(0x20); - einkPrvDeselect(); - - einkPrvWaitWithTimeout(TIMER_TICKS_PER_SECOND * 10); - - einkPrvCmd(0x44); - einkPrvData(0x00); - einkPrvData(SCREEN_WIDTH / 8 - 1); - einkPrvDeselect(); - - einkPrvCmd(0x45); - einkPrvData(0x00); - einkPrvData(0x00); - einkPrvData(0x97); - einkPrvData(0x00); - einkPrvDeselect(); - - einkPrvCmdWithOneByte(0x3c01); // border will be HiZ - einkPrvDeselect(); - einkPrvCmdWithOneByte(0x1880); // internal temp sensor - - einkPrvCmdWithOneByte(0x2108); - - // turn on clock & analog - einkPrvCmdWithOneByte(0x22B1); - einkPrvCmd(0x20); // do action - einkPrvDeselect(); - einkPrvWaitWithTimeout(TIMER_TICKS_PER_SECOND); - - if (forPartial) { - einkPrvCmd(0x32); - for (int i = 0; i < sizeof(partial_lut); i++) - einkPrvData(partial_lut[i]); - } - einkPrvDeselect(); -} - -#pragma callee_saves screenPrvDraw -static void screenPrvDraw(void) { - einkPrvCmdWithOneByte(0x2200 | SCREEN_CMD_REFRESH); - einkPrvCmd(0x20); // do actions - if (0) { - einkPrvWaitWithTimeoutSleep(1000 * 60UL); - screenSleep(); - } else { - einkPrvWaitWithTimeout(TIMER_TICKS_PER_SECOND * 60UL); - } -} - -__bit screenTxStart(__bit forPartial) { - screenInitIfNeeded(forPartial); - mPassNo = 0; - - screenPrvStartSubPhase(false); - - return true; -} - -void screenEndPass(void) { - switch (mPassNo) { - case 0: - screenPrvStartSubPhase(true); - break; - default: - return; - } - mPassNo++; -} - -void screenTxEnd(void) { - screenPrvDraw(); - screenShutdown(); -} - -void screenShutdown(void) { - if (!mInited) - return; - - mInited = false; - einkPrvCmdWithOneByte(0x1003); // shut down -} - -void screenSleep(void) { - P2_0 = 0; - timerDelay(10); - P2_0 = 1; - timerDelay(50); - - einkPrvCmd(0x12); // software reset - einkPrvDeselect(); - einkPrvWaitWithTimeout(TIMER_TICKS_PER_SECOND / 250); - einkPrvCmdWithOneByte(0x1003); // shut down -} - -#pragma callee_saves screenByteTx -void screenByteTx(uint8_t byte) { - static uint8_t __xdata prev, step = 0; - - prev <<= 2; - prev |= (mColorMap[mPassNo][byte >> 4] << 1) | mColorMap[mPassNo][byte & 0x0f]; - if (++step == 4) { - step = 0; - einkPrvSelect(); - einkPrvData(prev); - einkPrvDeselect(); - } -} - -void screenByteRawTx(uint8_t byte) { - einkPrvSelect(); - einkPrvData(byte); - einkPrvDeselect(); -} - -// yes this is here... -uint16_t adcSampleBattery(void) { - __bit wasInited = mInited; - uint16_t voltage = 2600; - - if (!mInited) - screenInitIfNeeded(false); - - uint8_t val; - - einkPrvCmdWithOneByte(0x2200 | SCREEN_CMD_CLOCK_ON | SCREEN_CMD_ANALOG_ON); - einkPrvCmd(0x20); // do action - einkPrvDeselect(); - einkPrvWaitWithTimeout(TIMER_TICKS_PER_SECOND); - - for (val = 3; val < 8; val++) { - einkPrvCmdWithOneByte(0x1500 + val); - einkPrvWaitWithTimeout(TIMER_TICKS_PER_SECOND); - if (einkPrvReadStatus() & 0x10) { // set if voltage is less than threshold ( == 1.9 + val / 10) - voltage = 1850 + mathPrvMul8x8(val, 100); - break; - } - } - - einkPrvCmdWithOneByte(0x22B1); - einkPrvCmd(0x20); // do action - einkPrvDeselect(); - einkPrvWaitWithTimeout(TIMER_TICKS_PER_SECOND); - - if (!wasInited) - screenShutdown(); - - return voltage; -} diff --git a/tag_fw/board/zbs154v033/screen.h b/tag_fw/board/zbs154v033/screen.h index 479da353..2dd805b3 100644 --- a/tag_fw/board/zbs154v033/screen.h +++ b/tag_fw/board/zbs154v033/screen.h @@ -4,12 +4,6 @@ #include #include - -//i hate globals, but for 8051 this makes life a lot easier, sorry :( -extern uint8_t __xdata mScreenVcom; -extern int8_t __xdata mCurTemperature; - - #define SCREEN_WIDTH 152 #define SCREEN_HEIGHT 152 @@ -27,23 +21,6 @@ extern int8_t __xdata mCurTemperature; #define SCREEN_DATA_PASSES 2 -void screenShutdown(void); - -void screenTest(void); - -__bit screenTxStart(__bit forPartial); - -void screenEndPass(void); //at end of each pass -void moveToXY(uint8_t x, uint16_t y, bool red); - -#pragma callee_saves screenByteTx -void screenByteTx(uint8_t byte); -void screenByteRawTx(uint8_t byte); -void screenTxEnd(void); - -void screenSleep(void); - -extern uint8_t __xdata mScreenRow[]; //320 bytes used as temp by many on cc where memory is tight #endif diff --git a/tag_fw/board/zbs29v033/screen.c b/tag_fw/board/zbs29v033/screen.c deleted file mode 100644 index d434b693..00000000 --- a/tag_fw/board/zbs29v033/screen.c +++ /dev/null @@ -1,397 +0,0 @@ -#include -#include "asmUtil.h" -#include "screen.h" -#include "printf.h" -#include "board.h" -#include "timer.h" -#include "sleep.h" -#include "adc.h" -#include "cpu.h" -#include "spi.h" - -uint8_t __xdata mScreenRow[320]; - -static __bit mInited = false, mPartial; -static uint8_t __xdata mPassNo; - -#define SCREEN_CMD_CLOCK_ON 0x80 -#define SCREEN_CMD_CLOCK_OFF 0x01 - -#define SCREEN_CMD_ANALOG_ON 0x40 -#define SCREEN_CMD_ANALOG_OFF 0x02 - -#define SCREEN_CMD_LATCH_TEMPERATURE_VAL 0x20 - -#define SCREEN_CMD_LOAD_LUT 0x10 -#define SCREEN_CMD_USE_MODE_2 0x08 // modified commands 0x10 and 0x04 - -#define SCREEN_CMD_REFRESH 0xC7 - -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) - }}; - -#define einkPrvSelect() \ - do \ - { \ - P1_7 = 0; \ - } while (0) - -#define einkPrvDeselect() \ - do \ - { \ - P1_7 = 1; \ - } while (0) -// urx pin -#define einkPrvMarkCommand() \ - do \ - { \ - P2_2 = 0; \ - } while (0) - -#define einkPrvMarkData() \ - do \ - { \ - P2_2 = 1; \ - } while (0) - -#pragma callee_saves einkPrvCmd -static void einkPrvCmd(uint8_t cmd) // sets chip select -{ - einkPrvSelect(); - einkPrvMarkCommand(); - spiByte(cmd); -} - -#pragma callee_saves einkPrvData -static void einkPrvData(uint8_t byte) -{ - einkPrvMarkData(); - spiByte(byte); -} - -#pragma callee_saves einkPrvCmdWithOneByte -static void einkPrvCmdWithOneByte(uint16_t vals) // passing in one u16 is better than two params cause SDCC sucks -{ - einkPrvCmd(vals >> 8); - einkPrvData(vals); - einkPrvDeselect(); -} - -#pragma callee_saves einkPrvWaitWithTimeout -static void einkPrvWaitWithTimeout(uint32_t timeout) -{ - uint32_t __xdata start = timerGet(); - - while (timerGet() - start < timeout) - { - - if (!P2_1) - return; - } - pr("screen timeout %lu ticks\n", timerGet() - start); - while (1) - ; -} - -#pragma callee_saves einkPrvWaitWithTimeout -static void einkPrvWaitWithTimeoutSleep(uint32_t timeout) -{ - uint8_t tmp_P2FUNC = P2FUNC; - uint8_t tmp_P2DIR = P2DIR; - uint8_t tmp_P2PULL = P2PULL; - uint8_t tmp_P2LVLSEL = P2LVLSEL; - P2FUNC &= 0xfd; - P2DIR |= 2; - P2PULL |= 2; - P2LVLSEL |= 2; - - P2CHSTA &= 0xfd; - P2INTEN |= 2; - P2CHSTA &= 0xfd; - sleepForMsec(timeout); - P2CHSTA &= 0xfd; - P2INTEN &= 0xfd; - - P2FUNC = tmp_P2FUNC; - P2DIR = tmp_P2DIR; - P2PULL = tmp_P2PULL; - P2LVLSEL = tmp_P2LVLSEL; - /*if (!P2_1) - return; - - pr("screen timeout\n"); - while(1);*/ -} - -#pragma callee_saves einkPrvReadByte -static uint8_t einkPrvReadByte(void) -{ - uint8_t val = 0, i; - - P0DIR = (P0DIR & ~(1 << 0)) | (1 << 1); - P0 &= ~(1 << 0); - P0FUNC &= ~((1 << 0) | (1 << 1)); - - P2_2 = 1; - - for (i = 0; i < 8; i++) - { - P0_0 = 1; - __asm__("nop\nnop\nnop\nnop\nnop\n"); - val <<= 1; - if (P0_1) - val++; - P0_0 = 0; - __asm__("nop\nnop\nnop\nnop\nnop\n"); - } - - // set up pins for spi (0.0,0.1,0.2) - P0FUNC |= (1 << 0) | (1 << 1); - - return val; -} - -#pragma callee_saves einkPrvReadStatus -static uint8_t einkPrvReadStatus(void) -{ - uint8_t sta; - einkPrvCmd(0x2f); - - sta = einkPrvReadByte(); - einkPrvDeselect(); - - return sta; -} - -#pragma callee_saves screenPrvStartSubPhase -static void screenPrvStartSubPhase(__bit redSubphase) -{ - einkPrvCmd(0x4e); - einkPrvData(0); - einkPrvDeselect(); - - einkPrvCmd(0x4f); - einkPrvData(0x00); - einkPrvData(0x00); - einkPrvDeselect(); - - einkPrvCmd(redSubphase ? 0x26 : 0x24); - - einkPrvDeselect(); -} - -#pragma callee_saves screenInitIfNeeded -static void screenInitIfNeeded(__bit forPartial) -{ - if (mInited) - return; - - mInited = true; - mPartial = forPartial; - - timerDelay(TIMER_TICKS_PER_SECOND / 1000); - P2_0 = 0; - timerDelay(TIMER_TICKS_PER_SECOND / 1000); - P2_0 = 1; - timerDelay(TIMER_TICKS_PER_SECOND / 1000); - - einkPrvCmd(0x12); // software reset - einkPrvDeselect(); - timerDelay(TIMER_TICKS_PER_SECOND / 1000); - - einkPrvCmdWithOneByte(0x7454); - - einkPrvCmdWithOneByte(0x7e3b); - - einkPrvCmd(0x2b); - einkPrvData(0x04); - einkPrvData(0x63); - einkPrvDeselect(); - - einkPrvCmd(0x0c); // they send 8f 8f 8f 3f - einkPrvData(0x8f); - einkPrvData(0x8f); - einkPrvData(0x8f); - einkPrvData(0x3f); - einkPrvDeselect(); - - einkPrvCmd(0x01); - einkPrvData((SCREEN_HEIGHT - 1) & 0xff); - einkPrvData((SCREEN_HEIGHT - 1) >> 8); - einkPrvData(0x00); - einkPrvDeselect(); - - einkPrvCmdWithOneByte(0x1103); - - einkPrvCmd(0x44); - einkPrvData(0x00); - einkPrvData(SCREEN_WIDTH / 8 - 1); - einkPrvDeselect(); - - einkPrvCmd(0x45); - einkPrvData(0x00); - einkPrvData(0x00); - einkPrvData((SCREEN_HEIGHT - 1) & 0xff); - einkPrvData((SCREEN_HEIGHT - 1) >> 8); - einkPrvDeselect(); - - einkPrvCmdWithOneByte(0x3cc0); // border will be HiZ - - einkPrvCmdWithOneByte(0x1880); // internal temp sensor - - einkPrvCmdWithOneByte(0x2108); - // turn on clock & analog - einkPrvCmdWithOneByte(0x22B1); - einkPrvCmd(0x20); // do action - einkPrvDeselect(); - einkPrvWaitWithTimeout(TIMER_TICKS_PER_SECOND); -} - -#pragma callee_saves screenPrvDraw -static void screenPrvDraw(void) -{ - /* einkPrvCmd(0x01); - einkPrvData(0x40); - einkPrvData(0x00); - einkPrvData(0x00); - einkPrvDeselect(); - - - einkPrvCmd(0x0f); - einkPrvData(0x64); - einkPrvData(0x00); - einkPrvDeselect(); - */ - - einkPrvCmdWithOneByte(0x3a16); -// einkPrvCmdWithOneByte(0x3b0f); - - - - einkPrvCmdWithOneByte(0x2200 | SCREEN_CMD_REFRESH); - einkPrvCmd(0x20); // do actions - if (1) - { - einkPrvWaitWithTimeoutSleep(1000 * 60UL); - screenSleep(); - } - else - { - einkPrvWaitWithTimeout(TIMER_TICKS_PER_SECOND * 60UL); - } -} - -__bit screenTxStart(__bit forPartial) -{ - screenInitIfNeeded(forPartial); - mPassNo = 0; - - screenPrvStartSubPhase(false); - - return true; -} - -void screenEndPass(void) -{ - switch (mPassNo) - { - case 0: - screenPrvStartSubPhase(true); - break; - default: - return; - } - mPassNo++; -} - -void screenTxEnd(void) -{ - screenPrvDraw(); - //screenShutdown(); -} - -void screenShutdown(void) -{ - if (!mInited) - return; - - mInited = false; - einkPrvCmdWithOneByte(0x1003); // shut down -} - -void screenSleep(void) -{ - P2_0 = 0; - timerDelay(TIMER_TICKS_PER_SECOND / 250); - P2_0 = 1; - timerDelay(TIMER_TICKS_PER_SECOND / 250); - - einkPrvCmd(0x12); // software reset - einkPrvDeselect(); - einkPrvWaitWithTimeout(TIMER_TICKS_PER_SECOND); - - einkPrvCmdWithOneByte(0x1003); // shut down -} - -#pragma callee_saves screenByteTx -void screenByteTx(uint8_t byte) -{ - static uint8_t __xdata prev, step = 0; - - prev <<= 2; - prev |= (mColorMap[mPassNo][byte >> 4] << 1) | mColorMap[mPassNo][byte & 0x0f]; - if (++step == 4) - { - step = 0; - einkPrvSelect(); - einkPrvData(prev); - einkPrvDeselect(); - } -} - -// yes this is here... -uint16_t adcSampleBattery(void) -{ - __bit wasInited = mInited; - uint16_t voltage = 2600; - - if (!mInited) - screenInitIfNeeded(false); - - uint8_t val; - - einkPrvCmdWithOneByte(0x2200 | SCREEN_CMD_CLOCK_ON | SCREEN_CMD_ANALOG_ON); - einkPrvCmd(0x20); // do action - einkPrvDeselect(); - einkPrvWaitWithTimeout(TIMER_TICKS_PER_SECOND); - - for (val = 3; val < 8; val++) - { - - einkPrvCmdWithOneByte(0x1500 + val); - einkPrvWaitWithTimeout(TIMER_TICKS_PER_SECOND); - if (einkPrvReadStatus() & 0x10) - { // set if voltage is less than threshold ( == 1.9 + val / 10) - voltage = 1850 + mathPrvMul8x8(val, 100); - break; - } - } - - einkPrvCmdWithOneByte(0x22B1); - einkPrvCmd(0x20); // do action - einkPrvDeselect(); - einkPrvWaitWithTimeout(TIMER_TICKS_PER_SECOND); - - if (!wasInited) - screenShutdown(); - - return voltage; -} diff --git a/tag_fw/board/zbs42v033/screen.c b/tag_fw/board/zbs42v033/screen.c deleted file mode 100644 index eb36fdea..00000000 --- a/tag_fw/board/zbs42v033/screen.c +++ /dev/null @@ -1,416 +0,0 @@ -#include -#include "asmUtil.h" -#include "screen.h" -#include "printf.h" -#include "board.h" -#include "timer.h" -#include "sleep.h" -#include "adc.h" -#include "cpu.h" -#include "spi.h" - -uint8_t __xdata mScreenRow[320]; - -static __bit mInited = false, mPartial; -static uint8_t __xdata mPassNo; - - -#define SCREEN_CMD_CLOCK_ON 0x80 -#define SCREEN_CMD_CLOCK_OFF 0x01 - -#define SCREEN_CMD_ANALOG_ON 0x40 -#define SCREEN_CMD_ANALOG_OFF 0x02 - -#define SCREEN_CMD_LATCH_TEMPERATURE_VAL 0x20 - -#define SCREEN_CMD_LOAD_LUT 0x10 -#define SCREEN_CMD_USE_MODE_2 0x08 //modified commands 0x10 and 0x04 - -#define SCREEN_CMD_REFRESH 0xC7 - -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) - } -}; - - - -#define einkPrvSelect() \ - do{ \ - P1_7 = 0; \ - } while (0) - -#define einkPrvDeselect() \ - do{ \ - P1_7 = 1; \ - } while (0) -//urx pin -#define einkPrvMarkCommand() \ - do{ \ - P2_2 = 0; \ - } while (0) - -#define einkPrvMarkData() \ - do{ \ - P2_2 = 1; \ - } while (0) - - - -#pragma callee_saves einkPrvCmd -static void einkPrvCmd(uint8_t cmd) //sets chip select -{ - einkPrvSelect(); - einkPrvMarkCommand(); - spiByte(cmd); -} - -#pragma callee_saves einkPrvData -static void einkPrvData(uint8_t byte) -{ - einkPrvMarkData(); - spiByte(byte); -} - -#pragma callee_saves einkPrvCmdWithOneByte -static void einkPrvCmdWithOneByte(uint16_t vals) //passing in one u16 is better than two params cause SDCC sucks -{ - einkPrvCmd(vals >> 8); - einkPrvData(vals); - einkPrvDeselect(); -} - -#pragma callee_saves einkPrvWaitWithTimeout -static void einkPrvWaitWithTimeout(uint32_t timeout) -{ - uint32_t __xdata start = timerGet(); - - while (timerGet() - start < timeout) { - - if (!P2_1) - return; - } - pr("screen timeout %lu ticks\n", timerGet() - start); - while(1); -} - -#pragma callee_saves einkPrvWaitWithTimeout -static void einkPrvWaitWithTimeoutSleep(uint32_t timeout) -{ - uint8_t tmp_P2FUNC = P2FUNC; - uint8_t tmp_P2DIR = P2DIR; - uint8_t tmp_P2PULL = P2PULL; - uint8_t tmp_P2LVLSEL = P2LVLSEL; - P2FUNC &= 0xfd; - P2DIR |= 2; - P2PULL |= 2; - P2LVLSEL |= 2; - - P2CHSTA &= 0xfd; - P2INTEN |= 2; - P2CHSTA &= 0xfd; - sleepForMsec(timeout); - P2CHSTA &= 0xfd; - P2INTEN &= 0xfd; - - P2FUNC = tmp_P2FUNC; - P2DIR = tmp_P2DIR; - P2PULL = tmp_P2PULL; - P2LVLSEL = tmp_P2LVLSEL; - /*if (!P2_1) - return; - - pr("screen timeout\n"); - while(1);*/ -} - -#pragma callee_saves einkPrvReadByte -static uint8_t einkPrvReadByte(void) -{ - uint8_t val = 0, i; - - P0DIR = (P0DIR &~ (1 << 0)) | (1 << 1); - P0 &=~ (1 << 0); - P0FUNC &=~ ((1 << 0) | (1 << 1)); - - P2_2 = 1; - - for (i = 0; i < 8; i++) { - P0_0 = 1; - __asm__("nop\nnop\nnop\nnop\nnop\n"); - val <<= 1; - if (P0_1) - val++; - P0_0 = 0; - __asm__("nop\nnop\nnop\nnop\nnop\n"); - } - - - //set up pins for spi (0.0,0.1,0.2) - P0FUNC |= (1 << 0) | (1 << 1); - - return val; -} - -#pragma callee_saves einkPrvReadStatus -static uint8_t einkPrvReadStatus(void) -{ - uint8_t sta; - einkPrvCmd(0x2f); - - sta = einkPrvReadByte(); - einkPrvDeselect(); - - return sta; -} - -#pragma callee_saves screenPrvStartSubPhase -static void screenPrvStartSubPhase(__bit redSubphase) -{ - einkPrvCmd(0x4e); - einkPrvData(0x00); - einkPrvDeselect(); - - einkPrvCmd(0x4f); - einkPrvData(0x2b); - einkPrvData(0x01); - einkPrvDeselect(); - - einkPrvCmd(redSubphase ? 0x26 : 0x24); - - einkPrvDeselect(); -} - -#pragma callee_saves screenInitIfNeeded -static void screenInitIfNeeded(__bit forPartial) -{ - if (mInited) - return; - - mInited = true; - mPartial = forPartial; - pr("init 4.2 screen\n"); - timerDelay(TIMER_TICKS_PER_SECOND / 1000); - P2_0 = 0; - timerDelay(TIMER_TICKS_PER_SECOND / 1000); - P2_0 = 1; - timerDelay(TIMER_TICKS_PER_SECOND / 1000); - - einkPrvCmd(0x12); //software reset - einkPrvDeselect(); - timerDelay(TIMER_TICKS_PER_SECOND); - - einkPrvCmdWithOneByte(0x7454); - - einkPrvCmdWithOneByte(0x7e3b); - - einkPrvCmd(0x2b); - einkPrvData(0x04); - einkPrvData(0x63); - einkPrvDeselect(); - - einkPrvCmd(0x0c); //they send 8f 8f 8f 3f - einkPrvData(0x8f); - einkPrvData(0x8f); - einkPrvData(0x8f); - einkPrvData(0x3f); - einkPrvDeselect(); - - einkPrvCmd(0x01); - einkPrvData(0x2b); - einkPrvData(0x01); - einkPrvData(0x01); - einkPrvDeselect(); - - einkPrvCmdWithOneByte(0x1101); - einkPrvDeselect(); - - - einkPrvCmdWithOneByte(0x2200 | SCREEN_CMD_CLOCK_ON | SCREEN_CMD_ANALOG_ON); - einkPrvCmd(0x20); - einkPrvDeselect(); - - einkPrvWaitWithTimeout(TIMER_TICKS_PER_SECOND * 10); - - - einkPrvCmd(0x44); - einkPrvData(0x00); - einkPrvData(0x31); - einkPrvDeselect(); - - einkPrvCmd(0x45); - einkPrvData(0x2b); - einkPrvData(0x01); - einkPrvData(0x00); - einkPrvData(0x00); - einkPrvDeselect(); - - //einkPrvCmdWithOneByte(0x3c01); //border will be HiZ - einkPrvCmdWithOneByte(0x3cc0); //border will be HiZ - einkPrvDeselect(); - einkPrvCmdWithOneByte(0x1880); //internal temp sensor - einkPrvDeselect(); - - einkPrvCmdWithOneByte(0x2108); - //turn on clock & analog - einkPrvCmdWithOneByte(0x22B1); - einkPrvCmd(0x20); //do action - einkPrvDeselect(); - einkPrvWaitWithTimeout(TIMER_TICKS_PER_SECOND); - - /*einkPrvCmd(0x32); - einkPrvData(0x00); einkPrvData(0x90); einkPrvData(0x00); einkPrvData(0x00); - einkPrvData(0x00); einkPrvData(0x00); einkPrvData(0x00); einkPrvData(0x00); - einkPrvData(0x90); einkPrvData(0x00); einkPrvData(0x00); einkPrvData(0x00); - einkPrvData(0x00); einkPrvData(0x00); einkPrvData(0x00); einkPrvData(0x90); - - einkPrvData(0x00); einkPrvData(0x00); einkPrvData(0x00); einkPrvData(0x00); - einkPrvData(0x00); einkPrvData(0x00); einkPrvData(0x90); einkPrvData(0x00); - einkPrvData(0x00); einkPrvData(0x00); einkPrvData(0x00); einkPrvData(0x00); - einkPrvData(0x00); einkPrvData(0x00); einkPrvData(0x00); einkPrvData(0x00); - - einkPrvData(0x00); einkPrvData(0x00); einkPrvData(0x00); einkPrvData(0x00); - einkPrvData(0x00); einkPrvData(0x00); einkPrvData(0x00); einkPrvData(0x00); - einkPrvData(0x27); einkPrvData(0x27); einkPrvData(0x00); einkPrvData(0x00); - einkPrvData(0x01); einkPrvData(0x00); einkPrvData(0x00); einkPrvData(0x00); - - einkPrvData(0x00); einkPrvData(0x00); einkPrvData(0x00); einkPrvData(0x00); - einkPrvData(0x00); einkPrvData(0x00); einkPrvData(0x00); einkPrvData(0x00); - einkPrvData(0x00); einkPrvData(0x00); einkPrvData(0x00); einkPrvData(0x00); - einkPrvData(0x00); einkPrvData(0x00); einkPrvData(0x00); einkPrvData(0x00); - - einkPrvData(0x00); einkPrvData(0x00); einkPrvData(0x00); einkPrvData(0x00); - einkPrvData(0x00); einkPrvData(0x00); einkPrvData(0x15); einkPrvData(0x41); - einkPrvData(0xce); einkPrvData(0x32); einkPrvData(0x0f); einkPrvData(0x0c); - einkPrvDeselect(); - */ - - -} - -#pragma callee_saves screenPrvDraw -static void screenPrvDraw(void) -{ - einkPrvCmdWithOneByte(0x2200 | SCREEN_CMD_REFRESH); - einkPrvCmd(0x20); //do actions - if (1) - { - einkPrvWaitWithTimeoutSleep(1000 * 60UL); - screenSleep(); - } - else - { - einkPrvWaitWithTimeout(TIMER_TICKS_PER_SECOND * 60UL); - } -} - -__bit screenTxStart(__bit forPartial) -{ - screenInitIfNeeded(forPartial); - mPassNo = 0; - - screenPrvStartSubPhase(false); - - return true; -} - -void screenEndPass(void) -{ - switch (mPassNo) { - case 0: - screenPrvStartSubPhase(true); - break; - default: - return; - } - mPassNo++; -} - -void screenTxEnd(void) -{ - screenPrvDraw(); - screenShutdown(); -} - -void screenShutdown(void) -{ - if (!mInited) - return; - - mInited = false; - einkPrvCmdWithOneByte(0x1003); //shut down -} - -void screenSleep(void) -{ - P2_0 = 0; - timerDelay(20); - P2_0 = 1; - timerDelay(80); - - einkPrvCmd(0x12); // software reset - einkPrvDeselect(); - einkPrvWaitWithTimeout(TIMER_TICKS_PER_SECOND/250); - - einkPrvCmdWithOneByte(0x1003); // shut down -} - - -#pragma callee_saves screenByteTx -void screenByteTx(uint8_t byte) -{ - static uint8_t __xdata prev, step = 0; - - prev <<= 2; - prev |= (mColorMap[mPassNo][byte >> 4] << 1) | mColorMap[mPassNo][byte & 0x0f]; - if (++step == 4) { - step = 0; - einkPrvSelect(); - einkPrvData(prev); - einkPrvDeselect(); - } -} - -//yes this is here... -uint16_t adcSampleBattery(void) -{ - __bit wasInited = mInited; - uint16_t voltage = 2600; - - if (!mInited) - screenInitIfNeeded(false); - - uint8_t val; - - einkPrvCmdWithOneByte(0x2200 | SCREEN_CMD_CLOCK_ON | SCREEN_CMD_ANALOG_ON); - einkPrvCmd(0x20); //do action - einkPrvDeselect(); - einkPrvWaitWithTimeout(TIMER_TICKS_PER_SECOND); - - for (val = 3; val < 8; val++) { - - einkPrvCmdWithOneByte(0x1500 + val); - einkPrvWaitWithTimeout(TIMER_TICKS_PER_SECOND); - if (einkPrvReadStatus() & 0x10) {//set if voltage is less than threshold ( == 1.9 + val / 10) - voltage = 1850 + mathPrvMul8x8(val, 100); - break; - } - } - - einkPrvCmdWithOneByte(0x22B1); - einkPrvCmd(0x20); //do action - einkPrvDeselect(); - einkPrvWaitWithTimeout(TIMER_TICKS_PER_SECOND); - - if (!wasInited) - screenShutdown(); - - return voltage; -} diff --git a/tag_fw/chars.c b/tag_fw/chars.c deleted file mode 100644 index c7ba9f26..00000000 --- a/tag_fw/chars.c +++ /dev/null @@ -1,182 +0,0 @@ -#include "asmUtil.h" -#include "printf.h" -#include "screen.h" -#include "chars.h" -#include "cpu.h" - -#define CANVAS_FLIP_H 0 -#define CANVAS_MSB_FIRST 1 - -#define NUM_CHARS (0x64) -#define FIRST_CHAR (0x1c) -#define MISSING_CHAR ('?') - -static const uint8_t __code mCharsImgs[]; - -//special RAM area that is not preserved across sleep - -#pragma callee_saves charsPrvDrawCharRow -static void charsPrvDrawCharRow(uint8_t ch, int16_t x, uint8_t imgRow, uint8_t foreColor, uint8_t backColor, uint8_t mag) __reentrant /* save pseg */ -{ - uint8_t c, mc, charRow = imgRow / mag, bitMask = (1 << SCREEN_TX_BPP) - 1; - const uint8_t __code *imgInfoBuf; - - if (ch < FIRST_CHAR || ch - FIRST_CHAR >= NUM_CHARS) - ch = MISSING_CHAR; - - ch -= FIRST_CHAR; - - //get pointer to proper char row - imgInfoBuf = mCharsImgs + (uint16_t)mathPrvMul16x8((CHAR_WIDTH * NUM_CHARS + 7) / 8, charRow) + mathPrvMul8x8(CHAR_WIDTH, ch) / 8; - - for (c = 0; c < CHAR_WIDTH; c++) { //iterate over the char's columns for this row - - uint8_t imgCol = ((uint8_t)((uint8_t)CHAR_WIDTH * (uint8_t)ch) & 7) + c; //sort out where in the row our data begins - uint8_t color = ((imgInfoBuf[imgCol >> 3] >> (7 - (imgCol % 8))) & 1) ? foreColor : backColor; //get the color - - if (color == CHAR_COLOR_TRANSPARENT) - continue; - - for (mc = 0; mc < mag; mc++, x++) { //set the pixel - - uint8_t __xdata *dst = mScreenRow; - uint8_t bitOfst; - uint16_t c = x; - - if (x < 0) - continue; - if (x >= SCREEN_WIDTH) - break; - - #if CANVAS_FLIP_H - c = SCREEN_WIDTH - c - 1; - #endif - - dst += mathPrvMul16x8(c, SCREEN_TX_BPP) / 8; - bitOfst = mathPrvMul16x8(c, SCREEN_TX_BPP) % 8; - - #if CANVAS_MSB_FIRST - bitOfst = 8 - bitOfst - SCREEN_TX_BPP; - #endif - - *dst = ((*dst) & ~(bitMask << bitOfst)) | ((color & bitMask) << bitOfst); - } - } -} - -void charsDrawString(const struct CharDrawingParams __xdata *params) -{ - const char *__xdata s = params->str; - int16_t x = params->x; - uint8_t ch; - - while ((ch = charsPrvDerefAndIncGenericPtr(&s)) != 0) { - - charsPrvDrawCharRow(ch, x, params->imgRow, params->foreColor, params->backColor, params->magnify); - x += (uint16_t)(uint8_t)(CHAR_WIDTH * params->magnify); - } -} - -static const uint8_t __code mCharsImgs[] = { - - 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, - 0x18, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x18, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xf0, 0x0f, 0xdc, - 0x00, 0x18, 0x7e, 0x36, 0x3c, 0xd8, 0x38, 0x1c, 0x0c, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, - 0x1e, 0x0c, 0x3c, 0x3c, 0x30, 0x7e, 0x1c, 0x7e, 0x3c, 0x3c, 0x00, 0x00, 0x06, 0x00, 0x60, 0x3c, - 0x7e, 0x18, 0x7c, 0x3c, 0x78, 0x7e, 0x7e, 0x3c, 0x66, 0x3c, 0x06, 0x66, 0x60, 0x63, 0x63, 0x3c, - 0x7c, 0x3c, 0x7c, 0x3c, 0x7e, 0x66, 0x66, 0x63, 0x66, 0x66, 0x7e, 0x3c, 0x60, 0x3c, 0x66, 0x00, - 0x0c, 0x00, 0x60, 0x00, 0x06, 0x00, 0x1e, 0x00, 0x60, 0x18, 0x0c, 0x60, 0x78, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x71, 0x00, - 0x30, 0x0c, 0x30, 0x38, 0x00, 0x3c, 0x7e, 0x36, 0x66, 0xda, 0x6c, 0x1c, 0x18, 0x18, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x06, 0x33, 0x1c, 0x66, 0x66, 0x30, 0x60, 0x18, 0x06, 0x66, 0x66, 0x00, 0x00, - 0x0c, 0x00, 0x30, 0x66, 0xc3, 0x3c, 0x66, 0x66, 0x6c, 0x60, 0x60, 0x66, 0x66, 0x18, 0x06, 0x66, - 0x60, 0x63, 0x63, 0x66, 0x66, 0x66, 0x66, 0x66, 0x18, 0x66, 0x66, 0x63, 0x66, 0x66, 0x06, 0x30, - 0x60, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x06, 0x00, 0x30, 0x00, 0x60, 0x00, 0x00, 0x60, - 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, - 0x18, 0x18, 0xdb, 0x00, 0x40, 0x02, 0x40, 0x72, 0x00, 0x3c, 0x7e, 0x7f, 0x60, 0x76, 0x6c, 0x0c, - 0x18, 0x18, 0x36, 0x18, 0x00, 0x00, 0x00, 0x0c, 0x37, 0x7c, 0x66, 0x66, 0x36, 0x60, 0x30, 0x0c, - 0x66, 0x66, 0x1c, 0x1c, 0x18, 0x00, 0x18, 0x66, 0xc3, 0x66, 0x66, 0x66, 0x66, 0x60, 0x60, 0x66, - 0x66, 0x18, 0x06, 0x6c, 0x60, 0x77, 0x73, 0x66, 0x66, 0x66, 0x66, 0x60, 0x18, 0x66, 0x66, 0x63, - 0x34, 0x66, 0x06, 0x30, 0x30, 0x0c, 0x00, 0x00, 0x00, 0x3c, 0x7c, 0x3c, 0x3e, 0x3c, 0x30, 0x3e, - 0x7c, 0x78, 0x3c, 0x66, 0x18, 0x7e, 0x7c, 0x3c, 0x7c, 0x3e, 0x66, 0x3e, 0x7e, 0x66, 0x66, 0x63, - 0x66, 0x66, 0x7e, 0x18, 0x18, 0x18, 0x8e, 0x00, 0x87, 0xe1, 0x86, 0xe1, 0x00, 0x3c, 0x7e, 0x36, - 0x30, 0x0c, 0x38, 0x18, 0x30, 0x0c, 0x1c, 0x18, 0x00, 0x00, 0x00, 0x0c, 0x37, 0x0c, 0x06, 0x06, - 0x36, 0x60, 0x7c, 0x0c, 0x76, 0x66, 0x1c, 0x1c, 0x30, 0x7e, 0x0c, 0x0c, 0xcf, 0x66, 0x66, 0x60, - 0x66, 0x60, 0x60, 0x60, 0x66, 0x18, 0x06, 0x6c, 0x60, 0x6b, 0x7b, 0x66, 0x66, 0x66, 0x66, 0x30, - 0x18, 0x66, 0x66, 0x6b, 0x18, 0x66, 0x0c, 0x30, 0x30, 0x0c, 0x00, 0x00, 0x00, 0x06, 0x66, 0x66, - 0x66, 0x66, 0x30, 0x66, 0x66, 0x18, 0x0c, 0x66, 0x18, 0x6b, 0x66, 0x66, 0x66, 0x66, 0x6e, 0x60, - 0x30, 0x66, 0x66, 0x6b, 0x66, 0x66, 0x06, 0x18, 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x19, 0xd8, - 0x00, 0x18, 0x7e, 0x36, 0x18, 0x18, 0x60, 0x00, 0x30, 0x0c, 0x7f, 0x7e, 0x00, 0x7e, 0x00, 0x18, - 0x33, 0x0c, 0x0c, 0x1c, 0x36, 0x7c, 0x66, 0x18, 0x3c, 0x66, 0x00, 0x00, 0x60, 0x00, 0x06, 0x18, - 0xdb, 0x66, 0x7c, 0x60, 0x66, 0x7c, 0x7c, 0x60, 0x7e, 0x18, 0x06, 0x78, 0x60, 0x6b, 0x6f, 0x66, - 0x7c, 0x66, 0x7c, 0x18, 0x18, 0x66, 0x66, 0x6b, 0x18, 0x3c, 0x18, 0x30, 0x18, 0x0c, 0x00, 0x00, - 0x00, 0x06, 0x66, 0x60, 0x66, 0x66, 0x7e, 0x66, 0x66, 0x18, 0x0c, 0x6c, 0x18, 0x6b, 0x66, 0x66, - 0x66, 0x66, 0x70, 0x60, 0x30, 0x66, 0x66, 0x6b, 0x3c, 0x66, 0x0c, 0x30, 0x18, 0x0c, 0x00, 0x00, - 0x20, 0x04, 0x23, 0x84, 0x00, 0x18, 0x7e, 0x36, 0x0c, 0x30, 0x6f, 0x00, 0x30, 0x0c, 0x1c, 0x18, - 0x00, 0x00, 0x00, 0x18, 0x3b, 0x0c, 0x18, 0x06, 0x66, 0x06, 0x66, 0x18, 0x6e, 0x3e, 0x00, 0x00, - 0x30, 0x7e, 0x0c, 0x18, 0xdb, 0x7e, 0x66, 0x60, 0x66, 0x60, 0x60, 0x6e, 0x66, 0x18, 0x06, 0x6c, - 0x60, 0x6b, 0x67, 0x66, 0x60, 0x66, 0x6c, 0x0c, 0x18, 0x66, 0x66, 0x6b, 0x2c, 0x18, 0x30, 0x30, - 0x18, 0x0c, 0x00, 0x00, 0x00, 0x3e, 0x66, 0x60, 0x66, 0x7e, 0x30, 0x66, 0x66, 0x18, 0x0c, 0x78, - 0x18, 0x6b, 0x66, 0x66, 0x66, 0x66, 0x60, 0x3c, 0x30, 0x66, 0x66, 0x6b, 0x18, 0x66, 0x18, 0x60, - 0x18, 0x06, 0x00, 0x00, 0x41, 0x82, 0x47, 0x02, 0x00, 0x00, 0x7e, 0x7f, 0x06, 0x6e, 0x66, 0x00, - 0x30, 0x0c, 0x36, 0x18, 0x00, 0x00, 0x00, 0x30, 0x3b, 0x0c, 0x30, 0x66, 0x7f, 0x06, 0x66, 0x30, - 0x66, 0x0c, 0x00, 0x00, 0x18, 0x00, 0x18, 0x00, 0xcf, 0x66, 0x66, 0x66, 0x66, 0x60, 0x60, 0x66, - 0x66, 0x18, 0x66, 0x6c, 0x60, 0x63, 0x63, 0x66, 0x60, 0x66, 0x66, 0x06, 0x18, 0x66, 0x66, 0x36, - 0x66, 0x18, 0x60, 0x30, 0x0c, 0x0c, 0x00, 0x00, 0x00, 0x66, 0x66, 0x60, 0x66, 0x60, 0x30, 0x66, - 0x66, 0x18, 0x0c, 0x6c, 0x18, 0x6b, 0x66, 0x66, 0x66, 0x66, 0x60, 0x06, 0x30, 0x66, 0x66, 0x6b, - 0x3c, 0x66, 0x30, 0x30, 0x18, 0x0c, 0x00, 0x00, 0x86, 0x61, 0x8e, 0x61, 0x00, 0x18, 0x7e, 0x36, - 0x66, 0x5b, 0x66, 0x00, 0x30, 0x0c, 0x00, 0x00, 0x1c, 0x00, 0x1c, 0x30, 0x33, 0x0c, 0x60, 0x66, - 0x06, 0x0c, 0x66, 0x30, 0x66, 0x18, 0x1c, 0x1c, 0x0c, 0x00, 0x30, 0x18, 0xc0, 0x66, 0x66, 0x66, - 0x6c, 0x60, 0x60, 0x66, 0x66, 0x18, 0x66, 0x66, 0x60, 0x63, 0x63, 0x66, 0x60, 0x66, 0x66, 0x66, - 0x18, 0x66, 0x3c, 0x36, 0x66, 0x18, 0x60, 0x30, 0x0c, 0x0c, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, - 0x66, 0x60, 0x30, 0x66, 0x66, 0x18, 0x0c, 0x66, 0x18, 0x6b, 0x66, 0x66, 0x66, 0x66, 0x60, 0x06, - 0x30, 0x66, 0x3c, 0x36, 0x66, 0x66, 0x60, 0x18, 0x18, 0x18, 0x00, 0x00, 0x88, 0x11, 0x9c, 0x11, - 0x00, 0x18, 0x7e, 0x36, 0x3c, 0x1b, 0x3b, 0x00, 0x18, 0x18, 0x00, 0x00, 0x1c, 0x00, 0x1c, 0x60, - 0x1e, 0x0c, 0x7e, 0x3c, 0x06, 0x78, 0x3c, 0x30, 0x3c, 0x38, 0x1c, 0x1c, 0x06, 0x00, 0x60, 0x18, - 0x7f, 0x66, 0x7c, 0x3c, 0x78, 0x7e, 0x60, 0x3e, 0x66, 0x3c, 0x3c, 0x66, 0x7e, 0x63, 0x63, 0x3c, - 0x60, 0x3c, 0x66, 0x3c, 0x18, 0x3c, 0x18, 0x36, 0x66, 0x18, 0x7e, 0x30, 0x06, 0x0c, 0x00, 0x00, - 0x00, 0x3e, 0x7c, 0x3c, 0x3e, 0x3c, 0x30, 0x3e, 0x66, 0x7e, 0x0c, 0x66, 0x7e, 0x63, 0x66, 0x3c, - 0x7c, 0x3e, 0x60, 0x7c, 0x1e, 0x3e, 0x18, 0x36, 0x66, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x00, 0x00, - 0x10, 0x08, 0x38, 0x08, 0x00, 0x00, 0x00, 0x00, 0x18, 0x0e, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, - 0x0c, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, - 0x06, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x0c, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x18, - 0x18, 0x18, 0x00, 0x00, 0x11, 0x88, 0x71, 0x88, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, - 0x0c, 0x30, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x30, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, - 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x18, 0x00, 0x0c, 0x18, 0x30, 0x00, 0x00, 0x03, 0xc0, 0xe3, 0xc0, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x3c, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x06, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x03, 0xc0, 0x43, 0xc0, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -}; \ No newline at end of file diff --git a/tag_fw/chars.h b/tag_fw/chars.h deleted file mode 100644 index 176968d6..00000000 --- a/tag_fw/chars.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef _CHARS_H_ -#define _CHARS_H_ - -#include -#include - - -#define CHAR_WIDTH 8 -#define CHAR_HEIGHT 16 - -#define CHAR_COLOR_TRANSPARENT (0xff) - -#define CHAR_SIGNAL_PT1 (0x1c) -#define CHAR_SIGNAL_PT2 (0x1d) - -#define CHAR_NO_SIGNAL_PT1 (0x1e) -#define CHAR_NO_SIGNAL_PT2 (0x1f) - -struct CharDrawingParams { - const char *str; - int16_t x; - uint8_t imgRow; - uint8_t foreColor; - uint8_t backColor; - uint8_t magnify; -}; - -//draws to screen the rows of this string. will draw 16 * magnify rows -void charsDrawString(const struct CharDrawingParams __xdata *params); - - -#endif diff --git a/tag_fw/drawing.c b/tag_fw/drawing.c index ce97dead..1c91b4bc 100644 --- a/tag_fw/drawing.c +++ b/tag_fw/drawing.c @@ -1,13 +1,10 @@ #include -// #include "datamatrix.h" -#include "adc.h" #include "asmUtil.h" -#include "barcode.h" #include "board.h" -#include "chars.h" #include "cpu.h" #include "drawing.h" #include "eeprom.h" +#include "epd.h" #include "printf.h" #include "screen.h" #include "timer.h" @@ -57,6 +54,16 @@ struct BitmapDrawInfo { 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; @@ -247,7 +254,7 @@ static void drawPrvDecodeImageOnce(void) { if (emit) { emit = false; - screenByteTx(txPrev | val); + ByteDecode(txPrev | val); nBytesOut++; txPrev = 0; } else { @@ -260,7 +267,7 @@ static void drawPrvDecodeImageOnce(void) { bitpoolOut |= val; bitpoolOutUsedUsed += SCREEN_TX_BPP; if (bitpoolOutUsedUsed >= 8) { - screenByteTx(bitpoolOut >> (bitpoolOutUsedUsed -= 8)); + ByteDecode(bitpoolOut >> (bitpoolOutUsedUsed -= 8)); bitpoolOut &= (1 << bitpoolOutUsedUsed) - 1; nBytesOut++; } @@ -272,14 +279,14 @@ static void drawPrvDecodeImageOnce(void) { #if SCREEN_TX_BPP == 4 if (emit) { - screenByteTx(txPrev); + ByteDecode(txPrev); nBytesOut++; } #else if (bitpoolOutUsedUsed) { - screenByteTx(bitpoolOut); + ByteDecode(bitpoolOut); nBytesOut++; } @@ -288,7 +295,7 @@ static void drawPrvDecodeImageOnce(void) { // if we did not produce enough bytes, do so nBytesOut = ((long)SCREEN_WIDTH * SCREEN_TX_BPP + 7) / 8 - nBytesOut; while (nBytesOut--) - screenByteTx(SCREEN_BYTE_FILL); + ByteDecode(SCREEN_BYTE_FILL); // update row if (mDrawInfo.bottomUp) { @@ -306,13 +313,25 @@ static void drawPrvDecodeImageOnce(void) { // 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--) { - screenByteTx(SCREEN_BYTE_FILL); + ByteDecode(SCREEN_BYTE_FILL); } } } extern uint8_t blockXferBuffer[]; +void ByteDecode(uint8_t byte) { + static uint8_t __xdata prev, step = 0; + prev <<= 2; + prev |= (mColorMap[mPassNo][byte >> 4] << 1) | mColorMap[mPassNo][byte & 0x0f]; + if (++step == 4) { + step = 0; + epdSelect(); + epdSend(prev); + epdDeselect(); + } +} + void drawImageAtAddress(uint32_t addr) { uint32_t __xdata clutAddr; uint8_t __xdata iter; @@ -322,105 +341,20 @@ void drawImageAtAddress(uint32_t addr) { return; drawPrvLoadAndMapClut(clutAddr); - screenTxStart(false); - for (iter = 0; iter < SCREEN_DATA_PASSES; iter++) { - pr("."); - drawPrvDecodeImageOnce(); - screenEndPass(); - } + //screenTxStart(false); + epdSetup(); + mPassNo = 0; + beginFullscreenImage(); + beginWriteFramebuffer(EPD_COLOR_BLACK); + drawPrvDecodeImageOnce(); + endWriteFramebuffer(); + mPassNo++; + beginWriteFramebuffer(EPD_COLOR_RED); + drawPrvDecodeImageOnce(); + endWriteFramebuffer(); + pr(" complete.\n"); - screenTxEnd(); - screenShutdown(); -} - -#pragma callee_saves myStrlen -static uint16_t myStrlen(const char *str) { - const char *__xdata strP = str; - - while (charsPrvDerefAndIncGenericPtr(&strP)) - ; - - return strP - str; -} - -void drawFullscreenMsg(const char *str) { - volatile uint16_t PDATA textRow, textRowEnd; // without volatile, compiler ignores "__pdata" - struct CharDrawingParams __xdata cdp; - uint8_t __xdata rowIdx; - uint8_t iteration; - uint16_t i, r; - - getVolt(); - pr("MESSAGE '%s'\n", str); - screenTxStart(false); - - for (iteration = 0; iteration < SCREEN_DATA_PASSES; iteration++) { - __bit inBarcode = false; - rowIdx = 0; - - cdp.magnify = UI_MSG_MAGNIFY1; - cdp.str = str; - cdp.x = mathPrvI16Asr1(SCREEN_WIDTH - mathPrvMul8x8(CHAR_WIDTH * cdp.magnify, myStrlen(cdp.str))); - - cdp.foreColor = UI_MSG_FORE_COLOR_1; - cdp.backColor = UI_MSG_BACK_COLOR; - - textRow = 5; - textRowEnd = textRow + (uint8_t)((uint8_t)CHAR_HEIGHT * (uint8_t)cdp.magnify); - - for (r = 0; r < SCREEN_HEIGHT; r++) { - // clear the row - for (i = 0; i < SCREEN_WIDTH * SCREEN_TX_BPP / 8; i++) - mScreenRow[i] = SCREEN_BYTE_FILL; - - if (r >= textRowEnd) { - switch (rowIdx) { - case 0: - rowIdx = 1; - textRow = textRowEnd + 3; - cdp.magnify = UI_MSG_MAGNIFY2; - cdp.foreColor = UI_MSG_FORE_COLOR_2; - // cdp.str = macSmallString(); - cdp.x = 0; - textRowEnd = textRow + CHAR_HEIGHT * cdp.magnify; - break; - - case 1: - rowIdx = 2; - textRow = SCREEN_HEIGHT - CHAR_HEIGHT - CHAR_HEIGHT; - cdp.magnify = UI_MSG_MAGNIFY3; - cdp.foreColor = UI_MSG_FORE_COLOR_3; - // cdp.str = voltString(); - cdp.x = 1; - inBarcode = false; - - break; - case 2: - rowIdx = 3; - textRow = SCREEN_HEIGHT - CHAR_HEIGHT; - cdp.magnify = UI_MSG_MAGNIFY3; - cdp.foreColor = UI_MSG_FORE_COLOR_3; - // cdp.str = fwVerString(); - cdp.x = 1; - inBarcode = false; - break; - case 3: - cdp.str = ""; - break; - } - } else if (r > textRow) { - inBarcode = false; - cdp.imgRow = r - textRow; - charsDrawString(&cdp); - } - - for (i = 0; i < SCREEN_WIDTH * SCREEN_TX_BPP / 8; i++) - screenByteTx(mScreenRow[i]); - } - - screenEndPass(); - } - - screenTxEnd(); + draw(); + epdEnterSleep(); } diff --git a/tag_fw/drawing.h b/tag_fw/drawing.h index defc621f..4e216e9e 100644 --- a/tag_fw/drawing.h +++ b/tag_fw/drawing.h @@ -9,26 +9,5 @@ void set_offline(__bit state); #pragma callee_saves drawImageAtAddress void drawImageAtAddress(uint32_t addr); -#pragma callee_saves drawImageAtAddress -void drawFullscreenMsg(const char *str); - - - -//expected external funcs -/* -#pragma callee_saves fwVerString -const char __xdata* fwVerString(void); -#pragma callee_saves voltString -const char __xdata* voltString(void); -void getVolt(); -*/ - -#pragma callee_saves macString -//const char __xdata* macString(void); -#pragma callee_saves macSmallString -//const char __xdata* macSmallString(void); - -extern uint8_t __xdata mSelfMac[]; - #endif diff --git a/tag_fw/eeprom.c b/tag_fw/eeprom.c index 7044ed0e..ab01bbc7 100644 --- a/tag_fw/eeprom.c +++ b/tag_fw/eeprom.c @@ -8,6 +8,8 @@ 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) { @@ -158,27 +160,27 @@ __bit eepromInit(void) uint8_t j; - eepromPrvSfdpRead(*(uint16_t __xdata*)(buf + 4), mScreenRow, 9 * 4); - if ((mScreenRow[0] & 3) != 1) { + eepromPrvSfdpRead(*(uint16_t __xdata*)(buf + 4), tempBufferE, 9 * 4); + if ((tempBufferE[0] & 3) != 1) { pr("SFDP: no 4K ERZ\n"); break; } - if (!(mScreenRow[0] & 0x04)) { + if (!(tempBufferE[0] & 0x04)) { pr("SFDP: no large write buf\n"); break; } - if ((mScreenRow[2] & 0x06)) { + if ((tempBufferE[2] & 0x06)) { pr("SFDP: addr.len != 3\n"); break; } - if (!mScreenRow[1] || mScreenRow[1] == 0xff) { + if (!tempBufferE[1] || tempBufferE[1] == 0xff) { pr("SFDP: 4K ERZ opcode invalid\n"); break; } - mOpcodeErz4K = mScreenRow[1]; + mOpcodeErz4K = tempBufferE[1]; - if (mScreenRow[7] & 0x80) { + if (tempBufferE[7] & 0x80) { pr("SFDP: device too big\n"); break; @@ -187,11 +189,11 @@ __bit eepromInit(void) uint8_t t; - if (t = mScreenRow[7]) + if (t = tempBufferE[7]) mEepromSize = 0x00200000UL; - else if (t = mScreenRow[6]) + else if (t = tempBufferE[6]) mEepromSize = 0x00002000UL; - else if (t = mScreenRow[5]) + else if (t = tempBufferE[5]) mEepromSize = 0x00000020UL; else { pr("SFDP: device so small?!\n"); @@ -206,12 +208,12 @@ __bit eepromInit(void) //get erase opcodes for (j = 0x1c; j < 0x24; j += 2) { - uint8_t instr = mScreenRow[j + 1]; + uint8_t instr = tempBufferE[j + 1]; if (!instr || instr == 0xff) continue; - switch (mScreenRow[j]) { + switch (tempBufferE[j]) { case 0x0c: if (mOpcodeErz4K != instr) { pr("4K ERZ opcode disagreement\n"); diff --git a/tag_fw/epd.c b/tag_fw/epd.c new file mode 100644 index 00000000..06bb23ef --- /dev/null +++ b/tag_fw/epd.c @@ -0,0 +1,539 @@ +#include "epd.h" + +#include +#include + +#include "asmUtil.h" +#include "board.h" +#include "cpu.h" +#include "font.h" +#include "lut.h" +#include "printf.h" +#include "screen.h" +#include "sleep.h" +#include "spi.h" +#include "timer.h" + +#define CMD_DRV_OUTPUT_CTRL 0x01 +#define CMD_SOFT_START_CTRL 0x0C +#define CMD_ENTER_SLEEP 0x10 +#define CMD_DATA_ENTRY_MODE 0x11 +#define CMD_SOFT_RESET 0x12 +#define CMD_SOFT_RESET2 0x13 +#define CMD_SETUP_VOLT_DETECT 0x15 +#define CMD_TEMP_SENSOR_CONTROL 0x18 +#define CMD_ACTIVATION 0x20 +#define CMD_DISP_UPDATE_CTRL 0x21 +#define CMD_DISP_UPDATE_CTRL2 0x22 +#define CMD_WRITE_FB_BW 0x24 +#define CMD_WRITE_FB_RED 0x26 +#define CMD_UNKNOWN_1 0x2B +#define CMD_LOAD_OTP_LUT 0x31 +#define CMD_WRITE_LUT 0x32 +#define CMD_BORDER_WAVEFORM_CTRL 0x3C +#define CMD_WINDOW_X_SIZE 0x44 +#define CMD_WINDOW_Y_SIZE 0x45 +#define CMD_WRITE_PATTERN_RED 0x46 +#define CMD_WRITE_PATTERN_BW 0x47 +#define CMD_XSTART_POS 0x4E +#define CMD_YSTART_POS 0x4F +#define CMD_ANALOG_BLK_CTRL 0x74 +#define CMD_DIGITAL_BLK_CTRL 0x7E + +#define SCREEN_CMD_CLOCK_ON 0x80 +#define SCREEN_CMD_CLOCK_OFF 0x01 +#define SCREEN_CMD_ANALOG_ON 0x40 +#define SCREEN_CMD_ANALOG_OFF 0x02 +#define SCREEN_CMD_LATCH_TEMPERATURE_VAL 0x20 +#define SCREEN_CMD_LOAD_LUT 0x10 +#define SCREEN_CMD_USE_MODE_2 0x08 // modified commands 0x10 and 0x04 +#define SCREEN_CMD_REFRESH 0xC7 + +#define commandEnd() \ + do { \ + P1_7 = 1; \ + } while (0) + +#define markCommand() \ + do { \ + P2_2 = 0; \ + } while (0) + +#define markData() \ + do { \ + P2_2 = 1; \ + } while (0) + +static uint8_t __xdata currentLUT = 0x00; // Current selected LUT +static bool __idata epdPr = false; // wheter or not we copy the pr("") output to the EPD +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 +static uint16_t __xdata fontCurXpos = 0; // current X value where working with +static bool __xdata isInited = false; +struct waveform __xdata waveform; + +#pragma callee_saves epdBusySleep +#pragma callee_saves epdBusyWait +static void epdBusySleep(uint32_t timeout) { + uint8_t tmp_P2FUNC = P2FUNC; + uint8_t tmp_P2DIR = P2DIR; + uint8_t tmp_P2PULL = P2PULL; + uint8_t tmp_P2LVLSEL = P2LVLSEL; + P2FUNC &= 0xfd; + P2DIR |= 2; + P2PULL |= 2; + P2LVLSEL |= 2; + + P2CHSTA &= 0xfd; + P2INTEN |= 2; + P2CHSTA &= 0xfd; + sleepForMsec(timeout); + P2CHSTA &= 0xfd; + P2INTEN &= 0xfd; + + P2FUNC = tmp_P2FUNC; + P2DIR = tmp_P2DIR; + P2PULL = tmp_P2PULL; + P2LVLSEL = tmp_P2LVLSEL; + eepromPrvDeselect(); +} +static void epdBusyWait(uint32_t timeout) { + uint32_t __xdata start = timerGet(); + + while (timerGet() - start < timeout) { + if (!P2_1) + return; + } + pr("screen timeout %lu ticks :(\n", timerGet() - start); + while (1) + ; +} +static void commandReadBegin(uint8_t cmd) { + epdSelect(); + markCommand(); + spiByte(cmd); // dump LUT + + P0DIR = (P0DIR & ~(1 << 0)) | (1 << 1); + P0 &= ~(1 << 0); + P0FUNC &= ~((1 << 0) | (1 << 1)); + P2_2 = 1; +} +static void commandReadEnd() { + // set up pins for spi (0.0,0.1,0.2) + P0FUNC |= (1 << 0) | (1 << 1); + epdDeselect(); +} +#pragma callee_saves epdReadByte +static uint8_t epdReadByte() { + uint8_t val = 0, i; + + for (i = 0; i < 8; i++) { + P0_0 = 1; + __asm__("nop\nnop\nnop\nnop\nnop\nnop\n"); + val <<= 1; + if (P0_1) + val++; + P0_0 = 0; + __asm__("nop\nnop\nnop\nnop\nnop\nnop\n"); + } + + return val; +} +static void shortCommand(uint8_t cmd) { + epdSelect(); + markCommand(); + spiTXByte(cmd); + epdDeselect(); +} +static void shortCommand1(uint8_t cmd, uint8_t arg) { + epdSelect(); + markCommand(); + spiTXByte(cmd); + markData(); + spiTXByte(arg); + epdDeselect(); +} +static void shortCommand2(uint8_t cmd, uint8_t arg1, uint8_t arg2) { + epdSelect(); + markCommand(); + spiTXByte(cmd); + markData(); + spiTXByte(arg1); + spiTXByte(arg2); + epdDeselect(); +} +static void commandBegin(uint8_t cmd) { + epdSelect(); + markCommand(); + spiTXByte(cmd); + markData(); +} +static void epdReset() { + timerDelay(TIMER_TICKS_PER_SECOND / 1000); + P2_0 = 0; + timerDelay(TIMER_TICKS_PER_SECOND / 1000); + P2_0 = 1; + timerDelay(TIMER_TICKS_PER_SECOND / 1000); + + shortCommand(CMD_SOFT_RESET); // software reset + timerDelay(TIMER_TICKS_PER_SECOND / 1000); + shortCommand(CMD_SOFT_RESET2); + timerDelay(TIMER_TICKS_PER_SECOND / 1000); +} +void epdEnterSleep() { + P2_0 = 0; + timerDelay(10); + P2_0 = 1; + timerDelay(50); + shortCommand(CMD_SOFT_RESET2); + epdBusyWait(133300); + shortCommand1(CMD_ENTER_SLEEP, 0x03); + isInited = false; +} +void epdSetup() { + epdReset(); + currentLUT = 0; + shortCommand1(CMD_ANALOG_BLK_CTRL, 0x54); + shortCommand1(CMD_DIGITAL_BLK_CTRL, 0x3B); + shortCommand2(CMD_UNKNOWN_1, 0x04, 0x63); + + commandBegin(CMD_SOFT_START_CTRL); + epdSend(0x8f); + epdSend(0x8f); + epdSend(0x8f); + epdSend(0x3f); + commandEnd(); + + commandBegin(CMD_DRV_OUTPUT_CTRL); + epdSend((SCREEN_HEIGHT - 1) & 0xff); + epdSend((SCREEN_HEIGHT - 1) >> 8); + epdSend(0x00); + commandEnd(); + + // shortCommand1(CMD_DATA_ENTRY_MODE, 0x03); + shortCommand1(CMD_BORDER_WAVEFORM_CTRL, 0xC0); + shortCommand1(CMD_TEMP_SENSOR_CONTROL, 0x80); + shortCommand1(CMD_DISP_UPDATE_CTRL2, 0xB1); // mode 1 (i2C) + // shortCommand1(CMD_DISP_UPDATE_CTRL2, 0xB9); // mode 2? + shortCommand(CMD_ACTIVATION); + epdBusyWait(1333000UL); + isInited = true; +} +static uint8_t epdGetStatus() { + uint8_t sta; + commandReadBegin(0x2F); + sta = epdReadByte(); + commandReadEnd(); + return sta; +} +uint16_t epdGetBattery(void) { + uint16_t voltage = 2600; + + if (!isInited) + epdReset(); + uint8_t val; + + shortCommand1(CMD_DISP_UPDATE_CTRL2, SCREEN_CMD_CLOCK_ON | SCREEN_CMD_ANALOG_ON); + shortCommand(CMD_ACTIVATION); + epdBusyWait(133300); + + for (val = 3; val < 8; val++) { + shortCommand1(CMD_SETUP_VOLT_DETECT, val); + epdBusyWait(133300); + if (epdGetStatus() & 0x10) { // set if voltage is less than threshold ( == 1.9 + val / 10) + voltage = 1850 + mathPrvMul8x8(val, 100); + break; + } + } + + shortCommand1(CMD_DISP_UPDATE_CTRL2, 0xB1); + shortCommand(CMD_ACTIVATION); + epdBusyWait(133300); + + if (!isInited) + epdEnterSleep(); + return voltage; +} + +void selectLUT(uint8_t lut) { + if (lut == currentLUT) return; + // lut = 1; + switch (lut) { + case 0: + shortCommand1(CMD_DISP_UPDATE_CTRL2, 0xB1); // mode 1? + shortCommand(CMD_ACTIVATION); + epdBusyWait(1333000UL); + break; + case 1: + commandBegin(CMD_WRITE_LUT); + for (uint8_t i = 0; i < 70; i++) + epdSend(lutorig[i]); + commandEnd(); + break; + } + currentLUT = lut; +} + +void setWindowX(uint16_t start, uint16_t end) { + shortCommand2(CMD_WINDOW_X_SIZE, start / 8, end / 8 - 1); +} +void setWindowY(uint16_t start, uint16_t end) { + commandBegin(CMD_WINDOW_Y_SIZE); + epdSend((start)&0xff); + epdSend((start) >> 8); + epdSend((end - 1) & 0xff); + epdSend((end - 1) >> 8); + commandEnd(); +} +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) >> 8); + commandEnd(); +} +void setColorMode(uint8_t red, uint8_t bw) { + shortCommand1(CMD_DISP_UPDATE_CTRL, (red << 4) | bw); +} +void fillWindowWithPattern(bool color) { + if (color == EPD_COLOR_RED) { + shortCommand1(CMD_WRITE_PATTERN_RED, 0x00); + } else { + shortCommand1(CMD_WRITE_PATTERN_BW, 0x00); + } +} +void clearWindow(bool color) { + if (color == EPD_COLOR_RED) { + shortCommand1(CMD_WRITE_PATTERN_RED, 0x66); + } else { + shortCommand1(CMD_WRITE_PATTERN_BW, 0x66); + } +} +void clearScreen() { + setWindowX(0, SCREEN_WIDTH); + setWindowY(0, SCREEN_HEIGHT); + setPosXY(0, 0); + shortCommand1(CMD_WRITE_PATTERN_BW, 0x66); + epdBusyWait(133300UL); + shortCommand1(CMD_WRITE_PATTERN_RED, 0x66); + epdBusyWait(133300UL); +} +void draw() { + shortCommand1(0x22, 0xCF); + // shortCommand1(0x22, SCREEN_CMD_REFRESH); + shortCommand(0x20); + epdBusyWait(TIMER_TICKS_PER_SECOND * 120); +} +void drawNoWait() { + shortCommand1(0x22, 0xCF); + // shortCommand1(0x22, SCREEN_CMD_REFRESH); + shortCommand(0x20); +} +void drawLineHorizontal(bool red, uint16_t y, uint8_t width) { + setWindowX(0, SCREEN_WIDTH); + setWindowY(y, y + width); + if (red) { + shortCommand1(CMD_WRITE_PATTERN_RED, 0xE6); + } else { + shortCommand1(CMD_WRITE_PATTERN_BW, 0xE6); + } + epdBusyWait(133300UL); +} +void beginFullscreenImage() { + setColorMode(EPD_MODE_NORMAL, EPD_MODE_INVERT); + setWindowX(0, SCREEN_WIDTH); + setWindowY(0, SCREEN_HEIGHT); + shortCommand1(CMD_DATA_ENTRY_MODE, 3); + setPosXY(0, 0); +} +void beginWriteFramebuffer(bool color) { + if (color == EPD_COLOR_RED) { + commandBegin(CMD_WRITE_FB_RED); + } else { + commandBegin(CMD_WRITE_FB_BW); + } + epdDeselect(); +} +void endWriteFramebuffer() { + commandEnd(); +} + +// stuff for printing text +static void pushXFontBytesToEPD(uint8_t byte1, uint8_t byte2) { + if (epdCharSize == 1) { + uint8_t offset = 7 - (fontCurXpos % 8); + for (uint8_t c = 0; c < 8; c++) { + if (byte1 & (1 << c)) rbuffer[c] |= (1 << offset); + } + for (uint8_t c = 0; c < 8; c++) { + if (byte2 & (1 << c)) rbuffer[8 + c] |= (1 << offset); + } + fontCurXpos++; + } else { + uint8_t offset = 6 - (fontCurXpos % 8); + // double font size + for (uint8_t c = 0; c < 8; c++) { + if (byte1 & (1 << c)) { + rbuffer[c * 2] |= (3 << offset); + rbuffer[(c * 2) + 1] |= (3 << offset); + } + } + for (uint8_t c = 0; c < 8; c++) { + if (byte2 & (1 << c)) { + rbuffer[(c * 2) + 16] |= (3 << offset); + rbuffer[(c * 2) + 17] |= (3 << offset); + } + } + fontCurXpos += 2; + } + if (fontCurXpos % 8 == 0) { + // next byte, flush current byte to EPD + + for (uint8_t i = 0; i < (16 * epdCharSize); i++) { + epdSend(rbuffer[i]); + } + memset(rbuffer, 0, 32); + } +} +static void pushYFontBytesToEPD(uint8_t byte1, uint8_t byte2) { + if (epdCharSize == 2) { + for (uint8_t j = 0; j < 2; j++) { + uint8_t c = 0; + for (uint8_t i = 7; i != 255; i--) { + if (byte1 & (1 << i)) c |= (0x03 << ((i % 4) * 2)); + if ((i % 4) == 0) { + epdSend(c); + c = 0; + } + } + for (uint8_t i = 7; i != 255; i--) { + if (byte2 & (1 << i)) c |= (0x03 << ((i % 4) * 2)); + if ((i % 4) == 0) { + epdSend(c); + c = 0; + } + } + } + } else { + epdSend(byte1); + epdSend(byte2); + } +} +void writeCharEPD(uint8_t c) { + if (!epdPr) { + return; + } + // Writes a single character to the framebuffer + bool empty = true; + for (uint8_t i = 0; i < 20; i++) { + if (font[c][i]) empty = false; + } + if (empty) { + for (uint8_t i = 0; i < 8; i++) { + if (directionY) { + pushYFontBytesToEPD(0x00, 0x00); + } else { + pushXFontBytesToEPD(0x00, 0x00); + } + } + return; + } + + uint8_t begin = 0; + while (font[c][begin] == 0x00 && font[c][begin + 1] == 0x00) { + begin += 2; + } + + uint8_t end = 20; + while (font[c][end - 1] == 0x00 && font[c][end - 2] == 0x00) { + end -= 2; + } + + for (uint8_t pos = begin; pos < end; pos += 2) { + if (directionY) { + pushYFontBytesToEPD(font[c][pos + 1], font[c][pos]); + } else { + pushXFontBytesToEPD(font[c][pos], font[c][pos + 1]); + } + } + + // spacing between characters + if (directionY) { + pushYFontBytesToEPD(0x00, 0x00); + } else { + pushXFontBytesToEPD(0x00, 0x00); + } +} +// Print text to the EPD. Origin is top-left +void epdPrintBegin(uint16_t x, uint16_t y, bool direction, bool fontsize, bool color) { + directionY = direction; + epdCharSize = 1 + fontsize; + if (directionY) { + if (epdCharSize == 2) { + setWindowX(x - 32, x); + setPosXY(x - 32, y); + + } else { + setWindowX(x - 16, x); + setPosXY(x - 16, y); + } + setWindowY(y, SCREEN_HEIGHT); + shortCommand1(CMD_DATA_ENTRY_MODE, 3); + } else { + if (epdCharSize == 2) { + x /= 2; + x *= 2; + setWindowY(y, y + 32); + } else { + setWindowY(y, y + 16); + } + setPosXY(x, y); + fontCurXpos = x; + setWindowX(x, SCREEN_WIDTH); + shortCommand1(CMD_DATA_ENTRY_MODE, 7); + memset(rbuffer, 0, 32); + } + + epdPr = true; + if (color) { + commandBegin(CMD_WRITE_FB_RED); + } else { + commandBegin(CMD_WRITE_FB_BW); + } +} +void epdPrintEnd() { + if (!directionY && ((fontCurXpos % 8) != 0)) { + for (uint8_t i = 0; i < (16 * epdCharSize); i++) { + epdSend(rbuffer[i]); + } + } + commandEnd(); + epdPr = false; +} + + +void loadFixedTempLUT() { + shortCommand1(0x18, 0x48); + shortCommand2(0x1A, 0x05, 0x00); // < temp register + shortCommand1(CMD_DISP_UPDATE_CTRL2, 0xB1); // mode 1 (i2C) + shortCommand(CMD_ACTIVATION); + epdBusyWait(1333000UL); +} +static void readLut() { + commandReadBegin(0x33); + uint16_t checksum = 0; + uint16_t ident = 0; + uint16_t shortl = 0; + for (uint16_t c = 0; c < 76; c++) { + ((uint8_t*)&waveform)[c] = epdReadByte(); + } + commandReadEnd(); +} + +extern void dump(uint8_t* __xdata a, uint16_t __xdata l); // remove me when done + +void lutTest() { + readLut(); + dump((uint8_t*)&waveform, 96); +} \ No newline at end of file diff --git a/tag_fw/epd.h b/tag_fw/epd.h new file mode 100644 index 00000000..e1251b74 --- /dev/null +++ b/tag_fw/epd.h @@ -0,0 +1,59 @@ +#ifndef _JSCREEN_H_ +#define _JSCREEN_H_ + +#include +#include + +#define epdSend spiTXByte +#define EPD_DIRECTION_X false +#define EPD_DIRECTION_Y true +#define EPD_SIZE_SINGLE false +#define EPD_SIZE_DOUBLE true +#define EPD_COLOR_RED true +#define EPD_COLOR_BLACK false + +#define EPD_MODE_NORMAL 0x00 +#define EPD_MODE_INVERT 0x08 +#define EPD_MODE_IGNORE 0x04 + +#define epdSelect() \ + do { \ + P1_7 = 0; \ + } while (0) + +#define epdDeselect() \ + do { \ + P1_7 = 1; \ + } while (0) + +void epdSetup(); +void epdEnterSleep(); + +void setWindowX(uint16_t start, uint16_t end); +void setWindowY(uint16_t start, uint16_t end); +void setPosXY(uint16_t x, uint16_t y); +void setColorMode(uint8_t red, uint8_t bw) ; +void fillWindowWithPattern(bool color); +void clearWindow(bool color); +void clearScreen(); +void draw(); +void drawNoWait(); +void drawLineHorizontal(bool red, uint16_t y, uint8_t width); +void beginFullscreenImage(); +void beginWriteFramebuffer(bool color); +void endWriteFramebuffer(); + +void selectLUT(uint8_t lut); + +void ByteDecode(uint8_t byte); + +void epdPrintBegin(uint16_t x, uint16_t y, bool direction, bool fontsize, bool red); +void epdPrintEnd(); + + +void beginFullscreenImage(); +void beginWriteFramebuffer(bool color); + +void lutTest(); + +#endif \ No newline at end of file diff --git a/tag_fw/font.h b/tag_fw/font.h new file mode 100644 index 00000000..55e1f604 --- /dev/null +++ b/tag_fw/font.h @@ -0,0 +1,259 @@ +static const uint8_t __code font[256][20]={ +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x00 +{0x80,0x07,0xC0,0x0C,0x40,0x0A,0xA0,0x14,0x20,0x14,0x20,0x14,0xA0,0x14,0x40,0x0A,0xC0,0x0C,0x80,0x07}, // 0x01 +{0x80,0x07,0xC0,0x0F,0xC0,0x0D,0x60,0x1B,0xE0,0x1B,0xE0,0x1B,0x60,0x1B,0xC0,0x0D,0xC0,0x0F,0x80,0x07}, // 0x02 +{0x7C,0x00,0xFE,0x01,0xFE,0x07,0xFE,0x0F,0xFC,0x1F,0xFC,0x1F,0xFE,0x0F,0xFE,0x07,0xFE,0x01,0x7C,0x00}, // 0x03 +{0x80,0x00,0xC0,0x01,0xF0,0x03,0xF8,0x07,0xFE,0x1F,0xF8,0x0F,0xF0,0x07,0xE0,0x03,0xC0,0x01,0x80,0x00}, // 0x04 +{0xC0,0x01,0xE0,0x03,0xE0,0x03,0xFC,0x03,0xFE,0x1F,0xFE,0x1D,0xFC,0x03,0xE0,0x03,0xE0,0x03,0xC0,0x01}, // 0x05 +{0xC0,0x01,0xE0,0x03,0xF0,0x03,0xF8,0x03,0xFC,0x1F,0xFE,0x1D,0xF8,0x03,0xF0,0x03,0xE0,0x03,0xC0,0x01}, // 0x06 +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x07 +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x08 +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x09 +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x0A +{0x80,0x07,0x40,0x08,0x20,0x10,0x20,0x10,0x20,0x10,0x24,0x10,0x74,0x08,0x8E,0x07,0x0E,0x00,0x18,0x00}, // 0x0B +{0x00,0x00,0x78,0x00,0x84,0x04,0x02,0x05,0x02,0x1F,0x02,0x05,0x82,0x05,0x84,0x00,0x78,0x00,0x00,0x00}, // 0x0C +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x0D +{0x00,0x60,0x00,0x70,0x00,0x70,0xF8,0x3F,0x18,0x00,0x08,0x0C,0x0C,0x0E,0x04,0x0E,0xFE,0x07,0x00,0x00}, // 0x0E +{0x80,0x00,0xF0,0x03,0x20,0x03,0x10,0x02,0x18,0x06,0x10,0x02,0x20,0x02,0x30,0x03,0xD0,0x03,0x80,0x00}, // 0x0F +{0xF0,0x1F,0xE0,0x0F,0xE0,0x0F,0xC0,0x07,0xC0,0x07,0xC0,0x07,0x80,0x03,0x80,0x03,0x00,0x01,0x00,0x01}, // 0x10 +{0x00,0x01,0x00,0x01,0x80,0x03,0x80,0x03,0xC0,0x07,0xC0,0x07,0xC0,0x07,0xE0,0x0F,0xE0,0x0F,0xF0,0x1F}, // 0x11 +{0x00,0x00,0x00,0x00,0x08,0x10,0x04,0x20,0xFE,0x7F,0x04,0x20,0x08,0x10,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x12 +{0x00,0x00,0x00,0x00,0xFE,0x1B,0x00,0x00,0x00,0x00,0xFE,0x1B,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x13 +{0x00,0x00,0x1C,0x00,0x3E,0x00,0x7E,0x00,0xFE,0x7F,0x02,0x00,0x02,0x00,0xFE,0x7F,0x00,0x00,0x00,0x00}, // 0x14 +{0x00,0x00,0x00,0x00,0xDC,0x61,0x32,0x43,0x22,0x42,0x62,0x46,0x42,0x4C,0x82,0x3B,0x00,0x00,0x00,0x00}, // 0x15 +{0x00,0x00,0xE0,0x00,0xE0,0x00,0xE0,0x00,0xE0,0x00,0xE0,0x00,0xE0,0x00,0xE0,0x00,0xE0,0x00,0x00,0x00}, // 0x16 +{0x00,0x00,0x00,0x00,0x08,0x88,0x04,0x90,0xFE,0xBF,0x04,0x90,0x08,0x88,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x17 +{0x00,0x00,0x00,0x00,0x08,0x00,0x04,0x00,0xFE,0x7F,0x04,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x18 +{0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x20,0xFE,0x7F,0x00,0x20,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x19 +{0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x40,0x05,0x80,0x03,0x00,0x01,0x00,0x00}, // 0x1A +{0x00,0x00,0x00,0x01,0x80,0x03,0x40,0x05,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x00}, // 0x1B +{0x00,0x00,0xE0,0x1F,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x00}, // 0x1C +{0x00,0x00,0x00,0x01,0x80,0x03,0x40,0x05,0x00,0x01,0x00,0x01,0x40,0x05,0x80,0x03,0x00,0x01,0x00,0x00}, // 0x1D +{0x00,0x10,0x00,0x18,0x00,0x1E,0x80,0x1F,0xC0,0x1F,0xF0,0x1F,0xC0,0x1F,0x00,0x1F,0x00,0x1C,0x00,0x10}, // 0x1E +{0x10,0x00,0x30,0x00,0xF0,0x00,0xF0,0x03,0xF0,0x07,0xF0,0x1F,0xF0,0x07,0xF0,0x01,0x70,0x00,0x10,0x00}, // 0x1F +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x20 +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x1B,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x21 +{0x00,0x00,0x00,0x00,0x1E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x22 +{0x00,0x01,0x20,0x19,0xA0,0x07,0x78,0x01,0x26,0x19,0xA0,0x07,0x78,0x01,0x26,0x01,0x20,0x01,0x00,0x00}, // 0x23 +{0x00,0x00,0x00,0x00,0x1C,0x18,0x26,0x10,0x42,0x10,0xFF,0x3F,0x82,0x11,0x02,0x0F,0x00,0x00,0x00,0x00}, // 0x24 +{0x1C,0x10,0x22,0x08,0x22,0x04,0x22,0x03,0x9C,0x00,0x40,0x0E,0x30,0x11,0x08,0x11,0x04,0x11,0x02,0x0E}, // 0x25 +{0x00,0x07,0x80,0x08,0x5C,0x10,0x62,0x10,0xA2,0x11,0x32,0x13,0x1C,0x1C,0x00,0x18,0x00,0x16,0x80,0x01}, // 0x26 +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x27 +{0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x07,0x18,0x18,0x0C,0x30,0x04,0x20,0x02,0x40,0x02,0x40,0x00,0x00}, // 0x28 +{0x00,0x00,0x02,0x40,0x02,0x40,0x04,0x20,0x0C,0x30,0x18,0x18,0xE0,0x07,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x29 +{0x00,0x00,0x08,0x00,0x18,0x00,0xF0,0x00,0x4E,0x00,0xF0,0x00,0x18,0x00,0x08,0x00,0x00,0x00,0x00,0x00}, // 0x2A +{0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0xE0,0x1F,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x00}, // 0x2B +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x98,0x00,0x78,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x2C +{0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x00,0x00,0x00}, // 0x2D +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x2E +{0x00,0x00,0x00,0x40,0x00,0x30,0x00,0x0C,0x00,0x03,0xC0,0x00,0x30,0x00,0x0C,0x00,0x02,0x00,0x00,0x00}, // 0x2F +{0x00,0x00,0xF0,0x03,0x0C,0x0C,0x02,0x10,0x02,0x10,0x02,0x10,0x0C,0x0C,0xF0,0x03,0x00,0x00,0x00,0x00}, // 0x30 +{0x00,0x00,0x04,0x10,0x04,0x10,0x04,0x10,0xFE,0x1F,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x00,0x00,0x00}, // 0x31 +{0x00,0x00,0x06,0x18,0x02,0x14,0x02,0x12,0x02,0x11,0xC2,0x10,0x3C,0x10,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x32 +{0x00,0x00,0x00,0x00,0x02,0x10,0x42,0x10,0x42,0x10,0x42,0x10,0xBC,0x0F,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x33 +{0x00,0x03,0xC0,0x02,0x20,0x02,0x18,0x02,0x04,0x02,0xFE,0x1F,0x00,0x02,0x00,0x02,0x00,0x00,0x00,0x00}, // 0x34 +{0x00,0x00,0x00,0x00,0x3E,0x10,0x22,0x10,0x22,0x10,0x42,0x08,0x82,0x07,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x35 +{0x00,0x00,0xF0,0x07,0x4C,0x08,0x22,0x10,0x22,0x10,0x22,0x10,0x42,0x08,0x80,0x07,0x00,0x00,0x00,0x00}, // 0x36 +{0x00,0x00,0x02,0x00,0x02,0x18,0x02,0x07,0xC2,0x00,0x32,0x00,0x0A,0x00,0x06,0x00,0x00,0x00,0x00,0x00}, // 0x37 +{0x00,0x00,0x1C,0x0F,0xA2,0x10,0x42,0x10,0x42,0x10,0xA2,0x10,0xA2,0x09,0x1C,0x06,0x00,0x00,0x00,0x00}, // 0x38 +{0x00,0x00,0x78,0x00,0x84,0x10,0x02,0x11,0x02,0x11,0x02,0x11,0x84,0x0C,0xF8,0x03,0x00,0x00,0x00,0x00}, // 0x39 +{0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x18,0x60,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x3A +{0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x98,0x60,0x78,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x3B +{0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x03,0x80,0x04,0x80,0x04,0x40,0x08,0x40,0x08,0x20,0x10,0x00,0x00}, // 0x3C +{0x00,0x00,0x80,0x04,0x80,0x04,0x80,0x04,0x80,0x04,0x80,0x04,0x80,0x04,0x80,0x04,0x80,0x04,0x00,0x00}, // 0x3D +{0x00,0x00,0x20,0x10,0x40,0x08,0x40,0x08,0x80,0x04,0x80,0x04,0x00,0x03,0x00,0x03,0x00,0x00,0x00,0x00}, // 0x3E +{0x00,0x00,0x0E,0x00,0x02,0x00,0x02,0x1B,0x82,0x00,0x42,0x00,0x26,0x00,0x1C,0x00,0x00,0x00,0x00,0x00}, // 0x3F +{0xF0,0x03,0x18,0x0C,0x04,0x18,0xE2,0x13,0x12,0x14,0x0A,0x16,0x8A,0x1B,0xFC,0x07,0x00,0x04,0x00,0x04}, // 0x40 +{0x00,0x10,0x00,0x0E,0x80,0x03,0x70,0x02,0x18,0x02,0x30,0x02,0xC0,0x02,0x00,0x03,0x00,0x0C,0x00,0x10}, // 0x41 +{0x00,0x00,0xF8,0x1F,0x88,0x10,0x88,0x10,0x88,0x10,0x88,0x10,0x48,0x11,0x30,0x0E,0x00,0x00,0x00,0x00}, // 0x42 +{0xC0,0x03,0x30,0x0C,0x10,0x08,0x08,0x10,0x08,0x10,0x08,0x10,0x08,0x10,0x18,0x10,0x00,0x00,0x00,0x00}, // 0x43 +{0x00,0x00,0xF8,0x1F,0x08,0x10,0x08,0x10,0x08,0x10,0x08,0x10,0x10,0x08,0xE0,0x07,0x00,0x00,0x00,0x00}, // 0x44 +{0x00,0x00,0xF8,0x1F,0x08,0x11,0x08,0x11,0x08,0x11,0x08,0x11,0x08,0x11,0x08,0x10,0x00,0x00,0x00,0x00}, // 0x45 +{0x00,0x00,0xF8,0x1F,0x08,0x01,0x08,0x01,0x08,0x01,0x08,0x01,0x08,0x01,0x08,0x00,0x00,0x00,0x00,0x00}, // 0x46 +{0x00,0x00,0xC0,0x03,0x30,0x0C,0x10,0x08,0x08,0x10,0x08,0x10,0x08,0x11,0x08,0x11,0x18,0x1F,0x00,0x00}, // 0x47 +{0x00,0x00,0xF8,0x1F,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0xF8,0x1F,0x00,0x00,0x00,0x00}, // 0x48 +{0x00,0x00,0x08,0x10,0x08,0x10,0x08,0x10,0xF8,0x1F,0x08,0x10,0x08,0x10,0x08,0x10,0x00,0x00,0x00,0x00}, // 0x49 +{0x00,0x00,0x00,0x00,0x00,0x10,0x08,0x10,0x08,0x10,0x08,0x10,0xF8,0x0F,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x4A +{0x00,0x00,0xF8,0x1F,0x80,0x00,0x80,0x01,0x40,0x02,0x20,0x04,0x10,0x04,0x08,0x08,0x00,0x10,0x00,0x00}, // 0x4B +{0x00,0x00,0xF8,0x1F,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x00,0x00,0x00}, // 0x4C +{0xF8,0x1F,0x38,0x00,0xE0,0x01,0x00,0x07,0x00,0x06,0xC0,0x01,0x38,0x00,0xF8,0x1F,0x00,0x00,0x00,0x00}, // 0x4D +{0x00,0x00,0xF8,0x1F,0x10,0x00,0x60,0x00,0x80,0x01,0x00,0x06,0x00,0x08,0xF8,0x1F,0x00,0x00,0x00,0x00}, // 0x4E +{0x00,0x00,0xE0,0x07,0x10,0x08,0x08,0x10,0x08,0x10,0x08,0x10,0x08,0x10,0x10,0x08,0xE0,0x07,0x00,0x00}, // 0x4F +{0x00,0x00,0xF8,0x1F,0x08,0x01,0x08,0x01,0x08,0x01,0x08,0x01,0x88,0x00,0x70,0x00,0x00,0x00,0x00,0x00}, // 0x50 +{0x00,0x00,0xE0,0x07,0x10,0x08,0x08,0x10,0x08,0x10,0x08,0x10,0x08,0x30,0x10,0x48,0xE0,0x47,0x00,0x00}, // 0x51 +{0x00,0x00,0xF8,0x1F,0x08,0x01,0x08,0x01,0x08,0x03,0x88,0x04,0x70,0x08,0x00,0x10,0x00,0x00,0x00,0x00}, // 0x52 +{0x00,0x00,0x70,0x18,0x48,0x10,0x88,0x10,0x88,0x10,0x08,0x11,0x08,0x09,0x18,0x0E,0x00,0x00,0x00,0x00}, // 0x53 +{0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0xF8,0x1F,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x00,0x00}, // 0x54 +{0x00,0x00,0xF8,0x07,0x00,0x18,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x08,0xF8,0x07,0x00,0x00,0x00,0x00}, // 0x55 +{0x08,0x00,0x30,0x00,0xC0,0x01,0x00,0x06,0x00,0x18,0x00,0x18,0x00,0x07,0xC0,0x00,0x30,0x00,0x08,0x00}, // 0x56 +{0x18,0x00,0xE0,0x03,0x00,0x1C,0x00,0x0F,0xE0,0x00,0xC0,0x01,0x00,0x0E,0x00,0x1C,0xE0,0x03,0x18,0x00}, // 0x57 +{0x08,0x10,0x10,0x08,0x20,0x04,0x40,0x02,0x80,0x01,0x80,0x01,0x40,0x02,0x20,0x04,0x10,0x08,0x08,0x10}, // 0x58 +{0x08,0x00,0x10,0x00,0x60,0x00,0x80,0x00,0x00,0x1F,0x80,0x00,0x40,0x00,0x20,0x00,0x10,0x00,0x08,0x00}, // 0x59 +{0x00,0x00,0x08,0x18,0x08,0x14,0x08,0x12,0x08,0x11,0x88,0x10,0x48,0x10,0x28,0x10,0x18,0x10,0x00,0x00}, // 0x5A +{0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x7F,0x02,0x40,0x02,0x40,0x02,0x40,0x02,0x40,0x00,0x00,0x00,0x00}, // 0x5B +{0x00,0x00,0x02,0x00,0x0C,0x00,0x30,0x00,0xC0,0x00,0x00,0x03,0x00,0x0C,0x00,0x30,0x00,0x40,0x00,0x00}, // 0x5C +{0x00,0x00,0x02,0x40,0x02,0x40,0x02,0x40,0x02,0x40,0xFE,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x5D +{0x00,0x00,0x00,0x04,0x00,0x03,0xE0,0x00,0x38,0x00,0x0E,0x00,0x70,0x00,0x80,0x03,0x00,0x04,0x00,0x00}, // 0x5E +{0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x20}, // 0x5F +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x60 +{0x00,0x00,0x00,0x0C,0x20,0x12,0x20,0x11,0x20,0x11,0x20,0x09,0xC0,0x1F,0x00,0x10,0x00,0x00,0x00,0x00}, // 0x61 +{0x00,0x00,0xFE,0x1F,0x40,0x08,0x20,0x10,0x20,0x10,0x20,0x10,0x60,0x08,0x80,0x07,0x00,0x00,0x00,0x00}, // 0x62 +{0x00,0x00,0x80,0x07,0x40,0x08,0x20,0x10,0x20,0x10,0x20,0x10,0x20,0x10,0x20,0x10,0x00,0x00,0x00,0x00}, // 0x63 +{0x00,0x00,0x80,0x07,0x40,0x18,0x20,0x10,0x20,0x10,0x20,0x10,0x40,0x08,0xFE,0x1F,0x00,0x00,0x00,0x00}, // 0x64 +{0x00,0x00,0x80,0x07,0x40,0x09,0x20,0x11,0x20,0x11,0x20,0x11,0x20,0x11,0xC0,0x11,0x00,0x00,0x00,0x00}, // 0x65 +{0x00,0x00,0x20,0x00,0x20,0x00,0xFC,0x1F,0x24,0x00,0x22,0x00,0x22,0x00,0x22,0x00,0x22,0x00,0x00,0x00}, // 0x66 +{0x00,0x00,0x80,0x07,0x40,0x98,0x20,0x90,0x20,0x90,0x20,0x90,0x40,0x48,0xE0,0x3F,0x00,0x00,0x00,0x00}, // 0x67 +{0x00,0x00,0xFE,0x1F,0x80,0x00,0x40,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0xC0,0x1F,0x00,0x00,0x00,0x00}, // 0x68 +{0x00,0x00,0x20,0x00,0x20,0x00,0x26,0x00,0xE6,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x69 +{0x00,0x00,0x00,0x80,0x20,0x80,0x20,0x80,0x26,0x80,0xE6,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x6A +{0x00,0x00,0xFE,0x1F,0x00,0x01,0x00,0x03,0x80,0x04,0x40,0x04,0x40,0x08,0x20,0x10,0x00,0x00,0x00,0x00}, // 0x6B +{0x00,0x00,0x00,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0xFE,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x6C +{0xE0,0x1F,0x40,0x00,0x20,0x00,0x20,0x00,0xC0,0x1F,0x40,0x00,0x20,0x00,0x20,0x00,0xC0,0x1F,0x00,0x00}, // 0x6D +{0x00,0x00,0xE0,0x1F,0xC0,0x00,0x40,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0xC0,0x1F,0x00,0x00,0x00,0x00}, // 0x6E +{0x00,0x00,0x80,0x07,0x40,0x08,0x20,0x10,0x20,0x10,0x20,0x10,0x40,0x08,0x80,0x07,0x00,0x00,0x00,0x00}, // 0x6F +{0x00,0x00,0xE0,0xFF,0x40,0x08,0x20,0x10,0x20,0x10,0x20,0x10,0x60,0x08,0x80,0x07,0x00,0x00,0x00,0x00}, // 0x70 +{0x00,0x00,0x80,0x07,0x40,0x18,0x20,0x10,0x20,0x10,0x20,0x10,0x40,0x08,0xE0,0xFF,0x00,0x00,0x00,0x00}, // 0x71 +{0x00,0x00,0x00,0x00,0xE0,0x1F,0x80,0x00,0x40,0x00,0x20,0x00,0x20,0x00,0xE0,0x00,0x00,0x00,0x00,0x00}, // 0x72 +{0x00,0x00,0xC0,0x18,0x20,0x11,0x20,0x11,0x20,0x12,0x20,0x12,0x20,0x0C,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x73 +{0x00,0x00,0x20,0x00,0x20,0x00,0xF8,0x0F,0x20,0x10,0x20,0x10,0x20,0x10,0x20,0x10,0x00,0x00,0x00,0x00}, // 0x74 +{0x00,0x00,0xE0,0x0F,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x08,0xE0,0x1F,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x75 +{0x20,0x00,0xC0,0x01,0x00,0x06,0x00,0x18,0x00,0x10,0x00,0x0C,0x00,0x03,0xC0,0x00,0x20,0x00,0x00,0x00}, // 0x76 +{0x60,0x00,0x80,0x07,0x00,0x18,0x00,0x0E,0xC0,0x01,0x80,0x01,0x00,0x0E,0x00,0x18,0x80,0x07,0x60,0x00}, // 0x77 +{0x00,0x00,0x20,0x10,0x40,0x08,0x80,0x04,0x00,0x03,0x00,0x03,0x80,0x04,0x40,0x08,0x20,0x10,0x00,0x00}, // 0x78 +{0x20,0x80,0xC0,0x80,0x00,0x83,0x00,0x46,0x00,0x38,0x00,0x18,0x00,0x06,0x00,0x01,0xC0,0x00,0x20,0x00}, // 0x79 +{0x00,0x00,0x20,0x10,0x20,0x18,0x20,0x14,0x20,0x12,0x20,0x11,0xA0,0x10,0x60,0x10,0x20,0x10,0x00,0x00}, // 0x7A +{0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0xFC,0x3E,0x02,0x40,0x02,0x40,0x02,0x40,0x00,0x00,0x00,0x00}, // 0x7B +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x7C +{0x00,0x00,0x00,0x00,0x02,0x40,0x02,0x40,0x02,0x40,0xFC,0x3E,0x00,0x01,0x00,0x01,0x00,0x00,0x00,0x00}, // 0x7D +{0x00,0x03,0x80,0x00,0x80,0x00,0x80,0x00,0x00,0x01,0x00,0x01,0x00,0x02,0x00,0x02,0x00,0x02,0x80,0x01}, // 0x7E +{0x00,0x00,0x80,0x1F,0xC0,0x10,0x20,0x10,0x10,0x10,0x20,0x10,0xC0,0x10,0x80,0x1F,0x00,0x00,0x00,0x00}, // 0x7F +{0xC0,0x03,0x30,0x0C,0x10,0x08,0x08,0x10,0x08,0x10,0x08,0x90,0x08,0xB0,0x18,0xD0,0x00,0x00,0x00,0x00}, // 0x80 +{0x00,0x00,0xE0,0x0F,0x04,0x10,0x00,0x10,0x00,0x10,0x04,0x08,0xE0,0x1F,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x81 +{0x00,0x00,0x80,0x07,0x40,0x09,0x20,0x11,0x24,0x11,0x22,0x11,0x20,0x11,0xC0,0x11,0x00,0x00,0x00,0x00}, // 0x82 +{0x00,0x00,0x00,0x0C,0x24,0x12,0x22,0x11,0x22,0x11,0x24,0x09,0xC0,0x1F,0x00,0x10,0x00,0x00,0x00,0x00}, // 0x83 +{0x00,0x00,0x00,0x0C,0x24,0x12,0x20,0x11,0x20,0x11,0x24,0x09,0xC0,0x1F,0x00,0x10,0x00,0x00,0x00,0x00}, // 0x84 +{0x00,0x00,0x00,0x0C,0x22,0x12,0x24,0x11,0x20,0x11,0x20,0x09,0xC0,0x1F,0x00,0x10,0x00,0x00,0x00,0x00}, // 0x85 +{0x00,0x00,0x00,0x0C,0x20,0x12,0x22,0x11,0x25,0x11,0x22,0x09,0xC0,0x1F,0x00,0x10,0x00,0x00,0x00,0x00}, // 0x86 +{0x00,0x00,0x80,0x07,0x40,0x08,0x20,0x10,0x20,0x90,0x20,0xB0,0x20,0xD0,0x20,0x10,0x00,0x00,0x00,0x00}, // 0x87 +{0x00,0x00,0x80,0x07,0x44,0x09,0x22,0x11,0x22,0x11,0x24,0x11,0x20,0x11,0xC0,0x11,0x00,0x00,0x00,0x00}, // 0x88 +{0x00,0x00,0x80,0x07,0x40,0x09,0x24,0x11,0x20,0x11,0x20,0x11,0x24,0x11,0xC0,0x11,0x00,0x00,0x00,0x00}, // 0x89 +{0x00,0x00,0x80,0x07,0x40,0x09,0x22,0x11,0x24,0x11,0x20,0x11,0x20,0x11,0xC0,0x11,0x00,0x00,0x00,0x00}, // 0x8A +{0x00,0x00,0x20,0x00,0x24,0x00,0x20,0x00,0xE0,0x1F,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x8B +{0x00,0x00,0x20,0x00,0x24,0x00,0x22,0x00,0xE2,0x1F,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x8C +{0x00,0x00,0x20,0x00,0x20,0x00,0x22,0x00,0xE4,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x8D +{0x00,0x10,0x00,0x0E,0x81,0x03,0x70,0x02,0x18,0x02,0x30,0x02,0xC1,0x02,0x00,0x03,0x00,0x0C,0x00,0x10}, // 0x8E +{0x00,0x10,0x00,0x0E,0x80,0x03,0x72,0x02,0x0D,0x02,0x1D,0x02,0xF2,0x02,0x80,0x03,0x00,0x0E,0x00,0x10}, // 0x8F +{0x00,0x00,0xF8,0x1F,0x08,0x11,0x08,0x11,0x0A,0x11,0x09,0x11,0x08,0x11,0x08,0x10,0x00,0x00,0x00,0x00}, // 0x90 +{0x20,0x0E,0x20,0x13,0x20,0x11,0x20,0x11,0xC0,0x0F,0x20,0x19,0x20,0x11,0x20,0x11,0xC0,0x11,0x00,0x00}, // 0x91 +{0x00,0x10,0x00,0x0C,0x80,0x07,0x60,0x04,0x18,0x04,0xF8,0x1F,0x08,0x11,0x08,0x11,0x08,0x10,0x00,0x00}, // 0x92 +{0x00,0x00,0x80,0x07,0x44,0x08,0x22,0x10,0x22,0x10,0x24,0x10,0x40,0x08,0x80,0x07,0x00,0x00,0x00,0x00}, // 0x93 +{0x00,0x00,0x80,0x07,0x44,0x08,0x20,0x10,0x20,0x10,0x24,0x10,0x40,0x08,0x80,0x07,0x00,0x00,0x00,0x00}, // 0x94 +{0x00,0x00,0x80,0x07,0x42,0x08,0x24,0x10,0x20,0x10,0x20,0x10,0x40,0x08,0x80,0x07,0x00,0x00,0x00,0x00}, // 0x95 +{0x00,0x00,0xE0,0x0F,0x04,0x10,0x02,0x10,0x02,0x10,0x04,0x08,0xE0,0x1F,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x96 +{0x00,0x00,0xE0,0x0F,0x02,0x10,0x04,0x10,0x00,0x10,0x00,0x08,0xE0,0x1F,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x97 +{0x20,0x80,0xC0,0x80,0x04,0x83,0x00,0x46,0x00,0x38,0x04,0x18,0x00,0x06,0x00,0x01,0xC0,0x00,0x20,0x00}, // 0x98 +{0x00,0x00,0xE0,0x07,0x11,0x08,0x08,0x10,0x08,0x10,0x08,0x10,0x09,0x10,0x10,0x08,0xE0,0x07,0x00,0x00}, // 0x99 +{0x00,0x00,0xF8,0x07,0x01,0x18,0x00,0x10,0x00,0x10,0x00,0x10,0x01,0x08,0xF8,0x07,0x00,0x00,0x00,0x00}, // 0x9A +{0x00,0x00,0x80,0x17,0x40,0x08,0x20,0x14,0x20,0x13,0xA0,0x10,0x40,0x08,0xA0,0x07,0x00,0x00,0x00,0x00}, // 0x9B +{0x00,0x00,0x00,0x00,0x00,0x10,0x40,0x18,0xFC,0x17,0x42,0x10,0x42,0x10,0x02,0x10,0x00,0x00,0x00,0x00}, // 0x9C +{0x00,0x00,0xE0,0x17,0x10,0x0C,0x08,0x16,0x08,0x11,0x88,0x10,0x68,0x10,0x30,0x08,0xE8,0x07,0x00,0x00}, // 0x9D +{0x00,0x00,0x20,0x10,0x40,0x08,0x80,0x04,0x00,0x03,0x00,0x03,0x80,0x04,0x40,0x08,0x20,0x10,0x00,0x00}, // 0x9E +{0x00,0x00,0x00,0x80,0x20,0x80,0x20,0x80,0xFE,0x7F,0x21,0x00,0x21,0x00,0x01,0x00,0x00,0x00,0x00,0x00}, // 0x9F +{0x00,0x00,0x00,0x0C,0x20,0x12,0x20,0x11,0x24,0x11,0x22,0x09,0xC0,0x1F,0x00,0x10,0x00,0x00,0x00,0x00}, // 0xA0 +{0x00,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0xE4,0x1F,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0xA1 +{0x00,0x00,0x80,0x07,0x40,0x08,0x20,0x10,0x24,0x10,0x22,0x10,0x40,0x08,0x80,0x07,0x00,0x00,0x00,0x00}, // 0xA2 +{0x00,0x00,0xE0,0x0F,0x00,0x10,0x00,0x10,0x04,0x10,0x02,0x08,0xE0,0x1F,0x00,0x00,0x00,0x00,0x00,0x00}, // 0xA3 +{0x00,0x00,0xE0,0x1F,0xC4,0x00,0x42,0x00,0x24,0x00,0x24,0x00,0x22,0x00,0xC0,0x1F,0x00,0x00,0x00,0x00}, // 0xA4 +{0x00,0x00,0xF8,0x1F,0x12,0x00,0x61,0x00,0x83,0x01,0x02,0x06,0x01,0x08,0xF8,0x1F,0x00,0x00,0x00,0x00}, // 0xA5 +{0x00,0x00,0x00,0x00,0x32,0x00,0x4A,0x00,0x4A,0x00,0x4A,0x00,0x7C,0x00,0x40,0x00,0x00,0x00,0x00,0x00}, // 0xA6 +{0x00,0x00,0x00,0x00,0x3C,0x00,0x42,0x00,0x42,0x00,0x42,0x00,0x42,0x00,0x3C,0x00,0x00,0x00,0x00,0x00}, // 0xA7 +{0x00,0x00,0x00,0x70,0x00,0xC8,0x00,0x88,0x00,0x84,0x60,0x83,0x00,0x80,0x00,0xE0,0x00,0x00,0x00,0x00}, // 0xA8 +{0x00,0x00,0x38,0x00,0x44,0x00,0xBA,0x00,0xAA,0x00,0xBA,0x00,0x44,0x00,0x38,0x00,0x00,0x00,0x00,0x00}, // 0xA9 +{0x00,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x07,0x00,0x00}, // 0xAA +{0x02,0x10,0x7E,0x0C,0x00,0x02,0x80,0x01,0x60,0x00,0x10,0x00,0x8C,0x10,0x82,0x1C,0x80,0x14,0x00,0x13}, // 0xAB +{0x02,0x10,0x7E,0x0C,0x00,0x02,0x80,0x01,0x60,0x00,0x10,0x06,0x0C,0x05,0x82,0x04,0x80,0x1F,0x00,0x04}, // 0xAC +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0xAD +{0x00,0x00,0x00,0x01,0x80,0x02,0x40,0x04,0x20,0x08,0x00,0x01,0x80,0x02,0x40,0x04,0x20,0x08,0x00,0x00}, // 0xAE +{0x00,0x00,0x20,0x08,0x40,0x04,0x80,0x02,0x00,0x01,0x20,0x08,0x40,0x04,0x80,0x02,0x00,0x01,0x00,0x00}, // 0xAF +{0xDB,0x6C,0xDB,0x6C,0x00,0x00,0xDB,0x6C,0xDB,0x6C,0x00,0x00,0xDB,0x6C,0xDB,0x6C,0x00,0x00,0x00,0x00}, // 0xB0 +{0x6C,0xDB,0x6C,0xDB,0xDB,0x6C,0xFF,0xFF,0x6C,0xDB,0xDB,0x6C,0xFF,0xFF,0x6C,0xDB,0xDB,0x6C,0xDB,0x6C}, // 0xB1 +{0xFF,0xFF,0xFF,0xFF,0xDB,0x6C,0xFF,0xFF,0xFF,0xFF,0xDB,0x6C,0xFF,0xFF,0xFF,0xFF,0xDB,0x6C,0xDB,0x6C}, // 0xB2 +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0xB3 +{0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0xB4 +{0x00,0x10,0x00,0x0E,0x80,0x03,0x70,0x02,0x1A,0x02,0x31,0x02,0xC0,0x02,0x00,0x03,0x00,0x0C,0x00,0x10}, // 0xB5 +{0x00,0x10,0x00,0x0E,0x80,0x03,0x72,0x02,0x19,0x02,0x31,0x02,0xC2,0x02,0x00,0x03,0x00,0x0C,0x00,0x10}, // 0xB6 +{0x00,0x10,0x00,0x0E,0x80,0x03,0x71,0x02,0x1A,0x02,0x30,0x02,0xC0,0x02,0x00,0x03,0x00,0x0C,0x00,0x10}, // 0xB7 +{0xF0,0x03,0x0C,0x0C,0xE6,0x19,0x32,0x13,0x12,0x12,0x12,0x12,0x16,0x1A,0x0C,0x0C,0xF0,0x03,0x00,0x00}, // 0xB8 +{0x80,0x02,0x80,0x02,0x80,0x02,0xFF,0xFE,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0xB9 +{0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0xBA +{0x80,0x02,0x80,0x02,0x80,0x02,0x80,0xFE,0x80,0x00,0x80,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0xBB +{0x80,0x02,0x80,0x02,0x80,0x02,0xFF,0x02,0x00,0x02,0xFF,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0xBC +{0x00,0x00,0xF0,0x03,0x08,0x04,0x04,0x0C,0x04,0x08,0xFE,0x1F,0x04,0x08,0x04,0x08,0x00,0x00,0x00,0x00}, // 0xBD +{0x02,0x00,0x04,0x00,0x98,0x04,0xA0,0x04,0xC0,0x1F,0xA0,0x04,0x90,0x04,0x08,0x00,0x04,0x00,0x02,0x00}, // 0xBE +{0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0xBF +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01}, // 0xC0 +{0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0xFF,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01}, // 0xC1 +{0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0xFF,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01}, // 0xC2 +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01}, // 0xC3 +{0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01}, // 0xC4 +{0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0xFF,0xFF,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01}, // 0xC5 +{0x00,0x00,0x00,0x0C,0x24,0x12,0x22,0x11,0x24,0x11,0x24,0x09,0xC2,0x1F,0x00,0x10,0x00,0x00,0x00,0x00}, // 0xC6 +{0x00,0x10,0x00,0x0E,0x82,0x03,0x71,0x02,0x1B,0x02,0x32,0x02,0xC1,0x02,0x00,0x03,0x00,0x0C,0x00,0x10}, // 0xC7 +{0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x03,0x00,0x02,0xFF,0x02,0x80,0x02,0x80,0x02,0x80,0x02,0x80,0x02}, // 0xC8 +{0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xFF,0x80,0x00,0x80,0xFE,0x80,0x02,0x80,0x02,0x80,0x02,0x80,0x02}, // 0xC9 +{0x80,0x02,0x80,0x02,0x80,0x02,0xFF,0x02,0x00,0x02,0xFF,0x02,0x80,0x02,0x80,0x02,0x80,0x02,0x80,0x02}, // 0xCA +{0x80,0x02,0x80,0x02,0x80,0x02,0x80,0xFE,0x80,0x00,0x80,0xFE,0x80,0x02,0x80,0x02,0x80,0x02,0x80,0x02}, // 0xCB +{0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0xFF,0xFE,0x80,0x02,0x80,0x02,0x80,0x02,0x80,0x02}, // 0xCC +{0x80,0x02,0x80,0x02,0x80,0x02,0x80,0x02,0x80,0x02,0x80,0x02,0x80,0x02,0x80,0x02,0x80,0x02,0x80,0x02}, // 0xCD +{0x80,0x02,0x80,0x02,0x80,0x02,0xFF,0xFE,0x00,0x00,0xFF,0xFE,0x80,0x02,0x80,0x02,0x80,0x02,0x80,0x02}, // 0xCE +{0x00,0x00,0x08,0x04,0xF0,0x03,0x10,0x02,0x10,0x02,0x10,0x02,0x10,0x02,0xF0,0x03,0x08,0x04,0x00,0x00}, // 0xCF +{0x00,0x00,0x82,0x07,0x4A,0x08,0x2E,0x10,0x24,0x10,0x2A,0x10,0x70,0x08,0xC0,0x07,0x00,0x00,0x00,0x00}, // 0xD0 +{0x80,0x00,0xF8,0x1F,0x88,0x10,0x88,0x10,0x08,0x10,0x08,0x10,0x10,0x08,0xE0,0x07,0x00,0x00,0x00,0x00}, // 0xD1 +{0x00,0x00,0xF8,0x1F,0x08,0x11,0x0A,0x11,0x09,0x11,0x09,0x11,0x0A,0x11,0x08,0x10,0x00,0x00,0x00,0x00}, // 0xD2 +{0x00,0x00,0xF8,0x1F,0x09,0x11,0x08,0x11,0x08,0x11,0x08,0x11,0x09,0x11,0x08,0x10,0x00,0x00,0x00,0x00}, // 0xD3 +{0x00,0x00,0xF8,0x1F,0x08,0x11,0x08,0x11,0x09,0x11,0x0A,0x11,0x08,0x11,0x08,0x10,0x00,0x00,0x00,0x00}, // 0xD4 +{0x00,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0xE0,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0xD5 +{0x00,0x00,0x08,0x10,0x08,0x10,0x08,0x10,0xFA,0x1F,0x09,0x10,0x08,0x10,0x08,0x10,0x00,0x00,0x00,0x00}, // 0xD6 +{0x00,0x00,0x08,0x10,0x08,0x10,0x0A,0x10,0xF9,0x1F,0x09,0x10,0x0A,0x10,0x08,0x10,0x00,0x00,0x00,0x00}, // 0xD7 +{0x00,0x00,0x08,0x10,0x09,0x10,0x08,0x10,0xF8,0x1F,0x08,0x10,0x09,0x10,0x08,0x10,0x00,0x00,0x00,0x00}, // 0xD8 +{0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0xFF,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0xD9 +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01}, // 0xDA +{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}, // 0xDB +{0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF}, // 0xDC +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x7C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0xDD +{0x00,0x00,0x08,0x10,0x08,0x10,0x09,0x10,0xFA,0x1F,0x08,0x10,0x08,0x10,0x08,0x10,0x00,0x00,0x00,0x00}, // 0xDE +{0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00}, // 0xDF +{0x00,0x00,0xE0,0x07,0x10,0x08,0x08,0x10,0x0A,0x10,0x09,0x10,0x08,0x10,0x10,0x08,0xE0,0x07,0x00,0x00}, // 0xE0 +{0x00,0x00,0xFC,0x1F,0x02,0x00,0x02,0x00,0xE2,0x10,0x1C,0x11,0x00,0x12,0x00,0x0C,0x00,0x00,0x00,0x00}, // 0xE1 +{0x00,0x00,0xE0,0x07,0x10,0x08,0x0A,0x10,0x09,0x10,0x09,0x10,0x0A,0x10,0x10,0x08,0xE0,0x07,0x00,0x00}, // 0xE2 +{0x00,0x00,0xE0,0x07,0x10,0x08,0x09,0x10,0x0A,0x10,0x08,0x10,0x08,0x10,0x10,0x08,0xE0,0x07,0x00,0x00}, // 0xE3 +{0x00,0x00,0x80,0x07,0x44,0x08,0x22,0x10,0x24,0x10,0x24,0x10,0x42,0x08,0x80,0x07,0x00,0x00,0x00,0x00}, // 0xE4 +{0x00,0x00,0xE0,0x07,0x12,0x08,0x09,0x10,0x0B,0x10,0x0A,0x10,0x09,0x10,0x10,0x08,0xE0,0x07,0x00,0x00}, // 0xE5 +{0x00,0x00,0xE0,0xFF,0x00,0x08,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x08,0xE0,0x1F,0x00,0x00,0x00,0x00}, // 0xE6 +{0x00,0x00,0xFE,0xFF,0x40,0x08,0x20,0x10,0x20,0x10,0x20,0x10,0x60,0x08,0x80,0x07,0x00,0x00,0x00,0x00}, // 0xE7 +{0x00,0x00,0xF8,0x1F,0x20,0x04,0x20,0x04,0x20,0x04,0x20,0x04,0x20,0x02,0xC0,0x01,0x00,0x00,0x00,0x00}, // 0xE8 +{0x00,0x00,0xF8,0x07,0x00,0x18,0x00,0x10,0x02,0x10,0x01,0x10,0x00,0x08,0xF8,0x07,0x00,0x00,0x00,0x00}, // 0xE9 +{0x00,0x00,0xF8,0x07,0x00,0x18,0x02,0x10,0x01,0x10,0x01,0x10,0x02,0x08,0xF8,0x07,0x00,0x00,0x00,0x00}, // 0xEA +{0x00,0x00,0xF8,0x07,0x00,0x18,0x01,0x10,0x02,0x10,0x00,0x10,0x00,0x08,0xF8,0x07,0x00,0x00,0x00,0x00}, // 0xEB +{0x20,0x80,0xC0,0x80,0x00,0x83,0x00,0x46,0x04,0x38,0x02,0x18,0x00,0x06,0x00,0x01,0xC0,0x00,0x20,0x00}, // 0xEC +{0x08,0x00,0x10,0x00,0x60,0x00,0x80,0x00,0x02,0x1F,0x81,0x00,0x40,0x00,0x20,0x00,0x10,0x00,0x08,0x00}, // 0xED +{0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00}, // 0xEE +{0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0xEF +{0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x00,0x00,0x00}, // 0xF0 +{0x00,0x00,0x80,0x10,0x80,0x10,0x80,0x10,0x80,0x10,0xE0,0x13,0x80,0x10,0x80,0x10,0x80,0x10,0x00,0x00}, // 0xF1 +{0x00,0xA0,0x00,0xA0,0x00,0xA0,0x00,0xA0,0x00,0xA0,0x00,0xA0,0x00,0xA0,0x00,0xA0,0x00,0xA0,0x00,0xA0}, // 0xF2 +{0x42,0x10,0x4A,0x08,0x5A,0x04,0x36,0x03,0x80,0x00,0x40,0x06,0x30,0x05,0x88,0x04,0x84,0x1F,0x02,0x04}, // 0xF3 +{0x00,0x00,0x1C,0x00,0x3E,0x00,0x7E,0x00,0xFE,0x7F,0x02,0x00,0x02,0x00,0xFE,0x7F,0x00,0x00,0x00,0x00}, // 0xF4 +{0x00,0x00,0x00,0x00,0xDC,0x61,0x32,0x43,0x22,0x42,0x62,0x46,0x42,0x4C,0x82,0x3B,0x00,0x00,0x00,0x00}, // 0xF5 +{0x00,0x00,0x00,0x02,0x00,0x02,0x00,0x02,0x60,0x1A,0x60,0x1A,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x00}, // 0xF6 +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0xA0,0x00,0xC0,0x00,0x00,0x00,0x00,0x00,0x00}, // 0xF7 +{0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x12,0x00,0x12,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0xF8 +{0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0xF9 +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0xFA +{0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x7E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0xFB +{0x00,0x00,0x00,0x00,0x42,0x00,0x4A,0x00,0x4A,0x00,0x4A,0x00,0x36,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0xFC +{0x00,0x00,0x00,0x00,0x42,0x00,0x62,0x00,0x52,0x00,0x52,0x00,0x4C,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0xFD +{0x00,0x00,0xE0,0x1F,0xE0,0x1F,0xE0,0x1F,0xE0,0x1F,0xE0,0x1F,0xE0,0x1F,0xE0,0x1F,0xE0,0x1F,0x00,0x00}, // 0xFE +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} // 0xFF +}; + diff --git a/tag_fw/fw154.bin b/tag_fw/fw154.bin deleted file mode 100644 index 4aaa1593..00000000 Binary files a/tag_fw/fw154.bin and /dev/null differ diff --git a/tag_fw/fw29.bin b/tag_fw/fw29.bin deleted file mode 100644 index 60dda2ec..00000000 Binary files a/tag_fw/fw29.bin and /dev/null differ diff --git a/tag_fw/fw42.bin b/tag_fw/fw42.bin deleted file mode 100644 index dcf0d475..00000000 Binary files a/tag_fw/fw42.bin and /dev/null differ diff --git a/tag_fw/lut.h b/tag_fw/lut.h new file mode 100644 index 00000000..7e0f8a34 --- /dev/null +++ b/tag_fw/lut.h @@ -0,0 +1,153 @@ +#define __packed + +struct vgroup { + uint8_t A : 2; + uint8_t B : 2; + uint8_t C : 2; + uint8_t D : 2; +} __packed; + +struct lut { + struct vgroup group[7]; +} __packed; + +struct group { + uint8_t phaselength[4]; + uint8_t repeat; +} __packed; + +struct waveform { + struct lut elut[5]; + struct group egroup[7]; + uint8_t gatelevel; + uint8_t sourcelevel[3]; + uint8_t dummyline; + uint8_t gatewidth; +} __packed; + +static const uint8_t __code lut154[] = { + // lut0 (KEEP) voltages + 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // lut1 (W2B) voltages + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // lut2 (B2W) voltages + 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // lut3 (unused) voltages + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // lut4 (vcom) voltages + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // group0 phase lengths and repeat count + 0x40, 0x0, 0x00, 0x00, 0x00, + // group1 not used + 0x00, 0x00, 0x00, 0x00, 0x00, + // group2 not used + 0x00, 0x00, 0x00, 0x00, 0x00, + // group3 phase lengths and repeat count + 0x00, 0x00, 0x00, 0x00, 0x00, + // group4 phase lengths and repeat count + 0x00, 0x00, 0x00, 0x00, 0x00, + // group5 phase lengths and repeat count + 0x00, 0x00, 0x00, 0x00, 0x00, + // group6 phase lengths and repeat count + 0x00, 0x00, 0x00, 0x00, 0x00, +}; + + +static const uint8_t __code lut29[] = { + // lut0 (KEEP) voltages + 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // lut1 (W2B) voltages + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // lut2 (B2W) voltages + 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // lut3 (unused) voltages + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // lut4 (vcom) voltages + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // group0 phase lengths and repeat count +// 0x10, 0x02, 0x00, 0x00, 0x03 - 1, + 0x05, 0x02, 0x00, 0x00, 0x00, + +// 0x40, 0x00, 0x00, 0x00, 0x00, + + // group1 not used + 0x00, 0x00, 0x00, 0x00, 0x00, + // group2 not used + 0x00, 0x00, 0x00, 0x00, 0x00, + // group3 phase lengths and repeat count + 0x00, 0x00, 0x00, 0x00, 0x00, + // group4 phase lengths and repeat count + 0x00, 0x00, 0x00, 0x00, 0x00, + // group5 phase lengths and repeat count + 0x00, 0x00, 0x00, 0x00, 0x00, + // group6 phase lengths and repeat count + 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +static const uint8_t __code lutSHA[] = { + // Voltages and other settings? Timing? + 0xA0, 0x90, 0x50, 0x0, 0x0, 0x0, 0x0, + 0x50, 0x90, 0xA0, 0x0, 0x0, 0x0, 0x0, + 0xA0, 0x90, 0x50, 0x0, 0x0, 0x0, 0x0, + 0x50, 0x90, 0xA0, 0x0, 0x0, 0x0, 0x0, + 0x00, 0x00, 0x00, 0x0, 0x0, 0x0, 0x0, + + // Update program + // + // Top three lines are the main program (bottom 4 have unknown function) + // Line 1: Negative image + // Line 2: White/Black flashing + // Line 3: Positive image + // + // Line construction + // First two bytes denote Intensity (range 0x00 to 0x0F) + // Second two bytes denote lenght of each 'pulse' (range 0x00 to 0xFF) + // Last byte denotes number of repeats (0 = line runs 1 time, range 0x00 to 0xFF) + // If you don't want a line to do anything, set all bytes to 0x0. + // This way you can make a quick update cycle between two screens. + // Maybe not as pretty/crisp but nice and fast is also awesome! + + // Negative image + // first two bytes negative image, length white pulse (0-FF), length black pulse (0-FF), last byte repeats + + 0x0, 0x0, 0x0, 0x0, 0x0, + + //0xF, 0xF, 0x0, 0x0, 0x0, + + // White or black flash + // white flash intensity, black flash intensity, length white pulse (0-FF), length black pulse (0-FF), repeats + + //0x0, 0x0, 0x0, 0x0, 0x00, + 0xF, 0xF, 0x1, 0x1, 0x00, + //0xF, 0xF, 0x0, 0x0, 0x02, + + + // Positive image + // first byte or second byte positive image (don't know why you need both), rest same as above + + 0xF, 0xF, 0x0, 0x0, 0x0, + + // Unknown what lines below actually do. + // They seem to be programs to, but have no visible effect on dislay. + 0x0F, 0x0F, 0x0, 0x0, 0x0, + 0x0F, 0x0F, 0x0, 0x0, 0x0, + 0x0F, 0x0F, 0x0, 0x0, 0x0, + 0x0F, 0x0F, 0x0, 0x0, 0x0, +}; + + +static const uint8_t __code lutorig[] = { + 0x00, 0x66, 0x21, 0x45, 0x40, 0x00, 0x00, + 0x15, 0x66, 0x21, 0xA8, 0x20, 0xA0, 0x00, + 0xA0, 0x66, 0x21, 0x85, 0x2B, 0x2F, 0x00, + 0xA0, 0x66, 0x21, 0x85, 0x2B, 0x2F, 0x00, + 0x00, 0x00, 0x12, 0x48, 0x00, 0x00, 0x00, + //0x04, 0x49, 0x2F, 0x2A, 0x00, + 0x0, 0x0, 0x0, 0x0, 0x0, + 0x02, 0x04, 0x01, 0x03, 0x00, // was 11 repeat + 0x01, 0x14, 0x01, 0x14, 0x00, // was 3 repeat + 0x02, 0x0A, 0x03, 0x0A, 0x00, // was 2 repeat + 0x06, 0x04, 0x04, 0x20, 0x00, // was 3 rpeat + 0x04, 0x04, 0x02, 0x26, 0x00, // was 3 repeat + 0x00, 0x00, 0x00, 0x00, 0x0, +}; \ No newline at end of file diff --git a/tag_fw/main.c b/tag_fw/main.c index 7c8ecb45..997b765a 100644 --- a/tag_fw/main.c +++ b/tag_fw/main.c @@ -4,11 +4,8 @@ #include #include #include - -#include "adc.h" #include "asmUtil.h" #include "board.h" -#include "chars.h" #include "comms.h" #include "cpu.h" #include "drawing.h" @@ -23,15 +20,6 @@ #include "syncedproto.h" -uint16_t __xdata battery_voltage = 0; -int8_t __xdata mCurTemperature; - - -void getVolt(void) { - if (battery_voltage == 0) - battery_voltage = adcSampleBattery(); -} - void main(void){ mainProtocolLoop(); } diff --git a/tag_fw/soc/zbs243/spi.c b/tag_fw/soc/zbs243/spi.c index c4088d4b..e2a8f7f6 100644 --- a/tag_fw/soc/zbs243/spi.c +++ b/tag_fw/soc/zbs243/spi.c @@ -29,4 +29,14 @@ uint8_t spiByte(uint8_t val) CFGPAGE = bcp; return val; +} + +void spiTXByte(uint8_t val) +{ + uint8_t bcp = CFGPAGE; + CFGPAGE = 4; + SPITX = val; + SPICFG = 0xa0; //spi at 4mhz, mode 0 + while(SPICFG & 0x20); + CFGPAGE = bcp; } \ No newline at end of file diff --git a/tag_fw/soc/zbs243/spi.h b/tag_fw/soc/zbs243/spi.h index b869e4a9..b2aeb4aa 100644 --- a/tag_fw/soc/zbs243/spi.h +++ b/tag_fw/soc/zbs243/spi.h @@ -11,6 +11,9 @@ void spiInit(void); #pragma callee_saves spiByte uint8_t spiByte(uint8_t val); +#pragma callee_saves spiTXByte +void spiTXByte(uint8_t val); + #endif diff --git a/tag_fw/soc/zbs243/temperature.c b/tag_fw/soc/zbs243/temperature.c index f51b492f..11b20544 100644 --- a/tag_fw/soc/zbs243/temperature.c +++ b/tag_fw/soc/zbs243/temperature.c @@ -1,7 +1,6 @@ #include "asmUtil.h" #include "flash.h" #include "timer.h" -#include "adc.h" #include "cpu.h" static volatile uint8_t __xdata mTempRet[4]; diff --git a/tag_fw/soc/zbs243/uart.c b/tag_fw/soc/zbs243/uart.c index 3bf25bc8..c41514c5 100644 --- a/tag_fw/soc/zbs243/uart.c +++ b/tag_fw/soc/zbs243/uart.c @@ -1,24 +1,23 @@ #include "uart.h" + #include "cpu.h" +void uartInit(void) { + // clock it up + CLKEN |= 0x20; - -void uartInit(void) -{ - //clock it up - CLKEN |= 0x20; - - //configure - UARTBRGH = 0x00; //config for 115200 - UARTBRGL = 0x8A; - UARTSTA = 0x12; //also set the "empty" bit else we wait forever for it to go up + // configure + UARTBRGH = 0x00; // config for 115200 + UARTBRGL = 0x8A; + UARTSTA = 0x12; // also set the "empty" bit else we wait forever for it to go up } -void uartTx(uint8_t val) -{ - while (!(UARTSTA & (1 << 1))); - UARTSTA &=~ (1 << 1); - UARTBUF = val; +extern void writeCharEPD(uint8_t c); + +void uartTx(uint8_t val) { + writeCharEPD(val); + while (!(UARTSTA & (1 << 1))) + ; + UARTSTA &= ~(1 << 1); + UARTBUF = val; } - - diff --git a/tag_fw/syncedproto.c b/tag_fw/syncedproto.c index 56e23fd1..5be1e4a2 100644 --- a/tag_fw/syncedproto.c +++ b/tag_fw/syncedproto.c @@ -6,11 +6,8 @@ #include #include #include - -#include "adc.h" #include "asmUtil.h" #include "board.h" -#include "chars.h" #include "comms.h" #include "cpu.h" #include "drawing.h" @@ -19,7 +16,8 @@ #include "printf.h" #include "proto.h" #include "radio.h" -#include "screen.h" +#include "epd.h" +#include "userinterface.h" #include "sleep.h" #include "timer.h" #include "wdt.h" @@ -104,7 +102,7 @@ struct burstMacData { #define BLOCK_PART_DATA_SIZE 99 #define BLOCK_MAX_PARTS 42 -#define BLOCK_DATA_SIZE 4096 +#define BLOCK_DATA_SIZE 4096UL #define BLOCK_XFER_BUFFER_SIZE BLOCK_DATA_SIZE + sizeof(struct blockData) #define BLOCK_REQ_PARTS_BYTES 6 @@ -133,6 +131,7 @@ uint16_t __xdata dataRemaining = 0; bool __xdata curXferComplete = false; bool __xdata requestPartialBlock = false; +//uint8_t __xdata *tempBuffer = blockXferBuffer; uint8_t __xdata curImgSlot = 0; uint32_t __xdata curHighSlotId = 0; uint8_t __xdata nextImgSlot = 0; @@ -151,17 +150,17 @@ uint8_t __xdata mSelfMac[8] = {0}; uint8_t __xdata seq = 0; // power saving algorithm -#define INTERVAL_BASE 40 // interval (in seconds) (when 1 packet is sent/received) for target current (7.2µA) -#define INTERVAL_AT_MAX_ATTEMPTS 600 // interval (in seconds) (at max attempts) for target average current -#define INTERVAL_NO_SIGNAL 1800 // interval (in seconds) when no answer for POWER_SAVING_SMOOTHING attempts, - // (INTERVAL_AT_MAX_ATTEMPTS * POWER_SAVING_SMOOTHING) seconds -#define DATA_REQ_RX_WINDOW_SIZE 5UL // How many milliseconds we should wait for a packet during the data_request. - // If the AP holds a long list of data for tags, it may need a little more time to lookup the mac address -#define DATA_REQ_MAX_ATTEMPTS 14 // How many attempts (at most) we should do to get something back from the AP -#define POWER_SAVING_SMOOTHING 8 // How many samples we should use to smooth the data request interval -#define MINIMUM_INTERVAL 45 // IMPORTANT: Minimum interval for check-in; this determines overal battery life! +#define INTERVAL_BASE 40 // interval (in seconds) (when 1 packet is sent/received) for target current (7.2µA) +#define INTERVAL_AT_MAX_ATTEMPTS 600 // interval (in seconds) (at max attempts) for target average current +#define INTERVAL_NO_SIGNAL 1800 // interval (in seconds) when no answer for POWER_SAVING_SMOOTHING attempts, + // (INTERVAL_AT_MAX_ATTEMPTS * POWER_SAVING_SMOOTHING) seconds +#define DATA_REQ_RX_WINDOW_SIZE 5UL // How many milliseconds we should wait for a packet during the data_request. + // If the AP holds a long list of data for tags, it may need a little more time to lookup the mac address +#define DATA_REQ_MAX_ATTEMPTS 14 // How many attempts (at most) we should do to get something back from the AP +#define POWER_SAVING_SMOOTHING 8 // How many samples we should use to smooth the data request interval +#define MINIMUM_INTERVAL 45 // IMPORTANT: Minimum interval for check-in; this determines overal battery life! -#define HAS_BUTTON // uncomment to enable reading a push button (connect between 'TEST' en 'GND' on the tag, along with a 100nF capacitor in parallel). +#define HAS_BUTTON // uncomment to enable reading a push button (connect between 'TEST' en 'GND' on the tag, along with a 100nF capacitor in parallel). uint16_t __xdata dataReqAttemptArr[POWER_SAVING_SMOOTHING] = {0}; // Holds the amount of attempts required per data_req/check-in uint8_t __xdata dataReqAttemptArrayIndex = 0; @@ -248,30 +247,30 @@ void initAfterWake() { timerInit(); // partialInit(); boardInit(); - screenSleep(); + epdEnterSleep(); irqsOn(); boardInitStage2(); initRadio(); } void doSleep(uint32_t __xdata t) { - if(t>1000)pr("s=%lu\n ", t / 1000); + if (t > 1000) pr("s=%lu\n ", t / 1000); powerPortsDownForSleep(); #ifdef HAS_BUTTON - //Button setup on TEST pin 1.0 (input pullup) - P1FUNC &=~ (1 << 0); - P1DIR |= (1 << 0); - P1PULL |= (1 << 0); - P1LVLSEL |= (1 << 0); - P1INTEN = (1 << 0); - P1CHSTA &=~ (1 << 0); + // Button setup on TEST pin 1.0 (input pullup) + P1FUNC &= ~(1 << 0); + P1DIR |= (1 << 0); + P1PULL |= (1 << 0); + P1LVLSEL |= (1 << 0); + P1INTEN = (1 << 0); + P1CHSTA &= ~(1 << 0); #endif // sleepy sleepForMsec(t); #ifdef HAS_BUTTON - P1INTEN = 0; + P1INTEN = 0; #endif initAfterWake(); @@ -315,11 +314,11 @@ void sendAvailDataReq() { txframe->srcPan = 0x4447; // TODO: send some meaningful data availreq->softVer = 1; - if (P1CHSTA && (1 << 0)) { - availreq->buttonState = 1; - pr("button pressed\n"); - P1CHSTA &=~ (1 << 0); - } + if (P1CHSTA && (1 << 0)) { + availreq->buttonState = 1; + pr("button pressed\n"); + P1CHSTA &= ~(1 << 0); + } addCRC(availreq, sizeof(struct AvailDataReq)); commsTxNoCpy(outBuffer); } @@ -504,45 +503,6 @@ bool validateBlockData() { return bd->checksum == t; } -const uint8_t epd_bitmap_ant[] = { - 0xff, 0xbf, 0xfd, 0xdf, 0xfe, 0xdf, 0xee, 0xdf, 0xee, 0xdf, 0xed, 0xdf, 0xd7, 0xbf, 0xd7, 0xff, - 0xd7, 0xff, 0xbb, 0xff, 0xbb, 0xbb, 0xbb, 0xd7, 0xbb, 0xef, 0x7d, 0xd7, 0x7d, 0xbb, 0x01, 0xff}; -void copyImage() { - uint8_t x_begin = 17; - uint16_t y_begin = 0; - uint8_t y_size = 16; - const uint8_t *p = epd_bitmap_ant; - pr("begin copy image to epd buffer"); - for (uint16_t y = 0; y < y_size; y++) { - // moveToXY(x_begin, y_begin + y, false); - pr("d=%02X,", *p); - // screenByteRawTx(*p); - p++; - // screenByteRawTx(*p); - p++; - } -} -void drawPartial() { - screenSleep(); - screenTxStart(true); - pr("sending bytes\n"); - for (uint8_t iteration = 0; iteration < SCREEN_DATA_PASSES; iteration++) { - for (uint16_t y = 0; y < SCREEN_HEIGHT; y++) { - for (uint8_t x = 0; x < SCREEN_WIDTH / 8; x++) { - if (iteration == 0) { - // screenByteRawTx(0xFF); - } else { - // screenByteRawTx(0x00); - } - } - } - screenEndPass(); - pr("pass complete\n"); - } - copyImage(); - screenTxEnd(); -} - // EEprom related stuff uint32_t getAddressForSlot(uint8_t s) { return EEPROM_IMG_START + (EEPROM_IMG_EACH * s); @@ -564,7 +524,7 @@ uint8_t findSlot(uint8_t *__xdata ver) { // return 0xFF; // remove me! This forces the tag to re-download each and every upload without checking if it's already in the eeprom somewhere uint32_t __xdata markerValid = EEPROM_IMG_VALID; for (uint8_t __xdata c = 0; c < imgSlots; c++) { - struct EepromImageHeader __xdata *eih = (struct EepromImageHeader __xdata *)mScreenRow; + struct EepromImageHeader __xdata *eih = (struct EepromImageHeader __xdata *)blockXferBuffer; eepromRead(getAddressForSlot(c), eih, sizeof(struct EepromImageHeader)); if (xMemEqual4(&eih->validMarker, &markerValid)) { if (xMemEqual(&eih->version, (void *)ver, 8)) { @@ -600,7 +560,7 @@ uint32_t getHighSlotId() { uint32_t temp = 0; uint32_t __xdata markerValid = EEPROM_IMG_VALID; for (uint8_t __xdata c = 0; c < imgSlots; c++) { - struct EepromImageHeader __xdata *eih = (struct EepromImageHeader __xdata *)mScreenRow; + struct EepromImageHeader __xdata *eih = (struct EepromImageHeader __xdata *)blockXferBuffer; eepromRead(getAddressForSlot(c), eih, sizeof(struct EepromImageHeader)); if (xMemEqual4(&eih->validMarker, &markerValid)) { if (temp < eih->id) { @@ -843,7 +803,7 @@ bool doDataDownload(struct AvailDataInfo *__xdata avail) { case DATATYPE_IMG: case DATATYPE_IMGRAW:; // transfer complete. Save data info and mark data in image slot as 'valid' - struct EepromImageHeader __xdata *eih = (struct EepromImageHeader __xdata *)mScreenRow; + struct EepromImageHeader __xdata *eih = (struct EepromImageHeader __xdata *)blockXferBuffer; xMemCopy8(&eih->version, &curDataInfo.dataVer); eih->size = curDataInfo.dataSize; eih->validMarker = EEPROM_IMG_VALID; @@ -858,6 +818,7 @@ bool doDataDownload(struct AvailDataInfo *__xdata avail) { break; case DATATYPE_UPDATE: pr("firmware download complete, doing update.\n"); + showApplyUpdate(); curXferComplete = true; sendXferComplete(); killRadio(); @@ -899,14 +860,12 @@ void mainProtocolLoop(void) { } irqsOn(); - boardInitStage2(); - // i2ctest(); + boardInitStage2(); - pr("BOOTED> (new version!)\n\n"); + pr("BOOTED> (UI 0.03-1)\n\n"); if (!eepromInit()) { pr("failed to init eeprom\n"); - drawFullscreenMsg((const __xdata char *)"eeprom failed"); while (1) ; } else { @@ -919,15 +878,15 @@ void mainProtocolLoop(void) { dataReqAttemptArr[c] = INTERVAL_BASE; } - screenSleep(); + // show the splashscreen + showSplashScreen(); + + epdEnterSleep(); eepromDeepPowerDown(); initRadio(); - - P1CHSTA &=~ (1 << 0); - - // drawPartial(); - // i2ctest(); - // doSleep(10000); + + P1CHSTA &= ~(1 << 0); + while (1) { radioRxEnable(true, true); diff --git a/tag_fw/userinterface.c b/tag_fw/userinterface.c new file mode 100644 index 00000000..57f4b89a --- /dev/null +++ b/tag_fw/userinterface.c @@ -0,0 +1,78 @@ +#include "userinterface.h" + +#include +#include + +#include "asmUtil.h" +#include "board.h" +#include "cpu.h" +#include "epd.h" +#include "font.h" +#include "lut.h" +#include "printf.h" +#include "screen.h" +#include "sleep.h" +#include "spi.h" +#include "timer.h" + +extern uint8_t mSelfMac[]; + +void showSplashScreen() { + epdSetup(); + lutTest(); +#if (SCREEN_WIDTH == 152) // 1.54" + selectLUT(1); + clearScreen(); + setColorMode(EPD_MODE_NORMAL, EPD_MODE_INVERT); + drawLineHorizontal(EPD_COLOR_BLACK, 33, 1); + epdPrintBegin(0, 0, EPD_DIRECTION_X, EPD_SIZE_DOUBLE, EPD_COLOR_BLACK); + pr("Booting!"); + epdPrintEnd(); + draw(); + timerDelay(1333000); +#endif +#if (SCREEN_WIDTH == 128) // 2.9" + selectLUT(1); + clearScreen(); + setColorMode(EPD_MODE_NORMAL, EPD_MODE_INVERT); + epdPrintBegin(128, 0, EPD_DIRECTION_Y, EPD_SIZE_DOUBLE, EPD_COLOR_BLACK); + pr("Booting!"); + epdPrintEnd(); + epdPrintBegin(16, 10, EPD_DIRECTION_Y, EPD_SIZE_SINGLE, EPD_COLOR_RED); + pr("MAC: %02X:%02X", mSelfMac[7], mSelfMac[6]); + pr(":%02X:%02X", mSelfMac[5], mSelfMac[4]); + pr(":%02X:%02X", mSelfMac[3], mSelfMac[2]); + pr(":%02X:%02X", mSelfMac[1], mSelfMac[0]); + epdPrintEnd(); + draw(); + timerDelay(1333000); +#endif +#if (SCREEN_WIDTH == 400) // 2.9" + selectLUT(1); + clearScreen(); + setColorMode(EPD_MODE_NORMAL, EPD_MODE_INVERT); + epdPrintBegin(0, 0, EPD_DIRECTION_X, EPD_SIZE_DOUBLE, EPD_COLOR_BLACK); + pr("Booting!"); + epdPrintEnd(); + epdPrintBegin(16, 284, EPD_DIRECTION_X, EPD_SIZE_SINGLE, EPD_COLOR_RED); + pr("MAC: %02X:%02X", mSelfMac[7], mSelfMac[6]); + pr(":%02X:%02X", mSelfMac[5], mSelfMac[4]); + pr(":%02X:%02X", mSelfMac[3], mSelfMac[2]); + pr(":%02X:%02X", mSelfMac[1], mSelfMac[0]); + epdPrintEnd(); + draw(); + timerDelay(1333000); +#endif + +} + +void showApplyUpdate() { + epdSetup(); + selectLUT(1); + clearScreen(); + setColorMode(EPD_MODE_IGNORE, EPD_MODE_NORMAL); + epdPrintBegin(8, 60, EPD_DIRECTION_X, EPD_SIZE_DOUBLE, EPD_COLOR_BLACK); + pr("Updating!"); + epdPrintEnd(); + drawNoWait(); +} \ No newline at end of file diff --git a/tag_fw/userinterface.h b/tag_fw/userinterface.h new file mode 100644 index 00000000..548affd7 --- /dev/null +++ b/tag_fw/userinterface.h @@ -0,0 +1,9 @@ + +#ifndef _UI_H_ +#define _UI_H_ + +void showSplashScreen(); +void showApplyUpdate(); + + +#endif \ No newline at end of file