another beta of the 88mz100 7.5 fw

This commit is contained in:
jjwbruijn
2023-08-12 02:26:33 +02:00
parent 3472b5d4b6
commit 2292aeaf7e
34 changed files with 3214 additions and 2503 deletions

View File

@@ -0,0 +1,98 @@
const char font[256][40]={
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,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,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x21
{0x00,0x00,0xC0,0x18,0xC0,0x18,0xC0,0x18,0xC0,0x18,0xC0,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x22
{0x00,0x00,0x00,0x00,0x00,0x22,0x00,0x22,0x00,0x11,0x00,0x11,0x00,0x11,0xE0,0xFF,0x80,0x08,0x80,0x08,0x80,0x08,0xE0,0x7F,0x40,0x04,0x40,0x04,0x20,0x02,0x20,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x23
{0x00,0x00,0x00,0x04,0x00,0x1F,0x80,0x3F,0xC0,0x24,0xC0,0x04,0xC0,0x04,0x80,0x07,0x00,0x07,0x00,0x1C,0x00,0x1C,0x00,0x34,0x00,0x34,0x40,0x34,0xC0,0x1F,0x80,0x0F,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x24
{0x00,0x00,0x00,0x00,0xE0,0x81,0x30,0x43,0x30,0x23,0x30,0x13,0x30,0x0B,0x30,0x0B,0xE0,0x05,0x00,0x7A,0x00,0xCD,0x00,0xCD,0x80,0xCC,0x40,0xCC,0x20,0xCC,0x10,0x78,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x25
{0x00,0x00,0x00,0x00,0x00,0x0F,0x80,0x1F,0x80,0x19,0x80,0x19,0x80,0x0D,0x00,0x07,0xC0,0x03,0x60,0xC6,0x30,0xCE,0x30,0xCC,0x30,0x78,0x70,0x78,0xE0,0x7F,0xC0,0xEF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x26
{0x00,0x00,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x27
{0x00,0x00,0x00,0x30,0x00,0x3C,0x00,0x0E,0x00,0x06,0x00,0x03,0x00,0x03,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x00,0x03,0x00,0x03,0x00,0x06,0x00,0x0E,0x00,0x3C,0x00,0x30,0x00,0x00}, // 0x28
{0x00,0x00,0xC0,0x00,0xC0,0x03,0x00,0x07,0x00,0x06,0x00,0x0C,0x00,0x0C,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x0C,0x00,0x0C,0x00,0x06,0x00,0x07,0xC0,0x03,0xC0,0x00,0x00,0x00}, // 0x29
{0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x03,0x60,0x33,0xE0,0x3C,0x00,0x00,0x80,0x0D,0xC0,0x19,0x80,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x2A
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0xE0,0x7F,0xE0,0x7F,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x2B
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x06,0x00,0x02,0x00,0x03,0x00,0x00}, // 0x2C
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x3F,0xC0,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x2D
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x2E
{0x00,0x00,0x00,0x60,0x00,0x30,0x00,0x30,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x0C,0x00,0x0C,0x00,0x06,0x00,0x06,0x00,0x03,0x00,0x03,0x80,0x01,0x80,0x01,0x80,0x01,0xC0,0x00,0xC0,0x00,0x60,0x00,0x00,0x00}, // 0x2F
{0x00,0x00,0x00,0x00,0x00,0x0F,0x80,0x1F,0xC0,0x30,0xC0,0x30,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0xC0,0x30,0xC0,0x30,0x80,0x1F,0x00,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x30
{0x00,0x00,0x00,0x00,0x00,0x06,0xC0,0x07,0x60,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0xE0,0x7F,0xE0,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x31
{0x00,0x00,0x00,0x00,0x80,0x0F,0xC0,0x1F,0x40,0x38,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0x18,0x00,0x0C,0x00,0x06,0x00,0x03,0x80,0x01,0xC0,0x00,0xC0,0x3F,0xC0,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x32
{0x00,0x00,0x00,0x00,0x80,0x0F,0xC0,0x3F,0x40,0x30,0x00,0x30,0x00,0x18,0x80,0x0F,0x80,0x0F,0x00,0x18,0x00,0x30,0x00,0x30,0x00,0x30,0x40,0x38,0xC0,0x1F,0xC0,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x33
{0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x1C,0x00,0x1E,0x00,0x1A,0x00,0x19,0x80,0x19,0xC0,0x18,0x40,0x18,0xE0,0x7F,0xE0,0x7F,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x34
{0x00,0x00,0x00,0x00,0x80,0x3F,0x80,0x3F,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x0F,0x80,0x1F,0x00,0x38,0x00,0x30,0x00,0x30,0x00,0x38,0x80,0x1F,0x80,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x35
{0x00,0x00,0x00,0x00,0x00,0x0F,0x80,0x1F,0xC0,0x11,0xC0,0x00,0x60,0x00,0x60,0x0E,0x60,0x1F,0xE0,0x38,0x60,0x30,0x60,0x30,0x60,0x30,0xC0,0x38,0xC0,0x1F,0x00,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x36
{0x00,0x00,0x00,0x00,0xC0,0x7F,0xC0,0x7F,0x00,0x60,0x00,0x30,0x00,0x10,0x00,0x18,0x00,0x0C,0x00,0x04,0x00,0x06,0x00,0x02,0x00,0x03,0x00,0x03,0x80,0x01,0x80,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x37
{0x00,0x00,0x00,0x00,0x00,0x0F,0xC0,0x1F,0xC0,0x18,0xC0,0x18,0xC0,0x19,0x80,0x0F,0x00,0x07,0xC0,0x1E,0x60,0x38,0x60,0x30,0x60,0x30,0xE0,0x38,0xC0,0x1F,0x80,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x38
{0x00,0x00,0x00,0x00,0x80,0x07,0xC0,0x1F,0xE0,0x18,0x60,0x30,0x60,0x30,0x60,0x30,0xE0,0x38,0xC0,0x37,0x80,0x33,0x00,0x30,0x00,0x18,0x40,0x1C,0xC0,0x0F,0x80,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x39
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x3A
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x06,0x00,0x02,0x00,0x03,0x00,0x00}, // 0x3B
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x70,0x00,0x3C,0x00,0x0E,0x80,0x03,0xE0,0x00,0x80,0x03,0x00,0x0E,0x00,0x3C,0x00,0x70,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x3C
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x7F,0xE0,0x7F,0x00,0x00,0x00,0x00,0xE0,0x7F,0xE0,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x3D
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0xE0,0x00,0xC0,0x03,0x00,0x07,0x00,0x1C,0x00,0x70,0x00,0x1C,0x00,0x07,0xC0,0x03,0xE0,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x3E
{0x00,0x00,0x00,0x00,0xE0,0x0F,0xE0,0x3F,0x20,0x38,0x00,0x30,0x00,0x30,0x00,0x18,0x00,0x0C,0x00,0x06,0x00,0x03,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x3F
{0x00,0x00,0x00,0x00,0x00,0x1F,0x80,0x31,0xC0,0x60,0x60,0x7C,0x30,0x66,0x30,0x63,0x30,0x63,0x30,0x73,0x30,0x73,0x30,0x6F,0x60,0xE6,0x60,0x00,0xC0,0x00,0x00,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x40
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x0F,0x00,0x0F,0x00,0x0D,0x80,0x19,0x80,0x19,0xC0,0x38,0xC0,0x30,0xC0,0x3F,0xE0,0x7F,0x60,0x60,0x60,0x60,0x30,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x41
{0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x0F,0xE0,0x1F,0x60,0x18,0x60,0x18,0x60,0x0C,0xE0,0x07,0xE0,0x0F,0x60,0x18,0x60,0x30,0x60,0x30,0x60,0x30,0xE0,0x1F,0xE0,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x42
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x80,0x7F,0xC0,0x41,0xC0,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0xC0,0x00,0xC0,0x43,0x80,0x7F,0x00,0x3E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x43
{0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x0F,0xE0,0x1F,0x60,0x38,0x60,0x70,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x30,0x60,0x38,0xE0,0x1F,0xE0,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x44
{0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x7F,0xC0,0x7F,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x3F,0xC0,0x3F,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x7F,0xC0,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x45
{0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x7F,0xC0,0x7F,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x3F,0xC0,0x3F,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x46
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x80,0x7F,0xC0,0x41,0xC0,0x00,0x60,0x00,0x60,0x00,0x60,0x78,0x60,0x78,0x60,0x60,0xC0,0x60,0xC0,0x61,0x80,0x7F,0x00,0x3E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x47
{0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x30,0x60,0x30,0x60,0x30,0x60,0x30,0x60,0x30,0xE0,0x3F,0xE0,0x3F,0x60,0x30,0x60,0x30,0x60,0x30,0x60,0x30,0x60,0x30,0x60,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x48
{0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x1F,0xE0,0x1F,0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x03,0xE0,0x1F,0xE0,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x49
{0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x1F,0x80,0x1F,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x1C,0xC0,0x0F,0xC0,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x4A
{0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x70,0x60,0x38,0x60,0x1C,0x60,0x0E,0x60,0x06,0x60,0x03,0xE0,0x03,0x60,0x07,0x60,0x0E,0x60,0x1C,0x60,0x38,0x60,0x70,0x60,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x4B
{0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x7F,0xC0,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x4C
{0x00,0x00,0x00,0x00,0x00,0x00,0x70,0x70,0x70,0x70,0xF0,0x78,0xB0,0x68,0xB0,0x68,0xB0,0x6D,0x30,0x65,0x30,0x65,0x30,0x67,0x30,0x62,0x30,0x60,0x30,0x60,0x30,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x4D
{0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x60,0xE0,0x60,0xE0,0x61,0xE0,0x61,0x60,0x63,0x60,0x67,0x60,0x66,0x60,0x6E,0x60,0x6C,0x60,0x78,0x60,0x78,0x60,0x70,0x60,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x4E
{0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x0F,0xC0,0x1F,0xE0,0x38,0x70,0x70,0x30,0x60,0x30,0x60,0x30,0x60,0x30,0x60,0x30,0x60,0x70,0x70,0xE0,0x38,0xC0,0x1F,0x80,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x4F
{0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x1F,0xC0,0x3F,0xC0,0x70,0xC0,0x60,0xC0,0x60,0xC0,0x70,0xC0,0x3F,0xC0,0x0F,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x50
{0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x0F,0xC0,0x1F,0xE0,0x38,0x70,0x70,0x30,0x60,0x30,0x60,0x30,0x60,0x30,0x60,0x30,0x60,0x60,0x30,0xE0,0x38,0xC0,0x1F,0x80,0x0F,0x00,0x38,0x00,0xF0,0x00,0x40,0x00,0x00}, // 0x51
{0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x07,0xE0,0x1F,0x60,0x18,0x60,0x18,0x60,0x18,0x60,0x1C,0xE0,0x0F,0xE0,0x07,0x60,0x0E,0x60,0x1C,0x60,0x38,0x60,0x70,0x60,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x52
{0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x0F,0xC0,0x1F,0x60,0x10,0x60,0x00,0xE0,0x00,0xC0,0x03,0x80,0x0F,0x00,0x3C,0x00,0x30,0x00,0x30,0x60,0x38,0xE0,0x1F,0xC0,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x53
{0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0xFF,0xF0,0xFF,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x54
{0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x30,0x60,0x30,0x60,0x30,0x60,0x30,0x60,0x30,0x60,0x30,0x60,0x30,0x60,0x30,0x60,0x30,0x60,0x30,0xE0,0x38,0xC0,0x1F,0x80,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x55
{0x00,0x00,0x00,0x00,0x00,0x00,0x70,0xC0,0x60,0x60,0x60,0x60,0xE0,0x60,0xC0,0x30,0xC0,0x30,0xC0,0x31,0x80,0x19,0x80,0x1B,0x00,0x0B,0x00,0x0F,0x00,0x0F,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x56
{0x00,0x00,0x00,0x00,0x00,0x00,0x30,0xC0,0x30,0xC0,0x30,0xC0,0x20,0x46,0x20,0x46,0x20,0x6E,0x60,0x6F,0x60,0x69,0x60,0x69,0x60,0x39,0xC0,0x39,0xC0,0x39,0xC0,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x57
{0x00,0x00,0x00,0x00,0x00,0x00,0x70,0xE0,0xE0,0x60,0xC0,0x30,0x80,0x19,0x80,0x0F,0x00,0x0F,0x00,0x06,0x00,0x0F,0x80,0x1D,0x80,0x19,0xC0,0x30,0x60,0x70,0x30,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x58
{0x00,0x00,0x00,0x00,0x00,0x00,0x70,0xC0,0x60,0x60,0xC0,0x30,0xC0,0x31,0x80,0x19,0x00,0x0F,0x00,0x0F,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x59
{0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x7F,0xE0,0x7F,0x00,0x60,0x00,0x30,0x00,0x18,0x00,0x0C,0x00,0x06,0x00,0x03,0x80,0x01,0xC0,0x00,0x60,0x00,0xE0,0x7F,0xE0,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x5A
{0x00,0x00,0x00,0x3F,0x00,0x3F,0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x3F,0x00,0x3F,0x00,0x00}, // 0x5B
{0x00,0x00,0x60,0x00,0xC0,0x00,0xC0,0x00,0x80,0x01,0x80,0x01,0x80,0x01,0x00,0x03,0x00,0x03,0x00,0x06,0x00,0x06,0x00,0x0C,0x00,0x0C,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x30,0x00,0x30,0x00,0x60,0x00,0x00}, // 0x5C
{0x00,0x00,0xC0,0x0F,0xC0,0x0F,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0xC0,0x0F,0xC0,0x0F,0x00,0x00}, // 0x5D
{0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x04,0x00,0x0E,0x00,0x0A,0x00,0x0B,0x00,0x1B,0x80,0x11,0x80,0x31,0xC0,0x30,0xC0,0x20,0x60,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x5E
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0xFF,0xF0,0xFF,0x00,0x00,0x00,0x00}, // 0x5F
{0x00,0x06,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x60
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x1F,0xC0,0x3F,0x40,0x30,0x00,0x30,0x00,0x30,0x80,0x3F,0xC0,0x30,0x60,0x30,0x60,0x38,0xE0,0xFF,0xC0,0xE7,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x61
{0x00,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x0E,0x60,0x1F,0xE0,0x39,0xE0,0x30,0x60,0x30,0x60,0x30,0x60,0x30,0x60,0x30,0xE0,0x18,0xE0,0x1F,0x60,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x62
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0xC0,0x3F,0xC0,0x21,0xE0,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0xE0,0x00,0xC0,0x01,0xC0,0x3F,0x00,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x63
{0x00,0x00,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0x30,0x80,0x37,0xC0,0x3F,0xC0,0x38,0x60,0x30,0x60,0x30,0x60,0x30,0x60,0x30,0x60,0x30,0xE0,0x38,0xC0,0x3F,0x80,0x33,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x64
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0xC0,0x1F,0xC0,0x38,0x60,0x30,0xE0,0x3F,0xE0,0x3F,0x60,0x00,0x60,0x00,0xC0,0x20,0xC0,0x3F,0x00,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x65
{0x00,0x00,0x00,0x7E,0x00,0x7F,0x00,0x03,0x00,0x03,0xE0,0x7F,0xE0,0x7F,0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x66
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x37,0xC0,0x3F,0xC0,0x38,0x60,0x30,0x60,0x30,0x60,0x30,0x60,0x30,0x60,0x30,0xE0,0x38,0xC0,0x3F,0x80,0x37,0x00,0x30,0x40,0x38,0xC0,0x1F,0x80,0x0F}, // 0x67
{0x00,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x1E,0x60,0x3F,0xE0,0x31,0x60,0x30,0x60,0x30,0x60,0x30,0x60,0x30,0x60,0x30,0x60,0x30,0x60,0x30,0x60,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x68
{0x00,0x00,0x00,0x0C,0x00,0x0C,0x00,0x00,0x00,0x00,0xC0,0x0F,0xC0,0x0F,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x69
{0x00,0x00,0x00,0x18,0x00,0x18,0x00,0x00,0x00,0x00,0x80,0x1F,0x80,0x1F,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x1C,0xC0,0x0F,0xC0,0x07}, // 0x6A
{0x00,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x70,0xC0,0x38,0xC0,0x1C,0xC0,0x0E,0xC0,0x06,0xC0,0x07,0xC0,0x0E,0xC0,0x1C,0xC0,0x38,0xC0,0x70,0xC0,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x6B
{0x00,0x00,0xC0,0x0F,0xC0,0x0F,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x6C
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xB0,0x39,0xF0,0x7F,0x70,0x67,0x30,0x63,0x30,0x63,0x30,0x63,0x30,0x63,0x30,0x63,0x30,0x63,0x30,0x63,0x30,0x63,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x6D
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x1E,0x60,0x3F,0xE0,0x31,0x60,0x30,0x60,0x30,0x60,0x30,0x60,0x30,0x60,0x30,0x60,0x30,0x60,0x30,0x60,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x6E
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0xC0,0x3F,0xC0,0x30,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0xC0,0x30,0xC0,0x3F,0x00,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x6F
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x0F,0xE0,0x1F,0xE0,0x38,0x60,0x30,0x60,0x30,0x60,0x30,0x60,0x30,0x60,0x30,0xE0,0x18,0xE0,0x1F,0x60,0x0F,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00}, // 0x70
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x37,0xC0,0x3F,0xC0,0x38,0x60,0x30,0x60,0x30,0x60,0x30,0x60,0x30,0x60,0x30,0xE0,0x38,0xC0,0x37,0x80,0x33,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0x30}, // 0x71
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x3C,0xC0,0x3E,0xC0,0x23,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x72
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x1F,0xC0,0x1F,0xC0,0x00,0xC0,0x00,0xC0,0x03,0x00,0x1F,0x00,0x38,0x00,0x30,0x40,0x30,0xC0,0x1F,0x80,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x73
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x03,0xE0,0x7F,0xE0,0x7F,0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x7F,0x00,0x7E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x74
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x30,0x60,0x30,0x60,0x30,0x60,0x30,0x60,0x30,0x60,0x30,0x60,0x30,0x60,0x30,0x60,0x3C,0xE0,0x37,0xC0,0x33,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x75
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x60,0xC0,0x20,0xC0,0x30,0xC0,0x30,0x80,0x11,0x80,0x19,0x80,0x19,0x00,0x0B,0x00,0x0F,0x00,0x0F,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x76
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0xC0,0x30,0xC6,0x30,0xC6,0x20,0x4E,0x60,0x4F,0x60,0x49,0x60,0x69,0x60,0x79,0xC0,0x39,0xC0,0x30,0xC0,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x77
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x70,0xC0,0x30,0x80,0x19,0x80,0x0B,0x00,0x0F,0x00,0x06,0x00,0x0F,0x80,0x1D,0x80,0x19,0xC0,0x30,0x60,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x78
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x60,0xC0,0x20,0xC0,0x30,0xC0,0x31,0x80,0x19,0x80,0x19,0x00,0x0B,0x00,0x0F,0x00,0x0F,0x00,0x06,0x00,0x06,0x00,0x02,0x00,0x03,0xC0,0x03,0xC0,0x01}, // 0x79
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x3F,0xE0,0x3F,0x00,0x30,0x00,0x18,0x00,0x0C,0x00,0x06,0x00,0x03,0x80,0x01,0xC0,0x00,0xE0,0x3F,0xE0,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x7A
{0x00,0x00,0x00,0x3C,0x00,0x3E,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0xC0,0x03,0xC0,0x03,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x3E,0x00,0x3C,0x00,0x00}, // 0x7B
{0x00,0x00,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x00}, // 0x7C
{0x00,0x00,0xC0,0x03,0xC0,0x07,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x3C,0x00,0x3C,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0xC0,0x07,0xC0,0x03,0x00,0x00}, // 0x7D
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x43,0xE0,0x7F,0x20,0x3C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x7E
{0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x3F,0x40,0x20,0x40,0x20,0x40,0x20,0x40,0x20,0x40,0x20,0x40,0x20,0x40,0x20,0x40,0x20,0x40,0x20,0x40,0x20,0x40,0x20,0xC0,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} // 0x7F
};

View File

@@ -1,10 +1,11 @@
MZ_FLASHER=python ../88MZ100_Flasher/88MZ100_Uart_flasher.py
ARMGCC=armgcc/bin/
ARMGCC=/usr/bin/
CC=$(ARMGCC)arm-none-eabi-gcc
AS=$(ARMGCC)arm-none-eabi-as
OBJCOPY=$(ARMGCC)arm-none-eabi-objcopy
#-Wall
CC_WARNING_FLAGS=-Wall -Wformat=0 -Wattributes -Wstrict-aliasing=0
CC_FlAGS=-mcpu=cortex-m3 -g -O0 -mthumb -fdata-sections -ffunction-sections -std=c99
@@ -16,10 +17,15 @@ C_EXECUTABLE :=$(C_SOURCES:.c=)
COMPORT = COM12
build: clean compile create_ota_img flash_uart_flash
build: compile
only: clean compile create_ota_img
uart: clean compile flash_uart
#build: clean compile create_ota_img flash_uart_flash
#only: clean compile create_ota_img
#uart: clean compile flash_uart
compile:
@mkdir -p build
@$(AS) -mcpu=cortex-m3 --gdwarf-2 -mthumb-interwork -o build/startup.o startup.S
@@ -40,16 +46,8 @@ compile:
@$(CC) $(CC_FlAGS) -c mz100_gpt.c -o build/mz100_gpt.o
@$(CC) $(CC_FlAGS) -c mz100_sleep.c -o build/mz100_sleep.o
@$(CC) $(CC_FlAGS) -c mz100_uart.c -o build/mz100_uart.o
# UZLIB
@$(CC) $(CC_FlAGS) $(CC_WARNING_FLAGS) -c uzlib/src/adler32.c -o build/adler32.o
@$(CC) $(CC_FlAGS) $(CC_WARNING_FLAGS) -c uzlib/src/crc32.c -o build/crc32.o
@$(CC) $(CC_FlAGS) $(CC_WARNING_FLAGS) -c uzlib/src/defl_static.c -o build/defl_static.o
@$(CC) $(CC_FlAGS) $(CC_WARNING_FLAGS) -c uzlib/src/genlz77.c -o build/genlz77.o
@$(CC) $(CC_FlAGS) $(CC_WARNING_FLAGS) -c uzlib/src/tinfgzip.c -o build/tinfgzip.o
@$(CC) $(CC_FlAGS) $(CC_WARNING_FLAGS) -c uzlib/src/tinflate.c -o build/tinflate.o
@$(CC) $(CC_FlAGS) $(CC_WARNING_FLAGS) -c uzlib/src/tinfzlib.c -o build/tinfzlib.o
# UZLIB END
@$(CC) $(CC_FlAGS) $(CC_WARNING_FLAGS) -c compression.c -o build/compression.o
@$(CC) $(CC_FlAGS) -c mz100_aon_ram.c -o build/mz100_aon_ram.o
@$(CC) $(CC_FlAGS) -c printf.c -o build/printf.o
@$(CC) $(CC_FlAGS) $(CC_WARNING_FLAGS) -c zigbee.c -o build/zigbee.o
@$(CC) $(CC_FlAGS) $(CC_WARNING_FLAGS) -c ccm.c -o build/ccm.o
@$(CC) $(CC_FlAGS) $(CC_WARNING_FLAGS) -c chars.c -o build/chars.o
@@ -61,10 +59,10 @@ compile:
@$(CC) $(CC_FlAGS) $(CC_WARNING_FLAGS) -c timer.c -o build/timer.o
@$(CC) $(CC_FlAGS) $(CC_WARNING_FLAGS) -c util.c -o build/util.o
@$(CC) $(CC_FlAGS) $(CC_WARNING_FLAGS) -c gpio.c -o build/gpio.o
@$(CC) $(CC_FlAGS) $(CC_WARNING_FLAGS) -c nfc.c -o build/nfc.o
@$(CC) $(CC_FlAGS) $(CC_WARNING_FLAGS) -c epd.c -o build/epd.o
@$(CC) $(CC_FlAGS) $(CC_WARNING_FLAGS) -c userinterface.c -o build/userinterface.o
@$(CC) $(CC_FlAGS) $(CC_WARNING_FLAGS) -c main.c -o build/main.o
@$(CC) $(CC_END_FLAGS) $(CC_WARNING_FLAGS) build/main.o build/adler32.o build/crc32.o build/defl_static.o build/genlz77.o build/tinfgzip.o build/tinflate.o build/tinfzlib.o build/compression.o build/zigbee.o build/ccm.o build/chars.o build/drawing.o build/powermgt.o build/syncedproto.o build/comms.o build/settings.o build/timer.o build/util.o build/gpio.o build/nfc.o build/epd.o build/mz100_sleep.o build/core_cm3.o build/mz100_ssp.o build/mz100_wdt.o build/mz100_gpio.o build/mz100_driver.o build/mz100_adc.o build/mz100_flash.o build/mz100_clock.o build/mz100_rtc.o build/mz100_pinmux.o build/mz100_pmu.o build/mz100_qspi.o build/mz100_aes.o build/mz100_gpt.o build/mz100_uart.o build/startup.o -o main.axf
@$(CC) $(CC_END_FLAGS) $(CC_WARNING_FLAGS) build/main.o build/userinterface.o build/printf.o build/mz100_aon_ram.o build/zigbee.o build/chars.o build/drawing.o build/powermgt.o build/syncedproto.o build/comms.o build/settings.o build/timer.o build/util.o build/gpio.o build/epd.o build/mz100_sleep.o build/core_cm3.o build/mz100_ssp.o build/mz100_wdt.o build/mz100_gpio.o build/mz100_driver.o build/mz100_adc.o build/mz100_flash.o build/mz100_clock.o build/mz100_rtc.o build/mz100_pinmux.o build/mz100_pmu.o build/mz100_qspi.o build/mz100_aes.o build/mz100_gpt.o build/mz100_uart.o build/startup.o -o main.axf
@$(OBJCOPY) -v -O binary main.axf main.bin
clean:
@@ -83,4 +81,4 @@ flash_dump:
@$(MZ_FLASHER) $(COMPORT) read dump.bin
create_ota_img:
@$(MZ_FLASHER) img main.bin UPDT0028.BIN
@$(MZ_FLASHER) img main.bin UPDT0028.BIN

View File

@@ -1,96 +1,32 @@
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include "comms.h"
#include "proto.h"
#include <stdint.h>
//#include <stdio.h>
#include <string.h>
#include "ccm.h"
#include "proto.h"
extern uint8_t Zigbee_tx_buffer(uint8_t tx_buffer[], int len);
static uint8_t packet[128];
static uint8_t mSeq = 0;
uint8_t mLastLqi = 0;
int8_t mLastRSSI = 0;
uint8_t commsGetLastPacketLQI(void)
{
return mLastLqi;
uint8_t commsGetLastPacketLQI(void) {
return mLastLqi;
}
int8_t commsGetLastPacketRSSI(void)
{
return mLastRSSI;
int8_t commsGetLastPacketRSSI(void) {
return mLastRSSI;
}
static inline void __attribute__((always_inline)) macCopy(uint8_t *restrict dst, const uint8_t *restrict src)
{
((uint32_t *)dst)[0] = ((const uint32_t *)src)[0];
((uint32_t *)dst)[1] = ((const uint32_t *)src)[1];
static inline void __attribute__((always_inline)) macCopy(uint8_t *restrict dst, const uint8_t *restrict src) {
((uint32_t *)dst)[0] = ((const uint32_t *)src)[0];
((uint32_t *)dst)[1] = ((const uint32_t *)src)[1];
}
static inline bool __attribute__((always_inline)) macIsEq(const uint8_t *restrict dst, const uint8_t *restrict src)
{
return ((uint32_t *)dst)[0] == ((const uint32_t *)src)[0] && ((uint32_t *)dst)[1] == ((const uint32_t *)src)[1];
}
bool commsTx(struct CommsInfo *info, bool bcast, const void *packet_in, uint32_t len)
{
uint8_t nonce[AES_CCM_NONCE_SIZE] = {};
struct MacFrameNormal *mfn;
struct MacFrameBcast *mfb;
uint32_t hdrSz;
char *payload;
static const struct MacFcs normalFcs = {
.frameType = FRAME_TYPE_DATA,
.panIdCompressed = 1,
.destAddrType = ADDR_MODE_LONG,
.srcAddrType = ADDR_MODE_LONG,
};
static const struct MacFcs broadcastFcs = {
.frameType = FRAME_TYPE_DATA,
.destAddrType = ADDR_MODE_SHORT,
.srcAddrType = ADDR_MODE_LONG,
};
if (len > COMMS_MAX_PACKET_SZ)
return false;
if (bcast)
{
mfb = (struct MacFrameBcast *)packet;
hdrSz = sizeof(struct MacFrameBcast);
payload = (char *)(mfb + 1);
mfb->fcs = broadcastFcs;
mfb->seq = mSeq++;
mfb->dstPan = 0xffff;
mfb->dstAddr = 0xffff;
mfb->srcPan = PROTO_PAN_ID;
macCopy(mfb->src, info->myMac);
}
else
{
mfn = (struct MacFrameNormal *)packet;
hdrSz = sizeof(struct MacFrameNormal);
payload = (char *)(mfn + 1);
mfn->fcs = normalFcs;
mfn->seq = mSeq++;
mfn->pan = PROTO_PAN_ID;
macCopy(mfn->dst, info->masterMac);
macCopy(mfn->src, info->myMac);
}
*(uint32_t *)nonce = (*info->nextIV)++;
macCopy(nonce + sizeof(uint32_t), info->myMac);
memcpy(payload, packet_in, len);
aesCcmEnc((void *)packet, (void *)packet, hdrSz, len, info->encrKey, nonce);
*(uint32_t *)(payload + len + AES_CCM_MIC_SIZE) = *(uint32_t *)nonce; // send nonce
len += hdrSz;
len += AES_CCM_MIC_SIZE;
len += sizeof(uint32_t);
return !Zigbee_tx_buffer((uint8_t *)&packet, len);
static inline bool __attribute__((always_inline)) macIsEq(const uint8_t *restrict dst, const uint8_t *restrict src) {
return ((uint32_t *)dst)[0] == ((const uint32_t *)src)[0] && ((uint32_t *)dst)[1] == ((const uint32_t *)src)[1];
}
extern volatile uint8_t rx_buffer[0x400];
@@ -98,94 +34,16 @@ extern volatile uint8_t new_rx;
extern volatile uint8_t new_rssi;
extern volatile int rx_len;
int32_t __attribute__((noinline)) commsRx(struct CommsInfo *info, void *data, uint8_t *fromMacP)
{
uint8_t *buf = packet, nonce[13] = {}, fromMac[8] = {0, 0, 0, 0, 0, 0, 0, 0};
uint32_t len, minNeedLen, hdrLen = 0;
struct MacFrameFromMaster *mfm;
struct MacFrameNormal *mfn;
// sort out how many bytes minimum are a valid packet
minNeedLen = sizeof(struct MacFrameFromMaster); // mac header
minNeedLen += sizeof(uint8_t); // packet type
minNeedLen += AES_CCM_MIC_SIZE; // MIC
minNeedLen += sizeof(uint32_t); // nonce counter
minNeedLen += 2 * sizeof(uint8_t); // RSSI/LQI
if (!new_rx)
return COMMS_RX_ERR_NO_PACKETS;
// some basic checks
mfm = (struct MacFrameFromMaster *)rx_buffer;
if (rx_len >= sizeof(packet) || rx_len < minNeedLen || mfm->fcs.frameType != FRAME_TYPE_DATA ||
mfm->fcs.secure || mfm->fcs.frameVer || mfm->fcs.destAddrType != ADDR_MODE_LONG || !mfm->fcs.panIdCompressed ||
(mfm->fcs.srcAddrType != ADDR_MODE_LONG && mfm->fcs.srcAddrType != ADDR_MODE_SHORT) ||
mfm->pan != PROTO_PAN_ID || !macIsEq(mfm->dst, info->myMac))
{
new_rx = 0;
return COMMS_RX_ERR_INVALID_PACKET;
}
// copy out and release buffer
memcpy(buf, &rx_buffer, len = rx_len - 2 * sizeof(uint8_t));
mLastLqi = rx_buffer[len + 0];
mLastRSSI = rx_buffer[len + 1];
mfm = (struct MacFrameFromMaster *)buf;
mfn = (struct MacFrameNormal *)buf;
new_rx = 0;
// sort out header len, copy mac into nonce
if (mfm->fcs.srcAddrType == ADDR_MODE_LONG)
{
macCopy(fromMac, mfn->src);
hdrLen = sizeof(struct MacFrameNormal);
// re-verify needed length
minNeedLen -= sizeof(struct MacFrameFromMaster);
minNeedLen += sizeof(struct MacFrameNormal);
if (rx_len < minNeedLen)
return COMMS_RX_ERR_INVALID_PACKET;
}
else if (mfm->fcs.srcAddrType == ADDR_MODE_SHORT)
{
macCopy(fromMac, info->masterMac);
hdrLen = sizeof(struct MacFrameFromMaster);
}
// sort out the nonce
macCopy(nonce + sizeof(uint32_t), fromMac);
*(uint32_t *)nonce = *(uint32_t *)(buf + len - sizeof(uint32_t));
// decrypt and auth
len -= hdrLen + AES_CCM_MIC_SIZE + sizeof(uint32_t);
if (!aesCcmDec(buf, buf, hdrLen, len, info->encrKey, nonce))
return COMMS_RX_ERR_MIC_FAIL;
if (fromMacP)
macCopy(fromMacP, fromMac);
memcpy(data, buf + hdrLen, len);
return len;
int32_t __attribute__((noinline)) commsRxUnenc(void *data) {
if (!new_rx)
return COMMS_RX_ERR_NO_PACKETS;
memcpy(data, (uint8_t*)&rx_buffer, rx_len);
mLastLqi = 255 - new_rssi;
mLastRSSI = new_rssi;
new_rx = 0;
return rx_len;
}
int32_t __attribute__((noinline)) commsRxUnenc(void *data)
{
if (!new_rx)
return COMMS_RX_ERR_NO_PACKETS;
memcpy(data, &rx_buffer, rx_len);
mLastLqi = 255 - new_rssi;
mLastRSSI = new_rssi;
new_rx = 0;
return rx_len;
}
void commsTxNoCpy(uint8_t *packetp)
{
Zigbee_tx_buffer((uint8_t *)&packetp[1], (packetp[0] - 2));
void commsTxNoCpy(uint8_t *packetp) {
Zigbee_tx_buffer((uint8_t *)&packetp[1], (packetp[0] - 2));
}

View File

@@ -4,12 +4,6 @@
#include <stdint.h>
#include "ccm.h"
struct CommsInfo {
const uint8_t *myMac;
const uint8_t *masterMac;
const void *encrKey;
uint32_t *nextIV;
};
extern uint8_t mLastLqi;
extern int8_t mLastRSSI;
@@ -23,8 +17,6 @@ extern int8_t mLastRSSI;
#define COMMS_MAX_PACKET_SZ (127 /* max phy len */ - 21 /* max mac frame with panID compression */ - 2 /* FCS len */ - AES_CCM_MIC_SIZE - COMMS_IV_SIZE)
bool commsTx(struct CommsInfo *info, bool bcast, const void *packet, uint32_t len);
int32_t commsRx(struct CommsInfo *info, void *data, uint8_t *fromMac); //returns length or COMMS_RX_ERR_*
uint8_t commsGetLastPacketLQI(void);
int8_t commsGetLastPacketRSSI(void);

View File

@@ -1,7 +1,7 @@
#include "compression.h"
#include "uzlib/src/uzlib.h"
#include <stdio.h>
//#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
#include <string.h>

View File

@@ -1,7 +1,7 @@
#pragma once
#include "uzlib/src/uzlib.h"
#include <stdio.h>
//#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
#include <string.h>

View File

@@ -2,6 +2,7 @@
#include <stdbool.h>
#include <stdbool.h>
#include "printf.h"
#include "board.h"
#include "eeprom.h"
@@ -11,366 +12,22 @@
#include "util.h"
#include "epd.h"
#define COMPRESSION_BITPACKED_3x5_to_7 0x62700357 // 3 pixels of 5 possible colors in 7 bits
#define COMPRESSION_BITPACKED_5x3_to_8 0x62700538 // 5 pixels of 3 possible colors in 8 bits
#define COMPRESSION_BITPACKED_3x6_to_8 0x62700368 // 3 pixels of 6 possible colors in 8 bits
struct BitmapFileHeader
{
uint8_t sig[2];
uint32_t fileSz;
uint8_t rfu[4];
uint32_t dataOfst;
uint32_t headerSz; // 40
int32_t width;
int32_t height;
uint16_t colorplanes; // must be one
uint16_t bpp;
uint32_t compression;
uint32_t dataLen; // may be 0
uint32_t pixelsPerMeterX;
uint32_t pixelsPerMeterY;
uint32_t numColors; // if zero, assume 2^bpp
uint32_t numImportantColors;
};
struct BitmapClutEntry
{
uint8_t b, g, r, x;
};
struct BitmapDrawInfo
{
// dimensions
uint16_t w, h, effectiveW, effectiveH, stride /* 0 -> 1, 5 - >7, 255 -> 256 */;
uint8_t numColorsM1;
// data start
uint32_t dataAddr;
// compression state
uint8_t packetPixelDivVal;
uint8_t packetNumPixels;
uint8_t packetBitSz;
uint8_t packetBitMask; // derived from the above
// flags
uint8_t bpp : 4;
uint8_t bottomUp : 1;
};
uint8_t mPassNo = 0;
static const uint8_t mColorMap[][6] = {
// colors are: B, DG, G, LG, W, R
// phase 0 (LUTS: B:W:R:G, purpose: BWR, prepare greys)
{1, 1, 1, 1, 0, 0}, // lo plane (B)
{0, 0, 0, 0, 0, 1} // hi plane (R)
};
static uint8_t mClutMap[256];
static uint8_t mClutMapRed[256];
static struct BitmapDrawInfo mDrawInfo;
static uint32_t drawPrvParseHeader(uint32_t addr) // return clut addr or zero on error
{
/*struct BitmapFileHeader bmph;
uint16_t packetsPerRow;
addr += sizeof(struct EepromImageHeader);
eepromRead(addr, &bmph, sizeof(bmph));
if (bmph.sig[0] != 'B' || bmph.sig[1] != 'M')
goto fail;
if (bmph.colorplanes != 1)
goto fail;
if ((&bmph.headerSz - 40)) // < 40
goto fail;
if (bmph.bpp > 8)
goto fail;
mDrawInfo.bpp = bmph.bpp;
if (!(&bmph.headerSz - 257)) // >= 257
goto fail;
if ((&bmph.numColors))
mDrawInfo.numColorsM1 = (uint8_t)bmph.numColors - (uint8_t)1;
else
mDrawInfo.numColorsM1 = (uint8_t)((uint8_t)1 << (uint8_t)mDrawInfo.bpp) - (uint8_t)1;
if (!(&bmph.height))
goto fail;
if ((&bmph.width - 1) || !(&bmph.width - 0xffff))
goto fail;
mDrawInfo.w = bmph.width;
if ((&bmph.height) < 0)
{
if ((&bmph.height + 0xffff)) // carries if val too negative
goto fail;
mDrawInfo.h = -bmph.height;
mDrawInfo.bottomUp = false;
}
else
{
if (!(&bmph.headerSz - 0xffff)) // no carry if val too big
goto fail;
mDrawInfo.h = bmph.height;
mDrawInfo.bottomUp = true;
}
if (bmph.compression)
{
printf("compression is not supported ;(");
goto fail;
}
mDrawInfo.packetPixelDivVal = 0;
mDrawInfo.packetNumPixels = 1;
if (mDrawInfo.bpp > 1)
{
mDrawInfo.packetBitSz = 2;
}
else
{
mDrawInfo.packetBitSz = 1; // mDrawInfo.bpp;
}
// mDrawInfo.stride = mathPrvDiv32x8(mathPrvMul16x8((mDrawInfo.w + mDrawInfo.packetNumPixels - 1), mDrawInfo.packetBitSz) + 31, 32) * 4UL;
// mDrawInfo.packetBitMask = (uint8_t)(((uint8_t)1) << (uint8_t)mDrawInfo.packetBitSz) - (uint8_t)1;
packetsPerRow = (mDrawInfo.w + mDrawInfo.packetNumPixels - 1) / (mDrawInfo.packetNumPixels);
mDrawInfo.stride = (((packetsPerRow * mDrawInfo.packetBitSz) + 31) / 32) * 4UL;
mDrawInfo.packetBitMask = (uint8_t)(((uint8_t)1) << (uint8_t)mDrawInfo.packetBitSz) - (uint8_t)1;
// calc effective size
mDrawInfo.effectiveH = (mDrawInfo.h > SCREEN_HEIGHT) ? SCREEN_HEIGHT : mDrawInfo.h;
mDrawInfo.effectiveW = (mDrawInfo.w > SCREEN_WIDTH) ? SCREEN_WIDTH : mDrawInfo.w;
// calc addrs
mDrawInfo.dataAddr = addr + bmph.dataOfst;
return addr + bmph.dataOfst - sizeof(struct BitmapClutEntry) * (1 + mDrawInfo.numColorsM1);
fail:
printf("Tried to parse the bmp header, didn't work...");*/
return 0;
}
static void drawPrvLoadAndMapClut(uint32_t clutAddr)
{
/*struct BitmapClutEntry clut;
uint8_t i;
// convert clut to our understanding of color
i = 0;
do
{
uint8_t entry;
eepromRead(clutAddr, &clut, sizeof(clut));
clutAddr += sizeof(struct BitmapClutEntry);
if (SCREEN_EXTRA_COLOR_INDEX >= 0 && clut.r == 0xff && (clut.g == 0xff || clut.g == 0) && clut.b == 0) // yellow/red
entry = SCREEN_EXTRA_COLOR_INDEX;
else
{
uint16_t intensity = 0;
intensity += (0x37 * clut.r);
intensity += (0xB7 * clut.g);
intensity += (0x12 * clut.b);
// adds up to 0xff00 -> fix it
intensity += (uint8_t)(intensity >> 8);
entry = (intensity * SCREEN_NUM_GREYS) >> 16;
entry += SCREEN_FIRST_GREY_IDX;
}
// printf("mapped clut %u (%d %d %d) -> %d\n", i, clut.r, clut.g, clut.b, entry);
mClutMap[i] = entry;
} while (i++ != mDrawInfo.numColorsM1);
// replicate clut down if not a full 256-entry clut
if (mDrawInfo.bpp != 8)
{
uint8_t num = (uint8_t)((uint8_t)1 << (uint8_t)mDrawInfo.bpp);
// we can use the fact that our memcpy always copies forward
memcpy(mClutMap + num, mClutMap, (uint8_t)256 - (uint8_t)num);
}*/
}
static void drawPrvDecodeImageOnce(void)
{
/*uint8_t rowBuf[SCREEN_WIDTH];
uint16_t er, c;
if (mDrawInfo.bottomUp)
er = mDrawInfo.effectiveH - 1;
else
er = 0;
while (1)
{ // we account differently for loop gets compiled worse
uint8_t inIdx = 0, bitpoolInUsed = 0, bitpoolIn = 0;
uint16_t nBytesOut = 0;
#if SCREEN_TX_BPP == 4
uint8_t txPrev = 0;
bool emit = false;
#else
uint8_t bitpoolOutUsedUsed = 0;
uint16_t bitpoolOut = 0;
#endif
// get a row
epdDeselect();
eepromRead((er * mDrawInfo.stride) + mDrawInfo.dataAddr, rowBuf, mDrawInfo.stride);
epdSelect();
// convert to our format
c = mDrawInfo.effectiveW;
do
{
// uartTx('.');
uint8_t packet, packetIdx, packetMembers = mDrawInfo.packetNumPixels;
if (bitpoolInUsed >= mDrawInfo.packetBitSz)
{
bitpoolInUsed -= mDrawInfo.packetBitSz;
packet = bitpoolIn >> bitpoolInUsed;
}
else
{
uint8_t packetBitSz = mDrawInfo.packetBitSz;
uint8_t t = rowBuf[inIdx++];
packet = (bitpoolIn << (packetBitSz - bitpoolInUsed)) | (t >> (8 - (packetBitSz - bitpoolInUsed)));
bitpoolInUsed += 8 - packetBitSz;
bitpoolIn = t;
}
packet &= mDrawInfo.packetBitMask;
// val is now a packet - unpack it
if (packetMembers > c)
packetMembers = c;
for (packetIdx = 0; packetIdx < packetMembers; packetIdx++)
{
uint8_t val;
// extract
if (mDrawInfo.packetPixelDivVal)
{
val = packet % mDrawInfo.packetPixelDivVal;
packet /= mDrawInfo.packetPixelDivVal;
}
else
val = packet;
// map
val = mClutMap[val];
// get bits out
#if SCREEN_TX_BPP == 4
if (emit)
{
emit = false;
ByteDecode(txPrev | val);
nBytesOut++;
txPrev = 0;
}
else
{
emit = true;
txPrev = val << 4;
}
#else
bitpoolOut <<= SCREEN_TX_BPP;
bitpoolOut |= val;
bitpoolOutUsedUsed += SCREEN_TX_BPP;
if (bitpoolOutUsedUsed >= 8)
{
ByteDecode(bitpoolOut >> (bitpoolOutUsedUsed -= 8));
bitpoolOut &= (1 << bitpoolOutUsedUsed) - 1;
nBytesOut++;
}
#endif
}
c -= packetMembers;
} while (c);
#if SCREEN_TX_BPP == 4
if (emit)
{
ByteDecode(txPrev);
nBytesOut++;
}
#else
if (bitpoolOutUsedUsed)
{
ByteDecode(bitpoolOut);
nBytesOut++;
}
#endif
// if we did not produce enough bytes, do so
nBytesOut = ((long)SCREEN_WIDTH * SCREEN_TX_BPP + 7) / 8 - nBytesOut;
while (nBytesOut--)
ByteDecode(SCREEN_BYTE_FILL);
// update row
if (mDrawInfo.bottomUp)
{
if (er)
er--;
else
break;
}
else
{
er++;
if (er == mDrawInfo.effectiveH)
break;
}
}
// fill the rest of the screen
for (er = mDrawInfo.effectiveH - SCREEN_HEIGHT; er; er--)
{
for (c = ((long)SCREEN_WIDTH * SCREEN_TX_BPP + 7) / 8; c; c--)
{
ByteDecode(SCREEN_BYTE_FILL);
}
}*/
}
static uint8_t prev, step = 0;
void ByteDecode(uint8_t byte)
{
/*prev <<= 2;
prev |= (mColorMap[mPassNo][byte >> 4] << 1) | mColorMap[mPassNo][byte & 0x0f];
if (++step == 4)
{
step = 0;
Display_Write_byte(prev);
}*/
}
void drawImageAtAddress(uint32_t addr, uint8_t lut)
{
struct EepromImageHeader *eih = (struct EepromImageHeader *)mClutMap;
eepromRead(addr, mClutMap, sizeof(struct EepromImageHeader));
uint8_t prevVal = 0;
switch (eih->dataType)
{
case DATATYPE_IMG_RAW_1BPP:
@@ -430,34 +87,6 @@ void drawImageAtAddress(uint32_t addr, uint8_t lut)
display_send_stop();
epd_refresh_and_sleep();
break;
case DATATYPE_IMG_BMP:;
uint32_t clutAddr;
printf("sending BMP to EPD - ");
/*clutAddr = drawPrvParseHeader(addr);
if (!clutAddr)
return;
drawPrvLoadAndMapClut(clutAddr);
epdSetup();
if (lut)
selectLUT(lut);
mPassNo = 0;
beginFullscreenImage();
beginWriteFramebuffer(EPD_COLOR_BLACK);
prev = 0;
step = 0;
drawPrvDecodeImageOnce();
endWriteFramebuffer();
mPassNo++;
beginFullscreenImage();
beginWriteFramebuffer(EPD_COLOR_RED);
prev = 0;
step = 0;
drawPrvDecodeImageOnce();
endWriteFramebuffer();*/
printf(" complete.\n");
break;
default: // prevent drawing from an unknown file image type
printf("Image with type 0x%02X was requested, but we don't know what to do with that currently...\n", eih->dataType);
return;

1110
ARM_Tag_FW/88MZ100_OpenEpaperLink_7.4/epd.c Normal file → Executable file

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,8 @@
#pragma once
#include <stdio.h>
//#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdbool.h>
#define DISPLAY_WIDTH (640)
#define DISPLAY_HEIGHT (384)
@@ -16,6 +17,18 @@
#define FORE_COLOR_2 4
#define FORE_COLOR_3 0
#define EPD_LUT_DEFAULT 0
#define EPD_LUT_NO_REPEATS 1
#define EPD_LUT_FAST_NO_REDS 2
#define EPD_LUT_FAST 3
#define EPD_DIRECTION_X false
#define EPD_DIRECTION_Y true
#define EPD_SIZE_SINGLE false
#define EPD_SIZE_DOUBLE true
#define EPD_COLOR_RED true
#define EPD_COLOR_BLACK false
void init_GPIO_EPD();
void display_send_buffer();
@@ -25,5 +38,16 @@ void display_tx_byte(uint8_t data);
void display_send_start(uint8_t inverted);
void display_send_stop();
void setDisplayWindow(uint16_t x, uint16_t y, uint16_t xe, uint16_t ye);
void init_epd();
void refresh_epd();
void refresh_epd();
void lutBeginTX(uint8_t reg);
void lutEndTX();
void epd_pin_enable(int a1);
void fillWindow(uint16_t x, uint16_t y, uint16_t xe, uint16_t ye, uint8_t color);
void epdPrintf(uint16_t x, uint16_t y, bool color, const char* c, ...);

View File

@@ -1,6 +1,6 @@
#include "nfc.h"
#include <stdio.h>
//#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
@@ -12,6 +12,8 @@
#include "mz100_pinmux.h"
#include "mz100_gpio.h"
#include "util.h"
#include "printf.h"
void NVIC_some_IRQ1(unsigned int a1)
{

898
ARM_Tag_FW/88MZ100_OpenEpaperLink_7.4/main.c Normal file → Executable file

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,5 @@
#pragma once
#include <stdio.h>
//#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
#include <string.h>

View File

@@ -4,8 +4,9 @@ GROUP(-lgcc -lc -lnosys)
MEMORY
{
FLASH (rx) : ORIGIN = 0x100000, LENGTH = 80k
RAM (rwx) : ORIGIN = 0x20100000 + 80k, LENGTH = 160k - 80k - 16k
RAM1 (rwx) : ORIGIN = 0x20124000 , LENGTH = 16k
RAM (rwx) : ORIGIN = 0x20100000 + 80k, LENGTH = 160k - 80k - 2k
AONSHADOW (rwx) : ORIGIN = 0x20128000 - 2k, LENGTH = 2k
AON (rwx) : ORIGIN = 0x20130000 , LENGTH = 4k
}
ENTRY(Reset_Handler)
@@ -123,6 +124,27 @@ SECTIONS
/* Check if data + heap + stack exceeds RAM limit */
ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack")
.aon (NOLOAD):
{
. = ALIGN(4);
_start_of_aon = .;
*(.aon)
*(.aon.*)
. = ALIGN(4);
_end_of_aon = .;
} > AON
.aonshadow (NOLOAD):
{
. = ALIGN(4);
_start_of_aonshadow = .;
*(.aonshadow)
*(.aonshadow.*)
. = ALIGN(4);
_end_of_aonshadow = .;
} > AONSHADOW
}

View File

@@ -0,0 +1,43 @@
#include "mz100_aon_ram.h"
#include <string.h>
#include "stdint.h"
__attribute__((section(".aon"))) volatile uint32_t aonChecksum;
__attribute__((section(".aon"))) volatile uint8_t aonShadow[AONSHADOW_SIZE];
bool aonRamValid = false;
void clearAonRam() {
memset((void *)0x130000, 0, 4096);
}
bool loadValidateAonRam() {
uint32_t testchecksum = aonChecksum;
aonChecksum = 0x00000000;
uint32_t checksum = 0xABBA5FF5;
for (uint32_t c = 0x130000; c < 0x131000; c += 4) {
checksum += *(uint32_t *)c;
}
if (checksum == testchecksum) {
// immediately invalidate the checksum; if we reboot, we want a clean reboot
aonChecksum = 0x5445A00A;
memcpy((void *)(0x128000 - AONSHADOW_SIZE), (uint8_t*)aonShadow, AONSHADOW_SIZE);
return true;
} else {
clearAonRam();
memset((void *)(0x128000 - AONSHADOW_SIZE), 0, AONSHADOW_SIZE);
return false;
}
}
void saveAonRam() {
memcpy((uint8_t*)aonShadow, (void *)(0x128000 - AONSHADOW_SIZE), AONSHADOW_SIZE);
aonChecksum = 0x00000000;
uint32_t checksum = 0xABBA5FF5;
for (uint32_t c = 0x130000; c < 0x131000; c += 4) {
checksum += *(uint32_t *)c;
}
aonChecksum = checksum;
}

View File

@@ -0,0 +1,11 @@
#include "stdint.h"
#include "stdbool.h"
#define AONSHADOW_SIZE 2048
extern bool aonRamValid;
bool loadValidateAonRam();
void saveAonRam();
void clearAonRam();

View File

@@ -1,4 +1,4 @@
#include <stdio.h>
//#include <stdio.h>
#include <stdint.h>
#include "core_cm3.h"
#include "mz100_gpio.h"
@@ -14,6 +14,9 @@
#include "gpio.h"
#include "main.h"
#include "proto.h"
#include "printf.h"
extern void saveAonRam();
void AON_level_VDD(int state)
{
@@ -90,9 +93,11 @@ extern struct AvailDataInfo curDataInfo; // last 'AvailDataInfo' we received fro
extern bool requestPartialBlock; // if we should ask the AP to get this block from the host or not
void sleep_with_with_wakeup(uint32_t sleep_time_ms)
{
memcpy((uint8_t *)&(*(volatile unsigned int *)0x130500), (uint8_t *)&curBlock, sizeof(struct blockRequest));
memcpy((uint8_t *)&(*(volatile unsigned int *)0x130600), (uint8_t *)&curDataInfo, sizeof(struct AvailDataInfo));
printf("sleep: %u\r\n", sleep_time_ms);
saveAonRam();
//memcpy((uint8_t *)&(*(volatile unsigned int *)0x130500), (uint8_t *)&curBlock, sizeof(struct blockRequest));
//memcpy((uint8_t *)&(*(volatile unsigned int *)0x130600), (uint8_t *)&curDataInfo, sizeof(struct AvailDataInfo));
//sleep_time_ms = 10000;
printf("sleep! %u\n", sleep_time_ms);
uint32_t sleep_time_ms_1;
AON_level_VDD(7);
AON_level_VAA(0);

View File

@@ -1,6 +1,6 @@
#pragma once
#include <stdio.h>
//#include <stdio.h>
#include <stdint.h>
#include "core_cm3.h"
#include "mz100_gpio.h"

View File

@@ -1,5 +1,5 @@
#include "nfc.h"
#include <stdio.h>
//#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
@@ -17,6 +17,8 @@
#include "timer.h"
#include "epd.h"
#include "proto.h"
#include "printf.h"
#define WHO_AM_I 0x04
uint8_t i2c_address = 0xAA;

View File

@@ -1,5 +1,5 @@
#pragma once
#include <stdio.h>
//#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
#include <string.h>

143
ARM_Tag_FW/88MZ100_OpenEpaperLink_7.4/powermgt.c Normal file → Executable file
View File

@@ -3,64 +3,69 @@
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
// #include <stdio.h>
#include <string.h>
#include "mz100_sleep.h"
#include "zigbee.h"
#include "eeprom.h"
#include "board.h"
#include "screen.h"
#include "eeprom.h"
#include "main.h"
#include "util.h"
#include "mz100_sleep.h"
#include "printf.h"
#include "screen.h"
#include "syncedproto.h"
#include <stdbool.h>
#include "util.h"
#include "zigbee.h"
uint16_t dataReqAttemptArr[POWER_SAVING_SMOOTHING] = {0}; // Holds the amount of attempts required per data_req/check-in
uint8_t dataReqAttemptArrayIndex = 0;
uint8_t dataReqLastAttempt = 0;
uint16_t nextCheckInFromAP = 0;
uint8_t wakeUpReason = 0;
uint8_t scanAttempts = 0;
__attribute__((section(".aonshadow"))) uint16_t dataReqAttemptArr[POWER_SAVING_SMOOTHING] = {0}; // Holds the amount of attempts required per data_req/check-in
__attribute__((section(".aonshadow"))) uint8_t dataReqAttemptArrayIndex = 0;
__attribute__((section(".aonshadow"))) uint8_t dataReqLastAttempt = 0;
__attribute__((section(".aonshadow"))) uint16_t nextCheckInFromAP = 0;
__attribute__((section(".aonshadow"))) uint8_t wakeUpReason = 0;
__attribute__((section(".aonshadow"))) uint8_t scanAttempts = 0;
int8_t temperature = 0;
uint16_t batteryVoltage = 0;
bool lowBattery = false;
uint16_t longDataReqCounter = 0;
uint16_t voltageCheckCounter = 0;
__attribute__((section(".aonshadow"))) int8_t temperature = 0;
__attribute__((section(".aonshadow"))) uint16_t batteryVoltage = 0;
__attribute__((section(".aonshadow"))) bool lowBattery = false;
__attribute__((section(".aonshadow"))) uint16_t longDataReqCounter = 0;
__attribute__((section(".aonshadow"))) uint16_t voltageCheckCounter = 0;
uint8_t capabilities = 0;
__attribute__((section(".aonshadow"))) uint8_t capabilities = 0;
bool spiActive = false;
bool uartActive = false;
bool eepromActive = false;
bool i2cActive = false;
extern int8_t adcSampleTemperature(void); // in degrees C
uint8_t checkButtonOrJig()
{
extern int8_t adcSampleTemperature(void); // in degrees C
uint8_t checkButtonOrJig() {
return DETECT_P1_0_NOTHING;
}
void setupPortsInitial()
{
void setupPortsInitial() {
}
void initPowerSaving(const uint16_t initialValue)
{
for (uint8_t c = 0; c < POWER_SAVING_SMOOTHING; c++)
{
uint16_t doVoltageReading() {
batteryVoltage = (uint16_t)measureBattery();
if (batteryVoltage < BATTERY_VOLTAGE_MINIMUM) {
lowBattery = true;
} else {
lowBattery = false;
}
return batteryVoltage;
}
void initPowerSaving(const uint16_t initialValue) {
for (uint8_t c = 0; c < POWER_SAVING_SMOOTHING; c++) {
dataReqAttemptArr[c] = initialValue;
}
}
static void configSPI(const bool setup)
{
static void configSPI(const bool setup) {
spiActive = setup;
}
static void configUART(const bool setup)
{
static void configUART(const bool setup) {
/* if (setup == uartActive)
return;
uartActive = setup;
@@ -70,69 +75,64 @@ static void configUART(const bool setup)
Serial.end();*/
}
static void configEEPROM(const bool setup)
{
static void configEEPROM(const bool setup) {
}
static void configI2C(const bool setup)
{
static void configI2C(const bool setup) {
}
void powerUp(const uint8_t parts)
{
printf("Power up: %d\r\n", parts);
if (parts & INIT_RADIO)
{
void powerUp(const uint8_t parts) {
// printf("Power up: %d\r\n", parts);
if (parts & INIT_RADIO) {
radioInit();
// radioRxFilterCfg(mSelfMac, 0x10000, PROTO_PAN_ID);
// radioSetTxPower(10);
if (currentChannel >= 11 && currentChannel <= 27)
{
if (currentChannel >= 11 && currentChannel <= 27) {
radioSetChannel(currentChannel);
}
else
{
} else {
radioSetChannel(RADIO_FIRST_CHANNEL);
}
}
if (parts & INIT_UART) {
configUART(true);
}
if (parts & INIT_EPD) {
configSPI(true);
}
if (parts & INIT_EEPROM) {
configEEPROM(true);
}
if (parts & INIT_I2C) {
configI2C(true);
}
}
void powerDown(const uint8_t parts)
{
printf("Power down: %d\r\n", parts);
void powerDown(const uint8_t parts) {
// printf("Power down: %d\r\n", parts);
}
void doSleep(const uint32_t t)
{
void doSleep(const uint32_t t) {
printf("Sleeping for: %d ms\r\n", t);
// sleepForMs(t);
delay(t);
}
uint32_t getNextScanSleep(const bool increment)
{
if (increment)
{
uint32_t getNextScanSleep(const bool increment) {
if (increment) {
if (scanAttempts < 255)
scanAttempts++;
}
if (scanAttempts < INTERVAL_1_ATTEMPTS)
{
if (scanAttempts < INTERVAL_1_ATTEMPTS) {
return INTERVAL_1_TIME;
}
else if (scanAttempts < (INTERVAL_1_ATTEMPTS + INTERVAL_2_ATTEMPTS))
{
} else if (scanAttempts < (INTERVAL_1_ATTEMPTS + INTERVAL_2_ATTEMPTS)) {
return INTERVAL_2_TIME;
}
else
{
} else {
return INTERVAL_3_TIME;
}
}
void addAverageValue()
{
void addAverageValue() {
uint16_t curval = INTERVAL_AT_MAX_ATTEMPTS - INTERVAL_BASE;
curval *= dataReqLastAttempt;
curval /= DATA_REQ_MAX_ATTEMPTS;
@@ -141,14 +141,11 @@ void addAverageValue()
dataReqAttemptArrayIndex++;
}
uint16_t getNextSleep()
{
/*uint16_t avg = 0;
for (uint8_t c = 0; c < POWER_SAVING_SMOOTHING; c++)
{
uint16_t getNextSleep() {
uint16_t avg = 0;
for (uint8_t c = 0; c < POWER_SAVING_SMOOTHING; c++) {
avg += dataReqAttemptArr[c];
}
avg /= POWER_SAVING_SMOOTHING;
return avg;*/
return 30;
return avg;
}

View File

@@ -60,20 +60,22 @@ extern void doSleep(const uint32_t t);
extern void addAverageValue();
extern uint16_t getNextSleep();
extern uint16_t doVoltageReading();
extern uint32_t getNextScanSleep(const bool increment);
extern void initPowerSaving(const uint16_t initialValue);
extern uint8_t wakeUpReason;
extern uint8_t capabilities;
extern __attribute__((section(".aonshadow"))) uint8_t capabilities;
extern uint16_t nextCheckInFromAP;
extern uint8_t dataReqLastAttempt;
extern int8_t temperature;
extern uint16_t batteryVoltage;
extern bool lowBattery;
extern uint8_t scanAttempts;
extern uint16_t longDataReqCounter;
extern uint16_t voltageCheckCounter;
extern __attribute__((section(".aonshadow"))) uint8_t dataReqLastAttempt;
extern __attribute__((section(".aonshadow"))) int8_t temperature;
extern __attribute__((section(".aonshadow"))) uint16_t batteryVoltage;
extern __attribute__((section(".aonshadow"))) bool lowBattery;
extern __attribute__((section(".aonshadow"))) uint8_t scanAttempts;
extern __attribute__((section(".aonshadow"))) uint16_t longDataReqCounter;
extern __attribute__((section(".aonshadow"))) uint16_t voltageCheckCounter;
#endif

View File

@@ -0,0 +1,914 @@
///////////////////////////////////////////////////////////////////////////////
// \author (c) Marco Paland (info@paland.com)
// 2014-2019, PALANDesign Hannover, Germany
//
// \license The MIT License (MIT)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
// \brief Tiny printf, sprintf and (v)snprintf implementation, optimized for speed on
// embedded systems with a very limited resources. These routines are thread
// safe and reentrant!
// Use this instead of the bloated standard/newlib printf cause these use
// malloc for printf (and may not be thread safe).
//
///////////////////////////////////////////////////////////////////////////////
#include <stdbool.h>
#include <stdint.h>
#include "printf.h"
// define this globally (e.g. gcc -DPRINTF_INCLUDE_CONFIG_H ...) to include the
// printf_config.h header file
// default: undefined
#ifdef PRINTF_INCLUDE_CONFIG_H
#include "printf_config.h"
#endif
// 'ntoa' conversion buffer size, this must be big enough to hold one converted
// numeric number including padded zeros (dynamically created on stack)
// default: 32 byte
#ifndef PRINTF_NTOA_BUFFER_SIZE
#define PRINTF_NTOA_BUFFER_SIZE 32U
#endif
// 'ftoa' conversion buffer size, this must be big enough to hold one converted
// float number including padded zeros (dynamically created on stack)
// default: 32 byte
#ifndef PRINTF_FTOA_BUFFER_SIZE
#define PRINTF_FTOA_BUFFER_SIZE 32U
#endif
// support for the floating point type (%f)
// default: activated
#ifndef PRINTF_DISABLE_SUPPORT_FLOAT
#define PRINTF_SUPPORT_FLOAT
#endif
// support for exponential floating point notation (%e/%g)
// default: activated
#ifndef PRINTF_DISABLE_SUPPORT_EXPONENTIAL
#define PRINTF_SUPPORT_EXPONENTIAL
#endif
// define the default floating point precision
// default: 6 digits
#ifndef PRINTF_DEFAULT_FLOAT_PRECISION
#define PRINTF_DEFAULT_FLOAT_PRECISION 6U
#endif
// define the largest float suitable to print with %f
// default: 1e9
#ifndef PRINTF_MAX_FLOAT
#define PRINTF_MAX_FLOAT 1e9
#endif
// support for the long long types (%llu or %p)
// default: activated
#ifndef PRINTF_DISABLE_SUPPORT_LONG_LONG
#define PRINTF_SUPPORT_LONG_LONG
#endif
// support for the ptrdiff_t type (%t)
// ptrdiff_t is normally defined in <stddef.h> as long or long long type
// default: activated
#ifndef PRINTF_DISABLE_SUPPORT_PTRDIFF_T
#define PRINTF_SUPPORT_PTRDIFF_T
#endif
///////////////////////////////////////////////////////////////////////////////
// internal flag definitions
#define FLAGS_ZEROPAD (1U << 0U)
#define FLAGS_LEFT (1U << 1U)
#define FLAGS_PLUS (1U << 2U)
#define FLAGS_SPACE (1U << 3U)
#define FLAGS_HASH (1U << 4U)
#define FLAGS_UPPERCASE (1U << 5U)
#define FLAGS_CHAR (1U << 6U)
#define FLAGS_SHORT (1U << 7U)
#define FLAGS_LONG (1U << 8U)
#define FLAGS_LONG_LONG (1U << 9U)
#define FLAGS_PRECISION (1U << 10U)
#define FLAGS_ADAPT_EXP (1U << 11U)
// import float.h for DBL_MAX
#if defined(PRINTF_SUPPORT_FLOAT)
#include <float.h>
#endif
// output function type
typedef void (*out_fct_type)(char character, void* buffer, size_t idx, size_t maxlen);
// wrapper (used as buffer) for output function type
typedef struct {
void (*fct)(char character, void* arg);
void* arg;
} out_fct_wrap_type;
// internal buffer output
static inline void _out_buffer(char character, void* buffer, size_t idx, size_t maxlen)
{
if (idx < maxlen) {
((char*)buffer)[idx] = character;
}
}
// internal null output
static inline void _out_null(char character, void* buffer, size_t idx, size_t maxlen)
{
(void)character; (void)buffer; (void)idx; (void)maxlen;
}
// internal _putchar wrapper
static inline void _out_char(char character, void* buffer, size_t idx, size_t maxlen)
{
(void)buffer; (void)idx; (void)maxlen;
if (character) {
_putchar(character);
}
}
// internal output function wrapper
static inline void _out_fct(char character, void* buffer, size_t idx, size_t maxlen)
{
(void)idx; (void)maxlen;
if (character) {
// buffer is the output fct pointer
((out_fct_wrap_type*)buffer)->fct(character, ((out_fct_wrap_type*)buffer)->arg);
}
}
// internal secure strlen
// \return The length of the string (excluding the terminating 0) limited by 'maxsize'
static inline unsigned int _strnlen_s(const char* str, size_t maxsize)
{
const char* s;
for (s = str; *s && maxsize--; ++s);
return (unsigned int)(s - str);
}
// internal test if char is a digit (0-9)
// \return true if char is a digit
static inline bool _is_digit(char ch)
{
return (ch >= '0') && (ch <= '9');
}
// internal ASCII string to unsigned int conversion
static unsigned int _atoi(const char** str)
{
unsigned int i = 0U;
while (_is_digit(**str)) {
i = i * 10U + (unsigned int)(*((*str)++) - '0');
}
return i;
}
// output the specified string in reverse, taking care of any zero-padding
static size_t _out_rev(out_fct_type out, char* buffer, size_t idx, size_t maxlen, const char* buf, size_t len, unsigned int width, unsigned int flags)
{
const size_t start_idx = idx;
// pad spaces up to given width
if (!(flags & FLAGS_LEFT) && !(flags & FLAGS_ZEROPAD)) {
for (size_t i = len; i < width; i++) {
out(' ', buffer, idx++, maxlen);
}
}
// reverse string
while (len) {
out(buf[--len], buffer, idx++, maxlen);
}
// append pad spaces up to given width
if (flags & FLAGS_LEFT) {
while (idx - start_idx < width) {
out(' ', buffer, idx++, maxlen);
}
}
return idx;
}
// internal itoa format
static size_t _ntoa_format(out_fct_type out, char* buffer, size_t idx, size_t maxlen, char* buf, size_t len, bool negative, unsigned int base, unsigned int prec, unsigned int width, unsigned int flags)
{
// pad leading zeros
if (!(flags & FLAGS_LEFT)) {
if (width && (flags & FLAGS_ZEROPAD) && (negative || (flags & (FLAGS_PLUS | FLAGS_SPACE)))) {
width--;
}
while ((len < prec) && (len < PRINTF_NTOA_BUFFER_SIZE)) {
buf[len++] = '0';
}
while ((flags & FLAGS_ZEROPAD) && (len < width) && (len < PRINTF_NTOA_BUFFER_SIZE)) {
buf[len++] = '0';
}
}
// handle hash
if (flags & FLAGS_HASH) {
if (!(flags & FLAGS_PRECISION) && len && ((len == prec) || (len == width))) {
len--;
if (len && (base == 16U)) {
len--;
}
}
if ((base == 16U) && !(flags & FLAGS_UPPERCASE) && (len < PRINTF_NTOA_BUFFER_SIZE)) {
buf[len++] = 'x';
}
else if ((base == 16U) && (flags & FLAGS_UPPERCASE) && (len < PRINTF_NTOA_BUFFER_SIZE)) {
buf[len++] = 'X';
}
else if ((base == 2U) && (len < PRINTF_NTOA_BUFFER_SIZE)) {
buf[len++] = 'b';
}
if (len < PRINTF_NTOA_BUFFER_SIZE) {
buf[len++] = '0';
}
}
if (len < PRINTF_NTOA_BUFFER_SIZE) {
if (negative) {
buf[len++] = '-';
}
else if (flags & FLAGS_PLUS) {
buf[len++] = '+'; // ignore the space if the '+' exists
}
else if (flags & FLAGS_SPACE) {
buf[len++] = ' ';
}
}
return _out_rev(out, buffer, idx, maxlen, buf, len, width, flags);
}
// internal itoa for 'long' type
static size_t _ntoa_long(out_fct_type out, char* buffer, size_t idx, size_t maxlen, unsigned long value, bool negative, unsigned long base, unsigned int prec, unsigned int width, unsigned int flags)
{
char buf[PRINTF_NTOA_BUFFER_SIZE];
size_t len = 0U;
// no hash for 0 values
if (!value) {
flags &= ~FLAGS_HASH;
}
// write if precision != 0 and value is != 0
if (!(flags & FLAGS_PRECISION) || value) {
do {
const char digit = (char)(value % base);
buf[len++] = digit < 10 ? '0' + digit : (flags & FLAGS_UPPERCASE ? 'A' : 'a') + digit - 10;
value /= base;
} while (value && (len < PRINTF_NTOA_BUFFER_SIZE));
}
return _ntoa_format(out, buffer, idx, maxlen, buf, len, negative, (unsigned int)base, prec, width, flags);
}
// internal itoa for 'long long' type
#if defined(PRINTF_SUPPORT_LONG_LONG)
static size_t _ntoa_long_long(out_fct_type out, char* buffer, size_t idx, size_t maxlen, unsigned long long value, bool negative, unsigned long long base, unsigned int prec, unsigned int width, unsigned int flags)
{
char buf[PRINTF_NTOA_BUFFER_SIZE];
size_t len = 0U;
// no hash for 0 values
if (!value) {
flags &= ~FLAGS_HASH;
}
// write if precision != 0 and value is != 0
if (!(flags & FLAGS_PRECISION) || value) {
do {
const char digit = (char)(value % base);
buf[len++] = digit < 10 ? '0' + digit : (flags & FLAGS_UPPERCASE ? 'A' : 'a') + digit - 10;
value /= base;
} while (value && (len < PRINTF_NTOA_BUFFER_SIZE));
}
return _ntoa_format(out, buffer, idx, maxlen, buf, len, negative, (unsigned int)base, prec, width, flags);
}
#endif // PRINTF_SUPPORT_LONG_LONG
#if defined(PRINTF_SUPPORT_FLOAT)
#if defined(PRINTF_SUPPORT_EXPONENTIAL)
// forward declaration so that _ftoa can switch to exp notation for values > PRINTF_MAX_FLOAT
static size_t _etoa(out_fct_type out, char* buffer, size_t idx, size_t maxlen, double value, unsigned int prec, unsigned int width, unsigned int flags);
#endif
// internal ftoa for fixed decimal floating point
static size_t _ftoa(out_fct_type out, char* buffer, size_t idx, size_t maxlen, double value, unsigned int prec, unsigned int width, unsigned int flags)
{
char buf[PRINTF_FTOA_BUFFER_SIZE];
size_t len = 0U;
double diff = 0.0;
// powers of 10
static const double pow10[] = { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000 };
// test for special values
if (value != value)
return _out_rev(out, buffer, idx, maxlen, "nan", 3, width, flags);
if (value < -DBL_MAX)
return _out_rev(out, buffer, idx, maxlen, "fni-", 4, width, flags);
if (value > DBL_MAX)
return _out_rev(out, buffer, idx, maxlen, (flags & FLAGS_PLUS) ? "fni+" : "fni", (flags & FLAGS_PLUS) ? 4U : 3U, width, flags);
// test for very large values
// standard printf behavior is to print EVERY whole number digit -- which could be 100s of characters overflowing your buffers == bad
if ((value > PRINTF_MAX_FLOAT) || (value < -PRINTF_MAX_FLOAT)) {
#if defined(PRINTF_SUPPORT_EXPONENTIAL)
return _etoa(out, buffer, idx, maxlen, value, prec, width, flags);
#else
return 0U;
#endif
}
// test for negative
bool negative = false;
if (value < 0) {
negative = true;
value = 0 - value;
}
// set default precision, if not set explicitly
if (!(flags & FLAGS_PRECISION)) {
prec = PRINTF_DEFAULT_FLOAT_PRECISION;
}
// limit precision to 9, cause a prec >= 10 can lead to overflow errors
while ((len < PRINTF_FTOA_BUFFER_SIZE) && (prec > 9U)) {
buf[len++] = '0';
prec--;
}
int whole = (int)value;
double tmp = (value - whole) * pow10[prec];
unsigned long frac = (unsigned long)tmp;
diff = tmp - frac;
if (diff > 0.5) {
++frac;
// handle rollover, e.g. case 0.99 with prec 1 is 1.0
if (frac >= pow10[prec]) {
frac = 0;
++whole;
}
}
else if (diff < 0.5) {
}
else if ((frac == 0U) || (frac & 1U)) {
// if halfway, round up if odd OR if last digit is 0
++frac;
}
if (prec == 0U) {
diff = value - (double)whole;
if ((!(diff < 0.5) || (diff > 0.5)) && (whole & 1)) {
// exactly 0.5 and ODD, then round up
// 1.5 -> 2, but 2.5 -> 2
++whole;
}
}
else {
unsigned int count = prec;
// now do fractional part, as an unsigned number
while (len < PRINTF_FTOA_BUFFER_SIZE) {
--count;
buf[len++] = (char)(48U + (frac % 10U));
if (!(frac /= 10U)) {
break;
}
}
// add extra 0s
while ((len < PRINTF_FTOA_BUFFER_SIZE) && (count-- > 0U)) {
buf[len++] = '0';
}
if (len < PRINTF_FTOA_BUFFER_SIZE) {
// add decimal
buf[len++] = '.';
}
}
// do whole part, number is reversed
while (len < PRINTF_FTOA_BUFFER_SIZE) {
buf[len++] = (char)(48 + (whole % 10));
if (!(whole /= 10)) {
break;
}
}
// pad leading zeros
if (!(flags & FLAGS_LEFT) && (flags & FLAGS_ZEROPAD)) {
if (width && (negative || (flags & (FLAGS_PLUS | FLAGS_SPACE)))) {
width--;
}
while ((len < width) && (len < PRINTF_FTOA_BUFFER_SIZE)) {
buf[len++] = '0';
}
}
if (len < PRINTF_FTOA_BUFFER_SIZE) {
if (negative) {
buf[len++] = '-';
}
else if (flags & FLAGS_PLUS) {
buf[len++] = '+'; // ignore the space if the '+' exists
}
else if (flags & FLAGS_SPACE) {
buf[len++] = ' ';
}
}
return _out_rev(out, buffer, idx, maxlen, buf, len, width, flags);
}
#if defined(PRINTF_SUPPORT_EXPONENTIAL)
// internal ftoa variant for exponential floating-point type, contributed by Martijn Jasperse <m.jasperse@gmail.com>
static size_t _etoa(out_fct_type out, char* buffer, size_t idx, size_t maxlen, double value, unsigned int prec, unsigned int width, unsigned int flags)
{
// check for NaN and special values
if ((value != value) || (value > DBL_MAX) || (value < -DBL_MAX)) {
return _ftoa(out, buffer, idx, maxlen, value, prec, width, flags);
}
// determine the sign
const bool negative = value < 0;
if (negative) {
value = -value;
}
// default precision
if (!(flags & FLAGS_PRECISION)) {
prec = PRINTF_DEFAULT_FLOAT_PRECISION;
}
// determine the decimal exponent
// based on the algorithm by David Gay (https://www.ampl.com/netlib/fp/dtoa.c)
union {
uint64_t U;
double F;
} conv;
conv.F = value;
int exp2 = (int)((conv.U >> 52U) & 0x07FFU) - 1023; // effectively log2
conv.U = (conv.U & ((1ULL << 52U) - 1U)) | (1023ULL << 52U); // drop the exponent so conv.F is now in [1,2)
// now approximate log10 from the log2 integer part and an expansion of ln around 1.5
int expval = (int)(0.1760912590558 + exp2 * 0.301029995663981 + (conv.F - 1.5) * 0.289529654602168);
// now we want to compute 10^expval but we want to be sure it won't overflow
exp2 = (int)(expval * 3.321928094887362 + 0.5);
const double z = expval * 2.302585092994046 - exp2 * 0.6931471805599453;
const double z2 = z * z;
conv.U = (uint64_t)(exp2 + 1023) << 52U;
// compute exp(z) using continued fractions, see https://en.wikipedia.org/wiki/Exponential_function#Continued_fractions_for_ex
conv.F *= 1 + 2 * z / (2 - z + (z2 / (6 + (z2 / (10 + z2 / 14)))));
// correct for rounding errors
if (value < conv.F) {
expval--;
conv.F /= 10;
}
// the exponent format is "%+03d" and largest value is "307", so set aside 4-5 characters
unsigned int minwidth = ((expval < 100) && (expval > -100)) ? 4U : 5U;
// in "%g" mode, "prec" is the number of *significant figures* not decimals
if (flags & FLAGS_ADAPT_EXP) {
// do we want to fall-back to "%f" mode?
if ((value >= 1e-4) && (value < 1e6)) {
if ((int)prec > expval) {
prec = (unsigned)((int)prec - expval - 1);
}
else {
prec = 0;
}
flags |= FLAGS_PRECISION; // make sure _ftoa respects precision
// no characters in exponent
minwidth = 0U;
expval = 0;
}
else {
// we use one sigfig for the whole part
if ((prec > 0) && (flags & FLAGS_PRECISION)) {
--prec;
}
}
}
// will everything fit?
unsigned int fwidth = width;
if (width > minwidth) {
// we didn't fall-back so subtract the characters required for the exponent
fwidth -= minwidth;
} else {
// not enough characters, so go back to default sizing
fwidth = 0U;
}
if ((flags & FLAGS_LEFT) && minwidth) {
// if we're padding on the right, DON'T pad the floating part
fwidth = 0U;
}
// rescale the float value
if (expval) {
value /= conv.F;
}
// output the floating part
const size_t start_idx = idx;
idx = _ftoa(out, buffer, idx, maxlen, negative ? -value : value, prec, fwidth, flags & ~FLAGS_ADAPT_EXP);
// output the exponent part
if (minwidth) {
// output the exponential symbol
out((flags & FLAGS_UPPERCASE) ? 'E' : 'e', buffer, idx++, maxlen);
// output the exponent value
idx = _ntoa_long(out, buffer, idx, maxlen, (expval < 0) ? -expval : expval, expval < 0, 10, 0, minwidth-1, FLAGS_ZEROPAD | FLAGS_PLUS);
// might need to right-pad spaces
if (flags & FLAGS_LEFT) {
while (idx - start_idx < width) out(' ', buffer, idx++, maxlen);
}
}
return idx;
}
#endif // PRINTF_SUPPORT_EXPONENTIAL
#endif // PRINTF_SUPPORT_FLOAT
// internal vsnprintf
static int _vsnprintf(out_fct_type out, char* buffer, const size_t maxlen, const char* format, va_list va)
{
unsigned int flags, width, precision, n;
size_t idx = 0U;
if (!buffer) {
// use null output function
out = _out_null;
}
while (*format)
{
// format specifier? %[flags][width][.precision][length]
if (*format != '%') {
// no
out(*format, buffer, idx++, maxlen);
format++;
continue;
}
else {
// yes, evaluate it
format++;
}
// evaluate flags
flags = 0U;
do {
switch (*format) {
case '0': flags |= FLAGS_ZEROPAD; format++; n = 1U; break;
case '-': flags |= FLAGS_LEFT; format++; n = 1U; break;
case '+': flags |= FLAGS_PLUS; format++; n = 1U; break;
case ' ': flags |= FLAGS_SPACE; format++; n = 1U; break;
case '#': flags |= FLAGS_HASH; format++; n = 1U; break;
default : n = 0U; break;
}
} while (n);
// evaluate width field
width = 0U;
if (_is_digit(*format)) {
width = _atoi(&format);
}
else if (*format == '*') {
const int w = va_arg(va, int);
if (w < 0) {
flags |= FLAGS_LEFT; // reverse padding
width = (unsigned int)-w;
}
else {
width = (unsigned int)w;
}
format++;
}
// evaluate precision field
precision = 0U;
if (*format == '.') {
flags |= FLAGS_PRECISION;
format++;
if (_is_digit(*format)) {
precision = _atoi(&format);
}
else if (*format == '*') {
const int prec = (int)va_arg(va, int);
precision = prec > 0 ? (unsigned int)prec : 0U;
format++;
}
}
// evaluate length field
switch (*format) {
case 'l' :
flags |= FLAGS_LONG;
format++;
if (*format == 'l') {
flags |= FLAGS_LONG_LONG;
format++;
}
break;
case 'h' :
flags |= FLAGS_SHORT;
format++;
if (*format == 'h') {
flags |= FLAGS_CHAR;
format++;
}
break;
#if defined(PRINTF_SUPPORT_PTRDIFF_T)
case 't' :
flags |= (sizeof(ptrdiff_t) == sizeof(long) ? FLAGS_LONG : FLAGS_LONG_LONG);
format++;
break;
#endif
case 'j' :
flags |= (sizeof(intmax_t) == sizeof(long) ? FLAGS_LONG : FLAGS_LONG_LONG);
format++;
break;
case 'z' :
flags |= (sizeof(size_t) == sizeof(long) ? FLAGS_LONG : FLAGS_LONG_LONG);
format++;
break;
default :
break;
}
// evaluate specifier
switch (*format) {
case 'd' :
case 'i' :
case 'u' :
case 'x' :
case 'X' :
case 'o' :
case 'b' : {
// set the base
unsigned int base;
if (*format == 'x' || *format == 'X') {
base = 16U;
}
else if (*format == 'o') {
base = 8U;
}
else if (*format == 'b') {
base = 2U;
}
else {
base = 10U;
flags &= ~FLAGS_HASH; // no hash for dec format
}
// uppercase
if (*format == 'X') {
flags |= FLAGS_UPPERCASE;
}
// no plus or space flag for u, x, X, o, b
if ((*format != 'i') && (*format != 'd')) {
flags &= ~(FLAGS_PLUS | FLAGS_SPACE);
}
// ignore '0' flag when precision is given
if (flags & FLAGS_PRECISION) {
flags &= ~FLAGS_ZEROPAD;
}
// convert the integer
if ((*format == 'i') || (*format == 'd')) {
// signed
if (flags & FLAGS_LONG_LONG) {
#if defined(PRINTF_SUPPORT_LONG_LONG)
const long long value = va_arg(va, long long);
idx = _ntoa_long_long(out, buffer, idx, maxlen, (unsigned long long)(value > 0 ? value : 0 - value), value < 0, base, precision, width, flags);
#endif
}
else if (flags & FLAGS_LONG) {
const long value = va_arg(va, long);
idx = _ntoa_long(out, buffer, idx, maxlen, (unsigned long)(value > 0 ? value : 0 - value), value < 0, base, precision, width, flags);
}
else {
const int value = (flags & FLAGS_CHAR) ? (char)va_arg(va, int) : (flags & FLAGS_SHORT) ? (short int)va_arg(va, int) : va_arg(va, int);
idx = _ntoa_long(out, buffer, idx, maxlen, (unsigned int)(value > 0 ? value : 0 - value), value < 0, base, precision, width, flags);
}
}
else {
// unsigned
if (flags & FLAGS_LONG_LONG) {
#if defined(PRINTF_SUPPORT_LONG_LONG)
idx = _ntoa_long_long(out, buffer, idx, maxlen, va_arg(va, unsigned long long), false, base, precision, width, flags);
#endif
}
else if (flags & FLAGS_LONG) {
idx = _ntoa_long(out, buffer, idx, maxlen, va_arg(va, unsigned long), false, base, precision, width, flags);
}
else {
const unsigned int value = (flags & FLAGS_CHAR) ? (unsigned char)va_arg(va, unsigned int) : (flags & FLAGS_SHORT) ? (unsigned short int)va_arg(va, unsigned int) : va_arg(va, unsigned int);
idx = _ntoa_long(out, buffer, idx, maxlen, value, false, base, precision, width, flags);
}
}
format++;
break;
}
#if defined(PRINTF_SUPPORT_FLOAT)
case 'f' :
case 'F' :
if (*format == 'F') flags |= FLAGS_UPPERCASE;
idx = _ftoa(out, buffer, idx, maxlen, va_arg(va, double), precision, width, flags);
format++;
break;
#if defined(PRINTF_SUPPORT_EXPONENTIAL)
case 'e':
case 'E':
case 'g':
case 'G':
if ((*format == 'g')||(*format == 'G')) flags |= FLAGS_ADAPT_EXP;
if ((*format == 'E')||(*format == 'G')) flags |= FLAGS_UPPERCASE;
idx = _etoa(out, buffer, idx, maxlen, va_arg(va, double), precision, width, flags);
format++;
break;
#endif // PRINTF_SUPPORT_EXPONENTIAL
#endif // PRINTF_SUPPORT_FLOAT
case 'c' : {
unsigned int l = 1U;
// pre padding
if (!(flags & FLAGS_LEFT)) {
while (l++ < width) {
out(' ', buffer, idx++, maxlen);
}
}
// char output
out((char)va_arg(va, int), buffer, idx++, maxlen);
// post padding
if (flags & FLAGS_LEFT) {
while (l++ < width) {
out(' ', buffer, idx++, maxlen);
}
}
format++;
break;
}
case 's' : {
const char* p = va_arg(va, char*);
unsigned int l = _strnlen_s(p, precision ? precision : (size_t)-1);
// pre padding
if (flags & FLAGS_PRECISION) {
l = (l < precision ? l : precision);
}
if (!(flags & FLAGS_LEFT)) {
while (l++ < width) {
out(' ', buffer, idx++, maxlen);
}
}
// string output
while ((*p != 0) && (!(flags & FLAGS_PRECISION) || precision--)) {
out(*(p++), buffer, idx++, maxlen);
}
// post padding
if (flags & FLAGS_LEFT) {
while (l++ < width) {
out(' ', buffer, idx++, maxlen);
}
}
format++;
break;
}
case 'p' : {
width = sizeof(void*) * 2U;
flags |= FLAGS_ZEROPAD | FLAGS_UPPERCASE;
#if defined(PRINTF_SUPPORT_LONG_LONG)
const bool is_ll = sizeof(uintptr_t) == sizeof(long long);
if (is_ll) {
idx = _ntoa_long_long(out, buffer, idx, maxlen, (uintptr_t)va_arg(va, void*), false, 16U, precision, width, flags);
}
else {
#endif
idx = _ntoa_long(out, buffer, idx, maxlen, (unsigned long)((uintptr_t)va_arg(va, void*)), false, 16U, precision, width, flags);
#if defined(PRINTF_SUPPORT_LONG_LONG)
}
#endif
format++;
break;
}
case '%' :
out('%', buffer, idx++, maxlen);
format++;
break;
default :
out(*format, buffer, idx++, maxlen);
format++;
break;
}
}
// termination
out((char)0, buffer, idx < maxlen ? idx : maxlen - 1U, maxlen);
// return written chars without terminating \0
return (int)idx;
}
///////////////////////////////////////////////////////////////////////////////
int printf_(const char* format, ...)
{
va_list va;
va_start(va, format);
char buffer[1];
const int ret = _vsnprintf(_out_char, buffer, (size_t)-1, format, va);
va_end(va);
return ret;
}
int sprintf_(char* buffer, const char* format, ...)
{
va_list va;
va_start(va, format);
const int ret = _vsnprintf(_out_buffer, buffer, (size_t)-1, format, va);
va_end(va);
return ret;
}
int snprintf_(char* buffer, size_t count, const char* format, ...)
{
va_list va;
va_start(va, format);
const int ret = _vsnprintf(_out_buffer, buffer, count, format, va);
va_end(va);
return ret;
}
int vprintf_(const char* format, va_list va)
{
char buffer[1];
return _vsnprintf(_out_char, buffer, (size_t)-1, format, va);
}
int vsnprintf_(char* buffer, size_t count, const char* format, va_list va)
{
return _vsnprintf(_out_buffer, buffer, count, format, va);
}
int fctprintf(void (*out)(char character, void* arg), void* arg, const char* format, ...)
{
va_list va;
va_start(va, format);
const out_fct_wrap_type out_fct_wrap = { out, arg };
const int ret = _vsnprintf(_out_fct, (char*)(uintptr_t)&out_fct_wrap, (size_t)-1, format, va);
va_end(va);
return ret;
}

View File

@@ -0,0 +1,116 @@
///////////////////////////////////////////////////////////////////////////////
// \author (c) Marco Paland (info@paland.com)
// 2014-2019, PALANDesign Hannover, Germany
//
// \license The MIT License (MIT)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
// \brief Tiny printf, sprintf and snprintf implementation, optimized for speed on
// embedded systems with a very limited resources.
// Use this instead of bloated standard/newlib printf.
// These routines are thread safe and reentrant.
//
///////////////////////////////////////////////////////////////////////////////
#ifndef _PRINTF_H_
#define _PRINTF_H_
#include <stdarg.h>
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* Output a character to a custom device like UART, used by the printf() function
* This function is declared here only. You have to write your custom implementation somewhere
* \param character Character to output
*/
void _putchar(char character);
/**
* Tiny printf implementation
* You have to implement _putchar if you use printf()
* To avoid conflicts with the regular printf() API it is overridden by macro defines
* and internal underscore-appended functions like printf_() are used
* \param format A string that specifies the format of the output
* \return The number of characters that are written into the array, not counting the terminating null character
*/
#define printf printf_
int printf_(const char* format, ...);
/**
* Tiny sprintf implementation
* Due to security reasons (buffer overflow) YOU SHOULD CONSIDER USING (V)SNPRINTF INSTEAD!
* \param buffer A pointer to the buffer where to store the formatted string. MUST be big enough to store the output!
* \param format A string that specifies the format of the output
* \return The number of characters that are WRITTEN into the buffer, not counting the terminating null character
*/
#define sprintf sprintf_
int sprintf_(char* buffer, const char* format, ...);
/**
* Tiny snprintf/vsnprintf implementation
* \param buffer A pointer to the buffer where to store the formatted string
* \param count The maximum number of characters to store in the buffer, including a terminating null character
* \param format A string that specifies the format of the output
* \param va A value identifying a variable arguments list
* \return The number of characters that COULD have been written into the buffer, not counting the terminating
* null character. A value equal or larger than count indicates truncation. Only when the returned value
* is non-negative and less than count, the string has been completely written.
*/
#define snprintf snprintf_
#define vsnprintf vsnprintf_
int snprintf_(char* buffer, size_t count, const char* format, ...);
int vsnprintf_(char* buffer, size_t count, const char* format, va_list va);
/**
* Tiny vprintf implementation
* \param format A string that specifies the format of the output
* \param va A value identifying a variable arguments list
* \return The number of characters that are WRITTEN into the buffer, not counting the terminating null character
*/
#define vprintf vprintf_
int vprintf_(const char* format, va_list va);
/**
* printf with output function
* You may use this as dynamic alternative to printf() with its fixed _putchar() output
* \param out An output function which takes one character and an argument pointer
* \param arg An argument pointer for user data passed to output function
* \param format A string that specifies the format of the output
* \return The number of characters that are sent to the output function, not counting the terminating null character
*/
int fctprintf(void (*out)(char character, void* arg), void* arg, const char* format, ...);
#ifdef __cplusplus
}
#endif
#endif // _PRINTF_H_

View File

@@ -4,49 +4,49 @@
#include <stdint.h>
/*
All communications are direct from tag to station, EXCEPT association (tag will broadcast).
All comms shall be encrypted and authenticated with AES-CCM. Shared key shall be burned into the firmware.
Master shall provision new key at association. All non-bcast packets shall have pan id compression.
Master may skip "from" field. Tag checking in confirms it got the master's provisioning reply.
Sadly filtering on MZ100 fails for long addr with no src addr. so short addr for src is used
T = tag, S = station
PACKET TYPE USE PAYLOAD STRUCT NOTES
ASSOC_REQ T2bcast TagInfo tag's info and assoc request (encrypted with shared key)
ASSOC_RESP S2T AssocInfo tag's association info (encrypted with shared key)
CHECKIN T2S CheckinInfo tag checking in occasionally
CHECKOUT S2T PendingInfo station's checkin reply telling tag what we have for it
CHUNK_REQ T2S ChunkReqInfo tag requesting a piece of data
CHUNK_RESP S2T ChunkInfo station provides chunk
All communications are direct from tag to station, EXCEPT association (tag will broadcast).
All comms shall be encrypted and authenticated with AES-CCM. Shared key shall be burned into the firmware.
Master shall provision new key at association. All non-bcast packets shall have pan id compression.
Master may skip "from" field. Tag checking in confirms it got the master's provisioning reply.
Sadly filtering on MZ100 fails for long addr with no src addr. so short addr for src is used
T = tag, S = station
PACKET TYPE USE PAYLOAD STRUCT NOTES
ASSOC_REQ T2bcast TagInfo tag's info and assoc request (encrypted with shared key)
ASSOC_RESP S2T AssocInfo tag's association info (encrypted with shared key)
CHECKIN T2S CheckinInfo tag checking in occasionally
CHECKOUT S2T PendingInfo station's checkin reply telling tag what we have for it
CHUNK_REQ T2S ChunkReqInfo tag requesting a piece of data
CHUNK_RESP S2T ChunkInfo station provides chunk
*/
#define PROTO_PRESHARED_KEY {0x34D906D3, 0xE3E5298E, 0x3429BF58, 0xC1022081}
#define PROTO_PRESHARED_KEY \
{ 0x34D906D3, 0xE3E5298E, 0x3429BF58, 0xC1022081 }
#define PROTO_PAN_ID (0x4447) //PAN ID compression shall be used
#define PROTO_PAN_ID (0x4447) // PAN ID compression shall be used
#define PKT_ASSOC_REQ (0xF0)
#define PKT_ASSOC_RESP (0xF1)
#define PKT_CHECKIN (0xF2)
#define PKT_CHECKOUT (0xF3)
#define PKT_CHUNK_REQ (0xF4)
#define PKT_CHUNK_RESP (0xF5)
#define PKT_ASSOC_REQ (0xF0)
#define PKT_ASSOC_RESP (0xF1)
#define PKT_CHECKIN (0xF2)
#define PKT_CHECKOUT (0xF3)
#define PKT_CHUNK_REQ (0xF4)
#define PKT_CHUNK_RESP (0xF5)
#define PROTO_VER_0 (0)
#define PROTO_VER_CURRENT (PROTO_VER_0)
#define PROTO_VER_0 (0)
#define PROTO_VER_CURRENT (PROTO_VER_0)
#define PROTO_COMPR_TYPE_LZ (0x0001)
#define PROTO_COMPR_TYPE_BITPACK (0x0002)
#define PROTO_MAX_DL_LEN (88)
#define PROTO_COMPR_TYPE_LZ (0x0001)
#define PROTO_COMPR_TYPE_BITPACK (0x0002)
#define PROTO_MAX_DL_LEN (88)
//////////////// NEW
#include "tag_types.h"
/*
// power saving algorithm
#define INTERVAL_BASE 40 // interval (in seconds) (when 1 packet is sent/received) for target current (7.2µA)
#define INTERVAL_AT_MAX_ATTEMPTS 600 // interval (in seconds) (at max attempts) for target average current
@@ -68,7 +68,7 @@
#define INTERVAL_2_TIME 7200UL // Try every 2 hours
#define INTERVAL_2_ATTEMPTS 12 // for 12 attempts (an additional day)
#define INTERVAL_3_TIME 86400UL // Finally, try every day
*/
#pragma pack(1)
enum TagScreenType {
TagScreenEink_BW_1bpp,
@@ -96,8 +96,6 @@ enum TagScreenType {
TagScreenTypeOther = 0x7f,
};
#define RADIO_MAX_PACKET_LEN (125) // useful payload, not including the crc
#define ADDR_MODE_NONE (0)
@@ -122,7 +120,7 @@ struct MacFcs {
uint8_t destAddrType : 2;
uint8_t frameVer : 2;
uint8_t srcAddrType : 2;
} ;
};
struct MacFrameFromMaster {
struct MacFcs fcs;
@@ -130,7 +128,7 @@ struct MacFrameFromMaster {
uint16_t pan;
uint8_t dst[8];
uint16_t from;
} ;
};
struct MacFrameNormal {
struct MacFcs fcs;
@@ -138,7 +136,7 @@ struct MacFrameNormal {
uint16_t pan;
uint8_t dst[8];
uint8_t src[8];
} ;
};
struct MacFrameBcast {
struct MacFcs fcs;
@@ -147,7 +145,7 @@ struct MacFrameBcast {
uint16_t dstAddr;
uint16_t srcPan;
uint8_t src[8];
} ;
};
#define PKT_AVAIL_DATA_SHORTREQ 0xE3
#define PKT_AVAIL_DATA_REQ 0xE5
@@ -175,7 +173,7 @@ struct AvailDataReq {
uint8_t currentChannel;
uint8_t customMode;
uint8_t reserved[8];
} ;
};
struct oldAvailDataReq {
uint8_t checksum;
@@ -186,7 +184,7 @@ struct oldAvailDataReq {
uint8_t hwType;
uint8_t wakeupReason;
uint8_t capabilities;
} ;
};
struct AvailDataInfo {
uint8_t checksum;
@@ -195,31 +193,31 @@ struct AvailDataInfo {
uint8_t dataType;
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
} ;
} __attribute__((packed)) ;
struct pendingData {
struct AvailDataInfo availdatainfo;
uint16_t attemptsLeft;
uint8_t targetMac[8];
} ;
};
struct blockPart {
uint8_t checksum;
uint8_t blockId;
uint8_t blockPart;
uint8_t data[];
} ;
};
struct blockData {
uint16_t size;
uint16_t checksum;
uint8_t data[];
} ;
};
struct burstMacData {
uint16_t offset;
uint8_t targetMac[8];
} ;
};
#define BLOCK_PART_DATA_SIZE 99
#define BLOCK_MAX_PARTS 42
@@ -238,140 +236,131 @@ struct blockRequest {
struct blockRequestAck {
uint8_t checksum;
uint16_t pleaseWaitMs;
} ;
};
struct espBlockRequest {
uint8_t checksum;
uint64_t ver;
uint8_t blockId;
uint8_t src[8];
} ;
};
struct espXferComplete {
uint8_t checksum;
uint8_t src[8];
} ;
};
struct espAvailDataReq {
uint8_t checksum;
uint8_t src[8];
struct AvailDataReq adr;
} ;
};
struct espSetChannelPower {
uint8_t checksum;
uint8_t channel;
uint8_t power;
} ;
};
#pragma pack(0)
///////////////// NEW END
#ifndef __packed
#define __packed __attribute__((packed))
#define __packed __attribute__((packed))
#endif
struct TagState {
uint64_t swVer;
uint16_t hwType;
uint16_t batteryMv;
uint64_t swVer;
uint16_t hwType;
uint16_t batteryMv;
} __packed;
struct TagInfo {
uint8_t protoVer; //PROTO_VER_*
struct TagState state;
uint8_t rfu1[1]; //shall be ignored for now
uint16_t screenPixWidth;
uint16_t screenPixHeight;
uint16_t screenMmWidth;
uint16_t screenMmHeight;
uint16_t compressionsSupported; //COMPR_TYPE_* bitfield
uint16_t maxWaitMsec; //how long tag will wait for packets before going to sleep
uint8_t screenType; //enum TagScreenType
uint8_t rfu[11]; //shall be zero for now
uint8_t protoVer; // PROTO_VER_*
struct TagState state;
uint8_t rfu1[1]; // shall be ignored for now
uint16_t screenPixWidth;
uint16_t screenPixHeight;
uint16_t screenMmWidth;
uint16_t screenMmHeight;
uint16_t compressionsSupported; // COMPR_TYPE_* bitfield
uint16_t maxWaitMsec; // how long tag will wait for packets before going to sleep
uint8_t screenType; // enum TagScreenType
uint8_t rfu[11]; // shall be zero for now
} __packed;
struct AssocInfo {
uint32_t checkinDelay; //space between checkins, in msec
uint32_t retryDelay; //if download fails mid-way wait thi smany msec to retry (IFF progress was made)
uint16_t failedCheckinsTillBlank; //how many fails till we go blank
uint16_t failedCheckinsTillDissoc; //how many fails till we dissociate
uint32_t newKey[4];
uint8_t rfu[8]; //shall be zero for now
uint32_t checkinDelay; // space between checkins, in msec
uint32_t retryDelay; // if download fails mid-way wait thi smany msec to retry (IFF progress was made)
uint16_t failedCheckinsTillBlank; // how many fails till we go blank
uint16_t failedCheckinsTillDissoc; // how many fails till we dissociate
uint32_t newKey[4];
uint8_t rfu[8]; // shall be zero for now
} __packed;
#define CHECKIN_TEMP_OFFSET 0x7f
#define CHECKIN_TEMP_OFFSET 0x7f
struct CheckinInfo {
struct TagState state;
uint8_t lastPacketLQI; //zero if not reported/not supported to be reported
int8_t lastPacketRSSI; //zero if not reported/not supported to be reported
uint8_t temperature; //zero if not reported/not supported to be reported. else, this minus CHECKIN_TEMP_OFFSET is temp in degrees C
uint8_t rfu[6]; //shall be zero for now
struct TagState state;
uint8_t lastPacketLQI; // zero if not reported/not supported to be reported
int8_t lastPacketRSSI; // zero if not reported/not supported to be reported
uint8_t temperature; // zero if not reported/not supported to be reported. else, this minus CHECKIN_TEMP_OFFSET is temp in degrees C
uint8_t rfu[6]; // shall be zero for now
} __packed;
struct PendingInfo {
uint64_t imgUpdateVer;
uint32_t imgUpdateSize;
uint64_t osUpdateVer; //version of OS update avail
uint32_t osUpdateSize;
uint8_t rfu[8]; //shall be zero for now
uint64_t imgUpdateVer;
uint32_t imgUpdateSize;
uint64_t osUpdateVer; // version of OS update avail
uint32_t osUpdateSize;
uint8_t rfu[8]; // shall be zero for now
} __packed;
struct ChunkReqInfo {
uint64_t versionRequested;
uint32_t offset;
uint8_t len;
uint8_t osUpdatePlz : 1;
uint8_t rfu[6]; //shall be zero for now
uint64_t versionRequested;
uint32_t offset;
uint8_t len;
uint8_t osUpdatePlz : 1;
uint8_t rfu[6]; // shall be zero for now
} __packed;
struct ChunkInfo {
uint32_t offset;
uint8_t osUpdatePlz : 1;
uint8_t rfu; //shall be zero for now
uint8_t data[]; //no data means request is out of bounds of this version no longer exists
uint32_t offset;
uint8_t osUpdatePlz : 1;
uint8_t rfu; // shall be zero for now
uint8_t data[]; // no data means request is out of bounds of this version no longer exists
} __packed;
#define MACFMT "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x"
#define MACCVT(x) ((const uint8_t*)(x))[7], ((const uint8_t*)(x))[6], ((const uint8_t*)(x))[5], ((const uint8_t*)(x))[4], ((const uint8_t*)(x))[3], ((const uint8_t*)(x))[2], ((const uint8_t*)(x))[1], ((const uint8_t*)(x))[0]
#define VERSION_SIGNIFICANT_MASK (0x0000ffffffffffffull)
#define MACFMT "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x"
#define MACCVT(x) ((const uint8_t*)(x))[7], ((const uint8_t*)(x))[6], ((const uint8_t*)(x))[5], ((const uint8_t*)(x))[4], ((const uint8_t*)(x))[3], ((const uint8_t*)(x))[2], ((const uint8_t*)(x))[1], ((const uint8_t*)(x))[0]
#define HW_TYPE_42_INCH_SAMSUNG (1)
#define HW_TYPE_42_INCH_SAMSUNG_ROM_VER_OFST (0xEFF8)
#define HW_TYPE_74_INCH_DISPDATA (2)
#define HW_TYPE_74_INCH_DISPDATA_FRAME_MODE (3)
#define HW_TYPE_74_INCH_DISPDATA_ROM_VER_OFST (0x008b)
#define VERSION_SIGNIFICANT_MASK (0x0000ffffffffffffull)
#define HW_TYPE_ZBD_EPOP50 (4)
#define HW_TYPE_ZBD_EPOP50_ROM_VER_OFST (0x008b)
#define HW_TYPE_42_INCH_SAMSUNG (1)
#define HW_TYPE_42_INCH_SAMSUNG_ROM_VER_OFST (0xEFF8)
#define HW_TYPE_ZBD_EPOP900 (5)
#define HW_TYPE_ZBD_EPOP900_ROM_VER_OFST (0x008b)
#define HW_TYPE_74_INCH_DISPDATA (2)
#define HW_TYPE_74_INCH_DISPDATA_FRAME_MODE (3)
#define HW_TYPE_74_INCH_DISPDATA_ROM_VER_OFST (0x008b)
#define HW_TYPE_ZBD_EPOP50 (4)
#define HW_TYPE_ZBD_EPOP50_ROM_VER_OFST (0x008b)
#define HW_TYPE_ZBD_EPOP900 (5)
#define HW_TYPE_ZBD_EPOP900_ROM_VER_OFST (0x008b)
#define HW_TYPE_29_INCH_DISPDATA (6)
#define HW_TYPE_29_INCH_DISPDATA_FRAME_MODE (7)
#define HW_TYPE_29_INCH_DISPDATA_ROM_VER_OFST (0x008b)
#define HW_TYPE_29_INCH_ZBS_026 (8)
#define HW_TYPE_29_INCH_ZBS_026_FRAME_MODE (9)
#define HW_TYPE_29_INCH_ZBS_025 (10)
#define HW_TYPE_29_INCH_ZBS_025_FRAME_MODE (11)
#define HW_TYPE_29_INCH_ZBS_ROM_VER_OFST (0x008b)
#define HW_TYPE_74_INCH_BWR (40)
#define HW_TYPE_74_INCH_BWR_ROM_VER_OFST (0x0160)
#define HW_TYPE_58_INCH_BWR (41)
#define HW_TYPE_58_INCH_BWR_ROM_VER_OFST (0x0160)
#define HW_TYPE_42_INCH_BWR (42)
#define HW_TYPE_42_INCH_BWR_ROM_VER_OFST (0x0160)
#define HW_TYPE_29_INCH_DISPDATA (6)
#define HW_TYPE_29_INCH_DISPDATA_FRAME_MODE (7)
#define HW_TYPE_29_INCH_DISPDATA_ROM_VER_OFST (0x008b)
#define HW_TYPE_29_INCH_ZBS_026 (8)
#define HW_TYPE_29_INCH_ZBS_026_FRAME_MODE (9)
#define HW_TYPE_29_INCH_ZBS_025 (10)
#define HW_TYPE_29_INCH_ZBS_025_FRAME_MODE (11)
#define HW_TYPE_29_INCH_ZBS_ROM_VER_OFST (0x008b)
#define HW_TYPE_74_INCH_BWR (40)
#define HW_TYPE_74_INCH_BWR_ROM_VER_OFST (0x0160)
#define HW_TYPE_58_INCH_BWR (41)
#define HW_TYPE_58_INCH_BWR_ROM_VER_OFST (0x0160)
#define HW_TYPE_42_INCH_BWR (42)
#define HW_TYPE_42_INCH_BWR_ROM_VER_OFST (0x0160)
#endif

View File

@@ -3,143 +3,24 @@
#include "eeprom.h"
#include "util.h"
#include "mz100_flash.h"
#include "powermgt.h"
__attribute__((section(".aonshadow"))) struct tagsettings tagSettings = {0};
extern uint8_t blockXferBuffer[];
uint8_t* infopageTempBuffer = 1024 + blockXferBuffer;
#define EEPROM_NUM_SETTINGS_PAGES (EEPROM_SETTINGS_AREA_LEN / EEPROM_PAGE_SIZE)
#define SETTINGS_MAGIC (0x31415926)
static uint32_t mCurSettingsAddr;
static void settingsPrvDoWriteAtLocation(uint32_t addr, struct Settings* settings)
{
settings->hdr.revision++;
mCurSettingsAddr = addr;
FLASH_Write(false, addr, (uint8_t*)settings, sizeof(struct Settings));
}
//this is impossible to call before calling read. thus mCurSettingsAddr will be set
void settingsPrvDoWrite(struct Settings* settings)
{
struct SettingsHeader sh;
uint32_t i, addr;
uint8_t byte;
//first we try to fit in the current page, after current (latest) settings
if (mCurSettingsAddr) {
FLASH_Read(0, mCurSettingsAddr, (uint8_t*)&sh, sizeof(struct SettingsHeader));
addr = mCurSettingsAddr + sh.structSize;
//is there space?
if (addr % EEPROM_PAGE_SIZE != 0 && addr % EEPROM_PAGE_SIZE + sizeof(struct Settings) <= EEPROM_PAGE_SIZE) {
//is it erased
for (i = 0; i < sizeof(struct Settings); i++) {
FLASH_Read(0, addr, &byte, 1);
if (byte != 0xff)
break;
}
if (i == sizeof(struct Settings)) {
settingsPrvDoWriteAtLocation(addr, settings);
return;
}
}
}
//we need to erase - use next page (or 0th page if no current page at all)
if (mCurSettingsAddr) {
addr = (mCurSettingsAddr + EEPROM_PAGE_SIZE - 1) / EEPROM_PAGE_SIZE * EEPROM_PAGE_SIZE;
if (addr == EEPROM_SETTINGS_AREA_START + EEPROM_SETTINGS_AREA_LEN)
addr = EEPROM_SETTINGS_AREA_START;
}
else
addr = EEPROM_SETTINGS_AREA_START;
qspiEraseRange(addr, EEPROM_PAGE_SIZE);
settingsPrvDoWriteAtLocation(addr, settings);
}
void settingsRead(struct Settings* settings)
{
uint32_t bestAddr = 0, page, ofst;
uint64_t bestRevision = 0;
struct SettingsHeader sh;
bool doWrite = true;
for (page = 0; page < EEPROM_NUM_SETTINGS_PAGES; page++) {
for (ofst = 0; ofst < EEPROM_PAGE_SIZE - sizeof(struct SettingsHeader); ofst += sh.structSize) {
uint32_t addr = EEPROM_SETTINGS_AREA_START + page * EEPROM_PAGE_SIZE + ofst;
FLASH_Read(0, addr, (uint8_t*)&sh, sizeof(struct SettingsHeader));
//sanity checks. struct is only allowed to grow in size...
if (sh.magic != SETTINGS_MAGIC || ofst + sh.structSize > EEPROM_PAGE_SIZE || sh.structSize > sizeof(struct Settings))
break;
if (sh.revision > bestRevision) {
bestRevision = sh.revision;
bestAddr = addr;
}
}
}
if (bestAddr) {
FLASH_Read(0, bestAddr, (uint8_t*)&sh, sizeof(struct SettingsHeader)); //to get size
FLASH_Read(0, bestAddr, (uint8_t*)settings, sh.structSize);
mCurSettingsAddr = bestAddr;
}
else {
settings->hdr.structVersion = SETTINGS_VER_NONE;
settings->hdr.revision = 1;
mCurSettingsAddr = 0;
}
//migrate
switch (settings->hdr.structVersion) {
//current version here - mark as such
case SETTINGS_CURRENT:
doWrite = false;
break;
case SETTINGS_VER_NONE: //migrate to v1
memset(settings, 0, sizeof(*settings));
settings->hdr.magic = SETTINGS_MAGIC;
//fallthrough
case SETTINGS_VER_1: //migrate to v2
settings->prevDlProgress = 0xffff;
//fallthrough
case SETTINGS_VER_2: //migrate to v3
settings->lastRxedRSSI = 0;
//fallthrough
//new migrations here in order from lower vers to higher vers
settings->hdr.structVersion = SETTINGS_CURRENT;
settings->hdr.structSize = sizeof(struct Settings);
break;
}
if (doWrite)
settingsPrvDoWrite(settings);
}
void settingsWrite(struct Settings* settings)
{
struct Settings s;
settingsRead(&s);
if (memcmp(&s, settings, sizeof(struct Settings)))
settingsPrvDoWrite(settings);
void loadDefaultSettings() {
tagSettings.settingsVer = SETTINGS_STRUCT_VERSION;
tagSettings.enableFastBoot = DEFAULT_SETTING_FASTBOOT;
tagSettings.enableRFWake = DEFAULT_SETTING_RFWAKE;
tagSettings.enableTagRoaming = DEFAULT_SETTING_TAGROAMING;
tagSettings.enableScanForAPAfterTimeout = DEFAULT_SETTING_SCANFORAP;
tagSettings.enableLowBatSymbol = DEFAULT_SETTING_LOWBATSYMBOL;
tagSettings.enableNoRFSymbol = DEFAULT_SETTING_NORFSYMBOL;
tagSettings.customMode = 0;
tagSettings.fastBootCapabilities = 0;
tagSettings.minimumCheckInTime = INTERVAL_BASE;
tagSettings.fixedChannel = 0;
tagSettings.batLowVoltage = BATTERY_VOLTAGE_MINIMUM;
}

View File

@@ -1,65 +1,41 @@
#ifndef _SETTINGS_H_
#define _SETTINGS_H_
#ifndef SETTINGS_H
#define SETTINGS_H
#include <stdint.h>
#define SETTINGS_VER_NONE (0x00000000)
#define SETTINGS_VER_1 (0x00000001)
#define SETTINGS_VER_2 (0x00000002)
#define SETTINGS_VER_3 (0x00000003)
#define FW_VERSION 20 // version number (max 2.5.5 :) )
#define FW_VERSION_SUFFIX "-75" // 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
struct SettingsHeader {
uint32_t magic;
uint64_t revision;
uint8_t structVersion;
uint8_t structSize; //incl this header
#define SETTINGS_STRUCT_VERSION 0x01
#define DEFAULT_SETTING_FASTBOOT 0
#define DEFAULT_SETTING_RFWAKE 0
#define DEFAULT_SETTING_TAGROAMING 0
#define DEFAULT_SETTING_SCANFORAP 1
#define DEFAULT_SETTING_LOWBATSYMBOL 1
#define DEFAULT_SETTING_NORFSYMBOL 1
struct tagsettings {
uint8_t settingsVer; // the version of the struct as written to the infopage
uint8_t enableFastBoot; // default 0; if set, it will skip splashscreen
uint8_t enableRFWake; // default 0; if set, it will enable RF wake. This will add about ~0.9µA idle power consumption
uint8_t enableTagRoaming; // default 0; if set, the tag will scan for an accesspoint every few check-ins. This will increase power consumption quite a bit
uint8_t enableScanForAPAfterTimeout; // default 1; if a the tag failed to check in, after a few attempts it will try to find a an AP on other channels
uint8_t enableLowBatSymbol; // default 1; tag will show 'low battery' icon on screen if the battery is depleted
uint8_t enableNoRFSymbol; // default 1; tag will show 'no signal' icon on screen if it failed to check in for a longer period of time
uint8_t fastBootCapabilities; // holds the byte with 'capabilities' as detected during a normal tag boot; allows the tag to skip detecting buttons and NFC chip
uint8_t customMode; // default 0; if anything else, tag will bootup in a different 'mode'
uint16_t batLowVoltage; // Low battery threshold voltage (2450 for 2.45v). defaults to BATTERY_VOLTAGE_MINIMUM from powermgt.h
uint16_t minimumCheckInTime; // defaults to BASE_INTERVAL from powermgt.h
uint8_t fixedChannel; // default 0; if set to a valid channel number, the tag will stick to that channel
} __attribute__((packed));
enum SettingsThingType {
SettingsThingTypeNone,
SettingsThingTypeImage,
SettingsThingTypeUpdate,
};
extern __attribute__((section(".aonshadow")))struct tagsettings tagSettings;
#define SETTING_CHANNEL_OFFSET 11
struct Settings { //V1
struct SettingsHeader hdr;
//master address
uint8_t masterMac[8];
//encryption things
uint32_t encrKey[4];
uint32_t nextIV;
//checkin tracking
uint32_t checkinDelay; //space between checkins, in msec
uint32_t retryDelay;
uint16_t failedCheckinsTillBlank; //how many fails till we go blank
uint16_t failedCheckinsTillDissoc; //how many fails till we dissociate
uint16_t numFailedCheckins;
//state
uint8_t lastRxedLQI;
uint8_t isPaired : 1;
uint8_t channel : 4; //minus SETTING_CHANNEL_OFFSET
uint8_t reserved : 3;
uint16_t prevDlProgress;
int8_t lastRxedRSSI;
uint32_t helperInit;
} __attribute__((packed));
#define SETTINGS_CURRENT SETTINGS_VER_3
void settingsRead(struct Settings* settings);
void settingsWrite(struct Settings* settings);
#endif
void loadDefaultSettings();
void writeSettings();
void loadSettings();
void loadSettingsFromBuffer(uint8_t* p);
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -1,14 +1,19 @@
#pragma once
#include <stdint.h>
#include <stdbool.h>
#include <stdint.h>
#include "settings.h"
extern uint8_t mSelfMac[];
extern uint8_t currentChannel;
extern __attribute__((section(".aonshadow"))) uint8_t mSelfMac[];
extern __attribute__((section(".aonshadow"))) volatile uint8_t currentChannel;
extern __attribute__((section(".aonshadow"))) struct blockRequest curBlock; // used by the block-requester, contains the next request that we'll send
extern __attribute__((section(".aonshadow"))) struct AvailDataInfo curDataInfo; // last 'AvailDataInfo' we received from the AP // __attribute__((section(".aon")))
extern uint8_t APmac[];
extern uint8_t curImgSlot;
extern __attribute__((section(".aonshadow"))) uint8_t curImgSlot;
extern void setupRadio(void);
extern void killRadio(void);

View File

@@ -0,0 +1,181 @@
#include "userinterface.h"
#include <stdbool.h>
#include <string.h>
#include "bitmaps.h"
#include "board.h"
#include "comms.h"
#include "epd.h"
#include "font.h"
#include "powermgt.h"
#include "printf.h"
#include "proto.h"
#include "screen.h"
#include "settings.h"
#include "syncedproto.h" // for APmac / Channel
#include "timer.h"
const uint16_t fwVersion = FW_VERSION;
const char fwVersionSuffix[] = FW_VERSION_SUFFIX;
extern uint8_t capabilities;
bool __attribute__((section(".aonshadow"))) lowBatteryShown = false;
bool __attribute__((section(".aonshadow"))) noAPShown = false;
void addCapabilities() {
// if (capabilities) epdpr("Options: ");
if (capabilities & CAPABILITY_HAS_NFC) {
// epdpr("-NFC");
if (capabilities & CAPABILITY_NFC_WAKE) {
// epdpr("+WAKE");
} else {
// epdpr(" ");
}
}
if (capabilities & CAPABILITY_HAS_WAKE_BUTTON) {
// epdpr("-WAKE BUTTON");
}
}
void addOverlay() {
if ((currentChannel == 0) && (tagSettings.enableNoRFSymbol)) {
// loadRawBitmap(ant, SCREEN_WIDTH - 24, 6, EPD_COLOR_BLACK);
// loadRawBitmap(cross, SCREEN_WIDTH - 16, 13, EPD_COLOR_RED);
noAPShown = true;
} else {
noAPShown = false;
}
if ((batteryVoltage < tagSettings.batLowVoltage) && (tagSettings.enableLowBatSymbol)) {
// loadRawBitmap(battery, SCREEN_WIDTH - 16, SCREEN_HEIGHT - 10, EPD_COLOR_BLACK);
lowBatteryShown = true;
} else {
lowBatteryShown = false;
}
}
void afterFlashScreenSaver() {
// selectLUT(EPD_LUT_DEFAULT);
// clearScreen();
#if (SCREEN_WIDTH == 400) // 4.2"
epdPrintBegin(3, 3, EPD_DIRECTION_X, EPD_SIZE_DOUBLE, EPD_COLOR_BLACK);
epdpr("OpenEPaperLink");
epdPrintEnd();
#endif
// drawWithSleep();
}
void showSplashScreen() {
// selectLUT(EPD_LUT_NO_REPEATS);
// clearScreen();
#if (SCREEN_WIDTH == 400) // 4.2"
epdPrintBegin(3, 3, EPD_DIRECTION_X, EPD_SIZE_DOUBLE, EPD_COLOR_BLACK);
epdpr("Starting");
epdPrintEnd();
epdPrintBegin(2, 252, EPD_DIRECTION_X, EPD_SIZE_SINGLE, EPD_COLOR_BLACK);
addCapabilities();
epdPrintEnd();
epdPrintBegin(3, 268, EPD_DIRECTION_X, EPD_SIZE_SINGLE, EPD_COLOR_BLACK);
epdpr("zbs42v033 %d.%d.%d%s", fwVersion / 100, (fwVersion % 100) / 10, (fwVersion % 10), fwVersionSuffix);
epdPrintEnd();
epdPrintBegin(3, 284, EPD_DIRECTION_X, EPD_SIZE_SINGLE, EPD_COLOR_RED);
epdpr("MAC: %02X:%02X", mSelfMac[7], mSelfMac[6]);
epdpr(":%02X:%02X", mSelfMac[5], mSelfMac[4]);
epdpr(":%02X:%02X", mSelfMac[3], mSelfMac[2]);
epdpr(":%02X:%02X", mSelfMac[1], mSelfMac[0]);
epdPrintEnd();
loadRawBitmap(oepli, 136, 22, EPD_COLOR_BLACK);
loadRawBitmap(cloud, 136, 10, EPD_COLOR_RED);
uint8_t __xdata buffer[17];
spr(buffer, "%02X%02X", mSelfMac[7], mSelfMac[6]);
spr(buffer + 4, "%02X%02X", mSelfMac[5], mSelfMac[4]);
spr(buffer + 8, "%02X%02X", mSelfMac[3], mSelfMac[2]);
spr(buffer + 12, "%02X%02X", mSelfMac[1], mSelfMac[0]);
printBarcode(buffer, 392, 264);
printBarcode(buffer, 384, 264);
#endif
// drawWithSleep();
}
void showApplyUpdate() {
// selectLUT(1);
// clearScreen();
#if (SCREEN_WIDTH == 400)
epdPrintBegin(136, 134, EPD_DIRECTION_X, EPD_SIZE_DOUBLE, EPD_COLOR_BLACK);
#endif
// epdpr("Updating!");
// epdPrintEnd();
// drawNoWait();
}
void showAPFound() {
init_epd();
fillWindow(0, 0, 640, 384, 1);
epdPrintf(10, 10, 1, "OpenEPaperLink");
epdPrintf(10, 40, 1, "AP Found at channel %d", currentChannel);
epdPrintf(10, 60, 1, "AP MAC: %02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X", APmac[7], APmac[6], APmac[5], APmac[4], APmac[3], APmac[2], APmac[1], APmac[0]);
epdPrintf(10, 330, 1, "Battery: %d.%dV", batteryVoltage / 1000, batteryVoltage % 1000);
epdPrintf(10, 350, 1, "Tag MAC: %02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X", mSelfMac[7], mSelfMac[6], mSelfMac[5], mSelfMac[4], mSelfMac[3], mSelfMac[2], mSelfMac[1], mSelfMac[0]);
epd_refresh_and_sleep();
}
void showNoAP() {
init_epd();
fillWindow(0, 0, 640, 384, 1);
epdPrintf(10, 10, 1, "OpenEPaperLink ");
epdPrintf(10, 40, 1, "No AP found... We'll try again in a little while though!");
epdPrintf(10, 350, 1, "Tag MAC: %02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X", mSelfMac[7], mSelfMac[6], mSelfMac[5], mSelfMac[4], mSelfMac[3], mSelfMac[2], mSelfMac[1], mSelfMac[0]);
epd_refresh_and_sleep();
}
void showLongTermSleep() {
// selectLUT(EPD_LUT_NO_REPEATS);
// clearScreen();
// epdPrintBegin(2, SCREEN_HEIGHT - 16, EPD_DIRECTION_X, EPD_SIZE_SINGLE, EPD_COLOR_BLACK);
// epdpr("zZ");
// epdPrintEnd();
addOverlay();
// drawWithSleep();
}
void showNoEEPROM() {
// selectLUT(EPD_LUT_NO_REPEATS);
// clearScreen();
#if (SCREEN_WIDTH == 400) // 4.2"
epdPrintBegin(50, 3, EPD_DIRECTION_X, EPD_SIZE_DOUBLE, EPD_COLOR_BLACK);
epdpr("EEPROM FAILED :(");
epdPrintEnd();
loadRawBitmap(failed, 176, 126, EPD_COLOR_RED);
epdPrintBegin(100, 284, EPD_DIRECTION_X, EPD_SIZE_SINGLE, EPD_COLOR_BLACK);
epdpr("Sleeping forever :'(");
epdPrintEnd();
#endif
// drawWithSleep();
}
void showNoMAC() {
// selectLUT(EPD_LUT_NO_REPEATS);
// clearScreen();
#if (SCREEN_WIDTH == 400) // 4.2"
epdPrintBegin(100, 3, EPD_DIRECTION_X, EPD_SIZE_DOUBLE, EPD_COLOR_BLACK);
epdpr("NO MAC SET :(");
epdPrintEnd();
loadRawBitmap(failed, 176, 126, EPD_COLOR_RED);
epdPrintBegin(100, 284, EPD_DIRECTION_X, EPD_SIZE_SINGLE, EPD_COLOR_BLACK);
epdpr("Sleeping forever :'(");
epdPrintEnd();
#endif
// drawWithSleep();
}

View File

@@ -0,0 +1,22 @@
#ifndef _UI_H_
#define _UI_H_
#include <stdint.h>
#include <stdbool.h>
void addOverlay();
void afterFlashScreenSaver();
void showSplashScreen();
void showApplyUpdate();
void showAPFound();
void showNoAP();
void showLongTermSleep();
void showNoEEPROM();
void showNoMAC();
extern const uint16_t fwVersion;
extern const char fwVersionSuffix[];
extern __attribute__((section(".aon"))) bool lowBatteryShown;
extern __attribute__((section(".aon"))) bool noAPShown;
#endif

View File

@@ -1,213 +1,185 @@
#include <stdarg.h>
#include <stdio.h>
#include "eeprom.h"
#include "timer.h"
#include "mz100.h"
#include "util.h"
#include "mz100_flash.h"
#include <stdarg.h>
//#include <stdio.h>
#include "printf.h"
#include "eeprom.h"
#include "mz100.h"
#include "mz100_adc.h"
#include "mz100_flash.h"
#include "mz100_wdt.h"
#include "timer.h"
void wdt10s()
{
void wdt10s() {
WDT_RestartCounter();
}
void wdt30s()
{
void wdt30s() {
WDT_RestartCounter();
}
void wdt60s()
{
void wdt60s() {
WDT_RestartCounter();
}
void delay(int cnt)
{
volatile unsigned int i;
for (i = 107 * cnt; i; --i)
;
void delay(int cnt) {
volatile unsigned int i;
for (i = 107 * cnt; i; --i)
;
}
void delay_us(unsigned int result)
{
volatile unsigned int i;
void delay_us(unsigned int result) {
volatile unsigned int i;
for (i = 0; i < result; ++i)
;
for (i = 0; i < result; ++i)
;
}
uint16_t crc16(uint16_t cur_crc, uint8_t data)
{
cur_crc ^= data;
for (uint8_t i = 8; i > 0; i--)
{
if ((cur_crc & 0x001) != 0)
{
cur_crc >>= 1;
cur_crc ^= 0x8005; // poly
}
else
{
cur_crc >>= 1;
}
}
return cur_crc;
uint16_t crc16(uint16_t cur_crc, uint8_t data) {
cur_crc ^= data;
for (uint8_t i = 8; i > 0; i--) {
if ((cur_crc & 0x001) != 0) {
cur_crc >>= 1;
cur_crc ^= 0x8005; // poly
} else {
cur_crc >>= 1;
}
}
return cur_crc;
}
uint32_t measureTemp(void)
{
uint32_t result = 0;
ADC_CFG_Type adc_config;
adc_config.adcResolution = ADC_RESOLUTION_14BIT;
adc_config.adcVrefSource = ADC_VREF_INTERNAL; // 1.2V
adc_config.adcGainSel = ADC_GAIN_1;
adc_config.adcClockDivider = ADC_CLOCK_DIVIDER_4;
adc_config.adcBiasMode = ADC_BIAS_FULL;
uint32_t measureTemp(void) {
uint32_t result = 0;
ADC_CFG_Type adc_config;
adc_config.adcResolution = ADC_RESOLUTION_14BIT;
adc_config.adcVrefSource = ADC_VREF_INTERNAL; // 1.2V
adc_config.adcGainSel = ADC_GAIN_1;
adc_config.adcClockDivider = ADC_CLOCK_DIVIDER_4;
adc_config.adcBiasMode = ADC_BIAS_FULL;
ADC_Reset();
ADC_ModeSelect(ADC_MODE_TSENSOR);
ADC_TSensorConfig(ADC_TEMPP, ADC_SENSOR_INTERNAL);
ADC_Init(&adc_config);
ADC_Enable();
for (int i = 0; i < 32; i++)
{
ADC_ConversionStart();
ADC_IntClr(ADC_RDY);
while (!ADC_GetStatus(ADC_STATUS_RDY))
;
ADC_ConversionStop();
}
for (int i = 0; i < 128; i++)
{
ADC_ConversionStart();
ADC_IntClr(ADC_RDY);
while (!ADC_GetStatus(ADC_STATUS_RDY))
;
ADC_ConversionStop();
result += (ADC_GetConversionResult() - 458) / 1.7;
}
result /= 128;
printf("Temp: %iC\r\n", result);
return result;
ADC_Reset();
ADC_ModeSelect(ADC_MODE_TSENSOR);
ADC_TSensorConfig(ADC_TEMPP, ADC_SENSOR_INTERNAL);
ADC_Init(&adc_config);
ADC_Enable();
for (int i = 0; i < 32; i++) {
ADC_ConversionStart();
ADC_IntClr(ADC_RDY);
while (!ADC_GetStatus(ADC_STATUS_RDY))
;
ADC_ConversionStop();
}
for (int i = 0; i < 128; i++) {
ADC_ConversionStart();
ADC_IntClr(ADC_RDY);
while (!ADC_GetStatus(ADC_STATUS_RDY))
;
ADC_ConversionStop();
result += (ADC_GetConversionResult() - 458) / 1.7;
}
result /= 128;
printf("Temp: %iC\r\n", result);
return result;
}
uint32_t measureBattery(void)
{
uint32_t result = 0;
ADC_CFG_Type adc_config;
adc_config.adcResolution = ADC_RESOLUTION_16BIT;
adc_config.adcVrefSource = ADC_VREF_VCAU; // 1.8V
adc_config.adcGainSel = ADC_GAIN_1; // range 0 - 1.8V
adc_config.adcClockDivider = ADC_CLOCK_DIVIDER_4;
adc_config.adcBiasMode = ADC_BIAS_FULL;
uint32_t measureBattery(void) {
uint32_t result = 0;
ADC_CFG_Type adc_config;
adc_config.adcResolution = ADC_RESOLUTION_16BIT;
adc_config.adcVrefSource = ADC_VREF_VCAU; // 1.8V
adc_config.adcGainSel = ADC_GAIN_1; // range 0 - 1.8V
adc_config.adcClockDivider = ADC_CLOCK_DIVIDER_4;
adc_config.adcBiasMode = ADC_BIAS_FULL;
ADC_Reset();
ADC_ModeSelect(ADC_MODE_ADC);
ADC_ChannelConfig(ADC_VBATS); // 0.33 of Actual Voltage
ADC_Init(&adc_config);
ADC_Enable();
ADC_ConversionStart();
ADC_IntClr(ADC_RDY);
for (int i = 0; i < 32; i++)
{
ADC_ConversionStart();
ADC_IntClr(ADC_RDY);
while (!ADC_GetStatus(ADC_STATUS_RDY))
;
ADC_ConversionStop();
}
for (int i = 0; i < 128; i++)
{
ADC_ConversionStart();
ADC_IntClr(ADC_RDY);
while (!ADC_GetStatus(ADC_STATUS_RDY))
;
ADC_ConversionStop();
result += ADC_GetConversionResult() * 5940 / 32768;
}
result /= 128;
printf("Voltage: %imV\r\n", result);
return result;
ADC_Reset();
ADC_ModeSelect(ADC_MODE_ADC);
ADC_ChannelConfig(ADC_VBATS); // 0.33 of Actual Voltage
ADC_Init(&adc_config);
ADC_Enable();
ADC_ConversionStart();
ADC_IntClr(ADC_RDY);
for (int i = 0; i < 32; i++) {
ADC_ConversionStart();
ADC_IntClr(ADC_RDY);
while (!ADC_GetStatus(ADC_STATUS_RDY))
;
ADC_ConversionStop();
}
for (int i = 0; i < 128; i++) {
ADC_ConversionStart();
ADC_IntClr(ADC_RDY);
while (!ADC_GetStatus(ADC_STATUS_RDY))
;
ADC_ConversionStop();
result += ADC_GetConversionResult() * 5940 / 32768;
}
result /= 128;
printf("Voltage: %imV\r\n", result);
return result;
}
void qspiEraseRange(uint32_t addr, uint32_t len)
{
uint64_t time;
// round starting address down
if (addr % EEPROM_PAGE_SIZE)
{
len += addr % EEPROM_PAGE_SIZE;
addr = addr / EEPROM_PAGE_SIZE * EEPROM_PAGE_SIZE;
}
void qspiEraseRange(uint32_t addr, uint32_t len) {
uint64_t time;
// round starting address down
if (addr % EEPROM_PAGE_SIZE) {
len += addr % EEPROM_PAGE_SIZE;
addr = addr / EEPROM_PAGE_SIZE * EEPROM_PAGE_SIZE;
}
// round length up
len = (len + EEPROM_PAGE_SIZE - 1) / EEPROM_PAGE_SIZE * EEPROM_PAGE_SIZE;
// round length up
len = (len + EEPROM_PAGE_SIZE - 1) / EEPROM_PAGE_SIZE * EEPROM_PAGE_SIZE;
while (len)
{
while (len) {
uint32_t now;
bool ok;
uint32_t now;
bool ok;
WDT_RestartCounter();
if (!(addr % 0x10000) && len >= 0x10000) {
ok = FLASH_Block64KErase(addr / 0x10000);
now = 0x10000;
} else if (!(addr % 0x8000) && len >= 0x8000) {
ok = FLASH_Block32KErase(addr / 0x8000);
now = 0x8000;
} else {
ok = FLASH_SectorErase(addr / 0x1000);
now = 0x1000;
}
WDT_RestartCounter();
if (!(addr % 0x10000) && len >= 0x10000)
{
ok = FLASH_Block64KErase(addr / 0x10000);
now = 0x10000;
}
else if (!(addr % 0x8000) && len >= 0x8000)
{
ok = FLASH_Block32KErase(addr / 0x8000);
now = 0x8000;
}
else
{
ok = FLASH_SectorErase(addr / 0x1000);
now = 0x1000;
}
if (!ok)
printf("ERZ fail at 0x%08x + %u\r\n", addr, now);
if (!ok)
printf("ERZ fail at 0x%08x + %u\r\n", addr, now);
addr += now;
len -= now;
if (len)
{
// let the caps recharge
time = timerGet();
while (timerGet() - time < TIMER_TICKS_PER_SEC / 10)
;
}
}
WDT_RestartCounter();
addr += now;
len -= now;
if (len) {
// let the caps recharge
time = timerGet();
while (timerGet() - time < TIMER_TICKS_PER_SEC / 10)
;
}
}
WDT_RestartCounter();
}
bool eepromWrite(uint32_t addr, const void *srcP, uint16_t len)
{
FLASH_Write(false, addr, srcP, len);
return true;
bool eepromWrite(uint32_t addr, const void *srcP, uint16_t len) {
FLASH_Write(false, addr, (void*)srcP, len);
return true;
}
bool eepromErase(uint32_t addr, uint16_t nSec)
{
qspiEraseRange(addr, nSec);
return true;
bool eepromErase(uint32_t addr, uint16_t nSec) {
qspiEraseRange(addr, nSec);
return true;
}
void eepromRead(uint32_t addr, void *dstP, uint16_t len)
{
uint8_t *dst = (uint8_t *)dstP;
FLASH_Read(0, addr, dst, len);
void eepromRead(uint32_t addr, void *dstP, uint16_t len) {
uint8_t *dst = (uint8_t *)dstP;
FLASH_Read(0, addr, dst, len);
}
uint32_t eepromGetSize(void)
{
return EEPROM_IMG_LEN;
uint32_t eepromGetSize(void) {
return EEPROM_IMG_LEN;
}
void radioShutdown(void)
{
// i have no idea what these do, determined by writing random registers and watching the current drawn
*(volatile uint32_t *)0x4C000000 = 0;
*(volatile uint32_t *)0x4C010000 = 0;
*(volatile uint32_t *)0x4C010004 = 0x10000000;
void radioShutdown(void) {
// i have no idea what these do, determined by writing random registers and watching the current drawn
*(volatile uint32_t *)0x4C000000 = 0;
*(volatile uint32_t *)0x4C010000 = 0;
*(volatile uint32_t *)0x4C010004 = 0x10000000;
}

View File

@@ -1,7 +1,8 @@
#include <stdio.h>
//#include <stdio.h>
#include <stdint.h>
#include "util.h"
#include "zigbee.h"
#include "printf.h"
volatile uint8_t calibration_irq_ocoured = 0;
volatile uint8_t zigbee_tx_done = 0;
@@ -145,24 +146,29 @@ void fill_rx_regs()
;
}
void sub_1021E6()
void load_calib()
{
int v0;
unsigned int v1;
unsigned int i;
v0 = (*(volatile unsigned int *)0x4C01000C);
v1 = get_register(0x130004);
v1 = zigbeeCalibData.len;
(*(volatile unsigned int *)0x4C010000) |= 4u;
while (((*(volatile unsigned int *)0x4C010008) & 0x1000000) == 0)
;
for (i = 0; i < v1; ++i)
set_register(v0 + 4 * i + 0x4C014000, *(uint32_t *)(4 * i + 0x130008));
set_register(v0 + 4 * i + 0x4C014000, zigbeeCalibData.data[i]);
(*(volatile unsigned int *)0x4C010000) &= ~4u;
while (((*(volatile unsigned int *)0x4C010008) & 0x1000000) != 0)
;
}
// It is from 0x130000 up to 0x1301000 But you can only use 0x130404 up to the 0x1301000
void save_calib_in_ram()
{
int v0;
@@ -171,14 +177,14 @@ void save_calib_in_ram()
v0 = (*(volatile unsigned int *)0x4C01000C) + 0x4C014000;
v1 = ((unsigned int)(uint8_t)((*(volatile unsigned int *)0x4C010008) >> 2) + 3) >> 2;
set_register(0x130000u, 0x464C4147);
set_register(0x130004u, v1);
zigbeeCalibData.isValid = true;
(*(volatile unsigned int *)0x4C01001C) = -5;
(*(volatile unsigned int *)0x4C010000) |= 2u;
while (((*(volatile unsigned int *)0x4C010008) & 0x1000000) == 0)
;
for (i = 0; i < v1; ++i)
set_register(4 * i + 0x130008, *(uint32_t *)(v0 + 4 * i));
for (i = 0; i < v1; ++i){
zigbeeCalibData.data[i] = *(uint32_t *)(v0 + 4 * i);
}
(*(volatile unsigned int *)0x4C010000) &= ~2u;
while (((*(volatile unsigned int *)0x4C010008) & 0x1000000) != 0)
;
@@ -189,12 +195,12 @@ int inner_calibration()
int is_in_ram;
(*(volatile unsigned int *)0x4C010000) |= 0x20u;
if (get_register(0x130000) == 0x464C4147)
if(zigbeeCalibData.isValid)
{
is_in_ram = 1;
(*(volatile unsigned int *)0x4C010000) |= 8u;
(*(volatile unsigned int *)0x4C010000) &= ~0x10u;
sub_1021E6();
load_calib();
}
else
{

View File

@@ -1,4 +1,5 @@
#pragma once
#include <stdlib.h>
extern uint8_t channelList[6];
@@ -10,4 +11,11 @@ uint8_t Zigbee_tx_buffer(uint8_t *tx_buffer, int len);
void radioInit();
void radioSetChannel(uint8_t channel);
void radioRxEnable(uint8_t channel);
void radioRxFlush();
void radioRxFlush();
struct zigbeeCalibDataStruct {
uint16_t len;
bool isValid;
uint32_t data[30];
};
extern __attribute__((section(".aon"))) volatile struct zigbeeCalibDataStruct zigbeeCalibData;