M2 v0026 firmware added

This commit is contained in:
jjwbruijn
2024-01-08 21:59:51 +01:00
parent f95e957361
commit 4dac6ab05c
23 changed files with 646 additions and 355 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -2,17 +2,17 @@
{
"00" : {
"type": "SOL_M2_154_SSD",
"version": "25",
"version": "26",
"md5": "57e02f80c9f2581be0a140979b1124e1"
},
"01" : {
"type": "SOL_M2_29_SSD",
"version": "25",
"version": "26",
"md5": "bed1a20ca6af04e29e5aabce480c1e9d"
},
"02" : {
"type": "SOL_M2_42_SSD",
"version": "25",
"version": "26",
"md5": "80e36c7d4d08beaca8ad2f00f42923d0"
},
"05" : {

View File

@@ -7,6 +7,8 @@ SOURCES += comms.c
SOURCES += syncedproto.c userinterface.c
SOURCES += powermgt.c barcode.c i2cdevices.c settings.c
all: #make sure it is the first target
include board/$(BUILD)/make.mk
@@ -20,6 +22,8 @@ SOURCES += cpu/$(CPU)/cpu.c
SOURCES += board/$(BUILD)/board.c
SOURCES += board/$(BUILD)/screen.c
SOURCES += md5.c
EEPROMDRV ?= eeprom.c

View File

@@ -16,17 +16,22 @@
uint8_t __xdata* drawBuffer;
void drawImageAtAddress(uint32_t addr, uint8_t lut) {
void drawImageAtAddress(uint32_t addr, uint8_t lut) __reentrant {
drawBuffer = malloc(512);
if (!drawBuffer) {
#ifdef DEBUGDRAWING
pr("malloc during draw failed..\n");
#endif
return;
}
struct EepromImageHeader* __xdata eih = (struct EepromImageHeader*)drawBuffer;
static struct EepromImageHeader* __xdata eih;
eih = (struct EepromImageHeader*)drawBuffer;
eepromRead(addr, drawBuffer, sizeof(struct EepromImageHeader));
switch (eih->dataType) {
case DATATYPE_IMG_RAW_1BPP:
pr("Doing raw 1bpp\n");
#ifdef DEBUGDRAWING
pr("Doing raw 1bpp with lut %d\n", lut);
#endif
epdSetup();
if (lut) selectLUT(lut);
beginFullscreenImage();
@@ -45,7 +50,9 @@ void drawImageAtAddress(uint32_t addr, uint8_t lut) {
endWriteFramebuffer();
break;
case DATATYPE_IMG_RAW_2BPP:
pr("Doing raw 2bpp\n");
#ifdef DEBUGDRAWING
pr("Doing raw 2bpp with lut %d\n", lut);
#endif
epdSetup();
if (lut) selectLUT(lut);
beginFullscreenImage();
@@ -76,7 +83,9 @@ void drawImageAtAddress(uint32_t addr, uint8_t lut) {
endWriteFramebuffer();
break;
default: // prevent drawing from an unknown file image type
#ifdef DEBUGDRAWING
pr("Image with type 0x%02X was requested, but we don't know what to do with that currently...\n", eih->dataType);
#endif
free(drawBuffer);
return;
}

View File

@@ -3,11 +3,8 @@
#include <stdint.h>
#define DRAWING_MIN_BITMAP_SIZE (128) //minimum size we'll consider
void set_offline(__bit state);
//void set_offline(__bit state);
#pragma callee_saves drawImageAtAddress
void drawImageAtAddress(uint32_t addr, uint8_t lut);
void drawImageFromBuffer(uint8_t* buffer, const uint8_t lut);
extern void drawImageAtAddress(uint32_t addr, uint8_t lut) __reentrant;
#endif

View File

@@ -24,7 +24,9 @@
extern void dump(uint8_t* __xdata a, uint16_t __xdata l); // remove me when done
__xdata uint8_t i2cbuffer[18];
#ifndef LEAN_VERSION
uint8_t __xdata i2cbuffer[18];
extern uint8_t __xdata blockbuffer[];
bool supportsNFCWake() {
@@ -106,16 +108,22 @@ void i2cBusScan() {
struct I2cTransaction __xdata iictest;
iictest.numBytes = 0;
iictest.bytes = NULL;
#ifdef DEBUGNFC
pr("Starting I2C scan...\n");
#endif
for (uint8_t address = 0x00; address <= 0x7F; address++) {
iictest.deviceAddr = address << 1;
uint8_t res = i2cTransact(&iictest, 1);
if (res == 0) {
#ifdef DEBUGNFC
pr(" - Found i2c device at %02X\n", address);
#endif
}
timerDelay(13330);
}
#ifdef DEBUGNFC
pr("I2C scan complete\n");
#endif
}
bool i2cCheckDevice(uint8_t address) {
@@ -124,8 +132,12 @@ bool i2cCheckDevice(uint8_t address) {
iictest.deviceAddr = address << 1;
uint8_t res = i2cTransact(&iictest, 1);
if (res == 0) {
#ifdef DEBUGNFC
pr("I2C: Device found at 0x%02X\n", address);
#endif
return true;
}
return false;
}
}
#endif

View File

@@ -30,7 +30,7 @@
// #define DEBUG_MODE
// static const uint64_t __code __at(0x008b) mVersionRom = 0x1000011300000000ull;
static const uint64_t __code __at(0x008b) firmwaremagic = (0xdeadd0d0beefcafeull) + HW_TYPE;
#define TAG_MODE_CHANSEARCH 0
#define TAG_MODE_ASSOCIATED 1
@@ -43,74 +43,11 @@ uint8_t __xdata slideShowRefreshCount = 1;
extern uint8_t *__idata blockp;
extern uint8_t __xdata blockbuffer[];
static bool __xdata secondLongCheckIn = false; // send another full request if the previous was a special reason
uint8_t *rebootP;
#ifdef ENABLE_EEPROM_LOADER
extern bool __idata serialBypassActive;
bool __xdata serialActive = false;
void processSerial(uint8_t lastchar) {
static uint8_t __xdata cmdbuffer[4];
// shift characters in
for (uint8_t c = 0; c < 3; c++) {
cmdbuffer[c] = cmdbuffer[c + 1];
}
cmdbuffer[3] = lastchar;
if (strncmp(cmdbuffer + 1, ">D>", 3) == 0) {
wdt120s();
blockp = blockbuffer;
serialBypassActive = true;
pr("ACK>\n");
while (serialBypassActive)
;
if (validateBlockData()) {
pr("ACK>\n");
} else {
pr("NOK>\n");
}
}
if (strncmp(cmdbuffer + 1, "<D<", 3) == 0) {
wdt120s();
pr("ACK>");
for (uint16_t c = 0; c < 4100; c++) {
uartTx(blockbuffer[c]);
timerDelay(TIMER_TICKS_PER_MS / 400); // 30 okay // 50 kinda okay // 80 ook okay?
}
pr("blaat");
}
if (strncmp(cmdbuffer, "STE", 3) == 0) { // store block to offset
if (!eepromErase(4096UL * cmdbuffer[3], 4096 / EEPROM_ERZ_SECTOR_SZ)) {
pr("NOK>\n");
return;
}
if (eepromWrite(4096UL * cmdbuffer[3], blockbuffer + 4, 4096))
pr("ACK>\n");
else
pr("NOK>\n");
}
if (strncmp(cmdbuffer, "LDE", 3) == 0) { // load block from offset
eepromRead(4096UL * cmdbuffer[3], blockbuffer + 4, 4096);
uint16_t *header = blockbuffer;
*header = 4096;
uint16_t *sum = blockbuffer + 2;
*sum = 0;
for (uint16_t c = 4; c < 4100; c++) {
*sum += blockbuffer[c];
}
pr("ACK>\n");
}
}
void serialTerminal() {
serialActive = true;
while (serialActive) {
while (uartBytesAvail()) {
processSerial(uartRx());
}
}
}
#endif
#ifdef DEBUGGUI
void displayLoop() {
powerUp(INIT_BASE | INIT_UART);
@@ -126,6 +63,12 @@ void displayLoop() {
wdt30s();
pr("Failed update screen\n");
powerUp(INIT_EPD);
showFailedUpdate();
timerDelay(TIMER_TICKS_PER_SECOND * 4);
wdt30s();
pr("AP Found\n");
powerUp(INIT_EPD);
showAPFound();
@@ -154,13 +97,15 @@ void displayLoop() {
wdt30s();
pr("NO EEPROM\n");
pr("NO MAC\n");
powerUp(INIT_EPD);
showNoMAC();
timerDelay(TIMER_TICKS_PER_SECOND * 4);
wdtDeviceReset();
}
#endif
#ifdef WRITE_MAC_FROM_FLASH
void writeInfoPageWithMac() {
uint8_t *settemp = blockbuffer + 2048;
@@ -215,7 +160,9 @@ uint8_t channelSelect(uint8_t rounds) { // returns 0 if no accesspoints were fo
for (uint8_t c = 0; c < sizeof(channelList); c++) {
if (detectAP(channelList[c])) {
if (mLastLqi > result[c]) result[c] = mLastLqi;
#ifdef DEBUGMAIN
if (rounds > 2) pr("Channel: %d - LQI: %d RSSI %d\n", channelList[c], mLastLqi, mLastRSSI);
#endif
}
}
}
@@ -238,8 +185,10 @@ void validateMacAddress() {
for (uint8_t __xdata c = 0; c < 8; c++) {
if (mSelfMac[c] != 0xFF) goto macIsValid;
}
// invalid mac address. Display warning screen and sleep forever
// invalid mac address. Display warning screen and sleep forever
#ifdef DEBUGMAIN
pr("Mac can't be all FF's.\n");
#endif
powerUp(INIT_EPD);
showNoMAC();
powerDown(INIT_EPD | INIT_UART | INIT_EEPROM);
@@ -250,11 +199,15 @@ macIsValid:
}
uint8_t getFirstWakeUpReason() {
if (RESET & 0x01) {
#ifdef DEBUGMAIN
pr("WDT reset!\n");
#endif
return WAKEUP_REASON_WDT_RESET;
}
return WAKEUP_REASON_FIRSTBOOT;
}
#ifndef LEAN_VERSION
void checkI2C() {
powerUp(INIT_I2C);
// i2cBusScan();
@@ -263,15 +216,20 @@ void checkI2C() {
// found something!
capabilities |= CAPABILITY_HAS_NFC;
if (supportsNFCWake()) {
#ifdef DEBUGNFC
pr("NFC: NFC Wake Supported\n");
#endif
capabilities |= CAPABILITY_NFC_WAKE;
}
} else {
#ifdef DEBUGNFC
pr("I2C: No devices found");
#endif
// didn't find a NFC chip on the expected ID
powerDown(INIT_I2C);
}
}
#endif
void detectButtonOrJig() {
switch (checkButtonOrJig()) {
@@ -280,18 +238,11 @@ void detectButtonOrJig() {
break;
case DETECT_P1_0_JIG:
wdt120s();
#ifdef ENABLE_EEPROM_LOADER
// run the eeprom loader interface
powerUp(INIT_EPD | INIT_EEPROM);
serialActive = true;
serialTerminal();
#else
// show splashscreen
powerUp(INIT_EPD);
afterFlashScreenSaver();
while (1)
;
#endif
break;
case DETECT_P1_0_NOTHING:
break;
@@ -302,10 +253,9 @@ void detectButtonOrJig() {
void TagAssociated() {
// associated
bool fastNextCheckin = false;
struct AvailDataInfo *__xdata avail;
// Is there any reason why we should do a long (full) get data request (including reason, status)?
if ((longDataReqCounter > LONG_DATAREQ_INTERVAL) || wakeUpReason != WAKEUP_REASON_TIMED) {
if ((longDataReqCounter > LONG_DATAREQ_INTERVAL) || wakeUpReason != WAKEUP_REASON_TIMED || secondLongCheckIn) {
// check if we should do a voltage measurement (those are pretty expensive)
if (voltageCheckCounter == VOLTAGE_CHECK_INTERVAL) {
doVoltageReading();
@@ -353,16 +303,26 @@ void TagAssociated() {
externalWakeHandler(CUSTOM_IMAGE_RF_WAKE);
fastNextCheckin = true;
break;
#ifndef LEAN_VERSION
case WAKEUP_REASON_NFC:
externalWakeHandler(CUSTOM_IMAGE_NFC_WAKE);
fastNextCheckin = true;
break;
#endif
}
if (avail != NULL) {
// we got some data!
longDataReqCounter = 0;
if (secondLongCheckIn == true) {
secondLongCheckIn = false;
}
// since we've had succesful contact, and communicated the wakeup reason succesfully, we can now reset to the 'normal' status
if (wakeUpReason != WAKEUP_REASON_TIMED) {
secondLongCheckIn = true;
}
wakeUpReason = WAKEUP_REASON_TIMED;
}
if (tagSettings.enableTagRoaming) {
@@ -431,6 +391,7 @@ void TagAssociated() {
doSleep(getNextSleep() * 1000UL);
}
}
powerUp(INIT_UART);
}
void TagChanSearch() {
@@ -541,12 +502,16 @@ void TagSlideShow() {
doSleep(1000UL * SLIDESHOW_INTERVAL_GLACIAL);
break;
}
#ifdef DEBUGMAIN
pr("wake...\n");
#endif
}
}
void TagShowWaitRFWake() {
#ifdef DEBUGMAIN
pr("waiting for RF wake to start slideshow, now showing image\n");
#endif
currentChannel = 11; // suppress the no-rf image thing
displayCustomImage(CUSTOM_IMAGE_SLIDESHOW);
// powerDown(INIT_EEPROM | INIT_EPD);
@@ -657,40 +622,36 @@ void executeCommand(uint8_t cmd) {
}
void main() {
// displayLoop(); // remove me
setupPortsInitial();
powerUp(INIT_BASE | INIT_UART);
pr("BOOTED> %d.%d.%d%s\n", fwVersion / 100, (fwVersion % 100) / 10, (fwVersion % 10), fwVersionSuffix);
#ifdef DEBUGGUI
displayLoop(); // remove me
#endif
// Find the reason why we're booting; is this a WDT?
wakeUpReason = getFirstWakeUpReason();
// dump(blockbuffer, 1024);
// get our own mac address. this is stored in Infopage at offset 0x10-onwards
boardGetOwnMac(mSelfMac);
#ifdef DEBUGMAIN
pr("MAC>%02X%02X", mSelfMac[0], mSelfMac[1]);
pr("%02X%02X", mSelfMac[2], mSelfMac[3]);
pr("%02X%02X", mSelfMac[4], mSelfMac[5]);
pr("%02X%02X\n", mSelfMac[6], mSelfMac[7]);
for (uint16_t c = 0; c < 4096; c++) {
blockbuffer[c] = (c % 256) & 0xFF;
}
#endif
// do a little sleep, this prevents a partial boot during battery insertion
doSleep(2000UL);
doSleep(400UL);
powerUp(INIT_EEPROM | INIT_UART);
uint8_t __idata dati;
pr("blockbuffer @%d, idata@%d\n",&blockbuffer[0], &dati);
dump(blockbuffer, 4096);
// load settings from infopage
loadSettings();
// invalidate the settings, and write them back in a later state
invalidateSettingsEEPROM();
#ifdef WRITE_MAC_FROM_FLASH
if (mSelfMac[7] == 0xFF && mSelfMac[6] == 0xFF) {
wdt10s();
@@ -738,8 +699,10 @@ void main() {
#endif
if (tagSettings.enableFastBoot) {
// Fastboot
// Fastboot
#ifdef DEBUGMAIN
pr("Doing fast boot\n");
#endif
capabilities = tagSettings.fastBootCapabilities;
if (tagSettings.fixedChannel) {
currentChannel = tagSettings.fixedChannel;
@@ -748,15 +711,18 @@ void main() {
}
} else {
// Normal boot/startup
#ifdef DEBUGMAIN
pr("Normal boot\n");
#endif
// validate the mac address; this will display a warning on the screen if the mac address is invalid
validateMacAddress();
#ifndef LEAN_VERSION
#if (NFC_TYPE == 1)
// initialize I2C
checkI2C();
#endif
#endif
// Get a voltage reading on the tag, loading down the battery with the radio
doVoltageReading();

208
zbs243_Tag_FW/md5.c Normal file
View File

@@ -0,0 +1,208 @@
/*
* Derived from the RSA Data Security, Inc. MD5 Message-Digest Algorithm
* and modified slightly to be functionally identical but condensed into control structures.
*/
#include "md5.h"
/*
* Constants defined by the MD5 algorithm
*/
#define A 0x67452301
#define B 0xefcdab89
#define C 0x98badcfe
#define D 0x10325476
const static uint32_t __code S[] = {7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22,
5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20,
4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23,
6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21};
const static uint32_t __code K[] = {0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee,
0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,
0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821,
0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa,
0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8,
0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed,
0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a,
0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c,
0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,
0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05,
0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,
0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039,
0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,
0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,
0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391};
/*
* Padding used to make the size (in bits) of the input congruent to 448 mod 512
*/
const static uint8_t __code PADDING[] = {0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
/*
* Bit-manipulation functions defined by the MD5 algorithm
*/
#define F(X, Y, Z) ((X & Y) | (~X & Z))
#define G(X, Y, Z) ((X & Z) | (Y & ~Z))
#define H(X, Y, Z) (X ^ Y ^ Z)
#define I(X, Y, Z) (Y ^ (X | ~Z))
/*
* Rotates a 32-bit word left by n bits
*/
uint32_t rotateLeft(uint32_t x, uint32_t n) {
return (x << n) | (x >> (32 - n));
}
/*
* Initialize a context
*/
uint64_t __xdata ctxsize = 0; // Size of input in bytes
uint32_t __xdata ctxbuffer[4] = {0}; // Current accumulation of hash
uint8_t __xdata ctxinput[64] = {0}; // Input to be used in the next step
uint8_t __xdata ctxdigest[16] = {0}; // Result of algorithm
void md5Init() {
ctxsize = (uint64_t)0;
ctxbuffer[0] = (uint32_t)A;
ctxbuffer[1] = (uint32_t)B;
ctxbuffer[2] = (uint32_t)C;
ctxbuffer[3] = (uint32_t)D;
}
/*
* Add some amount of input to the context
*
* If the input fills out a block of 512 bits, apply the algorithm (md5Step)
* and save the result in the buffer. Also updates the overall size.
*/
uint32_t swapEndian(uint8_t j) __reentrant{
static uint32_t __xdata temp;
temp = (uint32_t)(ctxinput[(j * 4) + 3]) << 24 |
(uint32_t)(ctxinput[(j * 4) + 2]) << 16 |
(uint32_t)(ctxinput[(j * 4) + 1]) << 8 |
(uint32_t)(ctxinput[(j * 4)]);
return temp;
}
uint32_t __xdata input[16];
void md5Update(uint8_t *input_buffer, size_t input_len) __reentrant{
static unsigned int __xdata offset;
offset = ctxsize % 64;
ctxsize += (uint64_t)input_len;
// Copy each byte in input_buffer into the next space in our context input
for (unsigned int i = 0; i < input_len; ++i) {
ctxinput[offset++] = (uint8_t) * (input_buffer + i);
// If we've filled our context input, copy it into our local array input
// then reset the offset to 0 and fill in a new buffer.
// Every time we fill out a chunk, we run it through the algorithm
// to enable some back and forth between cpu and i/o
if (offset % 64 == 0) {
for (unsigned int j = 0; j < 16; ++j) {
// Convert to little-endian
// The local variable `input` our 512-bit chunk separated into 32-bit words
// we can use in calculations
input[j] = swapEndian(j);
}
md5Step(input);
offset = 0;
}
}
}
/*
* Pad the current input to get to 448 bytes, append the size in bits to the very end,
* and save the result of the final iteration into digest.
*/
void md5Finalize() __reentrant{
// uint32_t __xdata input[16];
static unsigned int __xdata offset;
offset = ctxsize % 64;
static unsigned int __xdata padding_length;
padding_length = offset < 56 ? 56 - offset : (56 + 64) - offset;
// Fill in the padding and undo the changes to size that resulted from the update
md5Update(PADDING, padding_length);
ctxsize -= (uint64_t)padding_length;
// Do a final update (internal to this function)
// Last two 32-bit words are the two halves of the size (converted from bytes to bits)
for (unsigned int j = 0; j < 14; ++j) {
input[j] = swapEndian(j);
}
input[14] = (uint32_t)(ctxsize * 8);
input[15] = (uint32_t)((ctxsize * 8) >> 32);
md5Step(input);
// Move the result into digest (convert from little-endian)
for (unsigned int i = 0; i < 4; ++i) {
ctxdigest[(i * 4) + 0] = (uint8_t)((ctxbuffer[i] & 0x000000FF));
ctxdigest[(i * 4) + 1] = (uint8_t)((ctxbuffer[i] & 0x0000FF00) >> 8);
ctxdigest[(i * 4) + 2] = (uint8_t)((ctxbuffer[i] & 0x00FF0000) >> 16);
ctxdigest[(i * 4) + 3] = (uint8_t)((ctxbuffer[i]) >> 24);
}
}
/*
* Step on 512 bits of input with the main MD5 algorithm.
*/
void md5Step(uint32_t *input) __reentrant {
static uint32_t __xdata AA;
static uint32_t __xdata BB;
static uint32_t __xdata CC;
static uint32_t __xdata DD;
static uint32_t __xdata E;
static unsigned int __xdata j;
static unsigned int __xdata i;
AA = ctxbuffer[0];
BB = ctxbuffer[1];
CC = ctxbuffer[2];
DD = ctxbuffer[3];
for (i = 0; i < 64; ++i) {
switch (i / 16) {
case 0:
E = F(BB, CC, DD);
j = i;
break;
case 1:
E = G(BB, CC, DD);
j = ((i * 5) + 1) % 16;
break;
case 2:
E = H(BB, CC, DD);
j = ((i * 3) + 5) % 16;
break;
default:
E = I(BB, CC, DD);
j = (i * 7) % 16;
break;
}
uint32_t temp = DD;
DD = CC;
CC = BB;
BB = BB + rotateLeft(AA + E + K[i] + input[j], S[i]);
AA = temp;
}
ctxbuffer[0] += AA;
ctxbuffer[1] += BB;
ctxbuffer[2] += CC;
ctxbuffer[3] += DD;
}

19
zbs243_Tag_FW/md5.h Normal file
View File

@@ -0,0 +1,19 @@
#ifndef MD5_H
#define MD5_H
#include <stdio.h>
#include <stdint.h>
//#include <string.h>
//#include <stdlib.h>
extern uint64_t __xdata ctxsize; // Size of input in bytes
extern uint32_t __xdata ctxbuffer[4]; // Current accumulation of hash
extern uint8_t __xdata ctxinput[64]; // Input to be used in the next step
extern uint8_t __xdata ctxdigest[16]; // Result of algorithm
void md5Init();
void md5Update(uint8_t *input, size_t input_len) __reentrant;
void md5Finalize();
void md5Step(uint32_t *input);
#endif

View File

@@ -119,13 +119,12 @@ static void configSPI(const bool setup) {
static void configUART(const bool setup) {
if (uartActive == setup) return;
if (setup) {
P0FUNC |= (1 << 6) | (1 << 7);
P0FUNC |= (1 << 6);
P0DIR &= ~(1 << 6);
P0DIR |= (1 << 7);
uartInit();
} else {
P0DIR |= (1 << 6);
P0FUNC &= ~((1 << 6) | (1 << 7));
P0FUNC &= ~(1 << 6);
CLKEN &= ~(0x20);
}
uartActive = setup;
@@ -268,13 +267,6 @@ void powerDown(const uint8_t parts) {
}
void doSleep(const uint32_t __xdata t) {
// if (t > 1000) pr("s=%lu\n ", t / 1000);
// powerPortsDownForSleep();
// set up pins for spi(0.0,0.1,0.2), UART (0.6)
// setup 1.1(eeprom_nCS), 1.2(eink_BS1), 1.7(eink_nCS)
// setup 2.0(eink_nRST), 2.1(eink_BUSY), 2.2(eink_D/nC)
UartTxWait();
P0FUNC = 0;
P1FUNC = 0;
P2FUNC = 0;
@@ -294,7 +286,9 @@ void doSleep(const uint32_t __xdata t) {
uartActive = false;
eepromActive = false;
//capabilities |= CAPABILITY_HAS_WAKE_BUTTON;
#ifdef ISDEBUGBUILD
capabilities |= CAPABILITY_HAS_WAKE_BUTTON;
#endif
if (capabilities & CAPABILITY_HAS_WAKE_BUTTON) {
// Button setup on TEST pin 1.0 (input pullup)

View File

@@ -38,13 +38,17 @@ void loadDefaultSettings() {
}
void loadSettingsFromBuffer(uint8_t* p) {
#ifdef DEBUGSETTINGS
pr("SETTINGS: received settings from AP\n");
#endif
switch (*p) {
case SETTINGS_STRUCT_VERSION: // the current tag struct
memcpy((void*)tagSettings, (void*)p, sizeof(struct tagsettings));
break;
default:
#ifdef DEBUGSETTINGS
pr("SETTINGS: received something we couldn't really process, version %d\n");
#endif
break;
}
tagSettings.fastBootCapabilities = capabilities;
@@ -75,29 +79,39 @@ void loadSettings() {
if (tagSettings.settingsVer == 0xFF || valid != SETTINGS_MAGIC) {
// settings not set. load the defaults
loadDefaultSettings();
#ifdef DEBUGSETTINGS
pr("SETTINGS: Loaded default settings\n");
#endif
} else {
if (tagSettings.settingsVer < SETTINGS_STRUCT_VERSION) {
// upgrade
upgradeSettings();
#ifdef DEBUGSETTINGS
pr("SETTINGS: Upgraded from previous version\n");
#endif
} else {
// settings are valid
#ifdef DEBUGSETTINGS
pr("SETTINGS: Loaded from EEPROM\n");
#endif
}
}
}
void writeSettings() {
if (compareSettings()) {
#ifdef DEBUGSETTINGS
pr("SETTINGS: Settings matched current settings\n");
#endif
return;
}
eepromErase(EEPROM_SETTINGS_AREA_START, 1);
uint32_t __xdata valid = SETTINGS_MAGIC;
eepromWrite(EEPROM_SETTINGS_AREA_START, (void*)&valid, 4);
eepromWrite(EEPROM_SETTINGS_AREA_START + 4, (void*)&tagSettings, sizeof(tagSettings));
#ifdef DEBUGSETTINGS
pr("SETTINGS: Updated settings in EEPROM\n");
#endif
}
void invalidateSettingsEEPROM() {

View File

@@ -3,15 +3,28 @@
#include <stdint.h>
#define FW_VERSION 0x0025 // version number
#define FW_VERSION_SUFFIX "-FIX3" // suffix, like -RC1 or whatever.
// #define DEBUGBLOCKS // uncomment to enable extra debug information on the block transfers
// #define PRINT_LUT // uncomment if you want the tag to print the LUT for the current temperature bracket
// #define ENABLE_EEPROM_LOADER // uncomment if you want to load eeprom images via the serial interface
// #define ENABLE_GPIO_WAKE // uncomment to enable GPIO wake
// #define ENABLE_RETURN_DATA // enables the tag to send blocks of data back. Enabling this costs about 4 IRAM bytes
// #define LEAN_VERSION // makes a smaller version, leaving extra flash space for other things
// #define WRITE_MAC_FROM_FLASH // takes mac address from flash if none is set in the infopage
#define FW_VERSION 0x0026 // version number
#define FW_VERSION_SUFFIX "-MD5" // suffix, like -RC1 or whatever.
// #define DEBUGBLOCKS // uncomment to enable extra debug information on the block transfers
// #define DEBUGPROTO // debug protocol
// #define DEBUGOTA // debug OTA FW updates
// #define DEBUGDRAWING // debug the drawing part
// #define DEBUGEPD // debug the EPD driver
// #define DEBUGMAIN // parts in the main loop
// #define DEBUGNFC // debug NFC functions
// #define DEBUGGUI // debug GUI drawing (enabled)
// #define DEBUGSETTINGS // debug settings module (preferences/eeprom)
#define VALIDATE_IMAGE_MD5 // The firmware can validate the image MD5 before displaying it. This costs about 8mAS (milliamp-second) for a 1.54, 16
// #define PRINT_LUT // uncomment if you want the tag to print the LUT for the current temperature bracket
// #define ENABLE_GPIO_WAKE // uncomment to enable GPIO wake
// #define ENABLE_RETURN_DATA // enables the tag to send blocks of data back. Enabling this costs about 4 IRAM bytes
// #define LEAN_VERSION // makes a smaller version, leaving extra flash space for other things
// #define WRITE_MAC_FROM_FLASH // takes mac address from flash if none is set in the infopage
#if defined(DEBUGSETTINGS) || defined(DEBUGMSG) || defined(DEBUGBLOCKS) || defined(DEBUGPROTO) || defined(DEBUGOTA) || defined(DEBUGNFC) || defined(DEBUGEPD) || defined(DEBUGMAIN)
#define ISDEBUGBUILD
#endif
#define SETTINGS_STRUCT_VERSION 0x01

View File

@@ -26,6 +26,8 @@
#include "userinterface.h"
#include "wdt.h"
#include "uart.h"
#include "md5.h"
#include "flash.h"
// download-stuff
uint8_t __xdata blockbuffer[BLOCK_XFER_BUFFER_SIZE] = {0};
@@ -54,6 +56,9 @@ uint8_t __xdata currentChannel = 0;
static uint8_t __xdata inBuffer[128] = {0};
static uint8_t __xdata outBuffer[128] = {0};
// determines if the tagAssociated loop in main.c performs a rapid next checkin
bool __xdata fastNextCheckin = false;
// other stuff we shouldn't have to put here...
static uint32_t __xdata markerValid = EEPROM_IMG_VALID;
@@ -99,7 +104,6 @@ void dump(const uint8_t *__xdata a, const uint16_t __xdata l) {
pr("\n0x%04X | ", c);
}
pr("%02X ", a[c]);
UartTxWait();
}
pr("\n--------");
for (uint8_t c = 0; c < ROWS; c++) {
@@ -140,8 +144,8 @@ static void sendPing() {
txframe->srcPan = PROTO_PAN_ID;
commsTxNoCpy(outBuffer);
}
uint8_t detectAP(const uint8_t channel) {
uint32_t __xdata t;
uint8_t detectAP(const uint8_t channel) __reentrant {
static uint32_t __xdata t;
radioRxEnable(false, true);
radioSetChannel(channel);
radioRxFlush();
@@ -150,12 +154,14 @@ uint8_t detectAP(const uint8_t channel) {
sendPing();
t = timerGet() + (TIMER_TICKS_PER_MS * PING_REPLY_WINDOW);
while (timerGet() < t) {
int8_t __xdata ret = commsRxUnencrypted(inBuffer);
static int8_t __xdata ret;
ret = commsRxUnencrypted(inBuffer);
if (ret > 1) {
// dump(inBuffer+sizeof(struct MacFrameNormal),32);
if ((inBuffer[sizeof(struct MacFrameNormal) + 1] == channel) && (getPacketType(inBuffer) == PKT_PONG)) {
if (pktIsUnicast(inBuffer)) {
struct MacFrameNormal *__xdata f = (struct MacFrameNormal *)inBuffer;
static struct MacFrameNormal *__xdata f;
f = (struct MacFrameNormal *)inBuffer;
memcpy(APmac, f->src, 8);
APsrcPan = f->pan;
return c;
@@ -317,9 +323,6 @@ static bool processBlockPart(const struct blockPart *bp) {
size = sizeof(blockbuffer) - start;
}
// check if we already processed this blockpart
if (!(curBlock.requestedParts[bp->blockPart / 8] & (1 << (bp->blockPart % 8)))) return false;
if (checkCRC(bp, sizeof(struct blockPart) + BLOCK_PART_DATA_SIZE)) {
// copy block data to buffer
xMemCopy((void *)(blockbuffer + start), (const void *)bp->data, size);
@@ -381,15 +384,16 @@ static void sendBlockRequest() {
addCRC(blockreq, sizeof(struct blockRequest));
commsTxNoCpy(outBuffer);
}
static struct blockRequestAck *__xdata performBlockRequest() {
uint32_t __xdata t;
static struct blockRequestAck *__xdata performBlockRequest() __reentrant {
static uint32_t __xdata t;
radioRxEnable(true, true);
radioRxFlush();
for (uint8_t c = 0; c < 30; c++) {
sendBlockRequest();
t = timerGet() + (TIMER_TICKS_PER_MS * (7UL + c / 10));
do {
int8_t __xdata ret = commsRxUnencrypted(inBuffer);
static int8_t __xdata ret;
ret = commsRxUnencrypted(inBuffer);
if (ret > 1) {
switch (getPacketType(inBuffer)) {
case PKT_BLOCK_REQUEST_ACK:
@@ -405,7 +409,9 @@ static struct blockRequestAck *__xdata performBlockRequest() {
case PKT_CANCEL_XFER:
return NULL;
default:
#ifdef DEBUGPROTO
pr("pkt w/type %02X\n", getPacketType(inBuffer));
#endif
break;
}
}
@@ -444,13 +450,17 @@ static void sendXferComplete() {
int8_t __xdata ret = commsRxUnencrypted(inBuffer);
if (ret > 1) {
if (getPacketType(inBuffer) == PKT_XFER_COMPLETE_ACK) {
#ifdef DEBUGPROTO
pr("XFC ACK\n");
#endif
return;
}
}
}
}
#ifdef DEBUGPROTO
pr("XFC NACK!\n");
#endif
return;
}
bool validateBlockData() {
@@ -471,18 +481,26 @@ static void getNumSlots() {
eeSize = eepromGetSize();
uint16_t nSlots = mathPrvDiv32x16(eeSize - EEPROM_IMG_START, EEPROM_IMG_EACH >> 8) >> 8;
if (eeSize < EEPROM_IMG_START || !nSlots) {
#ifdef DEBUGPROTO
pr("eeprom is too small\n");
#endif
while (1)
;
} else if (nSlots >> 8) {
#ifdef DEBUGPROTO
pr("eeprom is too big, some will be unused\n");
#endif
imgSlots = 254;
} else
imgSlots = nSlots;
#ifdef DEBUGPROTO
pr("PROTO: %d image slots total\n", imgSlots);
#endif
}
static uint8_t findSlotVer(const uint8_t *ver) {
#ifdef DEBUGBLOCKS
return 0xFF;
#endif
// 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
for (uint8_t c = 0; c < imgSlots; c++) {
struct EepromImageHeader __xdata *eih = (struct EepromImageHeader __xdata *)blockbuffer;
@@ -538,15 +556,13 @@ static void eraseImageBlock(const uint8_t c) {
eepromErase(getAddressForSlot(c), EEPROM_IMG_EACH / EEPROM_ERZ_SECTOR_SZ);
}
static void saveUpdateBlockData(uint8_t blockId) {
if (!eepromWrite(eeSize - OTA_UPDATE_SIZE + (blockId * BLOCK_DATA_SIZE), blockbuffer + sizeof(struct blockData), BLOCK_DATA_SIZE))
pr("EEPROM write failed\n");
eepromWrite(eeSize - OTA_UPDATE_SIZE + (blockId * BLOCK_DATA_SIZE), blockbuffer + sizeof(struct blockData), BLOCK_DATA_SIZE);
}
static void saveImgBlockData(const uint8_t imgSlot, const uint8_t blockId) {
uint16_t length = EEPROM_IMG_EACH - (sizeof(struct EepromImageHeader) + (blockId * BLOCK_DATA_SIZE));
if (length > 4096) length = 4096;
if (!eepromWrite(getAddressForSlot(imgSlot) + sizeof(struct EepromImageHeader) + (blockId * BLOCK_DATA_SIZE), blockbuffer + sizeof(struct blockData), length))
pr("EEPROM write failed\n");
eepromWrite(getAddressForSlot(imgSlot) + sizeof(struct EepromImageHeader) + (blockId * BLOCK_DATA_SIZE), blockbuffer + sizeof(struct blockData), length);
}
void eraseImageBlocks() {
for (uint8_t c = 0; c < imgSlots; c++) {
@@ -568,7 +584,9 @@ static uint32_t getHighSlotId() {
}
}
}
#ifdef DEBUGPROTO
pr("found high id=%lu in slot %d\n", temp, nextImgSlot);
#endif
return temp;
}
@@ -612,7 +630,9 @@ static bool getDataBlock(const uint16_t blockSize) {
struct blockRequestAck *__xdata ack = performBlockRequest();
if (ack == NULL) {
#ifdef DEBUGPROTO
pr("Cancelled request\n");
#endif
return false;
}
if (ack->pleaseWaitMs) { // SLEEP - until the AP is ready with the data
@@ -674,17 +694,22 @@ static bool getDataBlock(const uint16_t blockSize) {
}
uint16_t __xdata dataRequestSize = 0;
uint16_t __xdata otaSize = 0;
static bool downloadFWUpdate(const struct AvailDataInfo *__xdata avail) {
// check if we already started the transfer of this information & haven't completed it
if (xMemEqual((const void *__xdata) & avail->dataVer, (const void *__xdata) & xferDataInfo.dataVer, 8) && xferDataInfo.dataSize) {
// looks like we did. We'll carry on where we left off.
} else {
#if defined(DEBUGOTA)
pr("OTA: Start update!\n");
#endif
// start, or restart the transfer from 0. Copy data from the AvailDataInfo struct, and the struct intself. This forces a new transfer
curBlock.blockId = 0;
xMemCopy8(&(curBlock.ver), &(avail->dataVer));
curBlock.type = avail->dataType;
xMemCopyShort(&xferDataInfo, (void *)avail, sizeof(struct AvailDataInfo));
eraseUpdateBlock();
otaSize = xferDataInfo.dataSize;
}
while (xferDataInfo.dataSize) {
@@ -708,18 +733,35 @@ static bool downloadFWUpdate(const struct AvailDataInfo *__xdata avail) {
return false;
}
}
wdt60s();
powerUp(INIT_EEPROM);
if (!validateMD5(eeSize - OTA_UPDATE_SIZE, otaSize)) {
#if defined(DEBUGOTA)
pr("OTA: MD5 verification failed!\n");
#endif
// if not valid, restart transfer from the beginning
curBlock.blockId = 0;
powerDown(INIT_EEPROM);
return false;
}
#if defined(DEBUGOTA)
pr("OTA: MD5 pass!\n");
#endif
// no more data, download complete
return true;
}
uint16_t __xdata imageSize = 0;
static bool downloadImageDataToEEPROM(const struct AvailDataInfo *__xdata avail) {
// check if we already started the transfer of this information & haven't completed it
// check if we already started the transfer of this information & haven't completed it
if (xMemEqual((const void *__xdata) & avail->dataVer, (const void *__xdata) & xferDataInfo.dataVer, 8) &&
(xferDataInfo.dataTypeArgument == avail->dataTypeArgument) &&
xferDataInfo.dataSize) {
// looks like we did. We'll carry on where we left off.
// looks like we did. We'll carry on where we left off.
#ifdef DEBUGPROTO
pr("restarting image download");
#endif
} else {
// new transfer
powerUp(INIT_EEPROM);
@@ -737,7 +779,9 @@ static bool downloadImageDataToEEPROM(const struct AvailDataInfo *__xdata avail)
if (nextImgSlot >= imgSlots) nextImgSlot = 0;
if (nextImgSlot == startingSlot) {
powerDown(INIT_EEPROM);
#ifdef DEBUGPROTO
pr("No slots available. Too many images in the slideshow?\n");
#endif
return true;
}
struct EepromImageHeader __xdata *eih = (struct EepromImageHeader __xdata *)blockbuffer;
@@ -768,8 +812,9 @@ static bool downloadImageDataToEEPROM(const struct AvailDataInfo *__xdata avail)
wdtDeviceReset();
eraseSuccess:
powerDown(INIT_EEPROM);
#ifdef DEBUGPROTO
pr("new download, writing to slot %d\n", xferImgSlot);
#endif
// start, or restart the transfer. Copy data from the AvailDataInfo struct, and the struct intself. This forces a new transfer
curBlock.blockId = 0;
xMemCopy8(&(curBlock.ver), &(avail->dataVer));
@@ -806,6 +851,16 @@ static bool downloadImageDataToEEPROM(const struct AvailDataInfo *__xdata avail)
}
// no more data, download complete
// validate MD5
powerUp(INIT_EEPROM);
#ifdef VALIDATE_IMAGE_MD5
if (!validateMD5(getAddressForSlot(xferImgSlot) + sizeof(struct EepromImageHeader), imageSize)) {
// if not valid, restart transfer from the beginning
curBlock.blockId = 0;
powerDown(INIT_EEPROM);
return false;
}
#endif
// borrow the blockbuffer temporarily
struct EepromImageHeader __xdata *eih = (struct EepromImageHeader __xdata *)blockbuffer;
xMemCopy8(&eih->version, &xferDataInfo.dataVer);
@@ -818,19 +873,19 @@ static bool downloadImageDataToEEPROM(const struct AvailDataInfo *__xdata avail)
#ifdef DEBUGBLOCKS
pr("Now writing datatype 0x%02X to slot %d\n", xferDataInfo.dataType, xferImgSlot);
#endif
powerUp(INIT_EEPROM);
eepromWrite(getAddressForSlot(xferImgSlot), eih, sizeof(struct EepromImageHeader));
powerDown(INIT_EEPROM);
return true;
}
struct imageDataTypeArgStruct __xdata arg = {0}; // this is related to the function below, but if declared -inside- the function, it gets cleared during sleep...
inline bool processImageDataAvail(struct AvailDataInfo *__xdata avail) {
struct imageDataTypeArgStruct arg;
*((uint8_t *)arg) = avail->dataTypeArgument;
if (arg.preloadImage) {
#ifdef DEBUGPROTO
pr("Preloading image with type 0x%02X from arg 0x%02X\n", arg.specialType, avail->dataTypeArgument);
#endif
powerUp(INIT_EEPROM);
switch (arg.specialType) {
// check if a slot with this argument is already set; if so, erase. Only one of each arg type should exist
@@ -855,11 +910,14 @@ inline bool processImageDataAvail(struct AvailDataInfo *__xdata avail) {
break;
}
powerDown(INIT_EEPROM);
#ifdef DEBUGPROTO
pr("downloading preload image...\n");
#endif
if (downloadImageDataToEEPROM(avail)) {
// sets xferImgSlot to the right slot
#ifdef DEBUGPROTO
pr("preload complete!\n");
#endif
powerUp(INIT_RADIO);
sendXferComplete();
powerDown(INIT_RADIO);
@@ -872,8 +930,9 @@ inline bool processImageDataAvail(struct AvailDataInfo *__xdata avail) {
// check if we're currently displaying this data payload
if (xMemEqual((const void *__xdata) & avail->dataVer, (const void *__xdata)curDispDataVer, 8)) {
// currently displayed, not doing anything except for sending an XFC
#ifdef DEBUGPROTO
pr("currently shown image, send xfc\n");
#endif
powerUp(INIT_RADIO);
sendXferComplete();
powerDown(INIT_RADIO);
@@ -904,11 +963,15 @@ inline bool processImageDataAvail(struct AvailDataInfo *__xdata avail) {
drawImageFromEeprom(findImgSlot, arg.lut);
powerDown(INIT_EPD | INIT_EEPROM);
} else {
// not found in cache, prepare to download
// not found in cache, prepare to download
#ifdef DEBUGPROTO
pr("downloading image...\n");
#endif
if (downloadImageDataToEEPROM(avail)) {
// sets xferImgSlot to the right slot
// sets xferImgSlot to the right slot
#ifdef DEBUGPROTO
pr("download complete!\n");
#endif
powerUp(INIT_RADIO);
sendXferComplete();
powerDown(INIT_RADIO);
@@ -942,23 +1005,42 @@ bool processAvailDataInfo(struct AvailDataInfo *__xdata avail) {
case DATATYPE_FW_UPDATE:
powerUp(INIT_EEPROM);
if (downloadFWUpdate(avail)) {
pr("firmware download complete, doing update.\n");
powerUp(INIT_EPD);
showApplyUpdate();
#if defined(DEBUGOTA)
pr("OTA: Download complete\n");
#endif
powerUp(INIT_RADIO);
sendXferComplete();
powerDown(INIT_RADIO);
powerUp(INIT_EEPROM);
wdt60s();
eepromReadStart(eeSize - OTA_UPDATE_SIZE);
selfUpdate();
if (validateFWMagic()) {
#if defined(DEBUGOTA)
pr("OTA: Valid magic number\n");
#endif
powerUp(INIT_EPD);
showApplyUpdate();
wdt60s();
eepromReadStart(eeSize - OTA_UPDATE_SIZE);
selfUpdate();
// ends in WDT reset
} else {
#if defined(DEBUGOTA)
pr("OTA: Invalid magic number!\n");
#endif
fastNextCheckin = true;
powerDown(INIT_EEPROM);
wakeUpReason = WAKEUP_REASON_FAILED_OTA_FW;
powerUp(INIT_EPD);
showFailedUpdate();
powerDown(INIT_EPD);
memset(curDispDataVer, 0x00, 8);
}
} else {
return false;
}
break;
case DATATYPE_NFC_URL_DIRECT:
case DATATYPE_NFC_RAW_CONTENT:
// Handle data for the NFC IC (if we have it)
@@ -971,11 +1053,15 @@ bool processAvailDataInfo(struct AvailDataInfo *__xdata avail) {
powerDown(INIT_RADIO);
return true;
}
#ifndef LEAN_VERSION
#ifdef DEBUGPROTO
pr("NFC URL received\n");
#endif
if (xferDataInfo.dataSize == 0 && xMemEqual((const void *__xdata) & avail->dataVer, (const void *__xdata) & xferDataInfo.dataVer, 8)) {
// we've already downloaded this NFC data, disregard and send XFC
#ifdef DEBUGPROTO
pr("this was the same as the last transfer, disregard\n");
#endif
powerUp(INIT_RADIO);
sendXferComplete();
powerDown(INIT_RADIO);
@@ -1005,10 +1091,14 @@ bool processAvailDataInfo(struct AvailDataInfo *__xdata avail) {
return true;
}
return false;
#endif
break;
case DATATYPE_TAG_CONFIG_DATA:
if (xferDataInfo.dataSize == 0 && xMemEqual((const void *__xdata) & avail->dataVer, (const void *__xdata) & xferDataInfo.dataVer, 8)) {
#ifdef DEBUGPROTO
pr("this was the same as the last transfer, disregard\n");
#endif
powerUp(INIT_RADIO);
sendXferComplete();
powerDown(INIT_RADIO);
@@ -1032,7 +1122,9 @@ bool processAvailDataInfo(struct AvailDataInfo *__xdata avail) {
return false;
break;
case DATATYPE_COMMAND_DATA:
#ifdef DEBUGPROTO
pr("CMD received\n");
#endif
powerUp(INIT_RADIO);
sendXferComplete();
powerDown(INIT_RADIO);
@@ -1051,9 +1143,13 @@ bool processAvailDataInfo(struct AvailDataInfo *__xdata avail) {
return true;
}
#ifdef EPD_SSD1619
#ifdef DEBUGPROTO
pr("OTA LUT received\n");
#endif
if (xferDataInfo.dataSize == 0 && xMemEqual((const void *__xdata) & avail->dataVer, (const void *__xdata) & xferDataInfo.dataVer, 8)) {
#ifdef DEBUGPROTO
pr("this was the same as the last transfer, disregard\n");
#endif
powerUp(INIT_RADIO);
sendXferComplete();
powerDown(INIT_RADIO);
@@ -1079,6 +1175,48 @@ bool processAvailDataInfo(struct AvailDataInfo *__xdata avail) {
return true;
}
bool validateMD5(uint32_t __xdata addr, uint16_t __xdata len) {
md5Init();
while (len) {
eepromRead(addr, blockbuffer, 256);
if (len >= 256) {
md5Update(blockbuffer, 256);
len -= 256;
addr += 256;
} else {
md5Update(blockbuffer, len);
len = 0;
}
}
md5Finalize();
if (xMemEqual((const void *__xdata)ctxdigest, (const void *__xdata) & xferDataInfo.dataVer, 8)) {
#ifdef DEBUGPROTO
pr("MD5 pass!");
#endif
return true;
} else {
#ifdef DEBUGPROTO
pr("MD5 fail...");
#endif
return false;
}
}
bool validateFWMagic() {
flashRead(0x8b, (void *)(blockbuffer + 1024), 256);
eepromRead(eeSize - OTA_UPDATE_SIZE, blockbuffer, 256);
if (xMemEqual((const void *__xdata)(blockbuffer + 1024), (const void *__xdata)(blockbuffer + 0x8b), 8)) {
#ifdef DEBUGPROTO
pr("magic number matches! good fw");
#endif
return true;
} else {
#ifdef DEBUGPROTO
pr("this probably isn't a (recent) firmware file\n");
#endif
return false;
}
}
void initializeProto() {
getNumSlots();
curHighSlotId = getHighSlotId();

View File

@@ -9,6 +9,8 @@ extern uint8_t __xdata currentChannel;
extern uint8_t __xdata APmac[];
extern uint8_t __xdata curImgSlot;
extern bool __xdata fastNextCheckin;
//extern void setupRadio(void);
//extern void killRadio(void);
@@ -35,4 +37,7 @@ extern bool processAvailDataInfo(struct AvailDataInfo *__xdata avail);
extern void initializeProto();
extern uint8_t detectAP(const uint8_t channel);
extern bool validateMD5(uint32_t __xdata addr, uint16_t __xdata len);
extern bool validateFWMagic();
#endif

View File

@@ -76,6 +76,19 @@ void addOverlay() {
} else {
lowBatteryShown = false;
}
#ifdef ISDEBUGBUILD
#if (SCREEN_WIDTH == 152)
epdPrintBegin(139, 151, EPD_DIRECTION_Y, EPD_SIZE_SINGLE, EPD_COLOR_RED);
#elif (SCREEN_WIDTH == 400)
epdPrintBegin(87, 0, EPD_DIRECTION_Y, EPD_SIZE_SINGLE, EPD_COLOR_RED);
#elif (SCREEN_WIDTH == 128)
epdPrintBegin(87, 0, EPD_DIRECTION_X, EPD_SIZE_SINGLE, EPD_COLOR_RED);
#endif
epdpr("DEBUG");
epdPrintEnd();
#endif
}
void afterFlashScreenSaver() {
@@ -203,7 +216,7 @@ void showSplashScreen() {
if (displayCustomImage(CUSTOM_IMAGE_SPLASHSCREEN)) return;
powerUp(INIT_EPD);
#if (HW_TYPE != SOLUM_M2_BW_29_LOWTEMP)
#if (HW_TYPE != SOLUM_M2_BW_29_LOWTEMP)
selectLUT(EPD_LUT_NO_REPEATS);
#endif
@@ -235,14 +248,27 @@ void showSplashScreen() {
epdpr("zbs154 %04X%s", fwVersion, fwVersionSuffix);
epdPrintEnd();
#ifdef ISDEBUGBUILD
epdPrintBegin(5, 78, EPD_DIRECTION_X, EPD_SIZE_DOUBLE, EPD_COLOR_RED);
epdpr("DEBUG");
epdPrintEnd();
#endif
#endif
#if (SCREEN_WIDTH == 128) // 2.9"
epdPrintBegin(0, 295, EPD_DIRECTION_Y, EPD_SIZE_DOUBLE, EPD_COLOR_BLACK);
epdpr("Starting");
epdpr("OpenEPaperLink");
epdPrintEnd();
#ifdef ISDEBUGBUILD
epdPrintBegin(35, 280, EPD_DIRECTION_Y, EPD_SIZE_DOUBLE, EPD_COLOR_BLACK);
epdpr("DEBUG");
epdPrintEnd();
#endif
epdPrintBegin(64, 295, EPD_DIRECTION_Y, EPD_SIZE_SINGLE, EPD_COLOR_BLACK);
addCapabilities();
epdPrintEnd();
@@ -268,11 +294,6 @@ void showSplashScreen() {
loadRawBitmap(oepli, 0, 12, EPD_COLOR_BLACK);
loadRawBitmap(cloud, 0, 0, EPD_COLOR_RED);
#endif
// lutTest();
// drawLineVertical(EPD_COLOR_RED, 64, 10, 286);
// drawLineVertical(EPD_COLOR_BLACK, 65, 10, 286);
// timerDelay(TIMER_TICKS_PER_SECOND * 4);
#endif
#if (SCREEN_WIDTH == 400) // 4.2"
epdPrintBegin(3, 3, EPD_DIRECTION_X, EPD_SIZE_DOUBLE, EPD_COLOR_BLACK);
@@ -331,13 +352,33 @@ void showApplyUpdate() {
drawNoWait();
}
void showFailedUpdate() {
setColorMode(EPD_MODE_NORMAL, EPD_MODE_INVERT);
selectLUT(1);
clearScreen();
setColorMode(EPD_MODE_IGNORE, EPD_MODE_NORMAL);
#if (SCREEN_WIDTH == 152)
epdPrintBegin(18, 60, EPD_DIRECTION_X, EPD_SIZE_SINGLE, EPD_COLOR_BLACK);
#endif
#if (SCREEN_WIDTH == 128)
epdPrintBegin(48, 270, EPD_DIRECTION_Y, EPD_SIZE_DOUBLE, EPD_COLOR_BLACK);
#endif
#if (SCREEN_WIDTH == 400)
epdPrintBegin(68, 134, EPD_DIRECTION_X, EPD_SIZE_DOUBLE, EPD_COLOR_BLACK);
#endif
epdpr("Invalid OTA FW!");
epdPrintEnd();
drawWithSleep();
}
void showAPFound() {
if (displayCustomImage(CUSTOM_IMAGE_APFOUND)) return;
powerUp(INIT_EPD | INIT_EEPROM);
clearScreen();
setColorMode(EPD_MODE_NORMAL, EPD_MODE_INVERT);
#if (HW_TYPE != SOLUM_M2_BW_29_LOWTEMP)
#if (HW_TYPE != SOLUM_M2_BW_29_LOWTEMP)
selectLUT(1);
#endif
@@ -451,7 +492,7 @@ void showAPFound() {
void showNoAP() {
if (displayCustomImage(CUSTOM_IMAGE_NOAPFOUND)) return;
powerUp(INIT_EPD | INIT_EEPROM);
#if (HW_TYPE != SOLUM_M2_BW_29_LOWTEMP)
#if (HW_TYPE != SOLUM_M2_BW_29_LOWTEMP)
selectLUT(EPD_LUT_NO_REPEATS);
#endif

View File

@@ -8,7 +8,10 @@ bool displayCustomImage(uint8_t imagetype);
void afterFlashScreenSaver();
void showSplashScreen();
void showApplyUpdate();
void showFailedUpdate();
void showAPFound();
void showNoAP();
void showLongTermSleep();

View File

@@ -8,6 +8,7 @@
#ifndef LEAN_VERSION
static const uint8_t __code oepli[] = {
128, 26,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,

View File

@@ -198,9 +198,9 @@ static void epdReset() {
timerDelay(TIMER_TICKS_PER_SECOND / 1000);
shortCommand(CMD_SOFT_RESET); // software reset
timerDelay(TIMER_TICKS_PER_SECOND / 1000);
timerDelay(TIMER_TICKS_PER_SECOND / 500);
shortCommand(CMD_SOFT_RESET2);
timerDelay(TIMER_TICKS_PER_SECOND / 1000);
timerDelay(TIMER_TICKS_PER_SECOND / 500);
}
void epdConfigGPIO(bool setup) {
// data / _command: 2.2
@@ -233,7 +233,7 @@ void epdEnterSleep() {
P2_0 = 1;
timerDelay(50);
shortCommand(CMD_SOFT_RESET2);
epdBusyWait(TIMER_TICKS_PER_MS * 15);
epdBusyWait(TIMER_TICKS_PER_MS * 150);
shortCommand1(CMD_ENTER_SLEEP, 0x03);
isInited = false;
}
@@ -291,11 +291,11 @@ uint16_t epdGetBattery(void) {
shortCommand1(CMD_DISP_UPDATE_CTRL2, SCREEN_CMD_CLOCK_ON | SCREEN_CMD_ANALOG_ON);
shortCommand(CMD_ACTIVATION);
epdBusyWait(TIMER_TICKS_PER_MS * 100);
epdBusyWait(TIMER_TICKS_PER_MS * 150);
for (val = 3; val < 8; val++) {
shortCommand1(CMD_SETUP_VOLT_DETECT, val);
epdBusyWait(TIMER_TICKS_PER_MS * 100);
epdBusyWait(TIMER_TICKS_PER_MS * 150);
if (epdGetStatus() & 0x10) { // set if voltage is less than threshold ( == 1.9 + val / 10)
voltage = 1850 + mathPrvMul8x8(val, 100);
break;
@@ -400,7 +400,9 @@ void selectLUT(uint8_t lut) {
if (dispLutSize == 0) {
dispLutSize = getLutSize();
dispLutSize /= 10;
#ifdef DEBUGEPD
pr("lut size = %d\n", dispLutSize);
#endif
#ifdef PRINT_LUT
dump(waveformbuffer, LUT_BUFFER_SIZE);
#endif
@@ -721,6 +723,8 @@ static void pushYFontBytesToEPD(uint8_t byte1, uint8_t byte2) {
}
}
void writeCharEPD(uint8_t c) {
c-=0x20;
// Writes a single character to the framebuffer
bool empty = true;
for (uint8_t i = 0; i < 20; i++) {

View File

@@ -1,36 +1,5 @@
static const uint8_t __code font[256][20]={ // https://raw.githubusercontent.com/basti79/LCD-fonts/master/10x16_vertikal_MSB_1.h
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x00
{0xE0,0x01,0x30,0x03,0x50,0x02,0x28,0x05,0x28,0x04,0x28,0x04,0x28,0x05,0x50,0x02,0x30,0x03,0xE0,0x01}, // 0x01
{0xE0,0x01,0xF0,0x03,0xB0,0x03,0xD8,0x06,0xD8,0x07,0xD8,0x07,0xD8,0x06,0xB0,0x03,0xF0,0x03,0xE0,0x01}, // 0x02
{0x00,0x3E,0x80,0x7F,0xE0,0x7F,0xF0,0x7F,0xF8,0x3F,0xF8,0x3F,0xF0,0x7F,0xE0,0x7F,0x80,0x7F,0x00,0x3E}, // 0x03
{0x00,0x01,0x80,0x03,0xC0,0x0F,0xE0,0x1F,0xF8,0x7F,0xF0,0x1F,0xE0,0x0F,0xC0,0x07,0x80,0x03,0x00,0x01}, // 0x04
{0x80,0x03,0xC0,0x07,0xC0,0x07,0xC0,0x3F,0xF8,0x7F,0xB8,0x7F,0xC0,0x3F,0xC0,0x07,0xC0,0x07,0x80,0x03}, // 0x05
{0x80,0x03,0xC0,0x07,0xC0,0x0F,0xC0,0x1F,0xF8,0x3F,0xB8,0x7F,0xC0,0x1F,0xC0,0x0F,0xC0,0x07,0x80,0x03}, // 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
{0xE0,0x01,0x10,0x02,0x08,0x04,0x08,0x04,0x08,0x04,0x08,0x24,0x10,0x2E,0xE0,0x71,0x00,0x70,0x00,0x18}, // 0x0B
{0x00,0x00,0x00,0x1E,0x20,0x21,0xA0,0x40,0xF8,0x40,0xA0,0x40,0xA0,0x41,0x00,0x21,0x00,0x1E,0x00,0x00}, // 0x0C
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x0D
{0x06,0x00,0x0E,0x00,0x0E,0x00,0xFC,0x1F,0x00,0x18,0x30,0x10,0x70,0x30,0x70,0x20,0xE0,0x7F,0x00,0x00}, // 0x0E
{0x00,0x01,0xC0,0x0F,0xC0,0x04,0x40,0x08,0x60,0x18,0x40,0x08,0x40,0x04,0xC0,0x0C,0xC0,0x0B,0x00,0x01}, // 0x0F
{0xF8,0x0F,0xF0,0x07,0xF0,0x07,0xE0,0x03,0xE0,0x03,0xE0,0x03,0xC0,0x01,0xC0,0x01,0x80,0x00,0x80,0x00}, // 0x10
{0x80,0x00,0x80,0x00,0xC0,0x01,0xC0,0x01,0xE0,0x03,0xE0,0x03,0xE0,0x03,0xF0,0x07,0xF0,0x07,0xF8,0x0F}, // 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,0xD8,0x7F,0x00,0x00,0x00,0x00,0xD8,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x13
{0x00,0x00,0x00,0x38,0x00,0x7C,0x00,0x7E,0xFE,0x7F,0x00,0x40,0x00,0x40,0xFE,0x7F,0x00,0x00,0x00,0x00}, // 0x14
{0x00,0x00,0x00,0x00,0x86,0x3B,0xC2,0x4C,0x42,0x44,0x62,0x46,0x32,0x42,0xDC,0x41,0x00,0x00,0x00,0x00}, // 0x15
{0x00,0x00,0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x00}, // 0x16
{0x00,0x00,0x00,0x00,0x11,0x10,0x09,0x20,0xFD,0x7F,0x09,0x20,0x11,0x10,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x17
{0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x20,0xFE,0x7F,0x00,0x20,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x18
{0x00,0x00,0x00,0x00,0x08,0x00,0x04,0x00,0xFE,0x7F,0x04,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x19
{0x00,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0xA0,0x02,0xC0,0x01,0x80,0x00,0x00,0x00}, // 0x1A
{0x00,0x00,0x80,0x00,0xC0,0x01,0xA0,0x02,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x00,0x00}, // 0x1B
{0x00,0x00,0xF8,0x07,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x00,0x00}, // 0x1C
{0x00,0x00,0x80,0x00,0xC0,0x01,0xA0,0x02,0x80,0x00,0x80,0x00,0xA0,0x02,0xC0,0x01,0x80,0x00,0x00,0x00}, // 0x1D
{0x08,0x00,0x18,0x00,0x78,0x00,0xF8,0x01,0xF8,0x03,0xF8,0x0F,0xF8,0x03,0xF8,0x00,0x38,0x00,0x08,0x00}, // 0x1E
{0x00,0x08,0x00,0x0C,0x00,0x0F,0xC0,0x0F,0xE0,0x0F,0xF8,0x0F,0xE0,0x0F,0x80,0x0F,0x00,0x0E,0x00,0x08}, // 0x1F
static const uint8_t __code font[96][20]={ // https://raw.githubusercontent.com/basti79/LCD-fonts/master/10x16_vertikal_MSB_1.h
{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,0xD8,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x21
{0x00,0x00,0x00,0x00,0x00,0x78,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x78,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x22
@@ -127,132 +96,4 @@ static const uint8_t __code font[256][20]={ // https://raw.githubusercontent.com
{0x00,0x00,0x00,0x00,0x02,0x40,0x02,0x40,0x02,0x40,0x7C,0x3F,0x80,0x00,0x80,0x00,0x00,0x00,0x00,0x00}, // 0x7D
{0xC0,0x00,0x00,0x01,0x00,0x01,0x00,0x01,0x80,0x00,0x80,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x80,0x01}, // 0x7E
{0x00,0x00,0xF8,0x01,0x08,0x03,0x08,0x04,0x08,0x08,0x08,0x04,0x08,0x03,0xF8,0x01,0x00,0x00,0x00,0x00}, // 0x7F
{0xC0,0x03,0x30,0x0C,0x10,0x08,0x08,0x10,0x08,0x10,0x09,0x10,0x0D,0x10,0x0B,0x18,0x00,0x00,0x00,0x00}, // 0x80
{0x00,0x00,0xF0,0x07,0x08,0x20,0x08,0x00,0x08,0x00,0x10,0x20,0xF8,0x07,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x81
{0x00,0x00,0xE0,0x01,0x90,0x02,0x88,0x04,0x88,0x24,0x88,0x44,0x88,0x04,0x88,0x03,0x00,0x00,0x00,0x00}, // 0x82
{0x00,0x00,0x30,0x00,0x48,0x24,0x88,0x44,0x88,0x44,0x90,0x24,0xF8,0x03,0x08,0x00,0x00,0x00,0x00,0x00}, // 0x83
{0x00,0x00,0x30,0x00,0x48,0x24,0x88,0x04,0x88,0x04,0x90,0x24,0xF8,0x03,0x08,0x00,0x00,0x00,0x00,0x00}, // 0x84
{0x00,0x00,0x30,0x00,0x48,0x44,0x88,0x24,0x88,0x04,0x90,0x04,0xF8,0x03,0x08,0x00,0x00,0x00,0x00,0x00}, // 0x85
{0x00,0x00,0x30,0x00,0x48,0x04,0x88,0x44,0x88,0xA4,0x90,0x44,0xF8,0x03,0x08,0x00,0x00,0x00,0x00,0x00}, // 0x86
{0x00,0x00,0xE0,0x01,0x10,0x02,0x08,0x04,0x09,0x04,0x0D,0x04,0x0B,0x04,0x08,0x04,0x00,0x00,0x00,0x00}, // 0x87
{0x00,0x00,0xE0,0x01,0x90,0x22,0x88,0x44,0x88,0x44,0x88,0x24,0x88,0x04,0x88,0x03,0x00,0x00,0x00,0x00}, // 0x88
{0x00,0x00,0xE0,0x01,0x90,0x02,0x88,0x24,0x88,0x04,0x88,0x04,0x88,0x24,0x88,0x03,0x00,0x00,0x00,0x00}, // 0x89
{0x00,0x00,0xE0,0x01,0x90,0x02,0x88,0x44,0x88,0x24,0x88,0x04,0x88,0x04,0x88,0x03,0x00,0x00,0x00,0x00}, // 0x8A
{0x00,0x00,0x00,0x04,0x00,0x24,0x00,0x04,0xF8,0x07,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x8B
{0x00,0x00,0x00,0x04,0x00,0x24,0x00,0x44,0xF8,0x47,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x8C
{0x00,0x00,0x00,0x04,0x00,0x04,0x00,0x44,0xF8,0x27,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x8D
{0x08,0x00,0x70,0x00,0xC0,0x81,0x40,0x0E,0x40,0x18,0x40,0x0C,0x40,0x83,0xC0,0x00,0x30,0x00,0x08,0x00}, // 0x8E
{0x08,0x00,0x70,0x00,0xC0,0x01,0x40,0x4E,0x40,0xB0,0x40,0xB8,0x40,0x4F,0xC0,0x01,0x70,0x00,0x08,0x00}, // 0x8F
{0x00,0x00,0xF8,0x1F,0x88,0x10,0x88,0x10,0x88,0x50,0x88,0x90,0x88,0x10,0x08,0x10,0x00,0x00,0x00,0x00}, // 0x90
{0x70,0x04,0xC8,0x04,0x88,0x04,0x88,0x04,0xF0,0x03,0x98,0x04,0x88,0x04,0x88,0x04,0x88,0x03,0x00,0x00}, // 0x91
{0x08,0x00,0x30,0x00,0xE0,0x01,0x20,0x06,0x20,0x18,0xF8,0x1F,0x88,0x10,0x88,0x10,0x08,0x10,0x00,0x00}, // 0x92
{0x00,0x00,0xE0,0x01,0x10,0x22,0x08,0x44,0x08,0x44,0x08,0x24,0x10,0x02,0xE0,0x01,0x00,0x00,0x00,0x00}, // 0x93
{0x00,0x00,0xE0,0x01,0x10,0x22,0x08,0x04,0x08,0x04,0x08,0x24,0x10,0x02,0xE0,0x01,0x00,0x00,0x00,0x00}, // 0x94
{0x00,0x00,0xE0,0x01,0x10,0x42,0x08,0x24,0x08,0x04,0x08,0x04,0x10,0x02,0xE0,0x01,0x00,0x00,0x00,0x00}, // 0x95
{0x00,0x00,0xF0,0x07,0x08,0x20,0x08,0x40,0x08,0x40,0x10,0x20,0xF8,0x07,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x96
{0x00,0x00,0xF0,0x07,0x08,0x40,0x08,0x20,0x08,0x00,0x10,0x00,0xF8,0x07,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x97
{0x01,0x04,0x01,0x03,0xC1,0x20,0x62,0x00,0x1C,0x00,0x18,0x20,0x60,0x00,0x80,0x00,0x00,0x03,0x00,0x04}, // 0x98
{0x00,0x00,0xE0,0x07,0x10,0x88,0x08,0x10,0x08,0x10,0x08,0x10,0x08,0x90,0x10,0x08,0xE0,0x07,0x00,0x00}, // 0x99
{0x00,0x00,0xE0,0x1F,0x18,0x80,0x08,0x00,0x08,0x00,0x08,0x00,0x10,0x80,0xE0,0x1F,0x00,0x00,0x00,0x00}, // 0x9A
{0x00,0x00,0xE8,0x01,0x10,0x02,0x28,0x04,0xC8,0x04,0x08,0x05,0x10,0x02,0xE0,0x05,0x00,0x00,0x00,0x00}, // 0x9B
{0x00,0x00,0x00,0x00,0x08,0x00,0x18,0x02,0xE8,0x3F,0x08,0x42,0x08,0x42,0x08,0x40,0x00,0x00,0x00,0x00}, // 0x9C
{0x00,0x00,0xE8,0x07,0x30,0x08,0x68,0x10,0x88,0x10,0x08,0x11,0x08,0x16,0x10,0x0C,0xE0,0x17,0x00,0x00}, // 0x9D
{0x00,0x00,0x08,0x04,0x10,0x02,0x20,0x01,0xC0,0x00,0xC0,0x00,0x20,0x01,0x10,0x02,0x08,0x04,0x00,0x00}, // 0x9E
{0x00,0x00,0x01,0x00,0x01,0x04,0x01,0x04,0xFE,0x7F,0x00,0x84,0x00,0x84,0x00,0x80,0x00,0x00,0x00,0x00}, // 0x9F
{0x00,0x00,0x30,0x00,0x48,0x04,0x88,0x04,0x88,0x24,0x90,0x44,0xF8,0x03,0x08,0x00,0x00,0x00,0x00,0x00}, // 0xA0
{0x00,0x00,0x00,0x04,0x00,0x04,0x00,0x04,0xF8,0x27,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0xA1
{0x00,0x00,0xE0,0x01,0x10,0x02,0x08,0x04,0x08,0x24,0x08,0x44,0x10,0x02,0xE0,0x01,0x00,0x00,0x00,0x00}, // 0xA2
{0x00,0x00,0xF0,0x07,0x08,0x00,0x08,0x00,0x08,0x20,0x10,0x40,0xF8,0x07,0x00,0x00,0x00,0x00,0x00,0x00}, // 0xA3
{0x00,0x00,0xF8,0x07,0x00,0x23,0x00,0x42,0x00,0x24,0x00,0x24,0x00,0x44,0xF8,0x03,0x00,0x00,0x00,0x00}, // 0xA4
{0x00,0x00,0xF8,0x1F,0x00,0x48,0x00,0x86,0x80,0xC1,0x60,0x40,0x10,0x80,0xF8,0x1F,0x00,0x00,0x00,0x00}, // 0xA5
{0x00,0x00,0x00,0x00,0x00,0x4C,0x00,0x52,0x00,0x52,0x00,0x52,0x00,0x3E,0x00,0x02,0x00,0x00,0x00,0x00}, // 0xA6
{0x00,0x00,0x00,0x00,0x00,0x3C,0x00,0x42,0x00,0x42,0x00,0x42,0x00,0x42,0x00,0x3C,0x00,0x00,0x00,0x00}, // 0xA7
{0x00,0x00,0x0E,0x00,0x13,0x00,0x11,0x00,0x21,0x00,0xC1,0x06,0x01,0x00,0x07,0x00,0x00,0x00,0x00,0x00}, // 0xA8
{0x00,0x00,0x00,0x1C,0x00,0x22,0x00,0x5D,0x00,0x55,0x00,0x5D,0x00,0x22,0x00,0x1C,0x00,0x00,0x00,0x00}, // 0xA9
{0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0xE0,0x01,0x00,0x00}, // 0xAA
{0x08,0x40,0x30,0x7E,0x40,0x00,0x80,0x01,0x00,0x06,0x00,0x08,0x08,0x31,0x38,0x41,0x28,0x01,0xC8,0x00}, // 0xAB
{0x08,0x40,0x30,0x7E,0x40,0x00,0x80,0x01,0x00,0x06,0x60,0x08,0xA0,0x30,0x20,0x41,0xF8,0x01,0x20,0x00}, // 0xAC
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0xAD
{0x00,0x00,0x80,0x00,0x40,0x01,0x20,0x02,0x10,0x04,0x80,0x00,0x40,0x01,0x20,0x02,0x10,0x04,0x00,0x00}, // 0xAE
{0x00,0x00,0x10,0x04,0x20,0x02,0x40,0x01,0x80,0x00,0x10,0x04,0x20,0x02,0x40,0x01,0x80,0x00,0x00,0x00}, // 0xAF
{0x36,0xDB,0x36,0xDB,0x00,0x00,0x36,0xDB,0x36,0xDB,0x00,0x00,0x36,0xDB,0x36,0xDB,0x00,0x00,0x00,0x00}, // 0xB0
{0xDB,0x36,0xDB,0x36,0x36,0xDB,0xFF,0xFF,0xDB,0x36,0x36,0xDB,0xFF,0xFF,0xDB,0x36,0x36,0xDB,0x36,0xDB}, // 0xB1
{0xFF,0xFF,0xFF,0xFF,0x36,0xDB,0xFF,0xFF,0xFF,0xFF,0x36,0xDB,0xFF,0xFF,0xFF,0xFF,0x36,0xDB,0x36,0xDB}, // 0xB2
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0xB3
{0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0xB4
{0x08,0x00,0x70,0x00,0xC0,0x01,0x40,0x0E,0x40,0x58,0x40,0x8C,0x40,0x03,0xC0,0x00,0x30,0x00,0x08,0x00}, // 0xB5
{0x08,0x00,0x70,0x00,0xC0,0x01,0x40,0x4E,0x40,0x98,0x40,0x8C,0x40,0x43,0xC0,0x00,0x30,0x00,0x08,0x00}, // 0xB6
{0x08,0x00,0x70,0x00,0xC0,0x01,0x40,0x8E,0x40,0x58,0x40,0x0C,0x40,0x03,0xC0,0x00,0x30,0x00,0x08,0x00}, // 0xB7
{0xC0,0x0F,0x30,0x30,0x98,0x67,0xC8,0x4C,0x48,0x48,0x48,0x48,0x58,0x68,0x30,0x30,0xC0,0x0F,0x00,0x00}, // 0xB8
{0x40,0x01,0x40,0x01,0x40,0x01,0x7F,0xFF,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
{0x40,0x01,0x40,0x01,0x40,0x01,0x7F,0x01,0x00,0x01,0xFF,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0xBB
{0x40,0x01,0x40,0x01,0x40,0x01,0x40,0xFF,0x40,0x00,0xC0,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0xBC
{0x00,0x00,0xC0,0x0F,0x20,0x10,0x30,0x20,0x10,0x20,0xF8,0x7F,0x10,0x20,0x10,0x20,0x00,0x00,0x00,0x00}, // 0xBD
{0x00,0x40,0x00,0x20,0x20,0x19,0x20,0x05,0xF8,0x03,0x20,0x05,0x20,0x09,0x00,0x10,0x00,0x20,0x00,0x40}, // 0xBE
{0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0xBF
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xFF,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00}, // 0xC0
{0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0xFF,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00}, // 0xC1
{0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0xFF,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00}, // 0xC2
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00}, // 0xC3
{0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00}, // 0xC4
{0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0xFF,0xFF,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00}, // 0xC5
{0x00,0x00,0x30,0x00,0x48,0x24,0x88,0x44,0x88,0x24,0x90,0x24,0xF8,0x43,0x08,0x00,0x00,0x00,0x00,0x00}, // 0xC6
{0x08,0x00,0x70,0x00,0xC0,0x41,0x40,0x8E,0x40,0xD8,0x40,0x4C,0x40,0x83,0xC0,0x00,0x30,0x00,0x08,0x00}, // 0xC7
{0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0x40,0x00,0x40,0xFF,0x40,0x01,0x40,0x01,0x40,0x01,0x40,0x01}, // 0xC8
{0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x01,0x00,0x01,0x7F,0x01,0x40,0x01,0x40,0x01,0x40,0x01,0x40,0x01}, // 0xC9
{0x40,0x01,0x40,0x01,0x40,0x01,0x40,0xFF,0x40,0x00,0x40,0xFF,0x40,0x01,0x40,0x01,0x40,0x01,0x40,0x01}, // 0xCA
{0x40,0x01,0x40,0x01,0x40,0x01,0x7F,0x01,0x00,0x01,0x7F,0x01,0x40,0x01,0x40,0x01,0x40,0x01,0x40,0x01}, // 0xCB
{0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x7F,0xFF,0x40,0x01,0x40,0x01,0x40,0x01,0x40,0x01}, // 0xCC
{0x40,0x01,0x40,0x01,0x40,0x01,0x40,0x01,0x40,0x01,0x40,0x01,0x40,0x01,0x40,0x01,0x40,0x01,0x40,0x01}, // 0xCD
{0x40,0x01,0x40,0x01,0x40,0x01,0x7F,0xFF,0x00,0x00,0x7F,0xFF,0x40,0x01,0x40,0x01,0x40,0x01,0x40,0x01}, // 0xCE
{0x00,0x00,0x20,0x10,0xC0,0x0F,0x40,0x08,0x40,0x08,0x40,0x08,0x40,0x08,0xC0,0x0F,0x20,0x10,0x00,0x00}, // 0xCF
{0x00,0x00,0xE0,0x41,0x10,0x52,0x08,0x74,0x08,0x24,0x08,0x54,0x10,0x0E,0xE0,0x03,0x00,0x00,0x00,0x00}, // 0xD0
{0x00,0x01,0xF8,0x1F,0x08,0x11,0x08,0x11,0x08,0x10,0x08,0x10,0x10,0x08,0xE0,0x07,0x00,0x00,0x00,0x00}, // 0xD1
{0x00,0x00,0xF8,0x1F,0x88,0x10,0x88,0x50,0x88,0x90,0x88,0x90,0x88,0x50,0x08,0x10,0x00,0x00,0x00,0x00}, // 0xD2
{0x00,0x00,0xF8,0x1F,0x88,0x90,0x88,0x10,0x88,0x10,0x88,0x10,0x88,0x90,0x08,0x10,0x00,0x00,0x00,0x00}, // 0xD3
{0x00,0x00,0xF8,0x1F,0x88,0x10,0x88,0x10,0x88,0x90,0x88,0x50,0x88,0x10,0x08,0x10,0x00,0x00,0x00,0x00}, // 0xD4
{0x00,0x00,0x00,0x04,0x00,0x04,0x00,0x04,0xF8,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0xD5
{0x00,0x00,0x08,0x10,0x08,0x10,0x08,0x10,0xF8,0x5F,0x08,0x90,0x08,0x10,0x08,0x10,0x00,0x00,0x00,0x00}, // 0xD6
{0x00,0x00,0x08,0x10,0x08,0x10,0x08,0x50,0xF8,0x9F,0x08,0x90,0x08,0x50,0x08,0x10,0x00,0x00,0x00,0x00}, // 0xD7
{0x00,0x00,0x08,0x10,0x08,0x90,0x08,0x10,0xF8,0x1F,0x08,0x10,0x08,0x90,0x08,0x10,0x00,0x00,0x00,0x00}, // 0xD8
{0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0xD9
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00}, // 0xDA
{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}, // 0xDB
{0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00}, // 0xDC
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x7E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0xDD
{0x00,0x00,0x08,0x10,0x08,0x10,0x08,0x90,0xF8,0x5F,0x08,0x10,0x08,0x10,0x08,0x10,0x00,0x00,0x00,0x00}, // 0xDE
{0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF}, // 0xDF
{0x00,0x00,0xE0,0x07,0x10,0x08,0x08,0x10,0x08,0x50,0x08,0x90,0x08,0x10,0x10,0x08,0xE0,0x07,0x00,0x00}, // 0xE0
{0x00,0x00,0xF8,0x3F,0x00,0x40,0x00,0x40,0x08,0x47,0x88,0x38,0x48,0x00,0x30,0x00,0x00,0x00,0x00,0x00}, // 0xE1
{0x00,0x00,0xE0,0x07,0x10,0x08,0x08,0x50,0x08,0x90,0x08,0x90,0x08,0x50,0x10,0x08,0xE0,0x07,0x00,0x00}, // 0xE2
{0x00,0x00,0xE0,0x07,0x10,0x08,0x08,0x90,0x08,0x50,0x08,0x10,0x08,0x10,0x10,0x08,0xE0,0x07,0x00,0x00}, // 0xE3
{0x00,0x00,0xE0,0x01,0x10,0x22,0x08,0x44,0x08,0x24,0x08,0x24,0x10,0x42,0xE0,0x01,0x00,0x00,0x00,0x00}, // 0xE4
{0x00,0x00,0xE0,0x07,0x10,0x48,0x08,0x90,0x08,0xD0,0x08,0x50,0x08,0x90,0x10,0x08,0xE0,0x07,0x00,0x00}, // 0xE5
{0x00,0x00,0xFF,0x07,0x10,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x10,0x00,0xF8,0x07,0x00,0x00,0x00,0x00}, // 0xE6
{0x00,0x00,0xFF,0x7F,0x10,0x02,0x08,0x04,0x08,0x04,0x08,0x04,0x10,0x06,0xE0,0x01,0x00,0x00,0x00,0x00}, // 0xE7
{0x00,0x00,0xF8,0x1F,0x20,0x04,0x20,0x04,0x20,0x04,0x20,0x04,0x40,0x04,0x80,0x03,0x00,0x00,0x00,0x00}, // 0xE8
{0x00,0x00,0xE0,0x1F,0x18,0x00,0x08,0x00,0x08,0x40,0x08,0x80,0x10,0x00,0xE0,0x1F,0x00,0x00,0x00,0x00}, // 0xE9
{0x00,0x00,0xE0,0x1F,0x18,0x00,0x08,0x40,0x08,0x80,0x08,0x80,0x10,0x40,0xE0,0x1F,0x00,0x00,0x00,0x00}, // 0xEA
{0x00,0x00,0xE0,0x1F,0x18,0x00,0x08,0x80,0x08,0x40,0x08,0x00,0x10,0x00,0xE0,0x1F,0x00,0x00,0x00,0x00}, // 0xEB
{0x01,0x04,0x01,0x03,0xC1,0x00,0x62,0x00,0x1C,0x20,0x18,0x40,0x60,0x00,0x80,0x00,0x00,0x03,0x00,0x04}, // 0xEC
{0x00,0x10,0x00,0x08,0x00,0x06,0x00,0x01,0xF8,0x40,0x00,0x81,0x00,0x02,0x00,0x04,0x00,0x08,0x00,0x10}, // 0xED
{0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80}, // 0xEE
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0xEF
{0x00,0x00,0x00,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x00,0x00,0x00,0x00}, // 0xF0
{0x00,0x00,0x08,0x01,0x08,0x01,0x08,0x01,0x08,0x01,0xC8,0x07,0x08,0x01,0x08,0x01,0x08,0x01,0x00,0x00}, // 0xF1
{0x05,0x00,0x05,0x00,0x05,0x00,0x05,0x00,0x05,0x00,0x05,0x00,0x05,0x00,0x05,0x00,0x05,0x00,0x05,0x00}, // 0xF2
{0x08,0x42,0x10,0x52,0x20,0x5A,0xC0,0x6C,0x00,0x01,0x60,0x02,0xA0,0x0C,0x20,0x11,0xF8,0x21,0x20,0x40}, // 0xF3
{0x00,0x00,0x00,0x38,0x00,0x7C,0x00,0x7E,0xFE,0x7F,0x00,0x40,0x00,0x40,0xFE,0x7F,0x00,0x00,0x00,0x00}, // 0xF4
{0x00,0x00,0x00,0x00,0x86,0x3B,0xC2,0x4C,0x42,0x44,0x62,0x46,0x32,0x42,0xDC,0x41,0x00,0x00,0x00,0x00}, // 0xF5
{0x00,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x58,0x06,0x58,0x06,0x40,0x00,0x40,0x00,0x40,0x00,0x00,0x00}, // 0xF6
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x05,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0xF7
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x48,0x00,0x48,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00}, // 0xF8
{0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00}, // 0xF9
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x00,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0xFA
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x7E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0xFB
{0x00,0x00,0x00,0x00,0x00,0x42,0x00,0x52,0x00,0x52,0x00,0x52,0x00,0x6C,0x00,0x00,0x00,0x00,0x00,0x00}, // 0xFC
{0x00,0x00,0x00,0x00,0x00,0x42,0x00,0x46,0x00,0x4A,0x00,0x4A,0x00,0x32,0x00,0x00,0x00,0x00,0x00,0x00}, // 0xFD
{0x00,0x00,0xF8,0x07,0xF8,0x07,0xF8,0x07,0xF8,0x07,0xF8,0x07,0xF8,0x07,0xF8,0x07,0xF8,0x07,0x00,0x00}, // 0xFE
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} // 0xFF
};

View File

@@ -2,42 +2,47 @@
#include "cpu.h"
#ifdef AP_FW
#include "stdbool.h"
// #include "string.h"
#include "string.h"
#endif
void uartInit(void) {
// clock it up
CLKEN |= 0x20;
// configure baud rate
UARTBRGH = 0x00;
#ifdef AP_FW
// UARTBRGL = 69; // nice. 230400 baud
// UARTBRGL = 70; // 79 == 200k
// UARTSTA = 0x12; // also set the "empty" bit else we wait forever for it to go up
UARTBRGL = 0x8A; // config for 115200
UARTSTA = 0x10; // clear the register, don't trigger the interrupt just yet
//UARTBRGL = 70; // 79 == 200k
IEN_UART0 = 1;
UARTBRGL = 0x8A; // config for 115200
#else
UARTBRGL = 0x8A; // config for 115200
#endif
UARTSTA = 0x12; // also set the "empty" bit else we wait forever for it to go up
}
#ifndef AP_FW
void uartTx(uint8_t val) {
while (!(UARTSTA & (1 << 1)))
;
UARTSTA &= ~(1 << 1);
UARTBUF = val;
}
#else
extern uint8_t __xdata blockbuffer[];
volatile uint8_t __xdata txtail = 0;
volatile uint8_t __xdata txhead = 0;
volatile uint8_t txtail = 0;
volatile uint8_t txhead = 0;
uint8_t __xdata txbuf[256] = {0};
volatile uint8_t __idata rxtail = 0;
volatile uint8_t __idata rxhead = 0;
uint8_t __xdata rxbuf[256] = {0};
void UartTxWait() {
while (txhead != txtail) {
}
}
void uartTx(uint8_t val) {
while(txhead+1 == txtail){
}
__critical {
txbuf[txhead] = val;
if (txhead == txtail) {
@@ -62,8 +67,20 @@ uint8_t uartBytesAvail() {
}
uint8_t* __idata blockp;
uint8_t __idata cmd[3];
volatile bool __idata serialBypassActive = false;
void checkcommand(uint8_t rx) {
for (uint8_t c = 0; c < 2; c++) {
cmd[c] = cmd[c + 1];
}
cmd[2] = rx;
if (strncmp(cmd, ">D>", 3) == 0) {
blockp = blockbuffer;
serialBypassActive = true;
}
}
void UART_IRQ1(void) __interrupt(0) {
if (UARTSTA & 1) { // RXC
UARTSTA &= 0xfe;
@@ -76,6 +93,7 @@ void UART_IRQ1(void) __interrupt(0) {
} else {
rxbuf[rxhead] = UARTBUF;
rxhead++;
// checkcommand(UARTBUF);
}
}
if (UARTSTA & 2) { // TXC
@@ -86,3 +104,4 @@ void UART_IRQ1(void) __interrupt(0) {
}
}
}
#endif

View File

@@ -3,12 +3,17 @@
#include <stdint.h>
//pre-configured for 115200 8n1
//RX can be done but i do not need it
#pragma callee_saves uartInit
void uartInit(void);
#pragma callee_saves uartTx
void uartTx(uint8_t val);
#ifdef AP_FW
void UART_IRQ1(void) __interrupt (0);
#pragma callee_saves uartBytesAvail
@@ -16,8 +21,6 @@ uint8_t uartBytesAvail(void);
#pragma callee_saves uartRX
uint8_t uartRx();
void UartTxWait();
#endif
#endif