mirror of
https://github.com/OpenEPaperLink/OpenEPaperLink.git
synced 2026-03-27 05:07:07 +01:00
Compare commits
120 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4f7a226312 | ||
|
|
43fd751d1e | ||
|
|
ab8cb3955a | ||
|
|
2694a0936f | ||
|
|
547d27e256 | ||
|
|
12f91fb293 | ||
|
|
5973607ad7 | ||
|
|
c4fb629ed4 | ||
|
|
e14ec92d48 | ||
|
|
b3887b6874 | ||
|
|
424cf2faf6 | ||
|
|
0621dda3cc | ||
|
|
9f55d72f97 | ||
|
|
3621d4b6e1 | ||
|
|
209f0f218a | ||
|
|
9bb857329e | ||
|
|
b0d1e1da2c | ||
|
|
d75a1d137f | ||
|
|
19fc8c6594 | ||
|
|
bcd2a4618d | ||
|
|
a962828c4f | ||
|
|
45530085f9 | ||
|
|
ae4a5d5994 | ||
|
|
bb11458167 | ||
|
|
1f02a8288d | ||
|
|
8065479557 | ||
|
|
ab65479917 | ||
|
|
36596542c4 | ||
|
|
eb66e4b7ec | ||
|
|
8d15bb72fd | ||
|
|
4c43d76e09 | ||
|
|
a1664daba4 | ||
|
|
60f9454bb2 | ||
|
|
db56860d26 | ||
|
|
bb73069097 | ||
|
|
14e4d17b31 | ||
|
|
a941cad902 | ||
|
|
80fc7997b7 | ||
|
|
ae0b44a424 | ||
|
|
372cb39c33 | ||
|
|
66c7ad6140 | ||
|
|
e95a1acae8 | ||
|
|
9410c47875 | ||
|
|
220b4ae3e8 | ||
|
|
c64190709a | ||
|
|
c446452b69 | ||
|
|
a24bccd1af | ||
|
|
246b234b22 | ||
|
|
22c5bda4c5 | ||
|
|
13f8dea68b | ||
|
|
696cb448fe | ||
|
|
a4e19b19ab | ||
|
|
9d579e9515 | ||
|
|
7faeb2eb54 | ||
|
|
5318f1fdc4 | ||
|
|
4bf61c1dd0 | ||
|
|
c4beaa51c8 | ||
|
|
26598fc408 | ||
|
|
06f3a5d524 | ||
|
|
0bed91ecc2 | ||
|
|
1e76d690ec | ||
|
|
9c06cdf2d7 | ||
|
|
7a0ca319e7 | ||
|
|
c095f4c881 | ||
|
|
c586c9f541 | ||
|
|
6c4f8ef35b | ||
|
|
c403c06b09 | ||
|
|
ddd043f44f | ||
|
|
81cc5ccc9a | ||
|
|
be325b0e62 | ||
|
|
3621c84cc4 | ||
|
|
ed82795e5f | ||
|
|
5b9f8b324e | ||
|
|
db80d23b52 | ||
|
|
125922f8e7 | ||
|
|
aa484575b8 | ||
|
|
fa97daef3c | ||
|
|
0c591660bc | ||
|
|
c8fb0ca4de | ||
|
|
87ce823776 | ||
|
|
7fe4a1e6ad | ||
|
|
29b8c9bc21 | ||
|
|
2e44889b19 | ||
|
|
4d08454fff | ||
|
|
f131b5ce84 | ||
|
|
33ba6a7aa7 | ||
|
|
75c6a6c0f9 | ||
|
|
f7e2025487 | ||
|
|
a91dd5c2a2 | ||
|
|
0ba287f734 | ||
|
|
ad52c64b94 | ||
|
|
8c06bb04f3 | ||
|
|
07807afe08 | ||
|
|
eb173e355f | ||
|
|
b792b71608 | ||
|
|
b0715fae97 | ||
|
|
6e326009c3 | ||
|
|
0a43c601fe | ||
|
|
f92448992e | ||
|
|
2d84583797 | ||
|
|
fac67eac7e | ||
|
|
6cee005e92 | ||
|
|
e68e549eaf | ||
|
|
3eb4b94b06 | ||
|
|
9951dc5ce5 | ||
|
|
c53f33f8ec | ||
|
|
abbc636948 | ||
|
|
7e32a1a197 | ||
|
|
95d0cf6804 | ||
|
|
a92e0eb5e6 | ||
|
|
c6c3c4f9f6 | ||
|
|
2e64ed2f16 | ||
|
|
2780b7ce36 | ||
|
|
9af2bd2a92 | ||
|
|
92ff939adc | ||
|
|
83ff8564a7 | ||
|
|
dc33ff5854 | ||
|
|
4176252b51 | ||
|
|
36c3c45510 | ||
|
|
abb9b195d3 |
2
.github/workflows/build-test.yml
vendored
2
.github/workflows/build-test.yml
vendored
@@ -26,7 +26,7 @@ jobs:
|
||||
- name: Build NRF firmware
|
||||
run: |
|
||||
cd ARM_Tag_FW/Newton_M3_nRF52811
|
||||
pio run --environment Newton_M3_29_BWR
|
||||
pio run --environment Newton_M3_Universal
|
||||
|
||||
- name: Build Simple_AP
|
||||
run: |
|
||||
|
||||
60
.github/workflows/release.yml
vendored
60
.github/workflows/release.yml
vendored
@@ -39,18 +39,18 @@ jobs:
|
||||
- name: Install intelhex
|
||||
run: pip install --upgrade intelhex
|
||||
|
||||
- name: Build NRF firmware
|
||||
run: |
|
||||
cd ARM_Tag_FW/Newton_M3_nRF52811
|
||||
pio run --environment Newton_M3_22_BWR
|
||||
pio run --environment Newton_M3_29_BWR
|
||||
pio run --environment Newton_M3_75_BWR
|
||||
cp Newton_M3_22_BWR-ota.bin /home/runner/work/OpenEPaperLink/OpenEPaperLink/binaries/Newton_M3_22_BWR-ota.bin
|
||||
cp Newton_M3_22_BWR-full-flash.bin /home/runner/work/OpenEPaperLink/OpenEPaperLink/binaries/Newton_M3_22_BWR-full-flash.bin
|
||||
cp Newton_M3_29_BWR-ota.bin /home/runner/work/OpenEPaperLink/OpenEPaperLink/binaries/Newton_M3_29_BWR-ota.bin
|
||||
cp Newton_M3_29_BWR-full-flash.bin /home/runner/work/OpenEPaperLink/OpenEPaperLink/binaries/Newton_M3_29_BWR-full-flash.bin
|
||||
cp Newton_M3_75_BWR-ota.bin /home/runner/work/OpenEPaperLink/OpenEPaperLink/binaries/Newton_M3_75_BWR-ota.bin
|
||||
cp Newton_M3_75_BWR-full-flash.bin /home/runner/work/OpenEPaperLink/OpenEPaperLink/binaries/Newton_M3_75_BWR-full-flash.bin
|
||||
# - name: Build NRF firmware
|
||||
# run: |
|
||||
# cd ARM_Tag_FW/Newton_M3_nRF52811
|
||||
# pio run --environment Newton_M3_22_BWR
|
||||
# pio run --environment Newton_M3_29_BWR
|
||||
# pio run --environment Newton_M3_75_BWR
|
||||
# cp Newton_M3_22_BWR-ota.bin /home/runner/work/OpenEPaperLink/OpenEPaperLink/binaries/Newton_M3_22_BWR-ota.bin
|
||||
# cp Newton_M3_22_BWR-full-flash.bin /home/runner/work/OpenEPaperLink/OpenEPaperLink/binaries/Newton_M3_22_BWR-full-flash.bin
|
||||
# cp Newton_M3_29_BWR-ota.bin /home/runner/work/OpenEPaperLink/OpenEPaperLink/binaries/Newton_M3_29_BWR-ota.bin
|
||||
# cp Newton_M3_29_BWR-full-flash.bin /home/runner/work/OpenEPaperLink/OpenEPaperLink/binaries/Newton_M3_29_BWR-full-flash.bin
|
||||
# cp Newton_M3_75_BWR-ota.bin /home/runner/work/OpenEPaperLink/OpenEPaperLink/binaries/Newton_M3_75_BWR-ota.bin
|
||||
# cp Newton_M3_75_BWR-full-flash.bin /home/runner/work/OpenEPaperLink/OpenEPaperLink/binaries/Newton_M3_75_BWR-full-flash.bin
|
||||
|
||||
- name: Install esptool
|
||||
run: pip install esptool
|
||||
@@ -184,7 +184,25 @@ jobs:
|
||||
cd /home/runner/work/OpenEPaperLink/OpenEPaperLink
|
||||
cp ESP32_S3_16_8_YELLOW_AP/firmware.bin espbinaries/ESP32_S3_16_8_YELLOW_AP.bin
|
||||
cp ESP32_S3_16_8_YELLOW_AP/merged-firmware.bin espbinaries/ESP32_S3_16_8_YELLOW_AP_full.bin
|
||||
|
||||
|
||||
- name: Build firmware for OpenEPaperLink_PoE_AP
|
||||
run: |
|
||||
cd ESP32_AP-Flasher
|
||||
export PLATFORMIO_BUILD_FLAGS="-D BUILD_VERSION=${{ github.ref_name }} -D SHA=$GITHUB_SHA"
|
||||
pio run --environment OpenEPaperLink_PoE_AP
|
||||
pio run --target buildfs --environment OpenEPaperLink_PoE_AP
|
||||
mkdir /home/runner/work/OpenEPaperLink/OpenEPaperLink/OpenEPaperLink_PoE_AP
|
||||
cp ~/.platformio/packages/framework-arduinoespressif32/tools/partitions/boot_app0.bin /home/runner/work/OpenEPaperLink/OpenEPaperLink/OpenEPaperLink_PoE_AP/boot_app0.bin
|
||||
cp .pio/build/OpenEPaperLink_PoE_AP/firmware.bin /home/runner/work/OpenEPaperLink/OpenEPaperLink/OpenEPaperLink_PoE_AP/firmware.bin
|
||||
cp .pio/build/OpenEPaperLink_PoE_AP/bootloader.bin /home/runner/work/OpenEPaperLink/OpenEPaperLink/OpenEPaperLink_PoE_AP/bootloader.bin
|
||||
cp .pio/build/OpenEPaperLink_PoE_AP/partitions.bin /home/runner/work/OpenEPaperLink/OpenEPaperLink/OpenEPaperLink_PoE_AP/partitions.bin
|
||||
cp .pio/build/OpenEPaperLink_PoE_AP/littlefs.bin /home/runner/work/OpenEPaperLink/OpenEPaperLink/OpenEPaperLink_PoE_AP/littlefs.bin
|
||||
cd /home/runner/work/OpenEPaperLink/OpenEPaperLink/OpenEPaperLink_PoE_AP
|
||||
esptool.py --chip esp32 merge_bin -o merged-firmware.bin --flash_mode qio --flash_freq 80m --flash_size 16MB 0x0000 bootloader.bin 0x8000 partitions.bin 0xD000 boot_app0.bin 0x10000 firmware.bin 0x410000 littlefs.bin
|
||||
cd /home/runner/work/OpenEPaperLink/OpenEPaperLink
|
||||
cp OpenEPaperLink_PoE_AP/firmware.bin espbinaries/OpenEPaperLink_PoE_AP.bin
|
||||
cp OpenEPaperLink_PoE_AP/merged-firmware.bin espbinaries/OpenEPaperLink_PoE_AP_full.bin
|
||||
|
||||
- name: generate release json file
|
||||
run: |
|
||||
mkdir jsonfiles
|
||||
@@ -199,14 +217,14 @@ jobs:
|
||||
file_glob: true
|
||||
overwrite: true
|
||||
|
||||
- name: Add tag bins to release
|
||||
uses: svenstaro/upload-release-action@v2
|
||||
with:
|
||||
repo_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
file: binaries/*
|
||||
tag: ${{ github.ref }}
|
||||
file_glob: true
|
||||
overwrite: true
|
||||
# - name: Add tag bins to release
|
||||
# uses: svenstaro/upload-release-action@v2
|
||||
# with:
|
||||
# repo_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
# file: binaries/*
|
||||
# tag: ${{ github.ref }}
|
||||
# file_glob: true
|
||||
# overwrite: true
|
||||
|
||||
# this is down here intentionally to be able to modify the binary folder before adding it to the Tag_Flasher later (ota binaries can be removed)
|
||||
|
||||
|
||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -23,3 +23,6 @@
|
||||
*.bin
|
||||
*.lk
|
||||
*.o
|
||||
sdcc/sdcc
|
||||
|
||||
ESP32_AP-Flasher/.vscode/extensions.json
|
||||
|
||||
@@ -268,6 +268,14 @@ static esp_loader_error_t spi_config_esp32xx(uint32_t efuse_base, uint32_t *spi_
|
||||
{
|
||||
*spi_config = 0;
|
||||
|
||||
// *** FIXME
|
||||
// There seems to be a bug here.
|
||||
// For ESP32-C6, esptool reads registers 0x600b0844 and 0x600b0848 (0x11 and 0x12).
|
||||
// This tools reads registers 0x600b0848 and 0x600b084C (0x12 and 0x13).
|
||||
// This function is supposted to read non-default SPI pins.
|
||||
// As mostly they will be connected like default, it's pretty save to just exit.
|
||||
return ESP_LOADER_SUCCESS;
|
||||
// *** end FIXME
|
||||
uint32_t reg1, reg2;
|
||||
RETURN_ON_ERROR( esp_loader_read_register(efuse_word_addr(efuse_base, 18), ®1) );
|
||||
RETURN_ON_ERROR( esp_loader_read_register(efuse_word_addr(efuse_base, 19), ®2) );
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -17,10 +17,10 @@ build_flags =
|
||||
-D SERIAL_FLASHER_RESET_HOLD_TIME_MS=100
|
||||
-D SERIAL_FLASHER_BOOT_HOLD_TIME_MS=50
|
||||
-D SERIAL_FLASHER_INTERFACE_UART
|
||||
;-D SERIAL_FLASHER_DEBUG_TRACE
|
||||
-D SERIAL_FLASHER_DEBUG_TRACE
|
||||
|
||||
upload_port = COM22
|
||||
monitor_port = COM22
|
||||
upload_port = COM11
|
||||
monitor_port = COM11
|
||||
|
||||
[env:ESP32_S3_16_8_YELLOW_AP]
|
||||
board = esp32-s3-devkitc-1
|
||||
@@ -68,4 +68,46 @@ board_build.arduino.memory_type = qio_opi
|
||||
board_build.psram_type=qspi_opi
|
||||
board_upload.maximum_size = 16777216
|
||||
board_upload.maximum_ram_size = 327680
|
||||
board_upload.flash_size = 16MB
|
||||
board_upload.flash_size = 16MB
|
||||
; ----------------------------------------------------------------------------------------
|
||||
; !!! this configuration expects the Nano_C6
|
||||
;
|
||||
; ----------------------------------------------------------------------------------------
|
||||
[env:OpenEPaperLink_Nano_C6_this]
|
||||
platform = https://github.com/platformio/platform-espressif32.git
|
||||
board=lolin_s2_mini
|
||||
board_build.partitions = default.csv
|
||||
build_unflags =
|
||||
-D CONFIG_MBEDTLS_INTERNAL_MEM_ALLOC=y
|
||||
build_flags =
|
||||
${env.build_flags}
|
||||
-D OPENEPAPERLINK_NANO_AP_PCB
|
||||
-D ARDUINO_USB_MODE=0
|
||||
-D CONFIG_SPIRAM_USE_MALLOC=1
|
||||
-D CONFIG_MBEDTLS_EXTERNAL_MEM_ALLOC=y
|
||||
-D POWER_NO_SOFT_POWER
|
||||
-D BOARD_HAS_PSRAM
|
||||
-D FLASHER_AP_SS=-1
|
||||
-D FLASHER_AP_CLK=-1
|
||||
-D FLASHER_AP_MOSI=-1
|
||||
-D FLASHER_AP_MISO=-1
|
||||
-D FLASHER_AP_RESET=39
|
||||
-D FLASHER_AP_POWER={-1}
|
||||
-D FLASHER_AP_TEST=-1
|
||||
-D FLASHER_AP_TXD=35
|
||||
-D FLASHER_AP_RXD=33
|
||||
;-D FLASHER_DEBUG_TXD=19
|
||||
;-D FLASHER_DEBUG_RXD=20
|
||||
;-D FLASHER_DEBUG_PROG=21
|
||||
-D FLASHER_LED=15
|
||||
-D FLASHER_RGB_LED=-1
|
||||
-D MD5_ENABLED=1
|
||||
-D SERIAL_FLASHER_INTERFACE_UART=1
|
||||
-D SERIAL_FLASHER_BOOT_HOLD_TIME_MS=50
|
||||
-D SERIAL_FLASHER_RESET_HOLD_TIME_MS=100
|
||||
build_src_filter =
|
||||
+<*>-<usbflasher.cpp>-<swd.cpp>-<espflasher.cpp>
|
||||
board_build.psram_type=qspi_opi
|
||||
board_upload.maximum_size = 4194304
|
||||
board_upload.maximum_ram_size = 327680
|
||||
board_upload.flash_size = 4MB
|
||||
File diff suppressed because it is too large
Load Diff
@@ -51,14 +51,14 @@ esp_loader_error_t flash_binary1(const uint8_t *bin, size_t size, size_t address
|
||||
static uint8_t payload[1024];
|
||||
const uint8_t *bin_addr = bin;
|
||||
|
||||
printf("Erasing flash (this may take a while)...\n");
|
||||
Serial.printf("Erasing flash (this may take a while)...\n");
|
||||
err = esp_loader_flash_start(address, size, sizeof(payload));
|
||||
if (err != ESP_LOADER_SUCCESS)
|
||||
{
|
||||
printf("Erasing flash failed with error %d.\n", err);
|
||||
Serial.printf("Erasing flash failed with error %d.\n", err);
|
||||
return err;
|
||||
}
|
||||
printf("Start programming\n");
|
||||
Serial.printf("Start programming\n");
|
||||
|
||||
size_t binary_size = size;
|
||||
size_t written = 0;
|
||||
@@ -68,10 +68,12 @@ esp_loader_error_t flash_binary1(const uint8_t *bin, size_t size, size_t address
|
||||
size_t to_read = MIN(size, sizeof(payload));
|
||||
memcpy(payload, bin_addr, to_read);
|
||||
|
||||
Serial.printf("Writing to_read: %i, %02X %02X %02X %02X %02X %02X \r\n",to_read, payload[0], payload[1], payload[2], payload[3], payload[4], payload[5]);
|
||||
|
||||
err = esp_loader_flash_write(payload, to_read);
|
||||
if (err != ESP_LOADER_SUCCESS)
|
||||
{
|
||||
printf("\nPacket could not be written! Error %d.\n", err);
|
||||
Serial.printf("\nPacket could not be written! Error %d.\n", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -80,25 +82,25 @@ esp_loader_error_t flash_binary1(const uint8_t *bin, size_t size, size_t address
|
||||
written += to_read;
|
||||
|
||||
int progress = (int)(((float)written / binary_size) * 100);
|
||||
printf("\rProgress: %d %%", progress);
|
||||
Serial.printf("\rProgress: %d %%", progress);
|
||||
fflush(stdout);
|
||||
};
|
||||
|
||||
printf("\nFinished programming\n");
|
||||
Serial.printf("\nFinished programming\n");
|
||||
|
||||
#if MD5_ENABLED
|
||||
err = esp_loader_flash_verify();
|
||||
if (err == ESP_LOADER_ERROR_UNSUPPORTED_FUNC)
|
||||
{
|
||||
printf("ESP8266 does not support flash verify command.");
|
||||
Serial.printf("ESP8266 does not support flash verify command.");
|
||||
return err;
|
||||
}
|
||||
else if (err != ESP_LOADER_SUCCESS)
|
||||
{
|
||||
printf("MD5 does not match. err: %d\n", err);
|
||||
Serial.printf("MD5 does not match. err: %d\n", err);
|
||||
return err;
|
||||
}
|
||||
printf("Flash verified\n");
|
||||
Serial.printf("Flash verified\n");
|
||||
#endif
|
||||
|
||||
return ESP_LOADER_SUCCESS;
|
||||
@@ -106,26 +108,31 @@ esp_loader_error_t flash_binary1(const uint8_t *bin, size_t size, size_t address
|
||||
|
||||
void setup()
|
||||
{
|
||||
pinMode(17, INPUT_PULLUP);
|
||||
pinMode(18, INPUT_PULLUP);
|
||||
pinMode(15,OUTPUT);
|
||||
pinMode(39,OUTPUT);
|
||||
pinMode(37,OUTPUT);
|
||||
digitalWrite(39, LOW);
|
||||
digitalWrite(37, LOW);
|
||||
delay(100);
|
||||
digitalWrite(39, HIGH);
|
||||
Serial.begin(115200);
|
||||
delay(1000);
|
||||
delay(10000);
|
||||
Serial.println("ESP_Flasher_hi");
|
||||
|
||||
const loader_esp32_config_t config = {
|
||||
.baud_rate = 115200,
|
||||
.uart_port = 2,
|
||||
.uart_rx_pin = GPIO_NUM_19,
|
||||
.uart_tx_pin = GPIO_NUM_20,
|
||||
.reset_trigger_pin = GPIO_NUM_47,
|
||||
.gpio0_trigger_pin = GPIO_NUM_21,
|
||||
.uart_port = 1,
|
||||
.uart_rx_pin = GPIO_NUM_18,
|
||||
.uart_tx_pin = GPIO_NUM_16,
|
||||
.reset_trigger_pin = GPIO_NUM_39,
|
||||
.gpio0_trigger_pin = GPIO_NUM_37,
|
||||
};
|
||||
|
||||
Serial.printf("serial initialization: %i \r\n", loader_port_esp32_init(&config));
|
||||
|
||||
if (connect_to_target1(230400) == ESP_LOADER_SUCCESS)
|
||||
{
|
||||
Serial.printf("We got the following ESP: %i\r\n", esp_loader_get_target());
|
||||
Serial.printf("We got the following ESP: %i\r\n", esp_loader_get_target());
|
||||
Serial.println("Loading bootloader...");
|
||||
flash_binary1(data_bootloader, sizeof(data_bootloader), 0x0);
|
||||
Serial.println("Loading partition table...");
|
||||
@@ -134,10 +141,20 @@ void setup()
|
||||
flash_binary1(data_application, sizeof(data_application), 0x10000);
|
||||
Serial.println("Done!");
|
||||
}
|
||||
loader_port_esp32_deinit();
|
||||
//Serial1.begin(115200, SERIAL_8N1, 16, 18);
|
||||
pinMode(39,OUTPUT);
|
||||
pinMode(37,OUTPUT);
|
||||
digitalWrite(39, LOW);
|
||||
digitalWrite(37, HIGH);
|
||||
delay(100);
|
||||
digitalWrite(39, HIGH);
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
Serial.printf("MS: %u\r\n", millis());
|
||||
delay(1000);
|
||||
digitalWrite(15, LOW);
|
||||
delay(100);
|
||||
digitalWrite(15, HIGH);
|
||||
delay(100);
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
BIN
ARM_Tag_FW/Newton_M3_nRF52811/Newton_M3_Universal-full-flash.bin
Normal file
BIN
ARM_Tag_FW/Newton_M3_nRF52811/Newton_M3_Universal-full-flash.bin
Normal file
Binary file not shown.
7558
ARM_Tag_FW/Newton_M3_nRF52811/Newton_M3_Universal-full-flash.hex
Normal file
7558
ARM_Tag_FW/Newton_M3_nRF52811/Newton_M3_Universal-full-flash.hex
Normal file
File diff suppressed because it is too large
Load Diff
BIN
ARM_Tag_FW/Newton_M3_nRF52811/Newton_M3_Universal-ota.bin
Normal file
BIN
ARM_Tag_FW/Newton_M3_nRF52811/Newton_M3_Universal-ota.bin
Normal file
Binary file not shown.
@@ -20,7 +20,7 @@
|
||||
#ifndef Binary_h
|
||||
#define Binary_h
|
||||
|
||||
#define B0 0
|
||||
//#define B0 0
|
||||
#define B00 0
|
||||
#define B000 0
|
||||
#define B0000 0
|
||||
@@ -28,7 +28,7 @@
|
||||
#define B000000 0
|
||||
#define B0000000 0
|
||||
#define B00000000 0
|
||||
#define B1 1
|
||||
//#define B1 1
|
||||
#define B01 1
|
||||
#define B001 1
|
||||
#define B0001 1
|
||||
|
||||
@@ -33,89 +33,89 @@ const SPISettings DEFAULT_SPI_SETTINGS = SPISettings();
|
||||
|
||||
SPIClass::SPIClass(NRF_SPI_Type *p_spi, uint8_t uc_pinMISO, uint8_t uc_pinSCK, uint8_t uc_pinMOSI)
|
||||
{
|
||||
initialized = false;
|
||||
assert(p_spi != NULL);
|
||||
_p_spi = p_spi;
|
||||
initialized = false;
|
||||
assert(p_spi != NULL);
|
||||
_p_spi = p_spi;
|
||||
|
||||
// pins
|
||||
_uc_pinMiso = g_ADigitalPinMap[uc_pinMISO];
|
||||
_uc_pinSCK = g_ADigitalPinMap[uc_pinSCK];
|
||||
_uc_pinMosi = g_ADigitalPinMap[uc_pinMOSI];
|
||||
// pins
|
||||
_uc_pinMiso = g_ADigitalPinMap[uc_pinMISO];
|
||||
_uc_pinSCK = g_ADigitalPinMap[uc_pinSCK];
|
||||
_uc_pinMosi = g_ADigitalPinMap[uc_pinMOSI];
|
||||
|
||||
_dataMode = SPI_MODE0;
|
||||
_bitOrder = SPI_CONFIG_ORDER_MsbFirst;
|
||||
_dataMode = SPI_MODE0;
|
||||
_bitOrder = SPI_CONFIG_ORDER_MsbFirst;
|
||||
}
|
||||
|
||||
#ifdef ARDUINO_GENERIC
|
||||
void SPIClass::setPins(uint8_t uc_pinMISO, uint8_t uc_pinSCK, uint8_t uc_pinMOSI)
|
||||
{
|
||||
_uc_pinMiso = g_ADigitalPinMap[uc_pinMISO];
|
||||
_uc_pinSCK = g_ADigitalPinMap[uc_pinSCK];
|
||||
_uc_pinMosi = g_ADigitalPinMap[uc_pinMOSI];
|
||||
_uc_pinMiso = g_ADigitalPinMap[uc_pinMISO];
|
||||
_uc_pinSCK = g_ADigitalPinMap[uc_pinSCK];
|
||||
_uc_pinMosi = g_ADigitalPinMap[uc_pinMOSI];
|
||||
}
|
||||
#endif // ARDUINO_GENERIC
|
||||
|
||||
void SPIClass::begin()
|
||||
{
|
||||
init();
|
||||
init();
|
||||
|
||||
_p_spi->PSELSCK = _uc_pinSCK;
|
||||
_p_spi->PSELMOSI = _uc_pinMosi;
|
||||
_p_spi->PSELMISO = _uc_pinMiso;
|
||||
_p_spi->PSELSCK = _uc_pinSCK;
|
||||
_p_spi->PSELMOSI = _uc_pinMosi;
|
||||
_p_spi->PSELMISO = _uc_pinMiso;
|
||||
|
||||
config(DEFAULT_SPI_SETTINGS);
|
||||
config(DEFAULT_SPI_SETTINGS);
|
||||
}
|
||||
|
||||
void SPIClass::init()
|
||||
{
|
||||
if (initialized)
|
||||
return;
|
||||
interruptMode = SPI_IMODE_NONE;
|
||||
interruptSave = 0;
|
||||
interruptMask = 0;
|
||||
initialized = true;
|
||||
if (initialized)
|
||||
return;
|
||||
interruptMode = SPI_IMODE_NONE;
|
||||
interruptSave = 0;
|
||||
interruptMask = 0;
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
void SPIClass::config(SPISettings settings)
|
||||
{
|
||||
_p_spi->ENABLE = (SPI_ENABLE_ENABLE_Disabled << SPI_ENABLE_ENABLE_Pos);
|
||||
_p_spi->ENABLE = (SPI_ENABLE_ENABLE_Disabled << SPI_ENABLE_ENABLE_Pos);
|
||||
|
||||
uint32_t config = settings.bitOrder;
|
||||
uint32_t config = settings.bitOrder;
|
||||
|
||||
switch (settings.dataMode) {
|
||||
default:
|
||||
case SPI_MODE0:
|
||||
config |= (SPI_CONFIG_CPOL_ActiveHigh << SPI_CONFIG_CPOL_Pos);
|
||||
config |= (SPI_CONFIG_CPHA_Leading << SPI_CONFIG_CPHA_Pos);
|
||||
break;
|
||||
switch (settings.dataMode) {
|
||||
default:
|
||||
case SPI_MODE0:
|
||||
config |= (SPI_CONFIG_CPOL_ActiveHigh << SPI_CONFIG_CPOL_Pos);
|
||||
config |= (SPI_CONFIG_CPHA_Leading << SPI_CONFIG_CPHA_Pos);
|
||||
break;
|
||||
|
||||
case SPI_MODE1:
|
||||
config |= (SPI_CONFIG_CPOL_ActiveHigh << SPI_CONFIG_CPOL_Pos);
|
||||
config |= (SPI_CONFIG_CPHA_Trailing << SPI_CONFIG_CPHA_Pos);
|
||||
break;
|
||||
case SPI_MODE1:
|
||||
config |= (SPI_CONFIG_CPOL_ActiveHigh << SPI_CONFIG_CPOL_Pos);
|
||||
config |= (SPI_CONFIG_CPHA_Trailing << SPI_CONFIG_CPHA_Pos);
|
||||
break;
|
||||
|
||||
case SPI_MODE2:
|
||||
config |= (SPI_CONFIG_CPOL_ActiveLow << SPI_CONFIG_CPOL_Pos);
|
||||
config |= (SPI_CONFIG_CPHA_Leading << SPI_CONFIG_CPHA_Pos);
|
||||
break;
|
||||
case SPI_MODE2:
|
||||
config |= (SPI_CONFIG_CPOL_ActiveLow << SPI_CONFIG_CPOL_Pos);
|
||||
config |= (SPI_CONFIG_CPHA_Leading << SPI_CONFIG_CPHA_Pos);
|
||||
break;
|
||||
|
||||
case SPI_MODE3:
|
||||
config |= (SPI_CONFIG_CPOL_ActiveLow << SPI_CONFIG_CPOL_Pos);
|
||||
config |= (SPI_CONFIG_CPHA_Trailing << SPI_CONFIG_CPHA_Pos);
|
||||
break;
|
||||
}
|
||||
case SPI_MODE3:
|
||||
config |= (SPI_CONFIG_CPOL_ActiveLow << SPI_CONFIG_CPOL_Pos);
|
||||
config |= (SPI_CONFIG_CPHA_Trailing << SPI_CONFIG_CPHA_Pos);
|
||||
break;
|
||||
}
|
||||
|
||||
_p_spi->CONFIG = config;
|
||||
_p_spi->FREQUENCY = settings.clockFreq;
|
||||
_p_spi->CONFIG = config;
|
||||
_p_spi->FREQUENCY = settings.clockFreq;
|
||||
|
||||
_p_spi->ENABLE = (SPI_ENABLE_ENABLE_Enabled << SPI_ENABLE_ENABLE_Pos);
|
||||
_p_spi->ENABLE = (SPI_ENABLE_ENABLE_Enabled << SPI_ENABLE_ENABLE_Pos);
|
||||
}
|
||||
|
||||
void SPIClass::end()
|
||||
{
|
||||
_p_spi->ENABLE = (SPI_ENABLE_ENABLE_Disabled << SPI_ENABLE_ENABLE_Pos);
|
||||
_p_spi->ENABLE = (SPI_ENABLE_ENABLE_Disabled << SPI_ENABLE_ENABLE_Pos);
|
||||
|
||||
initialized = false;
|
||||
initialized = false;
|
||||
}
|
||||
|
||||
void SPIClass::usingInterrupt(int /*interruptNumber*/)
|
||||
@@ -124,7 +124,7 @@ void SPIClass::usingInterrupt(int /*interruptNumber*/)
|
||||
|
||||
void SPIClass::beginTransaction(SPISettings settings)
|
||||
{
|
||||
config(settings);
|
||||
config(settings);
|
||||
}
|
||||
|
||||
void SPIClass::endTransaction(void)
|
||||
@@ -133,133 +133,133 @@ void SPIClass::endTransaction(void)
|
||||
|
||||
void SPIClass::setBitOrder(BitOrder order)
|
||||
{
|
||||
this->_bitOrder = (order == MSBFIRST ? SPI_CONFIG_ORDER_MsbFirst : SPI_CONFIG_ORDER_LsbFirst);
|
||||
this->_bitOrder = (order == MSBFIRST ? SPI_CONFIG_ORDER_MsbFirst : SPI_CONFIG_ORDER_LsbFirst);
|
||||
|
||||
uint32_t config = this->_bitOrder;
|
||||
uint32_t config = this->_bitOrder;
|
||||
|
||||
switch (this->_dataMode) {
|
||||
default:
|
||||
case SPI_MODE0:
|
||||
config |= (SPI_CONFIG_CPOL_ActiveHigh << SPI_CONFIG_CPOL_Pos);
|
||||
config |= (SPI_CONFIG_CPHA_Leading << SPI_CONFIG_CPHA_Pos);
|
||||
break;
|
||||
switch (this->_dataMode) {
|
||||
default:
|
||||
case SPI_MODE0:
|
||||
config |= (SPI_CONFIG_CPOL_ActiveHigh << SPI_CONFIG_CPOL_Pos);
|
||||
config |= (SPI_CONFIG_CPHA_Leading << SPI_CONFIG_CPHA_Pos);
|
||||
break;
|
||||
|
||||
case SPI_MODE1:
|
||||
config |= (SPI_CONFIG_CPOL_ActiveHigh << SPI_CONFIG_CPOL_Pos);
|
||||
config |= (SPI_CONFIG_CPHA_Trailing << SPI_CONFIG_CPHA_Pos);
|
||||
break;
|
||||
case SPI_MODE1:
|
||||
config |= (SPI_CONFIG_CPOL_ActiveHigh << SPI_CONFIG_CPOL_Pos);
|
||||
config |= (SPI_CONFIG_CPHA_Trailing << SPI_CONFIG_CPHA_Pos);
|
||||
break;
|
||||
|
||||
case SPI_MODE2:
|
||||
config |= (SPI_CONFIG_CPOL_ActiveLow << SPI_CONFIG_CPOL_Pos);
|
||||
config |= (SPI_CONFIG_CPHA_Leading << SPI_CONFIG_CPHA_Pos);
|
||||
break;
|
||||
case SPI_MODE2:
|
||||
config |= (SPI_CONFIG_CPOL_ActiveLow << SPI_CONFIG_CPOL_Pos);
|
||||
config |= (SPI_CONFIG_CPHA_Leading << SPI_CONFIG_CPHA_Pos);
|
||||
break;
|
||||
|
||||
case SPI_MODE3:
|
||||
config |= (SPI_CONFIG_CPOL_ActiveLow << SPI_CONFIG_CPOL_Pos);
|
||||
config |= (SPI_CONFIG_CPHA_Trailing << SPI_CONFIG_CPHA_Pos);
|
||||
break;
|
||||
}
|
||||
case SPI_MODE3:
|
||||
config |= (SPI_CONFIG_CPOL_ActiveLow << SPI_CONFIG_CPOL_Pos);
|
||||
config |= (SPI_CONFIG_CPHA_Trailing << SPI_CONFIG_CPHA_Pos);
|
||||
break;
|
||||
}
|
||||
|
||||
_p_spi->CONFIG = config;
|
||||
_p_spi->CONFIG = config;
|
||||
}
|
||||
|
||||
void SPIClass::setDataMode(uint8_t mode)
|
||||
{
|
||||
this->_dataMode = mode;
|
||||
this->_dataMode = mode;
|
||||
|
||||
uint32_t config = this->_bitOrder;
|
||||
uint32_t config = this->_bitOrder;
|
||||
|
||||
switch (this->_dataMode) {
|
||||
default:
|
||||
case SPI_MODE0:
|
||||
config |= (SPI_CONFIG_CPOL_ActiveHigh << SPI_CONFIG_CPOL_Pos);
|
||||
config |= (SPI_CONFIG_CPHA_Leading << SPI_CONFIG_CPHA_Pos);
|
||||
break;
|
||||
switch (this->_dataMode) {
|
||||
default:
|
||||
case SPI_MODE0:
|
||||
config |= (SPI_CONFIG_CPOL_ActiveHigh << SPI_CONFIG_CPOL_Pos);
|
||||
config |= (SPI_CONFIG_CPHA_Leading << SPI_CONFIG_CPHA_Pos);
|
||||
break;
|
||||
|
||||
case SPI_MODE1:
|
||||
config |= (SPI_CONFIG_CPOL_ActiveHigh << SPI_CONFIG_CPOL_Pos);
|
||||
config |= (SPI_CONFIG_CPHA_Trailing << SPI_CONFIG_CPHA_Pos);
|
||||
break;
|
||||
case SPI_MODE1:
|
||||
config |= (SPI_CONFIG_CPOL_ActiveHigh << SPI_CONFIG_CPOL_Pos);
|
||||
config |= (SPI_CONFIG_CPHA_Trailing << SPI_CONFIG_CPHA_Pos);
|
||||
break;
|
||||
|
||||
case SPI_MODE2:
|
||||
config |= (SPI_CONFIG_CPOL_ActiveLow << SPI_CONFIG_CPOL_Pos);
|
||||
config |= (SPI_CONFIG_CPHA_Leading << SPI_CONFIG_CPHA_Pos);
|
||||
break;
|
||||
case SPI_MODE2:
|
||||
config |= (SPI_CONFIG_CPOL_ActiveLow << SPI_CONFIG_CPOL_Pos);
|
||||
config |= (SPI_CONFIG_CPHA_Leading << SPI_CONFIG_CPHA_Pos);
|
||||
break;
|
||||
|
||||
case SPI_MODE3:
|
||||
config |= (SPI_CONFIG_CPOL_ActiveLow << SPI_CONFIG_CPOL_Pos);
|
||||
config |= (SPI_CONFIG_CPHA_Trailing << SPI_CONFIG_CPHA_Pos);
|
||||
break;
|
||||
}
|
||||
case SPI_MODE3:
|
||||
config |= (SPI_CONFIG_CPOL_ActiveLow << SPI_CONFIG_CPOL_Pos);
|
||||
config |= (SPI_CONFIG_CPHA_Trailing << SPI_CONFIG_CPHA_Pos);
|
||||
break;
|
||||
}
|
||||
|
||||
_p_spi->CONFIG = config;
|
||||
_p_spi->CONFIG = config;
|
||||
}
|
||||
|
||||
void SPIClass::setClockDivider(uint8_t div)
|
||||
{
|
||||
uint32_t clockFreq;
|
||||
uint32_t clockFreq;
|
||||
|
||||
if (div >= SPI_CLOCK_DIV128) {
|
||||
clockFreq = SPI_FREQUENCY_FREQUENCY_K125;
|
||||
} else if (div >= SPI_CLOCK_DIV64) {
|
||||
clockFreq = SPI_FREQUENCY_FREQUENCY_K250;
|
||||
} else if (div >= SPI_CLOCK_DIV32) {
|
||||
clockFreq = SPI_FREQUENCY_FREQUENCY_K500;
|
||||
} else if (div >= SPI_CLOCK_DIV16) {
|
||||
clockFreq = SPI_FREQUENCY_FREQUENCY_M1;
|
||||
} else if (div >= SPI_CLOCK_DIV8) {
|
||||
clockFreq = SPI_FREQUENCY_FREQUENCY_M2;
|
||||
} else if (div >= SPI_CLOCK_DIV4) {
|
||||
clockFreq = SPI_FREQUENCY_FREQUENCY_M4;
|
||||
} else {
|
||||
clockFreq = SPI_FREQUENCY_FREQUENCY_M8;
|
||||
}
|
||||
if (div >= SPI_CLOCK_DIV128) {
|
||||
clockFreq = SPI_FREQUENCY_FREQUENCY_K125;
|
||||
} else if (div >= SPI_CLOCK_DIV64) {
|
||||
clockFreq = SPI_FREQUENCY_FREQUENCY_K250;
|
||||
} else if (div >= SPI_CLOCK_DIV32) {
|
||||
clockFreq = SPI_FREQUENCY_FREQUENCY_K500;
|
||||
} else if (div >= SPI_CLOCK_DIV16) {
|
||||
clockFreq = SPI_FREQUENCY_FREQUENCY_M1;
|
||||
} else if (div >= SPI_CLOCK_DIV8) {
|
||||
clockFreq = SPI_FREQUENCY_FREQUENCY_M2;
|
||||
} else if (div >= SPI_CLOCK_DIV4) {
|
||||
clockFreq = SPI_FREQUENCY_FREQUENCY_M4;
|
||||
} else {
|
||||
clockFreq = SPI_FREQUENCY_FREQUENCY_M8;
|
||||
}
|
||||
|
||||
_p_spi->FREQUENCY = clockFreq;
|
||||
_p_spi->FREQUENCY = clockFreq;
|
||||
}
|
||||
|
||||
byte SPIClass::transfer(uint8_t data)
|
||||
{
|
||||
_p_spi->TXD = data;
|
||||
_p_spi->TXD = data;
|
||||
|
||||
while(!_p_spi->EVENTS_READY);
|
||||
while(!_p_spi->EVENTS_READY);
|
||||
|
||||
data = _p_spi->RXD;
|
||||
data = _p_spi->RXD;
|
||||
|
||||
_p_spi->EVENTS_READY = 0x0UL;
|
||||
_p_spi->EVENTS_READY = 0x0UL;
|
||||
|
||||
return data;
|
||||
return data;
|
||||
}
|
||||
|
||||
uint16_t SPIClass::transfer16(uint16_t data) {
|
||||
union { uint16_t val; struct { uint8_t lsb; uint8_t msb; }; } t;
|
||||
union { uint16_t val; struct { uint8_t lsb; uint8_t msb; }; } t;
|
||||
|
||||
t.val = data;
|
||||
t.val = data;
|
||||
|
||||
if (_bitOrder == SPI_CONFIG_ORDER_LsbFirst) {
|
||||
t.lsb = transfer(t.lsb);
|
||||
t.msb = transfer(t.msb);
|
||||
} else {
|
||||
t.msb = transfer(t.msb);
|
||||
t.lsb = transfer(t.lsb);
|
||||
}
|
||||
if (_bitOrder == SPI_CONFIG_ORDER_LsbFirst) {
|
||||
t.lsb = transfer(t.lsb);
|
||||
t.msb = transfer(t.msb);
|
||||
} else {
|
||||
t.msb = transfer(t.msb);
|
||||
t.lsb = transfer(t.lsb);
|
||||
}
|
||||
|
||||
return t.val;
|
||||
return t.val;
|
||||
}
|
||||
|
||||
void SPIClass::attachInterrupt() {
|
||||
// Should be enableInterrupt()
|
||||
// Should be enableInterrupt()
|
||||
}
|
||||
|
||||
void SPIClass::detachInterrupt() {
|
||||
// Should be disableInterrupt()
|
||||
// Should be disableInterrupt()
|
||||
}
|
||||
|
||||
#if SPI_INTERFACES_COUNT > 0
|
||||
#if defined(NRF52_SERIES) && !defined(NRF52811_XXAA)
|
||||
SPIClass SPI (NRF_SPI2, PIN_SPI_MISO, PIN_SPI_SCK, PIN_SPI_MOSI);
|
||||
#else
|
||||
SPIClass SPI (NRF_SPI0, PIN_SPI_MISO, PIN_SPI_SCK, PIN_SPI_MOSI);
|
||||
// SPIClass SPI (NRF_SPI0, PIN_SPI_MISO, PIN_SPI_SCK, PIN_SPI_MOSI);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,7 +1,18 @@
|
||||
#include <Arduino.h>
|
||||
|
||||
#include "hal.h"
|
||||
#include "wdt.h"
|
||||
#include "HAL_Newton_M3.h"
|
||||
#include "epd_driver/epd_interface.h"
|
||||
|
||||
int8_t temperature = 0;
|
||||
uint16_t batteryVoltage = 0;
|
||||
uint32_t batteryRaw = 0;
|
||||
uint32_t flashposition = 0;
|
||||
bool lowBattery = false;
|
||||
bool disablePinInterruptSleep = false;
|
||||
|
||||
epdInterface* epd = nullptr;
|
||||
tagSpecs tag;
|
||||
|
||||
int8_t startHFCLK(void) {
|
||||
if (!isHFCLKstable()) {
|
||||
@@ -29,9 +40,106 @@ uint8_t isHFCLKstable(void) {
|
||||
}
|
||||
}
|
||||
|
||||
void setupBatteryVoltage() {
|
||||
NRF_SAADC->CH[0]
|
||||
.CONFIG = (SAADC_CH_CONFIG_GAIN_Gain1_6 << SAADC_CH_CONFIG_GAIN_Pos) |
|
||||
(SAADC_CH_CONFIG_MODE_SE << SAADC_CH_CONFIG_MODE_Pos) |
|
||||
(SAADC_CH_CONFIG_REFSEL_Internal << SAADC_CH_CONFIG_REFSEL_Pos) |
|
||||
(SAADC_CH_CONFIG_RESN_Bypass << SAADC_CH_CONFIG_RESN_Pos) |
|
||||
(SAADC_CH_CONFIG_RESP_Bypass << SAADC_CH_CONFIG_RESP_Pos) |
|
||||
(SAADC_CH_CONFIG_TACQ_3us << SAADC_CH_CONFIG_TACQ_Pos);
|
||||
NRF_SAADC->CH[0].PSELP = SAADC_CH_PSELP_PSELP_VDD << SAADC_CH_PSELP_PSELP_Pos;
|
||||
NRF_SAADC->CH[0].PSELN = SAADC_CH_PSELN_PSELN_NC << SAADC_CH_PSELN_PSELN_Pos;
|
||||
NRF_SAADC->RESOLUTION = SAADC_RESOLUTION_VAL_14bit << SAADC_RESOLUTION_VAL_Pos;
|
||||
NRF_SAADC->RESULT.MAXCNT = 1;
|
||||
NRF_SAADC->RESULT.PTR = (uint32_t)&batteryRaw;
|
||||
NRF_SAADC->SAMPLERATE = SAADC_SAMPLERATE_MODE_Task << SAADC_SAMPLERATE_MODE_Pos;
|
||||
NRF_SAADC->ENABLE = SAADC_ENABLE_ENABLE_Enabled << SAADC_ENABLE_ENABLE_Pos;
|
||||
NRF_SAADC->TASKS_CALIBRATEOFFSET = 1;
|
||||
while (NRF_SAADC->EVENTS_CALIBRATEDONE == 0)
|
||||
;
|
||||
NRF_SAADC->EVENTS_CALIBRATEDONE = 0;
|
||||
while (NRF_SAADC->STATUS == (SAADC_STATUS_STATUS_Busy << SAADC_STATUS_STATUS_Pos))
|
||||
;
|
||||
NRF_SAADC->ENABLE = SAADC_ENABLE_ENABLE_Disabled << SAADC_ENABLE_ENABLE_Pos;
|
||||
}
|
||||
|
||||
void getVoltage() {
|
||||
NRF_SAADC->ENABLE = SAADC_ENABLE_ENABLE_Enabled << SAADC_ENABLE_ENABLE_Pos;
|
||||
|
||||
NRF_SAADC->TASKS_START = 1;
|
||||
while (NRF_SAADC->EVENTS_STARTED == 0)
|
||||
;
|
||||
NRF_SAADC->EVENTS_STARTED = 0;
|
||||
|
||||
NRF_SAADC->TASKS_SAMPLE = 1;
|
||||
while (NRF_SAADC->EVENTS_END == 0)
|
||||
;
|
||||
NRF_SAADC->EVENTS_END = 0;
|
||||
|
||||
// Convert the result to voltage
|
||||
// Result = [V(p) - V(n)] * GAIN/REFERENCE * 2^(RESOLUTION)
|
||||
// Result = (VDD - 0) * ((1/6) / 0.6) * 2^14
|
||||
// VDD = Result / 4551.1
|
||||
batteryRaw *= 10000;
|
||||
batteryRaw /= 45511;
|
||||
batteryVoltage = (uint16_t)batteryRaw;
|
||||
|
||||
printf("voltage = %d\n", batteryVoltage);
|
||||
|
||||
// Stop the SAADC, since it's not used anymore.
|
||||
NRF_SAADC->TASKS_STOP = 1;
|
||||
while (NRF_SAADC->EVENTS_STOPPED == 0)
|
||||
;
|
||||
NRF_SAADC->EVENTS_STOPPED = 0;
|
||||
NRF_SAADC->ENABLE = SAADC_ENABLE_ENABLE_Disabled << SAADC_ENABLE_ENABLE_Pos;
|
||||
}
|
||||
|
||||
void setupTemperature() {
|
||||
// Trigger temperature measurement
|
||||
|
||||
NRF_TEMP->A0 = NRF_FICR->TEMP.A0;
|
||||
NRF_TEMP->A1 = NRF_FICR->TEMP.A1;
|
||||
NRF_TEMP->A2 = NRF_FICR->TEMP.A2;
|
||||
NRF_TEMP->A3 = NRF_FICR->TEMP.A3;
|
||||
NRF_TEMP->A4 = NRF_FICR->TEMP.A4;
|
||||
NRF_TEMP->A5 = NRF_FICR->TEMP.A5;
|
||||
|
||||
// top two 'B0' and 'B1' are also in binary.h by the Arduino framework...
|
||||
NRF_TEMP->B0 = NRF_FICR->TEMP.B0;
|
||||
NRF_TEMP->B1 = NRF_FICR->TEMP.B1;
|
||||
NRF_TEMP->B2 = NRF_FICR->TEMP.B2;
|
||||
NRF_TEMP->B3 = NRF_FICR->TEMP.B3;
|
||||
NRF_TEMP->B4 = NRF_FICR->TEMP.B4;
|
||||
NRF_TEMP->B5 = NRF_FICR->TEMP.B5;
|
||||
|
||||
NRF_TEMP->T0 = NRF_FICR->TEMP.T0;
|
||||
NRF_TEMP->T1 = NRF_FICR->TEMP.T1;
|
||||
NRF_TEMP->T2 = NRF_FICR->TEMP.T2;
|
||||
NRF_TEMP->T3 = NRF_FICR->TEMP.T3;
|
||||
NRF_TEMP->T4 = NRF_FICR->TEMP.T4;
|
||||
}
|
||||
|
||||
void getTemperature() {
|
||||
NRF_TEMP->TASKS_START = 1;
|
||||
|
||||
// Wait until measurement is finished
|
||||
while (NRF_TEMP->EVENTS_DATARDY == 0)
|
||||
;
|
||||
NRF_TEMP->EVENTS_DATARDY = 0;
|
||||
|
||||
// Read temperature and convert to celcius (rounding down)
|
||||
int32_t temp = (int32_t)NRF_TEMP->TEMP;
|
||||
temp *= 25;
|
||||
|
||||
temperature = (uint8_t)(temp / 100);
|
||||
|
||||
printf("temp = %lu.%lu\n", temp / 100, temp % 100);
|
||||
}
|
||||
|
||||
void boardGetOwnMac(uint8_t *mac) {
|
||||
mac[0] = MAC_ID_1;
|
||||
mac[1] = MAC_ID_0;
|
||||
mac[0] = tag.macSuffix & 0xFF;
|
||||
mac[1] = tag.macSuffix >> 8;
|
||||
mac[2] = (NRF_UICR->CUSTOMER[0]) & 0xFF;
|
||||
mac[3] = (NRF_UICR->CUSTOMER[0] >> 8) & 0xFF;
|
||||
mac[4] = (NRF_UICR->CUSTOMER[0] >> 16) & 0xFF;
|
||||
@@ -56,74 +164,86 @@ void watchdog_enable(int timeout) {
|
||||
|
||||
uint32_t sleepMsEntry = 0;
|
||||
uint32_t loops = 0;
|
||||
bool interruped = false;
|
||||
bool interrupted = false;
|
||||
|
||||
//uint8_t ledcfg[12] = {0b00100010,0x78,0b00100100,5,0x03,0b01000011,1,0xC2,0b1100001,10,10,0};
|
||||
//uint8_t ledcfg[12] = {0b00010010,0x7D,0,0,0x03,0xE8,0,0,0,0,0,0};
|
||||
uint8_t ledcfg[12] = {255,0,0,0,0,0,0,0,0,0,0,0};
|
||||
// uint8_t ledcfg[12] = {0b00100010,0x78,0b00100100,5,0x03,0b01000011,1,0xC2,0b1100001,10,10,0};
|
||||
// uint8_t ledcfg[12] = {0b00010010,0x7D,0,0,0x03,0xE8,0,0,0,0,0,0};
|
||||
uint8_t ledcfg[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||
|
||||
void setled(uint64_t parta,u_int32_t partb){
|
||||
void setled(uint64_t parta, u_int32_t partb) {
|
||||
flashposition = 0;
|
||||
ledcfg[0] = parta & 0xFF;
|
||||
ledcfg[1] = (parta >> 8)& 0xFF;
|
||||
ledcfg[2] = (parta >> 16)& 0xFF;
|
||||
ledcfg[3] = (parta >> 24)& 0xFF;
|
||||
ledcfg[4] = (parta >> 32)& 0xFF;
|
||||
ledcfg[5] = (parta >> 40)& 0xFF;
|
||||
ledcfg[6] = (parta >> 48)& 0xFF;
|
||||
ledcfg[7] = (parta >> 56)& 0xFF;
|
||||
ledcfg[1] = (parta >> 8) & 0xFF;
|
||||
ledcfg[2] = (parta >> 16) & 0xFF;
|
||||
ledcfg[3] = (parta >> 24) & 0xFF;
|
||||
ledcfg[4] = (parta >> 32) & 0xFF;
|
||||
ledcfg[5] = (parta >> 40) & 0xFF;
|
||||
ledcfg[6] = (parta >> 48) & 0xFF;
|
||||
ledcfg[7] = (parta >> 56) & 0xFF;
|
||||
ledcfg[8] = partb & 0xFF;
|
||||
ledcfg[9] = (partb >> 8)& 0xFF;
|
||||
ledcfg[10] = (partb >> 16)& 0xFF;
|
||||
ledcfg[11] = (partb >> 24)& 0xFF;
|
||||
ledcfg[9] = (partb >> 8) & 0xFF;
|
||||
ledcfg[10] = (partb >> 16) & 0xFF;
|
||||
ledcfg[11] = (partb >> 24) & 0xFF;
|
||||
}
|
||||
|
||||
void resettimer(){
|
||||
//tell the sleep function to net sleep again
|
||||
void resettimer() {
|
||||
// tell the sleep function to net sleep again
|
||||
sleepMsEntry = sleepMsEntry - 999999999;
|
||||
loops = 0;
|
||||
interruped = true;
|
||||
interrupted = true;
|
||||
}
|
||||
|
||||
void flashled(uint8_t color,uint8_t brightnes){
|
||||
void flashled(uint8_t color, uint8_t brightness) {
|
||||
uint8_t colorred = (color >> 5) & 0b00000111;
|
||||
uint8_t colorgreen = (color >> 2) & 0b00000111;
|
||||
uint8_t colorblue = color & 0b00000011;
|
||||
for(uint16_t i = 0;i < brightnes;i++){
|
||||
digitalWrite(LED_RED, !(colorred >= 7));
|
||||
digitalWrite(LED_GREEN, !(colorgreen >= 7));
|
||||
digitalWrite(LED_BLUE, !(colorblue >= 3));
|
||||
nrf_delay_us(100);
|
||||
digitalWrite(LED_RED, !(colorred >= 1));
|
||||
digitalWrite(LED_GREEN, !(colorgreen >= 1));
|
||||
nrf_delay_us(100);
|
||||
digitalWrite(LED_RED, !(colorred >= 6));
|
||||
digitalWrite(LED_GREEN, !(colorgreen >= 6));
|
||||
digitalWrite(LED_BLUE, !(colorblue >= 1));
|
||||
nrf_delay_us(100);
|
||||
digitalWrite(LED_RED, !(colorred >= 2));
|
||||
digitalWrite(LED_GREEN, !(colorgreen >= 2));
|
||||
nrf_delay_us(100);
|
||||
digitalWrite(LED_RED, !(colorred >= 5));
|
||||
digitalWrite(LED_GREEN, !(colorgreen >= 5));
|
||||
nrf_delay_us(100);
|
||||
digitalWrite(LED_RED, !(colorred >= 3));
|
||||
digitalWrite(LED_GREEN, !(colorgreen >= 3));
|
||||
digitalWrite(LED_BLUE, !(colorblue >= 2));
|
||||
nrf_delay_us(100);
|
||||
digitalWrite(LED_RED, !(colorred >= 4));
|
||||
digitalWrite(LED_GREEN, !(colorgreen >= 4));
|
||||
nrf_delay_us(100);
|
||||
digitalWrite(LED_RED, HIGH);
|
||||
digitalWrite(LED_GREEN, HIGH);
|
||||
digitalWrite(LED_BLUE, HIGH);
|
||||
for (uint16_t i = 0; i < brightness; i++) {
|
||||
digitalWrite(LED_RED, !(colorred >= 7));
|
||||
digitalWrite(LED_GREEN, !(colorgreen >= 7));
|
||||
digitalWrite(LED_BLUE, !(colorblue >= 3));
|
||||
nrf_delay_us(100);
|
||||
digitalWrite(LED_RED, !(colorred >= 1));
|
||||
digitalWrite(LED_GREEN, !(colorgreen >= 1));
|
||||
nrf_delay_us(100);
|
||||
digitalWrite(LED_RED, !(colorred >= 6));
|
||||
digitalWrite(LED_GREEN, !(colorgreen >= 6));
|
||||
digitalWrite(LED_BLUE, !(colorblue >= 1));
|
||||
nrf_delay_us(100);
|
||||
digitalWrite(LED_RED, !(colorred >= 2));
|
||||
digitalWrite(LED_GREEN, !(colorgreen >= 2));
|
||||
nrf_delay_us(100);
|
||||
digitalWrite(LED_RED, !(colorred >= 5));
|
||||
digitalWrite(LED_GREEN, !(colorgreen >= 5));
|
||||
nrf_delay_us(100);
|
||||
digitalWrite(LED_RED, !(colorred >= 3));
|
||||
digitalWrite(LED_GREEN, !(colorgreen >= 3));
|
||||
digitalWrite(LED_BLUE, !(colorblue >= 2));
|
||||
nrf_delay_us(100);
|
||||
digitalWrite(LED_RED, !(colorred >= 4));
|
||||
digitalWrite(LED_GREEN, !(colorgreen >= 4));
|
||||
nrf_delay_us(100);
|
||||
digitalWrite(LED_RED, HIGH);
|
||||
digitalWrite(LED_GREEN, HIGH);
|
||||
digitalWrite(LED_BLUE, HIGH);
|
||||
}
|
||||
}
|
||||
|
||||
void sleepwithinterrupts(uint32_t sleepinterval){
|
||||
yield();
|
||||
sleepMsEntry = millis();
|
||||
//sometimes we wake up early
|
||||
while (millis() - sleepMsEntry < sleepinterval){
|
||||
void sleepwithinterrupts(uint32_t sleepinterval) {
|
||||
yield();
|
||||
sleepMsEntry = millis();
|
||||
|
||||
// disable GPIOTE
|
||||
if (disablePinInterruptSleep) {
|
||||
for (uint8_t c = 0; c < 8; c++) {
|
||||
for (uint8_t d = 0; d < 32; d++) {
|
||||
uint32_t e = ((uint32_t)d) << 8;
|
||||
NRF_GPIOTE->CONFIG[c] = e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// sometimes we wake up early
|
||||
while (millis() - sleepMsEntry < sleepinterval) {
|
||||
initRTC0(sleepinterval);
|
||||
__WFE();
|
||||
__SEV();
|
||||
@@ -131,99 +251,92 @@ void sleepwithinterrupts(uint32_t sleepinterval){
|
||||
}
|
||||
}
|
||||
|
||||
void ledflashlogic(uint32_t ms){
|
||||
void ledflashlogic(uint32_t ms) {
|
||||
watchdog_enable(ms + 1000);
|
||||
uint8_t brightnes = ledcfg[0] >> 4 & 0b00001111;
|
||||
uint8_t brightness = (ledcfg[0] >> 4 & 0b00001111) + 1;
|
||||
uint8_t mode = ledcfg[0] & 0b00001111;
|
||||
//lets not blink for short delays
|
||||
if(ms < 2000)mode = 15;
|
||||
//if(mode == 0)sleepwithinterrupts(ms);
|
||||
if(mode == 1){
|
||||
uint8_t color = ledcfg[1];
|
||||
uint32_t ledinerv = (ledcfg[2] << 24 )+ (ledcfg[3] << 16)+ (ledcfg[4] << 8)+ ledcfg[5];
|
||||
uint32_t sleepinterval = ledinerv;
|
||||
loops = ms / ledinerv;
|
||||
if(loops == 0){
|
||||
loops = 1;
|
||||
sleepinterval = ms;
|
||||
}
|
||||
if(sleepinterval > ms)sleepinterval = ms;
|
||||
for(uint32_t i = 0;i < loops;i++){
|
||||
flashled(color,brightnes);
|
||||
sleepwithinterrupts(sleepinterval);
|
||||
}
|
||||
}
|
||||
else if(mode == 0){
|
||||
interruped = false;
|
||||
// lets not blink for short delays
|
||||
if (ms < 2000) mode = 0;
|
||||
if (mode == 1) {
|
||||
interrupted = false;
|
||||
uint8_t interloopdelayfactor = 100;
|
||||
u_int8_t loopdelayfactor = 100;
|
||||
uint8_t c1 = ledcfg[1];
|
||||
uint8_t c2 = ledcfg[3];
|
||||
uint8_t c3 = ledcfg[5];
|
||||
uint8_t c2 = ledcfg[4];
|
||||
uint8_t c3 = ledcfg[7];
|
||||
uint8_t loop1delay = (ledcfg[2] >> 4) & 0b00001111;
|
||||
uint8_t loop2delay = (ledcfg[4] >> 4) & 0b00001111;
|
||||
uint8_t loop3delay = (ledcfg[6] >> 4) & 0b00001111;
|
||||
uint8_t loop2delay = (ledcfg[5] >> 4) & 0b00001111;
|
||||
uint8_t loop3delay = (ledcfg[8] >> 4) & 0b00001111;
|
||||
uint8_t loopcnt1 = ledcfg[2] & 0b00001111;
|
||||
uint8_t loopcnt2 = ledcfg[4] & 0b00001111;
|
||||
uint8_t loopcnt3 = ledcfg[6] & 0b00001111;
|
||||
uint8_t ildelay1 = 0;
|
||||
uint8_t ildelay2 = 0;
|
||||
uint8_t ildelay3 = 0;
|
||||
uint8_t grouprepeats = ledcfg[7];
|
||||
uint32_t fulllooptime1 = loopcnt1 * loop1delay * loopdelayfactor + ildelay1 * interloopdelayfactor;
|
||||
uint32_t fulllooptime2 = loopcnt2 * loop2delay * loopdelayfactor + ildelay2 * interloopdelayfactor;
|
||||
uint32_t fulllooptime3 = loopcnt3 * loop3delay * loopdelayfactor + ildelay3 * interloopdelayfactor;
|
||||
uint8_t loopcnt2 = ledcfg[5] & 0b00001111;
|
||||
uint8_t loopcnt3 = ledcfg[8] & 0b00001111;
|
||||
uint8_t ildelay1 = ledcfg[3];
|
||||
uint8_t ildelay2 = ledcfg[6];
|
||||
uint8_t ildelay3 = ledcfg[9];
|
||||
uint8_t grouprepeats = ledcfg[10] + 1;
|
||||
uint8_t spare = ledcfg[11];
|
||||
uint32_t fulllooptime1 = loopcnt1 * loop1delay * loopdelayfactor + ildelay1 * interloopdelayfactor;
|
||||
uint32_t fulllooptime2 = loopcnt2 * loop2delay * loopdelayfactor + ildelay2 * interloopdelayfactor;
|
||||
uint32_t fulllooptime3 = loopcnt3 * loop3delay * loopdelayfactor + ildelay3 * interloopdelayfactor;
|
||||
uint32_t looptimesum = fulllooptime1 + fulllooptime2 + fulllooptime3;
|
||||
int fittingrepeats = (int) ms / looptimesum;
|
||||
if (looptimesum == 0) looptimesum = 2;
|
||||
int fittingrepeats = (int)ms / looptimesum;
|
||||
|
||||
grouprepeats = fittingrepeats;
|
||||
if(grouprepeats == 0)grouprepeats = 1;
|
||||
for (int j = 0; j < fittingrepeats; j++) {
|
||||
if (flashposition >= grouprepeats && grouprepeats != 255) {
|
||||
brightness = 0;
|
||||
ledcfg[0] = 0x00;
|
||||
flashposition = 0;
|
||||
}
|
||||
if (!interrupted) {
|
||||
for (int i = 0; i < loopcnt1; i++) {
|
||||
flashled(c1, brightness);
|
||||
sleepwithinterrupts(loop1delay * loopdelayfactor);
|
||||
if (interrupted) break;
|
||||
}
|
||||
sleepwithinterrupts(ildelay1 * interloopdelayfactor);
|
||||
}
|
||||
if (!interrupted) {
|
||||
for (int i = 0; i < loopcnt2; i++) {
|
||||
flashled(c2, brightness);
|
||||
sleepwithinterrupts(loop2delay * loopdelayfactor);
|
||||
if (interrupted) break;
|
||||
}
|
||||
sleepwithinterrupts(ildelay2 * interloopdelayfactor);
|
||||
}
|
||||
|
||||
for(int j = 0;j < grouprepeats;j++){
|
||||
|
||||
if(!interruped){
|
||||
for(int i = 0;i < loopcnt1;i++){
|
||||
flashled(c1,brightnes);
|
||||
sleepwithinterrupts(loop1delay * loopdelayfactor);
|
||||
if(interruped)break;
|
||||
if (!interrupted) {
|
||||
for (int i = 0; i < loopcnt3; i++) {
|
||||
flashled(c3, brightness);
|
||||
sleepwithinterrupts(loop3delay * loopdelayfactor);
|
||||
if (interrupted) break;
|
||||
}
|
||||
sleepwithinterrupts(ildelay3 * interloopdelayfactor);
|
||||
}
|
||||
if (interrupted) break;
|
||||
flashposition++;
|
||||
}
|
||||
sleepwithinterrupts(ildelay1 * interloopdelayfactor);
|
||||
}
|
||||
if(!interruped){
|
||||
for(int i = 0;i < loopcnt2;i++){
|
||||
flashled(c2,brightnes);
|
||||
sleepwithinterrupts(loop2delay * loopdelayfactor);
|
||||
if(interruped)break;
|
||||
}
|
||||
sleepwithinterrupts(ildelay2 * interloopdelayfactor);
|
||||
}
|
||||
|
||||
if(!interruped){
|
||||
for(int i = 0;i < loopcnt3;i++){
|
||||
flashled(c3,brightnes);
|
||||
sleepwithinterrupts(loop3delay * loopdelayfactor);
|
||||
if(interruped)break;
|
||||
}
|
||||
sleepwithinterrupts(ildelay3 * interloopdelayfactor);
|
||||
}
|
||||
if(interruped)break;
|
||||
}
|
||||
}
|
||||
else sleepwithinterrupts(ms);
|
||||
if (interrupted) ledcfg[0] = 0x00;
|
||||
} else
|
||||
sleepwithinterrupts(ms);
|
||||
}
|
||||
|
||||
void sleepForMs(uint32_t ms) {
|
||||
// Turn everything off for minimal deep sleep current
|
||||
radioRxEnable(0);
|
||||
|
||||
// disable brownout
|
||||
NRF_POWER->POFCON &= ~((uint32_t)1);
|
||||
|
||||
NRF_CLOCK->TASKS_HFCLKSTOP = 1U;
|
||||
while ((NRF_CLOCK->HFCLKSTAT & 0x10001) == 0x10001);
|
||||
while ((NRF_CLOCK->HFCLKSTAT & 0x10001) == 0x10001)
|
||||
;
|
||||
Serial.end();
|
||||
yield();
|
||||
//led and sleep stuff
|
||||
// led and sleep stuff
|
||||
ledflashlogic(ms);
|
||||
//we have to restart the serial
|
||||
// we have to restart the serial
|
||||
Serial.begin(115200);
|
||||
Serial.println("wu");
|
||||
}
|
||||
|
||||
#define LF_FREQUENCY 32768UL
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
#include "zigbee.h"
|
||||
#include "epd_spi.h"
|
||||
#include "eeprom_spi.h"
|
||||
|
||||
#define RADIO_FIRST_CHANNEL (11) //2.4-GHz channels start at 11
|
||||
#define RADIO_FIRST_CHANNEL (11) // 2.4-GHz channels start at 11
|
||||
|
||||
#define eepromByte spiByte
|
||||
// #define eepromByte spiByte ??
|
||||
#define eepromPrvSelect() \
|
||||
do { \
|
||||
digitalWrite(FLASH_CS, LOW); \
|
||||
@@ -28,6 +29,12 @@
|
||||
#define EPD_CLK 19
|
||||
#define EPD_MOSI 20
|
||||
|
||||
// these are used by the UC8159 controller.
|
||||
// EPD_HLT is External (EPD)EEPROM _CS
|
||||
#define EPD_HLT 23
|
||||
// This is the EEPROM MISO pin (from SPI EEPROM to nRF)
|
||||
#define EPD_VPP 24
|
||||
|
||||
#define NFC_I2C_SDA 8
|
||||
#define NFC_I2C_SCL 9
|
||||
#define NFC_POWER 10
|
||||
@@ -47,10 +54,61 @@
|
||||
#define DBG_RXD 26
|
||||
#define DBG_TEST 27
|
||||
|
||||
#define EEPROM_SETTINGS_AREA_START 0
|
||||
|
||||
void initRTC0(uint32_t ms);
|
||||
int8_t startHFCLK(void);
|
||||
uint8_t isHFCLKstable(void);
|
||||
void boardGetOwnMac(uint8_t *mac);
|
||||
void sleepForMs(uint32_t ms);
|
||||
void setled(uint64_t parta,u_int32_t partb);
|
||||
void resettimer();
|
||||
void setled(uint64_t parta, u_int32_t partb);
|
||||
void resettimer();
|
||||
|
||||
extern uint16_t batteryVoltage;
|
||||
extern bool lowBattery;
|
||||
extern int8_t temperature;
|
||||
//extern bool disablePinInterruptSleep;
|
||||
|
||||
void setupBatteryVoltage();
|
||||
void getVoltage();
|
||||
void setupTemperature();
|
||||
void getTemperature();
|
||||
|
||||
|
||||
class epdInterface {
|
||||
public:
|
||||
virtual void epdSetup() = 0;
|
||||
virtual void epdEnterSleep() = 0;
|
||||
virtual void draw() = 0;
|
||||
virtual void drawNoWait() = 0;
|
||||
virtual void epdWaitRdy() = 0;
|
||||
virtual void selectLUT(uint8_t lut) = 0;
|
||||
uint8_t controllerType = 0;
|
||||
uint16_t Xres;
|
||||
uint16_t Yres;
|
||||
uint16_t effectiveXRes;
|
||||
uint16_t effectiveYRes;
|
||||
uint16_t XOffset = 0;
|
||||
uint16_t YOffset = 0;
|
||||
bool drawDirectionRight = false;
|
||||
bool epdMirrorV = false;
|
||||
bool epdMirrorH = false;
|
||||
// bool mirrorV = false;
|
||||
// bool mirrorH = false;
|
||||
protected:
|
||||
virtual void epdWriteDisplayData() = 0;
|
||||
};
|
||||
|
||||
extern epdInterface* epd;
|
||||
|
||||
struct tagSpecs {
|
||||
uint8_t buttonCount = 0;
|
||||
bool hasNFC = false;
|
||||
bool hasLED = false;
|
||||
uint16_t macSuffix = 0x0000;
|
||||
uint8_t OEPLtype = 0;
|
||||
uint8_t solumType = 0;
|
||||
uint32_t imageSize = 0;
|
||||
};
|
||||
|
||||
extern tagSpecs tag;
|
||||
@@ -1,35 +0,0 @@
|
||||
#ifndef _BOARDHEADER_H_
|
||||
#define _BOARDHEADER_H_
|
||||
|
||||
#include "../../../../tag_types.h"
|
||||
#include "HAL_Newton_M3.h"
|
||||
|
||||
// eeprom map
|
||||
#define EEPROM_SETTINGS_AREA_START (0x01000UL)
|
||||
#define EEPROM_SETTINGS_AREA_LEN (0x03000UL)
|
||||
#define EEPROM_UPDATE_AREA_START (0x04000UL)
|
||||
#define EEPROM_UPDATE_AREA_LEN (0x10000UL)
|
||||
#define EEPROM_IMG_START (0x14000UL)
|
||||
#define EEPROM_IMG_EACH (0x04000UL) // 160*296 / 8 * 2 = 0x2E40
|
||||
|
||||
// Mac fixed part
|
||||
// 7E22CC67B298 (B29)
|
||||
#define MAC_ID_0 0xB1
|
||||
#define MAC_ID_1 0x90
|
||||
|
||||
// AP mode definitions
|
||||
#define HAS_EEPROM 1
|
||||
#define HAS_SCREEN 1
|
||||
#define AP_EMULATE_TAG 1
|
||||
|
||||
// hw types
|
||||
#define HW_TYPE SOLUM_M3_BWR_22
|
||||
|
||||
#include "../include/ssd1619.h"
|
||||
|
||||
#define SCREEN_WIDTH 160
|
||||
#define SCREEN_HEIGHT 296
|
||||
#define SCREEN_XOFFSET 8
|
||||
#define SCREEN_YOFFSET 0
|
||||
|
||||
#endif
|
||||
@@ -1,35 +0,0 @@
|
||||
#ifndef _BOARDHEADER_H_
|
||||
#define _BOARDHEADER_H_
|
||||
|
||||
#include "../../../../tag_types.h"
|
||||
#include "HAL_Newton_M3.h"
|
||||
|
||||
// eeprom map
|
||||
#define EEPROM_SETTINGS_AREA_START (0x01000UL)
|
||||
#define EEPROM_SETTINGS_AREA_LEN (0x03000UL)
|
||||
#define EEPROM_UPDATE_AREA_START (0x04000UL)
|
||||
#define EEPROM_UPDATE_AREA_LEN (0x10000UL)
|
||||
#define EEPROM_IMG_START (0x14000UL)
|
||||
#define EEPROM_IMG_EACH (0x04000UL) // 168*384 / 8 * 2 = 0x3F00
|
||||
|
||||
// Mac fixed part
|
||||
// 7E22CC67B298 (B29)
|
||||
#define MAC_ID_0 0xB2
|
||||
#define MAC_ID_1 0x90
|
||||
|
||||
// AP mode definitions
|
||||
#define HAS_EEPROM 1
|
||||
#define HAS_SCREEN 1
|
||||
#define AP_EMULATE_TAG 1
|
||||
|
||||
// hw types
|
||||
#define HW_TYPE SOLUM_M3_BWR_29
|
||||
|
||||
#include "../include/ssd1619.h"
|
||||
|
||||
#define SCREEN_WIDTH 168
|
||||
#define SCREEN_HEIGHT 384
|
||||
#define SCREEN_XOFFSET 0
|
||||
#define SCREEN_YOFFSET 0
|
||||
|
||||
#endif
|
||||
@@ -1,35 +0,0 @@
|
||||
#ifndef _BOARDHEADER_H_
|
||||
#define _BOARDHEADER_H_
|
||||
|
||||
#include "../../../../tag_types.h"
|
||||
#include "HAL_Newton_M3.h"
|
||||
|
||||
// eeprom map
|
||||
#define EEPROM_SETTINGS_AREA_START (0x01000UL)
|
||||
#define EEPROM_SETTINGS_AREA_LEN (0x03000UL)
|
||||
#define EEPROM_UPDATE_AREA_START (0x04000UL)
|
||||
#define EEPROM_UPDATE_AREA_LEN (0x10000UL)
|
||||
#define EEPROM_IMG_START (0x14000UL)
|
||||
#define EEPROM_IMG_EACH (0x18000UL) // 800 * 480 * 2 / 8 = 0x17700
|
||||
|
||||
// Mac fixed part
|
||||
// 7E22CC67B298 (B29)
|
||||
#define MAC_ID_0 0xB2
|
||||
#define MAC_ID_1 0x90 // FIX FOR THIS TYPE!!
|
||||
|
||||
// AP mode definitions
|
||||
#define HAS_EEPROM 1
|
||||
#define HAS_SCREEN 1
|
||||
#define AP_EMULATE_TAG 1
|
||||
|
||||
// hw type
|
||||
#define HW_TYPE SOLUM_M3_BWR_75
|
||||
|
||||
#include "../include/uc8179.h"
|
||||
|
||||
#define SCREEN_WIDTH 800
|
||||
#define SCREEN_HEIGHT 480
|
||||
#define SCREEN_XOFFSET 0
|
||||
#define SCREEN_YOFFSET 0
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,66 @@
|
||||
#include "eeprom_spi.h"
|
||||
#include <Arduino.h>
|
||||
#include "HAL_Newton_M3.h"
|
||||
#include "wdt.h"
|
||||
|
||||
bool eepromHWSPIStatus = false;
|
||||
bool eepromHWSPIFirst = true;
|
||||
void setupEepromHWSPI(bool enable) {
|
||||
if (eepromHWSPIStatus != enable) {
|
||||
if (enable) {
|
||||
pinMode(FLASH_MISO, INPUT);
|
||||
// is this the first time we're called to activate HW SPI? Do the full setup
|
||||
if (eepromHWSPIFirst) {
|
||||
eepromHWSPIFirst = false;
|
||||
NRF_SPI1->PSELSCK = FLASH_CLK;
|
||||
NRF_SPI1->PSELMOSI = FLASH_MOSI;
|
||||
NRF_SPI1->PSELMISO = FLASH_MISO;
|
||||
NRF_SPI1->ENABLE = (SPI_ENABLE_ENABLE_Enabled << SPI_ENABLE_ENABLE_Pos);
|
||||
NRF_SPI1->CONFIG = (SPI_CONFIG_CPOL_ActiveHigh << SPI_CONFIG_CPOL_Pos) | (SPI_CONFIG_CPHA_Leading << SPI_CONFIG_CPHA_Pos);
|
||||
NRF_SPI1->FREQUENCY = SPI_FREQUENCY_FREQUENCY_M8;
|
||||
NRF_SPI1->EVENTS_READY = 0;
|
||||
} else {
|
||||
NRF_SPI1->ENABLE = (SPI_ENABLE_ENABLE_Enabled << SPI_ENABLE_ENABLE_Pos);
|
||||
}
|
||||
} else {
|
||||
NRF_SPI1->ENABLE = (SPI_ENABLE_ENABLE_Disabled << SPI_ENABLE_ENABLE_Pos);
|
||||
digitalWrite(FLASH_CS, HIGH);
|
||||
digitalWrite(FLASH_MISO, HIGH);
|
||||
pinMode(FLASH_MISO, OUTPUT);
|
||||
}
|
||||
eepromHWSPIStatus = enable;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t eepromSPIByte(uint8_t data) {
|
||||
// setupEepromHWSPI(true);
|
||||
NRF_SPI1->TXD = data;
|
||||
while (!NRF_SPI1->EVENTS_READY) {
|
||||
}
|
||||
data = NRF_SPI1->RXD;
|
||||
|
||||
NRF_SPI1->EVENTS_READY = 0;
|
||||
return data;
|
||||
}
|
||||
|
||||
void eepromSPIBlockRead(uint8_t* dst, uint16_t len) {
|
||||
while (len--) {
|
||||
NRF_SPI1->TXD = 0x00;
|
||||
while (!NRF_SPI1->EVENTS_READY) {
|
||||
}
|
||||
*dst++ = NRF_SPI1->RXD;
|
||||
NRF_SPI1->EVENTS_READY = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void eepromSPIBlockWrite(uint8_t* src, uint16_t len) {
|
||||
uint8_t dummy = 0;
|
||||
while (len--) {
|
||||
NRF_SPI1->TXD = *src++;
|
||||
while (!NRF_SPI1->EVENTS_READY) {
|
||||
}
|
||||
dummy = NRF_SPI1->RXD; // we have to read some data, otherwise SPI will clog up.
|
||||
NRF_SPI1->EVENTS_READY = 0;
|
||||
}
|
||||
(void)dummy; // shut up that unused warning
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
|
||||
uint8_t eepromSPIByte(uint8_t data);
|
||||
void eepromSPIBlockRead(uint8_t* dst, uint16_t len);
|
||||
void eepromSPIBlockWrite(uint8_t* src, uint16_t len);
|
||||
void setupEepromHWSPI(bool);
|
||||
@@ -4,6 +4,69 @@
|
||||
|
||||
#include "HAL_Newton_M3.h"
|
||||
#include "wdt.h"
|
||||
#include "stdarg.h"
|
||||
|
||||
|
||||
bool epdGPIOActive = false;
|
||||
|
||||
void epdReset() {
|
||||
digitalWrite(EPD_RST, HIGH);
|
||||
delay(12);
|
||||
digitalWrite(EPD_RST, LOW);
|
||||
delay(20);
|
||||
digitalWrite(EPD_RST, HIGH);
|
||||
delay(20);
|
||||
}
|
||||
|
||||
void epdConfigGPIO(bool setup) {
|
||||
if (epdGPIOActive == setup)
|
||||
return;
|
||||
if (setup) {
|
||||
pinMode(EPD_POWER, OUTPUT);
|
||||
digitalWrite(EPD_POWER, HIGH);
|
||||
pinMode(EPD_RST, OUTPUT);
|
||||
pinMode(EPD_BS, OUTPUT);
|
||||
pinMode(EPD_CS, OUTPUT);
|
||||
pinMode(EPD_DC, OUTPUT);
|
||||
pinMode(EPD_BUSY, INPUT);
|
||||
pinMode(EPD_CLK, OUTPUT);
|
||||
pinMode(EPD_MOSI, OUTPUT);
|
||||
|
||||
pinMode(EPD_HLT, OUTPUT);
|
||||
pinMode(EPD_VPP, INPUT);
|
||||
|
||||
digitalWrite(EPD_BS, LOW); // low works!
|
||||
digitalWrite(EPD_CS, HIGH);
|
||||
digitalWrite(EPD_HLT, HIGH);
|
||||
|
||||
epdHardSPI(true);
|
||||
|
||||
} else {
|
||||
epdHardSPI(false);
|
||||
|
||||
digitalWrite(EPD_POWER, LOW);
|
||||
pinMode(EPD_RST, OUTPUT);
|
||||
pinMode(EPD_BS, OUTPUT);
|
||||
pinMode(EPD_CS, OUTPUT);
|
||||
pinMode(EPD_DC, OUTPUT);
|
||||
pinMode(EPD_BUSY, OUTPUT);
|
||||
pinMode(EPD_CLK, OUTPUT);
|
||||
pinMode(EPD_MOSI, OUTPUT);
|
||||
pinMode(EPD_HLT, OUTPUT);
|
||||
pinMode(EPD_VPP, OUTPUT);
|
||||
|
||||
digitalWrite(EPD_RST, LOW);
|
||||
digitalWrite(EPD_BS, LOW);
|
||||
digitalWrite(EPD_CS, LOW);
|
||||
digitalWrite(EPD_DC, LOW);
|
||||
digitalWrite(EPD_BUSY, LOW);
|
||||
digitalWrite(EPD_CLK, LOW);
|
||||
digitalWrite(EPD_MOSI, LOW);
|
||||
digitalWrite(EPD_HLT, LOW);
|
||||
digitalWrite(EPD_VPP, LOW);
|
||||
}
|
||||
epdGPIOActive = setup;
|
||||
}
|
||||
|
||||
void epd_busy() {
|
||||
}
|
||||
@@ -39,14 +102,15 @@ void epdBusyWaitRising(uint32_t timeout) {
|
||||
attachInterrupt(digitalPinToInterrupt(EPD_BUSY), epd_busy, RISING);
|
||||
NRF_GPIO->PIN_CNF[EPD_BUSY] &= ~((uint32_t)GPIO_PIN_CNF_SENSE_Msk);
|
||||
NRF_GPIO->PIN_CNF[EPD_BUSY] |= ((uint32_t)GPIO_PIN_CNF_SENSE_High << GPIO_PIN_CNF_SENSE_Pos);
|
||||
|
||||
while (millis() - start < timeout) {
|
||||
initRTC0(100);
|
||||
__WFE();
|
||||
__SEV();
|
||||
__WFE();
|
||||
if (digitalRead(EPD_BUSY)) {
|
||||
printf("Screen done %lu ms\n", millis() - start);
|
||||
wdt30s();
|
||||
digitalPinToInterrupt(EPD_BUSY);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -60,17 +124,134 @@ void epdBusyWaitRising(uint32_t timeout) {
|
||||
}
|
||||
}
|
||||
|
||||
static uint16_t epdSPIXferBytes;
|
||||
static uint8_t* epdSPIWrite;
|
||||
static uint8_t* epdSPIRead;
|
||||
static volatile bool epdSPIWriteComplete = false;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
// Yes, this is the wrong interrupt handler. We're supposed to be using SPI0, I think. Something is not right in the definition :)
|
||||
void SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1_IRQHandler(void) {
|
||||
NRF_SPI0->EVENTS_READY = 0;
|
||||
if (epdSPIRead != nullptr)
|
||||
*epdSPIRead++ = NRF_SPI0->RXD;
|
||||
else {
|
||||
uint8_t dummy = NRF_SPI0->RXD;
|
||||
(void)dummy;
|
||||
}
|
||||
epdSPIXferBytes--;
|
||||
if (epdSPIXferBytes) {
|
||||
if (epdSPIWrite != nullptr)
|
||||
NRF_SPI0->TXD = *(epdSPIWrite++);
|
||||
else
|
||||
NRF_SPI0->TXD = 0x00;
|
||||
} else {
|
||||
epdSPIWriteComplete = true;
|
||||
}
|
||||
}
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
void epdSPIWait() {
|
||||
while (!epdSPIWriteComplete)
|
||||
;
|
||||
}
|
||||
|
||||
bool HWSPIStatus = false;
|
||||
bool HWSPIFirst = true;
|
||||
void epdHardSPI(bool enable) {
|
||||
if (HWSPIStatus != enable) {
|
||||
if (enable) {
|
||||
// is this the first time we're called to activate HW SPI? Do the full setup
|
||||
if (HWSPIFirst) {
|
||||
HWSPIFirst = false;
|
||||
NRF_SPI0->PSELSCK = EPD_CLK;
|
||||
NRF_SPI0->PSELMOSI = EPD_MOSI;
|
||||
NRF_SPI0->PSELMISO = EPD_VPP;
|
||||
NRF_SPI0->ENABLE = (SPI_ENABLE_ENABLE_Enabled << SPI_ENABLE_ENABLE_Pos);
|
||||
NRF_SPI0->CONFIG = (SPI_CONFIG_CPOL_ActiveHigh << SPI_CONFIG_CPOL_Pos) | (SPI_CONFIG_CPHA_Leading << SPI_CONFIG_CPHA_Pos);
|
||||
NRF_SPI0->FREQUENCY = SPI_FREQUENCY_FREQUENCY_M8;
|
||||
NRF_SPI0->EVENTS_READY = 0;
|
||||
NVIC_ClearPendingIRQ(SPIM0_SPIS0_SPI0_IRQn);
|
||||
NRF_SPI0->INTENSET = 0x04;
|
||||
NVIC_EnableIRQ(SPIM0_SPIS0_SPI0_IRQn);
|
||||
} else {
|
||||
NRF_SPI0->ENABLE = (SPI_ENABLE_ENABLE_Enabled << SPI_ENABLE_ENABLE_Pos);
|
||||
}
|
||||
} else {
|
||||
NRF_SPI0->ENABLE = (SPI_ENABLE_ENABLE_Disabled << SPI_ENABLE_ENABLE_Pos);
|
||||
}
|
||||
HWSPIStatus = enable;
|
||||
}
|
||||
}
|
||||
|
||||
void epdSPIAsyncWrite(uint8_t* data, uint16_t len) {
|
||||
epdSPIWriteComplete = false;
|
||||
epdSPIXferBytes = len;
|
||||
epdSPIWrite = data;
|
||||
epdSPIRead = nullptr;
|
||||
NRF_SPI0->TXD = *(epdSPIWrite++);
|
||||
}
|
||||
|
||||
void epdSPIReadBlock(uint8_t* data, uint16_t len) {
|
||||
epdSPIWriteComplete = false;
|
||||
epdSPIXferBytes = len;
|
||||
epdSPIRead = data;
|
||||
epdSPIWrite = nullptr;
|
||||
NRF_SPI0->TXD = 0x00;
|
||||
epdSPIWait();
|
||||
}
|
||||
|
||||
void spi_write(uint8_t data) {
|
||||
epdSPIWriteComplete = false;
|
||||
epdSPIXferBytes = 1;
|
||||
epdSPIWrite = &data;
|
||||
epdSPIRead = nullptr;
|
||||
NRF_SPI0->TXD = *(epdSPIWrite++);
|
||||
epdSPIWait();
|
||||
}
|
||||
|
||||
// This function is used by the UC8151 version of the code, for reading EEPROM LUT data
|
||||
uint8_t spi_trans(uint8_t data) {
|
||||
uint8_t b = 0;
|
||||
for (uint8_t i = 0; i < 8; i++) {
|
||||
b <<= 1;
|
||||
digitalWrite(EPD_CLK, LOW);
|
||||
if (data & 0x80) {
|
||||
digitalWrite(EPD_MOSI, HIGH);
|
||||
} else {
|
||||
digitalWrite(EPD_MOSI, LOW);
|
||||
}
|
||||
if (digitalRead(EPD_VPP)) b |= 1;
|
||||
data = (data << 1);
|
||||
digitalWrite(EPD_CLK, HIGH);
|
||||
}
|
||||
return b;
|
||||
}
|
||||
|
||||
// for reading 3-wire SPI data back from the EPD
|
||||
uint8_t spi3_read() {
|
||||
uint8_t b = 0;
|
||||
digitalWrite(EPD_BS, HIGH);
|
||||
digitalWrite(EPD_CLK, LOW);
|
||||
digitalWrite(EPD_MOSI, HIGH);
|
||||
digitalWrite(EPD_CS, LOW);
|
||||
digitalWrite(EPD_CLK, HIGH);
|
||||
pinMode(EPD_MOSI, INPUT);
|
||||
for (uint8_t i = 0; i < 8; i++) {
|
||||
b <<= 1;
|
||||
digitalWrite(EPD_CLK, LOW);
|
||||
if (digitalRead(EPD_MOSI)) b |= 1;
|
||||
digitalWrite(EPD_CLK, HIGH);
|
||||
}
|
||||
pinMode(EPD_MOSI, OUTPUT);
|
||||
digitalWrite(EPD_MOSI, LOW);
|
||||
digitalWrite(EPD_CS, HIGH);
|
||||
digitalWrite(EPD_BS, LOW);
|
||||
return b;
|
||||
}
|
||||
|
||||
void epd_cmd(uint8_t data) {
|
||||
@@ -91,3 +272,19 @@ void waitBusy() {
|
||||
while (digitalRead(EPD_BUSY) == HIGH) {
|
||||
}
|
||||
}
|
||||
|
||||
void epdWrite(uint8_t reg, uint8_t len, ...) {
|
||||
va_list valist;
|
||||
va_start(valist, len);
|
||||
markCommand();
|
||||
epdSelect();
|
||||
spi_write(reg);
|
||||
epdDeselect();
|
||||
markData();
|
||||
for (uint8_t i = 0; i < len; i++) {
|
||||
epdSelect();
|
||||
spi_write(va_arg(valist, int));
|
||||
epdDeselect();
|
||||
}
|
||||
va_end(valist);
|
||||
}
|
||||
@@ -6,4 +6,39 @@ void epd_cmd(uint8_t data);
|
||||
void epd_data(uint8_t data);
|
||||
void waitBusy();
|
||||
void epdBusyWaitFalling(uint32_t timeout);
|
||||
void epdBusyWaitRising(uint32_t timeout);
|
||||
void epdBusyWaitRising(uint32_t timeout);
|
||||
|
||||
uint8_t spi3_read();
|
||||
uint8_t spi_trans(uint8_t data);
|
||||
void epdWrite(uint8_t reg, uint8_t len, ...);
|
||||
|
||||
void epdReset();
|
||||
void epdConfigGPIO(bool setup);
|
||||
extern bool epdGPIOActive;
|
||||
|
||||
void epdSPIAsyncWrite(uint8_t* data, uint16_t len);
|
||||
void epdSPIWait();
|
||||
void epdSPIReadBlock(uint8_t* data, uint16_t len);
|
||||
void epdHardSPI(bool enable);
|
||||
|
||||
#define epdSelect() \
|
||||
do \
|
||||
{ \
|
||||
digitalWrite(EPD_CS, LOW); \
|
||||
} while (0)
|
||||
|
||||
#define epdDeselect() \
|
||||
do \
|
||||
{ \
|
||||
digitalWrite(EPD_CS, HIGH); \
|
||||
} while (0)
|
||||
|
||||
#define markCommand() \
|
||||
do { \
|
||||
digitalWrite(EPD_DC, LOW); \
|
||||
} while (0)
|
||||
|
||||
#define markData() \
|
||||
do { \
|
||||
digitalWrite(EPD_DC, HIGH); \
|
||||
} while (0)
|
||||
|
||||
@@ -0,0 +1,171 @@
|
||||
#include <Arduino.h>
|
||||
|
||||
#include "wdt.h"
|
||||
#include "HAL_Newton_M3.h"
|
||||
#include "../src/epd_driver/epd_interface.h"
|
||||
#include "../../../../oepl-definitions.h"
|
||||
#include "../include/eeprom.h"
|
||||
|
||||
uint8_t getUICRByte(uint8_t offset) {
|
||||
// the nRF accesses registers and data in 32-bit words. We'll need to do some quick maffs to get individual bytes
|
||||
uint32_t reg = NRF_UICR->CUSTOMER[offset / 4];
|
||||
offset %= 4;
|
||||
offset *= 8;
|
||||
reg >>= offset;
|
||||
return (reg & 0xFF);
|
||||
}
|
||||
|
||||
void identifyTagInfo() {
|
||||
// get some info about the tag from the UICR. Found the information when comparing the 'customer' area for various tags. The following information is known;
|
||||
// this has been deducted from comparing many of the UICR data from various tags
|
||||
/*
|
||||
00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F
|
||||
|
||||
93 47 2E 06 16 01 15 04 00 11 01 58 02 C0 01 04 00 03 81 9D 00 00 48 FF FF FF FF FF FF FF FF FF 6.0 UC8159
|
||||
62 65 F6 06 16 07 04 04 00 0E 01 0A 02 98 00 38 00 07 01 9C 00 00 47 03 68 00 00 00 00 00 00 00 4.3 UCvar43 (no buttons)
|
||||
E0 5F F6 06 16 07 04 04 00 0E 01 0A 02 98 00 38 00 07 01 9C 00 00 47 03 68 00 00 00 00 00 00 00 4.3 UCvar43 (no buttons)
|
||||
B1 42 68 06 16 03 0E 04 00 0E 01 0A 02 98 00 38 00 07 01 9C 00 00 47 FF FF FF FF FF FF FF FF FF 4.3 UCvar43-dif batch (no buttons)
|
||||
78 56 34 12 17 01 1E 04 00 1A 01 0A 02 98 00 38 00 07 81 9D 00 00 47 03 0A 00 00 00 00 00 00 00 4.3 with buttons
|
||||
49 B6 77 7E 16 06 0F 04 00 0F 01 28 01 A0 00 39 00 07 81 9D 00 00 41 03 14 00 00 00 00 00 00 00 2.2 SSD1619
|
||||
DF 00 C6 05 15 0A 14 04 00 15 01 68 01 B8 00 38 00 07 01 9C 00 00 43 FF FF FF FF FF FF FF FF FF 2.6 Lite (no buttons)
|
||||
E5 16 52 06 16 02 18 04 00 12 01 C8 00 C8 00 04 00 07 01 9C 00 00 40 FF FF FF FF FF FF FF FF FF 1.6 Lite SSD1619 (no buttons)
|
||||
67 CC 22 7E 15 0B 15 04 00 15 01 80 01 A8 00 39 00 07 81 9D 00 00 42 FF FF FF FF FF FF FF FF FF 2.9 SSD1619
|
||||
0B 81 08 04 14 09 0F 04 00 0D 01 80 01 A8 00 38 00 07 81 9D 00 00 42 FF FF FF FF FF FF FF FF FF 2.9 UC8151
|
||||
26 36 42 7E 16 03 14 04 00 15 01 80 01 A8 00 38 00 07 01 9C 00 00 42 FF FF FF FF FF FF FF FF FF 2.9 Lite (SSD) (no buttons)
|
||||
F1 D5 B2 05 15 0A 04 04 00 12 01 90 01 2C 01 04 00 07 01 9C 00 00 46 FF FF FF FF FF FF FF FF FF 4.2 SSD
|
||||
CA FE BA DE 15 0B 12 04 00 10 01 E0 01 20 03 39 00 03 81 9D 00 00 4C FF FF FF FF FF FF FF FF FF 7.4 UC8179
|
||||
F3 22 BC 05 15 0A 0D 04 00 19 01 A0 02 C0 03 38 07 07 01 80 00 00 64 FF FF FF FF FF FF FF FF FF 9.7 SSD
|
||||
AD BA FE CA 15 0A 1B 04 00 19 01 A0 02 C0 03 38 07 07 01 80 00 00 64 FF FF FF FF FF FF FF FF FF 9.7 type 2
|
||||
|
||||
MAC | calib | |?????|Xres |Yres | ??? |capab| |type|
|
||||
|
||||
0x09 - controller?
|
||||
0x0D - UC8151?
|
||||
0x0E - UVvar43
|
||||
0x1A - UVvar43 (probably)
|
||||
0x0F - SSD (var2.2)
|
||||
0x10 - UC8179
|
||||
0x11 - UC8159
|
||||
0x12 - SSD (var1.6)
|
||||
0x15 - SSD (2.9 lite)
|
||||
0x19 - SSD (9.7)
|
||||
|
||||
0x12 - 0x01 | (0x80 if it has a button)
|
||||
0x13 - 0x80 | (0x10 if it has a LED) | (0x0C ?? ) | (0x01 if it has a button)
|
||||
*/
|
||||
uint16_t tmp = getUICRByte(0x0B);
|
||||
tmp |= getUICRByte(0x0C) << 8;
|
||||
uint16_t epdXRes = tmp;
|
||||
tmp = getUICRByte(0x0D);
|
||||
tmp |= getUICRByte(0x0E) << 8;
|
||||
uint16_t epdYRes = tmp;
|
||||
uint8_t controllerType = getUICRByte(0x09);
|
||||
uint8_t capabilities[2];
|
||||
capabilities[0] = getUICRByte(0x12);
|
||||
capabilities[1] = getUICRByte(0x13);
|
||||
tag.solumType = getUICRByte(0x16);
|
||||
|
||||
switch (controllerType) {
|
||||
case 0x0F:
|
||||
case 0x12:
|
||||
case 0x15:
|
||||
case 0x19:
|
||||
epd = new unissd;
|
||||
break;
|
||||
case 0x0D:
|
||||
epd = new epdvar29;
|
||||
break;
|
||||
case 0x0E:
|
||||
case 0x1A: // 4.3 variant with buttons? probably var43
|
||||
epd = new epdvar43;
|
||||
break;
|
||||
case 0x11:
|
||||
epd = new uc8159;
|
||||
break;
|
||||
case 0x10:
|
||||
epd = new uc8179;
|
||||
break;
|
||||
}
|
||||
|
||||
epd->controllerType = controllerType;
|
||||
|
||||
// set the resolution based on UICR data
|
||||
epd->Xres = epdXRes;
|
||||
epd->Yres = epdYRes;
|
||||
|
||||
// set the effective (working) resolution
|
||||
epd->effectiveXRes = epdXRes;
|
||||
epd->effectiveYRes = epdYRes;
|
||||
|
||||
// set default offset;
|
||||
epd->XOffset = 0;
|
||||
epd->YOffset = 0;
|
||||
|
||||
if (capabilities[0] & 0x80) tag.buttonCount++;
|
||||
if (capabilities[1] & 0x01) tag.buttonCount++;
|
||||
if (capabilities[1] & 0x10) tag.hasLED = true;
|
||||
if (capabilities[0] & 0x01) tag.hasNFC = true;
|
||||
|
||||
// we'll calculate image slot size here
|
||||
uint32_t imageSize = epd->Xres * epd->Yres / 4;
|
||||
tag.imageSize = ((imageSize + EEPROM_ERZ_SECTOR_SZ - 1) / EEPROM_ERZ_SECTOR_SZ) * EEPROM_ERZ_SECTOR_SZ;
|
||||
|
||||
switch (tag.solumType) {
|
||||
case STYPE_SIZE_016:
|
||||
tag.macSuffix = 0xB0D0;
|
||||
epd->epdMirrorV = true;
|
||||
tag.OEPLtype = SOLUM_M3_BWR_16;
|
||||
break;
|
||||
case STYPE_SIZE_022:
|
||||
tag.macSuffix = 0xB190;
|
||||
epd->drawDirectionRight = true;
|
||||
tag.OEPLtype = SOLUM_M3_BWR_22;
|
||||
epd->XOffset = 8;
|
||||
break;
|
||||
case STYPE_SIZE_029:
|
||||
tag.OEPLtype = SOLUM_M3_BWR_29;
|
||||
if (tag.buttonCount == 2) {
|
||||
// probably the 'normal' M3 version
|
||||
tag.macSuffix = 0xB290;
|
||||
} else {
|
||||
// probably the 'lite' version
|
||||
tag.macSuffix = 0xB2DA;
|
||||
}
|
||||
epd->drawDirectionRight = true;
|
||||
epd->XOffset = 8;
|
||||
break;
|
||||
case STYPE_SIZE_042:
|
||||
tag.macSuffix = 0xB6D0;
|
||||
tag.OEPLtype = SOLUM_M3_BWR_42;
|
||||
epd->epdMirrorV = true;
|
||||
break;
|
||||
case STYPE_SIZE_043:
|
||||
tag.macSuffix = 0xB7D0;
|
||||
epd->drawDirectionRight = true;
|
||||
// epd->mirrorH = true;
|
||||
tag.OEPLtype = SOLUM_M3_BWR_43;
|
||||
break;
|
||||
case STYPE_SIZE_060:
|
||||
tag.macSuffix = 0xB890;
|
||||
tag.OEPLtype = SOLUM_M3_BWR_60;
|
||||
break;
|
||||
case STYPE_SIZE_075:
|
||||
tag.macSuffix = 0xBC90;
|
||||
tag.OEPLtype = SOLUM_M3_BWR_75;
|
||||
epd->Xres = epdYRes;
|
||||
epd->Yres = epdXRes;
|
||||
epd->effectiveXRes = epdYRes;
|
||||
epd->effectiveYRes = epdXRes;
|
||||
break;
|
||||
case STYPE_SIZE_097:
|
||||
tag.macSuffix = 0xE4D0;
|
||||
epd->drawDirectionRight = true;
|
||||
tag.OEPLtype = SOLUM_M3_BWR_97;
|
||||
break;
|
||||
}
|
||||
|
||||
if (epd->drawDirectionRight) {
|
||||
epd->effectiveXRes = epdYRes;
|
||||
epd->effectiveYRes = epdXRes;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
#include <Arduino.h>
|
||||
|
||||
uint8_t getUICRByte(uint8_t offset);
|
||||
void identifyTagInfo();
|
||||
@@ -13,7 +13,6 @@ uint8_t seq_nr = 0;
|
||||
uint8_t get_seq_nr() {
|
||||
return seq_nr++;
|
||||
}
|
||||
static uint8_t mCommsBuf[133];
|
||||
|
||||
#define MAX_RX_PKTS 8
|
||||
|
||||
|
||||
202
ARM_Tag_FW/Newton_M3_nRF52811/include/FreeSans9pt7b.h
Normal file
202
ARM_Tag_FW/Newton_M3_nRF52811/include/FreeSans9pt7b.h
Normal file
@@ -0,0 +1,202 @@
|
||||
#pragma once
|
||||
|
||||
const uint8_t FreeSans9pt7bBitmaps[] PROGMEM = {
|
||||
0xFF, 0xFF, 0xF8, 0xC0, 0xDE, 0xF7, 0x20, 0x09, 0x86, 0x41, 0x91, 0xFF,
|
||||
0x13, 0x04, 0xC3, 0x20, 0xC8, 0xFF, 0x89, 0x82, 0x61, 0x90, 0x10, 0x1F,
|
||||
0x14, 0xDA, 0x3D, 0x1E, 0x83, 0x40, 0x78, 0x17, 0x08, 0xF4, 0x7A, 0x35,
|
||||
0x33, 0xF0, 0x40, 0x20, 0x38, 0x10, 0xEC, 0x20, 0xC6, 0x20, 0xC6, 0x40,
|
||||
0xC6, 0x40, 0x6C, 0x80, 0x39, 0x00, 0x01, 0x3C, 0x02, 0x77, 0x02, 0x63,
|
||||
0x04, 0x63, 0x04, 0x77, 0x08, 0x3C, 0x0E, 0x06, 0x60, 0xCC, 0x19, 0x81,
|
||||
0xE0, 0x18, 0x0F, 0x03, 0x36, 0xC2, 0xD8, 0x73, 0x06, 0x31, 0xE3, 0xC4,
|
||||
0xFE, 0x13, 0x26, 0x6C, 0xCC, 0xCC, 0xC4, 0x66, 0x23, 0x10, 0x8C, 0x46,
|
||||
0x63, 0x33, 0x33, 0x32, 0x66, 0x4C, 0x80, 0x25, 0x7E, 0xA5, 0x00, 0x30,
|
||||
0xC3, 0x3F, 0x30, 0xC3, 0x0C, 0xD6, 0xF0, 0xC0, 0x08, 0x44, 0x21, 0x10,
|
||||
0x84, 0x42, 0x11, 0x08, 0x00, 0x3C, 0x66, 0x42, 0xC3, 0xC3, 0xC3, 0xC3,
|
||||
0xC3, 0xC3, 0xC3, 0x42, 0x66, 0x3C, 0x11, 0x3F, 0x33, 0x33, 0x33, 0x33,
|
||||
0x30, 0x3E, 0x31, 0xB0, 0x78, 0x30, 0x18, 0x1C, 0x1C, 0x1C, 0x18, 0x18,
|
||||
0x10, 0x08, 0x07, 0xF8, 0x3C, 0x66, 0xC3, 0xC3, 0x03, 0x06, 0x1C, 0x07,
|
||||
0x03, 0xC3, 0xC3, 0x66, 0x3C, 0x0C, 0x18, 0x71, 0x62, 0xC9, 0xA3, 0x46,
|
||||
0xFE, 0x18, 0x30, 0x60, 0xC0, 0x7F, 0x20, 0x10, 0x08, 0x08, 0x07, 0xF3,
|
||||
0x8C, 0x03, 0x01, 0x80, 0xF0, 0x6C, 0x63, 0xE0, 0x1E, 0x31, 0x98, 0x78,
|
||||
0x0C, 0x06, 0xF3, 0x8D, 0x83, 0xC1, 0xE0, 0xD0, 0x6C, 0x63, 0xE0, 0xFF,
|
||||
0x03, 0x02, 0x06, 0x04, 0x0C, 0x08, 0x18, 0x18, 0x18, 0x10, 0x30, 0x30,
|
||||
0x3E, 0x31, 0xB0, 0x78, 0x3C, 0x1B, 0x18, 0xF8, 0xC6, 0xC1, 0xE0, 0xF0,
|
||||
0x6C, 0x63, 0xE0, 0x3C, 0x66, 0xC2, 0xC3, 0xC3, 0xC3, 0x67, 0x3B, 0x03,
|
||||
0x03, 0xC2, 0x66, 0x3C, 0xC0, 0x00, 0x30, 0xC0, 0x00, 0x00, 0x64, 0xA0,
|
||||
0x00, 0x81, 0xC7, 0x8E, 0x0C, 0x07, 0x80, 0x70, 0x0E, 0x01, 0x80, 0xFF,
|
||||
0x80, 0x00, 0x1F, 0xF0, 0x00, 0x70, 0x0E, 0x01, 0xC0, 0x18, 0x38, 0x71,
|
||||
0xC0, 0x80, 0x00, 0x3E, 0x31, 0xB0, 0x78, 0x30, 0x18, 0x18, 0x38, 0x18,
|
||||
0x18, 0x0C, 0x00, 0x00, 0x01, 0x80, 0x03, 0xF0, 0x06, 0x0E, 0x06, 0x01,
|
||||
0x86, 0x00, 0x66, 0x1D, 0xBB, 0x31, 0xCF, 0x18, 0xC7, 0x98, 0x63, 0xCC,
|
||||
0x31, 0xE6, 0x11, 0xB3, 0x99, 0xCC, 0xF7, 0x86, 0x00, 0x01, 0x80, 0x00,
|
||||
0x70, 0x40, 0x0F, 0xE0, 0x06, 0x00, 0xF0, 0x0F, 0x00, 0x90, 0x19, 0x81,
|
||||
0x98, 0x10, 0x83, 0x0C, 0x3F, 0xC2, 0x04, 0x60, 0x66, 0x06, 0xC0, 0x30,
|
||||
0xFF, 0x18, 0x33, 0x03, 0x60, 0x6C, 0x0D, 0x83, 0x3F, 0xC6, 0x06, 0xC0,
|
||||
0x78, 0x0F, 0x01, 0xE0, 0x6F, 0xF8, 0x1F, 0x86, 0x19, 0x81, 0xA0, 0x3C,
|
||||
0x01, 0x80, 0x30, 0x06, 0x00, 0xC0, 0x68, 0x0D, 0x83, 0x18, 0x61, 0xF0,
|
||||
0xFF, 0x18, 0x33, 0x03, 0x60, 0x3C, 0x07, 0x80, 0xF0, 0x1E, 0x03, 0xC0,
|
||||
0x78, 0x0F, 0x03, 0x60, 0xCF, 0xF0, 0xFF, 0xE0, 0x30, 0x18, 0x0C, 0x06,
|
||||
0x03, 0xFD, 0x80, 0xC0, 0x60, 0x30, 0x18, 0x0F, 0xF8, 0xFF, 0xC0, 0xC0,
|
||||
0xC0, 0xC0, 0xC0, 0xFE, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0x0F, 0x83,
|
||||
0x0E, 0x60, 0x66, 0x03, 0xC0, 0x0C, 0x00, 0xC1, 0xFC, 0x03, 0xC0, 0x36,
|
||||
0x03, 0x60, 0x73, 0x0F, 0x0F, 0x10, 0xC0, 0x78, 0x0F, 0x01, 0xE0, 0x3C,
|
||||
0x07, 0x80, 0xFF, 0xFE, 0x03, 0xC0, 0x78, 0x0F, 0x01, 0xE0, 0x3C, 0x06,
|
||||
0xFF, 0xFF, 0xFF, 0xC0, 0x06, 0x0C, 0x18, 0x30, 0x60, 0xC1, 0x83, 0x07,
|
||||
0x8F, 0x1E, 0x27, 0x80, 0xC0, 0xD8, 0x33, 0x0C, 0x63, 0x0C, 0xC1, 0xB8,
|
||||
0x3F, 0x07, 0x30, 0xC3, 0x18, 0x63, 0x06, 0x60, 0x6C, 0x0C, 0xC0, 0xC0,
|
||||
0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xFF, 0xE0,
|
||||
0x3F, 0x01, 0xFC, 0x1F, 0xE0, 0xFD, 0x05, 0xEC, 0x6F, 0x63, 0x79, 0x13,
|
||||
0xCD, 0x9E, 0x6C, 0xF1, 0x47, 0x8E, 0x3C, 0x71, 0x80, 0xE0, 0x7C, 0x0F,
|
||||
0xC1, 0xE8, 0x3D, 0x87, 0x98, 0xF1, 0x1E, 0x33, 0xC3, 0x78, 0x6F, 0x07,
|
||||
0xE0, 0x7C, 0x0E, 0x0F, 0x81, 0x83, 0x18, 0x0C, 0xC0, 0x6C, 0x01, 0xE0,
|
||||
0x0F, 0x00, 0x78, 0x03, 0xC0, 0x1B, 0x01, 0x98, 0x0C, 0x60, 0xC0, 0xF8,
|
||||
0x00, 0xFF, 0x30, 0x6C, 0x0F, 0x03, 0xC0, 0xF0, 0x6F, 0xF3, 0x00, 0xC0,
|
||||
0x30, 0x0C, 0x03, 0x00, 0xC0, 0x00, 0x0F, 0x81, 0x83, 0x18, 0x0C, 0xC0,
|
||||
0x6C, 0x01, 0xE0, 0x0F, 0x00, 0x78, 0x03, 0xC0, 0x1B, 0x01, 0x98, 0x6C,
|
||||
0x60, 0xC0, 0xFB, 0x00, 0x08, 0xFF, 0x8C, 0x0E, 0xC0, 0x6C, 0x06, 0xC0,
|
||||
0x6C, 0x0C, 0xFF, 0x8C, 0x0E, 0xC0, 0x6C, 0x06, 0xC0, 0x6C, 0x06, 0xC0,
|
||||
0x70, 0x3F, 0x18, 0x6C, 0x0F, 0x03, 0xC0, 0x1E, 0x01, 0xF0, 0x0E, 0x00,
|
||||
0xF0, 0x3C, 0x0D, 0x86, 0x3F, 0x00, 0xFF, 0x86, 0x03, 0x01, 0x80, 0xC0,
|
||||
0x60, 0x30, 0x18, 0x0C, 0x06, 0x03, 0x01, 0x80, 0xC0, 0xC0, 0x78, 0x0F,
|
||||
0x01, 0xE0, 0x3C, 0x07, 0x80, 0xF0, 0x1E, 0x03, 0xC0, 0x78, 0x0F, 0x01,
|
||||
0xB0, 0x61, 0xF0, 0xC0, 0x6C, 0x0D, 0x81, 0x10, 0x63, 0x0C, 0x61, 0x04,
|
||||
0x60, 0xCC, 0x19, 0x01, 0x60, 0x3C, 0x07, 0x00, 0x60, 0xC1, 0x81, 0x30,
|
||||
0xE1, 0x98, 0x70, 0xCC, 0x28, 0x66, 0x26, 0x21, 0x13, 0x30, 0xC8, 0x98,
|
||||
0x6C, 0x4C, 0x14, 0x34, 0x0A, 0x1A, 0x07, 0x07, 0x03, 0x03, 0x80, 0x81,
|
||||
0x80, 0x60, 0x63, 0x0C, 0x30, 0xC1, 0x98, 0x0F, 0x00, 0xE0, 0x06, 0x00,
|
||||
0xF0, 0x19, 0x01, 0x98, 0x30, 0xC6, 0x0E, 0x60, 0x60, 0xC0, 0x36, 0x06,
|
||||
0x30, 0xC3, 0x0C, 0x19, 0x81, 0xD8, 0x0F, 0x00, 0x60, 0x06, 0x00, 0x60,
|
||||
0x06, 0x00, 0x60, 0x06, 0x00, 0xFF, 0xC0, 0x60, 0x30, 0x0C, 0x06, 0x03,
|
||||
0x01, 0xC0, 0x60, 0x30, 0x18, 0x06, 0x03, 0x00, 0xFF, 0xC0, 0xFB, 0x6D,
|
||||
0xB6, 0xDB, 0x6D, 0xB6, 0xE0, 0x84, 0x10, 0x84, 0x10, 0x84, 0x10, 0x84,
|
||||
0x10, 0x80, 0xED, 0xB6, 0xDB, 0x6D, 0xB6, 0xDB, 0xE0, 0x30, 0x60, 0xA2,
|
||||
0x44, 0xD8, 0xA1, 0x80, 0xFF, 0xC0, 0xC6, 0x30, 0x7E, 0x71, 0xB0, 0xC0,
|
||||
0x60, 0xF3, 0xDB, 0x0D, 0x86, 0xC7, 0x3D, 0xC0, 0xC0, 0x60, 0x30, 0x1B,
|
||||
0xCE, 0x36, 0x0F, 0x07, 0x83, 0xC1, 0xE0, 0xF0, 0x7C, 0x6D, 0xE0, 0x3C,
|
||||
0x66, 0xC3, 0xC0, 0xC0, 0xC0, 0xC0, 0xC3, 0x66, 0x3C, 0x03, 0x03, 0x03,
|
||||
0x3B, 0x67, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0x67, 0x3B, 0x3C, 0x66,
|
||||
0xC3, 0xC3, 0xFF, 0xC0, 0xC0, 0xC3, 0x66, 0x3C, 0x36, 0x6F, 0x66, 0x66,
|
||||
0x66, 0x66, 0x60, 0x3B, 0x67, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0x67,
|
||||
0x3B, 0x03, 0x03, 0xC6, 0x7C, 0xC0, 0xC0, 0xC0, 0xDE, 0xE3, 0xC3, 0xC3,
|
||||
0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xFF, 0xFF, 0xC0, 0x30, 0x03,
|
||||
0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0xE0, 0xC0, 0x60, 0x30, 0x18, 0x4C,
|
||||
0x46, 0x63, 0x61, 0xF0, 0xEC, 0x62, 0x31, 0x98, 0x6C, 0x30, 0xFF, 0xFF,
|
||||
0xFF, 0xC0, 0xDE, 0xF7, 0x1C, 0xF0, 0xC7, 0x86, 0x3C, 0x31, 0xE1, 0x8F,
|
||||
0x0C, 0x78, 0x63, 0xC3, 0x1E, 0x18, 0xC0, 0xDE, 0xE3, 0xC3, 0xC3, 0xC3,
|
||||
0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0x3C, 0x66, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3,
|
||||
0xC3, 0x66, 0x3C, 0xDE, 0x71, 0xB0, 0x78, 0x3C, 0x1E, 0x0F, 0x07, 0x83,
|
||||
0xE3, 0x6F, 0x30, 0x18, 0x0C, 0x00, 0x3B, 0x67, 0xC3, 0xC3, 0xC3, 0xC3,
|
||||
0xC3, 0xC3, 0x67, 0x3B, 0x03, 0x03, 0x03, 0xDF, 0x31, 0x8C, 0x63, 0x18,
|
||||
0xC6, 0x00, 0x3E, 0xE3, 0xC0, 0xC0, 0xE0, 0x3C, 0x07, 0xC3, 0xE3, 0x7E,
|
||||
0x66, 0xF6, 0x66, 0x66, 0x66, 0x67, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3,
|
||||
0xC3, 0xC3, 0xC7, 0x7B, 0xC1, 0xA0, 0x98, 0xCC, 0x42, 0x21, 0xB0, 0xD0,
|
||||
0x28, 0x1C, 0x0C, 0x00, 0xC6, 0x1E, 0x38, 0x91, 0xC4, 0xCA, 0x66, 0xD3,
|
||||
0x16, 0xD0, 0xA6, 0x87, 0x1C, 0x38, 0xC0, 0xC6, 0x00, 0x43, 0x62, 0x36,
|
||||
0x1C, 0x18, 0x1C, 0x3C, 0x26, 0x62, 0x43, 0xC1, 0x21, 0x98, 0xCC, 0x42,
|
||||
0x61, 0xB0, 0xD0, 0x38, 0x1C, 0x0C, 0x06, 0x03, 0x01, 0x03, 0x00, 0xFE,
|
||||
0x0C, 0x30, 0xC1, 0x86, 0x18, 0x20, 0xC1, 0xFC, 0x36, 0x66, 0x66, 0x6E,
|
||||
0xCE, 0x66, 0x66, 0x66, 0x30, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0xC6, 0x66,
|
||||
0x66, 0x67, 0x37, 0x66, 0x66, 0x66, 0xC0, 0x61, 0x24, 0x38};
|
||||
|
||||
const GFXglyph FreeSans9pt7bGlyphs[] PROGMEM = {
|
||||
{0, 0, 0, 5, 0, 1}, // 0x20 ' '
|
||||
{0, 2, 13, 6, 2, -12}, // 0x21 '!'
|
||||
{4, 5, 4, 6, 1, -12}, // 0x22 '"'
|
||||
{7, 10, 12, 10, 0, -11}, // 0x23 '#'
|
||||
{22, 9, 16, 10, 1, -13}, // 0x24 '$'
|
||||
{40, 16, 13, 16, 1, -12}, // 0x25 '%'
|
||||
{66, 11, 13, 12, 1, -12}, // 0x26 '&'
|
||||
{84, 2, 4, 4, 1, -12}, // 0x27 '''
|
||||
{85, 4, 17, 6, 1, -12}, // 0x28 '('
|
||||
{94, 4, 17, 6, 1, -12}, // 0x29 ')'
|
||||
{103, 5, 5, 7, 1, -12}, // 0x2A '*'
|
||||
{107, 6, 8, 11, 3, -7}, // 0x2B '+'
|
||||
{113, 2, 4, 5, 2, 0}, // 0x2C ','
|
||||
{114, 4, 1, 6, 1, -4}, // 0x2D '-'
|
||||
{115, 2, 1, 5, 1, 0}, // 0x2E '.'
|
||||
{116, 5, 13, 5, 0, -12}, // 0x2F '/'
|
||||
{125, 8, 13, 10, 1, -12}, // 0x30 '0'
|
||||
{138, 4, 13, 10, 3, -12}, // 0x31 '1'
|
||||
{145, 9, 13, 10, 1, -12}, // 0x32 '2'
|
||||
{160, 8, 13, 10, 1, -12}, // 0x33 '3'
|
||||
{173, 7, 13, 10, 2, -12}, // 0x34 '4'
|
||||
{185, 9, 13, 10, 1, -12}, // 0x35 '5'
|
||||
{200, 9, 13, 10, 1, -12}, // 0x36 '6'
|
||||
{215, 8, 13, 10, 0, -12}, // 0x37 '7'
|
||||
{228, 9, 13, 10, 1, -12}, // 0x38 '8'
|
||||
{243, 8, 13, 10, 1, -12}, // 0x39 '9'
|
||||
{256, 2, 10, 5, 1, -9}, // 0x3A ':'
|
||||
{259, 3, 12, 5, 1, -8}, // 0x3B ';'
|
||||
{264, 9, 9, 11, 1, -8}, // 0x3C '<'
|
||||
{275, 9, 4, 11, 1, -5}, // 0x3D '='
|
||||
{280, 9, 9, 11, 1, -8}, // 0x3E '>'
|
||||
{291, 9, 13, 10, 1, -12}, // 0x3F '?'
|
||||
{306, 17, 16, 18, 1, -12}, // 0x40 '@'
|
||||
{340, 12, 13, 12, 0, -12}, // 0x41 'A'
|
||||
{360, 11, 13, 12, 1, -12}, // 0x42 'B'
|
||||
{378, 11, 13, 13, 1, -12}, // 0x43 'C'
|
||||
{396, 11, 13, 13, 1, -12}, // 0x44 'D'
|
||||
{414, 9, 13, 11, 1, -12}, // 0x45 'E'
|
||||
{429, 8, 13, 11, 1, -12}, // 0x46 'F'
|
||||
{442, 12, 13, 14, 1, -12}, // 0x47 'G'
|
||||
{462, 11, 13, 13, 1, -12}, // 0x48 'H'
|
||||
{480, 2, 13, 5, 2, -12}, // 0x49 'I'
|
||||
{484, 7, 13, 10, 1, -12}, // 0x4A 'J'
|
||||
{496, 11, 13, 12, 1, -12}, // 0x4B 'K'
|
||||
{514, 8, 13, 10, 1, -12}, // 0x4C 'L'
|
||||
{527, 13, 13, 15, 1, -12}, // 0x4D 'M'
|
||||
{549, 11, 13, 13, 1, -12}, // 0x4E 'N'
|
||||
{567, 13, 13, 14, 1, -12}, // 0x4F 'O'
|
||||
{589, 10, 13, 12, 1, -12}, // 0x50 'P'
|
||||
{606, 13, 14, 14, 1, -12}, // 0x51 'Q'
|
||||
{629, 12, 13, 13, 1, -12}, // 0x52 'R'
|
||||
{649, 10, 13, 12, 1, -12}, // 0x53 'S'
|
||||
{666, 9, 13, 11, 1, -12}, // 0x54 'T'
|
||||
{681, 11, 13, 13, 1, -12}, // 0x55 'U'
|
||||
{699, 11, 13, 12, 0, -12}, // 0x56 'V'
|
||||
{717, 17, 13, 17, 0, -12}, // 0x57 'W'
|
||||
{745, 12, 13, 12, 0, -12}, // 0x58 'X'
|
||||
{765, 12, 13, 12, 0, -12}, // 0x59 'Y'
|
||||
{785, 10, 13, 11, 1, -12}, // 0x5A 'Z'
|
||||
{802, 3, 17, 5, 1, -12}, // 0x5B '['
|
||||
{809, 5, 13, 5, 0, -12}, // 0x5C '\'
|
||||
{818, 3, 17, 5, 0, -12}, // 0x5D ']'
|
||||
{825, 7, 7, 8, 1, -12}, // 0x5E '^'
|
||||
{832, 10, 1, 10, 0, 3}, // 0x5F '_'
|
||||
{834, 4, 3, 5, 0, -12}, // 0x60 '`'
|
||||
{836, 9, 10, 10, 1, -9}, // 0x61 'a'
|
||||
{848, 9, 13, 10, 1, -12}, // 0x62 'b'
|
||||
{863, 8, 10, 9, 1, -9}, // 0x63 'c'
|
||||
{873, 8, 13, 10, 1, -12}, // 0x64 'd'
|
||||
{886, 8, 10, 10, 1, -9}, // 0x65 'e'
|
||||
{896, 4, 13, 5, 1, -12}, // 0x66 'f'
|
||||
{903, 8, 14, 10, 1, -9}, // 0x67 'g'
|
||||
{917, 8, 13, 10, 1, -12}, // 0x68 'h'
|
||||
{930, 2, 13, 4, 1, -12}, // 0x69 'i'
|
||||
{934, 4, 17, 4, 0, -12}, // 0x6A 'j'
|
||||
{943, 9, 13, 9, 1, -12}, // 0x6B 'k'
|
||||
{958, 2, 13, 4, 1, -12}, // 0x6C 'l'
|
||||
{962, 13, 10, 15, 1, -9}, // 0x6D 'm'
|
||||
{979, 8, 10, 10, 1, -9}, // 0x6E 'n'
|
||||
{989, 8, 10, 10, 1, -9}, // 0x6F 'o'
|
||||
{999, 9, 13, 10, 1, -9}, // 0x70 'p'
|
||||
{1014, 8, 13, 10, 1, -9}, // 0x71 'q'
|
||||
{1027, 5, 10, 6, 1, -9}, // 0x72 'r'
|
||||
{1034, 8, 10, 9, 1, -9}, // 0x73 's'
|
||||
{1044, 4, 12, 5, 1, -11}, // 0x74 't'
|
||||
{1050, 8, 10, 10, 1, -9}, // 0x75 'u'
|
||||
{1060, 9, 10, 9, 0, -9}, // 0x76 'v'
|
||||
{1072, 13, 10, 13, 0, -9}, // 0x77 'w'
|
||||
{1089, 8, 10, 9, 0, -9}, // 0x78 'x'
|
||||
{1099, 9, 14, 9, 0, -9}, // 0x79 'y'
|
||||
{1115, 7, 10, 9, 1, -9}, // 0x7A 'z'
|
||||
{1124, 4, 17, 6, 1, -12}, // 0x7B '{'
|
||||
{1133, 2, 17, 4, 2, -12}, // 0x7C '|'
|
||||
{1138, 4, 17, 6, 1, -12}, // 0x7D '}'
|
||||
{1147, 7, 3, 9, 1, -7}}; // 0x7E '~'
|
||||
|
||||
const GFXfont FreeSans9pt7b PROGMEM = {(uint8_t *)FreeSans9pt7bBitmaps,
|
||||
(GFXglyph *)FreeSans9pt7bGlyphs, 0x20,
|
||||
0x7E, 22};
|
||||
|
||||
// Approx. 1822 bytes
|
||||
481
ARM_Tag_FW/Newton_M3_nRF52811/include/FreeSansBold18pt7b.h
Normal file
481
ARM_Tag_FW/Newton_M3_nRF52811/include/FreeSansBold18pt7b.h
Normal file
@@ -0,0 +1,481 @@
|
||||
const uint8_t FreeSansBold18pt7bBitmaps[] PROGMEM = {
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xE7, 0x39, 0xCE, 0x73, 0x80,
|
||||
0x0F, 0xFF, 0xFF, 0xF8, 0xF8, 0xFF, 0xC7, 0xFE, 0x3F, 0xF1, 0xFF, 0x8F,
|
||||
0xFC, 0x7D, 0xC1, 0xCE, 0x0E, 0x70, 0x70, 0x03, 0xC3, 0x80, 0x3C, 0x78,
|
||||
0x03, 0xC7, 0x80, 0x38, 0x78, 0x07, 0x87, 0x07, 0xFF, 0xFF, 0x7F, 0xFF,
|
||||
0xF7, 0xFF, 0xFF, 0x7F, 0xFF, 0xF0, 0xF0, 0xE0, 0x0F, 0x0E, 0x00, 0xF1,
|
||||
0xE0, 0x0F, 0x1E, 0x00, 0xE1, 0xE0, 0xFF, 0xFF, 0xCF, 0xFF, 0xFC, 0xFF,
|
||||
0xFF, 0xCF, 0xFF, 0xFC, 0x1C, 0x3C, 0x03, 0xC3, 0x80, 0x3C, 0x78, 0x03,
|
||||
0xC7, 0x80, 0x38, 0x78, 0x03, 0x87, 0x80, 0x00, 0x60, 0x00, 0x7F, 0x80,
|
||||
0x3F, 0xFC, 0x0F, 0xFF, 0xC3, 0xFF, 0xFC, 0xFC, 0xDF, 0x9F, 0x19, 0xFB,
|
||||
0xC3, 0x1F, 0x78, 0x63, 0xEF, 0x8C, 0x01, 0xFD, 0x80, 0x1F, 0xF0, 0x01,
|
||||
0xFF, 0xC0, 0x1F, 0xFE, 0x00, 0x7F, 0xE0, 0x03, 0xFE, 0x00, 0x67, 0xE0,
|
||||
0x0C, 0x7F, 0xE1, 0x8F, 0xFC, 0x31, 0xFF, 0xC6, 0x3E, 0xFC, 0xDF, 0x9F,
|
||||
0xFF, 0xF1, 0xFF, 0xFC, 0x0F, 0xFF, 0x00, 0x7F, 0x80, 0x01, 0x80, 0x00,
|
||||
0x30, 0x00, 0x06, 0x00, 0x0F, 0x00, 0x1C, 0x01, 0xFE, 0x00, 0xE0, 0x1F,
|
||||
0xF8, 0x0E, 0x00, 0xFF, 0xC0, 0x70, 0x0F, 0x0F, 0x07, 0x00, 0x70, 0x38,
|
||||
0x38, 0x03, 0x81, 0xC3, 0x80, 0x1C, 0x0E, 0x3C, 0x00, 0xF0, 0xF1, 0xC0,
|
||||
0x03, 0xFF, 0x1C, 0x00, 0x1F, 0xF8, 0xE0, 0x00, 0x7F, 0x8E, 0x00, 0x00,
|
||||
0xF0, 0x70, 0xF8, 0x00, 0x07, 0x1F, 0xF0, 0x00, 0x39, 0xFF, 0xC0, 0x03,
|
||||
0x8F, 0xFE, 0x00, 0x1C, 0xF0, 0x78, 0x01, 0xC7, 0x01, 0xC0, 0x0C, 0x38,
|
||||
0x0E, 0x00, 0xE1, 0xC0, 0x70, 0x06, 0x0F, 0x07, 0x80, 0x70, 0x3F, 0xF8,
|
||||
0x07, 0x01, 0xFF, 0xC0, 0x38, 0x07, 0xFC, 0x03, 0x80, 0x0F, 0x80, 0x01,
|
||||
0xF0, 0x00, 0x1F, 0xE0, 0x00, 0xFF, 0xC0, 0x03, 0xFF, 0x80, 0x1F, 0x1E,
|
||||
0x00, 0x7C, 0x78, 0x01, 0xF1, 0xE0, 0x07, 0xE7, 0x80, 0x0F, 0xBC, 0x00,
|
||||
0x1F, 0xE0, 0x00, 0x3F, 0x00, 0x01, 0xF8, 0x00, 0x1F, 0xF0, 0xF0, 0xFF,
|
||||
0xE3, 0xC7, 0xE7, 0xCF, 0x3F, 0x0F, 0xF8, 0xF8, 0x3F, 0xE3, 0xE0, 0x7F,
|
||||
0x8F, 0x80, 0xFC, 0x3F, 0x03, 0xF0, 0x7E, 0x3F, 0xE1, 0xFF, 0xFF, 0x83,
|
||||
0xFF, 0xFF, 0x07, 0xFE, 0x7E, 0x07, 0xF0, 0xFC, 0xFF, 0xFF, 0xFF, 0xFD,
|
||||
0xCE, 0x70, 0x07, 0x87, 0x83, 0xC3, 0xC1, 0xE1, 0xE0, 0xF0, 0x78, 0x78,
|
||||
0x3C, 0x1E, 0x1E, 0x0F, 0x07, 0x83, 0xC1, 0xE0, 0xF0, 0x78, 0x3C, 0x1E,
|
||||
0x0F, 0x03, 0x81, 0xE0, 0xF0, 0x78, 0x1E, 0x0F, 0x03, 0x81, 0xE0, 0x70,
|
||||
0x3C, 0x0E, 0x07, 0x80, 0xF0, 0x38, 0x1E, 0x07, 0x83, 0xC0, 0xF0, 0x78,
|
||||
0x3C, 0x0F, 0x07, 0x83, 0xC0, 0xF0, 0x78, 0x3C, 0x1E, 0x0F, 0x07, 0x83,
|
||||
0xC1, 0xE0, 0xF0, 0x78, 0x78, 0x3C, 0x1E, 0x0F, 0x0F, 0x07, 0x87, 0x83,
|
||||
0xC1, 0xC1, 0xE0, 0xE0, 0xF0, 0x00, 0x06, 0x00, 0x60, 0x06, 0x07, 0x6E,
|
||||
0x7F, 0xE3, 0xFC, 0x0F, 0x01, 0xF8, 0x1F, 0x83, 0x9C, 0x10, 0x80, 0x03,
|
||||
0xC0, 0x03, 0xC0, 0x03, 0xC0, 0x03, 0xC0, 0x03, 0xC0, 0x03, 0xC0, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0xC0, 0x03, 0xC0, 0x03,
|
||||
0xC0, 0x03, 0xC0, 0x03, 0xC0, 0x03, 0xC0, 0xFF, 0xFF, 0xFF, 0x8C, 0x63,
|
||||
0x37, 0xB0, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0xFF, 0x80, 0x01,
|
||||
0x81, 0xC0, 0xC0, 0x60, 0x70, 0x38, 0x18, 0x0C, 0x0E, 0x06, 0x03, 0x01,
|
||||
0x81, 0xC0, 0xC0, 0x60, 0x30, 0x38, 0x18, 0x0C, 0x0E, 0x07, 0x03, 0x01,
|
||||
0x81, 0xC0, 0xC0, 0x00, 0x07, 0xF0, 0x0F, 0xFE, 0x0F, 0xFF, 0x87, 0xFF,
|
||||
0xC7, 0xE3, 0xF3, 0xE0, 0xF9, 0xF0, 0x7D, 0xF0, 0x1F, 0xF8, 0x0F, 0xFC,
|
||||
0x07, 0xFE, 0x03, 0xFF, 0x01, 0xFF, 0x80, 0xFF, 0xC0, 0x7F, 0xE0, 0x3F,
|
||||
0xF0, 0x1F, 0xF8, 0x0F, 0xFC, 0x07, 0xDF, 0x07, 0xCF, 0x83, 0xE7, 0xE3,
|
||||
0xF1, 0xFF, 0xF0, 0xFF, 0xF8, 0x3F, 0xF8, 0x07, 0xF0, 0x00, 0x01, 0xC0,
|
||||
0xF0, 0x3C, 0x1F, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0xC1, 0xF0, 0x7C,
|
||||
0x1F, 0x07, 0xC1, 0xF0, 0x7C, 0x1F, 0x07, 0xC1, 0xF0, 0x7C, 0x1F, 0x07,
|
||||
0xC1, 0xF0, 0x7C, 0x1F, 0x07, 0xC0, 0x07, 0xF0, 0x0F, 0xFE, 0x0F, 0xFF,
|
||||
0x8F, 0xFF, 0xE7, 0xE3, 0xF7, 0xE0, 0xFF, 0xE0, 0x3F, 0xF0, 0x1F, 0xF8,
|
||||
0x0F, 0x80, 0x07, 0xC0, 0x07, 0xE0, 0x03, 0xE0, 0x03, 0xF0, 0x03, 0xF0,
|
||||
0x07, 0xF0, 0x07, 0xF0, 0x07, 0xE0, 0x07, 0xE0, 0x07, 0xC0, 0x07, 0xC0,
|
||||
0x03, 0xE0, 0x03, 0xFF, 0xFD, 0xFF, 0xFE, 0xFF, 0xFF, 0x7F, 0xFF, 0x80,
|
||||
0x07, 0xE0, 0x0F, 0xFC, 0x0F, 0xFF, 0x0F, 0xFF, 0xCF, 0xC3, 0xF7, 0xC0,
|
||||
0xFB, 0xE0, 0x7D, 0xF0, 0x3E, 0x00, 0x1F, 0x00, 0x1F, 0x00, 0x0F, 0x80,
|
||||
0x3F, 0x80, 0x1F, 0xC0, 0x0F, 0xF0, 0x00, 0xFC, 0x00, 0x3F, 0x00, 0x0F,
|
||||
0xFC, 0x07, 0xFE, 0x03, 0xFF, 0x83, 0xF7, 0xC3, 0xF3, 0xFF, 0xF8, 0xFF,
|
||||
0xF8, 0x3F, 0xF8, 0x07, 0xF0, 0x00, 0x00, 0xFC, 0x00, 0xFC, 0x01, 0xFC,
|
||||
0x01, 0xFC, 0x03, 0xFC, 0x07, 0x7C, 0x07, 0x7C, 0x0E, 0x7C, 0x0E, 0x7C,
|
||||
0x1C, 0x7C, 0x18, 0x7C, 0x38, 0x7C, 0x70, 0x7C, 0x60, 0x7C, 0xE0, 0x7C,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x7C, 0x00, 0x7C,
|
||||
0x00, 0x7C, 0x00, 0x7C, 0x00, 0x7C, 0x00, 0x7C, 0x1F, 0xFF, 0x0F, 0xFF,
|
||||
0x8F, 0xFF, 0xC7, 0xFF, 0xE3, 0xC0, 0x01, 0xE0, 0x00, 0xE0, 0x00, 0x70,
|
||||
0x00, 0x79, 0xF0, 0x3F, 0xFE, 0x1F, 0xFF, 0x8F, 0xFF, 0xE7, 0xC3, 0xF0,
|
||||
0x00, 0xFC, 0x00, 0x3E, 0x00, 0x1F, 0x00, 0x0F, 0x80, 0x07, 0xFE, 0x03,
|
||||
0xFF, 0x03, 0xFF, 0xC3, 0xF3, 0xFF, 0xF1, 0xFF, 0xF8, 0x3F, 0xF0, 0x07,
|
||||
0xE0, 0x00, 0x03, 0xF8, 0x03, 0xFF, 0x81, 0xFF, 0xF0, 0xFF, 0xFE, 0x3E,
|
||||
0x1F, 0x9F, 0x03, 0xE7, 0xC0, 0x03, 0xE0, 0x00, 0xF8, 0xF8, 0x3E, 0xFF,
|
||||
0x8F, 0xFF, 0xF3, 0xFF, 0xFE, 0xFE, 0x1F, 0xBF, 0x03, 0xFF, 0x80, 0x7F,
|
||||
0xE0, 0x1F, 0xF8, 0x07, 0xFE, 0x01, 0xF7, 0x80, 0x7D, 0xF0, 0x3E, 0x7E,
|
||||
0x1F, 0x8F, 0xFF, 0xC1, 0xFF, 0xF0, 0x3F, 0xF0, 0x03, 0xF0, 0x00, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0xF0, 0x00, 0xF8,
|
||||
0x00, 0xF8, 0x00, 0x78, 0x00, 0x7C, 0x00, 0x3C, 0x00, 0x3E, 0x00, 0x1E,
|
||||
0x00, 0x1F, 0x00, 0x0F, 0x00, 0x0F, 0x80, 0x07, 0xC0, 0x03, 0xC0, 0x03,
|
||||
0xE0, 0x01, 0xF0, 0x00, 0xF8, 0x00, 0x78, 0x00, 0x7C, 0x00, 0x3E, 0x00,
|
||||
0x1F, 0x00, 0x0F, 0x80, 0x00, 0x07, 0xE0, 0x07, 0xFC, 0x0F, 0xFF, 0x07,
|
||||
0xFF, 0xC7, 0xC3, 0xF3, 0xC0, 0xF9, 0xE0, 0x3C, 0xF0, 0x1E, 0x78, 0x1F,
|
||||
0x1E, 0x1F, 0x07, 0xFF, 0x01, 0xFF, 0x03, 0xFF, 0xE3, 0xF1, 0xF9, 0xF0,
|
||||
0x7D, 0xF0, 0x1F, 0xF8, 0x0F, 0xFC, 0x07, 0xFE, 0x03, 0xFF, 0x83, 0xF7,
|
||||
0xC3, 0xF3, 0xFF, 0xF8, 0xFF, 0xF8, 0x3F, 0xF8, 0x07, 0xF0, 0x00, 0x07,
|
||||
0xE0, 0x0F, 0xFC, 0x0F, 0xFF, 0x0F, 0xFF, 0xC7, 0xE3, 0xF7, 0xE0, 0xFB,
|
||||
0xE0, 0x3D, 0xF0, 0x1F, 0xF8, 0x0F, 0xFC, 0x07, 0xFE, 0x03, 0xFF, 0x83,
|
||||
0xF7, 0xE3, 0xFB, 0xFF, 0xFC, 0xFF, 0xFE, 0x3F, 0xDF, 0x07, 0xCF, 0x80,
|
||||
0x07, 0x80, 0x03, 0xDF, 0x03, 0xE7, 0xC3, 0xE3, 0xFF, 0xF0, 0xFF, 0xF0,
|
||||
0x3F, 0xF0, 0x07, 0xE0, 0x00, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00,
|
||||
0x00, 0x7F, 0xFF, 0xFF, 0xC0, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00,
|
||||
0x00, 0x7F, 0xFF, 0xFF, 0xC6, 0x33, 0x9B, 0xD8, 0x00, 0x00, 0xC0, 0x00,
|
||||
0xF0, 0x01, 0xFC, 0x03, 0xFF, 0x03, 0xFF, 0x07, 0xFE, 0x0F, 0xFC, 0x03,
|
||||
0xF8, 0x00, 0xF0, 0x00, 0x3F, 0x80, 0x0F, 0xFC, 0x00, 0x7F, 0xE0, 0x07,
|
||||
0xFF, 0x00, 0x3F, 0xF0, 0x01, 0xFC, 0x00, 0x1F, 0x00, 0x00, 0xC0, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xF0, 0xC0, 0x00, 0x3C, 0x00, 0x0F, 0xE0, 0x03, 0xFF, 0x00, 0x3F, 0xF0,
|
||||
0x01, 0xFF, 0x80, 0x0F, 0xFC, 0x00, 0x7F, 0x00, 0x03, 0xC0, 0x07, 0xF0,
|
||||
0x0F, 0xFC, 0x1F, 0xF8, 0x3F, 0xF8, 0x3F, 0xF0, 0x0F, 0xE0, 0x03, 0xC0,
|
||||
0x00, 0xC0, 0x00, 0x00, 0x07, 0xF0, 0x07, 0xFF, 0x03, 0xFF, 0xF1, 0xFF,
|
||||
0xFC, 0x7E, 0x3F, 0xBF, 0x03, 0xFF, 0x80, 0x7F, 0xE0, 0x1F, 0xF8, 0x07,
|
||||
0xC0, 0x03, 0xF0, 0x01, 0xFC, 0x00, 0xFE, 0x00, 0x7F, 0x00, 0x3F, 0x80,
|
||||
0x1F, 0xC0, 0x07, 0xC0, 0x03, 0xE0, 0x00, 0xF0, 0x00, 0x3C, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x3E, 0x00, 0x0F, 0x80, 0x03, 0xE0,
|
||||
0x00, 0xF8, 0x00, 0x00, 0x07, 0xFC, 0x00, 0x00, 0x3F, 0xFF, 0x00, 0x00,
|
||||
0xFF, 0xFF, 0xC0, 0x01, 0xF8, 0x07, 0xF0, 0x03, 0xE0, 0x01, 0xF8, 0x07,
|
||||
0x80, 0x00, 0x7C, 0x0F, 0x00, 0x00, 0x3C, 0x1E, 0x03, 0xE3, 0x9E, 0x3C,
|
||||
0x0F, 0xF7, 0x8E, 0x38, 0x1F, 0xFF, 0x0E, 0x78, 0x3E, 0x1F, 0x07, 0x70,
|
||||
0x38, 0x0F, 0x07, 0x70, 0x78, 0x0F, 0x07, 0xE0, 0x70, 0x0E, 0x07, 0xE0,
|
||||
0x70, 0x0E, 0x07, 0xE0, 0xE0, 0x0E, 0x07, 0xE0, 0xE0, 0x1E, 0x0F, 0xE0,
|
||||
0xE0, 0x1C, 0x0E, 0xE0, 0xE0, 0x3C, 0x1E, 0xE0, 0xF0, 0x3C, 0x3C, 0xF0,
|
||||
0xF0, 0xFC, 0x7C, 0x70, 0x7F, 0xFF, 0xF8, 0x78, 0x3F, 0xCF, 0xF0, 0x3C,
|
||||
0x1F, 0x07, 0xC0, 0x3E, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x0F,
|
||||
0xC0, 0x01, 0x00, 0x07, 0xF0, 0x0F, 0x00, 0x03, 0xFF, 0xFF, 0x00, 0x00,
|
||||
0xFF, 0xFF, 0x00, 0x00, 0x1F, 0xF8, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x7F,
|
||||
0x00, 0x00, 0x7F, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x80, 0x01, 0xFF,
|
||||
0x80, 0x01, 0xFF, 0x80, 0x01, 0xF7, 0xC0, 0x03, 0xE7, 0xC0, 0x03, 0xE7,
|
||||
0xC0, 0x03, 0xE3, 0xE0, 0x07, 0xC3, 0xE0, 0x07, 0xC3, 0xE0, 0x07, 0xC1,
|
||||
0xF0, 0x0F, 0x81, 0xF0, 0x0F, 0x81, 0xF0, 0x0F, 0xFF, 0xF8, 0x1F, 0xFF,
|
||||
0xF8, 0x1F, 0xFF, 0xFC, 0x1F, 0xFF, 0xFC, 0x3E, 0x00, 0x7C, 0x3E, 0x00,
|
||||
0x7E, 0x3E, 0x00, 0x3E, 0x7C, 0x00, 0x3E, 0x7C, 0x00, 0x3F, 0x7C, 0x00,
|
||||
0x1F, 0xFF, 0xFC, 0x0F, 0xFF, 0xF0, 0xFF, 0xFF, 0x8F, 0xFF, 0xFC, 0xF8,
|
||||
0x07, 0xEF, 0x80, 0x3E, 0xF8, 0x03, 0xEF, 0x80, 0x3E, 0xF8, 0x03, 0xEF,
|
||||
0x80, 0x3E, 0xF8, 0x07, 0xCF, 0xFF, 0xF8, 0xFF, 0xFF, 0x0F, 0xFF, 0xF8,
|
||||
0xFF, 0xFF, 0xCF, 0x80, 0x7E, 0xF8, 0x01, 0xEF, 0x80, 0x1F, 0xF8, 0x01,
|
||||
0xFF, 0x80, 0x1F, 0xF8, 0x01, 0xFF, 0x80, 0x3E, 0xFF, 0xFF, 0xEF, 0xFF,
|
||||
0xFC, 0xFF, 0xFF, 0x8F, 0xFF, 0xE0, 0x00, 0xFF, 0x00, 0x07, 0xFF, 0x80,
|
||||
0x3F, 0xFF, 0xC0, 0xFF, 0xFF, 0xC3, 0xF8, 0x1F, 0x87, 0xE0, 0x1F, 0x9F,
|
||||
0x80, 0x1F, 0x3E, 0x00, 0x1F, 0x7C, 0x00, 0x3F, 0xF0, 0x00, 0x03, 0xE0,
|
||||
0x00, 0x07, 0xC0, 0x00, 0x0F, 0x80, 0x00, 0x1F, 0x00, 0x00, 0x3E, 0x00,
|
||||
0x00, 0x7C, 0x00, 0x00, 0xF8, 0x00, 0x00, 0xF8, 0x00, 0x7D, 0xF0, 0x00,
|
||||
0xFB, 0xF0, 0x03, 0xF3, 0xF0, 0x0F, 0xC7, 0xF0, 0x3F, 0x87, 0xFF, 0xFE,
|
||||
0x07, 0xFF, 0xF8, 0x03, 0xFF, 0xC0, 0x01, 0xFE, 0x00, 0xFF, 0xFC, 0x07,
|
||||
0xFF, 0xF8, 0x3F, 0xFF, 0xE1, 0xFF, 0xFF, 0x8F, 0x80, 0xFE, 0x7C, 0x01,
|
||||
0xF3, 0xE0, 0x07, 0xDF, 0x00, 0x3E, 0xF8, 0x01, 0xF7, 0xC0, 0x07, 0xFE,
|
||||
0x00, 0x3F, 0xF0, 0x01, 0xFF, 0x80, 0x0F, 0xFC, 0x00, 0x7F, 0xE0, 0x03,
|
||||
0xFF, 0x00, 0x1F, 0xF8, 0x00, 0xFF, 0xC0, 0x0F, 0xFE, 0x00, 0x7D, 0xF0,
|
||||
0x03, 0xEF, 0x80, 0x3E, 0x7C, 0x07, 0xF3, 0xFF, 0xFF, 0x1F, 0xFF, 0xF0,
|
||||
0xFF, 0xFF, 0x07, 0xFF, 0xE0, 0x00, 0xFF, 0xFF, 0xDF, 0xFF, 0xFB, 0xFF,
|
||||
0xFF, 0x7F, 0xFF, 0xEF, 0x80, 0x01, 0xF0, 0x00, 0x3E, 0x00, 0x07, 0xC0,
|
||||
0x00, 0xF8, 0x00, 0x1F, 0x00, 0x03, 0xE0, 0x00, 0x7F, 0xFF, 0xCF, 0xFF,
|
||||
0xF9, 0xFF, 0xFF, 0x3F, 0xFF, 0xE7, 0xC0, 0x00, 0xF8, 0x00, 0x1F, 0x00,
|
||||
0x03, 0xE0, 0x00, 0x7C, 0x00, 0x0F, 0x80, 0x01, 0xF0, 0x00, 0x3F, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x07, 0xC0, 0x03, 0xE0, 0x01, 0xF0,
|
||||
0x00, 0xF8, 0x00, 0x7C, 0x00, 0x3E, 0x00, 0x1F, 0xFF, 0xEF, 0xFF, 0xF7,
|
||||
0xFF, 0xFB, 0xFF, 0xFD, 0xF0, 0x00, 0xF8, 0x00, 0x7C, 0x00, 0x3E, 0x00,
|
||||
0x1F, 0x00, 0x0F, 0x80, 0x07, 0xC0, 0x03, 0xE0, 0x01, 0xF0, 0x00, 0xF8,
|
||||
0x00, 0x7C, 0x00, 0x00, 0x00, 0x7F, 0x80, 0x03, 0xFF, 0xE0, 0x07, 0xFF,
|
||||
0xF8, 0x0F, 0xFF, 0xFC, 0x1F, 0xC0, 0xFE, 0x3F, 0x00, 0x7E, 0x7E, 0x00,
|
||||
0x3F, 0x7C, 0x00, 0x1F, 0x7C, 0x00, 0x00, 0xF8, 0x00, 0x00, 0xF8, 0x00,
|
||||
0x00, 0xF8, 0x00, 0x00, 0xF8, 0x03, 0xFF, 0xF8, 0x03, 0xFF, 0xF8, 0x03,
|
||||
0xFF, 0xF8, 0x03, 0xFF, 0xFC, 0x00, 0x0F, 0x7C, 0x00, 0x1F, 0x7C, 0x00,
|
||||
0x1F, 0x7E, 0x00, 0x3F, 0x3F, 0x00, 0x7F, 0x1F, 0xC1, 0xFF, 0x0F, 0xFF,
|
||||
0xFF, 0x07, 0xFF, 0xE7, 0x03, 0xFF, 0xC7, 0x00, 0xFF, 0x07, 0xF8, 0x01,
|
||||
0xFF, 0x80, 0x1F, 0xF8, 0x01, 0xFF, 0x80, 0x1F, 0xF8, 0x01, 0xFF, 0x80,
|
||||
0x1F, 0xF8, 0x01, 0xFF, 0x80, 0x1F, 0xF8, 0x01, 0xFF, 0x80, 0x1F, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x01, 0xFF,
|
||||
0x80, 0x1F, 0xF8, 0x01, 0xFF, 0x80, 0x1F, 0xF8, 0x01, 0xFF, 0x80, 0x1F,
|
||||
0xF8, 0x01, 0xFF, 0x80, 0x1F, 0xF8, 0x01, 0xFF, 0x80, 0x1F, 0xF8, 0x01,
|
||||
0xFF, 0x80, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x1F, 0x00, 0x1F,
|
||||
0x00, 0x1F, 0x00, 0x1F, 0x00, 0x1F, 0x00, 0x1F, 0x00, 0x1F, 0x00, 0x1F,
|
||||
0x00, 0x1F, 0x00, 0x1F, 0x00, 0x1F, 0x00, 0x1F, 0x00, 0x1F, 0x00, 0x1F,
|
||||
0x00, 0x1F, 0x00, 0x1F, 0xF8, 0x1F, 0xF8, 0x1F, 0xF8, 0x1F, 0xF8, 0x1F,
|
||||
0xF8, 0x1F, 0xFC, 0x3F, 0x7F, 0xFE, 0x3F, 0xFC, 0x1F, 0xF8, 0x07, 0xE0,
|
||||
0xF8, 0x01, 0xFB, 0xE0, 0x0F, 0xCF, 0x80, 0x7E, 0x3E, 0x03, 0xF0, 0xF8,
|
||||
0x1F, 0x83, 0xE0, 0xFC, 0x0F, 0x87, 0xE0, 0x3E, 0x3F, 0x00, 0xF8, 0xF8,
|
||||
0x03, 0xE7, 0xE0, 0x0F, 0xBF, 0x00, 0x3F, 0xF8, 0x00, 0xFF, 0xF0, 0x03,
|
||||
0xFF, 0xE0, 0x0F, 0xFF, 0x80, 0x3F, 0xBF, 0x00, 0xFC, 0x7E, 0x03, 0xE0,
|
||||
0xFC, 0x0F, 0x81, 0xF8, 0x3E, 0x07, 0xE0, 0xF8, 0x0F, 0xC3, 0xE0, 0x1F,
|
||||
0x8F, 0x80, 0x7F, 0x3E, 0x00, 0xFC, 0xF8, 0x01, 0xFB, 0xE0, 0x03, 0xF0,
|
||||
0xF8, 0x00, 0x7C, 0x00, 0x3E, 0x00, 0x1F, 0x00, 0x0F, 0x80, 0x07, 0xC0,
|
||||
0x03, 0xE0, 0x01, 0xF0, 0x00, 0xF8, 0x00, 0x7C, 0x00, 0x3E, 0x00, 0x1F,
|
||||
0x00, 0x0F, 0x80, 0x07, 0xC0, 0x03, 0xE0, 0x01, 0xF0, 0x00, 0xF8, 0x00,
|
||||
0x7C, 0x00, 0x3E, 0x00, 0x1F, 0x00, 0x0F, 0x80, 0x07, 0xC0, 0x03, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0xFF, 0x00, 0xFF, 0xFF,
|
||||
0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x01, 0xFF, 0xFF, 0x81, 0xFF, 0xFF,
|
||||
0x81, 0xFF, 0xFF, 0x81, 0xFF, 0xFF, 0x81, 0xFF, 0xFB, 0xC3, 0xDF, 0xFB,
|
||||
0xC3, 0xDF, 0xFB, 0xC3, 0xDF, 0xFB, 0xC3, 0xDF, 0xF9, 0xC7, 0xDF, 0xF9,
|
||||
0xE7, 0x9F, 0xF9, 0xE7, 0x9F, 0xF9, 0xE7, 0x9F, 0xF9, 0xE7, 0x9F, 0xF8,
|
||||
0xFF, 0x1F, 0xF8, 0xFF, 0x1F, 0xF8, 0xFF, 0x1F, 0xF8, 0xFF, 0x1F, 0xF8,
|
||||
0x7F, 0x1F, 0xF8, 0x7E, 0x1F, 0xF8, 0x7E, 0x1F, 0xF8, 0x7E, 0x1F, 0xF8,
|
||||
0x3E, 0x1F, 0xF8, 0x01, 0xFF, 0xC0, 0x1F, 0xFE, 0x01, 0xFF, 0xE0, 0x1F,
|
||||
0xFF, 0x01, 0xFF, 0xF0, 0x1F, 0xFF, 0x81, 0xFF, 0xF8, 0x1F, 0xFF, 0xC1,
|
||||
0xFF, 0xBC, 0x1F, 0xFB, 0xE1, 0xFF, 0x9F, 0x1F, 0xF9, 0xF1, 0xFF, 0x8F,
|
||||
0x9F, 0xF8, 0x79, 0xFF, 0x87, 0xDF, 0xF8, 0x3D, 0xFF, 0x83, 0xFF, 0xF8,
|
||||
0x1F, 0xFF, 0x81, 0xFF, 0xF8, 0x0F, 0xFF, 0x80, 0xFF, 0xF8, 0x07, 0xFF,
|
||||
0x80, 0x3F, 0xF8, 0x03, 0xFF, 0x80, 0x1F, 0x00, 0x7F, 0x00, 0x01, 0xFF,
|
||||
0xF0, 0x01, 0xFF, 0xFC, 0x03, 0xFF, 0xFF, 0x01, 0xFC, 0x1F, 0xC1, 0xF8,
|
||||
0x03, 0xF1, 0xF8, 0x00, 0xFC, 0xF8, 0x00, 0x3E, 0x7C, 0x00, 0x1F, 0x7C,
|
||||
0x00, 0x07, 0xFE, 0x00, 0x03, 0xFF, 0x00, 0x01, 0xFF, 0x80, 0x00, 0xFF,
|
||||
0xC0, 0x00, 0x7F, 0xE0, 0x00, 0x3F, 0xF0, 0x00, 0x1F, 0xF8, 0x00, 0x0F,
|
||||
0xBE, 0x00, 0x0F, 0x9F, 0x00, 0x07, 0xCF, 0xC0, 0x07, 0xE3, 0xF0, 0x07,
|
||||
0xE0, 0xFE, 0x0F, 0xE0, 0x7F, 0xFF, 0xE0, 0x0F, 0xFF, 0xE0, 0x03, 0xFF,
|
||||
0xE0, 0x00, 0x3F, 0x80, 0x00, 0xFF, 0xFC, 0x1F, 0xFF, 0xE3, 0xFF, 0xFE,
|
||||
0x7F, 0xFF, 0xEF, 0x80, 0xFF, 0xF0, 0x0F, 0xFE, 0x00, 0xFF, 0xC0, 0x1F,
|
||||
0xF8, 0x03, 0xFF, 0x00, 0x7F, 0xE0, 0x1F, 0xFC, 0x07, 0xEF, 0xFF, 0xFD,
|
||||
0xFF, 0xFF, 0x3F, 0xFF, 0xC7, 0xFF, 0xE0, 0xF8, 0x00, 0x1F, 0x00, 0x03,
|
||||
0xE0, 0x00, 0x7C, 0x00, 0x0F, 0x80, 0x01, 0xF0, 0x00, 0x3E, 0x00, 0x07,
|
||||
0xC0, 0x00, 0xF8, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x7F, 0x00, 0x01, 0xFF,
|
||||
0xF0, 0x01, 0xFF, 0xFC, 0x03, 0xFF, 0xFF, 0x01, 0xFC, 0x1F, 0xC1, 0xF8,
|
||||
0x03, 0xF1, 0xF8, 0x00, 0xFC, 0xF8, 0x00, 0x3E, 0x7C, 0x00, 0x1F, 0x7C,
|
||||
0x00, 0x07, 0xFE, 0x00, 0x03, 0xFF, 0x00, 0x01, 0xFF, 0x80, 0x00, 0xFF,
|
||||
0xC0, 0x00, 0x7F, 0xE0, 0x00, 0x3F, 0xF0, 0x00, 0x1F, 0xF8, 0x01, 0x0F,
|
||||
0xBE, 0x01, 0xCF, 0x9F, 0x01, 0xFF, 0xCF, 0xC0, 0x7F, 0xE3, 0xF0, 0x1F,
|
||||
0xE0, 0xFE, 0x0F, 0xF0, 0x7F, 0xFF, 0xF8, 0x0F, 0xFF, 0xFE, 0x03, 0xFF,
|
||||
0xEF, 0x80, 0x3F, 0xC3, 0x80, 0x00, 0x00, 0x80, 0xFF, 0xFF, 0x07, 0xFF,
|
||||
0xFE, 0x3F, 0xFF, 0xF9, 0xFF, 0xFF, 0xCF, 0x80, 0x3F, 0x7C, 0x00, 0xFB,
|
||||
0xE0, 0x07, 0xDF, 0x00, 0x3E, 0xF8, 0x01, 0xF7, 0xC0, 0x0F, 0x3E, 0x00,
|
||||
0xF9, 0xFF, 0xFF, 0x8F, 0xFF, 0xF8, 0x7F, 0xFF, 0xC3, 0xFF, 0xFF, 0x1F,
|
||||
0x00, 0xFC, 0xF8, 0x03, 0xE7, 0xC0, 0x1F, 0x3E, 0x00, 0xF9, 0xF0, 0x07,
|
||||
0xCF, 0x80, 0x3E, 0x7C, 0x01, 0xF3, 0xE0, 0x0F, 0x9F, 0x00, 0x7C, 0xF8,
|
||||
0x03, 0xF7, 0xC0, 0x0F, 0xC0, 0x07, 0xF8, 0x01, 0xFF, 0xF0, 0x3F, 0xFF,
|
||||
0x87, 0xFF, 0xFC, 0x7E, 0x0F, 0xCF, 0xC0, 0x7E, 0xF8, 0x03, 0xEF, 0x80,
|
||||
0x3E, 0xF8, 0x00, 0x0F, 0xC0, 0x00, 0xFF, 0x00, 0x07, 0xFF, 0xC0, 0x3F,
|
||||
0xFF, 0x81, 0xFF, 0xFC, 0x03, 0xFF, 0xE0, 0x01, 0xFF, 0x00, 0x03, 0xF0,
|
||||
0x00, 0x1F, 0xF8, 0x01, 0xFF, 0x80, 0x1F, 0xFC, 0x03, 0xFF, 0xE0, 0x7E,
|
||||
0x7F, 0xFF, 0xE3, 0xFF, 0xFC, 0x1F, 0xFF, 0x00, 0x3F, 0xC0, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x1F, 0x00, 0x03, 0xE0,
|
||||
0x00, 0x7C, 0x00, 0x0F, 0x80, 0x01, 0xF0, 0x00, 0x3E, 0x00, 0x07, 0xC0,
|
||||
0x00, 0xF8, 0x00, 0x1F, 0x00, 0x03, 0xE0, 0x00, 0x7C, 0x00, 0x0F, 0x80,
|
||||
0x01, 0xF0, 0x00, 0x3E, 0x00, 0x07, 0xC0, 0x00, 0xF8, 0x00, 0x1F, 0x00,
|
||||
0x03, 0xE0, 0x00, 0x7C, 0x00, 0x0F, 0x80, 0x01, 0xF0, 0x00, 0x3E, 0x00,
|
||||
0xF8, 0x01, 0xFF, 0x80, 0x1F, 0xF8, 0x01, 0xFF, 0x80, 0x1F, 0xF8, 0x01,
|
||||
0xFF, 0x80, 0x1F, 0xF8, 0x01, 0xFF, 0x80, 0x1F, 0xF8, 0x01, 0xFF, 0x80,
|
||||
0x1F, 0xF8, 0x01, 0xFF, 0x80, 0x1F, 0xF8, 0x01, 0xFF, 0x80, 0x1F, 0xF8,
|
||||
0x01, 0xFF, 0x80, 0x1F, 0xF8, 0x01, 0xFF, 0x80, 0x1F, 0xF8, 0x01, 0xFF,
|
||||
0x80, 0x1F, 0x7C, 0x03, 0xE7, 0xE0, 0x7E, 0x3F, 0xFF, 0xC3, 0xFF, 0xFC,
|
||||
0x0F, 0xFF, 0x00, 0x3F, 0xC0, 0xF8, 0x00, 0xFB, 0xE0, 0x03, 0xE7, 0xC0,
|
||||
0x1F, 0x9F, 0x00, 0x7C, 0x7C, 0x01, 0xF0, 0xF8, 0x07, 0xC3, 0xE0, 0x3E,
|
||||
0x0F, 0x80, 0xF8, 0x1E, 0x03, 0xE0, 0x7C, 0x1F, 0x01, 0xF0, 0x7C, 0x03,
|
||||
0xC1, 0xF0, 0x0F, 0x87, 0x80, 0x3E, 0x3E, 0x00, 0xF8, 0xF8, 0x01, 0xE3,
|
||||
0xC0, 0x07, 0xCF, 0x00, 0x1F, 0x7C, 0x00, 0x3D, 0xE0, 0x00, 0xFF, 0x80,
|
||||
0x03, 0xFE, 0x00, 0x07, 0xF0, 0x00, 0x1F, 0xC0, 0x00, 0x7F, 0x00, 0x00,
|
||||
0xF8, 0x00, 0x03, 0xE0, 0x00, 0xF8, 0x07, 0xC0, 0x3F, 0xF8, 0x07, 0xE0,
|
||||
0x3E, 0xFC, 0x07, 0xE0, 0x3E, 0x7C, 0x0F, 0xE0, 0x3E, 0x7C, 0x0F, 0xE0,
|
||||
0x7E, 0x7C, 0x0F, 0xE0, 0x7C, 0x7C, 0x0F, 0xF0, 0x7C, 0x3E, 0x0F, 0xF0,
|
||||
0x7C, 0x3E, 0x1E, 0xF0, 0x78, 0x3E, 0x1E, 0x70, 0xF8, 0x1E, 0x1E, 0x70,
|
||||
0xF8, 0x1E, 0x1E, 0x78, 0xF8, 0x1F, 0x1E, 0x78, 0xF0, 0x1F, 0x3C, 0x78,
|
||||
0xF0, 0x0F, 0x3C, 0x39, 0xF0, 0x0F, 0x3C, 0x3D, 0xF0, 0x0F, 0x3C, 0x3D,
|
||||
0xE0, 0x0F, 0xBC, 0x3D, 0xE0, 0x07, 0xF8, 0x3D, 0xE0, 0x07, 0xF8, 0x1F,
|
||||
0xE0, 0x07, 0xF8, 0x1F, 0xC0, 0x03, 0xF8, 0x1F, 0xC0, 0x03, 0xF8, 0x1F,
|
||||
0xC0, 0x03, 0xF0, 0x0F, 0x80, 0x03, 0xF0, 0x0F, 0x80, 0x01, 0xF0, 0x0F,
|
||||
0x80, 0xFE, 0x01, 0xF9, 0xF8, 0x07, 0xE3, 0xF0, 0x3F, 0x0F, 0xC0, 0xF8,
|
||||
0x1F, 0x87, 0xE0, 0x7E, 0x3F, 0x00, 0xFC, 0xFC, 0x01, 0xF7, 0xE0, 0x07,
|
||||
0xFF, 0x00, 0x0F, 0xFC, 0x00, 0x3F, 0xE0, 0x00, 0x7F, 0x00, 0x00, 0xFC,
|
||||
0x00, 0x07, 0xF0, 0x00, 0x1F, 0xE0, 0x00, 0xFF, 0x80, 0x03, 0xFF, 0x00,
|
||||
0x1F, 0x7E, 0x00, 0xFC, 0xF8, 0x03, 0xE3, 0xF0, 0x1F, 0x87, 0xC0, 0x7C,
|
||||
0x1F, 0x83, 0xF0, 0x3F, 0x1F, 0x80, 0xFC, 0x7E, 0x01, 0xFB, 0xF0, 0x07,
|
||||
0xF0, 0xFC, 0x01, 0xFF, 0xE0, 0x0F, 0x9F, 0x00, 0xFC, 0xFC, 0x07, 0xC3,
|
||||
0xE0, 0x7E, 0x1F, 0x83, 0xE0, 0x7C, 0x1F, 0x03, 0xF1, 0xF0, 0x0F, 0x8F,
|
||||
0x80, 0x7E, 0xF8, 0x01, 0xF7, 0xC0, 0x0F, 0xFC, 0x00, 0x3F, 0xE0, 0x00,
|
||||
0xFE, 0x00, 0x07, 0xF0, 0x00, 0x1F, 0x00, 0x00, 0xF8, 0x00, 0x07, 0xC0,
|
||||
0x00, 0x3E, 0x00, 0x01, 0xF0, 0x00, 0x0F, 0x80, 0x00, 0x7C, 0x00, 0x03,
|
||||
0xE0, 0x00, 0x1F, 0x00, 0x00, 0xF8, 0x00, 0x07, 0xC0, 0x00, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x7E, 0x00, 0x1F,
|
||||
0x80, 0x07, 0xE0, 0x00, 0xFC, 0x00, 0x3F, 0x00, 0x0F, 0xC0, 0x03, 0xF8,
|
||||
0x00, 0x7E, 0x00, 0x1F, 0x80, 0x07, 0xE0, 0x01, 0xFC, 0x00, 0x3F, 0x00,
|
||||
0x0F, 0xC0, 0x03, 0xF0, 0x00, 0x7E, 0x00, 0x1F, 0x80, 0x07, 0xE0, 0x01,
|
||||
0xFC, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8,
|
||||
0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8,
|
||||
0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x38, 0x06,
|
||||
0x01, 0x80, 0x70, 0x0C, 0x03, 0x00, 0xE0, 0x18, 0x06, 0x01, 0xC0, 0x30,
|
||||
0x0C, 0x03, 0x00, 0xE0, 0x18, 0x06, 0x01, 0xC0, 0x30, 0x0C, 0x03, 0x80,
|
||||
0x60, 0x18, 0x07, 0x01, 0xC0, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0x1F, 0x1F,
|
||||
0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F,
|
||||
0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0x03, 0xE0, 0x07, 0xE0, 0x07, 0xE0, 0x0F, 0xF0, 0x0F, 0xF0,
|
||||
0x0F, 0x78, 0x1E, 0x78, 0x1E, 0x78, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x1E,
|
||||
0x78, 0x1E, 0x78, 0x1E, 0x70, 0x0F, 0xF0, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFE, 0xF8, 0xF0, 0xF0, 0xE0, 0xE0, 0x07, 0xF8, 0x07,
|
||||
0xFF, 0x83, 0xFF, 0xF1, 0xFF, 0xFE, 0x7C, 0x1F, 0xBE, 0x03, 0xE0, 0x00,
|
||||
0xF8, 0x01, 0xFE, 0x0F, 0xFF, 0x8F, 0xFF, 0xE7, 0xF8, 0xFB, 0xF0, 0x3E,
|
||||
0xF8, 0x0F, 0xBE, 0x07, 0xEF, 0xC3, 0xFB, 0xFF, 0xFE, 0x7F, 0xFF, 0x8F,
|
||||
0xFB, 0xF1, 0xF8, 0xFC, 0xF8, 0x00, 0x3E, 0x00, 0x0F, 0x80, 0x03, 0xE0,
|
||||
0x00, 0xF8, 0x00, 0x3E, 0x00, 0x0F, 0x80, 0x03, 0xE7, 0xE0, 0xFB, 0xFC,
|
||||
0x3F, 0xFF, 0xCF, 0xFF, 0xF3, 0xF8, 0x7E, 0xFC, 0x0F, 0xBF, 0x03, 0xFF,
|
||||
0x80, 0x7F, 0xE0, 0x1F, 0xF8, 0x07, 0xFE, 0x01, 0xFF, 0x80, 0x7F, 0xF0,
|
||||
0x3F, 0xFC, 0x0F, 0xBF, 0x87, 0xEF, 0xFF, 0xF3, 0xFF, 0xFC, 0xFB, 0xFC,
|
||||
0x3E, 0x7E, 0x00, 0x03, 0xF0, 0x07, 0xFE, 0x0F, 0xFF, 0x87, 0xFF, 0xE7,
|
||||
0xE1, 0xFB, 0xE0, 0x7F, 0xE0, 0x3F, 0xF0, 0x00, 0xF8, 0x00, 0x7C, 0x00,
|
||||
0x3E, 0x00, 0x1F, 0x00, 0x0F, 0x80, 0xFB, 0xE0, 0x7D, 0xF8, 0x7E, 0x7F,
|
||||
0xFE, 0x3F, 0xFE, 0x0F, 0xFE, 0x00, 0xFC, 0x00, 0x00, 0x03, 0xE0, 0x00,
|
||||
0x7C, 0x00, 0x0F, 0x80, 0x01, 0xF0, 0x00, 0x3E, 0x00, 0x07, 0xC0, 0x00,
|
||||
0xF8, 0x1F, 0x1F, 0x0F, 0xFB, 0xE3, 0xFF, 0xFC, 0xFF, 0xFF, 0xBF, 0x8F,
|
||||
0xF7, 0xC0, 0x7F, 0xF8, 0x0F, 0xFE, 0x00, 0xFF, 0xC0, 0x1F, 0xF8, 0x03,
|
||||
0xFF, 0x00, 0x7F, 0xE0, 0x0F, 0xFE, 0x03, 0xF7, 0xC0, 0x7E, 0xFC, 0x3F,
|
||||
0xCF, 0xFF, 0xF8, 0xFF, 0xFF, 0x0F, 0xFB, 0xE0, 0xFC, 0x7C, 0x07, 0xE0,
|
||||
0x07, 0xFE, 0x03, 0xFF, 0xE0, 0xFF, 0xF8, 0x7E, 0x1F, 0x1F, 0x03, 0xCF,
|
||||
0x80, 0xFB, 0xE0, 0x1E, 0xFF, 0xFF, 0xBF, 0xFF, 0xEF, 0xFF, 0xFB, 0xE0,
|
||||
0x00, 0xF8, 0x00, 0x3F, 0x03, 0xE7, 0xE1, 0xF9, 0xFF, 0xFC, 0x3F, 0xFE,
|
||||
0x07, 0xFF, 0x00, 0x7F, 0x00, 0x0F, 0xC7, 0xF3, 0xFC, 0xFF, 0x3E, 0x0F,
|
||||
0x83, 0xE3, 0xFE, 0xFF, 0xBF, 0xE3, 0xE0, 0xF8, 0x3E, 0x0F, 0x83, 0xE0,
|
||||
0xF8, 0x3E, 0x0F, 0x83, 0xE0, 0xF8, 0x3E, 0x0F, 0x83, 0xE0, 0xF8, 0x3E,
|
||||
0x0F, 0x80, 0x07, 0xC7, 0xC3, 0xFD, 0xF3, 0xFF, 0xFC, 0xFF, 0xFF, 0x7E,
|
||||
0x1F, 0xDF, 0x03, 0xFF, 0xC0, 0xFF, 0xE0, 0x1F, 0xF8, 0x07, 0xFE, 0x01,
|
||||
0xFF, 0x80, 0x7F, 0xE0, 0x1F, 0xFC, 0x0F, 0xDF, 0x03, 0xF7, 0xE1, 0xFD,
|
||||
0xFF, 0xFF, 0x3F, 0xFF, 0xC7, 0xFD, 0xF0, 0x7C, 0x7C, 0x00, 0x1F, 0x00,
|
||||
0x07, 0xFF, 0x03, 0xF7, 0xE1, 0xF9, 0xFF, 0xFC, 0x3F, 0xFE, 0x01, 0xFE,
|
||||
0x00, 0xF8, 0x00, 0x7C, 0x00, 0x3E, 0x00, 0x1F, 0x00, 0x0F, 0x80, 0x07,
|
||||
0xC0, 0x03, 0xE0, 0x01, 0xF1, 0xF0, 0xFB, 0xFE, 0x7F, 0xFF, 0xBF, 0xFF,
|
||||
0xDF, 0xC3, 0xFF, 0xC0, 0xFF, 0xC0, 0x7F, 0xE0, 0x3F, 0xF0, 0x1F, 0xF8,
|
||||
0x0F, 0xFC, 0x07, 0xFE, 0x03, 0xFF, 0x01, 0xFF, 0x80, 0xFF, 0xC0, 0x7F,
|
||||
0xE0, 0x3F, 0xF0, 0x1F, 0xF8, 0x0F, 0xFC, 0x07, 0xC0, 0xFF, 0xFF, 0xF0,
|
||||
0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xC0, 0x3E, 0x7C, 0xF9, 0xF0, 0x00, 0x00, 0x1F, 0x3E, 0x7C, 0xF9,
|
||||
0xF3, 0xE7, 0xCF, 0x9F, 0x3E, 0x7C, 0xF9, 0xF3, 0xE7, 0xCF, 0x9F, 0x3E,
|
||||
0x7C, 0xF9, 0xF3, 0xFF, 0xFF, 0xFE, 0xF8, 0xF8, 0x00, 0x7C, 0x00, 0x3E,
|
||||
0x00, 0x1F, 0x00, 0x0F, 0x80, 0x07, 0xC0, 0x03, 0xE0, 0x01, 0xF0, 0x3E,
|
||||
0xF8, 0x3E, 0x7C, 0x3F, 0x3E, 0x3F, 0x1F, 0x3F, 0x0F, 0x9F, 0x07, 0xDF,
|
||||
0x03, 0xFF, 0x81, 0xFF, 0xC0, 0xFF, 0xF0, 0x7F, 0xF8, 0x3F, 0x7E, 0x1F,
|
||||
0x1F, 0x0F, 0x87, 0xC7, 0xC3, 0xF3, 0xE0, 0xF9, 0xF0, 0x7E, 0xF8, 0x1F,
|
||||
0x7C, 0x0F, 0xC0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0xF8, 0xF8, 0x3F, 0x1F,
|
||||
0x7F, 0x9F, 0xF3, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xC3, 0xF8,
|
||||
0x7F, 0xF8, 0x3F, 0x07, 0xFE, 0x07, 0xC0, 0xFF, 0xC0, 0xF8, 0x1F, 0xF8,
|
||||
0x1F, 0x03, 0xFF, 0x03, 0xE0, 0x7F, 0xE0, 0x7C, 0x0F, 0xFC, 0x0F, 0x81,
|
||||
0xFF, 0x81, 0xF0, 0x3F, 0xF0, 0x3E, 0x07, 0xFE, 0x07, 0xC0, 0xFF, 0xC0,
|
||||
0xF8, 0x1F, 0xF8, 0x1F, 0x03, 0xFF, 0x03, 0xE0, 0x7F, 0xE0, 0x7C, 0x0F,
|
||||
0x80, 0xF8, 0xF8, 0x7D, 0xFF, 0x3F, 0xFF, 0xDF, 0xFF, 0xEF, 0xE1, 0xFF,
|
||||
0xE0, 0x7F, 0xE0, 0x3F, 0xF0, 0x1F, 0xF8, 0x0F, 0xFC, 0x07, 0xFE, 0x03,
|
||||
0xFF, 0x01, 0xFF, 0x80, 0xFF, 0xC0, 0x7F, 0xE0, 0x3F, 0xF0, 0x1F, 0xF8,
|
||||
0x0F, 0xFC, 0x07, 0xFE, 0x03, 0xE0, 0x03, 0xF8, 0x01, 0xFF, 0xC0, 0x7F,
|
||||
0xFC, 0x1F, 0xFF, 0xC7, 0xF0, 0xFC, 0xF8, 0x0F, 0xBF, 0x01, 0xFF, 0xC0,
|
||||
0x1F, 0xF8, 0x03, 0xFF, 0x00, 0x7F, 0xE0, 0x0F, 0xFC, 0x01, 0xFF, 0xC0,
|
||||
0x7E, 0xF8, 0x0F, 0x9F, 0x87, 0xF1, 0xFF, 0xFC, 0x1F, 0xFF, 0x01, 0xFF,
|
||||
0xC0, 0x0F, 0xE0, 0x00, 0xF8, 0xF8, 0x3E, 0xFF, 0x8F, 0xFF, 0xF3, 0xFF,
|
||||
0xFC, 0xFE, 0x1F, 0xBF, 0x03, 0xEF, 0xC0, 0xFF, 0xE0, 0x1F, 0xF8, 0x07,
|
||||
0xFE, 0x01, 0xFF, 0x80, 0x7F, 0xE0, 0x1F, 0xFC, 0x0F, 0xFF, 0x03, 0xEF,
|
||||
0xE1, 0xFB, 0xFF, 0xFC, 0xFF, 0xFF, 0x3E, 0xFF, 0x0F, 0x8F, 0x83, 0xE0,
|
||||
0x00, 0xF8, 0x00, 0x3E, 0x00, 0x0F, 0x80, 0x03, 0xE0, 0x00, 0xF8, 0x00,
|
||||
0x3E, 0x00, 0x00, 0x07, 0xE3, 0xE1, 0xFF, 0x7C, 0x7F, 0xFF, 0x9F, 0xFF,
|
||||
0xF7, 0xF1, 0xFE, 0xF8, 0x0F, 0xFF, 0x01, 0xFF, 0xC0, 0x1F, 0xF8, 0x03,
|
||||
0xFF, 0x00, 0x7F, 0xE0, 0x0F, 0xFC, 0x01, 0xFF, 0xC0, 0x7E, 0xF8, 0x0F,
|
||||
0xDF, 0x83, 0xF9, 0xFF, 0xFF, 0x3F, 0xFF, 0xE1, 0xFF, 0x7C, 0x1F, 0x8F,
|
||||
0x80, 0x01, 0xF0, 0x00, 0x3E, 0x00, 0x07, 0xC0, 0x00, 0xF8, 0x00, 0x1F,
|
||||
0x00, 0x03, 0xE0, 0x00, 0x7C, 0xF8, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xE1,
|
||||
0xF8, 0x3E, 0x07, 0xC0, 0xF8, 0x1F, 0x03, 0xE0, 0x7C, 0x0F, 0x81, 0xF0,
|
||||
0x3E, 0x07, 0xC0, 0xF8, 0x1F, 0x03, 0xE0, 0x00, 0x07, 0xF0, 0x0F, 0xFE,
|
||||
0x0F, 0xFF, 0x87, 0xFF, 0xE7, 0xE1, 0xF3, 0xE0, 0x79, 0xF8, 0x00, 0xFF,
|
||||
0x80, 0x3F, 0xFC, 0x1F, 0xFF, 0x83, 0xFF, 0xC0, 0x3F, 0xF0, 0x01, 0xFF,
|
||||
0xC0, 0x7D, 0xF0, 0x7E, 0xFF, 0xFE, 0x3F, 0xFF, 0x0F, 0xFF, 0x01, 0xFE,
|
||||
0x00, 0x3E, 0x1F, 0x0F, 0x87, 0xC3, 0xE7, 0xFF, 0xFF, 0xFF, 0x3E, 0x1F,
|
||||
0x0F, 0x87, 0xC3, 0xE1, 0xF0, 0xF8, 0x7C, 0x3E, 0x1F, 0x0F, 0x87, 0xF3,
|
||||
0xF8, 0xFC, 0x3E, 0xF8, 0x0F, 0xFC, 0x07, 0xFE, 0x03, 0xFF, 0x01, 0xFF,
|
||||
0x80, 0xFF, 0xC0, 0x7F, 0xE0, 0x3F, 0xF0, 0x1F, 0xF8, 0x0F, 0xFC, 0x07,
|
||||
0xFE, 0x03, 0xFF, 0x01, 0xFF, 0x80, 0xFF, 0xC0, 0xFF, 0xF0, 0xFF, 0xFF,
|
||||
0xFF, 0x7F, 0xFF, 0x9F, 0xF7, 0xC7, 0xE3, 0xE0, 0x7C, 0x07, 0xCF, 0x80,
|
||||
0xF9, 0xF0, 0x1F, 0x1F, 0x07, 0xC3, 0xE0, 0xF8, 0x7C, 0x1F, 0x07, 0x83,
|
||||
0xC0, 0xF8, 0xF8, 0x1F, 0x1F, 0x01, 0xE3, 0xC0, 0x3E, 0x78, 0x07, 0xDF,
|
||||
0x00, 0x7B, 0xC0, 0x0F, 0xF8, 0x01, 0xFF, 0x00, 0x1F, 0xC0, 0x03, 0xF8,
|
||||
0x00, 0x7F, 0x00, 0x07, 0xC0, 0x00, 0xFC, 0x1F, 0x03, 0xEF, 0x83, 0xE0,
|
||||
0x7D, 0xF0, 0x7E, 0x1F, 0x3E, 0x0F, 0xC3, 0xE3, 0xC3, 0xF8, 0x7C, 0x7C,
|
||||
0x7F, 0x0F, 0x0F, 0x8F, 0xF3, 0xE1, 0xF1, 0xDE, 0x7C, 0x1E, 0x7B, 0xCF,
|
||||
0x83, 0xEF, 0x39, 0xE0, 0x7D, 0xE7, 0x3C, 0x07, 0xB8, 0xFF, 0x80, 0xF7,
|
||||
0x1F, 0xE0, 0x1F, 0xE3, 0xFC, 0x03, 0xFC, 0x3F, 0x80, 0x3F, 0x07, 0xF0,
|
||||
0x07, 0xE0, 0xFC, 0x00, 0xFC, 0x1F, 0x80, 0x0F, 0x83, 0xF0, 0x00, 0xFC,
|
||||
0x1F, 0x9F, 0x07, 0xE7, 0xE3, 0xF0, 0xF8, 0xF8, 0x1F, 0x7E, 0x07, 0xDF,
|
||||
0x00, 0xFF, 0x80, 0x1F, 0xE0, 0x07, 0xF0, 0x00, 0xF8, 0x00, 0x7F, 0x00,
|
||||
0x3F, 0xE0, 0x0F, 0xF8, 0x07, 0xDF, 0x03, 0xF7, 0xE0, 0xF8, 0xF8, 0x7E,
|
||||
0x3F, 0x1F, 0x07, 0xEF, 0xC0, 0xF8, 0x7C, 0x03, 0xEF, 0x80, 0xF9, 0xF8,
|
||||
0x1F, 0x1F, 0x03, 0xE3, 0xE0, 0xF8, 0x7C, 0x1F, 0x07, 0xC3, 0xE0, 0xF8,
|
||||
0x78, 0x0F, 0x1F, 0x01, 0xF3, 0xC0, 0x3E, 0x78, 0x03, 0xDF, 0x00, 0x7F,
|
||||
0xC0, 0x0F, 0xF8, 0x00, 0xFF, 0x00, 0x1F, 0xC0, 0x01, 0xF8, 0x00, 0x3F,
|
||||
0x00, 0x07, 0xC0, 0x00, 0xF8, 0x00, 0x1E, 0x00, 0x07, 0xC0, 0x07, 0xF8,
|
||||
0x00, 0xFE, 0x00, 0x1F, 0x80, 0x03, 0xE0, 0x00, 0x7F, 0xFE, 0x7F, 0xFE,
|
||||
0x7F, 0xFE, 0x7F, 0xFE, 0x00, 0x7E, 0x00, 0xFC, 0x01, 0xF8, 0x03, 0xF0,
|
||||
0x03, 0xF0, 0x07, 0xE0, 0x0F, 0xC0, 0x1F, 0x80, 0x3F, 0x00, 0x7E, 0x00,
|
||||
0xFE, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0x87,
|
||||
0xC7, 0xE3, 0xF1, 0xE0, 0xF0, 0x78, 0x3C, 0x1E, 0x0F, 0x07, 0x83, 0xC1,
|
||||
0xE0, 0xF0, 0xF9, 0xF8, 0xF0, 0x7E, 0x0F, 0x83, 0xC1, 0xE0, 0xF0, 0x78,
|
||||
0x3C, 0x1E, 0x0F, 0x07, 0x83, 0xC1, 0xE0, 0xFC, 0x7E, 0x1F, 0x07, 0x80,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xE0, 0xF0, 0x7C, 0x3E, 0x1F, 0x83, 0xC1, 0xE0, 0xF0, 0x78, 0x3C, 0x1E,
|
||||
0x0F, 0x07, 0x83, 0xC1, 0xE0, 0xF0, 0x7C, 0x1F, 0x83, 0xC7, 0xE7, 0xC3,
|
||||
0xC1, 0xE0, 0xF0, 0x78, 0x3C, 0x1E, 0x0F, 0x07, 0x83, 0xC7, 0xE3, 0xE1,
|
||||
0xF0, 0xF0, 0x00, 0x3C, 0x00, 0xFE, 0x0F, 0xFE, 0x1E, 0x1F, 0xFC, 0x0F,
|
||||
0xC0, 0x0F, 0x00 };
|
||||
|
||||
const GFXglyph FreeSansBold18pt7bGlyphs[] PROGMEM = {
|
||||
{ 0, 0, 0, 10, 0, 1 }, // 0x20 ' '
|
||||
{ 0, 5, 25, 12, 4, -24 }, // 0x21 '!'
|
||||
{ 16, 13, 9, 17, 2, -25 }, // 0x22 '"'
|
||||
{ 31, 20, 24, 19, 0, -23 }, // 0x23 '#'
|
||||
{ 91, 19, 29, 19, 0, -25 }, // 0x24 '$'
|
||||
{ 160, 29, 25, 31, 1, -24 }, // 0x25 '%'
|
||||
{ 251, 22, 25, 25, 2, -24 }, // 0x26 '&'
|
||||
{ 320, 5, 9, 9, 2, -25 }, // 0x27 '''
|
||||
{ 326, 9, 33, 12, 1, -25 }, // 0x28 '('
|
||||
{ 364, 9, 33, 12, 1, -25 }, // 0x29 ')'
|
||||
{ 402, 12, 11, 14, 0, -25 }, // 0x2A '*'
|
||||
{ 419, 16, 16, 20, 2, -15 }, // 0x2B '+'
|
||||
{ 451, 5, 11, 9, 2, -4 }, // 0x2C ','
|
||||
{ 458, 9, 4, 12, 1, -10 }, // 0x2D '-'
|
||||
{ 463, 5, 5, 9, 2, -4 }, // 0x2E '.'
|
||||
{ 467, 9, 25, 10, 0, -24 }, // 0x2F '/'
|
||||
{ 496, 17, 25, 19, 1, -24 }, // 0x30 '0'
|
||||
{ 550, 10, 25, 19, 3, -24 }, // 0x31 '1'
|
||||
{ 582, 17, 25, 19, 1, -24 }, // 0x32 '2'
|
||||
{ 636, 17, 25, 19, 1, -24 }, // 0x33 '3'
|
||||
{ 690, 16, 25, 19, 2, -24 }, // 0x34 '4'
|
||||
{ 740, 17, 25, 19, 1, -24 }, // 0x35 '5'
|
||||
{ 794, 18, 25, 19, 1, -24 }, // 0x36 '6'
|
||||
{ 851, 17, 25, 19, 1, -24 }, // 0x37 '7'
|
||||
{ 905, 17, 25, 19, 1, -24 }, // 0x38 '8'
|
||||
{ 959, 17, 25, 19, 1, -24 }, // 0x39 '9'
|
||||
{ 1013, 5, 18, 9, 2, -17 }, // 0x3A ':'
|
||||
{ 1025, 5, 24, 9, 2, -17 }, // 0x3B ';'
|
||||
{ 1040, 18, 17, 20, 1, -16 }, // 0x3C '<'
|
||||
{ 1079, 17, 12, 20, 2, -13 }, // 0x3D '='
|
||||
{ 1105, 18, 17, 20, 1, -16 }, // 0x3E '>'
|
||||
{ 1144, 18, 26, 21, 2, -25 }, // 0x3F '?'
|
||||
{ 1203, 32, 31, 34, 1, -25 }, // 0x40 '@'
|
||||
{ 1327, 24, 26, 24, 0, -25 }, // 0x41 'A'
|
||||
{ 1405, 20, 26, 25, 3, -25 }, // 0x42 'B'
|
||||
{ 1470, 23, 26, 25, 1, -25 }, // 0x43 'C'
|
||||
{ 1545, 21, 26, 25, 3, -25 }, // 0x44 'D'
|
||||
{ 1614, 19, 26, 23, 3, -25 }, // 0x45 'E'
|
||||
{ 1676, 17, 26, 22, 3, -25 }, // 0x46 'F'
|
||||
{ 1732, 24, 26, 27, 1, -25 }, // 0x47 'G'
|
||||
{ 1810, 20, 26, 26, 3, -25 }, // 0x48 'H'
|
||||
{ 1875, 5, 26, 11, 3, -25 }, // 0x49 'I'
|
||||
{ 1892, 16, 26, 20, 1, -25 }, // 0x4A 'J'
|
||||
{ 1944, 22, 26, 25, 3, -25 }, // 0x4B 'K'
|
||||
{ 2016, 17, 26, 22, 3, -25 }, // 0x4C 'L'
|
||||
{ 2072, 24, 26, 30, 3, -25 }, // 0x4D 'M'
|
||||
{ 2150, 20, 26, 26, 3, -25 }, // 0x4E 'N'
|
||||
{ 2215, 25, 26, 27, 1, -25 }, // 0x4F 'O'
|
||||
{ 2297, 19, 26, 24, 3, -25 }, // 0x50 'P'
|
||||
{ 2359, 25, 27, 27, 1, -25 }, // 0x51 'Q'
|
||||
{ 2444, 21, 26, 25, 3, -25 }, // 0x52 'R'
|
||||
{ 2513, 20, 26, 24, 2, -25 }, // 0x53 'S'
|
||||
{ 2578, 19, 26, 23, 2, -25 }, // 0x54 'T'
|
||||
{ 2640, 20, 26, 26, 3, -25 }, // 0x55 'U'
|
||||
{ 2705, 22, 26, 23, 1, -25 }, // 0x56 'V'
|
||||
{ 2777, 32, 26, 34, 1, -25 }, // 0x57 'W'
|
||||
{ 2881, 22, 26, 24, 1, -25 }, // 0x58 'X'
|
||||
{ 2953, 21, 26, 22, 1, -25 }, // 0x59 'Y'
|
||||
{ 3022, 19, 26, 21, 1, -25 }, // 0x5A 'Z'
|
||||
{ 3084, 8, 33, 12, 2, -25 }, // 0x5B '['
|
||||
{ 3117, 10, 25, 10, 0, -24 }, // 0x5C '\'
|
||||
{ 3149, 8, 33, 12, 1, -25 }, // 0x5D ']'
|
||||
{ 3182, 16, 15, 20, 2, -23 }, // 0x5E '^'
|
||||
{ 3212, 21, 3, 19, -1, 5 }, // 0x5F '_'
|
||||
{ 3220, 7, 5, 9, 1, -25 }, // 0x60 '`'
|
||||
{ 3225, 18, 19, 20, 1, -18 }, // 0x61 'a'
|
||||
{ 3268, 18, 26, 22, 2, -25 }, // 0x62 'b'
|
||||
{ 3327, 17, 19, 20, 1, -18 }, // 0x63 'c'
|
||||
{ 3368, 19, 26, 22, 1, -25 }, // 0x64 'd'
|
||||
{ 3430, 18, 19, 20, 1, -18 }, // 0x65 'e'
|
||||
{ 3473, 10, 26, 12, 1, -25 }, // 0x66 'f'
|
||||
{ 3506, 18, 26, 21, 1, -18 }, // 0x67 'g'
|
||||
{ 3565, 17, 26, 21, 2, -25 }, // 0x68 'h'
|
||||
{ 3621, 5, 26, 10, 2, -25 }, // 0x69 'i'
|
||||
{ 3638, 7, 33, 10, 0, -25 }, // 0x6A 'j'
|
||||
{ 3667, 17, 26, 20, 2, -25 }, // 0x6B 'k'
|
||||
{ 3723, 5, 26, 9, 2, -25 }, // 0x6C 'l'
|
||||
{ 3740, 27, 19, 31, 2, -18 }, // 0x6D 'm'
|
||||
{ 3805, 17, 19, 21, 2, -18 }, // 0x6E 'n'
|
||||
{ 3846, 19, 19, 21, 1, -18 }, // 0x6F 'o'
|
||||
{ 3892, 18, 26, 22, 2, -18 }, // 0x70 'p'
|
||||
{ 3951, 19, 26, 22, 1, -18 }, // 0x71 'q'
|
||||
{ 4013, 11, 19, 14, 2, -18 }, // 0x72 'r'
|
||||
{ 4040, 17, 19, 19, 1, -18 }, // 0x73 's'
|
||||
{ 4081, 9, 23, 12, 1, -22 }, // 0x74 't'
|
||||
{ 4107, 17, 19, 21, 2, -18 }, // 0x75 'u'
|
||||
{ 4148, 19, 19, 19, 0, -18 }, // 0x76 'v'
|
||||
{ 4194, 27, 19, 27, 0, -18 }, // 0x77 'w'
|
||||
{ 4259, 18, 19, 19, 1, -18 }, // 0x78 'x'
|
||||
{ 4302, 19, 26, 19, 0, -18 }, // 0x79 'y'
|
||||
{ 4364, 16, 19, 18, 1, -18 }, // 0x7A 'z'
|
||||
{ 4402, 9, 33, 14, 1, -25 }, // 0x7B '{'
|
||||
{ 4440, 3, 33, 10, 4, -25 }, // 0x7C '|'
|
||||
{ 4453, 9, 33, 14, 3, -25 }, // 0x7D '}'
|
||||
{ 4491, 15, 6, 18, 1, -10 } }; // 0x7E '~'
|
||||
|
||||
const GFXfont FreeSansBold18pt7b PROGMEM = {
|
||||
(uint8_t *)FreeSansBold18pt7bBitmaps,
|
||||
(GFXglyph *)FreeSansBold18pt7bGlyphs,
|
||||
0x20, 0x7E, 42 };
|
||||
|
||||
// Approx. 5175 bytes
|
||||
785
ARM_Tag_FW/Newton_M3_nRF52811/include/FreeSansBold24pt7b.h
Normal file
785
ARM_Tag_FW/Newton_M3_nRF52811/include/FreeSansBold24pt7b.h
Normal file
@@ -0,0 +1,785 @@
|
||||
#pragma once
|
||||
|
||||
const uint8_t FreeSansBold24pt7bBitmaps[] PROGMEM = {
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xDF, 0x3E, 0x7C, 0xF9, 0xF3, 0xE7, 0xC7, 0x0E, 0x1C, 0x00, 0x00, 0x07,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFE, 0x1F, 0xFF, 0x87, 0xFF, 0xE1,
|
||||
0xFF, 0xF8, 0x7F, 0xFE, 0x1F, 0xFF, 0x87, 0xFF, 0xE1, 0xFD, 0xF0, 0x3E,
|
||||
0x7C, 0x0F, 0x9F, 0x03, 0xE3, 0x80, 0x70, 0xE0, 0x1C, 0x00, 0xF8, 0x3E,
|
||||
0x00, 0x3E, 0x0F, 0x80, 0x0F, 0x83, 0xE0, 0x03, 0xE0, 0xF8, 0x00, 0xF8,
|
||||
0x7C, 0x00, 0x7C, 0x1F, 0x00, 0x1F, 0x07, 0xC1, 0xFF, 0xFF, 0xFF, 0x7F,
|
||||
0xFF, 0xFF, 0xDF, 0xFF, 0xFF, 0xF7, 0xFF, 0xFF, 0xFD, 0xFF, 0xFF, 0xFF,
|
||||
0x03, 0xE0, 0xF8, 0x00, 0xF8, 0x3E, 0x00, 0x3E, 0x1F, 0x00, 0x1F, 0x07,
|
||||
0xC0, 0x07, 0xC1, 0xF0, 0x01, 0xF0, 0x7C, 0x00, 0x7C, 0x1F, 0x03, 0xFF,
|
||||
0xFF, 0xFC, 0xFF, 0xFF, 0xFF, 0x3F, 0xFF, 0xFF, 0xCF, 0xFF, 0xFF, 0xF3,
|
||||
0xFF, 0xFF, 0xFC, 0x0F, 0x87, 0xC0, 0x07, 0xC1, 0xF0, 0x01, 0xF0, 0x7C,
|
||||
0x00, 0x7C, 0x1F, 0x00, 0x1F, 0x07, 0xC0, 0x07, 0xC3, 0xE0, 0x03, 0xE0,
|
||||
0xF8, 0x00, 0xF8, 0x3E, 0x00, 0x3E, 0x0F, 0x80, 0x00, 0x00, 0x38, 0x00,
|
||||
0x00, 0x1C, 0x00, 0x00, 0x7F, 0xE0, 0x00, 0xFF, 0xFC, 0x00, 0xFF, 0xFF,
|
||||
0x80, 0xFF, 0xFF, 0xE0, 0xFF, 0xFF, 0xF8, 0x7F, 0x73, 0xFE, 0x7F, 0x38,
|
||||
0xFF, 0x3F, 0x1C, 0x3F, 0xDF, 0x8E, 0x0F, 0xEF, 0xC7, 0x07, 0xF7, 0xE3,
|
||||
0x80, 0x03, 0xF9, 0xC0, 0x01, 0xFE, 0xE0, 0x00, 0x7F, 0xF0, 0x00, 0x3F,
|
||||
0xFC, 0x00, 0x0F, 0xFF, 0xC0, 0x03, 0xFF, 0xFC, 0x00, 0x7F, 0xFF, 0x80,
|
||||
0x0F, 0xFF, 0xE0, 0x01, 0xFF, 0xF8, 0x00, 0xE7, 0xFC, 0x00, 0x71, 0xFF,
|
||||
0x00, 0x38, 0x7F, 0xFF, 0x1C, 0x1F, 0xFF, 0x8E, 0x0F, 0xFF, 0xC7, 0x07,
|
||||
0xFF, 0xE3, 0x87, 0xFB, 0xF9, 0xC3, 0xF9, 0xFE, 0xE7, 0xFC, 0x7F, 0xFF,
|
||||
0xFC, 0x3F, 0xFF, 0xFC, 0x0F, 0xFF, 0xFC, 0x01, 0xFF, 0xF8, 0x00, 0x3F,
|
||||
0xE0, 0x00, 0x03, 0x80, 0x00, 0x01, 0xC0, 0x00, 0x00, 0xE0, 0x00, 0x00,
|
||||
0x70, 0x00, 0x03, 0xE0, 0x00, 0x3C, 0x00, 0x1F, 0xF0, 0x00, 0x78, 0x00,
|
||||
0x7F, 0xF8, 0x01, 0xE0, 0x01, 0xFF, 0xF0, 0x03, 0xC0, 0x07, 0xFF, 0xF0,
|
||||
0x0F, 0x00, 0x0F, 0x83, 0xE0, 0x1E, 0x00, 0x3E, 0x03, 0xE0, 0x78, 0x00,
|
||||
0x78, 0x03, 0xC0, 0xF0, 0x00, 0xF0, 0x07, 0x83, 0xC0, 0x01, 0xE0, 0x0F,
|
||||
0x07, 0x80, 0x03, 0xE0, 0x3E, 0x1E, 0x00, 0x03, 0xE0, 0xF8, 0x3C, 0x00,
|
||||
0x07, 0xFF, 0xF0, 0xF0, 0x00, 0x07, 0xFF, 0xC1, 0xE0, 0x00, 0x07, 0xFF,
|
||||
0x07, 0x80, 0x00, 0x07, 0xFC, 0x1F, 0x00, 0x00, 0x03, 0xE0, 0x3C, 0x00,
|
||||
0x00, 0x00, 0x00, 0xF0, 0x1F, 0x00, 0x00, 0x01, 0xE0, 0xFF, 0x80, 0x00,
|
||||
0x07, 0x87, 0xFF, 0xC0, 0x00, 0x0F, 0x0F, 0xFF, 0x80, 0x00, 0x3C, 0x3F,
|
||||
0xFF, 0x80, 0x00, 0x78, 0xFC, 0x1F, 0x00, 0x01, 0xE1, 0xF0, 0x1F, 0x00,
|
||||
0x03, 0xC3, 0xC0, 0x1E, 0x00, 0x0F, 0x07, 0x80, 0x3C, 0x00, 0x1E, 0x0F,
|
||||
0x00, 0x78, 0x00, 0x78, 0x1F, 0x01, 0xF0, 0x00, 0xF0, 0x1F, 0x07, 0xC0,
|
||||
0x03, 0xC0, 0x3F, 0xFF, 0x80, 0x07, 0x80, 0x3F, 0xFE, 0x00, 0x1E, 0x00,
|
||||
0x7F, 0xF8, 0x00, 0x7C, 0x00, 0x3F, 0xE0, 0x00, 0xF0, 0x00, 0x1F, 0x00,
|
||||
0x00, 0x3F, 0x00, 0x00, 0x03, 0xFE, 0x00, 0x00, 0x1F, 0xFC, 0x00, 0x00,
|
||||
0xFF, 0xF8, 0x00, 0x07, 0xFF, 0xF0, 0x00, 0x3F, 0xCF, 0xC0, 0x00, 0xFE,
|
||||
0x1F, 0x00, 0x03, 0xF8, 0x7C, 0x00, 0x0F, 0xE1, 0xF0, 0x00, 0x3F, 0xC7,
|
||||
0xC0, 0x00, 0x7F, 0x3E, 0x00, 0x01, 0xFF, 0xF8, 0x00, 0x03, 0xFF, 0xC0,
|
||||
0x00, 0x07, 0xFE, 0x00, 0x00, 0x0F, 0xF0, 0x00, 0x00, 0x7F, 0x80, 0x00,
|
||||
0x07, 0xFF, 0x03, 0xE0, 0x3F, 0xFE, 0x0F, 0x83, 0xFF, 0xF8, 0x3E, 0x1F,
|
||||
0xF3, 0xF1, 0xF8, 0x7F, 0x07, 0xE7, 0xE3, 0xFC, 0x1F, 0xFF, 0x0F, 0xE0,
|
||||
0x3F, 0xFC, 0x3F, 0x80, 0x7F, 0xF0, 0xFE, 0x01, 0xFF, 0x83, 0xF8, 0x03,
|
||||
0xFE, 0x0F, 0xF0, 0x0F, 0xF0, 0x3F, 0xE0, 0x7F, 0xE0, 0x7F, 0xC3, 0xFF,
|
||||
0xC1, 0xFF, 0xFF, 0xFF, 0x03, 0xFF, 0xFF, 0xFE, 0x07, 0xFF, 0xFB, 0xFC,
|
||||
0x0F, 0xFF, 0xC7, 0xF8, 0x1F, 0xFE, 0x0F, 0xE0, 0x0F, 0xE0, 0x00, 0x00,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xBE, 0x7C, 0xF8, 0xE1, 0xC0, 0x00,
|
||||
0xF0, 0x0F, 0x80, 0xF8, 0x07, 0xC0, 0x7C, 0x07, 0xE0, 0x3E, 0x03, 0xF0,
|
||||
0x1F, 0x80, 0xF8, 0x0F, 0xC0, 0x7E, 0x07, 0xE0, 0x3F, 0x01, 0xF8, 0x0F,
|
||||
0xC0, 0xFC, 0x07, 0xE0, 0x3F, 0x01, 0xF8, 0x0F, 0xC0, 0x7E, 0x03, 0xF0,
|
||||
0x1F, 0x80, 0xFC, 0x07, 0xE0, 0x3F, 0x00, 0xF8, 0x07, 0xE0, 0x3F, 0x01,
|
||||
0xF8, 0x07, 0xC0, 0x3F, 0x01, 0xF8, 0x07, 0xC0, 0x3F, 0x00, 0xF8, 0x07,
|
||||
0xE0, 0x1F, 0x00, 0xF8, 0x03, 0xE0, 0x1F, 0x00, 0x7C, 0x01, 0xE0, 0x78,
|
||||
0x03, 0xE0, 0x0F, 0x80, 0x7C, 0x01, 0xF0, 0x0F, 0x80, 0x3E, 0x01, 0xF0,
|
||||
0x0F, 0xC0, 0x3E, 0x01, 0xF8, 0x0F, 0xC0, 0x3F, 0x01, 0xF8, 0x0F, 0xC0,
|
||||
0x7E, 0x01, 0xF8, 0x0F, 0xC0, 0x7E, 0x03, 0xF0, 0x1F, 0x80, 0xFC, 0x07,
|
||||
0xE0, 0x3F, 0x01, 0xF8, 0x0F, 0xC0, 0x7E, 0x03, 0xE0, 0x3F, 0x01, 0xF8,
|
||||
0x0F, 0xC0, 0x7C, 0x07, 0xE0, 0x3F, 0x01, 0xF0, 0x1F, 0x80, 0xF8, 0x0F,
|
||||
0xC0, 0x7C, 0x07, 0xE0, 0x3E, 0x03, 0xF0, 0x1F, 0x01, 0xF0, 0x00, 0x03,
|
||||
0x80, 0x07, 0x00, 0x0E, 0x00, 0x1C, 0x06, 0x38, 0xDF, 0xFF, 0xFF, 0xFF,
|
||||
0x9F, 0xFE, 0x07, 0xC0, 0x1F, 0xC0, 0x3F, 0x80, 0xF7, 0x83, 0xC7, 0x87,
|
||||
0x8F, 0x02, 0x08, 0x00, 0x00, 0x7C, 0x00, 0x00, 0xF8, 0x00, 0x01, 0xF0,
|
||||
0x00, 0x03, 0xE0, 0x00, 0x07, 0xC0, 0x00, 0x0F, 0x80, 0x00, 0x1F, 0x00,
|
||||
0x00, 0x3E, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x1F, 0x00, 0x00,
|
||||
0x3E, 0x00, 0x00, 0x7C, 0x00, 0x00, 0xF8, 0x00, 0x01, 0xF0, 0x00, 0x03,
|
||||
0xE0, 0x00, 0x07, 0xC0, 0x00, 0x0F, 0x80, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0x87, 0x0E, 0x1C, 0x78, 0xEF, 0xDF, 0x38, 0x00, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0x80, 0x00, 0x38, 0x03, 0xC0, 0x1C, 0x00, 0xE0, 0x07, 0x00,
|
||||
0x70, 0x03, 0x80, 0x1C, 0x01, 0xE0, 0x0E, 0x00, 0x70, 0x03, 0x80, 0x38,
|
||||
0x01, 0xC0, 0x0E, 0x00, 0xF0, 0x07, 0x00, 0x38, 0x03, 0xC0, 0x1C, 0x00,
|
||||
0xE0, 0x07, 0x00, 0x70, 0x03, 0x80, 0x1C, 0x01, 0xE0, 0x0E, 0x00, 0x70,
|
||||
0x03, 0x80, 0x38, 0x01, 0xC0, 0x0E, 0x00, 0xF0, 0x07, 0x00, 0x00, 0x00,
|
||||
0xFF, 0x00, 0x03, 0xFF, 0xC0, 0x0F, 0xFF, 0xF0, 0x1F, 0xFF, 0xF8, 0x1F,
|
||||
0xFF, 0xF8, 0x3F, 0xFF, 0xFC, 0x3F, 0xC3, 0xFC, 0x7F, 0x81, 0xFE, 0x7F,
|
||||
0x00, 0xFE, 0x7F, 0x00, 0xFE, 0x7F, 0x00, 0xFE, 0xFE, 0x00, 0x7F, 0xFE,
|
||||
0x00, 0x7F, 0xFE, 0x00, 0x7F, 0xFE, 0x00, 0x7F, 0xFE, 0x00, 0x7F, 0xFE,
|
||||
0x00, 0x7F, 0xFE, 0x00, 0x7F, 0xFE, 0x00, 0x7F, 0xFE, 0x00, 0x7F, 0xFE,
|
||||
0x00, 0x7F, 0xFE, 0x00, 0x7F, 0xFE, 0x00, 0x7F, 0xFE, 0x00, 0x7F, 0x7F,
|
||||
0x00, 0xFE, 0x7F, 0x00, 0xFE, 0x7F, 0x00, 0xFE, 0x7F, 0x81, 0xFE, 0x3F,
|
||||
0xC3, 0xFC, 0x3F, 0xFF, 0xFC, 0x1F, 0xFF, 0xF8, 0x1F, 0xFF, 0xF8, 0x0F,
|
||||
0xFF, 0xF0, 0x03, 0xFF, 0xC0, 0x00, 0xFF, 0x00, 0x00, 0x3C, 0x01, 0xF0,
|
||||
0x07, 0xC0, 0x3F, 0x01, 0xFC, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xF0, 0x1F, 0xC0, 0x7F, 0x01, 0xFC, 0x07, 0xF0, 0x1F, 0xC0, 0x7F,
|
||||
0x01, 0xFC, 0x07, 0xF0, 0x1F, 0xC0, 0x7F, 0x01, 0xFC, 0x07, 0xF0, 0x1F,
|
||||
0xC0, 0x7F, 0x01, 0xFC, 0x07, 0xF0, 0x1F, 0xC0, 0x7F, 0x01, 0xFC, 0x07,
|
||||
0xF0, 0x1F, 0xC0, 0x7F, 0x01, 0xFC, 0x01, 0xFE, 0x00, 0x0F, 0xFF, 0x80,
|
||||
0x3F, 0xFF, 0x80, 0xFF, 0xFF, 0x83, 0xFF, 0xFF, 0x8F, 0xFF, 0xFF, 0x9F,
|
||||
0xE0, 0xFF, 0x7F, 0x80, 0xFF, 0xFE, 0x01, 0xFF, 0xFC, 0x01, 0xFF, 0xF8,
|
||||
0x03, 0xFF, 0xF0, 0x07, 0xF0, 0x00, 0x0F, 0xE0, 0x00, 0x1F, 0xC0, 0x00,
|
||||
0x7F, 0x80, 0x00, 0xFE, 0x00, 0x03, 0xFC, 0x00, 0x0F, 0xF0, 0x00, 0x7F,
|
||||
0xC0, 0x01, 0xFF, 0x00, 0x07, 0xF8, 0x00, 0x3F, 0xE0, 0x00, 0xFF, 0x00,
|
||||
0x03, 0xFC, 0x00, 0x0F, 0xF0, 0x00, 0x3F, 0xC0, 0x00, 0x7F, 0x00, 0x01,
|
||||
0xFC, 0x00, 0x03, 0xFF, 0xFF, 0xE7, 0xFF, 0xFF, 0xDF, 0xFF, 0xFF, 0xBF,
|
||||
0xFF, 0xFF, 0x7F, 0xFF, 0xFE, 0xFF, 0xFF, 0xFC, 0x01, 0xFE, 0x00, 0x0F,
|
||||
0xFF, 0x80, 0x7F, 0xFF, 0x81, 0xFF, 0xFF, 0x87, 0xFF, 0xFF, 0x8F, 0xFF,
|
||||
0xFF, 0x1F, 0xE1, 0xFF, 0x7F, 0x81, 0xFE, 0xFE, 0x01, 0xFD, 0xFC, 0x03,
|
||||
0xFB, 0xF8, 0x07, 0xF0, 0x00, 0x0F, 0xE0, 0x00, 0x1F, 0x80, 0x00, 0x7F,
|
||||
0x00, 0x01, 0xFC, 0x00, 0x1F, 0xF0, 0x00, 0x3F, 0xC0, 0x00, 0x7F, 0xC0,
|
||||
0x00, 0xFF, 0xE0, 0x00, 0x3F, 0xE0, 0x00, 0x1F, 0xC0, 0x00, 0x3F, 0xC0,
|
||||
0x00, 0x3F, 0x80, 0x00, 0x7F, 0x00, 0x00, 0xFF, 0xFC, 0x01, 0xFF, 0xF8,
|
||||
0x07, 0xFF, 0xF8, 0x0F, 0xF7, 0xF8, 0x3F, 0xCF, 0xFF, 0xFF, 0x9F, 0xFF,
|
||||
0xFE, 0x1F, 0xFF, 0xF8, 0x1F, 0xFF, 0xE0, 0x0F, 0xFF, 0x80, 0x07, 0xF8,
|
||||
0x00, 0x00, 0x1F, 0xE0, 0x00, 0x7F, 0x80, 0x03, 0xFE, 0x00, 0x0F, 0xF8,
|
||||
0x00, 0x7F, 0xE0, 0x03, 0xFF, 0x80, 0x0F, 0xFE, 0x00, 0x7B, 0xF8, 0x01,
|
||||
0xEF, 0xE0, 0x0F, 0x3F, 0x80, 0x78, 0xFE, 0x01, 0xE3, 0xF8, 0x0F, 0x0F,
|
||||
0xE0, 0x38, 0x3F, 0x81, 0xE0, 0xFE, 0x07, 0x03, 0xF8, 0x3C, 0x0F, 0xE1,
|
||||
0xE0, 0x3F, 0x87, 0x00, 0xFE, 0x3C, 0x03, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xF0, 0x00, 0xFE, 0x00, 0x03, 0xF8, 0x00, 0x0F, 0xE0, 0x00, 0x3F, 0x80,
|
||||
0x00, 0xFE, 0x00, 0x03, 0xF8, 0x00, 0x0F, 0xE0, 0x1F, 0xFF, 0xFC, 0x3F,
|
||||
0xFF, 0xF8, 0x7F, 0xFF, 0xF0, 0xFF, 0xFF, 0xE3, 0xFF, 0xFF, 0xC7, 0xFF,
|
||||
0xFF, 0x8F, 0x80, 0x00, 0x1F, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x78, 0x00,
|
||||
0x01, 0xF1, 0xF8, 0x03, 0xEF, 0xFE, 0x07, 0xFF, 0xFE, 0x0F, 0xFF, 0xFE,
|
||||
0x1F, 0xFF, 0xFE, 0x7F, 0xFF, 0xFC, 0xFE, 0x07, 0xFC, 0x00, 0x07, 0xF8,
|
||||
0x00, 0x07, 0xF8, 0x00, 0x07, 0xF0, 0x00, 0x0F, 0xE0, 0x00, 0x1F, 0xC0,
|
||||
0x00, 0x3F, 0x80, 0x00, 0x7F, 0x00, 0x00, 0xFF, 0xF8, 0x03, 0xFF, 0xF8,
|
||||
0x0F, 0xF7, 0xF8, 0x3F, 0xEF, 0xFF, 0xFF, 0x8F, 0xFF, 0xFF, 0x0F, 0xFF,
|
||||
0xFC, 0x0F, 0xFF, 0xE0, 0x0F, 0xFF, 0x80, 0x03, 0xF8, 0x00, 0x00, 0xFF,
|
||||
0x00, 0x07, 0xFF, 0x80, 0x1F, 0xFF, 0xC0, 0x7F, 0xFF, 0x81, 0xFF, 0xFF,
|
||||
0x87, 0xFF, 0xFF, 0x8F, 0xF0, 0xFF, 0x3F, 0xC0, 0xFE, 0x7F, 0x00, 0x00,
|
||||
0xFE, 0x00, 0x01, 0xFC, 0x00, 0x07, 0xF0, 0x00, 0x0F, 0xE3, 0xF0, 0x1F,
|
||||
0xDF, 0xF8, 0x3F, 0xFF, 0xFC, 0x7F, 0xFF, 0xFC, 0xFF, 0xFF, 0xF9, 0xFF,
|
||||
0x87, 0xFB, 0xFC, 0x07, 0xF7, 0xF8, 0x0F, 0xFF, 0xE0, 0x0F, 0xFF, 0xC0,
|
||||
0x1F, 0xFF, 0x80, 0x3F, 0xFF, 0x00, 0x7F, 0x7E, 0x00, 0xFE, 0xFC, 0x01,
|
||||
0xFD, 0xFC, 0x07, 0xFB, 0xF8, 0x0F, 0xE3, 0xFC, 0x7F, 0xC7, 0xFF, 0xFF,
|
||||
0x07, 0xFF, 0xFE, 0x0F, 0xFF, 0xF8, 0x0F, 0xFF, 0xE0, 0x07, 0xFF, 0x80,
|
||||
0x03, 0xF8, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x3F, 0x00,
|
||||
0x00, 0xFC, 0x00, 0x03, 0xF8, 0x00, 0x07, 0xE0, 0x00, 0x1F, 0x80, 0x00,
|
||||
0x7F, 0x00, 0x00, 0xFC, 0x00, 0x03, 0xF8, 0x00, 0x07, 0xE0, 0x00, 0x1F,
|
||||
0x80, 0x00, 0x7F, 0x00, 0x00, 0xFE, 0x00, 0x01, 0xF8, 0x00, 0x07, 0xF0,
|
||||
0x00, 0x0F, 0xC0, 0x00, 0x3F, 0x80, 0x00, 0x7F, 0x00, 0x00, 0xFC, 0x00,
|
||||
0x01, 0xF8, 0x00, 0x07, 0xF0, 0x00, 0x0F, 0xE0, 0x00, 0x1F, 0xC0, 0x00,
|
||||
0x3F, 0x00, 0x00, 0xFE, 0x00, 0x01, 0xFC, 0x00, 0x03, 0xF8, 0x00, 0x07,
|
||||
0xF0, 0x00, 0x00, 0xFE, 0x00, 0x03, 0xFF, 0xC0, 0x0F, 0xFF, 0xE0, 0x1F,
|
||||
0xFF, 0xF0, 0x3F, 0xFF, 0xF8, 0x3F, 0xFF, 0xF8, 0x7F, 0x83, 0xFC, 0x7F,
|
||||
0x00, 0xFC, 0x7E, 0x00, 0xFC, 0x7E, 0x00, 0x7C, 0x7E, 0x00, 0x7C, 0x7E,
|
||||
0x00, 0xFC, 0x3F, 0x00, 0xF8, 0x3F, 0x83, 0xF8, 0x0F, 0xFF, 0xF0, 0x07,
|
||||
0xFF, 0xC0, 0x0F, 0xFF, 0xF0, 0x1F, 0xFF, 0xF8, 0x3F, 0xC3, 0xFC, 0x7F,
|
||||
0x00, 0xFE, 0x7F, 0x00, 0xFE, 0xFE, 0x00, 0x7F, 0xFE, 0x00, 0x7F, 0xFE,
|
||||
0x00, 0x7F, 0xFE, 0x00, 0x7F, 0xFE, 0x00, 0x7F, 0xFF, 0x00, 0xFF, 0xFF,
|
||||
0x00, 0xFE, 0x7F, 0x83, 0xFE, 0x7F, 0xFF, 0xFE, 0x3F, 0xFF, 0xFC, 0x1F,
|
||||
0xFF, 0xF8, 0x0F, 0xFF, 0xF0, 0x07, 0xFF, 0xC0, 0x00, 0xFF, 0x00, 0x00,
|
||||
0xFF, 0x00, 0x03, 0xFF, 0xC0, 0x0F, 0xFF, 0xE0, 0x1F, 0xFF, 0xF0, 0x3F,
|
||||
0xFF, 0xF8, 0x3F, 0xFF, 0xFC, 0x7F, 0xC3, 0xFC, 0x7F, 0x01, 0xFE, 0xFF,
|
||||
0x00, 0xFE, 0xFE, 0x00, 0x7E, 0xFE, 0x00, 0x7E, 0xFE, 0x00, 0x7F, 0xFE,
|
||||
0x00, 0x7F, 0xFE, 0x00, 0x7F, 0xFE, 0x00, 0x7F, 0xFF, 0x00, 0xFF, 0x7F,
|
||||
0x01, 0xFF, 0x7F, 0xC3, 0xFF, 0x7F, 0xFF, 0xFF, 0x3F, 0xFF, 0xFF, 0x1F,
|
||||
0xFF, 0xFF, 0x0F, 0xFF, 0x7F, 0x07, 0xFE, 0x7F, 0x01, 0xFC, 0x7E, 0x00,
|
||||
0x00, 0x7E, 0x00, 0x00, 0xFE, 0x00, 0x00, 0xFE, 0x7F, 0x01, 0xFC, 0x7F,
|
||||
0x83, 0xFC, 0x7F, 0xFF, 0xF8, 0x3F, 0xFF, 0xF8, 0x3F, 0xFF, 0xF0, 0x1F,
|
||||
0xFF, 0xE0, 0x07, 0xFF, 0x80, 0x01, 0xFE, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFE, 0x1C, 0x38, 0x71, 0xE7, 0xBF, 0x7C, 0xE0, 0x00,
|
||||
0x00, 0x02, 0x00, 0x00, 0x3C, 0x00, 0x01, 0xF8, 0x00, 0x1F, 0xF0, 0x01,
|
||||
0xFF, 0xE0, 0x0F, 0xFF, 0xC0, 0xFF, 0xFC, 0x0F, 0xFF, 0xC0, 0x7F, 0xFC,
|
||||
0x01, 0xFF, 0xC0, 0x03, 0xFC, 0x00, 0x07, 0xC0, 0x00, 0x0F, 0xE0, 0x00,
|
||||
0x1F, 0xF8, 0x00, 0x3F, 0xFE, 0x00, 0x0F, 0xFF, 0x80, 0x07, 0xFF, 0xE0,
|
||||
0x01, 0xFF, 0xF8, 0x00, 0x7F, 0xF8, 0x00, 0x3F, 0xF0, 0x00, 0x0F, 0xE0,
|
||||
0x00, 0x03, 0xC0, 0x00, 0x00, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x80, 0x00,
|
||||
0x01, 0xC0, 0x00, 0x03, 0xF0, 0x00, 0x07, 0xFC, 0x00, 0x0F, 0xFE, 0x00,
|
||||
0x1F, 0xFF, 0x80, 0x07, 0xFF, 0xE0, 0x01, 0xFF, 0xF0, 0x00, 0x7F, 0xFC,
|
||||
0x00, 0x1F, 0xFC, 0x00, 0x07, 0xF8, 0x00, 0x03, 0xF0, 0x00, 0x1F, 0xE0,
|
||||
0x01, 0xFF, 0xC0, 0x0F, 0xFF, 0x80, 0xFF, 0xF8, 0x0F, 0xFF, 0x80, 0xFF,
|
||||
0xFC, 0x03, 0xFF, 0xC0, 0x07, 0xFC, 0x00, 0x0F, 0xE0, 0x00, 0x1E, 0x00,
|
||||
0x00, 0x20, 0x00, 0x00, 0x00, 0x01, 0xFE, 0x00, 0x07, 0xFF, 0xC0, 0x1F,
|
||||
0xFF, 0xF0, 0x3F, 0xFF, 0xF8, 0x3F, 0xFF, 0xFC, 0x7F, 0xFF, 0xFC, 0x7F,
|
||||
0x83, 0xFE, 0x7F, 0x01, 0xFE, 0xFF, 0x00, 0xFF, 0xFE, 0x00, 0x7F, 0xFE,
|
||||
0x00, 0x7F, 0xFE, 0x00, 0x7F, 0x00, 0x00, 0x7F, 0x00, 0x00, 0xFF, 0x00,
|
||||
0x01, 0xFE, 0x00, 0x03, 0xFE, 0x00, 0x07, 0xFC, 0x00, 0x0F, 0xF8, 0x00,
|
||||
0x3F, 0xF0, 0x00, 0x3F, 0xE0, 0x00, 0x7F, 0x80, 0x00, 0x7F, 0x00, 0x00,
|
||||
0xFE, 0x00, 0x00, 0xFC, 0x00, 0x00, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x00, 0xFE, 0x00, 0x00,
|
||||
0xFE, 0x00, 0x00, 0xFE, 0x00, 0x00, 0xFE, 0x00, 0x00, 0xFE, 0x00, 0x00,
|
||||
0xFE, 0x00, 0x00, 0x00, 0x1F, 0xF0, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xE0,
|
||||
0x00, 0x00, 0x1F, 0xFF, 0xFF, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xF8, 0x00,
|
||||
0x03, 0xFE, 0x01, 0xFF, 0x80, 0x01, 0xFE, 0x00, 0x07, 0xF8, 0x00, 0x7F,
|
||||
0x80, 0x00, 0x3F, 0x80, 0x1F, 0xC0, 0x00, 0x03, 0xF8, 0x07, 0xF0, 0x00,
|
||||
0x00, 0x1F, 0x00, 0xFC, 0x00, 0x00, 0x01, 0xF0, 0x3F, 0x00, 0x00, 0x00,
|
||||
0x3E, 0x0F, 0xC0, 0x07, 0xE3, 0xC3, 0xE1, 0xF0, 0x03, 0xFE, 0xF8, 0x3C,
|
||||
0x7E, 0x01, 0xFF, 0xFF, 0x07, 0x8F, 0x80, 0x7E, 0x1F, 0xC0, 0x7B, 0xF0,
|
||||
0x1F, 0x81, 0xF8, 0x0F, 0x7C, 0x03, 0xE0, 0x1F, 0x01, 0xEF, 0x80, 0xF8,
|
||||
0x03, 0xC0, 0x3F, 0xF0, 0x1E, 0x00, 0x78, 0x07, 0xFC, 0x07, 0xC0, 0x0F,
|
||||
0x00, 0xFF, 0x80, 0xF0, 0x01, 0xE0, 0x1F, 0xF0, 0x1E, 0x00, 0x38, 0x07,
|
||||
0xFE, 0x07, 0xC0, 0x0F, 0x00, 0xFF, 0xC0, 0xF8, 0x01, 0xE0, 0x1E, 0xF8,
|
||||
0x1F, 0x00, 0x38, 0x07, 0xDF, 0x03, 0xE0, 0x0F, 0x00, 0xF3, 0xF0, 0x7C,
|
||||
0x03, 0xE0, 0x3E, 0x3E, 0x0F, 0xC0, 0xFC, 0x0F, 0x87, 0xC0, 0xFC, 0x3F,
|
||||
0xC7, 0xF0, 0xFC, 0x1F, 0xFF, 0xFF, 0xFC, 0x0F, 0xC1, 0xFF, 0xEF, 0xFF,
|
||||
0x01, 0xFC, 0x1F, 0xF8, 0xFF, 0x80, 0x1F, 0xC0, 0xFC, 0x07, 0xC0, 0x01,
|
||||
0xFC, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xC0, 0x00, 0x00, 0x00, 0x01, 0xFE,
|
||||
0x00, 0x00, 0x00, 0x00, 0x1F, 0xF8, 0x00, 0x60, 0x00, 0x01, 0xFF, 0xFF,
|
||||
0xFE, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x7F, 0xFF, 0xF0,
|
||||
0x00, 0x00, 0x00, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x0F, 0xF8, 0x00, 0x00,
|
||||
0x0F, 0xF8, 0x00, 0x00, 0x0F, 0xF8, 0x00, 0x00, 0x1F, 0xFC, 0x00, 0x00,
|
||||
0x1F, 0xFC, 0x00, 0x00, 0x1F, 0xFC, 0x00, 0x00, 0x3F, 0xFE, 0x00, 0x00,
|
||||
0x3F, 0xFE, 0x00, 0x00, 0x3F, 0x7E, 0x00, 0x00, 0x7F, 0x7F, 0x00, 0x00,
|
||||
0x7F, 0x7F, 0x00, 0x00, 0x7E, 0x3F, 0x00, 0x00, 0xFE, 0x3F, 0x80, 0x00,
|
||||
0xFE, 0x3F, 0x80, 0x01, 0xFC, 0x1F, 0x80, 0x01, 0xFC, 0x1F, 0xC0, 0x01,
|
||||
0xF8, 0x1F, 0xC0, 0x03, 0xF8, 0x0F, 0xE0, 0x03, 0xF8, 0x0F, 0xE0, 0x03,
|
||||
0xF0, 0x0F, 0xE0, 0x07, 0xF0, 0x07, 0xF0, 0x07, 0xFF, 0xFF, 0xF0, 0x07,
|
||||
0xFF, 0xFF, 0xF0, 0x0F, 0xFF, 0xFF, 0xF8, 0x0F, 0xFF, 0xFF, 0xF8, 0x1F,
|
||||
0xFF, 0xFF, 0xF8, 0x1F, 0xFF, 0xFF, 0xFC, 0x1F, 0xC0, 0x01, 0xFC, 0x3F,
|
||||
0x80, 0x01, 0xFC, 0x3F, 0x80, 0x00, 0xFE, 0x3F, 0x80, 0x00, 0xFE, 0x7F,
|
||||
0x00, 0x00, 0xFE, 0x7F, 0x00, 0x00, 0x7F, 0x7F, 0x00, 0x00, 0x7F, 0xFF,
|
||||
0xFF, 0xE0, 0x1F, 0xFF, 0xFF, 0x83, 0xFF, 0xFF, 0xF8, 0x7F, 0xFF, 0xFF,
|
||||
0x8F, 0xFF, 0xFF, 0xF9, 0xFF, 0xFF, 0xFF, 0x3F, 0x80, 0x1F, 0xF7, 0xF0,
|
||||
0x01, 0xFE, 0xFE, 0x00, 0x1F, 0xDF, 0xC0, 0x03, 0xFB, 0xF8, 0x00, 0x7F,
|
||||
0x7F, 0x00, 0x1F, 0xCF, 0xE0, 0x07, 0xF9, 0xFF, 0xFF, 0xFE, 0x3F, 0xFF,
|
||||
0xFF, 0x87, 0xFF, 0xFF, 0xC0, 0xFF, 0xFF, 0xFE, 0x1F, 0xFF, 0xFF, 0xE3,
|
||||
0xFF, 0xFF, 0xFE, 0x7F, 0x00, 0x1F, 0xEF, 0xE0, 0x01, 0xFD, 0xFC, 0x00,
|
||||
0x1F, 0xFF, 0x80, 0x03, 0xFF, 0xF0, 0x00, 0x7F, 0xFE, 0x00, 0x0F, 0xFF,
|
||||
0xC0, 0x01, 0xFF, 0xF8, 0x00, 0x7F, 0xFF, 0x00, 0x1F, 0xEF, 0xFF, 0xFF,
|
||||
0xFD, 0xFF, 0xFF, 0xFF, 0x3F, 0xFF, 0xFF, 0xE7, 0xFF, 0xFF, 0xF8, 0xFF,
|
||||
0xFF, 0xFC, 0x1F, 0xFF, 0xFC, 0x00, 0x00, 0x1F, 0xF0, 0x00, 0x03, 0xFF,
|
||||
0xF8, 0x00, 0x1F, 0xFF, 0xF8, 0x01, 0xFF, 0xFF, 0xF0, 0x0F, 0xFF, 0xFF,
|
||||
0xE0, 0x3F, 0xFF, 0xFF, 0xC1, 0xFF, 0x81, 0xFF, 0x0F, 0xF8, 0x01, 0xFE,
|
||||
0x3F, 0xC0, 0x07, 0xF9, 0xFE, 0x00, 0x0F, 0xE7, 0xF8, 0x00, 0x1F, 0xDF,
|
||||
0xC0, 0x00, 0x7F, 0x7F, 0x00, 0x00, 0x03, 0xF8, 0x00, 0x00, 0x0F, 0xE0,
|
||||
0x00, 0x00, 0x3F, 0x80, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x03, 0xF8, 0x00,
|
||||
0x00, 0x0F, 0xE0, 0x00, 0x00, 0x3F, 0x80, 0x00, 0x00, 0xFE, 0x00, 0x00,
|
||||
0x03, 0xF8, 0x00, 0x00, 0x0F, 0xE0, 0x00, 0x00, 0x1F, 0xC0, 0x00, 0x00,
|
||||
0x7F, 0x00, 0x01, 0xFD, 0xFC, 0x00, 0x07, 0xF7, 0xF8, 0x00, 0x3F, 0xCF,
|
||||
0xF0, 0x00, 0xFE, 0x3F, 0xE0, 0x07, 0xF8, 0x7F, 0xE0, 0x7F, 0xC0, 0xFF,
|
||||
0xFF, 0xFF, 0x03, 0xFF, 0xFF, 0xF8, 0x07, 0xFF, 0xFF, 0xC0, 0x07, 0xFF,
|
||||
0xFE, 0x00, 0x0F, 0xFF, 0xE0, 0x00, 0x07, 0xFC, 0x00, 0xFF, 0xFF, 0xC0,
|
||||
0x0F, 0xFF, 0xFF, 0x80, 0xFF, 0xFF, 0xFC, 0x0F, 0xFF, 0xFF, 0xE0, 0xFF,
|
||||
0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0xF8, 0xFE, 0x00, 0xFF, 0xCF, 0xE0, 0x03,
|
||||
0xFC, 0xFE, 0x00, 0x1F, 0xEF, 0xE0, 0x01, 0xFE, 0xFE, 0x00, 0x0F, 0xEF,
|
||||
0xE0, 0x00, 0xFE, 0xFE, 0x00, 0x07, 0xFF, 0xE0, 0x00, 0x7F, 0xFE, 0x00,
|
||||
0x07, 0xFF, 0xE0, 0x00, 0x7F, 0xFE, 0x00, 0x07, 0xFF, 0xE0, 0x00, 0x7F,
|
||||
0xFE, 0x00, 0x07, 0xFF, 0xE0, 0x00, 0x7F, 0xFE, 0x00, 0x07, 0xFF, 0xE0,
|
||||
0x00, 0x7F, 0xFE, 0x00, 0x0F, 0xEF, 0xE0, 0x00, 0xFE, 0xFE, 0x00, 0x1F,
|
||||
0xEF, 0xE0, 0x01, 0xFE, 0xFE, 0x00, 0x3F, 0xCF, 0xE0, 0x0F, 0xFC, 0xFF,
|
||||
0xFF, 0xFF, 0x8F, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0xFE, 0x0F, 0xFF, 0xFF,
|
||||
0xC0, 0xFF, 0xFF, 0xF8, 0x0F, 0xFF, 0xFC, 0x00, 0xFF, 0xFF, 0xFF, 0x7F,
|
||||
0xFF, 0xFF, 0xBF, 0xFF, 0xFF, 0xDF, 0xFF, 0xFF, 0xEF, 0xFF, 0xFF, 0xF7,
|
||||
0xFF, 0xFF, 0xFB, 0xF8, 0x00, 0x01, 0xFC, 0x00, 0x00, 0xFE, 0x00, 0x00,
|
||||
0x7F, 0x00, 0x00, 0x3F, 0x80, 0x00, 0x1F, 0xC0, 0x00, 0x0F, 0xE0, 0x00,
|
||||
0x07, 0xFF, 0xFF, 0xF3, 0xFF, 0xFF, 0xF9, 0xFF, 0xFF, 0xFC, 0xFF, 0xFF,
|
||||
0xFE, 0x7F, 0xFF, 0xFF, 0x3F, 0xFF, 0xFF, 0x9F, 0xC0, 0x00, 0x0F, 0xE0,
|
||||
0x00, 0x07, 0xF0, 0x00, 0x03, 0xF8, 0x00, 0x01, 0xFC, 0x00, 0x00, 0xFE,
|
||||
0x00, 0x00, 0x7F, 0x00, 0x00, 0x3F, 0x80, 0x00, 0x1F, 0xC0, 0x00, 0x0F,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFE, 0x00, 0x00, 0xFE, 0x00, 0x00, 0xFE, 0x00, 0x00, 0xFE, 0x00,
|
||||
0x00, 0xFE, 0x00, 0x00, 0xFE, 0x00, 0x00, 0xFE, 0x00, 0x00, 0xFF, 0xFF,
|
||||
0xFC, 0xFF, 0xFF, 0xFC, 0xFF, 0xFF, 0xFC, 0xFF, 0xFF, 0xFC, 0xFF, 0xFF,
|
||||
0xFC, 0xFF, 0xFF, 0xFC, 0xFE, 0x00, 0x00, 0xFE, 0x00, 0x00, 0xFE, 0x00,
|
||||
0x00, 0xFE, 0x00, 0x00, 0xFE, 0x00, 0x00, 0xFE, 0x00, 0x00, 0xFE, 0x00,
|
||||
0x00, 0xFE, 0x00, 0x00, 0xFE, 0x00, 0x00, 0xFE, 0x00, 0x00, 0xFE, 0x00,
|
||||
0x00, 0xFE, 0x00, 0x00, 0xFE, 0x00, 0x00, 0xFE, 0x00, 0x00, 0xFE, 0x00,
|
||||
0x00, 0x00, 0x0F, 0xF8, 0x00, 0x00, 0xFF, 0xFE, 0x00, 0x07, 0xFF, 0xFF,
|
||||
0x00, 0x1F, 0xFF, 0xFF, 0x00, 0x7F, 0xFF, 0xFF, 0x01, 0xFF, 0xFF, 0xFF,
|
||||
0x07, 0xFE, 0x03, 0xFF, 0x0F, 0xF0, 0x01, 0xFE, 0x3F, 0xC0, 0x01, 0xFC,
|
||||
0x7F, 0x00, 0x01, 0xFD, 0xFE, 0x00, 0x03, 0xFB, 0xF8, 0x00, 0x00, 0x07,
|
||||
0xF0, 0x00, 0x00, 0x1F, 0xC0, 0x00, 0x00, 0x3F, 0x80, 0x00, 0x00, 0x7F,
|
||||
0x00, 0x00, 0x00, 0xFE, 0x00, 0x3F, 0xFF, 0xFC, 0x00, 0x7F, 0xFF, 0xF8,
|
||||
0x00, 0xFF, 0xFF, 0xF0, 0x01, 0xFF, 0xFF, 0xE0, 0x03, 0xFF, 0xFF, 0xC0,
|
||||
0x07, 0xFF, 0xFF, 0xC0, 0x00, 0x1F, 0xBF, 0x80, 0x00, 0x3F, 0x7F, 0x00,
|
||||
0x00, 0x7E, 0xFF, 0x00, 0x01, 0xFC, 0xFF, 0x00, 0x03, 0xF9, 0xFF, 0x00,
|
||||
0x0F, 0xF1, 0xFF, 0x00, 0x3F, 0xE3, 0xFF, 0x83, 0xFF, 0xC3, 0xFF, 0xFF,
|
||||
0xFF, 0x83, 0xFF, 0xFF, 0xDF, 0x03, 0xFF, 0xFF, 0x9E, 0x03, 0xFF, 0xFE,
|
||||
0x3C, 0x01, 0xFF, 0xF0, 0x78, 0x00, 0x7F, 0x80, 0x00, 0xFE, 0x00, 0x0F,
|
||||
0xFF, 0xC0, 0x01, 0xFF, 0xF8, 0x00, 0x3F, 0xFF, 0x00, 0x07, 0xFF, 0xE0,
|
||||
0x00, 0xFF, 0xFC, 0x00, 0x1F, 0xFF, 0x80, 0x03, 0xFF, 0xF0, 0x00, 0x7F,
|
||||
0xFE, 0x00, 0x0F, 0xFF, 0xC0, 0x01, 0xFF, 0xF8, 0x00, 0x3F, 0xFF, 0x00,
|
||||
0x07, 0xFF, 0xE0, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0x00, 0x07, 0xFF, 0xE0, 0x00, 0xFF, 0xFC, 0x00, 0x1F, 0xFF,
|
||||
0x80, 0x03, 0xFF, 0xF0, 0x00, 0x7F, 0xFE, 0x00, 0x0F, 0xFF, 0xC0, 0x01,
|
||||
0xFF, 0xF8, 0x00, 0x3F, 0xFF, 0x00, 0x07, 0xFF, 0xE0, 0x00, 0xFF, 0xFC,
|
||||
0x00, 0x1F, 0xFF, 0x80, 0x03, 0xFF, 0xF0, 0x00, 0x7F, 0xFE, 0x00, 0x0F,
|
||||
0xFF, 0xC0, 0x01, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x01,
|
||||
0xFC, 0x00, 0x07, 0xF0, 0x00, 0x1F, 0xC0, 0x00, 0x7F, 0x00, 0x01, 0xFC,
|
||||
0x00, 0x07, 0xF0, 0x00, 0x1F, 0xC0, 0x00, 0x7F, 0x00, 0x01, 0xFC, 0x00,
|
||||
0x07, 0xF0, 0x00, 0x1F, 0xC0, 0x00, 0x7F, 0x00, 0x01, 0xFC, 0x00, 0x07,
|
||||
0xF0, 0x00, 0x1F, 0xC0, 0x00, 0x7F, 0x00, 0x01, 0xFC, 0x00, 0x07, 0xF0,
|
||||
0x00, 0x1F, 0xC0, 0x00, 0x7F, 0x00, 0x01, 0xFC, 0x00, 0x07, 0xFF, 0xE0,
|
||||
0x1F, 0xFF, 0x80, 0x7F, 0xFE, 0x01, 0xFF, 0xF8, 0x07, 0xFF, 0xE0, 0x1F,
|
||||
0xFF, 0xC0, 0xFF, 0xFF, 0x87, 0xFD, 0xFF, 0xFF, 0xE7, 0xFF, 0xFF, 0x8F,
|
||||
0xFF, 0xFC, 0x1F, 0xFF, 0xE0, 0x3F, 0xFF, 0x00, 0x1F, 0xE0, 0x00, 0xFE,
|
||||
0x00, 0x0F, 0xF3, 0xF8, 0x00, 0x7F, 0x8F, 0xE0, 0x03, 0xFC, 0x3F, 0x80,
|
||||
0x1F, 0xE0, 0xFE, 0x00, 0xFF, 0x83, 0xF8, 0x07, 0xFC, 0x0F, 0xE0, 0x1F,
|
||||
0xE0, 0x3F, 0x80, 0xFF, 0x00, 0xFE, 0x07, 0xF8, 0x03, 0xF8, 0x3F, 0xC0,
|
||||
0x0F, 0xE1, 0xFE, 0x00, 0x3F, 0x8F, 0xF0, 0x00, 0xFE, 0x7F, 0x80, 0x03,
|
||||
0xFB, 0xFC, 0x00, 0x0F, 0xFF, 0xE0, 0x00, 0x3F, 0xFF, 0xC0, 0x00, 0xFF,
|
||||
0xFF, 0x00, 0x03, 0xFF, 0xFE, 0x00, 0x0F, 0xFF, 0xFC, 0x00, 0x3F, 0xF7,
|
||||
0xF8, 0x00, 0xFF, 0x8F, 0xF0, 0x03, 0xFC, 0x3F, 0xC0, 0x0F, 0xE0, 0x7F,
|
||||
0x80, 0x3F, 0x80, 0xFF, 0x00, 0xFE, 0x01, 0xFE, 0x03, 0xF8, 0x07, 0xFC,
|
||||
0x0F, 0xE0, 0x0F, 0xF0, 0x3F, 0x80, 0x1F, 0xE0, 0xFE, 0x00, 0x3F, 0xC3,
|
||||
0xF8, 0x00, 0xFF, 0x8F, 0xE0, 0x01, 0xFE, 0x3F, 0x80, 0x03, 0xFC, 0xFE,
|
||||
0x00, 0x07, 0xFB, 0xF8, 0x00, 0x1F, 0xF0, 0xFE, 0x00, 0x01, 0xFC, 0x00,
|
||||
0x03, 0xF8, 0x00, 0x07, 0xF0, 0x00, 0x0F, 0xE0, 0x00, 0x1F, 0xC0, 0x00,
|
||||
0x3F, 0x80, 0x00, 0x7F, 0x00, 0x00, 0xFE, 0x00, 0x01, 0xFC, 0x00, 0x03,
|
||||
0xF8, 0x00, 0x07, 0xF0, 0x00, 0x0F, 0xE0, 0x00, 0x1F, 0xC0, 0x00, 0x3F,
|
||||
0x80, 0x00, 0x7F, 0x00, 0x00, 0xFE, 0x00, 0x01, 0xFC, 0x00, 0x03, 0xF8,
|
||||
0x00, 0x07, 0xF0, 0x00, 0x0F, 0xE0, 0x00, 0x1F, 0xC0, 0x00, 0x3F, 0x80,
|
||||
0x00, 0x7F, 0x00, 0x00, 0xFE, 0x00, 0x01, 0xFC, 0x00, 0x03, 0xF8, 0x00,
|
||||
0x07, 0xF0, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFF, 0xE0, 0x03,
|
||||
0xFF, 0xFF, 0xF0, 0x01, 0xFF, 0xFF, 0xF8, 0x00, 0xFF, 0xFF, 0xFC, 0x00,
|
||||
0x7F, 0xFF, 0xFE, 0x00, 0x7F, 0xFF, 0xFF, 0x80, 0x3F, 0xFF, 0xFF, 0xC0,
|
||||
0x1F, 0xFF, 0xFF, 0xE0, 0x0F, 0xFF, 0xFF, 0xF0, 0x07, 0xFF, 0xFF, 0xFC,
|
||||
0x07, 0xFF, 0xFF, 0xBE, 0x03, 0xEF, 0xFF, 0xDF, 0x01, 0xF7, 0xFF, 0xEF,
|
||||
0x80, 0xFB, 0xFF, 0xF7, 0xC0, 0xFD, 0xFF, 0xFB, 0xF0, 0x7C, 0xFF, 0xFC,
|
||||
0xF8, 0x3E, 0x7F, 0xFE, 0x7C, 0x1F, 0x3F, 0xFF, 0x3E, 0x0F, 0x9F, 0xFF,
|
||||
0x9F, 0x8F, 0x8F, 0xFF, 0xC7, 0xC7, 0xC7, 0xFF, 0xE3, 0xE3, 0xE3, 0xFF,
|
||||
0xF1, 0xF1, 0xF1, 0xFF, 0xF8, 0xFC, 0xF8, 0xFF, 0xFC, 0x3E, 0xF8, 0x7F,
|
||||
0xFE, 0x1F, 0x7C, 0x3F, 0xFF, 0x0F, 0xBE, 0x1F, 0xFF, 0x87, 0xDF, 0x0F,
|
||||
0xFF, 0xC3, 0xFF, 0x07, 0xFF, 0xE0, 0xFF, 0x83, 0xFF, 0xF0, 0x7F, 0xC1,
|
||||
0xFF, 0xF8, 0x3F, 0xE0, 0xFF, 0xFC, 0x1F, 0xF0, 0x7F, 0xFE, 0x07, 0xF0,
|
||||
0x3F, 0xFF, 0x03, 0xF8, 0x1F, 0xC0, 0xFE, 0x00, 0x07, 0xFF, 0xF0, 0x00,
|
||||
0x7F, 0xFF, 0x80, 0x07, 0xFF, 0xF8, 0x00, 0x7F, 0xFF, 0xC0, 0x07, 0xFF,
|
||||
0xFC, 0x00, 0x7F, 0xFF, 0xE0, 0x07, 0xFF, 0xFF, 0x00, 0x7F, 0xFF, 0xF0,
|
||||
0x07, 0xFF, 0xFF, 0x80, 0x7F, 0xFF, 0xF8, 0x07, 0xFF, 0xEF, 0xC0, 0x7F,
|
||||
0xFE, 0xFE, 0x07, 0xFF, 0xE7, 0xE0, 0x7F, 0xFE, 0x7F, 0x07, 0xFF, 0xE3,
|
||||
0xF0, 0x7F, 0xFE, 0x1F, 0x87, 0xFF, 0xE1, 0xFC, 0x7F, 0xFE, 0x0F, 0xC7,
|
||||
0xFF, 0xE0, 0xFE, 0x7F, 0xFE, 0x07, 0xE7, 0xFF, 0xE0, 0x3F, 0x7F, 0xFE,
|
||||
0x03, 0xFF, 0xFF, 0xE0, 0x1F, 0xFF, 0xFE, 0x01, 0xFF, 0xFF, 0xE0, 0x0F,
|
||||
0xFF, 0xFE, 0x00, 0x7F, 0xFF, 0xE0, 0x07, 0xFF, 0xFE, 0x00, 0x3F, 0xFF,
|
||||
0xE0, 0x03, 0xFF, 0xFE, 0x00, 0x1F, 0xFF, 0xE0, 0x00, 0xFF, 0xFE, 0x00,
|
||||
0x0F, 0xFF, 0xE0, 0x00, 0x7F, 0x00, 0x0F, 0xF8, 0x00, 0x00, 0x3F, 0xFF,
|
||||
0x80, 0x00, 0x7F, 0xFF, 0xE0, 0x00, 0x7F, 0xFF, 0xFC, 0x00, 0x7F, 0xFF,
|
||||
0xFF, 0x00, 0x7F, 0xFF, 0xFF, 0xC0, 0x7F, 0xE0, 0x3F, 0xF0, 0x3F, 0xC0,
|
||||
0x0F, 0xF8, 0x3F, 0xC0, 0x01, 0xFE, 0x1F, 0xC0, 0x00, 0x7F, 0x1F, 0xE0,
|
||||
0x00, 0x3F, 0xCF, 0xE0, 0x00, 0x0F, 0xE7, 0xF0, 0x00, 0x07, 0xF7, 0xF8,
|
||||
0x00, 0x03, 0xFF, 0xF8, 0x00, 0x00, 0xFF, 0xFC, 0x00, 0x00, 0x7F, 0xFE,
|
||||
0x00, 0x00, 0x3F, 0xFF, 0x00, 0x00, 0x1F, 0xFF, 0x80, 0x00, 0x0F, 0xFF,
|
||||
0xC0, 0x00, 0x07, 0xFF, 0xE0, 0x00, 0x03, 0xFF, 0xF0, 0x00, 0x01, 0xFF,
|
||||
0xFC, 0x00, 0x01, 0xFE, 0xFE, 0x00, 0x00, 0xFE, 0x7F, 0x00, 0x00, 0x7F,
|
||||
0x3F, 0xC0, 0x00, 0x7F, 0x8F, 0xE0, 0x00, 0x3F, 0x87, 0xF8, 0x00, 0x3F,
|
||||
0xC1, 0xFE, 0x00, 0x3F, 0xC0, 0xFF, 0xC0, 0x7F, 0xE0, 0x3F, 0xFF, 0xFF,
|
||||
0xE0, 0x0F, 0xFF, 0xFF, 0xE0, 0x03, 0xFF, 0xFF, 0xE0, 0x00, 0xFF, 0xFF,
|
||||
0xE0, 0x00, 0x1F, 0xFF, 0xC0, 0x00, 0x01, 0xFF, 0x00, 0x00, 0xFF, 0xFF,
|
||||
0xE0, 0x3F, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0xE3, 0xFF, 0xFF, 0xFC, 0xFF,
|
||||
0xFF, 0xFF, 0xBF, 0xFF, 0xFF, 0xEF, 0xE0, 0x0F, 0xFB, 0xF8, 0x00, 0xFF,
|
||||
0xFE, 0x00, 0x1F, 0xFF, 0x80, 0x07, 0xFF, 0xE0, 0x01, 0xFF, 0xF8, 0x00,
|
||||
0x7F, 0xFE, 0x00, 0x1F, 0xFF, 0x80, 0x07, 0xFF, 0xE0, 0x03, 0xFF, 0xF8,
|
||||
0x03, 0xFE, 0xFF, 0xFF, 0xFF, 0xBF, 0xFF, 0xFF, 0xCF, 0xFF, 0xFF, 0xF3,
|
||||
0xFF, 0xFF, 0xF8, 0xFF, 0xFF, 0xF8, 0x3F, 0xFF, 0xF8, 0x0F, 0xE0, 0x00,
|
||||
0x03, 0xF8, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x3F, 0x80, 0x00, 0x0F, 0xE0,
|
||||
0x00, 0x03, 0xF8, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x3F, 0x80, 0x00, 0x0F,
|
||||
0xE0, 0x00, 0x03, 0xF8, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x3F, 0x80, 0x00,
|
||||
0x00, 0x00, 0x0F, 0xF8, 0x00, 0x00, 0x3F, 0xFF, 0x80, 0x00, 0x7F, 0xFF,
|
||||
0xE0, 0x00, 0x7F, 0xFF, 0xFC, 0x00, 0x7F, 0xFF, 0xFF, 0x00, 0x7F, 0xFF,
|
||||
0xFF, 0xC0, 0x7F, 0xE0, 0x3F, 0xF0, 0x3F, 0xC0, 0x07, 0xF8, 0x3F, 0xC0,
|
||||
0x01, 0xFE, 0x1F, 0xC0, 0x00, 0x7F, 0x1F, 0xE0, 0x00, 0x3F, 0xCF, 0xE0,
|
||||
0x00, 0x0F, 0xE7, 0xF0, 0x00, 0x07, 0xF7, 0xF8, 0x00, 0x03, 0xFF, 0xF8,
|
||||
0x00, 0x00, 0xFF, 0xFC, 0x00, 0x00, 0x7F, 0xFE, 0x00, 0x00, 0x3F, 0xFF,
|
||||
0x00, 0x00, 0x1F, 0xFF, 0x80, 0x00, 0x0F, 0xFF, 0xC0, 0x00, 0x07, 0xFF,
|
||||
0xE0, 0x00, 0x03, 0xFF, 0xF0, 0x00, 0x01, 0xFF, 0xFC, 0x00, 0x21, 0xFE,
|
||||
0xFE, 0x00, 0x38, 0xFE, 0x7F, 0x00, 0x3E, 0x7F, 0x3F, 0xC0, 0x3F, 0xFF,
|
||||
0x8F, 0xE0, 0x0F, 0xFF, 0x87, 0xF8, 0x03, 0xFF, 0xC1, 0xFE, 0x00, 0xFF,
|
||||
0xC0, 0xFF, 0xC0, 0x7F, 0xE0, 0x3F, 0xFF, 0xFF, 0xF0, 0x0F, 0xFF, 0xFF,
|
||||
0xFC, 0x03, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xC0, 0x1F, 0xFF,
|
||||
0xCF, 0xC0, 0x01, 0xFF, 0x03, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0xFF, 0xFF,
|
||||
0xF8, 0x0F, 0xFF, 0xFF, 0xE0, 0xFF, 0xFF, 0xFF, 0x8F, 0xFF, 0xFF, 0xF8,
|
||||
0xFF, 0xFF, 0xFF, 0xCF, 0xFF, 0xFF, 0xFC, 0xFE, 0x00, 0x3F, 0xEF, 0xE0,
|
||||
0x01, 0xFE, 0xFE, 0x00, 0x0F, 0xEF, 0xE0, 0x00, 0xFE, 0xFE, 0x00, 0x0F,
|
||||
0xEF, 0xE0, 0x00, 0xFE, 0xFE, 0x00, 0x0F, 0xEF, 0xE0, 0x01, 0xFC, 0xFE,
|
||||
0x00, 0x3F, 0xCF, 0xFF, 0xFF, 0xF8, 0xFF, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF,
|
||||
0xC0, 0xFF, 0xFF, 0xFE, 0x0F, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0xFF, 0x8F,
|
||||
0xE0, 0x07, 0xF8, 0xFE, 0x00, 0x1F, 0xCF, 0xE0, 0x01, 0xFC, 0xFE, 0x00,
|
||||
0x1F, 0xCF, 0xE0, 0x01, 0xFC, 0xFE, 0x00, 0x1F, 0xCF, 0xE0, 0x01, 0xFC,
|
||||
0xFE, 0x00, 0x1F, 0xCF, 0xE0, 0x01, 0xFC, 0xFE, 0x00, 0x1F, 0xCF, 0xE0,
|
||||
0x01, 0xFC, 0xFE, 0x00, 0x1F, 0xEF, 0xE0, 0x00, 0xFF, 0x00, 0xFF, 0xC0,
|
||||
0x00, 0x3F, 0xFF, 0x80, 0x0F, 0xFF, 0xFE, 0x01, 0xFF, 0xFF, 0xF0, 0x3F,
|
||||
0xFF, 0xFF, 0x87, 0xFF, 0xFF, 0xFC, 0x7F, 0xC0, 0xFF, 0xCF, 0xF0, 0x03,
|
||||
0xFE, 0xFE, 0x00, 0x1F, 0xEF, 0xE0, 0x00, 0xFE, 0xFE, 0x00, 0x0F, 0xEF,
|
||||
0xE0, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x0F, 0xFC, 0x00, 0x00, 0x7F, 0xFC,
|
||||
0x00, 0x07, 0xFF, 0xFE, 0x00, 0x3F, 0xFF, 0xFC, 0x01, 0xFF, 0xFF, 0xF0,
|
||||
0x07, 0xFF, 0xFF, 0xC0, 0x0F, 0xFF, 0xFE, 0x00, 0x07, 0xFF, 0xE0, 0x00,
|
||||
0x03, 0xFF, 0x00, 0x00, 0x0F, 0xF0, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x07,
|
||||
0xFF, 0xE0, 0x00, 0x7F, 0xFE, 0x00, 0x07, 0xFF, 0xE0, 0x00, 0xFF, 0xFF,
|
||||
0x00, 0x0F, 0xE7, 0xFC, 0x03, 0xFE, 0x7F, 0xFF, 0xFF, 0xE3, 0xFF, 0xFF,
|
||||
0xFC, 0x1F, 0xFF, 0xFF, 0x80, 0xFF, 0xFF, 0xF0, 0x03, 0xFF, 0xFC, 0x00,
|
||||
0x07, 0xFE, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0,
|
||||
0x0F, 0xE0, 0x00, 0x01, 0xFC, 0x00, 0x00, 0x3F, 0x80, 0x00, 0x07, 0xF0,
|
||||
0x00, 0x00, 0xFE, 0x00, 0x00, 0x1F, 0xC0, 0x00, 0x03, 0xF8, 0x00, 0x00,
|
||||
0x7F, 0x00, 0x00, 0x0F, 0xE0, 0x00, 0x01, 0xFC, 0x00, 0x00, 0x3F, 0x80,
|
||||
0x00, 0x07, 0xF0, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x1F, 0xC0, 0x00, 0x03,
|
||||
0xF8, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x0F, 0xE0, 0x00, 0x01, 0xFC, 0x00,
|
||||
0x00, 0x3F, 0x80, 0x00, 0x07, 0xF0, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x1F,
|
||||
0xC0, 0x00, 0x03, 0xF8, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x0F, 0xE0, 0x00,
|
||||
0x01, 0xFC, 0x00, 0x00, 0x3F, 0x80, 0x00, 0x07, 0xF0, 0x00, 0xFE, 0x00,
|
||||
0x0F, 0xFF, 0xC0, 0x01, 0xFF, 0xF8, 0x00, 0x3F, 0xFF, 0x00, 0x07, 0xFF,
|
||||
0xE0, 0x00, 0xFF, 0xFC, 0x00, 0x1F, 0xFF, 0x80, 0x03, 0xFF, 0xF0, 0x00,
|
||||
0x7F, 0xFE, 0x00, 0x0F, 0xFF, 0xC0, 0x01, 0xFF, 0xF8, 0x00, 0x3F, 0xFF,
|
||||
0x00, 0x07, 0xFF, 0xE0, 0x00, 0xFF, 0xFC, 0x00, 0x1F, 0xFF, 0x80, 0x03,
|
||||
0xFF, 0xF0, 0x00, 0x7F, 0xFE, 0x00, 0x0F, 0xFF, 0xC0, 0x01, 0xFF, 0xF8,
|
||||
0x00, 0x3F, 0xFF, 0x00, 0x07, 0xFF, 0xE0, 0x00, 0xFF, 0xFC, 0x00, 0x1F,
|
||||
0xFF, 0x80, 0x03, 0xFF, 0xF0, 0x00, 0x7F, 0xFE, 0x00, 0x0F, 0xFF, 0xC0,
|
||||
0x01, 0xFF, 0xFC, 0x00, 0x7F, 0xBF, 0xC0, 0x1F, 0xE7, 0xFC, 0x07, 0xFC,
|
||||
0x7F, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0xE0, 0xFF, 0xFF, 0xF8, 0x0F, 0xFF,
|
||||
0xFE, 0x00, 0x7F, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x00, 0xFE, 0x00, 0x03,
|
||||
0xFF, 0xF0, 0x00, 0x1F, 0xDF, 0xC0, 0x01, 0xFC, 0xFE, 0x00, 0x0F, 0xE7,
|
||||
0xF0, 0x00, 0x7F, 0x1F, 0xC0, 0x03, 0xF0, 0xFE, 0x00, 0x3F, 0x87, 0xF0,
|
||||
0x01, 0xFC, 0x1F, 0xC0, 0x0F, 0xC0, 0xFE, 0x00, 0xFE, 0x03, 0xF0, 0x07,
|
||||
0xF0, 0x1F, 0x80, 0x3F, 0x00, 0xFE, 0x03, 0xF8, 0x03, 0xF0, 0x1F, 0xC0,
|
||||
0x1F, 0x80, 0xFC, 0x00, 0xFE, 0x07, 0xE0, 0x03, 0xF0, 0x7F, 0x00, 0x1F,
|
||||
0x83, 0xF0, 0x00, 0xFE, 0x1F, 0x80, 0x03, 0xF1, 0xF8, 0x00, 0x1F, 0x8F,
|
||||
0xC0, 0x00, 0xFC, 0x7E, 0x00, 0x03, 0xF3, 0xE0, 0x00, 0x1F, 0xBF, 0x00,
|
||||
0x00, 0xFD, 0xF8, 0x00, 0x03, 0xFF, 0x80, 0x00, 0x1F, 0xFC, 0x00, 0x00,
|
||||
0xFF, 0xE0, 0x00, 0x03, 0xFE, 0x00, 0x00, 0x1F, 0xF0, 0x00, 0x00, 0xFF,
|
||||
0x80, 0x00, 0x03, 0xF8, 0x00, 0x00, 0x1F, 0xC0, 0x00, 0x00, 0xFE, 0x00,
|
||||
0x00, 0xFF, 0x00, 0x3F, 0x80, 0x1F, 0xFF, 0xE0, 0x07, 0xF0, 0x03, 0xFD,
|
||||
0xFC, 0x01, 0xFE, 0x00, 0x7F, 0x3F, 0x80, 0x3F, 0xE0, 0x0F, 0xE7, 0xF0,
|
||||
0x07, 0xFC, 0x01, 0xFC, 0x7F, 0x00, 0xFF, 0x80, 0x7F, 0x8F, 0xE0, 0x1F,
|
||||
0xF0, 0x0F, 0xE1, 0xFC, 0x07, 0xFF, 0x01, 0xFC, 0x3F, 0x80, 0xFB, 0xE0,
|
||||
0x3F, 0x83, 0xF0, 0x1F, 0x7C, 0x07, 0xE0, 0x7F, 0x03, 0xEF, 0x81, 0xFC,
|
||||
0x0F, 0xE0, 0x7D, 0xF0, 0x3F, 0x80, 0xFC, 0x1F, 0x9F, 0x07, 0xF0, 0x1F,
|
||||
0x83, 0xE3, 0xE0, 0xFC, 0x03, 0xF0, 0x7C, 0x7C, 0x1F, 0x80, 0x7F, 0x0F,
|
||||
0x8F, 0x87, 0xF0, 0x07, 0xE1, 0xF0, 0xF8, 0xFC, 0x00, 0xFC, 0x7E, 0x1F,
|
||||
0x1F, 0x80, 0x1F, 0x8F, 0x83, 0xE3, 0xF0, 0x01, 0xF9, 0xF0, 0x7C, 0x7E,
|
||||
0x00, 0x3F, 0x3E, 0x0F, 0x9F, 0x80, 0x07, 0xE7, 0xC0, 0xFB, 0xF0, 0x00,
|
||||
0xFD, 0xF0, 0x1F, 0x7E, 0x00, 0x0F, 0xBE, 0x03, 0xEF, 0xC0, 0x01, 0xFF,
|
||||
0xC0, 0x7D, 0xF0, 0x00, 0x3F, 0xF8, 0x0F, 0xFE, 0x00, 0x03, 0xFF, 0x00,
|
||||
0xFF, 0xC0, 0x00, 0x7F, 0xC0, 0x1F, 0xF0, 0x00, 0x0F, 0xF8, 0x03, 0xFE,
|
||||
0x00, 0x01, 0xFF, 0x00, 0x7F, 0xC0, 0x00, 0x1F, 0xE0, 0x07, 0xF8, 0x00,
|
||||
0x03, 0xFC, 0x00, 0xFE, 0x00, 0x00, 0x7F, 0x00, 0x1F, 0xC0, 0x00, 0x07,
|
||||
0xE0, 0x03, 0xF8, 0x00, 0x7F, 0x80, 0x07, 0xF9, 0xFF, 0x00, 0x3F, 0xC3,
|
||||
0xFC, 0x00, 0xFF, 0x07, 0xF8, 0x07, 0xF8, 0x1F, 0xE0, 0x1F, 0xC0, 0x3F,
|
||||
0xC0, 0xFF, 0x00, 0xFF, 0x07, 0xF8, 0x01, 0xFE, 0x1F, 0xE0, 0x03, 0xF8,
|
||||
0xFF, 0x00, 0x0F, 0xF3, 0xF8, 0x00, 0x1F, 0xDF, 0xE0, 0x00, 0x3F, 0xFF,
|
||||
0x00, 0x00, 0xFF, 0xF8, 0x00, 0x01, 0xFF, 0xE0, 0x00, 0x07, 0xFF, 0x00,
|
||||
0x00, 0x0F, 0xF8, 0x00, 0x00, 0x1F, 0xE0, 0x00, 0x00, 0xFF, 0x80, 0x00,
|
||||
0x03, 0xFF, 0x00, 0x00, 0x1F, 0xFC, 0x00, 0x00, 0x7F, 0xF8, 0x00, 0x03,
|
||||
0xFF, 0xF0, 0x00, 0x1F, 0xFF, 0xC0, 0x00, 0x7F, 0x7F, 0x80, 0x03, 0xF8,
|
||||
0xFF, 0x00, 0x1F, 0xE1, 0xFC, 0x00, 0x7F, 0x07, 0xF8, 0x03, 0xFC, 0x0F,
|
||||
0xF0, 0x1F, 0xE0, 0x3F, 0xC0, 0x7F, 0x80, 0x7F, 0x83, 0xFC, 0x01, 0xFE,
|
||||
0x0F, 0xF0, 0x03, 0xFC, 0x7F, 0x80, 0x0F, 0xFB, 0xFE, 0x00, 0x1F, 0xE0,
|
||||
0xFF, 0x00, 0x07, 0xFF, 0xF8, 0x00, 0x7F, 0x9F, 0xE0, 0x03, 0xFC, 0xFF,
|
||||
0x00, 0x3F, 0xC3, 0xFC, 0x01, 0xFE, 0x0F, 0xE0, 0x0F, 0xE0, 0x7F, 0x00,
|
||||
0xFF, 0x01, 0xFC, 0x07, 0xF0, 0x0F, 0xE0, 0x7F, 0x80, 0x3F, 0x83, 0xF8,
|
||||
0x01, 0xFC, 0x3F, 0xC0, 0x07, 0xF1, 0xFC, 0x00, 0x3F, 0x8F, 0xE0, 0x00,
|
||||
0xFE, 0xFE, 0x00, 0x07, 0xF7, 0xF0, 0x00, 0x1F, 0xFF, 0x00, 0x00, 0xFF,
|
||||
0xF8, 0x00, 0x03, 0xFF, 0x80, 0x00, 0x1F, 0xF8, 0x00, 0x00, 0x7F, 0xC0,
|
||||
0x00, 0x01, 0xFC, 0x00, 0x00, 0x0F, 0xE0, 0x00, 0x00, 0x7F, 0x00, 0x00,
|
||||
0x03, 0xF8, 0x00, 0x00, 0x1F, 0xC0, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x07,
|
||||
0xF0, 0x00, 0x00, 0x3F, 0x80, 0x00, 0x01, 0xFC, 0x00, 0x00, 0x0F, 0xE0,
|
||||
0x00, 0x00, 0x7F, 0x00, 0x00, 0x03, 0xF8, 0x00, 0x00, 0x1F, 0xC0, 0x00,
|
||||
0x00, 0xFE, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0,
|
||||
0x00, 0x03, 0xFC, 0x00, 0x01, 0xFE, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x7F,
|
||||
0x80, 0x00, 0x3F, 0xE0, 0x00, 0x0F, 0xF0, 0x00, 0x07, 0xF8, 0x00, 0x03,
|
||||
0xFC, 0x00, 0x01, 0xFE, 0x00, 0x00, 0xFF, 0x80, 0x00, 0x3F, 0xC0, 0x00,
|
||||
0x1F, 0xE0, 0x00, 0x0F, 0xF0, 0x00, 0x07, 0xF8, 0x00, 0x03, 0xFE, 0x00,
|
||||
0x00, 0xFF, 0x00, 0x00, 0x7F, 0x80, 0x00, 0x3F, 0xC0, 0x00, 0x1F, 0xE0,
|
||||
0x00, 0x0F, 0xF8, 0x00, 0x03, 0xFC, 0x00, 0x01, 0xFE, 0x00, 0x00, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFC, 0x3F, 0x87, 0xF0, 0xFE, 0x1F, 0xC3, 0xF8, 0x7F, 0x0F,
|
||||
0xE1, 0xFC, 0x3F, 0x87, 0xF0, 0xFE, 0x1F, 0xC3, 0xF8, 0x7F, 0x0F, 0xE1,
|
||||
0xFC, 0x3F, 0x87, 0xF0, 0xFE, 0x1F, 0xC3, 0xF8, 0x7F, 0x0F, 0xE1, 0xFC,
|
||||
0x3F, 0x87, 0xF0, 0xFE, 0x1F, 0xC3, 0xF8, 0x7F, 0x0F, 0xE1, 0xFC, 0x3F,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0xE0, 0x03, 0xC0, 0x07, 0x00,
|
||||
0x1C, 0x00, 0x78, 0x00, 0xE0, 0x03, 0x80, 0x0F, 0x00, 0x1C, 0x00, 0x70,
|
||||
0x01, 0xE0, 0x03, 0x80, 0x0E, 0x00, 0x38, 0x00, 0x70, 0x01, 0xC0, 0x07,
|
||||
0x00, 0x0E, 0x00, 0x38, 0x00, 0xE0, 0x01, 0xC0, 0x07, 0x00, 0x1C, 0x00,
|
||||
0x78, 0x00, 0xE0, 0x03, 0x80, 0x0F, 0x00, 0x1C, 0x00, 0x70, 0x01, 0xE0,
|
||||
0x03, 0x80, 0x0E, 0x00, 0x3C, 0x00, 0x70, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFE, 0x1F, 0xC3, 0xF8, 0x7F, 0x0F, 0xE1, 0xFC, 0x3F, 0x87, 0xF0,
|
||||
0xFE, 0x1F, 0xC3, 0xF8, 0x7F, 0x0F, 0xE1, 0xFC, 0x3F, 0x87, 0xF0, 0xFE,
|
||||
0x1F, 0xC3, 0xF8, 0x7F, 0x0F, 0xE1, 0xFC, 0x3F, 0x87, 0xF0, 0xFE, 0x1F,
|
||||
0xC3, 0xF8, 0x7F, 0x0F, 0xE1, 0xFC, 0x3F, 0x87, 0xF0, 0xFE, 0x1F, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0xFC, 0x00, 0x07, 0xF0,
|
||||
0x00, 0x1F, 0xC0, 0x00, 0xFF, 0x80, 0x03, 0xFE, 0x00, 0x0F, 0xFC, 0x00,
|
||||
0x7D, 0xF0, 0x01, 0xF7, 0xC0, 0x0F, 0xDF, 0x80, 0x3E, 0x3E, 0x00, 0xF8,
|
||||
0xFC, 0x07, 0xE1, 0xF0, 0x1F, 0x07, 0xC0, 0xFC, 0x1F, 0x83, 0xE0, 0x3E,
|
||||
0x0F, 0x80, 0xFC, 0x7E, 0x01, 0xF1, 0xF0, 0x07, 0xC7, 0xC0, 0x1F, 0xBE,
|
||||
0x00, 0x3E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x3E, 0x0F, 0x83, 0xC0, 0xF0, 0x38, 0x1E,
|
||||
0x01, 0xFF, 0x00, 0x0F, 0xFF, 0xC0, 0x1F, 0xFF, 0xF0, 0x3F, 0xFF, 0xF8,
|
||||
0x7F, 0xFF, 0xF8, 0x7F, 0xFF, 0xFC, 0x7F, 0x03, 0xFC, 0x7E, 0x01, 0xFC,
|
||||
0x00, 0x01, 0xFC, 0x00, 0x03, 0xFC, 0x00, 0x0F, 0xFC, 0x03, 0xFF, 0xFC,
|
||||
0x1F, 0xFF, 0xFC, 0x3F, 0xFF, 0xFC, 0x7F, 0xC1, 0xFC, 0xFF, 0x01, 0xFC,
|
||||
0xFE, 0x01, 0xFC, 0xFE, 0x03, 0xFC, 0xFE, 0x03, 0xFC, 0xFF, 0x07, 0xFC,
|
||||
0xFF, 0xFF, 0xFC, 0x7F, 0xFF, 0xFC, 0x7F, 0xFF, 0xFC, 0x3F, 0xFD, 0xFE,
|
||||
0x1F, 0xF0, 0xFF, 0x07, 0xE0, 0x00, 0xFE, 0x00, 0x00, 0x7F, 0x00, 0x00,
|
||||
0x3F, 0x80, 0x00, 0x1F, 0xC0, 0x00, 0x0F, 0xE0, 0x00, 0x07, 0xF0, 0x00,
|
||||
0x03, 0xF8, 0x00, 0x01, 0xFC, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x7F, 0x0F,
|
||||
0xC0, 0x3F, 0x9F, 0xF8, 0x1F, 0xDF, 0xFF, 0x0F, 0xFF, 0xFF, 0xC7, 0xFF,
|
||||
0xFF, 0xE3, 0xFF, 0xFF, 0xF9, 0xFF, 0x83, 0xFE, 0xFF, 0x80, 0xFF, 0x7F,
|
||||
0x80, 0x3F, 0xBF, 0xC0, 0x1F, 0xFF, 0xC0, 0x07, 0xFF, 0xE0, 0x03, 0xFF,
|
||||
0xF0, 0x01, 0xFF, 0xF8, 0x00, 0xFF, 0xFC, 0x00, 0x7F, 0xFE, 0x00, 0x3F,
|
||||
0xFF, 0x80, 0x3F, 0xFF, 0xC0, 0x1F, 0xDF, 0xF0, 0x1F, 0xEF, 0xFC, 0x1F,
|
||||
0xF7, 0xFF, 0xFF, 0xF3, 0xFF, 0xFF, 0xF1, 0xFF, 0xFF, 0xF8, 0xFE, 0xFF,
|
||||
0xF8, 0x7F, 0x3F, 0xF0, 0x00, 0x07, 0xE0, 0x00, 0x00, 0xFF, 0x00, 0x07,
|
||||
0xFF, 0xC0, 0x3F, 0xFF, 0xC0, 0xFF, 0xFF, 0xC3, 0xFF, 0xFF, 0xC7, 0xFF,
|
||||
0xFF, 0x9F, 0xF0, 0x7F, 0xBF, 0xC0, 0x7F, 0x7F, 0x00, 0x7F, 0xFC, 0x00,
|
||||
0x03, 0xF8, 0x00, 0x07, 0xF0, 0x00, 0x0F, 0xE0, 0x00, 0x1F, 0xC0, 0x00,
|
||||
0x3F, 0x80, 0x00, 0x7F, 0x00, 0x00, 0xFE, 0x00, 0x00, 0xFE, 0x00, 0xFD,
|
||||
0xFE, 0x03, 0xFB, 0xFE, 0x0F, 0xF3, 0xFF, 0xFF, 0xC7, 0xFF, 0xFF, 0x87,
|
||||
0xFF, 0xFE, 0x07, 0xFF, 0xF8, 0x03, 0xFF, 0xE0, 0x01, 0xFE, 0x00, 0x00,
|
||||
0x00, 0x3F, 0x80, 0x00, 0x1F, 0xC0, 0x00, 0x0F, 0xE0, 0x00, 0x07, 0xF0,
|
||||
0x00, 0x03, 0xF8, 0x00, 0x01, 0xFC, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x7F,
|
||||
0x00, 0x00, 0x3F, 0x80, 0x7E, 0x1F, 0xC0, 0xFF, 0xCF, 0xE1, 0xFF, 0xF7,
|
||||
0xF1, 0xFF, 0xFF, 0xF8, 0xFF, 0xFF, 0xFC, 0xFF, 0xFF, 0xFE, 0xFF, 0x83,
|
||||
0xFF, 0x7F, 0x80, 0xFF, 0xBF, 0x80, 0x3F, 0xFF, 0xC0, 0x1F, 0xFF, 0xC0,
|
||||
0x07, 0xFF, 0xE0, 0x03, 0xFF, 0xF0, 0x01, 0xFF, 0xF8, 0x00, 0xFF, 0xFC,
|
||||
0x00, 0x7F, 0xFE, 0x00, 0x3F, 0xFF, 0x80, 0x3F, 0xDF, 0xC0, 0x1F, 0xEF,
|
||||
0xF0, 0x1F, 0xF7, 0xFC, 0x1F, 0xF9, 0xFF, 0xFF, 0xFC, 0xFF, 0xFF, 0xFE,
|
||||
0x3F, 0xFF, 0xFF, 0x0F, 0xFF, 0xBF, 0x81, 0xFF, 0x9F, 0xC0, 0x3F, 0x00,
|
||||
0x00, 0x00, 0xFE, 0x00, 0x03, 0xFF, 0x80, 0x0F, 0xFF, 0xE0, 0x1F, 0xFF,
|
||||
0xF0, 0x3F, 0xFF, 0xF8, 0x3F, 0xC3, 0xF8, 0x7F, 0x80, 0xFC, 0x7F, 0x00,
|
||||
0xFC, 0x7F, 0x00, 0x7C, 0xFE, 0x00, 0x7E, 0xFE, 0x00, 0x7E, 0xFF, 0xFF,
|
||||
0xFE, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFE, 0xFE, 0x00,
|
||||
0x00, 0xFE, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x7F, 0x00, 0x7F, 0x7F, 0x00,
|
||||
0xFE, 0x3F, 0xC1, 0xFE, 0x3F, 0xFF, 0xFC, 0x1F, 0xFF, 0xF8, 0x0F, 0xFF,
|
||||
0xF0, 0x03, 0xFF, 0xC0, 0x00, 0xFF, 0x00, 0x01, 0xFC, 0x1F, 0xF0, 0xFF,
|
||||
0xC3, 0xFF, 0x1F, 0xFC, 0x7F, 0x81, 0xFC, 0x07, 0xF0, 0x1F, 0xC0, 0x7F,
|
||||
0x0F, 0xFF, 0xBF, 0xFE, 0xFF, 0xFB, 0xFF, 0xE1, 0xFC, 0x07, 0xF0, 0x1F,
|
||||
0xC0, 0x7F, 0x01, 0xFC, 0x07, 0xF0, 0x1F, 0xC0, 0x7F, 0x01, 0xFC, 0x07,
|
||||
0xF0, 0x1F, 0xC0, 0x7F, 0x01, 0xFC, 0x07, 0xF0, 0x1F, 0xC0, 0x7F, 0x01,
|
||||
0xFC, 0x07, 0xF0, 0x1F, 0xC0, 0x7F, 0x00, 0x00, 0xF8, 0x7F, 0x07, 0xFE,
|
||||
0x7F, 0x0F, 0xFF, 0x7F, 0x1F, 0xFF, 0x7F, 0x3F, 0xFF, 0xFF, 0x3F, 0xFF,
|
||||
0xFF, 0x7F, 0xC3, 0xFF, 0x7F, 0x81, 0xFF, 0x7F, 0x00, 0xFF, 0xFF, 0x00,
|
||||
0xFF, 0xFE, 0x00, 0x7F, 0xFE, 0x00, 0x7F, 0xFE, 0x00, 0x7F, 0xFE, 0x00,
|
||||
0x7F, 0xFE, 0x00, 0x7F, 0xFE, 0x00, 0x7F, 0xFE, 0x00, 0xFF, 0xFF, 0x00,
|
||||
0xFF, 0x7F, 0x81, 0xFF, 0x7F, 0xC3, 0xFF, 0x3F, 0xFF, 0xFF, 0x3F, 0xFF,
|
||||
0xFF, 0x1F, 0xFF, 0xFF, 0x0F, 0xFF, 0x7F, 0x07, 0xFE, 0x7F, 0x01, 0xF8,
|
||||
0x7F, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x7F, 0x7F, 0x00,
|
||||
0xFF, 0x7F, 0x01, 0xFE, 0x7F, 0xC3, 0xFE, 0x3F, 0xFF, 0xFC, 0x1F, 0xFF,
|
||||
0xF8, 0x0F, 0xFF, 0xE0, 0x01, 0xFF, 0x00, 0xFE, 0x00, 0x01, 0xFC, 0x00,
|
||||
0x03, 0xF8, 0x00, 0x07, 0xF0, 0x00, 0x0F, 0xE0, 0x00, 0x1F, 0xC0, 0x00,
|
||||
0x3F, 0x80, 0x00, 0x7F, 0x00, 0x00, 0xFE, 0x00, 0x01, 0xFC, 0x3F, 0x83,
|
||||
0xF8, 0xFF, 0xC7, 0xF7, 0xFF, 0xCF, 0xEF, 0xFF, 0xDF, 0xFF, 0xFF, 0xBF,
|
||||
0xFF, 0xFF, 0xFF, 0xE1, 0xFF, 0xFF, 0x01, 0xFF, 0xFE, 0x01, 0xFF, 0xF8,
|
||||
0x03, 0xFF, 0xF0, 0x07, 0xFF, 0xE0, 0x0F, 0xFF, 0xC0, 0x1F, 0xFF, 0x80,
|
||||
0x3F, 0xFF, 0x00, 0x7F, 0xFE, 0x00, 0xFF, 0xFC, 0x01, 0xFF, 0xF8, 0x03,
|
||||
0xFF, 0xF0, 0x07, 0xFF, 0xE0, 0x0F, 0xFF, 0xC0, 0x1F, 0xFF, 0x80, 0x3F,
|
||||
0xFF, 0x00, 0x7F, 0xFE, 0x00, 0xFF, 0xFC, 0x01, 0xFC, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xC0, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFC, 0x1F, 0xC7, 0xF1, 0xFC, 0x7F, 0x1F, 0xC7, 0xF0, 0x00,
|
||||
0x00, 0x00, 0x07, 0xF1, 0xFC, 0x7F, 0x1F, 0xC7, 0xF1, 0xFC, 0x7F, 0x1F,
|
||||
0xC7, 0xF1, 0xFC, 0x7F, 0x1F, 0xC7, 0xF1, 0xFC, 0x7F, 0x1F, 0xC7, 0xF1,
|
||||
0xFC, 0x7F, 0x1F, 0xC7, 0xF1, 0xFC, 0x7F, 0x1F, 0xC7, 0xF1, 0xFC, 0x7F,
|
||||
0x1F, 0xC7, 0xF1, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB, 0xFE, 0xFE, 0x00,
|
||||
0xFE, 0x00, 0x01, 0xFC, 0x00, 0x03, 0xF8, 0x00, 0x07, 0xF0, 0x00, 0x0F,
|
||||
0xE0, 0x00, 0x1F, 0xC0, 0x00, 0x3F, 0x80, 0x00, 0x7F, 0x00, 0x00, 0xFE,
|
||||
0x00, 0x01, 0xFC, 0x03, 0xFB, 0xF8, 0x0F, 0xE7, 0xF0, 0x3F, 0xCF, 0xE0,
|
||||
0xFF, 0x1F, 0xC3, 0xFC, 0x3F, 0x87, 0xF0, 0x7F, 0x1F, 0xC0, 0xFE, 0x7F,
|
||||
0x01, 0xFD, 0xFC, 0x03, 0xFF, 0xF0, 0x07, 0xFF, 0xF0, 0x0F, 0xFF, 0xE0,
|
||||
0x1F, 0xFF, 0xE0, 0x3F, 0xFF, 0xE0, 0x7F, 0xDF, 0xC0, 0xFF, 0x3F, 0xC1,
|
||||
0xFC, 0x3F, 0x83, 0xF8, 0x3F, 0x87, 0xF0, 0x7F, 0x8F, 0xE0, 0x7F, 0x1F,
|
||||
0xC0, 0xFF, 0x3F, 0x80, 0xFE, 0x7F, 0x01, 0xFE, 0xFE, 0x01, 0xFD, 0xFC,
|
||||
0x03, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFE, 0x1F, 0x80, 0x7E,
|
||||
0x0F, 0xE7, 0xFE, 0x1F, 0xF8, 0xFE, 0xFF, 0xF3, 0xFF, 0xCF, 0xFF, 0xFF,
|
||||
0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0x83, 0xFF, 0x0F, 0xFF, 0xF0, 0x1F, 0xE0, 0x7F, 0xFE, 0x01, 0xFC, 0x07,
|
||||
0xFF, 0xE0, 0x1F, 0xC0, 0x7F, 0xFE, 0x01, 0xFC, 0x07, 0xFF, 0xE0, 0x1F,
|
||||
0xC0, 0x7F, 0xFE, 0x01, 0xFC, 0x07, 0xFF, 0xE0, 0x1F, 0xC0, 0x7F, 0xFE,
|
||||
0x01, 0xFC, 0x07, 0xFF, 0xE0, 0x1F, 0xC0, 0x7F, 0xFE, 0x01, 0xFC, 0x07,
|
||||
0xFF, 0xE0, 0x1F, 0xC0, 0x7F, 0xFE, 0x01, 0xFC, 0x07, 0xFF, 0xE0, 0x1F,
|
||||
0xC0, 0x7F, 0xFE, 0x01, 0xFC, 0x07, 0xFF, 0xE0, 0x1F, 0xC0, 0x7F, 0xFE,
|
||||
0x01, 0xFC, 0x07, 0xFF, 0xE0, 0x1F, 0xC0, 0x7F, 0xFE, 0x01, 0xFC, 0x07,
|
||||
0xF0, 0xFE, 0x1F, 0xC1, 0xFC, 0xFF, 0xE3, 0xFB, 0xFF, 0xE7, 0xFF, 0xFF,
|
||||
0xEF, 0xFF, 0xFF, 0xDF, 0xFF, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0x80, 0xFF,
|
||||
0xFE, 0x00, 0xFF, 0xFC, 0x01, 0xFF, 0xF8, 0x03, 0xFF, 0xF0, 0x07, 0xFF,
|
||||
0xE0, 0x0F, 0xFF, 0xC0, 0x1F, 0xFF, 0x80, 0x3F, 0xFF, 0x00, 0x7F, 0xFE,
|
||||
0x00, 0xFF, 0xFC, 0x01, 0xFF, 0xF8, 0x03, 0xFF, 0xF0, 0x07, 0xFF, 0xE0,
|
||||
0x0F, 0xFF, 0xC0, 0x1F, 0xFF, 0x80, 0x3F, 0xFF, 0x00, 0x7F, 0xFE, 0x00,
|
||||
0xFE, 0x00, 0x7F, 0x80, 0x01, 0xFF, 0xF0, 0x01, 0xFF, 0xFE, 0x01, 0xFF,
|
||||
0xFF, 0x81, 0xFF, 0xFF, 0xE1, 0xFF, 0xFF, 0xF1, 0xFF, 0x07, 0xFC, 0xFF,
|
||||
0x01, 0xFE, 0x7F, 0x00, 0x7F, 0x7F, 0x80, 0x3F, 0xFF, 0x80, 0x0F, 0xFF,
|
||||
0xC0, 0x07, 0xFF, 0xE0, 0x03, 0xFF, 0xF0, 0x01, 0xFF, 0xF8, 0x00, 0xFF,
|
||||
0xFC, 0x00, 0x7F, 0xFF, 0x00, 0x7F, 0xBF, 0x80, 0x3F, 0x9F, 0xE0, 0x3F,
|
||||
0xCF, 0xF8, 0x3F, 0xE3, 0xFF, 0xFF, 0xE0, 0xFF, 0xFF, 0xF0, 0x3F, 0xFF,
|
||||
0xF0, 0x0F, 0xFF, 0xF0, 0x03, 0xFF, 0xE0, 0x00, 0x3F, 0xC0, 0x00, 0xFE,
|
||||
0x1F, 0x80, 0x7F, 0x3F, 0xF0, 0x3F, 0xBF, 0xFE, 0x1F, 0xDF, 0xFF, 0x8F,
|
||||
0xFF, 0xFF, 0xC7, 0xFF, 0xFF, 0xF3, 0xFF, 0x07, 0xFD, 0xFF, 0x01, 0xFE,
|
||||
0xFF, 0x00, 0x7F, 0x7F, 0x80, 0x3F, 0xFF, 0x80, 0x0F, 0xFF, 0xC0, 0x07,
|
||||
0xFF, 0xE0, 0x03, 0xFF, 0xF0, 0x01, 0xFF, 0xF8, 0x00, 0xFF, 0xFC, 0x00,
|
||||
0x7F, 0xFF, 0x00, 0x7F, 0xFF, 0x80, 0x3F, 0xBF, 0xE0, 0x3F, 0xDF, 0xF8,
|
||||
0x3F, 0xCF, 0xFF, 0xFF, 0xE7, 0xFF, 0xFF, 0xE3, 0xFB, 0xFF, 0xE1, 0xFD,
|
||||
0xFF, 0xF0, 0xFE, 0x7F, 0xE0, 0x7F, 0x0F, 0xC0, 0x3F, 0x80, 0x00, 0x1F,
|
||||
0xC0, 0x00, 0x0F, 0xE0, 0x00, 0x07, 0xF0, 0x00, 0x03, 0xF8, 0x00, 0x01,
|
||||
0xFC, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x3F, 0x80, 0x00,
|
||||
0x1F, 0xC0, 0x00, 0x00, 0x00, 0xFC, 0x3F, 0x81, 0xFF, 0x9F, 0xC3, 0xFF,
|
||||
0xEF, 0xE1, 0xFF, 0xF7, 0xF1, 0xFF, 0xFF, 0xF9, 0xFF, 0xFF, 0xFD, 0xFF,
|
||||
0x07, 0xFE, 0xFF, 0x01, 0xFF, 0x7F, 0x00, 0x7F, 0xFF, 0x80, 0x3F, 0xFF,
|
||||
0x80, 0x0F, 0xFF, 0xC0, 0x07, 0xFF, 0xE0, 0x03, 0xFF, 0xF0, 0x01, 0xFF,
|
||||
0xF8, 0x00, 0xFF, 0xFC, 0x00, 0x7F, 0xFF, 0x00, 0x7F, 0xBF, 0x80, 0x3F,
|
||||
0xDF, 0xE0, 0x3F, 0xEF, 0xF8, 0x3F, 0xF3, 0xFF, 0xFF, 0xF8, 0xFF, 0xFF,
|
||||
0xFC, 0x7F, 0xFE, 0xFE, 0x1F, 0xFF, 0x7F, 0x03, 0xFF, 0x3F, 0x80, 0x7E,
|
||||
0x1F, 0xC0, 0x00, 0x0F, 0xE0, 0x00, 0x07, 0xF0, 0x00, 0x03, 0xF8, 0x00,
|
||||
0x01, 0xFC, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x3F, 0x80,
|
||||
0x00, 0x1F, 0xC0, 0x00, 0x0F, 0xE0, 0x00, 0x07, 0xF0, 0xFE, 0x1F, 0xFC,
|
||||
0x7F, 0xFB, 0xFF, 0xF7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x7F, 0x80,
|
||||
0xFF, 0x01, 0xFC, 0x03, 0xF8, 0x07, 0xF0, 0x0F, 0xE0, 0x1F, 0xC0, 0x3F,
|
||||
0x80, 0x7F, 0x00, 0xFE, 0x01, 0xFC, 0x03, 0xF8, 0x07, 0xF0, 0x0F, 0xE0,
|
||||
0x1F, 0xC0, 0x3F, 0x80, 0x7F, 0x00, 0xFE, 0x00, 0x00, 0xFF, 0x00, 0x07,
|
||||
0xFF, 0xE0, 0x0F, 0xFF, 0xF8, 0x1F, 0xFF, 0xFC, 0x3F, 0xFF, 0xFC, 0x7F,
|
||||
0x81, 0xFE, 0x7F, 0x00, 0xFE, 0x7F, 0x00, 0xFE, 0x7F, 0xC0, 0x00, 0x7F,
|
||||
0xFC, 0x00, 0x7F, 0xFF, 0x80, 0x3F, 0xFF, 0xF0, 0x1F, 0xFF, 0xFC, 0x07,
|
||||
0xFF, 0xFE, 0x00, 0x7F, 0xFE, 0x00, 0x0F, 0xFF, 0x00, 0x01, 0xFF, 0x00,
|
||||
0x00, 0x7F, 0xFE, 0x00, 0x7F, 0x7F, 0x00, 0x7F, 0x7F, 0x81, 0xFE, 0x7F,
|
||||
0xFF, 0xFE, 0x3F, 0xFF, 0xFC, 0x1F, 0xFF, 0xF8, 0x0F, 0xFF, 0xF0, 0x01,
|
||||
0xFF, 0x80, 0x3F, 0x83, 0xF8, 0x3F, 0x83, 0xF8, 0x3F, 0x83, 0xF8, 0x3F,
|
||||
0x8F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF3, 0xF8, 0x3F, 0x83, 0xF8, 0x3F,
|
||||
0x83, 0xF8, 0x3F, 0x83, 0xF8, 0x3F, 0x83, 0xF8, 0x3F, 0x83, 0xF8, 0x3F,
|
||||
0x83, 0xF8, 0x3F, 0x83, 0xF8, 0x3F, 0x83, 0xFF, 0x3F, 0xF1, 0xFF, 0x0F,
|
||||
0xF0, 0x7F, 0xFE, 0x00, 0xFF, 0xFC, 0x01, 0xFF, 0xF8, 0x03, 0xFF, 0xF0,
|
||||
0x07, 0xFF, 0xE0, 0x0F, 0xFF, 0xC0, 0x1F, 0xFF, 0x80, 0x3F, 0xFF, 0x00,
|
||||
0x7F, 0xFE, 0x00, 0xFF, 0xFC, 0x01, 0xFF, 0xF8, 0x03, 0xFF, 0xF0, 0x07,
|
||||
0xFF, 0xE0, 0x0F, 0xFF, 0xC0, 0x1F, 0xFF, 0x80, 0x3F, 0xFF, 0x00, 0x7F,
|
||||
0xFE, 0x00, 0xFF, 0xFC, 0x03, 0xFF, 0xFC, 0x07, 0xFF, 0xFC, 0x3F, 0xFF,
|
||||
0xFF, 0xFF, 0xEF, 0xFF, 0xFF, 0xDF, 0xFF, 0xBF, 0x9F, 0xFF, 0x7F, 0x1F,
|
||||
0xFC, 0xFE, 0x0F, 0xE0, 0x00, 0x7F, 0x00, 0x3F, 0xBF, 0x80, 0x1F, 0x9F,
|
||||
0xC0, 0x1F, 0xC7, 0xE0, 0x0F, 0xE3, 0xF8, 0x07, 0xE1, 0xFC, 0x07, 0xF0,
|
||||
0x7E, 0x03, 0xF8, 0x3F, 0x81, 0xF8, 0x1F, 0xC0, 0xFC, 0x07, 0xE0, 0xFE,
|
||||
0x03, 0xF8, 0x7E, 0x00, 0xFC, 0x3F, 0x00, 0x7E, 0x1F, 0x80, 0x3F, 0x1F,
|
||||
0x80, 0x0F, 0xCF, 0xC0, 0x07, 0xE7, 0xE0, 0x03, 0xF7, 0xE0, 0x00, 0xFF,
|
||||
0xF0, 0x00, 0x7F, 0xF8, 0x00, 0x3F, 0xF8, 0x00, 0x0F, 0xFC, 0x00, 0x07,
|
||||
0xFE, 0x00, 0x03, 0xFE, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x7F, 0x00, 0x00,
|
||||
0xFC, 0x03, 0xF8, 0x0F, 0xFF, 0xC0, 0x7F, 0x01, 0xFF, 0xF8, 0x0F, 0xE0,
|
||||
0x3F, 0x3F, 0x03, 0xFE, 0x07, 0xE7, 0xE0, 0x7F, 0xC1, 0xFC, 0xFE, 0x0F,
|
||||
0xF8, 0x3F, 0x9F, 0xC1, 0xFF, 0x07, 0xE1, 0xF8, 0x3D, 0xE0, 0xFC, 0x3F,
|
||||
0x0F, 0xBE, 0x3F, 0x87, 0xF1, 0xF7, 0xC7, 0xE0, 0x7E, 0x3E, 0xF8, 0xFC,
|
||||
0x0F, 0xC7, 0xDF, 0x1F, 0x81, 0xF9, 0xF1, 0xE3, 0xF0, 0x3F, 0x3E, 0x3E,
|
||||
0xFC, 0x03, 0xF7, 0xC7, 0xDF, 0x80, 0x7E, 0xF8, 0xFB, 0xF0, 0x0F, 0xDE,
|
||||
0x1F, 0x7C, 0x00, 0xFF, 0xC1, 0xFF, 0x80, 0x1F, 0xF8, 0x3F, 0xF0, 0x03,
|
||||
0xFF, 0x07, 0xFE, 0x00, 0x7F, 0xC0, 0xFF, 0x80, 0x07, 0xF8, 0x1F, 0xF0,
|
||||
0x00, 0xFF, 0x01, 0xFE, 0x00, 0x1F, 0xE0, 0x3F, 0x80, 0x01, 0xFC, 0x07,
|
||||
0xF0, 0x00, 0xFF, 0x00, 0xFF, 0x7F, 0x81, 0xFE, 0x3F, 0x81, 0xFC, 0x3F,
|
||||
0xC3, 0xFC, 0x1F, 0xC3, 0xF8, 0x0F, 0xE7, 0xF0, 0x0F, 0xEF, 0xF0, 0x07,
|
||||
0xFF, 0xE0, 0x03, 0xFF, 0xC0, 0x03, 0xFF, 0xC0, 0x01, 0xFF, 0x80, 0x00,
|
||||
0xFF, 0x00, 0x00, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x80, 0x03,
|
||||
0xFF, 0xC0, 0x07, 0xFF, 0xC0, 0x07, 0xFF, 0xE0, 0x0F, 0xE7, 0xF0, 0x1F,
|
||||
0xE7, 0xF0, 0x1F, 0xC3, 0xF8, 0x3F, 0xC3, 0xFC, 0x7F, 0x81, 0xFC, 0x7F,
|
||||
0x01, 0xFE, 0xFF, 0x00, 0xFF, 0x7F, 0x00, 0x3F, 0xBF, 0x80, 0x1F, 0xDF,
|
||||
0xC0, 0x0F, 0xC7, 0xF0, 0x07, 0xE3, 0xF8, 0x07, 0xF1, 0xFC, 0x03, 0xF0,
|
||||
0x7F, 0x01, 0xF8, 0x3F, 0x81, 0xFC, 0x0F, 0xC0, 0xFC, 0x07, 0xF0, 0x7E,
|
||||
0x03, 0xF8, 0x3F, 0x00, 0xFC, 0x3F, 0x00, 0x7E, 0x1F, 0x80, 0x3F, 0x8F,
|
||||
0xC0, 0x0F, 0xCF, 0xC0, 0x07, 0xE7, 0xE0, 0x03, 0xFB, 0xF0, 0x00, 0xFD,
|
||||
0xF0, 0x00, 0x7F, 0xF8, 0x00, 0x3F, 0xFC, 0x00, 0x0F, 0xFC, 0x00, 0x07,
|
||||
0xFE, 0x00, 0x03, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x7F, 0x80, 0x00,
|
||||
0x1F, 0xC0, 0x00, 0x0F, 0xC0, 0x00, 0x07, 0xE0, 0x00, 0x03, 0xF0, 0x00,
|
||||
0x03, 0xF0, 0x00, 0x03, 0xF8, 0x00, 0x1F, 0xF8, 0x00, 0x0F, 0xFC, 0x00,
|
||||
0x07, 0xFC, 0x00, 0x03, 0xFC, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x7F, 0xFF,
|
||||
0xFB, 0xFF, 0xFF, 0xDF, 0xFF, 0xFE, 0xFF, 0xFF, 0xF7, 0xFF, 0xFF, 0xBF,
|
||||
0xFF, 0xFC, 0x00, 0x3F, 0xE0, 0x03, 0xFE, 0x00, 0x1F, 0xE0, 0x01, 0xFE,
|
||||
0x00, 0x1F, 0xE0, 0x01, 0xFE, 0x00, 0x1F, 0xE0, 0x01, 0xFE, 0x00, 0x1F,
|
||||
0xE0, 0x01, 0xFE, 0x00, 0x1F, 0xE0, 0x01, 0xFE, 0x00, 0x1F, 0xE0, 0x01,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xF8, 0x01, 0xF8, 0x1F, 0xC1, 0xFE, 0x0F, 0xF0, 0xFF,
|
||||
0x87, 0xE0, 0x3E, 0x01, 0xF0, 0x0F, 0x80, 0x7C, 0x03, 0xE0, 0x1F, 0x00,
|
||||
0xF8, 0x07, 0xC0, 0x3E, 0x01, 0xF0, 0x0F, 0x80, 0x7C, 0x03, 0xE0, 0x3F,
|
||||
0x0F, 0xF0, 0x7F, 0x03, 0xF8, 0x1F, 0xE0, 0x1F, 0x80, 0x7C, 0x03, 0xE0,
|
||||
0x1F, 0x00, 0xF8, 0x07, 0xC0, 0x3E, 0x01, 0xF0, 0x0F, 0x80, 0x7C, 0x03,
|
||||
0xE0, 0x1F, 0x00, 0xF8, 0x07, 0xE0, 0x3F, 0xE0, 0xFF, 0x07, 0xF8, 0x1F,
|
||||
0xC0, 0x7E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFC, 0x07, 0xF0, 0x3F, 0xC1, 0xFE, 0x0F, 0xF8, 0x0F, 0xC0, 0x3E, 0x01,
|
||||
0xF0, 0x0F, 0x80, 0x7C, 0x03, 0xE0, 0x1F, 0x00, 0xF8, 0x07, 0xC0, 0x3E,
|
||||
0x01, 0xF0, 0x0F, 0x80, 0x7C, 0x03, 0xE0, 0x1F, 0x80, 0x7F, 0x81, 0xFC,
|
||||
0x0F, 0xE0, 0xFF, 0x0F, 0xC0, 0x7C, 0x03, 0xE0, 0x1F, 0x00, 0xF8, 0x07,
|
||||
0xC0, 0x3E, 0x01, 0xF0, 0x0F, 0x80, 0x7C, 0x03, 0xE0, 0x1F, 0x00, 0xF8,
|
||||
0x0F, 0xC3, 0xFE, 0x1F, 0xE0, 0xFF, 0x07, 0xF0, 0x3F, 0x00, 0x1F, 0x00,
|
||||
0x03, 0xFE, 0x00, 0x1F, 0xF8, 0x0F, 0xFF, 0xF0, 0xFF, 0x0F, 0xFF, 0xF0,
|
||||
0x1F, 0xF8, 0x00, 0x7F, 0x80, 0x00, 0xF8};
|
||||
|
||||
const GFXglyph FreeSansBold24pt7bGlyphs[] PROGMEM = {
|
||||
{0, 0, 0, 13, 0, 1}, // 0x20 ' '
|
||||
{0, 7, 34, 16, 5, -33}, // 0x21 '!'
|
||||
{30, 18, 12, 22, 2, -33}, // 0x22 '"'
|
||||
{57, 26, 33, 26, 0, -31}, // 0x23 '#'
|
||||
{165, 25, 40, 26, 1, -34}, // 0x24 '$'
|
||||
{290, 39, 34, 42, 1, -32}, // 0x25 '%'
|
||||
{456, 30, 35, 34, 3, -33}, // 0x26 '&'
|
||||
{588, 7, 12, 12, 3, -33}, // 0x27 '''
|
||||
{599, 13, 44, 16, 2, -33}, // 0x28 '('
|
||||
{671, 13, 44, 16, 1, -33}, // 0x29 ')'
|
||||
{743, 15, 15, 18, 1, -33}, // 0x2A '*'
|
||||
{772, 23, 22, 27, 2, -21}, // 0x2B '+'
|
||||
{836, 7, 15, 12, 2, -6}, // 0x2C ','
|
||||
{850, 13, 6, 16, 1, -15}, // 0x2D '-'
|
||||
{860, 7, 7, 12, 2, -6}, // 0x2E '.'
|
||||
{867, 13, 34, 13, 0, -32}, // 0x2F '/'
|
||||
{923, 24, 35, 26, 1, -33}, // 0x30 '0'
|
||||
{1028, 14, 33, 26, 4, -32}, // 0x31 '1'
|
||||
{1086, 23, 34, 26, 2, -33}, // 0x32 '2'
|
||||
{1184, 23, 35, 26, 2, -33}, // 0x33 '3'
|
||||
{1285, 22, 33, 26, 2, -32}, // 0x34 '4'
|
||||
{1376, 23, 34, 26, 2, -32}, // 0x35 '5'
|
||||
{1474, 23, 35, 26, 2, -33}, // 0x36 '6'
|
||||
{1575, 23, 33, 26, 1, -32}, // 0x37 '7'
|
||||
{1670, 24, 35, 26, 1, -33}, // 0x38 '8'
|
||||
{1775, 24, 35, 26, 1, -33}, // 0x39 '9'
|
||||
{1880, 7, 25, 12, 2, -24}, // 0x3A ':'
|
||||
{1902, 7, 33, 12, 2, -24}, // 0x3B ';'
|
||||
{1931, 23, 23, 27, 2, -22}, // 0x3C '<'
|
||||
{1998, 23, 18, 27, 2, -19}, // 0x3D '='
|
||||
{2050, 23, 23, 27, 2, -22}, // 0x3E '>'
|
||||
{2117, 24, 35, 29, 3, -34}, // 0x3F '?'
|
||||
{2222, 43, 41, 46, 1, -34}, // 0x40 '@'
|
||||
{2443, 32, 34, 33, 0, -33}, // 0x41 'A'
|
||||
{2579, 27, 34, 33, 4, -33}, // 0x42 'B'
|
||||
{2694, 30, 36, 34, 2, -34}, // 0x43 'C'
|
||||
{2829, 28, 34, 34, 4, -33}, // 0x44 'D'
|
||||
{2948, 25, 34, 31, 4, -33}, // 0x45 'E'
|
||||
{3055, 24, 34, 30, 4, -33}, // 0x46 'F'
|
||||
{3157, 31, 36, 36, 2, -34}, // 0x47 'G'
|
||||
{3297, 27, 34, 35, 4, -33}, // 0x48 'H'
|
||||
{3412, 7, 34, 15, 4, -33}, // 0x49 'I'
|
||||
{3442, 22, 35, 27, 1, -33}, // 0x4A 'J'
|
||||
{3539, 30, 34, 34, 4, -33}, // 0x4B 'K'
|
||||
{3667, 23, 34, 29, 4, -33}, // 0x4C 'L'
|
||||
{3765, 33, 34, 41, 4, -33}, // 0x4D 'M'
|
||||
{3906, 28, 34, 35, 4, -33}, // 0x4E 'N'
|
||||
{4025, 33, 36, 37, 2, -34}, // 0x4F 'O'
|
||||
{4174, 26, 34, 32, 4, -33}, // 0x50 'P'
|
||||
{4285, 33, 37, 37, 2, -34}, // 0x51 'Q'
|
||||
{4438, 28, 34, 34, 4, -33}, // 0x52 'R'
|
||||
{4557, 28, 36, 32, 2, -34}, // 0x53 'S'
|
||||
{4683, 27, 34, 30, 2, -33}, // 0x54 'T'
|
||||
{4798, 27, 35, 35, 4, -33}, // 0x55 'U'
|
||||
{4917, 29, 34, 31, 1, -33}, // 0x56 'V'
|
||||
{5041, 43, 34, 45, 1, -33}, // 0x57 'W'
|
||||
{5224, 30, 34, 32, 1, -33}, // 0x58 'X'
|
||||
{5352, 29, 34, 30, 1, -33}, // 0x59 'Y'
|
||||
{5476, 26, 34, 29, 1, -33}, // 0x5A 'Z'
|
||||
{5587, 11, 43, 16, 3, -33}, // 0x5B '['
|
||||
{5647, 14, 34, 13, -1, -32}, // 0x5C '\'
|
||||
{5707, 11, 43, 16, 1, -33}, // 0x5D ']'
|
||||
{5767, 22, 20, 27, 3, -32}, // 0x5E '^'
|
||||
{5822, 28, 4, 26, -1, 6}, // 0x5F '_'
|
||||
{5836, 9, 7, 12, 1, -35}, // 0x60 '`'
|
||||
{5844, 24, 26, 27, 2, -24}, // 0x61 'a'
|
||||
{5922, 25, 35, 29, 3, -33}, // 0x62 'b'
|
||||
{6032, 23, 26, 26, 2, -24}, // 0x63 'c'
|
||||
{6107, 25, 35, 29, 2, -33}, // 0x64 'd'
|
||||
{6217, 24, 26, 27, 2, -24}, // 0x65 'e'
|
||||
{6295, 14, 34, 16, 1, -33}, // 0x66 'f'
|
||||
{6355, 24, 36, 29, 2, -24}, // 0x67 'g'
|
||||
{6463, 23, 34, 28, 3, -33}, // 0x68 'h'
|
||||
{6561, 7, 34, 13, 3, -33}, // 0x69 'i'
|
||||
{6591, 10, 45, 13, 0, -33}, // 0x6A 'j'
|
||||
{6648, 23, 34, 27, 3, -33}, // 0x6B 'k'
|
||||
{6746, 7, 34, 13, 3, -33}, // 0x6C 'l'
|
||||
{6776, 36, 25, 42, 3, -24}, // 0x6D 'm'
|
||||
{6889, 23, 25, 29, 3, -24}, // 0x6E 'n'
|
||||
{6961, 25, 26, 29, 2, -24}, // 0x6F 'o'
|
||||
{7043, 25, 36, 29, 3, -24}, // 0x70 'p'
|
||||
{7156, 25, 36, 29, 2, -24}, // 0x71 'q'
|
||||
{7269, 15, 25, 18, 3, -24}, // 0x72 'r'
|
||||
{7316, 24, 26, 26, 1, -24}, // 0x73 's'
|
||||
{7394, 12, 32, 16, 2, -30}, // 0x74 't'
|
||||
{7442, 23, 26, 29, 3, -24}, // 0x75 'u'
|
||||
{7517, 25, 25, 25, 0, -24}, // 0x76 'v'
|
||||
{7596, 35, 25, 37, 1, -24}, // 0x77 'w'
|
||||
{7706, 24, 25, 26, 1, -24}, // 0x78 'x'
|
||||
{7781, 25, 36, 26, 0, -24}, // 0x79 'y'
|
||||
{7894, 21, 25, 24, 1, -24}, // 0x7A 'z'
|
||||
{7960, 13, 43, 18, 2, -33}, // 0x7B '{'
|
||||
{8030, 4, 44, 13, 5, -33}, // 0x7C '|'
|
||||
{8052, 13, 43, 18, 3, -33}, // 0x7D '}'
|
||||
{8122, 21, 8, 23, 1, -14}}; // 0x7E '~'
|
||||
|
||||
const GFXfont FreeSansBold24pt7b PROGMEM = {
|
||||
(uint8_t *)FreeSansBold24pt7bBitmaps, (GFXglyph *)FreeSansBold24pt7bGlyphs,
|
||||
0x20, 0x7E, 56};
|
||||
|
||||
// Approx. 8815 bytes
|
||||
File diff suppressed because it is too large
Load Diff
@@ -4,10 +4,115 @@
|
||||
#include <Arduino.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define DRAWING_MIN_BITMAP_SIZE (128) //minimum size we'll consider
|
||||
#define COLOR_RED 1
|
||||
#define COLOR_BLACK 0
|
||||
|
||||
void set_offline(boolean state);
|
||||
#define IMAGE_OR 1
|
||||
#define IMAGE_REPLACE 0
|
||||
|
||||
#define DRAW_INVERTED 1
|
||||
#define DRAW_NORMAL 0
|
||||
|
||||
typedef struct {
|
||||
uint16_t bitmapOffset; ///< Pointer into GFXfont->bitmap
|
||||
uint8_t width; ///< Bitmap dimensions in pixels
|
||||
uint8_t height; ///< Bitmap dimensions in pixels
|
||||
uint8_t xAdvance; ///< Distance to advance cursor (x axis)
|
||||
int8_t xOffset; ///< X dist from cursor pos to UL corner
|
||||
int8_t yOffset; ///< Y dist from cursor pos to UL corner
|
||||
} GFXglyph;
|
||||
|
||||
/// Data stored for FONT AS A WHOLE
|
||||
typedef struct {
|
||||
uint8_t *bitmap; ///< Glyph bitmaps, concatenated
|
||||
GFXglyph *glyph; ///< Glyph array
|
||||
uint16_t first; ///< ASCII extents (first char)
|
||||
uint16_t last; ///< ASCII extents (last char)
|
||||
uint8_t yAdvance; ///< Newline distance (y axis)
|
||||
} GFXfont;
|
||||
|
||||
enum rotation {
|
||||
ROTATE_0,
|
||||
ROTATE_90,
|
||||
ROTATE_180,
|
||||
ROTATE_270
|
||||
};
|
||||
|
||||
void addBufferedImage(uint16_t x, uint16_t y, bool color, enum rotation ro, const uint8_t *image, bool mask);
|
||||
void addFlashImage(uint16_t x, uint16_t y, bool color, enum rotation ro, const uint8_t *image);
|
||||
void addQR(uint16_t x, uint16_t y, uint8_t version, uint8_t scale, const char *c, ...);
|
||||
void drawImageAtAddress(uint32_t addr, uint8_t lut);
|
||||
void drawImageFromBuffer(uint8_t* buffer, const uint8_t lut);
|
||||
void drawRoundedRectangle(uint16_t xpos, uint16_t ypos, uint16_t width, uint16_t height, bool color);
|
||||
void drawMask(uint16_t xpos, uint16_t ypos, uint16_t width, uint16_t height, bool color);
|
||||
|
||||
class drawItem {
|
||||
public:
|
||||
drawItem();
|
||||
~drawItem();
|
||||
void setRotation(enum rotation ro);
|
||||
void addItem(uint8_t *data, uint16_t width, uint16_t height);
|
||||
bool addToList();
|
||||
|
||||
static void shiftBytesRight(uint8_t *data, uint8_t shift, uint8_t len);
|
||||
static void renderDrawLine(uint8_t *line, uint16_t number, uint8_t c);
|
||||
static void flushDrawItems();
|
||||
|
||||
// these are also used for rotated screens
|
||||
static void reverseBytes(uint8_t *src, uint8_t src_len);
|
||||
static uint8_t bitReverse(uint8_t byte);
|
||||
|
||||
|
||||
enum drawType {
|
||||
DRAW_FONT,
|
||||
DRAW_BUFFERED_1BPP,
|
||||
DRAW_MASK,
|
||||
DRAW_EEPROM_1BPP,
|
||||
DRAW_EEPROM_2BPP,
|
||||
} type;
|
||||
|
||||
int16_t xpos;
|
||||
int16_t ypos;
|
||||
|
||||
enum rotation rotate = ROTATE_0;
|
||||
|
||||
uint8_t color = 0;
|
||||
|
||||
bool direction = false;
|
||||
|
||||
bool mirrorH = false;
|
||||
bool mirrorV = false;
|
||||
uint16_t width;
|
||||
uint16_t height;
|
||||
|
||||
// if this is true, clean up the reference (free memory).
|
||||
bool cleanUp = true;
|
||||
|
||||
protected:
|
||||
void copyWithByteShift(uint8_t *dst, uint8_t *src, uint8_t src_len, uint8_t offset);
|
||||
|
||||
|
||||
void getDrawLine(uint8_t *line, uint16_t number, uint8_t c);
|
||||
void getXLine(uint8_t *line, uint16_t yPos, uint8_t color);
|
||||
void getYLine(uint8_t *line, uint16_t xPos, uint8_t color);
|
||||
uint8_t widthBytes = 0;
|
||||
uint8_t *buffer;
|
||||
};
|
||||
|
||||
class fontrender {
|
||||
public:
|
||||
void epdPrintf(uint16_t x, uint16_t y, bool color, enum rotation ro, const char *c, ...);
|
||||
fontrender(const GFXfont *font);
|
||||
void setFont(const GFXfont *font);
|
||||
|
||||
protected:
|
||||
GFXfont *gfxFont; // = &FreeSansBold18pt7b;
|
||||
uint16_t bufferByteWidth = 0;
|
||||
uint8_t *fb = nullptr;
|
||||
uint16_t Xpixels;
|
||||
uint8_t drawChar(int32_t x, int32_t y, uint16_t c, uint8_t size);
|
||||
uint8_t getCharWidth(uint16_t c);
|
||||
void drawFastHLine(uint16_t x, uint16_t y, uint16_t w);
|
||||
void fillRect(uint16_t x, uint16_t y, uint16_t w, uint16_t h);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -30,17 +30,13 @@ void eepromReadStart(uint32_t addr) ;
|
||||
#define EEPROM_IMG_INPROGRESS (0x7fffffffUL)
|
||||
#define EEPROM_IMG_VALID (0x494d4721UL)
|
||||
|
||||
struct EepromImageHeader { //each image space is 0x17000 bytes, we have space for ten of them
|
||||
struct EepromImageHeader {
|
||||
uint64_t version;
|
||||
uint32_t validMarker;
|
||||
uint32_t size;
|
||||
uint8_t dataType;
|
||||
uint32_t id;
|
||||
|
||||
//image data here
|
||||
//we pre-erase so progress can be calculated by finding the first non-0xff byte
|
||||
uint8_t argument;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,260 +1,5 @@
|
||||
#pragma once
|
||||
#include <Arduino.h>
|
||||
static const uint8_t font[256][20]={ // https://raw.githubusercontent.com/basti79/LCD-fonts/master/10x16_vertikal_MSB_1.h
|
||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x00
|
||||
{0xE0,0x01,0x30,0x03,0x50,0x02,0x28,0x05,0x28,0x04,0x28,0x04,0x28,0x05,0x50,0x02,0x30,0x03,0xE0,0x01}, // 0x01
|
||||
{0xE0,0x01,0xF0,0x03,0xB0,0x03,0xD8,0x06,0xD8,0x07,0xD8,0x07,0xD8,0x06,0xB0,0x03,0xF0,0x03,0xE0,0x01}, // 0x02
|
||||
{0x00,0x3E,0x80,0x7F,0xE0,0x7F,0xF0,0x7F,0xF8,0x3F,0xF8,0x3F,0xF0,0x7F,0xE0,0x7F,0x80,0x7F,0x00,0x3E}, // 0x03
|
||||
{0x00,0x01,0x80,0x03,0xC0,0x0F,0xE0,0x1F,0xF8,0x7F,0xF0,0x1F,0xE0,0x0F,0xC0,0x07,0x80,0x03,0x00,0x01}, // 0x04
|
||||
{0x80,0x03,0xC0,0x07,0xC0,0x07,0xC0,0x3F,0xF8,0x7F,0xB8,0x7F,0xC0,0x3F,0xC0,0x07,0xC0,0x07,0x80,0x03}, // 0x05
|
||||
{0x80,0x03,0xC0,0x07,0xC0,0x0F,0xC0,0x1F,0xF8,0x3F,0xB8,0x7F,0xC0,0x1F,0xC0,0x0F,0xC0,0x07,0x80,0x03}, // 0x06
|
||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x07
|
||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x08
|
||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x09
|
||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x0A
|
||||
{0xE0,0x01,0x10,0x02,0x08,0x04,0x08,0x04,0x08,0x04,0x08,0x24,0x10,0x2E,0xE0,0x71,0x00,0x70,0x00,0x18}, // 0x0B
|
||||
{0x00,0x00,0x00,0x1E,0x20,0x21,0xA0,0x40,0xF8,0x40,0xA0,0x40,0xA0,0x41,0x00,0x21,0x00,0x1E,0x00,0x00}, // 0x0C
|
||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x0D
|
||||
{0x06,0x00,0x0E,0x00,0x0E,0x00,0xFC,0x1F,0x00,0x18,0x30,0x10,0x70,0x30,0x70,0x20,0xE0,0x7F,0x00,0x00}, // 0x0E
|
||||
{0x00,0x01,0xC0,0x0F,0xC0,0x04,0x40,0x08,0x60,0x18,0x40,0x08,0x40,0x04,0xC0,0x0C,0xC0,0x0B,0x00,0x01}, // 0x0F
|
||||
{0xF8,0x0F,0xF0,0x07,0xF0,0x07,0xE0,0x03,0xE0,0x03,0xE0,0x03,0xC0,0x01,0xC0,0x01,0x80,0x00,0x80,0x00}, // 0x10
|
||||
{0x80,0x00,0x80,0x00,0xC0,0x01,0xC0,0x01,0xE0,0x03,0xE0,0x03,0xE0,0x03,0xF0,0x07,0xF0,0x07,0xF8,0x0F}, // 0x11
|
||||
{0x00,0x00,0x00,0x00,0x08,0x10,0x04,0x20,0xFE,0x7F,0x04,0x20,0x08,0x10,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x12
|
||||
{0x00,0x00,0x00,0x00,0xD8,0x7F,0x00,0x00,0x00,0x00,0xD8,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x13
|
||||
{0x00,0x00,0x00,0x38,0x00,0x7C,0x00,0x7E,0xFE,0x7F,0x00,0x40,0x00,0x40,0xFE,0x7F,0x00,0x00,0x00,0x00}, // 0x14
|
||||
{0x00,0x00,0x00,0x00,0x86,0x3B,0xC2,0x4C,0x42,0x44,0x62,0x46,0x32,0x42,0xDC,0x41,0x00,0x00,0x00,0x00}, // 0x15
|
||||
{0x00,0x00,0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x00}, // 0x16
|
||||
{0x00,0x00,0x00,0x00,0x11,0x10,0x09,0x20,0xFD,0x7F,0x09,0x20,0x11,0x10,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x17
|
||||
{0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x20,0xFE,0x7F,0x00,0x20,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x18
|
||||
{0x00,0x00,0x00,0x00,0x08,0x00,0x04,0x00,0xFE,0x7F,0x04,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x19
|
||||
{0x00,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0xA0,0x02,0xC0,0x01,0x80,0x00,0x00,0x00}, // 0x1A
|
||||
{0x00,0x00,0x80,0x00,0xC0,0x01,0xA0,0x02,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x00,0x00}, // 0x1B
|
||||
{0x00,0x00,0xF8,0x07,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x00,0x00}, // 0x1C
|
||||
{0x00,0x00,0x80,0x00,0xC0,0x01,0xA0,0x02,0x80,0x00,0x80,0x00,0xA0,0x02,0xC0,0x01,0x80,0x00,0x00,0x00}, // 0x1D
|
||||
{0x08,0x00,0x18,0x00,0x78,0x00,0xF8,0x01,0xF8,0x03,0xF8,0x0F,0xF8,0x03,0xF8,0x00,0x38,0x00,0x08,0x00}, // 0x1E
|
||||
{0x00,0x08,0x00,0x0C,0x00,0x0F,0xC0,0x0F,0xE0,0x0F,0xF8,0x0F,0xE0,0x0F,0x80,0x0F,0x00,0x0E,0x00,0x08}, // 0x1F
|
||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x20
|
||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xD8,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x21
|
||||
{0x00,0x00,0x00,0x00,0x00,0x78,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x78,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x22
|
||||
{0x80,0x00,0x98,0x04,0xE0,0x05,0x80,0x1E,0x98,0x64,0xE0,0x05,0x80,0x1E,0x80,0x64,0x80,0x04,0x00,0x00}, // 0x23
|
||||
{0x00,0x00,0x00,0x00,0x18,0x38,0x08,0x64,0x08,0x42,0xFC,0xFF,0x88,0x41,0xF0,0x40,0x00,0x00,0x00,0x00}, // 0x24
|
||||
{0x08,0x38,0x10,0x44,0x20,0x44,0xC0,0x44,0x00,0x39,0x70,0x02,0x88,0x0C,0x88,0x10,0x88,0x20,0x70,0x40}, // 0x25
|
||||
{0xE0,0x00,0x10,0x01,0x08,0x3A,0x08,0x46,0x88,0x45,0xC8,0x4C,0x38,0x38,0x18,0x00,0x68,0x00,0x80,0x01}, // 0x26
|
||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x78,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x27
|
||||
{0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x07,0x18,0x18,0x0C,0x30,0x04,0x20,0x02,0x40,0x02,0x40,0x00,0x00}, // 0x28
|
||||
{0x00,0x00,0x02,0x40,0x02,0x40,0x04,0x20,0x0C,0x30,0x18,0x18,0xE0,0x07,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x29
|
||||
{0x00,0x00,0x00,0x10,0x00,0x18,0x00,0x0F,0x00,0x72,0x00,0x0F,0x00,0x18,0x00,0x10,0x00,0x00,0x00,0x00}, // 0x2A
|
||||
{0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0xF8,0x07,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x00,0x00}, // 0x2B
|
||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x19,0x00,0x1E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x2C
|
||||
{0x00,0x00,0x00,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x00,0x00,0x00,0x00}, // 0x2D
|
||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x2E
|
||||
{0x00,0x00,0x02,0x00,0x0C,0x00,0x30,0x00,0xC0,0x00,0x00,0x03,0x00,0x0C,0x00,0x30,0x00,0x40,0x00,0x00}, // 0x2F
|
||||
{0x00,0x00,0xC0,0x0F,0x30,0x30,0x08,0x40,0x08,0x40,0x08,0x40,0x30,0x30,0xC0,0x0F,0x00,0x00,0x00,0x00}, // 0x30
|
||||
{0x00,0x00,0x08,0x20,0x08,0x20,0x08,0x20,0xF8,0x7F,0x08,0x00,0x08,0x00,0x08,0x00,0x00,0x00,0x00,0x00}, // 0x31
|
||||
{0x00,0x00,0x18,0x60,0x28,0x40,0x48,0x40,0x88,0x40,0x08,0x43,0x08,0x3C,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x32
|
||||
{0x00,0x00,0x00,0x00,0x08,0x40,0x08,0x42,0x08,0x42,0x08,0x42,0xF0,0x3D,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x33
|
||||
{0xC0,0x00,0x40,0x03,0x40,0x04,0x40,0x18,0x40,0x20,0xF8,0x7F,0x40,0x00,0x40,0x00,0x00,0x00,0x00,0x00}, // 0x34
|
||||
{0x00,0x00,0x00,0x00,0x08,0x7C,0x08,0x44,0x08,0x44,0x10,0x42,0xE0,0x41,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x35
|
||||
{0x00,0x00,0xE0,0x0F,0x10,0x32,0x08,0x44,0x08,0x44,0x08,0x44,0x10,0x42,0xE0,0x01,0x00,0x00,0x00,0x00}, // 0x36
|
||||
{0x00,0x00,0x00,0x40,0x18,0x40,0xE0,0x40,0x00,0x43,0x00,0x4C,0x00,0x50,0x00,0x60,0x00,0x00,0x00,0x00}, // 0x37
|
||||
{0x00,0x00,0xF0,0x38,0x08,0x45,0x08,0x42,0x08,0x42,0x08,0x45,0x90,0x45,0x60,0x38,0x00,0x00,0x00,0x00}, // 0x38
|
||||
{0x00,0x00,0x00,0x1E,0x08,0x21,0x88,0x40,0x88,0x40,0x88,0x40,0x30,0x21,0xC0,0x1F,0x00,0x00,0x00,0x00}, // 0x39
|
||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x06,0x18,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x3A
|
||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x19,0x06,0x1E,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x3B
|
||||
{0x00,0x00,0x00,0x00,0xC0,0x00,0xC0,0x00,0x20,0x01,0x20,0x01,0x10,0x02,0x10,0x02,0x08,0x04,0x00,0x00}, // 0x3C
|
||||
{0x00,0x00,0x20,0x01,0x20,0x01,0x20,0x01,0x20,0x01,0x20,0x01,0x20,0x01,0x20,0x01,0x20,0x01,0x00,0x00}, // 0x3D
|
||||
{0x00,0x00,0x08,0x04,0x10,0x02,0x10,0x02,0x20,0x01,0x20,0x01,0xC0,0x00,0xC0,0x00,0x00,0x00,0x00,0x00}, // 0x3E
|
||||
{0x00,0x00,0x00,0x70,0x00,0x40,0xD8,0x40,0x00,0x41,0x00,0x42,0x00,0x64,0x00,0x38,0x00,0x00,0x00,0x00}, // 0x3F
|
||||
{0xC0,0x0F,0x30,0x18,0x18,0x20,0xC8,0x47,0x28,0x48,0x68,0x50,0xD8,0x51,0xE0,0x3F,0x20,0x00,0x20,0x00}, // 0x40
|
||||
{0x08,0x00,0x70,0x00,0xC0,0x01,0x40,0x0E,0x40,0x18,0x40,0x0C,0x40,0x03,0xC0,0x00,0x30,0x00,0x08,0x00}, // 0x41
|
||||
{0x00,0x00,0xF8,0x1F,0x08,0x11,0x08,0x11,0x08,0x11,0x08,0x11,0x88,0x12,0x70,0x0C,0x00,0x00,0x00,0x00}, // 0x42
|
||||
{0xC0,0x03,0x30,0x0C,0x10,0x08,0x08,0x10,0x08,0x10,0x08,0x10,0x08,0x10,0x08,0x18,0x00,0x00,0x00,0x00}, // 0x43
|
||||
{0x00,0x00,0xF8,0x1F,0x08,0x10,0x08,0x10,0x08,0x10,0x08,0x10,0x10,0x08,0xE0,0x07,0x00,0x00,0x00,0x00}, // 0x44
|
||||
{0x00,0x00,0xF8,0x1F,0x88,0x10,0x88,0x10,0x88,0x10,0x88,0x10,0x88,0x10,0x08,0x10,0x00,0x00,0x00,0x00}, // 0x45
|
||||
{0x00,0x00,0xF8,0x1F,0x80,0x10,0x80,0x10,0x80,0x10,0x80,0x10,0x80,0x10,0x00,0x10,0x00,0x00,0x00,0x00}, // 0x46
|
||||
{0x00,0x00,0xC0,0x03,0x30,0x0C,0x10,0x08,0x08,0x10,0x08,0x10,0x88,0x10,0x88,0x10,0xF8,0x18,0x00,0x00}, // 0x47
|
||||
{0x00,0x00,0xF8,0x1F,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0xF8,0x1F,0x00,0x00,0x00,0x00}, // 0x48
|
||||
{0x00,0x00,0x08,0x10,0x08,0x10,0x08,0x10,0xF8,0x1F,0x08,0x10,0x08,0x10,0x08,0x10,0x00,0x00,0x00,0x00}, // 0x49
|
||||
{0x00,0x00,0x00,0x00,0x08,0x00,0x08,0x10,0x08,0x10,0x08,0x10,0xF0,0x1F,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x4A
|
||||
{0x00,0x00,0xF8,0x1F,0x00,0x01,0x80,0x01,0x40,0x02,0x20,0x04,0x20,0x08,0x10,0x10,0x08,0x00,0x00,0x00}, // 0x4B
|
||||
{0x00,0x00,0xF8,0x1F,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x00,0x00,0x00,0x00}, // 0x4C
|
||||
{0xF8,0x1F,0x00,0x1C,0x80,0x07,0xE0,0x00,0x60,0x00,0x80,0x03,0x00,0x1C,0xF8,0x1F,0x00,0x00,0x00,0x00}, // 0x4D
|
||||
{0x00,0x00,0xF8,0x1F,0x00,0x08,0x00,0x06,0x80,0x01,0x60,0x00,0x10,0x00,0xF8,0x1F,0x00,0x00,0x00,0x00}, // 0x4E
|
||||
{0x00,0x00,0xE0,0x07,0x10,0x08,0x08,0x10,0x08,0x10,0x08,0x10,0x08,0x10,0x10,0x08,0xE0,0x07,0x00,0x00}, // 0x4F
|
||||
{0x00,0x00,0xF8,0x1F,0x80,0x10,0x80,0x10,0x80,0x10,0x80,0x10,0x00,0x11,0x00,0x0E,0x00,0x00,0x00,0x00}, // 0x50
|
||||
{0x00,0x00,0xE0,0x07,0x10,0x08,0x08,0x10,0x08,0x10,0x08,0x10,0x0C,0x10,0x12,0x08,0xE2,0x07,0x00,0x00}, // 0x51
|
||||
{0x00,0x00,0xF8,0x1F,0x80,0x10,0x80,0x10,0xC0,0x10,0x20,0x11,0x10,0x0E,0x08,0x00,0x00,0x00,0x00,0x00}, // 0x52
|
||||
{0x00,0x00,0x18,0x0E,0x08,0x12,0x08,0x11,0x08,0x11,0x88,0x10,0x90,0x10,0x70,0x18,0x00,0x00,0x00,0x00}, // 0x53
|
||||
{0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0xF8,0x1F,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x00}, // 0x54
|
||||
{0x00,0x00,0xE0,0x1F,0x18,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x10,0x00,0xE0,0x1F,0x00,0x00,0x00,0x00}, // 0x55
|
||||
{0x00,0x10,0x00,0x0C,0x80,0x03,0x60,0x00,0x18,0x00,0x18,0x00,0xE0,0x00,0x00,0x03,0x00,0x0C,0x00,0x10}, // 0x56
|
||||
{0x00,0x18,0xC0,0x07,0x38,0x00,0xF0,0x00,0x00,0x07,0x80,0x03,0x70,0x00,0x38,0x00,0xC0,0x07,0x00,0x18}, // 0x57
|
||||
{0x08,0x10,0x10,0x08,0x20,0x04,0x40,0x02,0x80,0x01,0x80,0x01,0x40,0x02,0x20,0x04,0x10,0x08,0x08,0x10}, // 0x58
|
||||
{0x00,0x10,0x00,0x08,0x00,0x06,0x00,0x01,0xF8,0x00,0x00,0x01,0x00,0x02,0x00,0x04,0x00,0x08,0x00,0x10}, // 0x59
|
||||
{0x00,0x00,0x18,0x10,0x28,0x10,0x48,0x10,0x88,0x10,0x08,0x11,0x08,0x12,0x08,0x14,0x08,0x18,0x00,0x00}, // 0x5A
|
||||
{0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x7F,0x02,0x40,0x02,0x40,0x02,0x40,0x02,0x40,0x00,0x00,0x00,0x00}, // 0x5B
|
||||
{0x00,0x00,0x00,0x40,0x00,0x30,0x00,0x0C,0x00,0x03,0xC0,0x00,0x30,0x00,0x0C,0x00,0x02,0x00,0x00,0x00}, // 0x5C
|
||||
{0x00,0x00,0x02,0x40,0x02,0x40,0x02,0x40,0x02,0x40,0xFE,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x5D
|
||||
{0x00,0x00,0x20,0x00,0xC0,0x00,0x00,0x07,0x00,0x1C,0x00,0x70,0x00,0x0E,0xC0,0x01,0x20,0x00,0x00,0x00}, // 0x5E
|
||||
{0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00}, // 0x5F
|
||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x60
|
||||
{0x00,0x00,0x30,0x00,0x48,0x04,0x88,0x04,0x88,0x04,0x90,0x04,0xF8,0x03,0x08,0x00,0x00,0x00,0x00,0x00}, // 0x61
|
||||
{0x00,0x00,0xF8,0x7F,0x10,0x02,0x08,0x04,0x08,0x04,0x08,0x04,0x10,0x06,0xE0,0x01,0x00,0x00,0x00,0x00}, // 0x62
|
||||
{0x00,0x00,0xE0,0x01,0x10,0x02,0x08,0x04,0x08,0x04,0x08,0x04,0x08,0x04,0x08,0x04,0x00,0x00,0x00,0x00}, // 0x63
|
||||
{0x00,0x00,0xE0,0x01,0x18,0x02,0x08,0x04,0x08,0x04,0x08,0x04,0x10,0x02,0xF8,0x7F,0x00,0x00,0x00,0x00}, // 0x64
|
||||
{0x00,0x00,0xE0,0x01,0x90,0x02,0x88,0x04,0x88,0x04,0x88,0x04,0x88,0x04,0x88,0x03,0x00,0x00,0x00,0x00}, // 0x65
|
||||
{0x00,0x00,0x00,0x04,0x00,0x04,0xF8,0x3F,0x00,0x24,0x00,0x44,0x00,0x44,0x00,0x44,0x00,0x44,0x00,0x00}, // 0x66
|
||||
{0x00,0x00,0xE0,0x01,0x19,0x02,0x09,0x04,0x09,0x04,0x09,0x04,0x12,0x02,0xFC,0x07,0x00,0x00,0x00,0x00}, // 0x67
|
||||
{0x00,0x00,0xF8,0x7F,0x00,0x01,0x00,0x02,0x00,0x04,0x00,0x04,0x00,0x04,0xF8,0x03,0x00,0x00,0x00,0x00}, // 0x68
|
||||
{0x00,0x00,0x00,0x04,0x00,0x04,0x00,0x64,0xF8,0x67,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x69
|
||||
{0x00,0x00,0x01,0x00,0x01,0x04,0x01,0x04,0x01,0x64,0xFE,0x67,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x6A
|
||||
{0x00,0x00,0xF8,0x7F,0x80,0x00,0xC0,0x00,0x20,0x01,0x20,0x02,0x10,0x02,0x08,0x04,0x00,0x00,0x00,0x00}, // 0x6B
|
||||
{0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x40,0x00,0x40,0xF8,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x6C
|
||||
{0xF8,0x07,0x00,0x02,0x00,0x04,0x00,0x04,0xF8,0x03,0x00,0x02,0x00,0x04,0x00,0x04,0xF8,0x03,0x00,0x00}, // 0x6D
|
||||
{0x00,0x00,0xF8,0x07,0x00,0x03,0x00,0x02,0x00,0x04,0x00,0x04,0x00,0x04,0xF8,0x03,0x00,0x00,0x00,0x00}, // 0x6E
|
||||
{0x00,0x00,0xE0,0x01,0x10,0x02,0x08,0x04,0x08,0x04,0x08,0x04,0x10,0x02,0xE0,0x01,0x00,0x00,0x00,0x00}, // 0x6F
|
||||
{0x00,0x00,0xFF,0x07,0x10,0x02,0x08,0x04,0x08,0x04,0x08,0x04,0x10,0x06,0xE0,0x01,0x00,0x00,0x00,0x00}, // 0x70
|
||||
{0x00,0x00,0xE0,0x01,0x18,0x02,0x08,0x04,0x08,0x04,0x08,0x04,0x10,0x02,0xFF,0x07,0x00,0x00,0x00,0x00}, // 0x71
|
||||
{0x00,0x00,0x00,0x00,0xF8,0x07,0x00,0x01,0x00,0x02,0x00,0x04,0x00,0x04,0x00,0x07,0x00,0x00,0x00,0x00}, // 0x72
|
||||
{0x00,0x00,0x18,0x03,0x88,0x04,0x88,0x04,0x48,0x04,0x48,0x04,0x30,0x04,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x73
|
||||
{0x00,0x00,0x00,0x04,0x00,0x04,0xF0,0x1F,0x08,0x04,0x08,0x04,0x08,0x04,0x08,0x04,0x00,0x00,0x00,0x00}, // 0x74
|
||||
{0x00,0x00,0xF0,0x07,0x08,0x00,0x08,0x00,0x08,0x00,0x10,0x00,0xF8,0x07,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x75
|
||||
{0x00,0x04,0x80,0x03,0x60,0x00,0x18,0x00,0x08,0x00,0x30,0x00,0xC0,0x00,0x00,0x03,0x00,0x04,0x00,0x00}, // 0x76
|
||||
{0x00,0x06,0xE0,0x01,0x18,0x00,0x70,0x00,0x80,0x03,0x80,0x01,0x70,0x00,0x18,0x00,0xE0,0x01,0x00,0x06}, // 0x77
|
||||
{0x00,0x00,0x08,0x04,0x10,0x02,0x20,0x01,0xC0,0x00,0xC0,0x00,0x20,0x01,0x10,0x02,0x08,0x04,0x00,0x00}, // 0x78
|
||||
{0x01,0x04,0x01,0x03,0xC1,0x00,0x62,0x00,0x1C,0x00,0x18,0x00,0x60,0x00,0x80,0x00,0x00,0x03,0x00,0x04}, // 0x79
|
||||
{0x00,0x00,0x08,0x04,0x18,0x04,0x28,0x04,0x48,0x04,0x88,0x04,0x08,0x05,0x08,0x06,0x08,0x04,0x00,0x00}, // 0x7A
|
||||
{0x00,0x00,0x00,0x00,0x80,0x00,0x80,0x00,0x7C,0x3F,0x02,0x40,0x02,0x40,0x02,0x40,0x00,0x00,0x00,0x00}, // 0x7B
|
||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x7C
|
||||
{0x00,0x00,0x00,0x00,0x02,0x40,0x02,0x40,0x02,0x40,0x7C,0x3F,0x80,0x00,0x80,0x00,0x00,0x00,0x00,0x00}, // 0x7D
|
||||
{0xC0,0x00,0x00,0x01,0x00,0x01,0x00,0x01,0x80,0x00,0x80,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x80,0x01}, // 0x7E
|
||||
{0x00,0x00,0xF8,0x01,0x08,0x03,0x08,0x04,0x08,0x08,0x08,0x04,0x08,0x03,0xF8,0x01,0x00,0x00,0x00,0x00}, // 0x7F
|
||||
{0xC0,0x03,0x30,0x0C,0x10,0x08,0x08,0x10,0x08,0x10,0x09,0x10,0x0D,0x10,0x0B,0x18,0x00,0x00,0x00,0x00}, // 0x80
|
||||
{0x00,0x00,0xF0,0x07,0x08,0x20,0x08,0x00,0x08,0x00,0x10,0x20,0xF8,0x07,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x81
|
||||
{0x00,0x00,0xE0,0x01,0x90,0x02,0x88,0x04,0x88,0x24,0x88,0x44,0x88,0x04,0x88,0x03,0x00,0x00,0x00,0x00}, // 0x82
|
||||
{0x00,0x00,0x30,0x00,0x48,0x24,0x88,0x44,0x88,0x44,0x90,0x24,0xF8,0x03,0x08,0x00,0x00,0x00,0x00,0x00}, // 0x83
|
||||
{0x00,0x00,0x30,0x00,0x48,0x24,0x88,0x04,0x88,0x04,0x90,0x24,0xF8,0x03,0x08,0x00,0x00,0x00,0x00,0x00}, // 0x84
|
||||
{0x00,0x00,0x30,0x00,0x48,0x44,0x88,0x24,0x88,0x04,0x90,0x04,0xF8,0x03,0x08,0x00,0x00,0x00,0x00,0x00}, // 0x85
|
||||
{0x00,0x00,0x30,0x00,0x48,0x04,0x88,0x44,0x88,0xA4,0x90,0x44,0xF8,0x03,0x08,0x00,0x00,0x00,0x00,0x00}, // 0x86
|
||||
{0x00,0x00,0xE0,0x01,0x10,0x02,0x08,0x04,0x09,0x04,0x0D,0x04,0x0B,0x04,0x08,0x04,0x00,0x00,0x00,0x00}, // 0x87
|
||||
{0x00,0x00,0xE0,0x01,0x90,0x22,0x88,0x44,0x88,0x44,0x88,0x24,0x88,0x04,0x88,0x03,0x00,0x00,0x00,0x00}, // 0x88
|
||||
{0x00,0x00,0xE0,0x01,0x90,0x02,0x88,0x24,0x88,0x04,0x88,0x04,0x88,0x24,0x88,0x03,0x00,0x00,0x00,0x00}, // 0x89
|
||||
{0x00,0x00,0xE0,0x01,0x90,0x02,0x88,0x44,0x88,0x24,0x88,0x04,0x88,0x04,0x88,0x03,0x00,0x00,0x00,0x00}, // 0x8A
|
||||
{0x00,0x00,0x00,0x04,0x00,0x24,0x00,0x04,0xF8,0x07,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x8B
|
||||
{0x00,0x00,0x00,0x04,0x00,0x24,0x00,0x44,0xF8,0x47,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x8C
|
||||
{0x00,0x00,0x00,0x04,0x00,0x04,0x00,0x44,0xF8,0x27,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x8D
|
||||
{0x08,0x00,0x70,0x00,0xC0,0x81,0x40,0x0E,0x40,0x18,0x40,0x0C,0x40,0x83,0xC0,0x00,0x30,0x00,0x08,0x00}, // 0x8E
|
||||
{0x08,0x00,0x70,0x00,0xC0,0x01,0x40,0x4E,0x40,0xB0,0x40,0xB8,0x40,0x4F,0xC0,0x01,0x70,0x00,0x08,0x00}, // 0x8F
|
||||
{0x00,0x00,0xF8,0x1F,0x88,0x10,0x88,0x10,0x88,0x50,0x88,0x90,0x88,0x10,0x08,0x10,0x00,0x00,0x00,0x00}, // 0x90
|
||||
{0x70,0x04,0xC8,0x04,0x88,0x04,0x88,0x04,0xF0,0x03,0x98,0x04,0x88,0x04,0x88,0x04,0x88,0x03,0x00,0x00}, // 0x91
|
||||
{0x08,0x00,0x30,0x00,0xE0,0x01,0x20,0x06,0x20,0x18,0xF8,0x1F,0x88,0x10,0x88,0x10,0x08,0x10,0x00,0x00}, // 0x92
|
||||
{0x00,0x00,0xE0,0x01,0x10,0x22,0x08,0x44,0x08,0x44,0x08,0x24,0x10,0x02,0xE0,0x01,0x00,0x00,0x00,0x00}, // 0x93
|
||||
{0x00,0x00,0xE0,0x01,0x10,0x22,0x08,0x04,0x08,0x04,0x08,0x24,0x10,0x02,0xE0,0x01,0x00,0x00,0x00,0x00}, // 0x94
|
||||
{0x00,0x00,0xE0,0x01,0x10,0x42,0x08,0x24,0x08,0x04,0x08,0x04,0x10,0x02,0xE0,0x01,0x00,0x00,0x00,0x00}, // 0x95
|
||||
{0x00,0x00,0xF0,0x07,0x08,0x20,0x08,0x40,0x08,0x40,0x10,0x20,0xF8,0x07,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x96
|
||||
{0x00,0x00,0xF0,0x07,0x08,0x40,0x08,0x20,0x08,0x00,0x10,0x00,0xF8,0x07,0x00,0x00,0x00,0x00,0x00,0x00}, // 0x97
|
||||
{0x01,0x04,0x01,0x03,0xC1,0x20,0x62,0x00,0x1C,0x00,0x18,0x20,0x60,0x00,0x80,0x00,0x00,0x03,0x00,0x04}, // 0x98
|
||||
{0x00,0x00,0xE0,0x07,0x10,0x88,0x08,0x10,0x08,0x10,0x08,0x10,0x08,0x90,0x10,0x08,0xE0,0x07,0x00,0x00}, // 0x99
|
||||
{0x00,0x00,0xE0,0x1F,0x18,0x80,0x08,0x00,0x08,0x00,0x08,0x00,0x10,0x80,0xE0,0x1F,0x00,0x00,0x00,0x00}, // 0x9A
|
||||
{0x00,0x00,0xE8,0x01,0x10,0x02,0x28,0x04,0xC8,0x04,0x08,0x05,0x10,0x02,0xE0,0x05,0x00,0x00,0x00,0x00}, // 0x9B
|
||||
{0x00,0x00,0x00,0x00,0x08,0x00,0x18,0x02,0xE8,0x3F,0x08,0x42,0x08,0x42,0x08,0x40,0x00,0x00,0x00,0x00}, // 0x9C
|
||||
{0x00,0x00,0xE8,0x07,0x30,0x08,0x68,0x10,0x88,0x10,0x08,0x11,0x08,0x16,0x10,0x0C,0xE0,0x17,0x00,0x00}, // 0x9D
|
||||
{0x00,0x00,0x08,0x04,0x10,0x02,0x20,0x01,0xC0,0x00,0xC0,0x00,0x20,0x01,0x10,0x02,0x08,0x04,0x00,0x00}, // 0x9E
|
||||
{0x00,0x00,0x01,0x00,0x01,0x04,0x01,0x04,0xFE,0x7F,0x00,0x84,0x00,0x84,0x00,0x80,0x00,0x00,0x00,0x00}, // 0x9F
|
||||
{0x00,0x00,0x30,0x00,0x48,0x04,0x88,0x04,0x88,0x24,0x90,0x44,0xF8,0x03,0x08,0x00,0x00,0x00,0x00,0x00}, // 0xA0
|
||||
{0x00,0x00,0x00,0x04,0x00,0x04,0x00,0x04,0xF8,0x27,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0xA1
|
||||
{0x00,0x00,0xE0,0x01,0x10,0x02,0x08,0x04,0x08,0x24,0x08,0x44,0x10,0x02,0xE0,0x01,0x00,0x00,0x00,0x00}, // 0xA2
|
||||
{0x00,0x00,0xF0,0x07,0x08,0x00,0x08,0x00,0x08,0x20,0x10,0x40,0xF8,0x07,0x00,0x00,0x00,0x00,0x00,0x00}, // 0xA3
|
||||
{0x00,0x00,0xF8,0x07,0x00,0x23,0x00,0x42,0x00,0x24,0x00,0x24,0x00,0x44,0xF8,0x03,0x00,0x00,0x00,0x00}, // 0xA4
|
||||
{0x00,0x00,0xF8,0x1F,0x00,0x48,0x00,0x86,0x80,0xC1,0x60,0x40,0x10,0x80,0xF8,0x1F,0x00,0x00,0x00,0x00}, // 0xA5
|
||||
{0x00,0x00,0x00,0x00,0x00,0x4C,0x00,0x52,0x00,0x52,0x00,0x52,0x00,0x3E,0x00,0x02,0x00,0x00,0x00,0x00}, // 0xA6
|
||||
{0x00,0x00,0x00,0x00,0x00,0x3C,0x00,0x42,0x00,0x42,0x00,0x42,0x00,0x42,0x00,0x3C,0x00,0x00,0x00,0x00}, // 0xA7
|
||||
{0x00,0x00,0x0E,0x00,0x13,0x00,0x11,0x00,0x21,0x00,0xC1,0x06,0x01,0x00,0x07,0x00,0x00,0x00,0x00,0x00}, // 0xA8
|
||||
{0x00,0x00,0x00,0x1C,0x00,0x22,0x00,0x5D,0x00,0x55,0x00,0x5D,0x00,0x22,0x00,0x1C,0x00,0x00,0x00,0x00}, // 0xA9
|
||||
{0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0xE0,0x01,0x00,0x00}, // 0xAA
|
||||
{0x08,0x40,0x30,0x7E,0x40,0x00,0x80,0x01,0x00,0x06,0x00,0x08,0x08,0x31,0x38,0x41,0x28,0x01,0xC8,0x00}, // 0xAB
|
||||
{0x08,0x40,0x30,0x7E,0x40,0x00,0x80,0x01,0x00,0x06,0x60,0x08,0xA0,0x30,0x20,0x41,0xF8,0x01,0x20,0x00}, // 0xAC
|
||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0xAD
|
||||
{0x00,0x00,0x80,0x00,0x40,0x01,0x20,0x02,0x10,0x04,0x80,0x00,0x40,0x01,0x20,0x02,0x10,0x04,0x00,0x00}, // 0xAE
|
||||
{0x00,0x00,0x10,0x04,0x20,0x02,0x40,0x01,0x80,0x00,0x10,0x04,0x20,0x02,0x40,0x01,0x80,0x00,0x00,0x00}, // 0xAF
|
||||
{0x36,0xDB,0x36,0xDB,0x00,0x00,0x36,0xDB,0x36,0xDB,0x00,0x00,0x36,0xDB,0x36,0xDB,0x00,0x00,0x00,0x00}, // 0xB0
|
||||
{0xDB,0x36,0xDB,0x36,0x36,0xDB,0xFF,0xFF,0xDB,0x36,0x36,0xDB,0xFF,0xFF,0xDB,0x36,0x36,0xDB,0x36,0xDB}, // 0xB1
|
||||
{0xFF,0xFF,0xFF,0xFF,0x36,0xDB,0xFF,0xFF,0xFF,0xFF,0x36,0xDB,0xFF,0xFF,0xFF,0xFF,0x36,0xDB,0x36,0xDB}, // 0xB2
|
||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0xB3
|
||||
{0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0xB4
|
||||
{0x08,0x00,0x70,0x00,0xC0,0x01,0x40,0x0E,0x40,0x58,0x40,0x8C,0x40,0x03,0xC0,0x00,0x30,0x00,0x08,0x00}, // 0xB5
|
||||
{0x08,0x00,0x70,0x00,0xC0,0x01,0x40,0x4E,0x40,0x98,0x40,0x8C,0x40,0x43,0xC0,0x00,0x30,0x00,0x08,0x00}, // 0xB6
|
||||
{0x08,0x00,0x70,0x00,0xC0,0x01,0x40,0x8E,0x40,0x58,0x40,0x0C,0x40,0x03,0xC0,0x00,0x30,0x00,0x08,0x00}, // 0xB7
|
||||
{0xC0,0x0F,0x30,0x30,0x98,0x67,0xC8,0x4C,0x48,0x48,0x48,0x48,0x58,0x68,0x30,0x30,0xC0,0x0F,0x00,0x00}, // 0xB8
|
||||
{0x40,0x01,0x40,0x01,0x40,0x01,0x7F,0xFF,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0xB9
|
||||
{0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0xBA
|
||||
{0x40,0x01,0x40,0x01,0x40,0x01,0x7F,0x01,0x00,0x01,0xFF,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0xBB
|
||||
{0x40,0x01,0x40,0x01,0x40,0x01,0x40,0xFF,0x40,0x00,0xC0,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0xBC
|
||||
{0x00,0x00,0xC0,0x0F,0x20,0x10,0x30,0x20,0x10,0x20,0xF8,0x7F,0x10,0x20,0x10,0x20,0x00,0x00,0x00,0x00}, // 0xBD
|
||||
{0x00,0x40,0x00,0x20,0x20,0x19,0x20,0x05,0xF8,0x03,0x20,0x05,0x20,0x09,0x00,0x10,0x00,0x20,0x00,0x40}, // 0xBE
|
||||
{0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0xBF
|
||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xFF,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00}, // 0xC0
|
||||
{0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0xFF,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00}, // 0xC1
|
||||
{0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0xFF,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00}, // 0xC2
|
||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00}, // 0xC3
|
||||
{0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00}, // 0xC4
|
||||
{0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0xFF,0xFF,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00}, // 0xC5
|
||||
{0x00,0x00,0x30,0x00,0x48,0x24,0x88,0x44,0x88,0x24,0x90,0x24,0xF8,0x43,0x08,0x00,0x00,0x00,0x00,0x00}, // 0xC6
|
||||
{0x08,0x00,0x70,0x00,0xC0,0x41,0x40,0x8E,0x40,0xD8,0x40,0x4C,0x40,0x83,0xC0,0x00,0x30,0x00,0x08,0x00}, // 0xC7
|
||||
{0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0x40,0x00,0x40,0xFF,0x40,0x01,0x40,0x01,0x40,0x01,0x40,0x01}, // 0xC8
|
||||
{0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x01,0x00,0x01,0x7F,0x01,0x40,0x01,0x40,0x01,0x40,0x01,0x40,0x01}, // 0xC9
|
||||
{0x40,0x01,0x40,0x01,0x40,0x01,0x40,0xFF,0x40,0x00,0x40,0xFF,0x40,0x01,0x40,0x01,0x40,0x01,0x40,0x01}, // 0xCA
|
||||
{0x40,0x01,0x40,0x01,0x40,0x01,0x7F,0x01,0x00,0x01,0x7F,0x01,0x40,0x01,0x40,0x01,0x40,0x01,0x40,0x01}, // 0xCB
|
||||
{0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x7F,0xFF,0x40,0x01,0x40,0x01,0x40,0x01,0x40,0x01}, // 0xCC
|
||||
{0x40,0x01,0x40,0x01,0x40,0x01,0x40,0x01,0x40,0x01,0x40,0x01,0x40,0x01,0x40,0x01,0x40,0x01,0x40,0x01}, // 0xCD
|
||||
{0x40,0x01,0x40,0x01,0x40,0x01,0x7F,0xFF,0x00,0x00,0x7F,0xFF,0x40,0x01,0x40,0x01,0x40,0x01,0x40,0x01}, // 0xCE
|
||||
{0x00,0x00,0x20,0x10,0xC0,0x0F,0x40,0x08,0x40,0x08,0x40,0x08,0x40,0x08,0xC0,0x0F,0x20,0x10,0x00,0x00}, // 0xCF
|
||||
{0x00,0x00,0xE0,0x41,0x10,0x52,0x08,0x74,0x08,0x24,0x08,0x54,0x10,0x0E,0xE0,0x03,0x00,0x00,0x00,0x00}, // 0xD0
|
||||
{0x00,0x01,0xF8,0x1F,0x08,0x11,0x08,0x11,0x08,0x10,0x08,0x10,0x10,0x08,0xE0,0x07,0x00,0x00,0x00,0x00}, // 0xD1
|
||||
{0x00,0x00,0xF8,0x1F,0x88,0x10,0x88,0x50,0x88,0x90,0x88,0x90,0x88,0x50,0x08,0x10,0x00,0x00,0x00,0x00}, // 0xD2
|
||||
{0x00,0x00,0xF8,0x1F,0x88,0x90,0x88,0x10,0x88,0x10,0x88,0x10,0x88,0x90,0x08,0x10,0x00,0x00,0x00,0x00}, // 0xD3
|
||||
{0x00,0x00,0xF8,0x1F,0x88,0x10,0x88,0x10,0x88,0x90,0x88,0x50,0x88,0x10,0x08,0x10,0x00,0x00,0x00,0x00}, // 0xD4
|
||||
{0x00,0x00,0x00,0x04,0x00,0x04,0x00,0x04,0xF8,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0xD5
|
||||
{0x00,0x00,0x08,0x10,0x08,0x10,0x08,0x10,0xF8,0x5F,0x08,0x90,0x08,0x10,0x08,0x10,0x00,0x00,0x00,0x00}, // 0xD6
|
||||
{0x00,0x00,0x08,0x10,0x08,0x10,0x08,0x50,0xF8,0x9F,0x08,0x90,0x08,0x50,0x08,0x10,0x00,0x00,0x00,0x00}, // 0xD7
|
||||
{0x00,0x00,0x08,0x10,0x08,0x90,0x08,0x10,0xF8,0x1F,0x08,0x10,0x08,0x90,0x08,0x10,0x00,0x00,0x00,0x00}, // 0xD8
|
||||
{0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0xD9
|
||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00}, // 0xDA
|
||||
{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}, // 0xDB
|
||||
{0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00}, // 0xDC
|
||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x7E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0xDD
|
||||
{0x00,0x00,0x08,0x10,0x08,0x10,0x08,0x90,0xF8,0x5F,0x08,0x10,0x08,0x10,0x08,0x10,0x00,0x00,0x00,0x00}, // 0xDE
|
||||
{0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF}, // 0xDF
|
||||
{0x00,0x00,0xE0,0x07,0x10,0x08,0x08,0x10,0x08,0x50,0x08,0x90,0x08,0x10,0x10,0x08,0xE0,0x07,0x00,0x00}, // 0xE0
|
||||
{0x00,0x00,0xF8,0x3F,0x00,0x40,0x00,0x40,0x08,0x47,0x88,0x38,0x48,0x00,0x30,0x00,0x00,0x00,0x00,0x00}, // 0xE1
|
||||
{0x00,0x00,0xE0,0x07,0x10,0x08,0x08,0x50,0x08,0x90,0x08,0x90,0x08,0x50,0x10,0x08,0xE0,0x07,0x00,0x00}, // 0xE2
|
||||
{0x00,0x00,0xE0,0x07,0x10,0x08,0x08,0x90,0x08,0x50,0x08,0x10,0x08,0x10,0x10,0x08,0xE0,0x07,0x00,0x00}, // 0xE3
|
||||
{0x00,0x00,0xE0,0x01,0x10,0x22,0x08,0x44,0x08,0x24,0x08,0x24,0x10,0x42,0xE0,0x01,0x00,0x00,0x00,0x00}, // 0xE4
|
||||
{0x00,0x00,0xE0,0x07,0x10,0x48,0x08,0x90,0x08,0xD0,0x08,0x50,0x08,0x90,0x10,0x08,0xE0,0x07,0x00,0x00}, // 0xE5
|
||||
{0x00,0x00,0xFF,0x07,0x10,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x10,0x00,0xF8,0x07,0x00,0x00,0x00,0x00}, // 0xE6
|
||||
{0x00,0x00,0xFF,0x7F,0x10,0x02,0x08,0x04,0x08,0x04,0x08,0x04,0x10,0x06,0xE0,0x01,0x00,0x00,0x00,0x00}, // 0xE7
|
||||
{0x00,0x00,0xF8,0x1F,0x20,0x04,0x20,0x04,0x20,0x04,0x20,0x04,0x40,0x04,0x80,0x03,0x00,0x00,0x00,0x00}, // 0xE8
|
||||
{0x00,0x00,0xE0,0x1F,0x18,0x00,0x08,0x00,0x08,0x40,0x08,0x80,0x10,0x00,0xE0,0x1F,0x00,0x00,0x00,0x00}, // 0xE9
|
||||
{0x00,0x00,0xE0,0x1F,0x18,0x00,0x08,0x40,0x08,0x80,0x08,0x80,0x10,0x40,0xE0,0x1F,0x00,0x00,0x00,0x00}, // 0xEA
|
||||
{0x00,0x00,0xE0,0x1F,0x18,0x00,0x08,0x80,0x08,0x40,0x08,0x00,0x10,0x00,0xE0,0x1F,0x00,0x00,0x00,0x00}, // 0xEB
|
||||
{0x01,0x04,0x01,0x03,0xC1,0x00,0x62,0x00,0x1C,0x20,0x18,0x40,0x60,0x00,0x80,0x00,0x00,0x03,0x00,0x04}, // 0xEC
|
||||
{0x00,0x10,0x00,0x08,0x00,0x06,0x00,0x01,0xF8,0x40,0x00,0x81,0x00,0x02,0x00,0x04,0x00,0x08,0x00,0x10}, // 0xED
|
||||
{0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80}, // 0xEE
|
||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0xEF
|
||||
{0x00,0x00,0x00,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x00,0x00,0x00,0x00}, // 0xF0
|
||||
{0x00,0x00,0x08,0x01,0x08,0x01,0x08,0x01,0x08,0x01,0xC8,0x07,0x08,0x01,0x08,0x01,0x08,0x01,0x00,0x00}, // 0xF1
|
||||
{0x05,0x00,0x05,0x00,0x05,0x00,0x05,0x00,0x05,0x00,0x05,0x00,0x05,0x00,0x05,0x00,0x05,0x00,0x05,0x00}, // 0xF2
|
||||
{0x08,0x42,0x10,0x52,0x20,0x5A,0xC0,0x6C,0x00,0x01,0x60,0x02,0xA0,0x0C,0x20,0x11,0xF8,0x21,0x20,0x40}, // 0xF3
|
||||
{0x00,0x00,0x00,0x38,0x00,0x7C,0x00,0x7E,0xFE,0x7F,0x00,0x40,0x00,0x40,0xFE,0x7F,0x00,0x00,0x00,0x00}, // 0xF4
|
||||
{0x00,0x00,0x00,0x00,0x86,0x3B,0xC2,0x4C,0x42,0x44,0x62,0x46,0x32,0x42,0xDC,0x41,0x00,0x00,0x00,0x00}, // 0xF5
|
||||
{0x00,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x58,0x06,0x58,0x06,0x40,0x00,0x40,0x00,0x40,0x00,0x00,0x00}, // 0xF6
|
||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x05,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0xF7
|
||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x48,0x00,0x48,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00}, // 0xF8
|
||||
{0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00}, // 0xF9
|
||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x00,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0xFA
|
||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x7E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0xFB
|
||||
{0x00,0x00,0x00,0x00,0x00,0x42,0x00,0x52,0x00,0x52,0x00,0x52,0x00,0x6C,0x00,0x00,0x00,0x00,0x00,0x00}, // 0xFC
|
||||
{0x00,0x00,0x00,0x00,0x00,0x42,0x00,0x46,0x00,0x4A,0x00,0x4A,0x00,0x32,0x00,0x00,0x00,0x00,0x00,0x00}, // 0xFD
|
||||
{0x00,0x00,0xF8,0x07,0xF8,0x07,0xF8,0x07,0xF8,0x07,0xF8,0x07,0xF8,0x07,0xF8,0x07,0xF8,0x07,0x00,0x00}, // 0xFE
|
||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} // 0xFF
|
||||
};
|
||||
#include "FreeSans9pt7b.h"
|
||||
#include "FreeSansBold18pt7b.h"
|
||||
#include "FreeSansBold24pt7b.h"
|
||||
@@ -1,14 +1,2 @@
|
||||
#ifdef BUILD_NEWTON_M3_22_BWR
|
||||
#include "../hal/Newton_M3_nRF52811/Newton_M3_nRF52811_22_BWR.h"
|
||||
#include "../hal/Newton_M3_nRF52811/HAL_Newton_M3.h"
|
||||
#endif
|
||||
#ifdef BUILD_NEWTON_M3_29_BWR
|
||||
#include "../hal/Newton_M3_nRF52811/Newton_M3_nRF52811_29_BWR.h"
|
||||
#include "../hal/Newton_M3_nRF52811/HAL_Newton_M3.h"
|
||||
#endif
|
||||
|
||||
#ifdef BUILD_NEWTON_M3_75_BWR
|
||||
#include "../hal/Newton_M3_nRF52811/Newton_M3_nRF52811_75_BWR.h"
|
||||
#include "../hal/Newton_M3_nRF52811/HAL_Newton_M3.h"
|
||||
#endif
|
||||
|
||||
#include "../hal/Newton_M3_nRF52811/HAL_Newton_M3.h"
|
||||
@@ -1,19 +1,17 @@
|
||||
#pragma once
|
||||
#include <Arduino.h>
|
||||
|
||||
#define LUTGROUP_NEGATIVE 0
|
||||
#define LUTGROUP_FASTBLINK 1
|
||||
#define LUTGROUP_SLOWBLINK 2
|
||||
#define LUTGROUP_SET 3
|
||||
#define LUTGROUP_IMPROVE_SHARPNESS 4
|
||||
#define LUTGROUP_IMPROVE_REDS 5
|
||||
#define LUTGROUP_UNUSED 6
|
||||
|
||||
#define LUTGROUP_NEGATIVE 0
|
||||
#define LUTGROUP_FASTBLINK 1
|
||||
#define LUTGROUP_SLOWBLINK 2
|
||||
#define LUTGROUP_SET 3
|
||||
#define LUTGROUP_IMPROVE_SHARPNESS 4
|
||||
#define LUTGROUP_IMPROVE_REDS 5
|
||||
#define LUTGROUP_UNUSED 6
|
||||
|
||||
#define LUTGROUP_UNKNOWN 7
|
||||
#define LUTGROUP_UNUSED3 8
|
||||
#define LUTGROUP_UNUSED4 9
|
||||
|
||||
#define LUTGROUP_UNKNOWN 7
|
||||
#define LUTGROUP_UNUSED3 8
|
||||
#define LUTGROUP_UNUSED4 9
|
||||
|
||||
#pragma pack(1)
|
||||
struct vgroup {
|
||||
@@ -29,12 +27,26 @@ struct lut {
|
||||
|
||||
struct lut10 {
|
||||
struct vgroup group[10];
|
||||
} ;
|
||||
};
|
||||
|
||||
struct lut12 {
|
||||
struct vgroup group[12];
|
||||
};
|
||||
|
||||
struct group {
|
||||
uint8_t phaselength[4];
|
||||
uint8_t repeat;
|
||||
} ;
|
||||
};
|
||||
|
||||
struct group12 {
|
||||
uint8_t tp0a;
|
||||
uint8_t tp0b;
|
||||
uint8_t sr0ab;
|
||||
uint8_t tp0c;
|
||||
uint8_t tp0d;
|
||||
uint8_t sr0cd;
|
||||
uint8_t repeat;
|
||||
};
|
||||
|
||||
struct waveform {
|
||||
struct lut lut[5];
|
||||
@@ -43,7 +55,7 @@ struct waveform {
|
||||
uint8_t sourcelevel[3];
|
||||
uint8_t dummyline;
|
||||
uint8_t gatewidth;
|
||||
} ;
|
||||
};
|
||||
|
||||
struct waveform10 {
|
||||
struct lut10 lut[5];
|
||||
@@ -52,5 +64,12 @@ struct waveform10 {
|
||||
uint8_t sourcelevel[3];
|
||||
uint8_t dummyline;
|
||||
uint8_t gatewidth;
|
||||
} ;
|
||||
};
|
||||
|
||||
struct waveform12 {
|
||||
struct lut12 lut[5];
|
||||
struct group12 group[12];
|
||||
uint8_t fr[6];
|
||||
uint8_t xon[3];
|
||||
};
|
||||
#pragma pack(0)
|
||||
@@ -24,7 +24,7 @@
|
||||
#define DETECT_P1_0_BUTTON 1
|
||||
#define DETECT_P1_0_JIG 2
|
||||
|
||||
#define INIT_EPD_VOLTREADING 0x80
|
||||
#define INIT_VOLTREADING 0x80
|
||||
#define INIT_RADIO 0x40
|
||||
#define INIT_I2C 0x20
|
||||
#define INIT_UART 0x10
|
||||
@@ -44,8 +44,9 @@
|
||||
#define MAXIMUM_PING_ATTEMPTS 20 // How many attempts to discover an AP the tag should do
|
||||
#define PING_REPLY_WINDOW 5UL
|
||||
|
||||
#define LONG_DATAREQ_INTERVAL 300 // How often (in seconds, approximately) the tag should do a long datareq (including temperature)
|
||||
#define VOLTAGE_CHECK_INTERVAL 288 // How often the tag should do a battery voltage check (multiplied by LONG_DATAREQ_INTERVAL)
|
||||
#define LONG_DATAREQ_INTERVAL 300 // How often (in seconds, approximately) the tag should do a long datareq (including temperature)
|
||||
#define VOLTAGE_CHECK_INTERVAL 288 // How often the tag should do a battery voltage check (multiplied by LONG_DATAREQ_INTERVAL)
|
||||
|
||||
#define BATTERY_VOLTAGE_MINIMUM 2450 // 2600 or below is the best we can do on the EPD
|
||||
|
||||
// power saving when no AP's were found (scanning every X)
|
||||
@@ -56,6 +57,13 @@
|
||||
#define INTERVAL_2_ATTEMPTS 12 // for 12 attempts (an additional day)
|
||||
#define INTERVAL_3_TIME 86400UL // Finally, try every day
|
||||
|
||||
// slideshow power settings
|
||||
#define SLIDESHOW_FORCE_FULL_REFRESH_EVERY 16 // force a full refresh every X screen draws
|
||||
#define SLIDESHOW_INTERVAL_FAST 15 // interval for 'fast'
|
||||
#define SLIDESHOW_INTERVAL_MEDIUM 60
|
||||
#define SLIDESHOW_INTERVAL_SLOW 300
|
||||
#define SLIDESHOW_INTERVAL_GLACIAL 1800
|
||||
|
||||
extern uint8_t checkButtonOrJig();
|
||||
|
||||
extern void setupPortsInitial();
|
||||
@@ -64,7 +72,7 @@ extern void powerUp(const uint8_t parts);
|
||||
extern void powerDown(const uint8_t parts);
|
||||
|
||||
extern void initAfterWake();
|
||||
extern void doSleep(const uint32_t t);
|
||||
extern void doSleep(const uint32_t t);
|
||||
|
||||
extern void addAverageValue();
|
||||
extern uint16_t getNextSleep();
|
||||
@@ -72,17 +80,14 @@ extern uint16_t getNextSleep();
|
||||
extern uint32_t getNextScanSleep(const bool increment);
|
||||
extern void initPowerSaving(const uint16_t initialValue);
|
||||
|
||||
extern uint8_t wakeUpReason;
|
||||
extern uint8_t wakeUpReason;
|
||||
|
||||
extern uint8_t capabilities;
|
||||
extern uint8_t capabilities;
|
||||
|
||||
extern uint16_t nextCheckInFromAP;
|
||||
extern uint8_t dataReqLastAttempt;
|
||||
extern int8_t temperature;
|
||||
extern uint16_t batteryVoltage;
|
||||
extern bool lowBattery;
|
||||
extern uint8_t scanAttempts;
|
||||
extern uint16_t longDataReqCounter;
|
||||
extern uint16_t voltageCheckCounter;
|
||||
extern uint16_t nextCheckInFromAP;
|
||||
extern uint8_t dataReqLastAttempt;
|
||||
extern uint8_t scanAttempts;
|
||||
extern uint16_t longDataReqCounter;
|
||||
extern uint16_t voltageCheckCounter;
|
||||
|
||||
#endif
|
||||
@@ -3,8 +3,24 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define FW_VERSION 017 // version number (max 2.5.5 :) )
|
||||
#define FW_VERSION_SUFFIX "BETA" // suffix, like -RC1 or whatever.
|
||||
// #define DEBUGBLOCKS // uncomment to enable extra debug information on the block transfers
|
||||
// #define PRINT_LUT // uncomment if you want the tag to print the LUT for the current temperature bracket
|
||||
#endif
|
||||
#define FW_VERSION 0x0026 // version number (max 2.5.5 :) )
|
||||
#define FW_VERSION_SUFFIX "LED2" // suffix, like RC1 or whatever.
|
||||
//#define DEBUGBLOCKS // uncomment to enable extra debug information on the block transfers
|
||||
#endif
|
||||
|
||||
#define SETTINGS_STRUCT_VERSION 0x01
|
||||
|
||||
#define DEFAULT_SETTING_FASTBOOT 0
|
||||
#define DEFAULT_SETTING_RFWAKE 0
|
||||
#define DEFAULT_SETTING_TAGROAMING 0
|
||||
#define DEFAULT_SETTING_SCANFORAP 1
|
||||
#define DEFAULT_SETTING_LOWBATSYMBOL 1
|
||||
#define DEFAULT_SETTING_NORFSYMBOL 1
|
||||
|
||||
extern struct tagsettings tagSettings;
|
||||
|
||||
void loadDefaultSettings();
|
||||
void writeSettings();
|
||||
void loadSettings();
|
||||
void loadSettingsFromBuffer(uint8_t* p);
|
||||
void invalidateSettingsEEPROM();
|
||||
|
||||
@@ -1,84 +0,0 @@
|
||||
#ifndef _JSCREEN_H_
|
||||
#define _JSCREEN_H_
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define EPD_SSD1619
|
||||
|
||||
#define epdSend spi_write
|
||||
#define EPD_DIRECTION_X false
|
||||
#define EPD_DIRECTION_Y true
|
||||
#define EPD_SIZE_SINGLE false
|
||||
#define EPD_SIZE_DOUBLE true
|
||||
#define EPD_COLOR_RED true
|
||||
#define EPD_COLOR_BLACK false
|
||||
#define EPD_LOAD_CUSTOM_LUT true
|
||||
#define EPD_LOAD_OTP_LUT false
|
||||
#define EPD_MODE_NORMAL 0x00
|
||||
#define EPD_MODE_INVERT 0x08
|
||||
#define EPD_MODE_IGNORE 0x04
|
||||
|
||||
#define EPD_LUT_DEFAULT 0
|
||||
#define EPD_LUT_NO_REPEATS 1
|
||||
#define EPD_LUT_FAST_NO_REDS 2
|
||||
#define EPD_LUT_FAST 3
|
||||
#define EPD_LUT_OTA 0x10
|
||||
|
||||
#define epdSelect() \
|
||||
do \
|
||||
{ \
|
||||
digitalWrite(EPD_CS, LOW); \
|
||||
} while (0)
|
||||
|
||||
#define epdDeselect() \
|
||||
do \
|
||||
{ \
|
||||
digitalWrite(EPD_CS, HIGH); \
|
||||
} while (0)
|
||||
|
||||
void epdSetup();
|
||||
void epdEnterSleep();
|
||||
uint16_t epdGetBattery();
|
||||
void epdConfigGPIO(bool setup);
|
||||
|
||||
extern bool epdGPIOActive;
|
||||
extern uint8_t dispLutSize;
|
||||
extern uint8_t customLUT[];
|
||||
|
||||
void setWindowX(uint16_t start, uint16_t end);
|
||||
void setWindowY(uint16_t start, uint16_t end);
|
||||
void setPosXY(uint16_t x, uint16_t y);
|
||||
void setColorMode(uint8_t red, uint8_t bw);
|
||||
void fillWindowWithPattern(bool color);
|
||||
void clearWindow(bool color);
|
||||
void clearScreen();
|
||||
void draw();
|
||||
void drawNoWait();
|
||||
void drawWithSleep();
|
||||
void epdWaitRdy();
|
||||
void drawLineHorizontal(bool color, uint16_t x1, uint16_t x2, uint16_t y);
|
||||
void drawLineVertical(bool color, uint16_t x, uint16_t y1, uint16_t y2);
|
||||
void beginFullscreenImage();
|
||||
void beginWriteFramebuffer(bool color);
|
||||
void endWriteFramebuffer();
|
||||
void loadRawBitmap(uint8_t *bmp, uint16_t x, uint16_t y, bool color);
|
||||
void printBarcode(const uint8_t *string, uint16_t x, uint16_t y);
|
||||
|
||||
void selectLUT(uint8_t lut);
|
||||
|
||||
void ByteDecode(uint8_t byte);
|
||||
|
||||
void epdPrintBegin(uint16_t x, uint16_t y, bool direction, bool fontsize, bool red);
|
||||
void epdPrintEnd();
|
||||
|
||||
void beginFullscreenImage();
|
||||
void beginWriteFramebuffer(bool color);
|
||||
|
||||
void lutTest();
|
||||
|
||||
// for printf.c
|
||||
void writeCharEPD(uint8_t c);
|
||||
void epdpr(const char *c, ...);
|
||||
|
||||
#endif
|
||||
@@ -12,9 +12,15 @@ extern uint8_t curImgSlot;
|
||||
extern void setupRadio(void);
|
||||
extern void killRadio(void);
|
||||
|
||||
extern uint8_t findSlotDataTypeArg(uint8_t arg);
|
||||
extern uint8_t findNextSlideshowImage(uint8_t start);
|
||||
extern uint8_t getEepromImageDataArgument(const uint8_t slot);
|
||||
|
||||
extern struct AvailDataInfo *getAvailDataInfo();
|
||||
extern struct AvailDataInfo *getShortAvailDataInfo();
|
||||
extern void drawImageFromEeprom(const uint8_t imgSlot);
|
||||
|
||||
extern void drawImageFromEeprom(const uint8_t imgSlot, uint8_t lut);
|
||||
extern void eraseImageBlocks();
|
||||
extern bool processAvailDataInfo(struct AvailDataInfo *avail);
|
||||
extern void initializeProto();
|
||||
extern uint8_t detectAP(const uint8_t channel);
|
||||
|
||||
@@ -1,82 +0,0 @@
|
||||
#ifndef _JSCREEN_H_
|
||||
#define _JSCREEN_H_
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define epdSend spi_write
|
||||
#define EPD_DIRECTION_X false
|
||||
#define EPD_DIRECTION_Y true
|
||||
#define EPD_SIZE_SINGLE false
|
||||
#define EPD_SIZE_DOUBLE true
|
||||
#define EPD_COLOR_RED true
|
||||
#define EPD_COLOR_BLACK false
|
||||
#define EPD_LOAD_CUSTOM_LUT true
|
||||
#define EPD_LOAD_OTP_LUT false
|
||||
#define EPD_MODE_NORMAL 0x00
|
||||
#define EPD_MODE_INVERT 0x08
|
||||
#define EPD_MODE_IGNORE 0x04
|
||||
|
||||
#define EPD_LUT_DEFAULT 0
|
||||
#define EPD_LUT_NO_REPEATS 1
|
||||
#define EPD_LUT_FAST_NO_REDS 2
|
||||
#define EPD_LUT_FAST 3
|
||||
|
||||
|
||||
#define epdSelect() \
|
||||
do \
|
||||
{ \
|
||||
digitalWrite(EPD_CS, LOW); \
|
||||
} while (0)
|
||||
|
||||
#define epdDeselect() \
|
||||
do \
|
||||
{ \
|
||||
digitalWrite(EPD_CS, HIGH); \
|
||||
} while (0)
|
||||
|
||||
void epdSetup();
|
||||
void epdEnterSleep();
|
||||
uint16_t epdGetBattery();
|
||||
void epdConfigGPIO(bool setup);
|
||||
|
||||
void epdSetup();
|
||||
void epdEnterSleep();
|
||||
uint16_t epdGetBattery();
|
||||
void epdConfigGPIO(bool setup);
|
||||
|
||||
extern bool epdGPIOActive;
|
||||
|
||||
void setColorMode(uint8_t red, uint8_t bw) ;
|
||||
void clearWindow(bool color);
|
||||
void clearScreen();
|
||||
void draw();
|
||||
void drawNoWait();
|
||||
void drawWithSleep();
|
||||
void epdWaitRdy();
|
||||
|
||||
void beginFullscreenImage();
|
||||
void beginWriteFramebuffer(bool color);
|
||||
void endWriteFramebuffer();
|
||||
void loadRawBitmap(uint8_t* bmp, uint16_t x, uint16_t y, bool color) ;
|
||||
void printBarcode(const uint8_t* string, uint16_t x, uint16_t y);
|
||||
|
||||
void selectLUT(uint8_t lut);
|
||||
|
||||
void ByteDecode(uint8_t byte);
|
||||
|
||||
void epdPrintBegin(uint16_t x, uint16_t y, bool direction, bool fontsize, bool red);
|
||||
void epdPrintEnd();
|
||||
|
||||
void beginFullscreenImage();
|
||||
void beginWriteFramebuffer(bool color);
|
||||
|
||||
void lutTest();
|
||||
|
||||
void epdTest();
|
||||
|
||||
// for printf.c
|
||||
void writeCharEPD(uint8_t c);
|
||||
void epdpr(const char *c, ...);
|
||||
|
||||
#endif
|
||||
@@ -11,32 +11,16 @@ lib_deps =
|
||||
stevemarple/SoftWire @ ^2.0.9
|
||||
stevemarple/AsyncDelay @ ^1.1.2
|
||||
https://github.com/calebstewart/md5
|
||||
https://github.com/ricmoo/QRCode
|
||||
extra_scripts = post:preparefiles.py
|
||||
|
||||
|
||||
[env:Newton_M3_22_BWR]
|
||||
[env:Newton_M3_Universal]
|
||||
board_build.ldscript = nrf52811_bootloader.ld
|
||||
build_flags =
|
||||
-Wunused-macros
|
||||
${env.build_flags}
|
||||
-D BUILD_NEWTON_M3_22_BWR
|
||||
-D BUILD_NEWTON_M3_43_BWR
|
||||
-D EPD_DRIVER=UCVARIANT043
|
||||
-Tnrf52811_bootloader.ld
|
||||
build_src_filter =
|
||||
+<*>-<uc8179.cpp>+<../hal/Newton_M3_nRF52811/*>
|
||||
|
||||
[env:Newton_M3_29_BWR]
|
||||
board_build.ldscript = nrf52811_bootloader.ld
|
||||
build_flags =
|
||||
${env.build_flags}
|
||||
-D BUILD_NEWTON_M3_29_BWR
|
||||
-Tnrf52811_bootloader.ld
|
||||
build_src_filter =
|
||||
+<*>-<uc8179.cpp>+<../hal/Newton_M3_nRF52811/*>
|
||||
|
||||
[env:Newton_M3_75_BWR]
|
||||
board_build.ldscript = nrf52811_bootloader.ld
|
||||
build_flags =
|
||||
${env.build_flags}
|
||||
-Tnrf52811_bootloader.ld
|
||||
-D BUILD_NEWTON_M3_75_BWR
|
||||
build_src_filter =
|
||||
+<*>-<ssd1619.cpp>+<../hal/Newton_M3_nRF52811/*>
|
||||
+<*>+<../hal/Newton_M3_nRF52811/*>
|
||||
@@ -3,17 +3,11 @@
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "proto.h"
|
||||
#include "../../../oepl-proto.h"
|
||||
#include "../../../oepl-definitions.h"
|
||||
|
||||
#include "hal.h"
|
||||
|
||||
#define ADDR_MODE_NONE (0)
|
||||
#define ADDR_MODE_SHORT (2)
|
||||
#define ADDR_MODE_LONG (3)
|
||||
|
||||
#define FRAME_TYPE_BEACON (0)
|
||||
#define FRAME_TYPE_DATA (1)
|
||||
#define FRAME_TYPE_ACK (2)
|
||||
#define FRAME_TYPE_MAC_CMD (3)
|
||||
|
||||
extern uint8_t mSelfMac[8];
|
||||
uint8_t mLastLqi = 0;
|
||||
|
||||
@@ -1,101 +1,649 @@
|
||||
#include "drawing.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <Arduino.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "eeprom.h"
|
||||
#include "proto.h"
|
||||
|
||||
#include "../../../oepl-proto.h"
|
||||
#include "../../../oepl-definitions.h"
|
||||
|
||||
#include "userinterface.h" // for addIcons
|
||||
|
||||
#include "powermgt.h"
|
||||
#include "hal.h"
|
||||
#include "qrcode.h"
|
||||
|
||||
#include "epd_driver/epd_interface.h"
|
||||
|
||||
#define EEPROM_XFER_BLOCKSIZE 512 // shouldn't be any less than 256 bytes probably
|
||||
#define DRAWITEM_LIST_SIZE 24
|
||||
|
||||
#if (SCREEN_WIDTH == 152)
|
||||
void drawImageFromBuffer(uint8_t *buffer, const uint8_t lut) {
|
||||
printf("Doing raw 1bpp\n");
|
||||
epdSetup();
|
||||
if (lut)
|
||||
selectLUT(lut);
|
||||
beginFullscreenImage();
|
||||
clearScreen();
|
||||
beginWriteFramebuffer(EPD_COLOR_BLACK);
|
||||
epdSelect();
|
||||
for (uint16_t c = 0; c < (SCREEN_HEIGHT * (SCREEN_WIDTH / 8)); c++) {
|
||||
epdSend(buffer[c]);
|
||||
static drawItem *drawItems[DRAWITEM_LIST_SIZE] = {0};
|
||||
|
||||
void addBufferedImage(uint16_t x, uint16_t y, bool color, enum rotation ro, const uint8_t *image, bool mask) {
|
||||
drawItem *di = new drawItem;
|
||||
|
||||
di->setRotation(ro);
|
||||
if (di->direction ^ epd->drawDirectionRight) {
|
||||
int16_t temp = x;
|
||||
x = y;
|
||||
y = temp;
|
||||
}
|
||||
epdDeselect();
|
||||
endWriteFramebuffer();
|
||||
addOverlay();
|
||||
drawWithSleep();
|
||||
}
|
||||
#endif
|
||||
|
||||
#define EEPROM_XFER_BLOCKSIZE 512 // shouldn't be any less than 256 bytes probably
|
||||
uint16_t originalWidthBytes = (((uint16_t *)image)[0]) / 8;
|
||||
uint16_t size = 0;
|
||||
uint16_t width = ((uint16_t *)image)[0];
|
||||
|
||||
// find out if the original data was aligned in one byte; if not, add a byte
|
||||
if (((uint16_t *)image)[0] % 8) originalWidthBytes++;
|
||||
|
||||
// if we're drawing in X direction, we shift the content here. Add extra space for shifting!
|
||||
if (!di->direction) {
|
||||
width += x % 8;
|
||||
}
|
||||
|
||||
// check if the size is aligned in bytes; if not, add an extra for good measure;
|
||||
if (width % 8) {
|
||||
width /= 8;
|
||||
width++;
|
||||
} else {
|
||||
width /= 8;
|
||||
}
|
||||
|
||||
size = width * ((uint16_t *)image)[1];
|
||||
size += 2; // not needed
|
||||
|
||||
uint8_t *im = (uint8_t *)calloc(size, 1);
|
||||
|
||||
for (uint16_t copyY = 0; copyY < ((uint16_t *)image)[1]; copyY++) {
|
||||
memcpy(im + (copyY * width), image + 4 + (copyY * originalWidthBytes), originalWidthBytes);
|
||||
|
||||
// if we draw in X direction, we need to shift bytes in the array
|
||||
if (!di->direction && (x % 8)) {
|
||||
drawItem::shiftBytesRight(im + (copyY * width), x % 8, width);
|
||||
}
|
||||
}
|
||||
|
||||
di->addItem(im, width * 8, ((uint16_t *)image)[1]);
|
||||
|
||||
di->xpos = x;
|
||||
di->ypos = y;
|
||||
di->color = color;
|
||||
if (mask)
|
||||
di->type = drawItem::drawType::DRAW_MASK;
|
||||
else
|
||||
di->type = drawItem::drawType::DRAW_BUFFERED_1BPP;
|
||||
|
||||
di->addToList();
|
||||
}
|
||||
|
||||
void addFlashImage(uint16_t x, uint16_t y, bool color, enum rotation ro, const uint8_t *image) {
|
||||
drawItem *di = new drawItem;
|
||||
|
||||
di->setRotation(ro);
|
||||
|
||||
if (di->direction ^ epd->drawDirectionRight) {
|
||||
int16_t temp = x;
|
||||
x = y;
|
||||
y = temp;
|
||||
}
|
||||
|
||||
di->addItem((uint8_t *)(image + 4), ((uint16_t *)image)[0], ((uint16_t *)image)[1]);
|
||||
|
||||
di->xpos = x;
|
||||
di->ypos = y;
|
||||
di->color = color;
|
||||
di->cleanUp = false;
|
||||
di->type = drawItem::drawType::DRAW_BUFFERED_1BPP;
|
||||
di->addToList();
|
||||
}
|
||||
|
||||
void addQR(uint16_t x, uint16_t y, uint8_t version, uint8_t scale, const char *c, ...) {
|
||||
char out_buffer[256];
|
||||
va_list lst;
|
||||
va_start(lst, c);
|
||||
vsnprintf(out_buffer, 255, c, lst);
|
||||
va_end(lst);
|
||||
|
||||
QRCode qrcode;
|
||||
// Allocate a chunk of memory to store the QR code
|
||||
uint8_t qrcodeBytes[qrcode_getBufferSize(version)];
|
||||
qrcode_initText(&qrcode, qrcodeBytes, version, ECC_LOW, out_buffer);
|
||||
|
||||
drawItem *di = new drawItem;
|
||||
di->setRotation(rotation::ROTATE_0);
|
||||
|
||||
uint8_t xbytes = (qrcode.size * scale) / 8;
|
||||
if (qrcode.size % 8) xbytes++;
|
||||
|
||||
uint16_t size = xbytes * (qrcode.size * scale);
|
||||
uint8_t *im = (uint8_t *)calloc(size + 1, 1);
|
||||
|
||||
uint8_t *qrbuf = im;
|
||||
|
||||
for (uint8_t qry = 0; qry < qrcode.size; qry++) {
|
||||
for (uint8_t scale_y = 0; scale_y < scale; scale_y++) {
|
||||
for (uint8_t qrx = 0; qrx < qrcode.size; qrx++) {
|
||||
for (uint8_t scale_x = 0; scale_x < scale; scale_x++) {
|
||||
if (qrcode_getModule(&qrcode, qrx, qry)) {
|
||||
// Calculate the position in the framebuffer for the scaled pixel
|
||||
uint8_t scaled_qrx = (qrx * scale) + scale_x;
|
||||
uint8_t scaled_qry = (qry * scale) + scale_y;
|
||||
|
||||
// Calculate the byte and bit positions in the framebuffer
|
||||
uint8_t fb_byte = scaled_qrx / 8;
|
||||
uint8_t fb_bit = 7 - (scaled_qrx % 8);
|
||||
|
||||
// Set the bit in the framebuffer
|
||||
qrbuf[fb_byte + (scaled_qry * xbytes)] |= (1 << fb_bit);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
di->addItem(im, xbytes * 8, qrcode.size * scale);
|
||||
|
||||
di->xpos = x;
|
||||
di->ypos = y;
|
||||
di->color = 0;
|
||||
di->type = drawItem::drawType::DRAW_BUFFERED_1BPP;
|
||||
di->addToList();
|
||||
}
|
||||
|
||||
void drawImageAtAddress(uint32_t addr, uint8_t lut) {
|
||||
uint8_t* xferbuffer = (uint8_t*)malloc(EEPROM_XFER_BLOCKSIZE);
|
||||
powerUp(INIT_EEPROM);
|
||||
uint8_t *xferbuffer = (uint8_t *)malloc(EEPROM_XFER_BLOCKSIZE);
|
||||
struct EepromImageHeader *eih = (struct EepromImageHeader *)xferbuffer;
|
||||
eepromRead(addr, xferbuffer, sizeof(struct EepromImageHeader));
|
||||
switch (eih->dataType) {
|
||||
case DATATYPE_IMG_RAW_1BPP:
|
||||
printf("Doing raw 1bpp\n");
|
||||
epdSetup();
|
||||
if (lut)
|
||||
selectLUT(lut);
|
||||
beginFullscreenImage();
|
||||
clearScreen();
|
||||
beginWriteFramebuffer(EPD_COLOR_BLACK);
|
||||
epdSelect();
|
||||
for (uint32_t c = 0; c < (SCREEN_HEIGHT * (SCREEN_WIDTH / 8)); c++) {
|
||||
if (c % EEPROM_XFER_BLOCKSIZE == 0) {
|
||||
epdDeselect();
|
||||
eepromRead(addr + sizeof(struct EepromImageHeader) + c, xferbuffer, EEPROM_XFER_BLOCKSIZE);
|
||||
epdSelect();
|
||||
}
|
||||
epdSend(xferbuffer[c % EEPROM_XFER_BLOCKSIZE]);
|
||||
}
|
||||
epdDeselect();
|
||||
endWriteFramebuffer();
|
||||
break;
|
||||
case DATATYPE_IMG_RAW_2BPP:
|
||||
printf("Doing raw 2bpp\n");
|
||||
epdSetup();
|
||||
if (lut)
|
||||
selectLUT(lut);
|
||||
beginFullscreenImage();
|
||||
beginWriteFramebuffer(EPD_COLOR_BLACK);
|
||||
epdSelect();
|
||||
for (uint32_t c = 0; c < (SCREEN_HEIGHT * (SCREEN_WIDTH / 8)); c++) {
|
||||
if (c % EEPROM_XFER_BLOCKSIZE == 0) {
|
||||
epdDeselect();
|
||||
eepromRead(addr + sizeof(struct EepromImageHeader) + c, xferbuffer, EEPROM_XFER_BLOCKSIZE);
|
||||
epdSelect();
|
||||
}
|
||||
epdSend(xferbuffer[c % EEPROM_XFER_BLOCKSIZE]);
|
||||
}
|
||||
epdDeselect();
|
||||
endWriteFramebuffer();
|
||||
|
||||
beginWriteFramebuffer(EPD_COLOR_RED);
|
||||
epdSelect();
|
||||
for (uint32_t c = 0; c < (SCREEN_HEIGHT * (SCREEN_WIDTH / 8)); c++) {
|
||||
if (c % EEPROM_XFER_BLOCKSIZE == 0) {
|
||||
epdDeselect();
|
||||
eepromRead(addr + sizeof(struct EepromImageHeader) + (SCREEN_HEIGHT * (SCREEN_WIDTH / 8)) + c, xferbuffer, EEPROM_XFER_BLOCKSIZE);
|
||||
epdSelect();
|
||||
}
|
||||
epdSend(xferbuffer[c % EEPROM_XFER_BLOCKSIZE]);
|
||||
}
|
||||
epdDeselect();
|
||||
endWriteFramebuffer();
|
||||
break;
|
||||
default: // prevent drawing from an unknown file image type
|
||||
printf("Image with type 0x%02X was requested, but we don't know what to do with that currently...\n", eih->dataType);
|
||||
free(xferbuffer);
|
||||
return;
|
||||
case DATATYPE_IMG_RAW_1BPP: {
|
||||
drawItem *di = new drawItem;
|
||||
// di->setRotation(ro);
|
||||
di->xpos = 0;
|
||||
di->ypos = 0;
|
||||
di->color = 0;
|
||||
di->addItem((uint8_t *)addr, epd->effectiveXRes, epd->effectiveYRes);
|
||||
di->type = drawItem::drawType::DRAW_EEPROM_1BPP;
|
||||
di->direction = false;
|
||||
di->cleanUp = false;
|
||||
di->addToList();
|
||||
} break;
|
||||
case DATATYPE_IMG_RAW_2BPP: {
|
||||
drawItem *di = new drawItem;
|
||||
// di->setRotation(ro);
|
||||
di->xpos = 0;
|
||||
di->ypos = 0;
|
||||
di->color = 0;
|
||||
di->addItem((uint8_t *)addr, epd->effectiveXRes, epd->effectiveYRes);
|
||||
di->type = drawItem::drawType::DRAW_EEPROM_2BPP;
|
||||
di->direction = false;
|
||||
di->cleanUp = false;
|
||||
di->addToList();
|
||||
} break;
|
||||
}
|
||||
free(xferbuffer);
|
||||
addOverlay();
|
||||
drawWithSleep();
|
||||
}
|
||||
draw();
|
||||
}
|
||||
|
||||
void drawRoundedRectangle(uint16_t xpos, uint16_t ypos, uint16_t width, uint16_t height, bool color) {
|
||||
uint16_t widthBytes = width / 8;
|
||||
if (width % 8) widthBytes++;
|
||||
uint32_t framebufferSize = widthBytes * height;
|
||||
uint8_t *framebuffer = (uint8_t *)calloc(framebufferSize + 4, 1);
|
||||
if (framebuffer == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
((uint16_t *)framebuffer)[0] = width;
|
||||
((uint16_t *)framebuffer)[1] = height;
|
||||
|
||||
framebuffer += 4;
|
||||
|
||||
uint16_t w = width - 2;
|
||||
uint16_t x = 1;
|
||||
while (w--) {
|
||||
framebuffer[(x / 8)] |= (uint8_t)(1 << (7 - ((uint8_t)x % 8)));
|
||||
x++;
|
||||
}
|
||||
for (uint16_t curY = 1; curY < (height - 1); curY++) {
|
||||
framebuffer[widthBytes * curY] = 0x80;
|
||||
if (width % 8)
|
||||
framebuffer[(widthBytes * curY) + widthBytes - 1] = (uint8_t)(1 << (7 - ((uint8_t)width % 8)));
|
||||
else
|
||||
framebuffer[(widthBytes * curY) + widthBytes - 1] = 0x01;
|
||||
}
|
||||
w = width - 2;
|
||||
x = 1;
|
||||
while (w--) {
|
||||
framebuffer[(x / 8) + ((height - 1) * widthBytes)] |= (uint8_t)(1 << (7 - ((uint8_t)x % 8)));
|
||||
x++;
|
||||
}
|
||||
framebuffer -= 4;
|
||||
addBufferedImage(xpos, ypos, color, rotation::ROTATE_0, framebuffer, DRAW_NORMAL);
|
||||
free(framebuffer);
|
||||
}
|
||||
|
||||
void drawMask(uint16_t xpos, uint16_t ypos, uint16_t width, uint16_t height, bool color) {
|
||||
uint16_t widthBytes = width / 8;
|
||||
if (width % 8) widthBytes++;
|
||||
uint32_t framebufferSize = widthBytes * height;
|
||||
uint8_t *framebuffer = (uint8_t *)calloc(framebufferSize + 4, 1);
|
||||
if (framebuffer == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
((uint16_t *)framebuffer)[0] = width;
|
||||
((uint16_t *)framebuffer)[1] = height;
|
||||
|
||||
framebuffer += 4;
|
||||
|
||||
for (uint16_t curY = 0; curY < height; curY++) {
|
||||
uint16_t w = width;
|
||||
uint16_t x = 0;
|
||||
while (w--) {
|
||||
framebuffer[(x / 8) + (curY * widthBytes)] |= (uint8_t)(1 << (7 - ((uint8_t)x % 8)));
|
||||
x++;
|
||||
}
|
||||
}
|
||||
|
||||
framebuffer -= 4;
|
||||
addBufferedImage(xpos, ypos, color, rotation::ROTATE_0, framebuffer, DRAW_INVERTED);
|
||||
free(framebuffer);
|
||||
}
|
||||
|
||||
// drawItem (sprite) functions
|
||||
void drawItem::shiftBytesRight(uint8_t *data, uint8_t shift, uint8_t len) {
|
||||
// Ensure the shift value is within bounds (0 to 7)
|
||||
shift = shift % 8;
|
||||
|
||||
// Handle the case where shift is 0 or len is 0
|
||||
if (shift == 0 || len == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Loop through the array from right to left
|
||||
for (int i = len - 1; i > 0; i--) {
|
||||
// Perform the shift by combining bits from the current byte
|
||||
// and the next byte to its right
|
||||
data[i] = (data[i] >> shift) | (data[i - 1] << (8 - shift));
|
||||
}
|
||||
|
||||
// For the leftmost byte, simply shift it to the right
|
||||
data[0] >>= shift;
|
||||
}
|
||||
|
||||
uint8_t drawItem::bitReverse(uint8_t byte) {
|
||||
byte = ((byte >> 1) & 0x55) | ((byte << 1) & 0xAA);
|
||||
byte = ((byte >> 2) & 0x33) | ((byte << 2) & 0xCC);
|
||||
byte = (byte >> 4) | (byte << 4);
|
||||
return byte;
|
||||
}
|
||||
|
||||
void drawItem::reverseBytes(uint8_t *src, uint8_t src_len) {
|
||||
// Check for valid input
|
||||
if (src == NULL || src_len == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Reverse the entire source array
|
||||
for (uint8_t i = 0; i < src_len / 2; i++) {
|
||||
uint8_t temp = src[i];
|
||||
src[i] = src[src_len - i - 1];
|
||||
src[src_len - i - 1] = temp;
|
||||
}
|
||||
// Reverse the bits within the bytes
|
||||
for (uint8_t i = 0; i < src_len; i++) {
|
||||
src[i] = bitReverse(src[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void drawItem::copyWithByteShift(uint8_t *dst, uint8_t *src, uint8_t src_len, uint8_t offset) {
|
||||
switch (type) {
|
||||
case DRAW_MASK:
|
||||
for (uint8_t i = 0; i < src_len; i++) {
|
||||
dst[i + offset] &= ~(src[i]);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
for (uint8_t i = 0; i < src_len; i++) {
|
||||
dst[i + offset] |= src[i];
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void drawItem::renderDrawLine(uint8_t *line, uint16_t number, uint8_t c) {
|
||||
drawItem *curDrawItem;
|
||||
for (uint8_t i = 0; i < DRAWITEM_LIST_SIZE; i++) {
|
||||
curDrawItem = drawItems[i];
|
||||
if (curDrawItem != nullptr) {
|
||||
curDrawItem->getDrawLine(line, number, c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void drawItem::flushDrawItems() {
|
||||
drawItem *curDrawItem;
|
||||
for (uint8_t i = 0; i < DRAWITEM_LIST_SIZE; i++) {
|
||||
curDrawItem = drawItems[i];
|
||||
if (curDrawItem != nullptr) {
|
||||
delete curDrawItem;
|
||||
drawItems[i] = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void drawItem::getXLine(uint8_t *line, uint16_t y, uint8_t c) {
|
||||
switch (type) {
|
||||
case DRAW_FONT:
|
||||
case DRAW_BUFFERED_1BPP:
|
||||
case DRAW_MASK:
|
||||
if (c != color) return;
|
||||
if ((y >= ypos) && (y < height + ypos)) { // was y > ypos, not >=
|
||||
// y = height-y;
|
||||
if (mirrorV) {
|
||||
if (mirrorH) {
|
||||
reverseBytes(&buffer[((height - (y - ypos)) * widthBytes)], widthBytes);
|
||||
// reverseBytes(&buffer[((y - ypos) * widthBytes)], widthBytes);
|
||||
} else {
|
||||
reverseBytes(&buffer[((y - ypos) * widthBytes)], widthBytes);
|
||||
}
|
||||
}
|
||||
if (mirrorH) {
|
||||
copyWithByteShift(line, &buffer[((height - (y - ypos)) * widthBytes)], widthBytes, xpos / 8);
|
||||
} else {
|
||||
copyWithByteShift(line, &buffer[((y - ypos) * widthBytes)], widthBytes, xpos / 8);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case DRAW_EEPROM_1BPP:
|
||||
if (c != color) return;
|
||||
if (epd->drawDirectionRight)
|
||||
y = epd->effectiveYRes - 1 - y;
|
||||
eepromRead((uint32_t)buffer + sizeof(struct EepromImageHeader) + (y * (epd->effectiveXRes / 8)), line, (epd->effectiveXRes / 8));
|
||||
break;
|
||||
case DRAW_EEPROM_2BPP:
|
||||
if (epd->drawDirectionRight)
|
||||
y = epd->effectiveYRes - 1 - y;
|
||||
eepromRead((uint32_t)buffer + sizeof(struct EepromImageHeader) + ((y + (c * epd->effectiveYRes)) * (epd->effectiveXRes / 8)), line, (epd->effectiveXRes / 8));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void drawItem::getYLine(uint8_t *line, uint16_t x, uint8_t c) {
|
||||
switch (type) {
|
||||
case DRAW_FONT:
|
||||
case DRAW_BUFFERED_1BPP:
|
||||
if (c != color) return;
|
||||
if ((x >= xpos) && (x < width + xpos)) {
|
||||
x -= xpos;
|
||||
for (uint16_t curY = 0; curY < height; curY++) {
|
||||
uint16_t curYMirrored = curY;
|
||||
if (!mirrorH) curYMirrored = height - 1 - curY;
|
||||
if (mirrorV) {
|
||||
if (buffer[((width - x) / 8) + (curYMirrored * widthBytes)] & (1 << (7 - ((width - x) % 8)))) {
|
||||
line[(curY + ypos) / 8] |= (1 << (7 - ((curY + ypos) % 8)));
|
||||
}
|
||||
} else {
|
||||
if (buffer[(x / 8) + (curYMirrored * widthBytes)] & (1 << (7 - (x % 8)))) {
|
||||
line[(curY + ypos) / 8] |= (1 << (7 - ((curY + ypos) % 8)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case DRAW_MASK:
|
||||
if (c != color) return;
|
||||
if ((x >= xpos) && (x < width + xpos)) {
|
||||
x -= xpos;
|
||||
for (uint16_t curY = 0; curY < height; curY++) {
|
||||
uint16_t curYMirrored = curY;
|
||||
if (!mirrorH) curYMirrored = height - 1 - curY;
|
||||
if (mirrorV) {
|
||||
if (buffer[((width - x) / 8) + (curYMirrored * widthBytes)] & (1 << (7 - ((width - x) % 8)))) {
|
||||
line[(curY + ypos) / 8] &= ~(1 << (7 - ((curY + ypos) % 8)));
|
||||
}
|
||||
} else {
|
||||
if (buffer[(x / 8) + (curYMirrored * widthBytes)] & (1 << (7 - (x % 8)))) {
|
||||
line[(curY + ypos) / 8] &= ~(1 << (7 - ((curY + ypos) % 8)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void drawItem::getDrawLine(uint8_t *line, uint16_t number, uint8_t c) {
|
||||
if (direction) {
|
||||
getYLine(line, number, c);
|
||||
} else {
|
||||
getXLine(line, number, c);
|
||||
}
|
||||
}
|
||||
|
||||
void drawItem::addItem(uint8_t *data, uint16_t w, uint16_t h) {
|
||||
width = w;
|
||||
height = h;
|
||||
widthBytes = w / 8;
|
||||
if (w % 8) widthBytes++;
|
||||
buffer = data;
|
||||
}
|
||||
|
||||
bool drawItem::addToList() {
|
||||
for (uint8_t i = 0; i < DRAWITEM_LIST_SIZE; i++) {
|
||||
if (drawItems[i] == nullptr) {
|
||||
drawItems[i] = this;
|
||||
return true;
|
||||
};
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
drawItem::~drawItem() {
|
||||
if (cleanUp) {
|
||||
free(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
drawItem::drawItem() {
|
||||
if (epd->drawDirectionRight) {
|
||||
direction = true;
|
||||
mirrorH = true;
|
||||
}
|
||||
}
|
||||
|
||||
void drawItem::setRotation(enum rotation ro) {
|
||||
if (epd->drawDirectionRight) {
|
||||
direction = true;
|
||||
mirrorH = true;
|
||||
}
|
||||
|
||||
switch (ro) {
|
||||
case ROTATE_0:
|
||||
break;
|
||||
case ROTATE_270:
|
||||
direction = !direction;
|
||||
mirrorH = !mirrorH;
|
||||
mirrorV = !mirrorV;
|
||||
break;
|
||||
case ROTATE_180:
|
||||
mirrorH = !mirrorH;
|
||||
mirrorV = !mirrorV;
|
||||
break;
|
||||
case ROTATE_90:
|
||||
direction = !direction;
|
||||
break;
|
||||
};
|
||||
}
|
||||
|
||||
// font rendering functions
|
||||
fontrender::fontrender(const GFXfont *font) {
|
||||
gfxFont = (GFXfont *)font;
|
||||
}
|
||||
|
||||
void fontrender::setFont(const GFXfont *font) {
|
||||
gfxFont = (GFXfont *)font;
|
||||
}
|
||||
|
||||
void fontrender::drawFastHLine(uint16_t x, uint16_t y, uint16_t w) {
|
||||
while (w--) {
|
||||
fb[(x / 8) + (y * bufferByteWidth)] |= (uint8_t)(1 << (7 - ((uint8_t)x % 8)));
|
||||
x++;
|
||||
}
|
||||
}
|
||||
|
||||
void fontrender::fillRect(uint16_t x, uint16_t y, uint16_t w, uint16_t h) {
|
||||
for (uint16_t curY = y; curY < y + h; curY++) {
|
||||
drawFastHLine(x, curY, w);
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t fontrender::getCharWidth(uint16_t c) {
|
||||
if ((c >= gfxFont->first) && (c <= gfxFont->last)) {
|
||||
c -= gfxFont->first;
|
||||
// GFXglyph *glyph = &(((GFXglyph *)pgm_read_dword(&gfxFont->glyph))[c]);
|
||||
GFXglyph *glyph = &(gfxFont->glyph[c]);
|
||||
return glyph->xAdvance;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t fontrender::drawChar(int32_t x, int32_t y, uint16_t c, uint8_t size) {
|
||||
// Filter out bad characters not present in font
|
||||
if ((c >= gfxFont->first) && (c <= gfxFont->last)) {
|
||||
c -= gfxFont->first;
|
||||
GFXglyph *glyph = &(gfxFont->glyph[c]);
|
||||
uint8_t *bitmap = (uint8_t *)gfxFont->bitmap;
|
||||
uint32_t bo = glyph->bitmapOffset;
|
||||
uint8_t w = glyph->width,
|
||||
h = glyph->height;
|
||||
int8_t xo = glyph->xOffset,
|
||||
yo = glyph->yOffset;
|
||||
uint8_t xx, yy, bits = 0, bit = 0;
|
||||
int16_t xo16 = 0, yo16 = 0;
|
||||
|
||||
if (size > 1) {
|
||||
xo16 = xo;
|
||||
yo16 = yo;
|
||||
}
|
||||
|
||||
// GFXFF rendering speed up
|
||||
uint16_t hpc = 0; // Horizontal foreground pixel count
|
||||
for (yy = 0; yy < h; yy++) {
|
||||
for (xx = 0; xx < w; xx++) {
|
||||
if (bit == 0) {
|
||||
bits = bitmap[bo++];
|
||||
bit = 0x80;
|
||||
}
|
||||
if (bits & bit)
|
||||
hpc++;
|
||||
else {
|
||||
if (hpc) {
|
||||
if (size == 1)
|
||||
drawFastHLine(x + xo + xx - hpc, y + yo + yy, hpc);
|
||||
else
|
||||
fillRect(x + (xo16 + xx - hpc) * size, y + (yo16 + yy) * size, size * hpc, size);
|
||||
hpc = 0;
|
||||
}
|
||||
}
|
||||
bit >>= 1;
|
||||
}
|
||||
// Draw pixels for this line as we are about to increment yy
|
||||
if (hpc) {
|
||||
if (size == 1)
|
||||
drawFastHLine(x + xo + xx - hpc, y + yo + yy, hpc);
|
||||
else
|
||||
fillRect(x + (xo16 + xx - hpc) * size, y + (yo16 + yy) * size, size * hpc, size);
|
||||
hpc = 0;
|
||||
}
|
||||
}
|
||||
return glyph->xAdvance;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void fontrender::epdPrintf(uint16_t x, uint16_t y, bool color, enum rotation ro, const char *c, ...) {
|
||||
drawItem *di = new drawItem;
|
||||
if (di == nullptr) return;
|
||||
di->setRotation(ro);
|
||||
|
||||
// prepare a drawItem, exchange x/y if necessary.
|
||||
if (di->direction ^ epd->drawDirectionRight) {
|
||||
int16_t temp = x;
|
||||
x = y;
|
||||
y = temp;
|
||||
}
|
||||
|
||||
// output string using vsnprintf
|
||||
char out_buffer[256];
|
||||
va_list lst;
|
||||
va_start(lst, c);
|
||||
uint8_t len = vsnprintf(out_buffer, 255, c, lst);
|
||||
va_end(lst);
|
||||
|
||||
// account for offset in font rendering
|
||||
if (!di->direction) {
|
||||
Xpixels = x % 8; // total drawing width increased by x%8
|
||||
} else {
|
||||
Xpixels = 0;
|
||||
}
|
||||
|
||||
// find out the total length of the string
|
||||
for (uint8_t c = 0; c < len; c++) {
|
||||
Xpixels += (uint16_t)getCharWidth(out_buffer[c]);
|
||||
}
|
||||
|
||||
// find out the high and low points for given font
|
||||
int8_t high = 0;
|
||||
int8_t low = 0;
|
||||
for (uint8_t curchar = 0; curchar < len; curchar++) {
|
||||
uint8_t c = out_buffer[curchar];
|
||||
if ((c >= gfxFont->first) && (c <= gfxFont->last)) {
|
||||
c -= gfxFont->first;
|
||||
int8_t glyphUL = gfxFont->glyph[c].yOffset;
|
||||
if (glyphUL < high) high = glyphUL;
|
||||
int8_t glyphHeight = gfxFont->glyph[c].height;
|
||||
if ((glyphUL + glyphHeight) > low) low = glyphUL + glyphHeight;
|
||||
}
|
||||
}
|
||||
// Actual font height (reduces memory footprint)
|
||||
int8_t height = -1 * (high - low) + 1;
|
||||
|
||||
// determine actual width
|
||||
bufferByteWidth = Xpixels / 8;
|
||||
if (Xpixels % 8) bufferByteWidth++;
|
||||
|
||||
// allocate framebuffer
|
||||
fb = (uint8_t *)calloc(bufferByteWidth * height, 1);
|
||||
|
||||
if (!fb) {
|
||||
printf("Failed to allocate buffer for drawitem, we can't render this text!\n");
|
||||
delete di;
|
||||
return;
|
||||
}
|
||||
|
||||
uint16_t curX;
|
||||
if (!di->direction) {
|
||||
curX = x % 8; // start drawing at x%8s
|
||||
} else {
|
||||
curX = 0;
|
||||
}
|
||||
for (uint8_t c = 0; c < len; c++) {
|
||||
curX += (uint16_t)drawChar(curX, height - low, out_buffer[c], 1);
|
||||
}
|
||||
|
||||
di->addItem(fb, curX, height);
|
||||
di->ypos = y;
|
||||
di->xpos = x;
|
||||
di->color = color;
|
||||
di->type = drawItem::drawType::DRAW_FONT;
|
||||
di->addToList();
|
||||
}
|
||||
|
||||
@@ -2,10 +2,23 @@
|
||||
#include "eeprom.h"
|
||||
#include "comms.h"
|
||||
#include "powermgt.h"
|
||||
#include "proto.h"
|
||||
|
||||
#include "syncedproto.h"
|
||||
#include "hal.h"
|
||||
|
||||
// *****************************************************************************
|
||||
// when using HW SPI, this file requires the following to be present in the HAL
|
||||
// uint8_t eepromSPIByte(uint8_t data);
|
||||
// void eepromSPIBlockRead(uint8_t* dst, uint16_t len);
|
||||
// void eepromSPIBlockWrite(uint8_t* src, uint16_t len);
|
||||
|
||||
#define EEPROM_USE_HW_SPI
|
||||
|
||||
#ifdef EEPROM_USE_HW_SPI
|
||||
#define eepromByte eepromSPIByte
|
||||
#endif
|
||||
|
||||
#ifndef EEPROM_USE_HW_SPI
|
||||
uint8_t eepromByte(uint8_t data) {
|
||||
uint8_t temp = 0;
|
||||
for (uint8_t i = 0; i < 8; i++) {
|
||||
@@ -22,6 +35,7 @@ uint8_t eepromByte(uint8_t data) {
|
||||
}
|
||||
return temp;
|
||||
}
|
||||
#endif
|
||||
|
||||
static uint32_t mEepromSize;
|
||||
static uint8_t mOpcodeErz4K = 0, mOpcodeErz32K = 0, mOpcodeErz64K = 0;
|
||||
@@ -49,9 +63,12 @@ void eepromRead(uint32_t addr, void *dstP, uint16_t len) {
|
||||
eepromByte(addr >> 16);
|
||||
eepromByte(addr >> 8);
|
||||
eepromByte(addr & 0xff);
|
||||
|
||||
#ifdef EEPROM_USE_HW_SPI
|
||||
eepromSPIBlockRead(dst, len);
|
||||
#else
|
||||
while (len--)
|
||||
*dst++ = eepromByte(0);
|
||||
#endif
|
||||
eepromPrvDeselect();
|
||||
}
|
||||
|
||||
@@ -84,8 +101,12 @@ static bool eepromWriteLL(uint32_t addr, const void *srcP, uint16_t len) {
|
||||
eepromByte(addr >> 8);
|
||||
eepromByte(addr & 0xff);
|
||||
|
||||
#ifdef EEPROM_USE_HW_SPI
|
||||
eepromSPIBlockWrite((uint8_t *)src, len);
|
||||
#else
|
||||
while (len--)
|
||||
eepromByte(*src++);
|
||||
#endif
|
||||
eepromPrvDeselect();
|
||||
|
||||
return eepromPrvBusyWait();
|
||||
@@ -115,6 +136,8 @@ boolean eepromInit(void) {
|
||||
uint8_t buf[8];
|
||||
uint8_t i, nParamHdrs;
|
||||
|
||||
eepromPrvWakeFromPowerdown();
|
||||
delay(1);
|
||||
eepromPrvWakeFromPowerdown();
|
||||
|
||||
// process SFDP
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
|
||||
#include <Arduino.h>
|
||||
#include "hal.h"
|
||||
#include "epd_driver/epd_interface.h"
|
||||
|
||||
|
||||
void epdSetup() {
|
||||
epd->epdSetup();
|
||||
}
|
||||
|
||||
void epdEnterSleep() {
|
||||
epd->epdEnterSleep();
|
||||
}
|
||||
void draw() {
|
||||
epd->draw();
|
||||
}
|
||||
void drawNoWait() {
|
||||
epd->drawNoWait();
|
||||
}
|
||||
|
||||
void epdWaitRdy() {
|
||||
epd->epdWaitRdy();
|
||||
}
|
||||
|
||||
void selectLUT(uint8_t sel) {
|
||||
}
|
||||
28
ARM_Tag_FW/Newton_M3_nRF52811/src/epd_driver/epd_interface.h
Normal file
28
ARM_Tag_FW/Newton_M3_nRF52811/src/epd_driver/epd_interface.h
Normal file
@@ -0,0 +1,28 @@
|
||||
#ifndef _EPD_IFACE_H_
|
||||
#define _EPD_IFACE_H_
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
void epdSetup();
|
||||
void epdEnterSleep();
|
||||
|
||||
void draw();
|
||||
void drawNoWait();
|
||||
void drawWithSleep();
|
||||
void epdWaitRdy();
|
||||
|
||||
#define EPD_LUT_DEFAULT 0
|
||||
#define EPD_LUT_NO_REPEATS 1
|
||||
#define EPD_LUT_FAST_NO_REDS 2
|
||||
#define EPD_LUT_FAST 3
|
||||
|
||||
void selectLUT(uint8_t lut);
|
||||
|
||||
#include "uc_variant_043.h"
|
||||
#include "unissd.h"
|
||||
#include "uc_variant_029.h"
|
||||
#include "uc8159.h"
|
||||
#include "uc8179.h"
|
||||
|
||||
#endif
|
||||
242
ARM_Tag_FW/Newton_M3_nRF52811/src/epd_driver/uc8159.cpp
Normal file
242
ARM_Tag_FW/Newton_M3_nRF52811/src/epd_driver/uc8159.cpp
Normal file
@@ -0,0 +1,242 @@
|
||||
#include <Arduino.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "hal.h"
|
||||
#include "lut.h"
|
||||
#include "settings.h"
|
||||
#include "wdt.h"
|
||||
#include "drawing.h"
|
||||
|
||||
#include "uc8159.h"
|
||||
|
||||
#define CMD_PANEL_SETTING 0x00
|
||||
#define CMD_POWER_SETTING 0x01
|
||||
#define CMD_POWER_OFF 0x02
|
||||
#define CMD_POWER_OFF_SEQUENCE 0x03
|
||||
#define CMD_POWER_ON 0x04
|
||||
#define CMD_BOOSTER_SOFT_START 0x06
|
||||
#define CMD_DEEP_SLEEP 0x07
|
||||
#define CMD_DISPLAY_START_TRANSMISSION_DTM1 0x10
|
||||
#define CMD_DATA_STOP 0x11
|
||||
#define CMD_DISPLAY_REFRESH 0x12
|
||||
#define CMD_DISPLAY_IMAGE_PROCESS 0x13
|
||||
#define CMD_VCOM_LUT_C 0x20
|
||||
#define CMD_LUT_B 0x21
|
||||
#define CMD_LUT_W 0x22
|
||||
#define CMD_LUT_G1 0x23
|
||||
#define CMD_LUT_G2 0x24
|
||||
#define CMD_LUT_R0 0x25
|
||||
#define CMD_LUT_R1 0x26
|
||||
#define CMD_LUT_R2 0x27
|
||||
#define CMD_LUT_R3 0x28
|
||||
#define CMD_LUT_XON 0x29
|
||||
#define CMD_PLL_CONTROL 0x30
|
||||
#define CMD_TEMPERATURE_DOREADING 0x40
|
||||
#define CMD_TEMPERATURE_SELECT 0x41
|
||||
#define CMD_TEMPERATURE_WRITE 0x42
|
||||
#define CMD_TEMPERATURE_READ 0x43
|
||||
#define CMD_VCOM_INTERVAL 0x50
|
||||
#define CMD_LOWER_POWER_DETECT 0x51
|
||||
#define CMD_TCON_SETTING 0x60
|
||||
#define CMD_RESOLUTION_SETING 0x61
|
||||
#define CMD_SPI_FLASH_CONTROL 0x65
|
||||
#define CMD_REVISION 0x70
|
||||
#define CMD_STATUS 0x71
|
||||
#define CMD_AUTO_MEASUREMENT_VCOM 0x80
|
||||
#define CMD_READ_VCOM 0x81
|
||||
#define CMD_VCOM_DC_SETTING 0x82
|
||||
#define CMD_PARTIAL_WINDOW 0x90
|
||||
#define CMD_PARTIAL_IN 0x91
|
||||
#define CMD_PARTIAL_OUT 0x92
|
||||
#define CMD_PROGRAM_MODE 0xA0
|
||||
#define CMD_ACTIVE_PROGRAM 0xA1
|
||||
#define CMD_READ_OTP 0xA2
|
||||
#define CMD_EPD_EEPROM_SLEEP 0xB9
|
||||
#define CMD_EPD_EEPROM_WAKE 0xAB
|
||||
#define CMD_CASCADE_SET 0xE0
|
||||
#define CMD_POWER_SAVING 0xE3
|
||||
#define CMD_FORCE_TEMPERATURE 0xE5
|
||||
#define CMD_LOAD_FLASH_LUT 0xE5
|
||||
|
||||
#define epdEepromSelect() \
|
||||
do { \
|
||||
digitalWrite(EPD_HLT, LOW); \
|
||||
} while (0)
|
||||
|
||||
#define epdEepromDeselect() \
|
||||
do { \
|
||||
digitalWrite(EPD_HLT, HIGH); \
|
||||
} while (0)
|
||||
|
||||
void dump(const uint8_t *a, const uint16_t l);
|
||||
|
||||
void uc8159::epdEepromRead(uint16_t addr, uint8_t *data, uint16_t len) {
|
||||
// return;
|
||||
epdWrite(CMD_SPI_FLASH_CONTROL, 1, 0x01);
|
||||
delay(1);
|
||||
epdEepromSelect();
|
||||
spi_write(0x03); // EEPROM READ;
|
||||
spi_write(0x00);
|
||||
spi_write(addr >> 8);
|
||||
spi_write(addr & 0xFF);
|
||||
epdSPIReadBlock(data, len);
|
||||
epdEepromDeselect();
|
||||
delay(1);
|
||||
epdWrite(CMD_SPI_FLASH_CONTROL, 1, 0x00);
|
||||
}
|
||||
uint8_t uc8159::getTempBracket() {
|
||||
uint8_t temptable[10];
|
||||
epdEepromRead(25002, temptable, 10);
|
||||
epdWrite(CMD_TEMPERATURE_DOREADING, 0);
|
||||
epdBusyWaitRising(1500);
|
||||
epdHardSPI(false);
|
||||
int8_t temp = spi3_read();
|
||||
temp <<= 1;
|
||||
temp |= (spi3_read() >> 7);
|
||||
|
||||
uint8_t bracket = 0;
|
||||
for (int i = 0; i < 9; i++) {
|
||||
if ((((char)temp - (uint8_t)temptable[i]) & 0x80) != 0) {
|
||||
bracket = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
epdHardSPI(true);
|
||||
return bracket;
|
||||
}
|
||||
void uc8159::loadFrameRatePLL(uint8_t bracket) {
|
||||
uint8_t pllvalue;
|
||||
uint8_t plltable[10];
|
||||
epdEepromRead(0x6410, plltable, 10);
|
||||
pllvalue = plltable[bracket];
|
||||
if (!pllvalue) pllvalue = 0x3C; // check if there's a valid pll value; if not; load preset
|
||||
epdWrite(CMD_PLL_CONTROL, 1, pllvalue);
|
||||
}
|
||||
void uc8159::loadTempVCOMDC(uint8_t bracket) {
|
||||
uint8_t vcomvalue;
|
||||
uint8_t vcomtable[10];
|
||||
epdEepromRead(25049, vcomtable, 10);
|
||||
vcomvalue = vcomtable[bracket];
|
||||
if (!vcomvalue) {
|
||||
// if we couldn't find the vcom table, then it's a fixed value sitting at 0x6400
|
||||
epdEepromRead(0x6400, vcomtable, 10);
|
||||
if (vcomtable[0])
|
||||
vcomvalue = vcomtable[0];
|
||||
else
|
||||
vcomvalue = 0x1E; // check if there's a valid vcomvalue; if not; load preset
|
||||
}
|
||||
epdWrite(CMD_VCOM_DC_SETTING, 1, vcomvalue);
|
||||
}
|
||||
|
||||
void uc8159::epdEnterSleep() {
|
||||
epdWrite(CMD_POWER_OFF, 0);
|
||||
epdBusyWaitRising(250);
|
||||
}
|
||||
void uc8159::epdSetup() {
|
||||
epdReset();
|
||||
digitalWrite(EPD_BS, LOW);
|
||||
|
||||
epdWrite(CMD_PANEL_SETTING, 2, 0xEF, 0x08); // default = 0xE7-0x08 // 0xEF-0x08 = right-side up
|
||||
epdWrite(CMD_POWER_SETTING, 4, 0x37, 0x00, 0x05, 0x05);
|
||||
epdWrite(CMD_POWER_OFF_SEQUENCE, 1, 0x00);
|
||||
epdWrite(CMD_BOOSTER_SOFT_START, 3, 0xC7, 0xCC, 0x1D);
|
||||
epdBusyWaitRising(250);
|
||||
epdWrite(CMD_POWER_ON, 0);
|
||||
epdBusyWaitRising(250);
|
||||
|
||||
epdWrite(CMD_DISPLAY_IMAGE_PROCESS, 1, 0x00);
|
||||
epdWrite(CMD_PLL_CONTROL, 1, 0x3C);
|
||||
epdWrite(CMD_TEMPERATURE_SELECT, 1, 0x00);
|
||||
epdWrite(CMD_VCOM_INTERVAL, 1, 0x77);
|
||||
epdWrite(CMD_TCON_SETTING, 1, 0x22);
|
||||
epdWrite(CMD_RESOLUTION_SETING, 4, 0x02, 0x58, 0x01, 0xC0); // set for 600x448
|
||||
epdWrite(CMD_SPI_FLASH_CONTROL, 1, 0x00);
|
||||
uint8_t bracket = getTempBracket();
|
||||
loadFrameRatePLL(bracket);
|
||||
epdBusyWaitRising(250);
|
||||
loadTempVCOMDC(bracket);
|
||||
epdBusyWaitRising(250);
|
||||
}
|
||||
|
||||
void uc8159::interleaveColorToBuffer(uint8_t *dst, uint8_t b, uint8_t r) {
|
||||
b ^= 0xFF;
|
||||
uint8_t b_out = 0;
|
||||
for (int8_t shift = 3; shift >= 0; shift--) {
|
||||
b_out = 0;
|
||||
if (((b >> 2 * shift) & 0x01) && ((r >> 2 * shift) & 0x01)) {
|
||||
b_out |= 0x04; // 0x30
|
||||
} else if ((b >> 2 * shift) & 0x01) {
|
||||
b_out |= 0x03; // 0x30
|
||||
} else if ((r >> 2 * shift) & 0x01) { // 4 or 5
|
||||
b_out |= 0x04; // 0x30
|
||||
} else {
|
||||
}
|
||||
|
||||
if (((b >> 2 * shift) & 0x02) && ((r >> 2 * shift) & 0x02)) {
|
||||
b_out |= 0x40; // 0x30
|
||||
} else if ((b >> 2 * shift) & 0x02) {
|
||||
b_out |= 0x30; // 0x30
|
||||
} else if ((r >> 2 * shift) & 0x02) {
|
||||
b_out |= 0x40; // 0x30
|
||||
} else {
|
||||
}
|
||||
*dst++ = b_out;
|
||||
}
|
||||
}
|
||||
|
||||
void uc8159::selectLUT(uint8_t lut) {
|
||||
// implement alternative LUTs here. Currently just reset the watchdog to two minutes,
|
||||
// to ensure it doesn't reset during the much longer bootup procedure
|
||||
lut += 1; // make the compiler a happy camper
|
||||
wdt120s();
|
||||
return;
|
||||
}
|
||||
|
||||
void uc8159::epdWriteDisplayData() {
|
||||
uint8_t screenrow_bw[epd->effectiveXRes / 8];
|
||||
uint8_t screenrow_r[epd->effectiveXRes / 8];
|
||||
uint8_t screenrowInterleaved[epd->effectiveXRes / 8 * 4];
|
||||
|
||||
epd_cmd(CMD_DISPLAY_START_TRANSMISSION_DTM1);
|
||||
markData();
|
||||
epdSelect();
|
||||
for (uint16_t curY = 0; curY < epd->effectiveYRes; curY++) {
|
||||
memset(screenrow_bw, 0, epd->effectiveXRes / 8);
|
||||
memset(screenrow_r, 0, epd->effectiveXRes / 8);
|
||||
drawItem::renderDrawLine(screenrow_bw, curY, 0);
|
||||
drawItem::renderDrawLine(screenrow_r, curY, 1);
|
||||
if (curY != 0) {
|
||||
epdSPIWait();
|
||||
epdDeselect();
|
||||
epdSelect();
|
||||
}
|
||||
for (uint16_t curX = 0; curX < (epd->effectiveXRes / 8); curX++) {
|
||||
interleaveColorToBuffer(screenrowInterleaved + (curX * 4), screenrow_bw[curX], screenrow_r[curX]);
|
||||
}
|
||||
epdSPIAsyncWrite(screenrowInterleaved, epd->effectiveXRes / 8 * 4);
|
||||
}
|
||||
epdSPIWait();
|
||||
|
||||
epdDeselect();
|
||||
epd_cmd(CMD_DATA_STOP);
|
||||
|
||||
drawItem::flushDrawItems();
|
||||
}
|
||||
|
||||
void uc8159::draw() {
|
||||
delay(1);
|
||||
drawNoWait();
|
||||
epdBusyWaitRising(25000);
|
||||
}
|
||||
void uc8159::drawNoWait() {
|
||||
epdWriteDisplayData();
|
||||
// epdWrite(CMD_LOAD_FLASH_LUT, 1, 0x03);
|
||||
epdWrite(CMD_DISPLAY_REFRESH, 0);
|
||||
}
|
||||
void uc8159::epdWaitRdy() {
|
||||
epdBusyWaitRising(25000);
|
||||
}
|
||||
21
ARM_Tag_FW/Newton_M3_nRF52811/src/epd_driver/uc8159.h
Normal file
21
ARM_Tag_FW/Newton_M3_nRF52811/src/epd_driver/uc8159.h
Normal file
@@ -0,0 +1,21 @@
|
||||
#ifndef _EPD_UC8159_H_
|
||||
#define _EPD_UC8159_H_
|
||||
|
||||
class uc8159 : public epdInterface {
|
||||
public:
|
||||
void epdSetup();
|
||||
void epdEnterSleep();
|
||||
void draw();
|
||||
void drawNoWait();
|
||||
void epdWaitRdy();
|
||||
void epdWriteDisplayData();
|
||||
void selectLUT(uint8_t lut);
|
||||
|
||||
protected:
|
||||
void epdEepromRead(uint16_t addr, uint8_t *data, uint16_t len);
|
||||
uint8_t getTempBracket();
|
||||
void loadFrameRatePLL(uint8_t bracket);
|
||||
void loadTempVCOMDC(uint8_t bracket);
|
||||
void interleaveColorToBuffer(uint8_t *dst, uint8_t b, uint8_t r);
|
||||
};
|
||||
#endif
|
||||
142
ARM_Tag_FW/Newton_M3_nRF52811/src/epd_driver/uc8179.cpp
Normal file
142
ARM_Tag_FW/Newton_M3_nRF52811/src/epd_driver/uc8179.cpp
Normal file
@@ -0,0 +1,142 @@
|
||||
#include <Arduino.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "drawing.h"
|
||||
#include "settings.h"
|
||||
#include "hal.h"
|
||||
#include "wdt.h"
|
||||
|
||||
#include "uc8179.h"
|
||||
|
||||
#define CMD_PANEL_SETTING 0x00
|
||||
#define CMD_POWER_SETTING 0x01
|
||||
#define CMD_POWER_OFF 0x02
|
||||
#define CMD_POWER_OFF_SEQUENCE 0x03
|
||||
#define CMD_POWER_ON 0x04
|
||||
#define CMD_POWER_ON_MEASURE 0x05
|
||||
#define CMD_BOOSTER_SOFT_START 0x06
|
||||
#define CMD_DEEP_SLEEP 0x07
|
||||
#define CMD_DISPLAY_START_TRANSMISSION_DTM1 0x10
|
||||
#define CMD_DATA_STOP 0x11
|
||||
#define CMD_DISPLAY_REFRESH 0x12
|
||||
#define CMD_DISPLAY_START_TRANSMISSION_DTM2 0x13
|
||||
#define CMD_PLL_CONTROL 0x30
|
||||
#define CMD_TEMPERATURE_CALIB 0x40
|
||||
#define CMD_TEMPERATURE_SELECT 0x41
|
||||
#define CMD_TEMPERATURE_WRITE 0x42
|
||||
#define CMD_TEMPERATURE_READ 0x43
|
||||
#define CMD_VCOM_INTERVAL 0x50
|
||||
#define CMD_LOWER_POWER_DETECT 0x51
|
||||
#define CMD_TCON_SETTING 0x60
|
||||
#define CMD_RESOLUTION_SETING 0x61
|
||||
#define CMD_REVISION 0x70
|
||||
#define CMD_STATUS 0x71
|
||||
#define CMD_AUTO_MEASUREMENT_VCOM 0x80
|
||||
#define CMD_READ_VCOM 0x81
|
||||
#define CMD_VCOM_DC_SETTING 0x82
|
||||
#define CMD_PARTIAL_WINDOW 0x90
|
||||
#define CMD_PARTIAL_IN 0x91
|
||||
#define CMD_PARTIAL_OUT 0x92
|
||||
#define CMD_PROGRAM_MODE 0xA0
|
||||
#define CMD_ACTIVE_PROGRAM 0xA1
|
||||
#define CMD_READ_OTP 0xA2
|
||||
#define CMD_CASCADE_SET 0xE0
|
||||
#define CMD_POWER_SAVING 0xE3
|
||||
#define CMD_FORCE_TEMPERATURE 0xE5
|
||||
|
||||
void uc8179::epdEnterSleep() {
|
||||
epdWrite(CMD_VCOM_INTERVAL, 1, 0x17);
|
||||
delay(10);
|
||||
epdWrite(CMD_VCOM_DC_SETTING, 1, 0x00);
|
||||
delay(10);
|
||||
epdWrite(CMD_POWER_OFF, 0);
|
||||
delay(10);
|
||||
epdWrite(CMD_DEEP_SLEEP, 1, 0xA5);
|
||||
delay(10);
|
||||
}
|
||||
|
||||
void uc8179::epdSetup() {
|
||||
epdReset();
|
||||
epdWrite(CMD_PANEL_SETTING, 1, 0x0F);
|
||||
epdWrite(CMD_VCOM_INTERVAL, 2, 0x30, 0x07);
|
||||
epdWrite(CMD_RESOLUTION_SETING, 4, epd->effectiveXRes >> 8, epd->effectiveXRes & 0xFF, epd->effectiveYRes >> 8, epd->effectiveYRes & 0xFF);
|
||||
}
|
||||
|
||||
void uc8179::selectLUT(uint8_t lut) {
|
||||
// implement alternative LUTs here. Currently just reset the watchdog to two minutes,
|
||||
// to ensure it doesn't reset during the much longer bootup procedure
|
||||
lut += 1; // make the compiler a happy camper
|
||||
wdt120s();
|
||||
return;
|
||||
}
|
||||
|
||||
void uc8179::epdWriteDisplayData() {
|
||||
uint32_t start = millis();
|
||||
// this display expects two entire framebuffers worth of data to be written, one for b/w and one for red
|
||||
uint8_t *buf[2] = {0, 0}; // this will hold pointers to odd/even data lines
|
||||
for (uint8_t c = 0; c < 2; c++) {
|
||||
if (c == 0) epd_cmd(CMD_DISPLAY_START_TRANSMISSION_DTM1);
|
||||
if (c == 1) epd_cmd(CMD_DISPLAY_START_TRANSMISSION_DTM2);
|
||||
markData();
|
||||
epdSelect();
|
||||
for (uint16_t curY = 0; curY < epd->effectiveYRes; curY += 2) {
|
||||
// Get 'even' screen line
|
||||
buf[0] = (uint8_t *)calloc(epd->effectiveXRes / 8, 1);
|
||||
drawItem::renderDrawLine(buf[0], curY, c);
|
||||
|
||||
// on the first pass, the second (buf[1]) buffer is unused, so we don't have to wait for it to flush to the display / free it
|
||||
if (buf[1]) {
|
||||
// wait for 'odd' display line to finish writing to the screen
|
||||
epdSPIWait();
|
||||
free(buf[1]);
|
||||
}
|
||||
|
||||
// start transfer of even data line to the screen
|
||||
epdSPIAsyncWrite(buf[0], (epd->effectiveXRes / 8));
|
||||
|
||||
// Get 'odd' screen display line
|
||||
buf[1] = (uint8_t *)calloc(epd->effectiveXRes / 8, 1);
|
||||
drawItem::renderDrawLine(buf[1], curY + 1, c);
|
||||
|
||||
// wait until the 'even' data has finished writing
|
||||
epdSPIWait();
|
||||
free(buf[0]);
|
||||
|
||||
// start transfer of the 'odd' data line
|
||||
epdSPIAsyncWrite(buf[1], (epd->effectiveXRes / 8));
|
||||
}
|
||||
// check if this was the first pass. If it was, we'll need to wait until the last display line finished writing
|
||||
if (c == 0) {
|
||||
epdSPIWait();
|
||||
epdDeselect();
|
||||
free(buf[1]);
|
||||
buf[1] = nullptr;
|
||||
}
|
||||
}
|
||||
// flush the draw list, make sure items don't appear on subsequent screens
|
||||
drawItem::flushDrawItems();
|
||||
|
||||
// wait until the last line of display has finished writing and clean our stuff up
|
||||
epdSPIWait();
|
||||
epdDeselect();
|
||||
if (buf[1]) free(buf[1]);
|
||||
printf("draw took %lu ms\n", millis() - start);
|
||||
}
|
||||
|
||||
void uc8179::draw() {
|
||||
drawNoWait();
|
||||
epdWaitRdy();
|
||||
}
|
||||
void uc8179::drawNoWait() {
|
||||
epdWriteDisplayData();
|
||||
epdWrite(CMD_POWER_ON, 0);
|
||||
epdWaitRdy();
|
||||
epdWrite(CMD_DISPLAY_REFRESH, 0);
|
||||
}
|
||||
void uc8179::epdWaitRdy() {
|
||||
epdBusyWaitRising(120000);
|
||||
}
|
||||
15
ARM_Tag_FW/Newton_M3_nRF52811/src/epd_driver/uc8179.h
Normal file
15
ARM_Tag_FW/Newton_M3_nRF52811/src/epd_driver/uc8179.h
Normal file
@@ -0,0 +1,15 @@
|
||||
#ifndef _EPD_UC8179_H_
|
||||
#define _EPD_UC8179_H_
|
||||
|
||||
class uc8179 : public epdInterface {
|
||||
public:
|
||||
void epdSetup();
|
||||
void epdEnterSleep();
|
||||
void draw();
|
||||
void drawNoWait();
|
||||
void epdWaitRdy();
|
||||
void epdWriteDisplayData();
|
||||
void selectLUT(uint8_t lut);
|
||||
};
|
||||
|
||||
#endif
|
||||
131
ARM_Tag_FW/Newton_M3_nRF52811/src/epd_driver/uc_variant_029.cpp
Normal file
131
ARM_Tag_FW/Newton_M3_nRF52811/src/epd_driver/uc_variant_029.cpp
Normal file
@@ -0,0 +1,131 @@
|
||||
#include <Arduino.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "hal.h"
|
||||
#include "lut.h"
|
||||
#include "settings.h"
|
||||
#include "wdt.h"
|
||||
#include "drawing.h"
|
||||
|
||||
#include "uc_variant_029.h"
|
||||
|
||||
#define EPD_CMD_POWER_OFF 0x02
|
||||
#define EPD_CMD_POWER_ON 0x04
|
||||
#define EPD_CMD_BOOSTER_SOFT_START 0x06
|
||||
#define EPD_CMD_DEEP_SLEEP 0x07
|
||||
#define EPD_CMD_DISPLAY_START_TRANSMISSION_DTM1 0x10
|
||||
#define EPD_CMD_DISPLAY_REFRESH 0x12
|
||||
#define EPD_CMD_DISPLAY_START_TRANSMISSION_DTM2 0x13
|
||||
#define EPD_CMD_VCOM_INTERVAL 0x50
|
||||
#define EPD_CMD_RESOLUTION_SETTING 0x61
|
||||
#define EPD_CMD_UNKNOWN 0xF8
|
||||
|
||||
void epdvar29::epdEnterSleep() {
|
||||
epd_cmd(EPD_CMD_POWER_OFF);
|
||||
epdBusyWaitRising(50000);
|
||||
epdWrite(EPD_CMD_DEEP_SLEEP, 1, 0xA5);
|
||||
delay(200);
|
||||
delay(1);
|
||||
}
|
||||
|
||||
void epdvar29::epdSetup() {
|
||||
epdReset();
|
||||
epdWrite(0x4D, 1, 0x55);
|
||||
epdWrite(0xF3, 1, 0x0A);
|
||||
epdWrite(0x31, 1, 0x00);
|
||||
epdWrite(0x06, 3, 0xE5, 0x35, 0x3C);
|
||||
epdWrite(0x50, 1, 0x57);
|
||||
epdWrite(0x00, 2, 0x03 | 0x04, 0x09);
|
||||
}
|
||||
|
||||
void epdvar29::epdWriteDisplayData() {
|
||||
// send a dummy byte. Don't ask me why, it's what she likes. She'll sometimes display garbage on the b/w framebuffer if she doesn't get the dummy byte.
|
||||
epd_data(0x00);
|
||||
|
||||
// this display expects two entire framebuffers worth of data to be written, one for b/w and one for red
|
||||
uint8_t* buf[2] = {0, 0}; // this will hold pointers to odd/even data lines
|
||||
for (uint8_t c = 0; c < 2; c++) {
|
||||
if (c == 0) epd_cmd(EPD_CMD_DISPLAY_START_TRANSMISSION_DTM1);
|
||||
if (c == 1) epd_cmd(EPD_CMD_DISPLAY_START_TRANSMISSION_DTM2);
|
||||
markData();
|
||||
epdSelect();
|
||||
for (uint16_t curY = 0; curY < epd->effectiveYRes; curY += 2) {
|
||||
// Get 'even' screen line
|
||||
buf[0] = (uint8_t*)calloc(epd->effectiveXRes / 8, 1);
|
||||
drawItem::renderDrawLine(buf[0], curY, c);
|
||||
if (c == 0) {
|
||||
for (uint8_t c = 0; c < epd->effectiveXRes / 8; c++) {
|
||||
buf[0][c] = ~buf[0][c];
|
||||
}
|
||||
}
|
||||
|
||||
// on the first pass, the second (buf[1]) buffer is unused, so we don't have to wait for it to flush to the display / free it
|
||||
if (buf[1]) {
|
||||
// wait for 'odd' display line to finish writing to the screen
|
||||
epdSPIWait();
|
||||
free(buf[1]);
|
||||
}
|
||||
|
||||
// start transfer of even data line to the screen
|
||||
epdSPIAsyncWrite(buf[0], (epd->effectiveXRes / 8));
|
||||
|
||||
// Get 'odd' screen display line
|
||||
buf[1] = (uint8_t*)calloc(epd->effectiveXRes / 8, 1);
|
||||
drawItem::renderDrawLine(buf[1], curY + 1, c);
|
||||
if (c == 0) {
|
||||
for (uint8_t c = 0; c < epd->effectiveXRes / 8; c++) {
|
||||
buf[1][c] = ~buf[1][c];
|
||||
}
|
||||
}
|
||||
|
||||
// wait until the 'even' data has finished writing
|
||||
epdSPIWait();
|
||||
free(buf[0]);
|
||||
|
||||
// start transfer of the 'odd' data line
|
||||
epdSPIAsyncWrite(buf[1], (epd->effectiveXRes / 8));
|
||||
}
|
||||
// check if this was the first pass. If it was, we'll need to wait until the last display line finished writing
|
||||
if (c == 0) {
|
||||
epdSPIWait();
|
||||
epdDeselect();
|
||||
free(buf[1]);
|
||||
buf[1] = nullptr;
|
||||
}
|
||||
}
|
||||
// flush the draw list, make sure items don't appear on subsequent screens
|
||||
drawItem::flushDrawItems();
|
||||
|
||||
// wait until the last line of display has finished writing and clean our stuff up
|
||||
epdSPIWait();
|
||||
epdDeselect();
|
||||
if (buf[1]) free(buf[1]);
|
||||
}
|
||||
|
||||
void epdvar29::selectLUT(uint8_t lut) {
|
||||
// implement alternative LUTs here. Currently just reset the watchdog to two minutes,
|
||||
// to ensure it doesn't reset during the much longer bootup procedure
|
||||
lut += 1; // make the compiler a happy camper
|
||||
wdt120s();
|
||||
return;
|
||||
}
|
||||
|
||||
void epdvar29::draw() {
|
||||
drawNoWait();
|
||||
epdBusyWaitRising(50000);
|
||||
}
|
||||
|
||||
void epdvar29::drawNoWait() {
|
||||
epdWriteDisplayData();
|
||||
epd_cmd(EPD_CMD_POWER_ON);
|
||||
epdBusyWaitRising(200);
|
||||
epd_cmd(EPD_CMD_DISPLAY_REFRESH);
|
||||
}
|
||||
|
||||
void epdvar29::epdWaitRdy() {
|
||||
epdBusyWaitRising(50000);
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
#ifndef _EPD_029_VAR1_H_
|
||||
#define _EPD_029_VAR1_H_
|
||||
|
||||
class epdvar29 : public epdInterface {
|
||||
public:
|
||||
void epdSetup();
|
||||
void epdEnterSleep();
|
||||
void draw();
|
||||
void drawNoWait();
|
||||
void epdWaitRdy();
|
||||
void epdWriteDisplayData();
|
||||
void selectLUT(uint8_t lut);
|
||||
};
|
||||
#endif
|
||||
130
ARM_Tag_FW/Newton_M3_nRF52811/src/epd_driver/uc_variant_043.cpp
Normal file
130
ARM_Tag_FW/Newton_M3_nRF52811/src/epd_driver/uc_variant_043.cpp
Normal file
@@ -0,0 +1,130 @@
|
||||
#include <Arduino.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "hal.h"
|
||||
#include "lut.h"
|
||||
#include "settings.h"
|
||||
#include "wdt.h"
|
||||
#include "drawing.h"
|
||||
|
||||
#include "epd_interface.h"
|
||||
#include "uc_variant_043.h"
|
||||
|
||||
#define EPD_CMD_POWER_OFF 0x02
|
||||
#define EPD_CMD_POWER_ON 0x04
|
||||
#define EPD_CMD_BOOSTER_SOFT_START 0x06
|
||||
#define EPD_CMD_DEEP_SLEEP 0x07
|
||||
#define EPD_CMD_DISPLAY_START_TRANSMISSION_DTM1 0x10
|
||||
#define EPD_CMD_DISPLAY_REFRESH 0x12
|
||||
#define EPD_CMD_DISPLAY_START_TRANSMISSION_DTM2 0x13
|
||||
#define EPD_CMD_VCOM_INTERVAL 0x50
|
||||
#define EPD_CMD_RESOLUTION_SETTING 0x61
|
||||
#define EPD_CMD_UNKNOWN 0xF8
|
||||
|
||||
void epdvar43::epdEnterSleep() {
|
||||
epdReset();
|
||||
delay(100);
|
||||
epd_cmd(EPD_CMD_POWER_OFF);
|
||||
delay(100);
|
||||
epdWrite(EPD_CMD_DEEP_SLEEP, 1, 0xA5);
|
||||
delay(100);
|
||||
}
|
||||
|
||||
void epdvar43::epdSetup() {
|
||||
epdReset();
|
||||
epdWrite(EPD_CMD_UNKNOWN, 2, 0x60, 0x05);
|
||||
epdWrite(EPD_CMD_UNKNOWN, 2, 0xA1, 0x00);
|
||||
epdWrite(EPD_CMD_UNKNOWN, 2, 0x73, 0x05);
|
||||
epdWrite(EPD_CMD_UNKNOWN, 2, 0x7E, 0x31);
|
||||
epdWrite(EPD_CMD_UNKNOWN, 2, 0xB8, 0x80);
|
||||
epdWrite(EPD_CMD_UNKNOWN, 2, 0x92, 0x00);
|
||||
epdWrite(EPD_CMD_UNKNOWN, 2, 0x87, 0x11);
|
||||
epdWrite(EPD_CMD_UNKNOWN, 2, 0x88, 0x06);
|
||||
epdWrite(EPD_CMD_UNKNOWN, 2, 0xA8, 0x30);
|
||||
epdWrite(EPD_CMD_RESOLUTION_SETTING, 4, 0x00, 0x98, 0x02, 0x0A);
|
||||
epdWrite(EPD_CMD_BOOSTER_SOFT_START, 3, 0x57, 0x63, 0x3A);
|
||||
epdWrite(EPD_CMD_VCOM_INTERVAL, 1, 0x87); // 47
|
||||
}
|
||||
|
||||
void epdvar43::epdWriteDisplayData() {
|
||||
// send a dummy byte. Don't ask me why, it's what she likes. She'll sometimes display garbage on the b/w framebuffer if she doesn't get the dummy byte.
|
||||
epd_data(0x00);
|
||||
|
||||
// this display expects two entire framebuffers worth of data to be written, one for b/w and one for red
|
||||
uint8_t* buf[2] = {0, 0}; // this will hold pointers to odd/even data lines
|
||||
for (uint8_t c = 0; c < 2; c++) {
|
||||
if (c == 0) epd_cmd(EPD_CMD_DISPLAY_START_TRANSMISSION_DTM1);
|
||||
if (c == 1) epd_cmd(EPD_CMD_DISPLAY_START_TRANSMISSION_DTM2);
|
||||
markData();
|
||||
epdSelect();
|
||||
for (uint16_t curY = 0; curY < this->effectiveYRes; curY += 2) {
|
||||
// Get 'even' screen line
|
||||
buf[0] = (uint8_t*)calloc(this->effectiveXRes / 8, 1);
|
||||
drawItem::renderDrawLine(buf[0], curY, c);
|
||||
|
||||
// on the first pass, the second (buf[1]) buffer is unused, so we don't have to wait for it to flush to the display / free it
|
||||
if (buf[1]) {
|
||||
// wait for 'odd' display line to finish writing to the screen
|
||||
epdSPIWait();
|
||||
free(buf[1]);
|
||||
}
|
||||
|
||||
// start transfer of even data line to the screen
|
||||
epdSPIAsyncWrite(buf[0], (this->effectiveXRes / 8));
|
||||
|
||||
// Get 'odd' screen display line
|
||||
buf[1] = (uint8_t*)calloc(this->effectiveXRes / 8, 1);
|
||||
drawItem::renderDrawLine(buf[1], curY + 1, c);
|
||||
|
||||
// wait until the 'even' data has finished writing
|
||||
epdSPIWait();
|
||||
free(buf[0]);
|
||||
|
||||
// start transfer of the 'odd' data line
|
||||
epdSPIAsyncWrite(buf[1], (this->effectiveXRes / 8));
|
||||
}
|
||||
// check if this was the first pass. If it was, we'll need to wait until the last display line finished writing
|
||||
if (c == 0) {
|
||||
epdSPIWait();
|
||||
epdDeselect();
|
||||
free(buf[1]);
|
||||
buf[1] = nullptr;
|
||||
}
|
||||
}
|
||||
// flush the draw list, make sure items don't appear on subsequent screens
|
||||
drawItem::flushDrawItems();
|
||||
|
||||
// wait until the last line of display has finished writing and clean our stuff up
|
||||
epdSPIWait();
|
||||
epdDeselect();
|
||||
if (buf[1]) free(buf[1]);
|
||||
}
|
||||
|
||||
void epdvar43::selectLUT(uint8_t lut) {
|
||||
// implement alternative LUTs here. Currently just reset the watchdog to two minutes,
|
||||
// to ensure it doesn't reset during the much longer bootup procedure
|
||||
lut += 1; // make the compiler a happy camper
|
||||
wdt120s();
|
||||
return;
|
||||
}
|
||||
|
||||
void epdvar43::draw() {
|
||||
this->drawNoWait();
|
||||
epdBusyWaitRising(50000);
|
||||
delay(100);
|
||||
}
|
||||
void epdvar43::drawNoWait() {
|
||||
this->epdWriteDisplayData();
|
||||
epd_cmd(EPD_CMD_POWER_ON);
|
||||
epdBusyWaitRising(200);
|
||||
epd_cmd(EPD_CMD_DISPLAY_REFRESH);
|
||||
}
|
||||
|
||||
void epdvar43::epdWaitRdy() {
|
||||
epdBusyWaitRising(50000);
|
||||
delay(100);
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
#ifndef _EPD_043_VAR1_H_
|
||||
#define _EPD_043_VAR1_H_
|
||||
|
||||
class epdvar43 : public epdInterface {
|
||||
public:
|
||||
void epdSetup() ;
|
||||
void epdEnterSleep() ;
|
||||
void draw();
|
||||
void drawNoWait();
|
||||
void epdWaitRdy();
|
||||
void epdWriteDisplayData();
|
||||
void selectLUT(uint8_t lut);
|
||||
};
|
||||
|
||||
#endif
|
||||
194
ARM_Tag_FW/Newton_M3_nRF52811/src/epd_driver/unissd.cpp
Normal file
194
ARM_Tag_FW/Newton_M3_nRF52811/src/epd_driver/unissd.cpp
Normal file
@@ -0,0 +1,194 @@
|
||||
#include <Arduino.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "lut.h"
|
||||
#include "settings.h"
|
||||
#include "hal.h"
|
||||
#include "wdt.h"
|
||||
|
||||
#include "drawing.h"
|
||||
#include "unissd.h"
|
||||
|
||||
#define CMD_DRV_OUTPUT_CTRL 0x01
|
||||
#define CMD_SOFT_START_CTRL 0x0C
|
||||
#define CMD_ENTER_SLEEP 0x10
|
||||
#define CMD_DATA_ENTRY_MODE 0x11
|
||||
#define CMD_SOFT_RESET 0x12
|
||||
#define CMD_SOFT_RESET2 0x13
|
||||
#define CMD_SETUP_VOLT_DETECT 0x15
|
||||
#define CMD_TEMP_SENSOR_CONTROL 0x18
|
||||
#define CMD_ACTIVATION 0x20
|
||||
#define CMD_DISP_UPDATE_CTRL 0x21
|
||||
#define CMD_DISP_UPDATE_CTRL2 0x22
|
||||
#define CMD_WRITE_FB_BW 0x24
|
||||
#define CMD_WRITE_FB_RED 0x26
|
||||
#define CMD_VCOM_GLITCH_CTRL 0x2B
|
||||
#define CMD_LOAD_OTP_LUT 0x31
|
||||
#define CMD_WRITE_LUT 0x32
|
||||
#define CMD_BORDER_WAVEFORM_CTRL 0x3C
|
||||
#define CMD_WINDOW_X_SIZE 0x44
|
||||
#define CMD_WINDOW_Y_SIZE 0x45
|
||||
#define CMD_WRITE_PATTERN_RED 0x46
|
||||
#define CMD_WRITE_PATTERN_BW 0x47
|
||||
#define CMD_XSTART_POS 0x4E
|
||||
#define CMD_YSTART_POS 0x4F
|
||||
#define CMD_ANALOG_BLK_CTRL 0x74
|
||||
#define CMD_DIGITAL_BLK_CTRL 0x7E
|
||||
|
||||
#define SCREEN_CMD_CLOCK_ON 0x80
|
||||
#define SCREEN_CMD_CLOCK_OFF 0x01
|
||||
#define SCREEN_CMD_ANALOG_ON 0x40
|
||||
#define SCREEN_CMD_ANALOG_OFF 0x02
|
||||
#define SCREEN_CMD_LATCH_TEMPERATURE_VAL 0x20
|
||||
#define SCREEN_CMD_LOAD_LUT 0x10
|
||||
#define SCREEN_CMD_USE_MODE_2 0x08 // modified commands 0x10 and 0x04
|
||||
#define SCREEN_CMD_REFRESH 0xC7
|
||||
|
||||
void unissd::selectLUT(uint8_t lut) {
|
||||
// implement alternative LUTs here. Currently just reset the watchdog to two minutes,
|
||||
// to ensure it doesn't reset during the much longer bootup procedure
|
||||
lut += 1; // make the compiler a happy camper
|
||||
wdt120s();
|
||||
return;
|
||||
}
|
||||
|
||||
void unissd::epdEnterSleep() {
|
||||
digitalWrite(EPD_RST, LOW);
|
||||
delay(10);
|
||||
digitalWrite(EPD_RST, HIGH);
|
||||
delay(50);
|
||||
epdWrite(CMD_SOFT_RESET2, 0);
|
||||
epdBusyWaitFalling(15);
|
||||
epdWrite(CMD_ENTER_SLEEP, 1, 0x03);
|
||||
}
|
||||
void unissd::epdSetup() {
|
||||
epdReset();
|
||||
epdWrite(CMD_SOFT_RESET, 0);
|
||||
delay(10);
|
||||
switch (this->controllerType) {
|
||||
case 0x0F:
|
||||
case 0x12:
|
||||
case 0x15:
|
||||
// stock init 1.6"
|
||||
epdWrite(CMD_DRV_OUTPUT_CTRL, 3, this->effectiveYRes & 0xFF, this->effectiveYRes >> 8, 0x00);
|
||||
epdWrite(CMD_DATA_ENTRY_MODE, 1, 0x01);
|
||||
epdWrite(CMD_WINDOW_X_SIZE, 2, this->XOffset / 8, ((this->XOffset + this->effectiveXRes) / 8) - 1);
|
||||
epdWrite(CMD_WINDOW_Y_SIZE, 4, (this->YOffset + this->effectiveYRes) & 0xFF, (this->YOffset + this->effectiveYRes) >> 8, this->YOffset & 0xFF, this->YOffset >> 8);
|
||||
epdWrite(CMD_BORDER_WAVEFORM_CTRL, 1, 0x05);
|
||||
epdWrite(CMD_TEMP_SENSOR_CONTROL, 1, 0x80);
|
||||
// end stock init
|
||||
// added
|
||||
epdWrite(CMD_DISP_UPDATE_CTRL, 2, 0x08, 0x00); // fix reversed image with stock setup
|
||||
break;
|
||||
case 0x19:
|
||||
// stock init 9.7"
|
||||
epdWrite(0x46, 1, 0xF7);
|
||||
delay(15);
|
||||
epdWrite(0x47, 1, 0xF7);
|
||||
delay(15);
|
||||
epdWrite(0x0C, 5, 0xAE, 0xC7, 0xC3, 0xC0, 0x80);
|
||||
epdWrite(0x01, 3, 0x9F, 0x02, 0x00);
|
||||
epdWrite(0x11, 1, 0x02);
|
||||
epdWrite(0x44, 4, 0xBF, 0x03, 0x00, 0x00);
|
||||
epdWrite(0x45, 4, 0x00, 0x00, 0x9F, 0x02);
|
||||
epdWrite(0x3C, 1, 0x01);
|
||||
epdWrite(0x18, 1, 0x80);
|
||||
epdWrite(0x22, 1, 0xF7);
|
||||
// end stock init
|
||||
// added
|
||||
epdWrite(CMD_DISP_UPDATE_CTRL, 2, 0x08, 0x00); // fix reversed image with stock setup
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void unissd::epdWriteDisplayData() {
|
||||
// this display expects two entire framebuffers worth of data to be written, one for b/w and one for red
|
||||
uint8_t *buf[2] = {0, 0}; // this will hold pointers to odd/even data lines
|
||||
for (uint8_t c = 0; c < 2; c++) {
|
||||
switch (this->controllerType) {
|
||||
case 0x0F:
|
||||
case 0x12:
|
||||
case 0x15:
|
||||
epdWrite(CMD_XSTART_POS, 1, (this->XOffset / 8));
|
||||
epdWrite(CMD_YSTART_POS, 2, (this->YOffset + this->effectiveYRes) & 0xFF, (this->YOffset + this->effectiveYRes) >> 8);
|
||||
break;
|
||||
case 0x19:
|
||||
epdWrite(CMD_XSTART_POS, 2, 0xBF, 0x03);
|
||||
epdWrite(CMD_YSTART_POS, 2, 0x00, 0x00);
|
||||
break;
|
||||
}
|
||||
if (c == 0) epd_cmd(CMD_WRITE_FB_BW);
|
||||
if (c == 1) epd_cmd(CMD_WRITE_FB_RED);
|
||||
delay(10);
|
||||
markData();
|
||||
epdSelect();
|
||||
for (uint16_t curY = 0; curY < epd->effectiveYRes; curY += 2) {
|
||||
// Get 'even' screen line
|
||||
buf[0] = (uint8_t *)calloc(epd->effectiveXRes / 8, 1);
|
||||
|
||||
if (epd->epdMirrorV) {
|
||||
drawItem::renderDrawLine(buf[0], (epd->effectiveYRes - 1) - curY, c);
|
||||
} else {
|
||||
drawItem::renderDrawLine(buf[0], curY, c);
|
||||
}
|
||||
if (epd->epdMirrorH) drawItem::reverseBytes(buf[0], epd->effectiveXRes / 8);
|
||||
// on the first pass, the second (buf[1]) buffer is unused, so we don't have to wait for it to flush to the display / free it
|
||||
if (buf[1]) {
|
||||
// wait for 'odd' display line to finish writing to the screen
|
||||
epdSPIWait();
|
||||
free(buf[1]);
|
||||
}
|
||||
|
||||
// start transfer of even data line to the screen
|
||||
epdSPIAsyncWrite(buf[0], (epd->effectiveXRes / 8));
|
||||
|
||||
// Get 'odd' screen display line
|
||||
buf[1] = (uint8_t *)calloc(epd->effectiveXRes / 8, 1);
|
||||
if (epd->epdMirrorV) {
|
||||
drawItem::renderDrawLine(buf[1], (epd->effectiveYRes - 1) - (curY + 1), c);
|
||||
} else {
|
||||
drawItem::renderDrawLine(buf[1], curY + 1, c);
|
||||
}
|
||||
if (epd->epdMirrorH) drawItem::reverseBytes(buf[1], epd->effectiveXRes / 8);
|
||||
|
||||
// wait until the 'even' data has finished writing
|
||||
epdSPIWait();
|
||||
free(buf[0]);
|
||||
|
||||
// start transfer of the 'odd' data line
|
||||
epdSPIAsyncWrite(buf[1], (epd->effectiveXRes / 8));
|
||||
}
|
||||
// check if this was the first pass. If it was, we'll need to wait until the last display line finished writing
|
||||
if (c == 0) {
|
||||
epdSPIWait();
|
||||
epdDeselect();
|
||||
free(buf[1]);
|
||||
buf[1] = nullptr;
|
||||
}
|
||||
}
|
||||
// flush the draw list, make sure items don't appear on subsequent screens
|
||||
drawItem::flushDrawItems();
|
||||
|
||||
// wait until the last line of display has finished writing and clean our stuff up
|
||||
epdSPIWait();
|
||||
epdDeselect();
|
||||
if (buf[1]) free(buf[1]);
|
||||
}
|
||||
|
||||
void unissd::draw() {
|
||||
drawNoWait();
|
||||
getVoltage();
|
||||
epdBusyWaitFalling(120000);
|
||||
}
|
||||
void unissd::drawNoWait() {
|
||||
epdWriteDisplayData();
|
||||
epdWrite(CMD_DISP_UPDATE_CTRL2, 1, 0xF7);
|
||||
epdWrite(CMD_ACTIVATION, 0);
|
||||
}
|
||||
void unissd::epdWaitRdy() {
|
||||
epdBusyWaitFalling(120000);
|
||||
}
|
||||
23
ARM_Tag_FW/Newton_M3_nRF52811/src/epd_driver/unissd.h
Normal file
23
ARM_Tag_FW/Newton_M3_nRF52811/src/epd_driver/unissd.h
Normal file
@@ -0,0 +1,23 @@
|
||||
#ifndef _EPD_UNISSD_H_
|
||||
#define _EPD_UNISSD_H_
|
||||
|
||||
class unissd : public epdInterface {
|
||||
public:
|
||||
void epdSetup();
|
||||
void epdEnterSleep();
|
||||
void draw();
|
||||
void drawNoWait();
|
||||
void epdWaitRdy();
|
||||
void epdWriteDisplayData();
|
||||
void selectLUT(uint8_t lut);
|
||||
|
||||
protected:
|
||||
void commandReadBegin(uint8_t cmd);
|
||||
void commandReadEnd();
|
||||
uint8_t epdReadByte();
|
||||
void setWindowX(uint16_t start, uint16_t end);
|
||||
void setWindowY(uint16_t start, uint16_t end);
|
||||
void setPosXY(uint16_t x, uint16_t y);
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -5,14 +5,27 @@
|
||||
#include <SoftWire.h>
|
||||
#include <AsyncDelay.h>
|
||||
|
||||
#include "settings.h"
|
||||
#include "comms.h"
|
||||
#include "drawing.h"
|
||||
#include "powermgt.h"
|
||||
#include "proto.h"
|
||||
#include "../../../oepl-proto.h"
|
||||
#include "../../../oepl-definitions.h"
|
||||
#include "syncedproto.h"
|
||||
#include "hal.h"
|
||||
#include "userinterface.h"
|
||||
#include "wdt.h"
|
||||
#include "../hal/Newton_M3_nRF52811/tagtype_db.h"
|
||||
|
||||
uint8_t getFirstWakeUpReason();
|
||||
|
||||
#define TAG_MODE_CHANSEARCH 0
|
||||
#define TAG_MODE_ASSOCIATED 1
|
||||
|
||||
uint8_t currentTagMode = TAG_MODE_CHANSEARCH;
|
||||
|
||||
uint8_t slideShowCurrentImg = 0;
|
||||
uint8_t slideShowRefreshCount = 1;
|
||||
|
||||
SoftWire sw(NFC_I2C_SDA, NFC_I2C_SCL);
|
||||
|
||||
@@ -22,48 +35,24 @@ extern "C" int _write(int file, char *ptr, int len) {
|
||||
return len;
|
||||
}
|
||||
|
||||
uint8_t showChannelSelect() { // returns 0 if no accesspoints were found
|
||||
uint8_t result[sizeof(channelList)];
|
||||
memset(result, 0, sizeof(result));
|
||||
// showScanningWindow();
|
||||
// drawNoWait();
|
||||
powerUp(INIT_RADIO);
|
||||
for (uint8_t i = 0; i < 4; i++) {
|
||||
for (uint8_t c = 0; c < sizeof(channelList); c++) {
|
||||
if (detectAP(channelList[c])) {
|
||||
if (mLastLqi > result[c])
|
||||
result[c] = mLastLqi;
|
||||
printf("Channel: %d - LQI: %d RSSI %d\n", channelList[c], mLastLqi, mLastRSSI);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t highestLqi = 0;
|
||||
uint8_t highestSlot = 0;
|
||||
for (uint8_t c = 0; c < sizeof(result); c++) {
|
||||
if (result[c] > highestLqi) {
|
||||
highestSlot = channelList[c];
|
||||
highestLqi = result[c];
|
||||
}
|
||||
}
|
||||
powerDown(INIT_RADIO);
|
||||
epdWaitRdy();
|
||||
mLastLqi = highestLqi;
|
||||
return highestSlot;
|
||||
uint8_t getFirstWakeUpReason() {
|
||||
return WAKEUP_REASON_FIRSTBOOT;
|
||||
}
|
||||
uint8_t channelSelect() { // returns 0 if no accesspoints were found
|
||||
|
||||
uint8_t channelSelect(uint8_t rounds) { // returns 0 if no accesspoints were found
|
||||
powerUp(INIT_RADIO);
|
||||
uint8_t result[16];
|
||||
memset(result, 0, sizeof(result));
|
||||
|
||||
for (uint8_t i = 0; i < 2; i++) {
|
||||
for (uint8_t i = 0; i < rounds; i++) {
|
||||
for (uint8_t c = 0; c < sizeof(channelList); c++) {
|
||||
if (detectAP(channelList[c])) {
|
||||
if (mLastLqi > result[c])
|
||||
result[c] = mLastLqi;
|
||||
if (mLastLqi > result[c]) result[c] = mLastLqi;
|
||||
if (rounds > 2) printf("Channel: %d - LQI: %d RSSI %d\n", channelList[c], mLastLqi, mLastRSSI);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
powerDown(INIT_RADIO);
|
||||
uint8_t highestLqi = 0;
|
||||
uint8_t highestSlot = 0;
|
||||
for (uint8_t c = 0; c < sizeof(result); c++) {
|
||||
@@ -77,269 +66,491 @@ uint8_t channelSelect() { // returns 0 if no accesspoints were found
|
||||
return highestSlot;
|
||||
}
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
delay(300);
|
||||
setupPortsInitial();
|
||||
powerUp(INIT_BASE | INIT_UART);
|
||||
bool displayCustomImage(uint8_t imagetype) {
|
||||
powerUp(INIT_EEPROM);
|
||||
uint8_t slot = findSlotDataTypeArg(imagetype << 3);
|
||||
if (slot != 0xFF) {
|
||||
// found a slot for gpio button 1
|
||||
|
||||
// if (RESET & 0x01) {
|
||||
// wakeUpReason = WAKEUP_REASON_WDT_RESET;
|
||||
// printf("WDT reset!\n");
|
||||
// } else {
|
||||
wakeUpReason = WAKEUP_REASON_FIRSTBOOT;
|
||||
//}
|
||||
uint8_t lut = getEepromImageDataArgument(slot);
|
||||
lut &= 0x03;
|
||||
powerUp(INIT_EPD);
|
||||
drawImageFromEeprom(slot, lut);
|
||||
powerDown(INIT_EPD | INIT_EEPROM);
|
||||
return true;
|
||||
} else {
|
||||
powerDown(INIT_EEPROM);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
wdt10s();
|
||||
void externalWakeHandler(uint8_t type) {
|
||||
if (displayCustomImage(type)) {
|
||||
doSleep(2000);
|
||||
|
||||
boardGetOwnMac(mSelfMac);
|
||||
// if something else was previously on the display, draw that
|
||||
if (curImgSlot != 0xFF) {
|
||||
powerUp(INIT_EEPROM);
|
||||
uint8_t lut = getEepromImageDataArgument(curImgSlot);
|
||||
lut &= 0x03;
|
||||
powerUp(INIT_EPD);
|
||||
drawImageFromEeprom(curImgSlot, lut);
|
||||
powerDown(INIT_EPD | INIT_EEPROM);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
bool macSet = false;
|
||||
for (uint8_t c = 0; c < 8; c++) {
|
||||
if (mSelfMac[c] != 0xFF) {
|
||||
macSet = true;
|
||||
break;
|
||||
void TagAssociated() {
|
||||
// associated
|
||||
bool fastNextCheckin = false;
|
||||
struct AvailDataInfo *avail;
|
||||
static bool buttonCheckOut = false; // send another full request if the previous was a trigger reason (buttons, nfc)
|
||||
// Is there any reason why we should do a long (full) get data request (including reason, status)?
|
||||
if ((longDataReqCounter > LONG_DATAREQ_INTERVAL) || wakeUpReason != WAKEUP_REASON_TIMED || buttonCheckOut) {
|
||||
// check if we should do a voltage measurement (those are pretty expensive)
|
||||
if (voltageCheckCounter == VOLTAGE_CHECK_INTERVAL) {
|
||||
powerUp(INIT_VOLTREADING);
|
||||
voltageCheckCounter = 0;
|
||||
} else {
|
||||
powerUp(INIT_TEMPREADING);
|
||||
}
|
||||
voltageCheckCounter++;
|
||||
|
||||
// check if the battery level is below minimum, and force a redraw of the screen
|
||||
|
||||
if ((lowBattery && !lowBatteryShown && tagSettings.enableLowBatSymbol) || (noAPShown && tagSettings.enableNoRFSymbol)) {
|
||||
// Check if we were already displaying an image
|
||||
if (curImgSlot != 0xFF) {
|
||||
powerUp(INIT_EEPROM | INIT_EPD);
|
||||
wdt60s();
|
||||
uint8_t lut = getEepromImageDataArgument(curImgSlot) & 0x03;
|
||||
drawImageFromEeprom(curImgSlot, lut);
|
||||
powerDown(INIT_EEPROM | INIT_EPD);
|
||||
} else {
|
||||
powerUp(INIT_EPD);
|
||||
if (!displayCustomImage(CUSTOM_IMAGE_APFOUND)) showAPFound();
|
||||
powerDown(INIT_EPD);
|
||||
}
|
||||
}
|
||||
|
||||
if (!macSet) {
|
||||
printf("Mac can't be all FF's.\n");
|
||||
powerUp(INIT_EPD);
|
||||
showNoMAC();
|
||||
powerDown(INIT_EPD | INIT_UART | INIT_EEPROM);
|
||||
doSleep(-1);
|
||||
NVIC_SystemReset();
|
||||
powerUp(INIT_RADIO);
|
||||
avail = getAvailDataInfo();
|
||||
powerDown(INIT_RADIO);
|
||||
|
||||
switch (wakeUpReason) {
|
||||
case WAKEUP_REASON_BUTTON1:
|
||||
externalWakeHandler(CUSTOM_IMAGE_BUTTON1);
|
||||
fastNextCheckin = true;
|
||||
break;
|
||||
case WAKEUP_REASON_BUTTON2:
|
||||
externalWakeHandler(CUSTOM_IMAGE_BUTTON2);
|
||||
fastNextCheckin = true;
|
||||
break;
|
||||
case WAKEUP_REASON_GPIO:
|
||||
externalWakeHandler(CUSTOM_IMAGE_GPIO);
|
||||
fastNextCheckin = true;
|
||||
break;
|
||||
case WAKEUP_REASON_RF:
|
||||
externalWakeHandler(CUSTOM_IMAGE_RF_WAKE);
|
||||
fastNextCheckin = true;
|
||||
break;
|
||||
case WAKEUP_REASON_NFC:
|
||||
externalWakeHandler(CUSTOM_IMAGE_NFC_WAKE);
|
||||
fastNextCheckin = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (avail != NULL) {
|
||||
// we got some data!
|
||||
longDataReqCounter = 0;
|
||||
if (buttonCheckOut == true) {
|
||||
buttonCheckOut = false;
|
||||
}
|
||||
|
||||
// since we've had succesful contact, and communicated the wakeup reason succesfully, we can now reset to the 'normal' status
|
||||
if ((wakeUpReason == WAKEUP_REASON_BUTTON1) | (wakeUpReason == WAKEUP_REASON_BUTTON2) | (wakeUpReason == WAKEUP_REASON_NFC) | (wakeUpReason == CUSTOM_IMAGE_RF_WAKE)) {
|
||||
buttonCheckOut = true;
|
||||
}
|
||||
wakeUpReason = WAKEUP_REASON_TIMED;
|
||||
}
|
||||
if (tagSettings.enableTagRoaming) {
|
||||
uint8_t roamChannel = channelSelect(1);
|
||||
if (roamChannel) currentChannel = roamChannel;
|
||||
}
|
||||
} else {
|
||||
powerUp(INIT_RADIO);
|
||||
|
||||
#ifdef ENABLE_RETURN_DATA
|
||||
// example code to send data back to the AP. Up to 90 bytes can be sent in one packet
|
||||
uint8_t blaat[2] = {0xAB, 0xBA};
|
||||
sendTagReturnData(blaat, 2, 0x55);
|
||||
#endif
|
||||
|
||||
avail = getShortAvailDataInfo();
|
||||
powerDown(INIT_RADIO);
|
||||
}
|
||||
|
||||
addAverageValue();
|
||||
|
||||
if (avail == NULL) {
|
||||
// no data :( this means no reply from AP
|
||||
nextCheckInFromAP = 0; // let the power-saving algorithm determine the next sleep period
|
||||
} else {
|
||||
nextCheckInFromAP = avail->nextCheckIn;
|
||||
// got some data from the AP!
|
||||
if (avail->dataType != DATATYPE_NOUPDATE) {
|
||||
// data transfer
|
||||
if (processAvailDataInfo(avail)) {
|
||||
// succesful transfer, next wake time is determined by the NextCheckin;
|
||||
} else {
|
||||
// failed transfer, let the algorithm determine next sleep interval (not the AP)
|
||||
nextCheckInFromAP = 0;
|
||||
}
|
||||
} else {
|
||||
// no data transfer, just sleep.
|
||||
}
|
||||
}
|
||||
|
||||
printf("BOOTED> %d.%d.%d%s\n", fwVersion / 100, (fwVersion % 100) / 10, (fwVersion % 10), fwVersionSuffix);
|
||||
uint16_t nextCheckin = getNextSleep();
|
||||
longDataReqCounter += nextCheckin;
|
||||
|
||||
/*
|
||||
powerUp(INIT_I2C);
|
||||
pinMode(NFC_POWER, OUTPUT);
|
||||
digitalWrite(NFC_POWER,HIGH);
|
||||
|
||||
sw.setTimeout_ms(40);
|
||||
sw.begin();
|
||||
delay(50);
|
||||
|
||||
const uint8_t firstAddr = 1;
|
||||
const uint8_t lastAddr = 0x7F;
|
||||
Serial.println();
|
||||
Serial.print("I2C scan in range 0x");
|
||||
Serial.print(firstAddr, HEX);
|
||||
Serial.print(" - 0x");
|
||||
Serial.print(lastAddr, HEX);
|
||||
Serial.println(" (inclusive) ...");
|
||||
for (uint8_t addr = firstAddr; addr <= lastAddr; addr++) {
|
||||
delayMicroseconds(50);
|
||||
uint8_t startResult = sw.llStart((addr << 1) + 1); // Signal a read
|
||||
sw.stop();
|
||||
if (startResult == 0) {
|
||||
Serial.print("\rDevice found at 0x");
|
||||
Serial.println(addr, HEX);
|
||||
Serial.flush();
|
||||
}
|
||||
delay(50);
|
||||
if (nextCheckin == INTERVAL_AT_MAX_ATTEMPTS) {
|
||||
// We've averaged up to the maximum interval, this means the tag hasn't been in contact with an AP for some time.
|
||||
if (tagSettings.enableScanForAPAfterTimeout) {
|
||||
currentTagMode = TAG_MODE_CHANSEARCH;
|
||||
return;
|
||||
}
|
||||
}
|
||||
Serial.println("Finished");
|
||||
|
||||
Serial.println((uint8_t)0x55 << 1);
|
||||
|
||||
sw.beginTransmission(30);
|
||||
sw.write(uint8_t(0)); // Access the first register
|
||||
sw.endTransmission();
|
||||
|
||||
digitalWrite(NFC_POWER,LOW);
|
||||
pinMode(NFC_POWER, INPUT_PULLDOWN);
|
||||
if (fastNextCheckin) {
|
||||
// do a fast check-in next
|
||||
fastNextCheckin = false;
|
||||
doSleep(100UL);
|
||||
} else {
|
||||
if (nextCheckInFromAP) {
|
||||
// if the AP told us to sleep for a specific period, do so.
|
||||
if (nextCheckInFromAP & 0x8000) {
|
||||
doSleep((nextCheckInFromAP & 0x7FFF) * 1000UL);
|
||||
} else {
|
||||
doSleep(nextCheckInFromAP * 60000UL);
|
||||
}
|
||||
} else {
|
||||
// sleep determined by algorithm
|
||||
doSleep(getNextSleep() * 1000UL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
powerDown(INIT_I2C);
|
||||
void TagChanSearch() {
|
||||
// not associated
|
||||
if (((scanAttempts != 0) && (scanAttempts % VOLTAGEREADING_DURING_SCAN_INTERVAL == 0)) || (scanAttempts > (INTERVAL_1_ATTEMPTS + INTERVAL_2_ATTEMPTS))) {
|
||||
powerUp(INIT_VOLTREADING);
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
//we always have NFC + NFC wake
|
||||
capabilities |= CAPABILITY_HAS_NFC;
|
||||
capabilities |= CAPABILITY_NFC_WAKE;
|
||||
// try to find a working channel
|
||||
currentChannel = channelSelect(2);
|
||||
|
||||
// Check if we should redraw the screen with icons, info screen or screensaver
|
||||
if ((!currentChannel && !noAPShown && tagSettings.enableNoRFSymbol) ||
|
||||
(lowBattery && !lowBatteryShown && tagSettings.enableLowBatSymbol) ||
|
||||
(scanAttempts == (INTERVAL_1_ATTEMPTS + INTERVAL_2_ATTEMPTS - 1))) {
|
||||
powerUp(INIT_EPD);
|
||||
wdt60s();
|
||||
if (curImgSlot != 0xFF) {
|
||||
if (!displayCustomImage(CUSTOM_IMAGE_LOST_CONNECTION)) {
|
||||
powerUp(INIT_EEPROM);
|
||||
uint8_t lut = getEepromImageDataArgument(curImgSlot) & 0x03;
|
||||
drawImageFromEeprom(curImgSlot, lut);
|
||||
powerDown(INIT_EEPROM);
|
||||
}
|
||||
} else if ((scanAttempts >= (INTERVAL_1_ATTEMPTS + INTERVAL_2_ATTEMPTS - 1))) {
|
||||
if (!displayCustomImage(CUSTOM_IMAGE_LONGTERMSLEEP)) showLongTermSleep();
|
||||
} else {
|
||||
if (!displayCustomImage(CUSTOM_IMAGE_LOST_CONNECTION)) showNoAP();
|
||||
}
|
||||
powerDown(INIT_EPD);
|
||||
}
|
||||
|
||||
// did we find a working channel?
|
||||
if (currentChannel) {
|
||||
// now associated! set up and bail out of this loop.
|
||||
scanAttempts = 0;
|
||||
wakeUpReason = WAKEUP_REASON_NETWORK_SCAN;
|
||||
initPowerSaving(INTERVAL_BASE);
|
||||
doSleep(getNextSleep() * 1000UL);
|
||||
currentTagMode = TAG_MODE_ASSOCIATED;
|
||||
return;
|
||||
} else {
|
||||
// still not associated
|
||||
doSleep(getNextScanSleep(true) * 1000UL);
|
||||
}
|
||||
}
|
||||
|
||||
void TagSlideShow() {
|
||||
currentChannel = 11; // suppress the no-rf image thing
|
||||
displayCustomImage(CUSTOM_IMAGE_SPLASHSCREEN);
|
||||
|
||||
// do a short channel search
|
||||
currentChannel = channelSelect(2);
|
||||
|
||||
printf("Slideshow mode ch: %d\n", currentChannel);
|
||||
|
||||
// if we did find an AP, check in once
|
||||
if (currentChannel) {
|
||||
powerUp(INIT_VOLTREADING);
|
||||
struct AvailDataInfo *avail;
|
||||
powerUp(INIT_RADIO);
|
||||
avail = getAvailDataInfo();
|
||||
|
||||
if (avail != NULL) {
|
||||
processAvailDataInfo(avail);
|
||||
}
|
||||
}
|
||||
powerDown(INIT_RADIO);
|
||||
|
||||
// suppress the no-rf image
|
||||
currentChannel = 11;
|
||||
|
||||
while (1) {
|
||||
powerUp(INIT_UART);
|
||||
wdt60s();
|
||||
powerUp(INIT_EEPROM);
|
||||
uint8_t img = findNextSlideshowImage(slideShowCurrentImg);
|
||||
if (img != slideShowCurrentImg) {
|
||||
slideShowCurrentImg = img;
|
||||
uint8_t lut = getEepromImageDataArgument(img) & 0x03;
|
||||
powerUp(INIT_EPD);
|
||||
if (SLIDESHOW_FORCE_FULL_REFRESH_EVERY) {
|
||||
slideShowRefreshCount++;
|
||||
}
|
||||
if ((slideShowRefreshCount == SLIDESHOW_FORCE_FULL_REFRESH_EVERY) || (lut == 0)) {
|
||||
slideShowRefreshCount = 1;
|
||||
lut = 0;
|
||||
}
|
||||
drawImageFromEeprom(img, lut);
|
||||
powerDown(INIT_EPD | INIT_EEPROM);
|
||||
} else {
|
||||
// same image, so don't update the screen; this only happens when there's exactly one slideshow image
|
||||
powerDown(INIT_EEPROM);
|
||||
}
|
||||
|
||||
switch (tagSettings.customMode) {
|
||||
case TAG_CUSTOM_SLIDESHOW_FAST:
|
||||
doSleep(1000UL * SLIDESHOW_INTERVAL_FAST);
|
||||
break;
|
||||
case TAG_CUSTOM_SLIDESHOW_MEDIUM:
|
||||
doSleep(1000UL * SLIDESHOW_INTERVAL_MEDIUM);
|
||||
break;
|
||||
case TAG_CUSTOM_SLIDESHOW_SLOW:
|
||||
doSleep(1000UL * SLIDESHOW_INTERVAL_SLOW);
|
||||
break;
|
||||
case TAG_CUSTOM_SLIDESHOW_GLACIAL:
|
||||
doSleep(1000UL * SLIDESHOW_INTERVAL_GLACIAL);
|
||||
break;
|
||||
}
|
||||
printf("wake...\n");
|
||||
}
|
||||
}
|
||||
|
||||
void executeCommand(uint8_t cmd) {
|
||||
printf("executing command %d \n", cmd);
|
||||
delay(20);
|
||||
switch (cmd) {
|
||||
case CMD_DO_REBOOT:
|
||||
NVIC_SystemReset();
|
||||
break;
|
||||
case CMD_DO_RESET_SETTINGS:
|
||||
powerUp(INIT_EEPROM);
|
||||
loadDefaultSettings();
|
||||
writeSettings();
|
||||
powerDown(INIT_EEPROM);
|
||||
break;
|
||||
case CMD_DO_SCAN:
|
||||
currentChannel = channelSelect(4);
|
||||
break;
|
||||
case CMD_DO_DEEPSLEEP:
|
||||
powerUp(INIT_EPD);
|
||||
afterFlashScreenSaver();
|
||||
powerDown(INIT_EPD | INIT_UART);
|
||||
while (1) {
|
||||
doSleep(-1);
|
||||
}
|
||||
break;
|
||||
case CMD_ERASE_EEPROM_IMAGES:
|
||||
powerUp(INIT_EEPROM);
|
||||
eraseImageBlocks();
|
||||
powerDown(INIT_EEPROM);
|
||||
break;
|
||||
case CMD_ENTER_SLIDESHOW_FAST:
|
||||
powerUp(INIT_EEPROM);
|
||||
if (findSlotDataTypeArg(CUSTOM_IMAGE_SLIDESHOW << 3) == 0xFF) {
|
||||
powerDown(INIT_EEPROM);
|
||||
return;
|
||||
}
|
||||
tagSettings.customMode = TAG_CUSTOM_SLIDESHOW_FAST;
|
||||
writeSettings();
|
||||
powerDown(INIT_EEPROM);
|
||||
NVIC_SystemReset();
|
||||
break;
|
||||
case CMD_ENTER_SLIDESHOW_MEDIUM:
|
||||
powerUp(INIT_EEPROM);
|
||||
if (findSlotDataTypeArg(CUSTOM_IMAGE_SLIDESHOW << 3) == 0xFF) {
|
||||
powerDown(INIT_EEPROM);
|
||||
return;
|
||||
}
|
||||
tagSettings.customMode = TAG_CUSTOM_SLIDESHOW_MEDIUM;
|
||||
writeSettings();
|
||||
powerDown(INIT_EEPROM);
|
||||
NVIC_SystemReset();
|
||||
break;
|
||||
case CMD_ENTER_SLIDESHOW_SLOW:
|
||||
powerUp(INIT_EEPROM);
|
||||
if (findSlotDataTypeArg(CUSTOM_IMAGE_SLIDESHOW << 3) == 0xFF) {
|
||||
powerDown(INIT_EEPROM);
|
||||
return;
|
||||
}
|
||||
tagSettings.customMode = TAG_CUSTOM_SLIDESHOW_SLOW;
|
||||
writeSettings();
|
||||
powerDown(INIT_EEPROM);
|
||||
NVIC_SystemReset();
|
||||
break;
|
||||
case CMD_ENTER_SLIDESHOW_GLACIAL:
|
||||
powerUp(INIT_EEPROM);
|
||||
if (findSlotDataTypeArg(CUSTOM_IMAGE_SLIDESHOW << 3) == 0xFF) {
|
||||
powerDown(INIT_EEPROM);
|
||||
return;
|
||||
}
|
||||
tagSettings.customMode = TAG_CUSTOM_SLIDESHOW_GLACIAL;
|
||||
writeSettings();
|
||||
powerDown(INIT_EEPROM);
|
||||
NVIC_SystemReset();
|
||||
break;
|
||||
case CMD_ENTER_NORMAL_MODE:
|
||||
tagSettings.customMode = TAG_CUSTOM_MODE_NONE;
|
||||
powerUp(INIT_EEPROM);
|
||||
writeSettings();
|
||||
powerDown(INIT_EEPROM);
|
||||
NVIC_SystemReset();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void mainLoop() {
|
||||
while (1) {
|
||||
powerUp(INIT_UART);
|
||||
wdt10s();
|
||||
switch (currentTagMode) {
|
||||
case TAG_MODE_ASSOCIATED:
|
||||
TagAssociated();
|
||||
break;
|
||||
case TAG_MODE_CHANSEARCH:
|
||||
TagChanSearch();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void setup() {
|
||||
setupBatteryVoltage();
|
||||
setupTemperature();
|
||||
Serial.begin(115200);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
setupPortsInitial();
|
||||
powerUp(INIT_BASE | INIT_UART);
|
||||
printf("BOOTED> %04X-%s\n", fwVersion, fwVersionSuffix);
|
||||
|
||||
wakeUpReason = getFirstWakeUpReason();
|
||||
identifyTagInfo();
|
||||
boardGetOwnMac(mSelfMac);
|
||||
|
||||
// do something if the mac isn't valid
|
||||
|
||||
boardGetOwnMac(mSelfMac);
|
||||
printf("MAC>%02X%02X", mSelfMac[0], mSelfMac[1]);
|
||||
printf("%02X%02X", mSelfMac[2], mSelfMac[3]);
|
||||
printf("%02X%02X", mSelfMac[4], mSelfMac[5]);
|
||||
printf("%02X%02X\n", mSelfMac[6], mSelfMac[7]);
|
||||
|
||||
powerUp(INIT_RADIO); // load down the battery using the radio to get a good voltage reading
|
||||
powerUp(INIT_EPD_VOLTREADING | INIT_TEMPREADING);
|
||||
powerDown(INIT_RADIO);
|
||||
// capabilities/options
|
||||
capabilities |= CAPABILITY_NFC_WAKE;
|
||||
if (tag.buttonCount) capabilities |= CAPABILITY_HAS_WAKE_BUTTON;
|
||||
if (tag.hasLED) capabilities |= CAPABILITY_HAS_LED;
|
||||
if (tag.hasNFC) {
|
||||
capabilities |= CAPABILITY_HAS_NFC;
|
||||
capabilities |= CAPABILITY_NFC_WAKE;
|
||||
}
|
||||
|
||||
powerUp(INIT_EEPROM);
|
||||
// get the highest slot number, number of slots
|
||||
loadSettings();
|
||||
initializeProto();
|
||||
invalidateSettingsEEPROM();
|
||||
|
||||
powerDown(INIT_EEPROM);
|
||||
|
||||
switch (checkButtonOrJig()) {
|
||||
case DETECT_P1_0_BUTTON:
|
||||
capabilities |= CAPABILITY_HAS_WAKE_BUTTON;
|
||||
break;
|
||||
case DETECT_P1_0_JIG:
|
||||
wdt120s();
|
||||
// show the screensaver (minimal text to prevent image burn-in)
|
||||
powerUp(INIT_EPD);
|
||||
afterFlashScreenSaver();
|
||||
while (1)
|
||||
;
|
||||
break;
|
||||
case DETECT_P1_0_NOTHING:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
powerUp(INIT_VOLTREADING);
|
||||
powerUp(INIT_TEMPREADING);
|
||||
|
||||
if (tagSettings.enableFastBoot) {
|
||||
// fast boot
|
||||
if (tagSettings.fixedChannel) {
|
||||
// don't scan, as this tag is bound to a fixed channel
|
||||
currentChannel = tagSettings.fixedChannel;
|
||||
} else {
|
||||
// do a quick scan
|
||||
wdt30s();
|
||||
currentChannel = channelSelect(2);
|
||||
}
|
||||
|
||||
if (currentChannel) {
|
||||
currentTagMode = TAG_MODE_ASSOCIATED;
|
||||
} else {
|
||||
currentTagMode = TAG_MODE_CHANSEARCH;
|
||||
}
|
||||
} else {
|
||||
// normal boot
|
||||
|
||||
// show the splashscreen
|
||||
powerUp(INIT_EPD);
|
||||
currentChannel = 1;
|
||||
if (!displayCustomImage(CUSTOM_IMAGE_SPLASHSCREEN)) showSplashScreen();
|
||||
currentChannel = 0;
|
||||
powerDown(INIT_EPD);
|
||||
|
||||
if (tagSettings.fixedChannel) {
|
||||
currentChannel = tagSettings.fixedChannel;
|
||||
} else {
|
||||
currentChannel = channelSelect(4);
|
||||
}
|
||||
}
|
||||
|
||||
// show the splashscreen
|
||||
powerUp(INIT_EPD);
|
||||
showSplashScreen();
|
||||
|
||||
powerUp(INIT_EPD);
|
||||
wdt30s();
|
||||
currentChannel = showChannelSelect();
|
||||
|
||||
wdt10s();
|
||||
|
||||
powerUp(INIT_EPD);
|
||||
if (currentChannel) {
|
||||
printf("AP Found\r\n");
|
||||
showAPFound();
|
||||
if (!displayCustomImage(CUSTOM_IMAGE_APFOUND)) showAPFound();
|
||||
powerDown(INIT_EPD);
|
||||
initPowerSaving(INTERVAL_BASE);
|
||||
powerDown(INIT_EPD | INIT_UART);
|
||||
currentTagMode = TAG_MODE_ASSOCIATED;
|
||||
|
||||
powerUp(INIT_EEPROM);
|
||||
writeSettings();
|
||||
powerDown(INIT_EEPROM);
|
||||
|
||||
doSleep(5000UL);
|
||||
} else {
|
||||
printf("No AP found\r\n");
|
||||
showNoAP();
|
||||
if (!displayCustomImage(CUSTOM_IMAGE_NOAPFOUND)) showNoAP();
|
||||
powerDown(INIT_EPD);
|
||||
initPowerSaving(INTERVAL_AT_MAX_ATTEMPTS);
|
||||
powerDown(INIT_EPD | INIT_UART);
|
||||
currentTagMode = TAG_MODE_CHANSEARCH;
|
||||
|
||||
powerUp(INIT_EEPROM);
|
||||
writeSettings();
|
||||
powerDown(INIT_EEPROM);
|
||||
|
||||
doSleep(120000UL);
|
||||
}
|
||||
}
|
||||
|
||||
void loop() {
|
||||
powerUp(INIT_UART);
|
||||
wdt10s();
|
||||
if (currentChannel) {
|
||||
// associated
|
||||
|
||||
struct AvailDataInfo *avail;
|
||||
// Is there any reason why we should do a long (full) get data request (including reason, status)?
|
||||
if ((longDataReqCounter > LONG_DATAREQ_INTERVAL) || wakeUpReason != WAKEUP_REASON_TIMED) {
|
||||
// check if we should do a voltage measurement (those are pretty expensive)
|
||||
if (voltageCheckCounter == VOLTAGE_CHECK_INTERVAL) {
|
||||
powerUp(INIT_RADIO); // load down the battery using the radio to get a good reading
|
||||
powerUp(INIT_TEMPREADING | INIT_EPD_VOLTREADING);
|
||||
powerDown(INIT_RADIO);
|
||||
voltageCheckCounter = 0;
|
||||
} else {
|
||||
powerUp(INIT_TEMPREADING);
|
||||
}
|
||||
voltageCheckCounter++;
|
||||
|
||||
// check if the battery level is below minimum, and force a redraw of the screen
|
||||
if ((lowBattery && !lowBatteryShown) || (noAPShown)) {
|
||||
// Check if we were already displaying an image
|
||||
if (curImgSlot != 0xFF) {
|
||||
powerUp(INIT_EEPROM | INIT_EPD);
|
||||
wdt60s();
|
||||
drawImageFromEeprom(curImgSlot);
|
||||
powerDown(INIT_EEPROM | INIT_EPD);
|
||||
} else {
|
||||
powerUp(INIT_EPD);
|
||||
showAPFound();
|
||||
powerDown(INIT_EPD);
|
||||
}
|
||||
}
|
||||
powerUp(INIT_RADIO);
|
||||
avail = getAvailDataInfo();
|
||||
powerDown(INIT_RADIO);
|
||||
|
||||
if (avail != NULL) {
|
||||
// we got some data!
|
||||
longDataReqCounter = 0;
|
||||
// since we've had succesful contact, and communicated the wakeup reason succesfully, we can now reset to the 'normal' status
|
||||
wakeUpReason = WAKEUP_REASON_TIMED;
|
||||
}
|
||||
} else {
|
||||
powerUp(INIT_RADIO);
|
||||
avail = getShortAvailDataInfo();
|
||||
powerDown(INIT_RADIO);
|
||||
}
|
||||
|
||||
addAverageValue();
|
||||
|
||||
if (avail == NULL) {
|
||||
// no data :(
|
||||
nextCheckInFromAP = 0; // let the power-saving algorithm determine the next sleep period
|
||||
} else {
|
||||
nextCheckInFromAP = avail->nextCheckIn;
|
||||
// got some data from the AP!
|
||||
if (avail->dataType != DATATYPE_NOUPDATE) {
|
||||
// data transfer
|
||||
if (processAvailDataInfo(avail)) {
|
||||
// succesful transfer, next wake time is determined by the NextCheckin;
|
||||
} else {
|
||||
// failed transfer, let the algorithm determine next sleep interval (not the AP)
|
||||
nextCheckInFromAP = 0;
|
||||
}
|
||||
} else {
|
||||
// no data transfer, just sleep.
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t nextCheckin = getNextSleep();
|
||||
longDataReqCounter += nextCheckin;
|
||||
if (nextCheckin == INTERVAL_AT_MAX_ATTEMPTS) {
|
||||
// disconnected, obviously...
|
||||
currentChannel = 0;
|
||||
}
|
||||
|
||||
// if the AP told us to sleep for a specific period, do so.
|
||||
if (nextCheckInFromAP) {
|
||||
doSleep(nextCheckInFromAP * 60000UL);
|
||||
} else {
|
||||
doSleep(getNextSleep() * 1000UL);
|
||||
}
|
||||
} else {
|
||||
// not associated
|
||||
if (((scanAttempts != 0) && (scanAttempts % VOLTAGEREADING_DURING_SCAN_INTERVAL == 0)) || (scanAttempts > (INTERVAL_1_ATTEMPTS + INTERVAL_2_ATTEMPTS))) {
|
||||
powerUp(INIT_RADIO); // load down the battery using the radio to get a good reading
|
||||
powerUp(INIT_EPD_VOLTREADING);
|
||||
powerDown(INIT_RADIO);
|
||||
}
|
||||
// try to find a working channel
|
||||
powerUp(INIT_RADIO);
|
||||
currentChannel = channelSelect();
|
||||
powerDown(INIT_RADIO);
|
||||
|
||||
if ((!currentChannel && !noAPShown) || (lowBattery && !lowBatteryShown) || (scanAttempts == (INTERVAL_1_ATTEMPTS + INTERVAL_2_ATTEMPTS - 1))) {
|
||||
powerUp(INIT_EPD);
|
||||
wdt60s();
|
||||
if (curImgSlot != 0xFF) {
|
||||
powerUp(INIT_EEPROM);
|
||||
drawImageFromEeprom(curImgSlot);
|
||||
powerDown(INIT_EEPROM);
|
||||
} else if ((scanAttempts >= (INTERVAL_1_ATTEMPTS + INTERVAL_2_ATTEMPTS - 1))) {
|
||||
showLongTermSleep();
|
||||
} else {
|
||||
showNoAP();
|
||||
}
|
||||
powerDown(INIT_EPD);
|
||||
}
|
||||
|
||||
// did we find a working channel?
|
||||
if (currentChannel) {
|
||||
// now associated!
|
||||
scanAttempts = 0;
|
||||
wakeUpReason = WAKEUP_REASON_NETWORK_SCAN;
|
||||
initPowerSaving(INTERVAL_BASE);
|
||||
doSleep(getNextSleep() * 1000UL);
|
||||
} else {
|
||||
// still not associated
|
||||
doSleep(getNextScanSleep(true) * 1000UL);
|
||||
}
|
||||
}
|
||||
}
|
||||
mainLoop();
|
||||
NVIC_SystemReset();
|
||||
}
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "hal.h"
|
||||
#include "userinterface.h"
|
||||
#include "wdt.h"
|
||||
#include "epd_driver/epd_interface.h"
|
||||
|
||||
uint16_t dataReqAttemptArr[POWER_SAVING_SMOOTHING] = {0}; // Holds the amount of attempts required per data_req/check-in
|
||||
uint8_t dataReqAttemptArrayIndex = 0;
|
||||
@@ -19,9 +20,6 @@ uint16_t nextCheckInFromAP = 0;
|
||||
uint8_t wakeUpReason = 0;
|
||||
uint8_t scanAttempts = 0;
|
||||
|
||||
int8_t temperature = 0;
|
||||
uint16_t batteryVoltage = 0;
|
||||
bool lowBattery = false;
|
||||
uint16_t longDataReqCounter = 0;
|
||||
uint16_t voltageCheckCounter = 0;
|
||||
|
||||
@@ -37,17 +35,17 @@ uint8_t checkButtonOrJig() {
|
||||
return DETECT_P1_0_NOTHING;
|
||||
}
|
||||
|
||||
void button1wake(){
|
||||
void button1wake() {
|
||||
wakeUpReason = WAKEUP_REASON_BUTTON1;
|
||||
resettimer();
|
||||
}
|
||||
|
||||
void button2wake(){
|
||||
void button2wake() {
|
||||
wakeUpReason = WAKEUP_REASON_BUTTON2;
|
||||
resettimer();
|
||||
}
|
||||
|
||||
void nfcwake(){
|
||||
void nfcwake() {
|
||||
wakeUpReason = WAKEUP_REASON_NFC;
|
||||
resettimer();
|
||||
}
|
||||
@@ -64,12 +62,20 @@ void setupPortsInitial() {
|
||||
pinMode(NFC_POWER, INPUT_PULLDOWN);
|
||||
pinMode(NFC_IRQ, INPUT_PULLDOWN);
|
||||
|
||||
pinMode(EPD_POWER, OUTPUT);
|
||||
digitalWrite(EPD_POWER, LOW);
|
||||
|
||||
pinMode(FLASH_MISO, INPUT);
|
||||
pinMode(FLASH_CLK, OUTPUT);
|
||||
pinMode(FLASH_MOSI, OUTPUT);
|
||||
digitalWrite(FLASH_CS, HIGH);
|
||||
pinMode(FLASH_CS, OUTPUT);
|
||||
|
||||
// pinMode(EPD_VPP, OUTPUT);
|
||||
// digitalWrite(EPD_VPP, HIGH);
|
||||
// pinMode(EPD_HLT, OUTPUT);
|
||||
// digitalWrite(EPD_HLT, HIGH);
|
||||
|
||||
attachInterrupt(digitalPinToInterrupt(BUTTON1), button1wake, FALLING);
|
||||
attachInterrupt(digitalPinToInterrupt(BUTTON2), button2wake, FALLING);
|
||||
attachInterrupt(digitalPinToInterrupt(NFC_IRQ), nfcwake, RISING);
|
||||
@@ -86,19 +92,22 @@ static void configSPI(const bool setup) {
|
||||
}
|
||||
|
||||
static void configUART(const bool setup) {
|
||||
/* if (setup == uartActive)
|
||||
return;
|
||||
uartActive = setup;
|
||||
if (setup)
|
||||
Serial.begin(115200);
|
||||
else
|
||||
Serial.end();*/
|
||||
return;
|
||||
if (setup == uartActive)
|
||||
return;
|
||||
uartActive = setup;
|
||||
if (setup) {
|
||||
NRF_UART0->ENABLE = 4;
|
||||
} else {
|
||||
NRF_UART0->ENABLE = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void configEEPROM(const bool setup) {
|
||||
if (setup == eepromActive)
|
||||
return;
|
||||
if (setup) {
|
||||
setupEepromHWSPI(true);
|
||||
if (!eepromInit()) {
|
||||
printf("Eeprom init error\r\n");
|
||||
powerDown(INIT_RADIO);
|
||||
@@ -109,19 +118,20 @@ static void configEEPROM(const bool setup) {
|
||||
NVIC_SystemReset();
|
||||
}
|
||||
} else {
|
||||
digitalWrite(FLASH_CS, HIGH);
|
||||
setupEepromHWSPI(false);
|
||||
}
|
||||
eepromActive = setup;
|
||||
}
|
||||
|
||||
static void configI2C(const bool setup) {
|
||||
if (setup == i2cActive)
|
||||
return;
|
||||
if (setup) {
|
||||
pinMode(NFC_I2C_SCL,OUTPUT);
|
||||
pinMode(NFC_I2C_SDA,OUTPUT);
|
||||
pinMode(NFC_I2C_SCL, OUTPUT);
|
||||
pinMode(NFC_I2C_SDA, OUTPUT);
|
||||
} else {
|
||||
pinMode(NFC_I2C_SDA,INPUT);
|
||||
pinMode(NFC_I2C_SCL,INPUT);
|
||||
pinMode(NFC_I2C_SDA, INPUT);
|
||||
pinMode(NFC_I2C_SCL, INPUT);
|
||||
}
|
||||
i2cActive = setup;
|
||||
}
|
||||
@@ -140,17 +150,13 @@ void powerUp(const uint8_t parts) {
|
||||
epdSetup();
|
||||
}
|
||||
|
||||
if (parts & INIT_EPD_VOLTREADING) {
|
||||
epdConfigGPIO(true);
|
||||
configSPI(true);
|
||||
batteryVoltage = epdGetBattery();
|
||||
if (parts & INIT_VOLTREADING) {
|
||||
getVoltage();
|
||||
if (batteryVoltage < BATTERY_VOLTAGE_MINIMUM) {
|
||||
lowBattery = true;
|
||||
} else {
|
||||
lowBattery = false;
|
||||
}
|
||||
configSPI(false);
|
||||
epdConfigGPIO(false);
|
||||
}
|
||||
|
||||
if (parts & INIT_UART) {
|
||||
@@ -163,7 +169,7 @@ void powerUp(const uint8_t parts) {
|
||||
}
|
||||
|
||||
if (parts & INIT_TEMPREADING) {
|
||||
//temperature = nrf_temp_read();
|
||||
getTemperature();
|
||||
}
|
||||
|
||||
if (parts & INIT_RADIO) {
|
||||
@@ -194,7 +200,6 @@ void powerDown(const uint8_t parts) {
|
||||
configEEPROM(false);
|
||||
}
|
||||
if (parts & INIT_EPD) {
|
||||
epdConfigGPIO(true);
|
||||
epdEnterSleep();
|
||||
epdConfigGPIO(false);
|
||||
}
|
||||
@@ -207,7 +212,7 @@ void powerDown(const uint8_t parts) {
|
||||
}
|
||||
|
||||
void doSleep(const uint32_t t) {
|
||||
printf("Sleeping for: %d ms\r\n", t);
|
||||
//printf("Sleeping for: %lu ms\r\n", t);
|
||||
sleepForMs(t);
|
||||
}
|
||||
|
||||
|
||||
91
ARM_Tag_FW/Newton_M3_nRF52811/src/settings.cpp
Normal file
91
ARM_Tag_FW/Newton_M3_nRF52811/src/settings.cpp
Normal file
@@ -0,0 +1,91 @@
|
||||
#define __packed
|
||||
#include "settings.h"
|
||||
|
||||
//#include <flash.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "powermgt.h"
|
||||
#include "syncedproto.h"
|
||||
#include "eeprom.h"
|
||||
#include "../../../oepl-definitions.h"
|
||||
#include "../../../oepl-proto.h"
|
||||
#include "hal.h"
|
||||
|
||||
#define __xdata
|
||||
|
||||
#define SETTINGS_MAGIC 0xABBA5AA5
|
||||
|
||||
struct tagsettings __xdata tagSettings = {0};
|
||||
extern uint8_t __xdata blockbuffer[];
|
||||
uint8_t* __xdata settingsTempBuffer = 1024 + blockbuffer;
|
||||
|
||||
void loadDefaultSettings() {
|
||||
tagSettings.settingsVer = SETTINGS_STRUCT_VERSION;
|
||||
tagSettings.enableFastBoot = DEFAULT_SETTING_FASTBOOT;
|
||||
tagSettings.enableRFWake = DEFAULT_SETTING_RFWAKE;
|
||||
tagSettings.enableTagRoaming = DEFAULT_SETTING_TAGROAMING;
|
||||
tagSettings.enableScanForAPAfterTimeout = DEFAULT_SETTING_SCANFORAP;
|
||||
tagSettings.enableLowBatSymbol = DEFAULT_SETTING_LOWBATSYMBOL;
|
||||
tagSettings.enableNoRFSymbol = DEFAULT_SETTING_NORFSYMBOL;
|
||||
tagSettings.customMode = 0;
|
||||
tagSettings.fastBootCapabilities = 0;
|
||||
tagSettings.minimumCheckInTime = INTERVAL_BASE;
|
||||
tagSettings.fixedChannel = 0;
|
||||
tagSettings.batLowVoltage = BATTERY_VOLTAGE_MINIMUM;
|
||||
}
|
||||
|
||||
void loadSettingsFromBuffer(uint8_t* p) {
|
||||
printf("SETTINGS: received settings from AP\n");
|
||||
switch (*p) {
|
||||
case SETTINGS_STRUCT_VERSION: // the current tag struct
|
||||
memcpy((void*)&tagSettings, (void*)p, sizeof(struct tagsettings));
|
||||
break;
|
||||
default:
|
||||
printf("SETTINGS: received something we couldn't really process, version %d\n", *p);
|
||||
break;
|
||||
}
|
||||
tagSettings.fastBootCapabilities = capabilities;
|
||||
writeSettings();
|
||||
}
|
||||
|
||||
static void upgradeSettings() {
|
||||
// add an upgrade strategy whenever you update the struct version
|
||||
}
|
||||
|
||||
void loadSettings() {
|
||||
eepromRead(EEPROM_SETTINGS_AREA_START+4, (void*)settingsTempBuffer, sizeof(struct tagsettings));
|
||||
memcpy((void*)&tagSettings, (void*)settingsTempBuffer, sizeof(struct tagsettings));
|
||||
uint32_t valid = 0;
|
||||
eepromRead(EEPROM_SETTINGS_AREA_START, (void*)&valid, 4);
|
||||
if (tagSettings.settingsVer == 0xFF || valid != SETTINGS_MAGIC) {
|
||||
// settings not set. load the defaults
|
||||
loadDefaultSettings();
|
||||
printf("SETTINGS: Loaded default settings\n");
|
||||
} else {
|
||||
if (tagSettings.settingsVer < SETTINGS_STRUCT_VERSION) {
|
||||
// upgrade
|
||||
upgradeSettings();
|
||||
printf("SETTINGS: Upgraded from previous version\n");
|
||||
} else {
|
||||
// settings are valid
|
||||
printf("SETTINGS: Loaded from EEPROM\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void writeSettings() {
|
||||
eepromErase(EEPROM_SETTINGS_AREA_START, 1);
|
||||
uint32_t valid = SETTINGS_MAGIC;
|
||||
eepromWrite(EEPROM_SETTINGS_AREA_START, (void*)&valid, 4);
|
||||
eepromWrite(EEPROM_SETTINGS_AREA_START+4, (void*)&tagSettings, sizeof(tagSettings));
|
||||
printf("SETTINGS: Updated settings in EEPROM\n");
|
||||
}
|
||||
|
||||
void invalidateSettingsEEPROM() {
|
||||
int32_t __xdata valid = 0x0000;
|
||||
eepromWrite(EEPROM_SETTINGS_AREA_START, (void*)&valid, 4);
|
||||
}
|
||||
@@ -8,7 +8,8 @@
|
||||
#include "eeprom.h"
|
||||
#include "hal.h"
|
||||
#include "powermgt.h"
|
||||
#include "proto.h"
|
||||
#include "../../../oepl-proto.h"
|
||||
#include "../../../oepl-definitions.h"
|
||||
#include "userinterface.h"
|
||||
#include "wdt.h"
|
||||
|
||||
@@ -22,19 +23,23 @@ struct fwmetadata {
|
||||
uint32_t magic2;
|
||||
};
|
||||
|
||||
#define EEPROM_SETTINGS_SIZE 4096
|
||||
|
||||
#define BLOCKSIZE_MS 320 // was 270
|
||||
|
||||
// download-stuff
|
||||
uint8_t blockXferBuffer[BLOCK_XFER_BUFFER_SIZE] = {0};
|
||||
static struct blockRequest curBlock = {0}; // used by the block-requester, contains the next request that we'll send
|
||||
static struct AvailDataInfo curDataInfo = {0}; // last 'AvailDataInfo' we received from the AP
|
||||
static bool requestPartialBlock = false; // if we should ask the AP to get this block from the host or not
|
||||
uint8_t blockbuffer[BLOCK_XFER_BUFFER_SIZE] = {0};
|
||||
static struct blockRequest curBlock = {0}; // used by the block-requester, contains the next request that we'll send
|
||||
static uint64_t curDispDataVer = 0;
|
||||
static struct AvailDataInfo xferDataInfo = {0}; // last 'AvailDataInfo' we received from the AP
|
||||
static bool requestPartialBlock = false; // if we should ask the AP to get this block from the host or not
|
||||
#define BLOCK_TRANSFER_ATTEMPTS 5
|
||||
|
||||
uint8_t prevImgSlot = 0xFF;
|
||||
uint8_t xferImgSlot = 0xFF;
|
||||
uint8_t curImgSlot = 0xFF;
|
||||
static uint32_t curHighSlotId = 0;
|
||||
static uint8_t nextImgSlot = 0;
|
||||
static uint8_t imgSlots = 0;
|
||||
uint8_t drawWithLut = 0;
|
||||
|
||||
// stuff we need to keep track of related to the network/AP
|
||||
uint8_t APmac[8] = {0};
|
||||
@@ -47,6 +52,8 @@ uint8_t currentChannel = 0;
|
||||
static uint8_t inBuffer[128] = {0};
|
||||
static uint8_t outBuffer[128] = {0};
|
||||
|
||||
extern void executeCommand(uint8_t cmd); // this is defined in main.c
|
||||
|
||||
// tools
|
||||
static uint8_t getPacketType(const void *buffer) {
|
||||
const struct MacFcs *fcs = (MacFcs *)buffer;
|
||||
@@ -185,13 +192,14 @@ static void sendAvailDataReq() {
|
||||
txframe->dstAddr = 0xFFFF;
|
||||
txframe->srcPan = PROTO_PAN_ID;
|
||||
// TODO: send some (more) meaningful data
|
||||
availreq->hwType = HW_TYPE;
|
||||
availreq->hwType = tag.OEPLtype;
|
||||
availreq->wakeupReason = wakeUpReason;
|
||||
availreq->lastPacketRSSI = mLastRSSI;
|
||||
availreq->lastPacketLQI = mLastLqi;
|
||||
availreq->temperature = temperature;
|
||||
availreq->batteryMv = batteryVoltage;
|
||||
availreq->capabilities = capabilities;
|
||||
availreq->tagSoftwareVersion = FW_VERSION;
|
||||
addCRC(availreq, sizeof(struct AvailDataReq));
|
||||
commsTxNoCpy(outBuffer);
|
||||
}
|
||||
@@ -252,16 +260,16 @@ static bool processBlockPart(const struct blockPart *bp) {
|
||||
// printf("got a packet for block %02X\n", bp->blockId);
|
||||
return false;
|
||||
}
|
||||
if (start >= (sizeof(blockXferBuffer) - 1))
|
||||
if (start >= (sizeof(blockbuffer) - 1))
|
||||
return false;
|
||||
if (bp->blockPart > BLOCK_MAX_PARTS)
|
||||
return false;
|
||||
if ((start + size) > sizeof(blockXferBuffer)) {
|
||||
size = sizeof(blockXferBuffer) - start;
|
||||
if ((start + size) > sizeof(blockbuffer)) {
|
||||
size = sizeof(blockbuffer) - start;
|
||||
}
|
||||
if (checkCRC(bp, sizeof(struct blockPart) + BLOCK_PART_DATA_SIZE)) {
|
||||
// copy block data to buffer
|
||||
memcpy((void *)(blockXferBuffer + start), (const void *)bp->data, size);
|
||||
memcpy((void *)(blockbuffer + start), (const void *)bp->data, size);
|
||||
// we don't need this block anymore, set bit to 0 so we don't request it again
|
||||
curBlock.requestedParts[bp->blockPart / 8] &= ~(1 << (bp->blockPart % 8));
|
||||
return true;
|
||||
@@ -393,7 +401,7 @@ static void sendXferComplete() {
|
||||
return;
|
||||
}
|
||||
static bool validateBlockData() {
|
||||
struct blockData *bd = (struct blockData *)blockXferBuffer;
|
||||
struct blockData *bd = (struct blockData *)blockbuffer;
|
||||
// printf("expected len = %04X, checksum=%04X\n", bd->size, bd->checksum);
|
||||
if (bd->size > BLOCK_XFER_BUFFER_SIZE - sizeof(blockData)) {
|
||||
printf("Impossible data size, we abort here\n");
|
||||
@@ -427,20 +435,20 @@ static bool validateEepromMD5(uint64_t ver, uint32_t eepromstart, uint32_t flen)
|
||||
bool isValid = ver == *((uint64_t *)hash);
|
||||
if (!isValid) {
|
||||
printf("MD5 failed check! This is what we should get:\n");
|
||||
dump((const uint8_t *)&(curDataInfo.dataVer), 8);
|
||||
dump((const uint8_t *)&(xferDataInfo.dataVer), 8);
|
||||
printf("This is what we got:\n");
|
||||
dump(hash, 16);
|
||||
}
|
||||
return isValid;
|
||||
}
|
||||
static uint32_t getAddressForSlot(const uint8_t s) {
|
||||
return EEPROM_IMG_START + (EEPROM_IMG_EACH * s);
|
||||
return (tag.imageSize * s);
|
||||
}
|
||||
static void getNumSlots() {
|
||||
uint32_t eeSize = eepromGetSize();
|
||||
|
||||
uint16_t nSlots = (eeSize - EEPROM_IMG_START) / (EEPROM_IMG_EACH >> 8) >> 8;
|
||||
if (eeSize < EEPROM_IMG_START || !nSlots) {
|
||||
uint16_t nSlots = (eeSize - EEPROM_SETTINGS_SIZE) / (tag.imageSize >> 8) >> 8;
|
||||
if (!nSlots) {
|
||||
printf("eeprom is too small\n");
|
||||
while (1)
|
||||
;
|
||||
@@ -451,28 +459,63 @@ static void getNumSlots() {
|
||||
imgSlots = nSlots;
|
||||
printf("EEPROM reported size = %lu, %d slots\n", eeSize, imgSlots);
|
||||
}
|
||||
static uint8_t findSlot(const uint8_t *ver) {
|
||||
static uint8_t findSlotVer(uint64_t ver) {
|
||||
// return 0xFF; // remove me! This forces the tag to re-download each and every upload without checking if it's already in the eeprom somewhere
|
||||
uint32_t markerValid = EEPROM_IMG_VALID;
|
||||
for (uint8_t c = 0; c < imgSlots; c++) {
|
||||
struct EepromImageHeader *eih = (struct EepromImageHeader *)blockXferBuffer;
|
||||
struct EepromImageHeader *eih = (struct EepromImageHeader *)blockbuffer;
|
||||
eepromRead(getAddressForSlot(c), eih, sizeof(struct EepromImageHeader));
|
||||
if (!memcmp(&eih->validMarker, &markerValid, 4)) {
|
||||
if (!memcmp(&eih->version, (void *)ver, 8)) {
|
||||
if (eih->version == ver) {
|
||||
return c;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0xFF;
|
||||
}
|
||||
|
||||
uint8_t findSlotDataTypeArg(uint8_t arg) {
|
||||
arg &= (0xF8); // unmatch with the 'preload' bit and LUT bits
|
||||
for (uint8_t c = 0; c < imgSlots; c++) {
|
||||
struct EepromImageHeader *eih = (struct EepromImageHeader *)blockbuffer;
|
||||
eepromRead(getAddressForSlot(c), eih, sizeof(struct EepromImageHeader));
|
||||
if (eih->validMarker == EEPROM_IMG_VALID) {
|
||||
if ((eih->argument & 0xF8) == arg) {
|
||||
return c;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0xFF;
|
||||
}
|
||||
uint8_t getEepromImageDataArgument(const uint8_t slot) {
|
||||
struct EepromImageHeader *eih = (struct EepromImageHeader *)blockbuffer;
|
||||
eepromRead(getAddressForSlot(slot), eih, sizeof(struct EepromImageHeader));
|
||||
return eih->argument;
|
||||
}
|
||||
uint8_t findNextSlideshowImage(uint8_t start) {
|
||||
struct EepromImageHeader *eih = (struct EepromImageHeader *)blockbuffer;
|
||||
uint8_t c = start;
|
||||
while (1) {
|
||||
c++;
|
||||
if (c > imgSlots) c = 0;
|
||||
if (c == start) return c;
|
||||
eepromRead(getAddressForSlot(c), eih, sizeof(struct EepromImageHeader));
|
||||
if (eih->validMarker == EEPROM_IMG_VALID) {
|
||||
if ((eih->argument & 0xF8) == (CUSTOM_IMAGE_SLIDESHOW << 3)) {
|
||||
return c;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void eraseUpdateBlock() {
|
||||
eepromErase(FW_LOC, (FW_METADATA_LOC + EEPROM_ERZ_SECTOR_SZ) / EEPROM_ERZ_SECTOR_SZ);
|
||||
}
|
||||
static void eraseImageBlock(const uint8_t c) {
|
||||
eepromErase(getAddressForSlot(c), EEPROM_IMG_EACH / EEPROM_ERZ_SECTOR_SZ);
|
||||
eepromErase(getAddressForSlot(c), tag.imageSize / EEPROM_ERZ_SECTOR_SZ);
|
||||
}
|
||||
static void saveUpdateBlockData(uint8_t blockId) {
|
||||
if (!eepromWrite(FW_LOC + (blockId * BLOCK_DATA_SIZE), blockXferBuffer + sizeof(struct blockData), BLOCK_DATA_SIZE))
|
||||
if (!eepromWrite(FW_LOC + (blockId * BLOCK_DATA_SIZE), blockbuffer + sizeof(struct blockData), BLOCK_DATA_SIZE))
|
||||
printf("EEPROM write failed\n");
|
||||
}
|
||||
static void saveUpdateMetadata(uint32_t size) {
|
||||
@@ -483,22 +526,26 @@ static void saveUpdateMetadata(uint32_t size) {
|
||||
eepromWrite(FW_METADATA_LOC, &metadata, sizeof(struct fwmetadata));
|
||||
}
|
||||
static void saveImgBlockData(const uint8_t imgSlot, const uint8_t blockId) {
|
||||
uint32_t length = EEPROM_IMG_EACH - (sizeof(struct EepromImageHeader) + (blockId * BLOCK_DATA_SIZE));
|
||||
uint32_t length = tag.imageSize - (sizeof(struct EepromImageHeader) + (blockId * BLOCK_DATA_SIZE));
|
||||
if (length > 4096)
|
||||
length = 4096;
|
||||
|
||||
if (!eepromWrite(getAddressForSlot(imgSlot) + sizeof(struct EepromImageHeader) + (blockId * BLOCK_DATA_SIZE), blockXferBuffer + sizeof(struct blockData), length))
|
||||
if (!eepromWrite(getAddressForSlot(imgSlot) + sizeof(struct EepromImageHeader) + (blockId * BLOCK_DATA_SIZE), blockbuffer + sizeof(struct blockData), length))
|
||||
printf("EEPROM write failed\n");
|
||||
}
|
||||
void drawImageFromEeprom(const uint8_t imgSlot) {
|
||||
drawImageAtAddress(getAddressForSlot(imgSlot), drawWithLut);
|
||||
drawWithLut = 0; // default back to the regular ol' stock/OTP LUT
|
||||
void eraseImageBlocks() {
|
||||
for (uint8_t c = 0; c < imgSlots; c++) {
|
||||
eraseImageBlock(c);
|
||||
}
|
||||
}
|
||||
void drawImageFromEeprom(const uint8_t imgSlot, uint8_t lut) {
|
||||
drawImageAtAddress(getAddressForSlot(imgSlot), lut);
|
||||
}
|
||||
static uint32_t getHighSlotId() {
|
||||
uint32_t temp = 0;
|
||||
uint32_t markerValid = EEPROM_IMG_VALID;
|
||||
for (uint8_t c = 0; c < imgSlots; c++) {
|
||||
struct EepromImageHeader *eih = (struct EepromImageHeader *)blockXferBuffer;
|
||||
struct EepromImageHeader *eih = (struct EepromImageHeader *)blockbuffer;
|
||||
eepromRead(getAddressForSlot(c), eih, sizeof(struct EepromImageHeader));
|
||||
if (!memcmp(&eih->validMarker, &markerValid, 4)) {
|
||||
if (temp < eih->id) {
|
||||
@@ -566,7 +613,7 @@ static bool getDataBlock(const uint16_t blockSize) {
|
||||
} else {
|
||||
// immediately start with the reception of the block data
|
||||
}
|
||||
blockRxLoop(270); // BLOCK RX LOOP - receive a block, until the timeout has passed
|
||||
blockRxLoop(BLOCKSIZE_MS); // BLOCK RX LOOP - receive a block, until the timeout has passed
|
||||
powerDown(INIT_RADIO);
|
||||
|
||||
#ifdef DEBUGBLOCKS
|
||||
@@ -620,26 +667,26 @@ uint32_t curXferSize = 0;
|
||||
|
||||
static bool downloadFWUpdate(const struct AvailDataInfo *avail) {
|
||||
// check if we already started the transfer of this information & haven't completed it
|
||||
if (!memcmp((const void *)&avail->dataVer, (const void *)&curDataInfo.dataVer, 8) && curDataInfo.dataSize) {
|
||||
if (!memcmp((const void *)&avail->dataVer, (const void *)&xferDataInfo.dataVer, 8) && xferDataInfo.dataSize) {
|
||||
// looks like we did. We'll carry on where we left off.
|
||||
} else {
|
||||
// start, or restart the transfer from 0. Copy data from the AvailDataInfo struct, and the struct intself. This forces a new transfer
|
||||
curBlock.blockId = 0;
|
||||
memcpy(&(curBlock.ver), &(avail->dataVer), 8);
|
||||
curBlock.type = avail->dataType;
|
||||
memcpy(&curDataInfo, (void *)avail, sizeof(struct AvailDataInfo));
|
||||
memcpy(&xferDataInfo, (void *)avail, sizeof(struct AvailDataInfo));
|
||||
curXferSize = avail->dataSize;
|
||||
eraseUpdateBlock();
|
||||
}
|
||||
|
||||
while (curDataInfo.dataSize) {
|
||||
while (xferDataInfo.dataSize) {
|
||||
wdt10s();
|
||||
if (curDataInfo.dataSize > BLOCK_DATA_SIZE) {
|
||||
if (xferDataInfo.dataSize > BLOCK_DATA_SIZE) {
|
||||
// more than one block remaining
|
||||
dataRequestSize = BLOCK_DATA_SIZE;
|
||||
} else {
|
||||
// only one block remains
|
||||
dataRequestSize = curDataInfo.dataSize;
|
||||
dataRequestSize = xferDataInfo.dataSize;
|
||||
}
|
||||
if (getDataBlock(dataRequestSize)) {
|
||||
// succesfully downloaded datablock, save to eeprom
|
||||
@@ -647,46 +694,65 @@ static bool downloadFWUpdate(const struct AvailDataInfo *avail) {
|
||||
saveUpdateBlockData(curBlock.blockId);
|
||||
powerDown(INIT_EEPROM);
|
||||
curBlock.blockId++;
|
||||
curDataInfo.dataSize -= dataRequestSize;
|
||||
xferDataInfo.dataSize -= dataRequestSize;
|
||||
} else {
|
||||
// failed to get the block we wanted, we'll stop for now, maybe resume later
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// no more data, download complete
|
||||
powerUp(INIT_EEPROM);
|
||||
if (validateEepromMD5(curDataInfo.dataVer, FW_LOC, curXferSize)) {
|
||||
if (validateEepromMD5(xferDataInfo.dataVer, FW_LOC, curXferSize)) {
|
||||
// md5 matches
|
||||
powerDown(INIT_EEPROM);
|
||||
return true;
|
||||
} else {
|
||||
// md5 does not match, invalidate current transfer result, forcing a restart of the transfer
|
||||
memset((void *)&curDataInfo, 0, sizeof(struct AvailDataInfo));
|
||||
memset((void *)&xferDataInfo, 0, sizeof(struct AvailDataInfo));
|
||||
powerDown(INIT_EEPROM);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t imageSize = 0;
|
||||
static bool downloadImageDataToEEPROM(const struct AvailDataInfo *avail) {
|
||||
powerUp(INIT_EEPROM);
|
||||
// check if we already started the transfer of this information & haven't completed it
|
||||
if (!memcmp((const void *)&avail->dataVer, (const void *)&curDataInfo.dataVer, 8) && curDataInfo.dataSize) {
|
||||
if (!memcmp((const void *)&avail->dataVer, (const void *)&xferDataInfo.dataVer, 8) && xferDataInfo.dataSize) {
|
||||
// looks like we did. We'll carry on where we left off.
|
||||
printf("restarting image download");
|
||||
curImgSlot = nextImgSlot;
|
||||
// curImgSlot = nextImgSlot; // hmmm
|
||||
} else {
|
||||
// go to the next image slot
|
||||
nextImgSlot++;
|
||||
if (nextImgSlot >= imgSlots)
|
||||
nextImgSlot = 0;
|
||||
curImgSlot = nextImgSlot;
|
||||
printf("Saving to image slot %d\n", curImgSlot);
|
||||
drawWithLut = avail->dataTypeArgument;
|
||||
powerUp(INIT_EEPROM);
|
||||
// new transfer
|
||||
uint8_t startingSlot = nextImgSlot;
|
||||
while (1) {
|
||||
nextImgSlot++;
|
||||
if (nextImgSlot >= imgSlots) nextImgSlot = 0;
|
||||
if (nextImgSlot == startingSlot) {
|
||||
// looped
|
||||
powerDown(INIT_EEPROM);
|
||||
printf("no slot available...\n");
|
||||
return true;
|
||||
}
|
||||
struct EepromImageHeader *eih = (struct EepromImageHeader *)blockbuffer;
|
||||
eepromRead(getAddressForSlot(nextImgSlot), eih, sizeof(struct EepromImageHeader));
|
||||
// checked if the marker is valid
|
||||
if (eih->validMarker == EEPROM_IMG_VALID) {
|
||||
struct imageDataTypeArgStruct *eepromDataArgument = (struct imageDataTypeArgStruct *)&(eih->argument);
|
||||
// if this is a normal type, we can replace it
|
||||
if (eepromDataArgument->specialType == 0x00) break;
|
||||
} else {
|
||||
// invalid header, so safe to overwrite anyway
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
xferImgSlot = nextImgSlot;
|
||||
|
||||
uint8_t attempt = 5;
|
||||
while (attempt--) {
|
||||
if (eepromErase(getAddressForSlot(curImgSlot), EEPROM_IMG_EACH / EEPROM_ERZ_SECTOR_SZ))
|
||||
goto eraseSuccess;
|
||||
if (eepromErase(getAddressForSlot(xferImgSlot), tag.imageSize / EEPROM_ERZ_SECTOR_SZ)) goto eraseSuccess;
|
||||
}
|
||||
eepromFail:
|
||||
powerDown(INIT_RADIO);
|
||||
@@ -696,34 +762,34 @@ static bool downloadImageDataToEEPROM(const struct AvailDataInfo *avail) {
|
||||
doSleep(-1);
|
||||
NVIC_SystemReset();
|
||||
eraseSuccess:
|
||||
printf("new download, writing to slot %d\n", curImgSlot);
|
||||
printf("new download, writing to slot %d\n", xferImgSlot);
|
||||
// start, or restart the transfer. Copy data from the AvailDataInfo struct, and the struct intself. This forces a new transfer
|
||||
curBlock.blockId = 0;
|
||||
memcpy(&(curBlock.ver), &(avail->dataVer), 8);
|
||||
curBlock.type = avail->dataType;
|
||||
memcpy(&curDataInfo, (void *)avail, sizeof(struct AvailDataInfo));
|
||||
curXferSize = curDataInfo.dataSize;
|
||||
memcpy(&xferDataInfo, (void *)avail, sizeof(struct AvailDataInfo));
|
||||
imageSize = xferDataInfo.dataSize;
|
||||
}
|
||||
|
||||
while (curDataInfo.dataSize) {
|
||||
while (xferDataInfo.dataSize) {
|
||||
wdt10s();
|
||||
if (curDataInfo.dataSize > BLOCK_DATA_SIZE) {
|
||||
if (xferDataInfo.dataSize > BLOCK_DATA_SIZE) {
|
||||
// more than one block remaining
|
||||
dataRequestSize = BLOCK_DATA_SIZE;
|
||||
} else {
|
||||
// only one block remains
|
||||
dataRequestSize = curDataInfo.dataSize;
|
||||
dataRequestSize = xferDataInfo.dataSize;
|
||||
}
|
||||
if (getDataBlock(dataRequestSize)) {
|
||||
// succesfully downloaded datablock, save to eeprom
|
||||
powerUp(INIT_EEPROM);
|
||||
#ifdef DEBUGBLOCKS
|
||||
printf("Saving block %d to slot %d\n", curBlock.blockId, curImgSlot);
|
||||
printf("Saving block %d to slot %d\n", curBlock.blockId, xferImgSlot);
|
||||
#endif
|
||||
saveImgBlockData(curImgSlot, curBlock.blockId);
|
||||
saveImgBlockData(xferImgSlot, curBlock.blockId);
|
||||
powerDown(INIT_EEPROM);
|
||||
curBlock.blockId++;
|
||||
curDataInfo.dataSize -= dataRequestSize;
|
||||
xferDataInfo.dataSize -= dataRequestSize;
|
||||
} else {
|
||||
// failed to get the block we wanted, we'll stop for now, probably resume later
|
||||
return false;
|
||||
@@ -731,91 +797,145 @@ static bool downloadImageDataToEEPROM(const struct AvailDataInfo *avail) {
|
||||
}
|
||||
// no more data, download complete
|
||||
|
||||
// borrow the blockXferBuffer temporarily
|
||||
struct EepromImageHeader *eih = (struct EepromImageHeader *)blockXferBuffer;
|
||||
memcpy(&eih->version, &curDataInfo.dataVer, 8);
|
||||
// borrow the blockbuffer temporarily
|
||||
struct EepromImageHeader *eih = (struct EepromImageHeader *)blockbuffer;
|
||||
memcpy(&eih->version, &xferDataInfo.dataVer, 8);
|
||||
eih->validMarker = EEPROM_IMG_VALID;
|
||||
eih->id = ++curHighSlotId;
|
||||
eih->size = curXferSize;
|
||||
eih->dataType = curDataInfo.dataType;
|
||||
eih->dataType = xferDataInfo.dataType;
|
||||
eih->argument = xferDataInfo.dataTypeArgument;
|
||||
|
||||
#ifdef DEBUGBLOCKS
|
||||
printf("Now writing datatype 0x%02X to slot %d\n", curDataInfo.dataType, curImgSlot);
|
||||
printf("Now writing datatype 0x%02X to slot %d\n", xferDataInfo.dataType, xferImgSlot);
|
||||
#endif
|
||||
|
||||
powerUp(INIT_EEPROM);
|
||||
if (validateEepromMD5(curDataInfo.dataVer, getAddressForSlot(curImgSlot) + sizeof(struct EepromImageHeader), curXferSize)) {
|
||||
if (validateEepromMD5(xferDataInfo.dataVer, getAddressForSlot(xferImgSlot) + sizeof(struct EepromImageHeader), imageSize)) {
|
||||
// md5 matches
|
||||
eepromWrite(getAddressForSlot(curImgSlot), eih, sizeof(struct EepromImageHeader));
|
||||
eepromWrite(getAddressForSlot(xferImgSlot), eih, sizeof(struct EepromImageHeader));
|
||||
powerDown(INIT_EEPROM);
|
||||
return true;
|
||||
} else {
|
||||
// md5 does not match, invalidate current transfer result, forcing a restart of the transfer
|
||||
memset((void *)&curDataInfo, 0, sizeof(struct AvailDataInfo));
|
||||
memset((void *)&xferDataInfo, 0, sizeof(struct AvailDataInfo));
|
||||
powerDown(INIT_EEPROM);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool processAvailDataInfo(struct AvailDataInfo *avail) {
|
||||
switch (avail->dataType) {
|
||||
case DATATYPE_IMG_BMP:
|
||||
case DATATYPE_IMG_DIFF:
|
||||
case DATATYPE_IMG_RAW_1BPP:
|
||||
case DATATYPE_IMG_RAW_2BPP:
|
||||
// check if this download is currently displayed or active
|
||||
if (curDataInfo.dataSize == 0 && !memcmp((const void *)&avail->dataVer, (const void *)&curDataInfo.dataVer, 8)) {
|
||||
// we've downloaded this already, we're guessing it's already displayed
|
||||
printf("currently shown image, send xfc\n");
|
||||
powerUp(INIT_RADIO);
|
||||
sendXferComplete();
|
||||
powerDown(INIT_RADIO);
|
||||
return true;
|
||||
}
|
||||
bool processImageDataAvail(struct AvailDataInfo *avail) {
|
||||
struct imageDataTypeArgStruct arg = *((struct imageDataTypeArgStruct *)avail->dataTypeArgument);
|
||||
|
||||
// check if we've seen this version before
|
||||
if (arg.preloadImage) {
|
||||
printf("Preloading image with type 0x%02X from arg 0x%02X\n", arg.specialType, avail->dataTypeArgument);
|
||||
powerUp(INIT_EEPROM);
|
||||
switch (arg.specialType) {
|
||||
// check if a slot with this argument is already set; if so, erase. Only one of each arg type should exist
|
||||
default: {
|
||||
uint8_t slot = findSlotDataTypeArg(avail->dataTypeArgument);
|
||||
if (slot != 0xFF) {
|
||||
eepromErase(getAddressForSlot(slot), tag.imageSize / EEPROM_ERZ_SECTOR_SZ);
|
||||
}
|
||||
} break;
|
||||
// regular image preload, there can be multiple of this type in the EEPROM
|
||||
case CUSTOM_IMAGE_NOCUSTOM: {
|
||||
// check if a version of this already exists
|
||||
uint8_t slot = findSlotVer(avail->dataVer);
|
||||
if (slot != 0xFF) {
|
||||
powerUp(INIT_RADIO);
|
||||
sendXferComplete();
|
||||
powerDown(INIT_RADIO);
|
||||
return true;
|
||||
}
|
||||
} break;
|
||||
case CUSTOM_IMAGE_SLIDESHOW:
|
||||
break;
|
||||
}
|
||||
powerDown(INIT_EEPROM);
|
||||
|
||||
printf("downloading preload image...\n");
|
||||
if (downloadImageDataToEEPROM(avail)) {
|
||||
// sets xferImgSlot to the right slot
|
||||
printf("preload complete!\n");
|
||||
powerUp(INIT_RADIO);
|
||||
sendXferComplete();
|
||||
powerDown(INIT_RADIO);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
} else {
|
||||
// check if we're currently displaying this data payload
|
||||
if (avail->dataVer == curDispDataVer) {
|
||||
// currently displayed, not doing anything except for sending an XFC
|
||||
|
||||
printf("currently shown image, send xfc\n");
|
||||
powerUp(INIT_RADIO);
|
||||
sendXferComplete();
|
||||
powerDown(INIT_RADIO);
|
||||
return true;
|
||||
|
||||
} else {
|
||||
// currently not displayed
|
||||
|
||||
// try to find the data in the SPI EEPROM
|
||||
powerUp(INIT_EEPROM);
|
||||
curImgSlot = findSlot((uint8_t *)&(avail->dataVer));
|
||||
uint8_t findImgSlot = findSlotVer(avail->dataVer);
|
||||
powerDown(INIT_EEPROM);
|
||||
if (curImgSlot != 0xFF) {
|
||||
|
||||
// Is this image already in a slot somewhere
|
||||
if (findImgSlot != 0xFF) {
|
||||
// found a (complete)valid image slot for this version
|
||||
powerUp(INIT_RADIO);
|
||||
sendXferComplete();
|
||||
powerDown(INIT_RADIO);
|
||||
|
||||
printf("already seen, drawing from eeprom slot %d\n", curImgSlot);
|
||||
|
||||
// mark as completed and draw from EEPROM
|
||||
memcpy(&curDataInfo, (void *)avail, sizeof(struct AvailDataInfo));
|
||||
curDataInfo.dataSize = 0; // mark as transfer not pending
|
||||
memcpy(&xferDataInfo, (void *)avail, sizeof(struct AvailDataInfo));
|
||||
xferDataInfo.dataSize = 0; // mark as transfer not pending
|
||||
|
||||
drawWithLut = avail->dataTypeArgument;
|
||||
wdt60s();
|
||||
curImgSlot = findImgSlot;
|
||||
powerUp(INIT_EPD | INIT_EEPROM);
|
||||
drawImageFromEeprom(curImgSlot);
|
||||
drawImageFromEeprom(findImgSlot, arg.lut);
|
||||
powerDown(INIT_EPD | INIT_EEPROM);
|
||||
return true;
|
||||
|
||||
} else {
|
||||
// not found in cache, prepare to download
|
||||
printf("downloading to imgslot curImgSlot\n");
|
||||
drawWithLut = avail->dataTypeArgument;
|
||||
powerUp(INIT_EEPROM);
|
||||
printf("downloading image...\n");
|
||||
if (downloadImageDataToEEPROM(avail)) {
|
||||
// sets xferImgSlot to the right slot
|
||||
printf("download complete!\n");
|
||||
powerUp(INIT_RADIO);
|
||||
sendXferComplete();
|
||||
powerDown(INIT_RADIO);
|
||||
|
||||
// not preload, draw now
|
||||
wdt60s();
|
||||
curImgSlot = xferImgSlot;
|
||||
powerUp(INIT_EPD | INIT_EEPROM);
|
||||
drawImageFromEeprom(curImgSlot);
|
||||
drawImageFromEeprom(xferImgSlot, arg.lut);
|
||||
powerDown(INIT_EPD | INIT_EEPROM);
|
||||
return true;
|
||||
|
||||
} else {
|
||||
powerDown(INIT_EEPROM);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// keep track on what is currently displayed
|
||||
curDispDataVer = xferDataInfo.dataVer;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool processAvailDataInfo(struct AvailDataInfo *avail) {
|
||||
switch (avail->dataType) {
|
||||
case DATATYPE_IMG_RAW_1BPP:
|
||||
case DATATYPE_IMG_RAW_2BPP:
|
||||
processImageDataAvail(avail);
|
||||
break;
|
||||
case DATATYPE_FW_UPDATE:
|
||||
powerUp(INIT_EEPROM);
|
||||
@@ -851,7 +971,7 @@ bool processAvailDataInfo(struct AvailDataInfo *avail) {
|
||||
}
|
||||
|
||||
printf("NFC URL received\n");
|
||||
if (curDataInfo.dataSize == 0 && !memcmp((const void *)&avail->dataVer, (const void *)&curDataInfo.dataVer, 8)) {
|
||||
if (xferDataInfo.dataSize == 0 && !memcmp((const void *)&avail->dataVer, (const void *)&xferDataInfo.dataVer, 8)) {
|
||||
// we've already downloaded this NFC data, disregard and send XFC
|
||||
printf("this was the same as the last transfer, disregard\n");
|
||||
powerUp(INIT_RADIO);
|
||||
@@ -862,11 +982,11 @@ bool processAvailDataInfo(struct AvailDataInfo *avail) {
|
||||
curBlock.blockId = 0;
|
||||
memcpy(&(curBlock.ver), &(avail->dataVer), 8);
|
||||
curBlock.type = avail->dataType;
|
||||
memcpy(&curDataInfo, (void *)avail, sizeof(struct AvailDataInfo));
|
||||
memcpy(&xferDataInfo, (void *)avail, sizeof(struct AvailDataInfo));
|
||||
uint16_t nfcsize = avail->dataSize;
|
||||
wdt10s();
|
||||
if (getDataBlock(avail->dataSize)) {
|
||||
curDataInfo.dataSize = 0; // mark as transfer not pending
|
||||
xferDataInfo.dataSize = 0; // mark as transfer not pending
|
||||
powerUp(INIT_I2C);
|
||||
if (avail->dataType == DATATYPE_NFC_URL_DIRECT) {
|
||||
// only one URL (handle NDEF records on the tag)
|
||||
@@ -886,31 +1006,21 @@ bool processAvailDataInfo(struct AvailDataInfo *avail) {
|
||||
break;
|
||||
}
|
||||
case DATATYPE_COMMAND_DATA:
|
||||
printf("CMD received\n");
|
||||
|
||||
memcpy(&xferDataInfo, (void *)avail, sizeof(struct AvailDataInfo));
|
||||
if (avail->dataTypeArgument == 4) {
|
||||
Serial.println("LED CMD");
|
||||
setled(avail->dataVer, avail->dataSize);
|
||||
setled(xferDataInfo.dataVer, xferDataInfo.dataSize);
|
||||
}
|
||||
powerUp(INIT_RADIO);
|
||||
sendXferComplete();
|
||||
powerDown(INIT_RADIO);
|
||||
if (avail->dataTypeArgument != 4) {
|
||||
executeCommand(xferDataInfo.dataTypeArgument);
|
||||
}
|
||||
return true;
|
||||
break;
|
||||
case DATATYPE_CUSTOM_LUT_OTA:
|
||||
// Handle data for the NFC IC (if we have it)
|
||||
|
||||
// check if we actually have the capability to do OTA Luts
|
||||
if (!(capabilities & CAPABILITY_SUPPORTS_CUSTOM_LUTS)) {
|
||||
// looks like we don't. mark as complete and then bail!
|
||||
powerUp(INIT_RADIO);
|
||||
sendXferComplete();
|
||||
powerDown(INIT_RADIO);
|
||||
return true;
|
||||
}
|
||||
#ifdef EPD_SSD1619
|
||||
printf("OTA LUT received\n");
|
||||
if (curDataInfo.dataSize == 0 && !memcmp((const void *)&avail->dataVer, (const void *)&curDataInfo.dataVer, 8)) {
|
||||
case DATATYPE_TAG_CONFIG_DATA:
|
||||
if (xferDataInfo.dataSize == 0 && memcmp((const void *)&avail->dataVer, (const void *)&xferDataInfo.dataVer, 8) == 0) {
|
||||
printf("this was the same as the last transfer, disregard\n");
|
||||
powerUp(INIT_RADIO);
|
||||
sendXferComplete();
|
||||
@@ -918,19 +1028,20 @@ bool processAvailDataInfo(struct AvailDataInfo *avail) {
|
||||
return true;
|
||||
}
|
||||
curBlock.blockId = 0;
|
||||
memcpy(&(curBlock.ver), &(avail->dataVer), 8);
|
||||
memcpy(&(curBlock.ver), &(avail->dataVer), sizeof(curBlock.ver));
|
||||
curBlock.type = avail->dataType;
|
||||
memcpy(&curDataInfo, (void *)avail, sizeof(struct AvailDataInfo));
|
||||
memcpy(&xferDataInfo, (void *)avail, sizeof(struct AvailDataInfo));
|
||||
wdt10s();
|
||||
if (getDataBlock(avail->dataSize)) {
|
||||
curDataInfo.dataSize = 0; // mark as transfer not pending
|
||||
memcpy(customLUT, sizeof(struct blockData) + blockXferBuffer, dispLutSize * 10);
|
||||
xferDataInfo.dataSize = 0; // mark as transfer not pending
|
||||
powerUp(INIT_EEPROM);
|
||||
loadSettingsFromBuffer(sizeof(struct blockData) + blockbuffer);
|
||||
powerDown(INIT_EEPROM);
|
||||
powerUp(INIT_RADIO);
|
||||
sendXferComplete();
|
||||
powerDown(INIT_RADIO);
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
@@ -940,4 +1051,4 @@ bool processAvailDataInfo(struct AvailDataInfo *avail) {
|
||||
void initializeProto() {
|
||||
getNumSlots();
|
||||
curHighSlotId = getHighSlotId();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,747 +0,0 @@
|
||||
#include "uc8179.h"
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "font.h"
|
||||
#include "lut.h"
|
||||
#include "settings.h"
|
||||
#include "hal.h"
|
||||
#include "wdt.h"
|
||||
|
||||
#define CMD_PANEL_SETTING 0x00
|
||||
#define CMD_POWER_SETTING 0x01
|
||||
#define CMD_POWER_OFF 0x02
|
||||
#define CMD_POWER_OFF_SEQUENCE 0x03
|
||||
#define CMD_POWER_ON 0x04
|
||||
#define CMD_POWER_ON_MEASURE 0x05
|
||||
#define CMD_BOOSTER_SOFT_START 0x06
|
||||
#define CMD_DEEP_SLEEP 0x07
|
||||
#define CMD_DISPLAY_START_TRANSMISSION_DTM1 0x10
|
||||
#define CMD_DATA_STOP 0x11
|
||||
#define CMD_DISPLAY_REFRESH 0x12
|
||||
#define CMD_DISPLAY_START_TRANSMISSION_DTM2 0x13
|
||||
#define CMD_PLL_CONTROL 0x30
|
||||
#define CMD_TEMPERATURE_CALIB 0x40
|
||||
#define CMD_TEMPERATURE_SELECT 0x41
|
||||
#define CMD_TEMPERATURE_WRITE 0x42
|
||||
#define CMD_TEMPERATURE_READ 0x43
|
||||
#define CMD_VCOM_INTERVAL 0x50
|
||||
#define CMD_LOWER_POWER_DETECT 0x51
|
||||
#define CMD_TCON_SETTING 0x60
|
||||
#define CMD_RESOLUTION_SETING 0x61
|
||||
#define CMD_REVISION 0x70
|
||||
#define CMD_STATUS 0x71
|
||||
#define CMD_AUTO_MEASUREMENT_VCOM 0x80
|
||||
#define CMD_READ_VCOM 0x81
|
||||
#define CMD_VCOM_DC_SETTING 0x82
|
||||
#define CMD_PARTIAL_WINDOW 0x90
|
||||
#define CMD_PARTIAL_IN 0x91
|
||||
#define CMD_PARTIAL_OUT 0x92
|
||||
#define CMD_PROGRAM_MODE 0xA0
|
||||
#define CMD_ACTIVE_PROGRAM 0xA1
|
||||
#define CMD_READ_OTP 0xA2
|
||||
#define CMD_CASCADE_SET 0xE0
|
||||
#define CMD_POWER_SAVING 0xE3
|
||||
#define CMD_FORCE_TEMPERATURE 0xE5
|
||||
|
||||
enum PSR_FLAGS {
|
||||
RES_96x230 = 0b00000000,
|
||||
RES_96x252 = 0b01000000,
|
||||
RES_128x296 = 0b10000000,
|
||||
RES_160x296 = 0b11000000,
|
||||
|
||||
LUT_OTP = 0b00000000,
|
||||
LUT_REG = 0b00100000,
|
||||
|
||||
FORMAT_BWR = 0b00000000,
|
||||
FORMAT_BW = 0b00010000,
|
||||
|
||||
SCAN_DOWN = 0b00000000,
|
||||
SCAN_UP = 0b00001000,
|
||||
|
||||
SHIFT_LEFT = 0b00000000,
|
||||
SHIFT_RIGHT = 0b00000100,
|
||||
|
||||
BOOSTER_OFF = 0b00000000,
|
||||
BOOSTER_ON = 0b00000010,
|
||||
|
||||
RESET_SOFT = 0b00000000,
|
||||
RESET_NONE = 0b00000001
|
||||
};
|
||||
|
||||
enum PWR_FLAGS_1 {
|
||||
VDS_EXTERNAL = 0b00000000,
|
||||
VDS_INTERNAL = 0b00000010,
|
||||
|
||||
VDG_EXTERNAL = 0b00000000,
|
||||
VDG_INTERNAL = 0b00000001
|
||||
};
|
||||
|
||||
enum PWR_FLAGS_2 {
|
||||
VCOM_VD = 0b00000000,
|
||||
VCOM_VG = 0b00000100,
|
||||
|
||||
VGHL_16V = 0b00000000,
|
||||
VGHL_15V = 0b00000001,
|
||||
VGHL_14V = 0b00000010,
|
||||
VGHL_13V = 0b00000011
|
||||
};
|
||||
|
||||
enum BOOSTER_FLAGS {
|
||||
START_10MS = 0b00000000,
|
||||
START_20MS = 0b01000000,
|
||||
START_30MS = 0b10000000,
|
||||
START_40MS = 0b11000000,
|
||||
|
||||
STRENGTH_1 = 0b00000000,
|
||||
STRENGTH_2 = 0b00001000,
|
||||
STRENGTH_3 = 0b00010000,
|
||||
STRENGTH_4 = 0b00011000,
|
||||
STRENGTH_5 = 0b00100000,
|
||||
STRENGTH_6 = 0b00101000,
|
||||
STRENGTH_7 = 0b00110000,
|
||||
STRENGTH_8 = 0b00111000,
|
||||
|
||||
OFF_0_27US = 0b00000000,
|
||||
OFF_0_34US = 0b00000001,
|
||||
OFF_0_40US = 0b00000010,
|
||||
OFF_0_54US = 0b00000011,
|
||||
OFF_0_80US = 0b00000100,
|
||||
OFF_1_54US = 0b00000101,
|
||||
OFF_3_34US = 0b00000110,
|
||||
OFF_6_58US = 0b00000111
|
||||
};
|
||||
|
||||
enum PFS_FLAGS {
|
||||
FRAMES_1 = 0b00000000,
|
||||
FRAMES_2 = 0b00010000,
|
||||
FRAMES_3 = 0b00100000,
|
||||
FRAMES_4 = 0b00110000
|
||||
};
|
||||
|
||||
enum TSE_FLAGS {
|
||||
TEMP_INTERNAL = 0b00000000,
|
||||
TEMP_EXTERNAL = 0b10000000,
|
||||
|
||||
OFFSET_0 = 0b00000000,
|
||||
OFFSET_1 = 0b00000001,
|
||||
OFFSET_2 = 0b00000010,
|
||||
OFFSET_3 = 0b00000011,
|
||||
OFFSET_4 = 0b00000100,
|
||||
OFFSET_5 = 0b00000101,
|
||||
OFFSET_6 = 0b00000110,
|
||||
OFFSET_7 = 0b00000111,
|
||||
|
||||
OFFSET_MIN_8 = 0b00001000,
|
||||
OFFSET_MIN_7 = 0b00001001,
|
||||
OFFSET_MIN_6 = 0b00001010,
|
||||
OFFSET_MIN_5 = 0b00001011,
|
||||
OFFSET_MIN_4 = 0b00001100,
|
||||
OFFSET_MIN_3 = 0b00001101,
|
||||
OFFSET_MIN_2 = 0b00001110,
|
||||
OFFSET_MIN_1 = 0b00001111
|
||||
};
|
||||
|
||||
enum PLL_FLAGS {
|
||||
// other frequency options exist but there doesn't seem to be much
|
||||
// point in including them - this is a fair range of options...
|
||||
HZ_29 = 0b00111111,
|
||||
HZ_33 = 0b00111110,
|
||||
HZ_40 = 0b00111101,
|
||||
HZ_50 = 0b00111100,
|
||||
HZ_67 = 0b00111011,
|
||||
HZ_100 = 0b00111010,
|
||||
HZ_200 = 0b00111001
|
||||
};
|
||||
|
||||
#define commandEnd() \
|
||||
do { \
|
||||
digitalWrite(EPD_CS, HIGH); \
|
||||
} while (0)
|
||||
|
||||
#define markCommand() \
|
||||
do { \
|
||||
digitalWrite(EPD_DC, LOW); \
|
||||
} while (0)
|
||||
|
||||
#define markData() \
|
||||
do { \
|
||||
digitalWrite(EPD_DC, HIGH); \
|
||||
} while (0)
|
||||
|
||||
extern void dump(uint8_t *a, uint16_t l); // remove me when done
|
||||
|
||||
static uint8_t epdCharSize = 1; // character size, 1 or 2 (doubled)
|
||||
static bool directionY = true; // print direction, X or Y (true)
|
||||
static uint8_t rbuffer[32]; // used to rotate bits around
|
||||
static uint16_t fontCurXpos = 0; // current X value we're working with
|
||||
static uint16_t fontCurYpos = 0; // current Y value we're working with
|
||||
static uint8_t currentLut = 0;
|
||||
static uint8_t dispLutSize = 0;
|
||||
static bool drawDirection = false;
|
||||
static bool isInited = false;
|
||||
|
||||
bool epdGPIOActive = false;
|
||||
|
||||
#define LUT_BUFFER_SIZE 128
|
||||
uint8_t waveformbuffer[LUT_BUFFER_SIZE];
|
||||
struct waveform10 *waveform10 = (struct waveform10 *)waveformbuffer; // holds the LUT/waveform
|
||||
struct waveform *waveform7 = (struct waveform *)waveformbuffer; // holds the LUT/waveform
|
||||
|
||||
static void epdBusySleep(uint32_t timeout) {
|
||||
epdBusyWaitFalling(timeout);
|
||||
}
|
||||
static void commandReadBegin(uint8_t cmd) {
|
||||
epdSelect();
|
||||
markCommand();
|
||||
spi_write(cmd); // dump LUT
|
||||
pinMode(EPD_MOSI, INPUT);
|
||||
markData();
|
||||
}
|
||||
static void commandReadEnd() {
|
||||
// set up pins for spi (0.0,0.1,0.2)
|
||||
pinMode(EPD_MOSI, OUTPUT);
|
||||
epdDeselect();
|
||||
}
|
||||
static uint8_t epdReadByte() {
|
||||
uint8_t val = 0, i;
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
digitalWrite(EPD_CLK, HIGH);
|
||||
delayMicroseconds(1);
|
||||
val <<= 1;
|
||||
if (digitalRead(EPD_MOSI))
|
||||
val++;
|
||||
digitalWrite(EPD_CLK, LOW);
|
||||
delayMicroseconds(1);
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
static void shortCommand(uint8_t cmd) {
|
||||
epdSelect();
|
||||
markCommand();
|
||||
spi_write(cmd);
|
||||
epdDeselect();
|
||||
}
|
||||
static void shortCommand1(uint8_t cmd, uint8_t arg) {
|
||||
epdSelect();
|
||||
markCommand();
|
||||
spi_write(cmd);
|
||||
markData();
|
||||
spi_write(arg);
|
||||
epdDeselect();
|
||||
}
|
||||
static void shortCommand2(uint8_t cmd, uint8_t arg1, uint8_t arg2) {
|
||||
epdSelect();
|
||||
markCommand();
|
||||
spi_write(cmd);
|
||||
markData();
|
||||
spi_write(arg1);
|
||||
spi_write(arg2);
|
||||
epdDeselect();
|
||||
}
|
||||
static void commandBegin(uint8_t cmd) {
|
||||
epdSelect();
|
||||
markCommand();
|
||||
spi_write(cmd);
|
||||
markData();
|
||||
}
|
||||
static void epdReset() {
|
||||
digitalWrite(EPD_RST, HIGH);
|
||||
delay(12);
|
||||
digitalWrite(EPD_RST, LOW);
|
||||
delay(20);
|
||||
digitalWrite(EPD_RST, HIGH);
|
||||
delay(20);
|
||||
}
|
||||
void epdConfigGPIO(bool setup) {
|
||||
if (epdGPIOActive == setup)
|
||||
return;
|
||||
if (setup) {
|
||||
pinMode(EPD_POWER, OUTPUT);
|
||||
digitalWrite(EPD_POWER, HIGH);
|
||||
pinMode(EPD_RST, OUTPUT);
|
||||
pinMode(EPD_BS, OUTPUT);
|
||||
pinMode(EPD_CS, OUTPUT);
|
||||
pinMode(EPD_DC, OUTPUT);
|
||||
pinMode(EPD_BUSY, INPUT);
|
||||
pinMode(EPD_CLK, OUTPUT);
|
||||
pinMode(EPD_MOSI, OUTPUT);
|
||||
} else {
|
||||
digitalWrite(EPD_POWER, LOW);
|
||||
pinMode(EPD_POWER, DEFAULT);
|
||||
}
|
||||
epdGPIOActive = setup;
|
||||
}
|
||||
void epdEnterSleep() {
|
||||
shortCommand1(CMD_VCOM_INTERVAL, 0x17);
|
||||
shortCommand1(CMD_VCOM_DC_SETTING, 0x00);
|
||||
// shortCommand(CMD_POWER_OFF);
|
||||
// epdWaitRdy();
|
||||
shortCommand1(CMD_DEEP_SLEEP, 0xA5);
|
||||
isInited = false;
|
||||
}
|
||||
|
||||
static void epdDrawDirection(bool direction) {
|
||||
if (direction == drawDirection)
|
||||
return;
|
||||
|
||||
drawDirection = direction;
|
||||
|
||||
uint8_t psr_setting = RES_160x296 | FORMAT_BWR | BOOSTER_ON | RESET_NONE | LUT_OTP | SHIFT_RIGHT;
|
||||
if (drawDirection) {
|
||||
psr_setting |= SCAN_DOWN;
|
||||
} else {
|
||||
psr_setting |= SCAN_UP;
|
||||
}
|
||||
shortCommand2(CMD_PANEL_SETTING, psr_setting, 0);
|
||||
}
|
||||
|
||||
void epdSetup() {
|
||||
epdReset();
|
||||
|
||||
drawDirection = false;
|
||||
epdDrawDirection(true);
|
||||
|
||||
shortCommand2(CMD_VCOM_INTERVAL, 0x30, 0x07);
|
||||
|
||||
commandBegin(CMD_RESOLUTION_SETING);
|
||||
epdSend(SCREEN_WIDTH >> 8);
|
||||
epdSend(SCREEN_WIDTH & 0xFF);
|
||||
epdSend(SCREEN_HEIGHT >> 8);
|
||||
epdSend(SCREEN_HEIGHT & 0xFF);
|
||||
commandEnd();
|
||||
|
||||
/* commandBegin(CMD_POWER_SETTING);
|
||||
epdSend(VDS_INTERNAL | VDG_INTERNAL);
|
||||
epdSend(VCOM_VD | VGHL_16V);
|
||||
epdSend(0b101011);
|
||||
epdSend(0b101011);
|
||||
epdSend(0b101011);
|
||||
commandEnd();
|
||||
|
||||
shortCommand(CMD_POWER_ON);
|
||||
epdWaitRdy();
|
||||
|
||||
commandBegin(CMD_BOOSTER_SOFT_START);
|
||||
epdSend(START_10MS | STRENGTH_3 | OFF_6_58US);
|
||||
epdSend(START_10MS | STRENGTH_3 | OFF_6_58US);
|
||||
epdSend(START_10MS | STRENGTH_3 | OFF_6_58US);
|
||||
commandEnd();
|
||||
|
||||
commandBegin(CMD_RESOLUTION_SETING);
|
||||
epdSend(SCREEN_WIDTH >> 8);
|
||||
epdSend(SCREEN_WIDTH & 0xFF);
|
||||
epdSend(SCREEN_HEIGHT >> 8);
|
||||
epdSend(SCREEN_HEIGHT & 0xFF);
|
||||
commandEnd();
|
||||
|
||||
shortCommand1(CMD_POWER_OFF_SEQUENCE, FRAMES_1);
|
||||
shortCommand1(CMD_TEMPERATURE_SELECT, TEMP_INTERNAL | OFFSET_0);
|
||||
shortCommand1(CMD_TCON_SETTING, 0x22);
|
||||
shortCommand1(CMD_VCOM_INTERVAL, 0x8d); // 0x87
|
||||
shortCommand1(CMD_PLL_CONTROL, HZ_200);
|
||||
epdWaitRdy();*/
|
||||
shortCommand(CMD_POWER_ON);
|
||||
epdWaitRdy();
|
||||
}
|
||||
static uint8_t epdGetStatus() {
|
||||
uint8_t sta;
|
||||
commandReadBegin(0x2F);
|
||||
sta = epdReadByte();
|
||||
commandReadEnd();
|
||||
return sta;
|
||||
}
|
||||
uint16_t epdGetBattery(void) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void readLut() {
|
||||
commandReadBegin(0x33);
|
||||
uint16_t checksum = 0;
|
||||
uint16_t ident = 0;
|
||||
uint16_t shortl = 0;
|
||||
for (uint16_t c = 0; c < LUT_BUFFER_SIZE; c++) {
|
||||
waveformbuffer[c] = epdReadByte();
|
||||
}
|
||||
commandReadEnd();
|
||||
}
|
||||
static uint8_t getLutSize() {
|
||||
uint8_t ref = 0;
|
||||
for (uint8_t c = (LUT_BUFFER_SIZE - 4); c > 16; c--) {
|
||||
uint8_t check = waveformbuffer[c];
|
||||
for (uint8_t d = 1; d < 4; d++) {
|
||||
if (waveformbuffer[c + d] != check) {
|
||||
ref = c;
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
}
|
||||
end:;
|
||||
return ref + 1;
|
||||
}
|
||||
static void lutGroupDisable(uint8_t group) {
|
||||
if (dispLutSize == 7) {
|
||||
memset(&(waveform7->group[group]), 0x00, 5);
|
||||
} else {
|
||||
memset(&(waveform10->group[group]), 0x00, 5);
|
||||
}
|
||||
}
|
||||
static void lutGroupSpeedup(uint8_t group, uint8_t speed) {
|
||||
if (dispLutSize == 7) {
|
||||
for (uint8_t i = 0; i < 4; i++) {
|
||||
waveform7->group[group].phaselength[i] = 1 + (waveform7->group[group].phaselength[i] / speed);
|
||||
}
|
||||
} else {
|
||||
for (uint8_t i = 0; i < 4; i++) {
|
||||
waveform10->group[group].phaselength[i] = 1 + (waveform10->group[group].phaselength[i] / speed);
|
||||
}
|
||||
}
|
||||
}
|
||||
static void lutGroupRepeat(uint8_t group, uint8_t repeat) {
|
||||
if (dispLutSize == 7) {
|
||||
waveform7->group[group].repeat = repeat;
|
||||
} else {
|
||||
waveform10->group[group].repeat = repeat;
|
||||
}
|
||||
}
|
||||
static void lutGroupRepeatReduce(uint8_t group, uint8_t factor) {
|
||||
if (dispLutSize == 7) {
|
||||
waveform7->group[group].repeat = waveform7->group[group].repeat / factor;
|
||||
} else {
|
||||
waveform10->group[group].repeat = waveform10->group[group].repeat / factor;
|
||||
}
|
||||
}
|
||||
void selectLUT(uint8_t lut) {
|
||||
// implement alternative LUTs here. Currently just reset the watchdog to two minutes,
|
||||
// to ensure it doesn't reset during the much longer bootup procedure
|
||||
lut += 1; // make the compiler a happy camper
|
||||
wdt120s();
|
||||
return;
|
||||
}
|
||||
|
||||
void setWindowXY(uint16_t xstart, uint16_t xend, uint16_t ystart, uint16_t yend) {
|
||||
shortCommand(CMD_PARTIAL_IN);
|
||||
commandBegin(CMD_PARTIAL_WINDOW);
|
||||
epdSend(xstart >> 8);
|
||||
epdSend(xstart & 0xFF);
|
||||
epdSend((xend - 1) >> 8);
|
||||
epdSend((xend - 1) & 0xff);
|
||||
epdSend(ystart >> 8);
|
||||
epdSend(ystart & 0xFF);
|
||||
epdSend((yend - 1) >> 8);
|
||||
epdSend((yend - 1) & 0xff);
|
||||
epdSend(0x01);
|
||||
commandEnd();
|
||||
}
|
||||
|
||||
void setColorMode(uint8_t red, uint8_t bw) {
|
||||
// this does exactly nothing, just keeps the compiler from barking
|
||||
red = 1;
|
||||
bw = 0;
|
||||
return;
|
||||
}
|
||||
void clearScreen() {
|
||||
shortCommand(CMD_PARTIAL_OUT);
|
||||
commandBegin(CMD_DISPLAY_START_TRANSMISSION_DTM2);
|
||||
for (uint16_t c = 0; c < ((1UL * SCREEN_HEIGHT * SCREEN_WIDTH) / 8); c++) {
|
||||
epdSend(0x00);
|
||||
}
|
||||
commandEnd();
|
||||
epdWaitRdy();
|
||||
commandBegin(CMD_DISPLAY_START_TRANSMISSION_DTM1);
|
||||
for (uint16_t c = 0; c < ((1UL * SCREEN_HEIGHT * SCREEN_WIDTH) / 8); c++) {
|
||||
epdSend(0x00);
|
||||
}
|
||||
commandEnd();
|
||||
}
|
||||
void draw() {
|
||||
shortCommand(CMD_DISPLAY_REFRESH);
|
||||
epdWaitRdy();
|
||||
}
|
||||
void drawNoWait() {
|
||||
shortCommand(CMD_DISPLAY_REFRESH);
|
||||
}
|
||||
void drawWithSleep() {
|
||||
shortCommand(CMD_DISPLAY_REFRESH);
|
||||
epdBusyWaitFalling(120000);
|
||||
}
|
||||
void epdWaitRdy() {
|
||||
epdBusyWaitFalling(120000);
|
||||
}
|
||||
void beginFullscreenImage() {
|
||||
shortCommand(CMD_PARTIAL_OUT);
|
||||
epdDrawDirection(false);
|
||||
// shortCommand1(CMD_DATA_ENTRY_MODE, 3);
|
||||
// setPosXY(0, 0);
|
||||
}
|
||||
void beginWriteFramebuffer(bool color) {
|
||||
if (color == EPD_COLOR_RED) {
|
||||
commandBegin(CMD_DISPLAY_START_TRANSMISSION_DTM2);
|
||||
} else {
|
||||
commandBegin(CMD_DISPLAY_START_TRANSMISSION_DTM1);
|
||||
}
|
||||
epdDeselect();
|
||||
}
|
||||
void endWriteFramebuffer() {
|
||||
commandEnd();
|
||||
}
|
||||
|
||||
void loadRawBitmap(uint8_t *bmp, uint16_t x, uint16_t y, bool color) {
|
||||
// this function is very badly hurt by the switch to UC8151, taking up LOTS of valuable idata space. Only defining variables
|
||||
// as static, or the function as reentrant (relegating variables to the stack) seemed to fix the idata issue. Fix me, or put me out of my misery...
|
||||
|
||||
uint16_t xsize = bmp[0] / 8;
|
||||
if (bmp[0] % 8)
|
||||
xsize++;
|
||||
uint16_t ysize = bmp[1];
|
||||
uint16_t size = xsize * bmp[1];
|
||||
|
||||
// shortCommand1(CMD_DATA_ENTRY_MODE, 3);
|
||||
|
||||
bmp += 2;
|
||||
|
||||
uint16_t c = 0;
|
||||
uint16_t curY = y;
|
||||
while (1) {
|
||||
if (c % xsize == 0) {
|
||||
commandEnd();
|
||||
if (drawDirection) {
|
||||
setWindowXY(x, x + xsize * 8, SCREEN_HEIGHT - curY - 1, SCREEN_HEIGHT - curY);
|
||||
} else {
|
||||
setWindowXY(x, x + xsize * 8, curY - 1, curY);
|
||||
}
|
||||
curY++;
|
||||
if (color) {
|
||||
commandBegin(CMD_DISPLAY_START_TRANSMISSION_DTM2);
|
||||
} else {
|
||||
commandBegin(CMD_DISPLAY_START_TRANSMISSION_DTM1);
|
||||
}
|
||||
}
|
||||
epdSend(*(bmp++));
|
||||
c++;
|
||||
if (!size--)
|
||||
break;
|
||||
}
|
||||
commandEnd();
|
||||
shortCommand(CMD_PARTIAL_OUT);
|
||||
}
|
||||
void printBarcode(const uint8_t *string, uint16_t x, uint16_t y) {
|
||||
}
|
||||
// stuff for printing text
|
||||
static void pushXFontBytesToEPD(uint8_t byte1, uint8_t byte2) {
|
||||
if (epdCharSize == 1) {
|
||||
uint8_t offset = 7 - (fontCurXpos % 8);
|
||||
for (uint8_t c = 0; c < 8; c++) {
|
||||
if (byte2 & (1 << (7 - c)))
|
||||
rbuffer[c] |= (1 << offset);
|
||||
}
|
||||
for (uint8_t c = 0; c < 8; c++) {
|
||||
if (byte1 & (1 << (7 - c)))
|
||||
rbuffer[8 + c] |= (1 << offset);
|
||||
}
|
||||
fontCurXpos++;
|
||||
} else {
|
||||
uint8_t offset = 6 - (fontCurXpos % 8);
|
||||
// double font size
|
||||
for (uint8_t c = 0; c < 8; c++) {
|
||||
if (byte2 & (1 << (7 - c))) {
|
||||
rbuffer[c * 2] |= (3 << offset);
|
||||
rbuffer[(c * 2) + 1] |= (3 << offset);
|
||||
}
|
||||
}
|
||||
for (uint8_t c = 0; c < 8; c++) {
|
||||
if (byte1 & (1 << (7 - c))) {
|
||||
rbuffer[(c * 2) + 16] |= (3 << offset);
|
||||
rbuffer[(c * 2) + 17] |= (3 << offset);
|
||||
}
|
||||
}
|
||||
fontCurXpos += 2;
|
||||
}
|
||||
if (fontCurXpos % 8 == 0) {
|
||||
// next byte, flush current byte to EPD
|
||||
for (uint8_t i = 0; i < (16 * epdCharSize); i++) {
|
||||
epdSend(rbuffer[i]);
|
||||
}
|
||||
memset(rbuffer, 0, 32);
|
||||
}
|
||||
}
|
||||
static void bufferByteShift(uint8_t byte) {
|
||||
/*
|
||||
rbuffer[0] = 0; // previous value
|
||||
rbuffer[1] = y%8; // offset
|
||||
rbuffer[2] = 0; // current byte counter;
|
||||
rbuffer[3] = 1+(epdCharsize*2);
|
||||
*/
|
||||
|
||||
if (rbuffer[1] == 0) {
|
||||
epdSend(byte);
|
||||
} else {
|
||||
uint8_t offset = rbuffer[1];
|
||||
rbuffer[0] |= (byte >> offset);
|
||||
epdSend(rbuffer[0]);
|
||||
// epdSend(byte);
|
||||
rbuffer[0] = (byte << (8 - offset));
|
||||
rbuffer[2]++;
|
||||
if (rbuffer[2] == rbuffer[3]) {
|
||||
epdSend(rbuffer[0]);
|
||||
rbuffer[0] = 0;
|
||||
rbuffer[2] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
static void pushYFontBytesToEPD(uint8_t byte1, uint8_t byte2) {
|
||||
if (epdCharSize == 2) {
|
||||
for (uint8_t j = 0; j < 2; j++) {
|
||||
uint8_t c = 0;
|
||||
for (uint8_t i = 7; i != 255; i--) {
|
||||
if (byte1 & (1 << i))
|
||||
c |= (0x03 << ((i % 4) * 2));
|
||||
if ((i % 4) == 0) {
|
||||
bufferByteShift(c);
|
||||
c = 0;
|
||||
}
|
||||
}
|
||||
for (uint8_t i = 7; i != 255; i--) {
|
||||
if (byte2 & (1 << i))
|
||||
c |= (0x03 << ((i % 4) * 2));
|
||||
if ((i % 4) == 0) {
|
||||
bufferByteShift(c);
|
||||
c = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
bufferByteShift(byte1);
|
||||
bufferByteShift(byte2);
|
||||
}
|
||||
}
|
||||
void writeCharEPD(uint8_t c) {
|
||||
// Writes a single character to the framebuffer
|
||||
bool empty = true;
|
||||
for (uint8_t i = 0; i < 20; i++) {
|
||||
if (font[c][i])
|
||||
empty = false;
|
||||
}
|
||||
if (empty) {
|
||||
for (uint8_t i = 0; i < 8; i++) {
|
||||
if (directionY) {
|
||||
pushYFontBytesToEPD(0x00, 0x00);
|
||||
} else {
|
||||
pushXFontBytesToEPD(0x00, 0x00);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t begin = 0;
|
||||
while (font[c][begin] == 0x00 && font[c][begin + 1] == 0x00) {
|
||||
begin += 2;
|
||||
}
|
||||
|
||||
uint8_t end = 20;
|
||||
while (font[c][end - 1] == 0x00 && font[c][end - 2] == 0x00) {
|
||||
end -= 2;
|
||||
}
|
||||
|
||||
for (uint8_t pos = begin; pos < end; pos += 2) {
|
||||
if (directionY) {
|
||||
pushYFontBytesToEPD(font[c][pos + 1], font[c][pos]);
|
||||
} else {
|
||||
pushXFontBytesToEPD(font[c][pos], font[c][pos + 1]);
|
||||
}
|
||||
}
|
||||
|
||||
// spacing between characters
|
||||
if (directionY) {
|
||||
pushYFontBytesToEPD(0x00, 0x00);
|
||||
} else {
|
||||
pushXFontBytesToEPD(0x00, 0x00);
|
||||
}
|
||||
}
|
||||
|
||||
// Print text to the EPD. Origin is top-left
|
||||
void epdPrintBegin(uint16_t x, uint16_t y, bool direction, bool fontsize, bool color) {
|
||||
directionY = direction;
|
||||
epdCharSize = 1 + fontsize;
|
||||
if (directionY) {
|
||||
uint8_t extra = 0;
|
||||
|
||||
// provisions for dealing with font in Y direction, byte-unaligned
|
||||
if (x % 8) {
|
||||
extra = 8;
|
||||
rbuffer[0] = 0; // previous value
|
||||
rbuffer[1] = x % 8; // offset
|
||||
rbuffer[2] = 0; // current byte counter;
|
||||
rbuffer[3] = (epdCharSize * 2);
|
||||
} else {
|
||||
rbuffer[1] = 0;
|
||||
}
|
||||
|
||||
// setWindowY(y, 1);
|
||||
if (epdCharSize == 2) {
|
||||
setWindowXY(x, x + 32 + extra, SCREEN_HEIGHT - y, SCREEN_HEIGHT);
|
||||
// setPosXY(x, y);
|
||||
} else {
|
||||
setWindowXY(x, x + 16 + extra, SCREEN_HEIGHT - y, SCREEN_HEIGHT);
|
||||
// setPosXY(x, y);
|
||||
}
|
||||
// shortCommand1(CMD_DATA_ENTRY_MODE, 1); // was 3
|
||||
} else {
|
||||
if (epdCharSize == 2) {
|
||||
x /= 2;
|
||||
x *= 2;
|
||||
setWindowXY(x, SCREEN_WIDTH, y, y + 32);
|
||||
} else {
|
||||
setWindowXY(x, SCREEN_WIDTH, y, y + 16);
|
||||
}
|
||||
// setPosXY(x, y);
|
||||
fontCurXpos = x;
|
||||
// setWindowXY(x, SCREEN_WIDTH);
|
||||
// shortCommand1(CMD_DATA_ENTRY_MODE, 7);
|
||||
memset(rbuffer, 0, 32);
|
||||
}
|
||||
|
||||
if (color) {
|
||||
commandBegin(CMD_DISPLAY_START_TRANSMISSION_DTM2);
|
||||
} else {
|
||||
commandBegin(CMD_DISPLAY_START_TRANSMISSION_DTM1);
|
||||
}
|
||||
}
|
||||
void epdPrintEnd() {
|
||||
if (!directionY && ((fontCurXpos % 8) != 0)) {
|
||||
for (uint8_t i = 0; i < (16 * epdCharSize); i++) {
|
||||
epdSend(rbuffer[i]);
|
||||
}
|
||||
}
|
||||
commandEnd();
|
||||
shortCommand(CMD_PARTIAL_OUT);
|
||||
epdDrawDirection(true);
|
||||
}
|
||||
|
||||
extern uint8_t blockXferBuffer[];
|
||||
|
||||
static void epdPutchar(uint8_t data) {
|
||||
writeCharEPD(data);
|
||||
}
|
||||
|
||||
void epdpr(const char *c, ...) {
|
||||
char out_buffer[512]; // you can define your own buffer’s size
|
||||
|
||||
va_list lst;
|
||||
va_start(lst, c);
|
||||
vsprintf(out_buffer, c, lst);
|
||||
va_end(lst);
|
||||
|
||||
int posi = 0;
|
||||
while (out_buffer[posi] != 0) {
|
||||
epdPutchar(out_buffer[posi]);
|
||||
posi++;
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -2,3 +2,7 @@ build
|
||||
*.axf
|
||||
# Allow
|
||||
!*.bin
|
||||
|
||||
.vscode
|
||||
sdkconfig
|
||||
sdkconfig.old
|
||||
|
||||
28
ARM_Tag_FW/OpenEPaperLink_esp32_C6_AP/main/Kconfig.projbuild
Normal file
28
ARM_Tag_FW/OpenEPaperLink_esp32_C6_AP/main/Kconfig.projbuild
Normal file
@@ -0,0 +1,28 @@
|
||||
menu "OEPL Hardware config"
|
||||
|
||||
choice OEPL_HARDWARE_PROFILE
|
||||
prompt "Hardware profile"
|
||||
default OEPL_HARDWARE_PROFILE_DEFAULT
|
||||
|
||||
config OEPL_HARDWARE_PROFILE_DEFAULT
|
||||
bool "Default"
|
||||
|
||||
config OEPL_HARDWARE_PROFILE_POE_AP
|
||||
bool "PoE-AP"
|
||||
|
||||
config OEPL_HARDWARE_PROFILE_CUSTOM
|
||||
bool "Custom"
|
||||
|
||||
endchoice
|
||||
|
||||
config OEPL_HARDWARE_UART_TX
|
||||
depends on OEPL_HARDWARE_PROFILE_CUSTOM
|
||||
int "GPIO - UART TX"
|
||||
default 3
|
||||
|
||||
config OEPL_HARDWARE_UART_RX
|
||||
depends on OEPL_HARDWARE_PROFILE_CUSTOM
|
||||
int "GPIO - UART RX"
|
||||
default 2
|
||||
|
||||
endmenu
|
||||
@@ -40,7 +40,7 @@ const uint8_t channelList[6] = {11, 15, 20, 25, 26, 27};
|
||||
struct pendingData pendingDataArr[MAX_PENDING_MACS];
|
||||
|
||||
// VERSION GOES HERE!
|
||||
uint16_t version = 0x0018;
|
||||
uint16_t version = 0x0019;
|
||||
|
||||
#define RAW_PKT_PADDING 2
|
||||
|
||||
@@ -64,8 +64,9 @@ uint8_t lastAckMac[8] = {0};
|
||||
#define CONCURRENT_REQUEST_DELAY 1200UL
|
||||
uint32_t lastBlockRequest = 0;
|
||||
uint8_t lastBlockMac[8];
|
||||
uint8_t lastTagReturn[8];
|
||||
|
||||
uint8_t curChannel = 11;
|
||||
uint8_t curChannel = 25;
|
||||
uint8_t curPower = 10;
|
||||
|
||||
uint8_t curPendingData = 0;
|
||||
@@ -325,12 +326,14 @@ void processSerial(uint8_t lastchar) {
|
||||
}
|
||||
goto SCPfailed;
|
||||
SCPchannelFound:
|
||||
curChannel = scp->channel;
|
||||
pr("ACK>");
|
||||
if (curChannel != scp->channel) {
|
||||
radioSetChannel(scp->channel);
|
||||
curChannel = scp->channel;
|
||||
}
|
||||
curPower = scp->power;
|
||||
radioSetChannel(scp->channel);
|
||||
radioSetTxPower(scp->power);
|
||||
ESP_LOGI(TAG, "Set channel: %d power: %d", curChannel, curPower);
|
||||
pr("ACK>");
|
||||
} else {
|
||||
SCPfailed:
|
||||
pr("NOK>");
|
||||
@@ -408,6 +411,30 @@ void espNotifyAPInfo() {
|
||||
pr("NOP>%02X", curNoUpdate);
|
||||
}
|
||||
|
||||
void espNotifyTagReturnData(uint8_t *src, uint8_t len) {
|
||||
struct tagReturnData *trd = (struct tagReturnData *)(radiorxbuffer + sizeof(struct MacFrameBcast) + 1); // oh how I'd love to pass this as an argument, but sdcc won't let me
|
||||
struct espTagReturnData *etrd = (struct espTagReturnData *)radiotxbuffer;
|
||||
|
||||
if (memcmp((void *) & trd->dataVer, lastTagReturn, 8) == 0) {
|
||||
return;
|
||||
} else {
|
||||
memcpy(lastTagReturn, &trd->dataVer, 8);
|
||||
}
|
||||
|
||||
memcpy(etrd->src, src, 8);
|
||||
etrd->len = len;
|
||||
memcpy(&etrd->returnData, trd, len);
|
||||
addCRC(etrd, len + 10);
|
||||
|
||||
uartTx('T');
|
||||
uartTx('R');
|
||||
uartTx('D');
|
||||
uartTx('>');
|
||||
for (uint8_t c = 0; c < len + 10; c++) {
|
||||
uartTx(((uint8_t *)etrd)[c]);
|
||||
}
|
||||
}
|
||||
|
||||
// process data from tag
|
||||
void processBlockRequest(const uint8_t *buffer, uint8_t forceBlockDownload) {
|
||||
struct MacFrameNormal *rxHeader = (struct MacFrameNormal *) buffer;
|
||||
@@ -465,7 +492,7 @@ void processBlockRequest(const uint8_t *buffer, uint8_t forceBlockDownload) {
|
||||
if (blockStartTimer == 0) {
|
||||
if (requestDataDownload) {
|
||||
if (highspeedSerial == true) {
|
||||
blockRequestAck->pleaseWaitMs = 220;
|
||||
blockRequestAck->pleaseWaitMs = 140;
|
||||
} else {
|
||||
blockRequestAck->pleaseWaitMs = 550;
|
||||
}
|
||||
@@ -555,6 +582,26 @@ void processXferComplete(uint8_t *buffer) {
|
||||
}
|
||||
}
|
||||
|
||||
void processTagReturnData(uint8_t *buffer, uint8_t len) {
|
||||
struct MacFrameBcast *rxframe = (struct MacFrameBcast *)buffer;
|
||||
struct MacFrameNormal *frameHeader = (struct MacFrameNormal *)(radiotxbuffer + 1);
|
||||
|
||||
if (!checkCRC((buffer + sizeof(struct MacFrameBcast) + 1), len - (sizeof(struct MacFrameBcast) + 1))) {
|
||||
return;
|
||||
}
|
||||
radiotxbuffer[sizeof(struct MacFrameNormal) + 1] = PKT_TAG_RETURN_DATA_ACK;
|
||||
radiotxbuffer[0] = sizeof(struct MacFrameNormal) + 1 + RAW_PKT_PADDING;
|
||||
memcpy(frameHeader->src, mSelfMac, 8);
|
||||
memcpy(frameHeader->dst, rxframe->src, 8);
|
||||
radiotxbuffer[1] = 0x41; // fast way to set the appropriate bits
|
||||
radiotxbuffer[2] = 0xCC; // normal frame
|
||||
frameHeader->seq = seq++;
|
||||
frameHeader->pan = rxframe->srcPan;
|
||||
radioTx(radiotxbuffer);
|
||||
|
||||
espNotifyTagReturnData(rxframe->src, len - (sizeof(struct MacFrameBcast) + 1));
|
||||
}
|
||||
|
||||
// send block data to the tag
|
||||
void sendPart(uint8_t partNo) {
|
||||
struct MacFrameNormal *frameHeader = (struct MacFrameNormal *) (radiotxbuffer + 1);
|
||||
@@ -581,6 +628,18 @@ void sendBlockData() {
|
||||
pr("Invalid block request received, 0 parts..\n");
|
||||
requestedData.requestedParts[0] |= 0x01;
|
||||
}
|
||||
|
||||
pr("Sending parts:");
|
||||
for (uint8_t c = 0; (c < BLOCK_MAX_PARTS); c++) {
|
||||
if (c % 10 == 0) pr(" ");
|
||||
if (requestedData.requestedParts[c / 8] & (1 << (c % 8))) {
|
||||
pr("X");
|
||||
} else {
|
||||
pr(".");
|
||||
}
|
||||
}
|
||||
pr("\n");
|
||||
|
||||
uint8_t partNo = 0;
|
||||
while (partNo < BLOCK_MAX_PARTS) {
|
||||
for (uint8_t c = 0; (c < BLOCK_MAX_PARTS) && (partNo < BLOCK_MAX_PARTS); c++) {
|
||||
@@ -637,23 +696,22 @@ void sendPong(void *buf) {
|
||||
}
|
||||
|
||||
void app_main(void) {
|
||||
esp_event_loop_create_default();
|
||||
|
||||
init_nvs();
|
||||
init_led();
|
||||
init_second_uart();
|
||||
|
||||
esp_event_loop_create_default();
|
||||
|
||||
radio_init();
|
||||
|
||||
requestedData.blockId = 0xFF;
|
||||
// clear the array with pending information
|
||||
memset(pendingDataArr, 0, sizeof(pendingDataArr));
|
||||
|
||||
radioSetChannel(curChannel);
|
||||
radio_init(curChannel);
|
||||
radioSetTxPower(10);
|
||||
|
||||
pr("RES>");
|
||||
pr("RDY>");
|
||||
ESP_LOGI(TAG, "C6 ready!");
|
||||
|
||||
housekeepingTimer = getMillis();
|
||||
while (1) {
|
||||
@@ -695,6 +753,9 @@ void app_main(void) {
|
||||
processAvailDataReq(radiorxbuffer);
|
||||
}
|
||||
break;
|
||||
case PKT_TAG_RETURN_DATA:
|
||||
processTagReturnData(radiorxbuffer, ret);
|
||||
break;
|
||||
default:
|
||||
ESP_LOGI(TAG, "t=%02X" , getPacketType(radiorxbuffer));
|
||||
break;
|
||||
@@ -714,6 +775,7 @@ void app_main(void) {
|
||||
}
|
||||
}
|
||||
|
||||
memset(&lastTagReturn, 0, 8);
|
||||
for (uint8_t cCount = 0; cCount < MAX_PENDING_MACS; cCount++) {
|
||||
if (pendingDataArr[cCount].attemptsLeft == 1) {
|
||||
if (pendingDataArr[cCount].availdatainfo.dataType != DATATYPE_NOUPDATE) {
|
||||
|
||||
@@ -58,6 +58,8 @@ struct MacFrameBcast {
|
||||
uint8_t src[8];
|
||||
} __attribute__((packed, aligned(1)));
|
||||
|
||||
#define PKT_TAG_RETURN_DATA 0xE1
|
||||
#define PKT_TAG_RETURN_DATA_ACK 0xE2
|
||||
#define PKT_AVAIL_DATA_SHORTREQ 0xE3
|
||||
#define PKT_AVAIL_DATA_REQ 0xE5
|
||||
#define PKT_AVAIL_DATA_INFO 0xE6
|
||||
@@ -125,9 +127,14 @@ struct blockData {
|
||||
uint8_t data[];
|
||||
} __attribute__((packed, aligned(1)));
|
||||
|
||||
struct burstMacData {
|
||||
uint16_t offset;
|
||||
uint8_t targetMac[8];
|
||||
#define TAG_RETURN_DATA_SIZE 90
|
||||
|
||||
struct tagReturnData {
|
||||
uint8_t checksum;
|
||||
uint8_t partId;
|
||||
uint64_t dataVer;
|
||||
uint8_t dataType;
|
||||
uint8_t data[TAG_RETURN_DATA_SIZE];
|
||||
} __attribute__((packed, aligned(1)));
|
||||
|
||||
#define BLOCK_PART_DATA_SIZE 99
|
||||
@@ -173,4 +180,11 @@ struct espSetChannelPower {
|
||||
uint8_t power;
|
||||
} __attribute__((packed, aligned(1)));
|
||||
|
||||
struct espTagReturnData {
|
||||
uint8_t checksum;
|
||||
uint8_t src[8];
|
||||
uint8_t len;
|
||||
struct tagReturnData returnData;
|
||||
} __attribute__((packed, aligned(1)));
|
||||
|
||||
#endif
|
||||
|
||||
@@ -14,6 +14,8 @@
|
||||
#include "main.h"
|
||||
#include "proto.h"
|
||||
#include "sdkconfig.h"
|
||||
// if you get an error about soc/lp_uart_reg.h not being found,
|
||||
// you didn't choose the right build target. :-)
|
||||
#include "soc/lp_uart_reg.h"
|
||||
#include "soc/uart_struct.h"
|
||||
#include "utils.h"
|
||||
@@ -47,37 +49,64 @@ void esp_ieee802154_transmit_done(const uint8_t *frame, const uint8_t *ack, esp_
|
||||
ESP_EARLY_LOGI(TAG, "TX %d", frame[0]);
|
||||
}
|
||||
|
||||
void radio_init() {
|
||||
packet_buffer = xQueueCreate(32, 130);
|
||||
void radio_init(uint8_t ch) {
|
||||
if (packet_buffer == NULL) packet_buffer = xQueueCreate(32, 130);
|
||||
|
||||
// this will trigger a "IEEE802154 MAC sleep init failed" when called a second time, but it works
|
||||
esp_ieee802154_enable();
|
||||
radioSetChannel(11);
|
||||
esp_ieee802154_set_channel(ch);
|
||||
// esp_ieee802154_set_txpower(int8_t power);
|
||||
esp_ieee802154_set_panid(PROTO_PAN_ID);
|
||||
esp_ieee802154_set_promiscuous(false); // Filter for our mac and PAN
|
||||
esp_ieee802154_set_promiscuous(false);
|
||||
esp_ieee802154_set_coordinator(false);
|
||||
esp_ieee802154_set_pending_mode(ESP_IEEE802154_AUTO_PENDING_ZIGBEE);
|
||||
|
||||
// esp_ieee802154_set_extended_address needs the MAC in reversed byte order
|
||||
esp_read_mac(mSelfMac, ESP_MAC_IEEE802154);
|
||||
esp_ieee802154_set_extended_address(mSelfMac);
|
||||
uint8_t eui64_rev[8] = {0};
|
||||
for (int i = 0; i < 8; i++) {
|
||||
eui64_rev[7 - i] = mSelfMac[i];
|
||||
}
|
||||
esp_ieee802154_set_extended_address(eui64_rev);
|
||||
esp_ieee802154_get_extended_address(mSelfMac);
|
||||
|
||||
esp_ieee802154_set_short_address(0xFFFE);
|
||||
esp_ieee802154_set_rx_when_idle(true);
|
||||
esp_ieee802154_receive();
|
||||
|
||||
led_flash(1);
|
||||
vTaskDelay(100 / portTICK_PERIOD_MS);
|
||||
led_flash(0);
|
||||
vTaskDelay(100 / portTICK_PERIOD_MS);
|
||||
led_flash(1);
|
||||
vTaskDelay(100 / portTICK_PERIOD_MS);
|
||||
led_flash(0);
|
||||
|
||||
ESP_LOGI(TAG, "Receiver ready, panId=0x%04x, channel=%d, long=%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x, short=%04x",
|
||||
esp_ieee802154_get_panid(), esp_ieee802154_get_channel(),
|
||||
mSelfMac[0], mSelfMac[1], mSelfMac[2], mSelfMac[3],
|
||||
mSelfMac[4], mSelfMac[5], mSelfMac[6], mSelfMac[7],
|
||||
esp_ieee802154_get_short_address());
|
||||
}
|
||||
|
||||
uint32_t lastZbTx = 0;
|
||||
// uint32_t lastZbTx = 0;
|
||||
bool radioTx(uint8_t *packet) {
|
||||
static uint8_t txPKT[130];
|
||||
while (isInTransmit) {
|
||||
}
|
||||
while (getMillis() - lastZbTx < 6) {
|
||||
}
|
||||
led_flash(1);
|
||||
memcpy(txPKT, packet, packet[0]);
|
||||
isInTransmit = 1;
|
||||
lastZbTx = getMillis();
|
||||
esp_ieee802154_transmit(txPKT, false);
|
||||
return true;
|
||||
while (isInTransmit) {
|
||||
}
|
||||
// while (getMillis() - lastZbTx < 6) {
|
||||
// }
|
||||
// lastZbTx = getMillis();
|
||||
memcpy(txPKT, packet, packet[0]);
|
||||
isInTransmit = 1;
|
||||
esp_ieee802154_transmit(txPKT, false);
|
||||
return true;
|
||||
}
|
||||
|
||||
void radioSetChannel(uint8_t ch) { esp_ieee802154_set_channel(ch); }
|
||||
void radioSetChannel(uint8_t ch) {
|
||||
radio_init(ch);
|
||||
}
|
||||
|
||||
void radioSetTxPower(uint8_t power) {}
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
extern uint8_t mSelfMac[8];
|
||||
|
||||
void radio_init();
|
||||
void radio_init(uint8_t ch);
|
||||
bool radioTx(uint8_t *packet);
|
||||
void radioSetChannel(uint8_t ch);
|
||||
void radioSetTxPower(uint8_t power);
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include "sdkconfig.h"
|
||||
#include "soc/uart_struct.h"
|
||||
#include "soc/lp_uart_reg.h"
|
||||
#include "second_uart.h"
|
||||
|
||||
static const char *TAG = "SECOND_UART";
|
||||
|
||||
@@ -32,8 +33,6 @@ volatile int curr_buff_pos = 0;
|
||||
volatile int worked_buff_pos = 0;
|
||||
volatile uint8_t buff_pos[MAX_BUFF_POS + 5];
|
||||
|
||||
|
||||
|
||||
static void uart_event_task(void *pvParameters);
|
||||
void init_second_uart() {
|
||||
uart_config_t uart_config = {
|
||||
@@ -46,9 +45,9 @@ void init_second_uart() {
|
||||
};
|
||||
ESP_ERROR_CHECK(uart_driver_install(1, BUF_SIZE * 2, BUF_SIZE * 2, 20, &uart0_queue, 0));
|
||||
ESP_ERROR_CHECK(uart_param_config(1, &uart_config));
|
||||
ESP_ERROR_CHECK(uart_set_pin(1, 3, 2, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE));
|
||||
ESP_ERROR_CHECK(uart_set_pin(1, CONFIG_OEPL_HARDWARE_UART_TX, CONFIG_OEPL_HARDWARE_UART_RX, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE));
|
||||
|
||||
xTaskCreate(uart_event_task, "uart_event_task", 16384, NULL, 12, NULL);
|
||||
xTaskCreate(uart_event_task, "uart_event_task", 16384, NULL, 12, NULL);
|
||||
}
|
||||
|
||||
void uart_switch_speed(int baudrate) {
|
||||
@@ -92,7 +91,7 @@ static void uart_event_task(void *pvParameters) {
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ESP_LOGI(TAG, "uart event type: %d", event.type);
|
||||
// ESP_LOGI(TAG, "uart event type: %d", event.type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
void init_second_uart();
|
||||
void uart_switch_speed(int baudrate);
|
||||
|
||||
@@ -9,3 +11,15 @@ bool getRxCharSecond(uint8_t *newChar);
|
||||
void uart_printf(const char *format, ...);
|
||||
|
||||
#define pr uart_printf
|
||||
|
||||
#if defined(CONFIG_OEPL_HARDWARE_PROFILE_DEFAULT)
|
||||
#define CONFIG_OEPL_HARDWARE_UART_TX 3
|
||||
#define CONFIG_OEPL_HARDWARE_UART_RX 2
|
||||
#elif defined(CONFIG_OEPL_HARDWARE_PROFILE_POE_AP)
|
||||
#define CONFIG_OEPL_HARDWARE_UART_TX 5
|
||||
#define CONFIG_OEPL_HARDWARE_UART_RX 18
|
||||
#elif defined(CONFIG_OEPL_HARDWARE_PROFILE_CUSTOM)
|
||||
#if !defined(CONFIG_OEPL_HARDWARE_UART_TX) || !defined(CONFIG_OEPL_HARDWARE_UART_RX)
|
||||
#error "No UART TX / RX pins defined. Please check menuconfig"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
5
ARM_Tag_FW/OpenEPaperLink_esp32_C6_AP/partitions.csv
Normal file
5
ARM_Tag_FW/OpenEPaperLink_esp32_C6_AP/partitions.csv
Normal file
@@ -0,0 +1,5 @@
|
||||
# ESP-IDF Partition Table
|
||||
# Name, Type, SubType, Offset, Size, Flags
|
||||
nvs,data,nvs,0x9000,0x6000,,
|
||||
factory,app,factory,0x10000,1M,,
|
||||
littlefs,data,spiffs,,3008K,,
|
||||
|
File diff suppressed because it is too large
Load Diff
8
ARM_Tag_FW/OpenEPaperLink_esp32_C6_AP/sdkconfig.defaults
Normal file
8
ARM_Tag_FW/OpenEPaperLink_esp32_C6_AP/sdkconfig.defaults
Normal file
@@ -0,0 +1,8 @@
|
||||
# This file was generated using idf.py save-defconfig. It can be edited manually.
|
||||
# Espressif IoT Development Framework (ESP-IDF) Project Minimal Configuration
|
||||
#
|
||||
CONFIG_IDF_TARGET="esp32c6"
|
||||
CONFIG_ESPTOOLPY_FLASHMODE_QIO=y
|
||||
CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y
|
||||
CONFIG_ESPTOOLPY_HEADER_FLASHSIZE_UPDATE=y
|
||||
CONFIG_PARTITION_TABLE_CUSTOM=y
|
||||
4
ESP32_AP-Flasher/.vscode/settings.json
vendored
4
ESP32_AP-Flasher/.vscode/settings.json
vendored
@@ -50,6 +50,8 @@
|
||||
"stdexcept": "cpp",
|
||||
"streambuf": "cpp",
|
||||
"cinttypes": "cpp",
|
||||
"typeinfo": "cpp"
|
||||
"typeinfo": "cpp",
|
||||
"chrono": "cpp",
|
||||
"ratio": "cpp"
|
||||
}
|
||||
}
|
||||
8
ESP32_AP-Flasher/16MB_partition table.csv
Normal file
8
ESP32_AP-Flasher/16MB_partition table.csv
Normal file
@@ -0,0 +1,8 @@
|
||||
# Name, Type, SubType, Offset, Size, Flags
|
||||
nvs, data, nvs, 0x9000, 0x4000
|
||||
otadata, data, ota, 0xD000, 0x2000
|
||||
phy_init, data, phy, 0xF000, 0x1000
|
||||
app0, app, ota_0, 0x10000, 0x200000
|
||||
app1, app, ota_1, 0x210000, 0x200000
|
||||
spiffs, data, spiffs, 0x410000, 0xBE0000
|
||||
coredump, data, coredump, 0xFF0000, 0x10000
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
56
ESP32_AP-Flasher/data/languages.json
Normal file
56
ESP32_AP-Flasher/data/languages.json
Normal file
@@ -0,0 +1,56 @@
|
||||
{
|
||||
"0": {
|
||||
"language": "en",
|
||||
"daysShort": ["SU", "MO", "TU", "WE", "TH", "FR", "SA"],
|
||||
"days": ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"],
|
||||
"months": ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]
|
||||
},
|
||||
"1": {
|
||||
"language": "nl",
|
||||
"daysShort": ["ZO", "MA", "DI", "WO", "DO", "VR", "ZA"],
|
||||
"days": ["zondag", "maandag", "dinsdag", "woensdag", "donderdag", "vrijdag", "zaterdag"],
|
||||
"months": ["januari", "februari", "maart", "april", "mei", "juni", "juli", "augustus", "september", "oktober", "november", "december"]
|
||||
},
|
||||
"2": {
|
||||
"language": "de",
|
||||
"daysShort": ["SO", "MO", "DI", "MI", "DO", "FR", "SA"],
|
||||
"days": ["Sonntag", "Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag"],
|
||||
"months": ["Januar", "Februar", "März", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Dezember"]
|
||||
},
|
||||
"3": {
|
||||
"language": "no",
|
||||
"daysShort": ["SØ", "MA", "TI", "ON", "TO", "FR", "LØ"],
|
||||
"days": ["Søndag", "Mandag", "Tirsdag", "Onsdag", "Torsdag", "Fredag", "Lørdag"],
|
||||
"months": ["Januar", "Februar", "Mars", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Desember"]
|
||||
},
|
||||
"5": {
|
||||
"language": "cz",
|
||||
"daysShort": ["NE", "PO", "ÚT", "ST", "ČT", "PÁ", "SO"],
|
||||
"days": ["Neděle", "Pondělí", "Úterý", "Středa", "Čtvrtek", "Pátek", "Sobota"],
|
||||
"months": ["Leden", "Únor", "Březen", "Duben", "Květen", "Červen", "Červenec", "Srpen", "Září", "Říjen", "Listopad", "Prosinec"]
|
||||
},
|
||||
"6": {
|
||||
"language": "sk",
|
||||
"daysShort": ["NE", "PO", "UT", "ST", "ŠT", "PI", "SO"],
|
||||
"days": ["Nedeľa", "Pondelok", "Utorok", "Streda", "Štvrtok", "Piatok", "Sobota"],
|
||||
"months": ["Január", "Február", "Marec", "Apríl", "Máj", "Jún", "Júl", "August", "September", "Oktober", "November", "December"]
|
||||
},
|
||||
"7": {
|
||||
"language": "pl",
|
||||
"daysShort": ["Ni", "Po", "Wt", "Śr", "Cz", "Pt", "So"],
|
||||
"days": ["Niedziela", "Poniedziałek", "Wtorek", "Środa", "Czwartek", "Piątek", "Sobota"],
|
||||
"months": ["Styczeń", "Luty", "Marzec", "Kwiecień", "Maj", "Czerwiec", "Lipiec", "Sierpień", "Wrzesień", "Październik", "Listopad", "Grudzień"]
|
||||
},
|
||||
"8": {
|
||||
"language": "es",
|
||||
"daysShort": ["D", "L", "MA", "MI", "J", "V", "S"],
|
||||
"days": ["Domingo", "Lunes", "Martes", "Miércoles", "Jueves", "Viernes", "Sábado"],
|
||||
"months": ["Enero", "Febrero", "Marzo", "Abril", "Mayo", "Junio", "Julio", "Agosto", "Septiembre", "Octubre", "Noviembre", "Diciembre"]
|
||||
},
|
||||
"4": {
|
||||
"language": "fr",
|
||||
"daysShort": ["DI", "LU", "MA", "ME", "JE", "VE", "SA"],
|
||||
"days": ["Dimanche", "Lundi", "Mardi", "Mercredi", "Jeudi", "Vendredi", "Samedi"],
|
||||
"months": ["Janvier", "Février", "Mars", "Avril", "Mai", "Juin", "Juillet", "Aout", "Septembre", "Octobre", "Novembre", "Decembre"]
|
||||
}
|
||||
}
|
||||
@@ -11,7 +11,9 @@
|
||||
"red": [255, 0, 0],
|
||||
"gray": [150, 150, 150]
|
||||
},
|
||||
"capabilities": ["button", "customlut"],
|
||||
"shortlut": 2,
|
||||
"options": ["button", "customlut"],
|
||||
"contentids": [ 0, 1, 2, 3, 4, 5, 7, 10, 14, 15, 17, 18, 19, 20, 21],
|
||||
"template": {
|
||||
"1": {
|
||||
"weekday": [ 76, 10, "fonts/calibrib30" ],
|
||||
|
||||
@@ -11,7 +11,9 @@
|
||||
"red": [255, 0, 0],
|
||||
"gray": [150, 150, 150]
|
||||
},
|
||||
"capabilities": ["button", "customlut"],
|
||||
"shortlut": 2,
|
||||
"options": ["button", "customlut"],
|
||||
"contentids": [ 0, 1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 15, 16, 17, 18, 19, 20, 21 ],
|
||||
"template": {
|
||||
"1": {
|
||||
"weekday": [148, 10, "fonts/calibrib60"],
|
||||
|
||||
@@ -11,7 +11,9 @@
|
||||
"red": [255, 0, 0],
|
||||
"gray": [150, 150, 150]
|
||||
},
|
||||
"capabilities": ["button", "customlut"],
|
||||
"shortlut": 1,
|
||||
"options": ["button"],
|
||||
"contentids": [ 0, 1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 17, 18, 19, 20, 21],
|
||||
"template": {
|
||||
"1": {
|
||||
"weekday": [ 200, 25, "fonts/calibrib60" ],
|
||||
|
||||
@@ -11,7 +11,9 @@
|
||||
"red": [255, 0, 0],
|
||||
"gray": [150, 150, 150]
|
||||
},
|
||||
"capabilities": ["button", "customlut"],
|
||||
"shortlut": 1,
|
||||
"options": [],
|
||||
"contentids": [ 0, 1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 17, 18, 19, 20],
|
||||
"template": {
|
||||
"1": {
|
||||
"weekday": [ 200, 25, "fonts/calibrib60" ],
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
"red": [255, 0, 0],
|
||||
"gray": [150, 150, 150]
|
||||
},
|
||||
"capabilities": ["button", "customlut"],
|
||||
"shortlut": 0,
|
||||
"options": ["button"],
|
||||
"contentids": [ 0, 1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 14, 15, 16, 17, 18, 19, 20, 21],
|
||||
"usetemplate": 1
|
||||
}
|
||||
|
||||
16
ESP32_AP-Flasher/data/tagtypes/21.json
Normal file
16
ESP32_AP-Flasher/data/tagtypes/21.json
Normal file
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"name": "ST‐GM29XXF 2.9\"",
|
||||
"width": 296,
|
||||
"height": 128,
|
||||
"rotatebuffer": 1,
|
||||
"bpp": 1,
|
||||
"colors": 2,
|
||||
"colortable": {
|
||||
"white": [255, 255, 255],
|
||||
"black": [0, 0, 0]
|
||||
},
|
||||
"shortlut": 0,
|
||||
"options": ["button", "customlut"],
|
||||
"contentids": [ 0, 1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 15, 16, 17, 18, 19, 20, 21 ],
|
||||
"usetemplate": 1
|
||||
}
|
||||
18
ESP32_AP-Flasher/data/tagtypes/2E.json
Normal file
18
ESP32_AP-Flasher/data/tagtypes/2E.json
Normal file
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"name": "EL097H2WRN 9.7\"",
|
||||
"width": 960,
|
||||
"height": 672,
|
||||
"rotatebuffer": 0,
|
||||
"bpp": 2,
|
||||
"colors": 3,
|
||||
"colortable": {
|
||||
"white": [255, 255, 255],
|
||||
"black": [0, 0, 0],
|
||||
"red": [255, 0, 0],
|
||||
"gray": [150, 150, 150]
|
||||
},
|
||||
"shortlut": 0,
|
||||
"options": ["button"],
|
||||
"contentids": [ 0, 1, 2, 3, 4, 8, 16, 9, 7, 19, 10, 11, 21 ],
|
||||
"usetemplate": 1
|
||||
}
|
||||
18
ESP32_AP-Flasher/data/tagtypes/2F.json
Normal file
18
ESP32_AP-Flasher/data/tagtypes/2F.json
Normal file
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"name": "EL043H3WRA 4.3\"",
|
||||
"width": 522,
|
||||
"height": 152,
|
||||
"rotatebuffer": 1,
|
||||
"bpp": 2,
|
||||
"colors": 3,
|
||||
"colortable": {
|
||||
"white": [255, 255, 255],
|
||||
"black": [0, 0, 0],
|
||||
"red": [255, 0, 0],
|
||||
"gray": [150, 150, 150]
|
||||
},
|
||||
"shortlut": 0,
|
||||
"options": ["button"],
|
||||
"contentids": [ 0, 1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 17, 18, 19, 20],
|
||||
"usetemplate": 1
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user