Use clang to make codestyle consistent
This commit is contained in:
parent
239415c7aa
commit
4aab02a040
31 changed files with 10588 additions and 10871 deletions
|
@ -1,482 +1,484 @@
|
|||
#include <Adafruit_GFX.h>
|
||||
#include <Arduino.h>
|
||||
|
||||
const uint8_t Antonio_SemiBold20pt7bBitmaps[] PROGMEM = {
|
||||
0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x66, 0x66, 0x66,
|
||||
0x66, 0x66, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xEF, 0x7B, 0xDE, 0xF7,
|
||||
0x98, 0xC6, 0x00, 0x03, 0x8F, 0x01, 0xC7, 0x80, 0xE3, 0x80, 0xF1, 0xC0,
|
||||
0x70, 0xE0, 0x38, 0x70, 0x1C, 0x78, 0x0E, 0x3C, 0x07, 0x1C, 0x07, 0x8E,
|
||||
0x03, 0x87, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x38, 0xE0, 0x3C,
|
||||
0x70, 0x1E, 0x38, 0x0E, 0x1C, 0x07, 0x0E, 0x03, 0x8F, 0x0F, 0xFF, 0xF7,
|
||||
0xFF, 0xF8, 0xF1, 0xC0, 0x70, 0xE0, 0x38, 0x70, 0x1C, 0x78, 0x0E, 0x3C,
|
||||
0x0F, 0x1C, 0x07, 0x8E, 0x03, 0x87, 0x01, 0xC3, 0x80, 0xE3, 0xC0, 0x71,
|
||||
0xE0, 0x78, 0xE0, 0x00, 0x06, 0x00, 0x30, 0x01, 0x80, 0x0C, 0x00, 0x60,
|
||||
0x1F, 0xC1, 0xFF, 0x9F, 0xFC, 0xFB, 0xF7, 0x87, 0xBC, 0x3D, 0xE1, 0xEF,
|
||||
0x0F, 0x78, 0x7B, 0xE3, 0xDF, 0x00, 0x7C, 0x01, 0xF8, 0x0F, 0xE0, 0x3F,
|
||||
0x80, 0x7C, 0x01, 0xF0, 0x07, 0xC0, 0x3E, 0xF0, 0xF7, 0x87, 0xFC, 0x3F,
|
||||
0xE1, 0xFF, 0x0F, 0xFC, 0x7B, 0xFF, 0xCF, 0xFE, 0x3F, 0xE0, 0xFE, 0x01,
|
||||
0xC0, 0x0E, 0x00, 0x70, 0x03, 0x80, 0x1C, 0x00, 0x1F, 0x80, 0x01, 0xC0,
|
||||
0x07, 0xFE, 0x00, 0x3C, 0x00, 0x7F, 0xE0, 0x03, 0xC0, 0x0F, 0x9F, 0x00,
|
||||
0x38, 0x00, 0xF0, 0xF0, 0x07, 0x80, 0x0F, 0x0F, 0x00, 0x70, 0x00, 0xF0,
|
||||
0xF0, 0x0F, 0x00, 0x0F, 0x0F, 0x00, 0xF0, 0x00, 0xF0, 0xF0, 0x0E, 0x00,
|
||||
0x0F, 0x0F, 0x01, 0xE0, 0x00, 0xF0, 0xF0, 0x1C, 0x00, 0x0F, 0x0F, 0x03,
|
||||
0xC0, 0x60, 0xF0, 0xF0, 0x3C, 0x3F, 0xCF, 0x0F, 0x03, 0x87, 0xFE, 0xF0,
|
||||
0xF0, 0x78, 0xFF, 0xEF, 0x0F, 0x07, 0x8F, 0x0E, 0xF0, 0xF0, 0xF0, 0xF0,
|
||||
0xFF, 0x0F, 0x0F, 0x0E, 0x0F, 0xF0, 0xF0, 0xE0, 0xE0, 0xF7, 0xDF, 0x1E,
|
||||
0x0E, 0x0F, 0x7F, 0xE1, 0xE0, 0xE0, 0xF3, 0xFC, 0x1C, 0x0E, 0x0F, 0x1F,
|
||||
0x83, 0xC0, 0xE0, 0xF0, 0x00, 0x38, 0x0E, 0x0F, 0x00, 0x07, 0x80, 0xE0,
|
||||
0xF0, 0x00, 0x78, 0x0E, 0x0F, 0x00, 0x07, 0x00, 0xE0, 0xF0, 0x00, 0xF0,
|
||||
0x0E, 0x0F, 0x00, 0x0E, 0x00, 0xE0, 0xF0, 0x01, 0xE0, 0x0F, 0x0F, 0x00,
|
||||
0x1E, 0x00, 0xF1, 0xE0, 0x01, 0xC0, 0x0F, 0xFE, 0x00, 0x3C, 0x00, 0x7F,
|
||||
0xC0, 0x03, 0x80, 0x03, 0xF8, 0x03, 0xE0, 0x03, 0xFE, 0x00, 0xFF, 0x80,
|
||||
0x7C, 0xF0, 0x1E, 0x1C, 0x07, 0x87, 0x01, 0xE1, 0xC0, 0x78, 0x70, 0x1E,
|
||||
0x1C, 0x07, 0x8F, 0x00, 0xF3, 0x80, 0x3D, 0xE0, 0x0F, 0x78, 0x01, 0xFC,
|
||||
0x00, 0x7E, 0x00, 0x1F, 0x80, 0x07, 0xC0, 0x03, 0xF0, 0x00, 0xFE, 0x08,
|
||||
0x7F, 0x86, 0x3F, 0xE3, 0x8F, 0x3C, 0xF7, 0x8F, 0x79, 0xE1, 0xFC, 0x78,
|
||||
0x7F, 0x3C, 0x1F, 0x8F, 0x03, 0xE3, 0xC0, 0xF0, 0xF0, 0x3E, 0x1E, 0x1F,
|
||||
0x87, 0xFF, 0xF1, 0xFF, 0xFC, 0x3F, 0xE7, 0x87, 0xF1, 0xE0, 0xFF, 0xFF,
|
||||
0xF7, 0x76, 0x66, 0x66, 0x3E, 0xFF, 0xFF, 0xCF, 0x1E, 0x3C, 0x78, 0xF1,
|
||||
0xE3, 0xC7, 0x8F, 0x1E, 0x3C, 0x78, 0xF1, 0xE3, 0xC7, 0x8F, 0x1E, 0x3C,
|
||||
0x78, 0xF1, 0xE3, 0xC7, 0x8F, 0x1E, 0x3C, 0x78, 0xF1, 0xE3, 0xFB, 0xF7,
|
||||
0xE1, 0xC0, 0xF1, 0xF3, 0xF1, 0xE3, 0xC7, 0xCF, 0x9F, 0x3E, 0x7C, 0xF9,
|
||||
0xF3, 0xE7, 0xCF, 0x9F, 0x3E, 0x7C, 0xF9, 0xF3, 0xE7, 0xCF, 0x9F, 0x3E,
|
||||
0x7C, 0xF9, 0xF3, 0xE7, 0xCF, 0x9F, 0x3E, 0x7B, 0xF7, 0xEF, 0x98, 0x00,
|
||||
0x07, 0x00, 0x1C, 0x04, 0x71, 0x39, 0xCE, 0xFB, 0x7D, 0xFF, 0xC1, 0xFC,
|
||||
0x03, 0xE0, 0x3F, 0xE3, 0xEF, 0xFF, 0x73, 0x99, 0xC6, 0x07, 0x08, 0x1C,
|
||||
0x00, 0x70, 0x00, 0x0F, 0x00, 0xF0, 0x0F, 0x00, 0xF0, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xF0, 0xF0, 0x0F, 0x00, 0xF0, 0x0F, 0x00, 0xF0, 0xFF, 0xFF, 0xFF,
|
||||
0x8C, 0xE7, 0x31, 0x9C, 0xC0, 0xFF, 0xFF, 0xFF, 0xE0, 0xFF, 0xFF, 0x00,
|
||||
0xF8, 0x07, 0x80, 0x3C, 0x01, 0xE0, 0x0E, 0x00, 0xF0, 0x07, 0x80, 0x3C,
|
||||
0x01, 0xC0, 0x1E, 0x00, 0xF0, 0x07, 0x80, 0x38, 0x03, 0xC0, 0x1E, 0x00,
|
||||
0xF0, 0x07, 0x80, 0x78, 0x03, 0xC0, 0x1E, 0x00, 0xF0, 0x0F, 0x00, 0x78,
|
||||
0x03, 0xC0, 0x1E, 0x01, 0xE0, 0x0F, 0x00, 0x78, 0x03, 0xC0, 0x3C, 0x01,
|
||||
0xE0, 0x0F, 0x00, 0x78, 0x07, 0x80, 0x00, 0x0F, 0xC1, 0xFF, 0x9F, 0xFC,
|
||||
0xFF, 0xF7, 0x8F, 0xFC, 0x3F, 0xE1, 0xFF, 0x0F, 0xF8, 0x7F, 0xC3, 0xFE,
|
||||
0x1F, 0xF0, 0xFF, 0x87, 0xFC, 0x3F, 0xE1, 0xFF, 0x0F, 0xF8, 0x7F, 0xC3,
|
||||
0xFE, 0x1F, 0xF0, 0xFF, 0x87, 0xFC, 0x3F, 0xE1, 0xFF, 0x0F, 0xF8, 0x7F,
|
||||
0xC3, 0xFE, 0x1F, 0xF0, 0xFF, 0x87, 0xBC, 0x7D, 0xF7, 0xEF, 0xFE, 0x3F,
|
||||
0xF0, 0xFF, 0x00, 0x03, 0x83, 0xC3, 0xE3, 0xFF, 0xFF, 0xFF, 0xFF, 0x9F,
|
||||
0x0F, 0x87, 0xC3, 0xE1, 0xF0, 0xF8, 0x7C, 0x3E, 0x1F, 0x0F, 0x87, 0xC3,
|
||||
0xE1, 0xF0, 0xF8, 0x7C, 0x3E, 0x1F, 0x0F, 0x87, 0xC3, 0xE1, 0xF0, 0xF8,
|
||||
0x7C, 0x3E, 0x1F, 0x0F, 0x87, 0xC0, 0x0F, 0x81, 0xFF, 0x1F, 0xF8, 0xFF,
|
||||
0xEF, 0x8F, 0x7C, 0x7B, 0xC3, 0xDE, 0x1E, 0xF0, 0xFF, 0x87, 0xFC, 0x3F,
|
||||
0xE1, 0xEF, 0x0F, 0x78, 0x78, 0x07, 0xC0, 0x3C, 0x03, 0xE0, 0x1E, 0x01,
|
||||
0xF0, 0x0F, 0x00, 0xF8, 0x07, 0x80, 0x7C, 0x07, 0xC0, 0x3E, 0x03, 0xE0,
|
||||
0x1F, 0x00, 0xF0, 0x07, 0x80, 0x7C, 0x03, 0xE0, 0x1F, 0xFE, 0xFF, 0xF7,
|
||||
0xFF, 0x80, 0x0F, 0xC0, 0xFF, 0x87, 0xFF, 0x1F, 0xFE, 0x78, 0xFB, 0xE1,
|
||||
0xEF, 0x87, 0xBC, 0x1E, 0xF0, 0x7B, 0xC1, 0xE0, 0x07, 0x80, 0x1E, 0x00,
|
||||
0x78, 0x03, 0xE0, 0x3F, 0x01, 0xF8, 0x07, 0xE0, 0x1F, 0xC0, 0x0F, 0x00,
|
||||
0x3E, 0x00, 0x78, 0x01, 0xE0, 0x07, 0xBC, 0x1E, 0xF0, 0x7F, 0xC1, 0xFF,
|
||||
0x07, 0xBC, 0x1E, 0xF0, 0x7B, 0xE1, 0xE7, 0xDF, 0x9F, 0xFC, 0x3F, 0xE0,
|
||||
0x7F, 0x00, 0x01, 0xF0, 0x07, 0xC0, 0x3F, 0x00, 0xFC, 0x03, 0xF0, 0x1F,
|
||||
0xC0, 0x7F, 0x01, 0xFC, 0x06, 0xF0, 0x3B, 0xC0, 0xEF, 0x03, 0xBC, 0x1C,
|
||||
0xF0, 0x73, 0xC1, 0xCF, 0x0F, 0x3C, 0x38, 0xF0, 0xE3, 0xC7, 0x8F, 0x1C,
|
||||
0x3C, 0x70, 0xF1, 0xC3, 0xCF, 0x0F, 0x38, 0x3C, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0x00, 0xF0, 0x03, 0xC0, 0x0F, 0x00, 0x3C, 0x00, 0xF0,
|
||||
0x03, 0xC0, 0xFF, 0xEF, 0xFE, 0xFF, 0xEF, 0xFE, 0xF0, 0x0F, 0x00, 0xF0,
|
||||
0x0F, 0x00, 0xF0, 0x0F, 0x00, 0xF3, 0x0F, 0xFC, 0xFF, 0xEF, 0xFE, 0xF9,
|
||||
0xEF, 0x1F, 0xF0, 0xF1, 0x0F, 0x00, 0xF0, 0x0F, 0x00, 0xF0, 0x0F, 0x00,
|
||||
0xF0, 0x0F, 0xF0, 0xFF, 0x0F, 0xF0, 0xFF, 0x0F, 0xF0, 0xFF, 0x1F, 0xFB,
|
||||
0xEF, 0xFE, 0x7F, 0xC3, 0xF8, 0x0F, 0xC0, 0xFF, 0x83, 0xFF, 0x1F, 0xFC,
|
||||
0x78, 0xF9, 0xE1, 0xEF, 0x87, 0xBE, 0x1E, 0xF8, 0x7B, 0xE1, 0xEF, 0x80,
|
||||
0x3E, 0x00, 0xF8, 0x03, 0xEF, 0x8F, 0xFF, 0x3F, 0xFE, 0xFF, 0xFB, 0xE1,
|
||||
0xEF, 0x87, 0xBE, 0x1E, 0xF8, 0x7F, 0xE1, 0xFF, 0x87, 0xFE, 0x1F, 0xF8,
|
||||
0x7F, 0xE1, 0xFF, 0x87, 0xFE, 0x1F, 0xF8, 0x79, 0xE1, 0xE7, 0xFF, 0x9F,
|
||||
0xFE, 0x3F, 0xF0, 0x7F, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0x00, 0x7C, 0x01, 0xE0, 0x0F, 0x80, 0x3C, 0x00, 0xF0, 0x07, 0xC0, 0x1E,
|
||||
0x00, 0x78, 0x03, 0xE0, 0x0F, 0x80, 0x3C, 0x00, 0xF0, 0x07, 0xC0, 0x1E,
|
||||
0x00, 0x78, 0x03, 0xE0, 0x0F, 0x80, 0x3C, 0x00, 0xF0, 0x07, 0xC0, 0x1F,
|
||||
0x00, 0x7C, 0x01, 0xF0, 0x07, 0x80, 0x1E, 0x00, 0xF8, 0x03, 0xE0, 0x0F,
|
||||
0x80, 0x3E, 0x00, 0xF8, 0x00, 0x1F, 0xC1, 0xFF, 0x1F, 0xFC, 0xFB, 0xFF,
|
||||
0x8F, 0xFC, 0x3F, 0xC1, 0xFE, 0x0F, 0xF0, 0x7F, 0x83, 0xFC, 0x1F, 0xE0,
|
||||
0xFF, 0x87, 0xBC, 0x79, 0xFF, 0xC7, 0xFC, 0x3F, 0xE3, 0xFF, 0x9E, 0x3D,
|
||||
0xF1, 0xFF, 0x07, 0xF8, 0x3F, 0xC1, 0xFE, 0x0F, 0xF0, 0x7F, 0x83, 0xFC,
|
||||
0x1F, 0xE0, 0xFF, 0x07, 0xFC, 0x3F, 0xF7, 0xEF, 0xFE, 0x3F, 0xF0, 0xFE,
|
||||
0x00, 0x1F, 0x81, 0xFF, 0x1F, 0xFD, 0xFF, 0xEF, 0x8F, 0x78, 0x7F, 0xC3,
|
||||
0xFE, 0x0F, 0xF0, 0x7F, 0x83, 0xFC, 0x1F, 0xE0, 0xFF, 0x07, 0xF8, 0x3F,
|
||||
0xC1, 0xFE, 0x0F, 0xF0, 0x7F, 0xC7, 0xDF, 0xFE, 0xFF, 0xF3, 0xFF, 0x80,
|
||||
0x3C, 0x01, 0xE0, 0x0F, 0xF0, 0x7F, 0x83, 0xFC, 0x1F, 0xE0, 0xFF, 0x0F,
|
||||
0xFC, 0x79, 0xF7, 0xCF, 0xFE, 0x3F, 0xE0, 0xFE, 0x00, 0xFF, 0xFF, 0xF0,
|
||||
0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xF3, 0x9C, 0xCE, 0x73, 0x98,
|
||||
0x00, 0x20, 0x0C, 0x07, 0x81, 0xF0, 0xFE, 0x3F, 0x9F, 0xC7, 0xF0, 0xF8,
|
||||
0x1C, 0x03, 0xE0, 0x7E, 0x07, 0xF0, 0x3F, 0x03, 0xF8, 0x1F, 0x01, 0xE0,
|
||||
0x0C, 0x00, 0x80, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x0F, 0xFF,
|
||||
0xFF, 0xFF, 0xC0, 0x80, 0x18, 0x03, 0x80, 0x7C, 0x0F, 0xC0, 0xFE, 0x07,
|
||||
0xF0, 0x7F, 0x03, 0xE0, 0x3C, 0x0F, 0x83, 0xF1, 0xFC, 0xFE, 0x3F, 0x87,
|
||||
0xC0, 0xF0, 0x18, 0x02, 0x00, 0x00, 0x1F, 0x87, 0xFC, 0x7F, 0xEF, 0xFE,
|
||||
0xF1, 0xEF, 0x1F, 0xF1, 0xFF, 0x1F, 0xF1, 0xFF, 0x1F, 0xF1, 0xFF, 0x1F,
|
||||
0x01, 0xF0, 0x1E, 0x01, 0xE0, 0x3E, 0x03, 0xE0, 0xFC, 0x3F, 0x83, 0xF0,
|
||||
0x3C, 0x03, 0xC0, 0x3C, 0x03, 0xC0, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x3C, 0x03, 0xC0, 0x3C, 0x03, 0xC0, 0x3C, 0x03, 0xC0, 0x00, 0x3F, 0x80,
|
||||
0x00, 0xFF, 0xF0, 0x00, 0xFF, 0xFC, 0x00, 0xF8, 0x0F, 0x00, 0xF0, 0x03,
|
||||
0xC0, 0xF0, 0x00, 0xF0, 0xF0, 0x00, 0x38, 0x78, 0x00, 0x1C, 0x38, 0x1F,
|
||||
0x87, 0x3C, 0x3F, 0xE3, 0x9E, 0x1E, 0xF1, 0xCE, 0x1C, 0x38, 0xE7, 0x0E,
|
||||
0x1C, 0x77, 0x8E, 0x0E, 0x1F, 0xC7, 0x07, 0x0F, 0xE3, 0x83, 0x87, 0xF1,
|
||||
0xC1, 0xC3, 0xF8, 0xE0, 0xE1, 0xFC, 0x70, 0x70, 0xFE, 0x38, 0x38, 0x7F,
|
||||
0x1C, 0x1C, 0x77, 0x8E, 0x0E, 0x39, 0xC7, 0x07, 0x1C, 0xE3, 0xC7, 0xCE,
|
||||
0x70, 0xF6, 0xFE, 0x3C, 0x7F, 0x3F, 0x1E, 0x1F, 0x0F, 0x07, 0x81, 0x00,
|
||||
0x03, 0xC0, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x1F, 0x80,
|
||||
0x70, 0x07, 0xFF, 0xF8, 0x00, 0xFF, 0xFE, 0x00, 0x1F, 0xF0, 0x00, 0x07,
|
||||
0xC0, 0x07, 0xE0, 0x0F, 0xE0, 0x0F, 0xE0, 0x0F, 0xE0, 0x0F, 0xE0, 0x0F,
|
||||
0xE0, 0x0F, 0xF0, 0x0E, 0xF0, 0x1E, 0xF0, 0x1E, 0xF0, 0x1E, 0xF0, 0x1E,
|
||||
0xF0, 0x1E, 0x70, 0x1E, 0x78, 0x1C, 0x78, 0x3C, 0x78, 0x3C, 0x78, 0x3C,
|
||||
0x78, 0x3C, 0x78, 0x3C, 0x3C, 0x3C, 0x3C, 0x7C, 0x3C, 0x78, 0x3C, 0x7F,
|
||||
0xFC, 0x7F, 0xFC, 0x7F, 0xFE, 0x7F, 0xFE, 0x78, 0x1E, 0xF8, 0x1E, 0xF8,
|
||||
0x1E, 0xF0, 0x1E, 0xF0, 0x1F, 0xF0, 0x1F, 0xFF, 0x03, 0xFF, 0x8F, 0xFF,
|
||||
0x3F, 0xFC, 0xF0, 0xFB, 0xC3, 0xEF, 0x07, 0xBC, 0x1E, 0xF0, 0x7B, 0xC1,
|
||||
0xEF, 0x07, 0xBC, 0x3E, 0xF0, 0xFB, 0xC3, 0xCF, 0xFF, 0x3F, 0xF8, 0xFF,
|
||||
0xF3, 0xFF, 0xCF, 0x0F, 0xBC, 0x1E, 0xF0, 0x7B, 0xC1, 0xEF, 0x07, 0xFC,
|
||||
0x1F, 0xF0, 0x7F, 0xC1, 0xFF, 0x07, 0xBC, 0x1E, 0xF0, 0x7B, 0xC3, 0xEF,
|
||||
0xFF, 0xBF, 0xFC, 0xFF, 0xE3, 0xFF, 0x00, 0x0F, 0xC0, 0x7F, 0xC3, 0xFF,
|
||||
0x9F, 0xFE, 0x7C, 0x79, 0xE1, 0xFF, 0x87, 0xFE, 0x0F, 0xF8, 0x3F, 0xE0,
|
||||
0xFF, 0x83, 0xFE, 0x0F, 0xF8, 0x3F, 0xE0, 0x0F, 0x80, 0x3E, 0x00, 0xF8,
|
||||
0x03, 0xE0, 0x0F, 0x80, 0x3E, 0x00, 0xF8, 0x3F, 0xE0, 0xFF, 0x83, 0xFE,
|
||||
0x0F, 0xF8, 0x3F, 0xE0, 0xFF, 0x83, 0xFE, 0x1F, 0x78, 0x7D, 0xE1, 0xE7,
|
||||
0xEF, 0x8F, 0xFE, 0x3F, 0xF0, 0x3F, 0x80, 0xFF, 0x07, 0xFF, 0x3F, 0xFD,
|
||||
0xFF, 0xEF, 0x0F, 0xF8, 0x7F, 0xC1, 0xFE, 0x0F, 0xF0, 0x7F, 0x83, 0xFC,
|
||||
0x1F, 0xE0, 0xFF, 0x07, 0xF8, 0x3F, 0xC1, 0xFE, 0x0F, 0xF0, 0x7F, 0x83,
|
||||
0xFC, 0x1F, 0xE0, 0xFF, 0x07, 0xF8, 0x3F, 0xC1, 0xFE, 0x0F, 0xF0, 0x7F,
|
||||
0x83, 0xFC, 0x1F, 0xE0, 0xFF, 0x07, 0xF8, 0x7F, 0xFF, 0xDF, 0xFE, 0xFF,
|
||||
0xE7, 0xFC, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x3C, 0x0F, 0x03,
|
||||
0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F,
|
||||
0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0x03,
|
||||
0xC0, 0xF0, 0x3C, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0xC0, 0xF0,
|
||||
0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F,
|
||||
0x03, 0xC0, 0xF0, 0x3C, 0x00, 0x0F, 0xE0, 0x7F, 0xC3, 0xFF, 0x9F, 0xFE,
|
||||
0x7C, 0x7D, 0xE0, 0xFF, 0x83, 0xFE, 0x0F, 0xF8, 0x3F, 0xE0, 0xFF, 0x83,
|
||||
0xFE, 0x0F, 0xF8, 0x03, 0xE0, 0x0F, 0x80, 0x3E, 0x00, 0xF9, 0xFF, 0xE7,
|
||||
0xFF, 0x9F, 0xFE, 0x0F, 0xF8, 0x3F, 0xE0, 0xFF, 0x83, 0xFE, 0x0F, 0xF8,
|
||||
0x3F, 0xE0, 0xFF, 0x83, 0xFE, 0x0F, 0x78, 0x3D, 0xE1, 0xF7, 0xEF, 0xCF,
|
||||
0xFF, 0x3F, 0xEC, 0x3F, 0x30, 0xF0, 0x7F, 0xC1, 0xFF, 0x07, 0xFC, 0x1F,
|
||||
0xF0, 0x7F, 0xC1, 0xFF, 0x07, 0xFC, 0x1F, 0xF0, 0x7F, 0xC1, 0xFF, 0x07,
|
||||
0xFC, 0x1F, 0xF0, 0x7F, 0xC1, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0x07, 0xFC, 0x1F, 0xF0, 0x7F, 0xC1, 0xFF, 0x07, 0xFC, 0x1F, 0xF0,
|
||||
0x7F, 0xC1, 0xFF, 0x07, 0xFC, 0x1F, 0xF0, 0x7F, 0xC1, 0xFF, 0x07, 0xFC,
|
||||
0x1F, 0xF0, 0x7F, 0xC1, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xF8,
|
||||
0x07, 0xC0, 0x3E, 0x01, 0xF0, 0x0F, 0x80, 0x7C, 0x03, 0xE0, 0x1F, 0x00,
|
||||
0xF8, 0x07, 0xC0, 0x3E, 0x01, 0xF0, 0x0F, 0x80, 0x7C, 0x03, 0xE0, 0x1F,
|
||||
0x00, 0xF8, 0x07, 0xC0, 0x3E, 0x01, 0xF0, 0x0F, 0xF8, 0x7F, 0xC3, 0xFE,
|
||||
0x1F, 0xF0, 0xFF, 0x87, 0xFC, 0x3F, 0xE1, 0xEF, 0x0F, 0x78, 0x7B, 0xF7,
|
||||
0xCF, 0xFC, 0x7F, 0xE1, 0xFE, 0x00, 0xF0, 0x3D, 0xE0, 0xFB, 0xC1, 0xE7,
|
||||
0x83, 0xCF, 0x0F, 0x9E, 0x1E, 0x3C, 0x3C, 0x78, 0xF8, 0xF1, 0xE1, 0xE7,
|
||||
0xC3, 0xCF, 0x87, 0x9E, 0x0F, 0x7C, 0x1E, 0xF8, 0x3D, 0xE0, 0x7F, 0xC0,
|
||||
0xFF, 0x01, 0xFE, 0x03, 0xFE, 0x07, 0xBC, 0x0F, 0x7C, 0x1E, 0xF8, 0x3C,
|
||||
0xF0, 0x79, 0xF0, 0xF1, 0xE1, 0xE3, 0xC3, 0xC7, 0xC7, 0x87, 0x8F, 0x0F,
|
||||
0x9E, 0x1F, 0x3C, 0x1E, 0x78, 0x3E, 0xF0, 0x7D, 0xE0, 0x7C, 0xF0, 0x3C,
|
||||
0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0x03,
|
||||
0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0,
|
||||
0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xF8, 0x01, 0xFF, 0x80, 0x1F, 0xF8, 0x03,
|
||||
0xFF, 0xC0, 0x3F, 0xFC, 0x03, 0xFF, 0xC0, 0x3F, 0xFC, 0x03, 0xFF, 0xC0,
|
||||
0x7F, 0xFE, 0x07, 0xFF, 0xE0, 0x7F, 0xFE, 0x07, 0xFE, 0xE0, 0x7F, 0xEE,
|
||||
0x0F, 0xFE, 0xF0, 0xFF, 0xEF, 0x0E, 0xFE, 0x70, 0xEF, 0xE7, 0x0E, 0xFE,
|
||||
0x70, 0xEF, 0xE7, 0x1E, 0xFE, 0x79, 0xCF, 0xE3, 0x9C, 0xFF, 0x39, 0xCF,
|
||||
0xF3, 0x9C, 0xFF, 0x3B, 0xCF, 0xF3, 0xF8, 0xFF, 0x1F, 0x8F, 0xF1, 0xF8,
|
||||
0xFF, 0x1F, 0x8F, 0xF1, 0xF8, 0xFF, 0x1F, 0x8F, 0xF0, 0xF0, 0xFF, 0x0F,
|
||||
0x0F, 0xF0, 0xF0, 0xFF, 0x0F, 0x0F, 0xE0, 0x3F, 0x80, 0xFF, 0x03, 0xFC,
|
||||
0x0F, 0xF8, 0x3F, 0xE0, 0xFF, 0x83, 0xFF, 0x0F, 0xFC, 0x3F, 0xF0, 0xFF,
|
||||
0xE3, 0xFF, 0x8F, 0xFE, 0x3F, 0xFC, 0xFF, 0xF3, 0xFD, 0xCF, 0xF7, 0xBF,
|
||||
0xDE, 0xFF, 0x3B, 0xFC, 0xFF, 0xF3, 0xDF, 0xC7, 0x7F, 0x1F, 0xFC, 0x7F,
|
||||
0xF0, 0xFF, 0xC3, 0xFF, 0x0F, 0xFC, 0x1F, 0xF0, 0x7F, 0xC1, 0xFF, 0x03,
|
||||
0xFC, 0x0F, 0xF0, 0x3F, 0xC0, 0x70, 0x0F, 0xE0, 0x7F, 0xC3, 0xFF, 0x9F,
|
||||
0xFE, 0x7C, 0x7D, 0xE1, 0xFF, 0x83, 0xFE, 0x0F, 0xF8, 0x3F, 0xE0, 0xFF,
|
||||
0x83, 0xFE, 0x0F, 0xF8, 0x3F, 0xE0, 0xFF, 0x83, 0xFE, 0x0F, 0xF8, 0x3F,
|
||||
0xE0, 0xFF, 0x83, 0xFE, 0x0F, 0xF8, 0x3F, 0xE0, 0xFF, 0x83, 0xFE, 0x0F,
|
||||
0xF8, 0x3F, 0xE0, 0xFF, 0x83, 0xFE, 0x0F, 0x78, 0x7D, 0xE1, 0xF7, 0xFF,
|
||||
0x8F, 0xFE, 0x3F, 0xF0, 0x3F, 0x80, 0xFF, 0x87, 0xFF, 0x3F, 0xFD, 0xFF,
|
||||
0xEF, 0x0F, 0xF8, 0x3F, 0xC1, 0xFE, 0x0F, 0xF0, 0x7F, 0x83, 0xFC, 0x1F,
|
||||
0xE0, 0xFF, 0x07, 0xF8, 0x3F, 0xC1, 0xFE, 0x1F, 0xF0, 0xFF, 0xFF, 0xBF,
|
||||
0xFD, 0xFF, 0xCF, 0xF8, 0x78, 0x03, 0xC0, 0x1E, 0x00, 0xF0, 0x07, 0x80,
|
||||
0x3C, 0x01, 0xE0, 0x0F, 0x00, 0x78, 0x03, 0xC0, 0x1E, 0x00, 0xF0, 0x07,
|
||||
0x80, 0x00, 0x0F, 0xE0, 0x7F, 0xC3, 0xFF, 0x9F, 0xFE, 0x7C, 0x7D, 0xE1,
|
||||
0xFF, 0x83, 0xFE, 0x0F, 0xF8, 0x3F, 0xE0, 0xFF, 0x83, 0xFE, 0x0F, 0xF8,
|
||||
0x3F, 0xE0, 0xFF, 0x83, 0xFE, 0x0F, 0xF8, 0x3F, 0xE0, 0xFF, 0x83, 0xFE,
|
||||
0x0F, 0xF8, 0x3F, 0xE0, 0xFF, 0x83, 0xFE, 0x0F, 0xF8, 0x3F, 0xE0, 0xFF,
|
||||
0x83, 0xFE, 0x0F, 0x78, 0x7D, 0xE1, 0xF7, 0xFF, 0x8F, 0xFE, 0x3F, 0xF0,
|
||||
0x3F, 0x80, 0x1E, 0x00, 0x3C, 0x00, 0x78, 0x01, 0xE0, 0x03, 0x00, 0xFF,
|
||||
0x83, 0xFF, 0x8F, 0xFF, 0x3F, 0xFE, 0xF0, 0xFB, 0xC1, 0xEF, 0x07, 0xBC,
|
||||
0x1E, 0xF0, 0x7B, 0xC1, 0xEF, 0x07, 0xBC, 0x1E, 0xF0, 0x7B, 0xC3, 0xEF,
|
||||
0x1F, 0x3F, 0xFC, 0xFF, 0xE3, 0xFF, 0xCF, 0x0F, 0xBC, 0x1E, 0xF0, 0x7B,
|
||||
0xC1, 0xEF, 0x07, 0xBC, 0x1E, 0xF0, 0x7B, 0xC1, 0xEF, 0x07, 0xBC, 0x1E,
|
||||
0xF0, 0x7B, 0xC1, 0xEF, 0x07, 0xBC, 0x1E, 0xF0, 0x7B, 0xC1, 0xF0, 0x0F,
|
||||
0xC0, 0xFF, 0xC3, 0xFF, 0x1F, 0xFE, 0x78, 0x79, 0xE1, 0xEF, 0x87, 0xBE,
|
||||
0x1F, 0xF8, 0x7D, 0xE1, 0xF7, 0x87, 0xDF, 0x1F, 0x7E, 0x00, 0xFC, 0x01,
|
||||
0xF8, 0x03, 0xF0, 0x0F, 0xE0, 0x1F, 0x80, 0x3F, 0x00, 0x7E, 0x00, 0xF9,
|
||||
0xE1, 0xF7, 0x87, 0xDE, 0x0F, 0x78, 0x3D, 0xE0, 0xF7, 0x83, 0xDE, 0x0F,
|
||||
0x78, 0x3D, 0xE1, 0xF7, 0xEF, 0x8F, 0xFE, 0x3F, 0xF0, 0x3F, 0x80, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x80, 0xF8, 0x0F, 0x80, 0xF8, 0x0F,
|
||||
0x80, 0xF8, 0x0F, 0x80, 0xF8, 0x0F, 0x80, 0xF8, 0x0F, 0x80, 0xF8, 0x0F,
|
||||
0x80, 0xF8, 0x0F, 0x80, 0xF8, 0x0F, 0x80, 0xF8, 0x0F, 0x80, 0xF8, 0x0F,
|
||||
0x80, 0xF8, 0x0F, 0x80, 0xF8, 0x0F, 0x80, 0xF8, 0x0F, 0x80, 0xF8, 0x0F,
|
||||
0x80, 0xF8, 0xF8, 0x3F, 0xE0, 0xFF, 0x83, 0xFE, 0x0F, 0xF8, 0x3F, 0xE0,
|
||||
0xFF, 0x83, 0xFE, 0x0F, 0xF8, 0x3F, 0xE0, 0xFF, 0x83, 0xFE, 0x0F, 0xF8,
|
||||
0x3F, 0xE0, 0xFF, 0x83, 0xFE, 0x0F, 0xF8, 0x3F, 0xE0, 0xFF, 0x83, 0xFE,
|
||||
0x0F, 0xF8, 0x3F, 0xE0, 0xFF, 0x83, 0xFE, 0x0F, 0xF8, 0x3F, 0xE0, 0xFF,
|
||||
0x83, 0xFE, 0x0F, 0x78, 0x3D, 0xE1, 0xF7, 0xEF, 0xCF, 0xFE, 0x3F, 0xF8,
|
||||
0x7F, 0x80, 0xF0, 0x1F, 0xF0, 0x1E, 0xF0, 0x1E, 0xF0, 0x1E, 0xF8, 0x1E,
|
||||
0x78, 0x1E, 0x78, 0x1E, 0x78, 0x3C, 0x78, 0x3C, 0x78, 0x3C, 0x7C, 0x3C,
|
||||
0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x78, 0x3C, 0x78, 0x3C, 0x78,
|
||||
0x1E, 0x78, 0x1E, 0x78, 0x1E, 0x78, 0x1E, 0x78, 0x1E, 0x70, 0x1E, 0xF0,
|
||||
0x0E, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xE0,
|
||||
0x0F, 0xE0, 0x07, 0xE0, 0x07, 0xE0, 0x07, 0xE0, 0x07, 0xE0, 0xF0, 0x3C,
|
||||
0x0F, 0xF0, 0x3C, 0x0F, 0xF0, 0x3C, 0x0F, 0xF0, 0x3C, 0x1E, 0xF0, 0x3C,
|
||||
0x1E, 0x78, 0x3E, 0x1E, 0x78, 0x7E, 0x1E, 0x78, 0x7E, 0x1E, 0x78, 0x7E,
|
||||
0x1E, 0x78, 0x7E, 0x1E, 0x78, 0x7E, 0x1E, 0x78, 0x7E, 0x1E, 0x38, 0x7F,
|
||||
0x1C, 0x38, 0xF7, 0x1C, 0x3C, 0xF7, 0x3C, 0x3C, 0xE7, 0x3C, 0x3C, 0xE7,
|
||||
0x3C, 0x3C, 0xE7, 0x3C, 0x3C, 0xE7, 0x3C, 0x3C, 0xE7, 0xBC, 0x1D, 0xE3,
|
||||
0xB8, 0x1D, 0xC3, 0xB8, 0x1D, 0xC3, 0xB8, 0x1F, 0xC3, 0xB8, 0x1F, 0xC3,
|
||||
0xB8, 0x1F, 0xC3, 0xF8, 0x1F, 0xC3, 0xF8, 0x1F, 0xC1, 0xF8, 0x0F, 0x81,
|
||||
0xF8, 0x0F, 0x81, 0xF0, 0x0F, 0x81, 0xF0, 0x0F, 0x81, 0xF0, 0x0F, 0x81,
|
||||
0xF0, 0x0F, 0x81, 0xF0, 0xF0, 0x3F, 0xC0, 0xF7, 0x07, 0x9E, 0x1E, 0x78,
|
||||
0x78, 0xE3, 0xE3, 0xCF, 0x0F, 0x3C, 0x3C, 0xF0, 0x7F, 0x81, 0xFE, 0x07,
|
||||
0xF8, 0x0F, 0xE0, 0x3F, 0x00, 0xFC, 0x01, 0xF0, 0x07, 0x80, 0x3E, 0x00,
|
||||
0xF8, 0x03, 0xF0, 0x0F, 0xC0, 0x7F, 0x01, 0xFE, 0x07, 0xF8, 0x3F, 0xE0,
|
||||
0xF3, 0xC3, 0xCF, 0x0F, 0x3C, 0x78, 0x71, 0xE1, 0xE7, 0x87, 0x9E, 0x0E,
|
||||
0xF0, 0x3F, 0xC0, 0xF0, 0xF8, 0x0F, 0x78, 0x1F, 0x78, 0x1E, 0x7C, 0x1E,
|
||||
0x3C, 0x1E, 0x3C, 0x3E, 0x3C, 0x3C, 0x3E, 0x3C, 0x1E, 0x3C, 0x1E, 0x78,
|
||||
0x1E, 0x78, 0x0F, 0x78, 0x0F, 0x78, 0x0F, 0xF0, 0x0F, 0xF0, 0x07, 0xF0,
|
||||
0x07, 0xF0, 0x07, 0xE0, 0x03, 0xE0, 0x03, 0xE0, 0x03, 0xE0, 0x03, 0xE0,
|
||||
0x03, 0xE0, 0x03, 0xE0, 0x03, 0xE0, 0x03, 0xE0, 0x03, 0xE0, 0x03, 0xE0,
|
||||
0x03, 0xE0, 0x03, 0xE0, 0x03, 0xE0, 0x03, 0xE0, 0x03, 0xE0, 0x03, 0xE0,
|
||||
0x7F, 0xF7, 0xFF, 0x7F, 0xF7, 0xFF, 0x01, 0xF0, 0x1E, 0x01, 0xE0, 0x3E,
|
||||
0x03, 0xE0, 0x3C, 0x07, 0xC0, 0x7C, 0x07, 0xC0, 0x78, 0x0F, 0x80, 0xF8,
|
||||
0x0F, 0x80, 0xF0, 0x1F, 0x01, 0xF0, 0x1E, 0x01, 0xE0, 0x3E, 0x03, 0xE0,
|
||||
0x3C, 0x07, 0xC0, 0x7C, 0x07, 0xC0, 0x78, 0x0F, 0x80, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0,
|
||||
0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0,
|
||||
0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xFF,
|
||||
0xFF, 0xFF, 0xF0, 0x1E, 0x03, 0xC0, 0x78, 0x07, 0x00, 0xF0, 0x1E, 0x03,
|
||||
0xC0, 0x78, 0x07, 0x80, 0xF0, 0x1E, 0x03, 0xC0, 0x3C, 0x07, 0x80, 0xF0,
|
||||
0x1E, 0x01, 0xC0, 0x3C, 0x07, 0x80, 0xF0, 0x0E, 0x01, 0xE0, 0x3C, 0x07,
|
||||
0x80, 0xF0, 0x0F, 0x01, 0xE0, 0x3C, 0x07, 0x80, 0x78, 0x0F, 0x01, 0xE0,
|
||||
0x3C, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F,
|
||||
0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F,
|
||||
0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0xFF, 0xFF, 0xFF,
|
||||
0x0F, 0xC0, 0x1F, 0x80, 0x3F, 0x80, 0x7F, 0x01, 0xFE, 0x03, 0xDC, 0x07,
|
||||
0xBC, 0x0E, 0x78, 0x3C, 0xF0, 0x79, 0xE0, 0xF1, 0xE1, 0xE3, 0xC7, 0x87,
|
||||
0x8F, 0x0F, 0x1E, 0x0F, 0x3C, 0x1E, 0xF8, 0x3D, 0xE0, 0x7C, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xF0, 0xF9, 0xE7, 0x8E, 0x38, 0x71, 0xC3, 0x0F, 0xC0, 0xFF,
|
||||
0xC3, 0xFF, 0x1F, 0xFE, 0x78, 0x79, 0xE1, 0xEF, 0x87, 0xBE, 0x1E, 0xF8,
|
||||
0x7C, 0x01, 0xF0, 0x07, 0xC0, 0x7F, 0x0F, 0xFC, 0x7F, 0xF3, 0xE7, 0xDE,
|
||||
0x1F, 0xF8, 0x7F, 0xE1, 0xFF, 0x87, 0xFE, 0x1F, 0xF8, 0x7F, 0xE1, 0xFF,
|
||||
0x87, 0xFE, 0x1F, 0xF8, 0x7D, 0xE3, 0xF7, 0xFF, 0xDF, 0xFF, 0x3F, 0x7C,
|
||||
0xF0, 0x07, 0x80, 0x3C, 0x01, 0xE0, 0x0F, 0x00, 0x79, 0xE3, 0xDF, 0x9F,
|
||||
0xFE, 0xFF, 0xFF, 0xC7, 0xFC, 0x1F, 0xE0, 0xFF, 0x07, 0xF8, 0x3F, 0xC1,
|
||||
0xFE, 0x0F, 0xF0, 0x7F, 0x83, 0xFC, 0x1F, 0xE0, 0xFF, 0x07, 0xF8, 0x3F,
|
||||
0xC1, 0xFE, 0x0F, 0xF0, 0x7F, 0x83, 0xFC, 0x1F, 0xE0, 0xFF, 0x07, 0xFC,
|
||||
0x7F, 0xF7, 0xFF, 0xFE, 0xF7, 0xF7, 0x9F, 0x00, 0x0F, 0xC1, 0xFF, 0x8F,
|
||||
0xFC, 0xFF, 0xF7, 0x87, 0xBC, 0x3F, 0xE1, 0xFF, 0x0F, 0xF8, 0x7F, 0xC3,
|
||||
0xFE, 0x1F, 0xF0, 0x0F, 0x80, 0x7C, 0x03, 0xE0, 0x1F, 0x00, 0xF8, 0x07,
|
||||
0xC0, 0x3E, 0x1F, 0xF0, 0xFF, 0x87, 0xFC, 0x3F, 0xE1, 0xEF, 0x0F, 0x78,
|
||||
0x7B, 0xE7, 0xDF, 0xFC, 0x7F, 0xE1, 0xFE, 0x00, 0x00, 0x7C, 0x01, 0xF0,
|
||||
0x07, 0xC0, 0x1F, 0x00, 0x7C, 0x7D, 0xF3, 0xFF, 0xDF, 0xFF, 0x7F, 0xFD,
|
||||
0xE1, 0xFF, 0x87, 0xFE, 0x1F, 0xF8, 0x7F, 0xE1, 0xFF, 0x87, 0xFE, 0x1F,
|
||||
0xF8, 0x7F, 0xE1, 0xFF, 0x87, 0xFE, 0x1F, 0xF8, 0x7F, 0xE1, 0xFF, 0x87,
|
||||
0xFE, 0x1F, 0xF8, 0x7F, 0xE1, 0xFF, 0x87, 0xFE, 0x1F, 0xF8, 0x7D, 0xE1,
|
||||
0xF7, 0xDF, 0xDF, 0xFF, 0x3F, 0xFC, 0x7D, 0xF0, 0x0F, 0xC0, 0x7F, 0xC3,
|
||||
0xFF, 0x1F, 0xFE, 0x78, 0x79, 0xE1, 0xEF, 0x87, 0xBE, 0x1E, 0xF8, 0x7B,
|
||||
0xE1, 0xFF, 0x87, 0xFE, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00,
|
||||
0xF8, 0x03, 0xE0, 0x0F, 0x87, 0xBE, 0x1E, 0xF8, 0x7B, 0xE1, 0xEF, 0x87,
|
||||
0x9E, 0x1E, 0x78, 0x79, 0xF3, 0xE7, 0xFF, 0x0F, 0xFC, 0x1F, 0xE0, 0x07,
|
||||
0xC3, 0xF1, 0xFC, 0x7C, 0x1E, 0x07, 0x8F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF1,
|
||||
0xE0, 0x78, 0x1E, 0x07, 0x81, 0xE0, 0x78, 0x1E, 0x07, 0x81, 0xE0, 0x78,
|
||||
0x1E, 0x07, 0x81, 0xE0, 0x78, 0x1E, 0x07, 0x81, 0xE0, 0x78, 0x1E, 0x07,
|
||||
0x81, 0xE0, 0x78, 0x1E, 0x07, 0x80, 0x1F, 0x7C, 0xFF, 0xF7, 0xFF, 0xDF,
|
||||
0xFF, 0x78, 0x7D, 0xE1, 0xFF, 0x87, 0xFE, 0x1F, 0xF8, 0x7F, 0xE1, 0xFF,
|
||||
0x87, 0xFE, 0x1F, 0xF8, 0x7F, 0xE1, 0xFF, 0x87, 0xFE, 0x1F, 0xF8, 0x7F,
|
||||
0xE1, 0xFF, 0x87, 0xFE, 0x1F, 0xF8, 0x7D, 0xE1, 0xF7, 0xCF, 0xDF, 0xFF,
|
||||
0x3F, 0xFC, 0x7D, 0xF0, 0x07, 0xC0, 0x1F, 0x00, 0x79, 0xC3, 0xE7, 0xFF,
|
||||
0xBF, 0xFC, 0x3F, 0xC0, 0xF0, 0x07, 0x80, 0x3C, 0x01, 0xE0, 0x0F, 0x00,
|
||||
0x79, 0xF3, 0xDF, 0xDF, 0xFF, 0xFF, 0xFF, 0xC3, 0xFC, 0x1F, 0xE0, 0xFF,
|
||||
0x07, 0xF8, 0x3F, 0xC1, 0xFE, 0x0F, 0xF0, 0x7F, 0x83, 0xFC, 0x1F, 0xE0,
|
||||
0xFF, 0x07, 0xF8, 0x3F, 0xC1, 0xFE, 0x0F, 0xF0, 0x7F, 0x83, 0xFC, 0x1F,
|
||||
0xE0, 0xFF, 0x07, 0xF8, 0x3F, 0xC1, 0xFE, 0x0F, 0xF0, 0x7F, 0x83, 0xC0,
|
||||
0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x3C, 0x78, 0xF1, 0xE0, 0x00, 0x0F,
|
||||
0x9F, 0x3E, 0x7C, 0xF9, 0xF3, 0xE7, 0xCF, 0x9F, 0x3E, 0x7C, 0xF9, 0xF3,
|
||||
0xE7, 0xCF, 0x9F, 0x3E, 0x7C, 0xF9, 0xF3, 0xE7, 0xCF, 0x9F, 0x3E, 0x7C,
|
||||
0xF9, 0xFF, 0xDF, 0xBE, 0x00, 0xF0, 0x03, 0xC0, 0x0F, 0x00, 0x3C, 0x00,
|
||||
0xF0, 0x03, 0xC1, 0xFF, 0x07, 0xBC, 0x1E, 0xF0, 0xFB, 0xC3, 0xCF, 0x1F,
|
||||
0x3C, 0x78, 0xF1, 0xE3, 0xCF, 0x8F, 0x3C, 0x3D, 0xF0, 0xF7, 0x83, 0xDE,
|
||||
0x0F, 0xF8, 0x3F, 0xC0, 0xFF, 0x83, 0xDE, 0x0F, 0x78, 0x3D, 0xF0, 0xF3,
|
||||
0xC3, 0xCF, 0x8F, 0x1E, 0x3C, 0x7C, 0xF0, 0xF3, 0xC3, 0xCF, 0x0F, 0xBC,
|
||||
0x1E, 0xF0, 0x7F, 0xC0, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF3, 0xE1,
|
||||
0xF3, 0xDF, 0xCF, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0xFC, 0x3F,
|
||||
0xC1, 0xE0, 0xFF, 0x07, 0x83, 0xFC, 0x1E, 0x0F, 0xF0, 0x78, 0x3F, 0xC1,
|
||||
0xE0, 0xFF, 0x07, 0x83, 0xFC, 0x1E, 0x0F, 0xF0, 0x78, 0x3F, 0xC1, 0xE0,
|
||||
0xFF, 0x07, 0x83, 0xFC, 0x1E, 0x0F, 0xF0, 0x78, 0x3F, 0xC1, 0xE0, 0xFF,
|
||||
0x07, 0x83, 0xFC, 0x1E, 0x0F, 0xF0, 0x78, 0x3F, 0xC1, 0xE0, 0xFF, 0x07,
|
||||
0x83, 0xFC, 0x1E, 0x0F, 0xF0, 0x78, 0x3F, 0xC1, 0xE0, 0xFF, 0x07, 0x83,
|
||||
0xFC, 0x1E, 0x0F, 0xF0, 0x78, 0x3C, 0xF3, 0xE7, 0xBF, 0xBF, 0xFF, 0xFF,
|
||||
0xFF, 0x87, 0xF8, 0x3F, 0xC1, 0xFE, 0x0F, 0xF0, 0x7F, 0x83, 0xFC, 0x1F,
|
||||
0xE0, 0xFF, 0x07, 0xF8, 0x3F, 0xC1, 0xFE, 0x0F, 0xF0, 0x7F, 0x83, 0xFC,
|
||||
0x1F, 0xE0, 0xFF, 0x07, 0xF8, 0x3F, 0xC1, 0xFE, 0x0F, 0xF0, 0x7F, 0x83,
|
||||
0xFC, 0x1F, 0xE0, 0xFF, 0x07, 0x80, 0x0F, 0xC0, 0x7F, 0x83, 0xFF, 0x1F,
|
||||
0xFE, 0x78, 0x79, 0xE1, 0xEF, 0x87, 0xBE, 0x1F, 0xF8, 0x7F, 0xE1, 0xFF,
|
||||
0x87, 0xFE, 0x1F, 0xF8, 0x7F, 0xE1, 0xFF, 0x87, 0xFE, 0x1F, 0xF8, 0x7F,
|
||||
0xE1, 0xFF, 0x87, 0xFE, 0x1F, 0xF8, 0x7F, 0xE1, 0xFF, 0x87, 0xDE, 0x1E,
|
||||
0x78, 0x79, 0xF3, 0xE7, 0xFF, 0x0F, 0xFC, 0x1F, 0xE0, 0xF3, 0xC7, 0xBF,
|
||||
0xBF, 0xFD, 0xFF, 0xFF, 0x8F, 0xF8, 0x7F, 0xC1, 0xFE, 0x0F, 0xF0, 0x7F,
|
||||
0x83, 0xFC, 0x1F, 0xE0, 0xFF, 0x07, 0xF8, 0x3F, 0xC1, 0xFE, 0x0F, 0xF0,
|
||||
0x7F, 0x83, 0xFC, 0x1F, 0xE0, 0xFF, 0x07, 0xF8, 0x3F, 0xC1, 0xFE, 0x0F,
|
||||
0xF8, 0xFF, 0xEF, 0xFF, 0xFD, 0xFF, 0xEF, 0x7E, 0x78, 0x03, 0xC0, 0x1E,
|
||||
0x00, 0xF0, 0x07, 0x80, 0x00, 0x1E, 0x7C, 0xFF, 0xF7, 0xFF, 0xDF, 0xFF,
|
||||
0x78, 0x7F, 0xE1, 0xFF, 0x87, 0xFE, 0x1F, 0xF8, 0x7F, 0xE1, 0xFF, 0x87,
|
||||
0xFE, 0x1F, 0xF8, 0x7F, 0xE1, 0xFF, 0x87, 0xFE, 0x1F, 0xF8, 0x7F, 0xE1,
|
||||
0xFF, 0x87, 0xFE, 0x1F, 0xF8, 0x7F, 0xE1, 0xFF, 0x87, 0xFE, 0x1F, 0x78,
|
||||
0x7D, 0xF7, 0xF7, 0xFF, 0xCF, 0xFF, 0x1F, 0x7C, 0x01, 0xF0, 0x07, 0xC0,
|
||||
0x1F, 0x00, 0x7C, 0x01, 0xF0, 0xF3, 0xFB, 0xFF, 0xFF, 0xFF, 0xC7, 0x83,
|
||||
0xC1, 0xE0, 0xF0, 0x78, 0x3C, 0x1E, 0x0F, 0x07, 0x83, 0xC1, 0xE0, 0xF0,
|
||||
0x78, 0x3C, 0x1E, 0x0F, 0x07, 0x83, 0xC1, 0xE0, 0xF0, 0x78, 0x3C, 0x1E,
|
||||
0x0F, 0x00, 0x1F, 0x83, 0xFE, 0x1F, 0xF9, 0xFF, 0xCF, 0x0F, 0x78, 0x7B,
|
||||
0xC3, 0xDE, 0x1E, 0xF0, 0xF7, 0xC7, 0xBE, 0x00, 0xF8, 0x07, 0xE0, 0x1F,
|
||||
0x80, 0x7E, 0x01, 0xF8, 0x07, 0xE0, 0x1F, 0x80, 0x7D, 0xE1, 0xEF, 0x0F,
|
||||
0xF8, 0x7F, 0xC3, 0xFE, 0x1F, 0xF0, 0xF7, 0xEF, 0x9F, 0xFC, 0xFF, 0xC1,
|
||||
0xFC, 0x00, 0x3E, 0x0F, 0x83, 0xE0, 0xF8, 0x3E, 0x0F, 0x8F, 0xFF, 0xFF,
|
||||
0xFF, 0xCF, 0x83, 0xE0, 0xF8, 0x3E, 0x0F, 0x83, 0xE0, 0xF8, 0x3E, 0x0F,
|
||||
0x83, 0xE0, 0xF8, 0x3E, 0x0F, 0x83, 0xE0, 0xF8, 0x3E, 0x0F, 0x83, 0xE0,
|
||||
0xF8, 0x3E, 0x0F, 0x83, 0xF0, 0xFF, 0x1F, 0xC3, 0xF0, 0xF8, 0x3F, 0xE0,
|
||||
0xFF, 0x83, 0xFE, 0x0F, 0xF8, 0x3F, 0xE0, 0xFF, 0x83, 0xFE, 0x0F, 0xF8,
|
||||
0x3F, 0xE0, 0xFF, 0x83, 0xFE, 0x0F, 0xF8, 0x3F, 0xE0, 0xFF, 0x83, 0xFE,
|
||||
0x0F, 0xF8, 0x3F, 0xE0, 0xFF, 0x83, 0xFE, 0x0F, 0xF8, 0x3F, 0xE0, 0xFF,
|
||||
0x83, 0xFE, 0x0F, 0x78, 0x7D, 0xF3, 0xF7, 0xFF, 0xCF, 0xEF, 0x1F, 0x3C,
|
||||
0xF0, 0x7F, 0xC1, 0xEF, 0x07, 0xBC, 0x1E, 0x78, 0x79, 0xE1, 0xE7, 0x87,
|
||||
0x9E, 0x1C, 0x78, 0x71, 0xE3, 0xC7, 0x8F, 0x0E, 0x3C, 0x3C, 0xF0, 0xF3,
|
||||
0xC3, 0xCE, 0x0F, 0x38, 0x3C, 0xE0, 0xF3, 0x81, 0xDE, 0x07, 0x78, 0x1F,
|
||||
0xE0, 0x7F, 0x01, 0xFC, 0x07, 0xF0, 0x1F, 0xC0, 0x3F, 0x00, 0xFC, 0x03,
|
||||
0xF0, 0x0F, 0x80, 0xF0, 0x78, 0x7F, 0x87, 0xC3, 0xFC, 0x3E, 0x1F, 0xE1,
|
||||
0xF0, 0xF7, 0x0F, 0x87, 0xB8, 0x7C, 0x39, 0xC3, 0xE1, 0xCE, 0x1F, 0x8E,
|
||||
0x79, 0xDC, 0x73, 0xCE, 0xE7, 0x9E, 0x77, 0x3C, 0xF3, 0xB9, 0xE3, 0x9D,
|
||||
0xCF, 0x1C, 0xE6, 0x70, 0xE7, 0x3B, 0x87, 0x71, 0xDC, 0x3B, 0x8E, 0xE1,
|
||||
0xDC, 0x77, 0x0F, 0xE3, 0xB8, 0x7F, 0x1D, 0xC3, 0xF8, 0xFE, 0x0F, 0x83,
|
||||
0xE0, 0x7C, 0x1F, 0x03, 0xE0, 0xF8, 0x1F, 0x07, 0xC0, 0xF8, 0x3E, 0x07,
|
||||
0xC1, 0xF0, 0x3E, 0x0F, 0x81, 0xE0, 0x7C, 0x00, 0xF0, 0x7B, 0xC1, 0xE7,
|
||||
0x87, 0x9E, 0x3C, 0x78, 0xF0, 0xF3, 0xC3, 0xCE, 0x0F, 0x78, 0x1F, 0xE0,
|
||||
0x7F, 0x01, 0xFC, 0x03, 0xF0, 0x0F, 0x80, 0x3E, 0x00, 0xF8, 0x03, 0xE0,
|
||||
0x0F, 0x80, 0x7F, 0x01, 0xFC, 0x07, 0xF0, 0x3D, 0xE0, 0xF7, 0x83, 0xDE,
|
||||
0x1E, 0x3C, 0x78, 0xF1, 0xE3, 0xCF, 0x07, 0xBC, 0x1E, 0xF0, 0x7C, 0xF0,
|
||||
0x3F, 0xC0, 0xFF, 0x07, 0xFE, 0x1E, 0x78, 0x79, 0xE1, 0xE7, 0x87, 0x9E,
|
||||
0x1E, 0x78, 0x79, 0xE1, 0xC3, 0x87, 0x0F, 0x3C, 0x3C, 0xF0, 0xF3, 0xC3,
|
||||
0xCF, 0x0F, 0x3C, 0x1C, 0xE0, 0x73, 0x81, 0xCE, 0x07, 0xB8, 0x1F, 0xE0,
|
||||
0x7F, 0x80, 0xFC, 0x03, 0xF0, 0x0F, 0xC0, 0x3F, 0x00, 0xFC, 0x03, 0xF0,
|
||||
0x07, 0x80, 0x1E, 0x00, 0xF8, 0x1F, 0xE0, 0x7F, 0x01, 0xFC, 0x00, 0x7F,
|
||||
0xEF, 0xFD, 0xFF, 0xBF, 0xF0, 0x1E, 0x07, 0xC0, 0xF0, 0x1E, 0x07, 0xC0,
|
||||
0xF0, 0x1E, 0x03, 0xC0, 0xF8, 0x1E, 0x03, 0xC0, 0xF8, 0x1E, 0x03, 0xC0,
|
||||
0xF8, 0x1F, 0x03, 0xC0, 0x78, 0x1F, 0x03, 0xC0, 0x78, 0x1F, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFE, 0x07, 0xC3, 0xF1, 0xFC, 0x7E, 0x1E, 0x07, 0x81, 0xE0,
|
||||
0x78, 0x1E, 0x07, 0x81, 0xE0, 0x78, 0x1E, 0x07, 0x81, 0xE0, 0xF8, 0x7E,
|
||||
0x3F, 0x0F, 0x83, 0xF0, 0xFE, 0x0F, 0x81, 0xE0, 0x78, 0x1E, 0x07, 0x81,
|
||||
0xE0, 0x78, 0x1E, 0x07, 0x81, 0xE0, 0x78, 0x1E, 0x07, 0xC1, 0xFC, 0x3F,
|
||||
0x07, 0xC0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xF8, 0x3F, 0x0F,
|
||||
0xC1, 0xF8, 0x3E, 0x07, 0x81, 0xE0, 0x78, 0x1E, 0x07, 0x81, 0xE0, 0x78,
|
||||
0x1E, 0x07, 0x81, 0xE0, 0x78, 0x1F, 0x83, 0xF0, 0x7C, 0x3F, 0x1F, 0xC7,
|
||||
0x81, 0xE0, 0x78, 0x1E, 0x07, 0x81, 0xE0, 0x78, 0x1E, 0x07, 0x81, 0xE0,
|
||||
0x78, 0x3E, 0x0F, 0x8F, 0xC3, 0xF0, 0xF8, 0x00, 0x1E, 0x07, 0x9F, 0xF3,
|
||||
0xDF, 0xFF, 0xDF, 0xFF, 0xEF, 0xFF, 0xE1, 0x03, 0xE0 };
|
||||
0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x66, 0x66, 0x66,
|
||||
0x66, 0x66, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xEF, 0x7B, 0xDE, 0xF7,
|
||||
0x98, 0xC6, 0x00, 0x03, 0x8F, 0x01, 0xC7, 0x80, 0xE3, 0x80, 0xF1, 0xC0,
|
||||
0x70, 0xE0, 0x38, 0x70, 0x1C, 0x78, 0x0E, 0x3C, 0x07, 0x1C, 0x07, 0x8E,
|
||||
0x03, 0x87, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x38, 0xE0, 0x3C,
|
||||
0x70, 0x1E, 0x38, 0x0E, 0x1C, 0x07, 0x0E, 0x03, 0x8F, 0x0F, 0xFF, 0xF7,
|
||||
0xFF, 0xF8, 0xF1, 0xC0, 0x70, 0xE0, 0x38, 0x70, 0x1C, 0x78, 0x0E, 0x3C,
|
||||
0x0F, 0x1C, 0x07, 0x8E, 0x03, 0x87, 0x01, 0xC3, 0x80, 0xE3, 0xC0, 0x71,
|
||||
0xE0, 0x78, 0xE0, 0x00, 0x06, 0x00, 0x30, 0x01, 0x80, 0x0C, 0x00, 0x60,
|
||||
0x1F, 0xC1, 0xFF, 0x9F, 0xFC, 0xFB, 0xF7, 0x87, 0xBC, 0x3D, 0xE1, 0xEF,
|
||||
0x0F, 0x78, 0x7B, 0xE3, 0xDF, 0x00, 0x7C, 0x01, 0xF8, 0x0F, 0xE0, 0x3F,
|
||||
0x80, 0x7C, 0x01, 0xF0, 0x07, 0xC0, 0x3E, 0xF0, 0xF7, 0x87, 0xFC, 0x3F,
|
||||
0xE1, 0xFF, 0x0F, 0xFC, 0x7B, 0xFF, 0xCF, 0xFE, 0x3F, 0xE0, 0xFE, 0x01,
|
||||
0xC0, 0x0E, 0x00, 0x70, 0x03, 0x80, 0x1C, 0x00, 0x1F, 0x80, 0x01, 0xC0,
|
||||
0x07, 0xFE, 0x00, 0x3C, 0x00, 0x7F, 0xE0, 0x03, 0xC0, 0x0F, 0x9F, 0x00,
|
||||
0x38, 0x00, 0xF0, 0xF0, 0x07, 0x80, 0x0F, 0x0F, 0x00, 0x70, 0x00, 0xF0,
|
||||
0xF0, 0x0F, 0x00, 0x0F, 0x0F, 0x00, 0xF0, 0x00, 0xF0, 0xF0, 0x0E, 0x00,
|
||||
0x0F, 0x0F, 0x01, 0xE0, 0x00, 0xF0, 0xF0, 0x1C, 0x00, 0x0F, 0x0F, 0x03,
|
||||
0xC0, 0x60, 0xF0, 0xF0, 0x3C, 0x3F, 0xCF, 0x0F, 0x03, 0x87, 0xFE, 0xF0,
|
||||
0xF0, 0x78, 0xFF, 0xEF, 0x0F, 0x07, 0x8F, 0x0E, 0xF0, 0xF0, 0xF0, 0xF0,
|
||||
0xFF, 0x0F, 0x0F, 0x0E, 0x0F, 0xF0, 0xF0, 0xE0, 0xE0, 0xF7, 0xDF, 0x1E,
|
||||
0x0E, 0x0F, 0x7F, 0xE1, 0xE0, 0xE0, 0xF3, 0xFC, 0x1C, 0x0E, 0x0F, 0x1F,
|
||||
0x83, 0xC0, 0xE0, 0xF0, 0x00, 0x38, 0x0E, 0x0F, 0x00, 0x07, 0x80, 0xE0,
|
||||
0xF0, 0x00, 0x78, 0x0E, 0x0F, 0x00, 0x07, 0x00, 0xE0, 0xF0, 0x00, 0xF0,
|
||||
0x0E, 0x0F, 0x00, 0x0E, 0x00, 0xE0, 0xF0, 0x01, 0xE0, 0x0F, 0x0F, 0x00,
|
||||
0x1E, 0x00, 0xF1, 0xE0, 0x01, 0xC0, 0x0F, 0xFE, 0x00, 0x3C, 0x00, 0x7F,
|
||||
0xC0, 0x03, 0x80, 0x03, 0xF8, 0x03, 0xE0, 0x03, 0xFE, 0x00, 0xFF, 0x80,
|
||||
0x7C, 0xF0, 0x1E, 0x1C, 0x07, 0x87, 0x01, 0xE1, 0xC0, 0x78, 0x70, 0x1E,
|
||||
0x1C, 0x07, 0x8F, 0x00, 0xF3, 0x80, 0x3D, 0xE0, 0x0F, 0x78, 0x01, 0xFC,
|
||||
0x00, 0x7E, 0x00, 0x1F, 0x80, 0x07, 0xC0, 0x03, 0xF0, 0x00, 0xFE, 0x08,
|
||||
0x7F, 0x86, 0x3F, 0xE3, 0x8F, 0x3C, 0xF7, 0x8F, 0x79, 0xE1, 0xFC, 0x78,
|
||||
0x7F, 0x3C, 0x1F, 0x8F, 0x03, 0xE3, 0xC0, 0xF0, 0xF0, 0x3E, 0x1E, 0x1F,
|
||||
0x87, 0xFF, 0xF1, 0xFF, 0xFC, 0x3F, 0xE7, 0x87, 0xF1, 0xE0, 0xFF, 0xFF,
|
||||
0xF7, 0x76, 0x66, 0x66, 0x3E, 0xFF, 0xFF, 0xCF, 0x1E, 0x3C, 0x78, 0xF1,
|
||||
0xE3, 0xC7, 0x8F, 0x1E, 0x3C, 0x78, 0xF1, 0xE3, 0xC7, 0x8F, 0x1E, 0x3C,
|
||||
0x78, 0xF1, 0xE3, 0xC7, 0x8F, 0x1E, 0x3C, 0x78, 0xF1, 0xE3, 0xFB, 0xF7,
|
||||
0xE1, 0xC0, 0xF1, 0xF3, 0xF1, 0xE3, 0xC7, 0xCF, 0x9F, 0x3E, 0x7C, 0xF9,
|
||||
0xF3, 0xE7, 0xCF, 0x9F, 0x3E, 0x7C, 0xF9, 0xF3, 0xE7, 0xCF, 0x9F, 0x3E,
|
||||
0x7C, 0xF9, 0xF3, 0xE7, 0xCF, 0x9F, 0x3E, 0x7B, 0xF7, 0xEF, 0x98, 0x00,
|
||||
0x07, 0x00, 0x1C, 0x04, 0x71, 0x39, 0xCE, 0xFB, 0x7D, 0xFF, 0xC1, 0xFC,
|
||||
0x03, 0xE0, 0x3F, 0xE3, 0xEF, 0xFF, 0x73, 0x99, 0xC6, 0x07, 0x08, 0x1C,
|
||||
0x00, 0x70, 0x00, 0x0F, 0x00, 0xF0, 0x0F, 0x00, 0xF0, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xF0, 0xF0, 0x0F, 0x00, 0xF0, 0x0F, 0x00, 0xF0, 0xFF, 0xFF, 0xFF,
|
||||
0x8C, 0xE7, 0x31, 0x9C, 0xC0, 0xFF, 0xFF, 0xFF, 0xE0, 0xFF, 0xFF, 0x00,
|
||||
0xF8, 0x07, 0x80, 0x3C, 0x01, 0xE0, 0x0E, 0x00, 0xF0, 0x07, 0x80, 0x3C,
|
||||
0x01, 0xC0, 0x1E, 0x00, 0xF0, 0x07, 0x80, 0x38, 0x03, 0xC0, 0x1E, 0x00,
|
||||
0xF0, 0x07, 0x80, 0x78, 0x03, 0xC0, 0x1E, 0x00, 0xF0, 0x0F, 0x00, 0x78,
|
||||
0x03, 0xC0, 0x1E, 0x01, 0xE0, 0x0F, 0x00, 0x78, 0x03, 0xC0, 0x3C, 0x01,
|
||||
0xE0, 0x0F, 0x00, 0x78, 0x07, 0x80, 0x00, 0x0F, 0xC1, 0xFF, 0x9F, 0xFC,
|
||||
0xFF, 0xF7, 0x8F, 0xFC, 0x3F, 0xE1, 0xFF, 0x0F, 0xF8, 0x7F, 0xC3, 0xFE,
|
||||
0x1F, 0xF0, 0xFF, 0x87, 0xFC, 0x3F, 0xE1, 0xFF, 0x0F, 0xF8, 0x7F, 0xC3,
|
||||
0xFE, 0x1F, 0xF0, 0xFF, 0x87, 0xFC, 0x3F, 0xE1, 0xFF, 0x0F, 0xF8, 0x7F,
|
||||
0xC3, 0xFE, 0x1F, 0xF0, 0xFF, 0x87, 0xBC, 0x7D, 0xF7, 0xEF, 0xFE, 0x3F,
|
||||
0xF0, 0xFF, 0x00, 0x03, 0x83, 0xC3, 0xE3, 0xFF, 0xFF, 0xFF, 0xFF, 0x9F,
|
||||
0x0F, 0x87, 0xC3, 0xE1, 0xF0, 0xF8, 0x7C, 0x3E, 0x1F, 0x0F, 0x87, 0xC3,
|
||||
0xE1, 0xF0, 0xF8, 0x7C, 0x3E, 0x1F, 0x0F, 0x87, 0xC3, 0xE1, 0xF0, 0xF8,
|
||||
0x7C, 0x3E, 0x1F, 0x0F, 0x87, 0xC0, 0x0F, 0x81, 0xFF, 0x1F, 0xF8, 0xFF,
|
||||
0xEF, 0x8F, 0x7C, 0x7B, 0xC3, 0xDE, 0x1E, 0xF0, 0xFF, 0x87, 0xFC, 0x3F,
|
||||
0xE1, 0xEF, 0x0F, 0x78, 0x78, 0x07, 0xC0, 0x3C, 0x03, 0xE0, 0x1E, 0x01,
|
||||
0xF0, 0x0F, 0x00, 0xF8, 0x07, 0x80, 0x7C, 0x07, 0xC0, 0x3E, 0x03, 0xE0,
|
||||
0x1F, 0x00, 0xF0, 0x07, 0x80, 0x7C, 0x03, 0xE0, 0x1F, 0xFE, 0xFF, 0xF7,
|
||||
0xFF, 0x80, 0x0F, 0xC0, 0xFF, 0x87, 0xFF, 0x1F, 0xFE, 0x78, 0xFB, 0xE1,
|
||||
0xEF, 0x87, 0xBC, 0x1E, 0xF0, 0x7B, 0xC1, 0xE0, 0x07, 0x80, 0x1E, 0x00,
|
||||
0x78, 0x03, 0xE0, 0x3F, 0x01, 0xF8, 0x07, 0xE0, 0x1F, 0xC0, 0x0F, 0x00,
|
||||
0x3E, 0x00, 0x78, 0x01, 0xE0, 0x07, 0xBC, 0x1E, 0xF0, 0x7F, 0xC1, 0xFF,
|
||||
0x07, 0xBC, 0x1E, 0xF0, 0x7B, 0xE1, 0xE7, 0xDF, 0x9F, 0xFC, 0x3F, 0xE0,
|
||||
0x7F, 0x00, 0x01, 0xF0, 0x07, 0xC0, 0x3F, 0x00, 0xFC, 0x03, 0xF0, 0x1F,
|
||||
0xC0, 0x7F, 0x01, 0xFC, 0x06, 0xF0, 0x3B, 0xC0, 0xEF, 0x03, 0xBC, 0x1C,
|
||||
0xF0, 0x73, 0xC1, 0xCF, 0x0F, 0x3C, 0x38, 0xF0, 0xE3, 0xC7, 0x8F, 0x1C,
|
||||
0x3C, 0x70, 0xF1, 0xC3, 0xCF, 0x0F, 0x38, 0x3C, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0x00, 0xF0, 0x03, 0xC0, 0x0F, 0x00, 0x3C, 0x00, 0xF0,
|
||||
0x03, 0xC0, 0xFF, 0xEF, 0xFE, 0xFF, 0xEF, 0xFE, 0xF0, 0x0F, 0x00, 0xF0,
|
||||
0x0F, 0x00, 0xF0, 0x0F, 0x00, 0xF3, 0x0F, 0xFC, 0xFF, 0xEF, 0xFE, 0xF9,
|
||||
0xEF, 0x1F, 0xF0, 0xF1, 0x0F, 0x00, 0xF0, 0x0F, 0x00, 0xF0, 0x0F, 0x00,
|
||||
0xF0, 0x0F, 0xF0, 0xFF, 0x0F, 0xF0, 0xFF, 0x0F, 0xF0, 0xFF, 0x1F, 0xFB,
|
||||
0xEF, 0xFE, 0x7F, 0xC3, 0xF8, 0x0F, 0xC0, 0xFF, 0x83, 0xFF, 0x1F, 0xFC,
|
||||
0x78, 0xF9, 0xE1, 0xEF, 0x87, 0xBE, 0x1E, 0xF8, 0x7B, 0xE1, 0xEF, 0x80,
|
||||
0x3E, 0x00, 0xF8, 0x03, 0xEF, 0x8F, 0xFF, 0x3F, 0xFE, 0xFF, 0xFB, 0xE1,
|
||||
0xEF, 0x87, 0xBE, 0x1E, 0xF8, 0x7F, 0xE1, 0xFF, 0x87, 0xFE, 0x1F, 0xF8,
|
||||
0x7F, 0xE1, 0xFF, 0x87, 0xFE, 0x1F, 0xF8, 0x79, 0xE1, 0xE7, 0xFF, 0x9F,
|
||||
0xFE, 0x3F, 0xF0, 0x7F, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0x00, 0x7C, 0x01, 0xE0, 0x0F, 0x80, 0x3C, 0x00, 0xF0, 0x07, 0xC0, 0x1E,
|
||||
0x00, 0x78, 0x03, 0xE0, 0x0F, 0x80, 0x3C, 0x00, 0xF0, 0x07, 0xC0, 0x1E,
|
||||
0x00, 0x78, 0x03, 0xE0, 0x0F, 0x80, 0x3C, 0x00, 0xF0, 0x07, 0xC0, 0x1F,
|
||||
0x00, 0x7C, 0x01, 0xF0, 0x07, 0x80, 0x1E, 0x00, 0xF8, 0x03, 0xE0, 0x0F,
|
||||
0x80, 0x3E, 0x00, 0xF8, 0x00, 0x1F, 0xC1, 0xFF, 0x1F, 0xFC, 0xFB, 0xFF,
|
||||
0x8F, 0xFC, 0x3F, 0xC1, 0xFE, 0x0F, 0xF0, 0x7F, 0x83, 0xFC, 0x1F, 0xE0,
|
||||
0xFF, 0x87, 0xBC, 0x79, 0xFF, 0xC7, 0xFC, 0x3F, 0xE3, 0xFF, 0x9E, 0x3D,
|
||||
0xF1, 0xFF, 0x07, 0xF8, 0x3F, 0xC1, 0xFE, 0x0F, 0xF0, 0x7F, 0x83, 0xFC,
|
||||
0x1F, 0xE0, 0xFF, 0x07, 0xFC, 0x3F, 0xF7, 0xEF, 0xFE, 0x3F, 0xF0, 0xFE,
|
||||
0x00, 0x1F, 0x81, 0xFF, 0x1F, 0xFD, 0xFF, 0xEF, 0x8F, 0x78, 0x7F, 0xC3,
|
||||
0xFE, 0x0F, 0xF0, 0x7F, 0x83, 0xFC, 0x1F, 0xE0, 0xFF, 0x07, 0xF8, 0x3F,
|
||||
0xC1, 0xFE, 0x0F, 0xF0, 0x7F, 0xC7, 0xDF, 0xFE, 0xFF, 0xF3, 0xFF, 0x80,
|
||||
0x3C, 0x01, 0xE0, 0x0F, 0xF0, 0x7F, 0x83, 0xFC, 0x1F, 0xE0, 0xFF, 0x0F,
|
||||
0xFC, 0x79, 0xF7, 0xCF, 0xFE, 0x3F, 0xE0, 0xFE, 0x00, 0xFF, 0xFF, 0xF0,
|
||||
0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xF3, 0x9C, 0xCE, 0x73, 0x98,
|
||||
0x00, 0x20, 0x0C, 0x07, 0x81, 0xF0, 0xFE, 0x3F, 0x9F, 0xC7, 0xF0, 0xF8,
|
||||
0x1C, 0x03, 0xE0, 0x7E, 0x07, 0xF0, 0x3F, 0x03, 0xF8, 0x1F, 0x01, 0xE0,
|
||||
0x0C, 0x00, 0x80, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x0F, 0xFF,
|
||||
0xFF, 0xFF, 0xC0, 0x80, 0x18, 0x03, 0x80, 0x7C, 0x0F, 0xC0, 0xFE, 0x07,
|
||||
0xF0, 0x7F, 0x03, 0xE0, 0x3C, 0x0F, 0x83, 0xF1, 0xFC, 0xFE, 0x3F, 0x87,
|
||||
0xC0, 0xF0, 0x18, 0x02, 0x00, 0x00, 0x1F, 0x87, 0xFC, 0x7F, 0xEF, 0xFE,
|
||||
0xF1, 0xEF, 0x1F, 0xF1, 0xFF, 0x1F, 0xF1, 0xFF, 0x1F, 0xF1, 0xFF, 0x1F,
|
||||
0x01, 0xF0, 0x1E, 0x01, 0xE0, 0x3E, 0x03, 0xE0, 0xFC, 0x3F, 0x83, 0xF0,
|
||||
0x3C, 0x03, 0xC0, 0x3C, 0x03, 0xC0, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x3C, 0x03, 0xC0, 0x3C, 0x03, 0xC0, 0x3C, 0x03, 0xC0, 0x00, 0x3F, 0x80,
|
||||
0x00, 0xFF, 0xF0, 0x00, 0xFF, 0xFC, 0x00, 0xF8, 0x0F, 0x00, 0xF0, 0x03,
|
||||
0xC0, 0xF0, 0x00, 0xF0, 0xF0, 0x00, 0x38, 0x78, 0x00, 0x1C, 0x38, 0x1F,
|
||||
0x87, 0x3C, 0x3F, 0xE3, 0x9E, 0x1E, 0xF1, 0xCE, 0x1C, 0x38, 0xE7, 0x0E,
|
||||
0x1C, 0x77, 0x8E, 0x0E, 0x1F, 0xC7, 0x07, 0x0F, 0xE3, 0x83, 0x87, 0xF1,
|
||||
0xC1, 0xC3, 0xF8, 0xE0, 0xE1, 0xFC, 0x70, 0x70, 0xFE, 0x38, 0x38, 0x7F,
|
||||
0x1C, 0x1C, 0x77, 0x8E, 0x0E, 0x39, 0xC7, 0x07, 0x1C, 0xE3, 0xC7, 0xCE,
|
||||
0x70, 0xF6, 0xFE, 0x3C, 0x7F, 0x3F, 0x1E, 0x1F, 0x0F, 0x07, 0x81, 0x00,
|
||||
0x03, 0xC0, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x1F, 0x80,
|
||||
0x70, 0x07, 0xFF, 0xF8, 0x00, 0xFF, 0xFE, 0x00, 0x1F, 0xF0, 0x00, 0x07,
|
||||
0xC0, 0x07, 0xE0, 0x0F, 0xE0, 0x0F, 0xE0, 0x0F, 0xE0, 0x0F, 0xE0, 0x0F,
|
||||
0xE0, 0x0F, 0xF0, 0x0E, 0xF0, 0x1E, 0xF0, 0x1E, 0xF0, 0x1E, 0xF0, 0x1E,
|
||||
0xF0, 0x1E, 0x70, 0x1E, 0x78, 0x1C, 0x78, 0x3C, 0x78, 0x3C, 0x78, 0x3C,
|
||||
0x78, 0x3C, 0x78, 0x3C, 0x3C, 0x3C, 0x3C, 0x7C, 0x3C, 0x78, 0x3C, 0x7F,
|
||||
0xFC, 0x7F, 0xFC, 0x7F, 0xFE, 0x7F, 0xFE, 0x78, 0x1E, 0xF8, 0x1E, 0xF8,
|
||||
0x1E, 0xF0, 0x1E, 0xF0, 0x1F, 0xF0, 0x1F, 0xFF, 0x03, 0xFF, 0x8F, 0xFF,
|
||||
0x3F, 0xFC, 0xF0, 0xFB, 0xC3, 0xEF, 0x07, 0xBC, 0x1E, 0xF0, 0x7B, 0xC1,
|
||||
0xEF, 0x07, 0xBC, 0x3E, 0xF0, 0xFB, 0xC3, 0xCF, 0xFF, 0x3F, 0xF8, 0xFF,
|
||||
0xF3, 0xFF, 0xCF, 0x0F, 0xBC, 0x1E, 0xF0, 0x7B, 0xC1, 0xEF, 0x07, 0xFC,
|
||||
0x1F, 0xF0, 0x7F, 0xC1, 0xFF, 0x07, 0xBC, 0x1E, 0xF0, 0x7B, 0xC3, 0xEF,
|
||||
0xFF, 0xBF, 0xFC, 0xFF, 0xE3, 0xFF, 0x00, 0x0F, 0xC0, 0x7F, 0xC3, 0xFF,
|
||||
0x9F, 0xFE, 0x7C, 0x79, 0xE1, 0xFF, 0x87, 0xFE, 0x0F, 0xF8, 0x3F, 0xE0,
|
||||
0xFF, 0x83, 0xFE, 0x0F, 0xF8, 0x3F, 0xE0, 0x0F, 0x80, 0x3E, 0x00, 0xF8,
|
||||
0x03, 0xE0, 0x0F, 0x80, 0x3E, 0x00, 0xF8, 0x3F, 0xE0, 0xFF, 0x83, 0xFE,
|
||||
0x0F, 0xF8, 0x3F, 0xE0, 0xFF, 0x83, 0xFE, 0x1F, 0x78, 0x7D, 0xE1, 0xE7,
|
||||
0xEF, 0x8F, 0xFE, 0x3F, 0xF0, 0x3F, 0x80, 0xFF, 0x07, 0xFF, 0x3F, 0xFD,
|
||||
0xFF, 0xEF, 0x0F, 0xF8, 0x7F, 0xC1, 0xFE, 0x0F, 0xF0, 0x7F, 0x83, 0xFC,
|
||||
0x1F, 0xE0, 0xFF, 0x07, 0xF8, 0x3F, 0xC1, 0xFE, 0x0F, 0xF0, 0x7F, 0x83,
|
||||
0xFC, 0x1F, 0xE0, 0xFF, 0x07, 0xF8, 0x3F, 0xC1, 0xFE, 0x0F, 0xF0, 0x7F,
|
||||
0x83, 0xFC, 0x1F, 0xE0, 0xFF, 0x07, 0xF8, 0x7F, 0xFF, 0xDF, 0xFE, 0xFF,
|
||||
0xE7, 0xFC, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x3C, 0x0F, 0x03,
|
||||
0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F,
|
||||
0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0x03,
|
||||
0xC0, 0xF0, 0x3C, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0xC0, 0xF0,
|
||||
0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F,
|
||||
0x03, 0xC0, 0xF0, 0x3C, 0x00, 0x0F, 0xE0, 0x7F, 0xC3, 0xFF, 0x9F, 0xFE,
|
||||
0x7C, 0x7D, 0xE0, 0xFF, 0x83, 0xFE, 0x0F, 0xF8, 0x3F, 0xE0, 0xFF, 0x83,
|
||||
0xFE, 0x0F, 0xF8, 0x03, 0xE0, 0x0F, 0x80, 0x3E, 0x00, 0xF9, 0xFF, 0xE7,
|
||||
0xFF, 0x9F, 0xFE, 0x0F, 0xF8, 0x3F, 0xE0, 0xFF, 0x83, 0xFE, 0x0F, 0xF8,
|
||||
0x3F, 0xE0, 0xFF, 0x83, 0xFE, 0x0F, 0x78, 0x3D, 0xE1, 0xF7, 0xEF, 0xCF,
|
||||
0xFF, 0x3F, 0xEC, 0x3F, 0x30, 0xF0, 0x7F, 0xC1, 0xFF, 0x07, 0xFC, 0x1F,
|
||||
0xF0, 0x7F, 0xC1, 0xFF, 0x07, 0xFC, 0x1F, 0xF0, 0x7F, 0xC1, 0xFF, 0x07,
|
||||
0xFC, 0x1F, 0xF0, 0x7F, 0xC1, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0x07, 0xFC, 0x1F, 0xF0, 0x7F, 0xC1, 0xFF, 0x07, 0xFC, 0x1F, 0xF0,
|
||||
0x7F, 0xC1, 0xFF, 0x07, 0xFC, 0x1F, 0xF0, 0x7F, 0xC1, 0xFF, 0x07, 0xFC,
|
||||
0x1F, 0xF0, 0x7F, 0xC1, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xF8,
|
||||
0x07, 0xC0, 0x3E, 0x01, 0xF0, 0x0F, 0x80, 0x7C, 0x03, 0xE0, 0x1F, 0x00,
|
||||
0xF8, 0x07, 0xC0, 0x3E, 0x01, 0xF0, 0x0F, 0x80, 0x7C, 0x03, 0xE0, 0x1F,
|
||||
0x00, 0xF8, 0x07, 0xC0, 0x3E, 0x01, 0xF0, 0x0F, 0xF8, 0x7F, 0xC3, 0xFE,
|
||||
0x1F, 0xF0, 0xFF, 0x87, 0xFC, 0x3F, 0xE1, 0xEF, 0x0F, 0x78, 0x7B, 0xF7,
|
||||
0xCF, 0xFC, 0x7F, 0xE1, 0xFE, 0x00, 0xF0, 0x3D, 0xE0, 0xFB, 0xC1, 0xE7,
|
||||
0x83, 0xCF, 0x0F, 0x9E, 0x1E, 0x3C, 0x3C, 0x78, 0xF8, 0xF1, 0xE1, 0xE7,
|
||||
0xC3, 0xCF, 0x87, 0x9E, 0x0F, 0x7C, 0x1E, 0xF8, 0x3D, 0xE0, 0x7F, 0xC0,
|
||||
0xFF, 0x01, 0xFE, 0x03, 0xFE, 0x07, 0xBC, 0x0F, 0x7C, 0x1E, 0xF8, 0x3C,
|
||||
0xF0, 0x79, 0xF0, 0xF1, 0xE1, 0xE3, 0xC3, 0xC7, 0xC7, 0x87, 0x8F, 0x0F,
|
||||
0x9E, 0x1F, 0x3C, 0x1E, 0x78, 0x3E, 0xF0, 0x7D, 0xE0, 0x7C, 0xF0, 0x3C,
|
||||
0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0x03,
|
||||
0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0,
|
||||
0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xF8, 0x01, 0xFF, 0x80, 0x1F, 0xF8, 0x03,
|
||||
0xFF, 0xC0, 0x3F, 0xFC, 0x03, 0xFF, 0xC0, 0x3F, 0xFC, 0x03, 0xFF, 0xC0,
|
||||
0x7F, 0xFE, 0x07, 0xFF, 0xE0, 0x7F, 0xFE, 0x07, 0xFE, 0xE0, 0x7F, 0xEE,
|
||||
0x0F, 0xFE, 0xF0, 0xFF, 0xEF, 0x0E, 0xFE, 0x70, 0xEF, 0xE7, 0x0E, 0xFE,
|
||||
0x70, 0xEF, 0xE7, 0x1E, 0xFE, 0x79, 0xCF, 0xE3, 0x9C, 0xFF, 0x39, 0xCF,
|
||||
0xF3, 0x9C, 0xFF, 0x3B, 0xCF, 0xF3, 0xF8, 0xFF, 0x1F, 0x8F, 0xF1, 0xF8,
|
||||
0xFF, 0x1F, 0x8F, 0xF1, 0xF8, 0xFF, 0x1F, 0x8F, 0xF0, 0xF0, 0xFF, 0x0F,
|
||||
0x0F, 0xF0, 0xF0, 0xFF, 0x0F, 0x0F, 0xE0, 0x3F, 0x80, 0xFF, 0x03, 0xFC,
|
||||
0x0F, 0xF8, 0x3F, 0xE0, 0xFF, 0x83, 0xFF, 0x0F, 0xFC, 0x3F, 0xF0, 0xFF,
|
||||
0xE3, 0xFF, 0x8F, 0xFE, 0x3F, 0xFC, 0xFF, 0xF3, 0xFD, 0xCF, 0xF7, 0xBF,
|
||||
0xDE, 0xFF, 0x3B, 0xFC, 0xFF, 0xF3, 0xDF, 0xC7, 0x7F, 0x1F, 0xFC, 0x7F,
|
||||
0xF0, 0xFF, 0xC3, 0xFF, 0x0F, 0xFC, 0x1F, 0xF0, 0x7F, 0xC1, 0xFF, 0x03,
|
||||
0xFC, 0x0F, 0xF0, 0x3F, 0xC0, 0x70, 0x0F, 0xE0, 0x7F, 0xC3, 0xFF, 0x9F,
|
||||
0xFE, 0x7C, 0x7D, 0xE1, 0xFF, 0x83, 0xFE, 0x0F, 0xF8, 0x3F, 0xE0, 0xFF,
|
||||
0x83, 0xFE, 0x0F, 0xF8, 0x3F, 0xE0, 0xFF, 0x83, 0xFE, 0x0F, 0xF8, 0x3F,
|
||||
0xE0, 0xFF, 0x83, 0xFE, 0x0F, 0xF8, 0x3F, 0xE0, 0xFF, 0x83, 0xFE, 0x0F,
|
||||
0xF8, 0x3F, 0xE0, 0xFF, 0x83, 0xFE, 0x0F, 0x78, 0x7D, 0xE1, 0xF7, 0xFF,
|
||||
0x8F, 0xFE, 0x3F, 0xF0, 0x3F, 0x80, 0xFF, 0x87, 0xFF, 0x3F, 0xFD, 0xFF,
|
||||
0xEF, 0x0F, 0xF8, 0x3F, 0xC1, 0xFE, 0x0F, 0xF0, 0x7F, 0x83, 0xFC, 0x1F,
|
||||
0xE0, 0xFF, 0x07, 0xF8, 0x3F, 0xC1, 0xFE, 0x1F, 0xF0, 0xFF, 0xFF, 0xBF,
|
||||
0xFD, 0xFF, 0xCF, 0xF8, 0x78, 0x03, 0xC0, 0x1E, 0x00, 0xF0, 0x07, 0x80,
|
||||
0x3C, 0x01, 0xE0, 0x0F, 0x00, 0x78, 0x03, 0xC0, 0x1E, 0x00, 0xF0, 0x07,
|
||||
0x80, 0x00, 0x0F, 0xE0, 0x7F, 0xC3, 0xFF, 0x9F, 0xFE, 0x7C, 0x7D, 0xE1,
|
||||
0xFF, 0x83, 0xFE, 0x0F, 0xF8, 0x3F, 0xE0, 0xFF, 0x83, 0xFE, 0x0F, 0xF8,
|
||||
0x3F, 0xE0, 0xFF, 0x83, 0xFE, 0x0F, 0xF8, 0x3F, 0xE0, 0xFF, 0x83, 0xFE,
|
||||
0x0F, 0xF8, 0x3F, 0xE0, 0xFF, 0x83, 0xFE, 0x0F, 0xF8, 0x3F, 0xE0, 0xFF,
|
||||
0x83, 0xFE, 0x0F, 0x78, 0x7D, 0xE1, 0xF7, 0xFF, 0x8F, 0xFE, 0x3F, 0xF0,
|
||||
0x3F, 0x80, 0x1E, 0x00, 0x3C, 0x00, 0x78, 0x01, 0xE0, 0x03, 0x00, 0xFF,
|
||||
0x83, 0xFF, 0x8F, 0xFF, 0x3F, 0xFE, 0xF0, 0xFB, 0xC1, 0xEF, 0x07, 0xBC,
|
||||
0x1E, 0xF0, 0x7B, 0xC1, 0xEF, 0x07, 0xBC, 0x1E, 0xF0, 0x7B, 0xC3, 0xEF,
|
||||
0x1F, 0x3F, 0xFC, 0xFF, 0xE3, 0xFF, 0xCF, 0x0F, 0xBC, 0x1E, 0xF0, 0x7B,
|
||||
0xC1, 0xEF, 0x07, 0xBC, 0x1E, 0xF0, 0x7B, 0xC1, 0xEF, 0x07, 0xBC, 0x1E,
|
||||
0xF0, 0x7B, 0xC1, 0xEF, 0x07, 0xBC, 0x1E, 0xF0, 0x7B, 0xC1, 0xF0, 0x0F,
|
||||
0xC0, 0xFF, 0xC3, 0xFF, 0x1F, 0xFE, 0x78, 0x79, 0xE1, 0xEF, 0x87, 0xBE,
|
||||
0x1F, 0xF8, 0x7D, 0xE1, 0xF7, 0x87, 0xDF, 0x1F, 0x7E, 0x00, 0xFC, 0x01,
|
||||
0xF8, 0x03, 0xF0, 0x0F, 0xE0, 0x1F, 0x80, 0x3F, 0x00, 0x7E, 0x00, 0xF9,
|
||||
0xE1, 0xF7, 0x87, 0xDE, 0x0F, 0x78, 0x3D, 0xE0, 0xF7, 0x83, 0xDE, 0x0F,
|
||||
0x78, 0x3D, 0xE1, 0xF7, 0xEF, 0x8F, 0xFE, 0x3F, 0xF0, 0x3F, 0x80, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x80, 0xF8, 0x0F, 0x80, 0xF8, 0x0F,
|
||||
0x80, 0xF8, 0x0F, 0x80, 0xF8, 0x0F, 0x80, 0xF8, 0x0F, 0x80, 0xF8, 0x0F,
|
||||
0x80, 0xF8, 0x0F, 0x80, 0xF8, 0x0F, 0x80, 0xF8, 0x0F, 0x80, 0xF8, 0x0F,
|
||||
0x80, 0xF8, 0x0F, 0x80, 0xF8, 0x0F, 0x80, 0xF8, 0x0F, 0x80, 0xF8, 0x0F,
|
||||
0x80, 0xF8, 0xF8, 0x3F, 0xE0, 0xFF, 0x83, 0xFE, 0x0F, 0xF8, 0x3F, 0xE0,
|
||||
0xFF, 0x83, 0xFE, 0x0F, 0xF8, 0x3F, 0xE0, 0xFF, 0x83, 0xFE, 0x0F, 0xF8,
|
||||
0x3F, 0xE0, 0xFF, 0x83, 0xFE, 0x0F, 0xF8, 0x3F, 0xE0, 0xFF, 0x83, 0xFE,
|
||||
0x0F, 0xF8, 0x3F, 0xE0, 0xFF, 0x83, 0xFE, 0x0F, 0xF8, 0x3F, 0xE0, 0xFF,
|
||||
0x83, 0xFE, 0x0F, 0x78, 0x3D, 0xE1, 0xF7, 0xEF, 0xCF, 0xFE, 0x3F, 0xF8,
|
||||
0x7F, 0x80, 0xF0, 0x1F, 0xF0, 0x1E, 0xF0, 0x1E, 0xF0, 0x1E, 0xF8, 0x1E,
|
||||
0x78, 0x1E, 0x78, 0x1E, 0x78, 0x3C, 0x78, 0x3C, 0x78, 0x3C, 0x7C, 0x3C,
|
||||
0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x78, 0x3C, 0x78, 0x3C, 0x78,
|
||||
0x1E, 0x78, 0x1E, 0x78, 0x1E, 0x78, 0x1E, 0x78, 0x1E, 0x70, 0x1E, 0xF0,
|
||||
0x0E, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xE0,
|
||||
0x0F, 0xE0, 0x07, 0xE0, 0x07, 0xE0, 0x07, 0xE0, 0x07, 0xE0, 0xF0, 0x3C,
|
||||
0x0F, 0xF0, 0x3C, 0x0F, 0xF0, 0x3C, 0x0F, 0xF0, 0x3C, 0x1E, 0xF0, 0x3C,
|
||||
0x1E, 0x78, 0x3E, 0x1E, 0x78, 0x7E, 0x1E, 0x78, 0x7E, 0x1E, 0x78, 0x7E,
|
||||
0x1E, 0x78, 0x7E, 0x1E, 0x78, 0x7E, 0x1E, 0x78, 0x7E, 0x1E, 0x38, 0x7F,
|
||||
0x1C, 0x38, 0xF7, 0x1C, 0x3C, 0xF7, 0x3C, 0x3C, 0xE7, 0x3C, 0x3C, 0xE7,
|
||||
0x3C, 0x3C, 0xE7, 0x3C, 0x3C, 0xE7, 0x3C, 0x3C, 0xE7, 0xBC, 0x1D, 0xE3,
|
||||
0xB8, 0x1D, 0xC3, 0xB8, 0x1D, 0xC3, 0xB8, 0x1F, 0xC3, 0xB8, 0x1F, 0xC3,
|
||||
0xB8, 0x1F, 0xC3, 0xF8, 0x1F, 0xC3, 0xF8, 0x1F, 0xC1, 0xF8, 0x0F, 0x81,
|
||||
0xF8, 0x0F, 0x81, 0xF0, 0x0F, 0x81, 0xF0, 0x0F, 0x81, 0xF0, 0x0F, 0x81,
|
||||
0xF0, 0x0F, 0x81, 0xF0, 0xF0, 0x3F, 0xC0, 0xF7, 0x07, 0x9E, 0x1E, 0x78,
|
||||
0x78, 0xE3, 0xE3, 0xCF, 0x0F, 0x3C, 0x3C, 0xF0, 0x7F, 0x81, 0xFE, 0x07,
|
||||
0xF8, 0x0F, 0xE0, 0x3F, 0x00, 0xFC, 0x01, 0xF0, 0x07, 0x80, 0x3E, 0x00,
|
||||
0xF8, 0x03, 0xF0, 0x0F, 0xC0, 0x7F, 0x01, 0xFE, 0x07, 0xF8, 0x3F, 0xE0,
|
||||
0xF3, 0xC3, 0xCF, 0x0F, 0x3C, 0x78, 0x71, 0xE1, 0xE7, 0x87, 0x9E, 0x0E,
|
||||
0xF0, 0x3F, 0xC0, 0xF0, 0xF8, 0x0F, 0x78, 0x1F, 0x78, 0x1E, 0x7C, 0x1E,
|
||||
0x3C, 0x1E, 0x3C, 0x3E, 0x3C, 0x3C, 0x3E, 0x3C, 0x1E, 0x3C, 0x1E, 0x78,
|
||||
0x1E, 0x78, 0x0F, 0x78, 0x0F, 0x78, 0x0F, 0xF0, 0x0F, 0xF0, 0x07, 0xF0,
|
||||
0x07, 0xF0, 0x07, 0xE0, 0x03, 0xE0, 0x03, 0xE0, 0x03, 0xE0, 0x03, 0xE0,
|
||||
0x03, 0xE0, 0x03, 0xE0, 0x03, 0xE0, 0x03, 0xE0, 0x03, 0xE0, 0x03, 0xE0,
|
||||
0x03, 0xE0, 0x03, 0xE0, 0x03, 0xE0, 0x03, 0xE0, 0x03, 0xE0, 0x03, 0xE0,
|
||||
0x7F, 0xF7, 0xFF, 0x7F, 0xF7, 0xFF, 0x01, 0xF0, 0x1E, 0x01, 0xE0, 0x3E,
|
||||
0x03, 0xE0, 0x3C, 0x07, 0xC0, 0x7C, 0x07, 0xC0, 0x78, 0x0F, 0x80, 0xF8,
|
||||
0x0F, 0x80, 0xF0, 0x1F, 0x01, 0xF0, 0x1E, 0x01, 0xE0, 0x3E, 0x03, 0xE0,
|
||||
0x3C, 0x07, 0xC0, 0x7C, 0x07, 0xC0, 0x78, 0x0F, 0x80, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0,
|
||||
0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0,
|
||||
0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xFF,
|
||||
0xFF, 0xFF, 0xF0, 0x1E, 0x03, 0xC0, 0x78, 0x07, 0x00, 0xF0, 0x1E, 0x03,
|
||||
0xC0, 0x78, 0x07, 0x80, 0xF0, 0x1E, 0x03, 0xC0, 0x3C, 0x07, 0x80, 0xF0,
|
||||
0x1E, 0x01, 0xC0, 0x3C, 0x07, 0x80, 0xF0, 0x0E, 0x01, 0xE0, 0x3C, 0x07,
|
||||
0x80, 0xF0, 0x0F, 0x01, 0xE0, 0x3C, 0x07, 0x80, 0x78, 0x0F, 0x01, 0xE0,
|
||||
0x3C, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F,
|
||||
0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F,
|
||||
0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0xFF, 0xFF, 0xFF,
|
||||
0x0F, 0xC0, 0x1F, 0x80, 0x3F, 0x80, 0x7F, 0x01, 0xFE, 0x03, 0xDC, 0x07,
|
||||
0xBC, 0x0E, 0x78, 0x3C, 0xF0, 0x79, 0xE0, 0xF1, 0xE1, 0xE3, 0xC7, 0x87,
|
||||
0x8F, 0x0F, 0x1E, 0x0F, 0x3C, 0x1E, 0xF8, 0x3D, 0xE0, 0x7C, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xF0, 0xF9, 0xE7, 0x8E, 0x38, 0x71, 0xC3, 0x0F, 0xC0, 0xFF,
|
||||
0xC3, 0xFF, 0x1F, 0xFE, 0x78, 0x79, 0xE1, 0xEF, 0x87, 0xBE, 0x1E, 0xF8,
|
||||
0x7C, 0x01, 0xF0, 0x07, 0xC0, 0x7F, 0x0F, 0xFC, 0x7F, 0xF3, 0xE7, 0xDE,
|
||||
0x1F, 0xF8, 0x7F, 0xE1, 0xFF, 0x87, 0xFE, 0x1F, 0xF8, 0x7F, 0xE1, 0xFF,
|
||||
0x87, 0xFE, 0x1F, 0xF8, 0x7D, 0xE3, 0xF7, 0xFF, 0xDF, 0xFF, 0x3F, 0x7C,
|
||||
0xF0, 0x07, 0x80, 0x3C, 0x01, 0xE0, 0x0F, 0x00, 0x79, 0xE3, 0xDF, 0x9F,
|
||||
0xFE, 0xFF, 0xFF, 0xC7, 0xFC, 0x1F, 0xE0, 0xFF, 0x07, 0xF8, 0x3F, 0xC1,
|
||||
0xFE, 0x0F, 0xF0, 0x7F, 0x83, 0xFC, 0x1F, 0xE0, 0xFF, 0x07, 0xF8, 0x3F,
|
||||
0xC1, 0xFE, 0x0F, 0xF0, 0x7F, 0x83, 0xFC, 0x1F, 0xE0, 0xFF, 0x07, 0xFC,
|
||||
0x7F, 0xF7, 0xFF, 0xFE, 0xF7, 0xF7, 0x9F, 0x00, 0x0F, 0xC1, 0xFF, 0x8F,
|
||||
0xFC, 0xFF, 0xF7, 0x87, 0xBC, 0x3F, 0xE1, 0xFF, 0x0F, 0xF8, 0x7F, 0xC3,
|
||||
0xFE, 0x1F, 0xF0, 0x0F, 0x80, 0x7C, 0x03, 0xE0, 0x1F, 0x00, 0xF8, 0x07,
|
||||
0xC0, 0x3E, 0x1F, 0xF0, 0xFF, 0x87, 0xFC, 0x3F, 0xE1, 0xEF, 0x0F, 0x78,
|
||||
0x7B, 0xE7, 0xDF, 0xFC, 0x7F, 0xE1, 0xFE, 0x00, 0x00, 0x7C, 0x01, 0xF0,
|
||||
0x07, 0xC0, 0x1F, 0x00, 0x7C, 0x7D, 0xF3, 0xFF, 0xDF, 0xFF, 0x7F, 0xFD,
|
||||
0xE1, 0xFF, 0x87, 0xFE, 0x1F, 0xF8, 0x7F, 0xE1, 0xFF, 0x87, 0xFE, 0x1F,
|
||||
0xF8, 0x7F, 0xE1, 0xFF, 0x87, 0xFE, 0x1F, 0xF8, 0x7F, 0xE1, 0xFF, 0x87,
|
||||
0xFE, 0x1F, 0xF8, 0x7F, 0xE1, 0xFF, 0x87, 0xFE, 0x1F, 0xF8, 0x7D, 0xE1,
|
||||
0xF7, 0xDF, 0xDF, 0xFF, 0x3F, 0xFC, 0x7D, 0xF0, 0x0F, 0xC0, 0x7F, 0xC3,
|
||||
0xFF, 0x1F, 0xFE, 0x78, 0x79, 0xE1, 0xEF, 0x87, 0xBE, 0x1E, 0xF8, 0x7B,
|
||||
0xE1, 0xFF, 0x87, 0xFE, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00,
|
||||
0xF8, 0x03, 0xE0, 0x0F, 0x87, 0xBE, 0x1E, 0xF8, 0x7B, 0xE1, 0xEF, 0x87,
|
||||
0x9E, 0x1E, 0x78, 0x79, 0xF3, 0xE7, 0xFF, 0x0F, 0xFC, 0x1F, 0xE0, 0x07,
|
||||
0xC3, 0xF1, 0xFC, 0x7C, 0x1E, 0x07, 0x8F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF1,
|
||||
0xE0, 0x78, 0x1E, 0x07, 0x81, 0xE0, 0x78, 0x1E, 0x07, 0x81, 0xE0, 0x78,
|
||||
0x1E, 0x07, 0x81, 0xE0, 0x78, 0x1E, 0x07, 0x81, 0xE0, 0x78, 0x1E, 0x07,
|
||||
0x81, 0xE0, 0x78, 0x1E, 0x07, 0x80, 0x1F, 0x7C, 0xFF, 0xF7, 0xFF, 0xDF,
|
||||
0xFF, 0x78, 0x7D, 0xE1, 0xFF, 0x87, 0xFE, 0x1F, 0xF8, 0x7F, 0xE1, 0xFF,
|
||||
0x87, 0xFE, 0x1F, 0xF8, 0x7F, 0xE1, 0xFF, 0x87, 0xFE, 0x1F, 0xF8, 0x7F,
|
||||
0xE1, 0xFF, 0x87, 0xFE, 0x1F, 0xF8, 0x7D, 0xE1, 0xF7, 0xCF, 0xDF, 0xFF,
|
||||
0x3F, 0xFC, 0x7D, 0xF0, 0x07, 0xC0, 0x1F, 0x00, 0x79, 0xC3, 0xE7, 0xFF,
|
||||
0xBF, 0xFC, 0x3F, 0xC0, 0xF0, 0x07, 0x80, 0x3C, 0x01, 0xE0, 0x0F, 0x00,
|
||||
0x79, 0xF3, 0xDF, 0xDF, 0xFF, 0xFF, 0xFF, 0xC3, 0xFC, 0x1F, 0xE0, 0xFF,
|
||||
0x07, 0xF8, 0x3F, 0xC1, 0xFE, 0x0F, 0xF0, 0x7F, 0x83, 0xFC, 0x1F, 0xE0,
|
||||
0xFF, 0x07, 0xF8, 0x3F, 0xC1, 0xFE, 0x0F, 0xF0, 0x7F, 0x83, 0xFC, 0x1F,
|
||||
0xE0, 0xFF, 0x07, 0xF8, 0x3F, 0xC1, 0xFE, 0x0F, 0xF0, 0x7F, 0x83, 0xC0,
|
||||
0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x3C, 0x78, 0xF1, 0xE0, 0x00, 0x0F,
|
||||
0x9F, 0x3E, 0x7C, 0xF9, 0xF3, 0xE7, 0xCF, 0x9F, 0x3E, 0x7C, 0xF9, 0xF3,
|
||||
0xE7, 0xCF, 0x9F, 0x3E, 0x7C, 0xF9, 0xF3, 0xE7, 0xCF, 0x9F, 0x3E, 0x7C,
|
||||
0xF9, 0xFF, 0xDF, 0xBE, 0x00, 0xF0, 0x03, 0xC0, 0x0F, 0x00, 0x3C, 0x00,
|
||||
0xF0, 0x03, 0xC1, 0xFF, 0x07, 0xBC, 0x1E, 0xF0, 0xFB, 0xC3, 0xCF, 0x1F,
|
||||
0x3C, 0x78, 0xF1, 0xE3, 0xCF, 0x8F, 0x3C, 0x3D, 0xF0, 0xF7, 0x83, 0xDE,
|
||||
0x0F, 0xF8, 0x3F, 0xC0, 0xFF, 0x83, 0xDE, 0x0F, 0x78, 0x3D, 0xF0, 0xF3,
|
||||
0xC3, 0xCF, 0x8F, 0x1E, 0x3C, 0x7C, 0xF0, 0xF3, 0xC3, 0xCF, 0x0F, 0xBC,
|
||||
0x1E, 0xF0, 0x7F, 0xC0, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF3, 0xE1,
|
||||
0xF3, 0xDF, 0xCF, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0xFC, 0x3F,
|
||||
0xC1, 0xE0, 0xFF, 0x07, 0x83, 0xFC, 0x1E, 0x0F, 0xF0, 0x78, 0x3F, 0xC1,
|
||||
0xE0, 0xFF, 0x07, 0x83, 0xFC, 0x1E, 0x0F, 0xF0, 0x78, 0x3F, 0xC1, 0xE0,
|
||||
0xFF, 0x07, 0x83, 0xFC, 0x1E, 0x0F, 0xF0, 0x78, 0x3F, 0xC1, 0xE0, 0xFF,
|
||||
0x07, 0x83, 0xFC, 0x1E, 0x0F, 0xF0, 0x78, 0x3F, 0xC1, 0xE0, 0xFF, 0x07,
|
||||
0x83, 0xFC, 0x1E, 0x0F, 0xF0, 0x78, 0x3F, 0xC1, 0xE0, 0xFF, 0x07, 0x83,
|
||||
0xFC, 0x1E, 0x0F, 0xF0, 0x78, 0x3C, 0xF3, 0xE7, 0xBF, 0xBF, 0xFF, 0xFF,
|
||||
0xFF, 0x87, 0xF8, 0x3F, 0xC1, 0xFE, 0x0F, 0xF0, 0x7F, 0x83, 0xFC, 0x1F,
|
||||
0xE0, 0xFF, 0x07, 0xF8, 0x3F, 0xC1, 0xFE, 0x0F, 0xF0, 0x7F, 0x83, 0xFC,
|
||||
0x1F, 0xE0, 0xFF, 0x07, 0xF8, 0x3F, 0xC1, 0xFE, 0x0F, 0xF0, 0x7F, 0x83,
|
||||
0xFC, 0x1F, 0xE0, 0xFF, 0x07, 0x80, 0x0F, 0xC0, 0x7F, 0x83, 0xFF, 0x1F,
|
||||
0xFE, 0x78, 0x79, 0xE1, 0xEF, 0x87, 0xBE, 0x1F, 0xF8, 0x7F, 0xE1, 0xFF,
|
||||
0x87, 0xFE, 0x1F, 0xF8, 0x7F, 0xE1, 0xFF, 0x87, 0xFE, 0x1F, 0xF8, 0x7F,
|
||||
0xE1, 0xFF, 0x87, 0xFE, 0x1F, 0xF8, 0x7F, 0xE1, 0xFF, 0x87, 0xDE, 0x1E,
|
||||
0x78, 0x79, 0xF3, 0xE7, 0xFF, 0x0F, 0xFC, 0x1F, 0xE0, 0xF3, 0xC7, 0xBF,
|
||||
0xBF, 0xFD, 0xFF, 0xFF, 0x8F, 0xF8, 0x7F, 0xC1, 0xFE, 0x0F, 0xF0, 0x7F,
|
||||
0x83, 0xFC, 0x1F, 0xE0, 0xFF, 0x07, 0xF8, 0x3F, 0xC1, 0xFE, 0x0F, 0xF0,
|
||||
0x7F, 0x83, 0xFC, 0x1F, 0xE0, 0xFF, 0x07, 0xF8, 0x3F, 0xC1, 0xFE, 0x0F,
|
||||
0xF8, 0xFF, 0xEF, 0xFF, 0xFD, 0xFF, 0xEF, 0x7E, 0x78, 0x03, 0xC0, 0x1E,
|
||||
0x00, 0xF0, 0x07, 0x80, 0x00, 0x1E, 0x7C, 0xFF, 0xF7, 0xFF, 0xDF, 0xFF,
|
||||
0x78, 0x7F, 0xE1, 0xFF, 0x87, 0xFE, 0x1F, 0xF8, 0x7F, 0xE1, 0xFF, 0x87,
|
||||
0xFE, 0x1F, 0xF8, 0x7F, 0xE1, 0xFF, 0x87, 0xFE, 0x1F, 0xF8, 0x7F, 0xE1,
|
||||
0xFF, 0x87, 0xFE, 0x1F, 0xF8, 0x7F, 0xE1, 0xFF, 0x87, 0xFE, 0x1F, 0x78,
|
||||
0x7D, 0xF7, 0xF7, 0xFF, 0xCF, 0xFF, 0x1F, 0x7C, 0x01, 0xF0, 0x07, 0xC0,
|
||||
0x1F, 0x00, 0x7C, 0x01, 0xF0, 0xF3, 0xFB, 0xFF, 0xFF, 0xFF, 0xC7, 0x83,
|
||||
0xC1, 0xE0, 0xF0, 0x78, 0x3C, 0x1E, 0x0F, 0x07, 0x83, 0xC1, 0xE0, 0xF0,
|
||||
0x78, 0x3C, 0x1E, 0x0F, 0x07, 0x83, 0xC1, 0xE0, 0xF0, 0x78, 0x3C, 0x1E,
|
||||
0x0F, 0x00, 0x1F, 0x83, 0xFE, 0x1F, 0xF9, 0xFF, 0xCF, 0x0F, 0x78, 0x7B,
|
||||
0xC3, 0xDE, 0x1E, 0xF0, 0xF7, 0xC7, 0xBE, 0x00, 0xF8, 0x07, 0xE0, 0x1F,
|
||||
0x80, 0x7E, 0x01, 0xF8, 0x07, 0xE0, 0x1F, 0x80, 0x7D, 0xE1, 0xEF, 0x0F,
|
||||
0xF8, 0x7F, 0xC3, 0xFE, 0x1F, 0xF0, 0xF7, 0xEF, 0x9F, 0xFC, 0xFF, 0xC1,
|
||||
0xFC, 0x00, 0x3E, 0x0F, 0x83, 0xE0, 0xF8, 0x3E, 0x0F, 0x8F, 0xFF, 0xFF,
|
||||
0xFF, 0xCF, 0x83, 0xE0, 0xF8, 0x3E, 0x0F, 0x83, 0xE0, 0xF8, 0x3E, 0x0F,
|
||||
0x83, 0xE0, 0xF8, 0x3E, 0x0F, 0x83, 0xE0, 0xF8, 0x3E, 0x0F, 0x83, 0xE0,
|
||||
0xF8, 0x3E, 0x0F, 0x83, 0xF0, 0xFF, 0x1F, 0xC3, 0xF0, 0xF8, 0x3F, 0xE0,
|
||||
0xFF, 0x83, 0xFE, 0x0F, 0xF8, 0x3F, 0xE0, 0xFF, 0x83, 0xFE, 0x0F, 0xF8,
|
||||
0x3F, 0xE0, 0xFF, 0x83, 0xFE, 0x0F, 0xF8, 0x3F, 0xE0, 0xFF, 0x83, 0xFE,
|
||||
0x0F, 0xF8, 0x3F, 0xE0, 0xFF, 0x83, 0xFE, 0x0F, 0xF8, 0x3F, 0xE0, 0xFF,
|
||||
0x83, 0xFE, 0x0F, 0x78, 0x7D, 0xF3, 0xF7, 0xFF, 0xCF, 0xEF, 0x1F, 0x3C,
|
||||
0xF0, 0x7F, 0xC1, 0xEF, 0x07, 0xBC, 0x1E, 0x78, 0x79, 0xE1, 0xE7, 0x87,
|
||||
0x9E, 0x1C, 0x78, 0x71, 0xE3, 0xC7, 0x8F, 0x0E, 0x3C, 0x3C, 0xF0, 0xF3,
|
||||
0xC3, 0xCE, 0x0F, 0x38, 0x3C, 0xE0, 0xF3, 0x81, 0xDE, 0x07, 0x78, 0x1F,
|
||||
0xE0, 0x7F, 0x01, 0xFC, 0x07, 0xF0, 0x1F, 0xC0, 0x3F, 0x00, 0xFC, 0x03,
|
||||
0xF0, 0x0F, 0x80, 0xF0, 0x78, 0x7F, 0x87, 0xC3, 0xFC, 0x3E, 0x1F, 0xE1,
|
||||
0xF0, 0xF7, 0x0F, 0x87, 0xB8, 0x7C, 0x39, 0xC3, 0xE1, 0xCE, 0x1F, 0x8E,
|
||||
0x79, 0xDC, 0x73, 0xCE, 0xE7, 0x9E, 0x77, 0x3C, 0xF3, 0xB9, 0xE3, 0x9D,
|
||||
0xCF, 0x1C, 0xE6, 0x70, 0xE7, 0x3B, 0x87, 0x71, 0xDC, 0x3B, 0x8E, 0xE1,
|
||||
0xDC, 0x77, 0x0F, 0xE3, 0xB8, 0x7F, 0x1D, 0xC3, 0xF8, 0xFE, 0x0F, 0x83,
|
||||
0xE0, 0x7C, 0x1F, 0x03, 0xE0, 0xF8, 0x1F, 0x07, 0xC0, 0xF8, 0x3E, 0x07,
|
||||
0xC1, 0xF0, 0x3E, 0x0F, 0x81, 0xE0, 0x7C, 0x00, 0xF0, 0x7B, 0xC1, 0xE7,
|
||||
0x87, 0x9E, 0x3C, 0x78, 0xF0, 0xF3, 0xC3, 0xCE, 0x0F, 0x78, 0x1F, 0xE0,
|
||||
0x7F, 0x01, 0xFC, 0x03, 0xF0, 0x0F, 0x80, 0x3E, 0x00, 0xF8, 0x03, 0xE0,
|
||||
0x0F, 0x80, 0x7F, 0x01, 0xFC, 0x07, 0xF0, 0x3D, 0xE0, 0xF7, 0x83, 0xDE,
|
||||
0x1E, 0x3C, 0x78, 0xF1, 0xE3, 0xCF, 0x07, 0xBC, 0x1E, 0xF0, 0x7C, 0xF0,
|
||||
0x3F, 0xC0, 0xFF, 0x07, 0xFE, 0x1E, 0x78, 0x79, 0xE1, 0xE7, 0x87, 0x9E,
|
||||
0x1E, 0x78, 0x79, 0xE1, 0xC3, 0x87, 0x0F, 0x3C, 0x3C, 0xF0, 0xF3, 0xC3,
|
||||
0xCF, 0x0F, 0x3C, 0x1C, 0xE0, 0x73, 0x81, 0xCE, 0x07, 0xB8, 0x1F, 0xE0,
|
||||
0x7F, 0x80, 0xFC, 0x03, 0xF0, 0x0F, 0xC0, 0x3F, 0x00, 0xFC, 0x03, 0xF0,
|
||||
0x07, 0x80, 0x1E, 0x00, 0xF8, 0x1F, 0xE0, 0x7F, 0x01, 0xFC, 0x00, 0x7F,
|
||||
0xEF, 0xFD, 0xFF, 0xBF, 0xF0, 0x1E, 0x07, 0xC0, 0xF0, 0x1E, 0x07, 0xC0,
|
||||
0xF0, 0x1E, 0x03, 0xC0, 0xF8, 0x1E, 0x03, 0xC0, 0xF8, 0x1E, 0x03, 0xC0,
|
||||
0xF8, 0x1F, 0x03, 0xC0, 0x78, 0x1F, 0x03, 0xC0, 0x78, 0x1F, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFE, 0x07, 0xC3, 0xF1, 0xFC, 0x7E, 0x1E, 0x07, 0x81, 0xE0,
|
||||
0x78, 0x1E, 0x07, 0x81, 0xE0, 0x78, 0x1E, 0x07, 0x81, 0xE0, 0xF8, 0x7E,
|
||||
0x3F, 0x0F, 0x83, 0xF0, 0xFE, 0x0F, 0x81, 0xE0, 0x78, 0x1E, 0x07, 0x81,
|
||||
0xE0, 0x78, 0x1E, 0x07, 0x81, 0xE0, 0x78, 0x1E, 0x07, 0xC1, 0xFC, 0x3F,
|
||||
0x07, 0xC0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xF8, 0x3F, 0x0F,
|
||||
0xC1, 0xF8, 0x3E, 0x07, 0x81, 0xE0, 0x78, 0x1E, 0x07, 0x81, 0xE0, 0x78,
|
||||
0x1E, 0x07, 0x81, 0xE0, 0x78, 0x1F, 0x83, 0xF0, 0x7C, 0x3F, 0x1F, 0xC7,
|
||||
0x81, 0xE0, 0x78, 0x1E, 0x07, 0x81, 0xE0, 0x78, 0x1E, 0x07, 0x81, 0xE0,
|
||||
0x78, 0x3E, 0x0F, 0x8F, 0xC3, 0xF0, 0xF8, 0x00, 0x1E, 0x07, 0x9F, 0xF3,
|
||||
0xDF, 0xFF, 0xDF, 0xFF, 0xEF, 0xFF, 0xE1, 0x03, 0xE0};
|
||||
|
||||
const GFXglyph Antonio_SemiBold20pt7bGlyphs[] PROGMEM = {
|
||||
{ 0, 1, 1, 8, 0, 0 }, // 0x20 ' '
|
||||
{ 1, 4, 34, 10, 3, -33 }, // 0x21 '!'
|
||||
{ 18, 5, 13, 16, 6, -33 }, // 0x22 '"'
|
||||
{ 27, 17, 34, 20, 2, -33 }, // 0x23 '#'
|
||||
{ 100, 13, 39, 16, 2, -33 }, // 0x24 '$'
|
||||
{ 164, 36, 34, 42, 3, -33 }, // 0x25 '%'
|
||||
{ 317, 18, 34, 19, 1, -33 }, // 0x26 '&'
|
||||
{ 394, 4, 12, 8, 2, -33 }, // 0x27 '''
|
||||
{ 400, 7, 38, 11, 3, -33 }, // 0x28 '('
|
||||
{ 434, 7, 38, 11, 2, -33 }, // 0x29 ')'
|
||||
{ 468, 14, 15, 17, 2, -32 }, // 0x2A '*'
|
||||
{ 495, 12, 12, 14, 1, -20 }, // 0x2B '+'
|
||||
{ 513, 5, 12, 9, 2, -4 }, // 0x2C ','
|
||||
{ 521, 9, 3, 13, 2, -16 }, // 0x2D '-'
|
||||
{ 525, 4, 4, 10, 3, -3 }, // 0x2E '.'
|
||||
{ 527, 13, 34, 15, 1, -33 }, // 0x2F '/'
|
||||
{ 583, 13, 34, 18, 2, -33 }, // 0x30 '0'
|
||||
{ 639, 9, 34, 15, 2, -33 }, // 0x31 '1'
|
||||
{ 678, 13, 34, 17, 3, -33 }, // 0x32 '2'
|
||||
{ 734, 14, 34, 17, 2, -33 }, // 0x33 '3'
|
||||
{ 794, 14, 34, 17, 2, -33 }, // 0x34 '4'
|
||||
{ 854, 12, 34, 17, 3, -33 }, // 0x35 '5'
|
||||
{ 905, 14, 34, 17, 2, -33 }, // 0x36 '6'
|
||||
{ 965, 14, 34, 17, 2, -33 }, // 0x37 '7'
|
||||
{ 1025, 13, 34, 17, 2, -33 }, // 0x38 '8'
|
||||
{ 1081, 13, 34, 17, 2, -33 }, // 0x39 '9'
|
||||
{ 1137, 4, 20, 10, 3, -24 }, // 0x3A ':'
|
||||
{ 1147, 5, 27, 11, 3, -24 }, // 0x3B ';'
|
||||
{ 1164, 11, 19, 14, 1, -23 }, // 0x3C '<'
|
||||
{ 1191, 10, 9, 14, 2, -19 }, // 0x3D '='
|
||||
{ 1203, 11, 19, 14, 2, -23 }, // 0x3E '>'
|
||||
{ 1230, 12, 34, 17, 3, -33 }, // 0x3F '?'
|
||||
{ 1281, 25, 35, 29, 2, -33 }, // 0x40 '@'
|
||||
{ 1391, 16, 34, 18, 1, -33 }, // 0x41 'A'
|
||||
{ 1459, 14, 34, 18, 3, -33 }, // 0x42 'B'
|
||||
{ 1519, 14, 34, 18, 2, -33 }, // 0x43 'C'
|
||||
{ 1579, 13, 34, 19, 3, -33 }, // 0x44 'D'
|
||||
{ 1635, 10, 34, 15, 3, -33 }, // 0x45 'E'
|
||||
{ 1678, 10, 34, 15, 3, -33 }, // 0x46 'F'
|
||||
{ 1721, 14, 34, 18, 2, -33 }, // 0x47 'G'
|
||||
{ 1781, 14, 34, 19, 3, -33 }, // 0x48 'H'
|
||||
{ 1841, 4, 34, 10, 3, -33 }, // 0x49 'I'
|
||||
{ 1858, 13, 34, 17, 2, -33 }, // 0x4A 'J'
|
||||
{ 1914, 15, 34, 18, 3, -33 }, // 0x4B 'K'
|
||||
{ 1978, 10, 34, 14, 3, -33 }, // 0x4C 'L'
|
||||
{ 2021, 20, 34, 26, 3, -33 }, // 0x4D 'M'
|
||||
{ 2106, 14, 34, 20, 3, -33 }, // 0x4E 'N'
|
||||
{ 2166, 14, 34, 19, 2, -33 }, // 0x4F 'O'
|
||||
{ 2226, 13, 34, 17, 3, -33 }, // 0x50 'P'
|
||||
{ 2282, 14, 39, 19, 2, -33 }, // 0x51 'Q'
|
||||
{ 2351, 14, 34, 18, 3, -33 }, // 0x52 'R'
|
||||
{ 2411, 14, 34, 16, 1, -33 }, // 0x53 'S'
|
||||
{ 2471, 12, 34, 13, 0, -33 }, // 0x54 'T'
|
||||
{ 2522, 14, 34, 19, 2, -33 }, // 0x55 'U'
|
||||
{ 2582, 16, 34, 17, 1, -33 }, // 0x56 'V'
|
||||
{ 2650, 24, 34, 26, 1, -33 }, // 0x57 'W'
|
||||
{ 2752, 14, 34, 16, 1, -33 }, // 0x58 'X'
|
||||
{ 2812, 16, 34, 16, 0, -33 }, // 0x59 'Y'
|
||||
{ 2880, 12, 34, 14, 1, -33 }, // 0x5A 'Z'
|
||||
{ 2931, 8, 35, 13, 3, -33 }, // 0x5B '['
|
||||
{ 2966, 11, 34, 15, 2, -33 }, // 0x5C '\'
|
||||
{ 3013, 8, 35, 13, 2, -33 }, // 0x5D ']'
|
||||
{ 3048, 15, 18, 18, 2, -33 }, // 0x5E '^'
|
||||
{ 3082, 12, 3, 14, 1, 2 }, // 0x5F '_'
|
||||
{ 3087, 6, 8, 8, 1, -38 }, // 0x60 '`'
|
||||
{ 3093, 14, 29, 18, 2, -28 }, // 0x61 'a'
|
||||
{ 3144, 13, 34, 18, 3, -33 }, // 0x62 'b'
|
||||
{ 3200, 13, 29, 17, 2, -28 }, // 0x63 'c'
|
||||
{ 3248, 14, 34, 18, 2, -33 }, // 0x64 'd'
|
||||
{ 3308, 14, 29, 17, 2, -28 }, // 0x65 'e'
|
||||
{ 3359, 10, 34, 13, 1, -33 }, // 0x66 'f'
|
||||
{ 3402, 14, 33, 18, 2, -28 }, // 0x67 'g'
|
||||
{ 3460, 13, 34, 19, 3, -33 }, // 0x68 'h'
|
||||
{ 3516, 4, 35, 10, 3, -34 }, // 0x69 'i'
|
||||
{ 3534, 7, 39, 10, 1, -34 }, // 0x6A 'j'
|
||||
{ 3569, 14, 34, 18, 3, -33 }, // 0x6B 'k'
|
||||
{ 3629, 4, 34, 10, 3, -33 }, // 0x6C 'l'
|
||||
{ 3646, 22, 29, 28, 3, -28 }, // 0x6D 'm'
|
||||
{ 3726, 13, 29, 19, 3, -28 }, // 0x6E 'n'
|
||||
{ 3774, 14, 29, 18, 2, -28 }, // 0x6F 'o'
|
||||
{ 3825, 13, 34, 18, 3, -28 }, // 0x70 'p'
|
||||
{ 3881, 14, 34, 18, 2, -28 }, // 0x71 'q'
|
||||
{ 3941, 9, 29, 13, 3, -28 }, // 0x72 'r'
|
||||
{ 3974, 13, 29, 16, 2, -28 }, // 0x73 's'
|
||||
{ 4022, 10, 34, 12, 1, -33 }, // 0x74 't'
|
||||
{ 4065, 14, 29, 19, 2, -28 }, // 0x75 'u'
|
||||
{ 4116, 14, 29, 15, 1, -28 }, // 0x76 'v'
|
||||
{ 4167, 21, 29, 23, 1, -28 }, // 0x77 'w'
|
||||
{ 4244, 14, 29, 15, 1, -28 }, // 0x78 'x'
|
||||
{ 4295, 14, 34, 16, 1, -28 }, // 0x79 'y'
|
||||
{ 4355, 11, 29, 13, 1, -28 }, // 0x7A 'z'
|
||||
{ 4395, 10, 37, 14, 2, -33 }, // 0x7B '{'
|
||||
{ 4442, 4, 37, 10, 3, -34 }, // 0x7C '|'
|
||||
{ 4461, 10, 37, 14, 2, -33 }, // 0x7D '}'
|
||||
{ 4508, 17, 6, 21, 2, -21 } }; // 0x7E '~'
|
||||
{0, 1, 1, 8, 0, 0}, // 0x20 ' '
|
||||
{1, 4, 34, 10, 3, -33}, // 0x21 '!'
|
||||
{18, 5, 13, 16, 6, -33}, // 0x22 '"'
|
||||
{27, 17, 34, 20, 2, -33}, // 0x23 '#'
|
||||
{100, 13, 39, 16, 2, -33}, // 0x24 '$'
|
||||
{164, 36, 34, 42, 3, -33}, // 0x25 '%'
|
||||
{317, 18, 34, 19, 1, -33}, // 0x26 '&'
|
||||
{394, 4, 12, 8, 2, -33}, // 0x27 '''
|
||||
{400, 7, 38, 11, 3, -33}, // 0x28 '('
|
||||
{434, 7, 38, 11, 2, -33}, // 0x29 ')'
|
||||
{468, 14, 15, 17, 2, -32}, // 0x2A '*'
|
||||
{495, 12, 12, 14, 1, -20}, // 0x2B '+'
|
||||
{513, 5, 12, 9, 2, -4}, // 0x2C ','
|
||||
{521, 9, 3, 13, 2, -16}, // 0x2D '-'
|
||||
{525, 4, 4, 10, 3, -3}, // 0x2E '.'
|
||||
{527, 13, 34, 15, 1, -33}, // 0x2F '/'
|
||||
{583, 13, 34, 18, 2, -33}, // 0x30 '0'
|
||||
{639, 9, 34, 15, 2, -33}, // 0x31 '1'
|
||||
{678, 13, 34, 17, 3, -33}, // 0x32 '2'
|
||||
{734, 14, 34, 17, 2, -33}, // 0x33 '3'
|
||||
{794, 14, 34, 17, 2, -33}, // 0x34 '4'
|
||||
{854, 12, 34, 17, 3, -33}, // 0x35 '5'
|
||||
{905, 14, 34, 17, 2, -33}, // 0x36 '6'
|
||||
{965, 14, 34, 17, 2, -33}, // 0x37 '7'
|
||||
{1025, 13, 34, 17, 2, -33}, // 0x38 '8'
|
||||
{1081, 13, 34, 17, 2, -33}, // 0x39 '9'
|
||||
{1137, 4, 20, 10, 3, -24}, // 0x3A ':'
|
||||
{1147, 5, 27, 11, 3, -24}, // 0x3B ';'
|
||||
{1164, 11, 19, 14, 1, -23}, // 0x3C '<'
|
||||
{1191, 10, 9, 14, 2, -19}, // 0x3D '='
|
||||
{1203, 11, 19, 14, 2, -23}, // 0x3E '>'
|
||||
{1230, 12, 34, 17, 3, -33}, // 0x3F '?'
|
||||
{1281, 25, 35, 29, 2, -33}, // 0x40 '@'
|
||||
{1391, 16, 34, 18, 1, -33}, // 0x41 'A'
|
||||
{1459, 14, 34, 18, 3, -33}, // 0x42 'B'
|
||||
{1519, 14, 34, 18, 2, -33}, // 0x43 'C'
|
||||
{1579, 13, 34, 19, 3, -33}, // 0x44 'D'
|
||||
{1635, 10, 34, 15, 3, -33}, // 0x45 'E'
|
||||
{1678, 10, 34, 15, 3, -33}, // 0x46 'F'
|
||||
{1721, 14, 34, 18, 2, -33}, // 0x47 'G'
|
||||
{1781, 14, 34, 19, 3, -33}, // 0x48 'H'
|
||||
{1841, 4, 34, 10, 3, -33}, // 0x49 'I'
|
||||
{1858, 13, 34, 17, 2, -33}, // 0x4A 'J'
|
||||
{1914, 15, 34, 18, 3, -33}, // 0x4B 'K'
|
||||
{1978, 10, 34, 14, 3, -33}, // 0x4C 'L'
|
||||
{2021, 20, 34, 26, 3, -33}, // 0x4D 'M'
|
||||
{2106, 14, 34, 20, 3, -33}, // 0x4E 'N'
|
||||
{2166, 14, 34, 19, 2, -33}, // 0x4F 'O'
|
||||
{2226, 13, 34, 17, 3, -33}, // 0x50 'P'
|
||||
{2282, 14, 39, 19, 2, -33}, // 0x51 'Q'
|
||||
{2351, 14, 34, 18, 3, -33}, // 0x52 'R'
|
||||
{2411, 14, 34, 16, 1, -33}, // 0x53 'S'
|
||||
{2471, 12, 34, 13, 0, -33}, // 0x54 'T'
|
||||
{2522, 14, 34, 19, 2, -33}, // 0x55 'U'
|
||||
{2582, 16, 34, 17, 1, -33}, // 0x56 'V'
|
||||
{2650, 24, 34, 26, 1, -33}, // 0x57 'W'
|
||||
{2752, 14, 34, 16, 1, -33}, // 0x58 'X'
|
||||
{2812, 16, 34, 16, 0, -33}, // 0x59 'Y'
|
||||
{2880, 12, 34, 14, 1, -33}, // 0x5A 'Z'
|
||||
{2931, 8, 35, 13, 3, -33}, // 0x5B '['
|
||||
{2966, 11, 34, 15, 2, -33}, // 0x5C '\'
|
||||
{3013, 8, 35, 13, 2, -33}, // 0x5D ']'
|
||||
{3048, 15, 18, 18, 2, -33}, // 0x5E '^'
|
||||
{3082, 12, 3, 14, 1, 2}, // 0x5F '_'
|
||||
{3087, 6, 8, 8, 1, -38}, // 0x60 '`'
|
||||
{3093, 14, 29, 18, 2, -28}, // 0x61 'a'
|
||||
{3144, 13, 34, 18, 3, -33}, // 0x62 'b'
|
||||
{3200, 13, 29, 17, 2, -28}, // 0x63 'c'
|
||||
{3248, 14, 34, 18, 2, -33}, // 0x64 'd'
|
||||
{3308, 14, 29, 17, 2, -28}, // 0x65 'e'
|
||||
{3359, 10, 34, 13, 1, -33}, // 0x66 'f'
|
||||
{3402, 14, 33, 18, 2, -28}, // 0x67 'g'
|
||||
{3460, 13, 34, 19, 3, -33}, // 0x68 'h'
|
||||
{3516, 4, 35, 10, 3, -34}, // 0x69 'i'
|
||||
{3534, 7, 39, 10, 1, -34}, // 0x6A 'j'
|
||||
{3569, 14, 34, 18, 3, -33}, // 0x6B 'k'
|
||||
{3629, 4, 34, 10, 3, -33}, // 0x6C 'l'
|
||||
{3646, 22, 29, 28, 3, -28}, // 0x6D 'm'
|
||||
{3726, 13, 29, 19, 3, -28}, // 0x6E 'n'
|
||||
{3774, 14, 29, 18, 2, -28}, // 0x6F 'o'
|
||||
{3825, 13, 34, 18, 3, -28}, // 0x70 'p'
|
||||
{3881, 14, 34, 18, 2, -28}, // 0x71 'q'
|
||||
{3941, 9, 29, 13, 3, -28}, // 0x72 'r'
|
||||
{3974, 13, 29, 16, 2, -28}, // 0x73 's'
|
||||
{4022, 10, 34, 12, 1, -33}, // 0x74 't'
|
||||
{4065, 14, 29, 19, 2, -28}, // 0x75 'u'
|
||||
{4116, 14, 29, 15, 1, -28}, // 0x76 'v'
|
||||
{4167, 21, 29, 23, 1, -28}, // 0x77 'w'
|
||||
{4244, 14, 29, 15, 1, -28}, // 0x78 'x'
|
||||
{4295, 14, 34, 16, 1, -28}, // 0x79 'y'
|
||||
{4355, 11, 29, 13, 1, -28}, // 0x7A 'z'
|
||||
{4395, 10, 37, 14, 2, -33}, // 0x7B '{'
|
||||
{4442, 4, 37, 10, 3, -34}, // 0x7C '|'
|
||||
{4461, 10, 37, 14, 2, -33}, // 0x7D '}'
|
||||
{4508, 17, 6, 21, 2, -21}}; // 0x7E '~'
|
||||
|
||||
const GFXfont Antonio_SemiBold20pt7b PROGMEM = {
|
||||
(uint8_t *)Antonio_SemiBold20pt7bBitmaps,
|
||||
(GFXglyph *)Antonio_SemiBold20pt7bGlyphs,
|
||||
0x20, 0x7E, 51 };
|
||||
(uint8_t *)Antonio_SemiBold20pt7bBitmaps,
|
||||
(GFXglyph *)Antonio_SemiBold20pt7bGlyphs, 0x20, 0x7E, 51};
|
||||
|
||||
// Approx. 5193 bytes
|
||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -3,4 +3,4 @@ dependencies:
|
|||
idf: ">=4.4"
|
||||
|
||||
esp_littlefs:
|
||||
git: https://github.com/joltwallet/esp_littlefs.git
|
||||
git: https://github.com/joltwallet/esp_littlefs.git
|
||||
|
|
|
@ -48,152 +48,141 @@ uint currentBlockHeight = 816000;
|
|||
// ew==
|
||||
// -----END CERTIFICATE-----)";
|
||||
|
||||
void setupBlockNotify()
|
||||
{
|
||||
//currentBlockHeight = preferences.getUInt("blockHeight", 816000);
|
||||
void setupBlockNotify() {
|
||||
// currentBlockHeight = preferences.getUInt("blockHeight", 816000);
|
||||
|
||||
IPAddress result;
|
||||
IPAddress result;
|
||||
|
||||
int dnsErr = -1;
|
||||
String mempoolInstance = preferences.getString("mempoolInstance", DEFAULT_MEMPOOL_INSTANCE);
|
||||
int dnsErr = -1;
|
||||
String mempoolInstance =
|
||||
preferences.getString("mempoolInstance", DEFAULT_MEMPOOL_INSTANCE);
|
||||
|
||||
while (dnsErr != 1)
|
||||
{
|
||||
dnsErr = WiFi.hostByName(mempoolInstance.c_str(), result);
|
||||
while (dnsErr != 1) {
|
||||
dnsErr = WiFi.hostByName(mempoolInstance.c_str(), result);
|
||||
|
||||
if (dnsErr != 1)
|
||||
{
|
||||
Serial.print(mempoolInstance);
|
||||
Serial.println(F("mempool DNS could not be resolved"));
|
||||
WiFi.reconnect();
|
||||
vTaskDelay(pdMS_TO_TICKS(1000));
|
||||
}
|
||||
if (dnsErr != 1) {
|
||||
Serial.print(mempoolInstance);
|
||||
Serial.println(F("mempool DNS could not be resolved"));
|
||||
WiFi.reconnect();
|
||||
vTaskDelay(pdMS_TO_TICKS(1000));
|
||||
}
|
||||
}
|
||||
|
||||
// Get current block height through regular API
|
||||
HTTPClient *http = new HTTPClient();
|
||||
http->begin("https://" + mempoolInstance + "/api/blocks/tip/height");
|
||||
int httpCode = http->GET();
|
||||
|
||||
if (httpCode > 0 && httpCode == HTTP_CODE_OK) {
|
||||
String blockHeightStr = http->getString();
|
||||
currentBlockHeight = blockHeightStr.toInt();
|
||||
// xTaskNotifyGive(blockUpdateTaskHandle);
|
||||
if (workQueue != nullptr) {
|
||||
WorkItem blockUpdate = {TASK_BLOCK_UPDATE, 0};
|
||||
xQueueSend(workQueue, &blockUpdate, portMAX_DELAY);
|
||||
}
|
||||
}
|
||||
|
||||
// std::strcpy(wsServer, String("wss://" + mempoolInstance +
|
||||
// "/api/v1/ws").c_str());
|
||||
|
||||
esp_websocket_client_config_t config = {
|
||||
.uri = "wss://mempool.space/api/v1/ws",
|
||||
// .task_stack = (6*1024),
|
||||
// .cert_pem = mempoolWsCert,
|
||||
.user_agent = USER_AGENT,
|
||||
};
|
||||
|
||||
blockNotifyClient = esp_websocket_client_init(&config);
|
||||
esp_websocket_register_events(blockNotifyClient, WEBSOCKET_EVENT_ANY,
|
||||
onWebsocketEvent, blockNotifyClient);
|
||||
esp_websocket_client_start(blockNotifyClient);
|
||||
}
|
||||
|
||||
void onWebsocketEvent(void *handler_args, esp_event_base_t base,
|
||||
int32_t event_id, void *event_data) {
|
||||
esp_websocket_event_data_t *data = (esp_websocket_event_data_t *)event_data;
|
||||
const String sub = "{\"action\": \"want\", \"data\":[\"blocks\"]}";
|
||||
switch (event_id) {
|
||||
case WEBSOCKET_EVENT_CONNECTED:
|
||||
Serial.println(F("Connected to Mempool.space WebSocket"));
|
||||
|
||||
Serial.println(sub);
|
||||
if (esp_websocket_client_send_text(blockNotifyClient, sub.c_str(),
|
||||
sub.length(), portMAX_DELAY) == -1) {
|
||||
Serial.println(F("Mempool.space WS Block Subscribe Error"));
|
||||
}
|
||||
|
||||
// Get current block height through regular API
|
||||
HTTPClient *http = new HTTPClient();
|
||||
http->begin("https://" + mempoolInstance + "/api/blocks/tip/height");
|
||||
int httpCode = http->GET();
|
||||
break;
|
||||
case WEBSOCKET_EVENT_DATA:
|
||||
onWebsocketMessage(data);
|
||||
break;
|
||||
case WEBSOCKET_EVENT_ERROR:
|
||||
Serial.println(F("Mempool.space WS Connnection error"));
|
||||
break;
|
||||
case WEBSOCKET_EVENT_DISCONNECTED:
|
||||
Serial.println(F("Mempool.space WS Connnection Closed"));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (httpCode > 0 && httpCode == HTTP_CODE_OK)
|
||||
{
|
||||
String blockHeightStr = http->getString();
|
||||
currentBlockHeight = blockHeightStr.toInt();
|
||||
// xTaskNotifyGive(blockUpdateTaskHandle);
|
||||
if (workQueue != nullptr)
|
||||
{
|
||||
WorkItem blockUpdate = {TASK_BLOCK_UPDATE, 0};
|
||||
xQueueSend(workQueue, &blockUpdate, portMAX_DELAY);
|
||||
void onWebsocketMessage(esp_websocket_event_data_t *event_data) {
|
||||
SpiRamJsonDocument doc(event_data->data_len);
|
||||
|
||||
deserializeJson(doc, (char *)event_data->data_ptr);
|
||||
|
||||
if (doc.containsKey("block")) {
|
||||
JsonObject block = doc["block"];
|
||||
|
||||
currentBlockHeight = block["height"].as<uint>();
|
||||
|
||||
Serial.printf("New block found: %d\r\n", block["height"].as<uint>());
|
||||
preferences.putUInt("blockHeight", currentBlockHeight);
|
||||
|
||||
if (workQueue != nullptr) {
|
||||
WorkItem blockUpdate = {TASK_BLOCK_UPDATE, 0};
|
||||
xQueueSend(workQueue, &blockUpdate, portMAX_DELAY);
|
||||
// xTaskNotifyGive(blockUpdateTaskHandle);
|
||||
|
||||
if (getCurrentScreen() != SCREEN_BLOCK_HEIGHT &&
|
||||
preferences.getBool("stealFocus", true)) {
|
||||
uint64_t timerPeriod = 0;
|
||||
if (isTimerActive()) {
|
||||
// store timer periode before making inactive to prevent artifacts
|
||||
timerPeriod = getTimerSeconds();
|
||||
esp_timer_stop(screenRotateTimer);
|
||||
}
|
||||
}
|
||||
|
||||
// std::strcpy(wsServer, String("wss://" + mempoolInstance + "/api/v1/ws").c_str());
|
||||
|
||||
esp_websocket_client_config_t config = {
|
||||
.uri = "wss://mempool.space/api/v1/ws",
|
||||
// .task_stack = (6*1024),
|
||||
// .cert_pem = mempoolWsCert,
|
||||
.user_agent = USER_AGENT,
|
||||
};
|
||||
|
||||
blockNotifyClient = esp_websocket_client_init(&config);
|
||||
esp_websocket_register_events(blockNotifyClient, WEBSOCKET_EVENT_ANY, onWebsocketEvent, blockNotifyClient);
|
||||
esp_websocket_client_start(blockNotifyClient);
|
||||
}
|
||||
|
||||
void onWebsocketEvent(void *handler_args, esp_event_base_t base, int32_t event_id, void *event_data)
|
||||
{
|
||||
esp_websocket_event_data_t *data = (esp_websocket_event_data_t *)event_data;
|
||||
const String sub = "{\"action\": \"want\", \"data\":[\"blocks\"]}";
|
||||
switch (event_id)
|
||||
{
|
||||
case WEBSOCKET_EVENT_CONNECTED:
|
||||
Serial.println(F("Connected to Mempool.space WebSocket"));
|
||||
|
||||
Serial.println(sub);
|
||||
if (esp_websocket_client_send_text(blockNotifyClient, sub.c_str(), sub.length(), portMAX_DELAY) == -1)
|
||||
{
|
||||
Serial.println(F("Mempool.space WS Block Subscribe Error"));
|
||||
setCurrentScreen(SCREEN_BLOCK_HEIGHT);
|
||||
if (timerPeriod > 0) {
|
||||
esp_timer_start_periodic(screenRotateTimer,
|
||||
timerPeriod * usPerSecond);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
case WEBSOCKET_EVENT_DATA:
|
||||
onWebsocketMessage(data);
|
||||
break;
|
||||
case WEBSOCKET_EVENT_ERROR:
|
||||
Serial.println(F("Mempool.space WS Connnection error"));
|
||||
break;
|
||||
case WEBSOCKET_EVENT_DISCONNECTED:
|
||||
Serial.println(F("Mempool.space WS Connnection Closed"));
|
||||
break;
|
||||
if (getCurrentScreen() == SCREEN_BLOCK_HEIGHT &&
|
||||
preferences.getBool("ledFlashOnUpd", false)) {
|
||||
vTaskDelay(pdMS_TO_TICKS(250)); // Wait until screens are updated
|
||||
queueLedEffect(LED_FLASH_BLOCK_NOTIFY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
doc.clear();
|
||||
}
|
||||
|
||||
void onWebsocketMessage(esp_websocket_event_data_t *event_data)
|
||||
{
|
||||
SpiRamJsonDocument doc(event_data->data_len);
|
||||
uint getBlockHeight() { return currentBlockHeight; }
|
||||
|
||||
deserializeJson(doc, (char *)event_data->data_ptr);
|
||||
|
||||
if (doc.containsKey("block"))
|
||||
{
|
||||
JsonObject block = doc["block"];
|
||||
|
||||
currentBlockHeight = block["height"].as<uint>();
|
||||
|
||||
Serial.printf("New block found: %d\r\n", block["height"].as<uint>());
|
||||
preferences.putUInt("blockHeight", currentBlockHeight);
|
||||
|
||||
if (workQueue != nullptr)
|
||||
{
|
||||
WorkItem blockUpdate = {TASK_BLOCK_UPDATE, 0};
|
||||
xQueueSend(workQueue, &blockUpdate, portMAX_DELAY);
|
||||
// xTaskNotifyGive(blockUpdateTaskHandle);
|
||||
|
||||
if (getCurrentScreen() != SCREEN_BLOCK_HEIGHT && preferences.getBool("stealFocus", true))
|
||||
{
|
||||
uint64_t timerPeriod = 0;
|
||||
if (isTimerActive()) {
|
||||
// store timer periode before making inactive to prevent artifacts
|
||||
timerPeriod = getTimerSeconds();
|
||||
esp_timer_stop(screenRotateTimer);
|
||||
}
|
||||
setCurrentScreen(SCREEN_BLOCK_HEIGHT);
|
||||
if (timerPeriod > 0) {
|
||||
esp_timer_start_periodic(screenRotateTimer, timerPeriod * usPerSecond);
|
||||
}
|
||||
}
|
||||
|
||||
if (getCurrentScreen() == SCREEN_BLOCK_HEIGHT && preferences.getBool("ledFlashOnUpd", false))
|
||||
{
|
||||
vTaskDelay(pdMS_TO_TICKS(250)); // Wait until screens are updated
|
||||
queueLedEffect(LED_FLASH_BLOCK_NOTIFY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
doc.clear();
|
||||
void setBlockHeight(uint newBlockHeight) {
|
||||
currentBlockHeight = newBlockHeight;
|
||||
}
|
||||
|
||||
uint getBlockHeight()
|
||||
{
|
||||
return currentBlockHeight;
|
||||
bool isBlockNotifyConnected() {
|
||||
if (blockNotifyClient == NULL)
|
||||
return false;
|
||||
return esp_websocket_client_is_connected(blockNotifyClient);
|
||||
}
|
||||
|
||||
void setBlockHeight(uint newBlockHeight)
|
||||
{
|
||||
currentBlockHeight = newBlockHeight;
|
||||
}
|
||||
|
||||
bool isBlockNotifyConnected()
|
||||
{
|
||||
if (blockNotifyClient == NULL)
|
||||
return false;
|
||||
return esp_websocket_client_is_connected(blockNotifyClient);
|
||||
}
|
||||
|
||||
void stopBlockNotify()
|
||||
{
|
||||
esp_websocket_client_stop(blockNotifyClient);
|
||||
esp_websocket_client_destroy(blockNotifyClient);
|
||||
void stopBlockNotify() {
|
||||
esp_websocket_client_stop(blockNotifyClient);
|
||||
esp_websocket_client_destroy(blockNotifyClient);
|
||||
}
|
|
@ -1,22 +1,23 @@
|
|||
#pragma once
|
||||
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
#include "lib/led_handler.hpp"
|
||||
#include "lib/screen_handler.hpp"
|
||||
#include "lib/shared.hpp"
|
||||
#include <Arduino.h>
|
||||
#include <HTTPClient.h>
|
||||
#include <ArduinoJson.h>
|
||||
#include "shared.hpp"
|
||||
#include "esp_timer.h"
|
||||
#include "esp_websocket_client.h"
|
||||
#include "screen_handler.hpp"
|
||||
#include "led_handler.hpp"
|
||||
#include <HTTPClient.h>
|
||||
#include <cstring>
|
||||
#include <esp_timer.h>
|
||||
#include <esp_websocket_client.h>
|
||||
#include <string>
|
||||
|
||||
//using namespace websockets;
|
||||
// using namespace websockets;
|
||||
|
||||
void setupBlockNotify();
|
||||
|
||||
void onWebsocketEvent(void *handler_args, esp_event_base_t base, int32_t event_id, void *event_data);
|
||||
void onWebsocketMessage(esp_websocket_event_data_t* event_data);
|
||||
void onWebsocketEvent(void *handler_args, esp_event_base_t base,
|
||||
int32_t event_id, void *event_data);
|
||||
void onWebsocketMessage(esp_websocket_event_data_t *event_data);
|
||||
|
||||
void setBlockHeight(uint newBlockHeight);
|
||||
uint getBlockHeight();
|
||||
|
|
|
@ -4,64 +4,54 @@ TaskHandle_t buttonTaskHandle = NULL;
|
|||
const TickType_t debounceDelay = pdMS_TO_TICKS(50);
|
||||
TickType_t lastDebounceTime = 0;
|
||||
|
||||
void buttonTask(void *parameter)
|
||||
{
|
||||
while (1)
|
||||
{
|
||||
ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
|
||||
std::lock_guard<std::mutex> lock(mcpMutex);
|
||||
void buttonTask(void *parameter) {
|
||||
while (1) {
|
||||
ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
|
||||
std::lock_guard<std::mutex> lock(mcpMutex);
|
||||
|
||||
TickType_t currentTime = xTaskGetTickCount();
|
||||
if ((currentTime - lastDebounceTime) >= debounceDelay)
|
||||
{
|
||||
lastDebounceTime = currentTime;
|
||||
TickType_t currentTime = xTaskGetTickCount();
|
||||
if ((currentTime - lastDebounceTime) >= debounceDelay) {
|
||||
lastDebounceTime = currentTime;
|
||||
|
||||
if (!digitalRead(MCP_INT_PIN))
|
||||
{
|
||||
uint pin = mcp1.getLastInterruptPin();
|
||||
if (!digitalRead(MCP_INT_PIN)) {
|
||||
uint pin = mcp1.getLastInterruptPin();
|
||||
|
||||
switch (pin)
|
||||
{
|
||||
case 3:
|
||||
toggleTimerActive();
|
||||
break;
|
||||
case 2:
|
||||
nextScreen();
|
||||
break;
|
||||
case 1:
|
||||
previousScreen();
|
||||
break;
|
||||
case 0:
|
||||
showSystemStatusScreen();
|
||||
break;
|
||||
}
|
||||
}
|
||||
mcp1.clearInterrupts();
|
||||
}
|
||||
else
|
||||
{
|
||||
}
|
||||
// Very ugly, but for some reason this is necessary
|
||||
while (!digitalRead(MCP_INT_PIN))
|
||||
{
|
||||
mcp1.clearInterrupts();
|
||||
switch (pin) {
|
||||
case 3:
|
||||
toggleTimerActive();
|
||||
break;
|
||||
case 2:
|
||||
nextScreen();
|
||||
break;
|
||||
case 1:
|
||||
previousScreen();
|
||||
break;
|
||||
case 0:
|
||||
showSystemStatusScreen();
|
||||
break;
|
||||
}
|
||||
}
|
||||
mcp1.clearInterrupts();
|
||||
} else {
|
||||
}
|
||||
}
|
||||
|
||||
void IRAM_ATTR handleButtonInterrupt()
|
||||
{
|
||||
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
||||
xTaskNotifyFromISR(buttonTaskHandle, 0, eNoAction, &xHigherPriorityTaskWoken);
|
||||
if (xHigherPriorityTaskWoken == pdTRUE)
|
||||
{
|
||||
portYIELD_FROM_ISR();
|
||||
// Very ugly, but for some reason this is necessary
|
||||
while (!digitalRead(MCP_INT_PIN)) {
|
||||
mcp1.clearInterrupts();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void setupButtonTask()
|
||||
{
|
||||
xTaskCreate(buttonTask, "ButtonTask", 4096, NULL, tskIDLE_PRIORITY, &buttonTaskHandle); // Create the FreeRTOS task
|
||||
// Use interrupt instead of task
|
||||
attachInterrupt(MCP_INT_PIN, handleButtonInterrupt, CHANGE);
|
||||
void IRAM_ATTR handleButtonInterrupt() {
|
||||
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
||||
xTaskNotifyFromISR(buttonTaskHandle, 0, eNoAction, &xHigherPriorityTaskWoken);
|
||||
if (xHigherPriorityTaskWoken == pdTRUE) {
|
||||
portYIELD_FROM_ISR();
|
||||
}
|
||||
}
|
||||
|
||||
void setupButtonTask() {
|
||||
xTaskCreate(buttonTask, "ButtonTask", 4096, NULL, tskIDLE_PRIORITY,
|
||||
&buttonTaskHandle); // Create the FreeRTOS task
|
||||
// Use interrupt instead of task
|
||||
attachInterrupt(MCP_INT_PIN, handleButtonInterrupt, CHANGE);
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
#pragma once
|
||||
|
||||
#include "lib/screen_handler.hpp"
|
||||
#include "lib/shared.hpp"
|
||||
#include <Arduino.h>
|
||||
#include "shared.hpp"
|
||||
#include "screen_handler.hpp"
|
||||
|
||||
extern TaskHandle_t buttonTaskHandle;
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,26 +1,23 @@
|
|||
#pragma once;
|
||||
#include <WiFiManager.h>
|
||||
#include "base64.h"
|
||||
|
||||
#include <WiFiClientSecure.h>
|
||||
#include <Preferences.h>
|
||||
#include <Adafruit_MCP23X17.h>
|
||||
|
||||
#include <Arduino.h>
|
||||
#include "shared.hpp"
|
||||
#include "epd.hpp"
|
||||
#include "improv.hpp"
|
||||
#include "esp_task_wdt.h"
|
||||
|
||||
#include <Preferences.h>
|
||||
#include <WiFiClientSecure.h>
|
||||
#include <WiFiManager.h>
|
||||
#include <base64.h>
|
||||
#include <esp_task_wdt.h>
|
||||
#include <map>
|
||||
|
||||
#include "ota.hpp"
|
||||
#include "lib/screen_handler.hpp"
|
||||
#include "lib/webserver.hpp"
|
||||
#include "lib/block_notify.hpp"
|
||||
#include "lib/price_notify.hpp"
|
||||
#include "lib/button_handler.hpp"
|
||||
#include "lib/epd.hpp"
|
||||
#include "lib/improv.hpp"
|
||||
#include "lib/led_handler.hpp"
|
||||
#include "lib/ota.hpp"
|
||||
#include "lib/price_notify.hpp"
|
||||
#include "lib/screen_handler.hpp"
|
||||
#include "lib/shared.hpp"
|
||||
#include "lib/webserver.hpp"
|
||||
|
||||
#define NTP_SERVER "pool.ntp.org"
|
||||
#define DEFAULT_MEMPOOL_INSTANCE "mempool.space"
|
||||
|
|
645
src/lib/epd.cpp
645
src/lib/epd.cpp
|
@ -16,21 +16,12 @@ Native_Pin EPD_CS[NUM_SCREENS] = {
|
|||
#endif
|
||||
};
|
||||
Native_Pin EPD_BUSY[NUM_SCREENS] = {
|
||||
Native_Pin(3),
|
||||
Native_Pin(5),
|
||||
Native_Pin(7),
|
||||
Native_Pin(9),
|
||||
Native_Pin(37),
|
||||
Native_Pin(18),
|
||||
Native_Pin(16),
|
||||
Native_Pin(3), Native_Pin(5), Native_Pin(7), Native_Pin(9),
|
||||
Native_Pin(37), Native_Pin(18), Native_Pin(16),
|
||||
};
|
||||
MCP23X17_Pin EPD_RESET_MPD[NUM_SCREENS] = {
|
||||
MCP23X17_Pin(mcp1, 8),
|
||||
MCP23X17_Pin(mcp1, 9),
|
||||
MCP23X17_Pin(mcp1, 10),
|
||||
MCP23X17_Pin(mcp1, 11),
|
||||
MCP23X17_Pin(mcp1, 12),
|
||||
MCP23X17_Pin(mcp1, 13),
|
||||
MCP23X17_Pin(mcp1, 8), MCP23X17_Pin(mcp1, 9), MCP23X17_Pin(mcp1, 10),
|
||||
MCP23X17_Pin(mcp1, 11), MCP23X17_Pin(mcp1, 12), MCP23X17_Pin(mcp1, 13),
|
||||
MCP23X17_Pin(mcp1, 14),
|
||||
};
|
||||
|
||||
|
@ -39,36 +30,20 @@ Native_Pin EPD_DC = Native_Pin(14);
|
|||
Native_Pin EPD_DC = Native_Pin(38);
|
||||
|
||||
MCP23X17_Pin EPD_BUSY[NUM_SCREENS] = {
|
||||
MCP23X17_Pin(mcp1, 8),
|
||||
MCP23X17_Pin(mcp1, 9),
|
||||
MCP23X17_Pin(mcp1, 10),
|
||||
MCP23X17_Pin(mcp1, 11),
|
||||
MCP23X17_Pin(mcp1, 12),
|
||||
MCP23X17_Pin(mcp1, 13),
|
||||
MCP23X17_Pin(mcp1, 14),
|
||||
MCP23X17_Pin(mcp1, 4),
|
||||
MCP23X17_Pin(mcp1, 8), MCP23X17_Pin(mcp1, 9), MCP23X17_Pin(mcp1, 10),
|
||||
MCP23X17_Pin(mcp1, 11), MCP23X17_Pin(mcp1, 12), MCP23X17_Pin(mcp1, 13),
|
||||
MCP23X17_Pin(mcp1, 14), MCP23X17_Pin(mcp1, 4),
|
||||
};
|
||||
|
||||
MCP23X17_Pin EPD_CS[NUM_SCREENS] = {
|
||||
MCP23X17_Pin(mcp2, 8),
|
||||
MCP23X17_Pin(mcp2, 10),
|
||||
MCP23X17_Pin(mcp2, 12),
|
||||
MCP23X17_Pin(mcp2, 14),
|
||||
MCP23X17_Pin(mcp2, 0),
|
||||
MCP23X17_Pin(mcp2, 2),
|
||||
MCP23X17_Pin(mcp2, 4),
|
||||
MCP23X17_Pin(mcp2, 6)
|
||||
};
|
||||
MCP23X17_Pin(mcp2, 8), MCP23X17_Pin(mcp2, 10), MCP23X17_Pin(mcp2, 12),
|
||||
MCP23X17_Pin(mcp2, 14), MCP23X17_Pin(mcp2, 0), MCP23X17_Pin(mcp2, 2),
|
||||
MCP23X17_Pin(mcp2, 4), MCP23X17_Pin(mcp2, 6)};
|
||||
|
||||
MCP23X17_Pin EPD_RESET_MPD[NUM_SCREENS] = {
|
||||
MCP23X17_Pin(mcp2, 9),
|
||||
MCP23X17_Pin(mcp2, 11),
|
||||
MCP23X17_Pin(mcp2, 13),
|
||||
MCP23X17_Pin(mcp2, 15),
|
||||
MCP23X17_Pin(mcp2, 1),
|
||||
MCP23X17_Pin(mcp2, 3),
|
||||
MCP23X17_Pin(mcp2, 5),
|
||||
MCP23X17_Pin(mcp2, 7),
|
||||
MCP23X17_Pin(mcp2, 9), MCP23X17_Pin(mcp2, 11), MCP23X17_Pin(mcp2, 13),
|
||||
MCP23X17_Pin(mcp2, 15), MCP23X17_Pin(mcp2, 1), MCP23X17_Pin(mcp2, 3),
|
||||
MCP23X17_Pin(mcp2, 5), MCP23X17_Pin(mcp2, 7),
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -108,369 +83,329 @@ std::mutex epdMutex[NUM_SCREENS];
|
|||
|
||||
uint8_t qrcode[800];
|
||||
|
||||
void forceFullRefresh()
|
||||
{
|
||||
for (uint i = 0; i < NUM_SCREENS; i++)
|
||||
{
|
||||
lastFullRefresh[i] = NULL;
|
||||
}
|
||||
void forceFullRefresh() {
|
||||
for (uint i = 0; i < NUM_SCREENS; i++) {
|
||||
lastFullRefresh[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void refreshFromMemory()
|
||||
{
|
||||
for (uint i = 0; i < NUM_SCREENS; i++)
|
||||
{
|
||||
int *taskParam = new int;
|
||||
*taskParam = i;
|
||||
void refreshFromMemory() {
|
||||
for (uint i = 0; i < NUM_SCREENS; i++) {
|
||||
int *taskParam = new int;
|
||||
*taskParam = i;
|
||||
|
||||
xTaskCreate([](void *pvParameters)
|
||||
{
|
||||
const int epdIndex = *(int *)pvParameters;
|
||||
delete (int *)pvParameters;
|
||||
displays[epdIndex].refresh(false);
|
||||
vTaskDelete(NULL); },
|
||||
"PrepareUpd", 4096, taskParam, tskIDLE_PRIORITY, NULL);
|
||||
}
|
||||
xTaskCreate(
|
||||
[](void *pvParameters) {
|
||||
const int epdIndex = *(int *)pvParameters;
|
||||
delete (int *)pvParameters;
|
||||
displays[epdIndex].refresh(false);
|
||||
vTaskDelete(NULL);
|
||||
},
|
||||
"PrepareUpd", 4096, taskParam, tskIDLE_PRIORITY, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
void setupDisplays()
|
||||
{
|
||||
std::lock_guard<std::mutex> lockMcp(mcpMutex);
|
||||
void setupDisplays() {
|
||||
std::lock_guard<std::mutex> lockMcp(mcpMutex);
|
||||
|
||||
for (uint i = 0; i < NUM_SCREENS; i++)
|
||||
{
|
||||
displays[i].init(0, true, 30);
|
||||
}
|
||||
for (uint i = 0; i < NUM_SCREENS; i++) {
|
||||
displays[i].init(0, true, 30);
|
||||
}
|
||||
|
||||
updateQueue = xQueueCreate(UPDATE_QUEUE_SIZE, sizeof(UpdateDisplayTaskItem));
|
||||
updateQueue = xQueueCreate(UPDATE_QUEUE_SIZE, sizeof(UpdateDisplayTaskItem));
|
||||
|
||||
xTaskCreate(prepareDisplayUpdateTask, "PrepareUpd", 4096, NULL, 11, NULL);
|
||||
xTaskCreate(prepareDisplayUpdateTask, "PrepareUpd", 4096, NULL, 11, NULL);
|
||||
|
||||
for (uint i = 0; i < NUM_SCREENS; i++)
|
||||
{
|
||||
// epdUpdateSemaphore[i] = xSemaphoreCreateBinary();
|
||||
// xSemaphoreGive(epdUpdateSemaphore[i]);
|
||||
for (uint i = 0; i < NUM_SCREENS; i++) {
|
||||
// epdUpdateSemaphore[i] = xSemaphoreCreateBinary();
|
||||
// xSemaphoreGive(epdUpdateSemaphore[i]);
|
||||
|
||||
int *taskParam = new int;
|
||||
*taskParam = i;
|
||||
int *taskParam = new int;
|
||||
*taskParam = i;
|
||||
|
||||
xTaskCreate(updateDisplay, ("EpdUpd" + String(i)).c_str(), 2048, taskParam, 11, &tasks[i]); // create task
|
||||
}
|
||||
xTaskCreate(updateDisplay, ("EpdUpd" + String(i)).c_str(), 2048, taskParam,
|
||||
11, &tasks[i]); // create task
|
||||
}
|
||||
|
||||
epdContent = {"B",
|
||||
"T",
|
||||
"C",
|
||||
"L",
|
||||
"O",
|
||||
"C",
|
||||
"K"};
|
||||
epdContent = {"B", "T", "C", "L", "O", "C", "K"};
|
||||
|
||||
setEpdContent(epdContent);
|
||||
setEpdContent(epdContent);
|
||||
}
|
||||
|
||||
void setEpdContent(std::array<String, NUM_SCREENS> newEpdContent)
|
||||
{
|
||||
setEpdContent(newEpdContent, false);
|
||||
void setEpdContent(std::array<String, NUM_SCREENS> newEpdContent) {
|
||||
setEpdContent(newEpdContent, false);
|
||||
}
|
||||
|
||||
void setEpdContent(std::array<std::string, NUM_SCREENS> newEpdContent) {
|
||||
std::array<String, NUM_SCREENS> conv;
|
||||
std::array<String, NUM_SCREENS> conv;
|
||||
|
||||
for (size_t i = 0; i < newEpdContent.size(); ++i) {
|
||||
conv[i] = String(newEpdContent[i].c_str());
|
||||
}
|
||||
for (size_t i = 0; i < newEpdContent.size(); ++i) {
|
||||
conv[i] = String(newEpdContent[i].c_str());
|
||||
}
|
||||
|
||||
return setEpdContent(conv);
|
||||
return setEpdContent(conv);
|
||||
}
|
||||
|
||||
void setEpdContent(std::array<String, NUM_SCREENS> newEpdContent, bool forceUpdate)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(epdUpdateMutex);
|
||||
void setEpdContent(std::array<String, NUM_SCREENS> newEpdContent,
|
||||
bool forceUpdate) {
|
||||
std::lock_guard<std::mutex> lock(epdUpdateMutex);
|
||||
|
||||
waitUntilNoneBusy();
|
||||
waitUntilNoneBusy();
|
||||
|
||||
for (uint i = 0; i < NUM_SCREENS; i++) {
|
||||
if (newEpdContent[i].compareTo(currentEpdContent[i]) != 0 || forceUpdate) {
|
||||
epdContent[i] = newEpdContent[i];
|
||||
UpdateDisplayTaskItem dispUpdate = {i};
|
||||
xQueueSend(updateQueue, &dispUpdate, portMAX_DELAY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void prepareDisplayUpdateTask(void *pvParameters) {
|
||||
UpdateDisplayTaskItem receivedItem;
|
||||
|
||||
while (1) {
|
||||
// Wait for a work item to be available in the queue
|
||||
if (xQueueReceive(updateQueue, &receivedItem, portMAX_DELAY)) {
|
||||
uint epdIndex = receivedItem.dispNum;
|
||||
std::lock_guard<std::mutex> lock(epdMutex[epdIndex]);
|
||||
// displays[epdIndex].init(0, false); // Little longer reset duration
|
||||
// because of MCP
|
||||
|
||||
bool updatePartial = true;
|
||||
|
||||
if (strstr(epdContent[epdIndex].c_str(), "/") != NULL) {
|
||||
String top = epdContent[epdIndex].substring(
|
||||
0, epdContent[epdIndex].indexOf("/"));
|
||||
String bottom = epdContent[epdIndex].substring(
|
||||
epdContent[epdIndex].indexOf("/") + 1);
|
||||
splitText(epdIndex, top, bottom, updatePartial);
|
||||
} else if (epdContent[epdIndex].startsWith(F("qr"))) {
|
||||
renderQr(epdIndex, epdContent[epdIndex], updatePartial);
|
||||
} else if (epdContent[epdIndex].length() > 5) {
|
||||
renderText(epdIndex, epdContent[epdIndex], updatePartial);
|
||||
} else {
|
||||
|
||||
if (epdContent[epdIndex].length() > 1) {
|
||||
showChars(epdIndex, epdContent[epdIndex], updatePartial,
|
||||
&FONT_MEDIUM);
|
||||
} else {
|
||||
showDigit(epdIndex, epdContent[epdIndex].c_str()[0], updatePartial,
|
||||
&FONT_BIG);
|
||||
}
|
||||
}
|
||||
|
||||
xTaskNotifyGive(tasks[epdIndex]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" void updateDisplay(void *pvParameters) noexcept {
|
||||
const int epdIndex = *(int *)pvParameters;
|
||||
delete (int *)pvParameters;
|
||||
|
||||
for (;;) {
|
||||
// Wait for the task notification
|
||||
ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
|
||||
|
||||
std::lock_guard<std::mutex> lock(epdMutex[epdIndex]);
|
||||
|
||||
for (uint i = 0; i < NUM_SCREENS; i++)
|
||||
{
|
||||
if (newEpdContent[i].compareTo(currentEpdContent[i]) != 0 || forceUpdate)
|
||||
{
|
||||
epdContent[i] = newEpdContent[i];
|
||||
UpdateDisplayTaskItem dispUpdate = {i};
|
||||
xQueueSend(updateQueue, &dispUpdate, portMAX_DELAY);
|
||||
}
|
||||
std::lock_guard<std::mutex> lockMcp(mcpMutex);
|
||||
|
||||
displays[epdIndex].init(0, false, 40);
|
||||
}
|
||||
}
|
||||
|
||||
void prepareDisplayUpdateTask(void *pvParameters)
|
||||
{
|
||||
UpdateDisplayTaskItem receivedItem;
|
||||
|
||||
while (1)
|
||||
{
|
||||
// Wait for a work item to be available in the queue
|
||||
if (xQueueReceive(updateQueue, &receivedItem, portMAX_DELAY))
|
||||
{
|
||||
uint epdIndex = receivedItem.dispNum;
|
||||
std::lock_guard<std::mutex> lock(epdMutex[epdIndex]);
|
||||
// displays[epdIndex].init(0, false); // Little longer reset duration because of MCP
|
||||
|
||||
bool updatePartial = true;
|
||||
|
||||
if (strstr(epdContent[epdIndex].c_str(), "/") != NULL)
|
||||
{
|
||||
String top = epdContent[epdIndex].substring(0, epdContent[epdIndex].indexOf("/"));
|
||||
String bottom = epdContent[epdIndex].substring(epdContent[epdIndex].indexOf("/") + 1);
|
||||
splitText(epdIndex, top, bottom, updatePartial);
|
||||
}
|
||||
else if (epdContent[epdIndex].startsWith(F("qr")))
|
||||
{
|
||||
renderQr(epdIndex, epdContent[epdIndex], updatePartial);
|
||||
}
|
||||
else if (epdContent[epdIndex].length() > 5)
|
||||
{
|
||||
renderText(epdIndex, epdContent[epdIndex], updatePartial);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
if (epdContent[epdIndex].length() > 1)
|
||||
{
|
||||
showChars(epdIndex, epdContent[epdIndex], updatePartial, &FONT_MEDIUM);
|
||||
}
|
||||
else
|
||||
{
|
||||
showDigit(epdIndex, epdContent[epdIndex].c_str()[0], updatePartial, &FONT_BIG);
|
||||
}
|
||||
}
|
||||
|
||||
xTaskNotifyGive(tasks[epdIndex]);
|
||||
}
|
||||
uint count = 0;
|
||||
while (EPD_BUSY[epdIndex].digitalRead() == HIGH || count < 10) {
|
||||
vTaskDelay(pdMS_TO_TICKS(100));
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" void updateDisplay(void *pvParameters) noexcept
|
||||
{
|
||||
const int epdIndex = *(int *)pvParameters;
|
||||
delete (int *)pvParameters;
|
||||
bool updatePartial = true;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
// Wait for the task notification
|
||||
ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
|
||||
|
||||
std::lock_guard<std::mutex> lock(epdMutex[epdIndex]);
|
||||
|
||||
{
|
||||
std::lock_guard<std::mutex> lockMcp(mcpMutex);
|
||||
|
||||
displays[epdIndex].init(0, false, 40);
|
||||
}
|
||||
uint count = 0;
|
||||
while (EPD_BUSY[epdIndex].digitalRead() == HIGH || count < 10)
|
||||
{
|
||||
vTaskDelay(pdMS_TO_TICKS(100));
|
||||
count++;
|
||||
}
|
||||
|
||||
bool updatePartial = true;
|
||||
|
||||
// Full Refresh every x minutes
|
||||
if (!lastFullRefresh[epdIndex] || (millis() - lastFullRefresh[epdIndex]) > (preferences.getUInt("fullRefreshMin", DEFAULT_MINUTES_FULL_REFRESH) * 60 * 1000))
|
||||
{
|
||||
updatePartial = false;
|
||||
}
|
||||
|
||||
char tries = 0;
|
||||
while (tries < 3)
|
||||
{
|
||||
if (displays[epdIndex].displayWithReturn(updatePartial))
|
||||
{
|
||||
displays[epdIndex].powerOff();
|
||||
currentEpdContent[epdIndex] = epdContent[epdIndex];
|
||||
if (!updatePartial)
|
||||
lastFullRefresh[epdIndex] = millis();
|
||||
|
||||
if (eventSourceTaskHandle != NULL)
|
||||
xTaskNotifyGive(eventSourceTaskHandle);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
vTaskDelay(pdMS_TO_TICKS(100));
|
||||
tries++;
|
||||
}
|
||||
// Full Refresh every x minutes
|
||||
if (!lastFullRefresh[epdIndex] ||
|
||||
(millis() - lastFullRefresh[epdIndex]) >
|
||||
(preferences.getUInt("fullRefreshMin",
|
||||
DEFAULT_MINUTES_FULL_REFRESH) *
|
||||
60 * 1000)) {
|
||||
updatePartial = false;
|
||||
}
|
||||
}
|
||||
|
||||
void splitText(const uint dispNum, const String &top, const String &bottom, bool partial)
|
||||
{
|
||||
displays[dispNum].setRotation(2);
|
||||
displays[dispNum].setFont(&FONT_SMALL);
|
||||
displays[dispNum].setTextColor(getFgColor());
|
||||
char tries = 0;
|
||||
while (tries < 3) {
|
||||
if (displays[epdIndex].displayWithReturn(updatePartial)) {
|
||||
displays[epdIndex].powerOff();
|
||||
currentEpdContent[epdIndex] = epdContent[epdIndex];
|
||||
if (!updatePartial)
|
||||
lastFullRefresh[epdIndex] = millis();
|
||||
|
||||
// Top text
|
||||
int16_t ttbx, ttby;
|
||||
uint16_t ttbw, ttbh;
|
||||
displays[dispNum].getTextBounds(top, 0, 0, &ttbx, &ttby, &ttbw, &ttbh);
|
||||
uint16_t tx = ((displays[dispNum].width() - ttbw) / 2) - ttbx;
|
||||
uint16_t ty = ((displays[dispNum].height() - ttbh) / 2) - ttby - ttbh / 2 - 12;
|
||||
if (eventSourceTaskHandle != NULL)
|
||||
xTaskNotifyGive(eventSourceTaskHandle);
|
||||
|
||||
// Bottom text
|
||||
int16_t tbbx, tbby;
|
||||
uint16_t tbbw, tbbh;
|
||||
displays[dispNum].getTextBounds(bottom, 0, 0, &tbbx, &tbby, &tbbw, &tbbh);
|
||||
uint16_t bx = ((displays[dispNum].width() - tbbw) / 2) - tbbx;
|
||||
uint16_t by = ((displays[dispNum].height() - tbbh) / 2) - tbby + tbbh / 2 + 12;
|
||||
break;
|
||||
}
|
||||
|
||||
// Make separator as wide as the shortest text.
|
||||
uint16_t lineWidth, lineX;
|
||||
if (tbbw < ttbh)
|
||||
lineWidth = tbbw;
|
||||
else
|
||||
lineWidth = ttbw;
|
||||
lineX = round((displays[dispNum].width() - lineWidth) / 2);
|
||||
|
||||
displays[dispNum].fillScreen(getBgColor());
|
||||
displays[dispNum].setCursor(tx, ty);
|
||||
displays[dispNum].print(top);
|
||||
displays[dispNum].fillRoundRect(lineX, displays[dispNum].height() / 2 - 3, lineWidth, 6, 3, getFgColor());
|
||||
displays[dispNum].setCursor(bx, by);
|
||||
displays[dispNum].print(bottom);
|
||||
}
|
||||
|
||||
void showDigit(const uint dispNum, char chr, bool partial, const GFXfont *font)
|
||||
{
|
||||
String str(chr);
|
||||
displays[dispNum].setRotation(2);
|
||||
displays[dispNum].setFont(font);
|
||||
displays[dispNum].setTextColor(getFgColor());
|
||||
int16_t tbx, tby;
|
||||
uint16_t tbw, tbh;
|
||||
displays[dispNum].getTextBounds(str, 0, 0, &tbx, &tby, &tbw, &tbh);
|
||||
// center the bounding box by transposition of the origin:
|
||||
uint16_t x = ((displays[dispNum].width() - tbw) / 2) - tbx;
|
||||
uint16_t y = ((displays[dispNum].height() - tbh) / 2) - tby;
|
||||
displays[dispNum].fillScreen(getBgColor());
|
||||
displays[dispNum].setCursor(x, y);
|
||||
displays[dispNum].print(str);
|
||||
}
|
||||
|
||||
void showChars(const uint dispNum, const String &chars, bool partial, const GFXfont *font)
|
||||
{
|
||||
displays[dispNum].setRotation(2);
|
||||
displays[dispNum].setFont(font);
|
||||
displays[dispNum].setTextColor(getFgColor());
|
||||
int16_t tbx, tby;
|
||||
uint16_t tbw, tbh;
|
||||
displays[dispNum].getTextBounds(chars, 0, 0, &tbx, &tby, &tbw, &tbh);
|
||||
// center the bounding box by transposition of the origin:
|
||||
uint16_t x = ((displays[dispNum].width() - tbw) / 2) - tbx;
|
||||
uint16_t y = ((displays[dispNum].height() - tbh) / 2) - tby;
|
||||
displays[dispNum].fillScreen(getBgColor());
|
||||
displays[dispNum].setCursor(x, y);
|
||||
displays[dispNum].print(chars);
|
||||
}
|
||||
|
||||
int getBgColor()
|
||||
{
|
||||
return bgColor;
|
||||
}
|
||||
|
||||
int getFgColor()
|
||||
{
|
||||
return fgColor;
|
||||
}
|
||||
|
||||
void setBgColor(int color)
|
||||
{
|
||||
bgColor = color;
|
||||
}
|
||||
|
||||
void setFgColor(int color)
|
||||
{
|
||||
fgColor = color;
|
||||
}
|
||||
|
||||
std::array<String, NUM_SCREENS> getCurrentEpdContent()
|
||||
{
|
||||
return currentEpdContent;
|
||||
}
|
||||
void renderText(const uint dispNum, const String &text, bool partial)
|
||||
{
|
||||
displays[dispNum].setRotation(2);
|
||||
displays[dispNum].setPartialWindow(0, 0, displays[dispNum].width(), displays[dispNum].height());
|
||||
displays[dispNum].fillScreen(GxEPD_WHITE);
|
||||
displays[dispNum].setTextColor(GxEPD_BLACK);
|
||||
displays[dispNum].setCursor(0, 50);
|
||||
|
||||
std::stringstream ss;
|
||||
ss.str(text.c_str());
|
||||
|
||||
std::string line;
|
||||
|
||||
while (std::getline(ss, line, '\n'))
|
||||
{
|
||||
if (line.rfind("*", 0) == 0)
|
||||
{
|
||||
line.erase(std::remove(line.begin(), line.end(), '*'), line.end());
|
||||
|
||||
displays[dispNum].setFont(&FreeSansBold9pt7b);
|
||||
displays[dispNum].println(line.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
displays[dispNum].setFont(&FreeSans9pt7b);
|
||||
displays[dispNum].println(line.c_str());
|
||||
}
|
||||
vTaskDelay(pdMS_TO_TICKS(100));
|
||||
tries++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void renderQr(const uint dispNum, const String &text, bool partial)
|
||||
{
|
||||
void splitText(const uint dispNum, const String &top, const String &bottom,
|
||||
bool partial) {
|
||||
displays[dispNum].setRotation(2);
|
||||
displays[dispNum].setFont(&FONT_SMALL);
|
||||
displays[dispNum].setTextColor(getFgColor());
|
||||
|
||||
// Top text
|
||||
int16_t ttbx, ttby;
|
||||
uint16_t ttbw, ttbh;
|
||||
displays[dispNum].getTextBounds(top, 0, 0, &ttbx, &ttby, &ttbw, &ttbh);
|
||||
uint16_t tx = ((displays[dispNum].width() - ttbw) / 2) - ttbx;
|
||||
uint16_t ty =
|
||||
((displays[dispNum].height() - ttbh) / 2) - ttby - ttbh / 2 - 12;
|
||||
|
||||
// Bottom text
|
||||
int16_t tbbx, tbby;
|
||||
uint16_t tbbw, tbbh;
|
||||
displays[dispNum].getTextBounds(bottom, 0, 0, &tbbx, &tbby, &tbbw, &tbbh);
|
||||
uint16_t bx = ((displays[dispNum].width() - tbbw) / 2) - tbbx;
|
||||
uint16_t by =
|
||||
((displays[dispNum].height() - tbbh) / 2) - tbby + tbbh / 2 + 12;
|
||||
|
||||
// Make separator as wide as the shortest text.
|
||||
uint16_t lineWidth, lineX;
|
||||
if (tbbw < ttbh)
|
||||
lineWidth = tbbw;
|
||||
else
|
||||
lineWidth = ttbw;
|
||||
lineX = round((displays[dispNum].width() - lineWidth) / 2);
|
||||
|
||||
displays[dispNum].fillScreen(getBgColor());
|
||||
displays[dispNum].setCursor(tx, ty);
|
||||
displays[dispNum].print(top);
|
||||
displays[dispNum].fillRoundRect(lineX, displays[dispNum].height() / 2 - 3,
|
||||
lineWidth, 6, 3, getFgColor());
|
||||
displays[dispNum].setCursor(bx, by);
|
||||
displays[dispNum].print(bottom);
|
||||
}
|
||||
|
||||
void showDigit(const uint dispNum, char chr, bool partial,
|
||||
const GFXfont *font) {
|
||||
String str(chr);
|
||||
displays[dispNum].setRotation(2);
|
||||
displays[dispNum].setFont(font);
|
||||
displays[dispNum].setTextColor(getFgColor());
|
||||
int16_t tbx, tby;
|
||||
uint16_t tbw, tbh;
|
||||
displays[dispNum].getTextBounds(str, 0, 0, &tbx, &tby, &tbw, &tbh);
|
||||
// center the bounding box by transposition of the origin:
|
||||
uint16_t x = ((displays[dispNum].width() - tbw) / 2) - tbx;
|
||||
uint16_t y = ((displays[dispNum].height() - tbh) / 2) - tby;
|
||||
displays[dispNum].fillScreen(getBgColor());
|
||||
displays[dispNum].setCursor(x, y);
|
||||
displays[dispNum].print(str);
|
||||
}
|
||||
|
||||
void showChars(const uint dispNum, const String &chars, bool partial,
|
||||
const GFXfont *font) {
|
||||
displays[dispNum].setRotation(2);
|
||||
displays[dispNum].setFont(font);
|
||||
displays[dispNum].setTextColor(getFgColor());
|
||||
int16_t tbx, tby;
|
||||
uint16_t tbw, tbh;
|
||||
displays[dispNum].getTextBounds(chars, 0, 0, &tbx, &tby, &tbw, &tbh);
|
||||
// center the bounding box by transposition of the origin:
|
||||
uint16_t x = ((displays[dispNum].width() - tbw) / 2) - tbx;
|
||||
uint16_t y = ((displays[dispNum].height() - tbh) / 2) - tby;
|
||||
displays[dispNum].fillScreen(getBgColor());
|
||||
displays[dispNum].setCursor(x, y);
|
||||
displays[dispNum].print(chars);
|
||||
}
|
||||
|
||||
int getBgColor() { return bgColor; }
|
||||
|
||||
int getFgColor() { return fgColor; }
|
||||
|
||||
void setBgColor(int color) { bgColor = color; }
|
||||
|
||||
void setFgColor(int color) { fgColor = color; }
|
||||
|
||||
std::array<String, NUM_SCREENS> getCurrentEpdContent() {
|
||||
return currentEpdContent;
|
||||
}
|
||||
void renderText(const uint dispNum, const String &text, bool partial) {
|
||||
displays[dispNum].setRotation(2);
|
||||
displays[dispNum].setPartialWindow(0, 0, displays[dispNum].width(),
|
||||
displays[dispNum].height());
|
||||
displays[dispNum].fillScreen(GxEPD_WHITE);
|
||||
displays[dispNum].setTextColor(GxEPD_BLACK);
|
||||
displays[dispNum].setCursor(0, 50);
|
||||
|
||||
std::stringstream ss;
|
||||
ss.str(text.c_str());
|
||||
|
||||
std::string line;
|
||||
|
||||
while (std::getline(ss, line, '\n')) {
|
||||
if (line.rfind("*", 0) == 0) {
|
||||
line.erase(std::remove(line.begin(), line.end(), '*'), line.end());
|
||||
|
||||
displays[dispNum].setFont(&FreeSansBold9pt7b);
|
||||
displays[dispNum].println(line.c_str());
|
||||
} else {
|
||||
displays[dispNum].setFont(&FreeSans9pt7b);
|
||||
displays[dispNum].println(line.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void renderQr(const uint dispNum, const String &text, bool partial) {
|
||||
#ifdef USE_QR
|
||||
|
||||
uint8_t tempBuffer[800];
|
||||
bool ok = qrcodegen_encodeText(text.substring(2).c_str(), tempBuffer, qrcode, qrcodegen_Ecc_LOW,
|
||||
qrcodegen_VERSION_MIN, qrcodegen_VERSION_MAX, qrcodegen_Mask_AUTO, true);
|
||||
uint8_t tempBuffer[800];
|
||||
bool ok = qrcodegen_encodeText(
|
||||
text.substring(2).c_str(), tempBuffer, qrcode, qrcodegen_Ecc_LOW,
|
||||
qrcodegen_VERSION_MIN, qrcodegen_VERSION_MAX, qrcodegen_Mask_AUTO, true);
|
||||
|
||||
const int size = qrcodegen_getSize(qrcode);
|
||||
const int size = qrcodegen_getSize(qrcode);
|
||||
|
||||
const int padding = floor(float(displays[dispNum].width() - (size * 4)) / 2);
|
||||
const int paddingY = floor(float(displays[dispNum].height() - (size * 4)) / 2);
|
||||
displays[dispNum].setRotation(2);
|
||||
const int padding = floor(float(displays[dispNum].width() - (size * 4)) / 2);
|
||||
const int paddingY =
|
||||
floor(float(displays[dispNum].height() - (size * 4)) / 2);
|
||||
displays[dispNum].setRotation(2);
|
||||
|
||||
displays[dispNum].setPartialWindow(0, 0, displays[dispNum].width(), displays[dispNum].height());
|
||||
displays[dispNum].fillScreen(GxEPD_WHITE);
|
||||
const int border = 0;
|
||||
displays[dispNum].setPartialWindow(0, 0, displays[dispNum].width(),
|
||||
displays[dispNum].height());
|
||||
displays[dispNum].fillScreen(GxEPD_WHITE);
|
||||
const int border = 0;
|
||||
|
||||
for (int y = -border; y < size * 4 + border; y++)
|
||||
{
|
||||
for (int x = -border; x < size * 4 + border; x++)
|
||||
{
|
||||
displays[dispNum].drawPixel(padding + x, paddingY + y, qrcodegen_getModule(qrcode, floor(float(x) / 4), floor(float(y) / 4)) ? GxEPD_BLACK : GxEPD_WHITE);
|
||||
}
|
||||
for (int y = -border; y < size * 4 + border; y++) {
|
||||
for (int x = -border; x < size * 4 + border; x++) {
|
||||
displays[dispNum].drawPixel(
|
||||
padding + x, paddingY + y,
|
||||
qrcodegen_getModule(qrcode, floor(float(x) / 4), floor(float(y) / 4))
|
||||
? GxEPD_BLACK
|
||||
: GxEPD_WHITE);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void waitUntilNoneBusy()
|
||||
{
|
||||
for (int i = 0; i < NUM_SCREENS; i++)
|
||||
{
|
||||
uint count = 0;
|
||||
while (EPD_BUSY[i].digitalRead())
|
||||
{
|
||||
count++;
|
||||
vTaskDelay(10);
|
||||
if (count == 200)
|
||||
{
|
||||
// displays[i].init(0, false);
|
||||
vTaskDelay(100);
|
||||
}
|
||||
else if (count > 205)
|
||||
{
|
||||
Serial.printf("Busy timeout %d", i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
void waitUntilNoneBusy() {
|
||||
for (int i = 0; i < NUM_SCREENS; i++) {
|
||||
uint count = 0;
|
||||
while (EPD_BUSY[i].digitalRead()) {
|
||||
count++;
|
||||
vTaskDelay(10);
|
||||
if (count == 200) {
|
||||
// displays[i].init(0, false);
|
||||
vTaskDelay(100);
|
||||
} else if (count > 205) {
|
||||
Serial.printf("Busy timeout %d", i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,34 +1,35 @@
|
|||
#pragma once
|
||||
|
||||
#include <GxEPD2_BW.h>
|
||||
#include <native_pin.hpp>
|
||||
#include <mcp23x17_pin.hpp>
|
||||
#include "shared.hpp"
|
||||
#include "config.hpp"
|
||||
#include "fonts/fonts.hpp"
|
||||
#include <Fonts/FreeSansBold9pt7b.h>
|
||||
#include "lib/config.hpp"
|
||||
#include "lib/shared.hpp"
|
||||
#include <Fonts/FreeSans9pt7b.h>
|
||||
#include <regex>
|
||||
#include <Fonts/FreeSansBold9pt7b.h>
|
||||
#include <GxEPD2_BW.h>
|
||||
#include <mcp23x17_pin.hpp>
|
||||
#include <mutex>
|
||||
#include <native_pin.hpp>
|
||||
#include <regex>
|
||||
|
||||
#ifdef USE_QR
|
||||
#include "qrcodegen.h"
|
||||
#endif
|
||||
// extern TaskHandle_t epdTaskHandle;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char dispNum;
|
||||
typedef struct {
|
||||
char dispNum;
|
||||
} UpdateDisplayTaskItem;
|
||||
|
||||
void forceFullRefresh();
|
||||
void refreshFromMemory();
|
||||
void setupDisplays();
|
||||
|
||||
void splitText(const uint dispNum, const String& top, const String& bottom, bool partial);
|
||||
void splitText(const uint dispNum, const String &top, const String &bottom,
|
||||
bool partial);
|
||||
|
||||
void showDigit(const uint dispNum, char chr, bool partial, const GFXfont *font);
|
||||
void showChars(const uint dispNum, const String& chars, bool partial, const GFXfont *font);
|
||||
void showChars(const uint dispNum, const String &chars, bool partial,
|
||||
const GFXfont *font);
|
||||
|
||||
extern "C" void updateDisplay(void *pvParameters) noexcept;
|
||||
void updateDisplayAlt(int epdIndex);
|
||||
|
@ -39,10 +40,11 @@ int getFgColor();
|
|||
void setBgColor(int color);
|
||||
void setFgColor(int color);
|
||||
|
||||
void renderText(const uint dispNum, const String& text, bool partial);
|
||||
void renderQr(const uint dispNum, const String& text, bool partial);
|
||||
void renderText(const uint dispNum, const String &text, bool partial);
|
||||
void renderQr(const uint dispNum, const String &text, bool partial);
|
||||
|
||||
void setEpdContent(std::array<String, NUM_SCREENS> newEpdContent, bool forceUpdate);
|
||||
void setEpdContent(std::array<String, NUM_SCREENS> newEpdContent,
|
||||
bool forceUpdate);
|
||||
void setEpdContent(std::array<String, NUM_SCREENS> newEpdContent);
|
||||
|
||||
void setEpdContent(std::array<std::string, NUM_SCREENS> newEpdContent);
|
||||
|
|
|
@ -2,13 +2,15 @@
|
|||
|
||||
namespace improv {
|
||||
|
||||
ImprovCommand parse_improv_data(const std::vector<uint8_t> &data, bool check_checksum) {
|
||||
ImprovCommand parse_improv_data(const std::vector<uint8_t> &data,
|
||||
bool check_checksum) {
|
||||
return parse_improv_data(data.data(), data.size(), check_checksum);
|
||||
}
|
||||
|
||||
ImprovCommand parse_improv_data(const uint8_t *data, size_t length, bool check_checksum) {
|
||||
ImprovCommand parse_improv_data(const uint8_t *data, size_t length,
|
||||
bool check_checksum) {
|
||||
ImprovCommand improv_command;
|
||||
Command command = (Command) data[0];
|
||||
Command command = (Command)data[0];
|
||||
uint8_t data_length = data[1];
|
||||
|
||||
if (data_length != length - 2 - check_checksum) {
|
||||
|
@ -24,7 +26,7 @@ ImprovCommand parse_improv_data(const uint8_t *data, size_t length, bool check_c
|
|||
calculated_checksum += data[i];
|
||||
}
|
||||
|
||||
if ((uint8_t) calculated_checksum != checksum) {
|
||||
if ((uint8_t)calculated_checksum != checksum) {
|
||||
improv_command.command = BAD_CHECKSUM;
|
||||
return improv_command;
|
||||
}
|
||||
|
@ -48,8 +50,10 @@ ImprovCommand parse_improv_data(const uint8_t *data, size_t length, bool check_c
|
|||
return improv_command;
|
||||
}
|
||||
|
||||
bool parse_improv_serial_byte(size_t position, uint8_t byte, const uint8_t *buffer,
|
||||
std::function<bool(ImprovCommand)> &&callback, std::function<void(Error)> &&on_error) {
|
||||
bool parse_improv_serial_byte(size_t position, uint8_t byte,
|
||||
const uint8_t *buffer,
|
||||
std::function<bool(ImprovCommand)> &&callback,
|
||||
std::function<void(Error)> &&on_error) {
|
||||
if (position == 0)
|
||||
return byte == 'I';
|
||||
if (position == 1)
|
||||
|
@ -94,7 +98,9 @@ bool parse_improv_serial_byte(size_t position, uint8_t byte, const uint8_t *buff
|
|||
return false;
|
||||
}
|
||||
|
||||
std::vector<uint8_t> build_rpc_response(Command command, const std::vector<std::string> &datum, bool add_checksum) {
|
||||
std::vector<uint8_t> build_rpc_response(Command command,
|
||||
const std::vector<std::string> &datum,
|
||||
bool add_checksum) {
|
||||
std::vector<uint8_t> out;
|
||||
uint32_t length = 0;
|
||||
out.push_back(command);
|
||||
|
@ -118,7 +124,9 @@ std::vector<uint8_t> build_rpc_response(Command command, const std::vector<std::
|
|||
}
|
||||
|
||||
#ifdef ARDUINO
|
||||
std::vector<uint8_t> build_rpc_response(Command command, const std::vector<String> &datum, bool add_checksum) {
|
||||
std::vector<uint8_t> build_rpc_response(Command command,
|
||||
const std::vector<String> &datum,
|
||||
bool add_checksum) {
|
||||
std::vector<uint8_t> out;
|
||||
uint32_t length = 0;
|
||||
out.push_back(command);
|
||||
|
@ -140,6 +148,6 @@ std::vector<uint8_t> build_rpc_response(Command command, const std::vector<Strin
|
|||
}
|
||||
return out;
|
||||
}
|
||||
#endif // ARDUINO
|
||||
#endif // ARDUINO
|
||||
|
||||
} // namespace improv
|
||||
} // namespace improv
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
#ifdef ARDUINO
|
||||
#include <Arduino.h>
|
||||
#endif // ARDUINO
|
||||
#endif // ARDUINO
|
||||
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
|
@ -14,9 +14,12 @@ namespace improv {
|
|||
static const char *const SERVICE_UUID = "00467768-6228-2272-4663-277478268000";
|
||||
static const char *const STATUS_UUID = "00467768-6228-2272-4663-277478268001";
|
||||
static const char *const ERROR_UUID = "00467768-6228-2272-4663-277478268002";
|
||||
static const char *const RPC_COMMAND_UUID = "00467768-6228-2272-4663-277478268003";
|
||||
static const char *const RPC_RESULT_UUID = "00467768-6228-2272-4663-277478268004";
|
||||
static const char *const CAPABILITIES_UUID = "00467768-6228-2272-4663-277478268005";
|
||||
static const char *const RPC_COMMAND_UUID =
|
||||
"00467768-6228-2272-4663-277478268003";
|
||||
static const char *const RPC_RESULT_UUID =
|
||||
"00467768-6228-2272-4663-277478268004";
|
||||
static const char *const CAPABILITIES_UUID =
|
||||
"00467768-6228-2272-4663-277478268005";
|
||||
|
||||
enum Error : uint8_t {
|
||||
ERROR_NONE = 0x00,
|
||||
|
@ -61,16 +64,23 @@ struct ImprovCommand {
|
|||
std::string password;
|
||||
};
|
||||
|
||||
ImprovCommand parse_improv_data(const std::vector<uint8_t> &data, bool check_checksum = true);
|
||||
ImprovCommand parse_improv_data(const uint8_t *data, size_t length, bool check_checksum = true);
|
||||
ImprovCommand parse_improv_data(const std::vector<uint8_t> &data,
|
||||
bool check_checksum = true);
|
||||
ImprovCommand parse_improv_data(const uint8_t *data, size_t length,
|
||||
bool check_checksum = true);
|
||||
|
||||
bool parse_improv_serial_byte(size_t position, uint8_t byte, const uint8_t *buffer,
|
||||
std::function<bool(ImprovCommand)> &&callback, std::function<void(Error)> &&on_error);
|
||||
bool parse_improv_serial_byte(size_t position, uint8_t byte,
|
||||
const uint8_t *buffer,
|
||||
std::function<bool(ImprovCommand)> &&callback,
|
||||
std::function<void(Error)> &&on_error);
|
||||
|
||||
std::vector<uint8_t> build_rpc_response(Command command, const std::vector<std::string> &datum,
|
||||
std::vector<uint8_t> build_rpc_response(Command command,
|
||||
const std::vector<std::string> &datum,
|
||||
bool add_checksum = true);
|
||||
#ifdef ARDUINO
|
||||
std::vector<uint8_t> build_rpc_response(Command command, const std::vector<String> &datum, bool add_checksum = true);
|
||||
#endif // ARDUINO
|
||||
std::vector<uint8_t> build_rpc_response(Command command,
|
||||
const std::vector<String> &datum,
|
||||
bool add_checksum = true);
|
||||
#endif // ARDUINO
|
||||
|
||||
} // namespace improv
|
||||
} // namespace improv
|
|
@ -5,375 +5,322 @@ QueueHandle_t ledTaskQueue = NULL;
|
|||
Adafruit_NeoPixel pixels(NEOPIXEL_COUNT, NEOPIXEL_PIN, NEO_GRB + NEO_KHZ800);
|
||||
uint ledTaskParams;
|
||||
|
||||
void ledTask(void *parameter)
|
||||
{
|
||||
while (1)
|
||||
{
|
||||
if (ledTaskQueue != NULL)
|
||||
{
|
||||
if (xQueueReceive(ledTaskQueue, &ledTaskParams, portMAX_DELAY) == pdPASS)
|
||||
{
|
||||
uint32_t oldLights[NEOPIXEL_COUNT];
|
||||
void ledTask(void *parameter) {
|
||||
while (1) {
|
||||
if (ledTaskQueue != NULL) {
|
||||
if (xQueueReceive(ledTaskQueue, &ledTaskParams, portMAX_DELAY) ==
|
||||
pdPASS) {
|
||||
uint32_t oldLights[NEOPIXEL_COUNT];
|
||||
|
||||
// get current state
|
||||
for (int i = 0; i < NEOPIXEL_COUNT; i++)
|
||||
{
|
||||
oldLights[i] = pixels.getPixelColor(i);
|
||||
}
|
||||
// get current state
|
||||
for (int i = 0; i < NEOPIXEL_COUNT; i++) {
|
||||
oldLights[i] = pixels.getPixelColor(i);
|
||||
}
|
||||
|
||||
switch (ledTaskParams)
|
||||
{
|
||||
case LED_POWER_TEST:
|
||||
ledRainbow(20);
|
||||
pixels.clear();
|
||||
break;
|
||||
case LED_EFFECT_WIFI_CONNECT_ERROR:
|
||||
blinkDelayTwoColor(100, 3, pixels.Color(8, 161, 236), pixels.Color(255, 0, 0));
|
||||
break;
|
||||
case LED_FLASH_ERROR:
|
||||
blinkDelayColor(250, 3, 255, 0, 0);
|
||||
break;
|
||||
case LED_EFFECT_HEARTBEAT:
|
||||
blinkDelayColor(150, 2, 0, 0, 255);
|
||||
break;
|
||||
case LED_EFFECT_WIFI_CONNECT_SUCCESS:
|
||||
case LED_FLASH_SUCCESS:
|
||||
blinkDelayColor(150, 3, 0, 255, 0);
|
||||
break;
|
||||
case LED_PROGRESS_100:
|
||||
pixels.setPixelColor(0, pixels.Color(0, 255, 0));
|
||||
case LED_PROGRESS_75:
|
||||
pixels.setPixelColor(1, pixels.Color(0, 255, 0));
|
||||
case LED_PROGRESS_50:
|
||||
pixels.setPixelColor(2, pixels.Color(0, 255, 0));
|
||||
case LED_PROGRESS_25:
|
||||
pixels.setPixelColor(3, pixels.Color(0, 255, 0));
|
||||
pixels.show();
|
||||
break;
|
||||
case LED_FLASH_UPDATE:
|
||||
break;
|
||||
case LED_FLASH_BLOCK_NOTIFY:
|
||||
blinkDelayTwoColor(250, 3, pixels.Color(224, 67, 0), pixels.Color(8, 2, 0));
|
||||
break;
|
||||
case LED_EFFECT_WIFI_WAIT_FOR_CONFIG:
|
||||
blinkDelayTwoColor(100, 1, pixels.Color(8, 161, 236), pixels.Color(156, 225, 240));
|
||||
break;
|
||||
case LED_EFFECT_WIFI_ERASE_SETTINGS:
|
||||
blinkDelay(100, 3);
|
||||
break;
|
||||
case LED_EFFECT_WIFI_CONNECTING:
|
||||
for (int i = NEOPIXEL_COUNT; i >= 0; i--)
|
||||
{
|
||||
for (int j = NEOPIXEL_COUNT; j >= 0; j--)
|
||||
{
|
||||
if (j == i)
|
||||
{
|
||||
pixels.setPixelColor(i, pixels.Color(16, 197, 236));
|
||||
}
|
||||
else
|
||||
{
|
||||
pixels.setPixelColor(j, pixels.Color(0, 0, 0));
|
||||
}
|
||||
}
|
||||
pixels.show();
|
||||
vTaskDelay(pdMS_TO_TICKS(100));
|
||||
}
|
||||
break;
|
||||
case LED_EFFECT_PAUSE_TIMER:
|
||||
for (int i = NEOPIXEL_COUNT; i >= 0; i--)
|
||||
{
|
||||
for (int j = NEOPIXEL_COUNT; j >= 0; j--)
|
||||
{
|
||||
uint32_t c = pixels.Color(0, 0, 0);
|
||||
if (i == j)
|
||||
c = pixels.Color(0, 255, 0);
|
||||
pixels.setPixelColor(j, c);
|
||||
}
|
||||
|
||||
pixels.show();
|
||||
|
||||
delay(100);
|
||||
}
|
||||
pixels.setPixelColor(0, pixels.Color(255, 0, 0));
|
||||
pixels.show();
|
||||
|
||||
delay(900);
|
||||
|
||||
pixels.clear();
|
||||
pixels.show();
|
||||
break;
|
||||
case LED_EFFECT_START_TIMER:
|
||||
pixels.clear();
|
||||
pixels.setPixelColor((NEOPIXEL_COUNT - 1), pixels.Color(255, 0, 0));
|
||||
pixels.show();
|
||||
|
||||
delay(900);
|
||||
|
||||
for (int i = NEOPIXEL_COUNT; i--; i > 0)
|
||||
{
|
||||
|
||||
for (int j = NEOPIXEL_COUNT; j--; j > 0)
|
||||
{
|
||||
uint32_t c = pixels.Color(0, 0, 0);
|
||||
if (i == j)
|
||||
c = pixels.Color(0, 255, 0);
|
||||
|
||||
pixels.setPixelColor(j, c);
|
||||
}
|
||||
|
||||
pixels.show();
|
||||
|
||||
delay(100);
|
||||
}
|
||||
|
||||
pixels.clear();
|
||||
pixels.show();
|
||||
break;
|
||||
}
|
||||
|
||||
// revert to previous state unless power test
|
||||
|
||||
for (int i = 0; i < NEOPIXEL_COUNT; i++)
|
||||
{
|
||||
pixels.setPixelColor(i, oldLights[i]);
|
||||
}
|
||||
|
||||
pixels.show();
|
||||
switch (ledTaskParams) {
|
||||
case LED_POWER_TEST:
|
||||
ledRainbow(20);
|
||||
pixels.clear();
|
||||
break;
|
||||
case LED_EFFECT_WIFI_CONNECT_ERROR:
|
||||
blinkDelayTwoColor(100, 3, pixels.Color(8, 161, 236),
|
||||
pixels.Color(255, 0, 0));
|
||||
break;
|
||||
case LED_FLASH_ERROR:
|
||||
blinkDelayColor(250, 3, 255, 0, 0);
|
||||
break;
|
||||
case LED_EFFECT_HEARTBEAT:
|
||||
blinkDelayColor(150, 2, 0, 0, 255);
|
||||
break;
|
||||
case LED_EFFECT_WIFI_CONNECT_SUCCESS:
|
||||
case LED_FLASH_SUCCESS:
|
||||
blinkDelayColor(150, 3, 0, 255, 0);
|
||||
break;
|
||||
case LED_PROGRESS_100:
|
||||
pixels.setPixelColor(0, pixels.Color(0, 255, 0));
|
||||
case LED_PROGRESS_75:
|
||||
pixels.setPixelColor(1, pixels.Color(0, 255, 0));
|
||||
case LED_PROGRESS_50:
|
||||
pixels.setPixelColor(2, pixels.Color(0, 255, 0));
|
||||
case LED_PROGRESS_25:
|
||||
pixels.setPixelColor(3, pixels.Color(0, 255, 0));
|
||||
pixels.show();
|
||||
break;
|
||||
case LED_FLASH_UPDATE:
|
||||
break;
|
||||
case LED_FLASH_BLOCK_NOTIFY:
|
||||
blinkDelayTwoColor(250, 3, pixels.Color(224, 67, 0),
|
||||
pixels.Color(8, 2, 0));
|
||||
break;
|
||||
case LED_EFFECT_WIFI_WAIT_FOR_CONFIG:
|
||||
blinkDelayTwoColor(100, 1, pixels.Color(8, 161, 236),
|
||||
pixels.Color(156, 225, 240));
|
||||
break;
|
||||
case LED_EFFECT_WIFI_ERASE_SETTINGS:
|
||||
blinkDelay(100, 3);
|
||||
break;
|
||||
case LED_EFFECT_WIFI_CONNECTING:
|
||||
for (int i = NEOPIXEL_COUNT; i >= 0; i--) {
|
||||
for (int j = NEOPIXEL_COUNT; j >= 0; j--) {
|
||||
if (j == i) {
|
||||
pixels.setPixelColor(i, pixels.Color(16, 197, 236));
|
||||
} else {
|
||||
pixels.setPixelColor(j, pixels.Color(0, 0, 0));
|
||||
}
|
||||
}
|
||||
pixels.show();
|
||||
vTaskDelay(pdMS_TO_TICKS(100));
|
||||
}
|
||||
break;
|
||||
case LED_EFFECT_PAUSE_TIMER:
|
||||
for (int i = NEOPIXEL_COUNT; i >= 0; i--) {
|
||||
for (int j = NEOPIXEL_COUNT; j >= 0; j--) {
|
||||
uint32_t c = pixels.Color(0, 0, 0);
|
||||
if (i == j)
|
||||
c = pixels.Color(0, 255, 0);
|
||||
pixels.setPixelColor(j, c);
|
||||
}
|
||||
|
||||
pixels.show();
|
||||
|
||||
delay(100);
|
||||
}
|
||||
pixels.setPixelColor(0, pixels.Color(255, 0, 0));
|
||||
pixels.show();
|
||||
|
||||
delay(900);
|
||||
|
||||
pixels.clear();
|
||||
pixels.show();
|
||||
break;
|
||||
case LED_EFFECT_START_TIMER:
|
||||
pixels.clear();
|
||||
pixels.setPixelColor((NEOPIXEL_COUNT - 1), pixels.Color(255, 0, 0));
|
||||
pixels.show();
|
||||
|
||||
delay(900);
|
||||
|
||||
for (int i = NEOPIXEL_COUNT; i--; i > 0) {
|
||||
|
||||
for (int j = NEOPIXEL_COUNT; j--; j > 0) {
|
||||
uint32_t c = pixels.Color(0, 0, 0);
|
||||
if (i == j)
|
||||
c = pixels.Color(0, 255, 0);
|
||||
|
||||
pixels.setPixelColor(j, c);
|
||||
}
|
||||
|
||||
pixels.show();
|
||||
|
||||
delay(100);
|
||||
}
|
||||
|
||||
pixels.clear();
|
||||
pixels.show();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void setupLeds()
|
||||
{
|
||||
pixels.begin();
|
||||
pixels.setBrightness(preferences.getUInt("ledBrightness", 128));
|
||||
pixels.clear();
|
||||
pixels.show();
|
||||
setupLedTask();
|
||||
if (preferences.getBool("ledTestOnPower", true))
|
||||
{
|
||||
while (!ledTaskQueue)
|
||||
{
|
||||
delay(1);
|
||||
// wait until queue is available
|
||||
}
|
||||
queueLedEffect(LED_POWER_TEST);
|
||||
}
|
||||
}
|
||||
// revert to previous state unless power test
|
||||
|
||||
void setupLedTask()
|
||||
{
|
||||
ledTaskQueue = xQueueCreate(5, sizeof(uint));
|
||||
|
||||
xTaskCreate(ledTask, "LedTask", 2048, NULL, tskIDLE_PRIORITY, &ledTaskHandle);
|
||||
}
|
||||
|
||||
void blinkDelay(int d, int times)
|
||||
{
|
||||
for (int j = 0; j < times; j++)
|
||||
{
|
||||
|
||||
pixels.setPixelColor(0, pixels.Color(255, 0, 0));
|
||||
pixels.setPixelColor(1, pixels.Color(0, 255, 0));
|
||||
pixels.setPixelColor(2, pixels.Color(255, 0, 0));
|
||||
pixels.setPixelColor(3, pixels.Color(0, 255, 0));
|
||||
pixels.show();
|
||||
vTaskDelay(pdMS_TO_TICKS(d));
|
||||
|
||||
pixels.setPixelColor(0, pixels.Color(255, 255, 0));
|
||||
pixels.setPixelColor(1, pixels.Color(0, 255, 255));
|
||||
pixels.setPixelColor(2, pixels.Color(255, 255, 0));
|
||||
pixels.setPixelColor(3, pixels.Color(0, 255, 255));
|
||||
pixels.show();
|
||||
vTaskDelay(pdMS_TO_TICKS(d));
|
||||
}
|
||||
pixels.clear();
|
||||
pixels.show();
|
||||
}
|
||||
|
||||
void blinkDelayColor(int d, int times, uint r, uint g, uint b)
|
||||
{
|
||||
for (int j = 0; j < times; j++)
|
||||
{
|
||||
for (int i = 0; i < NEOPIXEL_COUNT; i++)
|
||||
{
|
||||
pixels.setPixelColor(i, pixels.Color(r, g, b));
|
||||
for (int i = 0; i < NEOPIXEL_COUNT; i++) {
|
||||
pixels.setPixelColor(i, oldLights[i]);
|
||||
}
|
||||
|
||||
pixels.show();
|
||||
vTaskDelay(pdMS_TO_TICKS(d));
|
||||
|
||||
pixels.clear();
|
||||
pixels.show();
|
||||
vTaskDelay(pdMS_TO_TICKS(d));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void setupLeds() {
|
||||
pixels.begin();
|
||||
pixels.setBrightness(preferences.getUInt("ledBrightness", 128));
|
||||
pixels.clear();
|
||||
pixels.show();
|
||||
setupLedTask();
|
||||
if (preferences.getBool("ledTestOnPower", true)) {
|
||||
while (!ledTaskQueue) {
|
||||
delay(1);
|
||||
// wait until queue is available
|
||||
}
|
||||
queueLedEffect(LED_POWER_TEST);
|
||||
}
|
||||
}
|
||||
|
||||
void setupLedTask() {
|
||||
ledTaskQueue = xQueueCreate(5, sizeof(uint));
|
||||
|
||||
xTaskCreate(ledTask, "LedTask", 2048, NULL, tskIDLE_PRIORITY, &ledTaskHandle);
|
||||
}
|
||||
|
||||
void blinkDelay(int d, int times) {
|
||||
for (int j = 0; j < times; j++) {
|
||||
|
||||
pixels.setPixelColor(0, pixels.Color(255, 0, 0));
|
||||
pixels.setPixelColor(1, pixels.Color(0, 255, 0));
|
||||
pixels.setPixelColor(2, pixels.Color(255, 0, 0));
|
||||
pixels.setPixelColor(3, pixels.Color(0, 255, 0));
|
||||
pixels.show();
|
||||
vTaskDelay(pdMS_TO_TICKS(d));
|
||||
|
||||
pixels.setPixelColor(0, pixels.Color(255, 255, 0));
|
||||
pixels.setPixelColor(1, pixels.Color(0, 255, 255));
|
||||
pixels.setPixelColor(2, pixels.Color(255, 255, 0));
|
||||
pixels.setPixelColor(3, pixels.Color(0, 255, 255));
|
||||
pixels.show();
|
||||
vTaskDelay(pdMS_TO_TICKS(d));
|
||||
}
|
||||
pixels.clear();
|
||||
pixels.show();
|
||||
}
|
||||
|
||||
void blinkDelayColor(int d, int times, uint r, uint g, uint b) {
|
||||
for (int j = 0; j < times; j++) {
|
||||
for (int i = 0; i < NEOPIXEL_COUNT; i++) {
|
||||
pixels.setPixelColor(i, pixels.Color(r, g, b));
|
||||
}
|
||||
|
||||
pixels.show();
|
||||
vTaskDelay(pdMS_TO_TICKS(d));
|
||||
|
||||
pixels.clear();
|
||||
pixels.show();
|
||||
vTaskDelay(pdMS_TO_TICKS(d));
|
||||
}
|
||||
pixels.clear();
|
||||
pixels.show();
|
||||
}
|
||||
|
||||
void blinkDelayTwoColor(int d, int times, uint32_t c1, uint32_t c2)
|
||||
{
|
||||
for (int j = 0; j < times; j++)
|
||||
{
|
||||
for (int i = 0; i < NEOPIXEL_COUNT; i++)
|
||||
{
|
||||
pixels.setPixelColor(i, c1);
|
||||
}
|
||||
pixels.show();
|
||||
vTaskDelay(pdMS_TO_TICKS(d));
|
||||
|
||||
for (int i = 0; i < NEOPIXEL_COUNT; i++)
|
||||
{
|
||||
pixels.setPixelColor(i, c2);
|
||||
}
|
||||
pixels.show();
|
||||
vTaskDelay(pdMS_TO_TICKS(d));
|
||||
}
|
||||
pixels.clear();
|
||||
pixels.show();
|
||||
}
|
||||
|
||||
void clearLeds()
|
||||
{
|
||||
preferences.putBool("ledStatus", false);
|
||||
pixels.clear();
|
||||
pixels.show();
|
||||
}
|
||||
|
||||
void setLights(int r, int g, int b)
|
||||
{
|
||||
setLights(pixels.Color(r, g, b));
|
||||
}
|
||||
|
||||
void setLights(uint32_t color)
|
||||
{
|
||||
|
||||
bool ledStatus = true;
|
||||
|
||||
|
||||
for (int i = 0; i < NEOPIXEL_COUNT; i++)
|
||||
{
|
||||
pixels.setPixelColor(i, color);
|
||||
void blinkDelayTwoColor(int d, int times, uint32_t c1, uint32_t c2) {
|
||||
for (int j = 0; j < times; j++) {
|
||||
for (int i = 0; i < NEOPIXEL_COUNT; i++) {
|
||||
pixels.setPixelColor(i, c1);
|
||||
}
|
||||
pixels.show();
|
||||
vTaskDelay(pdMS_TO_TICKS(d));
|
||||
|
||||
if (color == pixels.Color(0, 0, 0))
|
||||
{
|
||||
ledStatus = false;
|
||||
} else {
|
||||
saveLedState();
|
||||
for (int i = 0; i < NEOPIXEL_COUNT; i++) {
|
||||
pixels.setPixelColor(i, c2);
|
||||
}
|
||||
preferences.putBool("ledStatus", ledStatus);
|
||||
pixels.show();
|
||||
vTaskDelay(pdMS_TO_TICKS(d));
|
||||
}
|
||||
pixels.clear();
|
||||
pixels.show();
|
||||
}
|
||||
|
||||
void clearLeds() {
|
||||
preferences.putBool("ledStatus", false);
|
||||
pixels.clear();
|
||||
pixels.show();
|
||||
}
|
||||
|
||||
void setLights(int r, int g, int b) { setLights(pixels.Color(r, g, b)); }
|
||||
|
||||
void setLights(uint32_t color) {
|
||||
|
||||
bool ledStatus = true;
|
||||
|
||||
for (int i = 0; i < NEOPIXEL_COUNT; i++) {
|
||||
pixels.setPixelColor(i, color);
|
||||
}
|
||||
pixels.show();
|
||||
|
||||
if (color == pixels.Color(0, 0, 0)) {
|
||||
ledStatus = false;
|
||||
} else {
|
||||
saveLedState();
|
||||
}
|
||||
preferences.putBool("ledStatus", ledStatus);
|
||||
}
|
||||
|
||||
void saveLedState() {
|
||||
for (int i = 0; i < pixels.numPixels(); i++)
|
||||
{
|
||||
int pixelColor = pixels.getPixelColor(i);
|
||||
char key[12];
|
||||
snprintf(key, 12, "%s%d", "ledColor_", i);
|
||||
preferences.putUInt(key, pixelColor);
|
||||
}
|
||||
for (int i = 0; i < pixels.numPixels(); i++) {
|
||||
int pixelColor = pixels.getPixelColor(i);
|
||||
char key[12];
|
||||
snprintf(key, 12, "%s%d", "ledColor_", i);
|
||||
preferences.putUInt(key, pixelColor);
|
||||
}
|
||||
|
||||
xTaskNotifyGive(eventSourceTaskHandle);
|
||||
xTaskNotifyGive(eventSourceTaskHandle);
|
||||
}
|
||||
|
||||
void restoreLedState() {
|
||||
for (int i = 0; i < pixels.numPixels(); i++)
|
||||
{
|
||||
char key[12];
|
||||
snprintf(key, 12, "%s%d", "ledColor_", i);
|
||||
uint pixelColor = preferences.getUInt(key, pixels.Color(0,0,0));
|
||||
pixels.setPixelColor(i, pixelColor);
|
||||
for (int i = 0; i < pixels.numPixels(); i++) {
|
||||
char key[12];
|
||||
snprintf(key, 12, "%s%d", "ledColor_", i);
|
||||
uint pixelColor = preferences.getUInt(key, pixels.Color(0, 0, 0));
|
||||
pixels.setPixelColor(i, pixelColor);
|
||||
}
|
||||
|
||||
pixels.show();
|
||||
}
|
||||
|
||||
QueueHandle_t getLedTaskQueue() { return ledTaskQueue; }
|
||||
|
||||
bool queueLedEffect(uint effect) {
|
||||
if (ledTaskQueue == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
uint flashType = effect;
|
||||
xQueueSend(ledTaskQueue, &flashType, portMAX_DELAY);
|
||||
}
|
||||
|
||||
void ledRainbow(int wait) {
|
||||
// Hue of first pixel runs 5 complete loops through the color wheel.
|
||||
// Color wheel has a range of 65536 but it's OK if we roll over, so
|
||||
// just count from 0 to 5*65536. Adding 256 to firstPixelHue each time
|
||||
// means we'll make 5*65536/256 = 1280 passes through this loop:
|
||||
for (long firstPixelHue = 0; firstPixelHue < 5 * 65536;
|
||||
firstPixelHue += 256) {
|
||||
// strip.rainbow() can take a single argument (first pixel hue) or
|
||||
// optionally a few extras: number of rainbow repetitions (default 1),
|
||||
// saturation and value (brightness) (both 0-255, similar to the
|
||||
// ColorHSV() function, default 255), and a true/false flag for whether
|
||||
// to apply gamma correction to provide 'truer' colors (default true).
|
||||
pixels.rainbow(firstPixelHue);
|
||||
// Above line is equivalent to:
|
||||
// strip.rainbow(firstPixelHue, 1, 255, 255, true);
|
||||
pixels.show(); // Update strip with new contents
|
||||
delayMicroseconds(wait);
|
||||
// vTaskDelay(pdMS_TO_TICKS(wait)); // Pause for a moment
|
||||
}
|
||||
}
|
||||
|
||||
void ledTheaterChase(uint32_t color, int wait) {
|
||||
for (int a = 0; a < 10; a++) { // Repeat 10 times...
|
||||
for (int b = 0; b < 3; b++) { // 'b' counts from 0 to 2...
|
||||
pixels.clear(); // Set all pixels in RAM to 0 (off)
|
||||
// 'c' counts up from 'b' to end of strip in steps of 3...
|
||||
for (int c = b; c < pixels.numPixels(); c += 3) {
|
||||
pixels.setPixelColor(c, color); // Set pixel 'c' to value 'color'
|
||||
}
|
||||
pixels.show(); // Update strip with new contents
|
||||
vTaskDelay(pdMS_TO_TICKS(wait)); // Pause for a moment
|
||||
}
|
||||
|
||||
pixels.show();
|
||||
}
|
||||
}
|
||||
|
||||
QueueHandle_t getLedTaskQueue()
|
||||
{
|
||||
return ledTaskQueue;
|
||||
}
|
||||
|
||||
bool queueLedEffect(uint effect)
|
||||
{
|
||||
if (ledTaskQueue == NULL)
|
||||
{
|
||||
return false;
|
||||
void ledTheaterChaseRainbow(int wait) {
|
||||
int firstPixelHue = 0; // First pixel starts at red (hue 0)
|
||||
for (int a = 0; a < 30; a++) { // Repeat 30 times...
|
||||
for (int b = 0; b < 3; b++) { // 'b' counts from 0 to 2...
|
||||
pixels.clear(); // Set all pixels in RAM to 0 (off)
|
||||
// 'c' counts up from 'b' to end of strip in increments of 3...
|
||||
for (int c = b; c < pixels.numPixels(); c += 3) {
|
||||
// hue of pixel 'c' is offset by an amount to make one full
|
||||
// revolution of the color wheel (range 65536) along the length
|
||||
// of the strip (strip.numPixels() steps):
|
||||
int hue = firstPixelHue + c * 65536L / pixels.numPixels();
|
||||
uint32_t color = pixels.gamma32(pixels.ColorHSV(hue)); // hue -> RGB
|
||||
pixels.setPixelColor(c, color); // Set pixel 'c' to value 'color'
|
||||
}
|
||||
pixels.show(); // Update strip with new contents
|
||||
vTaskDelay(pdMS_TO_TICKS(wait)); // Pause for a moment
|
||||
firstPixelHue += 65536 / 90; // One cycle of color wheel over 90 frames
|
||||
}
|
||||
|
||||
uint flashType = effect;
|
||||
xQueueSend(ledTaskQueue, &flashType, portMAX_DELAY);
|
||||
}
|
||||
}
|
||||
|
||||
void ledRainbow(int wait)
|
||||
{
|
||||
// Hue of first pixel runs 5 complete loops through the color wheel.
|
||||
// Color wheel has a range of 65536 but it's OK if we roll over, so
|
||||
// just count from 0 to 5*65536. Adding 256 to firstPixelHue each time
|
||||
// means we'll make 5*65536/256 = 1280 passes through this loop:
|
||||
for (long firstPixelHue = 0; firstPixelHue < 5 * 65536; firstPixelHue += 256)
|
||||
{
|
||||
// strip.rainbow() can take a single argument (first pixel hue) or
|
||||
// optionally a few extras: number of rainbow repetitions (default 1),
|
||||
// saturation and value (brightness) (both 0-255, similar to the
|
||||
// ColorHSV() function, default 255), and a true/false flag for whether
|
||||
// to apply gamma correction to provide 'truer' colors (default true).
|
||||
pixels.rainbow(firstPixelHue);
|
||||
// Above line is equivalent to:
|
||||
// strip.rainbow(firstPixelHue, 1, 255, 255, true);
|
||||
pixels.show(); // Update strip with new contents
|
||||
delayMicroseconds(wait);
|
||||
// vTaskDelay(pdMS_TO_TICKS(wait)); // Pause for a moment
|
||||
}
|
||||
}
|
||||
|
||||
void ledTheaterChase(uint32_t color, int wait)
|
||||
{
|
||||
for (int a = 0; a < 10; a++)
|
||||
{ // Repeat 10 times...
|
||||
for (int b = 0; b < 3; b++)
|
||||
{ // 'b' counts from 0 to 2...
|
||||
pixels.clear(); // Set all pixels in RAM to 0 (off)
|
||||
// 'c' counts up from 'b' to end of strip in steps of 3...
|
||||
for (int c = b; c < pixels.numPixels(); c += 3)
|
||||
{
|
||||
pixels.setPixelColor(c, color); // Set pixel 'c' to value 'color'
|
||||
}
|
||||
pixels.show(); // Update strip with new contents
|
||||
vTaskDelay(pdMS_TO_TICKS(wait)); // Pause for a moment
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ledTheaterChaseRainbow(int wait)
|
||||
{
|
||||
int firstPixelHue = 0; // First pixel starts at red (hue 0)
|
||||
for (int a = 0; a < 30; a++)
|
||||
{ // Repeat 30 times...
|
||||
for (int b = 0; b < 3; b++)
|
||||
{ // 'b' counts from 0 to 2...
|
||||
pixels.clear(); // Set all pixels in RAM to 0 (off)
|
||||
// 'c' counts up from 'b' to end of strip in increments of 3...
|
||||
for (int c = b; c < pixels.numPixels(); c += 3)
|
||||
{
|
||||
// hue of pixel 'c' is offset by an amount to make one full
|
||||
// revolution of the color wheel (range 65536) along the length
|
||||
// of the strip (strip.numPixels() steps):
|
||||
int hue = firstPixelHue + c * 65536L / pixels.numPixels();
|
||||
uint32_t color = pixels.gamma32(pixels.ColorHSV(hue)); // hue -> RGB
|
||||
pixels.setPixelColor(c, color); // Set pixel 'c' to value 'color'
|
||||
}
|
||||
pixels.show(); // Update strip with new contents
|
||||
vTaskDelay(pdMS_TO_TICKS(wait)); // Pause for a moment
|
||||
firstPixelHue += 65536 / 90; // One cycle of color wheel over 90 frames
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Adafruit_NeoPixel getPixels()
|
||||
{
|
||||
return pixels;
|
||||
}
|
||||
Adafruit_NeoPixel getPixels() { return pixels; }
|
|
@ -1,11 +1,11 @@
|
|||
#pragma once
|
||||
|
||||
#include <Arduino.h>
|
||||
#include "lib/shared.hpp"
|
||||
#include "lib/webserver.hpp"
|
||||
#include <Adafruit_NeoPixel.h>
|
||||
#include <Arduino.h>
|
||||
#include <freertos/FreeRTOS.h>
|
||||
#include <freertos/task.h>
|
||||
#include "webserver.hpp"
|
||||
#include "shared.hpp"
|
||||
|
||||
#ifndef NEOPIXEL_PIN
|
||||
#define NEOPIXEL_PIN 34
|
||||
|
|
|
@ -2,10 +2,8 @@
|
|||
|
||||
TaskHandle_t taskOtaHandle = NULL;
|
||||
|
||||
void setupOTA()
|
||||
{
|
||||
if (preferences.getBool("otaEnabled", true))
|
||||
{
|
||||
void setupOTA() {
|
||||
if (preferences.getBool("otaEnabled", true)) {
|
||||
ArduinoOTA.onStart(onOTAStart);
|
||||
|
||||
ArduinoOTA.onProgress(onOTAProgress);
|
||||
|
@ -16,39 +14,35 @@ void setupOTA()
|
|||
ArduinoOTA.setMdnsEnabled(false);
|
||||
ArduinoOTA.setRebootOnSuccess(false);
|
||||
ArduinoOTA.begin();
|
||||
//downloadUpdate();
|
||||
// downloadUpdate();
|
||||
|
||||
xTaskCreate(handleOTATask, "handleOTA", 4096, NULL, tskIDLE_PRIORITY, &taskOtaHandle);
|
||||
xTaskCreate(handleOTATask, "handleOTA", 4096, NULL, tskIDLE_PRIORITY,
|
||||
&taskOtaHandle);
|
||||
}
|
||||
}
|
||||
|
||||
void onOTAProgress(unsigned int progress, unsigned int total)
|
||||
{
|
||||
void onOTAProgress(unsigned int progress, unsigned int total) {
|
||||
uint percentage = progress / (total / 100);
|
||||
pixels.fill(pixels.Color(0, 255, 0));
|
||||
if (percentage < 100)
|
||||
{
|
||||
if (percentage < 100) {
|
||||
pixels.setPixelColor(0, pixels.Color(0, 0, 0));
|
||||
}
|
||||
if (percentage < 75)
|
||||
{
|
||||
if (percentage < 75) {
|
||||
pixels.setPixelColor(1, pixels.Color(0, 0, 0));
|
||||
}
|
||||
if (percentage < 50)
|
||||
{
|
||||
if (percentage < 50) {
|
||||
pixels.setPixelColor(2, pixels.Color(0, 0, 0));
|
||||
}
|
||||
if (percentage < 25)
|
||||
{
|
||||
if (percentage < 25) {
|
||||
pixels.setPixelColor(3, pixels.Color(0, 0, 0));
|
||||
}
|
||||
pixels.show();
|
||||
}
|
||||
|
||||
void onOTAStart()
|
||||
{
|
||||
void onOTAStart() {
|
||||
forceFullRefresh();
|
||||
std::array<String, NUM_SCREENS> epdContent = {"U", "P", "D", "A", "T", "E", "!"};
|
||||
std::array<String, NUM_SCREENS> epdContent = {"U", "P", "D", "A",
|
||||
"T", "E", "!"};
|
||||
setEpdContent(epdContent);
|
||||
// Stop all timers
|
||||
esp_timer_stop(screenRotateTimer);
|
||||
|
@ -68,17 +62,14 @@ void onOTAStart()
|
|||
stopPriceNotify();
|
||||
}
|
||||
|
||||
void handleOTATask(void *parameter)
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
void handleOTATask(void *parameter) {
|
||||
for (;;) {
|
||||
ArduinoOTA.handle(); // Allow OTA updates to occur
|
||||
vTaskDelay(pdMS_TO_TICKS(2500));
|
||||
}
|
||||
}
|
||||
|
||||
void downloadUpdate()
|
||||
{
|
||||
void downloadUpdate() {
|
||||
WiFiClientSecure client;
|
||||
client.setInsecure();
|
||||
HTTPClient http;
|
||||
|
@ -87,12 +78,12 @@ void downloadUpdate()
|
|||
// Send HTTP request to CoinGecko API
|
||||
http.useHTTP10(true);
|
||||
|
||||
http.begin(client, "https://api.github.com/repos/btclock/btclock_v3/releases/latest");
|
||||
http.begin(client,
|
||||
"https://api.github.com/repos/btclock/btclock_v3/releases/latest");
|
||||
int httpCode = http.GET();
|
||||
|
||||
if (httpCode == 200)
|
||||
{
|
||||
// WiFiClient * stream = http->getStreamPtr();
|
||||
if (httpCode == 200) {
|
||||
// WiFiClient * stream = http->getStreamPtr();
|
||||
|
||||
StaticJsonDocument<64> filter;
|
||||
|
||||
|
@ -102,18 +93,17 @@ void downloadUpdate()
|
|||
|
||||
SpiRamJsonDocument doc(1536);
|
||||
|
||||
DeserializationError error = deserializeJson(doc, http.getStream(), DeserializationOption::Filter(filter));
|
||||
DeserializationError error = deserializeJson(
|
||||
doc, http.getStream(), DeserializationOption::Filter(filter));
|
||||
|
||||
if (error)
|
||||
{
|
||||
if (error) {
|
||||
Serial.print("deserializeJson() failed: ");
|
||||
Serial.println(error.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
String downloadUrl;
|
||||
for (JsonObject asset : doc["assets"].as<JsonArray>())
|
||||
{
|
||||
for (JsonObject asset : doc["assets"].as<JsonArray>()) {
|
||||
if (asset["name"].as<String>().compareTo("firmware.bin") == 0) {
|
||||
downloadUrl = asset["browser_download_url"].as<String>();
|
||||
break;
|
||||
|
@ -122,8 +112,6 @@ void downloadUpdate()
|
|||
|
||||
Serial.printf("Download update from %s", downloadUrl);
|
||||
|
||||
|
||||
|
||||
// esp_http_client_config_t config = {
|
||||
// .url = CONFIG_FIRMWARE_UPGRADE_URL,
|
||||
// };
|
||||
|
@ -138,8 +126,7 @@ void downloadUpdate()
|
|||
}
|
||||
}
|
||||
|
||||
void onOTAError(ota_error_t error)
|
||||
{
|
||||
void onOTAError(ota_error_t error) {
|
||||
Serial.println("\nOTA update error, restarting");
|
||||
Wire.end();
|
||||
SPI.end();
|
||||
|
@ -147,8 +134,7 @@ void onOTAError(ota_error_t error)
|
|||
ESP.restart();
|
||||
}
|
||||
|
||||
void onOTAComplete()
|
||||
{
|
||||
void onOTAComplete() {
|
||||
Serial.println("\nOTA update finished");
|
||||
Wire.end();
|
||||
SPI.end();
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#include "lib/config.hpp"
|
||||
#include "lib/shared.hpp"
|
||||
#include <Arduino.h>
|
||||
#include <ArduinoOTA.h>
|
||||
#include "config.hpp"
|
||||
#include "shared.hpp"
|
||||
|
||||
void setupOTA();
|
||||
void onOTAStart();
|
||||
|
|
|
@ -1,60 +1,56 @@
|
|||
#include "price_fetch.hpp"
|
||||
|
||||
const PROGMEM char *cgApiUrl = "https://api.coingecko.com/api/v3/simple/price?ids=bitcoin&vs_currencies=usd%2Ceur";
|
||||
const PROGMEM char *cgApiUrl = "https://api.coingecko.com/api/v3/simple/"
|
||||
"price?ids=bitcoin&vs_currencies=usd%2Ceur";
|
||||
|
||||
TaskHandle_t priceFetchTaskHandle;
|
||||
|
||||
void taskPriceFetch(void *pvParameters)
|
||||
{
|
||||
WiFiClientSecure *client = new WiFiClientSecure;
|
||||
client->setInsecure();
|
||||
for (;;)
|
||||
{
|
||||
ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
|
||||
void taskPriceFetch(void *pvParameters) {
|
||||
WiFiClientSecure *client = new WiFiClientSecure;
|
||||
client->setInsecure();
|
||||
for (;;) {
|
||||
ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
|
||||
|
||||
HTTPClient *http = new HTTPClient();
|
||||
http->setUserAgent(USER_AGENT);
|
||||
HTTPClient *http = new HTTPClient();
|
||||
http->setUserAgent(USER_AGENT);
|
||||
|
||||
// Send HTTP request to CoinGecko API
|
||||
http->begin(*client, cgApiUrl);
|
||||
// Send HTTP request to CoinGecko API
|
||||
http->begin(*client, cgApiUrl);
|
||||
|
||||
int httpCode = http->GET();
|
||||
int httpCode = http->GET();
|
||||
|
||||
// Parse JSON response and extract average price
|
||||
uint usdPrice, eurPrice;
|
||||
if (httpCode == 200)
|
||||
{
|
||||
String payload = http->getString();
|
||||
StaticJsonDocument<96> doc;
|
||||
deserializeJson(doc, payload);
|
||||
// usdPrice = doc["bitcoin"]["usd"];
|
||||
eurPrice = doc["bitcoin"]["eur"].as<uint>();
|
||||
// Parse JSON response and extract average price
|
||||
uint usdPrice, eurPrice;
|
||||
if (httpCode == 200) {
|
||||
String payload = http->getString();
|
||||
StaticJsonDocument<96> doc;
|
||||
deserializeJson(doc, payload);
|
||||
// usdPrice = doc["bitcoin"]["usd"];
|
||||
eurPrice = doc["bitcoin"]["eur"].as<uint>();
|
||||
|
||||
setPrice(eurPrice);
|
||||
if (workQueue != nullptr && (getCurrentScreen() == SCREEN_BTC_TICKER || getCurrentScreen() == SCREEN_MSCW_TIME || getCurrentScreen() == SCREEN_MARKET_CAP))
|
||||
{
|
||||
WorkItem priceUpdate = {TASK_PRICE_UPDATE, 0};
|
||||
xQueueSend(workQueue, &priceUpdate, portMAX_DELAY);
|
||||
}
|
||||
setPrice(eurPrice);
|
||||
if (workQueue != nullptr && (getCurrentScreen() == SCREEN_BTC_TICKER ||
|
||||
getCurrentScreen() == SCREEN_MSCW_TIME ||
|
||||
getCurrentScreen() == SCREEN_MARKET_CAP)) {
|
||||
WorkItem priceUpdate = {TASK_PRICE_UPDATE, 0};
|
||||
xQueueSend(workQueue, &priceUpdate, portMAX_DELAY);
|
||||
}
|
||||
|
||||
preferences.putUInt("lastPrice", eurPrice);
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.print(F("Error retrieving BTC/USD price (CoinGecko). HTTP status code: "));
|
||||
Serial.println(httpCode);
|
||||
if (httpCode == -1)
|
||||
{
|
||||
WiFi.reconnect();
|
||||
}
|
||||
}
|
||||
preferences.putUInt("lastPrice", eurPrice);
|
||||
} else {
|
||||
Serial.print(
|
||||
F("Error retrieving BTC/USD price (CoinGecko). HTTP status code: "));
|
||||
Serial.println(httpCode);
|
||||
if (httpCode == -1) {
|
||||
WiFi.reconnect();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void setupPriceFetchTask()
|
||||
{
|
||||
xTaskCreate(taskPriceFetch, "priceFetch", (6*1024), NULL, tskIDLE_PRIORITY, &priceFetchTaskHandle);
|
||||
|
||||
xTaskNotifyGive(priceFetchTaskHandle);
|
||||
void setupPriceFetchTask() {
|
||||
xTaskCreate(taskPriceFetch, "priceFetch", (6 * 1024), NULL, tskIDLE_PRIORITY,
|
||||
&priceFetchTaskHandle);
|
||||
|
||||
xTaskNotifyGive(priceFetchTaskHandle);
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
#include "lib/config.hpp"
|
||||
#include "lib/shared.hpp"
|
||||
#include <Arduino.h>
|
||||
#include <HTTPClient.h>
|
||||
#include "config.hpp"
|
||||
#include "shared.hpp"
|
||||
|
||||
extern TaskHandle_t priceFetchTaskHandle;
|
||||
|
||||
|
|
|
@ -38,86 +38,82 @@ esp_websocket_client_handle_t clientPrice = NULL;
|
|||
uint currentPrice = 30000;
|
||||
unsigned long int lastPriceUpdate;
|
||||
|
||||
void setupPriceNotify()
|
||||
{
|
||||
// currentPrice = preferences.get("lastPrice", 30000);
|
||||
void setupPriceNotify() {
|
||||
// currentPrice = preferences.get("lastPrice", 30000);
|
||||
|
||||
esp_websocket_client_config_t config = {
|
||||
.uri = wsServerPrice,
|
||||
// .task_stack = (7*1024),
|
||||
// .cert_pem = coinCapWsCert,
|
||||
.user_agent = USER_AGENT
|
||||
};
|
||||
esp_websocket_client_config_t config = {.uri = wsServerPrice,
|
||||
// .task_stack = (7*1024),
|
||||
// .cert_pem = coinCapWsCert,
|
||||
.user_agent = USER_AGENT};
|
||||
|
||||
clientPrice = esp_websocket_client_init(&config);
|
||||
esp_websocket_register_events(clientPrice, WEBSOCKET_EVENT_ANY, onWebsocketPriceEvent, clientPrice);
|
||||
esp_websocket_client_start(clientPrice);
|
||||
clientPrice = esp_websocket_client_init(&config);
|
||||
esp_websocket_register_events(clientPrice, WEBSOCKET_EVENT_ANY,
|
||||
onWebsocketPriceEvent, clientPrice);
|
||||
esp_websocket_client_start(clientPrice);
|
||||
}
|
||||
|
||||
void onWebsocketPriceEvent(void *handler_args, esp_event_base_t base, int32_t event_id, void *event_data)
|
||||
{
|
||||
esp_websocket_event_data_t *data = (esp_websocket_event_data_t *)event_data;
|
||||
void onWebsocketPriceEvent(void *handler_args, esp_event_base_t base,
|
||||
int32_t event_id, void *event_data) {
|
||||
esp_websocket_event_data_t *data = (esp_websocket_event_data_t *)event_data;
|
||||
|
||||
switch (event_id)
|
||||
{
|
||||
case WEBSOCKET_EVENT_CONNECTED:
|
||||
Serial.println(F("Connected to CoinCap.io WebSocket"));
|
||||
break;
|
||||
case WEBSOCKET_EVENT_DATA:
|
||||
onWebsocketPriceMessage(data);
|
||||
break;
|
||||
case WEBSOCKET_EVENT_ERROR:
|
||||
Serial.println(F("Price WS Connnection error"));
|
||||
break;
|
||||
case WEBSOCKET_EVENT_DISCONNECTED:
|
||||
Serial.println(F("Price WS Connnection Closed"));
|
||||
break;
|
||||
}
|
||||
switch (event_id) {
|
||||
case WEBSOCKET_EVENT_CONNECTED:
|
||||
Serial.println(F("Connected to CoinCap.io WebSocket"));
|
||||
break;
|
||||
case WEBSOCKET_EVENT_DATA:
|
||||
onWebsocketPriceMessage(data);
|
||||
break;
|
||||
case WEBSOCKET_EVENT_ERROR:
|
||||
Serial.println(F("Price WS Connnection error"));
|
||||
break;
|
||||
case WEBSOCKET_EVENT_DISCONNECTED:
|
||||
Serial.println(F("Price WS Connnection Closed"));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void onWebsocketPriceMessage(esp_websocket_event_data_t* event_data)
|
||||
{
|
||||
SpiRamJsonDocument doc(event_data->data_len);
|
||||
void onWebsocketPriceMessage(esp_websocket_event_data_t *event_data) {
|
||||
SpiRamJsonDocument doc(event_data->data_len);
|
||||
|
||||
deserializeJson(doc, (char *)event_data->data_ptr);
|
||||
deserializeJson(doc, (char *)event_data->data_ptr);
|
||||
|
||||
if (doc.containsKey("bitcoin")) {
|
||||
if (currentPrice != doc["bitcoin"].as<long>()) {
|
||||
if (doc.containsKey("bitcoin")) {
|
||||
if (currentPrice != doc["bitcoin"].as<long>()) {
|
||||
|
||||
uint minSecPriceUpd = preferences.getUInt("minSecPriceUpd", DEFAULT_SECONDS_BETWEEN_PRICE_UPDATE);
|
||||
uint currentTime = esp_timer_get_time() / 1000000;
|
||||
uint minSecPriceUpd = preferences.getUInt(
|
||||
"minSecPriceUpd", DEFAULT_SECONDS_BETWEEN_PRICE_UPDATE);
|
||||
uint currentTime = esp_timer_get_time() / 1000000;
|
||||
|
||||
if (lastPriceUpdate == 0 || (currentTime - lastPriceUpdate) > minSecPriceUpd) {
|
||||
// const unsigned long oldPrice = currentPrice;
|
||||
currentPrice = doc["bitcoin"].as<uint>();
|
||||
preferences.putUInt("lastPrice", currentPrice);
|
||||
lastPriceUpdate = currentTime;
|
||||
// if (abs((int)(oldPrice-currentPrice)) > round(0.0015*oldPrice)) {
|
||||
if (workQueue != nullptr && (getCurrentScreen() == SCREEN_BTC_TICKER || getCurrentScreen() == SCREEN_MSCW_TIME || getCurrentScreen() == SCREEN_MARKET_CAP)) {
|
||||
WorkItem priceUpdate = {TASK_PRICE_UPDATE, 0};
|
||||
xQueueSend(workQueue, &priceUpdate, portMAX_DELAY);
|
||||
}
|
||||
//}
|
||||
}
|
||||
if (lastPriceUpdate == 0 ||
|
||||
(currentTime - lastPriceUpdate) > minSecPriceUpd) {
|
||||
// const unsigned long oldPrice = currentPrice;
|
||||
currentPrice = doc["bitcoin"].as<uint>();
|
||||
preferences.putUInt("lastPrice", currentPrice);
|
||||
lastPriceUpdate = currentTime;
|
||||
// if (abs((int)(oldPrice-currentPrice)) > round(0.0015*oldPrice)) {
|
||||
if (workQueue != nullptr && (getCurrentScreen() == SCREEN_BTC_TICKER ||
|
||||
getCurrentScreen() == SCREEN_MSCW_TIME ||
|
||||
getCurrentScreen() == SCREEN_MARKET_CAP)) {
|
||||
WorkItem priceUpdate = {TASK_PRICE_UPDATE, 0};
|
||||
xQueueSend(workQueue, &priceUpdate, portMAX_DELAY);
|
||||
}
|
||||
//}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint getPrice() {
|
||||
return currentPrice;
|
||||
}
|
||||
uint getPrice() { return currentPrice; }
|
||||
|
||||
void setPrice(uint newPrice) {
|
||||
currentPrice = newPrice;
|
||||
}
|
||||
void setPrice(uint newPrice) { currentPrice = newPrice; }
|
||||
|
||||
bool isPriceNotifyConnected() {
|
||||
if (clientPrice == NULL)
|
||||
return false;
|
||||
return esp_websocket_client_is_connected(clientPrice);
|
||||
if (clientPrice == NULL)
|
||||
return false;
|
||||
return esp_websocket_client_is_connected(clientPrice);
|
||||
}
|
||||
|
||||
void stopPriceNotify() {
|
||||
esp_websocket_client_stop(clientPrice);
|
||||
esp_websocket_client_destroy(clientPrice);
|
||||
esp_websocket_client_stop(clientPrice);
|
||||
esp_websocket_client_destroy(clientPrice);
|
||||
}
|
|
@ -1,18 +1,19 @@
|
|||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <Arduino.h>
|
||||
#include <ArduinoJson.h>
|
||||
#include <string>
|
||||
|
||||
#include "esp_websocket_client.h"
|
||||
#include "screen_handler.hpp"
|
||||
#include <esp_websocket_client.h>
|
||||
#include "lib/screen_handler.hpp"
|
||||
|
||||
//using namespace websockets;
|
||||
// using namespace websockets;
|
||||
|
||||
void setupPriceNotify();
|
||||
|
||||
void onWebsocketPriceEvent(void *handler_args, esp_event_base_t base, int32_t event_id, void *event_data);
|
||||
void onWebsocketPriceMessage(esp_websocket_event_data_t* event_data);
|
||||
void onWebsocketPriceEvent(void *handler_args, esp_event_base_t base,
|
||||
int32_t event_id, void *event_data);
|
||||
void onWebsocketPriceMessage(esp_websocket_event_data_t *event_data);
|
||||
|
||||
uint getPrice();
|
||||
void setPrice(uint newPrice);
|
||||
|
|
|
@ -8,7 +8,8 @@ TaskHandle_t workerTaskHandle;
|
|||
esp_timer_handle_t screenRotateTimer;
|
||||
esp_timer_handle_t minuteTimer;
|
||||
|
||||
std::array<std::string, NUM_SCREENS> taskEpdContent = {"", "", "", "", "", "", ""};
|
||||
std::array<std::string, NUM_SCREENS> taskEpdContent = {"", "", "", "",
|
||||
"", "", ""};
|
||||
std::string priceString;
|
||||
|
||||
// typedef enum
|
||||
|
@ -29,327 +30,280 @@ QueueHandle_t workQueue = NULL;
|
|||
|
||||
uint currentScreen;
|
||||
|
||||
void workerTask(void *pvParameters)
|
||||
{
|
||||
WorkItem receivedItem;
|
||||
void workerTask(void *pvParameters) {
|
||||
WorkItem receivedItem;
|
||||
|
||||
while (1)
|
||||
{
|
||||
// Wait for a work item to be available in the queue
|
||||
if (xQueueReceive(workQueue, &receivedItem, portMAX_DELAY))
|
||||
{
|
||||
uint firstIndex = 0;
|
||||
while (1) {
|
||||
// Wait for a work item to be available in the queue
|
||||
if (xQueueReceive(workQueue, &receivedItem, portMAX_DELAY)) {
|
||||
uint firstIndex = 0;
|
||||
|
||||
// Process the work item based on its type
|
||||
switch (receivedItem.type)
|
||||
{
|
||||
case TASK_PRICE_UPDATE:
|
||||
{
|
||||
uint price = getPrice();
|
||||
char priceSymbol = '$';
|
||||
if (preferences.getBool("fetchEurPrice", false))
|
||||
{
|
||||
priceSymbol = '[';
|
||||
}
|
||||
if (getCurrentScreen() == SCREEN_BTC_TICKER)
|
||||
{
|
||||
taskEpdContent = parsePriceData(price, priceSymbol);
|
||||
}
|
||||
else if (getCurrentScreen() == SCREEN_MSCW_TIME)
|
||||
{
|
||||
taskEpdContent = parseSatsPerCurrency(price, priceSymbol);
|
||||
}
|
||||
else
|
||||
{
|
||||
taskEpdContent = parseMarketCap(getBlockHeight(), price, priceSymbol, preferences.getBool("mcapBigChar", true));
|
||||
}
|
||||
|
||||
setEpdContent(taskEpdContent);
|
||||
break;
|
||||
}
|
||||
case TASK_BLOCK_UPDATE:
|
||||
{
|
||||
if (getCurrentScreen() != SCREEN_HALVING_COUNTDOWN)
|
||||
{
|
||||
taskEpdContent = parseBlockHeight(getBlockHeight());
|
||||
}
|
||||
else
|
||||
{
|
||||
taskEpdContent = parseHalvingCountdown(getBlockHeight());
|
||||
}
|
||||
|
||||
if (getCurrentScreen() == SCREEN_HALVING_COUNTDOWN || getCurrentScreen() == SCREEN_BLOCK_HEIGHT)
|
||||
{
|
||||
setEpdContent(taskEpdContent);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TASK_TIME_UPDATE:
|
||||
{
|
||||
if (getCurrentScreen() == SCREEN_TIME)
|
||||
{
|
||||
time_t currentTime;
|
||||
struct tm timeinfo;
|
||||
time(¤tTime);
|
||||
localtime_r(¤tTime, &timeinfo);
|
||||
std::string timeString;
|
||||
|
||||
String minute = String(timeinfo.tm_min);
|
||||
if (minute.length() < 2)
|
||||
{
|
||||
minute = "0" + minute;
|
||||
}
|
||||
|
||||
timeString = std::to_string(timeinfo.tm_hour) + ":" + minute.c_str();
|
||||
timeString.insert(timeString.begin(), NUM_SCREENS - timeString.length(), ' ');
|
||||
taskEpdContent[0] = std::to_string(timeinfo.tm_mday) + "/" + std::to_string(timeinfo.tm_mon + 1);
|
||||
|
||||
for (uint i = 1; i < NUM_SCREENS; i++)
|
||||
{
|
||||
taskEpdContent[i] = timeString[i];
|
||||
}
|
||||
setEpdContent(taskEpdContent);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
// Add more cases for additional task types
|
||||
}
|
||||
// Process the work item based on its type
|
||||
switch (receivedItem.type) {
|
||||
case TASK_PRICE_UPDATE: {
|
||||
uint price = getPrice();
|
||||
char priceSymbol = '$';
|
||||
if (preferences.getBool("fetchEurPrice", false)) {
|
||||
priceSymbol = '[';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void taskScreenRotate(void *pvParameters)
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
|
||||
|
||||
int nextScreen = (currentScreen + 1) % SCREEN_COUNT;
|
||||
String key = "screen" + String(nextScreen) + "Visible";
|
||||
|
||||
while (!preferences.getBool(key.c_str(), true))
|
||||
{
|
||||
nextScreen = (nextScreen + 1) % SCREEN_COUNT;
|
||||
key = "screen" + String(nextScreen) + "Visible";
|
||||
if (getCurrentScreen() == SCREEN_BTC_TICKER) {
|
||||
taskEpdContent = parsePriceData(price, priceSymbol);
|
||||
} else if (getCurrentScreen() == SCREEN_MSCW_TIME) {
|
||||
taskEpdContent = parseSatsPerCurrency(price, priceSymbol);
|
||||
} else {
|
||||
taskEpdContent =
|
||||
parseMarketCap(getBlockHeight(), price, priceSymbol,
|
||||
preferences.getBool("mcapBigChar", true));
|
||||
}
|
||||
|
||||
setCurrentScreen(nextScreen);
|
||||
setEpdContent(taskEpdContent);
|
||||
break;
|
||||
}
|
||||
case TASK_BLOCK_UPDATE: {
|
||||
if (getCurrentScreen() != SCREEN_HALVING_COUNTDOWN) {
|
||||
taskEpdContent = parseBlockHeight(getBlockHeight());
|
||||
} else {
|
||||
taskEpdContent = parseHalvingCountdown(getBlockHeight());
|
||||
}
|
||||
|
||||
if (getCurrentScreen() == SCREEN_HALVING_COUNTDOWN ||
|
||||
getCurrentScreen() == SCREEN_BLOCK_HEIGHT) {
|
||||
setEpdContent(taskEpdContent);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TASK_TIME_UPDATE: {
|
||||
if (getCurrentScreen() == SCREEN_TIME) {
|
||||
time_t currentTime;
|
||||
struct tm timeinfo;
|
||||
time(¤tTime);
|
||||
localtime_r(¤tTime, &timeinfo);
|
||||
std::string timeString;
|
||||
|
||||
String minute = String(timeinfo.tm_min);
|
||||
if (minute.length() < 2) {
|
||||
minute = "0" + minute;
|
||||
}
|
||||
|
||||
timeString = std::to_string(timeinfo.tm_hour) + ":" + minute.c_str();
|
||||
timeString.insert(timeString.begin(),
|
||||
NUM_SCREENS - timeString.length(), ' ');
|
||||
taskEpdContent[0] = std::to_string(timeinfo.tm_mday) + "/" +
|
||||
std::to_string(timeinfo.tm_mon + 1);
|
||||
|
||||
for (uint i = 1; i < NUM_SCREENS; i++) {
|
||||
taskEpdContent[i] = timeString[i];
|
||||
}
|
||||
setEpdContent(taskEpdContent);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
// Add more cases for additional task types
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void IRAM_ATTR minuteTimerISR(void *arg)
|
||||
{
|
||||
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
||||
// vTaskNotifyGiveFromISR(timeUpdateTaskHandle, &xHigherPriorityTaskWoken);
|
||||
WorkItem timeUpdate = {TASK_TIME_UPDATE, 0};
|
||||
xQueueSendFromISR(workQueue, &timeUpdate, &xHigherPriorityTaskWoken);
|
||||
if (priceFetchTaskHandle != NULL)
|
||||
{
|
||||
vTaskNotifyGiveFromISR(priceFetchTaskHandle, &xHigherPriorityTaskWoken);
|
||||
}
|
||||
if (xHigherPriorityTaskWoken == pdTRUE)
|
||||
{
|
||||
portYIELD_FROM_ISR();
|
||||
void taskScreenRotate(void *pvParameters) {
|
||||
for (;;) {
|
||||
ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
|
||||
|
||||
int nextScreen = (currentScreen + 1) % SCREEN_COUNT;
|
||||
String key = "screen" + String(nextScreen) + "Visible";
|
||||
|
||||
while (!preferences.getBool(key.c_str(), true)) {
|
||||
nextScreen = (nextScreen + 1) % SCREEN_COUNT;
|
||||
key = "screen" + String(nextScreen) + "Visible";
|
||||
}
|
||||
|
||||
setCurrentScreen(nextScreen);
|
||||
}
|
||||
}
|
||||
|
||||
void IRAM_ATTR screenRotateTimerISR(void *arg)
|
||||
{
|
||||
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
||||
vTaskNotifyGiveFromISR(taskScreenRotateTaskHandle, &xHigherPriorityTaskWoken);
|
||||
if (xHigherPriorityTaskWoken == pdTRUE)
|
||||
{
|
||||
portYIELD_FROM_ISR();
|
||||
}
|
||||
void IRAM_ATTR minuteTimerISR(void *arg) {
|
||||
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
||||
// vTaskNotifyGiveFromISR(timeUpdateTaskHandle, &xHigherPriorityTaskWoken);
|
||||
WorkItem timeUpdate = {TASK_TIME_UPDATE, 0};
|
||||
xQueueSendFromISR(workQueue, &timeUpdate, &xHigherPriorityTaskWoken);
|
||||
if (priceFetchTaskHandle != NULL) {
|
||||
vTaskNotifyGiveFromISR(priceFetchTaskHandle, &xHigherPriorityTaskWoken);
|
||||
}
|
||||
if (xHigherPriorityTaskWoken == pdTRUE) {
|
||||
portYIELD_FROM_ISR();
|
||||
}
|
||||
}
|
||||
|
||||
void setupTasks()
|
||||
{
|
||||
workQueue = xQueueCreate(WORK_QUEUE_SIZE, sizeof(WorkItem));
|
||||
|
||||
// xTaskCreate(taskPriceUpdate, "updatePrice", 1024, NULL, tskIDLE_PRIORITY, &priceUpdateTaskHandle);
|
||||
// xTaskCreate(taskBlockUpdate, "updateBlock", 1024, NULL, tskIDLE_PRIORITY, &blockUpdateTaskHandle);
|
||||
// xTaskCreate(taskTimeUpdate, "updateTime", 1024, NULL, tskIDLE_PRIORITY, &timeUpdateTaskHandle);
|
||||
xTaskCreate(workerTask, "workerTask", 4096, NULL, tskIDLE_PRIORITY, &workerTaskHandle);
|
||||
|
||||
xTaskCreate(taskScreenRotate, "rotateScreen", 2048, NULL, tskIDLE_PRIORITY, &taskScreenRotateTaskHandle);
|
||||
|
||||
waitUntilNoneBusy();
|
||||
setCurrentScreen(preferences.getUInt("currentScreen", 0));
|
||||
void IRAM_ATTR screenRotateTimerISR(void *arg) {
|
||||
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
||||
vTaskNotifyGiveFromISR(taskScreenRotateTaskHandle, &xHigherPriorityTaskWoken);
|
||||
if (xHigherPriorityTaskWoken == pdTRUE) {
|
||||
portYIELD_FROM_ISR();
|
||||
}
|
||||
}
|
||||
|
||||
void setupTimeUpdateTimer(void *pvParameters)
|
||||
{
|
||||
const esp_timer_create_args_t minuteTimerConfig = {
|
||||
.callback = &minuteTimerISR,
|
||||
.name = "minute_timer"};
|
||||
void setupTasks() {
|
||||
workQueue = xQueueCreate(WORK_QUEUE_SIZE, sizeof(WorkItem));
|
||||
|
||||
esp_timer_create(&minuteTimerConfig, &minuteTimer);
|
||||
// xTaskCreate(taskPriceUpdate, "updatePrice", 1024, NULL, tskIDLE_PRIORITY,
|
||||
// &priceUpdateTaskHandle); xTaskCreate(taskBlockUpdate, "updateBlock", 1024,
|
||||
// NULL, tskIDLE_PRIORITY, &blockUpdateTaskHandle);
|
||||
// xTaskCreate(taskTimeUpdate, "updateTime", 1024, NULL, tskIDLE_PRIORITY,
|
||||
// &timeUpdateTaskHandle);
|
||||
xTaskCreate(workerTask, "workerTask", 4096, NULL, tskIDLE_PRIORITY,
|
||||
&workerTaskHandle);
|
||||
|
||||
time_t currentTime;
|
||||
struct tm timeinfo;
|
||||
time(¤tTime);
|
||||
localtime_r(¤tTime, &timeinfo);
|
||||
uint32_t secondsUntilNextMinute = 60 - timeinfo.tm_sec;
|
||||
xTaskCreate(taskScreenRotate, "rotateScreen", 2048, NULL, tskIDLE_PRIORITY,
|
||||
&taskScreenRotateTaskHandle);
|
||||
|
||||
if (secondsUntilNextMinute > 0)
|
||||
vTaskDelay(pdMS_TO_TICKS((secondsUntilNextMinute * 1000)));
|
||||
waitUntilNoneBusy();
|
||||
setCurrentScreen(preferences.getUInt("currentScreen", 0));
|
||||
}
|
||||
|
||||
esp_timer_start_periodic(minuteTimer, usPerMinute);
|
||||
void setupTimeUpdateTimer(void *pvParameters) {
|
||||
const esp_timer_create_args_t minuteTimerConfig = {
|
||||
.callback = &minuteTimerISR, .name = "minute_timer"};
|
||||
|
||||
esp_timer_create(&minuteTimerConfig, &minuteTimer);
|
||||
|
||||
time_t currentTime;
|
||||
struct tm timeinfo;
|
||||
time(¤tTime);
|
||||
localtime_r(¤tTime, &timeinfo);
|
||||
uint32_t secondsUntilNextMinute = 60 - timeinfo.tm_sec;
|
||||
|
||||
if (secondsUntilNextMinute > 0)
|
||||
vTaskDelay(pdMS_TO_TICKS((secondsUntilNextMinute * 1000)));
|
||||
|
||||
esp_timer_start_periodic(minuteTimer, usPerMinute);
|
||||
|
||||
WorkItem timeUpdate = {TASK_TIME_UPDATE, 0};
|
||||
xQueueSend(workQueue, &timeUpdate, portMAX_DELAY);
|
||||
// xTaskNotifyGive(timeUpdateTaskHandle);
|
||||
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
void setupScreenRotateTimer(void *pvParameters) {
|
||||
const esp_timer_create_args_t screenRotateTimerConfig = {
|
||||
.callback = &screenRotateTimerISR, .name = "screen_rotate_timer"};
|
||||
|
||||
esp_timer_create(&screenRotateTimerConfig, &screenRotateTimer);
|
||||
|
||||
if (preferences.getBool("timerActive", true)) {
|
||||
esp_timer_start_periodic(screenRotateTimer,
|
||||
getTimerSeconds() * usPerSecond);
|
||||
}
|
||||
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
uint getTimerSeconds() { return preferences.getUInt("timerSeconds", 1800); }
|
||||
|
||||
bool isTimerActive() { return esp_timer_is_active(screenRotateTimer); }
|
||||
|
||||
void setTimerActive(bool status) {
|
||||
if (status) {
|
||||
esp_timer_start_periodic(screenRotateTimer,
|
||||
getTimerSeconds() * usPerSecond);
|
||||
queueLedEffect(LED_EFFECT_START_TIMER);
|
||||
preferences.putBool("timerActive", true);
|
||||
} else {
|
||||
esp_timer_stop(screenRotateTimer);
|
||||
queueLedEffect(LED_EFFECT_PAUSE_TIMER);
|
||||
preferences.putBool("timerActive", false);
|
||||
}
|
||||
|
||||
if (eventSourceTaskHandle != NULL)
|
||||
xTaskNotifyGive(eventSourceTaskHandle);
|
||||
}
|
||||
|
||||
void toggleTimerActive() { setTimerActive(!isTimerActive()); }
|
||||
|
||||
uint getCurrentScreen() { return currentScreen; }
|
||||
|
||||
void setCurrentScreen(uint newScreen) {
|
||||
if (newScreen != SCREEN_CUSTOM) {
|
||||
preferences.putUInt("currentScreen", newScreen);
|
||||
}
|
||||
|
||||
currentScreen = newScreen;
|
||||
|
||||
switch (currentScreen) {
|
||||
case SCREEN_TIME: {
|
||||
WorkItem timeUpdate = {TASK_TIME_UPDATE, 0};
|
||||
xQueueSend(workQueue, &timeUpdate, portMAX_DELAY);
|
||||
// xTaskNotifyGive(timeUpdateTaskHandle);
|
||||
// xTaskNotifyGive(timeUpdateTaskHandle);
|
||||
break;
|
||||
}
|
||||
case SCREEN_HALVING_COUNTDOWN:
|
||||
case SCREEN_BLOCK_HEIGHT: {
|
||||
WorkItem blockUpdate = {TASK_BLOCK_UPDATE, 0};
|
||||
xQueueSend(workQueue, &blockUpdate, portMAX_DELAY);
|
||||
// xTaskNotifyGive(blockUpdateTaskHandle);
|
||||
break;
|
||||
}
|
||||
case SCREEN_MARKET_CAP:
|
||||
case SCREEN_MSCW_TIME:
|
||||
case SCREEN_BTC_TICKER: {
|
||||
WorkItem priceUpdate = {TASK_PRICE_UPDATE, 0};
|
||||
xQueueSend(workQueue, &priceUpdate, portMAX_DELAY);
|
||||
// xTaskNotifyGive(priceUpdateTaskHandle);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
vTaskDelete(NULL);
|
||||
if (eventSourceTaskHandle != NULL)
|
||||
xTaskNotifyGive(eventSourceTaskHandle);
|
||||
}
|
||||
|
||||
void setupScreenRotateTimer(void *pvParameters)
|
||||
{
|
||||
const esp_timer_create_args_t screenRotateTimerConfig = {
|
||||
.callback = &screenRotateTimerISR,
|
||||
.name = "screen_rotate_timer"};
|
||||
void nextScreen() {
|
||||
int newCurrentScreen = (getCurrentScreen() + 1) % SCREEN_COUNT;
|
||||
String key = "screen" + String(newCurrentScreen) + "Visible";
|
||||
|
||||
esp_timer_create(&screenRotateTimerConfig, &screenRotateTimer);
|
||||
|
||||
if (preferences.getBool("timerActive", true))
|
||||
{
|
||||
esp_timer_start_periodic(screenRotateTimer, getTimerSeconds() * usPerSecond);
|
||||
}
|
||||
|
||||
vTaskDelete(NULL);
|
||||
while (!preferences.getBool(key.c_str(), true)) {
|
||||
newCurrentScreen = (newCurrentScreen + 1) % SCREEN_COUNT;
|
||||
key = "screen" + String(newCurrentScreen) + "Visible";
|
||||
}
|
||||
setCurrentScreen(newCurrentScreen);
|
||||
}
|
||||
|
||||
uint getTimerSeconds()
|
||||
{
|
||||
return preferences.getUInt("timerSeconds", 1800);
|
||||
void previousScreen() {
|
||||
|
||||
int newCurrentScreen = modulo(getCurrentScreen() - 1, SCREEN_COUNT);
|
||||
String key = "screen" + String(newCurrentScreen) + "Visible";
|
||||
|
||||
while (!preferences.getBool(key.c_str(), true)) {
|
||||
newCurrentScreen = modulo(newCurrentScreen - 1, SCREEN_COUNT);
|
||||
key = "screen" + String(newCurrentScreen) + "Visible";
|
||||
}
|
||||
setCurrentScreen(newCurrentScreen);
|
||||
}
|
||||
|
||||
bool isTimerActive()
|
||||
{
|
||||
return esp_timer_is_active(screenRotateTimer);
|
||||
}
|
||||
void showSystemStatusScreen() {
|
||||
std::array<String, NUM_SCREENS> sysStatusEpdContent = {"", "", "", "",
|
||||
"", "", ""};
|
||||
|
||||
void setTimerActive(bool status)
|
||||
{
|
||||
if (status)
|
||||
{
|
||||
esp_timer_start_periodic(screenRotateTimer, getTimerSeconds() * usPerSecond);
|
||||
queueLedEffect(LED_EFFECT_START_TIMER);
|
||||
preferences.putBool("timerActive", true);
|
||||
}
|
||||
else
|
||||
{
|
||||
esp_timer_stop(screenRotateTimer);
|
||||
queueLedEffect(LED_EFFECT_PAUSE_TIMER);
|
||||
preferences.putBool("timerActive", false);
|
||||
}
|
||||
String ipAddr = WiFi.localIP().toString();
|
||||
String subNet = WiFi.subnetMask().toString();
|
||||
|
||||
if (eventSourceTaskHandle != NULL)
|
||||
xTaskNotifyGive(eventSourceTaskHandle);
|
||||
}
|
||||
sysStatusEpdContent[0] = "IP/Subnet";
|
||||
|
||||
void toggleTimerActive()
|
||||
{
|
||||
setTimerActive(!isTimerActive());
|
||||
}
|
||||
int ipAddrPos = 0;
|
||||
int subnetPos = 0;
|
||||
for (int i = 0; i < 4; i++) {
|
||||
sysStatusEpdContent[1 + i] = ipAddr.substring(0, ipAddr.indexOf('.')) +
|
||||
"/" + subNet.substring(0, subNet.indexOf('.'));
|
||||
ipAddrPos = ipAddr.indexOf('.') + 1;
|
||||
subnetPos = subNet.indexOf('.') + 1;
|
||||
ipAddr = ipAddr.substring(ipAddrPos);
|
||||
subNet = subNet.substring(subnetPos);
|
||||
}
|
||||
sysStatusEpdContent[NUM_SCREENS - 2] = "RAM/Status";
|
||||
|
||||
uint getCurrentScreen()
|
||||
{
|
||||
return currentScreen;
|
||||
}
|
||||
|
||||
void setCurrentScreen(uint newScreen)
|
||||
{
|
||||
if (newScreen != SCREEN_CUSTOM)
|
||||
{
|
||||
preferences.putUInt("currentScreen", newScreen);
|
||||
}
|
||||
|
||||
currentScreen = newScreen;
|
||||
|
||||
switch (currentScreen)
|
||||
{
|
||||
case SCREEN_TIME:
|
||||
{
|
||||
WorkItem timeUpdate = {TASK_TIME_UPDATE, 0};
|
||||
xQueueSend(workQueue, &timeUpdate, portMAX_DELAY);
|
||||
// xTaskNotifyGive(timeUpdateTaskHandle);
|
||||
break;
|
||||
}
|
||||
case SCREEN_HALVING_COUNTDOWN:
|
||||
case SCREEN_BLOCK_HEIGHT:
|
||||
{
|
||||
WorkItem blockUpdate = {TASK_BLOCK_UPDATE, 0};
|
||||
xQueueSend(workQueue, &blockUpdate, portMAX_DELAY);
|
||||
// xTaskNotifyGive(blockUpdateTaskHandle);
|
||||
break;
|
||||
}
|
||||
case SCREEN_MARKET_CAP:
|
||||
case SCREEN_MSCW_TIME:
|
||||
case SCREEN_BTC_TICKER:
|
||||
{
|
||||
WorkItem priceUpdate = {TASK_PRICE_UPDATE, 0};
|
||||
xQueueSend(workQueue, &priceUpdate, portMAX_DELAY);
|
||||
// xTaskNotifyGive(priceUpdateTaskHandle);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (eventSourceTaskHandle != NULL)
|
||||
xTaskNotifyGive(eventSourceTaskHandle);
|
||||
}
|
||||
|
||||
void nextScreen()
|
||||
{
|
||||
int newCurrentScreen = (getCurrentScreen() + 1) % SCREEN_COUNT;
|
||||
String key = "screen" + String(newCurrentScreen) + "Visible";
|
||||
|
||||
while (!preferences.getBool(key.c_str(), true))
|
||||
{
|
||||
newCurrentScreen = (newCurrentScreen + 1) % SCREEN_COUNT;
|
||||
key = "screen" + String(newCurrentScreen) + "Visible";
|
||||
}
|
||||
setCurrentScreen(newCurrentScreen);
|
||||
}
|
||||
|
||||
void previousScreen()
|
||||
{
|
||||
|
||||
int newCurrentScreen = modulo(getCurrentScreen() - 1, SCREEN_COUNT);
|
||||
String key = "screen" + String(newCurrentScreen) + "Visible";
|
||||
|
||||
while (!preferences.getBool(key.c_str(), true))
|
||||
{
|
||||
newCurrentScreen = modulo(newCurrentScreen - 1, SCREEN_COUNT);
|
||||
key = "screen" + String(newCurrentScreen) + "Visible";
|
||||
}
|
||||
setCurrentScreen(newCurrentScreen);
|
||||
}
|
||||
|
||||
void showSystemStatusScreen()
|
||||
{
|
||||
std::array<String, NUM_SCREENS> sysStatusEpdContent = {"", "", "", "", "", "", ""};
|
||||
|
||||
String ipAddr = WiFi.localIP().toString();
|
||||
String subNet = WiFi.subnetMask().toString();
|
||||
|
||||
sysStatusEpdContent[0] = "IP/Subnet";
|
||||
|
||||
int ipAddrPos = 0;
|
||||
int subnetPos = 0;
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
sysStatusEpdContent[1 + i] = ipAddr.substring(0, ipAddr.indexOf('.')) + "/" + subNet.substring(0, subNet.indexOf('.'));
|
||||
ipAddrPos = ipAddr.indexOf('.') + 1;
|
||||
subnetPos = subNet.indexOf('.') + 1;
|
||||
ipAddr = ipAddr.substring(ipAddrPos);
|
||||
subNet = subNet.substring(subnetPos);
|
||||
}
|
||||
sysStatusEpdContent[NUM_SCREENS - 2] = "RAM/Status";
|
||||
|
||||
sysStatusEpdContent[NUM_SCREENS - 1] = String((int)round(ESP.getFreeHeap() / 1024)) + "/" + (int)round(ESP.getHeapSize() / 1024);
|
||||
setCurrentScreen(SCREEN_CUSTOM);
|
||||
setEpdContent(sysStatusEpdContent);
|
||||
sysStatusEpdContent[NUM_SCREENS - 1] =
|
||||
String((int)round(ESP.getFreeHeap() / 1024)) + "/" +
|
||||
(int)round(ESP.getHeapSize() / 1024);
|
||||
setCurrentScreen(SCREEN_CUSTOM);
|
||||
setEpdContent(sysStatusEpdContent);
|
||||
}
|
|
@ -2,13 +2,13 @@
|
|||
|
||||
#include <esp_timer.h>
|
||||
|
||||
#include <data_handler.hpp>
|
||||
#include <freertos/FreeRTOS.h>
|
||||
#include <freertos/task.h>
|
||||
#include <data_handler.hpp>
|
||||
|
||||
#include "price_fetch.hpp"
|
||||
#include "shared.hpp"
|
||||
#include "lib/epd.hpp"
|
||||
#include "lib/price_fetch.hpp"
|
||||
#include "lib/shared.hpp"
|
||||
|
||||
// extern TaskHandle_t priceUpdateTaskHandle;
|
||||
// extern TaskHandle_t blockUpdateTaskHandle;
|
||||
|
@ -21,17 +21,15 @@ extern esp_timer_handle_t minuteTimer;
|
|||
|
||||
extern QueueHandle_t workQueue;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
TASK_PRICE_UPDATE,
|
||||
TASK_BLOCK_UPDATE,
|
||||
TASK_TIME_UPDATE
|
||||
typedef enum {
|
||||
TASK_PRICE_UPDATE,
|
||||
TASK_BLOCK_UPDATE,
|
||||
TASK_TIME_UPDATE
|
||||
} TaskType;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
TaskType type;
|
||||
char data;
|
||||
typedef struct {
|
||||
TaskType type;
|
||||
char data;
|
||||
} WorkItem;
|
||||
|
||||
void workerTask(void *pvParameters);
|
||||
|
@ -45,8 +43,8 @@ void showSystemStatusScreen();
|
|||
void setupTimeUpdateTimer(void *pvParameters);
|
||||
void setupScreenRotateTimer(void *pvParameters);
|
||||
|
||||
void IRAM_ATTR minuteTimerISR(void* arg);
|
||||
void IRAM_ATTR screenRotateTimerISR(void* arg);
|
||||
void IRAM_ATTR minuteTimerISR(void *arg);
|
||||
void IRAM_ATTR screenRotateTimerISR(void *arg);
|
||||
|
||||
// void taskPriceUpdate(void *pvParameters);
|
||||
// void taskBlockUpdate(void *pvParameters);
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
#pragma once
|
||||
|
||||
#include <freertos/FreeRTOS.h>
|
||||
#include <freertos/task.h>
|
||||
#include <Adafruit_MCP23X17.h>
|
||||
#include <ArduinoJson.h>
|
||||
#include <Preferences.h>
|
||||
#include <freertos/FreeRTOS.h>
|
||||
#include <freertos/task.h>
|
||||
#include <mutex>
|
||||
|
||||
#include "utils.hpp"
|
||||
#include <utils.hpp>
|
||||
|
||||
extern Adafruit_MCP23X17 mcp1;
|
||||
#ifdef IS_BTCLOCK_S3
|
||||
|
@ -26,23 +26,22 @@ const PROGMEM int SCREEN_MARKET_CAP = 5;
|
|||
const PROGMEM int SCREEN_COUNTDOWN = 98;
|
||||
const PROGMEM int SCREEN_CUSTOM = 99;
|
||||
const int SCREEN_COUNT = 6;
|
||||
const PROGMEM int screens[SCREEN_COUNT] = { SCREEN_BLOCK_HEIGHT, SCREEN_MSCW_TIME, SCREEN_BTC_TICKER, SCREEN_TIME, SCREEN_HALVING_COUNTDOWN, SCREEN_MARKET_CAP };
|
||||
const PROGMEM int screens[SCREEN_COUNT] = {
|
||||
SCREEN_BLOCK_HEIGHT, SCREEN_MSCW_TIME, SCREEN_BTC_TICKER,
|
||||
SCREEN_TIME, SCREEN_HALVING_COUNTDOWN, SCREEN_MARKET_CAP};
|
||||
const int usPerSecond = 1000000;
|
||||
const int usPerMinute = 60 * usPerSecond;
|
||||
|
||||
struct SpiRamAllocator {
|
||||
void* allocate(size_t size) {
|
||||
void *allocate(size_t size) {
|
||||
return heap_caps_malloc(size, MALLOC_CAP_SPIRAM);
|
||||
}
|
||||
|
||||
void deallocate(void* pointer) {
|
||||
heap_caps_free(pointer);
|
||||
}
|
||||
void deallocate(void *pointer) { heap_caps_free(pointer); }
|
||||
|
||||
void* reallocate(void* ptr, size_t new_size) {
|
||||
void *reallocate(void *ptr, size_t new_size) {
|
||||
return heap_caps_realloc(ptr, new_size, MALLOC_CAP_SPIRAM);
|
||||
}
|
||||
};
|
||||
|
||||
using SpiRamJsonDocument = BasicJsonDocument<SpiRamAllocator>;
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,4 +1,5 @@
|
|||
#pragma once
|
||||
|
||||
#include "WebServer.h"
|
||||
#include "ESPAsyncWebServer.h"
|
||||
#include <ArduinoJson.h>
|
||||
|
@ -7,10 +8,19 @@
|
|||
#include "AsyncJson.h"
|
||||
#include <iostream>
|
||||
|
||||
|
||||
// #include "AsyncJson.h"
|
||||
// #include "ESPAsyncWebServer.h"
|
||||
// #include "WebServer.h"
|
||||
// #include <ArduinoJson.h>
|
||||
// #include <ESPmDNS.h>
|
||||
// #include <LittleFS.h>
|
||||
// #include <iostream>
|
||||
|
||||
#include "lib/block_notify.hpp"
|
||||
#include "lib/led_handler.hpp"
|
||||
#include "lib/price_notify.hpp"
|
||||
#include "lib/screen_handler.hpp"
|
||||
#include "lib/led_handler.hpp"
|
||||
|
||||
#include "webserver/OneParamRewrite.hpp"
|
||||
|
||||
|
@ -40,7 +50,6 @@ void onApiLightsOff(AsyncWebServerRequest *request);
|
|||
void onApiLightsSetColor(AsyncWebServerRequest *request);
|
||||
void onApiLightsSetJson(AsyncWebServerRequest *request, JsonVariant &json);
|
||||
|
||||
|
||||
void onApiRestart(AsyncWebServerRequest *request);
|
||||
|
||||
void onIndex(AsyncWebServerRequest *request);
|
||||
|
|
|
@ -1,43 +1,31 @@
|
|||
#include "OneParamRewrite.hpp"
|
||||
|
||||
OneParamRewrite::OneParamRewrite(const char *from, const char *to)
|
||||
: AsyncWebRewrite(from, to)
|
||||
{
|
||||
: AsyncWebRewrite(from, to) {
|
||||
|
||||
_paramIndex = _from.indexOf('{');
|
||||
_paramIndex = _from.indexOf('{');
|
||||
|
||||
if (_paramIndex >= 0 && _from.endsWith("}"))
|
||||
{
|
||||
_urlPrefix = _from.substring(0, _paramIndex);
|
||||
int index = _params.indexOf('{');
|
||||
if (index >= 0)
|
||||
{
|
||||
_params = _params.substring(0, index);
|
||||
}
|
||||
if (_paramIndex >= 0 && _from.endsWith("}")) {
|
||||
_urlPrefix = _from.substring(0, _paramIndex);
|
||||
int index = _params.indexOf('{');
|
||||
if (index >= 0) {
|
||||
_params = _params.substring(0, index);
|
||||
}
|
||||
else
|
||||
{
|
||||
_urlPrefix = _from;
|
||||
}
|
||||
_paramsBackup = _params;
|
||||
} else {
|
||||
_urlPrefix = _from;
|
||||
}
|
||||
_paramsBackup = _params;
|
||||
}
|
||||
|
||||
bool OneParamRewrite::match(AsyncWebServerRequest *request)
|
||||
{
|
||||
if (request->url().startsWith(_urlPrefix))
|
||||
{
|
||||
if (_paramIndex >= 0)
|
||||
{
|
||||
_params = _paramsBackup + request->url().substring(_paramIndex);
|
||||
}
|
||||
else
|
||||
{
|
||||
_params = _paramsBackup;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
bool OneParamRewrite::match(AsyncWebServerRequest *request) {
|
||||
if (request->url().startsWith(_urlPrefix)) {
|
||||
if (_paramIndex >= 0) {
|
||||
_params = _paramsBackup + request->url().substring(_paramIndex);
|
||||
} else {
|
||||
_params = _paramsBackup;
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -2,14 +2,13 @@
|
|||
|
||||
#include "ESPAsyncWebServer.h"
|
||||
|
||||
class OneParamRewrite : public AsyncWebRewrite
|
||||
{
|
||||
class OneParamRewrite : public AsyncWebRewrite {
|
||||
protected:
|
||||
String _urlPrefix;
|
||||
int _paramIndex;
|
||||
String _paramsBackup;
|
||||
String _urlPrefix;
|
||||
int _paramIndex;
|
||||
String _paramsBackup;
|
||||
|
||||
public:
|
||||
OneParamRewrite(const char *from, const char *to);
|
||||
bool match(AsyncWebServerRequest *request) override;
|
||||
OneParamRewrite(const char *from, const char *to);
|
||||
bool match(AsyncWebServerRequest *request) override;
|
||||
};
|
82
src/main.cpp
82
src/main.cpp
|
@ -1,50 +1,60 @@
|
|||
/*
|
||||
* Copyright 2023 Djuri Baars
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "Arduino.h"
|
||||
#include <WiFiManager.h>
|
||||
#define WEBSERVER_H
|
||||
#include "ESPAsyncWebServer.h"
|
||||
|
||||
#include "ESPAsyncWebServer.h"
|
||||
#include "lib/config.hpp"
|
||||
|
||||
//char ptrTaskList[400];
|
||||
|
||||
uint wifiLostConnection;
|
||||
|
||||
extern "C" void app_main()
|
||||
{
|
||||
initArduino();
|
||||
extern "C" void app_main() {
|
||||
initArduino();
|
||||
|
||||
Serial.begin(115200);
|
||||
setup();
|
||||
Serial.begin(115200);
|
||||
setup();
|
||||
|
||||
while (true)
|
||||
{
|
||||
// vTaskList(ptrTaskList);
|
||||
// Serial.println(F("**********************************"));
|
||||
// Serial.println(F("Task State Prio Stack Num"));
|
||||
// Serial.println(F("**********************************"));
|
||||
// Serial.print(ptrTaskList);
|
||||
// Serial.println(F("**********************************"));
|
||||
if (eventSourceTaskHandle != NULL)
|
||||
xTaskNotifyGive(eventSourceTaskHandle);
|
||||
while (true) {
|
||||
// vTaskList(ptrTaskList);
|
||||
// Serial.println(F("**********************************"));
|
||||
// Serial.println(F("Task State Prio Stack Num"));
|
||||
// Serial.println(F("**********************************"));
|
||||
// Serial.print(ptrTaskList);
|
||||
// Serial.println(F("**********************************"));
|
||||
if (eventSourceTaskHandle != NULL)
|
||||
xTaskNotifyGive(eventSourceTaskHandle);
|
||||
|
||||
if (!WiFi.isConnected()) {
|
||||
if (!wifiLostConnection) {
|
||||
wifiLostConnection = esp_timer_get_time() / 1000000;
|
||||
Serial.println("Lost WiFi connection, trying to reconnect...");
|
||||
}
|
||||
if (!WiFi.isConnected()) {
|
||||
if (!wifiLostConnection) {
|
||||
wifiLostConnection = esp_timer_get_time() / 1000000;
|
||||
Serial.println("Lost WiFi connection, trying to reconnect...");
|
||||
}
|
||||
|
||||
if (((esp_timer_get_time() / 1000000) - wifiLostConnection) > 600) {
|
||||
Serial.println("Still no connection after 10 minutes, restarting...");
|
||||
delay(2000);
|
||||
ESP.restart();
|
||||
}
|
||||
if (((esp_timer_get_time() / 1000000) - wifiLostConnection) > 600) {
|
||||
Serial.println("Still no connection after 10 minutes, restarting...");
|
||||
delay(2000);
|
||||
ESP.restart();
|
||||
}
|
||||
|
||||
WiFi.begin();
|
||||
} else if (wifiLostConnection) {
|
||||
wifiLostConnection = 0;
|
||||
Serial.println("Connection restored, reset timer.");
|
||||
}
|
||||
|
||||
vTaskDelay(pdMS_TO_TICKS(5000));
|
||||
WiFi.begin();
|
||||
} else if (wifiLostConnection) {
|
||||
wifiLostConnection = 0;
|
||||
Serial.println("Connection restored, reset timer.");
|
||||
}
|
||||
|
||||
vTaskDelay(pdMS_TO_TICKS(5000));
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue