mirror of
https://github.com/OpenEPaperLink/OpenEPaperLink.git
synced 2026-03-21 04:06:29 +01:00
290 lines
13 KiB
C
290 lines
13 KiB
C
#ifndef _ZBS243_H_
|
|
#define _ZBS243_H_
|
|
|
|
#include <stdint.h>
|
|
|
|
//P2 selects XPAGE which sucks for us
|
|
//IRAM is not at all mapped into XRAM
|
|
//id page is not in xram either
|
|
|
|
|
|
static __idata __at (0x00) unsigned char R0;
|
|
static __idata __at (0x01) unsigned char R1;
|
|
static __idata __at (0x02) unsigned char R2;
|
|
static __idata __at (0x03) unsigned char R3;
|
|
static __idata __at (0x04) unsigned char R4;
|
|
static __idata __at (0x05) unsigned char R5;
|
|
static __idata __at (0x06) unsigned char R6;
|
|
static __idata __at (0x07) unsigned char R7;
|
|
__sfr __at (0xf0) B;
|
|
__sfr __at (0xe0) ACC;
|
|
__sfr __at (0x82) DPL;
|
|
__sfr __at (0x83) DPH;
|
|
__sfr __at (0x84) DPL1;
|
|
__sfr __at (0x85) DPH1;
|
|
__sfr __at (0x92) DPS; //low bit switched DPTR
|
|
__sfr __at (0x87) PCON; //lower 4 bits as per 8051 spec, bit4 set disables xram
|
|
|
|
__sfr __at (0xb2) PERFMON0;
|
|
__sfr __at (0xb3) PERFMON1;
|
|
__sfr __at (0xb4) PCH; //current PC...yes...
|
|
__sfr __at (0xb5) PCL;
|
|
__sfr __at (0xb6) PERFMON4;
|
|
|
|
|
|
|
|
__sbit __at (0x80) P0_0;
|
|
__sbit __at (0x81) P0_1;
|
|
__sbit __at (0x82) P0_2;
|
|
__sbit __at (0x83) P0_3;
|
|
__sbit __at (0x84) P0_4;
|
|
__sbit __at (0x85) P0_5;
|
|
__sbit __at (0x86) P0_6;
|
|
__sbit __at (0x87) P0_7;
|
|
__sbit __at (0x90) P1_0;
|
|
__sbit __at (0x91) P1_1;
|
|
__sbit __at (0x92) P1_2;
|
|
__sbit __at (0x93) P1_3;
|
|
__sbit __at (0x94) P1_4;
|
|
__sbit __at (0x95) P1_5;
|
|
__sbit __at (0x96) P1_6;
|
|
__sbit __at (0x97) P1_7;
|
|
__sbit __at (0xa0) P2_0;
|
|
__sbit __at (0xa1) P2_1;
|
|
__sbit __at (0xa2) P2_2;
|
|
__sbit __at (0xa3) P2_3;
|
|
__sbit __at (0xa4) P2_4;
|
|
__sbit __at (0xa5) P2_5;
|
|
__sbit __at (0xa6) P2_6;
|
|
__sbit __at (0xa7) P2_7;
|
|
|
|
__sbit __at (0xA8) IEN_UART0;
|
|
__sbit __at (0xA9) IEN_TMR0;
|
|
__sbit __at (0xAB) IEN_TMR1;
|
|
__sbit __at (0xAC) IEN_RF1; //enable for RF interrupt #1 (irq #2)
|
|
__sbit __at (0xAD) IEN_RF2; //enable for RF interrupt #2 (irq #5)
|
|
__sbit __at (0xAF) IEN_EA;
|
|
|
|
//gpio configs (all in cfg page 0 only)
|
|
__sfr __at (0x80) P0; //RO for input pins, WO for output pins (written state not read back)
|
|
__sfr __at (0x90) P1;
|
|
__sfr __at (0xA0) P2; //disabled ot avoid accidental use
|
|
__sfr __at (0xA3) P0LVLSEL; //pin change interrupt edge desired. 0 - rising 1 - falling
|
|
__sfr __at (0xA4) P1LVLSEL;
|
|
__sfr __at (0xA5) P2LVLSEL;
|
|
__sfr __at (0xA6) P0INTEN; //pin change interrupt enable (1 = enabled). will wake device from sleep
|
|
__sfr __at (0xA7) P1INTEN;
|
|
__sfr __at (0xA9) P2INTEN;
|
|
__sfr __at (0xAA) P0CHSTA; //pin change status 1 = changed (remember to clear in ISR & before enabling ISR)
|
|
__sfr __at (0xAB) P1CHSTA;
|
|
__sfr __at (0xAC) P2CHSTA;
|
|
__sfr __at (0xAD) P0FUNC; //1 = func, 0 = gpio
|
|
__sfr __at (0xAE) P1FUNC;
|
|
__sfr __at (0xAF) P2FUNC;
|
|
__sfr __at (0xB9) P0DIR; //1 = in, 0 = out
|
|
__sfr __at (0xBA) P1DIR;
|
|
__sfr __at (0xBB) P2DIR;
|
|
__sfr __at (0xBC) P0PULL; //1 = pull up
|
|
__sfr __at (0xBD) P1PULL;
|
|
__sfr __at (0xBE) P2PULL;
|
|
|
|
__sfr __at (0xA0) XPAGE; //sadly this is accurate! same as P2
|
|
|
|
//these are both avail in both config pages
|
|
__sfr __at (0xA8) IEN0;
|
|
__sfr __at (0xA1) IEN1; //low 1, bits unknown, top 7 bits eable irqs (7..13)
|
|
|
|
|
|
__sfr __at (0x8E) CLKSPEED; //top bit likely selects osc (1 = crystal??), next 3 set divisor FOR CPU, not periphs, bottom 4 unknown
|
|
|
|
__sfr __at (0xB7) CLKEN; //one bit per periph to enable clocks. 0x08 - spi, 0x10 - i2c, 0x20 - uart, 0x80 temp sensor, 0x01 - in-cpu-timers(T0 & T1)
|
|
|
|
__sfr __at (0x8F) RESET; //resets periphs AND stores reset cause. bit 0x01 - we were reset due to WDT, 0x04 - resets radio (Active high), 0x02 resets cpu core
|
|
|
|
//wdt (accessible in CFG page 4), runs at about 62KHz. counter counts up, overflow causes reset
|
|
__sfr __at (0xBA) WDTENA; //low bit is used for WDT off. same SFR addr used as P1DIR when cfg page 0
|
|
__sfr __at (0xBB) WDTPET; //write 0 to pet, write 0xff to reset immediately. same SFR addr used as P2DIR when cfg page 0
|
|
__sfr __at (0xBC) WDTRSTVALL; //wdt reset value low
|
|
__sfr __at (0xBD) WDTRSTVALM; //wdt reset value mid
|
|
__sfr __at (0xBE) WDTRSTVALH; //wdt reset value high
|
|
__sfr __at (0xBF) WDTCONF; //top bit enable, 0x08 to hang instead of reset. top bit only accessible in CFG page 4
|
|
|
|
|
|
//SPI (accessible in CFG page 4)
|
|
__sfr __at (0xEB) SPIUNKNOWN; //existing code sets 0x08 after a byte tx. no idea why. not doing it works
|
|
__sfr __at (0xEC) SPICFG; //0x80 - 1, 0x40 - 0, 0x20 - do TX (cleared on done), {0x10,0x08}) - clock div {4mhz,2mhz,1mhz,500khz}, 0x04 - CPHA, 0x02 - CPOL, 0x01 ?? (breaks rx, maybe bidirectional or rx off)
|
|
__sfr __at (0xED) SPIENA; //0x80 - 1, 0x01 - unit enable. stock code also enables/disables after every byte but i do not think we need to
|
|
__sfr __at (0xEE) SPITX; //tx buffer
|
|
__sfr __at (0xEF) SPIRX; //rx buffer
|
|
|
|
//I2C (accessible in CFG page 0)
|
|
//it is in theory possible to drive it without IRQs but there seem to be hw bugs in figuring out when handling is needed, so i wouldn't. stock also doesn't
|
|
__sfr __at (0x91) I2CSTATE; //top 5 bits are current state: {???, START_SENT, RESTART_SENT, WR_ADDR_ACKED, WR_ADDR_NAKED, TX_BYTE_ACKED, TX_BYTE_NAKED, unused, RD_ADDR_ACKED, RD_ADDR_NAKED, RXED_BYTE}
|
|
//0x93 written by 0xe0 by stock but seems not needed
|
|
__sfr __at (0x94) I2CBUF; //data for RX/TX
|
|
__sfr __at (0x95) I2CCTL; //0x80 = irqOn (#8), 0x40 = master(?), 0x20 = start/restart, 0x10 = stop, 0x08 = irqReqd, 0x04 = sendAck (to RXed btes)
|
|
__sfr __at (0x96) I2CSPEED; //bottom 3 bits = dividerA. next 4 are dividerB. clock = 16MHz / ((dividerB ? 10 *(1 + dividerB) : 12) << dividerA)
|
|
__sfr __at (0xA2) I2CUNKNOWN; //4 ORRED at init or it will not work
|
|
|
|
|
|
//uart is basically hard wired to be a uart. clock is divided from 16MHz. only bottom 4 bits of BRGH are used. divisor is (BRGH:BRGL + 1)
|
|
__sbit __at (0x98) UART_RXF;
|
|
__sbit __at (0x99) UART_TXE;
|
|
__sfr __at (0x98) UARTSTA; //0x10 needed. 0x02 - have tx space, 0x01 - have rx byte. both can cause interrupts. both need to be cleared in irq. flag bits do NOT work if accessed using "jbc"
|
|
__sfr __at (0x99) UARTBUF; //fifo access
|
|
__sfr __at (0x9A) UARTBRGL;
|
|
__sfr __at (0x9B) UARTBRGH; //divisor for uart
|
|
|
|
//timers (same as 8051-classic)
|
|
__sfr __at (0x88) TCON;
|
|
__sfr __at (0x89) TMOD;
|
|
__sfr __at (0x8A) TL0;
|
|
__sfr __at (0x8B) TL1;
|
|
__sfr __at (0x8C) TH0;
|
|
__sfr __at (0x8D) TH1;
|
|
__sfr16 __at (0x8C8A) T0;
|
|
__sfr16 __at (0x8D8B) T1; //used by timer code for storage
|
|
|
|
//flash writing (must be done with CFGPAGE == 4). each page is 0x400 bytes
|
|
__sfr __at (0xD8) FPGNO; //page number (0x00..0x3f for main flash, 0x80 for info block)
|
|
__sfr __at (0xD9) FWRSRCL; //(flash source data for write).lo for write, (flash start offset in page).lo for read
|
|
__sfr __at (0xDA) FWRSRCH; //(flash source data for write).hi for write, (flash start offset in page).hi for read
|
|
__sfr __at (0xDB) FWRDSTL; //(flash start offset in page).lo for write, (dest xram addr).lo for read
|
|
__sfr __at (0xDC) FWRDSTH; //(flash start offset in page).hi for write, (dest xram addr).hi for read
|
|
__sfr __at (0xDD) FWRLENL; //(num bytes to write minus 1).lo
|
|
__sfr __at (0xDE) FWRLENH; //(num bytes to write minus 1).hi
|
|
__sfr __at (0xDF) FWRTHREE; //always written to three
|
|
|
|
|
|
//temp sensor (CLKEN bit 0x80). these only accessible in config page 4
|
|
__sfr __at (0xE6) TEMPCAL1; //purpose guessed
|
|
__sfr __at (0xE7) TEMPCAL2; //purpose guessed
|
|
|
|
__sfr __at (0xF7) TEMPCFG; //purpose guessed
|
|
|
|
__sfr __at (0xF8) TEMPRETH; //has high 8 bits of result. bitswapped
|
|
__sfr __at (0xF9) TEMPRETL; //has low two bits of result in lower 2 bits. bitswapped
|
|
|
|
__sfr __at (0xFB) TEMPCAL3; //purpose guessed
|
|
__sfr __at (0xFC) TEMPCAL4; //purpose guessed
|
|
__sfr __at (0xFD) TEMPCAL5; //purpose guessed
|
|
__sfr __at (0xFE) TEMPCAL6; //purpose guessed
|
|
|
|
//radio regs (cfg page 4)
|
|
__sfr __at (0xC9) RADIO_TXPTRL; //xram pointer to tx buffer's "length" byte. low byte
|
|
__sfr __at (0xCA) RADIO_TXPTRH; //xram pointer to tx buffer's "length" byte. high byte
|
|
__sfr __at (0xCB) RADIO_INITSEQ1;
|
|
__sfr __at (0xCC) RADIO_INITSEQ2;
|
|
__sfr __at (0xCD) RADIO_TXLEN; //data bytes to send (not incl "len" byte or crc)
|
|
__sfr __at (0xCE) RADIO_INITSEQ0;
|
|
__sfr __at (0xD1) RADIO_INITSEQ4;
|
|
__sfr __at (0xD2) RADIO_INITSEQ5;
|
|
__sfr __at (0xD3) RADIO_RXPTRL; //xram pointer to tx buffer's "length" byte. low byte
|
|
__sfr __at (0xD4) RADIO_RXPTRH; //xram pointer to tx buffer's "length" byte. high byte
|
|
__sfr __at (0xD5) RADIO_RXLEN; //data bytes to RX (not incl "len" byte or crc) 2 more than this will be RXed
|
|
__sfr __at (0xD6) RADIO_INITSEQ3;
|
|
|
|
//radio regs (any cfg page)
|
|
__sfr __at (0xFA) RADIO_GOTLEN; //size packet we GOT (incl len byte)
|
|
|
|
|
|
|
|
//shared regs
|
|
__sfr __at (0xC1) UNK_C1; //in cfg page 4 only, purpose unknown
|
|
|
|
__sfr __at (0xD7) TRIGGER; //in both cfg page, seach bit starts something. 0x08 starts flash op, 0x04 - start radio rx fifo dma, 0x02 - start radio tx fifo dma
|
|
|
|
|
|
//in cfg page 4
|
|
__sfr __at (0xC7) SETTINGS; //misc settings incl flasg access. 0x18 is flash write, 0x08 is flash read,
|
|
__sfr __at (0xCF) TCON2; //interrupt flags (0x08 is flash write)
|
|
|
|
|
|
|
|
__sfr __at (0xFF) CFGPAGE; //partially swaps SFR set to another. only 0x04 bit is used
|
|
|
|
|
|
/*
|
|
84 85 92 B2 B3 B4 B5 B6 B8 are visible on both pages
|
|
|
|
93 98 9D 9E 9F B9 C1-C7 E0-E9 are swapped
|
|
|
|
86 9C B0 B1 C0 C8 EA F1-F6 ??????
|
|
|
|
*/
|
|
|
|
|
|
|
|
//radio MMIO
|
|
|
|
static __xdata __at (0xdf48) unsigned char RADIO_command;
|
|
static __xdata __at (0xdf70) unsigned char RADIO_calibration_70;
|
|
static __xdata __at (0xdf71) unsigned char RADIO_calibration_71;
|
|
static __xdata __at (0xdf80) unsigned char RADIO_FLAGS;
|
|
static __xdata __at (0xdf81) unsigned char RADIO_calibration_81;
|
|
static __xdata __at (0xdf83) unsigned char RADIO_unk_83;
|
|
static __xdata __at (0xdf84) unsigned char RADIO_currentRSSI;
|
|
static __xdata __at (0xdf86) unsigned char RADIO_calibration_86;
|
|
static __xdata __at (0xdf88) unsigned char RADIO_ownMac_7;
|
|
static __xdata __at (0xdf89) unsigned char RADIO_ownMac_6;
|
|
static __xdata __at (0xdf8a) unsigned char RADIO_ownMac_5;
|
|
static __xdata __at (0xdf8b) unsigned char RADIO_ownMac_4;
|
|
static __xdata __at (0xdf8c) unsigned char RADIO_ownMac_3;
|
|
static __xdata __at (0xdf8d) unsigned char RADIO_ownMac_2;
|
|
static __xdata __at (0xdf8e) unsigned char RADIO_ownMac_1;
|
|
static __xdata __at (0xdf8f) unsigned char RADIO_ownMac_0;
|
|
static __xdata __at (0xdf90) unsigned char RADIO_PANID_Hi;
|
|
static __xdata __at (0xdf91) unsigned char RADIO_PANID_Lo;
|
|
static __xdata __at (0xdf92) unsigned char RADIO_ownShortAddress_Hi;
|
|
static __xdata __at (0xdf93) unsigned char RADIO_ownShortAddress_Lo;
|
|
static __xdata __at (0xdf94) unsigned char RADIO_calibration_94;
|
|
static __xdata __at (0xdf95) unsigned char RADIO_calibration_95;
|
|
static __xdata __at (0xdf96) unsigned char RADIO_calibration_96;
|
|
static __xdata __at (0xdf98) unsigned char RADIO_rxFirstByte; // first byte of the message actualyl RXed
|
|
static __xdata __at (0xdf9b) unsigned char RADIO_curRfState; // RFSTATUS ?
|
|
static __xdata __at (0xdf9d) unsigned char RADIO_calibration_9D;
|
|
static __xdata __at (0xdfa1) unsigned char RADIO_calibration_A1;
|
|
static __xdata __at (0xdfa5) unsigned char RADIO_unk_rxAckSta; //in irqh4, when RADIO_IRQ4_pending has 0x40 set, this is 0x04 if we got ack, and 0x02 if not
|
|
static __xdata __at (0xdfa6) unsigned char RADIO_unk_A6;
|
|
static __xdata __at (0xdfad) unsigned char RADIO_IRQ4_pending;
|
|
static __xdata __at (0xdfaf) unsigned char RADIO_unk_AF;
|
|
static __xdata __at (0xdfc0) unsigned char RADIO_channel;
|
|
static __xdata __at (0xdfc1) unsigned char RADIO_unk_C1;
|
|
static __xdata __at (0xdfc2) unsigned char RADIO_calibration_C2;
|
|
static __xdata __at (0xdfc3) unsigned char RADIO_calibration_C3;
|
|
static __xdata __at (0xdfc4) unsigned char RADIO_calibration_C4;
|
|
static __xdata __at (0xdfc5) unsigned char RADIO_calibration_C5;
|
|
static __xdata __at (0xdfc6) unsigned char RADIO_calibration_C6;
|
|
static __xdata __at (0xdfc7) unsigned char RADIO_calibration_C7;
|
|
static __xdata __at (0xdfc8) unsigned char RADIO_unk_C8;
|
|
static __xdata __at (0xdfc9) unsigned char RADIO_txPower; // 0..7 for -5..+8 dBm
|
|
static __xdata __at (0xdfca) unsigned char RADIO_unk_CA;
|
|
static __xdata __at (0xdfcb) unsigned char RADIO_perChannelSetting2; //relevant for tx
|
|
static __xdata __at (0xdfcd) unsigned char RADIO_unk_CD;
|
|
static __xdata __at (0xdfce) unsigned char RADIO_unk_CE;
|
|
static __xdata __at (0xdfcf) unsigned char RADIO_calibration_CF;
|
|
static __xdata __at (0xdfd0) unsigned char RADIO_calibration_D0;
|
|
static __xdata __at (0xdfd1) unsigned char RADIO_calibration_D1;
|
|
static __xdata __at (0xdfd2) unsigned char RADIO_calibration_D2;
|
|
static __xdata __at (0xdfd3) unsigned char RADIO_calibration_D3;
|
|
static __xdata __at (0xdfd4) unsigned char RADIO_calibration_D4;
|
|
static __xdata __at (0xdfd5) unsigned char RADIO_calibration_D5;
|
|
static __xdata __at (0xdfd7) unsigned char RADIO_unk_D7;
|
|
static __xdata __at (0xdfd8) unsigned char RADIO_unk_D8;
|
|
static __xdata __at (0xdfd9) unsigned char RADIO_SleepTimerHi; //only bottom 4 bits implemented, counts down to wake
|
|
static __xdata __at (0xdfda) unsigned char RADIO_SleepTimerMid;
|
|
static __xdata __at (0xdfdb) unsigned char RADIO_SleepTimerLo;
|
|
static __xdata __at (0xdfe2) unsigned char RADIO_unk_E2;
|
|
static __xdata __at (0xdff0) unsigned char RADIO_unk_F0;
|
|
static __xdata __at (0xdff3) unsigned char RADIO_SleepTimerSettings; //0x16 for one second tick, 0x56 for 1/32k second tick
|
|
static __xdata __at (0xdff4) unsigned char RADIO_RadioPowerCtl;
|
|
static __xdata __at (0xdffd) unsigned char RADIO_perChannelSetting1; //relevant fo rRX
|
|
|
|
#define RADIO_CMD_RECEIVE 0xc2 //tx always goes to RX anyways
|
|
#define RADIO_CMD_FLUSH_RX_FIFO 0xc6
|
|
#define RADIO_CMD_FLUSH_TX_FIFO 0xc7
|
|
#define RADIO_CMD_LOAD_TX_FIFO 0xcb
|
|
|
|
|
|
#endif
|