improved AP stability onder load, cleanup

This commit is contained in:
Jelmer
2023-02-05 00:07:25 +01:00
parent c620600caa
commit 300f0fe018
11 changed files with 29 additions and 907 deletions

View File

@@ -2,7 +2,7 @@
BUILD ?= zbs29v033
#file containing main() must be first!
SOURCES += main.c eeprom.c
SOURCES += main.c
SOURCES += comms.c

View File

@@ -64,102 +64,4 @@ void boardInitStage2(void)
__bit boardGetOwnMac(uint8_t __xdata *mac)
{
return flashRead(FLASH_INFOPAGE_ADDR + 0x10, mac, 8);
}
#pragma callee_saves prvUpdateApplierGet
static uint32_t prvUpdateApplierGet(void) __naked
{
__asm__(
" mov DPTR, #00098$ \n"
" mov A, #00099$ \n"
" clr C \n"
" subb A, DPL \n"
" mov B, A \n"
" ret \n"
///actual updater code
"00098$: \n"
//copied to last page of flash for updating, called with ints off and eeprom ready to read update
//flashes 63 flash pages, uses xram for buffer. uses combined erase+flash flash op
" mov _CLKSPEED, #0x21 \n"
" mov _CFGPAGE, #0x04 \n"
" mov R0, #0 \n"
"00001$: \n"
//read a page of update
" mov DPTR, #0xe000 \n"
" mov R1, #0x04 \n"
" mov R2, #0x00 \n"
"000010$: \n"
" mov _SPITX, #0x00 \n"
" mov _SPICFG, #0xa0 \n"
"000011$: \n"
" mov A, _SPICFG \n"
" jb A.5, 000011$ \n"
" mov A, _SPIRX \n"
" movx @DPTR, A \n"
" inc DPTR \n"
" djnz R2, 000010$ \n"
" djnz R1, 000010$ \n"
//flash it
" clr A \n"
" orl _SETTINGS, #0x38 \n"
" mov _FWRTHREE, #0x03 \n"
" mov _FPGNO, R0 \n"
" mov _FWRDSTL, A \n"
" mov _FWRDSTH, A \n"
" mov _FWRLENL, #0xff \n"
" mov _FWRLENH, #0x03 \n"
" mov _FWRSRCL, A \n"
" mov _FWRSRCH, #0xe0 \n"
" orl _TRIGGER, #0x08 \n"
"00050$: \n"
" mov A, _TCON2 \n"
" jnb A.3, 00050$ \n"
" anl _TCON2, #~0x48 \n"
" anl _SETTINGS, #~0x10 \n"
//go do next page
" inc R0 \n"
" cjne R0, #63, 00001$ \n"
//done? reset
" mov _WDTCONF, #0x80 \n"
" mov _WDTENA, #0x01 \n"
" mov A, #0xff \n"
" mov _WDTRSTVALH, A \n"
" mov _WDTRSTVALM, A \n"
" mov _WDTRSTVALL, A \n"
"00090$: \n"
" sjmp 00090$ \n"
"00099$: \n"
);
}
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;
for (i = len; i ; i--)
*dst++ = *src++;
if (!flashWrite(0xfc00, mScreenRow, len, true))
pr("failed to write updater\n");
IEN_EA = 0; //ints off
__asm__(
" mov dptr, #0xfc00 \n"
" clr a \n"
" jmp @a+dptr \n"
);
}

View File

@@ -1,379 +0,0 @@
#include <stdbool.h>
#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)
{
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;
}

View File

@@ -27,22 +27,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
#pragma callee_saves screenByteTx
void screenByteTx(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

View File

@@ -42,8 +42,6 @@ bool commsTxUnencrypted(const void __xdata *packetP, uint8_t len) {
mCommsBuf[0] = len + RADIO_PAD_LEN_BY;
return radioTx(mCommsBuf);;
radioTx(mCommsBuf);;
}
bool commsTxNoCpy(const void __xdata *packetp) {

View File

@@ -1,322 +0,0 @@
#include "asmUtil.h"
#include "screen.h"
#include "eeprom.h"
#include "printf.h"
#include "board.h"
#include "cpu.h"
static uint32_t __xdata mEepromSize;
static uint8_t __xdata mOpcodeErz4K = 0, mOpcodeErz32K = 0, mOpcodeErz64K = 0;
uint8_t mScreenRow[320];
uint32_t eepromGetSize(void)
{
return mEepromSize;
}
void eepromReadStart(uint32_t addr) __reentrant
{
eepromPrvSelect();
eepromByte(0x03);
eepromByte(addr >> 16);
eepromByte(addr >> 8);
eepromByte(addr & 0xff);
}
void eepromRead(uint32_t addr, void __xdata *dstP, uint16_t len) __reentrant
{
uint8_t __xdata *dst = (uint8_t __xdata*)dstP;
eepromPrvSelect();
eepromByte(0x03);
eepromByte(addr >> 16);
eepromByte(addr >> 8);
eepromByte(addr & 0xff);
while (len--)
*dst++ = eepromByte(0);
eepromPrvDeselect();
}
static void eepromPrvSimpleCmd(uint8_t cmd)
{
eepromPrvSelect();
eepromByte(cmd);
eepromPrvDeselect();
}
static bool eepromPrvBusyWait(void)
{
uint8_t val;
eepromPrvSelect();
eepromByte(0x05);
while ((val = eepromByte(0x00)) & 1);
eepromPrvDeselect();
return true;
}
static bool eepromWriteLL(uint32_t addr, const void __xdata *srcP, uint16_t len)
{
const uint8_t __xdata *src = (const uint8_t __xdata*)srcP;
eepromPrvSimpleCmd(0x06);
eepromPrvSelect();
eepromByte(0x02);
eepromByte(addr >> 16);
eepromByte(addr >> 8);
eepromByte(addr & 0xff);
while (len--)
eepromByte(*src++);
eepromPrvDeselect();
return eepromPrvBusyWait();
}
void eepromDeepPowerDown(void)
{
eepromPrvSimpleCmd(0xb9);
}
static void eepromPrvWakeFromPowerdown(void)
{
eepromPrvSimpleCmd(0xab);
}
#pragma callee_saves eepromPrvSfdpRead
static void eepromPrvSfdpRead(uint16_t ofst, uint8_t __xdata *dst, uint8_t len)
{
eepromPrvSelect();
eepromByte(0x5a); //cmd
eepromByte(0); //addr
eepromByte(ofst >> 8);
eepromByte(ofst);
eepromByte(0x00); //dummy
while(len--)
*dst++ = eepromByte(0);
eepromPrvDeselect();
}
__bit eepromInit(void)
{
uint8_t __xdata buf[8];
uint8_t i, nParamHdrs;
eepromPrvWakeFromPowerdown();
//process SFDP
eepromPrvSfdpRead(0, buf, 8);
if (buf[0] != 0x53 || buf[1] != 0x46 || buf[2] != 0x44 || buf[3] != 0x50 || buf[7] != 0xff) {
pr("SFDP: header not found\n");
__bit valid = false;
//try manual ID for chips we know of
eepromPrvSelect();
eepromByte(0x90);
eepromByte(0x00);
eepromByte(0x00);
eepromByte(0x00);
if (eepromByte(0) == 0xc2) { //old macronix chips
valid = true;
mOpcodeErz4K = 0x20;
switch (eepromByte(0)) {
case 0x05: //MX25V512
mEepromSize = 0x00010000ul;
break;
case 0x12: //MX25V4005
mEepromSize = 0x00080000ul;
break;
default:
valid = false;
break;
}
}
eepromPrvDeselect();
return valid;
}
if (buf[5] != 0x01) {
pr("SFDP: version wrong: %u.%d\n", buf[5], buf[4]);
return false;
}
nParamHdrs = buf[6];
if (nParamHdrs == 0xff) //that case is very unlikely and we just do not care
nParamHdrs--;
//now we need to find the JEDEC parameter table header
for (i = 0; i <= nParamHdrs; i++) {
eepromPrvSfdpRead(mathPrvMul8x8(i, 8) + 8, buf, 8);
if (buf[0] == 0x00 && buf[2] == 0x01 && buf[3] >= 9) {
uint8_t j;
eepromPrvSfdpRead(*(uint16_t __xdata*)(buf + 4), mScreenRow, 9 * 4);
if ((mScreenRow[0] & 3) != 1) {
pr("SFDP: no 4K ERZ\n");
break;
}
if (!(mScreenRow[0] & 0x04)) {
pr("SFDP: no large write buf\n");
break;
}
if ((mScreenRow[2] & 0x06)) {
pr("SFDP: addr.len != 3\n");
break;
}
if (!mScreenRow[1] || mScreenRow[1] == 0xff) {
pr("SFDP: 4K ERZ opcode invalid\n");
break;
}
mOpcodeErz4K = mScreenRow[1];
if (mScreenRow[7] & 0x80) {
pr("SFDP: device too big\n");
break;
}
else {
uint8_t t;
if (t = mScreenRow[7])
mEepromSize = 0x00200000UL;
else if (t = mScreenRow[6])
mEepromSize = 0x00002000UL;
else if (t = mScreenRow[5])
mEepromSize = 0x00000020UL;
else {
pr("SFDP: device so small?!\n");
break;
}
while (t) {
mEepromSize <<= 1;
t >>= 1;
}
}
//get erase opcodes
for (j = 0x1c; j < 0x24; j += 2) {
uint8_t instr = mScreenRow[j + 1];
if (!instr || instr == 0xff)
continue;
switch (mScreenRow[j]) {
case 0x0c:
if (mOpcodeErz4K != instr) {
pr("4K ERZ opcode disagreement\n");
return false;
}
break;
case 0x0f: //32K erase
mOpcodeErz32K = instr;
break;
case 0x10: //64K erase
mOpcodeErz64K = instr;
break;
}
}
/*
pr("EEPROM accepted\n");
pr(" ERZ opcodes: \n");
if (mOpcodeErz4K)
pr(" 4K: %02xh\n", mOpcodeErz4K);
if (mOpcodeErz32K)
pr(" 32K: %02xh\n", mOpcodeErz32K);
if (mOpcodeErz64K)
pr(" 64K: %02xh\n", mOpcodeErz64K);
pr(" Size: 0x%*08lx\n", (uint16_t)&mEepromSize);
*/
return true;
}
}
pr("SFDP: no JEDEC table of expected version found\n");
return false;
}
bool eepromWrite(uint32_t addr, const void __xdata *srcP, uint16_t len) __reentrant
{
const uint8_t __xdata *src = (const uint8_t __xdata*)srcP;
while (len) {
uint16_t lenNow = EEPROM_WRITE_PAGE_SZ - (addr & (EEPROM_WRITE_PAGE_SZ - 1));
if (lenNow > len)
lenNow = len;
if (!eepromWriteLL(addr, src, lenNow))
return false;
addr += lenNow;
src += lenNow;
len -= lenNow;
}
return true;
}
bool eepromErase(uint32_t addr, uint16_t nSec) __reentrant
{
uint8_t now;
if (((uint16_t)addr) & 0x0fff)
return false;
for (;nSec; nSec -= now) {
eepromPrvSimpleCmd(0x06);
eepromPrvSelect();
if (nSec >= 16 && !(uint16_t)addr && mOpcodeErz64K) { //erase 64K
eepromByte(mOpcodeErz64K);
now = 16;
}
else if (nSec >= 8 && !(((uint16_t)addr) & 0x7fff) && mOpcodeErz32K) { //erase 32K
eepromByte(mOpcodeErz32K);
now = 8;
}
else { //erase 4K
eepromByte(mOpcodeErz4K);
now = 1;
}
eepromByte(addr >> 16);
eepromByte(addr >> 8);
eepromByte(addr);
eepromPrvDeselect();
if (!eepromPrvBusyWait())
return false;
addr += mathPrvMul16x8(EEPROM_ERZ_SECTOR_SZ, now);
}
return true;
}
void eepromOtpModeEnter(void)
{
eepromPrvSimpleCmd(0xb1);
}
void eepromOtpModeExit(void)
{
eepromPrvSimpleCmd(0xc1);
}

View File

@@ -1,54 +0,0 @@
#ifndef _EEPROM_H_
#define _EEPROM_H_
#include <stdbool.h>
#include <stdint.h>
#define EEPROM_WRITE_PAGE_SZ 256 //max write size & alignment
#define EEPROM_ERZ_SECTOR_SZ 4096 //erase size and alignment
//device has 256 sectors, so eepromErase() cannot erase thw whole device...i can live with that
__bit eepromInit(void);
void eepromOtpModeEnter(void);
void eepromOtpModeExit(void);
#pragma callee_saves eepromRead
void eepromRead(uint32_t addr, void __xdata *dst, uint16_t len) __reentrant;
#pragma callee_saves eepromWrite
bool eepromWrite(uint32_t addr, const void __xdata *src, uint16_t len) __reentrant;
#pragma callee_saves eepromErase
bool eepromErase(uint32_t addr, uint16_t numSectors) __reentrant;
void eepromDeepPowerDown(void);
#pragma callee_saves eepromGetSize
uint32_t eepromGetSize(void);
//this is for firmware update use
void eepromReadStart(uint32_t addr) __reentrant;
//structures
#define EEPROM_IMG_INPROGRESS (0x7fffffffUL)
#define EEPROM_IMG_VALID (0x494d4722UL)
#include "board.h"
#define EEPROM_PIECE_SZ (88)
struct EepromImageHeader { //each image space is 0x17000 bytes, we have space for ten of them
uint64_t version;
uint32_t validMarker;
uint32_t size;
uint32_t rfu[8]; //zero-filled for now
uint8_t piecesMissing[EEPROM_PROGRESS_BYTES]; //each bit represents a EEPROM_PIECE_SZ-byte piece
uint32_t id;
//image data here
//we pre-erase so progress can be calculated by finding the first non-0xff byte
};
#endif

View File

@@ -9,7 +9,6 @@
#include "board.h"
#include "comms.h"
#include "cpu.h"
#include "eeprom.h"
#include "printf.h"
#include "proto.h"
#include "radio.h"
@@ -40,7 +39,8 @@ struct MacFrameBcast {
uint16_t srcPan;
uint8_t src[8];
} __packed;
#define PKT_AVAIL_DATA_REQ_SHORT 0xE4
#define PKT_AVAIL_DATA_SHORTREQ 0xE3
#define PKT_AVAIL_DATA_REQ 0xE5
#define PKT_AVAIL_DATA_INFO 0xE6
#define PKT_BLOCK_PARTIAL_REQUEST 0xE7
@@ -61,10 +61,9 @@ struct AvailDataReq {
uint16_t batteryMv;
uint8_t hwType;
uint8_t wakeupReason;
uint8_t capabilities; // undefined, as of now
uint8_t capabilities; // undefined, as of now
} __packed;
#define DATATYPE_NOUPDATE 0
#define DATATYPE_IMG 1
#define DATATYPE_IMGRAW 2
@@ -72,14 +71,13 @@ struct AvailDataReq {
struct AvailDataInfo {
uint8_t checksum;
uint64_t dataVer; // MD5 of potential traffic
uint32_t dataSize;
uint8_t dataType; // allows for 16 different datatypes
uint64_t dataVer; // MD5 of potential traffic
uint32_t dataSize;
uint8_t dataType; // allows for different datatypes
uint8_t dataTypeArgument; // extra specification or instruction for the tag (LUT to be used for drawing image)
uint16_t nextCheckIn; // when should the tag check-in again? Measured in minutes
uint16_t nextCheckIn; // when should the tag check-in again? Measured in minutes
} __packed;
struct blockPart {
uint8_t checksum;
uint8_t blockId;
@@ -585,7 +583,7 @@ void sendPart(uint8_t partNo) {
radioTx(radiotxbuffer);
}
void sendBlockData() {
if(getBlockDataLength()==0){
if (getBlockDataLength() == 0) {
pr("Invalid block request received, 0 parts..\n");
requestedData.requestedParts[0] |= 0x01;
}
@@ -632,20 +630,14 @@ void sendCancelXfer(uint8_t *dst) {
void sendPong(void *__xdata buf) {
struct MacFrameBcast *rxframe = (struct MacFrameBcast *)buf;
struct MacFrameNormal *frameHeader = (struct MacFrameNormal *)(radiotxbuffer + 1);
memset(radiotxbuffer, 0, sizeof(struct MacFrameNormal) + 2);
radiotxbuffer[sizeof(struct MacFrameNormal) + 1] = PKT_PONG;
radiotxbuffer[0] = sizeof(struct MacFrameNormal) + 1 + RAW_PKT_PADDING;
memcpy(frameHeader->src, mSelfMac, 8);
memcpy(frameHeader->dst, rxframe->src, 8);
frameHeader->fcs.frameType = 1;
frameHeader->fcs.panIdCompressed = 1;
frameHeader->fcs.destAddrType = 3;
frameHeader->fcs.srcAddrType = 3;
radiotxbuffer[1] = 0x41; // fast way to set the appropriate bits
radiotxbuffer[2] = 0xCC; // normal frame
frameHeader->seq = seq++;
frameHeader->pan = rxframe->srcPan;
radioTx(radiotxbuffer);
}
@@ -681,18 +673,16 @@ void main(void) {
radioSetTxPower(10);
radioRxEnable(true, true);
// uint8_t __xdata fromMac[8];
pr("RDY>\n");
housekeepingTimer = timerGet();
// really... if I do the call below, it'll cost me 8 bytes IRAM. Not the kind of 'optimization' I ever dreamed of doing
// pr("MAC>%02X%02X%02X%02X%02X%02X%02X%02X\n", mSelfMac[0], mSelfMac[1], mSelfMac[2], mSelfMac[3], mSelfMac[4], mSelfMac[5], mSelfMac[6], mSelfMac[7]);
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]);
uint16_t __xdata loopCount = 1;
pr("VER>%04X\n", version);
while (1) {
while ((timerGet() - housekeepingTimer) < ((TIMER_TICKS_PER_SECOND * HOUSEKEEPING_INTERVAL) - 100 * TIMER_TICKS_PER_MS)) {
@@ -715,10 +705,17 @@ void main(void) {
case PKT_PING:
sendPong(radiorxbuffer);
break;
case PKT_AVAIL_DATA_SHORTREQ:
// a short AvailDataReq is basically a very short (1 byte payload) packet that requires little preparation on the tx side, for optimal battery use
// bytes of the struct are set 0, so it passes the checksum test, and the ESP32 can detect that no interesting payload is sent
memset(radiorxbuffer + 1 + sizeof(struct MacFrameBcast) + 1, 0, sizeof(struct AvailDataReq));
processAvailDataReq(radiorxbuffer);
break;
default:
pr("t=%02X\n", getPacketType(radiorxbuffer));
break;
}
loopCount = 10000;
}
while (uartBytesAvail()) {
processSerial(uartRx());
@@ -730,8 +727,14 @@ void main(void) {
blockStartTimer = 0;
}
}
loopCount--;
if (loopCount == 0) {
loopCount = 10000;
// every once in a while, especially when handling a lot of traffic, the radio will hang. Calling this every once in while
// alleviates this problem. The radio is set back to 'receive' whenever loopCount overflows
RADIO_command = RADIO_CMD_RECEIVE;
}
}
pr("housekeeping...");
for (uint8_t __xdata c = 0; c < MAX_PENDING_MACS; c++) {
if (pendingDataArr[c].attemptsLeft == 1) {

View File

@@ -1,10 +0,0 @@
#ifndef _SLEEP_H_
#define _SLEEP_H_
#include <stdint.h>
void sleepForMsec(uint32_t msec);
void sleepTillInt(void); //assumes you left only one int enabled!
#endif

View File

@@ -2,7 +2,7 @@ FLAGS += -Isoc/zbs243
FLAGS += -DSOC_ZBS243 --xram-loc 0xe000 --xram-size 0x2000 --model-large
SOURCES += soc/zbs243/soc.c soc/zbs243/wdt.c soc/zbs243/sleep.c soc/zbs243/spi.c soc/zbs243/uart.c soc/zbs243/timer.c soc/zbs243/radio.c
SOURCES += soc/zbs243/soc.c soc/zbs243/wdt.c soc/zbs243/spi.c soc/zbs243/uart.c soc/zbs243/timer.c soc/zbs243/radio.c
SOURCES += soc/zbs243/flash.c soc/zbs243/temperature.c cpu/8051/random.c cpu/8051/printf.c
CPU = 8051
CPU = 8051

View File

@@ -7,7 +7,7 @@
#include "timer.h"
#define RX_BUFFER_SIZE (RADIO_MAX_PACKET_LEN + 1 /* len byte */ + 2 /* RSSI & LQI */)
#define RX_BUFFER_NUM 3
#define RX_BUFFER_NUM 7
static volatile uint8_t __xdata mRxBufs[RX_BUFFER_NUM][RX_BUFFER_SIZE];
static volatile uint8_t __xdata mLastRSSI, mLastTxedSeq, mRxOn, mRxBufNextR, mRxBufNextW, mRxBufNumFree;