mirror of
https://github.com/OpenEPaperLink/OpenEPaperLink.git
synced 2026-03-21 04:06:29 +01:00
Compare commits
121 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1aeea88696 | ||
|
|
837c5de1a8 | ||
|
|
d4f16f74e9 | ||
|
|
fdb4a3cbf1 | ||
|
|
5b7c96dcc0 | ||
|
|
c0a2bd01e5 | ||
|
|
bd8965174a | ||
|
|
229962165a | ||
|
|
4dac6ab05c | ||
|
|
f95e957361 | ||
|
|
b8161f21fa | ||
|
|
950931b9a6 | ||
|
|
af5e917cb3 | ||
|
|
8005ae71fc | ||
|
|
4965c68516 | ||
|
|
96e8fe8660 | ||
|
|
fcff10412d | ||
|
|
23c3611872 | ||
|
|
7cb7eddc22 | ||
|
|
b68cd22eb1 | ||
|
|
b0cfa1b2b4 | ||
|
|
29589bc5b0 | ||
|
|
00ce785158 | ||
|
|
9da9ac9395 | ||
|
|
022f72eee7 | ||
|
|
1d03eedfd6 | ||
|
|
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 |
38
.github/workflows/build-test.yml
vendored
38
.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: |
|
||||
@@ -39,12 +39,6 @@ jobs:
|
||||
cd ESP32_AP-Flasher
|
||||
pio run --environment OpenEPaperLink_Mini_AP
|
||||
pio run --target buildfs --environment OpenEPaperLink_Mini_AP
|
||||
|
||||
# - name: Build OpenEPaperLink_Nano_AP
|
||||
# run: |
|
||||
# cd ESP32_AP-Flasher
|
||||
# pio run --environment OpenEPaperLink_Nano_AP
|
||||
# pio run --target buildfs --environment OpenEPaperLink_Nano_AP
|
||||
|
||||
- name: Build OpenEPaperLink_AP_and_Flasher
|
||||
run: |
|
||||
@@ -52,38 +46,8 @@ jobs:
|
||||
pio run --environment OpenEPaperLink_AP_and_Flasher
|
||||
pio run --target buildfs --environment OpenEPaperLink_AP_and_Flasher
|
||||
|
||||
# - name: Build Wemos_d1_mini32_AP
|
||||
# run: |
|
||||
# cd ESP32_AP-Flasher
|
||||
# pio run --environment Wemos_d1_mini32_AP
|
||||
# pio run --target buildfs --environment Wemos_d1_mini32_AP
|
||||
|
||||
# - name: Build M5Stack_Core_ONE_AP
|
||||
# run: |
|
||||
# cd ESP32_AP-Flasher
|
||||
# pio run --environment M5Stack_Core_ONE_AP
|
||||
# pio run --target buildfs --environment M5Stack_Core_ONE_AP
|
||||
|
||||
- name: Build ESP32_S3_16_8_YELLOW_AP]
|
||||
run: |
|
||||
cd ESP32_AP-Flasher
|
||||
pio run --environment ESP32_S3_16_8_YELLOW_AP
|
||||
pio run --target buildfs --environment ESP32_S3_16_8_YELLOW_AP
|
||||
|
||||
# - name: Build Sonoff_zb_bridge_P_AP
|
||||
# run: |
|
||||
# cd ESP32_AP-Flasher
|
||||
# pio run --environment Sonoff_zb_bridge_P_AP
|
||||
# pio run --target buildfs --environment Sonoff_zb_bridge_P_AP
|
||||
|
||||
# - name: Build OpenEPaperLink_CC1352P
|
||||
# run: |
|
||||
# cd ESP32_AP-Flasher
|
||||
# pio run --environment OpenEPaperLink_CC1352P
|
||||
# pio run --target buildfs --environment OpenEPaperLink_CC1352P
|
||||
|
||||
# - name: OutdoorAP
|
||||
# run: |
|
||||
# cd ESP32_AP-Flasher
|
||||
# pio run --environment OutdoorAP
|
||||
# pio run --target buildfs --environment OutdoorAP
|
||||
|
||||
136
.github/workflows/release.yml
vendored
136
.github/workflows/release.yml
vendored
@@ -21,11 +21,6 @@ jobs:
|
||||
with:
|
||||
python-version: '3.9'
|
||||
|
||||
# - name: Zip web files
|
||||
# run: |
|
||||
# cd /home/runner/work/OpenEPaperLink/OpenEPaperLink/ESP32_AP-Flasher
|
||||
# python gzip_wwwfiles.py
|
||||
|
||||
# - name: Commit zipped files
|
||||
# run: |
|
||||
# git config --global user.name 'Bot'
|
||||
@@ -38,19 +33,6 @@ 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: Install esptool
|
||||
run: pip install esptool
|
||||
@@ -58,6 +40,11 @@ jobs:
|
||||
- name: create folders
|
||||
run: |
|
||||
mkdir espbinaries
|
||||
|
||||
- name: Zip web files
|
||||
run: |
|
||||
cd /home/runner/work/OpenEPaperLink/OpenEPaperLink/ESP32_AP-Flasher
|
||||
python gzip_wwwfiles.py
|
||||
|
||||
- name: Build firmware for Simple_AP
|
||||
run: |
|
||||
@@ -77,42 +64,6 @@ jobs:
|
||||
cp Simple_AP/firmware.bin espbinaries/Simple_AP.bin
|
||||
cp Simple_AP/merged-firmware.bin espbinaries/Simple_AP_full.bin
|
||||
|
||||
- name: Build firmware for Wemos_d1_mini32_AP
|
||||
run: |
|
||||
cd ESP32_AP-Flasher
|
||||
export PLATFORMIO_BUILD_FLAGS="-D BUILD_VERSION=${{ github.ref_name }} -D SHA=$GITHUB_SHA"
|
||||
pio run --environment Wemos_d1_mini32_AP
|
||||
pio run --target buildfs --environment Wemos_d1_mini32_AP
|
||||
mkdir /home/runner/work/OpenEPaperLink/OpenEPaperLink/Wemos_d1_mini32_AP
|
||||
cp ~/.platformio/packages/framework-arduinoespressif32/tools/partitions/boot_app0.bin /home/runner/work/OpenEPaperLink/OpenEPaperLink/Wemos_d1_mini32_AP/boot_app0.bin
|
||||
cp .pio/build/Wemos_d1_mini32_AP/firmware.bin /home/runner/work/OpenEPaperLink/OpenEPaperLink/Wemos_d1_mini32_AP/firmware.bin
|
||||
cp .pio/build/Wemos_d1_mini32_AP/bootloader.bin /home/runner/work/OpenEPaperLink/OpenEPaperLink/Wemos_d1_mini32_AP/bootloader.bin
|
||||
cp .pio/build/Wemos_d1_mini32_AP/partitions.bin /home/runner/work/OpenEPaperLink/OpenEPaperLink/Wemos_d1_mini32_AP/partitions.bin
|
||||
cp .pio/build/Wemos_d1_mini32_AP/littlefs.bin /home/runner/work/OpenEPaperLink/OpenEPaperLink/Wemos_d1_mini32_AP/littlefs.bin
|
||||
cd /home/runner/work/OpenEPaperLink/OpenEPaperLink/Wemos_d1_mini32_AP
|
||||
esptool.py --chip esp32 merge_bin -o merged-firmware.bin --flash_mode dio --flash_freq 40m --flash_size 4MB 0x1000 bootloader.bin 0x8000 partitions.bin 0xe000 boot_app0.bin 0x10000 firmware.bin 0x290000 littlefs.bin
|
||||
cd /home/runner/work/OpenEPaperLink/OpenEPaperLink
|
||||
cp Wemos_d1_mini32_AP/firmware.bin espbinaries/Wemos_d1_mini32_AP.bin
|
||||
cp Wemos_d1_mini32_AP/merged-firmware.bin espbinaries/Wemos_d1_mini32_AP_full.bin
|
||||
|
||||
- name: Build firmware for M5Stack_Core_ONE_AP
|
||||
run: |
|
||||
cd ESP32_AP-Flasher
|
||||
export PLATFORMIO_BUILD_FLAGS="-D BUILD_VERSION=${{ github.ref_name }} -D SHA=$GITHUB_SHA"
|
||||
pio run --environment M5Stack_Core_ONE_AP
|
||||
pio run --target buildfs --environment M5Stack_Core_ONE_AP
|
||||
mkdir /home/runner/work/OpenEPaperLink/OpenEPaperLink/M5Stack_Core_ONE_AP
|
||||
cp ~/.platformio/packages/framework-arduinoespressif32/tools/partitions/boot_app0.bin /home/runner/work/OpenEPaperLink/OpenEPaperLink/M5Stack_Core_ONE_AP/boot_app0.bin
|
||||
cp .pio/build/M5Stack_Core_ONE_AP/firmware.bin /home/runner/work/OpenEPaperLink/OpenEPaperLink/M5Stack_Core_ONE_AP/firmware.bin
|
||||
cp .pio/build/M5Stack_Core_ONE_AP/bootloader.bin /home/runner/work/OpenEPaperLink/OpenEPaperLink/M5Stack_Core_ONE_AP/bootloader.bin
|
||||
cp .pio/build/M5Stack_Core_ONE_AP/partitions.bin /home/runner/work/OpenEPaperLink/OpenEPaperLink/M5Stack_Core_ONE_AP/partitions.bin
|
||||
cp .pio/build/M5Stack_Core_ONE_AP/littlefs.bin /home/runner/work/OpenEPaperLink/OpenEPaperLink/M5Stack_Core_ONE_AP/littlefs.bin
|
||||
cd /home/runner/work/OpenEPaperLink/OpenEPaperLink/M5Stack_Core_ONE_AP
|
||||
esptool.py --chip esp32 merge_bin -o merged-firmware.bin --flash_mode dio --flash_freq 40m --flash_size 4MB 0x1000 bootloader.bin 0x8000 partitions.bin 0xe000 boot_app0.bin 0x10000 firmware.bin 0x2B0000 littlefs.bin
|
||||
cd /home/runner/work/OpenEPaperLink/OpenEPaperLink
|
||||
cp M5Stack_Core_ONE_AP/firmware.bin espbinaries/M5Stack_Core_ONE_AP.bin
|
||||
cp M5Stack_Core_ONE_AP/merged-firmware.bin espbinaries/M5Stack_Core_ONE_AP_full.bin
|
||||
|
||||
- name: Build firmware for OpenEPaperLink_Mini_AP
|
||||
run: |
|
||||
cd ESP32_AP-Flasher
|
||||
@@ -148,6 +99,10 @@ jobs:
|
||||
cd /home/runner/work/OpenEPaperLink/OpenEPaperLink
|
||||
cp OpenEPaperLink_Nano_AP/firmware.bin espbinaries/OpenEPaperLink_Nano_AP.bin
|
||||
cp OpenEPaperLink_Nano_AP/merged-firmware.bin espbinaries/OpenEPaperLink_Nano_AP_full.bin
|
||||
|
||||
# - name: move files for big APs
|
||||
# run: |
|
||||
# cp -a binaries/ESP32-C6/. ESP32_AP-Flasher/data/
|
||||
|
||||
- name: Build firmware for OpenEPaperLink_AP_and_Flasher
|
||||
run: |
|
||||
@@ -184,12 +139,48 @@ 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 ESP32_S3_C6_NANO_AP
|
||||
run: |
|
||||
cd ESP32_AP-Flasher
|
||||
export PLATFORMIO_BUILD_FLAGS="-D BUILD_VERSION=${{ github.ref_name }} -D SHA=$GITHUB_SHA"
|
||||
pio run --environment ESP32_S3_C6_NANO_AP
|
||||
pio run --target buildfs --environment ESP32_S3_C6_NANO_AP
|
||||
mkdir /home/runner/work/OpenEPaperLink/OpenEPaperLink/ESP32_S3_C6_NANO_AP
|
||||
cp ~/.platformio/packages/framework-arduinoespressif32/tools/partitions/boot_app0.bin /home/runner/work/OpenEPaperLink/OpenEPaperLink/ESP32_S3_C6_NANO_AP/boot_app0.bin
|
||||
cp .pio/build/ESP32_S3_C6_NANO_AP/firmware.bin /home/runner/work/OpenEPaperLink/OpenEPaperLink/ESP32_S3_C6_NANO_AP/firmware.bin
|
||||
cp .pio/build/ESP32_S3_C6_NANO_AP/bootloader.bin /home/runner/work/OpenEPaperLink/OpenEPaperLink/ESP32_S3_C6_NANO_AP/bootloader.bin
|
||||
cp .pio/build/ESP32_S3_C6_NANO_AP/partitions.bin /home/runner/work/OpenEPaperLink/OpenEPaperLink/ESP32_S3_C6_NANO_AP/partitions.bin
|
||||
cp .pio/build/ESP32_S3_C6_NANO_AP/littlefs.bin /home/runner/work/OpenEPaperLink/OpenEPaperLink/ESP32_S3_C6_NANO_AP/littlefs.bin
|
||||
cd /home/runner/work/OpenEPaperLink/OpenEPaperLink/ESP32_S3_C6_NANO_AP
|
||||
esptool.py --chip esp32-s3 merge_bin -o merged-firmware.bin --flash_mode dio --flash_freq 80m --flash_size 16MB 0x0000 bootloader.bin 0x8000 partitions.bin 0xe000 boot_app0.bin 0x10000 firmware.bin 0x00910000 littlefs.bin
|
||||
cd /home/runner/work/OpenEPaperLink/OpenEPaperLink
|
||||
cp ESP32_S3_C6_NANO_AP/firmware.bin espbinaries/ESP32_S3_C6_NANO_AP.bin
|
||||
cp ESP32_S3_C6_NANO_AP/merged-firmware.bin espbinaries/ESP32_S3_C6_NANO_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
|
||||
python genfilelist.py ${{ github.ref_name }} $GITHUB_REPOSITORY $GITHUB_SHA
|
||||
|
||||
|
||||
- name: Add file lists to release
|
||||
uses: svenstaro/upload-release-action@v2
|
||||
with:
|
||||
@@ -198,16 +189,7 @@ jobs:
|
||||
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)
|
||||
|
||||
- name: Build firmware for Tag_Flasher
|
||||
@@ -236,27 +218,3 @@ jobs:
|
||||
tag: ${{ github.ref }}
|
||||
file_glob: true
|
||||
overwrite: true
|
||||
|
||||
# - name: Add www folder to release
|
||||
# uses: svenstaro/upload-release-action@v2
|
||||
# with:
|
||||
# repo_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
# file: ESP32_AP-Flasher/data/www/*
|
||||
# tag: ${{ github.ref }}
|
||||
# file_glob: true
|
||||
|
||||
# - name: Add fonts folder to release
|
||||
# uses: svenstaro/upload-release-action@v2
|
||||
# with:
|
||||
# repo_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
# file: ESP32_AP-Flasher/data/fonts/*
|
||||
# tag: ${{ github.ref }}
|
||||
# file_glob: true
|
||||
|
||||
# - name: Add data folder to release
|
||||
# uses: svenstaro/upload-release-action@v2
|
||||
# with:
|
||||
# repo_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
# file: ESP32_AP-Flasher/data/*
|
||||
# tag: ${{ github.ref }}
|
||||
# file_glob: true
|
||||
|
||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -23,3 +23,6 @@
|
||||
*.bin
|
||||
*.lk
|
||||
*.o
|
||||
sdcc/sdcc
|
||||
|
||||
ESP32_AP-Flasher/.vscode/extensions.json
|
||||
|
||||
@@ -0,0 +1,799 @@
|
||||
// Ported to ESP32-C6 Arduino By ATC1441(ATCnetz.de) for OpenEPaperLink at ~01.2024
|
||||
|
||||
#include "led.h"
|
||||
#include "proto.h"
|
||||
#include "radio.h"
|
||||
#include "subGhz.h"
|
||||
#include "driver/gpio.h"
|
||||
#include "driver/uart.h"
|
||||
#include "esp_err.h"
|
||||
#include "esp_event.h"
|
||||
#include "esp_ieee802154.h"
|
||||
#include "esp_phy_init.h"
|
||||
#include "esp_timer.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/queue.h"
|
||||
#include "freertos/task.h"
|
||||
#include "sdkconfig.h"
|
||||
#include "second_uart.h"
|
||||
#include "soc/lp_uart_reg.h"
|
||||
#include "soc/uart_struct.h"
|
||||
#include <esp_mac.h>
|
||||
#include <math.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
const uint8_t channelList[6] = { 11, 15, 20, 25, 26, 27 };
|
||||
|
||||
#define DATATYPE_NOUPDATE 0
|
||||
#define HW_TYPE 0xC6
|
||||
|
||||
#define MAX_PENDING_MACS 250
|
||||
#define HOUSEKEEPING_INTERVAL 60UL
|
||||
|
||||
struct pendingData pendingDataArr[MAX_PENDING_MACS];
|
||||
|
||||
// VERSION GOES HERE!
|
||||
uint16_t version = 0x0019;
|
||||
|
||||
#define RAW_PKT_PADDING 2
|
||||
|
||||
uint8_t radiotxbuffer[135];
|
||||
uint8_t radiorxbuffer[135];
|
||||
|
||||
static uint32_t housekeepingTimer;
|
||||
|
||||
struct blockRequest requestedData = { 0 }; // holds which data was requested by the tag
|
||||
|
||||
uint8_t dstMac[8]; // target for the block transfer
|
||||
uint16_t dstPan; //
|
||||
|
||||
static uint32_t blockStartTimer = 0; // reference that holds when the AP sends the next block
|
||||
uint32_t nextBlockAttempt = 0; // reference time for when the AP can request a new block from the ESP32
|
||||
uint8_t seq = 0; // holds current sequence number for transmission
|
||||
uint8_t blockbuffer[BLOCK_XFER_BUFFER_SIZE + 5]; // block transfer buffer
|
||||
uint8_t lastAckMac[8] = { 0 };
|
||||
|
||||
// these variables hold the current mac were talking to
|
||||
#define CONCURRENT_REQUEST_DELAY 1200UL
|
||||
uint32_t lastBlockRequest = 0;
|
||||
uint8_t lastBlockMac[8];
|
||||
uint8_t lastTagReturn[8];
|
||||
|
||||
uint8_t curChannel = 25;
|
||||
uint8_t curPower = 10;
|
||||
|
||||
uint8_t curPendingData = 0;
|
||||
uint8_t curNoUpdate = 0;
|
||||
|
||||
bool highspeedSerial = false;
|
||||
|
||||
void sendXferCompleteAck(uint8_t *dst, bool isSubGHz);
|
||||
void sendCancelXfer(uint8_t *dst, bool isSubGHz);
|
||||
void espNotifyAPInfo();
|
||||
|
||||
// tools
|
||||
void addCRC(void *p, uint8_t len) {
|
||||
uint8_t total = 0;
|
||||
for (uint8_t c = 1; c < len; c++) {
|
||||
total += ((uint8_t *)p)[c];
|
||||
}
|
||||
((uint8_t *)p)[0] = total;
|
||||
}
|
||||
bool checkCRC(void *p, uint8_t len) {
|
||||
uint8_t total = 0;
|
||||
for (uint8_t c = 1; c < len; c++) {
|
||||
total += ((uint8_t *)p)[c];
|
||||
}
|
||||
return ((uint8_t *)p)[0] == total;
|
||||
}
|
||||
|
||||
uint8_t getPacketType(void *buffer) {
|
||||
struct MacFcs *fcs = (MacFcs *)buffer;
|
||||
if ((fcs->frameType == 1) && (fcs->destAddrType == 2) && (fcs->srcAddrType == 3) && (fcs->panIdCompressed == 0)) {
|
||||
// broadcast frame
|
||||
uint8_t type = ((uint8_t *)buffer)[sizeof(struct MacFrameBcast)];
|
||||
return type;
|
||||
} else if ((fcs->frameType == 1) && (fcs->destAddrType == 3) && (fcs->srcAddrType == 3) && (fcs->panIdCompressed == 1)) {
|
||||
// normal frame
|
||||
uint8_t type = ((uint8_t *)buffer)[sizeof(struct MacFrameNormal)];
|
||||
return type;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
uint8_t getBlockDataLength() {
|
||||
uint8_t partNo = 0;
|
||||
for (uint8_t c = 0; c < BLOCK_MAX_PARTS; c++) {
|
||||
if (requestedData.requestedParts[c / 8] & (1 << (c % 8))) {
|
||||
partNo++;
|
||||
}
|
||||
}
|
||||
return partNo;
|
||||
}
|
||||
|
||||
// pendingdata slot stuff
|
||||
int8_t findSlotForMac(const uint8_t *mac) {
|
||||
for (uint8_t c = 0; c < MAX_PENDING_MACS; c++) {
|
||||
if (memcmp(mac, ((uint8_t *) & (pendingDataArr[c].targetMac)), 8) == 0) {
|
||||
if (pendingDataArr[c].attemptsLeft != 0) {
|
||||
return c;
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
int8_t findFreeSlot() {
|
||||
for (uint8_t c = 0; c < MAX_PENDING_MACS; c++) {
|
||||
if (pendingDataArr[c].attemptsLeft == 0) {
|
||||
return c;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
int8_t findSlotForVer(const uint8_t *ver) {
|
||||
for (uint8_t c = 0; c < MAX_PENDING_MACS; c++) {
|
||||
if (memcmp(ver, ((uint8_t *) & (pendingDataArr[c].availdatainfo.dataVer)), 8) == 0) {
|
||||
if (pendingDataArr[c].attemptsLeft != 0) return c;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
void deleteAllPendingDataForVer(const uint8_t *ver) {
|
||||
int8_t slot = -1;
|
||||
do {
|
||||
slot = findSlotForVer(ver);
|
||||
if (slot != -1) pendingDataArr[slot].attemptsLeft = 0;
|
||||
} while (slot != -1);
|
||||
}
|
||||
void deleteAllPendingDataForMac(const uint8_t *mac) {
|
||||
int8_t slot = -1;
|
||||
do {
|
||||
slot = findSlotForMac(mac);
|
||||
if (slot != -1) pendingDataArr[slot].attemptsLeft = 0;
|
||||
} while (slot != -1);
|
||||
}
|
||||
|
||||
void countSlots() {
|
||||
curPendingData = 0;
|
||||
curNoUpdate = 0;
|
||||
for (uint8_t c = 0; c < MAX_PENDING_MACS; c++) {
|
||||
if (pendingDataArr[c].attemptsLeft != 0) {
|
||||
if (pendingDataArr[c].availdatainfo.dataType != 0) {
|
||||
curPendingData++;
|
||||
} else {
|
||||
curNoUpdate++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// processing serial data
|
||||
#define ZBS_RX_WAIT_HEADER 0
|
||||
#define ZBS_RX_WAIT_SDA 1 // send data avail
|
||||
#define ZBS_RX_WAIT_CANCEL 2 // cancel traffic for mac
|
||||
#define ZBS_RX_WAIT_SCP 3 // set channel power
|
||||
#define ZBS_RX_WAIT_BLOCKDATA 4
|
||||
|
||||
bool isSame(uint8_t *in1, char *in2, int len) {
|
||||
bool flag = 1;
|
||||
for (int i = 0; i < len; i++) {
|
||||
if (in1[i] != in2[i]) flag = 0;
|
||||
}
|
||||
return flag;
|
||||
}
|
||||
|
||||
int blockPosition = 0;
|
||||
void processSerial(uint8_t lastchar) {
|
||||
static uint8_t cmdbuffer[4];
|
||||
static uint8_t RXState = 0;
|
||||
static uint8_t serialbuffer[48];
|
||||
static uint8_t *serialbufferp;
|
||||
static uint8_t bytesRemain = 0;
|
||||
static uint32_t lastSerial = 0;
|
||||
static uint32_t blockStartTime = 0;
|
||||
if ((RXState != ZBS_RX_WAIT_HEADER) && ((millis() - lastSerial) > 1000)) {
|
||||
RXState = ZBS_RX_WAIT_HEADER;
|
||||
Serial.printf("UART Timeout\r\n");
|
||||
}
|
||||
lastSerial = millis();
|
||||
switch (RXState) {
|
||||
case ZBS_RX_WAIT_HEADER:
|
||||
// shift characters in
|
||||
for (uint8_t c = 0; c < 3; c++) {
|
||||
cmdbuffer[c] = cmdbuffer[c + 1];
|
||||
}
|
||||
cmdbuffer[3] = lastchar;
|
||||
|
||||
if (isSame(cmdbuffer + 1, ">D>", 3)) {
|
||||
pr("ACK>");
|
||||
blockStartTime = millis();
|
||||
Serial.printf("Starting BlkData, %lu ms after request\r\n", blockStartTime - nextBlockAttempt);
|
||||
blockPosition = 0;
|
||||
RXState = ZBS_RX_WAIT_BLOCKDATA;
|
||||
}
|
||||
|
||||
if (isSame(cmdbuffer, "SDA>", 4)) {
|
||||
Serial.printf("SDA In\r\n");
|
||||
RXState = ZBS_RX_WAIT_SDA;
|
||||
bytesRemain = sizeof(struct pendingData);
|
||||
serialbufferp = serialbuffer;
|
||||
break;
|
||||
}
|
||||
if (isSame(cmdbuffer, "CXD>", 4)) {
|
||||
Serial.printf("CXD In\r\n");
|
||||
RXState = ZBS_RX_WAIT_CANCEL;
|
||||
bytesRemain = sizeof(struct pendingData);
|
||||
serialbufferp = serialbuffer;
|
||||
break;
|
||||
}
|
||||
if (isSame(cmdbuffer, "SCP>", 4)) {
|
||||
Serial.printf("SCP In\r\n");
|
||||
RXState = ZBS_RX_WAIT_SCP;
|
||||
bytesRemain = sizeof(struct espSetChannelPower);
|
||||
serialbufferp = serialbuffer;
|
||||
break;
|
||||
}
|
||||
if (isSame(cmdbuffer, "NFO?", 4)) {
|
||||
pr("ACK>");
|
||||
Serial.printf("NFO? In\r\n");
|
||||
espNotifyAPInfo();
|
||||
RXState = ZBS_RX_WAIT_HEADER;
|
||||
}
|
||||
if (isSame(cmdbuffer, "RDY?", 4)) {
|
||||
pr("ACK>");
|
||||
Serial.printf("RDY? In\r\n");
|
||||
RXState = ZBS_RX_WAIT_HEADER;
|
||||
}
|
||||
if (isSame(cmdbuffer, "RSET", 4)) {
|
||||
pr("ACK>");
|
||||
Serial.printf("RSET In\r\n");
|
||||
delay(100);
|
||||
// TODO RESET US HERE
|
||||
RXState = ZBS_RX_WAIT_HEADER;
|
||||
}
|
||||
if (isSame(cmdbuffer, "HSPD", 4)) {
|
||||
pr("ACK>");
|
||||
Serial.printf("HSPD In, switching to 2000000\r\n");
|
||||
delay(100);
|
||||
uart_switch_speed(2000000);
|
||||
delay(100);
|
||||
highspeedSerial = true;
|
||||
pr("ACK>");
|
||||
RXState = ZBS_RX_WAIT_HEADER;
|
||||
}
|
||||
break;
|
||||
case ZBS_RX_WAIT_BLOCKDATA:
|
||||
blockbuffer[blockPosition++] = 0xAA ^ lastchar;
|
||||
if (blockPosition >= 4100) {
|
||||
Serial.printf("Blockdata fully received in %lu ms, %lu ms after the request\r\n", millis() - blockStartTime, millis() - nextBlockAttempt);
|
||||
RXState = ZBS_RX_WAIT_HEADER;
|
||||
}
|
||||
break;
|
||||
|
||||
case ZBS_RX_WAIT_SDA:
|
||||
*serialbufferp = lastchar;
|
||||
serialbufferp++;
|
||||
bytesRemain--;
|
||||
if (bytesRemain == 0) {
|
||||
if (checkCRC(serialbuffer, sizeof(struct pendingData))) {
|
||||
struct pendingData *pd = (struct pendingData *)serialbuffer;
|
||||
int8_t slot = findSlotForMac(pd->targetMac);
|
||||
if (slot == -1) slot = findFreeSlot();
|
||||
if (slot != -1) {
|
||||
memcpy(&(pendingDataArr[slot]), serialbuffer, sizeof(struct pendingData));
|
||||
pr("ACK>");
|
||||
} else {
|
||||
pr("NOQ>");
|
||||
}
|
||||
} else {
|
||||
pr("NOK>");
|
||||
}
|
||||
|
||||
RXState = ZBS_RX_WAIT_HEADER;
|
||||
}
|
||||
break;
|
||||
case ZBS_RX_WAIT_CANCEL:
|
||||
*serialbufferp = lastchar;
|
||||
serialbufferp++;
|
||||
bytesRemain--;
|
||||
if (bytesRemain == 0) {
|
||||
if (checkCRC(serialbuffer, sizeof(struct pendingData))) {
|
||||
struct pendingData *pd = (struct pendingData *)serialbuffer;
|
||||
deleteAllPendingDataForMac((uint8_t *)&pd->targetMac);
|
||||
pr("ACK>");
|
||||
} else {
|
||||
pr("NOK>");
|
||||
}
|
||||
|
||||
RXState = ZBS_RX_WAIT_HEADER;
|
||||
}
|
||||
break;
|
||||
case ZBS_RX_WAIT_SCP:
|
||||
*serialbufferp = lastchar;
|
||||
serialbufferp++;
|
||||
bytesRemain--;
|
||||
if (bytesRemain == 0) {
|
||||
if (checkCRC(serialbuffer, sizeof(struct espSetChannelPower))) {
|
||||
struct espSetChannelPower *scp = (struct espSetChannelPower *)serialbuffer;
|
||||
for (uint8_t c = 0; c < sizeof(channelList); c++) {
|
||||
if (channelList[c] == scp->channel) goto SCPchannelFound;
|
||||
}
|
||||
goto SCPfailed;
|
||||
SCPchannelFound:
|
||||
pr("ACK>");
|
||||
if (curChannel != scp->channel) {
|
||||
radioSetChannel(scp->channel);
|
||||
curChannel = scp->channel;
|
||||
}
|
||||
curPower = scp->power;
|
||||
radioSetTxPower(scp->power);
|
||||
Serial.printf("Set channel: %d power: %d\r\n", curChannel, curPower);
|
||||
} else {
|
||||
SCPfailed:
|
||||
pr("NOK>");
|
||||
}
|
||||
RXState = ZBS_RX_WAIT_HEADER;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// sending data to the ESP
|
||||
void espBlockRequest(const struct blockRequest *br, uint8_t *src) {
|
||||
struct espBlockRequest *ebr = (struct espBlockRequest *)blockbuffer;
|
||||
uartTx('R');
|
||||
uartTx('Q');
|
||||
uartTx('B');
|
||||
uartTx('>');
|
||||
memcpy(&(ebr->ver), &(br->ver), 8);
|
||||
memcpy(&(ebr->src), src, 8);
|
||||
ebr->blockId = br->blockId;
|
||||
addCRC(ebr, sizeof(struct espBlockRequest));
|
||||
for (uint8_t c = 0; c < sizeof(struct espBlockRequest); c++) {
|
||||
uartTx(((uint8_t *)ebr)[c]);
|
||||
}
|
||||
}
|
||||
void espNotifyAvailDataReq(const struct AvailDataReq *adr, const uint8_t *src) {
|
||||
uartTx('A');
|
||||
uartTx('D');
|
||||
uartTx('R');
|
||||
uartTx('>');
|
||||
|
||||
struct espAvailDataReq eadr = { 0 };
|
||||
memcpy((void *)eadr.src, (void *)src, 8);
|
||||
memcpy((void *)&eadr.adr, (void *)adr, sizeof(struct AvailDataReq));
|
||||
addCRC(&eadr, sizeof(struct espAvailDataReq));
|
||||
for (uint8_t c = 0; c < sizeof(struct espAvailDataReq); c++) {
|
||||
uartTx(((uint8_t *)&eadr)[c]);
|
||||
}
|
||||
}
|
||||
void espNotifyXferComplete(const uint8_t *src) {
|
||||
struct espXferComplete exfc;
|
||||
memcpy(&exfc.src, src, 8);
|
||||
uartTx('X');
|
||||
uartTx('F');
|
||||
uartTx('C');
|
||||
uartTx('>');
|
||||
addCRC(&exfc, sizeof(exfc));
|
||||
for (uint8_t c = 0; c < sizeof(exfc); c++) {
|
||||
uartTx(((uint8_t *)&exfc)[c]);
|
||||
}
|
||||
}
|
||||
void espNotifyTimeOut(const uint8_t *src) {
|
||||
struct espXferComplete exfc;
|
||||
memcpy(&exfc.src, src, 8);
|
||||
uartTx('X');
|
||||
uartTx('T');
|
||||
uartTx('O');
|
||||
uartTx('>');
|
||||
addCRC(&exfc, sizeof(exfc));
|
||||
for (uint8_t c = 0; c < sizeof(exfc); c++) {
|
||||
uartTx(((uint8_t *)&exfc)[c]);
|
||||
}
|
||||
}
|
||||
void espNotifyAPInfo() {
|
||||
pr("TYP>%02X", HW_TYPE);
|
||||
pr("VER>%04X", version);
|
||||
pr("MAC>%02X%02X", mSelfMac[0], mSelfMac[1]);
|
||||
pr("%02X%02X", mSelfMac[2], mSelfMac[3]);
|
||||
pr("%02X%02X", mSelfMac[4], mSelfMac[5]);
|
||||
pr("%02X%02X", mSelfMac[6], mSelfMac[7]);
|
||||
pr("ZCH>%02X", curChannel);
|
||||
pr("ZPW>%02X", curPower);
|
||||
countSlots();
|
||||
pr("PEN>%02X", curPendingData);
|
||||
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, bool isSubGHz) {
|
||||
struct MacFrameNormal *rxHeader = (struct MacFrameNormal *)buffer;
|
||||
struct blockRequest *blockReq = (struct blockRequest *)(buffer + sizeof(struct MacFrameNormal) + 1);
|
||||
if (!checkCRC(blockReq, sizeof(struct blockRequest))) return;
|
||||
|
||||
// check if we're already talking to this mac
|
||||
if (memcmp(rxHeader->src, lastBlockMac, 8) == 0) {
|
||||
lastBlockRequest = millis();
|
||||
} else {
|
||||
// we weren't talking to this mac, see if there was a transfer in progress from another mac, recently
|
||||
if ((millis() - lastBlockRequest) > CONCURRENT_REQUEST_DELAY) {
|
||||
// mark this mac as the new current mac we're talking to
|
||||
memcpy((void *)lastBlockMac, (void *)rxHeader->src, 8);
|
||||
lastBlockRequest = millis();
|
||||
} else {
|
||||
// we're talking to another mac, let this mac know we can't accomodate another request right now
|
||||
pr("BUSY!\n");
|
||||
sendCancelXfer(rxHeader->src, isSubGHz);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// check if we have data for this mac
|
||||
if (findSlotForMac(rxHeader->src) == -1) {
|
||||
// no data for this mac, politely tell it to fuck off
|
||||
sendCancelXfer(rxHeader->src, isSubGHz);
|
||||
return;
|
||||
}
|
||||
|
||||
bool requestDataDownload = false;
|
||||
if ((blockReq->blockId != requestedData.blockId) || (blockReq->ver != requestedData.ver)) {
|
||||
// requested block isn't already in the buffer
|
||||
requestDataDownload = true;
|
||||
} else {
|
||||
// requested block is already in the buffer
|
||||
if (forceBlockDownload) {
|
||||
if ((millis() - nextBlockAttempt) > 380) {
|
||||
requestDataDownload = true;
|
||||
pr("FORCED\n");
|
||||
} else {
|
||||
pr("IGNORED\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// copy blockrequest into requested data
|
||||
memcpy(&requestedData, blockReq, sizeof(struct blockRequest));
|
||||
|
||||
struct MacFrameNormal *txHeader = (struct MacFrameNormal *)(radiotxbuffer + 1);
|
||||
struct blockRequestAck *blockRequestAck = (struct blockRequestAck *)(radiotxbuffer + sizeof(struct MacFrameNormal) + 2);
|
||||
radiotxbuffer[0] = sizeof(struct MacFrameNormal) + 1 + sizeof(struct blockRequestAck) + RAW_PKT_PADDING;
|
||||
radiotxbuffer[sizeof(struct MacFrameNormal) + 1] = PKT_BLOCK_REQUEST_ACK;
|
||||
|
||||
if (blockStartTimer == 0) {
|
||||
if (requestDataDownload) {
|
||||
if (highspeedSerial == true) {
|
||||
blockRequestAck->pleaseWaitMs = 140;
|
||||
} else {
|
||||
blockRequestAck->pleaseWaitMs = 550;
|
||||
}
|
||||
} else {
|
||||
// block is already in buffer
|
||||
blockRequestAck->pleaseWaitMs = 30;
|
||||
}
|
||||
} else {
|
||||
blockRequestAck->pleaseWaitMs = 30;
|
||||
}
|
||||
blockStartTimer = millis() + blockRequestAck->pleaseWaitMs;
|
||||
|
||||
memcpy(txHeader->src, mSelfMac, 8);
|
||||
memcpy(txHeader->dst, rxHeader->src, 8);
|
||||
|
||||
txHeader->pan = rxHeader->pan;
|
||||
txHeader->fcs.frameType = 1;
|
||||
txHeader->fcs.panIdCompressed = 1;
|
||||
txHeader->fcs.destAddrType = 3;
|
||||
txHeader->fcs.srcAddrType = 3;
|
||||
txHeader->seq = seq++;
|
||||
|
||||
addCRC((void *)blockRequestAck, sizeof(struct blockRequestAck));
|
||||
|
||||
radioTx(radiotxbuffer, isSubGHz);
|
||||
|
||||
// save the target for the blockdata
|
||||
memcpy(dstMac, rxHeader->src, 8);
|
||||
dstPan = rxHeader->pan;
|
||||
|
||||
if (requestDataDownload) {
|
||||
blockPosition = 0;
|
||||
espBlockRequest(&requestedData, rxHeader->src);
|
||||
nextBlockAttempt = millis();
|
||||
}
|
||||
}
|
||||
|
||||
void processAvailDataReq(uint8_t *buffer, bool isSubGHz) {
|
||||
struct MacFrameBcast *rxHeader = (struct MacFrameBcast *)buffer;
|
||||
struct AvailDataReq *availDataReq = (struct AvailDataReq *)(buffer + sizeof(struct MacFrameBcast) + 1);
|
||||
|
||||
if (!checkCRC(availDataReq, sizeof(struct AvailDataReq))) return;
|
||||
|
||||
// prepare tx buffer to send a response
|
||||
memset(radiotxbuffer, 0, sizeof(struct MacFrameNormal) + sizeof(struct AvailDataInfo) + 2); // 120);
|
||||
struct MacFrameNormal *txHeader = (struct MacFrameNormal *)(radiotxbuffer + 1);
|
||||
struct AvailDataInfo *availDataInfo = (struct AvailDataInfo *)(radiotxbuffer + sizeof(struct MacFrameNormal) + 2);
|
||||
radiotxbuffer[0] = sizeof(struct MacFrameNormal) + 1 + sizeof(struct AvailDataInfo) + RAW_PKT_PADDING;
|
||||
radiotxbuffer[sizeof(struct MacFrameNormal) + 1] = PKT_AVAIL_DATA_INFO;
|
||||
|
||||
// check to see if we have data available for this mac
|
||||
bool haveData = false;
|
||||
for (uint8_t c = 0; c < MAX_PENDING_MACS; c++) {
|
||||
if (pendingDataArr[c].attemptsLeft) {
|
||||
if (memcmp(pendingDataArr[c].targetMac, rxHeader->src, 8) == 0) {
|
||||
haveData = true;
|
||||
memcpy((void *)availDataInfo, &(pendingDataArr[c].availdatainfo), sizeof(struct AvailDataInfo));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// couldn't find data for this mac
|
||||
if (!haveData) availDataInfo->dataType = DATATYPE_NOUPDATE;
|
||||
|
||||
memcpy(txHeader->src, mSelfMac, 8);
|
||||
memcpy(txHeader->dst, rxHeader->src, 8);
|
||||
txHeader->pan = rxHeader->dstPan;
|
||||
txHeader->fcs.frameType = 1;
|
||||
txHeader->fcs.panIdCompressed = 1;
|
||||
txHeader->fcs.destAddrType = 3;
|
||||
txHeader->fcs.srcAddrType = 3;
|
||||
txHeader->seq = seq++;
|
||||
addCRC(availDataInfo, sizeof(struct AvailDataInfo));
|
||||
radioTx(radiotxbuffer, isSubGHz);
|
||||
memset(lastAckMac, 0, 8); // reset lastAckMac, so we can record if we've received exactly one ack packet
|
||||
espNotifyAvailDataReq(availDataReq, rxHeader->src);
|
||||
}
|
||||
void processXferComplete(uint8_t *buffer, bool isSubGHz) {
|
||||
struct MacFrameNormal *rxHeader = (struct MacFrameNormal *)buffer;
|
||||
sendXferCompleteAck(rxHeader->src, isSubGHz);
|
||||
if (memcmp(lastAckMac, rxHeader->src, 8) != 0) {
|
||||
memcpy((void *)lastAckMac, (void *)rxHeader->src, 8);
|
||||
espNotifyXferComplete(rxHeader->src);
|
||||
int8_t slot = findSlotForMac(rxHeader->src);
|
||||
if (slot != -1) pendingDataArr[slot].attemptsLeft = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void processTagReturnData(uint8_t *buffer, uint8_t len, bool isSubGHz) {
|
||||
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, isSubGHz);
|
||||
|
||||
espNotifyTagReturnData(rxframe->src, len - (sizeof(struct MacFrameBcast) + 1));
|
||||
}
|
||||
|
||||
// send block data to the tag
|
||||
void sendPart(uint8_t partNo, bool isSubGHz) {
|
||||
struct MacFrameNormal *frameHeader = (struct MacFrameNormal *)(radiotxbuffer + 1);
|
||||
struct blockPart *blockPart = (struct blockPart *)(radiotxbuffer + sizeof(struct MacFrameNormal) + 2);
|
||||
memset(radiotxbuffer + 1, 0, sizeof(struct blockPart) + sizeof(struct MacFrameNormal));
|
||||
radiotxbuffer[sizeof(struct MacFrameNormal) + 1] = PKT_BLOCK_PART;
|
||||
radiotxbuffer[0] = sizeof(struct MacFrameNormal) + sizeof(struct blockPart) + BLOCK_PART_DATA_SIZE + 1 + RAW_PKT_PADDING;
|
||||
memcpy(frameHeader->src, mSelfMac, 8);
|
||||
memcpy(frameHeader->dst, dstMac, 8);
|
||||
blockPart->blockId = requestedData.blockId;
|
||||
blockPart->blockPart = partNo;
|
||||
memcpy(&(blockPart->data), blockbuffer + (partNo * BLOCK_PART_DATA_SIZE), BLOCK_PART_DATA_SIZE);
|
||||
addCRC(blockPart, sizeof(struct blockPart) + BLOCK_PART_DATA_SIZE);
|
||||
frameHeader->fcs.frameType = 1;
|
||||
frameHeader->fcs.panIdCompressed = 1;
|
||||
frameHeader->fcs.destAddrType = 3;
|
||||
frameHeader->fcs.srcAddrType = 3;
|
||||
frameHeader->seq = seq++;
|
||||
frameHeader->pan = dstPan;
|
||||
radioTx(radiotxbuffer, isSubGHz);
|
||||
}
|
||||
void sendBlockData(bool isSubGHz) {
|
||||
if (getBlockDataLength() == 0) {
|
||||
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++) {
|
||||
if (requestedData.requestedParts[c / 8] & (1 << (c % 8))) {
|
||||
sendPart(c, isSubGHz);
|
||||
partNo++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
void sendXferCompleteAck(uint8_t *dst, bool isSubGHz) {
|
||||
struct MacFrameNormal *frameHeader = (struct MacFrameNormal *)(radiotxbuffer + 1);
|
||||
memset(radiotxbuffer + 1, 0, sizeof(struct blockPart) + sizeof(struct MacFrameNormal));
|
||||
radiotxbuffer[sizeof(struct MacFrameNormal) + 1] = PKT_XFER_COMPLETE_ACK;
|
||||
radiotxbuffer[0] = sizeof(struct MacFrameNormal) + 1 + RAW_PKT_PADDING;
|
||||
memcpy(frameHeader->src, mSelfMac, 8);
|
||||
memcpy(frameHeader->dst, dst, 8);
|
||||
frameHeader->fcs.frameType = 1;
|
||||
frameHeader->fcs.panIdCompressed = 1;
|
||||
frameHeader->fcs.destAddrType = 3;
|
||||
frameHeader->fcs.srcAddrType = 3;
|
||||
frameHeader->seq = seq++;
|
||||
frameHeader->pan = dstPan;
|
||||
radioTx(radiotxbuffer, isSubGHz);
|
||||
}
|
||||
void sendCancelXfer(uint8_t *dst, bool isSubGHz) {
|
||||
struct MacFrameNormal *frameHeader = (struct MacFrameNormal *)(radiotxbuffer + 1);
|
||||
memset(radiotxbuffer + 1, 0, sizeof(struct blockPart) + sizeof(struct MacFrameNormal));
|
||||
radiotxbuffer[sizeof(struct MacFrameNormal) + 1] = PKT_CANCEL_XFER;
|
||||
radiotxbuffer[0] = sizeof(struct MacFrameNormal) + 1 + RAW_PKT_PADDING;
|
||||
memcpy(frameHeader->src, mSelfMac, 8);
|
||||
memcpy(frameHeader->dst, dst, 8);
|
||||
frameHeader->fcs.frameType = 1;
|
||||
frameHeader->fcs.panIdCompressed = 1;
|
||||
frameHeader->fcs.destAddrType = 3;
|
||||
frameHeader->fcs.srcAddrType = 3;
|
||||
frameHeader->seq = seq++;
|
||||
frameHeader->pan = dstPan;
|
||||
radioTx(radiotxbuffer, isSubGHz);
|
||||
}
|
||||
void sendPong(void *buf, bool isSubGHz) {
|
||||
struct MacFrameBcast *rxframe = (struct MacFrameBcast *)buf;
|
||||
struct MacFrameNormal *frameHeader = (struct MacFrameNormal *)(radiotxbuffer + 1);
|
||||
radiotxbuffer[sizeof(struct MacFrameNormal) + 1] = PKT_PONG;
|
||||
radiotxbuffer[sizeof(struct MacFrameNormal) + 2] = curChannel;
|
||||
radiotxbuffer[0] = sizeof(struct MacFrameNormal) + 1 + 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, isSubGHz);
|
||||
}
|
||||
|
||||
extern uint8_t mSelfMac[8];
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
|
||||
init_led();
|
||||
init_second_uart();
|
||||
|
||||
requestedData.blockId = 0xFF;
|
||||
// clear the array with pending information
|
||||
memset(pendingDataArr, 0, sizeof(pendingDataArr));
|
||||
|
||||
radio_init(curChannel);
|
||||
radioSetTxPower(10);
|
||||
|
||||
pr("RES>");
|
||||
pr("RDY>");
|
||||
Serial.printf("C6 ready!\r\n");
|
||||
|
||||
housekeepingTimer = millis();
|
||||
}
|
||||
|
||||
bool isSubGhzRx = false;
|
||||
void loop() {
|
||||
while ((millis() - housekeepingTimer) < ((1000 * HOUSEKEEPING_INTERVAL) - 100)) {
|
||||
int8_t ret = commsRxUnencrypted(radiorxbuffer, &isSubGhzRx);
|
||||
if (ret > 1) {
|
||||
if (0)
|
||||
{
|
||||
Serial.printf("RXed packet len %u :", ret);
|
||||
for (int t = 0; t < ret; t++) {
|
||||
Serial.printf(" %02x", radiorxbuffer[t]);
|
||||
}
|
||||
Serial.printf("\n");
|
||||
}
|
||||
|
||||
led_flash(0);
|
||||
// received a packet, lets see what it is
|
||||
switch (getPacketType(radiorxbuffer)) {
|
||||
case PKT_AVAIL_DATA_REQ:
|
||||
if (ret == 28) {
|
||||
// old version of the AvailDataReq struct, set all the new fields to zero, so it will pass the CRC
|
||||
memset(radiorxbuffer + 1 + sizeof(struct MacFrameBcast) + sizeof(struct oldAvailDataReq), 0,
|
||||
sizeof(struct AvailDataReq) - sizeof(struct oldAvailDataReq) + 2);
|
||||
processAvailDataReq(radiorxbuffer, isSubGhzRx);
|
||||
} else if (ret == 40) {
|
||||
// new version of the AvailDataReq struct
|
||||
processAvailDataReq(radiorxbuffer, isSubGhzRx);
|
||||
}
|
||||
break;
|
||||
case PKT_BLOCK_REQUEST:
|
||||
processBlockRequest(radiorxbuffer, 1, isSubGhzRx);
|
||||
break;
|
||||
case PKT_BLOCK_PARTIAL_REQUEST:
|
||||
processBlockRequest(radiorxbuffer, 0, isSubGhzRx);
|
||||
break;
|
||||
case PKT_XFER_COMPLETE:
|
||||
processXferComplete(radiorxbuffer, isSubGhzRx);
|
||||
break;
|
||||
case PKT_PING:
|
||||
sendPong(radiorxbuffer, isSubGhzRx);
|
||||
break;
|
||||
case PKT_AVAIL_DATA_SHORTREQ:
|
||||
// a short AvailDataReq is basically a very short (1 byte payload) packet that requires little preparation on the tx side, for optimal
|
||||
// battery use bytes of the struct are set 0, so it passes the checksum test, and the ESP32 can detect that no interesting payload is
|
||||
// sent
|
||||
if (ret == 18) {
|
||||
memset(radiorxbuffer + 1 + sizeof(struct MacFrameBcast), 0, sizeof(struct AvailDataReq) + 2);
|
||||
processAvailDataReq(radiorxbuffer, isSubGhzRx);
|
||||
}
|
||||
break;
|
||||
case PKT_TAG_RETURN_DATA:
|
||||
processTagReturnData(radiorxbuffer, ret, isSubGhzRx);
|
||||
break;
|
||||
default:
|
||||
Serial.printf("t=%02X\r\n", getPacketType(radiorxbuffer));
|
||||
break;
|
||||
}
|
||||
} else if (blockStartTimer == 0) {
|
||||
delay(10);
|
||||
}
|
||||
|
||||
uint8_t curr_char;
|
||||
while (getRxCharSecond(&curr_char)) processSerial(curr_char);
|
||||
|
||||
if (blockStartTimer) {
|
||||
if (millis() > blockStartTimer) {
|
||||
sendBlockData(isSubGhzRx);
|
||||
blockStartTimer = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
espNotifyTimeOut(pendingDataArr[cCount].targetMac);
|
||||
}
|
||||
pendingDataArr[cCount].attemptsLeft = 0;
|
||||
} else if (pendingDataArr[cCount].attemptsLeft > 1) {
|
||||
pendingDataArr[cCount].attemptsLeft--;
|
||||
if (pendingDataArr[cCount].availdatainfo.nextCheckIn) pendingDataArr[cCount].availdatainfo.nextCheckIn--;
|
||||
}
|
||||
}
|
||||
housekeepingTimer = millis();
|
||||
}
|
||||
44
ARM_Tag_FW/Arduino_OpenEPaperLink_C6_AP/led.cpp
Normal file
44
ARM_Tag_FW/Arduino_OpenEPaperLink_C6_AP/led.cpp
Normal file
@@ -0,0 +1,44 @@
|
||||
#include "led.h"
|
||||
#include "driver/gpio.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/queue.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/timers.h"
|
||||
#include "proto.h"
|
||||
#include <Arduino.h>
|
||||
#include <inttypes.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#define NUM_LEDS 2
|
||||
|
||||
const uint8_t led_pins[NUM_LEDS] = { LED1, LED2 };
|
||||
TimerHandle_t led_timers[NUM_LEDS] = { 0 };
|
||||
|
||||
void led_timer_callback(TimerHandle_t xTimer) {
|
||||
int led_index = (int)pvTimerGetTimerID(xTimer);
|
||||
if (led_index >= 0 && led_index < NUM_LEDS) {
|
||||
digitalWrite(led_pins[led_index], 0);
|
||||
}
|
||||
}
|
||||
|
||||
void init_led() {
|
||||
pinMode(LED1,OUTPUT);
|
||||
pinMode(LED2,OUTPUT);
|
||||
|
||||
for (int i = 0; i < NUM_LEDS; i++) {
|
||||
led_timers[i] = xTimerCreate("led_timer", pdMS_TO_TICKS(50), pdFALSE, (void *)i, led_timer_callback);
|
||||
}
|
||||
}
|
||||
|
||||
void led_flash(int nr) {
|
||||
digitalWrite(led_pins[nr], 1);
|
||||
if (nr >= 0 && nr < NUM_LEDS) {
|
||||
xTimerStart(led_timers[nr], 0);
|
||||
}
|
||||
}
|
||||
|
||||
void led_set(int nr, bool state) {
|
||||
digitalWrite(nr, state);
|
||||
}
|
||||
6
ARM_Tag_FW/Arduino_OpenEPaperLink_C6_AP/led.h
Normal file
6
ARM_Tag_FW/Arduino_OpenEPaperLink_C6_AP/led.h
Normal file
@@ -0,0 +1,6 @@
|
||||
#pragma once
|
||||
#include <stdbool.h>
|
||||
|
||||
void init_led();
|
||||
void led_set(int nr, bool state);
|
||||
void led_flash(int nr);
|
||||
190
ARM_Tag_FW/Arduino_OpenEPaperLink_C6_AP/proto.h
Normal file
190
ARM_Tag_FW/Arduino_OpenEPaperLink_C6_AP/proto.h
Normal file
@@ -0,0 +1,190 @@
|
||||
#ifndef _PROTO_H_
|
||||
#define _PROTO_H_
|
||||
#include <stdint.h>
|
||||
|
||||
#define LED1 22
|
||||
#define LED2 23
|
||||
|
||||
#define PROTO_PAN_ID (0x4447) // PAN ID compression shall be used
|
||||
|
||||
#define RADIO_MAX_PACKET_LEN (125) // useful payload, not including the crc
|
||||
|
||||
#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)
|
||||
|
||||
#define SHORT_MAC_UNUSED (0x10000000UL) // for radioRxFilterCfg's myShortMac
|
||||
|
||||
struct MacFcs {
|
||||
uint8_t frameType : 3;
|
||||
uint8_t secure : 1;
|
||||
uint8_t framePending : 1;
|
||||
uint8_t ackReqd : 1;
|
||||
uint8_t panIdCompressed : 1;
|
||||
uint8_t rfu1 : 1;
|
||||
uint8_t rfu2 : 2;
|
||||
uint8_t destAddrType : 2;
|
||||
uint8_t frameVer : 2;
|
||||
uint8_t srcAddrType : 2;
|
||||
} __attribute__((packed, aligned(1)));
|
||||
|
||||
struct MacFrameFromMaster {
|
||||
struct MacFcs fcs;
|
||||
uint8_t seq;
|
||||
uint16_t pan;
|
||||
uint8_t dst[8];
|
||||
uint16_t from;
|
||||
} __attribute__((packed, aligned(1)));
|
||||
|
||||
struct MacFrameNormal {
|
||||
struct MacFcs fcs;
|
||||
uint8_t seq;
|
||||
uint16_t pan;
|
||||
uint8_t dst[8];
|
||||
uint8_t src[8];
|
||||
} __attribute__((packed, aligned(1)));
|
||||
|
||||
struct MacFrameBcast {
|
||||
struct MacFcs fcs;
|
||||
uint8_t seq;
|
||||
uint16_t dstPan;
|
||||
uint16_t dstAddr;
|
||||
uint16_t srcPan;
|
||||
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
|
||||
#define PKT_BLOCK_PARTIAL_REQUEST 0xE7
|
||||
#define PKT_BLOCK_REQUEST_ACK 0xE9
|
||||
#define PKT_BLOCK_REQUEST 0xE4
|
||||
#define PKT_BLOCK_PART 0xE8
|
||||
#define PKT_XFER_COMPLETE 0xEA
|
||||
#define PKT_XFER_COMPLETE_ACK 0xEB
|
||||
#define PKT_CANCEL_XFER 0xEC
|
||||
#define PKT_PING 0xED
|
||||
#define PKT_PONG 0xEE
|
||||
|
||||
struct AvailDataReq {
|
||||
uint8_t checksum;
|
||||
uint8_t lastPacketLQI;
|
||||
int8_t lastPacketRSSI;
|
||||
int8_t temperature;
|
||||
uint16_t batteryMv;
|
||||
uint8_t hwType;
|
||||
uint8_t wakeupReason;
|
||||
uint8_t capabilities;
|
||||
uint16_t tagSoftwareVersion;
|
||||
uint8_t currentChannel;
|
||||
uint8_t customMode;
|
||||
uint8_t reserved[8];
|
||||
} __attribute__((packed, aligned(1)));
|
||||
|
||||
struct oldAvailDataReq {
|
||||
uint8_t checksum;
|
||||
uint8_t lastPacketLQI;
|
||||
int8_t lastPacketRSSI;
|
||||
int8_t temperature;
|
||||
uint16_t batteryMv;
|
||||
uint8_t hwType;
|
||||
uint8_t wakeupReason;
|
||||
uint8_t capabilities;
|
||||
} __attribute__((packed, aligned(1)));
|
||||
|
||||
struct AvailDataInfo {
|
||||
uint8_t checksum;
|
||||
uint64_t dataVer; // MD5 of potential traffic
|
||||
uint32_t dataSize;
|
||||
uint8_t dataType;
|
||||
uint8_t dataTypeArgument; // extra specification or instruction for the tag (LUT to be used for drawing image)
|
||||
uint16_t nextCheckIn; // when should the tag check-in again? Measured in minutes
|
||||
} __attribute__((packed, aligned(1)));
|
||||
|
||||
struct pendingData {
|
||||
struct AvailDataInfo availdatainfo;
|
||||
uint16_t attemptsLeft;
|
||||
uint8_t targetMac[8];
|
||||
} __attribute__((packed, aligned(1)));
|
||||
|
||||
struct blockPart {
|
||||
uint8_t checksum;
|
||||
uint8_t blockId;
|
||||
uint8_t blockPart;
|
||||
uint8_t data[];
|
||||
} __attribute__((packed, aligned(1)));
|
||||
|
||||
struct blockData {
|
||||
uint16_t size;
|
||||
uint16_t checksum;
|
||||
uint8_t data[];
|
||||
} __attribute__((packed, aligned(1)));
|
||||
|
||||
#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
|
||||
#define BLOCK_MAX_PARTS 42
|
||||
#define BLOCK_DATA_SIZE 4096UL
|
||||
#define BLOCK_XFER_BUFFER_SIZE BLOCK_DATA_SIZE + sizeof(struct blockData)
|
||||
#define BLOCK_REQ_PARTS_BYTES 6
|
||||
|
||||
struct blockRequest {
|
||||
uint8_t checksum;
|
||||
uint64_t ver;
|
||||
uint8_t blockId;
|
||||
uint8_t type;
|
||||
uint8_t requestedParts[BLOCK_REQ_PARTS_BYTES];
|
||||
} __attribute__((packed, aligned(1)));
|
||||
|
||||
struct blockRequestAck {
|
||||
uint8_t checksum;
|
||||
uint16_t pleaseWaitMs;
|
||||
} __attribute__((packed, aligned(1)));
|
||||
|
||||
struct espBlockRequest {
|
||||
uint8_t checksum;
|
||||
uint64_t ver;
|
||||
uint8_t blockId;
|
||||
uint8_t src[8];
|
||||
} __attribute__((packed, aligned(1)));
|
||||
|
||||
struct espXferComplete {
|
||||
uint8_t checksum;
|
||||
uint8_t src[8];
|
||||
} __attribute__((packed, aligned(1)));
|
||||
|
||||
struct espAvailDataReq {
|
||||
uint8_t checksum;
|
||||
uint8_t src[8];
|
||||
struct AvailDataReq adr;
|
||||
} __attribute__((packed, aligned(1)));
|
||||
|
||||
struct espSetChannelPower {
|
||||
uint8_t checksum;
|
||||
uint8_t channel;
|
||||
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
|
||||
155
ARM_Tag_FW/Arduino_OpenEPaperLink_C6_AP/radio.cpp
Normal file
155
ARM_Tag_FW/Arduino_OpenEPaperLink_C6_AP/radio.cpp
Normal file
@@ -0,0 +1,155 @@
|
||||
#include "radio.h"
|
||||
#include "driver/gpio.h"
|
||||
#include "driver/uart.h"
|
||||
#include "esp_err.h"
|
||||
#include "esp_event.h"
|
||||
#include "esp_ieee802154.h"
|
||||
#include "esp_phy_init.h"
|
||||
#include "esp_timer.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/queue.h"
|
||||
#include "freertos/task.h"
|
||||
#include "led.h"
|
||||
#include "subGhz.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 <esp_mac.h>
|
||||
#include <math.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <Arduino.h>
|
||||
|
||||
bool has_sub_ghz = false;
|
||||
|
||||
uint8_t mSelfMac[8];
|
||||
volatile uint8_t isInTransmit = 0;
|
||||
QueueHandle_t packet_buffer = NULL;
|
||||
|
||||
void esp_ieee802154_receive_done(uint8_t *frame, esp_ieee802154_frame_info_t *frame_info) {
|
||||
Serial.printf("RADIO info RX %d\r\n", frame[0]);
|
||||
BaseType_t xHigherPriorityTaskWoken;
|
||||
static uint8_t inner_rxPKT[130];
|
||||
memcpy(inner_rxPKT, &frame[0], frame[0] + 1);
|
||||
xQueueSendFromISR(packet_buffer, (void *)&inner_rxPKT, &xHigherPriorityTaskWoken);
|
||||
portYIELD_FROM_ISR_ARG(xHigherPriorityTaskWoken);
|
||||
}
|
||||
|
||||
void esp_ieee802154_transmit_failed(const uint8_t *frame, esp_ieee802154_tx_error_t error) {
|
||||
isInTransmit = 0;
|
||||
Serial.printf("RADIO err TX Err: %d\r\n", error);
|
||||
}
|
||||
|
||||
void esp_ieee802154_transmit_done(const uint8_t *frame, const uint8_t *ack, esp_ieee802154_frame_info_t *ack_frame_info) {
|
||||
isInTransmit = 0;
|
||||
Serial.printf("RADIO info TX %d\r\n", frame[0]);
|
||||
}
|
||||
|
||||
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();
|
||||
esp_ieee802154_set_channel(ch);
|
||||
// esp_ieee802154_set_txpower(int8_t power);
|
||||
esp_ieee802154_set_panid(PROTO_PAN_ID);
|
||||
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);
|
||||
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);
|
||||
delay(100);
|
||||
led_flash(0);
|
||||
delay(100);
|
||||
led_flash(1);
|
||||
delay(100);
|
||||
led_flash(0);
|
||||
|
||||
Serial.printf("RADIO Receiver ready, panId=0x%04x, channel=%d, long=%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x, short=%04x\r\n",
|
||||
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());
|
||||
|
||||
|
||||
// Lets here take care of the SubGhz Init
|
||||
if (!init_subGhz())
|
||||
Serial.printf("Sub-GHz radio init failed\r\n");
|
||||
else if (!tiRadioSetChannel(ch))
|
||||
Serial.printf("SubGHz radio channel fail\r\n");
|
||||
else
|
||||
has_sub_ghz = true;
|
||||
|
||||
Serial.printf("SubGhz %s\r\n", has_sub_ghz ? "Active" : "Not Found");
|
||||
if (has_sub_ghz) {
|
||||
tiRadioRxFilterCfg(mSelfMac, SHORT_MAC_UNUSED, PROTO_PAN_ID, true);
|
||||
tiRadioTxConfigure(mSelfMac, SHORT_MAC_UNUSED, PROTO_PAN_ID);
|
||||
tiRadioRxEnable(true, false);
|
||||
}
|
||||
}
|
||||
|
||||
// uint32_t lastZbTx = 0;
|
||||
bool radioTx(uint8_t *packet, bool subGhz) {
|
||||
led_flash(1);
|
||||
if (has_sub_ghz && subGhz) {
|
||||
tiRadioTxLL(packet);
|
||||
} else {
|
||||
static uint8_t txPKT[130];
|
||||
while (isInTransmit) {
|
||||
}
|
||||
// while (millis() - lastZbTx < 6) {
|
||||
// }
|
||||
// lastZbTx = millis();
|
||||
memcpy(txPKT, packet, packet[0]);
|
||||
isInTransmit = 1;
|
||||
esp_ieee802154_transmit(txPKT, false);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
void radioSetChannel(uint8_t ch) {
|
||||
radio_init(ch);
|
||||
if (has_sub_ghz)
|
||||
tiRadioSetChannel(ch);
|
||||
}
|
||||
|
||||
void radioSetTxPower(uint8_t power) {}
|
||||
|
||||
int8_t commsRxUnencrypted(uint8_t *data, bool *subGhzRx) {
|
||||
int8_t rssi_sub_rx = 0;
|
||||
uint8_t lqi_sub_rx = 0;
|
||||
|
||||
static uint8_t inner_rxPKT_out[135];
|
||||
if (xQueueReceive(packet_buffer, (void *)&inner_rxPKT_out, pdMS_TO_TICKS(100)) == pdTRUE) {
|
||||
memcpy(data, &inner_rxPKT_out[1], inner_rxPKT_out[0] + 1);
|
||||
*subGhzRx = false; // This is Normal data
|
||||
return inner_rxPKT_out[0] - 2;
|
||||
}
|
||||
if (has_sub_ghz) {
|
||||
int32_t ret_sub_rx_len = tiRadioRxDequeuePkt(inner_rxPKT_out, sizeof(inner_rxPKT_out), &rssi_sub_rx, &lqi_sub_rx);
|
||||
if (ret_sub_rx_len > 0)
|
||||
{
|
||||
//Serial.printf("Got Sub Ghz Len %i data: %i %u\r\n", ret_sub_rx, rssi_sub_rx, lqi_sub_rx);
|
||||
memcpy(data, inner_rxPKT_out, ret_sub_rx_len);
|
||||
*subGhzRx = true; // This is SubGHz data
|
||||
return ret_sub_rx_len;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
11
ARM_Tag_FW/Arduino_OpenEPaperLink_C6_AP/radio.h
Normal file
11
ARM_Tag_FW/Arduino_OpenEPaperLink_C6_AP/radio.h
Normal file
@@ -0,0 +1,11 @@
|
||||
#pragma once
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
extern uint8_t mSelfMac[8];
|
||||
|
||||
void radio_init(uint8_t ch);
|
||||
bool radioTx(uint8_t *packet, bool subGhz);
|
||||
void radioSetChannel(uint8_t ch);
|
||||
void radioSetTxPower(uint8_t power);
|
||||
int8_t commsRxUnencrypted(uint8_t *data, bool *subGhzRx);
|
||||
125
ARM_Tag_FW/Arduino_OpenEPaperLink_C6_AP/second_uart.cpp
Normal file
125
ARM_Tag_FW/Arduino_OpenEPaperLink_C6_AP/second_uart.cpp
Normal file
@@ -0,0 +1,125 @@
|
||||
#include <esp_mac.h>
|
||||
#include <math.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <Arduino.h>
|
||||
#include "driver/gpio.h"
|
||||
#include "driver/uart.h"
|
||||
#include "esp_err.h"
|
||||
#include "esp_event.h"
|
||||
#include "esp_ieee802154.h"
|
||||
#include "esp_phy_init.h"
|
||||
#include "esp_timer.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/queue.h"
|
||||
#include "freertos/task.h"
|
||||
#include "nvs.h"
|
||||
#include "nvs_flash.h"
|
||||
#include "proto.h"
|
||||
#include "sdkconfig.h"
|
||||
#include "soc/uart_struct.h"
|
||||
#include "soc/lp_uart_reg.h"
|
||||
#include "second_uart.h"
|
||||
|
||||
#if defined(CONFIG_OEPL_HARDWARE_PROFILE_POE_AP)
|
||||
#define CONFIG_OEPL_HARDWARE_UART_TX 5
|
||||
#define CONFIG_OEPL_HARDWARE_UART_RX 18
|
||||
#else
|
||||
#if !defined(CONFIG_OEPL_HARDWARE_UART_TX) || !defined(CONFIG_OEPL_HARDWARE_UART_RX)
|
||||
#define CONFIG_OEPL_HARDWARE_UART_TX 3
|
||||
#define CONFIG_OEPL_HARDWARE_UART_RX 2
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define BUF_SIZE (1024)
|
||||
#define RD_BUF_SIZE (BUF_SIZE)
|
||||
static QueueHandle_t uart0_queue;
|
||||
|
||||
#define MAX_BUFF_POS 8000
|
||||
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 = {
|
||||
.baud_rate = 115200,
|
||||
.data_bits = UART_DATA_8_BITS,
|
||||
.parity = UART_PARITY_DISABLE,
|
||||
.stop_bits = UART_STOP_BITS_1,
|
||||
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
|
||||
.source_clk = UART_SCLK_DEFAULT,
|
||||
};
|
||||
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, 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);
|
||||
}
|
||||
|
||||
void uart_switch_speed(int baudrate) {
|
||||
uart_config_t uart_config = {
|
||||
.baud_rate = baudrate,
|
||||
.data_bits = UART_DATA_8_BITS,
|
||||
.parity = UART_PARITY_DISABLE,
|
||||
.stop_bits = UART_STOP_BITS_1,
|
||||
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
|
||||
.source_clk = UART_SCLK_DEFAULT,
|
||||
};
|
||||
ESP_ERROR_CHECK(uart_param_config(1, &uart_config));
|
||||
}
|
||||
|
||||
void uartTx(uint8_t data) {
|
||||
uart_write_bytes(1, (const char *)&data, 1);
|
||||
}
|
||||
|
||||
|
||||
bool getRxCharSecond(uint8_t *newChar) {
|
||||
if (curr_buff_pos != worked_buff_pos) {
|
||||
*newChar = buff_pos[worked_buff_pos];
|
||||
worked_buff_pos++;
|
||||
worked_buff_pos %= MAX_BUFF_POS;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static void uart_event_task(void *pvParameters) {
|
||||
uart_event_t event;
|
||||
uint8_t *dtmp = (uint8_t *)malloc(RD_BUF_SIZE);
|
||||
for (;;) {
|
||||
if (xQueueReceive(uart0_queue, (void *)&event, (TickType_t)portMAX_DELAY)) {
|
||||
bzero(dtmp, RD_BUF_SIZE);
|
||||
switch (event.type) {
|
||||
case UART_DATA:
|
||||
uart_read_bytes(1, dtmp, event.size, portMAX_DELAY);
|
||||
for (int i = 0; i < event.size; i++) {
|
||||
buff_pos[curr_buff_pos] = dtmp[i];
|
||||
curr_buff_pos++;
|
||||
curr_buff_pos %= MAX_BUFF_POS;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
Serial.printf("Second UART uart event type: %d\r\n", event.type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
free(dtmp);
|
||||
dtmp = NULL;
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
void uart_printf(const char *format, ...) {
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
|
||||
char buffer[128];
|
||||
int len = vsnprintf(buffer, sizeof(buffer), format, args);
|
||||
|
||||
va_end(args);
|
||||
|
||||
if (len > 0) {
|
||||
uart_write_bytes(1, buffer, len);
|
||||
}
|
||||
}
|
||||
13
ARM_Tag_FW/Arduino_OpenEPaperLink_C6_AP/second_uart.h
Normal file
13
ARM_Tag_FW/Arduino_OpenEPaperLink_C6_AP/second_uart.h
Normal file
@@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
void init_second_uart();
|
||||
void uart_switch_speed(int baudrate);
|
||||
|
||||
void uartTx(uint8_t data);
|
||||
bool getRxCharSecond(uint8_t *newChar);
|
||||
|
||||
void uart_printf(const char *format, ...);
|
||||
|
||||
#define pr uart_printf
|
||||
609
ARM_Tag_FW/Arduino_OpenEPaperLink_C6_AP/subGhz.cpp
Normal file
609
ARM_Tag_FW/Arduino_OpenEPaperLink_C6_AP/subGhz.cpp
Normal file
@@ -0,0 +1,609 @@
|
||||
|
||||
// This code is heavily depending on Dmitrys wonderful Work !
|
||||
// https://dmitry.gr/?r=05.Projects&proj=29.%20eInk%20Price%20Tags
|
||||
// Ported and modified to fit the OpenEPaperLink Project by ATC1441 (ATCnetz.de) ~01.2024
|
||||
|
||||
#include "subGhz.h"
|
||||
#include "driver/gpio.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/queue.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/timers.h"
|
||||
#include "proto.h"
|
||||
#include <Arduino.h>
|
||||
#include <SPI.h>
|
||||
#include <inttypes.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#define SUB_GHZ_CH_OFST 11
|
||||
#define SUB_GHZ_NUM_CHANNELS 25
|
||||
|
||||
/*
|
||||
//we configure GDO_2 is for TX.has_fifo_space
|
||||
//we configure GDO_0 is for RX.has_data
|
||||
WIRING:
|
||||
*/
|
||||
#define sub_CS 4
|
||||
#define sub_GD0 5
|
||||
#define sub_GD2 6
|
||||
#define sub_MISO 7
|
||||
#define sub_CLK 0
|
||||
#define sub_MOSI 1
|
||||
|
||||
#define CMD_SRES 0x30
|
||||
#define CMD_SFSTXON 0x31
|
||||
#define CMD_SXOFF 0x32
|
||||
#define CMD_SCAL 0x33
|
||||
#define CMD_SRX 0x34
|
||||
#define CMD_STX 0x35
|
||||
#define CMD_SIDLE 0x36
|
||||
#define CMD_SWOR 0x38
|
||||
#define CMD_SPWD 0x39
|
||||
#define CMD_SFRX 0x3a
|
||||
#define CMD_SFTX 0x3b
|
||||
#define CMD_SWORRST 0x3c
|
||||
#define CMD_SNOP 0x3d
|
||||
|
||||
#define REG_IOCFG2 0x00
|
||||
#define REG_IOCFG1 0x01
|
||||
#define REG_IOCFG0 0x02
|
||||
#define REG_FIFOTHR 0x03
|
||||
#define REG_SYNC1 0x04
|
||||
#define REG_SYNC0 0x05
|
||||
#define REG_PKTLEN 0x06
|
||||
#define REG_PKTCTRL1 0x07
|
||||
#define REG_PKTCTRL0 0x08
|
||||
#define REG_ADDR 0x09
|
||||
#define REG_CHANNR 0x0a
|
||||
#define REG_FSCTRL1 0x0b
|
||||
#define REG_FSCTRL0 0x0c
|
||||
#define REG_FREQ2 0x0d
|
||||
#define REG_FREQ1 0x0e
|
||||
#define REG_FREQ0 0x0f
|
||||
#define REG_MDMCFG4 0x10
|
||||
#define REG_MDMCFG3 0x11
|
||||
#define REG_MDMCFG2 0x12
|
||||
#define REG_MDMCFG1 0x13
|
||||
#define REG_MDMCFG0 0x14
|
||||
#define REG_DEVIATN 0x15
|
||||
#define REG_MCSM2 0x16
|
||||
#define REG_MCSM1 0x17
|
||||
#define REG_MCSM0 0x18
|
||||
#define REG_FOCCFG 0x19
|
||||
#define REG_BSCFG 0x1a
|
||||
#define REG_AGCTRL2 0x1b
|
||||
#define REG_AGCTRL1 0x1c
|
||||
#define REG_AGCTRL0 0x1d
|
||||
#define REG_WOREVT1 0x1e
|
||||
#define REG_WOREVT0 0x1f
|
||||
#define REG_WORCTRL 0x20
|
||||
#define REG_FREND1 0x21
|
||||
#define REG_FREND0 0x22
|
||||
#define REG_FSCAL3 0x23
|
||||
#define REG_FSCAL2 0x24
|
||||
#define REG_FSCAL1 0x25
|
||||
#define REG_FSCAL0 0x26
|
||||
#define REG_RCCTRL1 0x27
|
||||
#define REG_RCCTRL0 0x28
|
||||
#define REG_FSTEST 0x29
|
||||
#define REG_PTEST 0x2a
|
||||
#define REG_AGCTEST 0x2b
|
||||
#define REG_TEST2 0x2c
|
||||
#define REG_TEST1 0x2d
|
||||
#define REG_TEST0 0x2e
|
||||
|
||||
#define REG_PATABLE 0x3e
|
||||
#define REG_FIFO 0x3f
|
||||
|
||||
#define REG_PARTNUM 0xf0
|
||||
#define REG_VERSION 0xf1
|
||||
#define REG_FREQEST 0xf2
|
||||
#define REG_LQI 0xf3
|
||||
#define REG_RSSI 0xf4
|
||||
#define REG_MARCSTATE 0xf5
|
||||
#define REG_WORTIME1 0xf6
|
||||
#define REG_WORTIME0 0xf7
|
||||
#define REG_PKTSTATUS 0xf8
|
||||
#define REG_VCO_VC_DAC 0xf9
|
||||
#define REG_TXBYTES 0xfa
|
||||
#define REG_RXBYTES 0xfb
|
||||
#define REG_RCCTRL1_STA 0xfc
|
||||
#define REG_RCCTRL0_STA 0xfd
|
||||
|
||||
|
||||
|
||||
#define MAX_RX_PKTS 80
|
||||
|
||||
static volatile uint8_t mRxBufs[MAX_RX_PKTS][RADIO_MAX_PACKET_LEN + 1 /* length */ + 2 /* RSSI, LQI/STA */];
|
||||
static volatile uint8_t mRxNextWrite, mRxNextRead, mRxNumFree, mRxNumGot;
|
||||
static uint8_t mRxFilterLongMac[8], mTxLongMac[8];
|
||||
static uint32_t mRxFilterShortMac, mTxShortMac;
|
||||
static bool mRxEnabled, mAutoAck, mPromisc;
|
||||
static uint16_t mRxFilterPan, mTxPan;
|
||||
static volatile int16_t mLastAck;
|
||||
|
||||
struct MacHeaderGenericAddr {
|
||||
struct MacFcs fixed;
|
||||
uint8_t seq;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct MacHeaderShortAddr {
|
||||
struct MacFcs fixed;
|
||||
uint8_t seq;
|
||||
uint16_t pan;
|
||||
uint16_t shortDstAddr;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct MacHeaderLongAddr {
|
||||
struct MacFcs fixed;
|
||||
uint8_t seq;
|
||||
uint16_t pan;
|
||||
uint8_t longDstAddr[8];
|
||||
} __attribute__((packed));
|
||||
|
||||
|
||||
|
||||
void tiRadioTxConfigure(const uint8_t *myLongMac, uint32_t myShortMac, uint16_t pan) {
|
||||
memcpy(mTxLongMac, myLongMac, sizeof(mTxLongMac));
|
||||
mTxShortMac = myShortMac;
|
||||
mTxPan = pan;
|
||||
}
|
||||
|
||||
void tiRadioRxFilterCfg(const uint8_t *myMac, uint32_t myShortMac, uint16_t myPan, bool promisc) {
|
||||
mPromisc = promisc;
|
||||
mRxFilterShortMac = myShortMac;
|
||||
mRxFilterPan = myPan;
|
||||
memcpy(mRxFilterLongMac, myMac, sizeof(mRxFilterLongMac));
|
||||
}
|
||||
|
||||
static bool tiRadioPrvSelect(void) {
|
||||
digitalWrite(sub_CS, LOW);
|
||||
SPI.beginTransaction(SPISettings(6000000, MSBFIRST, SPI_MODE0));
|
||||
asm volatile("nop \n nop \n nop \n");
|
||||
return true;
|
||||
}
|
||||
|
||||
static void tiRadioPrvDeselect(void) {
|
||||
asm volatile("nop \n nop \n nop \n");
|
||||
SPI.endTransaction();
|
||||
digitalWrite(sub_CS, HIGH);
|
||||
asm volatile("nop \n nop \n nop \n");
|
||||
}
|
||||
|
||||
static void read_multiple(uint8_t *dst, uint_fast8_t rxLen) {
|
||||
for (int i = 0; i < rxLen; i++) {
|
||||
dst[i] = SPI.transfer(0xff);
|
||||
}
|
||||
}
|
||||
|
||||
static int_fast16_t tiRadioPrvStrobe(uint8_t cmd) //negative on error
|
||||
{
|
||||
if (!tiRadioPrvSelect())
|
||||
return -1;
|
||||
|
||||
cmd = SPI.transfer(cmd);
|
||||
|
||||
tiRadioPrvDeselect();
|
||||
|
||||
return (uint_fast16_t)cmd;
|
||||
}
|
||||
|
||||
static bool tiRadioPrvRegWrite(uint_fast8_t reg, uint_fast8_t val) {
|
||||
if (!tiRadioPrvSelect())
|
||||
return false;
|
||||
|
||||
SPI.transfer(reg);
|
||||
SPI.transfer(val);
|
||||
|
||||
tiRadioPrvDeselect();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static int_fast16_t tiRadioPrvRegRead(uint_fast8_t reg) {
|
||||
uint8_t read_data = 0x00;
|
||||
|
||||
if (!tiRadioPrvSelect())
|
||||
return -1;
|
||||
|
||||
SPI.transfer(reg | 0x80);
|
||||
read_data = SPI.transfer(0xff);
|
||||
|
||||
tiRadioPrvDeselect();
|
||||
|
||||
return (uint_fast16_t)read_data;
|
||||
}
|
||||
|
||||
static bool tiRadioPrvRegWriteLong(uint8_t reg, const uint8_t *valP, uint8_t len) {
|
||||
if (!tiRadioPrvSelect())
|
||||
return false;
|
||||
|
||||
SPI.transfer(reg | 0x40);
|
||||
|
||||
for (int i = 0; i < len; i++) {
|
||||
SPI.transfer(valP[i]);
|
||||
}
|
||||
|
||||
tiRadioPrvDeselect();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool tiRadioRxEnable(bool on, bool autoAck) {
|
||||
bool ret = false;
|
||||
|
||||
if (on) {
|
||||
|
||||
mAutoAck = autoAck;
|
||||
if (mRxEnabled) {
|
||||
ret = true;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!tiRadioPrvStrobe(CMD_SRX))
|
||||
goto out;
|
||||
|
||||
mRxEnabled = true;
|
||||
} else if (mRxEnabled) {
|
||||
|
||||
if (!tiRadioPrvStrobe(CMD_SIDLE))
|
||||
goto out;
|
||||
|
||||
mRxEnabled = false;
|
||||
}
|
||||
ret = true;
|
||||
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool radioPrvMacsEqual(const uint8_t *macA, const uint8_t *macB) {
|
||||
const uint32_t *a = (const uint32_t *)(const char *)macA;
|
||||
const uint32_t *b = (const uint32_t *)(const char *)macB;
|
||||
return a[0] == b[0] && a[1] == b[1];
|
||||
}
|
||||
|
||||
static uint_fast8_t tiRadioPrvGetState(void) {
|
||||
uint_fast8_t state;
|
||||
|
||||
do {
|
||||
state = tiRadioPrvRegRead(REG_MARCSTATE);
|
||||
} while (tiRadioPrvRegRead(REG_MARCSTATE) != state);
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
static void tiRadioPrvPacketRx(void) {
|
||||
uint8_t *rxedPkt = (uint8_t *)mRxBufs[mRxNextWrite];
|
||||
const struct MacHeaderShortAddr *withShortDst = (const struct MacHeaderShortAddr *)(rxedPkt + 1);
|
||||
const struct MacHeaderGenericAddr *generic = (const struct MacHeaderGenericAddr *)(rxedPkt + 1);
|
||||
const struct MacHeaderLongAddr *withLongDst = (const struct MacHeaderLongAddr *)(rxedPkt + 1);
|
||||
bool crcOk, acceptPacket, sendAck = false;
|
||||
int32_t t, lenNoCrc, lenNoMacFixed;
|
||||
uint32_t nWaitCycles = 10000;
|
||||
uint_fast8_t spiLen, now;
|
||||
|
||||
t = tiRadioPrvRegRead(REG_FIFO);
|
||||
if (t < 0)
|
||||
goto fail;
|
||||
|
||||
if (!mRxNumFree)
|
||||
goto fail;
|
||||
|
||||
spiLen = t;
|
||||
if (spiLen > RADIO_MAX_PACKET_LEN)
|
||||
goto fail;
|
||||
|
||||
t = 0;
|
||||
rxedPkt[t++] = lenNoCrc = spiLen;
|
||||
now = 31; //we just read one so 31 left for sure in the FIFO
|
||||
spiLen += 2; //we expect 2 more bytes
|
||||
|
||||
while (spiLen) {
|
||||
|
||||
uint8_t reg;
|
||||
|
||||
if (!tiRadioPrvSelect()) {
|
||||
tiRadioPrvDeselect();
|
||||
goto fail;
|
||||
}
|
||||
|
||||
reg = 0xc0 | REG_FIFO; //burst read
|
||||
reg = SPI.transfer(reg);
|
||||
now = reg & 0x0f;
|
||||
|
||||
if (now > spiLen)
|
||||
now = spiLen;
|
||||
|
||||
if (!now && !--nWaitCycles) {
|
||||
tiRadioPrvDeselect();
|
||||
//Serial.printf(" !!! RX timeout !!! \r\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
read_multiple(rxedPkt + t, now);
|
||||
t += now;
|
||||
spiLen -= now;
|
||||
|
||||
tiRadioPrvDeselect();
|
||||
}
|
||||
|
||||
rxedPkt++; //skip len;
|
||||
crcOk = !!(rxedPkt[lenNoCrc + 1] & 0x80);
|
||||
|
||||
lenNoMacFixed = lenNoCrc - sizeof(struct MacFcs) - sizeof(uint8_t);
|
||||
|
||||
if (mPromisc)
|
||||
acceptPacket = true;
|
||||
//otherwise, we need a valid crc
|
||||
else if (!crcOk) {
|
||||
acceptPacket = false;
|
||||
}
|
||||
//packet should be big enough to contain a header
|
||||
else if (lenNoMacFixed < 0)
|
||||
acceptPacket = false;
|
||||
else switch (generic->fixed.frameType) {
|
||||
|
||||
case FRAME_TYPE_ACK:
|
||||
mLastAck = (uint16_t)generic->seq;
|
||||
acceptPacket = false; //no need to save it as a packet
|
||||
break;
|
||||
|
||||
case FRAME_TYPE_DATA: //we are not the coordinator, so we demand to see our address as destination...
|
||||
|
||||
switch (generic->fixed.destAddrType) {
|
||||
case ADDR_MODE_SHORT:
|
||||
acceptPacket = (withShortDst->pan == 0xffff && withShortDst->shortDstAddr == 0xffff) || (withShortDst->pan == mRxFilterPan && (withShortDst->shortDstAddr == 0xffff || ((uint32_t)withShortDst->shortDstAddr) == mRxFilterShortMac));
|
||||
break;
|
||||
|
||||
case ADDR_MODE_LONG:
|
||||
acceptPacket = withLongDst->pan == mRxFilterPan && radioPrvMacsEqual(withLongDst->longDstAddr, mRxFilterLongMac);
|
||||
break;
|
||||
|
||||
default:
|
||||
acceptPacket = false;
|
||||
break;
|
||||
}
|
||||
sendAck = generic->fixed.ackReqd && mAutoAck;
|
||||
break;
|
||||
|
||||
default:
|
||||
//no riff-raff please
|
||||
acceptPacket = false;
|
||||
break;
|
||||
}
|
||||
|
||||
if (acceptPacket) { //other checks here too plz
|
||||
|
||||
if (sendAck) {
|
||||
|
||||
static struct {
|
||||
uint8_t len;
|
||||
struct MacFcs mac;
|
||||
uint8_t seq;
|
||||
} __attribute__((packed)) ack = {
|
||||
.len = sizeof(ack) + sizeof(uint16_t) - sizeof(ack.len),
|
||||
.mac = {
|
||||
.frameType = FRAME_TYPE_ACK,
|
||||
},
|
||||
};
|
||||
|
||||
ack.seq = generic->seq;
|
||||
|
||||
tiRadioTxLL(&ack);
|
||||
}
|
||||
|
||||
mRxNumFree--;
|
||||
if (++mRxNextWrite == MAX_RX_PKTS)
|
||||
mRxNextWrite = 0;
|
||||
mRxNumGot++;
|
||||
}
|
||||
|
||||
out:
|
||||
if (mRxEnabled && !sendAck) { //if ack is being TXed, TX irq will restart rx later
|
||||
uint32_t maxWait = 100000;
|
||||
uint8_t state;
|
||||
|
||||
(void)tiRadioPrvStrobe(CMD_SRX);
|
||||
|
||||
do {
|
||||
state = tiRadioPrvGetState();
|
||||
|
||||
if (!--maxWait) {
|
||||
//Serial.printf("too long wait for rx state. state is %d\n", state);
|
||||
break;
|
||||
}
|
||||
|
||||
} while (state != 13 && state != 14 && state != 15);
|
||||
}
|
||||
return;
|
||||
|
||||
fail:
|
||||
(void)tiRadioPrvStrobe(CMD_SFRX);
|
||||
goto out;
|
||||
}
|
||||
|
||||
void tiRadioRxAckReset(void) {
|
||||
mLastAck = -1;
|
||||
}
|
||||
|
||||
int16_t tiRadioRxAckGetLast(void) {
|
||||
return mLastAck;
|
||||
}
|
||||
|
||||
int32_t tiRadioRxDequeuePkt(void *dstBuf, uint32_t maxLen, int8_t *rssiP, uint8_t *lqiP) {
|
||||
uint32_t len, copyLen = maxLen;
|
||||
|
||||
if (!mRxNumGot)
|
||||
return -1;
|
||||
|
||||
len = mRxBufs[mRxNextRead][0];
|
||||
|
||||
if (copyLen > len)
|
||||
copyLen = len;
|
||||
memcpy(dstBuf, (const void *)(mRxBufs[mRxNextRead] + 1), copyLen);
|
||||
|
||||
if (lqiP) {
|
||||
|
||||
uint32_t lqi = 296 - ((mRxBufs[mRxNextRead][len + 2] & 0x7f) * 2);
|
||||
|
||||
//LQI: lower is better. 48 is very good (no lower value seen), 127 is very bad (max value possible)
|
||||
//we want LQI 0..255 so we scale as SATURATE(296 - 2 * val)
|
||||
|
||||
if (lqi > 255)
|
||||
lqi = 255;
|
||||
|
||||
*lqiP = lqi;
|
||||
}
|
||||
|
||||
if (rssiP)
|
||||
*rssiP = ((int8_t)mRxBufs[mRxNextRead][len + 1]) / 2 - 77;
|
||||
|
||||
if (++mRxNextRead == MAX_RX_PKTS)
|
||||
mRxNextRead = 0;
|
||||
|
||||
noInterrupts();
|
||||
mRxNumFree++;
|
||||
mRxNumGot--;
|
||||
interrupts();
|
||||
|
||||
//ti radio never stalls RX state machine so nothing to do even if we just freed up a buffer
|
||||
return len;
|
||||
}
|
||||
|
||||
void data_input_interrupt(void) {
|
||||
while (digitalRead(sub_GD0)) //while there is data (packets)
|
||||
tiRadioPrvPacketRx();
|
||||
}
|
||||
|
||||
static void tiRadioPrvIfInit(void) {
|
||||
//configure pins
|
||||
pinMode(sub_CS, OUTPUT);
|
||||
pinMode(sub_GD0, INPUT_PULLUP);
|
||||
pinMode(sub_GD2, INPUT_PULLUP);
|
||||
SPI.begin(sub_CLK, sub_MISO, sub_MOSI);
|
||||
|
||||
tiRadioPrvDeselect();
|
||||
|
||||
mRxNumFree = MAX_RX_PKTS;
|
||||
}
|
||||
|
||||
static void tiRadioPrvIrqInit(void) {
|
||||
attachInterrupt(sub_GD0, data_input_interrupt, RISING);
|
||||
}
|
||||
|
||||
bool tiRadioSetChannel(uint_fast8_t channel) {
|
||||
channel -= SUB_GHZ_CH_OFST;
|
||||
if (channel >= SUB_GHZ_NUM_CHANNELS)
|
||||
return false;
|
||||
|
||||
return tiRadioPrvRegWrite(REG_CHANNR, channel * 3);
|
||||
}
|
||||
|
||||
bool tiRadioTxLL(const void *pkt) {
|
||||
const uint8_t *data = (const uint8_t *)pkt;
|
||||
uint32_t len = 1 + *data, now;
|
||||
bool ret = false;
|
||||
|
||||
if (0) {
|
||||
Serial.printf("TX packet len %u :", len);
|
||||
for (int t = 0; t < len; t++) {
|
||||
Serial.printf(" %02x", data[1 + t]);
|
||||
}
|
||||
Serial.printf("\n");
|
||||
}
|
||||
|
||||
if (tiRadioPrvStrobe(CMD_SIDLE) < 0)
|
||||
goto out;
|
||||
|
||||
if (tiRadioPrvStrobe(CMD_SFTX) < 0)
|
||||
goto out;
|
||||
|
||||
now = (len > 64 ? 64 : len);
|
||||
if (!tiRadioPrvRegWriteLong(REG_FIFO, data, now))
|
||||
goto out;
|
||||
len -= now;
|
||||
data += now;
|
||||
|
||||
if (tiRadioPrvStrobe(CMD_STX) < 0)
|
||||
goto out;
|
||||
|
||||
while (len) {
|
||||
|
||||
now = 8;
|
||||
if (now > len)
|
||||
now = len;
|
||||
|
||||
while (digitalRead(sub_GD2))
|
||||
; //wait till there is space
|
||||
|
||||
if (!tiRadioPrvRegWriteLong(REG_FIFO, data, now))
|
||||
goto out;
|
||||
|
||||
data += now;
|
||||
len -= now;
|
||||
}
|
||||
|
||||
while (tiRadioPrvGetState() != 1)
|
||||
;
|
||||
|
||||
if (!tiRadioPrvStrobe(mRxEnabled ? CMD_SRX : CMD_SIDLE))
|
||||
goto out;
|
||||
|
||||
ret = true;
|
||||
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool init_subGhz(void) {
|
||||
uint8_t regsCfg[] = {
|
||||
/* 0x00 */ 0x02, 0x2e, 0x01, 0x07, 0xd3, 0x91, 0x7f, 0x04,
|
||||
/* 0x08 */ 0x45, 0x22, 0x00, 0x0e, 0x00, 0x22, 0xbb, 0x13,
|
||||
/* 0x10 */ 0x1d, 0x3b, 0x13, 0x43, 0xa4, 0x65, 0x07, 0x30,
|
||||
/* 0x18 */ 0x1d, 0x1e, 0x1c, 0xc7, 0x00, 0xb0, 0x87, 0x6b,
|
||||
/* 0x20 */ 0xfb, 0xb6, 0x10, 0xea, 0x2a, 0x00, 0x1f, 0x41,
|
||||
/* 0x28 */ 0x00,
|
||||
};
|
||||
|
||||
uint8_t paTab[] = { 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0 };
|
||||
|
||||
tiRadioPrvIfInit();
|
||||
|
||||
if (tiRadioPrvRegRead(REG_PARTNUM) != 0x00) {
|
||||
Serial.printf("partnum is wrong\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (tiRadioPrvStrobe(CMD_SRES) < 0) {
|
||||
Serial.printf("res reply\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
delayMicroseconds(300);
|
||||
|
||||
if (tiRadioPrvStrobe(CMD_SIDLE) != 0x0f) {
|
||||
Serial.printf("idle reply\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!tiRadioPrvRegWriteLong(0, regsCfg, sizeof(regsCfg))) {
|
||||
Serial.printf("config issue\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!tiRadioPrvRegWriteLong(REG_PATABLE, paTab, sizeof(paTab))) {
|
||||
Serial.printf("PAtable issue\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
tiRadioPrvIrqInit();
|
||||
|
||||
Serial.printf("Sub-GHz radio inited\n");
|
||||
|
||||
tiRadioRxEnable(true, false);
|
||||
Serial.printf("Sub-GHz rx is on\n");
|
||||
return true;
|
||||
}
|
||||
32
ARM_Tag_FW/Arduino_OpenEPaperLink_C6_AP/subGhz.h
Normal file
32
ARM_Tag_FW/Arduino_OpenEPaperLink_C6_AP/subGhz.h
Normal file
@@ -0,0 +1,32 @@
|
||||
|
||||
// This code is heavily depending on Dmitrys wonderful Work !
|
||||
// https://dmitry.gr/?r=05.Projects&proj=29.%20eInk%20Price%20Tags
|
||||
// Ported and modified to fit the OpenEPaperLink Project by ATC1441 (ATCnetz.de) ~01.2024
|
||||
|
||||
#pragma once
|
||||
#include <Arduino.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
void tiRadioTxConfigure(const uint8_t *myLongMac, uint32_t myShortMac, uint16_t pan);
|
||||
void tiRadioRxFilterCfg(const uint8_t *myMac, uint32_t myShortMac, uint16_t myPan, bool promisc);
|
||||
static bool tiRadioPrvSelect(void);
|
||||
static void tiRadioPrvDeselect(void);
|
||||
static void read_multiple(uint8_t *dst, uint_fast8_t rxLen);
|
||||
static int_fast16_t tiRadioPrvStrobe(uint8_t cmd);
|
||||
static bool tiRadioPrvRegWrite(uint_fast8_t reg, uint_fast8_t val);
|
||||
static int_fast16_t tiRadioPrvRegRead(uint_fast8_t reg);
|
||||
static bool tiRadioPrvRegWriteLong(uint8_t reg, const uint8_t *valP, uint8_t len);
|
||||
bool tiRadioRxEnable(bool on, bool autoAck);
|
||||
static bool radioPrvMacsEqual(const uint8_t *macA, const uint8_t *macB);
|
||||
static uint_fast8_t tiRadioPrvGetState(void);
|
||||
static void tiRadioPrvPacketRx(void);
|
||||
void tiRadioRxAckReset(void);
|
||||
int16_t tiRadioRxAckGetLast(void);
|
||||
int32_t tiRadioRxDequeuePkt(void* dstBuf, uint32_t maxLen, int8_t *rssiP, uint8_t *lqiP);
|
||||
void data_input_interrupt(void);
|
||||
static void tiRadioPrvIfInit(void);
|
||||
static void tiRadioPrvIrqInit(void);
|
||||
bool tiRadioSetChannel(uint_fast8_t channel);
|
||||
bool tiRadioTxLL(const void* pkt);
|
||||
|
||||
bool init_subGhz(void);
|
||||
@@ -1,281 +0,0 @@
|
||||
|
||||
|
||||
TRACE +0.008 command op=0x0a data len=4 wait_response=1 timeout=3.000 data=00100040
|
||||
TRACE +0.000 Write 14 bytes: c0000a04000000000000100040c0
|
||||
TRACE +0.002 Read 1 bytes: c0
|
||||
TRACE +0.000 Read 13 bytes: 010a04006f80e02c00000000c0
|
||||
TRACE +0.000 Received full packet: 010a04006f80e02c00000000
|
||||
|
||||
Detecting chip type...
|
||||
|
||||
TRACE +0.000 command op=0x14 data len=0 wait_response=1 timeout=3.000 data=
|
||||
TRACE +0.000 Write 10 bytes: c00014000000000000c0
|
||||
TRACE +0.008 Read 1 bytes: c0
|
||||
TRACE +0.000 Read 33 bytes:
|
||||
011418006f80e02c 0000000000000000 | ....o..,........
|
||||
0000000c0d000000 0000000000000000 | ................
|
||||
c0 | .
|
||||
TRACE +0.000 Received full packet:
|
||||
011418006f80e02c 0000000000000000 | ....o..,........
|
||||
0000000c0d000000 0000000000000000 | ................
|
||||
|
||||
TRACE +0.000 command op=0x0a data len=4 wait_response=1 timeout=3.000 data=80f58740
|
||||
TRACE +0.000 Write 14 bytes: c0000a04000000000080f58740c0
|
||||
TRACE +0.002 Read 1 bytes: c0
|
||||
TRACE +0.000 Read 13 bytes: 010a04000000000000000000c0
|
||||
TRACE +0.000 Received full packet: 010a04000000000000000000
|
||||
|
||||
TRACE +0.000 command op=0x0a data len=4 wait_response=1 timeout=3.000 data=50080b60
|
||||
TRACE +0.000 Write 14 bytes: c0000a04000000000050080b60c0
|
||||
TRACE +0.000 Read 1 bytes: c0
|
||||
TRACE +0.000 Read 13 bytes: 010a04000000000800000000c0
|
||||
TRACE +0.000 Received full packet: 010a04000000000800000000
|
||||
|
||||
TRACE +0.008 command op=0x0a data len=4 wait_response=1 timeout=3.000 data=50080b60
|
||||
TRACE +0.000 Write 14 bytes: c0000a04000000000050080b60c0
|
||||
TRACE +0.002 Read 1 bytes: c0
|
||||
TRACE +0.000 Read 13 bytes: 010a04000000000800000000c0
|
||||
TRACE +0.000 Received full packet: 010a04000000000800000000
|
||||
|
||||
TRACE +0.000 command op=0x0a data len=4 wait_response=1 timeout=3.000 data=50080b60
|
||||
TRACE +0.000 Write 14 bytes: c0000a04000000000050080b60c0
|
||||
TRACE +0.000 Read 1 bytes: c0
|
||||
TRACE +0.000 Read 13 bytes: 010a04000000000800000000c0
|
||||
TRACE +0.000 Received full packet: 010a04000000000800000000
|
||||
|
||||
Chip is ESP32-C6 (QFN40) (revision v0.0)
|
||||
Features: WiFi 6, BT 5, IEEE802.15.4
|
||||
Crystal is 40MHz
|
||||
|
||||
TRACE +0.000 command op=0x0a data len=4 wait_response=1 timeout=3.000 data=44080b60
|
||||
TRACE +0.000 Write 14 bytes: c0000a04000000000044080b60c0
|
||||
TRACE +0.010 Read 1 bytes: c0
|
||||
TRACE +0.000 Read 13 bytes: 010a0400e85342ca00000000c0
|
||||
TRACE +0.000 Received full packet: 010a0400e85342ca00000000
|
||||
|
||||
TRACE +0.000 command op=0x0a data len=4 wait_response=1 timeout=3.000 data=48080b60
|
||||
TRACE +0.000 Write 14 bytes: c0000a04000000000048080b60c0
|
||||
TRACE +0.000 Read 1 bytes: c0
|
||||
TRACE +0.000 Read 13 bytes: 010a04004c40feff00000000c0
|
||||
TRACE +0.000 Received full packet: 010a04004c40feff00000000
|
||||
|
||||
MAC: 40:4c:ca:ff:fe:42:53:e8
|
||||
|
||||
TRACE +0.000 command op=0x0a data len=4 wait_response=1 timeout=3.000 data=44080b60
|
||||
TRACE +0.000 Write 14 bytes: c0000a04000000000044080b60c0
|
||||
TRACE +0.008 Read 1 bytes: c0
|
||||
TRACE +0.000 Read 13 bytes: 010a0400e85342ca00000000c0
|
||||
TRACE +0.000 Received full packet: 010a0400e85342ca00000000
|
||||
|
||||
TRACE +0.002 command op=0x0a data len=4 wait_response=1 timeout=3.000 data=48080b60
|
||||
TRACE +0.000 Write 14 bytes: c0000a04000000000048080b60c0
|
||||
TRACE +0.000 Read 1 bytes: c0
|
||||
TRACE +0.000 Read 13 bytes: 010a04004c40feff00000000c0
|
||||
TRACE +0.000 Received full packet: 010a04004c40feff00000000
|
||||
|
||||
BASE MAC: 40:4c:ca:42:53:e8
|
||||
|
||||
TRACE +0.000 command op=0x0a data len=4 wait_response=1 timeout=3.000 data=44080b60
|
||||
TRACE +0.000 Write 14 bytes: c0000a04000000000044080b60c0
|
||||
TRACE +0.008 Read 1 bytes: c0
|
||||
TRACE +0.000 Read 13 bytes: 010a0400e85342ca00000000c0
|
||||
TRACE +0.000 Received full packet: 010a0400e85342ca00000000
|
||||
|
||||
!!! TRACE +0.000 command op=0x0a data len=4 wait_response=1 timeout=3.000 data=48080b60
|
||||
TRACE +0.000 Write 14 bytes: c0000a04000000000048080b60c0
|
||||
TRACE +0.002 Read 1 bytes: c0
|
||||
TRACE +0.000 Read 13 bytes: 010a04004c40feff00000000c0
|
||||
TRACE +0.000 Received full packet: 010a04004c40feff00000000
|
||||
|
||||
MAC_EXT: ff:fe
|
||||
|
||||
Enabling default SPI flash mode...
|
||||
|
||||
!!!! TRACE +0.000 command op=0x0d data len=8 wait_response=1 timeout=3.000 data=0000000000000000
|
||||
TRACE +0.000 Write 18 bytes:
|
||||
c0000d0800000000 0000000000000000 | ................
|
||||
00c0 | ..
|
||||
TRACE +0.000 Read 1 bytes: c0
|
||||
TRACE +0.000 Read 13 bytes: 010d04004c40feff00000000c0
|
||||
TRACE +0.000 Received full packet: 010d04004c40feff00000000
|
||||
|
||||
v TRACE +0.008 command op=0x0a data len=4 wait_response=1 timeout=3.000 data=18300060
|
||||
TRACE +0.000 Write 14 bytes: c0000a04000000000018300060c0
|
||||
TRACE +0.002 Read 1 bytes: c0
|
||||
TRACE +0.000 Read 13 bytes: 010a04000000008000000000c0
|
||||
TRACE +0.000 Received full packet: 010a04000000008000000000
|
||||
|
||||
v TRACE +0.000 command op=0x0a data len=4 wait_response=1 timeout=3.000 data=20300060
|
||||
TRACE +0.000 Write 14 bytes: c0000a04000000000020300060c0
|
||||
TRACE +0.000 Read 1 bytes: c0
|
||||
TRACE +0.000 Read 13 bytes: 010a04000000007000000000c0
|
||||
TRACE +0.000 Received full packet: 010a04000000007000000000
|
||||
|
||||
v TRACE +0.000 command op=0x09 data len=16 wait_response=1 timeout=3.000 data=2830006017000000ffffffff00000000
|
||||
TRACE +0.000 Write 26 bytes:
|
||||
c000091000000000 0028300060170000 | .........(0.`...
|
||||
00ffffffff000000 00c0 | ..........
|
||||
TRACE +0.010 Read 1 bytes: c0
|
||||
TRACE +0.000 Read 13 bytes: 010904000000007000000000c0
|
||||
TRACE +0.000 Received full packet: 010904000000007000000000
|
||||
|
||||
TRACE +0.000 command op=0x09 data len=16 wait_response=1 timeout=3.000 data=1830006000000090ffffffff00000000
|
||||
TRACE +0.000 Write 26 bytes:
|
||||
c000091000000000 0018300060000000 | ..........0.`...
|
||||
90ffffffff000000 00c0 | ..........
|
||||
TRACE +0.000 Read 1 bytes: c0
|
||||
TRACE +0.000 Read 13 bytes: 010904000000007000000000c0
|
||||
TRACE +0.000 Received full packet: 010904000000007000000000
|
||||
|
||||
TRACE +0.008 command op=0x09 data len=16 wait_response=1 timeout=3.000 data=203000609f000070ffffffff00000000
|
||||
TRACE +0.000 Write 26 bytes:
|
||||
c000091000000000 00203000609f0000 | ......... 0.`...
|
||||
70ffffffff000000 00c0 | p.........
|
||||
TRACE +0.002 Read 1 bytes: c0
|
||||
TRACE +0.000 Read 13 bytes: 010904000000007000000000c0
|
||||
TRACE +0.000 Received full packet: 010904000000007000000000
|
||||
|
||||
TRACE +0.000 command op=0x09 data len=16 wait_response=1 timeout=3.000 data=5830006000000000ffffffff00000000
|
||||
TRACE +0.000 Write 26 bytes:
|
||||
c000091000000000 0058300060000000 | .........X0.`...
|
||||
00ffffffff000000 00c0 | ..........
|
||||
TRACE +0.008 Read 1 bytes: c0
|
||||
TRACE +0.000 Read 13 bytes: 010904000000007000000000c0
|
||||
TRACE +0.000 Received full packet: 010904000000007000000000
|
||||
|
||||
TRACE +0.000 command op=0x09 data len=16 wait_response=1 timeout=3.000 data=0030006000000400ffffffff00000000
|
||||
TRACE +0.000 Write 26 bytes:
|
||||
c000091000000000 0000300060000004 | ..........0.`...
|
||||
00ffffffff000000 00c0 | ..........
|
||||
TRACE +0.002 Read 1 bytes: c0
|
||||
TRACE +0.000 Read 13 bytes: 010904000000007000000000c0
|
||||
TRACE +0.000 Received full packet: 010904000000007000000000
|
||||
|
||||
TRACE +0.000 command op=0x0a data len=4 wait_response=1 timeout=3.000 data=00300060
|
||||
TRACE +0.000 Write 14 bytes: c0000a04000000000000300060c0
|
||||
TRACE +0.008 Read 1 bytes: c0
|
||||
TRACE +0.000 Read 13 bytes: 010a04000000000000000000c0
|
||||
TRACE +0.000 Received full packet: 010a04000000000000000000
|
||||
|
||||
!!! TRACE +0.000 command op=0x0a data len=4 wait_response=1 timeout=3.000 data=58300060
|
||||
TRACE +0.000 Write 14 bytes: c0000a04000000000058300060c0
|
||||
TRACE +0.002 Read 1 bytes: c0
|
||||
TRACE +0.000 Read 13 bytes: 010a0400c840170000000000c0
|
||||
TRACE +0.000 Received full packet: 010a0400c840170000000000
|
||||
|
||||
!!! TRACE +0.000 command op=0x09 data len=16 wait_response=1 timeout=3.000 data=1830006000000080ffffffff00000000
|
||||
TRACE +0.000 Write 26 bytes:
|
||||
c000091000000000 0018300060000000 | ..........0.`...
|
||||
80ffffffff000000 00c0 | ..........
|
||||
TRACE +0.000 Read 1 bytes: c0
|
||||
TRACE +0.008 Read 13 bytes: 01090400c840170000000000c0
|
||||
TRACE +0.000 Received full packet: 01090400c840170000000000
|
||||
|
||||
TRACE +0.000 command op=0x09 data len=16 wait_response=1 timeout=3.000 data=2030006000000070ffffffff00000000
|
||||
TRACE +0.000 Write 26 bytes:
|
||||
c000091000000000 0020300060000000 | ......... 0.`...
|
||||
70ffffffff000000 00c0 | p.........
|
||||
TRACE +0.002 Read 1 bytes: c0
|
||||
TRACE +0.000 Read 13 bytes: 01090400c840170000000000c0
|
||||
TRACE +0.000 Received full packet: 01090400c840170000000000
|
||||
|
||||
TRACE +0.000 command op=0x0a data len=4 wait_response=1 timeout=3.000 data=18300060
|
||||
TRACE +0.000 Write 14 bytes: c0000a04000000000018300060c0
|
||||
TRACE +0.008 Read 1 bytes: c0
|
||||
TRACE +0.000 Read 13 bytes: 010a04000000008000000000c0
|
||||
TRACE +0.000 Received full packet: 010a04000000008000000000
|
||||
|
||||
TRACE +0.000 command op=0x0a data len=4 wait_response=1 timeout=3.000 data=20300060
|
||||
TRACE +0.000 Write 14 bytes: c0000a04000000000020300060c0
|
||||
TRACE +0.002 Read 1 bytes: c0
|
||||
TRACE +0.000 Read 13 bytes: 010a04000000007000000000c0
|
||||
TRACE +0.000 Received full packet: 010a04000000007000000000
|
||||
|
||||
TRACE +0.000 command op=0x09 data len=16 wait_response=1 timeout=3.000 data=2830006007000000ffffffff00000000
|
||||
TRACE +0.000 Write 26 bytes:
|
||||
c000091000000000 0028300060070000 | .........(0.`...
|
||||
00ffffffff000000 00c0 | ..........
|
||||
TRACE +0.008 Read 1 bytes: c0
|
||||
TRACE +0.000 Read 13 bytes: 010904000000007000000000c0
|
||||
TRACE +0.000 Received full packet: 010904000000007000000000
|
||||
|
||||
TRACE +0.000 command op=0x09 data len=16 wait_response=1 timeout=3.000 data=1c3000600700005cffffffff00000000
|
||||
TRACE +0.000 Write 26 bytes:
|
||||
c000091000000000 001c300060070000 | ..........0.`...
|
||||
5cffffffff000000 00c0 | \.........
|
||||
TRACE +0.002 Read 1 bytes: c0
|
||||
TRACE +0.000 Read 13 bytes: 010904000000007000000000c0
|
||||
TRACE +0.000 Received full packet: 010904000000007000000000
|
||||
|
||||
TRACE +0.000 command op=0x09 data len=16 wait_response=1 timeout=3.000 data=18300060000000f0ffffffff00000000
|
||||
TRACE +0.000 Write 26 bytes:
|
||||
c000091000000000 0018300060000000 | ..........0.`...
|
||||
f0ffffffff000000 00c0 | ..........
|
||||
TRACE +0.008 Read 1 bytes: c0
|
||||
TRACE +0.000 Read 13 bytes: 010904000000007000000000c0
|
||||
TRACE +0.000 Received full packet: 010904000000007000000000
|
||||
|
||||
TRACE +0.000 command op=0x09 data len=16 wait_response=1 timeout=3.000 data=203000605a000070ffffffff00000000
|
||||
TRACE +0.000 Write 26 bytes:
|
||||
c000091000000000 00203000605a0000 | ......... 0.`Z..
|
||||
70ffffffff000000 00c0 | p.........
|
||||
TRACE +0.000 Read 1 bytes: c0
|
||||
TRACE +0.000 Read 13 bytes: 010904000000007000000000c0
|
||||
TRACE +0.000 Received full packet: 010904000000007000000000
|
||||
|
||||
TRACE +0.000 command op=0x09 data len=16 wait_response=1 timeout=3.000 data=0430006010000000ffffffff00000000
|
||||
TRACE +0.000 Write 26 bytes:
|
||||
c000091000000000 0004300060100000 | ..........0.`...
|
||||
00ffffffff000000 00c0 | ..........
|
||||
TRACE +0.012 Read 1 bytes: c0
|
||||
TRACE +0.000 Read 13 bytes: 010904000000007000000000c0
|
||||
TRACE +0.000 Received full packet: 010904000000007000000000
|
||||
|
||||
TRACE +0.000 command op=0x09 data len=16 wait_response=1 timeout=3.000 data=5830006000000000ffffffff00000000
|
||||
TRACE +0.000 Write 26 bytes:
|
||||
c000091000000000 0058300060000000 | .........X0.`...
|
||||
00ffffffff000000 00c0 | ..........
|
||||
TRACE +0.000 Read 1 bytes: c0
|
||||
TRACE +0.000 Read 13 bytes: 010904000000007000000000c0
|
||||
TRACE +0.000 Received full packet: 010904000000007000000000
|
||||
|
||||
TRACE +0.000 command op=0x09 data len=16 wait_response=1 timeout=3.000 data=0030006000000400ffffffff00000000
|
||||
TRACE +0.000 Write 26 bytes:
|
||||
c000091000000000 0000300060000004 | ..........0.`...
|
||||
00ffffffff000000 00c0 | ..........
|
||||
TRACE +0.010 Read 1 bytes: c0
|
||||
TRACE +0.000 Read 13 bytes: 010904000000007000000000c0
|
||||
TRACE +0.000 Received full packet: 010904000000007000000000
|
||||
|
||||
TRACE +0.000 command op=0x0a data len=4 wait_response=1 timeout=3.000 data=00300060
|
||||
TRACE +0.000 Write 14 bytes: c0000a04000000000000300060c0
|
||||
TRACE +0.000 Read 1 bytes: c0
|
||||
TRACE +0.000 Read 13 bytes: 010a04000000000000000000c0
|
||||
TRACE +0.000 Received full packet: 010a04000000000000000000
|
||||
|
||||
TRACE +0.000 command op=0x0a data len=4 wait_response=1 timeout=3.000 data=58300060
|
||||
TRACE +0.000 Write 14 bytes: c0000a04000000000058300060c0
|
||||
TRACE +0.010 Read 1 bytes: c0
|
||||
TRACE +0.000 Read 13 bytes: 010a0400c800000000000000c0
|
||||
TRACE +0.000 Received full packet: 010a0400c800000000000000
|
||||
|
||||
TRACE +0.000 command op=0x09 data len=16 wait_response=1 timeout=3.000 data=1830006000000080ffffffff00000000
|
||||
TRACE +0.000 Write 26 bytes:
|
||||
c000091000000000 0018300060000000 | ..........0.`...
|
||||
80ffffffff000000 00c0 | ..........
|
||||
TRACE +0.000 Read 1 bytes: c0
|
||||
TRACE +0.000 Read 13 bytes: 01090400c800000000000000c0
|
||||
TRACE +0.000 Received full packet: 01090400c800000000000000
|
||||
|
||||
TRACE +0.000 command op=0x09 data len=16 wait_response=1 timeout=3.000 data=2030006000000070ffffffff00000000
|
||||
TRACE +0.000 Write 26 bytes:
|
||||
c000091000000000 0020300060000000 | ......... 0.`...
|
||||
70ffffffff000000 00c0 | p.........
|
||||
TRACE +0.010 Read 1 bytes: c0
|
||||
TRACE +0.000 Read 13 bytes: 01090400c800000000000000c0
|
||||
TRACE +0.000 Received full packet: 01090400c800000000000000
|
||||
|
||||
Manufacturer: c8
|
||||
Device: 4017
|
||||
Detected flash size: 8MB
|
||||
|
||||
@@ -1,96 +0,0 @@
|
||||
C6 flash starting
|
||||
|
||||
Write 1 bytes: c000082400000000000707122055555555
|
||||
55555555555555555555555555555555
|
||||
555555555555555555555555c0
|
||||
Read 1 bytes: 004553502d524f4d3a657370333263362d32303232303931390d0a4275696c643a53657020313920323032320d0a7273743a3078312028504f5745524f4e292c626f6f743a307836362028444f574e4c4f4144285553422f55415254302f5344494f5f5245495f46454f29290d0a77616974696e6720666f7220646f776e6c6f61640d0a
|
||||
|
||||
Write 1 bytes: c000082400000000000707122055555555
|
||||
55555555555555555555555555555555
|
||||
555555555555555555555555c0
|
||||
Read 1 bytes: c0010804000707122000000000c0
|
||||
|
||||
Write 1 bytes: c0000a04000000000000100040c0
|
||||
Read 1 bytes: c0010804000707122000000000c0
|
||||
c0010804000707122000000000c0
|
||||
c0010804000707122000000000c0
|
||||
c0010804000707122000000000c0
|
||||
c0010804000707122000000000c0
|
||||
c0010804000707122000000000c0
|
||||
c0010804000707122000000000c0
|
||||
c0010a04006f80e02c00000000c0
|
||||
|
||||
Write 1 bytes: c0000a04000000000048080b60c0 600b0848!!! read 0x12
|
||||
c0000a04000000000044080b60c0 600b0844 read 0x11
|
||||
Read 1 bytes: c0010a04004c40feff00000000c0
|
||||
c0010a0400e85342ca00000000c0
|
||||
esptool: c0010a04004c40feff00000000c0
|
||||
|
||||
>>>>> Write 1 bytes: c0000a0400000000004c080b60c0 600b084C!!! read 0x13
|
||||
esptool: c0000a04000000000048080b60c0 600b0848 read 0x12
|
||||
Read 1 bytes: c0010a04000000000000000000c0
|
||||
esptool: c0010a04004c40feff00000000c0
|
||||
|
||||
command op=0x0d data len=8
|
||||
>>>>> Write 1 bytes: c0000d080000000000feff000000000000c0
|
||||
esptool:c0000d0800000000000000000000000000c0
|
||||
>>>>> Read 1 bytes: c0010d04000000000000000000c0
|
||||
esptool: c0010d04004c40feff00000000c0
|
||||
|
||||
Connected to target
|
||||
Connected to ESP32-C6
|
||||
bootloader
|
||||
size: 21248
|
||||
Erasing flash (this may take a while)...
|
||||
esp_loader_flash_start
|
||||
block_size 1024
|
||||
detect_flash_size
|
||||
|
||||
spi_flash_command 159 0 24
|
||||
v Write 1 bytes: c0000a04000000000018300060c0
|
||||
Read 1 bytes: c0010a04000000008000000000c0
|
||||
|
||||
v Write 1 bytes: c0000a04000000000020300060c0
|
||||
Read 1 bytes: c0010a04000000007000000000c0
|
||||
|
||||
v Write 1 bytes: c000091000000000002830006017000000
|
||||
ffffffff00000000c0
|
||||
Read 1 bytes: c0010904000000007000000000c0
|
||||
|
||||
v Write 1 bytes: c000091000000000001830006000000090
|
||||
ffffffff00000000c0
|
||||
Read 1 bytes: c0010904000000007000000000c0
|
||||
|
||||
v Write 1 bytes: c00009100000000000203000609f000070
|
||||
ffffffff00000000c0
|
||||
Read 1 bytes: c0010904000000007000000000c0
|
||||
|
||||
v Write 1 bytes: c000091000000000005830006000000000
|
||||
ffffffff00000000c0
|
||||
Read 1 bytes: c0010904000000007000000000c0
|
||||
|
||||
v Write 1 bytes: c000091000000000000030006000000400
|
||||
ffffffff00000000c0
|
||||
Read 1 bytes: c0010904000000007000000000c0try 9
|
||||
|
||||
v Write 1 bytes: c0000a04000000000000300060c0
|
||||
Read 1 bytes: c0010a04000000000000000000c0
|
||||
|
||||
Write 1 bytes: c0000a04000000000058300060c0
|
||||
!!! Read 1 bytes: c0010a0400ffffff0000000000c0
|
||||
|
||||
Write 1 bytes: c000091000000000001830006000000080
|
||||
ffffffff00000000c0
|
||||
!!! Read 1 bytes: c001090400ffffff0000000000c0
|
||||
|
||||
Write 1 bytes: c000091000000000002030006000000070
|
||||
ffffffff00000000c0
|
||||
Read 1 bytes: c001090400ffffff0000000000c0
|
||||
|
||||
size_id 255
|
||||
DEBUG: Flash size detection failed, falling back to default
|
||||
|
||||
Write 1 bytes: c000021400000000000053000015000000
|
||||
000400000000000000000000c0
|
||||
Read 0 bytes:
|
||||
Erasing flash failed with error 2.
|
||||
@@ -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);
|
||||
}
|
||||
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
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
File diff suppressed because it is too large
Load Diff
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
Binary file not shown.
@@ -1,15 +1,19 @@
|
||||
#include <Arduino.h>
|
||||
|
||||
#include "hal.h"
|
||||
#include "wdt.h"
|
||||
#include "HAL_Newton_M3.h"
|
||||
#include "epd_driver/epd_interface.h"
|
||||
|
||||
int8_t temperature = 0;
|
||||
uint32_t batteryRaw = 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()) {
|
||||
NRF_CLOCK->EVENTS_HFCLKSTARTED = 0;
|
||||
@@ -134,8 +138,8 @@ void getTemperature() {
|
||||
}
|
||||
|
||||
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;
|
||||
@@ -160,13 +164,14 @@ 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] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||
|
||||
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;
|
||||
@@ -185,14 +190,14 @@ 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++) {
|
||||
for (uint16_t i = 0; i < brightness; i++) {
|
||||
digitalWrite(LED_RED, !(colorred >= 7));
|
||||
digitalWrite(LED_GREEN, !(colorgreen >= 7));
|
||||
digitalWrite(LED_BLUE, !(colorblue >= 3));
|
||||
@@ -248,79 +253,70 @@ void sleepwithinterrupts(uint32_t sleepinterval) {
|
||||
|
||||
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 (ms < 2000) mode = 0;
|
||||
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;
|
||||
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];
|
||||
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;
|
||||
if (looptimesum == 0) looptimesum = 2;
|
||||
int fittingrepeats = (int)ms / looptimesum;
|
||||
|
||||
grouprepeats = fittingrepeats;
|
||||
if (grouprepeats == 0) grouprepeats = 1;
|
||||
|
||||
for (int j = 0; j < grouprepeats; j++) {
|
||||
if (!interruped) {
|
||||
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, brightnes);
|
||||
flashled(c1, brightness);
|
||||
sleepwithinterrupts(loop1delay * loopdelayfactor);
|
||||
if (interruped) break;
|
||||
if (interrupted) break;
|
||||
}
|
||||
sleepwithinterrupts(ildelay1 * interloopdelayfactor);
|
||||
}
|
||||
if (!interruped) {
|
||||
if (!interrupted) {
|
||||
for (int i = 0; i < loopcnt2; i++) {
|
||||
flashled(c2, brightnes);
|
||||
flashled(c2, brightness);
|
||||
sleepwithinterrupts(loop2delay * loopdelayfactor);
|
||||
if (interruped) break;
|
||||
if (interrupted) break;
|
||||
}
|
||||
sleepwithinterrupts(ildelay2 * interloopdelayfactor);
|
||||
}
|
||||
|
||||
if (!interruped) {
|
||||
if (!interrupted) {
|
||||
for (int i = 0; i < loopcnt3; i++) {
|
||||
flashled(c3, brightnes);
|
||||
flashled(c3, brightness);
|
||||
sleepwithinterrupts(loop3delay * loopdelayfactor);
|
||||
if (interruped) break;
|
||||
if (interrupted) break;
|
||||
}
|
||||
sleepwithinterrupts(ildelay3 * interloopdelayfactor);
|
||||
}
|
||||
if (interruped) break;
|
||||
if (interrupted) break;
|
||||
flashposition++;
|
||||
}
|
||||
if (interrupted) ledcfg[0] = 0x00;
|
||||
} else
|
||||
sleepwithinterrupts(ms);
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@
|
||||
#define DBG_RXD 26
|
||||
#define DBG_TEST 27
|
||||
|
||||
#define BATTERY_VOLTAGE_MINIMUM 2450 // 2600 or below is the best we can do on the EPD
|
||||
#define EEPROM_SETTINGS_AREA_START 0
|
||||
|
||||
void initRTC0(uint32_t ms);
|
||||
int8_t startHFCLK(void);
|
||||
@@ -67,9 +67,48 @@ void resettimer();
|
||||
extern uint16_t batteryVoltage;
|
||||
extern bool lowBattery;
|
||||
extern int8_t temperature;
|
||||
extern bool disablePinInterruptSleep;
|
||||
//extern bool disablePinInterruptSleep;
|
||||
|
||||
void setupBatteryVoltage();
|
||||
void getVoltage();
|
||||
void setupTemperature();
|
||||
void getTemperature();
|
||||
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,27 +0,0 @@
|
||||
#ifndef _BOARDHEADER_H_
|
||||
#define _BOARDHEADER_H_
|
||||
|
||||
#include "../../../../tag_types.h"
|
||||
#include "HAL_Newton_M3.h"
|
||||
|
||||
// Mac fixed part
|
||||
// 7E77B949B19A (B19)
|
||||
#define MAC_ID_0 0xB1
|
||||
#define MAC_ID_1 0x90
|
||||
|
||||
// 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
|
||||
|
||||
#define EEPROM_IMG_EACH 0x3000UL // ((SCREEN_WIDTH*SCREEN_HEIGHT/8*2)+sizeof(struct eepromImageHeader)) rounded up to the nearest sector size (4096)
|
||||
|
||||
#define EPD_MIRROR_H
|
||||
#define EPD_DRAW_DIRECTION_RIGHT
|
||||
//#define CUSTOM_LUT_SUPPORT
|
||||
#endif
|
||||
@@ -1,34 +0,0 @@
|
||||
#ifndef _BOARDHEADER_H_
|
||||
#define _BOARDHEADER_H_
|
||||
|
||||
#include "../../../../tag_types.h"
|
||||
#include "HAL_Newton_M3.h"
|
||||
|
||||
|
||||
// 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 8
|
||||
#define SCREEN_YOFFSET 0
|
||||
|
||||
#define EEPROM_IMG_EACH 0x4000UL // ((SCREEN_WIDTH*SCREEN_HEIGHT/8*2)+sizeof(struct eepromImageHeader)) rounded up to the nearest sector size (4096)
|
||||
|
||||
#define EPD_MIRROR_H
|
||||
#define EPD_DRAW_DIRECTION_RIGHT
|
||||
//#define CUSTOM_LUT_SUPPORT
|
||||
|
||||
#endif
|
||||
@@ -1,35 +0,0 @@
|
||||
#ifndef _BOARDHEADER_H_
|
||||
#define _BOARDHEADER_H_
|
||||
|
||||
#include "../../../../tag_types.h"
|
||||
#include "HAL_Newton_M3.h"
|
||||
|
||||
|
||||
#define EEPROM_IMG_EACH (0x05000UL) // 800 * 480 * 2 / 8 = 0x17700
|
||||
|
||||
// Mac fixed part
|
||||
// 06F66008B7D0 (B7D)
|
||||
#define MAC_ID_0 0xB7
|
||||
#define MAC_ID_1 0xD0
|
||||
|
||||
// AP mode definitions
|
||||
#define HAS_EEPROM 1
|
||||
#define HAS_SCREEN 1
|
||||
#define AP_EMULATE_TAG 1
|
||||
|
||||
// hw type
|
||||
#define HW_TYPE SOLUM_M3_BWR_43
|
||||
#include "../include/uc_variant_043.h"
|
||||
|
||||
#define SCREEN_WIDTH 152
|
||||
#define SCREEN_HEIGHT 522
|
||||
|
||||
#define SCREEN_XOFFSET 0
|
||||
#define SCREEN_YOFFSET 0
|
||||
|
||||
#define EPD_MIRROR_H
|
||||
#define EPD_DRAW_DIRECTION_RIGHT
|
||||
|
||||
#define NO_BUTTONS 1
|
||||
|
||||
#endif
|
||||
@@ -1,30 +0,0 @@
|
||||
#ifndef _BOARDHEADER_H_
|
||||
#define _BOARDHEADER_H_
|
||||
|
||||
#include "../../../../tag_types.h"
|
||||
#include "HAL_Newton_M3.h"
|
||||
|
||||
|
||||
// Mac fixed part
|
||||
// 062E4793B899 (B29)
|
||||
#define MAC_ID_0 0xB8
|
||||
#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_60
|
||||
|
||||
#include "../include/uc8159.h"
|
||||
|
||||
#define SCREEN_WIDTH 600
|
||||
#define SCREEN_HEIGHT 448
|
||||
#define SCREEN_XOFFSET 0
|
||||
#define SCREEN_YOFFSET 0
|
||||
|
||||
#define EEPROM_IMG_EACH (0x11000UL)
|
||||
|
||||
#endif
|
||||
@@ -1,30 +0,0 @@
|
||||
#ifndef _BOARDHEADER_H_
|
||||
#define _BOARDHEADER_H_
|
||||
|
||||
#include "../../../../tag_types.h"
|
||||
#include "HAL_Newton_M3.h"
|
||||
|
||||
|
||||
|
||||
// Mac fixed part
|
||||
// 7E22CC67B298 (B29)
|
||||
#define MAC_ID_0 0xBC
|
||||
#define MAC_ID_1 0x90
|
||||
// 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
|
||||
|
||||
#define EEPROM_IMG_EACH (0x18000UL) // 800 * 480 * 2 / 8 = 0x17700
|
||||
|
||||
#endif
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -4,9 +4,6 @@
|
||||
// images generated by https://lvgl.io/tools/imageconverter, prepended with width, height. "CF_INDEXED_1_BIT"-mode, little-endian
|
||||
#include <stdint.h>
|
||||
|
||||
#include "hal.h"
|
||||
|
||||
|
||||
static const uint8_t oepli[] = {
|
||||
128,0x00, 26,0x00,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
|
||||
@@ -57,6 +57,11 @@ class drawItem {
|
||||
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,
|
||||
@@ -84,8 +89,7 @@ class drawItem {
|
||||
|
||||
protected:
|
||||
void copyWithByteShift(uint8_t *dst, uint8_t *src, uint8_t src_len, uint8_t offset);
|
||||
void reverseBytes(uint8_t *src, uint8_t src_len);
|
||||
uint8_t bitReverse(uint8_t byte);
|
||||
|
||||
|
||||
void getDrawLine(uint8_t *line, uint16_t number, uint8_t c);
|
||||
void getXLine(uint8_t *line, uint16_t yPos, uint8_t color);
|
||||
|
||||
@@ -36,6 +36,7 @@ struct EepromImageHeader {
|
||||
uint32_t size;
|
||||
uint8_t dataType;
|
||||
uint32_t id;
|
||||
uint8_t argument;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,25 +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_43_BWR
|
||||
#include "../hal/Newton_M3_nRF52811/Newton_M3_nRF52811_43_BWR.h"
|
||||
#include "../hal/Newton_M3_nRF52811/HAL_Newton_M3.h"
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef BUILD_NEWTON_M3_60_BWR
|
||||
#include "../hal/Newton_M3_nRF52811/Newton_M3_nRF52811_60_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"
|
||||
@@ -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
|
||||
@@ -47,6 +47,8 @@
|
||||
#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)
|
||||
#define VOLTAGEREADING_DURING_SCAN_INTERVAL 2 // how often we should read voltages; this is done every scan attempt in interval bracket 3
|
||||
#define INTERVAL_1_TIME 3600UL // Try every hour
|
||||
@@ -55,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();
|
||||
|
||||
@@ -3,8 +3,24 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define FW_VERSION 16 // version number (max 2.5.5 :) )
|
||||
#define FW_VERSION_SUFFIX "BETA3" // 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();
|
||||
|
||||
@@ -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,23 +0,0 @@
|
||||
#ifndef _JSCREEN_H_
|
||||
#define _JSCREEN_H_
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define EPD_LUT_DEFAULT 0
|
||||
#define EPD_LUT_NO_REPEATS 1
|
||||
#define EPD_LUT_FAST_NO_REDS 2
|
||||
#define EPD_LUT_FAST 3
|
||||
|
||||
void epdSetup();
|
||||
void epdEnterSleep();
|
||||
|
||||
|
||||
void draw();
|
||||
void drawNoWait();
|
||||
|
||||
void epdWaitRdy();
|
||||
|
||||
void selectLUT(uint8_t lut);
|
||||
|
||||
#endif
|
||||
@@ -1,24 +0,0 @@
|
||||
#ifndef _JSCREEN_H_
|
||||
#define _JSCREEN_H_
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define EPD_LUT_DEFAULT 0
|
||||
#define EPD_LUT_NO_REPEATS 1
|
||||
#define EPD_LUT_FAST_NO_REDS 2
|
||||
#define EPD_LUT_FAST 3
|
||||
|
||||
|
||||
void epdSetup();
|
||||
void epdEnterSleep();
|
||||
|
||||
|
||||
void draw();
|
||||
void drawNoWait();
|
||||
void epdWaitRdy();
|
||||
|
||||
void selectLUT(uint8_t lut);
|
||||
|
||||
|
||||
#endif
|
||||
@@ -1,23 +0,0 @@
|
||||
#ifndef _JSCREEN_H_
|
||||
#define _JSCREEN_H_
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define EPD_LUT_DEFAULT 0
|
||||
#define EPD_LUT_NO_REPEATS 1
|
||||
#define EPD_LUT_FAST_NO_REDS 2
|
||||
#define EPD_LUT_FAST 3
|
||||
|
||||
void epdSetup();
|
||||
void epdEnterSleep();
|
||||
|
||||
void draw();
|
||||
void drawNoWait();
|
||||
void drawWithSleep();
|
||||
void epdWaitRdy();
|
||||
|
||||
void selectLUT(uint8_t lut);
|
||||
|
||||
|
||||
#endif
|
||||
@@ -14,50 +14,13 @@ lib_deps =
|
||||
https://github.com/ricmoo/QRCode
|
||||
extra_scripts = post:preparefiles.py
|
||||
|
||||
|
||||
[env:Newton_M3_22_BWR]
|
||||
board_build.ldscript = nrf52811_bootloader.ld
|
||||
build_flags =
|
||||
${env.build_flags}
|
||||
-D BUILD_NEWTON_M3_22_BWR
|
||||
-Tnrf52811_bootloader.ld
|
||||
build_src_filter =
|
||||
+<*>-<uc_variant_043.cpp>-<uc8179.cpp>-<uc8159.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 =
|
||||
+<*>-<uc_variant_043.cpp>-<uc8179.cpp>-<uc8159.cpp>+<../hal/Newton_M3_nRF52811/*>
|
||||
|
||||
[env:Newton_M3_43_BWR]
|
||||
[env:Newton_M3_Universal]
|
||||
board_build.ldscript = nrf52811_bootloader.ld
|
||||
build_flags =
|
||||
-Wunused-macros
|
||||
${env.build_flags}
|
||||
-D BUILD_NEWTON_M3_43_BWR
|
||||
-D EPD_DRIVER=UCVARIANT043
|
||||
-Tnrf52811_bootloader.ld
|
||||
build_src_filter =
|
||||
+<*>-<ssd1619.cpp>-<uc8179.cpp>-<uc8159.cpp>+<../hal/Newton_M3_nRF52811/*>
|
||||
|
||||
[env:Newton_M3_60_BWR]
|
||||
board_build.ldscript = nrf52811_bootloader.ld
|
||||
build_flags =
|
||||
${env.build_flags}
|
||||
-Tnrf52811_bootloader.ld
|
||||
-D BUILD_NEWTON_M3_60_BWR
|
||||
build_src_filter =
|
||||
+<*>-<uc_variant_043.cpp>-<ssd1619.cpp>-<ssd1619.cpp>-<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 =
|
||||
+<*>-<uc_variant_043.cpp>-<ssd1619.cpp>-<uc8159.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;
|
||||
|
||||
@@ -6,29 +6,28 @@
|
||||
#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
|
||||
|
||||
static drawItem *drawItems[DRAWITEM_LIST_SIZE] = {0};
|
||||
|
||||
#ifdef EPD_DRAW_DIRECTION_RIGHT
|
||||
static bool drawDirection = true;
|
||||
#else
|
||||
static bool drawDirection = false;
|
||||
#endif
|
||||
|
||||
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 ^ drawDirection) {
|
||||
if (di->direction ^ epd->drawDirectionRight) {
|
||||
int16_t temp = x;
|
||||
x = y;
|
||||
y = temp;
|
||||
@@ -86,7 +85,7 @@ void addFlashImage(uint16_t x, uint16_t y, bool color, enum rotation ro, const u
|
||||
|
||||
di->setRotation(ro);
|
||||
|
||||
if (di->direction ^ drawDirection) {
|
||||
if (di->direction ^ epd->drawDirectionRight) {
|
||||
int16_t temp = x;
|
||||
x = y;
|
||||
y = temp;
|
||||
@@ -167,7 +166,7 @@ void drawImageAtAddress(uint32_t addr, uint8_t lut) {
|
||||
di->xpos = 0;
|
||||
di->ypos = 0;
|
||||
di->color = 0;
|
||||
di->addItem((uint8_t *)addr, SCREEN_WIDTH, SCREEN_HEIGHT);
|
||||
di->addItem((uint8_t *)addr, epd->effectiveXRes, epd->effectiveYRes);
|
||||
di->type = drawItem::drawType::DRAW_EEPROM_1BPP;
|
||||
di->direction = false;
|
||||
di->cleanUp = false;
|
||||
@@ -179,7 +178,7 @@ void drawImageAtAddress(uint32_t addr, uint8_t lut) {
|
||||
di->xpos = 0;
|
||||
di->ypos = 0;
|
||||
di->color = 0;
|
||||
di->addItem((uint8_t *)addr, SCREEN_WIDTH, SCREEN_HEIGHT);
|
||||
di->addItem((uint8_t *)addr, epd->effectiveXRes, epd->effectiveYRes);
|
||||
di->type = drawItem::drawType::DRAW_EEPROM_2BPP;
|
||||
di->direction = false;
|
||||
di->cleanUp = false;
|
||||
@@ -364,16 +363,14 @@ void drawItem::getXLine(uint8_t *line, uint16_t y, uint8_t c) {
|
||||
break;
|
||||
case DRAW_EEPROM_1BPP:
|
||||
if (c != color) return;
|
||||
#ifdef EPD_DRAW_DIRECTION_RIGHT
|
||||
y = SCREEN_HEIGHT - 1 - y;
|
||||
#endif
|
||||
eepromRead((uint32_t)buffer + sizeof(struct EepromImageHeader) + (y * (SCREEN_WIDTH / 8)), line, (SCREEN_WIDTH / 8));
|
||||
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:
|
||||
#ifdef EPD_DRAW_DIRECTION_RIGHT
|
||||
y = SCREEN_HEIGHT - 1 - y;
|
||||
#endif
|
||||
eepromRead((uint32_t)buffer + sizeof(struct EepromImageHeader) + ((y + (c * SCREEN_HEIGHT)) * (SCREEN_WIDTH / 8)), line, (SCREEN_WIDTH / 8));
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -457,27 +454,18 @@ drawItem::~drawItem() {
|
||||
}
|
||||
|
||||
drawItem::drawItem() {
|
||||
#ifdef EPD_DRAW_DIRECTION_RIGHT
|
||||
direction = true;
|
||||
#endif
|
||||
#ifdef EPD_MIRROR_H
|
||||
mirrorH = true;
|
||||
#endif
|
||||
#ifdef EPD_MIRROR_V
|
||||
mirrorV = true;
|
||||
#endif
|
||||
if (epd->drawDirectionRight) {
|
||||
direction = true;
|
||||
mirrorH = true;
|
||||
}
|
||||
}
|
||||
|
||||
void drawItem::setRotation(enum rotation ro) {
|
||||
#ifdef EPD_DRAW_DIRECTION_RIGHT
|
||||
direction = true;
|
||||
#endif
|
||||
#ifdef EPD_MIRROR_H
|
||||
mirrorH = true;
|
||||
#endif
|
||||
#ifdef EPD_MIRROR_V
|
||||
mirrorV = true;
|
||||
#endif
|
||||
if (epd->drawDirectionRight) {
|
||||
direction = true;
|
||||
mirrorH = true;
|
||||
}
|
||||
|
||||
switch (ro) {
|
||||
case ROTATE_0:
|
||||
break;
|
||||
@@ -588,7 +576,7 @@ void fontrender::epdPrintf(uint16_t x, uint16_t y, bool color, enum rotation ro,
|
||||
di->setRotation(ro);
|
||||
|
||||
// prepare a drawItem, exchange x/y if necessary.
|
||||
if (di->direction ^ drawDirection) {
|
||||
if (di->direction ^ epd->drawDirectionRight) {
|
||||
int16_t temp = x;
|
||||
x = y;
|
||||
y = temp;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#include "eeprom.h"
|
||||
#include "comms.h"
|
||||
#include "powermgt.h"
|
||||
#include "proto.h"
|
||||
|
||||
#include "syncedproto.h"
|
||||
#include "hal.h"
|
||||
|
||||
@@ -136,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) {
|
||||
}
|
||||
@@ -1,30 +1,28 @@
|
||||
#ifndef _JSCREEN_H_
|
||||
#define _JSCREEN_H_
|
||||
#ifndef _EPD_IFACE_H_
|
||||
#define _EPD_IFACE_H_
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define EPD_SSD1619
|
||||
|
||||
#define epdSend spi_write
|
||||
|
||||
#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
|
||||
|
||||
void epdSetup();
|
||||
void epdEnterSleep();
|
||||
|
||||
extern uint8_t dispLutSize;
|
||||
extern uint8_t customLUT[];
|
||||
|
||||
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);
|
||||
|
||||
#endif
|
||||
#include "uc_variant_043.h"
|
||||
#include "unissd.h"
|
||||
#include "uc_variant_029.h"
|
||||
#include "uc8159.h"
|
||||
#include "uc8179.h"
|
||||
|
||||
#endif
|
||||
@@ -1,5 +1,3 @@
|
||||
#include "uc8159.h"
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
@@ -13,6 +11,8 @@
|
||||
#include "wdt.h"
|
||||
#include "drawing.h"
|
||||
|
||||
#include "uc8159.h"
|
||||
|
||||
#define CMD_PANEL_SETTING 0x00
|
||||
#define CMD_POWER_SETTING 0x01
|
||||
#define CMD_POWER_OFF 0x02
|
||||
@@ -74,7 +74,7 @@
|
||||
|
||||
void dump(const uint8_t *a, const uint16_t l);
|
||||
|
||||
static void epdEepromRead(uint16_t addr, uint8_t *data, uint16_t len) {
|
||||
void uc8159::epdEepromRead(uint16_t addr, uint8_t *data, uint16_t len) {
|
||||
// return;
|
||||
epdWrite(CMD_SPI_FLASH_CONTROL, 1, 0x01);
|
||||
delay(1);
|
||||
@@ -88,7 +88,7 @@ static void epdEepromRead(uint16_t addr, uint8_t *data, uint16_t len) {
|
||||
delay(1);
|
||||
epdWrite(CMD_SPI_FLASH_CONTROL, 1, 0x00);
|
||||
}
|
||||
uint8_t getTempBracket() {
|
||||
uint8_t uc8159::getTempBracket() {
|
||||
uint8_t temptable[10];
|
||||
epdEepromRead(25002, temptable, 10);
|
||||
epdWrite(CMD_TEMPERATURE_DOREADING, 0);
|
||||
@@ -108,7 +108,7 @@ uint8_t getTempBracket() {
|
||||
epdHardSPI(true);
|
||||
return bracket;
|
||||
}
|
||||
static void loadFrameRatePLL(uint8_t bracket) {
|
||||
void uc8159::loadFrameRatePLL(uint8_t bracket) {
|
||||
uint8_t pllvalue;
|
||||
uint8_t plltable[10];
|
||||
epdEepromRead(0x6410, plltable, 10);
|
||||
@@ -116,7 +116,7 @@ static void loadFrameRatePLL(uint8_t bracket) {
|
||||
if (!pllvalue) pllvalue = 0x3C; // check if there's a valid pll value; if not; load preset
|
||||
epdWrite(CMD_PLL_CONTROL, 1, pllvalue);
|
||||
}
|
||||
static void loadTempVCOMDC(uint8_t bracket) {
|
||||
void uc8159::loadTempVCOMDC(uint8_t bracket) {
|
||||
uint8_t vcomvalue;
|
||||
uint8_t vcomtable[10];
|
||||
epdEepromRead(25049, vcomtable, 10);
|
||||
@@ -132,11 +132,11 @@ static void loadTempVCOMDC(uint8_t bracket) {
|
||||
epdWrite(CMD_VCOM_DC_SETTING, 1, vcomvalue);
|
||||
}
|
||||
|
||||
void epdEnterSleep() {
|
||||
void uc8159::epdEnterSleep() {
|
||||
epdWrite(CMD_POWER_OFF, 0);
|
||||
epdBusyWaitRising(250);
|
||||
}
|
||||
void epdSetup() {
|
||||
void uc8159::epdSetup() {
|
||||
epdReset();
|
||||
digitalWrite(EPD_BS, LOW);
|
||||
|
||||
@@ -162,7 +162,7 @@ void epdSetup() {
|
||||
epdBusyWaitRising(250);
|
||||
}
|
||||
|
||||
static void interleaveColorToBuffer(uint8_t *dst, uint8_t b, uint8_t r) {
|
||||
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--) {
|
||||
@@ -188,7 +188,7 @@ static void interleaveColorToBuffer(uint8_t *dst, uint8_t b, uint8_t r) {
|
||||
}
|
||||
}
|
||||
|
||||
void selectLUT(uint8_t lut) {
|
||||
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
|
||||
@@ -196,17 +196,17 @@ void selectLUT(uint8_t lut) {
|
||||
return;
|
||||
}
|
||||
|
||||
static void epdWriteDisplayData() {
|
||||
uint8_t screenrow_bw[SCREEN_WIDTH / 8];
|
||||
uint8_t screenrow_r[SCREEN_WIDTH / 8];
|
||||
uint8_t screenrowInterleaved[SCREEN_WIDTH / 8 * 4];
|
||||
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 < SCREEN_HEIGHT; curY++) {
|
||||
memset(screenrow_bw, 0, SCREEN_WIDTH / 8);
|
||||
memset(screenrow_r, 0, SCREEN_WIDTH / 8);
|
||||
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) {
|
||||
@@ -214,10 +214,10 @@ static void epdWriteDisplayData() {
|
||||
epdDeselect();
|
||||
epdSelect();
|
||||
}
|
||||
for (uint16_t curX = 0; curX < (SCREEN_WIDTH / 8); curX++) {
|
||||
for (uint16_t curX = 0; curX < (epd->effectiveXRes / 8); curX++) {
|
||||
interleaveColorToBuffer(screenrowInterleaved + (curX * 4), screenrow_bw[curX], screenrow_r[curX]);
|
||||
}
|
||||
epdSPIAsyncWrite(screenrowInterleaved, SCREEN_WIDTH / 8 * 4);
|
||||
epdSPIAsyncWrite(screenrowInterleaved, epd->effectiveXRes / 8 * 4);
|
||||
}
|
||||
epdSPIWait();
|
||||
|
||||
@@ -227,19 +227,16 @@ static void epdWriteDisplayData() {
|
||||
drawItem::flushDrawItems();
|
||||
}
|
||||
|
||||
void draw() {
|
||||
void uc8159::draw() {
|
||||
delay(1);
|
||||
drawNoWait();
|
||||
epdBusyWaitRising(25000);
|
||||
}
|
||||
void drawNoWait() {
|
||||
void uc8159::drawNoWait() {
|
||||
epdWriteDisplayData();
|
||||
// epdWrite(CMD_LOAD_FLASH_LUT, 1, 0x03);
|
||||
epdWrite(CMD_DISPLAY_REFRESH, 0);
|
||||
}
|
||||
void drawWithSleep() {
|
||||
draw();
|
||||
}
|
||||
void epdWaitRdy() {
|
||||
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
|
||||
@@ -1,5 +1,3 @@
|
||||
#include "uc8179.h"
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
@@ -12,6 +10,8 @@
|
||||
#include "hal.h"
|
||||
#include "wdt.h"
|
||||
|
||||
#include "uc8179.h"
|
||||
|
||||
#define CMD_PANEL_SETTING 0x00
|
||||
#define CMD_POWER_SETTING 0x01
|
||||
#define CMD_POWER_OFF 0x02
|
||||
@@ -48,9 +48,7 @@
|
||||
#define CMD_POWER_SAVING 0xE3
|
||||
#define CMD_FORCE_TEMPERATURE 0xE5
|
||||
|
||||
static bool isInited = false;
|
||||
|
||||
void epdEnterSleep() {
|
||||
void uc8179::epdEnterSleep() {
|
||||
epdWrite(CMD_VCOM_INTERVAL, 1, 0x17);
|
||||
delay(10);
|
||||
epdWrite(CMD_VCOM_DC_SETTING, 1, 0x00);
|
||||
@@ -59,17 +57,16 @@ void epdEnterSleep() {
|
||||
delay(10);
|
||||
epdWrite(CMD_DEEP_SLEEP, 1, 0xA5);
|
||||
delay(10);
|
||||
isInited = false;
|
||||
}
|
||||
|
||||
void epdSetup() {
|
||||
void uc8179::epdSetup() {
|
||||
epdReset();
|
||||
epdWrite(CMD_PANEL_SETTING, 1, 0x0F);
|
||||
epdWrite(CMD_VCOM_INTERVAL, 2, 0x30, 0x07);
|
||||
epdWrite(CMD_RESOLUTION_SETING, 4, SCREEN_WIDTH >> 8, SCREEN_WIDTH & 0xFF, SCREEN_HEIGHT >> 8, SCREEN_HEIGHT & 0xFF);
|
||||
epdWrite(CMD_RESOLUTION_SETING, 4, epd->effectiveXRes >> 8, epd->effectiveXRes & 0xFF, epd->effectiveYRes >> 8, epd->effectiveYRes & 0xFF);
|
||||
}
|
||||
|
||||
void selectLUT(uint8_t lut) {
|
||||
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
|
||||
@@ -77,7 +74,7 @@ void selectLUT(uint8_t lut) {
|
||||
return;
|
||||
}
|
||||
|
||||
void epdWriteDisplayData() {
|
||||
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
|
||||
@@ -86,9 +83,9 @@ void epdWriteDisplayData() {
|
||||
if (c == 1) epd_cmd(CMD_DISPLAY_START_TRANSMISSION_DTM2);
|
||||
markData();
|
||||
epdSelect();
|
||||
for (uint16_t curY = 0; curY < SCREEN_HEIGHT; curY += 2) {
|
||||
for (uint16_t curY = 0; curY < epd->effectiveYRes; curY += 2) {
|
||||
// Get 'even' screen line
|
||||
buf[0] = (uint8_t *)calloc(SCREEN_WIDTH / 8, 1);
|
||||
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
|
||||
@@ -99,10 +96,10 @@ void epdWriteDisplayData() {
|
||||
}
|
||||
|
||||
// start transfer of even data line to the screen
|
||||
epdSPIAsyncWrite(buf[0], (SCREEN_WIDTH / 8));
|
||||
epdSPIAsyncWrite(buf[0], (epd->effectiveXRes / 8));
|
||||
|
||||
// Get 'odd' screen display line
|
||||
buf[1] = (uint8_t *)calloc(SCREEN_WIDTH / 8, 1);
|
||||
buf[1] = (uint8_t *)calloc(epd->effectiveXRes / 8, 1);
|
||||
drawItem::renderDrawLine(buf[1], curY + 1, c);
|
||||
|
||||
// wait until the 'even' data has finished writing
|
||||
@@ -110,7 +107,7 @@ void epdWriteDisplayData() {
|
||||
free(buf[0]);
|
||||
|
||||
// start transfer of the 'odd' data line
|
||||
epdSPIAsyncWrite(buf[1], (SCREEN_WIDTH / 8));
|
||||
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) {
|
||||
@@ -130,16 +127,16 @@ void epdWriteDisplayData() {
|
||||
printf("draw took %lu ms\n", millis() - start);
|
||||
}
|
||||
|
||||
void draw() {
|
||||
void uc8179::draw() {
|
||||
drawNoWait();
|
||||
epdWaitRdy();
|
||||
}
|
||||
void drawNoWait() {
|
||||
void uc8179::drawNoWait() {
|
||||
epdWriteDisplayData();
|
||||
epdWrite(CMD_POWER_ON, 0);
|
||||
epdWaitRdy();
|
||||
epdWrite(CMD_DISPLAY_REFRESH, 0);
|
||||
}
|
||||
void epdWaitRdy() {
|
||||
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
|
||||
@@ -1,5 +1,3 @@
|
||||
#include "uc_variant_043.h"
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
@@ -13,6 +11,9 @@
|
||||
#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
|
||||
@@ -24,15 +25,16 @@
|
||||
#define EPD_CMD_RESOLUTION_SETTING 0x61
|
||||
#define EPD_CMD_UNKNOWN 0xF8
|
||||
|
||||
void epdEnterSleep() {
|
||||
void epdvar43::epdEnterSleep() {
|
||||
epdReset();
|
||||
delay(100);
|
||||
epd_cmd(EPD_CMD_POWER_OFF);
|
||||
epdBusyWaitRising(50000);
|
||||
delay(100);
|
||||
epdWrite(EPD_CMD_DEEP_SLEEP, 1, 0xA5);
|
||||
delay(200);
|
||||
delay(1);
|
||||
delay(100);
|
||||
}
|
||||
|
||||
void epdSetup() {
|
||||
void epdvar43::epdSetup() {
|
||||
epdReset();
|
||||
epdWrite(EPD_CMD_UNKNOWN, 2, 0x60, 0x05);
|
||||
epdWrite(EPD_CMD_UNKNOWN, 2, 0xA1, 0x00);
|
||||
@@ -48,20 +50,20 @@ void epdSetup() {
|
||||
epdWrite(EPD_CMD_VCOM_INTERVAL, 1, 0x87); // 47
|
||||
}
|
||||
|
||||
void epdWriteDisplayData() {
|
||||
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
|
||||
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 < SCREEN_HEIGHT; curY += 2) {
|
||||
for (uint16_t curY = 0; curY < this->effectiveYRes; curY += 2) {
|
||||
// Get 'even' screen line
|
||||
buf[0] = (uint8_t*)calloc(SCREEN_WIDTH / 8, 1);
|
||||
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
|
||||
@@ -72,10 +74,10 @@ void epdWriteDisplayData() {
|
||||
}
|
||||
|
||||
// start transfer of even data line to the screen
|
||||
epdSPIAsyncWrite(buf[0], (SCREEN_WIDTH / 8));
|
||||
epdSPIAsyncWrite(buf[0], (this->effectiveXRes / 8));
|
||||
|
||||
// Get 'odd' screen display line
|
||||
buf[1] = (uint8_t*)calloc(SCREEN_WIDTH / 8, 1);
|
||||
buf[1] = (uint8_t*)calloc(this->effectiveXRes / 8, 1);
|
||||
drawItem::renderDrawLine(buf[1], curY + 1, c);
|
||||
|
||||
// wait until the 'even' data has finished writing
|
||||
@@ -83,7 +85,7 @@ void epdWriteDisplayData() {
|
||||
free(buf[0]);
|
||||
|
||||
// start transfer of the 'odd' data line
|
||||
epdSPIAsyncWrite(buf[1], (SCREEN_WIDTH / 8));
|
||||
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) {
|
||||
@@ -99,10 +101,10 @@ void epdWriteDisplayData() {
|
||||
// wait until the last line of display has finished writing and clean our stuff up
|
||||
epdSPIWait();
|
||||
epdDeselect();
|
||||
if(buf[1])free(buf[1]);
|
||||
if (buf[1]) free(buf[1]);
|
||||
}
|
||||
|
||||
void selectLUT(uint8_t lut) {
|
||||
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
|
||||
@@ -110,17 +112,19 @@ void selectLUT(uint8_t lut) {
|
||||
return;
|
||||
}
|
||||
|
||||
void draw() {
|
||||
drawNoWait();
|
||||
void epdvar43::draw() {
|
||||
this->drawNoWait();
|
||||
epdBusyWaitRising(50000);
|
||||
delay(100);
|
||||
}
|
||||
void drawNoWait() {
|
||||
epdWriteDisplayData();
|
||||
void epdvar43::drawNoWait() {
|
||||
this->epdWriteDisplayData();
|
||||
epd_cmd(EPD_CMD_POWER_ON);
|
||||
epdBusyWaitRising(200);
|
||||
epd_cmd(EPD_CMD_DISPLAY_REFRESH);
|
||||
}
|
||||
|
||||
void epdWaitRdy() {
|
||||
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,280 +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);
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sw.beginTransmission(30);
|
||||
sw.write(uint8_t(0)); // Access the first register
|
||||
sw.endTransmission();
|
||||
void TagChanSearch() {
|
||||
// not associated
|
||||
if (((scanAttempts != 0) && (scanAttempts % VOLTAGEREADING_DURING_SCAN_INTERVAL == 0)) || (scanAttempts > (INTERVAL_1_ATTEMPTS + INTERVAL_2_ATTEMPTS))) {
|
||||
powerUp(INIT_VOLTREADING);
|
||||
}
|
||||
|
||||
digitalWrite(NFC_POWER,LOW);
|
||||
pinMode(NFC_POWER, INPUT_PULLDOWN);
|
||||
// try to find a working channel
|
||||
currentChannel = channelSelect(2);
|
||||
|
||||
powerDown(INIT_I2C);
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
|
||||
// we always have NFC + NFC wake
|
||||
capabilities |= CAPABILITY_HAS_NFC;
|
||||
capabilities |= CAPABILITY_NFC_WAKE;
|
||||
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();
|
||||
getVoltage();
|
||||
setupTemperature();
|
||||
getTemperature();
|
||||
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) {
|
||||
#ifdef NO_BUTTONS
|
||||
disablePinInterruptSleep = true;
|
||||
#endif
|
||||
// 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 {
|
||||
#ifdef NO_BUTTONS
|
||||
disablePinInterruptSleep = false;
|
||||
#endif
|
||||
// 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;
|
||||
@@ -61,7 +62,8 @@ void setupPortsInitial() {
|
||||
pinMode(NFC_POWER, INPUT_PULLDOWN);
|
||||
pinMode(NFC_IRQ, INPUT_PULLDOWN);
|
||||
|
||||
pinMode(EPD_POWER, DEFAULT);
|
||||
pinMode(EPD_POWER, OUTPUT);
|
||||
digitalWrite(EPD_POWER, LOW);
|
||||
|
||||
pinMode(FLASH_MISO, INPUT);
|
||||
pinMode(FLASH_CLK, OUTPUT);
|
||||
@@ -148,7 +150,7 @@ void powerUp(const uint8_t parts) {
|
||||
epdSetup();
|
||||
}
|
||||
|
||||
if (parts & INIT_EPD_VOLTREADING) {
|
||||
if (parts & INIT_VOLTREADING) {
|
||||
getVoltage();
|
||||
if (batteryVoltage < BATTERY_VOLTAGE_MINIMUM) {
|
||||
lowBattery = true;
|
||||
@@ -198,7 +200,6 @@ void powerDown(const uint8_t parts) {
|
||||
configEEPROM(false);
|
||||
}
|
||||
if (parts & INIT_EPD) {
|
||||
epdConfigGPIO(true);
|
||||
epdEnterSleep();
|
||||
epdConfigGPIO(false);
|
||||
}
|
||||
@@ -211,7 +212,7 @@ void powerDown(const uint8_t parts) {
|
||||
}
|
||||
|
||||
void doSleep(const uint32_t t) {
|
||||
printf("Sleeping for: %lu 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);
|
||||
}
|
||||
@@ -1,436 +0,0 @@
|
||||
#include "ssd1619.h"
|
||||
|
||||
#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"
|
||||
|
||||
#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
|
||||
|
||||
#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(const uint8_t *a, const uint16_t l); // remove me when done
|
||||
|
||||
static uint8_t currentLut = 0;
|
||||
uint8_t dispLutSize = 0; // we'll need to expose this in the 'capabilities' flag
|
||||
|
||||
static bool isInited = false;
|
||||
|
||||
#define LUT_BUFFER_SIZE 256
|
||||
static uint8_t waveformbuffer[LUT_BUFFER_SIZE];
|
||||
uint8_t customLUT[LUT_BUFFER_SIZE] = {0};
|
||||
|
||||
struct waveform10 *waveform10 = (struct waveform10 *)waveformbuffer; // holds the LUT/waveform
|
||||
struct waveform *waveform7 = (struct waveform *)waveformbuffer; // holds the LUT/waveform
|
||||
struct waveform12 *waveform12 = (struct waveform12 *)waveformbuffer; // holds the LUT/waveform
|
||||
|
||||
static void commandReadBegin(uint8_t cmd) {
|
||||
epdSelect();
|
||||
markCommand();
|
||||
spi_write(cmd);
|
||||
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();
|
||||
}
|
||||
|
||||
void setWindowX(uint16_t start, uint16_t end) {
|
||||
epdWrite(CMD_WINDOW_X_SIZE, 2, start / 8, end / 8 - 1);
|
||||
}
|
||||
void setWindowY(uint16_t start, uint16_t end) {
|
||||
epdWrite(CMD_WINDOW_Y_SIZE, 4, (start)&0xff, (start) >> 8, (end - 1) & 0xff, (end - 1) >> 8);
|
||||
}
|
||||
void setPosXY(uint16_t x, uint16_t y) {
|
||||
epdWrite(CMD_XSTART_POS, 1, (uint8_t)(x / 8));
|
||||
epdWrite(CMD_YSTART_POS, 2, (y)&0xff, (y) >> 8);
|
||||
}
|
||||
|
||||
void epdEnterSleep() {
|
||||
digitalWrite(EPD_RST, LOW);
|
||||
delay(10);
|
||||
digitalWrite(EPD_RST, HIGH);
|
||||
delay(50);
|
||||
shortCommand(CMD_SOFT_RESET2);
|
||||
epdBusyWaitFalling(15);
|
||||
shortCommand1(CMD_ENTER_SLEEP, 0x03);
|
||||
isInited = false;
|
||||
}
|
||||
void epdSetup() {
|
||||
epdReset();
|
||||
shortCommand(CMD_SOFT_RESET); // software reset
|
||||
delay(10);
|
||||
shortCommand(CMD_SOFT_RESET2);
|
||||
delay(10);
|
||||
epdWrite(CMD_ANALOG_BLK_CTRL, 1, 0x54);
|
||||
epdWrite(CMD_DIGITAL_BLK_CTRL, 1, 0x3B);
|
||||
epdWrite(CMD_VCOM_GLITCH_CTRL, 2, 0x04, 0x63);
|
||||
epdWrite(CMD_DRV_OUTPUT_CTRL, 3, (SCREEN_HEIGHT - 1) & 0xff, (SCREEN_HEIGHT - 1) >> 8, 0x00);
|
||||
epdWrite(CMD_DISP_UPDATE_CTRL, 2, 0x08, 0x00);
|
||||
epdWrite(CMD_BORDER_WAVEFORM_CTRL, 1, 0x01);
|
||||
epdWrite(CMD_TEMP_SENSOR_CONTROL, 1, 0x80);
|
||||
epdWrite(CMD_DISP_UPDATE_CTRL2, 1, 0xB1);
|
||||
epdWrite(CMD_ACTIVATION, 0);
|
||||
epdBusyWaitFalling(10000);
|
||||
isInited = true;
|
||||
currentLut = EPD_LUT_DEFAULT;
|
||||
}
|
||||
static uint8_t epdGetStatus() {
|
||||
uint8_t sta;
|
||||
commandReadBegin(0x2F);
|
||||
sta = epdReadByte();
|
||||
commandReadEnd();
|
||||
return sta;
|
||||
}
|
||||
|
||||
void loadFixedTempOTPLUT() {
|
||||
shortCommand1(0x18, 0x48); // external temp sensor
|
||||
shortCommand2(0x1A, 0x05, 0x00); // < temp register
|
||||
shortCommand1(CMD_DISP_UPDATE_CTRL2, 0xB1); // mode 1 (i2C)
|
||||
shortCommand(CMD_ACTIVATION);
|
||||
epdBusyWaitFalling(1000);
|
||||
}
|
||||
static void writeLut() {
|
||||
commandBegin(CMD_WRITE_LUT);
|
||||
if (dispLutSize == 12) {
|
||||
for (uint8_t i = 0; i < 153; i++)
|
||||
epdSend(waveformbuffer[i]);
|
||||
} else {
|
||||
for (uint8_t i = 0; i < (dispLutSize * 10); i++)
|
||||
epdSend(waveformbuffer[i]);
|
||||
}
|
||||
commandEnd();
|
||||
}
|
||||
static void readLut() {
|
||||
commandReadBegin(0x33);
|
||||
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) {
|
||||
switch (dispLutSize) {
|
||||
case 7:
|
||||
memset(&(waveform7->group[group]), 0x00, 5);
|
||||
break;
|
||||
case 10:
|
||||
memset(&(waveform10->group[group]), 0x00, 5);
|
||||
break;
|
||||
case 12:
|
||||
memset(&(waveform12->group[group]), 0x00, sizeof(waveform12->group[0]));
|
||||
break;
|
||||
}
|
||||
}
|
||||
static void lutGroupSpeedup(uint8_t group, uint8_t speed) {
|
||||
switch (dispLutSize) {
|
||||
case 7:
|
||||
for (uint8_t i = 0; i < 4; i++) {
|
||||
waveform7->group[group].phaselength[i] = 1 + (waveform7->group[group].phaselength[i] / speed);
|
||||
}
|
||||
break;
|
||||
case 10:
|
||||
for (uint8_t i = 0; i < 4; i++) {
|
||||
waveform10->group[group].phaselength[i] = 1 + (waveform10->group[group].phaselength[i] / speed);
|
||||
}
|
||||
break;
|
||||
case 12:
|
||||
waveform12->group[group].tp0a = 1 + (waveform12->group[group].tp0a / speed);
|
||||
waveform12->group[group].tp0b = 1 + (waveform12->group[group].tp0b / speed);
|
||||
waveform12->group[group].tp0c = 1 + (waveform12->group[group].tp0c / speed);
|
||||
waveform12->group[group].tp0d = 1 + (waveform12->group[group].tp0d / speed);
|
||||
break;
|
||||
}
|
||||
}
|
||||
static void lutGroupRepeat(uint8_t group, uint8_t repeat) {
|
||||
switch (dispLutSize) {
|
||||
case 7:
|
||||
waveform7->group[group].repeat = repeat;
|
||||
break;
|
||||
case 10:
|
||||
waveform10->group[group].repeat = repeat;
|
||||
break;
|
||||
case 12:
|
||||
waveform12->group[group].repeat = repeat;
|
||||
break;
|
||||
}
|
||||
}
|
||||
static void lutGroupRepeatReduce(uint8_t group, uint8_t factor) {
|
||||
switch (dispLutSize) {
|
||||
case 7:
|
||||
waveform7->group[group].repeat = waveform7->group[group].repeat / factor;
|
||||
break;
|
||||
case 10:
|
||||
waveform10->group[group].repeat = waveform10->group[group].repeat / factor;
|
||||
break;
|
||||
case 12:
|
||||
waveform12->group[group].repeat = waveform12->group[group].repeat / factor;
|
||||
break;
|
||||
}
|
||||
}
|
||||
void selectLUT(uint8_t lut) {
|
||||
if (currentLut == lut) {
|
||||
// return;
|
||||
}
|
||||
|
||||
// Handling if we received an OTA LUT
|
||||
if (lut == EPD_LUT_OTA) {
|
||||
memcpy(waveformbuffer, customLUT, dispLutSize * 10);
|
||||
writeLut();
|
||||
currentLut = lut;
|
||||
return;
|
||||
}
|
||||
|
||||
if (currentLut != EPD_LUT_DEFAULT) {
|
||||
// load the 'default' LUT for the current temperature in the EPD lut register
|
||||
shortCommand1(CMD_DISP_UPDATE_CTRL2, 0xB1); // mode 1?
|
||||
shortCommand(CMD_ACTIVATION);
|
||||
epdBusyWaitFalling(1000);
|
||||
}
|
||||
|
||||
currentLut = lut;
|
||||
|
||||
// if we're going to be using the default LUT, we're done here.
|
||||
if (lut == EPD_LUT_DEFAULT) {
|
||||
return;
|
||||
}
|
||||
|
||||
// download the current LUT from the waveform buffer
|
||||
readLut();
|
||||
|
||||
if (dispLutSize == 0) {
|
||||
dispLutSize = getLutSize();
|
||||
dispLutSize /= 10;
|
||||
printf("lut size = %d\n", dispLutSize);
|
||||
dispLutSize = 12;
|
||||
#ifdef PRINT_LUT
|
||||
dump(waveformbuffer, LUT_BUFFER_SIZE);
|
||||
#endif
|
||||
memcpy(customLUT, waveformbuffer, LUT_BUFFER_SIZE);
|
||||
}
|
||||
|
||||
switch (lut) {
|
||||
default:
|
||||
case EPD_LUT_NO_REPEATS:
|
||||
lutGroupDisable(LUTGROUP_NEGATIVE);
|
||||
lutGroupDisable(LUTGROUP_FASTBLINK);
|
||||
lutGroupRepeat(LUTGROUP_SLOWBLINK, 0);
|
||||
lutGroupSpeedup(LUTGROUP_SET, 2);
|
||||
lutGroupSpeedup(LUTGROUP_IMPROVE_SHARPNESS, 2);
|
||||
lutGroupRepeatReduce(LUTGROUP_IMPROVE_SHARPNESS, 2);
|
||||
lutGroupSpeedup(LUTGROUP_IMPROVE_REDS, 2);
|
||||
lutGroupRepeatReduce(LUTGROUP_IMPROVE_REDS, 2);
|
||||
lutGroupDisable(LUTGROUP_UNUSED);
|
||||
break;
|
||||
case EPD_LUT_FAST_NO_REDS:
|
||||
lutGroupDisable(LUTGROUP_NEGATIVE);
|
||||
lutGroupDisable(LUTGROUP_FASTBLINK);
|
||||
lutGroupDisable(LUTGROUP_SLOWBLINK);
|
||||
lutGroupSpeedup(LUTGROUP_SET, 2);
|
||||
lutGroupDisable(LUTGROUP_IMPROVE_REDS);
|
||||
lutGroupDisable(LUTGROUP_IMPROVE_SHARPNESS);
|
||||
lutGroupDisable(LUTGROUP_UNUSED);
|
||||
break;
|
||||
case EPD_LUT_FAST:
|
||||
lutGroupDisable(LUTGROUP_NEGATIVE);
|
||||
lutGroupDisable(LUTGROUP_FASTBLINK);
|
||||
lutGroupDisable(LUTGROUP_SLOWBLINK);
|
||||
lutGroupRepeat(LUTGROUP_SET, 1);
|
||||
lutGroupSpeedup(LUTGROUP_SET, 2);
|
||||
lutGroupDisable(LUTGROUP_IMPROVE_SHARPNESS);
|
||||
lutGroupDisable(LUTGROUP_IMPROVE_REDS);
|
||||
lutGroupDisable(LUTGROUP_UNUSED);
|
||||
break;
|
||||
}
|
||||
|
||||
if (dispLutSize == 10) {
|
||||
lutGroupDisable(LUTGROUP_UNUSED);
|
||||
lutGroupDisable(LUTGROUP_UNKNOWN);
|
||||
lutGroupDisable(LUTGROUP_UNUSED3);
|
||||
lutGroupDisable(LUTGROUP_UNUSED4);
|
||||
}
|
||||
writeLut();
|
||||
}
|
||||
|
||||
void epdWriteDisplayData() {
|
||||
setWindowX(SCREEN_XOFFSET, SCREEN_WIDTH + SCREEN_XOFFSET);
|
||||
setPosXY(SCREEN_XOFFSET, 0);
|
||||
// epdWrite(CMD_DISP_UPDATE_CTRL, 1, 0x08);
|
||||
|
||||
// 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_WRITE_FB_BW);
|
||||
if (c == 1) epd_cmd(CMD_WRITE_FB_RED);
|
||||
markData();
|
||||
epdSelect();
|
||||
for (uint16_t curY = 0; curY < SCREEN_HEIGHT; curY += 2) {
|
||||
// Get 'even' screen line
|
||||
buf[0] = (uint8_t *)calloc(SCREEN_WIDTH / 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], (SCREEN_WIDTH / 8));
|
||||
|
||||
// Get 'odd' screen display line
|
||||
buf[1] = (uint8_t *)calloc(SCREEN_WIDTH / 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], (SCREEN_WIDTH / 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 draw() {
|
||||
drawNoWait();
|
||||
getVoltage();
|
||||
epdBusyWaitFalling(120000);
|
||||
}
|
||||
void drawNoWait() {
|
||||
epdWriteDisplayData();
|
||||
epdWrite(0x22, 1, 0xF7);
|
||||
epdWrite(0x20, 0);
|
||||
}
|
||||
void epdWaitRdy() {
|
||||
epdBusyWaitFalling(120000);
|
||||
}
|
||||
@@ -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"
|
||||
|
||||
@@ -24,19 +25,21 @@ struct fwmetadata {
|
||||
|
||||
#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};
|
||||
@@ -49,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;
|
||||
@@ -187,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);
|
||||
}
|
||||
@@ -254,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;
|
||||
@@ -395,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");
|
||||
@@ -429,19 +435,19 @@ 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_EACH * s);
|
||||
return (tag.imageSize * s);
|
||||
}
|
||||
static void getNumSlots() {
|
||||
uint32_t eeSize = eepromGetSize();
|
||||
|
||||
uint16_t nSlots = (eeSize - EEPROM_SETTINGS_SIZE) / (EEPROM_IMG_EACH >> 8) >> 8;
|
||||
uint16_t nSlots = (eeSize - EEPROM_SETTINGS_SIZE) / (tag.imageSize >> 8) >> 8;
|
||||
if (!nSlots) {
|
||||
printf("eeprom is too small\n");
|
||||
while (1)
|
||||
@@ -453,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) {
|
||||
@@ -485,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) {
|
||||
@@ -568,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
|
||||
@@ -622,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
|
||||
@@ -649,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);
|
||||
@@ -698,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;
|
||||
@@ -733,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);
|
||||
@@ -853,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);
|
||||
@@ -864,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)
|
||||
@@ -888,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();
|
||||
@@ -920,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;
|
||||
}
|
||||
@@ -942,4 +1051,4 @@ bool processAvailDataInfo(struct AvailDataInfo *avail) {
|
||||
void initializeProto() {
|
||||
getNumSlots();
|
||||
curHighSlotId = getHighSlotId();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
|
||||
|
||||
#include "userinterface.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
@@ -10,20 +8,16 @@
|
||||
|
||||
#include "lut.h"
|
||||
#include "powermgt.h"
|
||||
#include "proto.h"
|
||||
|
||||
#include "settings.h"
|
||||
#include "syncedproto.h" // for APmac / Channel
|
||||
#include "hal.h"
|
||||
#include "drawing.h"
|
||||
#include "font.h"
|
||||
|
||||
#ifdef EPD_DRAW_DIRECTION_RIGHT
|
||||
#define UI_SCREEN_WIDTH SCREEN_HEIGHT
|
||||
#define UI_SCREEN_HEIGHT SCREEN_WIDTH
|
||||
#else
|
||||
#define UI_SCREEN_WIDTH SCREEN_WIDTH
|
||||
#define UI_SCREEN_HEIGHT SCREEN_HEIGHT
|
||||
#endif
|
||||
#include "epd_driver/epd_interface.h"
|
||||
|
||||
#include "../../../oepl-definitions.h"
|
||||
|
||||
const uint8_t fwVersion = FW_VERSION;
|
||||
const char fwVersionSuffix[] = FW_VERSION_SUFFIX;
|
||||
@@ -33,21 +27,21 @@ bool noAPShown = false;
|
||||
|
||||
void addOverlay() {
|
||||
if (currentChannel == 0) {
|
||||
drawMask(SCREEN_WIDTH - 27, 5, 22, 22, COLOR_BLACK);
|
||||
drawMask(SCREEN_WIDTH - 27, 5, 22, 22, COLOR_RED);
|
||||
drawRoundedRectangle(SCREEN_WIDTH - 28, 4, 24, 24, COLOR_RED);
|
||||
addBufferedImage(SCREEN_WIDTH - 24, 8, COLOR_BLACK, rotation::ROTATE_0, ant, DRAW_NORMAL);
|
||||
addBufferedImage(SCREEN_WIDTH - 16, 15, COLOR_RED, rotation::ROTATE_0, cross, DRAW_NORMAL);
|
||||
drawMask(epd->Xres - 27, 5, 22, 22, COLOR_BLACK);
|
||||
drawMask(epd->Xres - 27, 5, 22, 22, COLOR_RED);
|
||||
drawRoundedRectangle(epd->Xres - 28, 4, 24, 24, COLOR_RED);
|
||||
addBufferedImage(epd->Xres - 24, 8, COLOR_BLACK, rotation::ROTATE_0, ant, DRAW_NORMAL);
|
||||
addBufferedImage(epd->Xres - 16, 15, COLOR_RED, rotation::ROTATE_0, cross, DRAW_NORMAL);
|
||||
noAPShown = true;
|
||||
} else {
|
||||
noAPShown = false;
|
||||
}
|
||||
|
||||
if (lowBattery) {
|
||||
drawMask(SCREEN_WIDTH - 27, SCREEN_HEIGHT - 26, 22, 22, COLOR_BLACK);
|
||||
drawMask(SCREEN_WIDTH - 27, SCREEN_HEIGHT - 26, 22, 22, COLOR_RED);
|
||||
drawRoundedRectangle(SCREEN_WIDTH - 28, SCREEN_HEIGHT - 27, 24, 24, COLOR_RED);
|
||||
addBufferedImage(SCREEN_WIDTH - 24, SCREEN_HEIGHT - 19, COLOR_BLACK, rotation::ROTATE_0, battery, DRAW_NORMAL);
|
||||
drawMask(epd->Xres - 27, epd->Yres - 26, 22, 22, COLOR_BLACK);
|
||||
drawMask(epd->Xres - 27, epd->Yres - 26, 22, 22, COLOR_RED);
|
||||
drawRoundedRectangle(epd->Xres - 28, epd->Yres - 26, 24, 24, COLOR_RED);
|
||||
addBufferedImage(epd->Xres - 24, epd->Yres - 19, COLOR_BLACK, rotation::ROTATE_0, battery, DRAW_NORMAL);
|
||||
|
||||
lowBatteryShown = true;
|
||||
} else {
|
||||
@@ -62,59 +56,89 @@ void afterFlashScreenSaver() {
|
||||
|
||||
void showSplashScreen() {
|
||||
selectLUT(EPD_LUT_FAST_NO_REDS);
|
||||
#if (HW_TYPE == SOLUM_M3_BWR_22)
|
||||
fontrender fr(&FreeSansBold18pt7b);
|
||||
fr.epdPrintf(2, 2, COLOR_BLACK, rotation::ROTATE_0, "OpenEPaperLink");
|
||||
fr.setFont(&FreeSans9pt7b);
|
||||
fr.epdPrintf(10, 38, COLOR_RED, rotation::ROTATE_0, "Newton M3 2.2\"");
|
||||
// fr.setFont(&FreeSans9pt7b);
|
||||
fr.epdPrintf(5, UI_SCREEN_HEIGHT - 40, 0, rotation::ROTATE_0, "FW: %d.%d.%d-%s", fwVersion / 100, (fwVersion % 100) / 10, (fwVersion % 10), fwVersionSuffix);
|
||||
fr.epdPrintf(5, UI_SCREEN_HEIGHT - 20, 0, rotation::ROTATE_0, "MAC: %02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X", mSelfMac[7], mSelfMac[6], mSelfMac[5], mSelfMac[4], mSelfMac[3], mSelfMac[2], mSelfMac[1], mSelfMac[0]);
|
||||
addQR(UI_SCREEN_WIDTH - 120, 42, 3, 3, "https://openepaperlink.eu/tag/0/%02X/%02X%02X%02X%02X%02X%02X%02X%02X/", HW_TYPE, mSelfMac[7], mSelfMac[6], mSelfMac[5], mSelfMac[4], mSelfMac[3], mSelfMac[2], mSelfMac[1], mSelfMac[0]);
|
||||
#endif
|
||||
#if (HW_TYPE == SOLUM_M3_BWR_29)
|
||||
fontrender fr(&FreeSansBold18pt7b);
|
||||
fr.epdPrintf(2, 2, COLOR_BLACK, rotation::ROTATE_0, "OpenEPaperLink");
|
||||
fr.setFont(&FreeSans9pt7b);
|
||||
fr.epdPrintf(10, 38, 1, rotation::ROTATE_0, "Newton M3 2.9\"");
|
||||
// fr.setFont(&FreeSans9pt7b);
|
||||
fr.epdPrintf(UI_SCREEN_WIDTH - 17, 0, 0, rotation::ROTATE_270, "FW: %d.%d.%d-%s", fwVersion / 100, (fwVersion % 100) / 10, (fwVersion % 10), fwVersionSuffix);
|
||||
fr.epdPrintf(5, UI_SCREEN_HEIGHT - 20, 0, rotation::ROTATE_0, "MAC: %02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X", mSelfMac[7], mSelfMac[6], mSelfMac[5], mSelfMac[4], mSelfMac[3], mSelfMac[2], mSelfMac[1], mSelfMac[0]);
|
||||
addQR(UI_SCREEN_WIDTH - 120, 42, 3, 3, "https://openepaperlink.eu/tag/0/%02X/%02X%02X%02X%02X%02X%02X%02X%02X/", HW_TYPE, mSelfMac[7], mSelfMac[6], mSelfMac[5], mSelfMac[4], mSelfMac[3], mSelfMac[2], mSelfMac[1], mSelfMac[0]);
|
||||
#endif
|
||||
#if (HW_TYPE == SOLUM_M3_BWR_43)
|
||||
fontrender fr(&FreeSansBold24pt7b);
|
||||
fr.epdPrintf(7, 7, COLOR_BLACK, rotation::ROTATE_0, "OpenEPaperLink");
|
||||
fr.setFont(&FreeSansBold18pt7b);
|
||||
fr.epdPrintf(15, 60, COLOR_RED, rotation::ROTATE_0, "Newton M3 4.3\"");
|
||||
fr.setFont(&FreeSans9pt7b);
|
||||
fr.epdPrintf(UI_SCREEN_WIDTH - 17, 0, 0, rotation::ROTATE_270, "FW: %d.%d.%d-%s", fwVersion / 100, (fwVersion % 100) / 10, (fwVersion % 10), fwVersionSuffix);
|
||||
fr.epdPrintf(10, UI_SCREEN_HEIGHT - 25, 0, rotation::ROTATE_0, "MAC: %02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X", mSelfMac[7], mSelfMac[6], mSelfMac[5], mSelfMac[4], mSelfMac[3], mSelfMac[2], mSelfMac[1], mSelfMac[0]);
|
||||
addQR(UI_SCREEN_WIDTH - 120, 32, 3, 3, "https://openepaperlink.eu/tag/0/%02X/%02X%02X%02X%02X%02X%02X%02X%02X/", HW_TYPE, mSelfMac[7], mSelfMac[6], mSelfMac[5], mSelfMac[4], mSelfMac[3], mSelfMac[2], mSelfMac[1], mSelfMac[0]);
|
||||
#endif
|
||||
#if (HW_TYPE == SOLUM_M3_BWR_60)
|
||||
fontrender fr(&FreeSansBold24pt7b);
|
||||
fr.epdPrintf(10, 10, COLOR_BLACK, rotation::ROTATE_0, "OpenEPaperLink");
|
||||
fr.setFont(&FreeSansBold18pt7b);
|
||||
fr.epdPrintf(15, 60, 1, rotation::ROTATE_0, "Newton M3 6.0\"");
|
||||
fr.setFont(&FreeSans9pt7b);
|
||||
fr.epdPrintf(UI_SCREEN_WIDTH - 17, 310, 0, rotation::ROTATE_270, "FW: %d.%d.%d-%s", fwVersion / 100, (fwVersion % 100) / 10, (fwVersion % 10), fwVersionSuffix);
|
||||
fr.epdPrintf(10, UI_SCREEN_HEIGHT - 25, 0, rotation::ROTATE_0, "MAC: %02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X", mSelfMac[7], mSelfMac[6], mSelfMac[5], mSelfMac[4], mSelfMac[3], mSelfMac[2], mSelfMac[1], mSelfMac[0]);
|
||||
addFlashImage(293, 61, COLOR_BLACK, rotation::ROTATE_0, newton);
|
||||
addQR(40, 120, 3, 7, "https://openepaperlink.eu/tag/0/%02X/%02X%02X%02X%02X%02X%02X%02X%02X/", HW_TYPE, mSelfMac[7], mSelfMac[6], mSelfMac[5], mSelfMac[4], mSelfMac[3], mSelfMac[2], mSelfMac[1], mSelfMac[0]);
|
||||
#endif
|
||||
#if (HW_TYPE == SOLUM_M3_BWR_75)
|
||||
fontrender fr(&FreeSansBold24pt7b);
|
||||
fr.epdPrintf(10, 10, COLOR_BLACK, rotation::ROTATE_0, "OpenEPaperLink");
|
||||
fr.setFont(&FreeSansBold18pt7b);
|
||||
fr.epdPrintf(15, 60, COLOR_RED, rotation::ROTATE_0, "Newton M3 7.5\"");
|
||||
fr.setFont(&FreeSans9pt7b);
|
||||
fr.epdPrintf(UI_SCREEN_WIDTH - 17, 310, 0, rotation::ROTATE_270, "FW: %d.%d.%d-%s", fwVersion / 100, (fwVersion % 100) / 10, (fwVersion % 10), fwVersionSuffix);
|
||||
fr.epdPrintf(10, UI_SCREEN_HEIGHT - 25, 0, rotation::ROTATE_0, "MAC: %02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X", mSelfMac[7], mSelfMac[6], mSelfMac[5], mSelfMac[4], mSelfMac[3], mSelfMac[2], mSelfMac[1], mSelfMac[0]);
|
||||
addFlashImage(420, 81, COLOR_BLACK, rotation::ROTATE_0, newton);
|
||||
addQR(100, 160, 3, 7, "https://openepaperlink.eu/tag/0/%02X/%02X%02X%02X%02X%02X%02X%02X%02X/", HW_TYPE, mSelfMac[7], mSelfMac[6], mSelfMac[5], mSelfMac[4], mSelfMac[3], mSelfMac[2], mSelfMac[1], mSelfMac[0]);
|
||||
|
||||
#endif
|
||||
switch (tag.solumType) {
|
||||
case STYPE_SIZE_016:
|
||||
fr.setFont(&FreeSans9pt7b);
|
||||
fr.epdPrintf(2, 2, COLOR_BLACK, rotation::ROTATE_0, "OpenEPaperLink");
|
||||
fr.epdPrintf(10, 38, COLOR_RED, rotation::ROTATE_0, "Newton M3 2.2\"");
|
||||
fr.epdPrintf(5, epd->Yres - 40, 0, rotation::ROTATE_0, "FW: %04X-%s", fwVersion, fwVersionSuffix);
|
||||
fr.epdPrintf(2, epd->Yres - 20, 0, rotation::ROTATE_0, "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X", mSelfMac[7], mSelfMac[6], mSelfMac[5], mSelfMac[4], mSelfMac[3], mSelfMac[2], mSelfMac[1], mSelfMac[0]);
|
||||
break;
|
||||
case STYPE_SIZE_022:
|
||||
fr.setFont(&FreeSansBold18pt7b);
|
||||
fr.epdPrintf(2, 2, COLOR_BLACK, rotation::ROTATE_0, "OpenEPaperLink");
|
||||
fr.setFont(&FreeSans9pt7b);
|
||||
fr.epdPrintf(10, 38, COLOR_RED, rotation::ROTATE_0, "Newton M3 2.2\"");
|
||||
// fr.setFont(&FreeSans9pt7b);
|
||||
fr.epdPrintf(5, epd->Yres - 40, 0, rotation::ROTATE_0, "FW: %04X-%s", fwVersion, fwVersionSuffix);
|
||||
fr.epdPrintf(5, epd->Yres - 20, 0, rotation::ROTATE_0, "MAC: %02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X", mSelfMac[7], mSelfMac[6], mSelfMac[5], mSelfMac[4], mSelfMac[3], mSelfMac[2], mSelfMac[1], mSelfMac[0]);
|
||||
addQR(epd->Xres - 120, 42, 3, 3, "https://openepaperlink.eu/tag/0/%02X/%02X%02X%02X%02X%02X%02X%02X%02X/", tag.OEPLtype, mSelfMac[7], mSelfMac[6], mSelfMac[5], mSelfMac[4], mSelfMac[3], mSelfMac[2], mSelfMac[1], mSelfMac[0]);
|
||||
break;
|
||||
case STYPE_SIZE_029:
|
||||
fr.setFont(&FreeSansBold18pt7b);
|
||||
fr.epdPrintf(2, 2, COLOR_BLACK, rotation::ROTATE_0, "OpenEPaperLink");
|
||||
fr.setFont(&FreeSans9pt7b);
|
||||
fr.epdPrintf(10, 38, 1, rotation::ROTATE_0, "Newton M3 2.9\"");
|
||||
// fr.setFont(&FreeSans9pt7b);
|
||||
fr.epdPrintf(epd->Xres - 17, 0, 0, rotation::ROTATE_270, "FW: %04X-%s", fwVersion, fwVersionSuffix);
|
||||
fr.epdPrintf(5, epd->Yres - 20, 0, rotation::ROTATE_0, "MAC: %02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X", mSelfMac[7], mSelfMac[6], mSelfMac[5], mSelfMac[4], mSelfMac[3], mSelfMac[2], mSelfMac[1], mSelfMac[0]);
|
||||
addQR(epd->Xres - 120, 42, 3, 3, "https://openepaperlink.eu/tag/0/%02X/%02X%02X%02X%02X%02X%02X%02X%02X/", tag.OEPLtype, mSelfMac[7], mSelfMac[6], mSelfMac[5], mSelfMac[4], mSelfMac[3], mSelfMac[2], mSelfMac[1], mSelfMac[0]);
|
||||
break;
|
||||
case STYPE_SIZE_042:
|
||||
fr.setFont(&FreeSansBold18pt7b);
|
||||
fr.epdPrintf(2, 2, COLOR_BLACK, rotation::ROTATE_0, "OpenEPaperLink");
|
||||
fr.setFont(&FreeSans9pt7b);
|
||||
fr.epdPrintf(10, 38, 1, rotation::ROTATE_0, "Newton M3 4.2\"");
|
||||
// fr.setFont(&FreeSans9pt7b);
|
||||
fr.epdPrintf(epd->Xres - 17, 0, 0, rotation::ROTATE_270, "FW: %04X-%s", fwVersion, fwVersionSuffix);
|
||||
fr.epdPrintf(5, epd->Yres - 20, 0, rotation::ROTATE_0, "MAC: %02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X", mSelfMac[7], mSelfMac[6], mSelfMac[5], mSelfMac[4], mSelfMac[3], mSelfMac[2], mSelfMac[1], mSelfMac[0]);
|
||||
addQR(epd->Xres - 120, 120, 3, 3, "https://openepaperlink.eu/tag/0/%02X/%02X%02X%02X%02X%02X%02X%02X%02X/", tag.OEPLtype, mSelfMac[7], mSelfMac[6], mSelfMac[5], mSelfMac[4], mSelfMac[3], mSelfMac[2], mSelfMac[1], mSelfMac[0]);
|
||||
break;
|
||||
case STYPE_SIZE_043:
|
||||
fr.setFont(&FreeSansBold24pt7b);
|
||||
fr.epdPrintf(7, 7, COLOR_BLACK, rotation::ROTATE_0, "OpenEPaperLink");
|
||||
fr.setFont(&FreeSansBold18pt7b);
|
||||
fr.epdPrintf(15, 60, COLOR_RED, rotation::ROTATE_0, "Newton M3 4.3\"");
|
||||
fr.setFont(&FreeSans9pt7b);
|
||||
fr.epdPrintf(epd->Xres - 17, 0, 0, rotation::ROTATE_270, "FW: %04X-%s", fwVersion, fwVersionSuffix);
|
||||
fr.epdPrintf(10, epd->Yres - 25, 0, rotation::ROTATE_0, "MAC: %02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X", mSelfMac[7], mSelfMac[6], mSelfMac[5], mSelfMac[4], mSelfMac[3], mSelfMac[2], mSelfMac[1], mSelfMac[0]);
|
||||
addQR(epd->Xres - 120, 32, 3, 3, "https://openepaperlink.eu/tag/0/%02X/%02X%02X%02X%02X%02X%02X%02X%02X/", tag.OEPLtype, mSelfMac[7], mSelfMac[6], mSelfMac[5], mSelfMac[4], mSelfMac[3], mSelfMac[2], mSelfMac[1], mSelfMac[0]);
|
||||
break;
|
||||
case STYPE_SIZE_060:
|
||||
fr.setFont(&FreeSansBold24pt7b);
|
||||
fr.epdPrintf(10, 10, COLOR_BLACK, rotation::ROTATE_0, "OpenEPaperLink");
|
||||
fr.setFont(&FreeSansBold18pt7b);
|
||||
fr.epdPrintf(15, 60, 1, rotation::ROTATE_0, "Newton M3 6.0\"");
|
||||
fr.setFont(&FreeSans9pt7b);
|
||||
fr.epdPrintf(epd->Xres - 17, 310, 0, rotation::ROTATE_270, "FW: %04X-%s", fwVersion, fwVersionSuffix);
|
||||
fr.epdPrintf(10, epd->Yres - 25, 0, rotation::ROTATE_0, "MAC: %02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X", mSelfMac[7], mSelfMac[6], mSelfMac[5], mSelfMac[4], mSelfMac[3], mSelfMac[2], mSelfMac[1], mSelfMac[0]);
|
||||
addFlashImage(293, 61, COLOR_BLACK, rotation::ROTATE_0, newton);
|
||||
addQR(40, 120, 3, 7, "https://openepaperlink.eu/tag/0/%02X/%02X%02X%02X%02X%02X%02X%02X%02X/", tag.OEPLtype, mSelfMac[7], mSelfMac[6], mSelfMac[5], mSelfMac[4], mSelfMac[3], mSelfMac[2], mSelfMac[1], mSelfMac[0]);
|
||||
break;
|
||||
case STYPE_SIZE_075:
|
||||
fr.setFont(&FreeSansBold24pt7b);
|
||||
fr.epdPrintf(10, 10, COLOR_BLACK, rotation::ROTATE_0, "OpenEPaperLink");
|
||||
fr.setFont(&FreeSansBold18pt7b);
|
||||
fr.epdPrintf(15, 60, COLOR_RED, rotation::ROTATE_0, "Newton M3 7.5\"");
|
||||
fr.setFont(&FreeSans9pt7b);
|
||||
fr.epdPrintf(epd->Xres - 17, 310, 0, rotation::ROTATE_270, "FW: %04X-%s", fwVersion, fwVersionSuffix);
|
||||
fr.epdPrintf(10, epd->Yres - 25, 0, rotation::ROTATE_0, "MAC: %02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X", mSelfMac[7], mSelfMac[6], mSelfMac[5], mSelfMac[4], mSelfMac[3], mSelfMac[2], mSelfMac[1], mSelfMac[0]);
|
||||
addFlashImage(420, 81, COLOR_BLACK, rotation::ROTATE_0, newton);
|
||||
addQR(100, 160, 3, 7, "https://openepaperlink.eu/tag/0/%02X/%02X%02X%02X%02X%02X%02X%02X%02X/", tag.OEPLtype, mSelfMac[7], mSelfMac[6], mSelfMac[5], mSelfMac[4], mSelfMac[3], mSelfMac[2], mSelfMac[1], mSelfMac[0]);
|
||||
break;
|
||||
case STYPE_SIZE_097:
|
||||
fr.setFont(&FreeSansBold24pt7b);
|
||||
fr.epdPrintf(10, 10, COLOR_BLACK, rotation::ROTATE_0, "OpenEPaperLink");
|
||||
fr.setFont(&FreeSansBold18pt7b);
|
||||
fr.epdPrintf(15, 60, COLOR_RED, rotation::ROTATE_0, "Newton M3 9.7\"");
|
||||
fr.setFont(&FreeSans9pt7b);
|
||||
fr.epdPrintf(epd->Xres - 37, 310, 0, rotation::ROTATE_270, "FW: %04X-%s", fwVersion, fwVersionSuffix);
|
||||
fr.epdPrintf(10, epd->Yres - 25, 0, rotation::ROTATE_0, "MAC: %02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X", mSelfMac[7], mSelfMac[6], mSelfMac[5], mSelfMac[4], mSelfMac[3], mSelfMac[2], mSelfMac[1], mSelfMac[0]);
|
||||
addFlashImage(220, 420, COLOR_BLACK, rotation::ROTATE_0, newton);
|
||||
addQR(260, 160, 3, 7, "https://openepaperlink.eu/tag/0/%02X/%02X%02X%02X%02X%02X%02X%02X%02X/", tag.OEPLtype, mSelfMac[7], mSelfMac[6], mSelfMac[5], mSelfMac[4], mSelfMac[3], mSelfMac[2], mSelfMac[1], mSelfMac[0]);
|
||||
break;
|
||||
}
|
||||
draw();
|
||||
}
|
||||
|
||||
@@ -136,129 +160,195 @@ void showScanningWindow() {
|
||||
|
||||
void showAPFound() {
|
||||
selectLUT(EPD_LUT_NO_REPEATS);
|
||||
fontrender fr(&FreeSansBold18pt7b);
|
||||
switch (tag.solumType) {
|
||||
case STYPE_SIZE_016:
|
||||
fr.setFont(&FreeSans9pt7b);
|
||||
fr.epdPrintf(7, 6, COLOR_BLACK, rotation::ROTATE_0, "AP Found");
|
||||
fr.epdPrintf(0, 24, COLOR_RED, rotation::ROTATE_0, "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X", APmac[7], APmac[6], APmac[5], APmac[4], APmac[3], APmac[2], APmac[1], APmac[0]);
|
||||
fr.epdPrintf(5, 42, COLOR_RED, rotation::ROTATE_0, "RSSI: %ddBm LQI: %d", mLastRSSI, mLastLqi);
|
||||
fr.epdPrintf(5, 60, COLOR_RED, rotation::ROTATE_0, "Ch %d", currentChannel);
|
||||
fr.setFont(&FreeSans9pt7b);
|
||||
fr.epdPrintf(5, epd->Yres - 43, 0, rotation::ROTATE_0, "Battery: %d.%dV Temp: %d'C", batteryVoltage / 1000, batteryVoltage % 1000, temperature);
|
||||
fr.epdPrintf(0, epd->Yres - 25, 0, rotation::ROTATE_0, "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X", mSelfMac[7], mSelfMac[6], mSelfMac[5], mSelfMac[4], mSelfMac[3], mSelfMac[2], mSelfMac[1], mSelfMac[0]);
|
||||
|
||||
#if (HW_TYPE == SOLUM_M3_BWR_22)
|
||||
fontrender fr(&FreeSansBold18pt7b);
|
||||
fr.epdPrintf(7, 7, COLOR_BLACK, rotation::ROTATE_0, "AP Found");
|
||||
fr.setFont(&FreeSans9pt7b);
|
||||
fr.epdPrintf(10, 53, COLOR_RED, rotation::ROTATE_0, "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X", APmac[7], APmac[6], APmac[5], APmac[4], APmac[3], APmac[2], APmac[1], APmac[0]);
|
||||
fr.epdPrintf(10, 71, COLOR_RED, rotation::ROTATE_0, "RSSI: %ddBm LQI: %d", mLastRSSI, mLastLqi);
|
||||
fr.epdPrintf(10, 89, COLOR_RED, rotation::ROTATE_0, "Ch %d", currentChannel);
|
||||
fr.setFont(&FreeSans9pt7b);
|
||||
fr.epdPrintf(10, UI_SCREEN_HEIGHT - 43, 0, rotation::ROTATE_0, "Battery: %d.%dV Temp: %d'C", batteryVoltage / 1000, batteryVoltage % 1000, temperature);
|
||||
fr.epdPrintf(10, UI_SCREEN_HEIGHT - 25, 0, rotation::ROTATE_0, "MAC: %02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X", mSelfMac[7], mSelfMac[6], mSelfMac[5], mSelfMac[4], mSelfMac[3], mSelfMac[2], mSelfMac[1], mSelfMac[0]);
|
||||
addQR(UI_SCREEN_WIDTH - 66, 47, 3, 2, "https://openepaperlink.eu/tag/1/%02X/%02X%02X%02X%02X%02X%02X%02X%02X/", HW_TYPE, mSelfMac[7], mSelfMac[6], mSelfMac[5], mSelfMac[4], mSelfMac[3], mSelfMac[2], mSelfMac[1], mSelfMac[0]);
|
||||
#endif
|
||||
#if (HW_TYPE == SOLUM_M3_BWR_29)
|
||||
fontrender fr(&FreeSansBold18pt7b);
|
||||
fr.epdPrintf(7, 7, COLOR_BLACK, rotation::ROTATE_0, "AP Found");
|
||||
fr.setFont(&FreeSans9pt7b);
|
||||
fr.epdPrintf(10, 53, COLOR_RED, rotation::ROTATE_0, "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X", APmac[7], APmac[6], APmac[5], APmac[4], APmac[3], APmac[2], APmac[1], APmac[0]);
|
||||
fr.epdPrintf(10, 71, COLOR_RED, rotation::ROTATE_0, "RSSI: %ddBm LQI: %d", mLastRSSI, mLastLqi);
|
||||
fr.epdPrintf(10, 89, COLOR_RED, rotation::ROTATE_0, "Ch %d", currentChannel);
|
||||
fr.setFont(&FreeSans9pt7b);
|
||||
fr.epdPrintf(10, UI_SCREEN_HEIGHT - 43, 0, rotation::ROTATE_0, "Battery: %d.%dV Temp: %d'C", batteryVoltage / 1000, batteryVoltage % 1000, temperature);
|
||||
fr.epdPrintf(10, UI_SCREEN_HEIGHT - 25, 0, rotation::ROTATE_0, "MAC: %02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X", mSelfMac[7], mSelfMac[6], mSelfMac[5], mSelfMac[4], mSelfMac[3], mSelfMac[2], mSelfMac[1], mSelfMac[0]);
|
||||
addQR(UI_SCREEN_WIDTH - 66, 47, 3, 2, "https://openepaperlink.eu/tag/1/%02X/%02X%02X%02X%02X%02X%02X%02X%02X/", HW_TYPE, mSelfMac[7], mSelfMac[6], mSelfMac[5], mSelfMac[4], mSelfMac[3], mSelfMac[2], mSelfMac[1], mSelfMac[0]);
|
||||
#endif
|
||||
#if (HW_TYPE == SOLUM_M3_BWR_43)
|
||||
fontrender fr(&FreeSansBold18pt7b);
|
||||
fr.epdPrintf(7, 7, COLOR_BLACK, rotation::ROTATE_0, "AP Found - Waiting for data");
|
||||
fr.setFont(&FreeSans9pt7b);
|
||||
fr.epdPrintf(15, 55, COLOR_RED, rotation::ROTATE_0, "AP: %02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X", APmac[7], APmac[6], APmac[5], APmac[4], APmac[3], APmac[2], APmac[1], APmac[0]);
|
||||
fr.epdPrintf(15, 73, COLOR_RED, rotation::ROTATE_0, "RSSI: %ddBm LQI: %d", mLastRSSI, mLastLqi);
|
||||
fr.setFont(&FreeSansBold18pt7b);
|
||||
fr.epdPrintf(270, 55, COLOR_RED, rotation::ROTATE_0, "Ch %d", currentChannel);
|
||||
fr.setFont(&FreeSans9pt7b);
|
||||
fr.epdPrintf(10, UI_SCREEN_HEIGHT - 43, 0, rotation::ROTATE_0, "Battery: %d.%dV Temp: %d'C", batteryVoltage / 1000, batteryVoltage % 1000, temperature);
|
||||
fr.epdPrintf(10, UI_SCREEN_HEIGHT - 25, 0, rotation::ROTATE_0, "MAC: %02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X", mSelfMac[7], mSelfMac[6], mSelfMac[5], mSelfMac[4], mSelfMac[3], mSelfMac[2], mSelfMac[1], mSelfMac[0]);
|
||||
addQR(UI_SCREEN_WIDTH - 66, 47, 3, 2, "https://openepaperlink.eu/tag/1/%02X/%02X%02X%02X%02X%02X%02X%02X%02X/", HW_TYPE, mSelfMac[7], mSelfMac[6], mSelfMac[5], mSelfMac[4], mSelfMac[3], mSelfMac[2], mSelfMac[1], mSelfMac[0]);
|
||||
#endif
|
||||
#if (HW_TYPE == SOLUM_M3_BWR_60)
|
||||
fontrender fr(&FreeSansBold18pt7b);
|
||||
fr.epdPrintf(7, 7, COLOR_BLACK, rotation::ROTATE_0, "AP Found - Waiting for data");
|
||||
fr.setFont(&FreeSans9pt7b);
|
||||
fr.epdPrintf(15, 55, COLOR_RED, rotation::ROTATE_0, "AP: %02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X", APmac[7], APmac[6], APmac[5], APmac[4], APmac[3], APmac[2], APmac[1], APmac[0]);
|
||||
fr.epdPrintf(15, 73, COLOR_RED, rotation::ROTATE_0, "RSSI: %ddBm LQI: %d", mLastRSSI, mLastLqi);
|
||||
fr.setFont(&FreeSansBold18pt7b);
|
||||
fr.epdPrintf(270, 55, COLOR_RED, rotation::ROTATE_0, "Ch %d", currentChannel);
|
||||
fr.setFont(&FreeSans9pt7b);
|
||||
fr.epdPrintf(10, UI_SCREEN_HEIGHT - 43, 0, rotation::ROTATE_0, "Battery: %d.%dV Temp: %d'C", batteryVoltage / 1000, batteryVoltage % 1000, temperature);
|
||||
fr.epdPrintf(10, UI_SCREEN_HEIGHT - 25, 0, rotation::ROTATE_0, "MAC: %02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X", mSelfMac[7], mSelfMac[6], mSelfMac[5], mSelfMac[4], mSelfMac[3], mSelfMac[2], mSelfMac[1], mSelfMac[0]);
|
||||
addQR(UI_SCREEN_WIDTH - 66, 47, 3, 2, "https://openepaperlink.eu/tag/1/%02X/%02X%02X%02X%02X%02X%02X%02X%02X/", HW_TYPE, mSelfMac[7], mSelfMac[6], mSelfMac[5], mSelfMac[4], mSelfMac[3], mSelfMac[2], mSelfMac[1], mSelfMac[0]);
|
||||
#endif
|
||||
#if (HW_TYPE == SOLUM_M3_BWR_75)
|
||||
fontrender fr(&FreeSansBold18pt7b);
|
||||
fr.epdPrintf(7, 7, COLOR_BLACK, rotation::ROTATE_0, "AP Found - Waiting for data");
|
||||
fr.setFont(&FreeSans9pt7b);
|
||||
fr.epdPrintf(15, 55, COLOR_RED, rotation::ROTATE_0, "AP: %02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X", APmac[7], APmac[6], APmac[5], APmac[4], APmac[3], APmac[2], APmac[1], APmac[0]);
|
||||
fr.epdPrintf(15, 73, COLOR_RED, rotation::ROTATE_0, "RSSI: %ddBm LQI: %d", mLastRSSI, mLastLqi);
|
||||
fr.setFont(&FreeSansBold18pt7b);
|
||||
fr.epdPrintf(270, 55, COLOR_RED, rotation::ROTATE_0, "Ch %d", currentChannel);
|
||||
fr.setFont(&FreeSans9pt7b);
|
||||
fr.epdPrintf(10, UI_SCREEN_HEIGHT - 43, 0, rotation::ROTATE_0, "Battery: %d.%dV Temp: %d'C", batteryVoltage / 1000, batteryVoltage % 1000, temperature);
|
||||
fr.epdPrintf(10, UI_SCREEN_HEIGHT - 25, 0, rotation::ROTATE_0, "MAC: %02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X", mSelfMac[7], mSelfMac[6], mSelfMac[5], mSelfMac[4], mSelfMac[3], mSelfMac[2], mSelfMac[1], mSelfMac[0]);
|
||||
addQR(UI_SCREEN_WIDTH - 66, 47, 3, 2, "https://openepaperlink.eu/tag/1/%02X/%02X%02X%02X%02X%02X%02X%02X%02X/", HW_TYPE, mSelfMac[7], mSelfMac[6], mSelfMac[5], mSelfMac[4], mSelfMac[3], mSelfMac[2], mSelfMac[1], mSelfMac[0]);
|
||||
#endif
|
||||
break;
|
||||
case STYPE_SIZE_022:
|
||||
fr.setFont(&FreeSansBold18pt7b);
|
||||
fr.epdPrintf(7, 7, COLOR_BLACK, rotation::ROTATE_0, "AP Found");
|
||||
fr.setFont(&FreeSans9pt7b);
|
||||
fr.epdPrintf(10, 53, COLOR_RED, rotation::ROTATE_0, "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X", APmac[7], APmac[6], APmac[5], APmac[4], APmac[3], APmac[2], APmac[1], APmac[0]);
|
||||
fr.epdPrintf(10, 71, COLOR_RED, rotation::ROTATE_0, "RSSI: %ddBm LQI: %d", mLastRSSI, mLastLqi);
|
||||
fr.epdPrintf(10, 89, COLOR_RED, rotation::ROTATE_0, "Ch %d", currentChannel);
|
||||
fr.setFont(&FreeSans9pt7b);
|
||||
fr.epdPrintf(10, epd->Yres - 43, 0, rotation::ROTATE_0, "Battery: %d.%dV Temp: %d'C", batteryVoltage / 1000, batteryVoltage % 1000, temperature);
|
||||
fr.epdPrintf(10, epd->Yres - 25, 0, rotation::ROTATE_0, "MAC: %02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X", mSelfMac[7], mSelfMac[6], mSelfMac[5], mSelfMac[4], mSelfMac[3], mSelfMac[2], mSelfMac[1], mSelfMac[0]);
|
||||
addQR(epd->Xres - 66, 47, 3, 2, "https://openepaperlink.eu/tag/1/%02X/%02X%02X%02X%02X%02X%02X%02X%02X/", tag.OEPLtype, mSelfMac[7], mSelfMac[6], mSelfMac[5], mSelfMac[4], mSelfMac[3], mSelfMac[2], mSelfMac[1], mSelfMac[0]);
|
||||
break;
|
||||
case STYPE_SIZE_029:
|
||||
fr.setFont(&FreeSansBold18pt7b);
|
||||
fr.epdPrintf(7, 7, COLOR_BLACK, rotation::ROTATE_0, "AP Found");
|
||||
fr.setFont(&FreeSans9pt7b);
|
||||
fr.epdPrintf(10, 53, COLOR_RED, rotation::ROTATE_0, "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X", APmac[7], APmac[6], APmac[5], APmac[4], APmac[3], APmac[2], APmac[1], APmac[0]);
|
||||
fr.epdPrintf(10, 71, COLOR_RED, rotation::ROTATE_0, "RSSI: %ddBm LQI: %d", mLastRSSI, mLastLqi);
|
||||
fr.epdPrintf(10, 89, COLOR_RED, rotation::ROTATE_0, "Ch %d", currentChannel);
|
||||
fr.setFont(&FreeSans9pt7b);
|
||||
fr.epdPrintf(10, epd->Yres - 43, 0, rotation::ROTATE_0, "Battery: %d.%dV Temp: %d'C", batteryVoltage / 1000, batteryVoltage % 1000, temperature);
|
||||
fr.epdPrintf(10, epd->Yres - 25, 0, rotation::ROTATE_0, "MAC: %02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X", mSelfMac[7], mSelfMac[6], mSelfMac[5], mSelfMac[4], mSelfMac[3], mSelfMac[2], mSelfMac[1], mSelfMac[0]);
|
||||
addQR(epd->Xres - 66, 47, 3, 2, "https://openepaperlink.eu/tag/1/%02X/%02X%02X%02X%02X%02X%02X%02X%02X/", tag.OEPLtype, mSelfMac[7], mSelfMac[6], mSelfMac[5], mSelfMac[4], mSelfMac[3], mSelfMac[2], mSelfMac[1], mSelfMac[0]);
|
||||
break;
|
||||
case STYPE_SIZE_042:
|
||||
fr.setFont(&FreeSansBold18pt7b);
|
||||
fr.epdPrintf(7, 7, COLOR_BLACK, rotation::ROTATE_0, "AP Found");
|
||||
fr.setFont(&FreeSans9pt7b);
|
||||
fr.epdPrintf(10, 53, COLOR_RED, rotation::ROTATE_0, "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X", APmac[7], APmac[6], APmac[5], APmac[4], APmac[3], APmac[2], APmac[1], APmac[0]);
|
||||
fr.epdPrintf(10, 71, COLOR_RED, rotation::ROTATE_0, "RSSI: %ddBm LQI: %d", mLastRSSI, mLastLqi);
|
||||
fr.epdPrintf(10, 89, COLOR_RED, rotation::ROTATE_0, "Ch %d", currentChannel);
|
||||
fr.setFont(&FreeSans9pt7b);
|
||||
fr.epdPrintf(10, epd->Yres - 43, 0, rotation::ROTATE_0, "Battery: %d.%dV Temp: %d'C", batteryVoltage / 1000, batteryVoltage % 1000, temperature);
|
||||
fr.epdPrintf(10, epd->Yres - 25, 0, rotation::ROTATE_0, "MAC: %02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X", mSelfMac[7], mSelfMac[6], mSelfMac[5], mSelfMac[4], mSelfMac[3], mSelfMac[2], mSelfMac[1], mSelfMac[0]);
|
||||
addQR(epd->Xres - 66, 47, 3, 2, "https://openepaperlink.eu/tag/1/%02X/%02X%02X%02X%02X%02X%02X%02X%02X/", tag.OEPLtype, mSelfMac[7], mSelfMac[6], mSelfMac[5], mSelfMac[4], mSelfMac[3], mSelfMac[2], mSelfMac[1], mSelfMac[0]);
|
||||
break;
|
||||
case STYPE_SIZE_043:
|
||||
fr.setFont(&FreeSansBold18pt7b);
|
||||
fr.epdPrintf(7, 7, COLOR_BLACK, rotation::ROTATE_0, "AP Found - Waiting for data");
|
||||
fr.setFont(&FreeSans9pt7b);
|
||||
fr.epdPrintf(15, 55, COLOR_RED, rotation::ROTATE_0, "AP: %02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X", APmac[7], APmac[6], APmac[5], APmac[4], APmac[3], APmac[2], APmac[1], APmac[0]);
|
||||
fr.epdPrintf(15, 73, COLOR_RED, rotation::ROTATE_0, "RSSI: %ddBm LQI: %d", mLastRSSI, mLastLqi);
|
||||
fr.setFont(&FreeSansBold18pt7b);
|
||||
fr.epdPrintf(270, 55, COLOR_RED, rotation::ROTATE_0, "Ch %d", currentChannel);
|
||||
fr.setFont(&FreeSans9pt7b);
|
||||
fr.epdPrintf(10, epd->Yres - 43, 0, rotation::ROTATE_0, "Battery: %d.%dV Temp: %d'C", batteryVoltage / 1000, batteryVoltage % 1000, temperature);
|
||||
fr.epdPrintf(10, epd->Yres - 25, 0, rotation::ROTATE_0, "MAC: %02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X", mSelfMac[7], mSelfMac[6], mSelfMac[5], mSelfMac[4], mSelfMac[3], mSelfMac[2], mSelfMac[1], mSelfMac[0]);
|
||||
addQR(epd->Xres - 66, 47, 3, 2, "https://openepaperlink.eu/tag/1/%02X/%02X%02X%02X%02X%02X%02X%02X%02X/", tag.OEPLtype, mSelfMac[7], mSelfMac[6], mSelfMac[5], mSelfMac[4], mSelfMac[3], mSelfMac[2], mSelfMac[1], mSelfMac[0]);
|
||||
break;
|
||||
case STYPE_SIZE_060:
|
||||
fr.setFont(&FreeSansBold18pt7b);
|
||||
fr.epdPrintf(7, 7, COLOR_BLACK, rotation::ROTATE_0, "AP Found - Waiting for data");
|
||||
fr.setFont(&FreeSans9pt7b);
|
||||
fr.epdPrintf(15, 55, COLOR_RED, rotation::ROTATE_0, "AP: %02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X", APmac[7], APmac[6], APmac[5], APmac[4], APmac[3], APmac[2], APmac[1], APmac[0]);
|
||||
fr.epdPrintf(15, 73, COLOR_RED, rotation::ROTATE_0, "RSSI: %ddBm LQI: %d", mLastRSSI, mLastLqi);
|
||||
fr.setFont(&FreeSansBold18pt7b);
|
||||
fr.epdPrintf(270, 55, COLOR_RED, rotation::ROTATE_0, "Ch %d", currentChannel);
|
||||
fr.setFont(&FreeSans9pt7b);
|
||||
fr.epdPrintf(10, epd->Yres - 43, 0, rotation::ROTATE_0, "Battery: %d.%dV Temp: %d'C", batteryVoltage / 1000, batteryVoltage % 1000, temperature);
|
||||
fr.epdPrintf(10, epd->Yres - 25, 0, rotation::ROTATE_0, "MAC: %02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X", mSelfMac[7], mSelfMac[6], mSelfMac[5], mSelfMac[4], mSelfMac[3], mSelfMac[2], mSelfMac[1], mSelfMac[0]);
|
||||
addQR(epd->Xres - 66, 47, 3, 2, "https://openepaperlink.eu/tag/1/%02X/%02X%02X%02X%02X%02X%02X%02X%02X/", tag.OEPLtype, mSelfMac[7], mSelfMac[6], mSelfMac[5], mSelfMac[4], mSelfMac[3], mSelfMac[2], mSelfMac[1], mSelfMac[0]);
|
||||
break;
|
||||
case STYPE_SIZE_075:
|
||||
fr.setFont(&FreeSansBold18pt7b);
|
||||
fr.epdPrintf(7, 7, COLOR_BLACK, rotation::ROTATE_0, "AP Found - Waiting for data");
|
||||
fr.setFont(&FreeSans9pt7b);
|
||||
fr.epdPrintf(15, 55, COLOR_RED, rotation::ROTATE_0, "AP: %02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X", APmac[7], APmac[6], APmac[5], APmac[4], APmac[3], APmac[2], APmac[1], APmac[0]);
|
||||
fr.epdPrintf(15, 73, COLOR_RED, rotation::ROTATE_0, "RSSI: %ddBm LQI: %d", mLastRSSI, mLastLqi);
|
||||
fr.setFont(&FreeSansBold18pt7b);
|
||||
fr.epdPrintf(270, 55, COLOR_RED, rotation::ROTATE_0, "Ch %d", currentChannel);
|
||||
fr.setFont(&FreeSans9pt7b);
|
||||
fr.epdPrintf(10, epd->Yres - 43, 0, rotation::ROTATE_0, "Battery: %d.%dV Temp: %d'C", batteryVoltage / 1000, batteryVoltage % 1000, temperature);
|
||||
fr.epdPrintf(10, epd->Yres - 25, 0, rotation::ROTATE_0, "MAC: %02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X", mSelfMac[7], mSelfMac[6], mSelfMac[5], mSelfMac[4], mSelfMac[3], mSelfMac[2], mSelfMac[1], mSelfMac[0]);
|
||||
addQR(epd->Xres - 66, 47, 3, 2, "https://openepaperlink.eu/tag/1/%02X/%02X%02X%02X%02X%02X%02X%02X%02X/", tag.OEPLtype, mSelfMac[7], mSelfMac[6], mSelfMac[5], mSelfMac[4], mSelfMac[3], mSelfMac[2], mSelfMac[1], mSelfMac[0]);
|
||||
break;
|
||||
case STYPE_SIZE_097:
|
||||
fr.setFont(&FreeSansBold18pt7b);
|
||||
fr.epdPrintf(7, 7, COLOR_BLACK, rotation::ROTATE_0, "AP Found - Waiting for data");
|
||||
fr.setFont(&FreeSans9pt7b);
|
||||
fr.epdPrintf(15, 55, COLOR_RED, rotation::ROTATE_0, "AP: %02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X", APmac[7], APmac[6], APmac[5], APmac[4], APmac[3], APmac[2], APmac[1], APmac[0]);
|
||||
fr.epdPrintf(15, 73, COLOR_RED, rotation::ROTATE_0, "RSSI: %ddBm LQI: %d", mLastRSSI, mLastLqi);
|
||||
fr.setFont(&FreeSansBold18pt7b);
|
||||
fr.epdPrintf(270, 55, COLOR_RED, rotation::ROTATE_0, "Ch %d", currentChannel);
|
||||
fr.setFont(&FreeSans9pt7b);
|
||||
fr.epdPrintf(10, epd->Yres - 43, 0, rotation::ROTATE_0, "Battery: %d.%dV Temp: %d'C", batteryVoltage / 1000, batteryVoltage % 1000, temperature);
|
||||
fr.epdPrintf(10, epd->Yres - 25, 0, rotation::ROTATE_0, "MAC: %02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X", mSelfMac[7], mSelfMac[6], mSelfMac[5], mSelfMac[4], mSelfMac[3], mSelfMac[2], mSelfMac[1], mSelfMac[0]);
|
||||
addQR(epd->Xres - 66, 47, 3, 2, "https://openepaperlink.eu/tag/1/%02X/%02X%02X%02X%02X%02X%02X%02X%02X/", tag.OEPLtype, mSelfMac[7], mSelfMac[6], mSelfMac[5], mSelfMac[4], mSelfMac[3], mSelfMac[2], mSelfMac[1], mSelfMac[0]);
|
||||
break;
|
||||
}
|
||||
addOverlay();
|
||||
draw();
|
||||
}
|
||||
void showNoAP() {
|
||||
// selectLUT(EPD_LUT_NO_REPEATS);
|
||||
#if (HW_TYPE == SOLUM_M3_BWR_22)
|
||||
fontrender fr(&FreeSansBold18pt7b);
|
||||
fr.epdPrintf(7, 7, COLOR_BLACK, rotation::ROTATE_0, "No AP Found");
|
||||
fr.setFont(&FreeSans9pt7b);
|
||||
addQR(UI_SCREEN_WIDTH - 66, 47, 3, 2, "https://openepaperlink.eu/tag/1/%02X/%02X%02X%02X%02X%02X%02X%02X%02X/", HW_TYPE, mSelfMac[7], mSelfMac[6], mSelfMac[5], mSelfMac[4], mSelfMac[3], mSelfMac[2], mSelfMac[1], mSelfMac[0]);
|
||||
fr.epdPrintf(10, 69, COLOR_BLACK, rotation::ROTATE_0, "Couldn't find an AP :(");
|
||||
fr.epdPrintf(10, 89, COLOR_BLACK, rotation::ROTATE_0, "I'll try again in a little while, but you");
|
||||
fr.epdPrintf(10, 109, COLOR_BLACK, rotation::ROTATE_0, "can force a retry now by pressing a button");
|
||||
#endif
|
||||
#if (HW_TYPE == SOLUM_M3_BWR_29)
|
||||
fontrender fr(&FreeSansBold18pt7b);
|
||||
fr.epdPrintf(7, 7, COLOR_BLACK, rotation::ROTATE_0, "No AP Found");
|
||||
fr.setFont(&FreeSans9pt7b);
|
||||
addQR(UI_SCREEN_WIDTH - 66, 47, 3, 2, "https://openepaperlink.eu/tag/1/%02X/%02X%02X%02X%02X%02X%02X%02X%02X/", HW_TYPE, mSelfMac[7], mSelfMac[6], mSelfMac[5], mSelfMac[4], mSelfMac[3], mSelfMac[2], mSelfMac[1], mSelfMac[0]);
|
||||
fr.epdPrintf(10, 69, COLOR_BLACK, rotation::ROTATE_0, "Couldn't find an AP :(");
|
||||
fr.epdPrintf(10, 89, COLOR_BLACK, rotation::ROTATE_0, "I'll try again in a little while, but you");
|
||||
fr.epdPrintf(10, 109, COLOR_BLACK, rotation::ROTATE_0, "can force a retry now by pressing a button");
|
||||
#endif
|
||||
#if (HW_TYPE == SOLUM_M3_BWR_43)
|
||||
fontrender fr(&FreeSansBold18pt7b);
|
||||
fr.epdPrintf(7, 7, COLOR_BLACK, rotation::ROTATE_0, "No AP Found UwU");
|
||||
fr.setFont(&FreeSans9pt7b);
|
||||
addQR(UI_SCREEN_WIDTH - 66, 47, 3, 2, "https://openepaperlink.eu/tag/1/%02X/%02X%02X%02X%02X%02X%02X%02X%02X/", HW_TYPE, mSelfMac[7], mSelfMac[6], mSelfMac[5], mSelfMac[4], mSelfMac[3], mSelfMac[2], mSelfMac[1], mSelfMac[0]);
|
||||
drawRoundedRectangle(36, 55, 112, 42, COLOR_RED);
|
||||
fr.epdPrintf(44, 61, COLOR_BLACK, rotation::ROTATE_0, "NFC WAKE");
|
||||
fr.epdPrintf(41, 77, COLOR_BLACK, rotation::ROTATE_0, "SCAN HERE");
|
||||
switch (tag.solumType) {
|
||||
case STYPE_SIZE_016:
|
||||
fr.setFont(&FreeSans9pt7b);
|
||||
fr.epdPrintf(7, 7, COLOR_BLACK, rotation::ROTATE_0, "NO AP Found");
|
||||
fr.epdPrintf(2, 25, COLOR_BLACK, rotation::ROTATE_0, "Couldn't find an AP :(");
|
||||
break;
|
||||
case STYPE_SIZE_022:
|
||||
fr.setFont(&FreeSansBold18pt7b);
|
||||
fr.epdPrintf(7, 7, COLOR_BLACK, rotation::ROTATE_0, "No AP Found");
|
||||
fr.setFont(&FreeSans9pt7b);
|
||||
addQR(epd->Xres - 66, 47, 3, 2, "https://openepaperlink.eu/tag/1/%02X/%02X%02X%02X%02X%02X%02X%02X%02X/", tag.OEPLtype, mSelfMac[7], mSelfMac[6], mSelfMac[5], mSelfMac[4], mSelfMac[3], mSelfMac[2], mSelfMac[1], mSelfMac[0]);
|
||||
fr.epdPrintf(10, 69, COLOR_BLACK, rotation::ROTATE_0, "Couldn't find an AP :(");
|
||||
fr.epdPrintf(10, 89, COLOR_BLACK, rotation::ROTATE_0, "I'll try again in a little while, but you");
|
||||
fr.epdPrintf(10, 109, COLOR_BLACK, rotation::ROTATE_0, "can force a retry now by pressing a button");
|
||||
break;
|
||||
case STYPE_SIZE_029:
|
||||
fr.setFont(&FreeSansBold18pt7b);
|
||||
fr.epdPrintf(7, 7, COLOR_BLACK, rotation::ROTATE_0, "No AP Found");
|
||||
fr.setFont(&FreeSans9pt7b);
|
||||
addQR(epd->Xres - 66, 47, 3, 2, "https://openepaperlink.eu/tag/1/%02X/%02X%02X%02X%02X%02X%02X%02X%02X/", tag.OEPLtype, mSelfMac[7], mSelfMac[6], mSelfMac[5], mSelfMac[4], mSelfMac[3], mSelfMac[2], mSelfMac[1], mSelfMac[0]);
|
||||
fr.epdPrintf(10, 69, COLOR_BLACK, rotation::ROTATE_0, "Couldn't find an AP :(");
|
||||
fr.epdPrintf(10, 89, COLOR_BLACK, rotation::ROTATE_0, "I'll try again in a little while, but you");
|
||||
fr.epdPrintf(10, 109, COLOR_BLACK, rotation::ROTATE_0, "can force a retry now by pressing a button");
|
||||
break;
|
||||
case STYPE_SIZE_042:
|
||||
fr.setFont(&FreeSansBold18pt7b);
|
||||
fr.epdPrintf(7, 7, COLOR_BLACK, rotation::ROTATE_0, "No AP Found");
|
||||
fr.setFont(&FreeSans9pt7b);
|
||||
addQR(epd->Xres - 66, 47, 3, 2, "https://openepaperlink.eu/tag/1/%02X/%02X%02X%02X%02X%02X%02X%02X%02X/", tag.OEPLtype, mSelfMac[7], mSelfMac[6], mSelfMac[5], mSelfMac[4], mSelfMac[3], mSelfMac[2], mSelfMac[1], mSelfMac[0]);
|
||||
fr.epdPrintf(10, 69, COLOR_BLACK, rotation::ROTATE_0, "Couldn't find an AP :(");
|
||||
fr.epdPrintf(10, 89, COLOR_BLACK, rotation::ROTATE_0, "I'll try again in a little while, but you");
|
||||
fr.epdPrintf(10, 109, COLOR_BLACK, rotation::ROTATE_0, "can force a retry now by pressing a button");
|
||||
break;
|
||||
case STYPE_SIZE_043:
|
||||
fr.setFont(&FreeSansBold18pt7b);
|
||||
fr.epdPrintf(7, 7, COLOR_BLACK, rotation::ROTATE_0, "No AP Found UwU");
|
||||
fr.setFont(&FreeSans9pt7b);
|
||||
addQR(epd->Xres - 66, 47, 3, 2, "https://openepaperlink.eu/tag/1/%02X/%02X%02X%02X%02X%02X%02X%02X%02X/", tag.OEPLtype, mSelfMac[7], mSelfMac[6], mSelfMac[5], mSelfMac[4], mSelfMac[3], mSelfMac[2], mSelfMac[1], mSelfMac[0]);
|
||||
drawRoundedRectangle(36, 55, 112, 42, COLOR_RED);
|
||||
fr.epdPrintf(44, 61, COLOR_BLACK, rotation::ROTATE_0, "NFC WAKE");
|
||||
fr.epdPrintf(41, 77, COLOR_BLACK, rotation::ROTATE_0, "SCAN HERE");
|
||||
|
||||
fr.epdPrintf(152, 49, COLOR_BLACK, rotation::ROTATE_0, "Couldn't find an AP :(");
|
||||
fr.epdPrintf(152, 69, COLOR_BLACK, rotation::ROTATE_0, "I'll try again in a little while, but you");
|
||||
fr.epdPrintf(152, 89, COLOR_BLACK, rotation::ROTATE_0, "can force a retry now by scanning");
|
||||
fr.epdPrintf(152, 109, COLOR_BLACK, rotation::ROTATE_0, "the NFC-wake area with your phone");
|
||||
#endif
|
||||
#if (HW_TYPE == SOLUM_M3_BWR_60)
|
||||
fontrender fr(&FreeSansBold18pt7b);
|
||||
fr.epdPrintf(7, 7, COLOR_BLACK, rotation::ROTATE_0, "No AP Found U_U");
|
||||
fr.setFont(&FreeSans9pt7b);
|
||||
addQR(UI_SCREEN_WIDTH - 66, 47, 3, 2, "https://openepaperlink.eu/tag/1/%02X/%02X%02X%02X%02X%02X%02X%02X%02X/", HW_TYPE, mSelfMac[7], mSelfMac[6], mSelfMac[5], mSelfMac[4], mSelfMac[3], mSelfMac[2], mSelfMac[1], mSelfMac[0]);
|
||||
fr.epdPrintf(10, 39, COLOR_BLACK, rotation::ROTATE_0, "Couldn't find an AP :(");
|
||||
fr.epdPrintf(10, 58, COLOR_BLACK, rotation::ROTATE_0, "I'll try again in a little while, but you");
|
||||
fr.epdPrintf(10, 77, COLOR_BLACK, rotation::ROTATE_0, "can force a retry now by pressing a button");
|
||||
addFlashImage(0, 96, COLOR_BLACK, rotation::ROTATE_0, pandablack);
|
||||
addFlashImage(112, 242, COLOR_RED, rotation::ROTATE_0, pandared);
|
||||
#endif
|
||||
#if (HW_TYPE == SOLUM_M3_BWR_75)
|
||||
fontrender fr(&FreeSansBold18pt7b);
|
||||
fr.epdPrintf(7, 7, COLOR_BLACK, rotation::ROTATE_0, "No AP Found U_U");
|
||||
fr.setFont(&FreeSans9pt7b);
|
||||
addQR(UI_SCREEN_WIDTH - 66, 47, 3, 2, "https://openepaperlink.eu/tag/1/%02X/%02X%02X%02X%02X%02X%02X%02X%02X/", HW_TYPE, mSelfMac[7], mSelfMac[6], mSelfMac[5], mSelfMac[4], mSelfMac[3], mSelfMac[2], mSelfMac[1], mSelfMac[0]);
|
||||
fr.epdPrintf(10, 39, COLOR_BLACK, rotation::ROTATE_0, "Couldn't find an AP :(");
|
||||
fr.epdPrintf(10, 58, COLOR_BLACK, rotation::ROTATE_0, "I'll try again in a little while, but you");
|
||||
fr.epdPrintf(10, 77, COLOR_BLACK, rotation::ROTATE_0, "can force a retry now by pressing a button");
|
||||
addFlashImage(200, 128, COLOR_BLACK, rotation::ROTATE_0, pandablack);
|
||||
addFlashImage(312, 274, COLOR_RED, rotation::ROTATE_0, pandared);
|
||||
#endif
|
||||
fr.epdPrintf(152, 49, COLOR_BLACK, rotation::ROTATE_0, "Couldn't find an AP :(");
|
||||
fr.epdPrintf(152, 69, COLOR_BLACK, rotation::ROTATE_0, "I'll try again in a little while, but you");
|
||||
fr.epdPrintf(152, 89, COLOR_BLACK, rotation::ROTATE_0, "can force a retry now by scanning");
|
||||
fr.epdPrintf(152, 109, COLOR_BLACK, rotation::ROTATE_0, "the NFC-wake area with your phone");
|
||||
break;
|
||||
case STYPE_SIZE_060:
|
||||
fr.setFont(&FreeSansBold18pt7b);
|
||||
fr.epdPrintf(7, 7, COLOR_BLACK, rotation::ROTATE_0, "No AP Found U_U");
|
||||
fr.setFont(&FreeSans9pt7b);
|
||||
addQR(epd->Xres - 66, 47, 3, 2, "https://openepaperlink.eu/tag/1/%02X/%02X%02X%02X%02X%02X%02X%02X%02X/", tag.OEPLtype, mSelfMac[7], mSelfMac[6], mSelfMac[5], mSelfMac[4], mSelfMac[3], mSelfMac[2], mSelfMac[1], mSelfMac[0]);
|
||||
fr.epdPrintf(10, 39, COLOR_BLACK, rotation::ROTATE_0, "Couldn't find an AP :(");
|
||||
fr.epdPrintf(10, 58, COLOR_BLACK, rotation::ROTATE_0, "I'll try again in a little while, but you");
|
||||
fr.epdPrintf(10, 77, COLOR_BLACK, rotation::ROTATE_0, "can force a retry now by pressing a button");
|
||||
addFlashImage(0, 96, COLOR_BLACK, rotation::ROTATE_0, pandablack);
|
||||
addFlashImage(112, 242, COLOR_RED, rotation::ROTATE_0, pandared);
|
||||
break;
|
||||
case STYPE_SIZE_075:
|
||||
fr.setFont(&FreeSansBold18pt7b);
|
||||
fr.epdPrintf(7, 7, COLOR_BLACK, rotation::ROTATE_0, "No AP Found U_U");
|
||||
fr.setFont(&FreeSans9pt7b);
|
||||
addQR(epd->Xres - 66, 47, 3, 2, "https://openepaperlink.eu/tag/1/%02X/%02X%02X%02X%02X%02X%02X%02X%02X/", tag.OEPLtype, mSelfMac[7], mSelfMac[6], mSelfMac[5], mSelfMac[4], mSelfMac[3], mSelfMac[2], mSelfMac[1], mSelfMac[0]);
|
||||
fr.epdPrintf(10, 39, COLOR_BLACK, rotation::ROTATE_0, "Couldn't find an AP :(");
|
||||
fr.epdPrintf(10, 58, COLOR_BLACK, rotation::ROTATE_0, "I'll try again in a little while, but you");
|
||||
fr.epdPrintf(10, 77, COLOR_BLACK, rotation::ROTATE_0, "can force a retry now by pressing a button");
|
||||
addFlashImage(200, 128, COLOR_BLACK, rotation::ROTATE_0, pandablack);
|
||||
addFlashImage(312, 274, COLOR_RED, rotation::ROTATE_0, pandared);
|
||||
break;
|
||||
case STYPE_SIZE_097:
|
||||
fr.setFont(&FreeSansBold18pt7b);
|
||||
fr.epdPrintf(7, 7, COLOR_BLACK, rotation::ROTATE_0, "No AP Found U_U");
|
||||
fr.setFont(&FreeSans9pt7b);
|
||||
addQR(epd->Xres - 66, 47, 3, 2, "https://openepaperlink.eu/tag/1/%02X/%02X%02X%02X%02X%02X%02X%02X%02X/", tag.OEPLtype, mSelfMac[7], mSelfMac[6], mSelfMac[5], mSelfMac[4], mSelfMac[3], mSelfMac[2], mSelfMac[1], mSelfMac[0]);
|
||||
fr.epdPrintf(10, 39, COLOR_BLACK, rotation::ROTATE_0, "Couldn't find an AP :(");
|
||||
fr.epdPrintf(10, 58, COLOR_BLACK, rotation::ROTATE_0, "I'll try again in a little while, but you");
|
||||
fr.epdPrintf(10, 77, COLOR_BLACK, rotation::ROTATE_0, "can force a retry now by pressing a button");
|
||||
addFlashImage(200, 128, COLOR_BLACK, rotation::ROTATE_0, pandablack);
|
||||
addFlashImage(312, 274, COLOR_RED, rotation::ROTATE_0, pandared);
|
||||
break;
|
||||
}
|
||||
addOverlay();
|
||||
draw();
|
||||
delay(5000);
|
||||
@@ -273,6 +363,8 @@ void showLongTermSleep() {
|
||||
}
|
||||
void showNoEEPROM() {
|
||||
selectLUT(EPD_LUT_NO_REPEATS);
|
||||
fontrender fr(&FreeSans9pt7b);
|
||||
fr.epdPrintf(2, 2, COLOR_BLACK, rotation::ROTATE_0, "EEPROM FAILED!");
|
||||
draw();
|
||||
}
|
||||
|
||||
|
||||
5
ARM_Tag_FW/OpenEPaperLink_TLSR/flash.bat
Normal file
5
ARM_Tag_FW/OpenEPaperLink_TLSR/flash.bat
Normal file
@@ -0,0 +1,5 @@
|
||||
makeit.exe clean all
|
||||
flashing\telink_flasher.exe 1 8258 ac
|
||||
rem flashing\telink_flasher.exe 1 8258 wf 0 -s 512k -e
|
||||
flashing\telink_flasher.exe 1 8258 wf 0 -i TLSR_OpenEPaperLink.bin
|
||||
flashing\telink_flasher.exe 1 8258 rst -f
|
||||
53
ARM_Tag_FW/OpenEPaperLink_TLSR/flashing/config.ini
Normal file
53
ARM_Tag_FW/OpenEPaperLink_TLSR/flashing/config.ini
Normal file
@@ -0,0 +1,53 @@
|
||||
[MCU]
|
||||
TYPE 3 0x0d = 8258 \bin\dut_8258_flash_v0003.bin 40000 b010b010 End
|
||||
default = 8258 End
|
||||
[MODE]
|
||||
MODE 0x01 = USB End
|
||||
MODE 0x04 = EVK End
|
||||
default = EVK End
|
||||
[OBJ]
|
||||
OBJ 0x01 = FLASH End
|
||||
OBJ 0x02 = CORE End
|
||||
OBJ 0x03 = ANALOG End
|
||||
OBJ 0x04 = OTP End
|
||||
default = CORE End
|
||||
[SIZE]
|
||||
SIZE 0x01 = 1 End
|
||||
SIZE 0x02 = 2 End
|
||||
SIZE 0x03 = 4 End
|
||||
SIZE 0x04 = 8 End
|
||||
SIZE 0x05 = 16 End
|
||||
default = 1 End
|
||||
[DOWNLOAD_ADDR]
|
||||
DOWNLOAD 0x01 = 0 End
|
||||
DOWNLOAD 0x02 = 20000 End
|
||||
DOWNLOAD 0x03 = 40000 End
|
||||
default = 0 End
|
||||
[ERASE_ADDR]
|
||||
ERASE 0x01 = 0 End
|
||||
ERASE 0x02 = 20000 End
|
||||
ERASE 0x03 = 40000 End
|
||||
default = 0 End
|
||||
[ERASE_SIZE]
|
||||
SIZE 0x01 = 4 End
|
||||
SIZE 0x02 = 16 End
|
||||
SIZE 0x03 = 64 End
|
||||
SIZE 0x04 = 128 End
|
||||
SIZE 0x05 = 512 End
|
||||
default = 512 End
|
||||
[PAGE_DISPLAY]
|
||||
PAGE 0x01 = 0 Download End
|
||||
PAGE 0x02 = 1 Tdebug End
|
||||
PAGE 0x03 = 2 Log windows End
|
||||
default = 0 End
|
||||
[SECTION]
|
||||
SECTION 0x01 = .data End
|
||||
SECTION 0x02 = .bss End
|
||||
SECTION 0x03 = .retention_data End
|
||||
SECTION 0x04 = .retention_bss End
|
||||
SECTION 0x05 = .no_ret_data End
|
||||
SECTION 0x06 = .no_ret_bss End
|
||||
default End
|
||||
[BUTTON]
|
||||
|
||||
[PATH]
|
||||
BIN
ARM_Tag_FW/OpenEPaperLink_TLSR/flashing/telink_flasher.exe
Normal file
BIN
ARM_Tag_FW/OpenEPaperLink_TLSR/flashing/telink_flasher.exe
Normal file
Binary file not shown.
BIN
ARM_Tag_FW/OpenEPaperLink_TLSR/flashing/tl_usb2.2.dll
Normal file
BIN
ARM_Tag_FW/OpenEPaperLink_TLSR/flashing/tl_usb2.2.dll
Normal file
Binary file not shown.
13
ARM_Tag_FW/OpenEPaperLink_TLSR/make/div_mod.mk
Normal file
13
ARM_Tag_FW/OpenEPaperLink_TLSR/make/div_mod.mk
Normal file
@@ -0,0 +1,13 @@
|
||||
# Add inputs and outputs from these tool invocations to the build variables
|
||||
OUT_DIR += \
|
||||
/platform/tc32
|
||||
|
||||
OBJS += \
|
||||
$(OUT_PATH)/platform/tc32/div_mod.o
|
||||
|
||||
|
||||
# Each subdirectory must supply rules for building sources it contributes
|
||||
$(OUT_PATH)/platform/tc32/%.o: $(SDK_PATH)/platform/tc32/%.S
|
||||
@echo 'Building file: $<'
|
||||
@$(CC) $(BOOT_FLAG) $(INCLUDE_PATHS) -c -o"$@" "$<"
|
||||
|
||||
28
ARM_Tag_FW/OpenEPaperLink_TLSR/make/platform.mk
Normal file
28
ARM_Tag_FW/OpenEPaperLink_TLSR/make/platform.mk
Normal file
@@ -0,0 +1,28 @@
|
||||
# Add inputs and outputs from these tool invocations to the build variables
|
||||
OUT_DIR += \
|
||||
/platform/chip_8258 \
|
||||
/platform/chip_8258/flash \
|
||||
/platform/services/b85m
|
||||
|
||||
|
||||
OBJS += \
|
||||
$(OUT_PATH)/platform/chip_8258/flash.o \
|
||||
$(OUT_PATH)/platform/chip_8258/adc.o \
|
||||
$(OUT_PATH)/platform/chip_8258/flash/flash_mid011460c8.o \
|
||||
$(OUT_PATH)/platform/chip_8258/flash/flash_mid1060c8.o \
|
||||
$(OUT_PATH)/platform/chip_8258/flash/flash_mid13325e.o \
|
||||
$(OUT_PATH)/platform/chip_8258/flash/flash_mid134051.o \
|
||||
$(OUT_PATH)/platform/chip_8258/flash/flash_mid136085.o \
|
||||
$(OUT_PATH)/platform/chip_8258/flash/flash_mid1360c8.o \
|
||||
$(OUT_PATH)/platform/chip_8258/flash/flash_mid1360eb.o \
|
||||
$(OUT_PATH)/platform/chip_8258/flash/flash_mid14325e.o \
|
||||
$(OUT_PATH)/platform/chip_8258/flash/flash_mid1460c8.o \
|
||||
$(OUT_PATH)/platform/services/b85m/irq_handler.o
|
||||
|
||||
|
||||
|
||||
# Each subdirectory must supply rules for building sources it contributes
|
||||
$(OUT_PATH)/platform/%.o: $(SDK_PATH)/platform/%.c
|
||||
@echo 'Building file: $<'
|
||||
@$(CC) $(GCC_FLAGS) $(INCLUDE_PATHS) -c -o"$@" "$<"
|
||||
|
||||
16
ARM_Tag_FW/OpenEPaperLink_TLSR/make/platformS.mk
Normal file
16
ARM_Tag_FW/OpenEPaperLink_TLSR/make/platformS.mk
Normal file
@@ -0,0 +1,16 @@
|
||||
# Add inputs and outputs from these tool invocations to the build variables
|
||||
OUT_DIR += \
|
||||
/platform/boot \
|
||||
/platform/boot/8258
|
||||
|
||||
OBJS += \
|
||||
$(OUT_PATH)/platform/boot/link_cfg.o \
|
||||
$(OUT_PATH)/platform/boot/8258/cstartup_8258.o
|
||||
|
||||
|
||||
|
||||
# Each subdirectory must supply rules for building sources it contributes
|
||||
$(OUT_PATH)/platform/boot/%.o: $(SDK_PATH)/platform/boot/%.S
|
||||
@echo 'Building file: $<'
|
||||
@$(CC) $(BOOT_FLAG) $(INCLUDE_PATHS) -c -o"$@" "$<"
|
||||
|
||||
40
ARM_Tag_FW/OpenEPaperLink_TLSR/make/proj.mk
Normal file
40
ARM_Tag_FW/OpenEPaperLink_TLSR/make/proj.mk
Normal file
@@ -0,0 +1,40 @@
|
||||
# Add inputs and outputs from these tool invocations to the build variables
|
||||
OUT_DIR += \
|
||||
/proj/common \
|
||||
/proj/drivers \
|
||||
/proj/drivers/usb \
|
||||
/proj/os
|
||||
|
||||
OBJS += \
|
||||
$(OUT_PATH)/proj/common/list.o \
|
||||
$(OUT_PATH)/proj/common/mempool.o \
|
||||
$(OUT_PATH)/proj/common/string.o \
|
||||
$(OUT_PATH)/proj/common/tlPrintf.o \
|
||||
$(OUT_PATH)/proj/common/utility.o \
|
||||
$(OUT_PATH)/proj/drivers/drv_adc.o \
|
||||
$(OUT_PATH)/proj/drivers/drv_calibration.o \
|
||||
$(OUT_PATH)/proj/drivers/drv_flash.o \
|
||||
$(OUT_PATH)/proj/drivers/drv_gpio.o \
|
||||
$(OUT_PATH)/proj/drivers/drv_hw.o \
|
||||
$(OUT_PATH)/proj/drivers/drv_i2c.o \
|
||||
$(OUT_PATH)/proj/drivers/drv_keyboard.o \
|
||||
$(OUT_PATH)/proj/drivers/drv_nv.o \
|
||||
$(OUT_PATH)/proj/drivers/drv_pm.o \
|
||||
$(OUT_PATH)/proj/drivers/drv_pwm.o \
|
||||
$(OUT_PATH)/proj/drivers/drv_spi.o \
|
||||
$(OUT_PATH)/proj/drivers/drv_timer.o \
|
||||
$(OUT_PATH)/proj/drivers/drv_uart.o \
|
||||
$(OUT_PATH)/proj/os/ev.o \
|
||||
$(OUT_PATH)/proj/os/ev_buffer.o \
|
||||
$(OUT_PATH)/proj/os/ev_poll.o \
|
||||
$(OUT_PATH)/proj/os/ev_queue.o \
|
||||
$(OUT_PATH)/proj/os/ev_timer.o
|
||||
|
||||
|
||||
|
||||
# Each subdirectory must supply rules for building sources it contributes
|
||||
$(OUT_PATH)/proj/%.o: $(SDK_PATH)/proj/%.c
|
||||
@echo 'Building file: $<'
|
||||
@$(CC) $(GCC_FLAGS) $(INCLUDE_PATHS) -c -o"$@" "$<"
|
||||
|
||||
|
||||
143
ARM_Tag_FW/OpenEPaperLink_TLSR/makefile
Normal file
143
ARM_Tag_FW/OpenEPaperLink_TLSR/makefile
Normal file
@@ -0,0 +1,143 @@
|
||||
PROJECT_NAME := TLSR_OpenEPaperLink
|
||||
|
||||
|
||||
ifeq ($(OS), Windows_NT)
|
||||
TC32_COMPILER_PATH := "tc32_windows\\bin\\"
|
||||
WINDOWS_PREFIX :=$(TC32_COMPILER_PATH)
|
||||
LINUX_CHMOD :=
|
||||
else
|
||||
TC32_COMPILER_PATH := ./tc32_linux/bin/
|
||||
WINDOWS_PREFIX :=
|
||||
LINUX_CHMOD := chmod 777 -R ./tc32_linux/
|
||||
endif
|
||||
|
||||
AS = $(TC32_COMPILER_PATH)tc32-elf-as
|
||||
CC = $(TC32_COMPILER_PATH)tc32-elf-gcc
|
||||
LD = $(TC32_COMPILER_PATH)tc32-elf-ld
|
||||
NM = $(TC32_COMPILER_PATH)tc32-elf-nm
|
||||
OBJCOPY = $(TC32_COMPILER_PATH)tc32-elf-objcopy
|
||||
OBJDUMP = $(TC32_COMPILER_PATH)tc32-elf-objdump
|
||||
ARCH = $(TC32_COMPILER_PATH)tc32-elf-ar
|
||||
SIZE = $(TC32_COMPILER_PATH)tc32-elf-size
|
||||
|
||||
LIBS := -ldrivers_8258
|
||||
|
||||
DEVICE_TYPE = -DEND_DEVICE=1
|
||||
MCU_TYPE = -DMCU_CORE_8258=1
|
||||
BOOT_FLAG = -DMCU_CORE_8258 -DMCU_STARTUP_8258
|
||||
|
||||
SDK_PATH := ./tl_zigbee_sdk
|
||||
SRC_PATH := ./src
|
||||
OUT_PATH := ./out
|
||||
MAKE_INCLUDES := ./make
|
||||
|
||||
INCLUDE_PATHS := \
|
||||
-I$(SDK_PATH)/platform \
|
||||
-I$(SDK_PATH)/proj/common \
|
||||
-I$(SDK_PATH)/proj \
|
||||
-I$(SDK_PATH)/zbhci \
|
||||
-I$(SRC_PATH) \
|
||||
-I./common
|
||||
|
||||
|
||||
LS_FLAGS := $(SDK_PATH)/platform/boot/8258/boot_8258.link
|
||||
|
||||
GCC_FLAGS := \
|
||||
-ffunction-sections \
|
||||
-fdata-sections \
|
||||
-Wall \
|
||||
-O2 \
|
||||
-fpack-struct \
|
||||
-fshort-enums \
|
||||
-finline-small-functions \
|
||||
-std=gnu99 \
|
||||
-fshort-wchar \
|
||||
-fms-extensions
|
||||
|
||||
GCC_FLAGS += \
|
||||
$(DEVICE_TYPE) \
|
||||
$(MCU_TYPE) \
|
||||
-D__PROJECT_TL_SWITCH__=1
|
||||
|
||||
OBJ_SRCS :=
|
||||
S_SRCS :=
|
||||
ASM_SRCS :=
|
||||
C_SRCS :=
|
||||
S_UPPER_SRCS :=
|
||||
O_SRCS :=
|
||||
FLASH_IMAGE :=
|
||||
ELFS :=
|
||||
OBJS :=
|
||||
LST :=
|
||||
SIZEDUMMY :=
|
||||
|
||||
|
||||
RM := $(WINDOWS_PREFIX)rm -rf
|
||||
|
||||
# All of the sources participating in the build are defined here
|
||||
-include $(MAKE_INCLUDES)/proj.mk
|
||||
-include $(MAKE_INCLUDES)/platformS.mk
|
||||
-include $(MAKE_INCLUDES)/div_mod.mk
|
||||
-include $(MAKE_INCLUDES)/platform.mk
|
||||
-include ./project.mk
|
||||
|
||||
# Add inputs and outputs from these tool invocations to the build variables
|
||||
LST_FILE := $(OUT_PATH)/$(PROJECT_NAME).lst
|
||||
BIN_FILE := $(OUT_PATH)/../$(PROJECT_NAME).bin
|
||||
ELF_FILE := $(OUT_PATH)/$(PROJECT_NAME).elf
|
||||
|
||||
SIZEDUMMY += \
|
||||
sizedummy \
|
||||
|
||||
|
||||
# All Target
|
||||
all: chmod_all pre-build main-build
|
||||
|
||||
# Main-build Target
|
||||
main-build: $(ELF_FILE) secondary-outputs
|
||||
|
||||
# Tool invocations
|
||||
$(ELF_FILE): $(OBJS) $(USER_OBJS)
|
||||
@echo 'Building target: $@'
|
||||
@echo 'Invoking: TC32 C Linker'
|
||||
$(LD) --gc-sections -L $(SDK_PATH)/zigbee/lib/tc32 -L $(SDK_PATH)/platform/lib -T $(LS_FLAGS) -o "$(ELF_FILE)" $(OBJS) $(USER_OBJS) $(LIBS)
|
||||
@echo 'Finished building target: $@'
|
||||
@echo ' '
|
||||
|
||||
|
||||
$(LST_FILE): $(ELF_FILE)
|
||||
@echo 'Invoking: TC32 Create Extended Listing'
|
||||
$(OBJDUMP) -x -D -l -S $(ELF_FILE) > $(LST_FILE)
|
||||
@echo 'Finished building: $@'
|
||||
@echo ' '
|
||||
|
||||
$(BIN_FILE): $(ELF_FILE)
|
||||
@echo 'Create Flash image (binary format)'
|
||||
@$(OBJCOPY) -v -O binary $(ELF_FILE) $(BIN_FILE)
|
||||
@echo 'Finished building: $@'
|
||||
@echo ' '
|
||||
|
||||
|
||||
sizedummy: $(ELF_FILE)
|
||||
@echo 'Invoking: Print Size'
|
||||
@$(SIZE) -t $(ELF_FILE)
|
||||
@echo 'Finished building: $@'
|
||||
@echo ' '
|
||||
|
||||
clean:
|
||||
-$(RM) $(FLASH_IMAGE) $(ELFS) $(OBJS) $(SIZEDUMMY) $(LST_FILE) $(ELF_FILE) $(BIN_FILE)
|
||||
-@echo ' '
|
||||
|
||||
pre-build:
|
||||
$(WINDOWS_PREFIX)mkdir -p $(foreach s,$(OUT_DIR),$(OUT_PATH)$(s))
|
||||
-@echo ' '
|
||||
|
||||
chmod_all:
|
||||
-@$(LINUX_CHMOD)
|
||||
-@echo 'chmod_all'
|
||||
|
||||
secondary-outputs: $(BIN_FILE) $(LST_FILE) $(FLASH_IMAGE) $(SIZEDUMMY)
|
||||
|
||||
.PHONY: all clean dependents pre-build
|
||||
.SECONDARY: main-build pre-build
|
||||
|
||||
BIN
ARM_Tag_FW/OpenEPaperLink_TLSR/makeit.exe
Normal file
BIN
ARM_Tag_FW/OpenEPaperLink_TLSR/makeit.exe
Normal file
Binary file not shown.
34
ARM_Tag_FW/OpenEPaperLink_TLSR/project.mk
Normal file
34
ARM_Tag_FW/OpenEPaperLink_TLSR/project.mk
Normal file
@@ -0,0 +1,34 @@
|
||||
# Add inputs and outputs from these tool invocations to the build variables
|
||||
OUT_DIR += \
|
||||
/$(SRC_PATH) \
|
||||
|
||||
OBJS += \
|
||||
$(OUT_PATH)/$(SRC_PATH)/main.o \
|
||||
$(OUT_PATH)/$(SRC_PATH)/epd_spi.o \
|
||||
$(OUT_PATH)/$(SRC_PATH)/epd.o \
|
||||
$(OUT_PATH)/$(SRC_PATH)/epd_bw_213.o \
|
||||
$(OUT_PATH)/$(SRC_PATH)/epd_bwr_213.o \
|
||||
$(OUT_PATH)/$(SRC_PATH)/epd_bwr_350.o \
|
||||
$(OUT_PATH)/$(SRC_PATH)/epd_bwy_350.o \
|
||||
$(OUT_PATH)/$(SRC_PATH)/epd_bw_213_ice.o \
|
||||
$(OUT_PATH)/$(SRC_PATH)/epd_bwr_154.o \
|
||||
$(OUT_PATH)/$(SRC_PATH)/led.o \
|
||||
$(OUT_PATH)/$(SRC_PATH)/i2c.o \
|
||||
$(OUT_PATH)/$(SRC_PATH)/battery.o \
|
||||
$(OUT_PATH)/$(SRC_PATH)/nfc.o \
|
||||
$(OUT_PATH)/$(SRC_PATH)/uart.o \
|
||||
$(OUT_PATH)/$(SRC_PATH)/one_bit_display.o \
|
||||
$(OUT_PATH)/$(SRC_PATH)/eeprom.o \
|
||||
$(OUT_PATH)/$(SRC_PATH)/zigbee.o \
|
||||
$(OUT_PATH)/$(SRC_PATH)/comms.o \
|
||||
$(OUT_PATH)/$(SRC_PATH)/drawing.o \
|
||||
$(OUT_PATH)/$(SRC_PATH)/syncedproto.o \
|
||||
$(OUT_PATH)/$(SRC_PATH)/wdt.o \
|
||||
$(OUT_PATH)/$(SRC_PATH)/powermgt.o \
|
||||
|
||||
# Each subdirectory must supply rules for building sources it contributes
|
||||
$(OUT_PATH)/$(SRC_PATH)/%.o: $(SRC_PATH)/%.c
|
||||
@echo 'Building file: $<'
|
||||
@$(CC) $(GCC_FLAGS) $(INCLUDE_PATHS) -c -o"$@" "$<"
|
||||
|
||||
|
||||
822
ARM_Tag_FW/OpenEPaperLink_TLSR/src/OneBitDisplay.cpp
Normal file
822
ARM_Tag_FW/OpenEPaperLink_TLSR/src/OneBitDisplay.cpp
Normal file
@@ -0,0 +1,822 @@
|
||||
//
|
||||
// OneBitDisplay (OLED+LCD library)
|
||||
// Copyright (c) 2020 BitBank Software, Inc.
|
||||
// Written by Larry Bank (bitbank@pobox.com)
|
||||
// Project started 3/23/2020
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
#ifdef _LINUX_
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
// convert wire library constants into ArmbianIO values
|
||||
#define OUTPUT GPIO_OUT
|
||||
#define INPUT GPIO_IN
|
||||
#define INPUT_PULLUP GPIO_IN_PULLUP
|
||||
#define HIGH 1
|
||||
#define LOW 0
|
||||
void delay(int);
|
||||
#else // Arduino
|
||||
|
||||
#include <Arduino.h>
|
||||
#ifdef __AVR__
|
||||
#include <avr/pgmspace.h>
|
||||
#endif
|
||||
#include <SPI.h>
|
||||
|
||||
#endif // _LINUX_
|
||||
#include "OneBitDisplay.h"
|
||||
// All of the drawing code is in here
|
||||
#include "obd.inl"
|
||||
|
||||
// Initialization sequences
|
||||
const unsigned char oled128_initbuf[] PROGMEM = {0x00, 0xae,0xdc,0x00,0x81,0x40,
|
||||
0xa1,0xc8,0xa8,0x7f,0xd5,0x50,0xd9,0x22,0xdb,0x35,0xb0,0xda,0x12,
|
||||
0xa4,0xa6,0xaf};
|
||||
|
||||
const unsigned char oled64x128_initbuf[] PROGMEM ={
|
||||
0x00, 0xae, 0xd5, 0x51, 0x20, 0xa8, 0x3f, 0xdc, 0x00, 0xd3, 0x60, 0xad, 0x80, 0xa6, 0xa4, 0xa0, 0xc0, 0x81, 0x40, 0xd9, 0x22, 0xdb, 0x35, 0xaf
|
||||
};
|
||||
|
||||
const unsigned char oled132_initbuf[] PROGMEM = {0x00,0xae,0x02,0x10,0x40,0x81,0xa0,0xc0,0xa6,0xa8,0x3f,0xd3,0x00,0xd5,0x80,0xd9,0xf1,0xda,0x12,0xdb,0x40,0x20,0x02,0xa4,0xa6};
|
||||
|
||||
const unsigned char oled64_initbuf[] PROGMEM ={0x00,0xae,0xa8,0x3f,0xd3,0x00,0x40,0xa1,0xc8,
|
||||
0xda,0x12,0x81,0xff,0xa4,0xa6,0xd5,0x80,0x8d,0x14,
|
||||
0xaf,0x20,0x02};
|
||||
|
||||
const unsigned char oled32_initbuf[] PROGMEM = {
|
||||
0x00,0xae,0xd5,0x80,0xa8,0x1f,0xd3,0x00,0x40,0x8d,0x14,0xa1,0xc8,0xda,0x02,
|
||||
0x81,0x7f,0xd9,0xf1,0xdb,0x40,0xa4,0xa6,0xaf};
|
||||
|
||||
const unsigned char oled72_initbuf[] PROGMEM ={0x00,0xae,0xa8,0x3f,0xd3,0x00,0x40,0xa1,0xc8,
|
||||
0xda,0x12,0x81,0xff,0xad,0x30,0xd9,0xf1,0xa4,0xa6,0xd5,0x80,0x8d,0x14,
|
||||
0xaf,0x20,0x02};
|
||||
|
||||
const unsigned char uc1701_initbuf[] PROGMEM = {0xe2, 0x40, 0xa0, 0xc8, 0xa2, 0x2c, 0x2e, 0x2f, 0xf8, 0x00, 0x23, 0x81, 0x28, 0xac, 0x00, 0xa6};
|
||||
|
||||
const unsigned char hx1230_initbuf[] PROGMEM = {0x2f, 0x90, 0xa6, 0xa4, 0xaf, 0x40, 0xb0, 0x10, 0x00};
|
||||
const unsigned char nokia5110_initbuf[] PROGMEM = {0x21, 0xa4, 0xb1, 0x04,0x14,0x20,0x0c};
|
||||
|
||||
static void obdCachedFlush(OBDISP *pOBD, int bRender);
|
||||
static void obdCachedWrite(OBDISP *pOBD, uint8_t *pData, uint8_t u8Len, int bRender);
|
||||
void obdSetPosition(OBDISP *pOBD, int x, int y, int bRender);
|
||||
void obdWriteCommand(OBDISP *pOBD, unsigned char c);
|
||||
void obdWriteDataBlock(OBDISP *pOBD, unsigned char *ucBuf, int iLen, int bRender);
|
||||
//static void SPI_BitBang(OBDISP *pOBD, uint8_t *pData, int iLen, uint8_t iMOSIPin, uint8_t iSCKPin);
|
||||
|
||||
//
|
||||
// Draw the contents of a memory buffer onto a display
|
||||
// The sub-window will be clipped if it specifies too large an area
|
||||
// for the destination display. The source OBDISP structure must have
|
||||
// a valid back buffer defined
|
||||
// The top and bottom destination edges will be drawn on byte boundaries (8 rows)
|
||||
// The source top/bot edges can be on pixel boundaries
|
||||
// This can be used for partial screen updates
|
||||
//
|
||||
void obdDumpWindow(OBDISP *pOBDSrc, OBDISP *pOBDDest, int srcx, int srcy, int destx, int desty, int width, int height)
|
||||
{
|
||||
uint8_t *s,ucTemp[32]; // temp buffer to gather source pixels
|
||||
int x, y, tx, i;
|
||||
int iPitch;
|
||||
|
||||
if (pOBDSrc == NULL || pOBDDest == NULL || pOBDSrc->ucScreen == NULL)
|
||||
return; // invalid pointers
|
||||
if (width > pOBDDest->width)
|
||||
width = pOBDDest->width;
|
||||
if (height > pOBDDest->height)
|
||||
height = pOBDDest->height;
|
||||
iPitch = pOBDSrc->width;
|
||||
for (y=0; y<height; y+=8)
|
||||
{
|
||||
obdSetPosition(pOBDDest, destx, (desty+y)/8, 1);
|
||||
for (x=0; x<width; x+=32)
|
||||
{
|
||||
tx = 32;
|
||||
if (width-x < 32) tx = width-x;
|
||||
s = &pOBDSrc->ucScreen[((srcy+y)/8)*iPitch + srcx+x];
|
||||
if (srcy & 7) // need to shift the bits to get 8 rows of src data
|
||||
{
|
||||
uint8_t uc, ucShift = srcy & 7;
|
||||
for (i=0; i<tx; i++)
|
||||
{ // combine current and next line to capture 8 pixels
|
||||
uc = s[0] >> ucShift;
|
||||
uc |= s[iPitch] << (7-ucShift);
|
||||
ucTemp[i] = uc;
|
||||
}
|
||||
obdCachedWrite(pOBDDest, ucTemp, tx, 1);
|
||||
}
|
||||
else
|
||||
{ // simpler case
|
||||
obdCachedWrite(pOBDDest, s, tx, 1); // just copy it
|
||||
}
|
||||
} // for x
|
||||
} // for y
|
||||
obdCachedFlush(pOBDDest, 1);
|
||||
} /* obdDumpWindow() */
|
||||
|
||||
//
|
||||
// Write a single line to a Sharp memory LCD
|
||||
// You must provide the exact number of bytes needed for a complete line
|
||||
// e.g. for the 144x168 display, pSrc must provide 144 pixels (18 bytes)
|
||||
//
|
||||
void obdWriteLCDLine(OBDISP *pOBD, uint8_t *pSrc, int iLine)
|
||||
{
|
||||
int x;
|
||||
uint8_t c, ucInvert, *d, ucStart;
|
||||
uint8_t ucLineBuf[54]; // 400 pixels is max supported width = 50 bytes + 4
|
||||
int iPitch = pOBD->width / 8;
|
||||
static int iVCOM = 0;
|
||||
|
||||
// if (pOBD == NULL || pSrc == NULL || pOBD->type < SHARP_144x168)
|
||||
// return; // invalid request
|
||||
if (iLine < 0 || iLine >= pOBD->height)
|
||||
return;
|
||||
|
||||
ucInvert = (pOBD->invert) ? 0x00 : 0xff;
|
||||
digitalWrite(pOBD->iCSPin, HIGH); // active high
|
||||
|
||||
ucStart = 0x80; // write command
|
||||
iVCOM++;
|
||||
if (iVCOM & 0x100) // flip it every 256 lines
|
||||
ucStart |= 0x40; // VCOM bit
|
||||
ucLineBuf[1] = ucStart;
|
||||
// this code assumes I2C, so the first byte is ignored
|
||||
_I2CWrite(pOBD, ucLineBuf, 2); // write command(01) + vcom(02)
|
||||
|
||||
d = &ucLineBuf[2];
|
||||
ucLineBuf[1] = pgm_read_byte(&ucMirror[iLine+1]); // current line number
|
||||
for (x=0; x<iPitch; x++)
|
||||
{
|
||||
c = pSrc[0] ^ ucInvert; // we need to brute-force invert it
|
||||
*d++ = pgm_read_byte(&ucMirror[c]);
|
||||
pSrc++;
|
||||
} // for x
|
||||
// write this line to the display
|
||||
ucLineBuf[iPitch+2] = 0; // end of line
|
||||
_I2CWrite(pOBD, ucLineBuf, iPitch+3);
|
||||
ucLineBuf[1] = 0;
|
||||
_I2CWrite(pOBD, ucLineBuf, 2); // final transfer
|
||||
digitalWrite(pOBD->iCSPin, LOW); // de-activate
|
||||
} /* obdWriteLCDLine() */
|
||||
|
||||
//
|
||||
// Turn the display on or off
|
||||
//
|
||||
void obdPower(OBDISP *pOBD, int bOn)
|
||||
{
|
||||
uint8_t ucCMD;
|
||||
|
||||
if (pOBD->type == LCD_NOKIA5110)
|
||||
ucCMD = (bOn) ? 0x20 : 0x24;
|
||||
else // all other supported displays
|
||||
ucCMD = (bOn) ? 0xaf : 0xae;
|
||||
obdWriteCommand(pOBD, ucCMD);
|
||||
} /* obdPower() */
|
||||
|
||||
// Controls the LED backlight
|
||||
void obdBacklight(OBDISP *pOBD, int bOn)
|
||||
{
|
||||
if (pOBD->iLEDPin != 0xff)
|
||||
{
|
||||
digitalWrite(pOBD->iLEDPin, (bOn) ? HIGH:LOW);
|
||||
}
|
||||
} /* obdBacklight() */
|
||||
|
||||
//
|
||||
// Initialize the display controller on an SPI bus
|
||||
//
|
||||
void obdSPIInit(OBDISP *pOBD, int iType, int iDC, int iCS, int iReset, int iMOSI, int iCLK, int iLED, int bFlip, int bInvert, int bBitBang, int32_t iSpeed)
|
||||
{
|
||||
} /* obdSPIInit() */
|
||||
//
|
||||
// Set the memory configuration to display the pixels at 0 or 180 degrees (flipped)
|
||||
// Pass true (1) to flip 180, false (0) to set to 0
|
||||
//
|
||||
void obdSetFlip(OBDISP *pOBD, int iOnOff)
|
||||
{
|
||||
if (pOBD == NULL) return;
|
||||
pOBD->flip = iOnOff;
|
||||
if (pOBD->type == LCD_UC1701 || pOBD->type == LCD_UC1609)
|
||||
{
|
||||
if (iOnOff) // rotate display 180
|
||||
{
|
||||
obdWriteCommand(pOBD, 0xa1); // SEG direction (A1 to flip horizontal)
|
||||
obdWriteCommand(pOBD, 0xc0); // COM direction (C0 to flip vert)
|
||||
} else { // non-rotated
|
||||
obdWriteCommand(pOBD, 0xa0);
|
||||
obdWriteCommand(pOBD, 0xc8);
|
||||
}
|
||||
} else { // OLEDs
|
||||
if (iOnOff)
|
||||
{
|
||||
obdWriteCommand(pOBD, 0xa0);
|
||||
obdWriteCommand(pOBD, 0xc0);
|
||||
} else {
|
||||
obdWriteCommand(pOBD, 0xa1);
|
||||
obdWriteCommand(pOBD, 0xc8);
|
||||
}
|
||||
}
|
||||
} /* obdSetFlip() */
|
||||
//
|
||||
// Initializes the OLED controller into "page mode"
|
||||
//
|
||||
int obdI2CInit(OBDISP *pOBD, int iType, int iAddr, int bFlip, int bInvert, int bWire, int sda, int scl, int reset, int32_t iSpeed)
|
||||
{
|
||||
return 0;
|
||||
} /* obdInit() */
|
||||
//
|
||||
// Sends a command to turn on or off the OLED display
|
||||
//
|
||||
void oledPower(OBDISP *pOBD, uint8_t bOn)
|
||||
{
|
||||
if (bOn)
|
||||
obdWriteCommand(pOBD, 0xaf); // turn on OLED
|
||||
else
|
||||
obdWriteCommand(pOBD, 0xae); // turn off OLED
|
||||
} /* oledPower() */
|
||||
|
||||
#ifdef _LINUX_
|
||||
void delay(int iDelay)
|
||||
{
|
||||
// usleep(iDelay * 1000);
|
||||
} /* delay() */
|
||||
void delayMicroseconds(int iDelay)
|
||||
{
|
||||
//usleep(iDelay);
|
||||
} /* delayMicroseconds() */
|
||||
#endif // _LINUX_
|
||||
//
|
||||
// Bit Bang the data on GPIO pins
|
||||
//
|
||||
void SPI_BitBang(OBDISP *pOBD, uint8_t *pData, int iLen, uint8_t iMOSIPin, uint8_t iSCKPin)
|
||||
{
|
||||
int i;
|
||||
uint8_t c;
|
||||
// We can access the GPIO ports much quicker on AVR by directly manipulating
|
||||
// the port registers
|
||||
#ifdef __AVR__
|
||||
volatile uint8_t *outSCK, *outMOSI; // port registers for fast I/O
|
||||
uint8_t port, bitSCK, bitMOSI; // bit mask for the chosen pins
|
||||
|
||||
port = digitalPinToPort(iMOSIPin);
|
||||
outMOSI = portOutputRegister(port);
|
||||
bitMOSI = digitalPinToBitMask(iMOSIPin);
|
||||
port = digitalPinToPort(iSCKPin);
|
||||
outSCK = portOutputRegister(port);
|
||||
bitSCK = digitalPinToBitMask(iSCKPin);
|
||||
|
||||
#endif
|
||||
|
||||
while (iLen)
|
||||
{
|
||||
c = *pData++;
|
||||
if (pOBD->iDCPin == 0xff) // 3-wire SPI, write D/C bit first
|
||||
{
|
||||
#ifdef __AVR__
|
||||
if (pOBD->mode == MODE_DATA)
|
||||
*outMOSI |= bitMOSI;
|
||||
else
|
||||
*outMOSI &= ~bitMOSI;
|
||||
*outSCK |= bitSCK; // toggle clock
|
||||
*outSCK &= ~bitSCK; // no delay needed on SPI devices since AVR is slow
|
||||
#else
|
||||
digitalWrite(iMOSIPin, (pOBD->mode == MODE_DATA));
|
||||
digitalWrite(iSCKPin, HIGH);
|
||||
delayMicroseconds(0);
|
||||
digitalWrite(iSCKPin, LOW);
|
||||
#endif
|
||||
}
|
||||
if (c == 0 || c == 0xff) // quicker for all bits equal
|
||||
{
|
||||
#ifdef __AVR__
|
||||
if (c & 1)
|
||||
*outMOSI |= bitMOSI;
|
||||
else
|
||||
*outMOSI &= ~bitMOSI;
|
||||
for (i=0; i<8; i++)
|
||||
{
|
||||
*outSCK |= bitSCK;
|
||||
*outSCK &= ~bitSCK;
|
||||
}
|
||||
#else
|
||||
digitalWrite(iMOSIPin, (c & 1));
|
||||
for (i=0; i<8; i++)
|
||||
{
|
||||
digitalWrite(iSCKPin, HIGH);
|
||||
delayMicroseconds(0);
|
||||
digitalWrite(iSCKPin, LOW);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i=0; i<8; i++)
|
||||
{
|
||||
#ifdef __AVR__
|
||||
if (c & 0x80) // MSB first
|
||||
*outMOSI |= bitMOSI;
|
||||
else
|
||||
*outMOSI &= ~bitMOSI;
|
||||
*outSCK |= bitSCK;
|
||||
c <<= 1;
|
||||
*outSCK &= ~bitSCK;
|
||||
#else
|
||||
digitalWrite(iMOSIPin, (c & 0x80) != 0); // MSB first
|
||||
digitalWrite(iSCKPin, HIGH);
|
||||
c <<= 1;
|
||||
delayMicroseconds(0);
|
||||
digitalWrite(iSCKPin, LOW);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
iLen--;
|
||||
}
|
||||
} /* SPI_BitBang() */
|
||||
|
||||
// Sets the D/C pin to data or command mode
|
||||
void obdSetDCMode(OBDISP *pOBD, int iMode)
|
||||
{
|
||||
if (pOBD->iDCPin == 0xff) // 9-bit SPI
|
||||
pOBD->mode = (uint8_t)iMode;
|
||||
else // set the GPIO line
|
||||
digitalWrite(pOBD->iDCPin, (iMode == MODE_DATA));
|
||||
} /* obdSetDCMode() */
|
||||
|
||||
static void obdWriteCommand2(OBDISP *pOBD, unsigned char c, unsigned char d)
|
||||
{
|
||||
unsigned char buf[4];
|
||||
|
||||
if (pOBD->com_mode == COM_I2C) {// I2C device
|
||||
buf[0] = 0x00;
|
||||
buf[1] = c;
|
||||
buf[2] = d;
|
||||
_I2CWrite(pOBD, buf, 3);
|
||||
} else { // must be SPI
|
||||
obdWriteCommand(pOBD, c);
|
||||
obdWriteCommand(pOBD, d);
|
||||
}
|
||||
} /* obdWriteCommand2() */
|
||||
|
||||
//
|
||||
// Sets the brightness (0=off, 255=brightest)
|
||||
//
|
||||
void obdSetContrast(OBDISP *pOBD, unsigned char ucContrast)
|
||||
{
|
||||
if (pOBD->type == LCD_HX1230)
|
||||
{ // valid values are 0-31, so scale it
|
||||
ucContrast >>= 3;
|
||||
obdWriteCommand(pOBD, 0x80 + ucContrast);
|
||||
}
|
||||
else if (pOBD->type == LCD_NOKIA5110)
|
||||
{
|
||||
// we allow values of 0xb0-0xbf, so shrink the range
|
||||
ucContrast >>= 4;
|
||||
obdWriteCommand(pOBD, 0x21); // set advanced command mode
|
||||
obdWriteCommand(pOBD, 0xb0 | ucContrast);
|
||||
obdWriteCommand(pOBD, 0x20); // set simple command mode
|
||||
}
|
||||
else // OLEDs + UC1701
|
||||
obdWriteCommand2(pOBD, 0x81, ucContrast);
|
||||
} /* obdSetContrast() */
|
||||
|
||||
//
|
||||
// Special case for Sharp Memory LCD
|
||||
//
|
||||
static void SharpDumpBuffer(OBDISP *pOBD, uint8_t *pBuffer)
|
||||
{
|
||||
int x, y;
|
||||
uint8_t c, ucInvert, *s, *d, ucStart;
|
||||
uint8_t ucLineBuf[56];
|
||||
int iPitch = pOBD->width / 8;
|
||||
static uint8_t ucVCOM = 0;
|
||||
int iBit;
|
||||
uint8_t ucMask;
|
||||
|
||||
ucInvert = (pOBD->invert) ? 0x00 : 0xff;
|
||||
digitalWrite(pOBD->iCSPin, HIGH); // active high
|
||||
|
||||
ucLineBuf[0] = 0;
|
||||
ucStart = 0x80; // write command
|
||||
if (ucVCOM)
|
||||
ucStart |= 0x40; // VCOM bit
|
||||
ucLineBuf[1] = ucStart;
|
||||
// this code assumes I2C, so the first byte is ignored
|
||||
_I2CWrite(pOBD, ucLineBuf, 2); // write command(01) + vcom(02)
|
||||
ucVCOM = !ucVCOM; // need to toggle this each transaction
|
||||
|
||||
// We need to flip and invert the image in code because the Sharp memory LCD
|
||||
// controller only has the simplest of commands for data writing
|
||||
if (pOBD->flip)
|
||||
{
|
||||
for (y=0; y<pOBD->height; y++) // we have to write the memory in the wrong direction
|
||||
{
|
||||
ucMask = 0x80 >> (y & 7);
|
||||
s = &pBuffer[pOBD->width - 1 + (pOBD->width * ((pOBD->height - 1 - y) >> 3))]; // point to last line first
|
||||
d = &ucLineBuf[2];
|
||||
ucLineBuf[1] = pgm_read_byte(&ucMirror[y+1]); // current line number
|
||||
for (x=0; x<pOBD->width/8; x++)
|
||||
{
|
||||
c = ucInvert; // we need to brute-force invert it
|
||||
for (iBit=7; iBit>=0; iBit--)
|
||||
{
|
||||
if (s[0] & ucMask)
|
||||
c ^= (1 << iBit);
|
||||
s--;
|
||||
}
|
||||
*d++ = c;
|
||||
} // for y
|
||||
// write this line to the display
|
||||
ucLineBuf[iPitch+2] = 0; // end of line
|
||||
_I2CWrite(pOBD, ucLineBuf, iPitch+3);
|
||||
} // for x
|
||||
}
|
||||
else // normal orientation
|
||||
{
|
||||
for (y=0; y<pOBD->height; y++) // we have to write the memory in the wrong direction
|
||||
{
|
||||
ucMask = 1 << (y & 7);
|
||||
s = &pBuffer[pOBD->width * (y >> 3)]; // point to last line first
|
||||
d = &ucLineBuf[2];
|
||||
|
||||
ucLineBuf[1] = pgm_read_byte(&ucMirror[y+1]); // current line number
|
||||
for (x=0; x<pOBD->width/8; x++)
|
||||
{
|
||||
c = ucInvert;
|
||||
for (iBit=7; iBit>=0; iBit--)
|
||||
{
|
||||
if (s[0] & ucMask)
|
||||
c ^= (1 << iBit);
|
||||
s++;
|
||||
}
|
||||
*d++ = c;
|
||||
} // for y
|
||||
// write this line to the display
|
||||
ucLineBuf[iPitch+2] = 0; // end of line
|
||||
_I2CWrite(pOBD, ucLineBuf, iPitch+3);
|
||||
} // for x
|
||||
}
|
||||
ucLineBuf[1] = 0;
|
||||
_I2CWrite(pOBD, ucLineBuf, 2); // final transfer
|
||||
digitalWrite(pOBD->iCSPin, LOW); // de-activate
|
||||
} /* SharpDumpBuffer() */
|
||||
//
|
||||
// Dump a screen's worth of data directly to the display
|
||||
// Try to speed it up by comparing the new bytes with the existing buffer
|
||||
//
|
||||
void obdDumpBuffer(OBDISP *pOBD, uint8_t *pBuffer)
|
||||
{
|
||||
int x, y, iPitch;
|
||||
int iLines, iCols;
|
||||
uint8_t bNeedPos;
|
||||
uint8_t *pSrc = pOBD->ucScreen;
|
||||
|
||||
iPitch = pOBD->width;
|
||||
if (pOBD->type == LCD_VIRTUAL) // wrong function for this type of display
|
||||
return;
|
||||
if (pBuffer == NULL) // dump the internal buffer if none is given
|
||||
pBuffer = pOBD->ucScreen;
|
||||
if (pBuffer == NULL)
|
||||
return; // no backbuffer and no provided buffer
|
||||
|
||||
if (pOBD->type >= SHARP_144x168) // special case for Sharp Memory LCD
|
||||
{
|
||||
SharpDumpBuffer(pOBD, pBuffer);
|
||||
return;
|
||||
}
|
||||
iLines = pOBD->height >> 3;
|
||||
iCols = pOBD->width >> 4;
|
||||
for (y=0; y<iLines; y++)
|
||||
{
|
||||
bNeedPos = 1; // start of a new line means we need to set the position too
|
||||
for (x=0; x<iCols; x++) // wiring library has a 32-byte buffer, so send 16 bytes so that the data prefix (0x40) can fit
|
||||
{
|
||||
if (pOBD->ucScreen == NULL || pBuffer == pSrc || memcmp(pSrc, pBuffer, 16) != 0) // doesn't match, need to send it
|
||||
{
|
||||
if (bNeedPos) // need to reposition output cursor?
|
||||
{
|
||||
bNeedPos = 0;
|
||||
obdCachedFlush(pOBD, 1);
|
||||
obdSetPosition(pOBD, x*16, y, 1);
|
||||
}
|
||||
obdCachedWrite(pOBD, pBuffer, 16, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
bNeedPos = 1; // we're skipping a block, so next time will need to set the new position
|
||||
}
|
||||
pSrc += 16;
|
||||
pBuffer += 16;
|
||||
} // for x
|
||||
pSrc += (iPitch - pOBD->width); // for narrow displays, skip to the next line
|
||||
pBuffer += (iPitch - pOBD->width);
|
||||
} // for y
|
||||
obdCachedFlush(pOBD, 1);
|
||||
} /* obdDumpBuffer() */
|
||||
|
||||
//
|
||||
// Menu functions are not (yet) supported on Linux
|
||||
//
|
||||
#ifndef _LINUX_
|
||||
// A valid CW or CCW move returns 1 or -1, invalid returns 0.
|
||||
static int obdMenuReadRotary(SIMPLEMENU *sm) {
|
||||
static int8_t rot_enc_table[] = {0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0};
|
||||
uint8_t c;
|
||||
int rc = 0;
|
||||
|
||||
|
||||
sm->prevNextCode <<= 2;
|
||||
if (digitalRead(sm->u8Dn) == sm->iPressed)
|
||||
sm->prevNextCode |= 0x02;
|
||||
if (digitalRead(sm->u8Up) == sm->iPressed)
|
||||
sm->prevNextCode |= 0x01;
|
||||
sm->prevNextCode &= 0x0f;
|
||||
|
||||
// If valid then store as 16 bit data.
|
||||
if (rot_enc_table[sm->prevNextCode]) {
|
||||
sm->store <<= 4;
|
||||
sm->store |= sm->prevNextCode;
|
||||
c = sm->store & 0xff;
|
||||
//if (store==0xd42b) return 1;
|
||||
//if (store==0xe817) return -1;
|
||||
if ((c & 0xf) == 2) rc = -1;
|
||||
else if ((c & 0xf) == 1) rc = 1;
|
||||
}
|
||||
// Serial.printf("store = 0x%04x, val = %d\r\n", sm->store, rc);
|
||||
return rc;
|
||||
} /* obdMenuReadRotary() */
|
||||
|
||||
//
|
||||
// Initialize the simple menu structure
|
||||
//
|
||||
int obdMenuInit(OBDISP *pOBD, SIMPLEMENU *sm, char **pText, int iFontSize, int bCenter, int btnUp, int btnDn, int btnEnter, int iPressedState, int bIsRotary)
|
||||
{
|
||||
int iLen;
|
||||
if (sm == NULL || pText == NULL) return 0;
|
||||
sm->pOBD = pOBD;
|
||||
sm->u8Up = btnUp; // pin numbers of the action buttons
|
||||
sm->u8Dn = btnDn; // or rotary A line
|
||||
sm->u8Enter = btnEnter; // or rotary B line
|
||||
sm->bIsRotary = bIsRotary;
|
||||
sm->u8BtnState = 0; // no active buttons to start
|
||||
sm->iPressed = iPressedState; // active state of a pressed button
|
||||
sm->bCenter = bCenter;
|
||||
sm->iFontSize = iFontSize;
|
||||
sm->pMenuText = pText;
|
||||
sm->iMenuIndex = 0; // start at first item
|
||||
sm->iDispX = 128; // DEBUG
|
||||
sm->iDispY = 64; // DEBUG
|
||||
sm->bOneButton = (btnDn == -1 && btnEnter == -1); // only 1 button defined
|
||||
sm->pfnCallback = NULL;
|
||||
sm->prevNextCode = 0;
|
||||
sm->store = 0;
|
||||
iLen = 0;
|
||||
while (pText[iLen] != NULL) {
|
||||
iLen++;
|
||||
}
|
||||
sm->iMenuLen = iLen-1; // don't count the title text
|
||||
return 1; // success
|
||||
} /* obdMenuInit() */
|
||||
|
||||
//
|
||||
// Get the text and centering position for
|
||||
// a specific menu item
|
||||
// returns the X position
|
||||
//
|
||||
static int obdMenuGetItem(SIMPLEMENU *sm, int iItem, char *szText)
|
||||
{
|
||||
int x, cx, len;
|
||||
|
||||
if (iItem > sm->iMenuLen)
|
||||
return -1; // invalid request
|
||||
|
||||
if (sm->iFontSize == FONT_6x8)
|
||||
cx = 6;
|
||||
else if (sm->iFontSize == FONT_8x8)
|
||||
cx = 8;
|
||||
else cx = 16;
|
||||
strcpy(szText, sm->pMenuText[iItem]);
|
||||
if (sm->pfnCallback && iItem > 0) // don't add callback for menu title
|
||||
{
|
||||
strcat(szText, " ");
|
||||
strcat(szText, (*sm->pfnCallback)(iItem-1));
|
||||
}
|
||||
x = 0;
|
||||
if (sm->bCenter || iItem == 0) // always center the menu title
|
||||
{
|
||||
len = strlen(szText);
|
||||
x = (sm->iDispX - (len * cx)) / 2;
|
||||
}
|
||||
return x;
|
||||
} /* obdMenuGetItem() */
|
||||
|
||||
//
|
||||
// Erase the display and show the given menu
|
||||
//
|
||||
void obdMenuShow(SIMPLEMENU *sm, int iItem)
|
||||
{
|
||||
int i, x, iCount, iStart = 0;
|
||||
int iFirst, iLast;
|
||||
char szTemp[64];
|
||||
|
||||
iCount = (sm->iDispY / 8) - 1; // DEBUG - number of visible menu lines
|
||||
iFirst = iLast = iItem;
|
||||
if (iItem == -1) // show the entire menu
|
||||
{
|
||||
obdFill(sm->pOBD, 0, 0);
|
||||
x = obdMenuGetItem(sm, 0, szTemp); // get the title text
|
||||
obdMenuShowItem(sm->pOBD, x, 0, szTemp, 0, 0, sm->iFontSize, 0); // show title
|
||||
iFirst = 0;
|
||||
iLast = iCount-1;
|
||||
}
|
||||
if (sm->iMenuIndex >= iCount) // needs to scroll up
|
||||
iStart = sm->iMenuIndex - (iCount-1);
|
||||
if (sm->iMenuIndex < 0 || sm->iMenuIndex+iCount > sm->iMenuLen) { // invalid
|
||||
sm->iMenuIndex = 0;
|
||||
iStart = 0;
|
||||
}
|
||||
|
||||
for (i=iFirst; i<=iLast && i+iStart < sm->iMenuLen; i++) // draw the visible menu lines
|
||||
{
|
||||
x = obdMenuGetItem(sm, i + iStart + 1, szTemp);
|
||||
if (x >= 0) // display if valid
|
||||
obdMenuShowItem(sm->pOBD, x, i+1, szTemp, (i+iStart == sm->iMenuIndex), (iFirst==iLast), sm->iFontSize, (iFirst==iLast));
|
||||
}
|
||||
if (iItem == -1) // now the display it in one shot
|
||||
obdDumpBuffer(sm->pOBD, NULL);
|
||||
} /* obdMenuShow() */
|
||||
|
||||
//
|
||||
// Set a callback function to return custom info/status
|
||||
// for each menu item
|
||||
//
|
||||
void obdMenuSetCallback(SIMPLEMENU *sm, SIMPLECALLBACK pfnCallBack)
|
||||
{
|
||||
if (sm != NULL)
|
||||
sm->pfnCallback = pfnCallBack;
|
||||
} /* obdMenuSetCallback() */
|
||||
//
|
||||
// Display the text of a single menu item
|
||||
// optionally erases what's under it to prevent left-over text when the length changes
|
||||
//
|
||||
void obdMenuShowItem(OBDISP *pOBD, int x, int y, char *szText, int bInvert, int bErase, int iFontSize, int bRender)
|
||||
{
|
||||
static char *szBlank = (char *)" ";
|
||||
if (bErase)
|
||||
obdWriteString(pOBD, 0, 0, y, szBlank, iFontSize, 0, bRender); // erase old info
|
||||
obdWriteString(pOBD, 0, x, y, szText, iFontSize, bInvert, bRender);
|
||||
} /* obdMenuShowItem() */
|
||||
|
||||
//
|
||||
// Flash a menu item when it is selected
|
||||
//
|
||||
static void obdMenuFlash(SIMPLEMENU *sm, int iItem)
|
||||
{
|
||||
int x, y, i, iCount;
|
||||
char szTemp[64];
|
||||
|
||||
iCount = (sm->iDispY / 8) - 1; // DEBUG - number of visible menu lines
|
||||
y = iItem+1;
|
||||
if (y > iCount) // max bottom line
|
||||
y = iCount;
|
||||
|
||||
x = obdMenuGetItem(sm, iItem+1, szTemp);
|
||||
if (x < 0) return; // invalid request
|
||||
|
||||
for (i=0; i<3; i++)
|
||||
{
|
||||
obdMenuShowItem(sm->pOBD, x, y, szTemp, 0, 0, sm->iFontSize, 1); // show non-inverted
|
||||
delay(200);
|
||||
obdMenuShowItem(sm->pOBD, x, y, szTemp, 1, 0, sm->iFontSize, 1); // show inverted
|
||||
delay(200);
|
||||
}
|
||||
} /* obdMenuFlash() */
|
||||
|
||||
//
|
||||
// Change the menu index incrementally
|
||||
// redraws the minimum amount of screen to show the new info
|
||||
// (this prevents flicker/flash and saves battery life)
|
||||
// returns the new menu index
|
||||
//
|
||||
int obdMenuDelta(SIMPLEMENU *sm, int iDelta)
|
||||
{
|
||||
int i, x, iNewIndex, iCount;
|
||||
int iStart1, iStart2;
|
||||
char szTemp[64];
|
||||
|
||||
if (iDelta == 0) return sm->iMenuIndex; // nothing to do
|
||||
|
||||
iNewIndex = sm->iMenuIndex + iDelta;
|
||||
if (!sm->bOneButton && (iNewIndex < 0 || iNewIndex >= sm->iMenuLen)) // no change possible, exit
|
||||
return sm->iMenuIndex; // unchanged
|
||||
// If we are using a single button, wrap around the ends
|
||||
if (iNewIndex < 0) iNewIndex = (sm->iMenuLen - 1);
|
||||
else if (iNewIndex > sm->iMenuLen-1) iNewIndex = 0;
|
||||
|
||||
iCount = (sm->iDispY / 8) - 1; // DEBUG - number of visible menu lines
|
||||
iStart1 = iStart2 = 0;
|
||||
if (sm->iMenuIndex > iCount-1)
|
||||
iStart1 = sm->iMenuIndex - (iCount-1);
|
||||
if (iNewIndex > iCount-1) // needs to scroll up
|
||||
iStart2 = iNewIndex - (iCount-1);
|
||||
if (iStart1 != iStart2) // need to redraw all items
|
||||
{
|
||||
for (i=0; i<iCount; i++)
|
||||
{
|
||||
x = obdMenuGetItem(sm, i+iStart2+1, szTemp);
|
||||
if (x >= 0)
|
||||
obdMenuShowItem(sm->pOBD, x, i+1, szTemp, (i+iStart2 == iNewIndex), 1, sm->iFontSize, 0);
|
||||
}
|
||||
obdDumpBuffer(sm->pOBD, NULL);
|
||||
}
|
||||
else // need to redraw only the new and old items
|
||||
{
|
||||
i = sm->iMenuIndex - iStart1;
|
||||
x = obdMenuGetItem(sm, sm->iMenuIndex+1, szTemp);
|
||||
if (x >= 0)
|
||||
obdMenuShowItem(sm->pOBD, x, i+1, szTemp, 0, 0, sm->iFontSize, 1);
|
||||
i = iNewIndex - iStart2;
|
||||
x = obdMenuGetItem(sm, iNewIndex+1, szTemp);
|
||||
if (x >= 0)
|
||||
obdMenuShowItem(sm->pOBD, x, i+1, szTemp, 1, 0, sm->iFontSize, 1);
|
||||
}
|
||||
sm->iMenuIndex = iNewIndex;
|
||||
return iNewIndex;
|
||||
} /* obdMenuDelta() */
|
||||
|
||||
//
|
||||
// With the given setup, check for button presses
|
||||
// and act accordingly
|
||||
// returns -1 for normal interactions and the menu item index if the user presses the ENTER button
|
||||
//
|
||||
// time in milliseconds for a long press
|
||||
#define MENU_LONG_PRESS 600
|
||||
int obdMenuRun(SIMPLEMENU *sm)
|
||||
{
|
||||
uint8_t buttons = 0;
|
||||
unsigned long ul;
|
||||
int iDelta, rc = -1;
|
||||
|
||||
if (sm->bIsRotary) { // read the rotary encoder
|
||||
if (digitalRead(sm->u8Enter) == sm->iPressed) {
|
||||
buttons |= 1; // pressed
|
||||
if (buttons != sm->u8BtnState)
|
||||
rc = sm->iMenuIndex; // user pressed ENTER, return current menu index
|
||||
} else { // check for rotary encoder activity
|
||||
iDelta = obdMenuReadRotary(sm);
|
||||
obdMenuDelta(sm, iDelta);
|
||||
}
|
||||
sm->u8BtnState = buttons;
|
||||
} else {
|
||||
// check the button states
|
||||
if (digitalRead(sm->u8Up) == sm->iPressed)
|
||||
buttons |= 1;
|
||||
if (buttons != sm->u8BtnState) // something changed
|
||||
{
|
||||
if (sm->bOneButton) // different logic for a single button system
|
||||
{
|
||||
if (sm->u8BtnState == 0 && buttons == 1) // up button just pressed
|
||||
{
|
||||
sm->ulPressTime = millis(); // record the press time
|
||||
}
|
||||
if (sm->u8BtnState == 1 && buttons == 0) // up button just released
|
||||
{
|
||||
ul = millis() - sm->ulPressTime;
|
||||
if (ul < MENU_LONG_PRESS) // short press = navigate menu
|
||||
obdMenuDelta(sm, 1);
|
||||
else // treat it like a long press
|
||||
rc = sm->iMenuIndex; // action
|
||||
}
|
||||
}
|
||||
else // 3 button setup (UP/DOWN/ENTER)
|
||||
{
|
||||
if (digitalRead(sm->u8Dn) == sm->iPressed)
|
||||
buttons |= 2;
|
||||
if (digitalRead(sm->u8Enter) == sm->iPressed)
|
||||
rc = sm->iMenuIndex; // user pressed ENTER, return current menu index
|
||||
if ((sm->u8BtnState & 1) == 0 && (buttons & 1) == 1) // Up button pressed
|
||||
{
|
||||
obdMenuDelta(sm, -1);
|
||||
}
|
||||
if ((sm->u8BtnState & 2) == 0 && (buttons & 2) == 2) // Down button pressed
|
||||
{
|
||||
obdMenuDelta(sm, 1);
|
||||
}
|
||||
}
|
||||
sm->u8BtnState = buttons; // save the latest state
|
||||
}
|
||||
}
|
||||
if (rc != -1) // selected
|
||||
obdMenuFlash(sm, sm->iMenuIndex);
|
||||
return rc;
|
||||
} /* obdMenuRun() */
|
||||
#endif // !_LINUX_
|
||||
390
ARM_Tag_FW/OpenEPaperLink_TLSR/src/OneBitDisplay.h
Normal file
390
ARM_Tag_FW/OpenEPaperLink_TLSR/src/OneBitDisplay.h
Normal file
@@ -0,0 +1,390 @@
|
||||
#ifndef __ONEBITDISPLAY__
|
||||
#define __ONEBITDISPLAY__
|
||||
|
||||
// Proportional font data taken from Adafruit_GFX library
|
||||
/// Font data stored PER GLYPH
|
||||
#if !defined( _ADAFRUIT_GFX_H ) && !defined( _GFXFONT_H_ )
|
||||
#define _GFXFONT_H_
|
||||
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
|
||||
uint8_t first; ///< ASCII extents (first char)
|
||||
uint8_t last; ///< ASCII extents (last char)
|
||||
uint8_t yAdvance; ///< Newline distance (y axis)
|
||||
} GFXfont;
|
||||
#endif // _ADAFRUIT_GFX_H
|
||||
|
||||
typedef struct obdstruct
|
||||
{
|
||||
uint8_t oled_addr; // requested address or 0xff for automatic detection
|
||||
uint8_t wrap, flip, invert, type;
|
||||
uint8_t *ucScreen;
|
||||
int iCursorX, iCursorY;
|
||||
int width, height;
|
||||
int iScreenOffset;
|
||||
//BBI2C bbi2c;
|
||||
uint8_t com_mode; // communication mode (I2C / SPI)
|
||||
uint8_t mode; // data/command mode for 9-bit SPI
|
||||
uint8_t iDCPin, iMOSIPin, iCLKPin, iCSPin;
|
||||
uint8_t iLEDPin; // backlight
|
||||
uint8_t bBitBang;
|
||||
} OBDISP;
|
||||
|
||||
typedef char * (*SIMPLECALLBACK)(int iMenuItem);
|
||||
|
||||
typedef struct smenu {
|
||||
uint8_t u8Up, u8Dn, u8Enter; // button pin numbers
|
||||
uint8_t bIsRotary; // rotary encoder or up/down buttons?
|
||||
uint8_t bCenter; // center all menu text if true
|
||||
uint8_t u8BtnState; // state of all buttons
|
||||
uint8_t bOneButton; // flag indicating the menu operates from a single button
|
||||
uint8_t prevNextCode; // rotary encoder state machine
|
||||
int iMenuIndex; // current menu index
|
||||
int iMenuLen; // number of entries in the menu (calculated at startup)
|
||||
char **pMenuText; // string array with menu title and text
|
||||
int iFontSize;
|
||||
int iPressed; // polarity of button pressed state
|
||||
unsigned long ulPressTime; // time in millis when button was pressed
|
||||
int iDispX, iDispY; // display width/height in pixels
|
||||
SIMPLECALLBACK pfnCallback;
|
||||
OBDISP *pOBD; // display structureme
|
||||
uint16_t store;
|
||||
} SIMPLEMENU;
|
||||
|
||||
// Make the Linux library interface C instead of C++
|
||||
#if defined(_LINUX_) && defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if !defined(BITBANK_LCD_MODES)
|
||||
#define BITBANK_LCD_MODES
|
||||
typedef enum
|
||||
{
|
||||
MODE_DATA = 0,
|
||||
MODE_COMMAND
|
||||
} DC_MODE;
|
||||
#endif
|
||||
|
||||
typedef enum
|
||||
{
|
||||
COM_I2C = 0,
|
||||
COM_SPI,
|
||||
} COM_MODE;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
ROT_0 = 0,
|
||||
ROT_90,
|
||||
ROT_180,
|
||||
ROT_270
|
||||
} FONT_ROTATION;
|
||||
|
||||
// These are defined the same in my SPI_LCD library
|
||||
#ifndef SPI_LCD_H
|
||||
|
||||
// 5 possible font sizes: 8x8, 16x32, 6x8, 12x16 (stretched from 6x8 with smoothing), 16x16 (stretched from 8x8)
|
||||
enum {
|
||||
FONT_6x8 = 0,
|
||||
FONT_8x8,
|
||||
FONT_12x16,
|
||||
FONT_16x16,
|
||||
FONT_16x32,
|
||||
FONT_COUNT
|
||||
};
|
||||
// For backwards compatibility, keep the old names valid
|
||||
#define FONT_NORMAL FONT_8x8
|
||||
#define FONT_SMALL FONT_6x8
|
||||
#define FONT_STRETCHED FONT_16x16
|
||||
#define FONT_LARGE FONT_16x32
|
||||
#endif
|
||||
|
||||
// Display type for init function
|
||||
enum {
|
||||
OLED_128x128 = 1,
|
||||
OLED_128x32,
|
||||
OLED_128x64,
|
||||
OLED_132x64,
|
||||
OLED_64x128,
|
||||
OLED_64x32,
|
||||
OLED_96x16,
|
||||
OLED_72x40,
|
||||
LCD_UC1701,
|
||||
LCD_UC1609,
|
||||
LCD_HX1230,
|
||||
LCD_NOKIA5110,
|
||||
LCD_VIRTUAL,
|
||||
SHARP_144x168,
|
||||
SHARP_400x240
|
||||
};
|
||||
|
||||
// Rotation and flip angles to draw tiles
|
||||
enum {
|
||||
ANGLE_0=0,
|
||||
ANGLE_90,
|
||||
ANGLE_180,
|
||||
ANGLE_270,
|
||||
ANGLE_FLIPX,
|
||||
ANGLE_FLIPY
|
||||
};
|
||||
|
||||
// Return value from obd obdI2CInit()
|
||||
enum {
|
||||
OLED_NOT_FOUND = -1, // no display found
|
||||
OLED_SSD1306_3C, // SSD1306 found at 0x3C
|
||||
OLED_SSD1306_3D, // SSD1306 found at 0x3D
|
||||
OLED_SH1106_3C, // SH1106 found at 0x3C
|
||||
OLED_SH1106_3D, // SH1106 found at 0x3D
|
||||
OLED_SH1107_3C, // SH1107
|
||||
OLED_SH1107_3D,
|
||||
LCD_OK,
|
||||
LCD_ERROR
|
||||
};
|
||||
//
|
||||
// Create a virtual display of any size
|
||||
// The memory buffer must be provided at the time of creation
|
||||
//
|
||||
void obdCreateVirtualDisplay(OBDISP *pOBD, int width, int height, uint8_t *buffer);
|
||||
// Constants for the obdCopy() function
|
||||
// Output format options -
|
||||
#define OBD_LSB_FIRST 0x001
|
||||
#define OBD_MSB_FIRST 0x002
|
||||
#define OBD_VERT_BYTES 0x004
|
||||
#define OBD_HORZ_BYTES 0x008
|
||||
// Orientation options -
|
||||
#define OBD_ROTATE_90 0x010
|
||||
#define OBD_FLIP_VERT 0x020
|
||||
#define OBD_FLIP_HORZ 0x040
|
||||
#define OBD_INVERT 0x080
|
||||
// Copy the current bitmap buffer from its native form (LSB_FIRST, VERTICAL_BYTES) to the requested form
|
||||
// A copy of the same format will just do a memcpy
|
||||
int obdCopy(OBDISP *pOBD, int iFlags, uint8_t *pDestination);
|
||||
//
|
||||
// Draw the contents of a memory buffer onto a display
|
||||
// The sub-window will be clipped if it specifies too large an area
|
||||
// for the destination display. The source OBDISP structure must have
|
||||
// a valid back buffer defined
|
||||
// The top and bottom destination edges will be drawn on byte boundaries (8 rows)
|
||||
// The source top/bot edges can be on pixel boundaries
|
||||
//
|
||||
void obdDumpWindow(OBDISP *pOBDSrc, OBDISP *pOBDDest, int srcx, int srcy, int destx, int desty, int width, int height);
|
||||
//
|
||||
// Write a single line to a Sharp memory LCD
|
||||
// You must provide the exact number of bytes needed for a complete line
|
||||
// e.g. for the 144x168 display, pSrc must provide 144 pixels (18 bytes)
|
||||
//
|
||||
void obdWriteLCDLine(OBDISP *pOBD, uint8_t *pSrc, int iLine);
|
||||
//
|
||||
// Initializes the display controller into "page mode" on I2C
|
||||
// If SDAPin and SCLPin are not -1, then bit bang I2C on those pins
|
||||
// Otherwise use the Wire library.
|
||||
// If you don't need to use a separate reset pin, set it to -1
|
||||
//
|
||||
int obdI2CInit(OBDISP *pOBD, int iType, int iAddr, int bFlip, int bInvert, int bWire, int iSDAPin, int iSCLPin, int iResetPin, int32_t iSpeed);
|
||||
//
|
||||
// Initialize an SPI version of the display
|
||||
//
|
||||
void obdSPIInit(OBDISP *pOBD, int iType, int iDC, int iCS, int iReset, int iMOSI, int iCLK, int iLED, int bFlip, int bInvert, int iBitBang, int32_t iSpeed);
|
||||
|
||||
//
|
||||
// Set the memory configuration to display the pixels at 0 or 180 degrees (flipped)
|
||||
// pass true (1) to flip 180, false (0) to set to 0
|
||||
void obdSetFlip(OBDISP *pOBD, int iOnOff);
|
||||
//
|
||||
// Provide or revoke a back buffer for your OLED graphics
|
||||
// This allows you to manage the RAM used by ss_oled on tiny
|
||||
// embedded platforms like the ATmega series
|
||||
// Pass NULL to revoke the buffer. Make sure you provide a buffer
|
||||
// large enough for your display (e.g. 128x64 needs 1K - 1024 bytes)
|
||||
//
|
||||
void obdSetBackBuffer(OBDISP *pOBD, uint8_t *pBuffer);
|
||||
//
|
||||
// Sets the brightness (0=off, 255=brightest)
|
||||
//
|
||||
void obdSetContrast(OBDISP *pOBD, unsigned char ucContrast);
|
||||
//
|
||||
// Load a 1-bpp Windows bitmap
|
||||
// Pass the pointer to the beginning of the BMP file
|
||||
// First pass version assumes a full screen bitmap
|
||||
//
|
||||
int obdLoadBMP(OBDISP *pOBD, uint8_t *pBMP, int x, int y, int bInvert);
|
||||
//
|
||||
// Power up/down the display
|
||||
// useful for low power situations
|
||||
//
|
||||
void obdPower(OBDISP *pOBD, int bOn);
|
||||
//
|
||||
// Set the current cursor position
|
||||
// The column represents the pixel column (0-127)
|
||||
// The row represents the text row (0-7)
|
||||
//
|
||||
void obdSetCursor(OBDISP *pOBD, int x, int y);
|
||||
|
||||
//
|
||||
// Turn text wrap on or off for the obdWriteString() function
|
||||
//
|
||||
void obdSetTextWrap(OBDISP *pOBD, int bWrap);
|
||||
//
|
||||
// Draw a string of normal (8x8), small (6x8) or large (16x32) characters
|
||||
// At the given col+row with the given scroll offset. The scroll offset allows you to
|
||||
// horizontally scroll text which does not fit on the width of the display. The offset
|
||||
// represents the pixels to skip when drawing the text. An offset of 0 starts at the beginning
|
||||
// of the text.
|
||||
// The system remembers where the last text was written (the cursor position)
|
||||
// To continue writing from the last position, set the x,y values to -1
|
||||
// The text can optionally wrap around to the next line by calling oledSetTextWrap(true);
|
||||
// otherwise text which would go off the right edge will not be drawn and the cursor will
|
||||
// be left "off screen" until set to a new position explicitly
|
||||
//
|
||||
// Returns 0 for success, -1 for invalid parameter
|
||||
//
|
||||
int obdWriteString(OBDISP *pOBD, int iScrollX, int x, int y, char *szMsg, int iSize, int bInvert, int bRender);
|
||||
//
|
||||
// Draw a string with a fractional scale in both dimensions
|
||||
// the scale is a 16-bit integer with and 8-bit fraction and 8-bit mantissa
|
||||
// To draw at 1x scale, set the scale factor to 256. To draw at 2x, use 512
|
||||
// The output must be drawn into a memory buffer, not directly to the display
|
||||
// The string can be drawn in one of 4 rotations (ROT_0, ROT_90, ROT_180, ROT_270)
|
||||
//
|
||||
int obdScaledString(OBDISP *pOBD, int x, int y, char *szMsg, int iSize, int bInvert, int iXScale, int iYScale, int iRotation);
|
||||
//
|
||||
// Draw a string in a proportional font you supply
|
||||
// Requires a back buffer
|
||||
//
|
||||
int obdWriteStringCustom(OBDISP *pOBD, GFXfont *pFont, int x, int y, char *szMsg, uint8_t ucColor);
|
||||
//
|
||||
// Get the width of text in a custom font
|
||||
//
|
||||
void obdGetStringBox(GFXfont *pFont, char *szMsg, int *width, int *top, int *bottom);
|
||||
//
|
||||
// Fill the frame buffer with a byte pattern
|
||||
// e.g. all off (0x00) or all on (0xff)
|
||||
//
|
||||
void obdFill(OBDISP *pOBD, unsigned char ucData, int bRender);
|
||||
//
|
||||
// Set (or clear) an individual pixel
|
||||
// The local copy of the frame buffer is used to avoid
|
||||
// reading data from the display controller
|
||||
// (which isn't possible in most configurations)
|
||||
// This function needs the USE_BACKBUFFER macro to be defined
|
||||
// otherwise, new pixels will erase old pixels within the same byte
|
||||
//
|
||||
int obdSetPixel(OBDISP *pOBD, int x, int y, unsigned char ucColor, int bRender);
|
||||
//
|
||||
// Dump an entire custom buffer to the display
|
||||
// useful for custom animation effects
|
||||
//
|
||||
void obdDumpBuffer(OBDISP *pOBD, uint8_t *pBuffer);
|
||||
//
|
||||
// Render a window of pixels from a provided buffer or the library's internal buffer
|
||||
// to the display. The row values refer to byte rows, not pixel rows due to the memory
|
||||
// layout of OLEDs. Pass a src pointer of NULL to use the internal backing buffer
|
||||
// returns 0 for success, -1 for invalid parameter
|
||||
//
|
||||
int obdDrawGFX(OBDISP *pOBD, uint8_t *pSrc, int iSrcCol, int iSrcRow, int iDestCol, int iDestRow, int iWidth, int iHeight, int iSrcPitch);
|
||||
|
||||
//
|
||||
// Draw a line between 2 points
|
||||
//
|
||||
void obdDrawLine(OBDISP *pOBD, int x1, int y1, int x2, int y2, uint8_t ucColor, int bRender);
|
||||
//
|
||||
// Play a frame of animation data
|
||||
// The animation data is assumed to be encoded for a full frame of the display
|
||||
// Given the pointer to the start of the compressed data,
|
||||
// it returns the pointer to the start of the next frame
|
||||
// Frame rate control is up to the calling program to manage
|
||||
// When it finishes the last frame, it will start again from the beginning
|
||||
//
|
||||
uint8_t * obdPlayAnimFrame(OBDISP *pOBD, uint8_t *pAnimation, uint8_t *pCurrent, int iLen);
|
||||
void obdWriteCommand(OBDISP *pOBD, unsigned char c);
|
||||
void obdSetPosition(OBDISP *pOBD, int x, int y, int bRender);
|
||||
void obdWriteDataBlock(OBDISP *pOBD, unsigned char *ucBuf, int iLen, int bRender);
|
||||
//
|
||||
// Scroll the internal buffer by 1 scanline (up/down)
|
||||
// width is in pixels, lines is group of 8 rows
|
||||
// Returns 0 for success, -1 for invalid parameter
|
||||
//
|
||||
int obdScrollBuffer(OBDISP *pOBD, int iStartCol, int iEndCol, int iStartRow, int iEndRow, int bUp);
|
||||
//
|
||||
// Draw a sprite of any size in any position
|
||||
// If it goes beyond the left/right or top/bottom edges
|
||||
// it's trimmed to show the valid parts
|
||||
// This function requires a back buffer to be defined
|
||||
// The priority color (0 or 1) determines which color is painted
|
||||
// when a 1 is encountered in the source image.
|
||||
// e.g. when 0, the input bitmap acts like a mask to clear
|
||||
// the destination where bits are set.
|
||||
//
|
||||
void obdDrawSprite(OBDISP *pOBD, uint8_t *pSprite, int cx, int cy, int iPitch, int x, int y, uint8_t iPriority);
|
||||
//
|
||||
// Draw a 16x16 tile in any of 4 rotated positions
|
||||
// Assumes input image is laid out like "normal" graphics with
|
||||
// the MSB on the left and 2 bytes per line
|
||||
// On AVR, the source image is assumed to be in FLASH memory
|
||||
// The function can draw the tile on byte boundaries, so the x value
|
||||
// can be from 0 to 112 and y can be from 0 to 6
|
||||
//
|
||||
void obdDrawTile(OBDISP *pOBD, const uint8_t *pTile, int x, int y, int iRotation, int bInvert, int bRender);
|
||||
//
|
||||
// Draw an outline or filled ellipse
|
||||
//
|
||||
void obdEllipse(OBDISP *pOBD, int iCenterX, int iCenterY, int32_t iRadiusX, int32_t iRadiusY, uint8_t ucColor, uint8_t bFilled);
|
||||
//
|
||||
// Draw an outline or filled rectangle
|
||||
//
|
||||
void obdRectangle(OBDISP *pOBD, int x1, int y1, int x2, int y2, uint8_t ucColor, uint8_t bFilled);
|
||||
|
||||
//
|
||||
// Turn the LCD backlight on or off
|
||||
//
|
||||
void obdBacklight(OBDISP *pODB, int bOn);
|
||||
|
||||
//
|
||||
// Menu functions
|
||||
//
|
||||
// Initialize the simple menu structure
|
||||
//
|
||||
int obdMenuInit(OBDISP *pOBD, SIMPLEMENU *sm, char **pText, int iFontSize, int bCenter, int btnUp, int btnDn, int btnEnter, int iPressedState, int bIsRotary);
|
||||
//
|
||||
// Erase the display and show the given menu
|
||||
//
|
||||
void obdMenuShow(SIMPLEMENU *sm, int iItem);
|
||||
//
|
||||
// Set a callback function to return custom info/status
|
||||
// for each menu item
|
||||
//
|
||||
void obdMenuSetCallback(SIMPLEMENU *sm, SIMPLECALLBACK pfnCallBack);
|
||||
//
|
||||
// Display the text of a single menu item
|
||||
// optionally erases what's under it to prevent left-over text when the length changes
|
||||
//
|
||||
void obdMenuShowItem(OBDISP *pOBD, int x, int y, char *szText, int bInvert, int bErase, int iFontSize, int bRender);
|
||||
//
|
||||
// Change the menu index incrementally
|
||||
// redraws the minimum amount of screen to show the new info
|
||||
// (this prevents flicker/flash and saves battery life)
|
||||
// returns the new menu index
|
||||
//
|
||||
int obdMenuDelta(SIMPLEMENU *sm, int iDelta);
|
||||
//
|
||||
// With the given setup, check for button presses
|
||||
// and act accordingly
|
||||
// returns -1 for normal interactions and the menu item index if the user presses the ENTER button
|
||||
//
|
||||
int obdMenuRun(SIMPLEMENU *sm);
|
||||
|
||||
#if defined(_LINUX_) && defined(__cplusplus)
|
||||
}
|
||||
#endif // _LINUX_
|
||||
|
||||
#endif // __ONEBITDISPLAY__
|
||||
|
||||
200
ARM_Tag_FW/OpenEPaperLink_TLSR/src/Roboto_Black_80.h
Normal file
200
ARM_Tag_FW/OpenEPaperLink_TLSR/src/Roboto_Black_80.h
Normal file
@@ -0,0 +1,200 @@
|
||||
// Created by http://oleddisplay.squix.ch/ Consider a donation
|
||||
// In case of problems make sure that you are using the font file with the correct version!
|
||||
const uint8_t Roboto_Black_80Bitmaps[] = {
|
||||
|
||||
// Bitmap Data:
|
||||
0x00, // ' '
|
||||
0xFF,0xFC,0xFF,0xFC,0x7F,0xFC,0x7F,0xFC,0x7F,0xFC,0x7F,0xFC,0x7F,0xFC,0x7F,0xFC,0x7F,0xFC,0x7F,0xFC,0x7F,0xFC,0x7F,0xFC,0x7F,0xFC,0x7F,0xFC,0x7F,0xFC,0x7F,0xFC,0x7F,0xFC,0x7F,0xFC,0x7F,0xFC,0x7F,0xFC,0x7F,0xFC,0x7F,0xFC,0x7F,0xF8,0x7F,0xF8,0x7F,0xF8,0x7F,0xF8,0x3F,0xF8,0x3F,0xF8,0x3F,0xF8,0x3F,0xF8,0x3F,0xF8,0x3F,0xF8,0x3F,0xF8,0x3F,0xF8,0x3F,0xF8,0x3F,0xF8,0x3F,0xF8,0x3F,0xF8,0x3F,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0xC0,0x3F,0xF0,0x7F,0xF8,0x7F,0xFC,0xFF,0xFC,0xFF,0xFE,0xFF,0xFE,0xFF,0xFE,0xFF,0xFC,0x7F,0xFC,0x7F,0xF8,0x3F,0xF0,0x0F,0xC0, // '!'
|
||||
0xFF,0x83,0xFE,0xFF,0x83,0xFE,0xFF,0x83,0xFE,0xFF,0x83,0xFE,0xFF,0x83,0xFE,0xFF,0x83,0xFE,0xFF,0x83,0xFC,0xFF,0x83,0xFC,0xFF,0x83,0xFC,0xFF,0x03,0xFC,0xFF,0x03,0xFC,0xFF,0x03,0xFC,0xFF,0x03,0xFC,0xFF,0x03,0xFC,0xFF,0x03,0xFC,0xFF,0x03,0xFC,0xFF,0x03,0xF8,0xFF,0x03,0xF8,0xFF,0x03,0xF8,0xFE,0x03,0xF8,0xFE,0x03,0xF8,0xFE,0x03,0xF8, // '"'
|
||||
0x00,0x01,0xFE,0x07,0xF8,0x00,0x00,0x0F,0xF0,0x3F,0xC0,0x00,0x00,0x7F,0x81,0xFE,0x00,0x00,0x03,0xFC,0x0F,0xF0,0x00,0x00,0x1F,0xC0,0x7F,0x80,0x00,0x01,0xFE,0x03,0xF8,0x00,0x00,0x0F,0xF0,0x3F,0xC0,0x00,0x00,0x7F,0x81,0xFE,0x00,0x00,0x03,0xFC,0x0F,0xF0,0x00,0x00,0x1F,0xE0,0x7F,0x80,0x00,0x00,0xFE,0x03,0xFC,0x00,0x00,0x07,0xF0,0x1F,0xC0,0x00,0x00,0x7F,0x81,0xFE,0x00,0x00,0x03,0xFC,0x0F,0xF0,0x00,0x00,0x1F,0xE0,0x7F,0x80,0x00,0x00,0xFF,0x03,0xFC,0x00,0x00,0x07,0xF8,0x1F,0xE0,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0x87,0xFF,0xFF,0xFF,0xFF,0xFC,0x3F,0xFF,0xFF,0xFF,0xFF,0xE1,0xFF,0xFF,0xFF,0xFF,0xFF,0x0F,0xFF,0xFF,0xFF,0xFF,0xF8,0x7F,0xFF,0xFF,0xFF,0xFF,0xC3,0xFF,0xFF,0xFF,0xFF,0xFE,0x00,0x1F,0xE0,0x7F,0x80,0x00,0x00,0xFF,0x03,0xFC,0x00,0x00,0x07,0xF8,0x1F,0xE0,0x00,0x00,0x3F,0xC0,0xFF,0x00,0x00,0x01,0xFE,0x07,0xF8,0x00,0x00,0x0F,0xE0,0x3F,0x80,0x00,0x00,0xFF,0x03,0xFC,0x00,0x00,0x07,0xF8,0x1F,0xE0,0x00,0x00,0x3F,0xC0,0xFF,0x00,0x00,0x01,0xFE,0x07,0xF8,0x00,0x3F,0xFF,0xFF,0xFF,0xFF,0xE1,0xFF,0xFF,0xFF,0xFF,0xFF,0x0F,0xFF,0xFF,0xFF,0xFF,0xF8,0x7F,0xFF,0xFF,0xFF,0xFF,0xC3,0xFF,0xFF,0xFF,0xFF,0xFE,0x1F,0xFF,0xFF,0xFF,0xFF,0xF0,0xFF,0xFF,0xFF,0xFF,0xFF,0x80,0x03,0xF8,0x0F,0xE0,0x00,0x00,0x3F,0xC0,0xFF,0x00,0x00,0x01,0xFE,0x07,0xF8,0x00,0x00,0x0F,0xF0,0x3F,0xC0,0x00,0x00,0x7F,0x81,0xFE,0x00,0x00,0x03,0xFC,0x0F,0xF0,0x00,0x00,0x1F,0xC0,0x7F,0x00,0x00,0x01,0xFE,0x07,0xF8,0x00,0x00,0x0F,0xF0,0x3F,0xC0,0x00,0x00,0x7F,0x81,0xFE,0x00,0x00,0x03,0xFC,0x0F,0xF0,0x00,0x00,0x1F,0xE0,0x7F,0x80,0x00,0x00,0xFE,0x03,0xF8,0x00,0x00,0x0F,0xF0,0x3F,0xC0,0x00,0x00,0x7F,0x81,0xFE,0x00,0x00,0x03,0xFC,0x0F,0xF0,0x00,0x00, // '#'
|
||||
0x00,0x00,0x3F,0x80,0x00,0x00,0x00,0x1F,0xC0,0x00,0x00,0x00,0x0F,0xE0,0x00,0x00,0x00,0x07,0xF0,0x00,0x00,0x00,0x03,0xF8,0x00,0x00,0x00,0x01,0xFC,0x00,0x00,0x00,0x00,0xFE,0x00,0x00,0x00,0x00,0x7F,0x00,0x00,0x00,0x01,0xFF,0xC0,0x00,0x00,0x07,0xFF,0xFE,0x00,0x00,0x0F,0xFF,0xFF,0xC0,0x00,0x1F,0xFF,0xFF,0xF0,0x00,0x1F,0xFF,0xFF,0xFC,0x00,0x1F,0xFF,0xFF,0xFF,0x00,0x1F,0xFF,0xFF,0xFF,0xC0,0x0F,0xFF,0xFF,0xFF,0xF0,0x0F,0xFF,0xFF,0xFF,0xFC,0x0F,0xFF,0xFF,0xFF,0xFE,0x07,0xFF,0xF0,0x7F,0xFF,0x03,0xFF,0xF0,0x0F,0xFF,0xC3,0xFF,0xF0,0x07,0xFF,0xE1,0xFF,0xF8,0x01,0xFF,0xF0,0xFF,0xFC,0x00,0xFF,0xFC,0x7F,0xFC,0x00,0x3F,0xFE,0x3F,0xFE,0x00,0x1F,0xFF,0x1F,0xFF,0x00,0x0F,0xFF,0x8F,0xFF,0xC0,0x07,0xFF,0xC7,0xFF,0xE0,0x00,0x00,0x01,0xFF,0xF0,0x00,0x00,0x00,0xFF,0xFC,0x00,0x00,0x00,0x7F,0xFF,0x00,0x00,0x00,0x1F,0xFF,0xE0,0x00,0x00,0x0F,0xFF,0xFC,0x00,0x00,0x03,0xFF,0xFF,0x80,0x00,0x00,0xFF,0xFF,0xF0,0x00,0x00,0x3F,0xFF,0xFE,0x00,0x00,0x0F,0xFF,0xFF,0xC0,0x00,0x03,0xFF,0xFF,0xF8,0x00,0x00,0x7F,0xFF,0xFE,0x00,0x00,0x1F,0xFF,0xFF,0x80,0x00,0x03,0xFF,0xFF,0xE0,0x00,0x00,0x3F,0xFF,0xF8,0x00,0x00,0x07,0xFF,0xFE,0x00,0x00,0x00,0xFF,0xFF,0x80,0x00,0x00,0x1F,0xFF,0xC0,0x00,0x00,0x07,0xFF,0xF0,0x00,0x00,0x01,0xFF,0xF8,0x00,0x00,0x00,0x7F,0xFC,0xFF,0xF8,0x00,0x3F,0xFE,0x7F,0xFC,0x00,0x1F,0xFF,0xBF,0xFE,0x00,0x0F,0xFF,0xDF,0xFF,0x80,0x07,0xFF,0xEF,0xFF,0xC0,0x03,0xFF,0xF3,0xFF,0xE0,0x01,0xFF,0xF9,0xFF,0xF8,0x00,0xFF,0xF8,0xFF,0xFE,0x00,0xFF,0xFC,0x3F,0xFF,0xC1,0xFF,0xFE,0x1F,0xFF,0xFF,0xFF,0xFF,0x07,0xFF,0xFF,0xFF,0xFF,0x03,0xFF,0xFF,0xFF,0xFF,0x80,0xFF,0xFF,0xFF,0xFF,0x80,0x3F,0xFF,0xFF,0xFF,0x80,0x0F,0xFF,0xFF,0xFF,0x80,0x03,0xFF,0xFF,0xFF,0x80,0x00,0x7F,0xFF,0xFF,0x00,0x00,0x0F,0xFF,0xFE,0x00,0x00,0x00,0x7F,0xF8,0x00,0x00,0x00,0x07,0xE0,0x00,0x00,0x00,0x03,0xF0,0x00,0x00,0x00,0x01,0xF8,0x00,0x00,0x00,0x00,0xFC,0x00,0x00,0x00,0x00,0x7E,0x00,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00,0x1F,0x80,0x00,0x00,0x00,0x0F,0xC0,0x00,0x00, // '$'
|
||||
0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x3F,0xFF,0x00,0x00,0x00,0x00,0x03,0xFF,0xFE,0x00,0x00,0x00,0x00,0x3F,0xFF,0xF8,0x00,0x00,0x00,0x03,0xFF,0xFF,0xE0,0x00,0x00,0x00,0x3F,0xFF,0xFF,0x00,0x00,0x00,0x01,0xFF,0xFF,0xFC,0x00,0x20,0x00,0x1F,0xF8,0x7F,0xE0,0x03,0xC0,0x00,0xFF,0x81,0xFF,0x00,0x1F,0x80,0x07,0xF8,0x07,0xFC,0x01,0xFF,0x00,0x3F,0xC0,0x3F,0xE0,0x0F,0xF0,0x01,0xFE,0x01,0xFF,0x00,0xFF,0x00,0x0F,0xF0,0x0F,0xF8,0x0F,0xF0,0x00,0x7F,0x80,0x7F,0xC0,0x7F,0x80,0x03,0xFC,0x03,0xFE,0x07,0xF8,0x00,0x1F,0xE0,0x1F,0xF0,0x7F,0xC0,0x00,0xFF,0x00,0xFF,0x83,0xFC,0x00,0x07,0xFC,0x0F,0xFC,0x3F,0xC0,0x00,0x3F,0xF0,0xFF,0xC1,0xFE,0x00,0x00,0xFF,0xFF,0xFE,0x1F,0xE0,0x00,0x07,0xFF,0xFF,0xE1,0xFF,0x00,0x00,0x1F,0xFF,0xFF,0x0F,0xF0,0x00,0x00,0x7F,0xFF,0xF0,0xFF,0x00,0x00,0x01,0xFF,0xFF,0x07,0xF8,0x00,0x00,0x07,0xFF,0xE0,0x7F,0x80,0x00,0x00,0x07,0xFC,0x07,0xF8,0x00,0x00,0x00,0x00,0x00,0x3F,0xC0,0x00,0x00,0x00,0x00,0x03,0xFC,0x00,0x00,0x00,0x00,0x00,0x3F,0xE0,0x00,0x00,0x00,0x00,0x01,0xFE,0x00,0x00,0x00,0x00,0x00,0x1F,0xE0,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x0F,0xF0,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0xFF,0x00,0x00,0x00,0x07,0xF8,0x3F,0xFF,0x00,0x00,0x00,0x7F,0x83,0xFF,0xFE,0x00,0x00,0x03,0xFC,0x3F,0xFF,0xF8,0x00,0x00,0x3F,0xC3,0xFF,0xFF,0xE0,0x00,0x03,0xFC,0x3F,0xFF,0xFF,0x00,0x00,0x1F,0xE1,0xFF,0xFF,0xFC,0x00,0x01,0xFE,0x1F,0xF8,0x7F,0xE0,0x00,0x1F,0xF0,0xFF,0x81,0xFF,0x80,0x00,0xFF,0x07,0xF8,0x07,0xFC,0x00,0x0F,0xF0,0x3F,0xC0,0x3F,0xE0,0x00,0x7F,0x81,0xFE,0x01,0xFF,0x00,0x07,0xF8,0x0F,0xF0,0x0F,0xF8,0x00,0x7F,0x80,0x7F,0x80,0x7F,0xC0,0x03,0xFC,0x03,0xFC,0x03,0xFE,0x00,0x3F,0xC0,0x1F,0xE0,0x1F,0xF0,0x03,0xFE,0x00,0xFF,0x00,0xFF,0x80,0x1F,0xE0,0x07,0xFC,0x07,0xFC,0x00,0x7E,0x00,0x3F,0xF0,0x7F,0xC0,0x00,0xF0,0x00,0xFF,0xFF,0xFE,0x00,0x01,0x00,0x07,0xFF,0xFF,0xE0,0x00,0x00,0x00,0x1F,0xFF,0xFF,0x00,0x00,0x00,0x00,0x7F,0xFF,0xF0,0x00,0x00,0x00,0x01,0xFF,0xFF,0x00,0x00,0x00,0x00,0x07,0xFF,0xE0,0x00,0x00,0x00,0x00,0x07,0xFC,0x00, // '%'
|
||||
0x00,0x00,0x7F,0xC0,0x00,0x00,0x00,0x00,0x3F,0xFF,0x00,0x00,0x00,0x00,0x0F,0xFF,0xFC,0x00,0x00,0x00,0x01,0xFF,0xFF,0xE0,0x00,0x00,0x00,0x7F,0xFF,0xFF,0x00,0x00,0x00,0x07,0xFF,0xFF,0xF8,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xC0,0x00,0x00,0x1F,0xFF,0xFF,0xFE,0x00,0x00,0x01,0xFF,0xFF,0xFF,0xE0,0x00,0x00,0x3F,0xFF,0xFF,0xFF,0x00,0x00,0x03,0xFF,0xE1,0xFF,0xF0,0x00,0x00,0x3F,0xFC,0x0F,0xFF,0x00,0x00,0x07,0xFF,0x80,0x7F,0xF0,0x00,0x00,0x7F,0xF8,0x07,0xFF,0x00,0x00,0x07,0xFF,0x80,0x3F,0xF0,0x00,0x00,0x7F,0xF8,0x03,0xFF,0x00,0x00,0x07,0xFF,0x80,0x7F,0xF0,0x00,0x00,0x7F,0xF8,0x07,0xFF,0x00,0x00,0x03,0xFF,0x80,0xFF,0xE0,0x00,0x00,0x3F,0xFC,0x1F,0xFE,0x00,0x00,0x03,0xFF,0xC3,0xFF,0xC0,0x00,0x00,0x3F,0xFE,0xFF,0xFC,0x00,0x00,0x01,0xFF,0xFF,0xFF,0x80,0x00,0x00,0x1F,0xFF,0xFF,0xF0,0x00,0x00,0x00,0xFF,0xFF,0xFE,0x00,0x00,0x00,0x07,0xFF,0xFF,0xC0,0x00,0x00,0x00,0x7F,0xFF,0xF8,0x00,0x00,0x00,0x03,0xFF,0xFE,0x00,0x00,0x00,0x00,0x7F,0xFF,0xC0,0x00,0x00,0x00,0x0F,0xFF,0xFC,0x00,0xFF,0xE0,0x01,0xFF,0xFF,0xE0,0x0F,0xFE,0x00,0x3F,0xFF,0xFF,0x00,0xFF,0xE0,0x07,0xFF,0xFF,0xF0,0x0F,0xFE,0x00,0xFF,0xFF,0xFF,0x80,0xFF,0xE0,0x1F,0xFF,0xFF,0xFC,0x0F,0xFE,0x03,0xFF,0xFF,0xFF,0xE1,0xFF,0xE0,0x3F,0xFE,0x7F,0xFF,0x1F,0xFE,0x07,0xFF,0xC3,0xFF,0xF9,0xFF,0xC0,0x7F,0xFC,0x1F,0xFF,0xFF,0xFC,0x07,0xFF,0xC1,0xFF,0xFF,0xFF,0xC0,0xFF,0xF8,0x0F,0xFF,0xFF,0xFC,0x0F,0xFF,0x80,0x7F,0xFF,0xFF,0x80,0xFF,0xF8,0x03,0xFF,0xFF,0xF8,0x0F,0xFF,0xC0,0x1F,0xFF,0xFF,0x80,0xFF,0xFC,0x00,0xFF,0xFF,0xF0,0x0F,0xFF,0xC0,0x07,0xFF,0xFF,0x00,0x7F,0xFE,0x00,0x7F,0xFF,0xE0,0x07,0xFF,0xF0,0x03,0xFF,0xFC,0x00,0x7F,0xFF,0x81,0xFF,0xFF,0xC0,0x03,0xFF,0xFF,0xFF,0xFF,0xFE,0x00,0x3F,0xFF,0xFF,0xFF,0xFF,0xF0,0x01,0xFF,0xFF,0xFF,0xFF,0xFF,0x80,0x1F,0xFF,0xFF,0xFF,0xFF,0xFC,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xE0,0x07,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x3F,0xFF,0xFF,0xFB,0xFF,0xF0,0x00,0xFF,0xFF,0xFE,0x3F,0xFF,0x80,0x03,0xFF,0xFF,0x01,0xFF,0xFC,0x00,0x03,0xFF,0x80,0x00,0x00,0x20, // '&'
|
||||
0xFF,0xDF,0xFB,0xFF,0x7F,0xEF,0xFD,0xFF,0xBF,0xF7,0xFE,0xFF,0xDF,0xFB,0xFE,0x7F,0xCF,0xF9,0xFF,0x3F,0xE7,0xFC,0xFF,0x9F,0xF3,0xFE,0x7F,0xCF,0xF9,0xFF,0x00, // '''
|
||||
0x00,0x00,0x20,0x00,0x01,0xE0,0x00,0x07,0xC0,0x00,0x3F,0x80,0x00,0xFF,0x80,0x03,0xFF,0x00,0x0F,0xFF,0x00,0x1F,0xF8,0x00,0x7F,0xE0,0x01,0xFF,0x80,0x07,0xFF,0x00,0x0F,0xFC,0x00,0x3F,0xF0,0x00,0x7F,0xE0,0x01,0xFF,0x80,0x03,0xFF,0x00,0x0F,0xFC,0x00,0x1F,0xF8,0x00,0x7F,0xE0,0x00,0xFF,0xC0,0x01,0xFF,0x80,0x07,0xFE,0x00,0x0F,0xFC,0x00,0x1F,0xF8,0x00,0x7F,0xF0,0x00,0xFF,0xC0,0x01,0xFF,0x80,0x03,0xFF,0x00,0x07,0xFE,0x00,0x1F,0xFC,0x00,0x3F,0xF8,0x00,0x7F,0xE0,0x00,0xFF,0xC0,0x01,0xFF,0x80,0x03,0xFF,0x00,0x07,0xFE,0x00,0x0F,0xFC,0x00,0x1F,0xF8,0x00,0x3F,0xF0,0x00,0x7F,0xE0,0x00,0xFF,0xC0,0x01,0xFF,0x80,0x03,0xFF,0x00,0x07,0xFE,0x00,0x0F,0xFC,0x00,0x1F,0xF8,0x00,0x3F,0xF0,0x00,0x7F,0xE0,0x00,0xFF,0xC0,0x01,0xFF,0x80,0x03,0xFF,0x80,0x07,0xFF,0x00,0x07,0xFE,0x00,0x0F,0xFC,0x00,0x1F,0xF8,0x00,0x3F,0xF0,0x00,0x7F,0xF0,0x00,0x7F,0xE0,0x00,0xFF,0xC0,0x01,0xFF,0x80,0x01,0xFF,0x80,0x03,0xFF,0x00,0x07,0xFE,0x00,0x07,0xFE,0x00,0x0F,0xFC,0x00,0x0F,0xFC,0x00,0x1F,0xF8,0x00,0x1F,0xF8,0x00,0x3F,0xF0,0x00,0x3F,0xF0,0x00,0x7F,0xF0,0x00,0x7F,0xE0,0x00,0x7F,0xE0,0x00,0x7F,0xE0,0x00,0xFF,0xF0,0x00,0xFF,0xC0,0x00,0xFF,0x80,0x00,0xFE,0x00,0x00,0x7C,0x00,0x00,0x78,0x00,0x00,0x20, // '('
|
||||
0x10,0x00,0x00,0x3C,0x00,0x00,0x3E,0x00,0x00,0x3F,0x80,0x00,0x7F,0xC0,0x00,0x7F,0xE0,0x00,0xFF,0xF0,0x00,0x3F,0xF8,0x00,0x1F,0xFC,0x00,0x0F,0xFC,0x00,0x0F,0xFE,0x00,0x07,0xFF,0x00,0x03,0xFF,0x00,0x03,0xFF,0x80,0x01,0xFF,0x80,0x01,0xFF,0xC0,0x00,0xFF,0xC0,0x00,0xFF,0xE0,0x00,0x7F,0xE0,0x00,0x7F,0xF0,0x00,0x7F,0xF0,0x00,0x3F,0xF0,0x00,0x3F,0xF8,0x00,0x3F,0xF8,0x00,0x3F,0xF8,0x00,0x1F,0xFC,0x00,0x1F,0xFC,0x00,0x1F,0xFC,0x00,0x1F,0xFC,0x00,0x1F,0xFC,0x00,0x1F,0xFE,0x00,0x0F,0xFE,0x00,0x0F,0xFE,0x00,0x0F,0xFE,0x00,0x0F,0xFE,0x00,0x0F,0xFE,0x00,0x0F,0xFE,0x00,0x0F,0xFE,0x00,0x0F,0xFE,0x00,0x0F,0xFE,0x00,0x0F,0xFE,0x00,0x0F,0xFE,0x00,0x0F,0xFE,0x00,0x0F,0xFE,0x00,0x0F,0xFE,0x00,0x0F,0xFE,0x00,0x0F,0xFE,0x00,0x0F,0xFE,0x00,0x0F,0xFE,0x00,0x0F,0xFE,0x00,0x1F,0xFE,0x00,0x1F,0xFC,0x00,0x1F,0xFC,0x00,0x1F,0xFC,0x00,0x1F,0xFC,0x00,0x1F,0xFC,0x00,0x3F,0xF8,0x00,0x3F,0xF8,0x00,0x3F,0xF8,0x00,0x3F,0xF0,0x00,0x7F,0xF0,0x00,0x7F,0xF0,0x00,0x7F,0xE0,0x00,0xFF,0xE0,0x00,0xFF,0xC0,0x01,0xFF,0xC0,0x01,0xFF,0x80,0x03,0xFF,0x80,0x03,0xFF,0x00,0x07,0xFF,0x00,0x0F,0xFE,0x00,0x0F,0xFC,0x00,0x1F,0xFC,0x00,0x3F,0xF8,0x00,0xFF,0xF0,0x00,0x7F,0xE0,0x00,0x7F,0xC0,0x00,0x3F,0x80,0x00,0x3F,0x00,0x00,0x3C,0x00,0x00,0x10,0x00,0x00, // ')'
|
||||
0x00,0x03,0xFC,0x00,0x00,0x00,0x1F,0xE0,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x07,0xF8,0x00,0x00,0x00,0x3F,0xC0,0x00,0x00,0x01,0xFE,0x00,0x00,0x00,0x07,0xF0,0x00,0x00,0x00,0x3F,0x80,0x00,0x00,0x01,0xFC,0x00,0x01,0xC0,0x0F,0xE0,0x06,0x0F,0x80,0x7F,0x01,0xF0,0x7F,0x83,0xF8,0x3F,0x87,0xFF,0x1F,0x8F,0xFE,0x3F,0xFE,0xFD,0xFF,0xF1,0xFF,0xFF,0xFF,0xFF,0x9F,0xFF,0xFF,0xFF,0xFE,0x3F,0xFF,0xFF,0xFF,0xC0,0x1F,0xFF,0xFF,0xF0,0x00,0x1F,0xFF,0xF8,0x00,0x00,0x0F,0xFC,0x00,0x00,0x00,0xFF,0xF0,0x00,0x00,0x0F,0xFF,0xC0,0x00,0x00,0xFF,0xFF,0x00,0x00,0x0F,0xF7,0xF8,0x00,0x00,0xFF,0x9F,0xE0,0x00,0x0F,0xF8,0xFF,0x80,0x00,0x7F,0xC3,0xFE,0x00,0x07,0xFC,0x0F,0xF8,0x00,0x7F,0xC0,0x7F,0xE0,0x07,0xFE,0x01,0xFF,0x00,0x1F,0xE0,0x0F,0xFC,0x00,0x3E,0x00,0x3F,0x00,0x00,0xF0,0x00,0xF0,0x00,0x01,0x00,0x06,0x00,0x00, // '*'
|
||||
0x00,0x07,0xFF,0x80,0x00,0x00,0x07,0xFF,0x80,0x00,0x00,0x07,0xFF,0x80,0x00,0x00,0x07,0xFF,0x80,0x00,0x00,0x07,0xFF,0x80,0x00,0x00,0x07,0xFF,0x80,0x00,0x00,0x07,0xFF,0x80,0x00,0x00,0x07,0xFF,0x80,0x00,0x00,0x07,0xFF,0x80,0x00,0x00,0x07,0xFF,0x80,0x00,0x00,0x07,0xFF,0x80,0x00,0x00,0x07,0xFF,0x80,0x00,0x00,0x07,0xFF,0x80,0x00,0x00,0x07,0xFF,0x80,0x00,0x00,0x07,0xFF,0x80,0x00,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0xFE,0x00,0x07,0xFF,0x80,0x00,0x00,0x07,0xFF,0x80,0x00,0x00,0x07,0xFF,0x80,0x00,0x00,0x07,0xFF,0x80,0x00,0x00,0x07,0xFF,0x80,0x00,0x00,0x07,0xFF,0x80,0x00,0x00,0x07,0xFF,0x80,0x00,0x00,0x07,0xFF,0x80,0x00,0x00,0x07,0xFF,0x80,0x00,0x00,0x07,0xFF,0x80,0x00,0x00,0x07,0xFF,0x80,0x00,0x00,0x07,0xFF,0x80,0x00,0x00,0x07,0xFF,0x80,0x00,0x00,0x07,0xFF,0x80,0x00,0x00,0x07,0xFF,0x80,0x00, // '+'
|
||||
0x0F,0xFE,0x0F,0xFE,0x0F,0xFE,0x0F,0xFE,0x0F,0xFE,0x0F,0xFE,0x0F,0xFE,0x0F,0xFE,0x0F,0xFE,0x0F,0xFE,0x0F,0xFC,0x0F,0xFC,0x0F,0xFC,0x0F,0xFC,0x1F,0xFC,0x1F,0xF8,0x1F,0xF8,0x3F,0xF0,0x3F,0xF0,0x7F,0xE0,0x7F,0xE0,0xFF,0xC0,0x7F,0x80,0x1F,0x00,0x06,0x00, // ','
|
||||
0xFF,0xFF,0xFE,0xFF,0xFF,0xFE,0xFF,0xFF,0xFE,0xFF,0xFF,0xFE,0xFF,0xFF,0xFE,0xFF,0xFF,0xFE,0xFF,0xFF,0xFE,0xFF,0xFF,0xFE,0xFF,0xFF,0xFE,0xFF,0xFF,0xFE, // '-'
|
||||
0x0F,0xC0,0x7F,0xE1,0xFF,0xE7,0xFF,0xCF,0xFF,0xDF,0xFF,0xBF,0xFF,0x7F,0xFE,0xFF,0xFD,0xFF,0xF1,0xFF,0xE1,0xFF,0x80,0xFC,0x00, // '.'
|
||||
0x00,0x00,0x1F,0xF8,0x00,0x00,0x7F,0xC0,0x00,0x03,0xFF,0x00,0x00,0x0F,0xFC,0x00,0x00,0x3F,0xE0,0x00,0x00,0xFF,0x80,0x00,0x07,0xFE,0x00,0x00,0x1F,0xF0,0x00,0x00,0x7F,0xC0,0x00,0x03,0xFF,0x00,0x00,0x0F,0xF8,0x00,0x00,0x3F,0xE0,0x00,0x01,0xFF,0x80,0x00,0x07,0xFC,0x00,0x00,0x1F,0xF0,0x00,0x00,0xFF,0xC0,0x00,0x03,0xFE,0x00,0x00,0x0F,0xF8,0x00,0x00,0x7F,0xE0,0x00,0x01,0xFF,0x80,0x00,0x07,0xFC,0x00,0x00,0x1F,0xF0,0x00,0x00,0xFF,0xC0,0x00,0x03,0xFE,0x00,0x00,0x0F,0xF8,0x00,0x00,0x7F,0xE0,0x00,0x01,0xFF,0x00,0x00,0x07,0xFC,0x00,0x00,0x3F,0xF0,0x00,0x00,0xFF,0x80,0x00,0x03,0xFE,0x00,0x00,0x1F,0xF8,0x00,0x00,0x7F,0xC0,0x00,0x01,0xFF,0x00,0x00,0x0F,0xFC,0x00,0x00,0x3F,0xF0,0x00,0x00,0xFF,0x80,0x00,0x03,0xFE,0x00,0x00,0x1F,0xF8,0x00,0x00,0x7F,0xC0,0x00,0x01,0xFF,0x00,0x00,0x0F,0xFC,0x00,0x00,0x3F,0xE0,0x00,0x00,0xFF,0x80,0x00,0x07,0xFE,0x00,0x00,0x1F,0xF0,0x00,0x00,0x7F,0xC0,0x00,0x03,0xFF,0x00,0x00,0x0F,0xF8,0x00,0x00,0x3F,0xE0,0x00,0x01,0xFF,0x80,0x00,0x07,0xFE,0x00,0x00,0x1F,0xF0,0x00,0x00,0x7F,0xC0,0x00,0x03,0xFF,0x00,0x00,0x0F,0xF8,0x00,0x00,0x3F,0xE0,0x00,0x01,0xFF,0x80,0x00,0x07,0xFC,0x00,0x00,0x1F,0xF0,0x00,0x00,0xFF,0xC0,0x00,0x03,0xFE,0x00,0x00,0x00, // '/'
|
||||
0x00,0x01,0xFF,0x80,0x00,0x00,0x07,0xFF,0xF8,0x00,0x00,0x0F,0xFF,0xFF,0x00,0x00,0x1F,0xFF,0xFF,0xE0,0x00,0x1F,0xFF,0xFF,0xF8,0x00,0x1F,0xFF,0xFF,0xFE,0x00,0x1F,0xFF,0xFF,0xFF,0x80,0x1F,0xFF,0xFF,0xFF,0xC0,0x0F,0xFF,0xFF,0xFF,0xF0,0x0F,0xFF,0xFF,0xFF,0xFC,0x07,0xFF,0xE0,0xFF,0xFE,0x07,0xFF,0xE0,0x1F,0xFF,0x83,0xFF,0xE0,0x07,0xFF,0xC1,0xFF,0xF0,0x03,0xFF,0xE1,0xFF,0xF0,0x00,0xFF,0xF8,0xFF,0xF8,0x00,0x7F,0xFC,0x7F,0xFC,0x00,0x3F,0xFE,0x3F,0xFE,0x00,0x1F,0xFF,0x3F,0xFF,0x00,0x0F,0xFF,0x9F,0xFF,0x00,0x03,0xFF,0xEF,0xFF,0x80,0x01,0xFF,0xF7,0xFF,0xC0,0x00,0xFF,0xFB,0xFF,0xE0,0x00,0x7F,0xFD,0xFF,0xF0,0x00,0x3F,0xFE,0xFF,0xF8,0x00,0x1F,0xFF,0x7F,0xFC,0x00,0x0F,0xFF,0xBF,0xFE,0x00,0x07,0xFF,0xDF,0xFF,0x00,0x03,0xFF,0xEF,0xFF,0x80,0x01,0xFF,0xF7,0xFF,0xC0,0x00,0xFF,0xFB,0xFF,0xE0,0x00,0x7F,0xFD,0xFF,0xF0,0x00,0x3F,0xFE,0xFF,0xF8,0x00,0x1F,0xFF,0x7F,0xFC,0x00,0x0F,0xFF,0xBF,0xFE,0x00,0x07,0xFF,0xDF,0xFF,0x00,0x03,0xFF,0xEF,0xFF,0x80,0x01,0xFF,0xF7,0xFF,0xC0,0x00,0xFF,0xFB,0xFF,0xE0,0x00,0x7F,0xFD,0xFF,0xF0,0x00,0x7F,0xFE,0x7F,0xFC,0x00,0x3F,0xFE,0x3F,0xFE,0x00,0x1F,0xFF,0x1F,0xFF,0x00,0x0F,0xFF,0x8F,0xFF,0x80,0x07,0xFF,0xC7,0xFF,0xC0,0x03,0xFF,0xE1,0xFF,0xF0,0x03,0xFF,0xE0,0xFF,0xF8,0x01,0xFF,0xF0,0x7F,0xFE,0x01,0xFF,0xF8,0x1F,0xFF,0xC3,0xFF,0xF8,0x0F,0xFF,0xFF,0xFF,0xFC,0x03,0xFF,0xFF,0xFF,0xFC,0x01,0xFF,0xFF,0xFF,0xFE,0x00,0x7F,0xFF,0xFF,0xFE,0x00,0x1F,0xFF,0xFF,0xFE,0x00,0x07,0xFF,0xFF,0xFE,0x00,0x01,0xFF,0xFF,0xFE,0x00,0x00,0x3F,0xFF,0xFC,0x00,0x00,0x07,0xFF,0xF8,0x00,0x00,0x00,0x7F,0xE0,0x00,0x00, // '0'
|
||||
0x00,0x00,0x00,0xE0,0x00,0x00,0x7E,0x00,0x00,0x1F,0xE0,0x00,0x0F,0xFE,0x00,0x07,0xFF,0xE0,0x03,0xFF,0xFE,0x01,0xFF,0xFF,0xE0,0x7F,0xFF,0xFE,0x3F,0xFF,0xFF,0xEF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xEF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xEF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xEF,0xFF,0x7F,0xFE,0xFF,0x87,0xFF,0xEF,0xC0,0x7F,0xFE,0xC0,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,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,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,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, // '1'
|
||||
0x00,0x00,0xFF,0xC0,0x00,0x00,0x03,0xFF,0xFF,0x00,0x00,0x03,0xFF,0xFF,0xF0,0x00,0x03,0xFF,0xFF,0xFF,0x00,0x01,0xFF,0xFF,0xFF,0xE0,0x00,0xFF,0xFF,0xFF,0xFC,0x00,0x7F,0xFF,0xFF,0xFF,0x80,0x3F,0xFF,0xFF,0xFF,0xE0,0x1F,0xFF,0xFF,0xFF,0xFC,0x07,0xFF,0xFF,0xFF,0xFF,0x03,0xFF,0xFC,0x1F,0xFF,0xE0,0xFF,0xFC,0x03,0xFF,0xF8,0x7F,0xFE,0x00,0x7F,0xFE,0x1F,0xFF,0x80,0x0F,0xFF,0x87,0xFF,0xC0,0x03,0xFF,0xF3,0xFF,0xF0,0x00,0xFF,0xFC,0xFF,0xFC,0x00,0x3F,0xFF,0x3F,0xFE,0x00,0x0F,0xFF,0xCF,0xFF,0x80,0x03,0xFF,0xF0,0x00,0x00,0x00,0xFF,0xF8,0x00,0x00,0x00,0x3F,0xFE,0x00,0x00,0x00,0x1F,0xFF,0x80,0x00,0x00,0x07,0xFF,0xE0,0x00,0x00,0x03,0xFF,0xF0,0x00,0x00,0x00,0xFF,0xFC,0x00,0x00,0x00,0x7F,0xFE,0x00,0x00,0x00,0x3F,0xFF,0x80,0x00,0x00,0x0F,0xFF,0xC0,0x00,0x00,0x07,0xFF,0xE0,0x00,0x00,0x03,0xFF,0xF8,0x00,0x00,0x01,0xFF,0xFC,0x00,0x00,0x00,0xFF,0xFE,0x00,0x00,0x00,0x7F,0xFF,0x00,0x00,0x00,0x3F,0xFF,0xC0,0x00,0x00,0x1F,0xFF,0xE0,0x00,0x00,0x0F,0xFF,0xF0,0x00,0x00,0x03,0xFF,0xF8,0x00,0x00,0x01,0xFF,0xFC,0x00,0x00,0x00,0xFF,0xFE,0x00,0x00,0x00,0x7F,0xFF,0x00,0x00,0x00,0x3F,0xFF,0x80,0x00,0x00,0x1F,0xFF,0xC0,0x00,0x00,0x0F,0xFF,0xE0,0x00,0x00,0x07,0xFF,0xF0,0x00,0x00,0x03,0xFF,0xFC,0x00,0x00,0x01,0xFF,0xFE,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0x7F,0xFF,0x80,0x00,0x00,0x3F,0xFF,0xFF,0xFF,0xFF,0x9F,0xFF,0xFF,0xFF,0xFF,0xE7,0xFF,0xFF,0xFF,0xFF,0xF9,0xFF,0xFF,0xFF,0xFF,0xFE,0x7F,0xFF,0xFF,0xFF,0xFF,0x9F,0xFF,0xFF,0xFF,0xFF,0xE7,0xFF,0xFF,0xFF,0xFF,0xF9,0xFF,0xFF,0xFF,0xFF,0xFE,0x7F,0xFF,0xFF,0xFF,0xFF,0x9F,0xFF,0xFF,0xFF,0xFF,0xE0, // '2'
|
||||
0x00,0x01,0xFF,0xC0,0x00,0x00,0x07,0xFF,0xFE,0x00,0x00,0x07,0xFF,0xFF,0xF0,0x00,0x07,0xFF,0xFF,0xFF,0x00,0x03,0xFF,0xFF,0xFF,0xE0,0x01,0xFF,0xFF,0xFF,0xFC,0x00,0xFF,0xFF,0xFF,0xFF,0x80,0x7F,0xFF,0xFF,0xFF,0xF0,0x3F,0xFF,0xFF,0xFF,0xFC,0x0F,0xFF,0xFF,0xFF,0xFF,0x87,0xFF,0xF8,0x1F,0xFF,0xE1,0xFF,0xFC,0x01,0xFF,0xFC,0x7F,0xFE,0x00,0x3F,0xFF,0x1F,0xFF,0x00,0x0F,0xFF,0xC7,0xFF,0xC0,0x01,0xFF,0xF0,0x00,0x00,0x00,0x7F,0xFC,0x00,0x00,0x00,0x1F,0xFF,0x00,0x00,0x00,0x07,0xFF,0xC0,0x00,0x00,0x01,0xFF,0xF0,0x00,0x00,0x00,0xFF,0xFC,0x00,0x00,0x00,0x3F,0xFE,0x00,0x00,0x00,0x1F,0xFF,0x80,0x00,0x00,0x1F,0xFF,0xC0,0x00,0x1F,0xFF,0xFF,0xE0,0x00,0x07,0xFF,0xFF,0xF0,0x00,0x01,0xFF,0xFF,0xF8,0x00,0x00,0x7F,0xFF,0xFC,0x00,0x00,0x1F,0xFF,0xFC,0x00,0x00,0x07,0xFF,0xFF,0x80,0x00,0x01,0xFF,0xFF,0xF8,0x00,0x00,0x7F,0xFF,0xFF,0x00,0x00,0x1F,0xFF,0xFF,0xE0,0x00,0x07,0xFF,0xFF,0xFC,0x00,0x00,0x00,0x7F,0xFF,0x80,0x00,0x00,0x07,0xFF,0xE0,0x00,0x00,0x00,0xFF,0xFC,0x00,0x00,0x00,0x1F,0xFF,0x00,0x00,0x00,0x07,0xFF,0xC0,0x00,0x00,0x00,0xFF,0xF8,0x00,0x00,0x00,0x3F,0xFE,0x00,0x00,0x00,0x0F,0xFF,0x80,0x00,0x00,0x03,0xFF,0xEF,0xFF,0x80,0x00,0xFF,0xFB,0xFF,0xE0,0x00,0x3F,0xFE,0xFF,0xF8,0x00,0x1F,0xFF,0xBF,0xFF,0x00,0x07,0xFF,0xEF,0xFF,0xE0,0x03,0xFF,0xF1,0xFF,0xFC,0x01,0xFF,0xFC,0x7F,0xFF,0x81,0xFF,0xFF,0x1F,0xFF,0xFF,0xFF,0xFF,0x83,0xFF,0xFF,0xFF,0xFF,0xE0,0x7F,0xFF,0xFF,0xFF,0xF0,0x1F,0xFF,0xFF,0xFF,0xF8,0x03,0xFF,0xFF,0xFF,0xFC,0x00,0x7F,0xFF,0xFF,0xFE,0x00,0x07,0xFF,0xFF,0xFE,0x00,0x00,0x7F,0xFF,0xFF,0x00,0x00,0x07,0xFF,0xFE,0x00,0x00,0x00,0x1F,0xF8,0x00,0x00, // '3'
|
||||
0x00,0x00,0x01,0xFF,0xF0,0x00,0x00,0x00,0x7F,0xFE,0x00,0x00,0x00,0x1F,0xFF,0xC0,0x00,0x00,0x03,0xFF,0xF8,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0x1F,0xFF,0xE0,0x00,0x00,0x07,0xFF,0xFC,0x00,0x00,0x01,0xFF,0xFF,0x80,0x00,0x00,0x3F,0xFF,0xF0,0x00,0x00,0x0F,0xFF,0xFE,0x00,0x00,0x01,0xFF,0xFF,0xC0,0x00,0x00,0x7F,0xFF,0xF8,0x00,0x00,0x1F,0xFF,0xFF,0x00,0x00,0x03,0xFF,0xFF,0xE0,0x00,0x00,0xFF,0xFF,0xFC,0x00,0x00,0x3F,0xFF,0xFF,0x80,0x00,0x07,0xFF,0xFF,0xF0,0x00,0x01,0xFF,0xFF,0xFE,0x00,0x00,0x3F,0xF7,0xFF,0xC0,0x00,0x0F,0xFE,0xFF,0xF8,0x00,0x03,0xFF,0x9F,0xFF,0x00,0x00,0x7F,0xE3,0xFF,0xE0,0x00,0x1F,0xFC,0x7F,0xFC,0x00,0x03,0xFF,0x0F,0xFF,0x80,0x00,0xFF,0xE1,0xFF,0xF0,0x00,0x3F,0xF8,0x3F,0xFE,0x00,0x07,0xFF,0x07,0xFF,0xC0,0x01,0xFF,0xC0,0xFF,0xF8,0x00,0x7F,0xF0,0x1F,0xFF,0x00,0x0F,0xFE,0x03,0xFF,0xE0,0x03,0xFF,0x80,0x7F,0xFC,0x00,0x7F,0xF0,0x0F,0xFF,0x80,0x1F,0xFC,0x01,0xFF,0xF0,0x07,0xFF,0x80,0x3F,0xFE,0x00,0xFF,0xE0,0x07,0xFF,0xC0,0x3F,0xFF,0xFF,0xFF,0xFF,0xE7,0xFF,0xFF,0xFF,0xFF,0xFD,0xFF,0xFF,0xFF,0xFF,0xFF,0xBF,0xFF,0xFF,0xFF,0xFF,0xF7,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xCF,0xFF,0xFF,0xFF,0xFF,0xF9,0xFF,0xFF,0xFF,0xFF,0xFF,0x3F,0xFF,0xFF,0xFF,0xFF,0xE7,0xFF,0xFF,0xFF,0xFF,0xFC,0x00,0x00,0x03,0xFF,0xE0,0x00,0x00,0x00,0x7F,0xFC,0x00,0x00,0x00,0x0F,0xFF,0x80,0x00,0x00,0x01,0xFF,0xF0,0x00,0x00,0x00,0x3F,0xFE,0x00,0x00,0x00,0x07,0xFF,0xC0,0x00,0x00,0x00,0xFF,0xF8,0x00,0x00,0x00,0x1F,0xFF,0x00,0x00,0x00,0x03,0xFF,0xE0,0x00,0x00,0x00,0x7F,0xFC,0x00,0x00,0x00,0x0F,0xFF,0x80,0x00,0x00,0x01,0xFF,0xF0,0x00, // '4'
|
||||
0x0F,0xFF,0xFF,0xFF,0xFC,0x07,0xFF,0xFF,0xFF,0xFE,0x03,0xFF,0xFF,0xFF,0xFF,0x01,0xFF,0xFF,0xFF,0xFF,0x80,0xFF,0xFF,0xFF,0xFF,0xC0,0x7F,0xFF,0xFF,0xFF,0xE0,0x3F,0xFF,0xFF,0xFF,0xF0,0x1F,0xFF,0xFF,0xFF,0xF8,0x0F,0xFF,0xFF,0xFF,0xFC,0x0F,0xFF,0xFF,0xFF,0xFE,0x07,0xFF,0x80,0x00,0x00,0x03,0xFF,0xC0,0x00,0x00,0x01,0xFF,0xE0,0x00,0x00,0x00,0xFF,0xF0,0x00,0x00,0x00,0x7F,0xF8,0x00,0x00,0x00,0x3F,0xFC,0x00,0x00,0x00,0x1F,0xFE,0x00,0x00,0x00,0x1F,0xFE,0x00,0x00,0x00,0x0F,0xFF,0x00,0x00,0x00,0x07,0xFF,0x80,0x00,0x00,0x03,0xFF,0xC3,0xFE,0x00,0x01,0xFF,0xEF,0xFF,0xE0,0x00,0xFF,0xFF,0xFF,0xFC,0x00,0x7F,0xFF,0xFF,0xFF,0x80,0x3F,0xFF,0xFF,0xFF,0xE0,0x1F,0xFF,0xFF,0xFF,0xF8,0x1F,0xFF,0xFF,0xFF,0xFC,0x0F,0xFF,0xFF,0xFF,0xFF,0x07,0xFF,0xFF,0xFF,0xFF,0xC3,0xFF,0xF0,0x1F,0xFF,0xE0,0x1F,0xE0,0x03,0xFF,0xF0,0x00,0x60,0x00,0xFF,0xFC,0x00,0x00,0x00,0x7F,0xFE,0x00,0x00,0x00,0x1F,0xFF,0x00,0x00,0x00,0x0F,0xFF,0x80,0x00,0x00,0x07,0xFF,0xC0,0x00,0x00,0x03,0xFF,0xF0,0x00,0x00,0x00,0xFF,0xF8,0x00,0x00,0x00,0x7F,0xFC,0x00,0x00,0x00,0x7F,0xFE,0x00,0x00,0x00,0x3F,0xFF,0x7F,0xFC,0x00,0x1F,0xFF,0xBF,0xFE,0x00,0x0F,0xFF,0x9F,0xFF,0x80,0x07,0xFF,0xCF,0xFF,0xC0,0x07,0xFF,0xE3,0xFF,0xF0,0x03,0xFF,0xF1,0xFF,0xFC,0x03,0xFF,0xF0,0xFF,0xFF,0x07,0xFF,0xF8,0x3F,0xFF,0xFF,0xFF,0xF8,0x1F,0xFF,0xFF,0xFF,0xFC,0x07,0xFF,0xFF,0xFF,0xFC,0x01,0xFF,0xFF,0xFF,0xFE,0x00,0x7F,0xFF,0xFF,0xFE,0x00,0x1F,0xFF,0xFF,0xFE,0x00,0x03,0xFF,0xFF,0xFC,0x00,0x00,0xFF,0xFF,0xFC,0x00,0x00,0x0F,0xFF,0xF8,0x00,0x00,0x00,0xFF,0xC0,0x00,0x00, // '5'
|
||||
0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x03,0xFF,0xC0,0x00,0x00,0x03,0xFF,0xF0,0x00,0x00,0x03,0xFF,0xFC,0x00,0x00,0x03,0xFF,0xFF,0x00,0x00,0x03,0xFF,0xFF,0xC0,0x00,0x01,0xFF,0xFF,0xF0,0x00,0x00,0xFF,0xFF,0xFC,0x00,0x00,0x7F,0xFF,0xFF,0x00,0x00,0x3F,0xFF,0xFF,0xC0,0x00,0x1F,0xFF,0xFE,0x00,0x00,0x0F,0xFF,0xF8,0x00,0x00,0x07,0xFF,0xF8,0x00,0x00,0x01,0xFF,0xFC,0x00,0x00,0x00,0xFF,0xFE,0x00,0x00,0x00,0x3F,0xFF,0x00,0x00,0x00,0x1F,0xFF,0x80,0x00,0x00,0x07,0xFF,0xC0,0x00,0x00,0x03,0xFF,0xE0,0x00,0x00,0x00,0xFF,0xF8,0x00,0x00,0x00,0x3F,0xFE,0x07,0xF8,0x00,0x1F,0xFF,0x0F,0xFF,0xC0,0x07,0xFF,0xCF,0xFF,0xF8,0x01,0xFF,0xF7,0xFF,0xFF,0x80,0x7F,0xFF,0xFF,0xFF,0xF0,0x3F,0xFF,0xFF,0xFF,0xFE,0x0F,0xFF,0xFF,0xFF,0xFF,0x83,0xFF,0xFF,0xFF,0xFF,0xF0,0xFF,0xFF,0xFF,0xFF,0xFE,0x3F,0xFF,0xFF,0xFF,0xFF,0x8F,0xFF,0xF8,0x1F,0xFF,0xE3,0xFF,0xF8,0x01,0xFF,0xFC,0xFF,0xFC,0x00,0x3F,0xFF,0x3F,0xFF,0x00,0x0F,0xFF,0xCF,0xFF,0x80,0x01,0xFF,0xFB,0xFF,0xE0,0x00,0x7F,0xFE,0xFF,0xF8,0x00,0x1F,0xFF,0xBF,0xFE,0x00,0x03,0xFF,0xEF,0xFF,0x80,0x00,0xFF,0xFB,0xFF,0xE0,0x00,0x3F,0xFE,0xFF,0xF8,0x00,0x0F,0xFF,0x9F,0xFE,0x00,0x03,0xFF,0xE7,0xFF,0xC0,0x01,0xFF,0xF9,0xFF,0xF0,0x00,0x7F,0xFE,0x7F,0xFC,0x00,0x1F,0xFF,0x0F,0xFF,0x80,0x0F,0xFF,0xC3,0xFF,0xE0,0x03,0xFF,0xF0,0xFF,0xFC,0x01,0xFF,0xF8,0x1F,0xFF,0xC1,0xFF,0xFE,0x07,0xFF,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0xFF,0xC0,0x1F,0xFF,0xFF,0xFF,0xE0,0x03,0xFF,0xFF,0xFF,0xF0,0x00,0x7F,0xFF,0xFF,0xF8,0x00,0x0F,0xFF,0xFF,0xFC,0x00,0x01,0xFF,0xFF,0xFE,0x00,0x00,0x1F,0xFF,0xFE,0x00,0x00,0x01,0xFF,0xFE,0x00,0x00,0x00,0x0F,0xFC,0x00,0x00, // '6'
|
||||
0xFF,0xFF,0xFF,0xFF,0xFF,0xBF,0xFF,0xFF,0xFF,0xFF,0xEF,0xFF,0xFF,0xFF,0xFF,0xFB,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xBF,0xFF,0xFF,0xFF,0xFF,0xEF,0xFF,0xFF,0xFF,0xFF,0xFB,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0x3F,0xFF,0xFF,0xFF,0xFF,0xC0,0x00,0x00,0x01,0xFF,0xF0,0x00,0x00,0x00,0xFF,0xF8,0x00,0x00,0x00,0x3F,0xFE,0x00,0x00,0x00,0x0F,0xFF,0x00,0x00,0x00,0x07,0xFF,0xC0,0x00,0x00,0x01,0xFF,0xE0,0x00,0x00,0x00,0xFF,0xF8,0x00,0x00,0x00,0x3F,0xFE,0x00,0x00,0x00,0x1F,0xFF,0x00,0x00,0x00,0x07,0xFF,0xC0,0x00,0x00,0x03,0xFF,0xE0,0x00,0x00,0x00,0xFF,0xF8,0x00,0x00,0x00,0x7F,0xFC,0x00,0x00,0x00,0x1F,0xFF,0x00,0x00,0x00,0x07,0xFF,0xC0,0x00,0x00,0x03,0xFF,0xE0,0x00,0x00,0x00,0xFF,0xF8,0x00,0x00,0x00,0x7F,0xFC,0x00,0x00,0x00,0x1F,0xFF,0x00,0x00,0x00,0x0F,0xFF,0x80,0x00,0x00,0x03,0xFF,0xE0,0x00,0x00,0x01,0xFF,0xF8,0x00,0x00,0x00,0x7F,0xFC,0x00,0x00,0x00,0x3F,0xFF,0x00,0x00,0x00,0x0F,0xFF,0x80,0x00,0x00,0x03,0xFF,0xE0,0x00,0x00,0x01,0xFF,0xF0,0x00,0x00,0x00,0x7F,0xFC,0x00,0x00,0x00,0x3F,0xFF,0x00,0x00,0x00,0x0F,0xFF,0x80,0x00,0x00,0x07,0xFF,0xE0,0x00,0x00,0x01,0xFF,0xF0,0x00,0x00,0x00,0xFF,0xFC,0x00,0x00,0x00,0x3F,0xFF,0x00,0x00,0x00,0x1F,0xFF,0x80,0x00,0x00,0x07,0xFF,0xE0,0x00,0x00,0x01,0xFF,0xF0,0x00,0x00,0x00,0xFF,0xFC,0x00,0x00,0x00,0x3F,0xFE,0x00,0x00,0x00,0x1F,0xFF,0x80,0x00,0x00,0x07,0xFF,0xE0,0x00,0x00,0x03,0xFF,0xF0,0x00,0x00,0x00,0xFF,0xFC,0x00,0x00,0x00,0x7F,0xFE,0x00,0x00,0x00,0x1F,0xFF,0x80,0x00,0x00,0x07,0xFF,0xC0,0x00,0x00,0x03,0xFF,0xF0,0x00,0x00,0x00, // '7'
|
||||
0x00,0x01,0xFF,0x80,0x00,0x00,0x0F,0xFF,0xFC,0x00,0x00,0x1F,0xFF,0xFF,0x80,0x00,0x3F,0xFF,0xFF,0xF0,0x00,0x3F,0xFF,0xFF,0xFC,0x00,0x3F,0xFF,0xFF,0xFF,0x00,0x3F,0xFF,0xFF,0xFF,0xC0,0x3F,0xFF,0xFF,0xFF,0xE0,0x1F,0xFF,0xFF,0xFF,0xF8,0x1F,0xFF,0xFF,0xFF,0xFE,0x0F,0xFF,0xF0,0xFF,0xFF,0x07,0xFF,0xE0,0x1F,0xFF,0x83,0xFF,0xE0,0x07,0xFF,0xC3,0xFF,0xF0,0x03,0xFF,0xF1,0xFF,0xF8,0x01,0xFF,0xF8,0xFF,0xFC,0x00,0xFF,0xFC,0x7F,0xFE,0x00,0x7F,0xFE,0x3F,0xFF,0x00,0x3F,0xFF,0x0F,0xFF,0x80,0x1F,0xFF,0x07,0xFF,0xC0,0x0F,0xFF,0x83,0xFF,0xE0,0x07,0xFF,0xC0,0xFF,0xF8,0x07,0xFF,0xC0,0x7F,0xFF,0x07,0xFF,0xE0,0x1F,0xFF,0xFF,0xFF,0xE0,0x07,0xFF,0xFF,0xFF,0xE0,0x01,0xFF,0xFF,0xFF,0xE0,0x00,0x7F,0xFF,0xFF,0xE0,0x00,0x0F,0xFF,0xFF,0xE0,0x00,0x0F,0xFF,0xFF,0xF0,0x00,0x1F,0xFF,0xFF,0xFE,0x00,0x1F,0xFF,0xFF,0xFF,0x80,0x1F,0xFF,0xFF,0xFF,0xE0,0x1F,0xFF,0xFF,0xFF,0xF8,0x1F,0xFF,0xC0,0xFF,0xFC,0x0F,0xFF,0xC0,0x3F,0xFF,0x0F,0xFF,0xC0,0x0F,0xFF,0xC7,0xFF,0xC0,0x03,0xFF,0xE3,0xFF,0xE0,0x01,0xFF,0xF3,0xFF,0xF0,0x00,0xFF,0xF9,0xFF,0xF0,0x00,0x3F,0xFE,0xFF,0xF8,0x00,0x1F,0xFF,0x7F,0xFC,0x00,0x0F,0xFF,0xBF,0xFE,0x00,0x0F,0xFF,0xDF,0xFF,0x80,0x07,0xFF,0xEF,0xFF,0xC0,0x03,0xFF,0xF7,0xFF,0xE0,0x01,0xFF,0xF9,0xFF,0xF8,0x01,0xFF,0xF8,0xFF,0xFE,0x01,0xFF,0xFC,0x7F,0xFF,0x81,0xFF,0xFE,0x1F,0xFF,0xFF,0xFF,0xFE,0x0F,0xFF,0xFF,0xFF,0xFF,0x03,0xFF,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0xFF,0x00,0x7F,0xFF,0xFF,0xFF,0x80,0x0F,0xFF,0xFF,0xFF,0x00,0x03,0xFF,0xFF,0xFF,0x00,0x00,0x7F,0xFF,0xFF,0x00,0x00,0x0F,0xFF,0xFC,0x00,0x00,0x00,0xFF,0xF0,0x00,0x00, // '8'
|
||||
0x00,0x01,0xFF,0x00,0x00,0x00,0x07,0xFF,0xF0,0x00,0x00,0x0F,0xFF,0xFE,0x00,0x00,0x0F,0xFF,0xFF,0xC0,0x00,0x1F,0xFF,0xFF,0xF0,0x00,0x1F,0xFF,0xFF,0xFC,0x00,0x1F,0xFF,0xFF,0xFF,0x00,0x1F,0xFF,0xFF,0xFF,0xC0,0x0F,0xFF,0xFF,0xFF,0xF0,0x0F,0xFF,0xFF,0xFF,0xF8,0x0F,0xFF,0xF0,0xFF,0xFE,0x07,0xFF,0xE0,0x1F,0xFF,0x03,0xFF,0xF0,0x07,0xFF,0xC3,0xFF,0xF0,0x03,0xFF,0xE1,0xFF,0xF0,0x00,0xFF,0xF8,0xFF,0xF8,0x00,0x7F,0xFC,0xFF,0xFC,0x00,0x3F,0xFE,0x7F,0xFE,0x00,0x1F,0xFF,0x3F,0xFE,0x00,0x0F,0xFF,0x9F,0xFF,0x00,0x03,0xFF,0xEF,0xFF,0x80,0x01,0xFF,0xF7,0xFF,0xC0,0x00,0xFF,0xFB,0xFF,0xE0,0x00,0x7F,0xFD,0xFF,0xF8,0x00,0x3F,0xFE,0xFF,0xFC,0x00,0x1F,0xFF,0x7F,0xFE,0x00,0x0F,0xFF,0x9F,0xFF,0x80,0x0F,0xFF,0xCF,0xFF,0xC0,0x07,0xFF,0xE7,0xFF,0xF0,0x07,0xFF,0xF1,0xFF,0xFE,0x0F,0xFF,0xF8,0xFF,0xFF,0xFF,0xFF,0xFC,0x7F,0xFF,0xFF,0xFF,0xFE,0x1F,0xFF,0xFF,0xFF,0xFF,0x07,0xFF,0xFF,0xFF,0xFF,0x03,0xFF,0xFF,0xFF,0xFF,0x80,0xFF,0xFF,0xFF,0xFF,0xC0,0x3F,0xFF,0xFF,0xFF,0xE0,0x07,0xFF,0xFD,0xFF,0xF0,0x00,0xFF,0xF8,0xFF,0xF0,0x00,0x0F,0xF0,0x7F,0xF8,0x00,0x00,0x00,0x7F,0xFC,0x00,0x00,0x00,0x3F,0xFC,0x00,0x00,0x00,0x3F,0xFE,0x00,0x00,0x00,0x1F,0xFF,0x00,0x00,0x00,0x1F,0xFF,0x00,0x00,0x00,0x1F,0xFF,0x80,0x00,0x00,0x3F,0xFF,0x80,0x00,0x00,0x7F,0xFF,0x80,0x00,0x01,0xFF,0xFF,0xC0,0x00,0x3F,0xFF,0xFF,0xC0,0x00,0x1F,0xFF,0xFF,0xC0,0x00,0x0F,0xFF,0xFF,0xC0,0x00,0x07,0xFF,0xFF,0xC0,0x00,0x03,0xFF,0xFF,0x80,0x00,0x01,0xFF,0xFF,0x80,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0x7F,0xFE,0x00,0x00,0x00,0x3F,0xF8,0x00,0x00,0x00,0x1F,0xC0,0x00,0x00,0x00, // '9'
|
||||
0x0F,0xC0,0x7F,0xE1,0xFF,0xE7,0xFF,0xCF,0xFF,0xDF,0xFF,0xBF,0xFF,0x7F,0xFE,0xFF,0xFD,0xFF,0xF1,0xFF,0xE1,0xFF,0x80,0xFC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0xE0,0x3F,0xF0,0xFF,0xF3,0xFF,0xE7,0xFF,0xEF,0xFF,0xDF,0xFF,0xBF,0xFF,0x7F,0xFE,0xFF,0xF8,0xFF,0xF0,0xFF,0xC0,0x7E,0x00, // ':'
|
||||
0x03,0xF0,0x07,0xFE,0x07,0xFF,0x87,0xFF,0xC3,0xFF,0xF1,0xFF,0xF8,0xFF,0xFC,0x7F,0xFE,0x3F,0xFF,0x1F,0xFF,0x07,0xFF,0x81,0xFF,0x80,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0xFF,0x81,0xFF,0xC0,0xFF,0xE0,0x7F,0xF0,0x3F,0xF8,0x1F,0xFC,0x0F,0xFE,0x07,0xFF,0x03,0xFF,0x81,0xFF,0xC0,0xFF,0xC0,0x7F,0xE0,0x3F,0xF0,0x1F,0xF8,0x1F,0xFC,0x0F,0xFC,0x07,0xFE,0x07,0xFE,0x03,0xFF,0x03,0xFF,0x01,0xFF,0x81,0xFF,0x80,0x7F,0x80,0x0F,0x80,0x01,0x80,0x00, // ';'
|
||||
0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x1F,0xE0,0x00,0x00,0x1F,0xFC,0x00,0x00,0x0F,0xFF,0x80,0x00,0x07,0xFF,0xF0,0x00,0x07,0xFF,0xFE,0x00,0x03,0xFF,0xFF,0xC0,0x03,0xFF,0xFF,0xF8,0x01,0xFF,0xFF,0xFF,0x01,0xFF,0xFF,0xFF,0xE0,0xFF,0xFF,0xFF,0xF8,0x7F,0xFF,0xFF,0xF8,0x3F,0xFF,0xFF,0xFC,0x07,0xFF,0xFF,0xFC,0x00,0xFF,0xFF,0xFC,0x00,0x1F,0xFF,0xFC,0x00,0x03,0xFF,0xFC,0x00,0x00,0x7F,0xFC,0x00,0x00,0x0F,0xFF,0xF0,0x00,0x01,0xFF,0xFF,0xC0,0x00,0x3F,0xFF,0xFF,0x00,0x07,0xFF,0xFF,0xF8,0x00,0xFF,0xFF,0xFF,0xE0,0x07,0xFF,0xFF,0xFF,0x80,0x3F,0xFF,0xFF,0xFE,0x01,0xFF,0xFF,0xFF,0xE0,0x07,0xFF,0xFF,0xFC,0x00,0x3F,0xFF,0xFF,0x80,0x00,0xFF,0xFF,0xF0,0x00,0x07,0xFF,0xFE,0x00,0x00,0x1F,0xFF,0xC0,0x00,0x00,0xFF,0xF8,0x00,0x00,0x07,0xFF,0x00,0x00,0x00,0x1F,0xE0,0x00,0x00,0x00,0xFC,0x00,0x00,0x00,0x03,0x80,0x00,0x00,0x00,0x10, // '<'
|
||||
0xFF,0xFF,0xFF,0xFF,0xF7,0xFF,0xFF,0xFF,0xFF,0xBF,0xFF,0xFF,0xFF,0xFD,0xFF,0xFF,0xFF,0xFF,0xEF,0xFF,0xFF,0xFF,0xFF,0x7F,0xFF,0xFF,0xFF,0xFB,0xFF,0xFF,0xFF,0xFF,0xDF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0xF7,0xFF,0xFF,0xFF,0xFF,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0xFF,0xFF,0xFF,0xFF,0xBF,0xFF,0xFF,0xFF,0xFD,0xFF,0xFF,0xFF,0xFF,0xEF,0xFF,0xFF,0xFF,0xFF,0x7F,0xFF,0xFF,0xFF,0xFB,0xFF,0xFF,0xFF,0xFF,0xDF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0xF7,0xFF,0xFF,0xFF,0xFF,0xBF,0xFF,0xFF,0xFF,0xFC, // '='
|
||||
0xC0,0x00,0x00,0x00,0x0F,0x00,0x00,0x00,0x00,0xFC,0x00,0x00,0x00,0x0F,0xF8,0x00,0x00,0x00,0xFF,0xE0,0x00,0x00,0x0F,0xFF,0xC0,0x00,0x00,0xFF,0xFF,0x00,0x00,0x0F,0xFF,0xFC,0x00,0x00,0xFF,0xFF,0xF8,0x00,0x0F,0xFF,0xFF,0xE0,0x00,0xFF,0xFF,0xFF,0xC0,0x0F,0xFF,0xFF,0xFF,0x00,0x7F,0xFF,0xFF,0xFC,0x00,0xFF,0xFF,0xFF,0xF8,0x01,0xFF,0xFF,0xFF,0xE0,0x03,0xFF,0xFF,0xFE,0x00,0x07,0xFF,0xFF,0xE0,0x00,0x0F,0xFF,0xFE,0x00,0x00,0x1F,0xFF,0xE0,0x00,0x00,0x7F,0xFE,0x00,0x00,0x1F,0xFF,0xE0,0x00,0x0F,0xFF,0xFE,0x00,0x07,0xFF,0xFF,0xE0,0x03,0xFF,0xFF,0xFE,0x01,0xFF,0xFF,0xFF,0xE0,0xFF,0xFF,0xFF,0xF8,0x7F,0xFF,0xFF,0xFE,0x0F,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0xC0,0x0F,0xFF,0xFF,0xE0,0x00,0xFF,0xFF,0xF8,0x00,0x0F,0xFF,0xFC,0x00,0x00,0xFF,0xFF,0x00,0x00,0x0F,0xFF,0xC0,0x00,0x00,0xFF,0xE0,0x00,0x00,0x0F,0xF8,0x00,0x00,0x00,0xFC,0x00,0x00,0x00,0x0F,0x00,0x00,0x00,0x00,0xC0,0x00,0x00,0x00,0x00, // '>'
|
||||
0x00,0x03,0xFF,0x00,0x00,0x00,0xFF,0xFF,0xC0,0x00,0x0F,0xFF,0xFF,0xC0,0x00,0xFF,0xFF,0xFF,0xC0,0x07,0xFF,0xFF,0xFF,0x80,0x3F,0xFF,0xFF,0xFF,0x01,0xFF,0xFF,0xFF,0xFE,0x07,0xFF,0xFF,0xFF,0xF8,0x3F,0xFF,0xFF,0xFF,0xF0,0xFF,0xFF,0xFF,0xFF,0xC7,0xFF,0xF8,0x7F,0xFF,0x1F,0xFF,0x80,0x7F,0xFE,0x7F,0xFE,0x01,0xFF,0xF9,0xFF,0xF0,0x03,0xFF,0xEF,0xFF,0xC0,0x0F,0xFF,0xBF,0xFF,0x00,0x3F,0xFE,0xFF,0xFC,0x00,0xFF,0xF8,0x00,0x00,0x03,0xFF,0xE0,0x00,0x00,0x0F,0xFF,0x80,0x00,0x00,0x7F,0xFE,0x00,0x00,0x03,0xFF,0xF0,0x00,0x00,0x0F,0xFF,0xC0,0x00,0x00,0x7F,0xFE,0x00,0x00,0x03,0xFF,0xF8,0x00,0x00,0x1F,0xFF,0xC0,0x00,0x00,0xFF,0xFE,0x00,0x00,0x07,0xFF,0xF0,0x00,0x00,0x3F,0xFF,0x80,0x00,0x01,0xFF,0xFC,0x00,0x00,0x0F,0xFF,0xE0,0x00,0x00,0x3F,0xFF,0x00,0x00,0x00,0xFF,0xF8,0x00,0x00,0x07,0xFF,0xC0,0x00,0x00,0x1F,0xFE,0x00,0x00,0x00,0x7F,0xF8,0x00,0x00,0x01,0xFF,0xC0,0x00,0x00,0x07,0xFF,0x00,0x00,0x00,0x1F,0xFC,0x00,0x00,0x00,0x7F,0xF0,0x00,0x00,0x01,0xFF,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0xE0,0x00,0x00,0x00,0x7F,0xE0,0x00,0x00,0x03,0xFF,0xC0,0x00,0x00,0x0F,0xFF,0x80,0x00,0x00,0x7F,0xFE,0x00,0x00,0x01,0xFF,0xF8,0x00,0x00,0x07,0xFF,0xF0,0x00,0x00,0x1F,0xFF,0xC0,0x00,0x00,0x7F,0xFE,0x00,0x00,0x00,0xFF,0xF8,0x00,0x00,0x03,0xFF,0xC0,0x00,0x00,0x07,0xFE,0x00,0x00,0x00,0x07,0xE0,0x00,0x00, // '?'
|
||||
0x00,0x00,0x00,0x03,0xFF,0xC0,0x00,0x00,0x00,0x00,0x00,0x07,0xFF,0xFF,0xE0,0x00,0x00,0x00,0x00,0x03,0xFF,0xFF,0xFF,0x80,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x3F,0xFF,0xFF,0xFF,0xF8,0x00,0x00,0x00,0x07,0xFF,0xFF,0xFF,0xFF,0xE0,0x00,0x00,0x01,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x3F,0xFF,0xC0,0x07,0xFF,0xF8,0x00,0x00,0x07,0xFF,0xE0,0x00,0x07,0xFF,0xC0,0x00,0x00,0xFF,0xF0,0x00,0x00,0x1F,0xFE,0x00,0x00,0x1F,0xFE,0x00,0x00,0x00,0x7F,0xF0,0x00,0x03,0xFF,0x80,0x00,0x00,0x01,0xFF,0x80,0x00,0x7F,0xF0,0x00,0x00,0x00,0x0F,0xFC,0x00,0x0F,0xFE,0x00,0x00,0x00,0x00,0x7F,0xC0,0x00,0xFF,0xC0,0x00,0x00,0x00,0x03,0xFE,0x00,0x1F,0xF8,0x00,0x00,0x00,0x00,0x3F,0xE0,0x03,0xFF,0x00,0x00,0x7F,0x80,0x01,0xFF,0x00,0x3F,0xE0,0x00,0x3F,0xFF,0x00,0x0F,0xF0,0x07,0xFE,0x00,0x0F,0xFF,0xFC,0x00,0xFF,0x00,0x7F,0xC0,0x01,0xFF,0xFF,0xF0,0x07,0xF8,0x0F,0xFC,0x00,0x7F,0xFF,0xFF,0x80,0x7F,0x80,0xFF,0x80,0x07,0xFF,0xFF,0xF8,0x07,0xF8,0x0F,0xF8,0x00,0xFF,0xFF,0xFF,0x80,0x3F,0xC1,0xFF,0x00,0x1F,0xFF,0xFF,0xF8,0x03,0xFC,0x1F,0xF0,0x03,0xFF,0xC0,0xFF,0x80,0x3F,0xC1,0xFE,0x00,0x3F,0xF0,0x0F,0xF8,0x03,0xFC,0x3F,0xE0,0x07,0xFE,0x00,0xFF,0x00,0x3F,0xC3,0xFE,0x00,0x7F,0xE0,0x0F,0xF0,0x01,0xFC,0x3F,0xE0,0x0F,0xFC,0x01,0xFF,0x00,0x1F,0xE3,0xFC,0x00,0xFF,0x80,0x1F,0xF0,0x01,0xFE,0x7F,0xC0,0x1F,0xF8,0x01,0xFF,0x00,0x1F,0xE7,0xFC,0x01,0xFF,0x80,0x1F,0xF0,0x01,0xFE,0x7F,0xC0,0x1F,0xF0,0x01,0xFF,0x00,0x1F,0xE7,0xFC,0x01,0xFF,0x00,0x1F,0xF0,0x01,0xFE,0x7F,0x80,0x3F,0xF0,0x01,0xFF,0x00,0x1F,0xE7,0xF8,0x03,0xFF,0x00,0x1F,0xF0,0x01,0xFC,0x7F,0x80,0x3F,0xF0,0x01,0xFF,0x00,0x1F,0xC7,0xF8,0x03,0xFF,0x00,0x1F,0xE0,0x03,0xFC,0x7F,0x80,0x3F,0xE0,0x01,0xFE,0x00,0x3F,0xC7,0xF8,0x03,0xFE,0x00,0x3F,0xE0,0x03,0xFC,0x7F,0x80,0x3F,0xE0,0x03,0xFE,0x00,0x3F,0xC7,0xF8,0x03,0xFE,0x00,0x3F,0xE0,0x03,0xFC,0x7F,0x80,0x3F,0xF0,0x03,0xFE,0x00,0x7F,0x87,0xF8,0x03,0xFF,0x00,0x3F,0xE0,0x07,0xF8,0x7F,0x80,0x3F,0xF0,0x07,0xFE,0x00,0xFF,0x87,0xFC,0x03,0xFF,0x00,0xFF,0xE0,0x0F,0xF0,0x7F,0xC0,0x3F,0xF8,0x0F,0xFE,0x01,0xFF,0x07,0xFC,0x01,0xFF,0xC3,0xFF,0xF0,0x3F,0xE0,0x7F,0xC0,0x1F,0xFF,0xFF,0xFF,0x8F,0xFE,0x03,0xFC,0x01,0xFF,0xFF,0xFF,0xFF,0xFF,0xC0,0x3F,0xE0,0x0F,0xFF,0xFF,0xFF,0xFF,0xF8,0x03,0xFE,0x00,0x7F,0xFF,0xEF,0xFF,0xFF,0x00,0x3F,0xE0,0x07,0xFF,0xFC,0x7F,0xFF,0xE0,0x01,0xFF,0x00,0x3F,0xFF,0x83,0xFF,0xFC,0x00,0x1F,0xF0,0x00,0xFF,0xE0,0x1F,0xFF,0x00,0x01,0xFF,0x80,0x03,0xF8,0x00,0x7F,0xC0,0x00,0x0F,0xFC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0xFF,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xFF,0xF8,0x00,0x00,0x04,0x00,0x00,0x00,0x0F,0xFF,0xE0,0x00,0x01,0xC0,0x00,0x00,0x00,0x7F,0xFF,0xE0,0x01,0xFC,0x00,0x00,0x00,0x03,0xFF,0xFF,0xFF,0xFF,0xE0,0x00,0x00,0x00,0x1F,0xFF,0xFF,0xFF,0xFE,0x00,0x00,0x00,0x00,0x7F,0xFF,0xFF,0xFF,0xE0,0x00,0x00,0x00,0x03,0xFF,0xFF,0xFF,0xFE,0x00,0x00,0x00,0x00,0x0F,0xFF,0xFF,0xFF,0xE0,0x00,0x00,0x00,0x00,0x3F,0xFF,0xFF,0xF8,0x00,0x00,0x00,0x00,0x00,0x7F,0xFF,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0xFC,0x00,0x00,0x00,0x00, // '@'
|
||||
0x00,0x00,0x07,0xFF,0xC0,0x00,0x00,0x00,0x00,0x0F,0xFF,0xC0,0x00,0x00,0x00,0x00,0x0F,0xFF,0xE0,0x00,0x00,0x00,0x00,0x1F,0xFF,0xE0,0x00,0x00,0x00,0x00,0x1F,0xFF,0xE0,0x00,0x00,0x00,0x00,0x1F,0xFF,0xF0,0x00,0x00,0x00,0x00,0x3F,0xFF,0xF0,0x00,0x00,0x00,0x00,0x3F,0xFF,0xF0,0x00,0x00,0x00,0x00,0x3F,0xFF,0xF8,0x00,0x00,0x00,0x00,0x7F,0xFF,0xF8,0x00,0x00,0x00,0x00,0x7F,0xFF,0xFC,0x00,0x00,0x00,0x00,0x7F,0xFF,0xFC,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFC,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFE,0x00,0x00,0x00,0x01,0xFF,0xFF,0xFE,0x00,0x00,0x00,0x01,0xFF,0xFF,0xFE,0x00,0x00,0x00,0x01,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x03,0xFF,0xEF,0xFF,0x00,0x00,0x00,0x03,0xFF,0xCF,0xFF,0x00,0x00,0x00,0x03,0xFF,0xCF,0xFF,0x80,0x00,0x00,0x07,0xFF,0xC7,0xFF,0x80,0x00,0x00,0x07,0xFF,0xC7,0xFF,0xC0,0x00,0x00,0x0F,0xFF,0x87,0xFF,0xC0,0x00,0x00,0x0F,0xFF,0x87,0xFF,0xC0,0x00,0x00,0x0F,0xFF,0x83,0xFF,0xE0,0x00,0x00,0x1F,0xFF,0x03,0xFF,0xE0,0x00,0x00,0x1F,0xFF,0x03,0xFF,0xE0,0x00,0x00,0x1F,0xFF,0x01,0xFF,0xF0,0x00,0x00,0x3F,0xFE,0x01,0xFF,0xF0,0x00,0x00,0x3F,0xFE,0x01,0xFF,0xF8,0x00,0x00,0x3F,0xFE,0x00,0xFF,0xF8,0x00,0x00,0x7F,0xFC,0x00,0xFF,0xF8,0x00,0x00,0x7F,0xFC,0x00,0xFF,0xFC,0x00,0x00,0xFF,0xFC,0x00,0x7F,0xFC,0x00,0x00,0xFF,0xFC,0x00,0x7F,0xFC,0x00,0x00,0xFF,0xF8,0x00,0x7F,0xFE,0x00,0x01,0xFF,0xFF,0xFF,0xFF,0xFE,0x00,0x01,0xFF,0xFF,0xFF,0xFF,0xFE,0x00,0x01,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x03,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x03,0xFF,0xFF,0xFF,0xFF,0xFF,0x80,0x03,0xFF,0xFF,0xFF,0xFF,0xFF,0x80,0x07,0xFF,0xFF,0xFF,0xFF,0xFF,0x80,0x07,0xFF,0xFF,0xFF,0xFF,0xFF,0xC0,0x0F,0xFF,0xFF,0xFF,0xFF,0xFF,0xC0,0x0F,0xFF,0xFF,0xFF,0xFF,0xFF,0xC0,0x0F,0xFF,0xC0,0x00,0x07,0xFF,0xE0,0x1F,0xFF,0x80,0x00,0x07,0xFF,0xE0,0x1F,0xFF,0x80,0x00,0x07,0xFF,0xF0,0x1F,0xFF,0x80,0x00,0x03,0xFF,0xF0,0x3F,0xFF,0x00,0x00,0x03,0xFF,0xF0,0x3F,0xFF,0x00,0x00,0x03,0xFF,0xF8,0x3F,0xFF,0x00,0x00,0x01,0xFF,0xF8,0x7F,0xFF,0x00,0x00,0x01,0xFF,0xF8,0x7F,0xFE,0x00,0x00,0x01,0xFF,0xFC,0xFF,0xFE,0x00,0x00,0x01,0xFF,0xFC,0xFF,0xFE,0x00,0x00,0x00,0xFF,0xFE, // 'A'
|
||||
0xFF,0xFF,0xFF,0xF0,0x00,0x03,0xFF,0xFF,0xFF,0xFC,0x00,0x0F,0xFF,0xFF,0xFF,0xFE,0x00,0x3F,0xFF,0xFF,0xFF,0xFE,0x00,0xFF,0xFF,0xFF,0xFF,0xFC,0x03,0xFF,0xFF,0xFF,0xFF,0xF8,0x0F,0xFF,0xFF,0xFF,0xFF,0xF0,0x3F,0xFF,0xFF,0xFF,0xFF,0xE0,0xFF,0xFF,0xFF,0xFF,0xFF,0xC3,0xFF,0xFF,0xFF,0xFF,0xFF,0x0F,0xFF,0xFF,0xFF,0xFF,0xFC,0x3F,0xFF,0x00,0x1F,0xFF,0xF8,0xFF,0xFC,0x00,0x1F,0xFF,0xE3,0xFF,0xF0,0x00,0x3F,0xFF,0x8F,0xFF,0xC0,0x00,0x7F,0xFE,0x3F,0xFF,0x00,0x01,0xFF,0xF8,0xFF,0xFC,0x00,0x03,0xFF,0xE3,0xFF,0xF0,0x00,0x0F,0xFF,0x8F,0xFF,0xC0,0x00,0x3F,0xFE,0x3F,0xFF,0x00,0x01,0xFF,0xF8,0xFF,0xFC,0x00,0x07,0xFF,0xE3,0xFF,0xF0,0x00,0x1F,0xFF,0x0F,0xFF,0xC0,0x00,0xFF,0xFC,0x3F,0xFF,0x00,0x1F,0xFF,0xE0,0xFF,0xFF,0xFF,0xFF,0xFF,0x83,0xFF,0xFF,0xFF,0xFF,0xFC,0x0F,0xFF,0xFF,0xFF,0xFF,0xC0,0x3F,0xFF,0xFF,0xFF,0xFE,0x00,0xFF,0xFF,0xFF,0xFF,0xF0,0x03,0xFF,0xFF,0xFF,0xFF,0xF8,0x0F,0xFF,0xFF,0xFF,0xFF,0xF0,0x3F,0xFF,0xFF,0xFF,0xFF,0xE0,0xFF,0xFF,0xFF,0xFF,0xFF,0xC3,0xFF,0xF0,0x00,0x7F,0xFF,0x8F,0xFF,0xC0,0x00,0x7F,0xFE,0x3F,0xFF,0x00,0x00,0xFF,0xFC,0xFF,0xFC,0x00,0x03,0xFF,0xF3,0xFF,0xF0,0x00,0x07,0xFF,0xCF,0xFF,0xC0,0x00,0x1F,0xFF,0x3F,0xFF,0x00,0x00,0x7F,0xFC,0xFF,0xFC,0x00,0x01,0xFF,0xFB,0xFF,0xF0,0x00,0x07,0xFF,0xCF,0xFF,0xC0,0x00,0x3F,0xFF,0x3F,0xFF,0x00,0x00,0xFF,0xFC,0xFF,0xFC,0x00,0x07,0xFF,0xF3,0xFF,0xF0,0x00,0x7F,0xFF,0xCF,0xFF,0xFF,0xFF,0xFF,0xFF,0x3F,0xFF,0xFF,0xFF,0xFF,0xF8,0xFF,0xFF,0xFF,0xFF,0xFF,0xE3,0xFF,0xFF,0xFF,0xFF,0xFF,0x0F,0xFF,0xFF,0xFF,0xFF,0xF8,0x3F,0xFF,0xFF,0xFF,0xFF,0xE0,0xFF,0xFF,0xFF,0xFF,0xFF,0x03,0xFF,0xFF,0xFF,0xFF,0xF0,0x0F,0xFF,0xFF,0xFF,0xFF,0x00,0x3F,0xFF,0xFF,0xFF,0xF0,0x00,0xFF,0xFF,0xFF,0xFC,0x00,0x00, // 'B'
|
||||
0x00,0x00,0x1F,0xFC,0x00,0x00,0x00,0x00,0xFF,0xFF,0xE0,0x00,0x00,0x01,0xFF,0xFF,0xFC,0x00,0x00,0x03,0xFF,0xFF,0xFF,0x80,0x00,0x03,0xFF,0xFF,0xFF,0xE0,0x00,0x07,0xFF,0xFF,0xFF,0xFC,0x00,0x07,0xFF,0xFF,0xFF,0xFF,0x00,0x03,0xFF,0xFF,0xFF,0xFF,0x80,0x03,0xFF,0xFF,0xFF,0xFF,0xE0,0x03,0xFF,0xFF,0xFF,0xFF,0xF8,0x03,0xFF,0xFF,0xFF,0xFF,0xFE,0x01,0xFF,0xFF,0x01,0xFF,0xFF,0x01,0xFF,0xFE,0x00,0x3F,0xFF,0xC0,0xFF,0xFC,0x00,0x07,0xFF,0xE0,0xFF,0xFE,0x00,0x03,0xFF,0xF0,0x7F,0xFE,0x00,0x00,0xFF,0xFC,0x3F,0xFF,0x00,0x00,0x7F,0xFE,0x3F,0xFF,0x00,0x00,0x1F,0xFF,0x1F,0xFF,0x80,0x00,0x0F,0xFF,0x8F,0xFF,0xC0,0x00,0x07,0xFF,0xE7,0xFF,0xC0,0x00,0x03,0xFF,0xF7,0xFF,0xE0,0x00,0x00,0x00,0x03,0xFF,0xF0,0x00,0x00,0x00,0x01,0xFF,0xF8,0x00,0x00,0x00,0x00,0xFF,0xFC,0x00,0x00,0x00,0x00,0x7F,0xFE,0x00,0x00,0x00,0x00,0x3F,0xFF,0x00,0x00,0x00,0x00,0x1F,0xFF,0x80,0x00,0x00,0x00,0x0F,0xFF,0xC0,0x00,0x00,0x00,0x07,0xFF,0xE0,0x00,0x00,0x00,0x03,0xFF,0xF0,0x00,0x00,0x00,0x01,0xFF,0xF8,0x00,0x00,0x00,0x00,0xFF,0xFC,0x00,0x00,0x00,0x00,0x7F,0xFE,0x00,0x00,0x00,0x00,0x3F,0xFF,0x00,0x00,0x00,0x00,0x1F,0xFF,0x80,0x00,0x00,0x00,0x0F,0xFF,0xC0,0x00,0x00,0x00,0x07,0xFF,0xE0,0x00,0x00,0x00,0x01,0xFF,0xF0,0x00,0x00,0x00,0x00,0xFF,0xFC,0x00,0x00,0x7F,0xFE,0x7F,0xFE,0x00,0x00,0x3F,0xFE,0x3F,0xFF,0x00,0x00,0x1F,0xFF,0x1F,0xFF,0x80,0x00,0x1F,0xFF,0x87,0xFF,0xE0,0x00,0x0F,0xFF,0xC3,0xFF,0xF0,0x00,0x0F,0xFF,0xE0,0xFF,0xFC,0x00,0x07,0xFF,0xE0,0x7F,0xFF,0x00,0x0F,0xFF,0xF0,0x1F,0xFF,0xE0,0x1F,0xFF,0xF0,0x0F,0xFF,0xFF,0xFF,0xFF,0xF8,0x03,0xFF,0xFF,0xFF,0xFF,0xF8,0x01,0xFF,0xFF,0xFF,0xFF,0xFC,0x00,0x7F,0xFF,0xFF,0xFF,0xFC,0x00,0x1F,0xFF,0xFF,0xFF,0xFC,0x00,0x07,0xFF,0xFF,0xFF,0xFC,0x00,0x01,0xFF,0xFF,0xFF,0xFC,0x00,0x00,0x3F,0xFF,0xFF,0xF8,0x00,0x00,0x07,0xFF,0xFF,0xF0,0x00,0x00,0x00,0xFF,0xFF,0xE0,0x00,0x00,0x00,0x0F,0xFF,0x00,0x00,0x00, // 'C'
|
||||
0xFF,0xFF,0xFF,0x00,0x00,0x03,0xFF,0xFF,0xFF,0xC0,0x00,0x0F,0xFF,0xFF,0xFF,0xC0,0x00,0x3F,0xFF,0xFF,0xFF,0xC0,0x00,0xFF,0xFF,0xFF,0xFF,0xC0,0x03,0xFF,0xFF,0xFF,0xFF,0x80,0x0F,0xFF,0xFF,0xFF,0xFF,0x00,0x3F,0xFF,0xFF,0xFF,0xFE,0x00,0xFF,0xFF,0xFF,0xFF,0xFC,0x03,0xFF,0xFF,0xFF,0xFF,0xF8,0x0F,0xFF,0xC0,0x3F,0xFF,0xF0,0x3F,0xFF,0x00,0x1F,0xFF,0xE0,0xFF,0xFC,0x00,0x3F,0xFF,0x83,0xFF,0xF0,0x00,0x7F,0xFF,0x0F,0xFF,0xC0,0x00,0xFF,0xFC,0x3F,0xFF,0x00,0x01,0xFF,0xF8,0xFF,0xFC,0x00,0x07,0xFF,0xE3,0xFF,0xF0,0x00,0x1F,0xFF,0x8F,0xFF,0xC0,0x00,0x3F,0xFF,0x3F,0xFF,0x00,0x00,0xFF,0xFC,0xFF,0xFC,0x00,0x03,0xFF,0xF3,0xFF,0xF0,0x00,0x07,0xFF,0xCF,0xFF,0xC0,0x00,0x1F,0xFF,0xBF,0xFF,0x00,0x00,0x7F,0xFE,0xFF,0xFC,0x00,0x01,0xFF,0xFB,0xFF,0xF0,0x00,0x07,0xFF,0xEF,0xFF,0xC0,0x00,0x1F,0xFF,0xBF,0xFF,0x00,0x00,0x7F,0xFE,0xFF,0xFC,0x00,0x01,0xFF,0xFB,0xFF,0xF0,0x00,0x07,0xFF,0xEF,0xFF,0xC0,0x00,0x1F,0xFF,0xBF,0xFF,0x00,0x00,0x7F,0xFE,0xFF,0xFC,0x00,0x01,0xFF,0xFB,0xFF,0xF0,0x00,0x07,0xFF,0xEF,0xFF,0xC0,0x00,0x1F,0xFF,0xBF,0xFF,0x00,0x00,0x7F,0xFC,0xFF,0xFC,0x00,0x03,0xFF,0xF3,0xFF,0xF0,0x00,0x0F,0xFF,0xCF,0xFF,0xC0,0x00,0x3F,0xFF,0x3F,0xFF,0x00,0x01,0xFF,0xF8,0xFF,0xFC,0x00,0x07,0xFF,0xE3,0xFF,0xF0,0x00,0x1F,0xFF,0x8F,0xFF,0xC0,0x00,0xFF,0xFC,0x3F,0xFF,0x00,0x07,0xFF,0xF0,0xFF,0xFC,0x00,0x3F,0xFF,0x83,0xFF,0xF0,0x01,0xFF,0xFE,0x0F,0xFF,0xC0,0x3F,0xFF,0xF0,0x3F,0xFF,0xFF,0xFF,0xFF,0x80,0xFF,0xFF,0xFF,0xFF,0xFC,0x03,0xFF,0xFF,0xFF,0xFF,0xE0,0x0F,0xFF,0xFF,0xFF,0xFF,0x00,0x3F,0xFF,0xFF,0xFF,0xF8,0x00,0xFF,0xFF,0xFF,0xFF,0xC0,0x03,0xFF,0xFF,0xFF,0xFC,0x00,0x0F,0xFF,0xFF,0xFF,0xC0,0x00,0x3F,0xFF,0xFF,0xFC,0x00,0x00,0xFF,0xFF,0xFF,0x00,0x00,0x00, // 'D'
|
||||
0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,0xFF,0xFF,0xFF,0xFF,0xBF,0xFF,0xFF,0xFF,0xFF,0xDF,0xFF,0xFF,0xFF,0xFF,0xEF,0xFF,0xFF,0xFF,0xFF,0xF7,0xFF,0xFF,0xFF,0xFF,0xFB,0xFF,0xFF,0xFF,0xFF,0xFD,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,0xFF,0xFF,0xFF,0xFF,0xBF,0xFF,0x00,0x00,0x00,0x1F,0xFF,0x80,0x00,0x00,0x0F,0xFF,0xC0,0x00,0x00,0x07,0xFF,0xE0,0x00,0x00,0x03,0xFF,0xF0,0x00,0x00,0x01,0xFF,0xF8,0x00,0x00,0x00,0xFF,0xFC,0x00,0x00,0x00,0x7F,0xFE,0x00,0x00,0x00,0x3F,0xFF,0x00,0x00,0x00,0x1F,0xFF,0x80,0x00,0x00,0x0F,0xFF,0xC0,0x00,0x00,0x07,0xFF,0xE0,0x00,0x00,0x03,0xFF,0xF0,0x00,0x00,0x01,0xFF,0xFF,0xFF,0xFF,0xE0,0xFF,0xFF,0xFF,0xFF,0xF0,0x7F,0xFF,0xFF,0xFF,0xF8,0x3F,0xFF,0xFF,0xFF,0xFC,0x1F,0xFF,0xFF,0xFF,0xFE,0x0F,0xFF,0xFF,0xFF,0xFF,0x07,0xFF,0xFF,0xFF,0xFF,0x83,0xFF,0xFF,0xFF,0xFF,0xC1,0xFF,0xFF,0xFF,0xFF,0xE0,0xFF,0xFF,0xFF,0xFF,0xF0,0x7F,0xFE,0x00,0x00,0x00,0x3F,0xFF,0x00,0x00,0x00,0x1F,0xFF,0x80,0x00,0x00,0x0F,0xFF,0xC0,0x00,0x00,0x07,0xFF,0xE0,0x00,0x00,0x03,0xFF,0xF0,0x00,0x00,0x01,0xFF,0xF8,0x00,0x00,0x00,0xFF,0xFC,0x00,0x00,0x00,0x7F,0xFE,0x00,0x00,0x00,0x3F,0xFF,0x00,0x00,0x00,0x1F,0xFF,0x80,0x00,0x00,0x0F,0xFF,0xC0,0x00,0x00,0x07,0xFF,0xE0,0x00,0x00,0x03,0xFF,0xF0,0x00,0x00,0x01,0xFF,0xFF,0xFF,0xFF,0xFC,0xFF,0xFF,0xFF,0xFF,0xFE,0x7F,0xFF,0xFF,0xFF,0xFF,0x3F,0xFF,0xFF,0xFF,0xFF,0x9F,0xFF,0xFF,0xFF,0xFF,0xCF,0xFF,0xFF,0xFF,0xFF,0xE7,0xFF,0xFF,0xFF,0xFF,0xF3,0xFF,0xFF,0xFF,0xFF,0xF9,0xFF,0xFF,0xFF,0xFF,0xFC,0xFF,0xFF,0xFF,0xFF,0xFE,0x00, // 'E'
|
||||
0xFF,0xFF,0xFF,0xFF,0xFD,0xFF,0xFF,0xFF,0xFF,0xFB,0xFF,0xFF,0xFF,0xFF,0xF7,0xFF,0xFF,0xFF,0xFF,0xEF,0xFF,0xFF,0xFF,0xFF,0xDF,0xFF,0xFF,0xFF,0xFF,0xBF,0xFF,0xFF,0xFF,0xFF,0x7F,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0xFD,0xFF,0xFF,0xFF,0xFF,0xFB,0xFF,0xF0,0x00,0x00,0x07,0xFF,0xE0,0x00,0x00,0x0F,0xFF,0xC0,0x00,0x00,0x1F,0xFF,0x80,0x00,0x00,0x3F,0xFF,0x00,0x00,0x00,0x7F,0xFE,0x00,0x00,0x00,0xFF,0xFC,0x00,0x00,0x01,0xFF,0xF8,0x00,0x00,0x03,0xFF,0xF0,0x00,0x00,0x07,0xFF,0xE0,0x00,0x00,0x0F,0xFF,0xC0,0x00,0x00,0x1F,0xFF,0x80,0x00,0x00,0x3F,0xFF,0x00,0x00,0x00,0x7F,0xFE,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xF1,0xFF,0xFF,0xFF,0xFF,0xE3,0xFF,0xFF,0xFF,0xFF,0xC7,0xFF,0xFF,0xFF,0xFF,0x8F,0xFF,0xFF,0xFF,0xFF,0x1F,0xFF,0xFF,0xFF,0xFE,0x3F,0xFF,0xFF,0xFF,0xFC,0x7F,0xFF,0xFF,0xFF,0xF8,0xFF,0xFF,0xFF,0xFF,0xF1,0xFF,0xFF,0xFF,0xFF,0xE3,0xFF,0xF0,0x00,0x00,0x07,0xFF,0xE0,0x00,0x00,0x0F,0xFF,0xC0,0x00,0x00,0x1F,0xFF,0x80,0x00,0x00,0x3F,0xFF,0x00,0x00,0x00,0x7F,0xFE,0x00,0x00,0x00,0xFF,0xFC,0x00,0x00,0x01,0xFF,0xF8,0x00,0x00,0x03,0xFF,0xF0,0x00,0x00,0x07,0xFF,0xE0,0x00,0x00,0x0F,0xFF,0xC0,0x00,0x00,0x1F,0xFF,0x80,0x00,0x00,0x3F,0xFF,0x00,0x00,0x00,0x7F,0xFE,0x00,0x00,0x00,0xFF,0xFC,0x00,0x00,0x01,0xFF,0xF8,0x00,0x00,0x03,0xFF,0xF0,0x00,0x00,0x07,0xFF,0xE0,0x00,0x00,0x0F,0xFF,0xC0,0x00,0x00,0x1F,0xFF,0x80,0x00,0x00,0x3F,0xFF,0x00,0x00,0x00,0x7F,0xFE,0x00,0x00,0x00,0xFF,0xFC,0x00,0x00,0x00, // 'F'
|
||||
0x00,0x00,0x1F,0xFE,0x00,0x00,0x00,0x00,0x7F,0xFF,0xF0,0x00,0x00,0x00,0xFF,0xFF,0xFE,0x00,0x00,0x01,0xFF,0xFF,0xFF,0xC0,0x00,0x03,0xFF,0xFF,0xFF,0xF8,0x00,0x03,0xFF,0xFF,0xFF,0xFE,0x00,0x03,0xFF,0xFF,0xFF,0xFF,0x80,0x03,0xFF,0xFF,0xFF,0xFF,0xE0,0x03,0xFF,0xFF,0xFF,0xFF,0xF0,0x03,0xFF,0xFF,0xFF,0xFF,0xFC,0x01,0xFF,0xFF,0xFF,0xFF,0xFF,0x01,0xFF,0xFF,0x80,0xFF,0xFF,0x80,0xFF,0xFF,0x00,0x1F,0xFF,0xC0,0xFF,0xFF,0x00,0x07,0xFF,0xF0,0x7F,0xFF,0x00,0x01,0xFF,0xF8,0x7F,0xFF,0x00,0x00,0x7F,0xFC,0x3F,0xFF,0x80,0x00,0x3F,0xFF,0x1F,0xFF,0x80,0x00,0x1F,0xFF,0x9F,0xFF,0xC0,0x00,0x07,0xFF,0xCF,0xFF,0xC0,0x00,0x03,0xFF,0xE7,0xFF,0xE0,0x00,0x00,0x00,0x03,0xFF,0xF0,0x00,0x00,0x00,0x01,0xFF,0xF8,0x00,0x00,0x00,0x00,0xFF,0xFC,0x00,0x00,0x00,0x00,0x7F,0xFC,0x00,0x00,0x00,0x00,0x7F,0xFE,0x00,0x00,0x00,0x00,0x3F,0xFF,0x00,0x00,0x00,0x00,0x1F,0xFF,0x80,0x00,0x00,0x00,0x0F,0xFF,0xC0,0x07,0xFF,0xFF,0xF7,0xFF,0xE0,0x03,0xFF,0xFF,0xFB,0xFF,0xF0,0x01,0xFF,0xFF,0xFD,0xFF,0xF8,0x00,0xFF,0xFF,0xFE,0xFF,0xFC,0x00,0x7F,0xFF,0xFF,0x7F,0xFE,0x00,0x3F,0xFF,0xFF,0x9F,0xFF,0x00,0x1F,0xFF,0xFF,0xCF,0xFF,0xC0,0x0F,0xFF,0xFF,0xE7,0xFF,0xE0,0x07,0xFF,0xFF,0xF3,0xFF,0xF0,0x00,0x01,0xFF,0xF9,0xFF,0xF8,0x00,0x00,0xFF,0xFC,0xFF,0xFC,0x00,0x00,0x7F,0xFE,0x7F,0xFF,0x00,0x00,0x3F,0xFF,0x1F,0xFF,0x80,0x00,0x1F,0xFF,0x8F,0xFF,0xC0,0x00,0x0F,0xFF,0xC7,0xFF,0xF0,0x00,0x07,0xFF,0xE1,0xFF,0xFC,0x00,0x03,0xFF,0xF0,0xFF,0xFF,0x00,0x01,0xFF,0xF8,0x3F,0xFF,0xC0,0x01,0xFF,0xFC,0x1F,0xFF,0xFC,0x03,0xFF,0xFE,0x07,0xFF,0xFF,0xFF,0xFF,0xFF,0x03,0xFF,0xFF,0xFF,0xFF,0xFF,0x80,0xFF,0xFF,0xFF,0xFF,0xFF,0xC0,0x3F,0xFF,0xFF,0xFF,0xFF,0xE0,0x0F,0xFF,0xFF,0xFF,0xFF,0xE0,0x03,0xFF,0xFF,0xFF,0xFF,0xE0,0x00,0xFF,0xFF,0xFF,0xFF,0xC0,0x00,0x1F,0xFF,0xFF,0xFF,0x80,0x00,0x03,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x7F,0xFF,0xFC,0x00,0x00,0x00,0x03,0xFF,0xC0,0x00,0x00, // 'G'
|
||||
0xFF,0xFC,0x00,0x00,0x3F,0xFF,0x7F,0xFE,0x00,0x00,0x1F,0xFF,0xBF,0xFF,0x00,0x00,0x0F,0xFF,0xDF,0xFF,0x80,0x00,0x07,0xFF,0xEF,0xFF,0xC0,0x00,0x03,0xFF,0xF7,0xFF,0xE0,0x00,0x01,0xFF,0xFB,0xFF,0xF0,0x00,0x00,0xFF,0xFD,0xFF,0xF8,0x00,0x00,0x7F,0xFE,0xFF,0xFC,0x00,0x00,0x3F,0xFF,0x7F,0xFE,0x00,0x00,0x1F,0xFF,0xBF,0xFF,0x00,0x00,0x0F,0xFF,0xDF,0xFF,0x80,0x00,0x07,0xFF,0xEF,0xFF,0xC0,0x00,0x03,0xFF,0xF7,0xFF,0xE0,0x00,0x01,0xFF,0xFB,0xFF,0xF0,0x00,0x00,0xFF,0xFD,0xFF,0xF8,0x00,0x00,0x7F,0xFE,0xFF,0xFC,0x00,0x00,0x3F,0xFF,0x7F,0xFE,0x00,0x00,0x1F,0xFF,0xBF,0xFF,0x00,0x00,0x0F,0xFF,0xDF,0xFF,0x80,0x00,0x07,0xFF,0xEF,0xFF,0xC0,0x00,0x03,0xFF,0xF7,0xFF,0xE0,0x00,0x01,0xFF,0xFB,0xFF,0xF0,0x00,0x00,0xFF,0xFD,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xBF,0xFF,0xFF,0xFF,0xFF,0xFF,0xDF,0xFF,0xFF,0xFF,0xFF,0xFF,0xEF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF7,0xFF,0xFF,0xFF,0xFF,0xFF,0xFB,0xFF,0xFF,0xFF,0xFF,0xFF,0xFD,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,0xFE,0x00,0x00,0x1F,0xFF,0xBF,0xFF,0x00,0x00,0x0F,0xFF,0xDF,0xFF,0x80,0x00,0x07,0xFF,0xEF,0xFF,0xC0,0x00,0x03,0xFF,0xF7,0xFF,0xE0,0x00,0x01,0xFF,0xFB,0xFF,0xF0,0x00,0x00,0xFF,0xFD,0xFF,0xF8,0x00,0x00,0x7F,0xFE,0xFF,0xFC,0x00,0x00,0x3F,0xFF,0x7F,0xFE,0x00,0x00,0x1F,0xFF,0xBF,0xFF,0x00,0x00,0x0F,0xFF,0xDF,0xFF,0x80,0x00,0x07,0xFF,0xEF,0xFF,0xC0,0x00,0x03,0xFF,0xF7,0xFF,0xE0,0x00,0x01,0xFF,0xFB,0xFF,0xF0,0x00,0x00,0xFF,0xFD,0xFF,0xF8,0x00,0x00,0x7F,0xFE,0xFF,0xFC,0x00,0x00,0x3F,0xFF,0x7F,0xFE,0x00,0x00,0x1F,0xFF,0xBF,0xFF,0x00,0x00,0x0F,0xFF,0xDF,0xFF,0x80,0x00,0x07,0xFF,0xEF,0xFF,0xC0,0x00,0x03,0xFF,0xF7,0xFF,0xE0,0x00,0x01,0xFF,0xFB,0xFF,0xF0,0x00,0x00,0xFF,0xFD,0xFF,0xF8,0x00,0x00,0x7F,0xFE,0xFF,0xFC,0x00,0x00,0x3F,0xFF,0x00, // 'H'
|
||||
0xFF,0xFD,0xFF,0xFB,0xFF,0xF7,0xFF,0xEF,0xFF,0xDF,0xFF,0xBF,0xFF,0x7F,0xFE,0xFF,0xFD,0xFF,0xFB,0xFF,0xF7,0xFF,0xEF,0xFF,0xDF,0xFF,0xBF,0xFF,0x7F,0xFE,0xFF,0xFD,0xFF,0xFB,0xFF,0xF7,0xFF,0xEF,0xFF,0xDF,0xFF,0xBF,0xFF,0x7F,0xFE,0xFF,0xFD,0xFF,0xFB,0xFF,0xF7,0xFF,0xEF,0xFF,0xDF,0xFF,0xBF,0xFF,0x7F,0xFE,0xFF,0xFD,0xFF,0xFB,0xFF,0xF7,0xFF,0xEF,0xFF,0xDF,0xFF,0xBF,0xFF,0x7F,0xFE,0xFF,0xFD,0xFF,0xFB,0xFF,0xF7,0xFF,0xEF,0xFF,0xDF,0xFF,0xBF,0xFF,0x7F,0xFE,0xFF,0xFD,0xFF,0xFB,0xFF,0xF7,0xFF,0xEF,0xFF,0xDF,0xFF,0xBF,0xFF,0x7F,0xFE,0xFF,0xFC, // 'I'
|
||||
0x00,0x00,0x00,0x3F,0xFF,0x00,0x00,0x00,0x1F,0xFF,0x80,0x00,0x00,0x0F,0xFF,0xC0,0x00,0x00,0x07,0xFF,0xE0,0x00,0x00,0x03,0xFF,0xF0,0x00,0x00,0x01,0xFF,0xF8,0x00,0x00,0x00,0xFF,0xFC,0x00,0x00,0x00,0x7F,0xFE,0x00,0x00,0x00,0x3F,0xFF,0x00,0x00,0x00,0x1F,0xFF,0x80,0x00,0x00,0x0F,0xFF,0xC0,0x00,0x00,0x07,0xFF,0xE0,0x00,0x00,0x03,0xFF,0xF0,0x00,0x00,0x01,0xFF,0xF8,0x00,0x00,0x00,0xFF,0xFC,0x00,0x00,0x00,0x7F,0xFE,0x00,0x00,0x00,0x3F,0xFF,0x00,0x00,0x00,0x1F,0xFF,0x80,0x00,0x00,0x0F,0xFF,0xC0,0x00,0x00,0x07,0xFF,0xE0,0x00,0x00,0x03,0xFF,0xF0,0x00,0x00,0x01,0xFF,0xF8,0x00,0x00,0x00,0xFF,0xFC,0x00,0x00,0x00,0x7F,0xFE,0x00,0x00,0x00,0x3F,0xFF,0x00,0x00,0x00,0x1F,0xFF,0x80,0x00,0x00,0x0F,0xFF,0xC0,0x00,0x00,0x07,0xFF,0xE0,0x00,0x00,0x03,0xFF,0xF0,0x00,0x00,0x01,0xFF,0xF8,0x00,0x00,0x00,0xFF,0xFC,0x00,0x00,0x00,0x7F,0xFE,0x00,0x00,0x00,0x3F,0xFF,0x00,0x00,0x00,0x1F,0xFF,0x80,0x00,0x00,0x0F,0xFF,0xC0,0x00,0x00,0x07,0xFF,0xE0,0x00,0x00,0x03,0xFF,0xF0,0x00,0x00,0x01,0xFF,0xF8,0x00,0x00,0x00,0xFF,0xFC,0x00,0x00,0x00,0x7F,0xFE,0x00,0x00,0x00,0x3F,0xFF,0x7F,0xFE,0x00,0x1F,0xFF,0xBF,0xFF,0x00,0x0F,0xFF,0x8F,0xFF,0x80,0x0F,0xFF,0xC7,0xFF,0xE0,0x07,0xFF,0xE3,0xFF,0xF0,0x03,0xFF,0xF1,0xFF,0xFC,0x03,0xFF,0xF0,0xFF,0xFF,0x07,0xFF,0xF8,0x3F,0xFF,0xFF,0xFF,0xF8,0x1F,0xFF,0xFF,0xFF,0xFC,0x07,0xFF,0xFF,0xFF,0xFC,0x01,0xFF,0xFF,0xFF,0xFC,0x00,0xFF,0xFF,0xFF,0xFC,0x00,0x1F,0xFF,0xFF,0xFC,0x00,0x07,0xFF,0xFF,0xFC,0x00,0x01,0xFF,0xFF,0xF8,0x00,0x00,0x1F,0xFF,0xF0,0x00,0x00,0x01,0xFF,0xC0,0x00,0x00, // 'J'
|
||||
0xFF,0xFC,0x00,0x01,0xFF,0xFF,0x7F,0xFE,0x00,0x01,0xFF,0xFF,0x3F,0xFF,0x00,0x01,0xFF,0xFF,0x1F,0xFF,0x80,0x00,0xFF,0xFF,0x0F,0xFF,0xC0,0x00,0xFF,0xFF,0x07,0xFF,0xE0,0x00,0xFF,0xFF,0x83,0xFF,0xF0,0x00,0xFF,0xFF,0x81,0xFF,0xF8,0x00,0x7F,0xFF,0x80,0xFF,0xFC,0x00,0x7F,0xFF,0x80,0x7F,0xFE,0x00,0x7F,0xFF,0xC0,0x3F,0xFF,0x00,0x3F,0xFF,0xC0,0x1F,0xFF,0x80,0x3F,0xFF,0xC0,0x0F,0xFF,0xC0,0x3F,0xFF,0xC0,0x07,0xFF,0xE0,0x1F,0xFF,0xE0,0x03,0xFF,0xF0,0x1F,0xFF,0xE0,0x01,0xFF,0xF8,0x1F,0xFF,0xE0,0x00,0xFF,0xFC,0x0F,0xFF,0xE0,0x00,0x7F,0xFE,0x0F,0xFF,0xF0,0x00,0x3F,0xFF,0x0F,0xFF,0xF0,0x00,0x1F,0xFF,0x87,0xFF,0xF0,0x00,0x0F,0xFF,0xC7,0xFF,0xF0,0x00,0x07,0xFF,0xE7,0xFF,0xF8,0x00,0x03,0xFF,0xF3,0xFF,0xF8,0x00,0x01,0xFF,0xFB,0xFF,0xF8,0x00,0x00,0xFF,0xFF,0xFF,0xF8,0x00,0x00,0x7F,0xFF,0xFF,0xFC,0x00,0x00,0x3F,0xFF,0xFF,0xFE,0x00,0x00,0x1F,0xFF,0xFF,0xFF,0x80,0x00,0x0F,0xFF,0xFF,0xFF,0xE0,0x00,0x07,0xFF,0xFF,0xFF,0xF0,0x00,0x03,0xFF,0xFF,0xFF,0xFC,0x00,0x01,0xFF,0xFF,0xFF,0xFE,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0x80,0x00,0x7F,0xFF,0xFF,0xFF,0xE0,0x00,0x3F,0xFF,0xFF,0xFF,0xF0,0x00,0x1F,0xFF,0xFF,0xFF,0xFC,0x00,0x0F,0xFF,0xFE,0xFF,0xFF,0x00,0x07,0xFF,0xFE,0x3F,0xFF,0x80,0x03,0xFF,0xFE,0x1F,0xFF,0xE0,0x01,0xFF,0xFE,0x07,0xFF,0xF0,0x00,0xFF,0xFE,0x03,0xFF,0xFC,0x00,0x7F,0xFE,0x00,0xFF,0xFF,0x00,0x3F,0xFF,0x00,0x7F,0xFF,0x80,0x1F,0xFF,0x80,0x1F,0xFF,0xE0,0x0F,0xFF,0xC0,0x07,0xFF,0xF0,0x07,0xFF,0xE0,0x03,0xFF,0xFC,0x03,0xFF,0xF0,0x00,0xFF,0xFF,0x01,0xFF,0xF8,0x00,0x7F,0xFF,0x80,0xFF,0xFC,0x00,0x1F,0xFF,0xE0,0x7F,0xFE,0x00,0x0F,0xFF,0xF0,0x3F,0xFF,0x00,0x03,0xFF,0xFC,0x1F,0xFF,0x80,0x00,0xFF,0xFF,0x0F,0xFF,0xC0,0x00,0x7F,0xFF,0x87,0xFF,0xE0,0x00,0x1F,0xFF,0xE3,0xFF,0xF0,0x00,0x0F,0xFF,0xF1,0xFF,0xF8,0x00,0x03,0xFF,0xFC,0xFF,0xFC,0x00,0x01,0xFF,0xFF,0x00, // 'K'
|
||||
0xFF,0xFC,0x00,0x00,0x01,0xFF,0xF8,0x00,0x00,0x03,0xFF,0xF0,0x00,0x00,0x07,0xFF,0xE0,0x00,0x00,0x0F,0xFF,0xC0,0x00,0x00,0x1F,0xFF,0x80,0x00,0x00,0x3F,0xFF,0x00,0x00,0x00,0x7F,0xFE,0x00,0x00,0x00,0xFF,0xFC,0x00,0x00,0x01,0xFF,0xF8,0x00,0x00,0x03,0xFF,0xF0,0x00,0x00,0x07,0xFF,0xE0,0x00,0x00,0x0F,0xFF,0xC0,0x00,0x00,0x1F,0xFF,0x80,0x00,0x00,0x3F,0xFF,0x00,0x00,0x00,0x7F,0xFE,0x00,0x00,0x00,0xFF,0xFC,0x00,0x00,0x01,0xFF,0xF8,0x00,0x00,0x03,0xFF,0xF0,0x00,0x00,0x07,0xFF,0xE0,0x00,0x00,0x0F,0xFF,0xC0,0x00,0x00,0x1F,0xFF,0x80,0x00,0x00,0x3F,0xFF,0x00,0x00,0x00,0x7F,0xFE,0x00,0x00,0x00,0xFF,0xFC,0x00,0x00,0x01,0xFF,0xF8,0x00,0x00,0x03,0xFF,0xF0,0x00,0x00,0x07,0xFF,0xE0,0x00,0x00,0x0F,0xFF,0xC0,0x00,0x00,0x1F,0xFF,0x80,0x00,0x00,0x3F,0xFF,0x00,0x00,0x00,0x7F,0xFE,0x00,0x00,0x00,0xFF,0xFC,0x00,0x00,0x01,0xFF,0xF8,0x00,0x00,0x03,0xFF,0xF0,0x00,0x00,0x07,0xFF,0xE0,0x00,0x00,0x0F,0xFF,0xC0,0x00,0x00,0x1F,0xFF,0x80,0x00,0x00,0x3F,0xFF,0x00,0x00,0x00,0x7F,0xFE,0x00,0x00,0x00,0xFF,0xFC,0x00,0x00,0x01,0xFF,0xF8,0x00,0x00,0x03,0xFF,0xF0,0x00,0x00,0x07,0xFF,0xE0,0x00,0x00,0x0F,0xFF,0xC0,0x00,0x00,0x1F,0xFF,0x80,0x00,0x00,0x3F,0xFF,0x00,0x00,0x00,0x7F,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0xFD,0xFF,0xFF,0xFF,0xFF,0xFB,0xFF,0xFF,0xFF,0xFF,0xF7,0xFF,0xFF,0xFF,0xFF,0xEF,0xFF,0xFF,0xFF,0xFF,0xDF,0xFF,0xFF,0xFF,0xFF,0xBF,0xFF,0xFF,0xFF,0xFF,0x7F,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0xFC, // 'L'
|
||||
0xFF,0xFF,0xC0,0x00,0x00,0x1F,0xFF,0xFD,0xFF,0xFF,0xC0,0x00,0x00,0x3F,0xFF,0xFB,0xFF,0xFF,0x80,0x00,0x00,0x7F,0xFF,0xF7,0xFF,0xFF,0x00,0x00,0x00,0xFF,0xFF,0xEF,0xFF,0xFF,0x00,0x00,0x03,0xFF,0xFF,0xDF,0xFF,0xFE,0x00,0x00,0x07,0xFF,0xFF,0xBF,0xFF,0xFC,0x00,0x00,0x0F,0xFF,0xFF,0x7F,0xFF,0xFC,0x00,0x00,0x3F,0xFF,0xFE,0xFF,0xFF,0xF8,0x00,0x00,0x7F,0xFF,0xFD,0xFF,0xFF,0xF0,0x00,0x00,0xFF,0xFF,0xFB,0xFF,0xFF,0xF0,0x00,0x03,0xFF,0xFF,0xF7,0xFF,0xFF,0xE0,0x00,0x07,0xFF,0xFF,0xEF,0xFF,0xFF,0xC0,0x00,0x0F,0xFF,0xFF,0xDF,0xFF,0xFF,0xC0,0x00,0x3F,0xFF,0xFF,0xBF,0xFF,0xFF,0x80,0x00,0x7F,0xFF,0xFF,0x7F,0xFF,0xFF,0x00,0x00,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0x00,0x03,0xFF,0xFF,0xFD,0xFF,0xFF,0xFE,0x00,0x07,0xFF,0xFF,0xFB,0xFF,0xFF,0xFC,0x00,0x0F,0xFF,0xFF,0xF7,0xFF,0xDF,0xFC,0x00,0x3F,0xFB,0xFF,0xEF,0xFF,0xBF,0xF8,0x00,0x7F,0xF7,0xFF,0xDF,0xFF,0x7F,0xF0,0x00,0xFF,0xEF,0xFF,0xBF,0xFE,0x7F,0xF0,0x03,0xFF,0x9F,0xFF,0x7F,0xFC,0xFF,0xE0,0x07,0xFF,0x3F,0xFE,0xFF,0xF9,0xFF,0xC0,0x0F,0xFE,0x7F,0xFD,0xFF,0xF1,0xFF,0x80,0x3F,0xF8,0xFF,0xFB,0xFF,0xE3,0xFF,0x80,0x7F,0xF1,0xFF,0xF7,0xFF,0xC7,0xFF,0x00,0xFF,0xE3,0xFF,0xEF,0xFF,0x87,0xFE,0x01,0xFF,0x87,0xFF,0xDF,0xFF,0x0F,0xFE,0x07,0xFF,0x0F,0xFF,0xBF,0xFE,0x1F,0xFC,0x0F,0xFE,0x1F,0xFF,0x7F,0xFC,0x1F,0xF8,0x1F,0xF8,0x3F,0xFE,0xFF,0xF8,0x3F,0xF8,0x7F,0xF0,0xFF,0xFD,0xFF,0xF8,0x7F,0xF0,0xFF,0xE1,0xFF,0xFB,0xFF,0xF0,0x7F,0xE1,0xFF,0x83,0xFF,0xF7,0xFF,0xE0,0xFF,0xE7,0xFF,0x07,0xFF,0xEF,0xFF,0xC0,0xFF,0xCF,0xFE,0x0F,0xFF,0xDF,0xFF,0x81,0xFF,0x9F,0xF8,0x1F,0xFF,0xBF,0xFF,0x03,0xFF,0xFF,0xF0,0x3F,0xFF,0x7F,0xFE,0x03,0xFF,0xFF,0xC0,0x7F,0xFE,0xFF,0xFC,0x07,0xFF,0xFF,0x80,0xFF,0xFD,0xFF,0xF8,0x0F,0xFF,0xFF,0x01,0xFF,0xFB,0xFF,0xF0,0x0F,0xFF,0xFC,0x03,0xFF,0xF7,0xFF,0xE0,0x1F,0xFF,0xF8,0x07,0xFF,0xEF,0xFF,0xC0,0x3F,0xFF,0xF0,0x0F,0xFF,0xDF,0xFF,0x80,0x3F,0xFF,0xC0,0x1F,0xFF,0xBF,0xFF,0x00,0x7F,0xFF,0x80,0x3F,0xFF,0x7F,0xFE,0x00,0xFF,0xFF,0x00,0x7F,0xFE,0xFF,0xFC,0x00,0xFF,0xFC,0x00,0xFF,0xFD,0xFF,0xF8,0x01,0xFF,0xF8,0x01,0xFF,0xFB,0xFF,0xF0,0x03,0xFF,0xF0,0x03,0xFF,0xF7,0xFF,0xE0,0x03,0xFF,0xC0,0x07,0xFF,0xEF,0xFF,0xC0,0x07,0xFF,0x80,0x0F,0xFF,0xDF,0xFF,0x80,0x0F,0xFF,0x00,0x1F,0xFF,0xBF,0xFF,0x00,0x0F,0xFC,0x00,0x3F,0xFF,0x7F,0xFE,0x00,0x1F,0xF8,0x00,0x7F,0xFE,0xFF,0xFC,0x00,0x3F,0xF0,0x00,0xFF,0xFC, // 'M'
|
||||
0xFF,0xFC,0x00,0x00,0x3F,0xFF,0x7F,0xFF,0x00,0x00,0x1F,0xFF,0xBF,0xFF,0x80,0x00,0x0F,0xFF,0xDF,0xFF,0xE0,0x00,0x07,0xFF,0xEF,0xFF,0xF0,0x00,0x03,0xFF,0xF7,0xFF,0xFC,0x00,0x01,0xFF,0xFB,0xFF,0xFF,0x00,0x00,0xFF,0xFD,0xFF,0xFF,0x80,0x00,0x7F,0xFE,0xFF,0xFF,0xE0,0x00,0x3F,0xFF,0x7F,0xFF,0xF0,0x00,0x1F,0xFF,0xBF,0xFF,0xFC,0x00,0x0F,0xFF,0xDF,0xFF,0xFE,0x00,0x07,0xFF,0xEF,0xFF,0xFF,0x80,0x03,0xFF,0xF7,0xFF,0xFF,0xE0,0x01,0xFF,0xFB,0xFF,0xFF,0xF0,0x00,0xFF,0xFD,0xFF,0xFF,0xFC,0x00,0x7F,0xFE,0xFF,0xFF,0xFE,0x00,0x3F,0xFF,0x7F,0xFF,0xFF,0x80,0x1F,0xFF,0xBF,0xFF,0xFF,0xC0,0x0F,0xFF,0xDF,0xFF,0xFF,0xF0,0x07,0xFF,0xEF,0xFF,0xFF,0xFC,0x03,0xFF,0xF7,0xFF,0xFF,0xFE,0x01,0xFF,0xFB,0xFF,0xFF,0xFF,0x80,0xFF,0xFD,0xFF,0xFB,0xFF,0xC0,0x7F,0xFE,0xFF,0xFC,0xFF,0xF0,0x3F,0xFF,0x7F,0xFE,0x7F,0xF8,0x1F,0xFF,0xBF,0xFF,0x1F,0xFE,0x0F,0xFF,0xDF,0xFF,0x8F,0xFF,0x07,0xFF,0xEF,0xFF,0xC3,0xFF,0xC3,0xFF,0xF7,0xFF,0xE1,0xFF,0xF1,0xFF,0xFB,0xFF,0xF0,0x7F,0xF8,0xFF,0xFD,0xFF,0xF8,0x1F,0xFE,0x7F,0xFE,0xFF,0xFC,0x0F,0xFF,0x3F,0xFF,0x7F,0xFE,0x03,0xFF,0xDF,0xFF,0xBF,0xFF,0x01,0xFF,0xEF,0xFF,0xDF,0xFF,0x80,0x7F,0xFF,0xFF,0xEF,0xFF,0xC0,0x3F,0xFF,0xFF,0xF7,0xFF,0xE0,0x0F,0xFF,0xFF,0xFB,0xFF,0xF0,0x03,0xFF,0xFF,0xFD,0xFF,0xF8,0x01,0xFF,0xFF,0xFE,0xFF,0xFC,0x00,0x7F,0xFF,0xFF,0x7F,0xFE,0x00,0x3F,0xFF,0xFF,0xBF,0xFF,0x00,0x0F,0xFF,0xFF,0xDF,0xFF,0x80,0x07,0xFF,0xFF,0xEF,0xFF,0xC0,0x01,0xFF,0xFF,0xF7,0xFF,0xE0,0x00,0x7F,0xFF,0xFB,0xFF,0xF0,0x00,0x3F,0xFF,0xFD,0xFF,0xF8,0x00,0x0F,0xFF,0xFE,0xFF,0xFC,0x00,0x07,0xFF,0xFF,0x7F,0xFE,0x00,0x01,0xFF,0xFF,0xBF,0xFF,0x00,0x00,0xFF,0xFF,0xDF,0xFF,0x80,0x00,0x3F,0xFF,0xEF,0xFF,0xC0,0x00,0x1F,0xFF,0xF7,0xFF,0xE0,0x00,0x07,0xFF,0xFB,0xFF,0xF0,0x00,0x01,0xFF,0xFD,0xFF,0xF8,0x00,0x00,0xFF,0xFE,0xFF,0xFC,0x00,0x00,0x3F,0xFF,0x00, // 'N'
|
||||
0x00,0x00,0x1F,0xFC,0x00,0x00,0x00,0x00,0x3F,0xFF,0xE0,0x00,0x00,0x00,0x7F,0xFF,0xFF,0x00,0x00,0x00,0x7F,0xFF,0xFF,0xE0,0x00,0x00,0x3F,0xFF,0xFF,0xFE,0x00,0x00,0x1F,0xFF,0xFF,0xFF,0xC0,0x00,0x0F,0xFF,0xFF,0xFF,0xF8,0x00,0x07,0xFF,0xFF,0xFF,0xFF,0x00,0x03,0xFF,0xFF,0xFF,0xFF,0xE0,0x01,0xFF,0xFF,0xFF,0xFF,0xFC,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0x80,0x3F,0xFF,0xE0,0x3F,0xFF,0xE0,0x1F,0xFF,0xE0,0x03,0xFF,0xFC,0x07,0xFF,0xF0,0x00,0x7F,0xFF,0x03,0xFF,0xF8,0x00,0x0F,0xFF,0xE0,0xFF,0xFC,0x00,0x01,0xFF,0xF8,0x7F,0xFF,0x00,0x00,0x7F,0xFE,0x1F,0xFF,0x80,0x00,0x0F,0xFF,0xC7,0xFF,0xE0,0x00,0x03,0xFF,0xF1,0xFF,0xF8,0x00,0x00,0xFF,0xFC,0xFF,0xFC,0x00,0x00,0x1F,0xFF,0xBF,0xFF,0x00,0x00,0x07,0xFF,0xEF,0xFF,0xC0,0x00,0x01,0xFF,0xFB,0xFF,0xF0,0x00,0x00,0x7F,0xFE,0xFF,0xFC,0x00,0x00,0x1F,0xFF,0xBF,0xFF,0x00,0x00,0x07,0xFF,0xEF,0xFF,0xC0,0x00,0x01,0xFF,0xFB,0xFF,0xF0,0x00,0x00,0x7F,0xFE,0xFF,0xFC,0x00,0x00,0x1F,0xFF,0xBF,0xFF,0x00,0x00,0x07,0xFF,0xEF,0xFF,0xC0,0x00,0x01,0xFF,0xFB,0xFF,0xF0,0x00,0x00,0x7F,0xFE,0xFF,0xFC,0x00,0x00,0x1F,0xFF,0xBF,0xFF,0x00,0x00,0x07,0xFF,0xEF,0xFF,0xC0,0x00,0x01,0xFF,0xFB,0xFF,0xF0,0x00,0x00,0x7F,0xFE,0xFF,0xFC,0x00,0x00,0x1F,0xFF,0xBF,0xFF,0x00,0x00,0x07,0xFF,0xEF,0xFF,0xC0,0x00,0x01,0xFF,0xF9,0xFF,0xF8,0x00,0x00,0xFF,0xFC,0x7F,0xFE,0x00,0x00,0x3F,0xFF,0x1F,0xFF,0x80,0x00,0x0F,0xFF,0xC7,0xFF,0xF0,0x00,0x07,0xFF,0xF0,0xFF,0xFC,0x00,0x01,0xFF,0xF8,0x3F,0xFF,0x80,0x00,0xFF,0xFE,0x07,0xFF,0xF0,0x00,0x7F,0xFF,0x01,0xFF,0xFE,0x00,0x3F,0xFF,0xC0,0x3F,0xFF,0xE0,0x3F,0xFF,0xE0,0x0F,0xFF,0xFF,0xFF,0xFF,0xF8,0x01,0xFF,0xFF,0xFF,0xFF,0xFC,0x00,0x3F,0xFF,0xFF,0xFF,0xFE,0x00,0x07,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0x80,0x00,0x1F,0xFF,0xFF,0xFF,0xC0,0x00,0x03,0xFF,0xFF,0xFF,0xE0,0x00,0x00,0x7F,0xFF,0xFF,0xF0,0x00,0x00,0x07,0xFF,0xFF,0xF0,0x00,0x00,0x00,0x3F,0xFF,0xE0,0x00,0x00,0x00,0x01,0xFF,0xC0,0x00,0x00, // 'O'
|
||||
0xFF,0xFF,0xFF,0xF0,0x00,0x03,0xFF,0xFF,0xFF,0xFC,0x00,0x0F,0xFF,0xFF,0xFF,0xFE,0x00,0x3F,0xFF,0xFF,0xFF,0xFE,0x00,0xFF,0xFF,0xFF,0xFF,0xFC,0x03,0xFF,0xFF,0xFF,0xFF,0xF8,0x0F,0xFF,0xFF,0xFF,0xFF,0xF0,0x3F,0xFF,0xFF,0xFF,0xFF,0xE0,0xFF,0xFF,0xFF,0xFF,0xFF,0xC3,0xFF,0xFF,0xFF,0xFF,0xFF,0x0F,0xFF,0xC0,0x03,0xFF,0xFE,0x3F,0xFF,0x00,0x03,0xFF,0xFC,0xFF,0xFC,0x00,0x07,0xFF,0xF3,0xFF,0xF0,0x00,0x0F,0xFF,0xCF,0xFF,0xC0,0x00,0x3F,0xFF,0xBF,0xFF,0x00,0x00,0x7F,0xFE,0xFF,0xFC,0x00,0x01,0xFF,0xFB,0xFF,0xF0,0x00,0x07,0xFF,0xEF,0xFF,0xC0,0x00,0x1F,0xFF,0xBF,0xFF,0x00,0x00,0x7F,0xFE,0xFF,0xFC,0x00,0x01,0xFF,0xFB,0xFF,0xF0,0x00,0x07,0xFF,0xEF,0xFF,0xC0,0x00,0x1F,0xFF,0xBF,0xFF,0x00,0x00,0xFF,0xFE,0xFF,0xFC,0x00,0x07,0xFF,0xF3,0xFF,0xF0,0x00,0x3F,0xFF,0xCF,0xFF,0xC0,0x03,0xFF,0xFE,0x3F,0xFF,0xFF,0xFF,0xFF,0xF8,0xFF,0xFF,0xFF,0xFF,0xFF,0xC3,0xFF,0xFF,0xFF,0xFF,0xFF,0x0F,0xFF,0xFF,0xFF,0xFF,0xF8,0x3F,0xFF,0xFF,0xFF,0xFF,0xC0,0xFF,0xFF,0xFF,0xFF,0xFE,0x03,0xFF,0xFF,0xFF,0xFF,0xE0,0x0F,0xFF,0xFF,0xFF,0xFE,0x00,0x3F,0xFF,0xFF,0xFF,0xE0,0x00,0xFF,0xFF,0xFF,0xF8,0x00,0x03,0xFF,0xF0,0x00,0x00,0x00,0x0F,0xFF,0xC0,0x00,0x00,0x00,0x3F,0xFF,0x00,0x00,0x00,0x00,0xFF,0xFC,0x00,0x00,0x00,0x03,0xFF,0xF0,0x00,0x00,0x00,0x0F,0xFF,0xC0,0x00,0x00,0x00,0x3F,0xFF,0x00,0x00,0x00,0x00,0xFF,0xFC,0x00,0x00,0x00,0x03,0xFF,0xF0,0x00,0x00,0x00,0x0F,0xFF,0xC0,0x00,0x00,0x00,0x3F,0xFF,0x00,0x00,0x00,0x00,0xFF,0xFC,0x00,0x00,0x00,0x03,0xFF,0xF0,0x00,0x00,0x00,0x0F,0xFF,0xC0,0x00,0x00,0x00,0x3F,0xFF,0x00,0x00,0x00,0x00,0xFF,0xFC,0x00,0x00,0x00,0x03,0xFF,0xF0,0x00,0x00,0x00,0x0F,0xFF,0xC0,0x00,0x00,0x00,0x3F,0xFF,0x00,0x00,0x00,0x00,0xFF,0xFC,0x00,0x00,0x00,0x00, // 'P'
|
||||
0x00,0x00,0x1F,0xFC,0x00,0x00,0x00,0x00,0x3F,0xFF,0xE0,0x00,0x00,0x00,0x7F,0xFF,0xFF,0x00,0x00,0x00,0x3F,0xFF,0xFF,0xE0,0x00,0x00,0x3F,0xFF,0xFF,0xFE,0x00,0x00,0x1F,0xFF,0xFF,0xFF,0xC0,0x00,0x0F,0xFF,0xFF,0xFF,0xF8,0x00,0x07,0xFF,0xFF,0xFF,0xFF,0x00,0x03,0xFF,0xFF,0xFF,0xFF,0xE0,0x01,0xFF,0xFF,0xFF,0xFF,0xFC,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0x80,0x3F,0xFF,0xE0,0x3F,0xFF,0xE0,0x1F,0xFF,0xE0,0x03,0xFF,0xFC,0x07,0xFF,0xF0,0x00,0x7F,0xFF,0x03,0xFF,0xF8,0x00,0x0F,0xFF,0xE0,0xFF,0xFC,0x00,0x01,0xFF,0xF8,0x7F,0xFF,0x00,0x00,0x7F,0xFF,0x1F,0xFF,0x80,0x00,0x0F,0xFF,0xC7,0xFF,0xE0,0x00,0x03,0xFF,0xF1,0xFF,0xF8,0x00,0x00,0xFF,0xFC,0xFF,0xFC,0x00,0x00,0x1F,0xFF,0xBF,0xFF,0x00,0x00,0x07,0xFF,0xEF,0xFF,0xC0,0x00,0x01,0xFF,0xFB,0xFF,0xF0,0x00,0x00,0x7F,0xFE,0xFF,0xFC,0x00,0x00,0x1F,0xFF,0xBF,0xFF,0x00,0x00,0x07,0xFF,0xEF,0xFF,0xC0,0x00,0x01,0xFF,0xFB,0xFF,0xF0,0x00,0x00,0x7F,0xFE,0xFF,0xFC,0x00,0x00,0x1F,0xFF,0xBF,0xFF,0x00,0x00,0x07,0xFF,0xEF,0xFF,0xC0,0x00,0x01,0xFF,0xFB,0xFF,0xF0,0x00,0x00,0x7F,0xFE,0xFF,0xFC,0x00,0x00,0x1F,0xFF,0xBF,0xFF,0x00,0x00,0x07,0xFF,0xEF,0xFF,0xC0,0x00,0x01,0xFF,0xFB,0xFF,0xF0,0x00,0x00,0x7F,0xFE,0xFF,0xFC,0x00,0x00,0x1F,0xFF,0xBF,0xFF,0x00,0x00,0x07,0xFF,0xEF,0xFF,0xC0,0x00,0x01,0xFF,0xF9,0xFF,0xF8,0x00,0x00,0xFF,0xFC,0x7F,0xFE,0x00,0x00,0x3F,0xFF,0x1F,0xFF,0x80,0x00,0x0F,0xFF,0xC3,0xFF,0xF0,0x00,0x07,0xFF,0xF0,0xFF,0xFC,0x00,0x01,0xFF,0xF8,0x3F,0xFF,0x80,0x00,0xFF,0xFE,0x07,0xFF,0xF0,0x00,0x7F,0xFF,0x01,0xFF,0xFE,0x00,0x3F,0xFF,0xC0,0x3F,0xFF,0xE0,0x3F,0xFF,0xE0,0x0F,0xFF,0xFF,0xFF,0xFF,0xF8,0x01,0xFF,0xFF,0xFF,0xFF,0xFC,0x00,0x3F,0xFF,0xFF,0xFF,0xFE,0x00,0x07,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0x80,0x00,0x1F,0xFF,0xFF,0xFF,0xC0,0x00,0x03,0xFF,0xFF,0xFF,0xF0,0x00,0x00,0x3F,0xFF,0xFF,0xFE,0x00,0x00,0x07,0xFF,0xFF,0xFF,0xE0,0x00,0x00,0x3F,0xFF,0xFF,0xFC,0x00,0x00,0x01,0xFF,0xFF,0xFF,0x80,0x00,0x00,0x00,0x1F,0xFF,0xF0,0x00,0x00,0x00,0x03,0xFF,0xFF,0x00,0x00,0x00,0x00,0x7F,0xFF,0xE0,0x00,0x00,0x00,0x07,0xFF,0xE0,0x00,0x00,0x00,0x00,0xFF,0xF0,0x00,0x00,0x00,0x00,0x1F,0xF8,0x00,0x00,0x00,0x00,0x03,0xFC,0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00, // 'Q'
|
||||
0xFF,0xFF,0xFF,0xF8,0x00,0x01,0xFF,0xFF,0xFF,0xFF,0x00,0x03,0xFF,0xFF,0xFF,0xFF,0x80,0x07,0xFF,0xFF,0xFF,0xFF,0xC0,0x0F,0xFF,0xFF,0xFF,0xFF,0xC0,0x1F,0xFF,0xFF,0xFF,0xFF,0xC0,0x3F,0xFF,0xFF,0xFF,0xFF,0xC0,0x7F,0xFF,0xFF,0xFF,0xFF,0xC0,0xFF,0xFF,0xFF,0xFF,0xFF,0xC1,0xFF,0xFF,0xFF,0xFF,0xFF,0x83,0xFF,0xFF,0xFF,0xFF,0xFF,0x87,0xFF,0xE0,0x01,0xFF,0xFF,0x0F,0xFF,0xC0,0x00,0xFF,0xFF,0x1F,0xFF,0x80,0x00,0xFF,0xFE,0x3F,0xFF,0x00,0x00,0xFF,0xFC,0x7F,0xFE,0x00,0x01,0xFF,0xF8,0xFF,0xFC,0x00,0x03,0xFF,0xF1,0xFF,0xF8,0x00,0x07,0xFF,0xE3,0xFF,0xF0,0x00,0x0F,0xFF,0xC7,0xFF,0xE0,0x00,0x1F,0xFF,0x8F,0xFF,0xC0,0x00,0x3F,0xFF,0x1F,0xFF,0x80,0x00,0x7F,0xFE,0x3F,0xFF,0x00,0x00,0xFF,0xFC,0x7F,0xFE,0x00,0x03,0xFF,0xF0,0xFF,0xFC,0x00,0x0F,0xFF,0xE1,0xFF,0xF8,0x00,0x7F,0xFF,0xC3,0xFF,0xFF,0xFF,0xFF,0xFF,0x07,0xFF,0xFF,0xFF,0xFF,0xFC,0x0F,0xFF,0xFF,0xFF,0xFF,0xF8,0x1F,0xFF,0xFF,0xFF,0xFF,0xE0,0x3F,0xFF,0xFF,0xFF,0xFF,0x80,0x7F,0xFF,0xFF,0xFF,0xFE,0x00,0xFF,0xFF,0xFF,0xFF,0xF0,0x01,0xFF,0xFF,0xFF,0xFF,0x80,0x03,0xFF,0xFF,0xFF,0xFF,0x80,0x07,0xFF,0xFF,0xFF,0xFF,0x00,0x0F,0xFF,0xFF,0xFF,0xFF,0x00,0x1F,0xFF,0x80,0x7F,0xFE,0x00,0x3F,0xFF,0x00,0xFF,0xFE,0x00,0x7F,0xFE,0x00,0xFF,0xFC,0x00,0xFF,0xFC,0x01,0xFF,0xFC,0x01,0xFF,0xF8,0x01,0xFF,0xF8,0x03,0xFF,0xF0,0x03,0xFF,0xF8,0x07,0xFF,0xE0,0x03,0xFF,0xF0,0x0F,0xFF,0xC0,0x07,0xFF,0xF0,0x1F,0xFF,0x80,0x07,0xFF,0xE0,0x3F,0xFF,0x00,0x0F,0xFF,0xE0,0x7F,0xFE,0x00,0x0F,0xFF,0xC0,0xFF,0xFC,0x00,0x1F,0xFF,0xC1,0xFF,0xF8,0x00,0x1F,0xFF,0x83,0xFF,0xF0,0x00,0x3F,0xFF,0x87,0xFF,0xE0,0x00,0x3F,0xFF,0x0F,0xFF,0xC0,0x00,0x7F,0xFF,0x1F,0xFF,0x80,0x00,0x7F,0xFF,0x3F,0xFF,0x00,0x00,0xFF,0xFE,0x7F,0xFE,0x00,0x00,0xFF,0xFE,0xFF,0xFC,0x00,0x01,0xFF,0xFC, // 'R'
|
||||
0x00,0x00,0x3F,0xF8,0x00,0x00,0x00,0x0F,0xFF,0xFE,0x00,0x00,0x00,0xFF,0xFF,0xFF,0x00,0x00,0x0F,0xFF,0xFF,0xFE,0x00,0x00,0xFF,0xFF,0xFF,0xFE,0x00,0x07,0xFF,0xFF,0xFF,0xFC,0x00,0x3F,0xFF,0xFF,0xFF,0xF8,0x01,0xFF,0xFF,0xFF,0xFF,0xF0,0x0F,0xFF,0xFF,0xFF,0xFF,0xE0,0x3F,0xFF,0xFF,0xFF,0xFF,0x81,0xFF,0xFF,0x01,0xFF,0xFF,0x07,0xFF,0xF0,0x01,0xFF,0xFC,0x1F,0xFF,0x80,0x03,0xFF,0xF0,0xFF,0xFC,0x00,0x07,0xFF,0xE3,0xFF,0xF0,0x00,0x1F,0xFF,0x8F,0xFF,0xC0,0x00,0x7F,0xFE,0x3F,0xFF,0x00,0x00,0xFF,0xF8,0xFF,0xFC,0x00,0x03,0xFF,0xE3,0xFF,0xF0,0x00,0x00,0x00,0x07,0xFF,0xE0,0x00,0x00,0x00,0x1F,0xFF,0xC0,0x00,0x00,0x00,0x7F,0xFF,0xC0,0x00,0x00,0x00,0xFF,0xFF,0x80,0x00,0x00,0x03,0xFF,0xFF,0xC0,0x00,0x00,0x07,0xFF,0xFF,0xC0,0x00,0x00,0x0F,0xFF,0xFF,0xE0,0x00,0x00,0x3F,0xFF,0xFF,0xF0,0x00,0x00,0x3F,0xFF,0xFF,0xF0,0x00,0x00,0x7F,0xFF,0xFF,0xF0,0x00,0x00,0xFF,0xFF,0xFF,0xE0,0x00,0x00,0xFF,0xFF,0xFF,0xE0,0x00,0x00,0xFF,0xFF,0xFF,0xC0,0x00,0x00,0xFF,0xFF,0xFF,0x80,0x00,0x00,0x7F,0xFF,0xFF,0x00,0x00,0x00,0x7F,0xFF,0xFE,0x00,0x00,0x00,0x3F,0xFF,0xF8,0x00,0x00,0x00,0x3F,0xFF,0xF0,0x00,0x00,0x00,0x3F,0xFF,0xC0,0x00,0x00,0x00,0x3F,0xFF,0x80,0x00,0x00,0x00,0x7F,0xFE,0xFF,0xFC,0x00,0x01,0xFF,0xF9,0xFF,0xF0,0x00,0x07,0xFF,0xE7,0xFF,0xC0,0x00,0x0F,0xFF,0x9F,0xFF,0x80,0x00,0x3F,0xFE,0x7F,0xFE,0x00,0x01,0xFF,0xF9,0xFF,0xFC,0x00,0x07,0xFF,0xE3,0xFF,0xF0,0x00,0x1F,0xFF,0x8F,0xFF,0xF0,0x00,0xFF,0xFE,0x1F,0xFF,0xF0,0x0F,0xFF,0xF0,0x7F,0xFF,0xFF,0xFF,0xFF,0xC0,0xFF,0xFF,0xFF,0xFF,0xFF,0x01,0xFF,0xFF,0xFF,0xFF,0xF8,0x03,0xFF,0xFF,0xFF,0xFF,0xC0,0x07,0xFF,0xFF,0xFF,0xFE,0x00,0x0F,0xFF,0xFF,0xFF,0xF0,0x00,0x0F,0xFF,0xFF,0xFF,0x80,0x00,0x0F,0xFF,0xFF,0xF8,0x00,0x00,0x0F,0xFF,0xFF,0x00,0x00,0x00,0x03,0xFF,0xC0,0x00,0x00, // 'S'
|
||||
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xBF,0xFF,0xFF,0xFF,0xFF,0xFF,0xDF,0xFF,0xFF,0xFF,0xFF,0xFF,0xEF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF7,0xFF,0xFF,0xFF,0xFF,0xFF,0xFB,0xFF,0xFF,0xFF,0xFF,0xFF,0xFD,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0x80,0x00,0x1F,0xFF,0x80,0x00,0x00,0x00,0x0F,0xFF,0xC0,0x00,0x00,0x00,0x07,0xFF,0xE0,0x00,0x00,0x00,0x03,0xFF,0xF0,0x00,0x00,0x00,0x01,0xFF,0xF8,0x00,0x00,0x00,0x00,0xFF,0xFC,0x00,0x00,0x00,0x00,0x7F,0xFE,0x00,0x00,0x00,0x00,0x3F,0xFF,0x00,0x00,0x00,0x00,0x1F,0xFF,0x80,0x00,0x00,0x00,0x0F,0xFF,0xC0,0x00,0x00,0x00,0x07,0xFF,0xE0,0x00,0x00,0x00,0x03,0xFF,0xF0,0x00,0x00,0x00,0x01,0xFF,0xF8,0x00,0x00,0x00,0x00,0xFF,0xFC,0x00,0x00,0x00,0x00,0x7F,0xFE,0x00,0x00,0x00,0x00,0x3F,0xFF,0x00,0x00,0x00,0x00,0x1F,0xFF,0x80,0x00,0x00,0x00,0x0F,0xFF,0xC0,0x00,0x00,0x00,0x07,0xFF,0xE0,0x00,0x00,0x00,0x03,0xFF,0xF0,0x00,0x00,0x00,0x01,0xFF,0xF8,0x00,0x00,0x00,0x00,0xFF,0xFC,0x00,0x00,0x00,0x00,0x7F,0xFE,0x00,0x00,0x00,0x00,0x3F,0xFF,0x00,0x00,0x00,0x00,0x1F,0xFF,0x80,0x00,0x00,0x00,0x0F,0xFF,0xC0,0x00,0x00,0x00,0x07,0xFF,0xE0,0x00,0x00,0x00,0x03,0xFF,0xF0,0x00,0x00,0x00,0x01,0xFF,0xF8,0x00,0x00,0x00,0x00,0xFF,0xFC,0x00,0x00,0x00,0x00,0x7F,0xFE,0x00,0x00,0x00,0x00,0x3F,0xFF,0x00,0x00,0x00,0x00,0x1F,0xFF,0x80,0x00,0x00,0x00,0x0F,0xFF,0xC0,0x00,0x00,0x00,0x07,0xFF,0xE0,0x00,0x00,0x00,0x03,0xFF,0xF0,0x00,0x00,0x00,0x01,0xFF,0xF8,0x00,0x00,0x00,0x00,0xFF,0xFC,0x00,0x00,0x00,0x00,0x7F,0xFE,0x00,0x00,0x00,0x00,0x3F,0xFF,0x00,0x00,0x00,0x00,0x1F,0xFF,0x80,0x00,0x00,0x00,0x0F,0xFF,0xC0,0x00,0x00,0x00,0x07,0xFF,0xE0,0x00,0x00,0x00,0x03,0xFF,0xF0,0x00,0x00,0x00,0x01,0xFF,0xF8,0x00,0x00,0x00,0x00,0xFF,0xFC,0x00,0x00,0x00,0x00,0x7F,0xFE,0x00,0x00,0x00, // 'T'
|
||||
0xFF,0xFC,0x00,0x01,0xFF,0xFB,0xFF,0xF0,0x00,0x07,0xFF,0xEF,0xFF,0xC0,0x00,0x1F,0xFF,0xBF,0xFF,0x00,0x00,0x7F,0xFE,0xFF,0xFC,0x00,0x01,0xFF,0xFB,0xFF,0xF0,0x00,0x07,0xFF,0xEF,0xFF,0xC0,0x00,0x1F,0xFF,0xBF,0xFF,0x00,0x00,0x7F,0xFE,0xFF,0xFC,0x00,0x01,0xFF,0xFB,0xFF,0xF0,0x00,0x07,0xFF,0xEF,0xFF,0xC0,0x00,0x1F,0xFF,0xBF,0xFF,0x00,0x00,0x7F,0xFE,0xFF,0xFC,0x00,0x01,0xFF,0xFB,0xFF,0xF0,0x00,0x07,0xFF,0xEF,0xFF,0xC0,0x00,0x1F,0xFF,0xBF,0xFF,0x00,0x00,0x7F,0xFE,0xFF,0xFC,0x00,0x01,0xFF,0xFB,0xFF,0xF0,0x00,0x07,0xFF,0xEF,0xFF,0xC0,0x00,0x1F,0xFF,0xBF,0xFF,0x00,0x00,0x7F,0xFE,0xFF,0xFC,0x00,0x01,0xFF,0xFB,0xFF,0xF0,0x00,0x07,0xFF,0xEF,0xFF,0xC0,0x00,0x1F,0xFF,0xBF,0xFF,0x00,0x00,0x7F,0xFE,0xFF,0xFC,0x00,0x01,0xFF,0xFB,0xFF,0xF0,0x00,0x07,0xFF,0xEF,0xFF,0xC0,0x00,0x1F,0xFF,0xBF,0xFF,0x00,0x00,0x7F,0xFE,0xFF,0xFC,0x00,0x01,0xFF,0xFB,0xFF,0xF0,0x00,0x07,0xFF,0xEF,0xFF,0xC0,0x00,0x1F,0xFF,0xBF,0xFF,0x00,0x00,0x7F,0xFE,0xFF,0xFC,0x00,0x01,0xFF,0xFB,0xFF,0xF0,0x00,0x07,0xFF,0xEF,0xFF,0xC0,0x00,0x1F,0xFF,0xBF,0xFF,0x00,0x00,0x7F,0xFE,0xFF,0xFC,0x00,0x01,0xFF,0xFB,0xFF,0xF0,0x00,0x07,0xFF,0xEF,0xFF,0xC0,0x00,0x1F,0xFF,0xBF,0xFF,0x00,0x00,0x7F,0xFE,0xFF,0xFC,0x00,0x01,0xFF,0xFB,0xFF,0xF0,0x00,0x07,0xFF,0xE7,0xFF,0xE0,0x00,0x3F,0xFF,0x1F,0xFF,0x80,0x00,0xFF,0xFC,0x7F,0xFF,0x00,0x07,0xFF,0xF1,0xFF,0xFE,0x00,0x3F,0xFF,0xC3,0xFF,0xFE,0x03,0xFF,0xFE,0x0F,0xFF,0xFF,0xFF,0xFF,0xF8,0x1F,0xFF,0xFF,0xFF,0xFF,0xC0,0x7F,0xFF,0xFF,0xFF,0xFE,0x00,0xFF,0xFF,0xFF,0xFF,0xF8,0x01,0xFF,0xFF,0xFF,0xFF,0xC0,0x03,0xFF,0xFF,0xFF,0xFE,0x00,0x07,0xFF,0xFF,0xFF,0xF0,0x00,0x07,0xFF,0xFF,0xFF,0x00,0x00,0x0F,0xFF,0xFF,0xF8,0x00,0x00,0x07,0xFF,0xFF,0x00,0x00,0x00,0x01,0xFF,0xC0,0x00,0x00, // 'U'
|
||||
0xFF,0xFE,0x00,0x00,0x03,0xFF,0xFB,0xFF,0xFC,0x00,0x00,0x1F,0xFF,0xE7,0xFF,0xF0,0x00,0x00,0x7F,0xFF,0x1F,0xFF,0xC0,0x00,0x01,0xFF,0xFC,0x7F,0xFF,0x00,0x00,0x07,0xFF,0xF0,0xFF,0xFE,0x00,0x00,0x3F,0xFF,0x83,0xFF,0xF8,0x00,0x00,0xFF,0xFE,0x0F,0xFF,0xE0,0x00,0x03,0xFF,0xF8,0x1F,0xFF,0x80,0x00,0x1F,0xFF,0xC0,0x7F,0xFF,0x00,0x00,0x7F,0xFF,0x01,0xFF,0xFC,0x00,0x01,0xFF,0xFC,0x03,0xFF,0xF0,0x00,0x07,0xFF,0xE0,0x0F,0xFF,0xE0,0x00,0x3F,0xFF,0x80,0x3F,0xFF,0x80,0x00,0xFF,0xFE,0x00,0x7F,0xFE,0x00,0x03,0xFF,0xF0,0x01,0xFF,0xF8,0x00,0x0F,0xFF,0xC0,0x07,0xFF,0xF0,0x00,0x7F,0xFF,0x00,0x0F,0xFF,0xC0,0x01,0xFF,0xF8,0x00,0x3F,0xFF,0x00,0x07,0xFF,0xE0,0x00,0xFF,0xFC,0x00,0x3F,0xFF,0x80,0x01,0xFF,0xF8,0x00,0xFF,0xFC,0x00,0x07,0xFF,0xE0,0x03,0xFF,0xF0,0x00,0x1F,0xFF,0x80,0x0F,0xFF,0xC0,0x00,0x3F,0xFF,0x00,0x7F,0xFE,0x00,0x00,0xFF,0xFC,0x01,0xFF,0xF8,0x00,0x03,0xFF,0xF0,0x07,0xFF,0xE0,0x00,0x07,0xFF,0xC0,0x1F,0xFF,0x00,0x00,0x1F,0xFF,0x80,0xFF,0xFC,0x00,0x00,0x7F,0xFE,0x03,0xFF,0xF0,0x00,0x00,0xFF,0xF8,0x0F,0xFF,0x80,0x00,0x03,0xFF,0xE0,0x7F,0xFE,0x00,0x00,0x0F,0xFF,0xC1,0xFF,0xF8,0x00,0x00,0x1F,0xFF,0x07,0xFF,0xC0,0x00,0x00,0x7F,0xFC,0x1F,0xFF,0x00,0x00,0x01,0xFF,0xF8,0xFF,0xFC,0x00,0x00,0x03,0xFF,0xE3,0xFF,0xE0,0x00,0x00,0x0F,0xFF,0x8F,0xFF,0x80,0x00,0x00,0x3F,0xFE,0x3F,0xFC,0x00,0x00,0x00,0x7F,0xFD,0xFF,0xF0,0x00,0x00,0x01,0xFF,0xF7,0xFF,0xC0,0x00,0x00,0x07,0xFF,0xDF,0xFE,0x00,0x00,0x00,0x0F,0xFF,0xFF,0xF8,0x00,0x00,0x00,0x3F,0xFF,0xFF,0xE0,0x00,0x00,0x00,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x01,0xFF,0xFF,0xFC,0x00,0x00,0x00,0x07,0xFF,0xFF,0xF0,0x00,0x00,0x00,0x1F,0xFF,0xFF,0x80,0x00,0x00,0x00,0x3F,0xFF,0xFE,0x00,0x00,0x00,0x00,0xFF,0xFF,0xF8,0x00,0x00,0x00,0x03,0xFF,0xFF,0xC0,0x00,0x00,0x00,0x07,0xFF,0xFF,0x00,0x00,0x00,0x00,0x1F,0xFF,0xFC,0x00,0x00,0x00,0x00,0x7F,0xFF,0xE0,0x00,0x00,0x00,0x00,0xFF,0xFF,0x80,0x00,0x00,0x00,0x03,0xFF,0xFE,0x00,0x00,0x00,0x00,0x0F,0xFF,0xF0,0x00,0x00,0x00,0x00,0x1F,0xFF,0xC0,0x00,0x00, // 'V'
|
||||
0xFF,0xFC,0x00,0x0F,0xFF,0x00,0x03,0xFF,0xF7,0xFF,0xE0,0x00,0x7F,0xF8,0x00,0x1F,0xFF,0x1F,0xFF,0x00,0x07,0xFF,0xC0,0x00,0xFF,0xF8,0xFF,0xF8,0x00,0x3F,0xFE,0x00,0x0F,0xFF,0xC7,0xFF,0xC0,0x01,0xFF,0xF8,0x00,0x7F,0xFE,0x3F,0xFF,0x00,0x0F,0xFF,0xC0,0x03,0xFF,0xF1,0xFF,0xF8,0x00,0x7F,0xFE,0x00,0x1F,0xFF,0x07,0xFF,0xC0,0x07,0xFF,0xF0,0x00,0xFF,0xF8,0x3F,0xFE,0x00,0x3F,0xFF,0xC0,0x07,0xFF,0xC1,0xFF,0xF0,0x01,0xFF,0xFE,0x00,0x7F,0xFE,0x0F,0xFF,0xC0,0x0F,0xFF,0xF0,0x03,0xFF,0xE0,0x7F,0xFE,0x00,0xFF,0xFF,0x80,0x1F,0xFF,0x01,0xFF,0xF0,0x07,0xFF,0xFC,0x00,0xFF,0xF8,0x0F,0xFF,0x80,0x3F,0xFF,0xF0,0x07,0xFF,0xC0,0x7F,0xFC,0x01,0xFF,0xFF,0x80,0x7F,0xFE,0x03,0xFF,0xF0,0x0F,0xFF,0xFC,0x03,0xFF,0xE0,0x0F,0xFF,0x80,0xFF,0xFF,0xE0,0x1F,0xFF,0x00,0x7F,0xFC,0x07,0xFF,0xFF,0x80,0xFF,0xF8,0x03,0xFF,0xE0,0x3F,0xFF,0xFC,0x07,0xFF,0xC0,0x1F,0xFF,0x01,0xFF,0xFF,0xE0,0x3F,0xFE,0x00,0xFF,0xF8,0x0F,0xFF,0xFF,0x03,0xFF,0xE0,0x03,0xFF,0xE0,0xFF,0xFF,0xF8,0x1F,0xFF,0x00,0x1F,0xFF,0x07,0xFF,0xFF,0xE0,0xFF,0xF8,0x00,0xFF,0xF8,0x3F,0xFF,0xFF,0x07,0xFF,0xC0,0x07,0xFF,0xC1,0xFF,0xFF,0xF8,0x3F,0xFE,0x00,0x3F,0xFE,0x1F,0xFF,0xFF,0xC3,0xFF,0xE0,0x00,0xFF,0xF8,0xFF,0xEF,0xFF,0x1F,0xFF,0x00,0x07,0xFF,0xC7,0xFF,0x3F,0xF8,0xFF,0xF8,0x00,0x3F,0xFE,0x3F,0xF9,0xFF,0xC7,0xFF,0xC0,0x01,0xFF,0xF1,0xFF,0xCF,0xFE,0x3F,0xFC,0x00,0x07,0xFF,0x9F,0xFC,0x7F,0xF1,0xFF,0xE0,0x00,0x3F,0xFC,0xFF,0xE3,0xFF,0xDF,0xFF,0x00,0x01,0xFF,0xF7,0xFF,0x0F,0xFE,0xFF,0xF8,0x00,0x0F,0xFF,0xBF,0xF8,0x7F,0xF7,0xFF,0xC0,0x00,0x7F,0xFF,0xFF,0xC3,0xFF,0xBF,0xFC,0x00,0x01,0xFF,0xFF,0xFC,0x1F,0xFF,0xFF,0xE0,0x00,0x0F,0xFF,0xFF,0xE0,0x7F,0xFF,0xFF,0x00,0x00,0x7F,0xFF,0xFF,0x03,0xFF,0xFF,0xF8,0x00,0x03,0xFF,0xFF,0xF8,0x1F,0xFF,0xFF,0xC0,0x00,0x1F,0xFF,0xFF,0x80,0xFF,0xFF,0xFC,0x00,0x00,0x7F,0xFF,0xFC,0x03,0xFF,0xFF,0xE0,0x00,0x03,0xFF,0xFF,0xE0,0x1F,0xFF,0xFF,0x00,0x00,0x1F,0xFF,0xFF,0x00,0xFF,0xFF,0xF8,0x00,0x00,0xFF,0xFF,0xF0,0x07,0xFF,0xFF,0x80,0x00,0x07,0xFF,0xFF,0x80,0x3F,0xFF,0xFC,0x00,0x00,0x1F,0xFF,0xFC,0x00,0xFF,0xFF,0xE0,0x00,0x00,0xFF,0xFF,0xE0,0x07,0xFF,0xFF,0x00,0x00,0x07,0xFF,0xFF,0x00,0x3F,0xFF,0xF8,0x00,0x00,0x3F,0xFF,0xF0,0x01,0xFF,0xFF,0x80,0x00,0x00,0xFF,0xFF,0x80,0x07,0xFF,0xFC,0x00,0x00,0x07,0xFF,0xFC,0x00,0x3F,0xFF,0xE0,0x00,0x00,0x3F,0xFF,0xE0,0x01,0xFF,0xFF,0x00,0x00,0x01,0xFF,0xFE,0x00,0x0F,0xFF,0xF8,0x00,0x00,0x0F,0xFF,0xF0,0x00,0x3F,0xFF,0x80,0x00,0x00,0x3F,0xFF,0x80,0x01,0xFF,0xFC,0x00,0x00,0x01,0xFF,0xFC,0x00,0x0F,0xFF,0xE0,0x00,0x00,0x0F,0xFF,0xC0,0x00,0x7F,0xFF,0x00,0x00, // 'W'
|
||||
0x7F,0xFF,0x00,0x00,0x1F,0xFF,0xC7,0xFF,0xF8,0x00,0x03,0xFF,0xFC,0x3F,0xFF,0x80,0x00,0x3F,0xFF,0x81,0xFF,0xFC,0x00,0x07,0xFF,0xF8,0x1F,0xFF,0xC0,0x00,0x7F,0xFF,0x00,0xFF,0xFE,0x00,0x0F,0xFF,0xE0,0x0F,0xFF,0xE0,0x00,0xFF,0xFE,0x00,0x7F,0xFF,0x00,0x1F,0xFF,0xC0,0x07,0xFF,0xF0,0x01,0xFF,0xFC,0x00,0x3F,0xFF,0x80,0x3F,0xFF,0x80,0x03,0xFF,0xF8,0x03,0xFF,0xF8,0x00,0x1F,0xFF,0xC0,0x7F,0xFF,0x00,0x00,0xFF,0xFC,0x07,0xFF,0xE0,0x00,0x0F,0xFF,0xE0,0xFF,0xFE,0x00,0x00,0x7F,0xFE,0x0F,0xFF,0xC0,0x00,0x07,0xFF,0xF1,0xFF,0xFC,0x00,0x00,0x3F,0xFF,0x1F,0xFF,0x80,0x00,0x03,0xFF,0xFB,0xFF,0xF8,0x00,0x00,0x1F,0xFF,0xBF,0xFF,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xF0,0x00,0x00,0x0F,0xFF,0xFF,0xFE,0x00,0x00,0x00,0x7F,0xFF,0xFF,0xC0,0x00,0x00,0x07,0xFF,0xFF,0xFC,0x00,0x00,0x00,0x3F,0xFF,0xFF,0x80,0x00,0x00,0x03,0xFF,0xFF,0xF8,0x00,0x00,0x00,0x1F,0xFF,0xFF,0x00,0x00,0x00,0x01,0xFF,0xFF,0xF0,0x00,0x00,0x00,0x0F,0xFF,0xFE,0x00,0x00,0x00,0x00,0xFF,0xFF,0xE0,0x00,0x00,0x00,0x0F,0xFF,0xFE,0x00,0x00,0x00,0x01,0xFF,0xFF,0xF0,0x00,0x00,0x00,0x1F,0xFF,0xFF,0x00,0x00,0x00,0x03,0xFF,0xFF,0xF8,0x00,0x00,0x00,0x7F,0xFF,0xFF,0xC0,0x00,0x00,0x07,0xFF,0xFF,0xFC,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xE0,0x00,0x00,0x0F,0xFF,0xFF,0xFE,0x00,0x00,0x01,0xFF,0xFF,0xFF,0xF0,0x00,0x00,0x1F,0xFF,0xBF,0xFF,0x00,0x00,0x03,0xFF,0xFB,0xFF,0xF8,0x00,0x00,0x7F,0xFF,0x1F,0xFF,0xC0,0x00,0x07,0xFF,0xF1,0xFF,0xFC,0x00,0x00,0xFF,0xFE,0x0F,0xFF,0xE0,0x00,0x0F,0xFF,0xE0,0xFF,0xFE,0x00,0x01,0xFF,0xFC,0x07,0xFF,0xF0,0x00,0x1F,0xFF,0xC0,0x7F,0xFF,0x00,0x03,0xFF,0xF8,0x03,0xFF,0xF8,0x00,0x3F,0xFF,0x80,0x3F,0xFF,0xC0,0x07,0xFF,0xF0,0x01,0xFF,0xFC,0x00,0xFF,0xFF,0x00,0x1F,0xFF,0xE0,0x0F,0xFF,0xE0,0x00,0xFF,0xFE,0x01,0xFF,0xFE,0x00,0x0F,0xFF,0xF0,0x1F,0xFF,0xC0,0x00,0x7F,0xFF,0x03,0xFF,0xFC,0x00,0x07,0xFF,0xF8,0x3F,0xFF,0x80,0x00,0x3F,0xFF,0x87,0xFF,0xF8,0x00,0x03,0xFF,0xFC,0xFF,0xFF,0x00,0x00,0x1F,0xFF,0xE0, // 'X'
|
||||
0xFF,0xFE,0x00,0x00,0x1F,0xFF,0xCF,0xFF,0xC0,0x00,0x03,0xFF,0xF9,0xFF,0xFC,0x00,0x00,0x7F,0xFE,0x1F,0xFF,0x80,0x00,0x1F,0xFF,0xC3,0xFF,0xF8,0x00,0x03,0xFF,0xF0,0x3F,0xFF,0x00,0x00,0xFF,0xFE,0x07,0xFF,0xE0,0x00,0x1F,0xFF,0x80,0x7F,0xFE,0x00,0x07,0xFF,0xF0,0x0F,0xFF,0xC0,0x00,0xFF,0xFC,0x00,0xFF,0xFC,0x00,0x1F,0xFF,0x80,0x1F,0xFF,0x80,0x07,0xFF,0xE0,0x01,0xFF,0xF8,0x00,0xFF,0xFC,0x00,0x3F,0xFF,0x00,0x3F,0xFF,0x00,0x03,0xFF,0xE0,0x07,0xFF,0xE0,0x00,0x7F,0xFE,0x01,0xFF,0xF8,0x00,0x07,0xFF,0xC0,0x3F,0xFF,0x00,0x00,0xFF,0xFC,0x07,0xFF,0xC0,0x00,0x0F,0xFF,0x81,0xFF,0xF8,0x00,0x01,0xFF,0xF0,0x3F,0xFE,0x00,0x00,0x1F,0xFF,0x0F,0xFF,0xC0,0x00,0x03,0xFF,0xE1,0xFF,0xF0,0x00,0x00,0x3F,0xFE,0x7F,0xFE,0x00,0x00,0x07,0xFF,0xCF,0xFF,0x80,0x00,0x00,0x7F,0xFD,0xFF,0xF0,0x00,0x00,0x0F,0xFF,0xFF,0xFC,0x00,0x00,0x00,0xFF,0xFF,0xFF,0x80,0x00,0x00,0x1F,0xFF,0xFF,0xE0,0x00,0x00,0x01,0xFF,0xFF,0xFC,0x00,0x00,0x00,0x3F,0xFF,0xFF,0x00,0x00,0x00,0x03,0xFF,0xFF,0xE0,0x00,0x00,0x00,0x7F,0xFF,0xF8,0x00,0x00,0x00,0x07,0xFF,0xFF,0x00,0x00,0x00,0x00,0xFF,0xFF,0xC0,0x00,0x00,0x00,0x0F,0xFF,0xF8,0x00,0x00,0x00,0x01,0xFF,0xFE,0x00,0x00,0x00,0x00,0x1F,0xFF,0xC0,0x00,0x00,0x00,0x03,0xFF,0xF0,0x00,0x00,0x00,0x00,0x7F,0xFE,0x00,0x00,0x00,0x00,0x0F,0xFF,0xC0,0x00,0x00,0x00,0x01,0xFF,0xF8,0x00,0x00,0x00,0x00,0x3F,0xFF,0x00,0x00,0x00,0x00,0x07,0xFF,0xE0,0x00,0x00,0x00,0x00,0xFF,0xFC,0x00,0x00,0x00,0x00,0x1F,0xFF,0x80,0x00,0x00,0x00,0x03,0xFF,0xF0,0x00,0x00,0x00,0x00,0x7F,0xFE,0x00,0x00,0x00,0x00,0x0F,0xFF,0xC0,0x00,0x00,0x00,0x01,0xFF,0xF8,0x00,0x00,0x00,0x00,0x3F,0xFF,0x00,0x00,0x00,0x00,0x07,0xFF,0xE0,0x00,0x00,0x00,0x00,0xFF,0xFC,0x00,0x00,0x00,0x00,0x1F,0xFF,0x80,0x00,0x00,0x00,0x03,0xFF,0xF0,0x00,0x00,0x00,0x00,0x7F,0xFE,0x00,0x00,0x00,0x00,0x0F,0xFF,0xC0,0x00,0x00,0x00,0x01,0xFF,0xF8,0x00,0x00,0x00,0x00,0x3F,0xFF,0x00,0x00,0x00, // 'Y'
|
||||
0xFF,0xFF,0xFF,0xFF,0xFF,0xFB,0xFF,0xFF,0xFF,0xFF,0xFF,0xEF,0xFF,0xFF,0xFF,0xFF,0xFF,0xBF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFB,0xFF,0xFF,0xFF,0xFF,0xFF,0xEF,0xFF,0xFF,0xFF,0xFF,0xFF,0xBF,0xFF,0xFF,0xFF,0xFF,0xFC,0xFF,0xFF,0xFF,0xFF,0xFF,0xE3,0xFF,0xFF,0xFF,0xFF,0xFF,0x80,0x00,0x00,0x01,0xFF,0xFC,0x00,0x00,0x00,0x07,0xFF,0xE0,0x00,0x00,0x00,0x3F,0xFF,0x80,0x00,0x00,0x01,0xFF,0xFC,0x00,0x00,0x00,0x07,0xFF,0xE0,0x00,0x00,0x00,0x3F,0xFF,0x80,0x00,0x00,0x01,0xFF,0xFC,0x00,0x00,0x00,0x07,0xFF,0xE0,0x00,0x00,0x00,0x3F,0xFF,0x80,0x00,0x00,0x01,0xFF,0xFC,0x00,0x00,0x00,0x07,0xFF,0xE0,0x00,0x00,0x00,0x3F,0xFF,0x80,0x00,0x00,0x01,0xFF,0xFC,0x00,0x00,0x00,0x07,0xFF,0xE0,0x00,0x00,0x00,0x3F,0xFF,0x80,0x00,0x00,0x01,0xFF,0xFC,0x00,0x00,0x00,0x07,0xFF,0xE0,0x00,0x00,0x00,0x3F,0xFF,0x80,0x00,0x00,0x01,0xFF,0xFC,0x00,0x00,0x00,0x07,0xFF,0xE0,0x00,0x00,0x00,0x3F,0xFF,0x80,0x00,0x00,0x01,0xFF,0xFC,0x00,0x00,0x00,0x0F,0xFF,0xE0,0x00,0x00,0x00,0x3F,0xFF,0x80,0x00,0x00,0x01,0xFF,0xFC,0x00,0x00,0x00,0x0F,0xFF,0xE0,0x00,0x00,0x00,0x3F,0xFF,0x80,0x00,0x00,0x01,0xFF,0xFC,0x00,0x00,0x00,0x0F,0xFF,0xE0,0x00,0x00,0x00,0x3F,0xFF,0x80,0x00,0x00,0x01,0xFF,0xFC,0x00,0x00,0x00,0x0F,0xFF,0xE0,0x00,0x00,0x00,0x3F,0xFF,0x80,0x00,0x00,0x01,0xFF,0xFC,0x00,0x00,0x00,0x0F,0xFF,0xE0,0x00,0x00,0x00,0x3F,0xFF,0x80,0x00,0x00,0x01,0xFF,0xFC,0x00,0x00,0x00,0x0F,0xFF,0xFF,0xFF,0xFF,0xFE,0x3F,0xFF,0xFF,0xFF,0xFF,0xF9,0xFF,0xFF,0xFF,0xFF,0xFF,0xE7,0xFF,0xFF,0xFF,0xFF,0xFF,0x9F,0xFF,0xFF,0xFF,0xFF,0xFE,0x7F,0xFF,0xFF,0xFF,0xFF,0xF9,0xFF,0xFF,0xFF,0xFF,0xFF,0xE7,0xFF,0xFF,0xFF,0xFF,0xFF,0x9F,0xFF,0xFF,0xFF,0xFF,0xFE,0x7F,0xFF,0xFF,0xFF,0xFF,0xF8, // 'Z'
|
||||
0xFF,0xFF,0xDF,0xFF,0xFB,0xFF,0xFF,0x7F,0xFF,0xEF,0xFF,0xFD,0xFF,0xFF,0xBF,0xFF,0xF7,0xFF,0xFE,0xFF,0xFF,0xDF,0xFF,0xFB,0xFF,0xE0,0x7F,0xFC,0x0F,0xFF,0x81,0xFF,0xF0,0x3F,0xFE,0x07,0xFF,0xC0,0xFF,0xF8,0x1F,0xFF,0x03,0xFF,0xE0,0x7F,0xFC,0x0F,0xFF,0x81,0xFF,0xF0,0x3F,0xFE,0x07,0xFF,0xC0,0xFF,0xF8,0x1F,0xFF,0x03,0xFF,0xE0,0x7F,0xFC,0x0F,0xFF,0x81,0xFF,0xF0,0x3F,0xFE,0x07,0xFF,0xC0,0xFF,0xF8,0x1F,0xFF,0x03,0xFF,0xE0,0x7F,0xFC,0x0F,0xFF,0x81,0xFF,0xF0,0x3F,0xFE,0x07,0xFF,0xC0,0xFF,0xF8,0x1F,0xFF,0x03,0xFF,0xE0,0x7F,0xFC,0x0F,0xFF,0x81,0xFF,0xF0,0x3F,0xFE,0x07,0xFF,0xC0,0xFF,0xF8,0x1F,0xFF,0x03,0xFF,0xE0,0x7F,0xFC,0x0F,0xFF,0x81,0xFF,0xF0,0x3F,0xFE,0x07,0xFF,0xC0,0xFF,0xF8,0x1F,0xFF,0x03,0xFF,0xE0,0x7F,0xFC,0x0F,0xFF,0x81,0xFF,0xF0,0x3F,0xFE,0x07,0xFF,0xC0,0xFF,0xF8,0x1F,0xFF,0x03,0xFF,0xE0,0x7F,0xFC,0x0F,0xFF,0x81,0xFF,0xF0,0x3F,0xFE,0x07,0xFF,0xFE,0xFF,0xFF,0xDF,0xFF,0xFB,0xFF,0xFF,0x7F,0xFF,0xEF,0xFF,0xFD,0xFF,0xFF,0xBF,0xFF,0xF7,0xFF,0xFE,0xFF,0xFF,0xC0, // '['
|
||||
0xFF,0xFC,0x00,0x00,0x00,0xFF,0xFC,0x00,0x00,0x01,0xFF,0xF8,0x00,0x00,0x01,0xFF,0xF0,0x00,0x00,0x03,0xFF,0xF0,0x00,0x00,0x07,0xFF,0xE0,0x00,0x00,0x07,0xFF,0xC0,0x00,0x00,0x0F,0xFF,0xC0,0x00,0x00,0x1F,0xFF,0x80,0x00,0x00,0x1F,0xFF,0x80,0x00,0x00,0x3F,0xFF,0x00,0x00,0x00,0x3F,0xFE,0x00,0x00,0x00,0x7F,0xFE,0x00,0x00,0x00,0xFF,0xFC,0x00,0x00,0x00,0xFF,0xF8,0x00,0x00,0x01,0xFF,0xF8,0x00,0x00,0x01,0xFF,0xF0,0x00,0x00,0x03,0xFF,0xF0,0x00,0x00,0x07,0xFF,0xE0,0x00,0x00,0x07,0xFF,0xC0,0x00,0x00,0x0F,0xFF,0xC0,0x00,0x00,0x1F,0xFF,0x80,0x00,0x00,0x1F,0xFF,0x80,0x00,0x00,0x3F,0xFF,0x00,0x00,0x00,0x3F,0xFE,0x00,0x00,0x00,0x7F,0xFE,0x00,0x00,0x00,0xFF,0xFC,0x00,0x00,0x00,0xFF,0xF8,0x00,0x00,0x01,0xFF,0xF8,0x00,0x00,0x03,0xFF,0xF0,0x00,0x00,0x03,0xFF,0xF0,0x00,0x00,0x07,0xFF,0xE0,0x00,0x00,0x07,0xFF,0xC0,0x00,0x00,0x0F,0xFF,0xC0,0x00,0x00,0x1F,0xFF,0x80,0x00,0x00,0x1F,0xFF,0x80,0x00,0x00,0x3F,0xFF,0x00,0x00,0x00,0x3F,0xFE,0x00,0x00,0x00,0x7F,0xFE,0x00,0x00,0x00,0xFF,0xFC,0x00,0x00,0x00,0xFF,0xF8,0x00,0x00,0x01,0xFF,0xF8,0x00,0x00,0x03,0xFF,0xF0,0x00,0x00,0x03,0xFF,0xF0,0x00,0x00,0x07,0xFF,0xE0,0x00,0x00,0x07,0xFF,0xC0,0x00,0x00,0x0F,0xFF,0xC0,0x00,0x00,0x1F,0xFF,0x80,0x00,0x00,0x1F,0xFF,0x80,0x00,0x00,0x3F,0xFF,0x00,0x00,0x00,0x3F,0xFE,0x00,0x00,0x00,0x7F,0xFE,0x00,0x00,0x00,0xFF,0xFC,0x00,0x00,0x00,0xFF,0xF8,0x00,0x00,0x01,0xFF,0xF8,0x00,0x00,0x03,0xFF,0xF0,0x00,0x00,0x03,0xFF,0xF0,0x00,0x00,0x07,0xFF,0xE0,0x00,0x00,0x07,0xFF,0xC0,0x00,0x00,0x0F,0xFF,0xC0,0x00,0x00,0x1F,0xFF,0x80,0x00,0x00,0x1F,0xFF,0x80, // '\'
|
||||
0xFF,0xFF,0xBF,0xFF,0xEF,0xFF,0xFB,0xFF,0xFE,0xFF,0xFF,0xBF,0xFF,0xEF,0xFF,0xFB,0xFF,0xFE,0xFF,0xFF,0xBF,0xFF,0xE0,0xFF,0xF8,0x3F,0xFE,0x0F,0xFF,0x83,0xFF,0xE0,0xFF,0xF8,0x3F,0xFE,0x0F,0xFF,0x83,0xFF,0xE0,0xFF,0xF8,0x3F,0xFE,0x0F,0xFF,0x83,0xFF,0xE0,0xFF,0xF8,0x3F,0xFE,0x0F,0xFF,0x83,0xFF,0xE0,0xFF,0xF8,0x3F,0xFE,0x0F,0xFF,0x83,0xFF,0xE0,0xFF,0xF8,0x3F,0xFE,0x0F,0xFF,0x83,0xFF,0xE0,0xFF,0xF8,0x3F,0xFE,0x0F,0xFF,0x83,0xFF,0xE0,0xFF,0xF8,0x3F,0xFE,0x0F,0xFF,0x83,0xFF,0xE0,0xFF,0xF8,0x3F,0xFE,0x0F,0xFF,0x83,0xFF,0xE0,0xFF,0xF8,0x3F,0xFE,0x0F,0xFF,0x83,0xFF,0xE0,0xFF,0xF8,0x3F,0xFE,0x0F,0xFF,0x83,0xFF,0xE0,0xFF,0xF8,0x3F,0xFE,0x0F,0xFF,0x83,0xFF,0xE0,0xFF,0xF8,0x3F,0xFE,0x0F,0xFF,0x83,0xFF,0xE0,0xFF,0xF8,0x3F,0xFE,0x0F,0xFF,0x83,0xFF,0xE0,0xFF,0xF8,0x3F,0xFE,0x0F,0xFF,0x83,0xFF,0xE0,0xFF,0xFB,0xFF,0xFE,0xFF,0xFF,0xBF,0xFF,0xEF,0xFF,0xFB,0xFF,0xFE,0xFF,0xFF,0xBF,0xFF,0xEF,0xFF,0xFB,0xFF,0xFE,0xFF,0xFF,0x80, // ']'
|
||||
0x00,0x1F,0xF8,0x00,0x00,0x07,0xFF,0x00,0x00,0x03,0xFF,0xC0,0x00,0x00,0xFF,0xF0,0x00,0x00,0x7F,0xFE,0x00,0x00,0x1F,0xFF,0x80,0x00,0x0F,0xFF,0xF0,0x00,0x03,0xFF,0xFC,0x00,0x00,0xFF,0xFF,0x00,0x00,0x7F,0xFF,0xE0,0x00,0x1F,0xFF,0xF8,0x00,0x0F,0xFF,0xFF,0x00,0x03,0xFE,0x7F,0xC0,0x00,0xFF,0x9F,0xF8,0x00,0x7F,0xE3,0xFE,0x00,0x1F,0xF0,0xFF,0x80,0x0F,0xFC,0x3F,0xF0,0x03,0xFE,0x07,0xFC,0x01,0xFF,0x81,0xFF,0x80,0x7F,0xE0,0x7F,0xE0,0x1F,0xF0,0x0F,0xF8,0x0F,0xFC,0x03,0xFF,0x03,0xFF,0x00,0x7F,0xC1,0xFF,0x80,0x1F,0xF8,0x7F,0xE0,0x07,0xFE,0x1F,0xF0,0x00,0xFF,0xCF,0xFC,0x00,0x3F,0xF3,0xFF,0x00,0x07,0xFE, // '^'
|
||||
0xFF,0xFF,0xFF,0xFF,0xEF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0xEF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0xEF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0xEF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0xEF,0xFF,0xFF,0xFF,0xFE, // '_'
|
||||
0xFF,0xFC,0x00,0xFF,0xFC,0x00,0xFF,0xFC,0x00,0xFF,0xF8,0x00,0xFF,0xF8,0x00,0xFF,0xF8,0x00,0xFF,0xF0,0x00,0xFF,0xF0,0x00,0xFF,0xF0,0x00,0xFF,0xE0,0x00,0xFF,0xE0,0x00,0xFF,0xE0, // '`'
|
||||
0x00,0x03,0xFF,0x80,0x00,0x00,0x3F,0xFF,0xF0,0x00,0x00,0xFF,0xFF,0xFC,0x00,0x03,0xFF,0xFF,0xFE,0x00,0x07,0xFF,0xFF,0xFF,0x80,0x0F,0xFF,0xFF,0xFF,0xC0,0x1F,0xFF,0xFF,0xFF,0xC0,0x3F,0xFF,0xFF,0xFF,0xE0,0x3F,0xFF,0xFF,0xFF,0xF0,0x7F,0xFF,0x07,0xFF,0xF0,0x7F,0xFE,0x03,0xFF,0xF0,0x7F,0xFC,0x01,0xFF,0xF8,0x7F,0xFC,0x01,0xFF,0xF8,0x7F,0xFC,0x00,0xFF,0xF8,0x00,0x00,0x00,0xFF,0xF8,0x00,0x00,0x00,0xFF,0xF8,0x00,0x00,0x00,0xFF,0xF8,0x00,0x07,0xFF,0xFF,0xF8,0x00,0x7F,0xFF,0xFF,0xF8,0x01,0xFF,0xFF,0xFF,0xF8,0x07,0xFF,0xFF,0xFF,0xF8,0x0F,0xFF,0xFF,0xFF,0xF8,0x1F,0xFF,0xFF,0xFF,0xF8,0x3F,0xFF,0xFF,0xFF,0xF8,0x7F,0xFF,0xFF,0xFF,0xF8,0x7F,0xFF,0x80,0xFF,0xF8,0xFF,0xFE,0x00,0xFF,0xF8,0xFF,0xFC,0x00,0xFF,0xF8,0xFF,0xF8,0x00,0xFF,0xF8,0xFF,0xF8,0x00,0xFF,0xF8,0xFF,0xF8,0x00,0xFF,0xF8,0xFF,0xF8,0x00,0xFF,0xF8,0xFF,0xF8,0x01,0xFF,0xF8,0xFF,0xFC,0x03,0xFF,0xF8,0xFF,0xFE,0x0F,0xFF,0xF8,0x7F,0xFF,0xFF,0xFF,0xF8,0x7F,0xFF,0xFF,0xFF,0xF8,0x7F,0xFF,0xFF,0xFF,0xF8,0x3F,0xFF,0xFF,0xFF,0xF8,0x1F,0xFF,0xFF,0xFF,0xFC,0x0F,0xFF,0xFE,0xFF,0xFC,0x07,0xFF,0xFC,0x7F,0xFC,0x01,0xFF,0xF8,0x7F,0xFE,0x00,0x3F,0xC0,0x00,0x00, // 'a'
|
||||
0xFF,0xF8,0x00,0x00,0x00,0xFF,0xF8,0x00,0x00,0x00,0xFF,0xF8,0x00,0x00,0x00,0xFF,0xF8,0x00,0x00,0x00,0xFF,0xF8,0x00,0x00,0x00,0xFF,0xF8,0x00,0x00,0x00,0xFF,0xF8,0x00,0x00,0x00,0xFF,0xF8,0x00,0x00,0x00,0xFF,0xF8,0x00,0x00,0x00,0xFF,0xF8,0x00,0x00,0x00,0xFF,0xF8,0x00,0x00,0x00,0xFF,0xF8,0x00,0x00,0x00,0xFF,0xF8,0x00,0x00,0x00,0xFF,0xF8,0x00,0x00,0x00,0xFF,0xF8,0x00,0x00,0x00,0xFF,0xF8,0x00,0x00,0x00,0xFF,0xF8,0x00,0x00,0x00,0xFF,0xF8,0x1F,0xE0,0x00,0xFF,0xF8,0xFF,0xFC,0x00,0xFF,0xF9,0xFF,0xFE,0x00,0xFF,0xFB,0xFF,0xFF,0x80,0xFF,0xFF,0xFF,0xFF,0xC0,0xFF,0xFF,0xFF,0xFF,0xC0,0xFF,0xFF,0xFF,0xFF,0xE0,0xFF,0xFF,0xFF,0xFF,0xF0,0xFF,0xFF,0xFF,0xFF,0xF0,0xFF,0xFF,0xFF,0xFF,0xF8,0xFF,0xFF,0x03,0xFF,0xF8,0xFF,0xFC,0x01,0xFF,0xFC,0xFF,0xFC,0x00,0xFF,0xFC,0xFF,0xF8,0x00,0x7F,0xFC,0xFF,0xF8,0x00,0x7F,0xFC,0xFF,0xF8,0x00,0x7F,0xFC,0xFF,0xF8,0x00,0x7F,0xFE,0xFF,0xF8,0x00,0x7F,0xFE,0xFF,0xF8,0x00,0x3F,0xFE,0xFF,0xF8,0x00,0x3F,0xFE,0xFF,0xF8,0x00,0x3F,0xFE,0xFF,0xF8,0x00,0x3F,0xFE,0xFF,0xF8,0x00,0x3F,0xFE,0xFF,0xF8,0x00,0x3F,0xFE,0xFF,0xF8,0x00,0x3F,0xFE,0xFF,0xF8,0x00,0x3F,0xFE,0xFF,0xF8,0x00,0x3F,0xFE,0xFF,0xF8,0x00,0x7F,0xFE,0xFF,0xF8,0x00,0x7F,0xFC,0xFF,0xF8,0x00,0x7F,0xFC,0xFF,0xF8,0x00,0x7F,0xFC,0xFF,0xF8,0x00,0xFF,0xFC,0xFF,0xFC,0x01,0xFF,0xFC,0xFF,0xFF,0x03,0xFF,0xF8,0xFF,0xFF,0xFF,0xFF,0xF8,0xFF,0xFF,0xFF,0xFF,0xF0,0xFF,0xFF,0xFF,0xFF,0xF0,0xFF,0xFF,0xFF,0xFF,0xE0,0xFF,0xFF,0xFF,0xFF,0xE0,0xFF,0xF7,0xFF,0xFF,0xC0,0xFF,0xF3,0xFF,0xFF,0x80,0xFF,0xF1,0xFF,0xFE,0x00,0xFF,0xF0,0xFF,0xFC,0x00,0x00,0x00,0x1F,0xE0,0x00, // 'b'
|
||||
0x00,0x01,0xFF,0x80,0x00,0x00,0x1F,0xFF,0xE0,0x00,0x00,0xFF,0xFF,0xF0,0x00,0x07,0xFF,0xFF,0xF8,0x00,0x1F,0xFF,0xFF,0xF8,0x00,0x7F,0xFF,0xFF,0xF8,0x01,0xFF,0xFF,0xFF,0xF8,0x07,0xFF,0xFF,0xFF,0xF0,0x0F,0xFF,0xFF,0xFF,0xF0,0x3F,0xFF,0xFF,0xFF,0xE0,0xFF,0xFE,0x0F,0xFF,0xE1,0xFF,0xF8,0x07,0xFF,0xC3,0xFF,0xE0,0x0F,0xFF,0x8F,0xFF,0x80,0x0F,0xFF,0x9F,0xFF,0x00,0x1F,0xFF,0x3F,0xFE,0x00,0x3F,0xFE,0x7F,0xFC,0x00,0x3F,0xFD,0xFF,0xF8,0x00,0x00,0x03,0xFF,0xF0,0x00,0x00,0x07,0xFF,0xC0,0x00,0x00,0x0F,0xFF,0x80,0x00,0x00,0x1F,0xFF,0x00,0x00,0x00,0x3F,0xFE,0x00,0x00,0x00,0x7F,0xFC,0x00,0x00,0x00,0xFF,0xF8,0x00,0x00,0x01,0xFF,0xF8,0x00,0x00,0x01,0xFF,0xF0,0x00,0x00,0x03,0xFF,0xE0,0x00,0x00,0x07,0xFF,0xC0,0x03,0xFF,0xCF,0xFF,0x80,0x0F,0xFF,0x9F,0xFF,0x00,0x1F,0xFF,0x1F,0xFF,0x00,0x3F,0xFE,0x3F,0xFF,0x00,0xFF,0xF8,0x7F,0xFF,0x07,0xFF,0xF0,0x7F,0xFF,0xFF,0xFF,0xE0,0x7F,0xFF,0xFF,0xFF,0x80,0xFF,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0xFC,0x00,0xFF,0xFF,0xFF,0xF0,0x00,0xFF,0xFF,0xFF,0xC0,0x00,0xFF,0xFF,0xFF,0x00,0x00,0x7F,0xFF,0xF8,0x00,0x00,0x3F,0xFF,0xC0,0x00,0x00,0x0F,0xFC,0x00,0x00, // 'c'
|
||||
0x00,0x00,0x00,0x3F,0xFE,0x00,0x00,0x00,0x3F,0xFE,0x00,0x00,0x00,0x3F,0xFE,0x00,0x00,0x00,0x3F,0xFE,0x00,0x00,0x00,0x3F,0xFE,0x00,0x00,0x00,0x3F,0xFE,0x00,0x00,0x00,0x3F,0xFE,0x00,0x00,0x00,0x3F,0xFE,0x00,0x00,0x00,0x3F,0xFE,0x00,0x00,0x00,0x3F,0xFE,0x00,0x00,0x00,0x3F,0xFE,0x00,0x00,0x00,0x3F,0xFE,0x00,0x00,0x00,0x3F,0xFE,0x00,0x00,0x00,0x3F,0xFE,0x00,0x00,0x00,0x3F,0xFE,0x00,0x00,0x00,0x3F,0xFE,0x00,0x00,0x00,0x3F,0xFE,0x00,0x0F,0xF0,0x3F,0xFE,0x00,0x7F,0xFC,0x3F,0xFE,0x00,0xFF,0xFF,0x3F,0xFE,0x03,0xFF,0xFF,0xBF,0xFE,0x07,0xFF,0xFF,0xFF,0xFE,0x07,0xFF,0xFF,0xFF,0xFE,0x0F,0xFF,0xFF,0xFF,0xFE,0x1F,0xFF,0xFF,0xFF,0xFE,0x1F,0xFF,0xFF,0xFF,0xFE,0x3F,0xFF,0xFF,0xFF,0xFE,0x3F,0xFF,0xC1,0xFF,0xFE,0x7F,0xFF,0x00,0xFF,0xFE,0x7F,0xFE,0x00,0x7F,0xFE,0x7F,0xFE,0x00,0x3F,0xFE,0x7F,0xFC,0x00,0x3F,0xFE,0xFF,0xFC,0x00,0x3F,0xFE,0xFF,0xFC,0x00,0x3F,0xFE,0xFF,0xF8,0x00,0x3F,0xFE,0xFF,0xF8,0x00,0x3F,0xFE,0xFF,0xF8,0x00,0x3F,0xFE,0xFF,0xF8,0x00,0x3F,0xFE,0xFF,0xF8,0x00,0x3F,0xFE,0xFF,0xF8,0x00,0x3F,0xFE,0xFF,0xF8,0x00,0x3F,0xFE,0xFF,0xF8,0x00,0x3F,0xFE,0xFF,0xF8,0x00,0x3F,0xFE,0xFF,0xF8,0x00,0x3F,0xFE,0xFF,0xFC,0x00,0x3F,0xFE,0x7F,0xFC,0x00,0x3F,0xFE,0x7F,0xFC,0x00,0x3F,0xFE,0x7F,0xFC,0x00,0x3F,0xFE,0x7F,0xFE,0x00,0x7F,0xFE,0x7F,0xFF,0x00,0xFF,0xFE,0x3F,0xFF,0x81,0xFF,0xFE,0x3F,0xFF,0xFF,0xFF,0xFE,0x1F,0xFF,0xFF,0xFF,0xFE,0x1F,0xFF,0xFF,0xFF,0xFE,0x0F,0xFF,0xFF,0xFF,0xFE,0x07,0xFF,0xFF,0xFF,0xFE,0x07,0xFF,0xFF,0xDF,0xFE,0x01,0xFF,0xFF,0x9F,0xFE,0x00,0xFF,0xFF,0x1F,0xFE,0x00,0x7F,0xFC,0x1F,0xFE,0x00,0x0F,0xF0,0x00,0x00, // 'd'
|
||||
0x00,0x00,0xFF,0xC0,0x00,0x00,0x07,0xFF,0xFC,0x00,0x00,0x0F,0xFF,0xFF,0x80,0x00,0x0F,0xFF,0xFF,0xE0,0x00,0x1F,0xFF,0xFF,0xFC,0x00,0x1F,0xFF,0xFF,0xFF,0x00,0x1F,0xFF,0xFF,0xFF,0xC0,0x0F,0xFF,0xFF,0xFF,0xE0,0x0F,0xFF,0xFF,0xFF,0xF8,0x0F,0xFF,0xFF,0xFF,0xFE,0x07,0xFF,0xF0,0x3F,0xFF,0x07,0xFF,0xF0,0x0F,0xFF,0x83,0xFF,0xF0,0x03,0xFF,0xE1,0xFF,0xF0,0x01,0xFF,0xF1,0xFF,0xF8,0x00,0x7F,0xF8,0xFF,0xF8,0x00,0x3F,0xFC,0x7F,0xFC,0x00,0x1F,0xFF,0x3F,0xFE,0x00,0x0F,0xFF,0x9F,0xFF,0xFF,0xFF,0xFF,0xDF,0xFF,0xFF,0xFF,0xFF,0xEF,0xFF,0xFF,0xFF,0xFF,0xF7,0xFF,0xFF,0xFF,0xFF,0xFB,0xFF,0xFF,0xFF,0xFF,0xFD,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,0xFF,0xFF,0xFF,0xFF,0x9F,0xFF,0x00,0x00,0x00,0x0F,0xFF,0x80,0x00,0x00,0x07,0xFF,0xC0,0x00,0x00,0x03,0xFF,0xF0,0x00,0x04,0x00,0xFF,0xFC,0x00,0x03,0x00,0x7F,0xFE,0x00,0x03,0xC0,0x3F,0xFF,0xC0,0x07,0xE0,0x0F,0xFF,0xF8,0x0F,0xF8,0x07,0xFF,0xFF,0xFF,0xFE,0x01,0xFF,0xFF,0xFF,0xFF,0x80,0x7F,0xFF,0xFF,0xFF,0xE0,0x1F,0xFF,0xFF,0xFF,0xE0,0x07,0xFF,0xFF,0xFF,0xE0,0x01,0xFF,0xFF,0xFF,0xE0,0x00,0x7F,0xFF,0xFF,0xE0,0x00,0x0F,0xFF,0xFF,0xC0,0x00,0x01,0xFF,0xFF,0x80,0x00,0x00,0x0F,0xFC,0x00,0x00, // 'e'
|
||||
0x00,0x00,0x3F,0xE0,0x00,0x07,0xFF,0xE0,0x00,0x7F,0xFF,0x80,0x07,0xFF,0xFE,0x00,0x3F,0xFF,0xF8,0x00,0xFF,0xFF,0xE0,0x07,0xFF,0xFF,0x80,0x3F,0xFF,0xFE,0x00,0xFF,0xFF,0xF8,0x07,0xFF,0xFF,0xE0,0x1F,0xFF,0xE0,0x00,0x7F,0xFE,0x00,0x01,0xFF,0xF0,0x00,0x07,0xFF,0xC0,0x00,0x1F,0xFF,0x00,0x00,0x7F,0xFC,0x00,0x01,0xFF,0xF0,0x00,0x07,0xFF,0xC0,0x00,0x1F,0xFF,0x00,0x3F,0xFF,0xFF,0xFC,0xFF,0xFF,0xFF,0xF3,0xFF,0xFF,0xFF,0xCF,0xFF,0xFF,0xFF,0x3F,0xFF,0xFF,0xFC,0xFF,0xFF,0xFF,0xF3,0xFF,0xFF,0xFF,0xCF,0xFF,0xFF,0xFF,0x3F,0xFF,0xFF,0xFC,0x01,0xFF,0xF0,0x00,0x07,0xFF,0xC0,0x00,0x1F,0xFF,0x00,0x00,0x7F,0xFC,0x00,0x01,0xFF,0xF0,0x00,0x07,0xFF,0xC0,0x00,0x1F,0xFF,0x00,0x00,0x7F,0xFC,0x00,0x01,0xFF,0xF0,0x00,0x07,0xFF,0xC0,0x00,0x1F,0xFF,0x00,0x00,0x7F,0xFC,0x00,0x01,0xFF,0xF0,0x00,0x07,0xFF,0xC0,0x00,0x1F,0xFF,0x00,0x00,0x7F,0xFC,0x00,0x01,0xFF,0xF0,0x00,0x07,0xFF,0xC0,0x00,0x1F,0xFF,0x00,0x00,0x7F,0xFC,0x00,0x01,0xFF,0xF0,0x00,0x07,0xFF,0xC0,0x00,0x1F,0xFF,0x00,0x00,0x7F,0xFC,0x00,0x01,0xFF,0xF0,0x00,0x07,0xFF,0xC0,0x00,0x1F,0xFF,0x00,0x00,0x7F,0xFC,0x00,0x01,0xFF,0xF0,0x00,0x07,0xFF,0xC0,0x00,0x1F,0xFF,0x00,0x00,0x7F,0xFC,0x00,0x01,0xFF,0xF0,0x00, // 'f'
|
||||
0x00,0x07,0xF8,0x00,0x00,0x00,0x1F,0xFF,0x87,0xFF,0x80,0x1F,0xFF,0xF3,0xFF,0xC0,0x3F,0xFF,0xFD,0xFF,0xE0,0x3F,0xFF,0xFF,0xFF,0xF0,0x3F,0xFF,0xFF,0xFF,0xF8,0x3F,0xFF,0xFF,0xFF,0xFC,0x1F,0xFF,0xFF,0xFF,0xFE,0x1F,0xFF,0xFF,0xFF,0xFF,0x0F,0xFF,0xFF,0xFF,0xFF,0x8F,0xFF,0xF0,0x3F,0xFF,0xC7,0xFF,0xF0,0x07,0xFF,0xE7,0xFF,0xF0,0x01,0xFF,0xF3,0xFF,0xF0,0x00,0xFF,0xF9,0xFF,0xF8,0x00,0x7F,0xFC,0xFF,0xF8,0x00,0x3F,0xFE,0xFF,0xFC,0x00,0x1F,0xFF,0x7F,0xFE,0x00,0x0F,0xFF,0xBF,0xFF,0x00,0x07,0xFF,0xDF,0xFF,0x00,0x03,0xFF,0xEF,0xFF,0x80,0x01,0xFF,0xF7,0xFF,0xC0,0x00,0xFF,0xFB,0xFF,0xE0,0x00,0x7F,0xFD,0xFF,0xF0,0x00,0x3F,0xFE,0xFF,0xF8,0x00,0x1F,0xFF,0x7F,0xFE,0x00,0x0F,0xFF,0xBF,0xFF,0x00,0x07,0xFF,0xCF,0xFF,0x80,0x03,0xFF,0xE7,0xFF,0xC0,0x01,0xFF,0xF3,0xFF,0xF0,0x00,0xFF,0xF9,0xFF,0xF8,0x00,0x7F,0xFC,0xFF,0xFE,0x00,0x3F,0xFE,0x3F,0xFF,0x80,0x3F,0xFF,0x1F,0xFF,0xE0,0x7F,0xFF,0x87,0xFF,0xFF,0xFF,0xFF,0xC3,0xFF,0xFF,0xFF,0xFF,0xE0,0xFF,0xFF,0xFF,0xFF,0xF0,0x7F,0xFF,0xFF,0xFF,0xF8,0x1F,0xFF,0xFF,0xFF,0xFC,0x07,0xFF,0xFF,0xFF,0xFE,0x01,0xFF,0xFF,0xDF,0xFF,0x00,0x3F,0xFF,0xCF,0xFF,0x80,0x0F,0xFF,0xC7,0xFF,0xC0,0x00,0xFF,0x03,0xFF,0xE0,0x00,0x00,0x01,0xFF,0xF0,0x00,0x00,0x01,0xFF,0xF8,0x02,0x00,0x00,0xFF,0xFC,0x03,0x80,0x00,0xFF,0xFC,0x01,0xF0,0x00,0xFF,0xFE,0x01,0xFE,0x01,0xFF,0xFF,0x01,0xFF,0xFF,0xFF,0xFF,0x01,0xFF,0xFF,0xFF,0xFF,0x80,0xFF,0xFF,0xFF,0xFF,0x80,0xFF,0xFF,0xFF,0xFF,0x80,0x3F,0xFF,0xFF,0xFF,0x80,0x0F,0xFF,0xFF,0xFF,0x80,0x03,0xFF,0xFF,0xFF,0x80,0x00,0x7F,0xFF,0xFF,0x00,0x00,0x0F,0xFF,0xFC,0x00,0x00,0x00,0x7F,0xE0,0x00,0x00, // 'g'
|
||||
0xFF,0xF8,0x00,0x00,0x01,0xFF,0xF0,0x00,0x00,0x03,0xFF,0xE0,0x00,0x00,0x07,0xFF,0xC0,0x00,0x00,0x0F,0xFF,0x80,0x00,0x00,0x1F,0xFF,0x00,0x00,0x00,0x3F,0xFE,0x00,0x00,0x00,0x7F,0xFC,0x00,0x00,0x00,0xFF,0xF8,0x00,0x00,0x01,0xFF,0xF0,0x00,0x00,0x03,0xFF,0xE0,0x00,0x00,0x07,0xFF,0xC0,0x00,0x00,0x0F,0xFF,0x80,0x00,0x00,0x1F,0xFF,0x00,0x00,0x00,0x3F,0xFE,0x00,0x00,0x00,0x7F,0xFC,0x00,0x00,0x00,0xFF,0xF8,0x00,0x00,0x01,0xFF,0xF0,0x0F,0xF0,0x03,0xFF,0xE0,0xFF,0xF8,0x07,0xFF,0xC7,0xFF,0xFC,0x0F,0xFF,0x9F,0xFF,0xFC,0x1F,0xFF,0x7F,0xFF,0xFC,0x3F,0xFF,0xFF,0xFF,0xFC,0x7F,0xFF,0xFF,0xFF,0xF8,0xFF,0xFF,0xFF,0xFF,0xF9,0xFF,0xFF,0xFF,0xFF,0xF3,0xFF,0xFF,0xFF,0xFF,0xF7,0xFF,0xF8,0x1F,0xFF,0xEF,0xFF,0xC0,0x0F,0xFF,0xDF,0xFF,0x80,0x1F,0xFF,0xBF,0xFE,0x00,0x1F,0xFF,0x7F,0xFC,0x00,0x3F,0xFE,0xFF,0xF8,0x00,0x7F,0xFD,0xFF,0xF0,0x00,0xFF,0xFB,0xFF,0xE0,0x01,0xFF,0xF7,0xFF,0xC0,0x03,0xFF,0xEF,0xFF,0x80,0x07,0xFF,0xDF,0xFF,0x00,0x0F,0xFF,0xBF,0xFE,0x00,0x1F,0xFF,0x7F,0xFC,0x00,0x3F,0xFE,0xFF,0xF8,0x00,0x7F,0xFD,0xFF,0xF0,0x00,0xFF,0xFB,0xFF,0xE0,0x01,0xFF,0xF7,0xFF,0xC0,0x03,0xFF,0xEF,0xFF,0x80,0x07,0xFF,0xDF,0xFF,0x00,0x0F,0xFF,0xBF,0xFE,0x00,0x1F,0xFF,0x7F,0xFC,0x00,0x3F,0xFE,0xFF,0xF8,0x00,0x7F,0xFD,0xFF,0xF0,0x00,0xFF,0xFB,0xFF,0xE0,0x01,0xFF,0xF7,0xFF,0xC0,0x03,0xFF,0xEF,0xFF,0x80,0x07,0xFF,0xDF,0xFF,0x00,0x0F,0xFF,0xBF,0xFE,0x00,0x1F,0xFF,0x7F,0xFC,0x00,0x3F,0xFE,0xFF,0xF8,0x00,0x7F,0xFD,0xFF,0xF0,0x00,0xFF,0xFB,0xFF,0xE0,0x01,0xFF,0xF7,0xFF,0xC0,0x03,0xFF,0xE0, // 'h'
|
||||
0x0F,0xC0,0x7F,0xE1,0xFF,0xE7,0xFF,0xCF,0xFF,0xDF,0xFF,0xBF,0xFF,0x7F,0xFE,0xFF,0xFD,0xFF,0xF9,0xFF,0xE1,0xFF,0x80,0xFC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0xFF,0xF7,0xFF,0xEF,0xFF,0xDF,0xFF,0xBF,0xFF,0x7F,0xFE,0xFF,0xFD,0xFF,0xFB,0xFF,0xF7,0xFF,0xEF,0xFF,0xDF,0xFF,0xBF,0xFF,0x7F,0xFE,0xFF,0xFD,0xFF,0xFB,0xFF,0xF7,0xFF,0xEF,0xFF,0xDF,0xFF,0xBF,0xFF,0x7F,0xFE,0xFF,0xFD,0xFF,0xFB,0xFF,0xF7,0xFF,0xEF,0xFF,0xDF,0xFF,0xBF,0xFF,0x7F,0xFE,0xFF,0xFD,0xFF,0xFB,0xFF,0xF7,0xFF,0xEF,0xFF,0xDF,0xFF,0xBF,0xFF,0x7F,0xFE,0xFF,0xFD,0xFF,0xFB,0xFF,0xF7,0xFF,0xE0, // 'i'
|
||||
0x00,0x0F,0xC0,0x00,0x7F,0xE0,0x01,0xFF,0xE0,0x03,0xFF,0xE0,0x0F,0xFF,0xC0,0x1F,0xFF,0x80,0x3F,0xFF,0x00,0x7F,0xFE,0x00,0xFF,0xFC,0x00,0xFF,0xF8,0x01,0xFF,0xE0,0x01,0xFF,0x80,0x00,0xFC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xFF,0xF0,0x03,0xFF,0xE0,0x07,0xFF,0xC0,0x0F,0xFF,0x80,0x1F,0xFF,0x00,0x3F,0xFE,0x00,0x7F,0xFC,0x00,0xFF,0xF8,0x01,0xFF,0xF0,0x03,0xFF,0xE0,0x07,0xFF,0xC0,0x0F,0xFF,0x80,0x1F,0xFF,0x00,0x3F,0xFE,0x00,0x7F,0xFC,0x00,0xFF,0xF8,0x01,0xFF,0xF0,0x03,0xFF,0xE0,0x07,0xFF,0xC0,0x0F,0xFF,0x80,0x1F,0xFF,0x00,0x3F,0xFE,0x00,0x7F,0xFC,0x00,0xFF,0xF8,0x01,0xFF,0xF0,0x03,0xFF,0xE0,0x07,0xFF,0xC0,0x0F,0xFF,0x80,0x1F,0xFF,0x00,0x3F,0xFE,0x00,0x7F,0xFC,0x00,0xFF,0xF8,0x01,0xFF,0xF0,0x03,0xFF,0xE0,0x07,0xFF,0xC0,0x0F,0xFF,0x80,0x1F,0xFF,0x00,0x3F,0xFE,0x00,0x7F,0xFC,0x00,0xFF,0xF8,0x01,0xFF,0xF0,0x03,0xFF,0xE0,0x07,0xFF,0xC0,0x0F,0xFF,0x80,0x1F,0xFF,0x00,0x3F,0xFE,0x00,0xFF,0xFC,0x01,0xFF,0xF8,0x0F,0xFF,0xE7,0xFF,0xFF,0xCF,0xFF,0xFF,0x9F,0xFF,0xFE,0x3F,0xFF,0xFC,0x7F,0xFF,0xF0,0xFF,0xFF,0xC1,0xFF,0xFF,0x03,0xFF,0xFC,0x07,0xFF,0xE0,0x07,0xFE,0x00,0x00, // 'j'
|
||||
0xFF,0xF8,0x00,0x00,0x00,0x3F,0xFE,0x00,0x00,0x00,0x0F,0xFF,0x80,0x00,0x00,0x03,0xFF,0xE0,0x00,0x00,0x00,0xFF,0xF8,0x00,0x00,0x00,0x3F,0xFE,0x00,0x00,0x00,0x0F,0xFF,0x80,0x00,0x00,0x03,0xFF,0xE0,0x00,0x00,0x00,0xFF,0xF8,0x00,0x00,0x00,0x3F,0xFE,0x00,0x00,0x00,0x0F,0xFF,0x80,0x00,0x00,0x03,0xFF,0xE0,0x00,0x00,0x00,0xFF,0xF8,0x00,0x00,0x00,0x3F,0xFE,0x00,0x00,0x00,0x0F,0xFF,0x80,0x00,0x00,0x03,0xFF,0xE0,0x00,0x00,0x00,0xFF,0xF8,0x00,0x00,0x00,0x3F,0xFE,0x00,0x00,0x00,0x0F,0xFF,0x80,0x0F,0xFF,0xF3,0xFF,0xE0,0x07,0xFF,0xF8,0xFF,0xF8,0x03,0xFF,0xFC,0x3F,0xFE,0x01,0xFF,0xFE,0x0F,0xFF,0x80,0x7F,0xFF,0x03,0xFF,0xE0,0x3F,0xFF,0x80,0xFF,0xF8,0x1F,0xFF,0xC0,0x3F,0xFE,0x0F,0xFF,0xF0,0x0F,0xFF,0x87,0xFF,0xF8,0x03,0xFF,0xE1,0xFF,0xFC,0x00,0xFF,0xF8,0xFF,0xFE,0x00,0x3F,0xFE,0x7F,0xFF,0x00,0x0F,0xFF,0xBF,0xFF,0x80,0x03,0xFF,0xFF,0xFF,0xC0,0x00,0xFF,0xFF,0xFF,0xF0,0x00,0x3F,0xFF,0xFF,0xF8,0x00,0x0F,0xFF,0xFF,0xFC,0x00,0x03,0xFF,0xFF,0xFE,0x00,0x00,0xFF,0xFF,0xFF,0xC0,0x00,0x3F,0xFF,0xFF,0xF8,0x00,0x0F,0xFF,0xFF,0xFE,0x00,0x03,0xFF,0xFF,0xFF,0xC0,0x00,0xFF,0xFF,0xFF,0xF8,0x00,0x3F,0xFF,0xFF,0xFE,0x00,0x0F,0xFF,0xFF,0xFF,0xC0,0x03,0xFF,0xFF,0xFF,0xF0,0x00,0xFF,0xFF,0xFF,0xFE,0x00,0x3F,0xFF,0xDF,0xFF,0xC0,0x0F,0xFF,0xE3,0xFF,0xF0,0x03,0xFF,0xF0,0x7F,0xFE,0x00,0xFF,0xF8,0x1F,0xFF,0xC0,0x3F,0xFE,0x03,0xFF,0xF0,0x0F,0xFF,0x80,0xFF,0xFE,0x03,0xFF,0xE0,0x1F,0xFF,0xC0,0xFF,0xF8,0x07,0xFF,0xF0,0x3F,0xFE,0x00,0xFF,0xFE,0x0F,0xFF,0x80,0x1F,0xFF,0x83,0xFF,0xE0,0x07,0xFF,0xF0,0xFF,0xF8,0x00,0xFF,0xFE,0x3F,0xFE,0x00,0x3F,0xFF,0x8F,0xFF,0x80,0x07,0xFF,0xF3,0xFF,0xE0,0x00,0xFF,0xFE, // 'k'
|
||||
0xFF,0xFD,0xFF,0xFB,0xFF,0xF7,0xFF,0xEF,0xFF,0xDF,0xFF,0xBF,0xFF,0x7F,0xFE,0xFF,0xFD,0xFF,0xFB,0xFF,0xF7,0xFF,0xEF,0xFF,0xDF,0xFF,0xBF,0xFF,0x7F,0xFE,0xFF,0xFD,0xFF,0xFB,0xFF,0xF7,0xFF,0xEF,0xFF,0xDF,0xFF,0xBF,0xFF,0x7F,0xFE,0xFF,0xFD,0xFF,0xFB,0xFF,0xF7,0xFF,0xEF,0xFF,0xDF,0xFF,0xBF,0xFF,0x7F,0xFE,0xFF,0xFD,0xFF,0xFB,0xFF,0xF7,0xFF,0xEF,0xFF,0xDF,0xFF,0xBF,0xFF,0x7F,0xFE,0xFF,0xFD,0xFF,0xFB,0xFF,0xF7,0xFF,0xEF,0xFF,0xDF,0xFF,0xBF,0xFF,0x7F,0xFE,0xFF,0xFD,0xFF,0xFB,0xFF,0xF7,0xFF,0xEF,0xFF,0xDF,0xFF,0xBF,0xFF,0x7F,0xFE,0xFF,0xFD,0xFF,0xFB,0xFF,0xF7,0xFF,0xE0, // 'l'
|
||||
0x00,0x00,0x07,0xF8,0x00,0x0F,0xF0,0x03,0xFF,0xC0,0xFF,0xF8,0x01,0xFF,0xF8,0x0F,0xFF,0x0F,0xFF,0xF8,0x1F,0xFF,0xF0,0x3F,0xFC,0x7F,0xFF,0xF0,0xFF,0xFF,0xE0,0xFF,0xFB,0xFF,0xFF,0xC7,0xFF,0xFF,0xC3,0xFF,0xFF,0xFF,0xFF,0xBF,0xFF,0xFF,0x8F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0x3F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFC,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF3,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xCF,0xFF,0xF0,0x7F,0xFF,0xF0,0x3F,0xFF,0xBF,0xFF,0x80,0x7F,0xFF,0x80,0x7F,0xFE,0xFF,0xFC,0x01,0xFF,0xFC,0x01,0xFF,0xFB,0xFF,0xE0,0x03,0xFF,0xE0,0x03,0xFF,0xEF,0xFF,0x80,0x0F,0xFF,0x80,0x0F,0xFF,0xBF,0xFE,0x00,0x3F,0xFE,0x00,0x3F,0xFE,0xFF,0xF8,0x00,0xFF,0xF8,0x00,0xFF,0xFB,0xFF,0xE0,0x03,0xFF,0xE0,0x03,0xFF,0xEF,0xFF,0x80,0x0F,0xFF,0x80,0x0F,0xFF,0xBF,0xFE,0x00,0x3F,0xFE,0x00,0x3F,0xFE,0xFF,0xF8,0x00,0xFF,0xF8,0x00,0xFF,0xFB,0xFF,0xE0,0x03,0xFF,0xE0,0x03,0xFF,0xEF,0xFF,0x80,0x0F,0xFF,0x80,0x0F,0xFF,0xBF,0xFE,0x00,0x3F,0xFE,0x00,0x3F,0xFE,0xFF,0xF8,0x00,0xFF,0xF8,0x00,0xFF,0xFB,0xFF,0xE0,0x03,0xFF,0xE0,0x03,0xFF,0xEF,0xFF,0x80,0x0F,0xFF,0x80,0x0F,0xFF,0xBF,0xFE,0x00,0x3F,0xFE,0x00,0x3F,0xFE,0xFF,0xF8,0x00,0xFF,0xF8,0x00,0xFF,0xFB,0xFF,0xE0,0x03,0xFF,0xE0,0x03,0xFF,0xEF,0xFF,0x80,0x0F,0xFF,0x80,0x0F,0xFF,0xBF,0xFE,0x00,0x3F,0xFE,0x00,0x3F,0xFE,0xFF,0xF8,0x00,0xFF,0xF8,0x00,0xFF,0xFB,0xFF,0xE0,0x03,0xFF,0xE0,0x03,0xFF,0xEF,0xFF,0x80,0x0F,0xFF,0x80,0x0F,0xFF,0xBF,0xFE,0x00,0x3F,0xFE,0x00,0x3F,0xFE,0xFF,0xF8,0x00,0xFF,0xF8,0x00,0xFF,0xFB,0xFF,0xE0,0x03,0xFF,0xE0,0x03,0xFF,0xEF,0xFF,0x80,0x0F,0xFF,0x80,0x0F,0xFF,0xBF,0xFE,0x00,0x3F,0xFE,0x00,0x3F,0xFE,0xFF,0xF8,0x00,0xFF,0xF8,0x00,0xFF,0xFB,0xFF,0xE0,0x03,0xFF,0xE0,0x03,0xFF,0xEF,0xFF,0x80,0x0F,0xFF,0x80,0x0F,0xFF,0x80, // 'm'
|
||||
0x00,0x00,0x07,0xF8,0x01,0xFF,0xF0,0x7F,0xFE,0x03,0xFF,0xE1,0xFF,0xFF,0x07,0xFF,0xCF,0xFF,0xFF,0x0F,0xFF,0xBF,0xFF,0xFE,0x1F,0xFF,0xFF,0xFF,0xFE,0x3F,0xFF,0xFF,0xFF,0xFE,0x7F,0xFF,0xFF,0xFF,0xFC,0xFF,0xFF,0xFF,0xFF,0xF9,0xFF,0xFF,0xFF,0xFF,0xFB,0xFF,0xFE,0x0F,0xFF,0xF7,0xFF,0xF0,0x07,0xFF,0xEF,0xFF,0xC0,0x07,0xFF,0xDF,0xFF,0x80,0x0F,0xFF,0xBF,0xFF,0x00,0x1F,0xFF,0x7F,0xFE,0x00,0x3F,0xFE,0xFF,0xFC,0x00,0x7F,0xFD,0xFF,0xF8,0x00,0xFF,0xFB,0xFF,0xF0,0x01,0xFF,0xF7,0xFF,0xE0,0x03,0xFF,0xEF,0xFF,0xC0,0x07,0xFF,0xDF,0xFF,0x80,0x0F,0xFF,0xBF,0xFF,0x00,0x1F,0xFF,0x7F,0xFE,0x00,0x3F,0xFE,0xFF,0xFC,0x00,0x7F,0xFD,0xFF,0xF8,0x00,0xFF,0xFB,0xFF,0xF0,0x01,0xFF,0xF7,0xFF,0xE0,0x03,0xFF,0xEF,0xFF,0xC0,0x07,0xFF,0xDF,0xFF,0x80,0x0F,0xFF,0xBF,0xFF,0x00,0x1F,0xFF,0x7F,0xFE,0x00,0x3F,0xFE,0xFF,0xFC,0x00,0x7F,0xFD,0xFF,0xF8,0x00,0xFF,0xFB,0xFF,0xF0,0x01,0xFF,0xF7,0xFF,0xE0,0x03,0xFF,0xEF,0xFF,0xC0,0x07,0xFF,0xDF,0xFF,0x80,0x0F,0xFF,0xBF,0xFF,0x00,0x1F,0xFF,0x7F,0xFE,0x00,0x3F,0xFE,0xFF,0xFC,0x00,0x7F,0xFD,0xFF,0xF8,0x00,0xFF,0xFB,0xFF,0xF0,0x01,0xFF,0xF0, // 'n'
|
||||
0x00,0x01,0xFF,0x80,0x00,0x00,0x03,0xFF,0xFE,0x00,0x00,0x03,0xFF,0xFF,0xE0,0x00,0x03,0xFF,0xFF,0xFE,0x00,0x01,0xFF,0xFF,0xFF,0xC0,0x00,0xFF,0xFF,0xFF,0xF8,0x00,0x7F,0xFF,0xFF,0xFF,0x00,0x3F,0xFF,0xFF,0xFF,0xE0,0x1F,0xFF,0xFF,0xFF,0xF8,0x07,0xFF,0xFF,0xFF,0xFF,0x03,0xFF,0xFC,0x1F,0xFF,0xC0,0xFF,0xFC,0x01,0xFF,0xF8,0x3F,0xFE,0x00,0x3F,0xFE,0x1F,0xFF,0x80,0x0F,0xFF,0xC7,0xFF,0xC0,0x01,0xFF,0xF1,0xFF,0xF0,0x00,0x7F,0xFC,0xFF,0xFC,0x00,0x1F,0xFF,0x3F,0xFE,0x00,0x07,0xFF,0xEF,0xFF,0x80,0x01,0xFF,0xFB,0xFF,0xE0,0x00,0x3F,0xFE,0xFF,0xF8,0x00,0x0F,0xFF,0xBF,0xFE,0x00,0x03,0xFF,0xEF,0xFF,0x80,0x00,0xFF,0xFB,0xFF,0xE0,0x00,0x3F,0xFE,0xFF,0xF8,0x00,0x0F,0xFF,0xBF,0xFE,0x00,0x07,0xFF,0xEF,0xFF,0x80,0x01,0xFF,0xFB,0xFF,0xF0,0x00,0x7F,0xFC,0x7F,0xFC,0x00,0x1F,0xFF,0x1F,0xFF,0x00,0x07,0xFF,0xC7,0xFF,0xE0,0x03,0xFF,0xF1,0xFF,0xF8,0x00,0xFF,0xF8,0x3F,0xFF,0x00,0x7F,0xFE,0x0F,0xFF,0xF0,0x7F,0xFF,0x81,0xFF,0xFF,0xFF,0xFF,0xC0,0x7F,0xFF,0xFF,0xFF,0xE0,0x0F,0xFF,0xFF,0xFF,0xF8,0x01,0xFF,0xFF,0xFF,0xFC,0x00,0x3F,0xFF,0xFF,0xFE,0x00,0x07,0xFF,0xFF,0xFF,0x00,0x00,0xFF,0xFF,0xFF,0x80,0x00,0x0F,0xFF,0xFF,0x80,0x00,0x00,0xFF,0xFF,0x80,0x00,0x00,0x07,0xFF,0x00,0x00, // 'o'
|
||||
0x00,0x00,0x1F,0xE0,0x00,0xFF,0xF0,0xFF,0xF8,0x00,0xFF,0xF1,0xFF,0xFE,0x00,0xFF,0xF3,0xFF,0xFF,0x00,0xFF,0xF7,0xFF,0xFF,0x80,0xFF,0xFF,0xFF,0xFF,0xC0,0xFF,0xFF,0xFF,0xFF,0xE0,0xFF,0xFF,0xFF,0xFF,0xF0,0xFF,0xFF,0xFF,0xFF,0xF0,0xFF,0xFF,0xFF,0xFF,0xF8,0xFF,0xFF,0x03,0xFF,0xF8,0xFF,0xFC,0x01,0xFF,0xF8,0xFF,0xF8,0x00,0xFF,0xFC,0xFF,0xF8,0x00,0xFF,0xFC,0xFF,0xF8,0x00,0x7F,0xFC,0xFF,0xF8,0x00,0x7F,0xFC,0xFF,0xF8,0x00,0x7F,0xFE,0xFF,0xF8,0x00,0x7F,0xFE,0xFF,0xF8,0x00,0x3F,0xFE,0xFF,0xF8,0x00,0x3F,0xFE,0xFF,0xF8,0x00,0x3F,0xFE,0xFF,0xF8,0x00,0x3F,0xFE,0xFF,0xF8,0x00,0x3F,0xFE,0xFF,0xF8,0x00,0x3F,0xFE,0xFF,0xF8,0x00,0x3F,0xFE,0xFF,0xF8,0x00,0x3F,0xFE,0xFF,0xF8,0x00,0x7F,0xFE,0xFF,0xF8,0x00,0x7F,0xFE,0xFF,0xF8,0x00,0x7F,0xFC,0xFF,0xF8,0x00,0x7F,0xFC,0xFF,0xF8,0x00,0xFF,0xFC,0xFF,0xFC,0x00,0xFF,0xFC,0xFF,0xFC,0x01,0xFF,0xF8,0xFF,0xFF,0x03,0xFF,0xF8,0xFF,0xFF,0xFF,0xFF,0xF8,0xFF,0xFF,0xFF,0xFF,0xF0,0xFF,0xFF,0xFF,0xFF,0xF0,0xFF,0xFF,0xFF,0xFF,0xE0,0xFF,0xFF,0xFF,0xFF,0xC0,0xFF,0xFF,0xFF,0xFF,0x80,0xFF,0xFB,0xFF,0xFF,0x00,0xFF,0xF9,0xFF,0xFE,0x00,0xFF,0xF8,0xFF,0xF8,0x00,0xFF,0xF8,0x1F,0xE0,0x00,0xFF,0xF8,0x00,0x00,0x00,0xFF,0xF8,0x00,0x00,0x00,0xFF,0xF8,0x00,0x00,0x00,0xFF,0xF8,0x00,0x00,0x00,0xFF,0xF8,0x00,0x00,0x00,0xFF,0xF8,0x00,0x00,0x00,0xFF,0xF8,0x00,0x00,0x00,0xFF,0xF8,0x00,0x00,0x00,0xFF,0xF8,0x00,0x00,0x00,0xFF,0xF8,0x00,0x00,0x00,0xFF,0xF8,0x00,0x00,0x00,0xFF,0xF8,0x00,0x00,0x00,0xFF,0xF8,0x00,0x00,0x00,0xFF,0xF8,0x00,0x00,0x00,0xFF,0xF8,0x00,0x00,0x00, // 'p'
|
||||
0x00,0x0F,0xF0,0x00,0x00,0x00,0x3F,0xFE,0x0F,0xFE,0x00,0xFF,0xFF,0x0F,0xFE,0x01,0xFF,0xFF,0x9F,0xFE,0x07,0xFF,0xFF,0xDF,0xFE,0x07,0xFF,0xFF,0xFF,0xFE,0x0F,0xFF,0xFF,0xFF,0xFE,0x1F,0xFF,0xFF,0xFF,0xFE,0x1F,0xFF,0xFF,0xFF,0xFE,0x3F,0xFF,0xFF,0xFF,0xFE,0x3F,0xFF,0x81,0xFF,0xFE,0x7F,0xFF,0x00,0x7F,0xFE,0x7F,0xFE,0x00,0x7F,0xFE,0x7F,0xFE,0x00,0x3F,0xFE,0x7F,0xFC,0x00,0x3F,0xFE,0x7F,0xFC,0x00,0x3F,0xFE,0xFF,0xFC,0x00,0x3F,0xFE,0xFF,0xF8,0x00,0x3F,0xFE,0xFF,0xF8,0x00,0x3F,0xFE,0xFF,0xF8,0x00,0x3F,0xFE,0xFF,0xF8,0x00,0x3F,0xFE,0xFF,0xF8,0x00,0x3F,0xFE,0xFF,0xF8,0x00,0x3F,0xFE,0xFF,0xF8,0x00,0x3F,0xFE,0xFF,0xF8,0x00,0x3F,0xFE,0xFF,0xF8,0x00,0x3F,0xFE,0xFF,0xF8,0x00,0x3F,0xFE,0xFF,0xFC,0x00,0x3F,0xFE,0x7F,0xFC,0x00,0x3F,0xFE,0x7F,0xFC,0x00,0x3F,0xFE,0x7F,0xFE,0x00,0x3F,0xFE,0x7F,0xFE,0x00,0x7F,0xFE,0x3F,0xFF,0x00,0xFF,0xFE,0x3F,0xFF,0x81,0xFF,0xFE,0x3F,0xFF,0xFF,0xFF,0xFE,0x1F,0xFF,0xFF,0xFF,0xFE,0x1F,0xFF,0xFF,0xFF,0xFE,0x0F,0xFF,0xFF,0xFF,0xFE,0x07,0xFF,0xFF,0xFF,0xFE,0x03,0xFF,0xFF,0xFF,0xFE,0x01,0xFF,0xFF,0xBF,0xFE,0x00,0xFF,0xFF,0x3F,0xFE,0x00,0x3F,0xFE,0x3F,0xFE,0x00,0x0F,0xF0,0x3F,0xFE,0x00,0x00,0x00,0x3F,0xFE,0x00,0x00,0x00,0x3F,0xFE,0x00,0x00,0x00,0x3F,0xFE,0x00,0x00,0x00,0x3F,0xFE,0x00,0x00,0x00,0x3F,0xFE,0x00,0x00,0x00,0x3F,0xFE,0x00,0x00,0x00,0x3F,0xFE,0x00,0x00,0x00,0x3F,0xFE,0x00,0x00,0x00,0x3F,0xFE,0x00,0x00,0x00,0x3F,0xFE,0x00,0x00,0x00,0x3F,0xFE,0x00,0x00,0x00,0x3F,0xFE,0x00,0x00,0x00,0x3F,0xFE,0x00,0x00,0x00,0x3F,0xFE,0x00,0x00,0x00,0x3F,0xFE, // 'q'
|
||||
0x00,0x00,0x1F,0xBF,0xFC,0x1F,0xEF,0xFF,0x1F,0xFB,0xFF,0xCF,0xFE,0xFF,0xF3,0xFF,0xBF,0xFD,0xFF,0xEF,0xFF,0xFF,0xFB,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xBF,0xFF,0xFF,0xEF,0xFF,0xFF,0xFB,0xFF,0xFF,0xFE,0xFF,0xFF,0x80,0x3F,0xFF,0x80,0x0F,0xFF,0xC0,0x03,0xFF,0xE0,0x00,0xFF,0xF8,0x00,0x3F,0xFE,0x00,0x0F,0xFF,0x80,0x03,0xFF,0xE0,0x00,0xFF,0xF8,0x00,0x3F,0xFE,0x00,0x0F,0xFF,0x80,0x03,0xFF,0xE0,0x00,0xFF,0xF8,0x00,0x3F,0xFE,0x00,0x0F,0xFF,0x80,0x03,0xFF,0xE0,0x00,0xFF,0xF8,0x00,0x3F,0xFE,0x00,0x0F,0xFF,0x80,0x03,0xFF,0xE0,0x00,0xFF,0xF8,0x00,0x3F,0xFE,0x00,0x0F,0xFF,0x80,0x03,0xFF,0xE0,0x00,0xFF,0xF8,0x00,0x3F,0xFE,0x00,0x0F,0xFF,0x80,0x03,0xFF,0xE0,0x00,0xFF,0xF8,0x00,0x3F,0xFE,0x00,0x0F,0xFF,0x80,0x00, // 'r'
|
||||
0x00,0x03,0xFF,0x00,0x00,0x00,0x7F,0xFF,0xE0,0x00,0x03,0xFF,0xFF,0xF0,0x00,0x0F,0xFF,0xFF,0xF8,0x00,0x3F,0xFF,0xFF,0xF8,0x00,0xFF,0xFF,0xFF,0xF8,0x03,0xFF,0xFF,0xFF,0xF8,0x0F,0xFF,0xFF,0xFF,0xF8,0x1F,0xFF,0xFF,0xFF,0xF0,0x7F,0xFF,0x07,0xFF,0xF0,0xFF,0xF8,0x07,0xFF,0xE1,0xFF,0xE0,0x07,0xFF,0xC3,0xFF,0xC0,0x0F,0xFF,0x87,0xFF,0x80,0x1F,0xFF,0x8F,0xFF,0x80,0x00,0x00,0x1F,0xFF,0x80,0x00,0x00,0x3F,0xFF,0xC0,0x00,0x00,0x7F,0xFF,0xF8,0x00,0x00,0x7F,0xFF,0xFF,0x00,0x00,0x7F,0xFF,0xFF,0xC0,0x00,0xFF,0xFF,0xFF,0xE0,0x00,0xFF,0xFF,0xFF,0xF0,0x00,0x7F,0xFF,0xFF,0xF0,0x00,0x7F,0xFF,0xFF,0xF0,0x00,0x3F,0xFF,0xFF,0xF0,0x00,0x0F,0xFF,0xFF,0xE0,0x00,0x01,0xFF,0xFF,0xE0,0x00,0x00,0x7F,0xFF,0xC0,0x00,0x00,0x1F,0xFF,0x9F,0xFF,0x00,0x1F,0xFF,0x3F,0xFE,0x00,0x1F,0xFF,0x3F,0xFC,0x00,0x3F,0xFE,0x7F,0xFC,0x00,0x7F,0xF8,0xFF,0xF8,0x01,0xFF,0xF0,0xFF,0xFC,0x0F,0xFF,0xE1,0xFF,0xFF,0xFF,0xFF,0xC1,0xFF,0xFF,0xFF,0xFF,0x03,0xFF,0xFF,0xFF,0xFC,0x03,0xFF,0xFF,0xFF,0xF8,0x03,0xFF,0xFF,0xFF,0xC0,0x01,0xFF,0xFF,0xFF,0x00,0x01,0xFF,0xFF,0xFC,0x00,0x00,0x7F,0xFF,0xC0,0x00,0x00,0x1F,0xFC,0x00,0x00, // 's'
|
||||
0x03,0xFF,0xE0,0x00,0x7F,0xFC,0x00,0x0F,0xFF,0x80,0x01,0xFF,0xF0,0x00,0x3F,0xFE,0x00,0x07,0xFF,0xC0,0x00,0xFF,0xF8,0x00,0x1F,0xFF,0x00,0x03,0xFF,0xE0,0x00,0x7F,0xFC,0x00,0x0F,0xFF,0x80,0x7F,0xFF,0xFF,0xEF,0xFF,0xFF,0xFD,0xFF,0xFF,0xFF,0xBF,0xFF,0xFF,0xF7,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xDF,0xFF,0xFF,0xFB,0xFF,0xFF,0xFF,0x7F,0xFF,0xFF,0xE0,0x3F,0xFE,0x00,0x07,0xFF,0xC0,0x00,0xFF,0xF8,0x00,0x1F,0xFF,0x00,0x03,0xFF,0xE0,0x00,0x7F,0xFC,0x00,0x0F,0xFF,0x80,0x01,0xFF,0xF0,0x00,0x3F,0xFE,0x00,0x07,0xFF,0xC0,0x00,0xFF,0xF8,0x00,0x1F,0xFF,0x00,0x03,0xFF,0xE0,0x00,0x7F,0xFC,0x00,0x0F,0xFF,0x80,0x01,0xFF,0xF0,0x00,0x3F,0xFE,0x00,0x07,0xFF,0xC0,0x00,0xFF,0xF8,0x00,0x1F,0xFF,0x00,0x03,0xFF,0xE0,0x00,0x7F,0xFC,0x00,0x0F,0xFF,0x80,0x01,0xFF,0xF8,0x00,0x3F,0xFF,0xFC,0x07,0xFF,0xFF,0x80,0xFF,0xFF,0xF0,0x0F,0xFF,0xFE,0x01,0xFF,0xFF,0xC0,0x1F,0xFF,0xF8,0x01,0xFF,0xFF,0x00,0x1F,0xFF,0xE0,0x01,0xFF,0xFC,0x00,0x07,0xFE,0x00, // 't'
|
||||
0xFF,0xFC,0x00,0x7F,0xFE,0xFF,0xFC,0x00,0x7F,0xFE,0xFF,0xFC,0x00,0x7F,0xFE,0xFF,0xFC,0x00,0x7F,0xFE,0xFF,0xFC,0x00,0x7F,0xFE,0xFF,0xFC,0x00,0x7F,0xFE,0xFF,0xFC,0x00,0x7F,0xFE,0xFF,0xFC,0x00,0x7F,0xFE,0xFF,0xFC,0x00,0x7F,0xFE,0xFF,0xFC,0x00,0x7F,0xFE,0xFF,0xFC,0x00,0x7F,0xFE,0xFF,0xFC,0x00,0x7F,0xFE,0xFF,0xFC,0x00,0x7F,0xFE,0xFF,0xFC,0x00,0x7F,0xFE,0xFF,0xFC,0x00,0x7F,0xFE,0xFF,0xFC,0x00,0x7F,0xFE,0xFF,0xFC,0x00,0x7F,0xFE,0xFF,0xFC,0x00,0x7F,0xFE,0xFF,0xFC,0x00,0x7F,0xFE,0xFF,0xFC,0x00,0x7F,0xFE,0xFF,0xFC,0x00,0x7F,0xFE,0xFF,0xFC,0x00,0x7F,0xFE,0xFF,0xFC,0x00,0x7F,0xFE,0xFF,0xFC,0x00,0x7F,0xFE,0xFF,0xFC,0x00,0x7F,0xFE,0xFF,0xFC,0x00,0x7F,0xFE,0xFF,0xFC,0x00,0x7F,0xFE,0xFF,0xFC,0x00,0x7F,0xFE,0xFF,0xFC,0x00,0x7F,0xFE,0xFF,0xFC,0x00,0x7F,0xFE,0x7F,0xFC,0x00,0x7F,0xFE,0x7F,0xFE,0x00,0xFF,0xFE,0x7F,0xFF,0x03,0xFF,0xFE,0x7F,0xFF,0xFF,0xFF,0xFE,0x7F,0xFF,0xFF,0xFF,0xFE,0x3F,0xFF,0xFF,0xFF,0xFE,0x3F,0xFF,0xFF,0xFF,0xFE,0x1F,0xFF,0xFF,0xFF,0xFE,0x0F,0xFF,0xFF,0xBF,0xFE,0x0F,0xFF,0xFF,0x3F,0xFE,0x03,0xFF,0xFE,0x3F,0xFE,0x01,0xFF,0xF8,0x3F,0xFE,0x00,0x3F,0xE0,0x00,0x00, // 'u'
|
||||
0xFF,0xFC,0x00,0x1F,0xFF,0xBF,0xFF,0x00,0x07,0xFF,0xC7,0xFF,0xC0,0x03,0xFF,0xF1,0xFF,0xF8,0x00,0xFF,0xFC,0x7F,0xFE,0x00,0x3F,0xFE,0x0F,0xFF,0x80,0x0F,0xFF,0x83,0xFF,0xE0,0x07,0xFF,0xE0,0xFF,0xFC,0x01,0xFF,0xF0,0x1F,0xFF,0x00,0x7F,0xFC,0x07,0xFF,0xC0,0x1F,0xFF,0x01,0xFF,0xF0,0x0F,0xFF,0x80,0x3F,0xFE,0x03,0xFF,0xE0,0x0F,0xFF,0x80,0xFF,0xF8,0x03,0xFF,0xE0,0x3F,0xFE,0x00,0x7F,0xF8,0x1F,0xFF,0x00,0x1F,0xFF,0x07,0xFF,0xC0,0x07,0xFF,0xC1,0xFF,0xF0,0x00,0xFF,0xF0,0x7F,0xF8,0x00,0x3F,0xFC,0x3F,0xFE,0x00,0x0F,0xFF,0x8F,0xFF,0x80,0x01,0xFF,0xE3,0xFF,0xC0,0x00,0x7F,0xF8,0xFF,0xF0,0x00,0x1F,0xFE,0x7F,0xFC,0x00,0x03,0xFF,0xDF,0xFE,0x00,0x00,0xFF,0xF7,0xFF,0x80,0x00,0x3F,0xFD,0xFF,0xE0,0x00,0x07,0xFF,0xFF,0xF0,0x00,0x01,0xFF,0xFF,0xFC,0x00,0x00,0x7F,0xFF,0xFF,0x00,0x00,0x0F,0xFF,0xFF,0x80,0x00,0x03,0xFF,0xFF,0xE0,0x00,0x00,0xFF,0xFF,0xF8,0x00,0x00,0x1F,0xFF,0xFC,0x00,0x00,0x07,0xFF,0xFF,0x00,0x00,0x01,0xFF,0xFF,0xC0,0x00,0x00,0x3F,0xFF,0xE0,0x00,0x00,0x0F,0xFF,0xF8,0x00,0x00,0x03,0xFF,0xFE,0x00,0x00,0x00,0x7F,0xFF,0x00,0x00,0x00,0x1F,0xFF,0xC0,0x00,0x00,0x07,0xFF,0xF0,0x00,0x00,0x00,0xFF,0xF8,0x00,0x00, // 'v'
|
||||
0xFF,0xF8,0x01,0xFF,0x80,0x1F,0xFF,0x7F,0xFC,0x00,0xFF,0xC0,0x0F,0xFF,0xBF,0xFE,0x00,0x7F,0xE0,0x07,0xFF,0x8F,0xFF,0x00,0x7F,0xF0,0x03,0xFF,0xC7,0xFF,0x80,0x3F,0xFC,0x01,0xFF,0xE3,0xFF,0xC0,0x1F,0xFE,0x01,0xFF,0xF1,0xFF,0xF0,0x0F,0xFF,0x00,0xFF,0xF0,0x7F,0xF8,0x0F,0xFF,0xC0,0x7F,0xF8,0x3F,0xFC,0x07,0xFF,0xE0,0x3F,0xFC,0x1F,0xFE,0x03,0xFF,0xF0,0x1F,0xFE,0x0F,0xFF,0x01,0xFF,0xF8,0x0F,0xFF,0x03,0xFF,0x81,0xFF,0xFE,0x0F,0xFF,0x01,0xFF,0xC0,0xFF,0xFF,0x07,0xFF,0x80,0xFF,0xF0,0x7F,0xFF,0x83,0xFF,0xC0,0x7F,0xF8,0x7F,0xFF,0xC1,0xFF,0xE0,0x3F,0xFC,0x3F,0xFF,0xF0,0xFF,0xE0,0x0F,0xFE,0x1F,0xFF,0xF8,0x7F,0xF0,0x07,0xFF,0x0F,0xFF,0xFC,0x7F,0xF8,0x03,0xFF,0x8F,0xFF,0xFE,0x3F,0xFC,0x01,0xFF,0xE7,0xFC,0xFF,0x9F,0xFC,0x00,0x7F,0xF3,0xFE,0x7F,0xCF,0xFE,0x00,0x3F,0xF9,0xFF,0x3F,0xE7,0xFF,0x00,0x1F,0xFD,0xFF,0x1F,0xFB,0xFF,0x80,0x0F,0xFE,0xFF,0x87,0xFF,0xFF,0x80,0x03,0xFF,0x7F,0xC3,0xFF,0xFF,0xC0,0x01,0xFF,0xFF,0xE1,0xFF,0xFF,0xE0,0x00,0xFF,0xFF,0xE0,0x7F,0xFF,0xF0,0x00,0x7F,0xFF,0xF0,0x3F,0xFF,0xF8,0x00,0x1F,0xFF,0xF8,0x1F,0xFF,0xF8,0x00,0x0F,0xFF,0xF8,0x0F,0xFF,0xFC,0x00,0x07,0xFF,0xFC,0x03,0xFF,0xFE,0x00,0x03,0xFF,0xFE,0x01,0xFF,0xFF,0x00,0x00,0xFF,0xFF,0x00,0xFF,0xFF,0x00,0x00,0x7F,0xFF,0x00,0x3F,0xFF,0x80,0x00,0x3F,0xFF,0x80,0x1F,0xFF,0xC0,0x00,0x1F,0xFF,0xC0,0x0F,0xFF,0xE0,0x00,0x0F,0xFF,0xC0,0x07,0xFF,0xE0,0x00,0x03,0xFF,0xE0,0x01,0xFF,0xF0,0x00,0x01,0xFF,0xF0,0x00,0xFF,0xF8,0x00,0x00,0xFF,0xF8,0x00,0x7F,0xFC,0x00,0x00,0x7F,0xF8,0x00,0x1F,0xFC,0x00,0x00,0x1F,0xFC,0x00,0x0F,0xFE,0x00,0x00, // 'w'
|
||||
0x7F,0xFE,0x00,0x1F,0xFF,0x8F,0xFF,0xC0,0x0F,0xFF,0xC3,0xFF,0xF0,0x03,0xFF,0xE0,0x7F,0xFE,0x01,0xFF,0xF8,0x0F,0xFF,0x80,0x7F,0xFC,0x03,0xFF,0xF0,0x3F,0xFF,0x00,0x7F,0xFC,0x1F,0xFF,0x80,0x1F,0xFF,0x87,0xFF,0xE0,0x03,0xFF,0xE3,0xFF,0xF0,0x00,0xFF,0xFC,0xFF,0xF8,0x00,0x1F,0xFF,0x7F,0xFE,0x00,0x07,0xFF,0xFF,0xFF,0x00,0x00,0xFF,0xFF,0xFF,0xC0,0x00,0x3F,0xFF,0xFF,0xE0,0x00,0x07,0xFF,0xFF,0xF8,0x00,0x01,0xFF,0xFF,0xFC,0x00,0x00,0x3F,0xFF,0xFF,0x00,0x00,0x07,0xFF,0xFF,0x80,0x00,0x01,0xFF,0xFF,0xE0,0x00,0x00,0x3F,0xFF,0xF0,0x00,0x00,0x0F,0xFF,0xFC,0x00,0x00,0x03,0xFF,0xFF,0x00,0x00,0x01,0xFF,0xFF,0xE0,0x00,0x00,0xFF,0xFF,0xF8,0x00,0x00,0x3F,0xFF,0xFF,0x00,0x00,0x1F,0xFF,0xFF,0xC0,0x00,0x07,0xFF,0xFF,0xF8,0x00,0x03,0xFF,0xFF,0xFE,0x00,0x00,0xFF,0xFF,0xFF,0xC0,0x00,0x7F,0xFF,0xFF,0xF0,0x00,0x1F,0xFF,0x7F,0xFE,0x00,0x0F,0xFF,0xCF,0xFF,0x80,0x03,0xFF,0xE3,0xFF,0xF0,0x01,0xFF,0xF8,0x7F,0xFE,0x00,0xFF,0xFC,0x1F,0xFF,0x80,0x3F,0xFF,0x03,0xFF,0xF0,0x1F,0xFF,0x80,0xFF,0xFC,0x07,0xFF,0xE0,0x1F,0xFF,0x83,0xFF,0xF0,0x03,0xFF,0xE0,0xFF,0xFC,0x00,0xFF,0xFC,0x7F,0xFE,0x00,0x1F,0xFF,0x3F,0xFF,0x80,0x07,0xFF,0xE0, // 'x'
|
||||
0xFF,0xFC,0x00,0x1F,0xFF,0xBF,0xFF,0x00,0x07,0xFF,0xEF,0xFF,0xC0,0x01,0xFF,0xF9,0xFF,0xF8,0x00,0xFF,0xFC,0x7F,0xFE,0x00,0x3F,0xFF,0x0F,0xFF,0x80,0x0F,0xFF,0xC3,0xFF,0xF0,0x07,0xFF,0xE0,0xFF,0xFC,0x01,0xFF,0xF8,0x1F,0xFF,0x00,0x7F,0xFE,0x07,0xFF,0xC0,0x1F,0xFF,0x01,0xFF,0xF8,0x0F,0xFF,0xC0,0x3F,0xFE,0x03,0xFF,0xE0,0x0F,0xFF,0x80,0xFF,0xF8,0x03,0xFF,0xE0,0x7F,0xFE,0x00,0x7F,0xFC,0x1F,0xFF,0x00,0x1F,0xFF,0x07,0xFF,0xC0,0x07,0xFF,0xC3,0xFF,0xF0,0x00,0xFF,0xF8,0xFF,0xF8,0x00,0x3F,0xFE,0x3F,0xFE,0x00,0x0F,0xFF,0x8F,0xFF,0x80,0x01,0xFF,0xE7,0xFF,0xC0,0x00,0x7F,0xFD,0xFF,0xF0,0x00,0x1F,0xFF,0x7F,0xFC,0x00,0x03,0xFF,0xFF,0xFE,0x00,0x00,0xFF,0xFF,0xFF,0x80,0x00,0x3F,0xFF,0xFF,0xE0,0x00,0x07,0xFF,0xFF,0xF0,0x00,0x01,0xFF,0xFF,0xFC,0x00,0x00,0x7F,0xFF,0xFF,0x00,0x00,0x0F,0xFF,0xFF,0x80,0x00,0x03,0xFF,0xFF,0xE0,0x00,0x00,0xFF,0xFF,0xF0,0x00,0x00,0x1F,0xFF,0xFC,0x00,0x00,0x07,0xFF,0xFF,0x00,0x00,0x00,0xFF,0xFF,0x80,0x00,0x00,0x3F,0xFF,0xE0,0x00,0x00,0x0F,0xFF,0xF8,0x00,0x00,0x01,0xFF,0xFC,0x00,0x00,0x00,0x7F,0xFF,0x00,0x00,0x00,0x1F,0xFF,0xC0,0x00,0x00,0x03,0xFF,0xE0,0x00,0x00,0x00,0xFF,0xF8,0x00,0x00,0x00,0x3F,0xFE,0x00,0x00,0x00,0x0F,0xFF,0x00,0x00,0x00,0x03,0xFF,0xC0,0x00,0x00,0x01,0xFF,0xF0,0x00,0x00,0x00,0x7F,0xF8,0x00,0x00,0x00,0x3F,0xFE,0x00,0x00,0x00,0x3F,0xFF,0x00,0x00,0x01,0xFF,0xFF,0xC0,0x00,0x00,0x7F,0xFF,0xF0,0x00,0x00,0x1F,0xFF,0xF8,0x00,0x00,0x07,0xFF,0xFE,0x00,0x00,0x01,0xFF,0xFF,0x00,0x00,0x00,0x7F,0xFF,0x80,0x00,0x00,0x1F,0xFF,0xC0,0x00,0x00,0x07,0xFF,0xE0,0x00,0x00,0x01,0xFF,0xF0,0x00,0x00,0x00,0x3F,0xE0,0x00,0x00,0x00, // 'y'
|
||||
0xFF,0xFF,0xFF,0xFF,0xEF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0xEF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0xEF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0xEF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0xCF,0xFF,0xFF,0xFF,0xF8,0x00,0x00,0x3F,0xFF,0x00,0x00,0x07,0xFF,0xF0,0x00,0x00,0xFF,0xFE,0x00,0x00,0x0F,0xFF,0xC0,0x00,0x01,0xFF,0xF8,0x00,0x00,0x3F,0xFF,0x80,0x00,0x07,0xFF,0xF0,0x00,0x00,0x7F,0xFE,0x00,0x00,0x0F,0xFF,0xC0,0x00,0x01,0xFF,0xFC,0x00,0x00,0x3F,0xFF,0x80,0x00,0x03,0xFF,0xF0,0x00,0x00,0x7F,0xFE,0x00,0x00,0x0F,0xFF,0xE0,0x00,0x01,0xFF,0xFC,0x00,0x00,0x1F,0xFF,0x80,0x00,0x03,0xFF,0xF0,0x00,0x00,0x7F,0xFF,0x00,0x00,0x0F,0xFF,0xE0,0x00,0x00,0xFF,0xFC,0x00,0x00,0x1F,0xFF,0x80,0x00,0x03,0xFF,0xF8,0x00,0x00,0x7F,0xFF,0xFF,0xFF,0xE7,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0xEF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0xEF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0xEF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0xEF,0xFF,0xFF,0xFF,0xFE, // 'z'
|
||||
0x00,0x00,0x30,0x00,0x01,0xE0,0x00,0x0F,0xE0,0x00,0x3F,0xC0,0x01,0xFF,0xC0,0x07,0xFF,0x80,0x1F,0xFF,0x00,0x3F,0xFC,0x00,0xFF,0xF0,0x01,0xFF,0xC0,0x07,0xFF,0x80,0x0F,0xFE,0x00,0x1F,0xFC,0x00,0x7F,0xF8,0x00,0xFF,0xF0,0x01,0xFF,0xC0,0x03,0xFF,0x80,0x07,0xFF,0x00,0x0F,0xFE,0x00,0x1F,0xFC,0x00,0x3F,0xF8,0x00,0x7F,0xF0,0x00,0xFF,0xE0,0x01,0xFF,0xC0,0x03,0xFF,0x80,0x07,0xFF,0x00,0x0F,0xFE,0x00,0x1F,0xFC,0x00,0x3F,0xF8,0x00,0xFF,0xF0,0x01,0xFF,0xE0,0x03,0xFF,0x80,0x0F,0xFF,0x00,0x7F,0xFE,0x03,0xFF,0xF8,0x07,0xFF,0xE0,0x0F,0xFF,0x80,0x1F,0xFE,0x00,0x3F,0xF0,0x00,0x7F,0xF8,0x00,0xFF,0xF8,0x01,0xFF,0xF8,0x03,0xFF,0xF8,0x01,0xFF,0xF8,0x00,0xFF,0xF0,0x00,0xFF,0xE0,0x01,0xFF,0xE0,0x01,0xFF,0xC0,0x03,0xFF,0x80,0x07,0xFF,0x00,0x0F,0xFE,0x00,0x1F,0xFC,0x00,0x3F,0xF8,0x00,0x7F,0xF0,0x00,0xFF,0xE0,0x01,0xFF,0xC0,0x03,0xFF,0x80,0x07,0xFF,0x00,0x0F,0xFE,0x00,0x1F,0xFC,0x00,0x3F,0xF8,0x00,0x7F,0xF0,0x00,0xFF,0xF0,0x01,0xFF,0xE0,0x01,0xFF,0xC0,0x03,0xFF,0xC0,0x07,0xFF,0x80,0x07,0xFF,0x80,0x07,0xFF,0x80,0x0F,0xFF,0x80,0x0F,0xFF,0x00,0x0F,0xFE,0x00,0x0F,0xF8,0x00,0x07,0xF0,0x00,0x03,0xE0,0x00,0x01,0x80, // '{'
|
||||
0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE, // '|'
|
||||
0x30,0x00,0x00,0x78,0x00,0x01,0xFC,0x00,0x03,0xFE,0x00,0x0F,0xFE,0x00,0x1F,0xFE,0x00,0x3F,0xFE,0x00,0x3F,0xFC,0x00,0x3F,0xFC,0x00,0x3F,0xF8,0x00,0x7F,0xF8,0x00,0x7F,0xF0,0x00,0xFF,0xE0,0x01,0xFF,0xE0,0x03,0xFF,0xC0,0x03,0xFF,0x80,0x07,0xFF,0x00,0x0F,0xFE,0x00,0x1F,0xFC,0x00,0x3F,0xF8,0x00,0x7F,0xF0,0x00,0xFF,0xE0,0x01,0xFF,0xC0,0x03,0xFF,0x80,0x07,0xFF,0x00,0x0F,0xFE,0x00,0x1F,0xFC,0x00,0x3F,0xF8,0x00,0x7F,0xF0,0x00,0xFF,0xF0,0x01,0xFF,0xE0,0x01,0xFF,0xC0,0x03,0xFF,0xC0,0x07,0xFF,0xE0,0x07,0xFF,0xF0,0x07,0xFF,0xE0,0x07,0xFF,0xC0,0x07,0xFF,0x80,0x03,0xFF,0x00,0x1F,0xFE,0x00,0x7F,0xFC,0x01,0xFF,0xF8,0x07,0xFF,0xF0,0x1F,0xFF,0x80,0x3F,0xFC,0x00,0x7F,0xF0,0x01,0xFF,0xE0,0x03,0xFF,0x80,0x07,0xFF,0x00,0x0F,0xFE,0x00,0x1F,0xFC,0x00,0x3F,0xF8,0x00,0x7F,0xF0,0x00,0xFF,0xE0,0x01,0xFF,0xC0,0x03,0xFF,0x80,0x07,0xFF,0x00,0x0F,0xFE,0x00,0x1F,0xFC,0x00,0x3F,0xF8,0x00,0x7F,0xF0,0x00,0xFF,0xE0,0x03,0xFF,0xC0,0x07,0xFF,0x80,0x0F,0xFE,0x00,0x3F,0xFC,0x00,0x7F,0xF8,0x01,0xFF,0xE0,0x07,0xFF,0x80,0x1F,0xFF,0x00,0x3F,0xFC,0x00,0x7F,0xF0,0x00,0x7F,0xC0,0x00,0xFE,0x00,0x00,0xF0,0x00,0x01,0x80,0x00,0x00 // '}'
|
||||
};
|
||||
const GFXglyph Roboto_Black_80Glyphs[] = {
|
||||
// bitmapOffset, width, height, xAdvance, xOffset, yOffset
|
||||
{ 0, 1, 1, 21, 0, 0 }, // ' '
|
||||
{ 1, 16, 58, 23, 4, -57 }, // '!'
|
||||
{ 117, 24, 22, 26, 1, -60 }, // '"'
|
||||
{ 183, 45, 57, 47, 1, -57 }, // '#'
|
||||
{ 504, 41, 75, 47, 3, -66 }, // '$'
|
||||
{ 889, 53, 59, 60, 4, -58 }, // '%'
|
||||
{ 1280, 52, 59, 55, 2, -58 }, // '&'
|
||||
{ 1664, 11, 22, 13, 1, -60 }, // '''
|
||||
{ 1695, 23, 81, 29, 5, -63 }, // '('
|
||||
{ 1928, 24, 81, 29, 1, -63 }, // ')'
|
||||
{ 2171, 37, 34, 38, 1, -57 }, // '*'
|
||||
{ 2329, 40, 41, 44, 2, -47 }, // '+'
|
||||
{ 2534, 16, 25, 23, 2, -10 }, // ','
|
||||
{ 2584, 24, 10, 37, 6, -30 }, // '-'
|
||||
{ 2614, 15, 13, 25, 5, -13 }, // '.'
|
||||
{ 2639, 30, 62, 29, -1, -57 }, // '/'
|
||||
{ 2872, 41, 59, 47, 3, -58 }, // '0'
|
||||
{ 3175, 28, 57, 47, 6, -57 }, // '1'
|
||||
{ 3375, 42, 58, 47, 2, -58 }, // '2'
|
||||
{ 3680, 42, 59, 47, 2, -58 }, // '3'
|
||||
{ 3990, 43, 57, 47, 2, -57 }, // '4'
|
||||
{ 4297, 41, 58, 47, 3, -57 }, // '5'
|
||||
{ 4595, 42, 59, 47, 3, -58 }, // '6'
|
||||
{ 4905, 42, 57, 47, 2, -57 }, // '7'
|
||||
{ 5205, 41, 59, 47, 3, -58 }, // '8'
|
||||
{ 5508, 41, 59, 47, 3, -58 }, // '9'
|
||||
{ 5811, 15, 44, 25, 5, -44 }, // ':'
|
||||
{ 5894, 17, 59, 24, 3, -44 }, // ';'
|
||||
{ 6020, 35, 39, 42, 2, -43 }, // '<'
|
||||
{ 6191, 37, 27, 48, 5, -38 }, // '='
|
||||
{ 6316, 36, 39, 42, 4, -43 }, // '>'
|
||||
{ 6492, 38, 58, 42, 1, -58 }, // '?'
|
||||
{ 6768, 68, 73, 73, 2, -55 }, // '@'
|
||||
{ 7389, 56, 57, 56, 0, -57 }, // 'A'
|
||||
{ 7788, 46, 57, 53, 4, -57 }, // 'B'
|
||||
{ 8116, 49, 59, 54, 3, -58 }, // 'C'
|
||||
{ 8478, 46, 57, 53, 4, -57 }, // 'D'
|
||||
{ 8806, 41, 57, 46, 4, -57 }, // 'E'
|
||||
{ 9099, 39, 57, 45, 4, -57 }, // 'F'
|
||||
{ 9377, 49, 59, 56, 3, -58 }, // 'G'
|
||||
{ 9739, 49, 57, 57, 4, -57 }, // 'H'
|
||||
{ 10089, 15, 57, 25, 5, -57 }, // 'I'
|
||||
{ 10196, 41, 58, 46, 1, -57 }, // 'J'
|
||||
{ 10494, 49, 57, 52, 4, -57 }, // 'K'
|
||||
{ 10844, 39, 57, 44, 4, -57 }, // 'L'
|
||||
{ 11122, 63, 57, 71, 4, -57 }, // 'M'
|
||||
{ 11571, 49, 57, 57, 4, -57 }, // 'N'
|
||||
{ 11921, 50, 59, 56, 3, -58 }, // 'O'
|
||||
{ 12290, 46, 57, 53, 4, -57 }, // 'P'
|
||||
{ 12618, 50, 69, 56, 3, -58 }, // 'Q'
|
||||
{ 13050, 47, 57, 53, 4, -57 }, // 'R'
|
||||
{ 13385, 46, 59, 51, 2, -58 }, // 'S'
|
||||
{ 13725, 49, 57, 51, 1, -57 }, // 'T'
|
||||
{ 14075, 46, 58, 54, 4, -57 }, // 'U'
|
||||
{ 14409, 54, 57, 54, 0, -57 }, // 'V'
|
||||
{ 14794, 69, 57, 71, 1, -57 }, // 'W'
|
||||
{ 15286, 52, 57, 52, 0, -57 }, // 'X'
|
||||
{ 15657, 51, 57, 51, 0, -57 }, // 'Y'
|
||||
{ 16021, 46, 57, 50, 2, -57 }, // 'Z'
|
||||
{ 16349, 19, 81, 24, 4, -67 }, // '['
|
||||
{ 16542, 39, 62, 35, -1, -57 }, // '\'
|
||||
{ 16845, 18, 81, 24, 1, -67 }, // ']'
|
||||
{ 17028, 34, 28, 37, 2, -57 }, // '^'
|
||||
{ 17147, 36, 10, 36, 0, 0 }, // '_'
|
||||
{ 17192, 23, 12, 28, 2, -60 }, // '`'
|
||||
{ 17227, 40, 44, 43, 2, -43 }, // 'a'
|
||||
{ 17447, 40, 61, 46, 4, -60 }, // 'b'
|
||||
{ 17752, 39, 44, 43, 2, -43 }, // 'c'
|
||||
{ 17967, 40, 61, 46, 2, -60 }, // 'd'
|
||||
{ 18272, 41, 44, 45, 2, -43 }, // 'e'
|
||||
{ 18498, 30, 61, 30, 0, -61 }, // 'f'
|
||||
{ 18727, 41, 60, 47, 2, -43 }, // 'g'
|
||||
{ 19035, 39, 60, 46, 3, -60 }, // 'h'
|
||||
{ 19328, 15, 60, 23, 4, -60 }, // 'i'
|
||||
{ 19441, 23, 77, 23, -4, -60 }, // 'j'
|
||||
{ 19663, 42, 60, 45, 4, -60 }, // 'k'
|
||||
{ 19978, 15, 60, 23, 4, -60 }, // 'l'
|
||||
{ 20091, 62, 43, 70, 4, -43 }, // 'm'
|
||||
{ 20425, 39, 43, 46, 3, -43 }, // 'n'
|
||||
{ 20635, 42, 44, 46, 2, -43 }, // 'o'
|
||||
{ 20866, 40, 59, 46, 4, -43 }, // 'p'
|
||||
{ 21161, 40, 59, 46, 2, -43 }, // 'q'
|
||||
{ 21456, 26, 43, 31, 4, -43 }, // 'r'
|
||||
{ 21596, 39, 44, 42, 1, -43 }, // 's'
|
||||
{ 21811, 27, 54, 28, 0, -53 }, // 't'
|
||||
{ 21994, 40, 43, 46, 3, -42 }, // 'u'
|
||||
{ 22209, 42, 42, 42, 0, -42 }, // 'v'
|
||||
{ 22430, 57, 42, 59, 1, -42 }, // 'w'
|
||||
{ 22730, 42, 42, 42, 0, -42 }, // 'x'
|
||||
{ 22951, 42, 59, 42, 0, -42 }, // 'y'
|
||||
{ 23261, 36, 42, 42, 3, -42 }, // 'z'
|
||||
{ 23450, 23, 76, 27, 2, -62 }, // '{'
|
||||
{ 23669, 8, 68, 21, 7, -57 }, // '|'
|
||||
{ 23737, 23, 76, 27, 2, -62 } // '}'
|
||||
};
|
||||
const GFXfont Roboto_Black_80 = {
|
||||
(uint8_t *)Roboto_Black_80Bitmaps,(GFXglyph *)Roboto_Black_80Glyphs,0x20, 0x7E, 95};
|
||||
|
||||
128
ARM_Tag_FW/OpenEPaperLink_TLSR/src/app_cfg.h
Normal file
128
ARM_Tag_FW/OpenEPaperLink_TLSR/src/app_cfg.h
Normal file
@@ -0,0 +1,128 @@
|
||||
/********************************************************************************************************
|
||||
* @file app_cfg.h
|
||||
*
|
||||
* @brief This is the header file for app_cfg
|
||||
*
|
||||
* @author Zigbee Group
|
||||
* @date 2021
|
||||
*
|
||||
* @par Copyright (c) 2021, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK")
|
||||
* All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*******************************************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
/* Enable C linkage for C++ Compilers: */
|
||||
#if defined(__cplusplus)
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#define ON 1
|
||||
#define OFF 0
|
||||
|
||||
#ifndef MCU_CORE_8258
|
||||
#define MCU_CORE_8258 1
|
||||
#endif
|
||||
|
||||
#define RAM _attribute_data_retention_ // short version, this is needed to keep the values in ram after sleep
|
||||
|
||||
/**********************************************************************
|
||||
* Version configuration
|
||||
*/
|
||||
#include "version_cfg.h"
|
||||
|
||||
/* PM */
|
||||
#define PM_ENABLE ON
|
||||
|
||||
|
||||
/* Board ID */
|
||||
#define BOARD_8258_DIY 10
|
||||
|
||||
/* Board define */
|
||||
#if (CHIP_TYPE == TLSR_8258_1M)
|
||||
#define FLASH_CAP_SIZE_1M 1
|
||||
#endif
|
||||
#define BOARD BOARD_8258_DIY // BOARD_8258_DONGLE //BOARD_TB_04 //BOARD_8258_EVK //
|
||||
#define CLOCK_SYS_CLOCK_HZ 24000000
|
||||
/************************* For 512K Flash only ***************************************/
|
||||
/* Flash map:
|
||||
0x00000 Old Firmware bin
|
||||
0x34000 NV_1
|
||||
0x40000 OTA New bin storage Area
|
||||
0x76000 MAC address
|
||||
0x77000 C_Cfg_Info
|
||||
0x78000 U_Cfg_Info
|
||||
0x7A000 NV_2
|
||||
0x80000 End Flash
|
||||
*/
|
||||
#define USER_DATA_SIZE 0x34000
|
||||
#define BEGIN_USER_DATA1 0x00000
|
||||
#define END_USER_DATA1 (BEGIN_USER_DATA1 + USER_DATA_SIZE)
|
||||
#define BEGIN_USER_DATA2 0x40000
|
||||
#define END_USER_DATA2 (BEGIN_USER_DATA2 + USER_DATA_SIZE)
|
||||
// #define GEN_USER_CFG_DATA END_USER_DATA2
|
||||
#define NV_ITEM_APP_USER_CFG (NV_ITEM_APP_GP_TRANS_TABLE + 1) // see sdk/proj/drivers/drv_nv.h
|
||||
|
||||
/* Board include */
|
||||
#include "board_8258_diy.h"
|
||||
|
||||
/* Voltage detect module */
|
||||
/* If VOLTAGE_DETECT_ENABLE is set,
|
||||
* 1) if MCU_CORE_826x is defined, the DRV_ADC_VBAT_MODE mode is used by default,
|
||||
* and there is no need to configure the detection IO port;
|
||||
* 2) if MCU_CORE_8258 or MCU_CORE_8278 is defined, the DRV_ADC_VBAT_MODE mode is used by default,
|
||||
* we need to configure the detection IO port, and the IO must be in a floating state.
|
||||
* 3) if MCU_CORE_B91 is defined, the DRV_ADC_BASE_MODE mode is used by default,
|
||||
* we need to configure the detection IO port, and the IO must be connected to the target under test,
|
||||
* such as VCC.
|
||||
*/
|
||||
#define VOLTAGE_DETECT_ENABLE OFF
|
||||
|
||||
#if defined(MCU_CORE_826x)
|
||||
#define VOLTAGE_DETECT_ADC_PIN 0
|
||||
#elif defined(MCU_CORE_8258) || defined(MCU_CORE_8278)
|
||||
#define VOLTAGE_DETECT_ADC_PIN GPIO_PB7
|
||||
#elif defined(MCU_CORE_B91)
|
||||
#define VOLTAGE_DETECT_ADC_PIN ADC_GPIO_PB0
|
||||
#endif
|
||||
|
||||
/* Watch dog module */
|
||||
#define MODULE_WATCHDOG_ENABLE OFF
|
||||
|
||||
/* UART module */
|
||||
#define MODULE_UART_ENABLE OFF
|
||||
|
||||
/**********************************************************************
|
||||
* EV configuration
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
EV_POLL_ED_DETECT,
|
||||
EV_POLL_HCI,
|
||||
EV_POLL_IDLE,
|
||||
EV_POLL_MAX,
|
||||
} ev_poll_e;
|
||||
|
||||
enum{
|
||||
CLOCK_SYS_CLOCK_1S = CLOCK_SYS_CLOCK_HZ,
|
||||
CLOCK_SYS_CLOCK_1MS = (CLOCK_SYS_CLOCK_1S / 1000),
|
||||
CLOCK_SYS_CLOCK_1US = (CLOCK_SYS_CLOCK_1S / 1000000),
|
||||
};
|
||||
/* Disable C linkage for C++ Compilers: */
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
85
ARM_Tag_FW/OpenEPaperLink_TLSR/src/battery.c
Normal file
85
ARM_Tag_FW/OpenEPaperLink_TLSR/src/battery.c
Normal file
@@ -0,0 +1,85 @@
|
||||
#include <stdint.h>
|
||||
#include "tl_common.h"
|
||||
|
||||
#include "battery.h"
|
||||
|
||||
RAM volatile unsigned int adc_dat_buf[8];
|
||||
|
||||
void adc_bat_init(void)
|
||||
{
|
||||
adc_power_on_sar_adc(0);
|
||||
gpio_set_output_en(GPIO_PB7, 1);
|
||||
gpio_set_input_en(GPIO_PB7, 0);
|
||||
gpio_write(GPIO_PB7, 1);
|
||||
adc_set_sample_clk(5);
|
||||
adc_set_left_right_gain_bias(GAIN_STAGE_BIAS_PER100, GAIN_STAGE_BIAS_PER100);
|
||||
adc_set_chn_enable_and_max_state_cnt(ADC_MISC_CHN, 2);
|
||||
adc_set_state_length(240, 0, 10);
|
||||
analog_write(anareg_adc_res_m, RES14 | FLD_ADC_EN_DIFF_CHN_M);
|
||||
adc_set_ain_chn_misc(B7P, GND);
|
||||
adc_set_ref_voltage(ADC_MISC_CHN, ADC_VREF_1P2V);
|
||||
adc_set_tsample_cycle_chn_misc(SAMPLING_CYCLES_6);
|
||||
adc_set_ain_pre_scaler(ADC_PRESCALER_1F8);
|
||||
adc_power_on_sar_adc(1);
|
||||
}
|
||||
|
||||
uint16_t get_battery_mv()
|
||||
{
|
||||
uint16_t temp;
|
||||
int i, j;
|
||||
adc_bat_init();
|
||||
adc_reset_adc_module();
|
||||
u32 t0 = clock_time();
|
||||
|
||||
uint16_t adc_sample[8] = {0};
|
||||
u32 adc_result;
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
adc_dat_buf[i] = 0;
|
||||
}
|
||||
while (!clock_time_exceed(t0, 25))
|
||||
;
|
||||
adc_config_misc_channel_buf((uint16_t *)adc_dat_buf, 8 << 2);
|
||||
dfifo_enable_dfifo2();
|
||||
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
while (!adc_dat_buf[i])
|
||||
;
|
||||
if (adc_dat_buf[i] & BIT(13))
|
||||
{
|
||||
adc_sample[i] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
adc_sample[i] = ((uint16_t)adc_dat_buf[i] & 0x1FFF);
|
||||
}
|
||||
if (i)
|
||||
{
|
||||
if (adc_sample[i] < adc_sample[i - 1])
|
||||
{
|
||||
temp = adc_sample[i];
|
||||
adc_sample[i] = adc_sample[i - 1];
|
||||
for (j = i - 1; j >= 0 && adc_sample[j] > temp; j--)
|
||||
{
|
||||
adc_sample[j + 1] = adc_sample[j];
|
||||
}
|
||||
adc_sample[j + 1] = temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
dfifo_disable_dfifo2();
|
||||
u32 adc_average = (adc_sample[2] + adc_sample[3] + adc_sample[4] + adc_sample[5]) / 4;
|
||||
adc_result = adc_average;
|
||||
return (adc_result * 1175) >> 10;
|
||||
}
|
||||
|
||||
uint8_t get_battery_level(uint16_t battery_mv)
|
||||
{
|
||||
uint8_t battery_level = (battery_mv - 2200) / (31 - 22);
|
||||
if (battery_level > 100)
|
||||
battery_level = 100;
|
||||
if (battery_mv < 2200)
|
||||
battery_level = 0;
|
||||
return battery_level;
|
||||
}
|
||||
6
ARM_Tag_FW/OpenEPaperLink_TLSR/src/battery.h
Normal file
6
ARM_Tag_FW/OpenEPaperLink_TLSR/src/battery.h
Normal file
@@ -0,0 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
uint16_t get_battery_mv();
|
||||
uint8_t get_battery_level(uint16_t battery_mv);
|
||||
298
ARM_Tag_FW/OpenEPaperLink_TLSR/src/bitmaps.h
Normal file
298
ARM_Tag_FW/OpenEPaperLink_TLSR/src/bitmaps.h
Normal file
@@ -0,0 +1,298 @@
|
||||
#ifndef _BITMAPS_H_
|
||||
#define _BITMAPS_H_
|
||||
|
||||
// images generated by https://lvgl.io/tools/imageconverter, prepended with width, height. "CF_INDEXED_1_BIT"-mode, little-endian
|
||||
#include <stdint.h>
|
||||
|
||||
#include "screen.h"
|
||||
|
||||
static const uint8_t oepli[] = {
|
||||
128, 26,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x1c, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x9f, 0x80, 0x00, 0x00, 0x00, 0x00, 0x38, 0x70, 0x01, 0xc0,
|
||||
0x7f, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x9f, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x38, 0x70, 0x01, 0xc0,
|
||||
0x7f, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x9f, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x38, 0x70, 0x01, 0xc0,
|
||||
0xf7, 0x80, 0x00, 0x00, 0x00, 0x1c, 0x1c, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x01, 0xc0,
|
||||
0xe3, 0x80, 0x00, 0x00, 0x00, 0x1c, 0x1c, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x01, 0xc0,
|
||||
0xe3, 0x9d, 0xc1, 0xc7, 0x70, 0x1f, 0x9c, 0xe7, 0x73, 0xb8, 0x71, 0xd0, 0x38, 0x73, 0xb9, 0xc7,
|
||||
0xe3, 0x9f, 0xe3, 0xe7, 0xf8, 0x1f, 0x9f, 0xef, 0xf3, 0xfc, 0xf9, 0xf0, 0x38, 0x73, 0xfd, 0xce,
|
||||
0xe3, 0x9f, 0xe7, 0x77, 0xf8, 0x1f, 0x9f, 0xcf, 0xf3, 0xfd, 0xdd, 0xf0, 0x38, 0x73, 0xfd, 0xdc,
|
||||
0xe3, 0x9c, 0xe7, 0xf7, 0x38, 0x1c, 0x1f, 0x8e, 0x73, 0x9d, 0xfd, 0xc0, 0x38, 0x73, 0x9d, 0xf8,
|
||||
0xe3, 0x9c, 0xe7, 0xf7, 0x38, 0x1c, 0x1c, 0x0e, 0x73, 0x9d, 0xfd, 0xc0, 0x38, 0x73, 0x9d, 0xf8,
|
||||
0xf7, 0x9c, 0xe7, 0x07, 0x38, 0x1c, 0x1c, 0x0e, 0x73, 0x9d, 0xc1, 0xc0, 0x38, 0x73, 0x9d, 0xdc,
|
||||
0x7f, 0x1f, 0xe7, 0xf7, 0x38, 0x1f, 0x9c, 0x0f, 0xf3, 0xfd, 0xfd, 0xc0, 0x3f, 0x73, 0x9d, 0xdc,
|
||||
0x7f, 0x1f, 0xe3, 0xe7, 0x38, 0x1f, 0x9c, 0x0f, 0xf3, 0xfc, 0xf9, 0xc0, 0x3f, 0x73, 0x9d, 0xce,
|
||||
0x1e, 0x1d, 0xc1, 0xc7, 0x38, 0x1f, 0x9c, 0x07, 0x73, 0xb8, 0x71, 0xc0, 0x3f, 0x73, 0x9d, 0xc7,
|
||||
0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
};
|
||||
|
||||
static const uint8_t cloud[] = {
|
||||
128, 50,
|
||||
0x00, 0x08, 0x82, 0xa2, 0xab, 0x55, 0xbf, 0xff, 0xff, 0xff, 0x7d, 0xb4, 0x62, 0x28, 0x00, 0x00,
|
||||
0x00, 0x10, 0x10, 0x11, 0x76, 0xff, 0x7b, 0xff, 0xff, 0x7f, 0xb7, 0xa9, 0x55, 0x50, 0x51, 0x00,
|
||||
0x00, 0x29, 0x22, 0x96, 0x6f, 0xf7, 0xbf, 0xff, 0xff, 0xff, 0xea, 0xe6, 0x22, 0xaa, 0x08, 0x00,
|
||||
0x00, 0x02, 0x54, 0x2a, 0xbf, 0x3f, 0x7f, 0xff, 0xff, 0xff, 0xfd, 0x59, 0xb4, 0x10, 0x20, 0x00,
|
||||
0x00, 0x24, 0x23, 0xb5, 0xb5, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xf6, 0xae, 0x48, 0x55, 0x10, 0x00,
|
||||
0x00, 0x88, 0x90, 0x54, 0x6a, 0xef, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xf5, 0xa3, 0x82, 0x00, 0x00,
|
||||
0x00, 0x01, 0x2d, 0xa3, 0xb3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf6, 0xbe, 0x4e, 0x52, 0x09, 0x00,
|
||||
0x04, 0x90, 0x02, 0x0d, 0x55, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xfd, 0xdd, 0x68, 0xa9, 0x00, 0x10,
|
||||
0x00, 0x49, 0x0c, 0xfb, 0xab, 0x6f, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xeb, 0x95, 0x5a, 0x00, 0x20,
|
||||
0x00, 0x12, 0x91, 0x22, 0xbf, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf5, 0x65, 0x81, 0x40, 0x40,
|
||||
0x00, 0x28, 0x12, 0x7d, 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xab, 0x28, 0x00, 0x00,
|
||||
0x00, 0x42, 0x0a, 0x97, 0x75, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf7, 0x4a, 0xc2, 0x04, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x08, 0x02, 0x9c, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x6a, 0x6a, 0x8d, 0x00, 0x20,
|
||||
0x00, 0x04, 0x4d, 0x72, 0xaa, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xd5, 0xd5, 0x74, 0x80, 0x00,
|
||||
0x02, 0x40, 0x12, 0x8e, 0xdf, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xae, 0xaa, 0x0a, 0x11, 0x20,
|
||||
0x00, 0x20, 0x52, 0x5f, 0xf5, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0x72, 0x94, 0xaa, 0x24, 0x00,
|
||||
0x00, 0x01, 0x0a, 0xab, 0x6f, 0x77, 0xff, 0xff, 0xff, 0xff, 0xfd, 0xaf, 0x54, 0x54, 0x88, 0x00,
|
||||
0x00, 0x04, 0x80, 0x4d, 0x95, 0xeb, 0xff, 0xff, 0xff, 0xff, 0x5b, 0x58, 0xb5, 0x51, 0x40, 0x00,
|
||||
0x00, 0x08, 0x08, 0xa6, 0xb3, 0xf7, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xad, 0x4a, 0xa0, 0x10, 0x00,
|
||||
0x00, 0x02, 0x96, 0x41, 0xdc, 0xae, 0xff, 0xff, 0xff, 0xff, 0xfd, 0xbf, 0xea, 0x48, 0x02, 0x00,
|
||||
0x00, 0x00, 0x09, 0x3e, 0xab, 0x75, 0xef, 0xff, 0xff, 0xff, 0xff, 0xd4, 0xb1, 0x21, 0x08, 0x00,
|
||||
0x00, 0x00, 0x0a, 0xc3, 0x5d, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xef, 0xef, 0x44, 0x4a, 0x64, 0x80,
|
||||
0x00, 0x00, 0xa1, 0x52, 0xa6, 0xef, 0xef, 0xff, 0xff, 0xff, 0xd6, 0xca, 0xf5, 0x10, 0x18, 0x00,
|
||||
0x00, 0x00, 0x02, 0x15, 0x4b, 0xd5, 0xdf, 0xff, 0xff, 0xf7, 0xeb, 0xd4, 0xd8, 0x85, 0x00, 0x00,
|
||||
};
|
||||
|
||||
static const uint8_t receive[] = {
|
||||
56, 56,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xc0,
|
||||
0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xf0,
|
||||
0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xf0,
|
||||
0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xf0,
|
||||
0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xf0,
|
||||
0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xc0,
|
||||
0x00, 0x00, 0x00, 0x1f, 0xff, 0x80, 0x00,
|
||||
0x00, 0x00, 0x00, 0x7f, 0xf8, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0xff, 0xe0, 0x00, 0x00,
|
||||
0x00, 0x00, 0x01, 0xff, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x07, 0xfe, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x0f, 0xf8, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x1f, 0xe0, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x3f, 0xc0, 0x00, 0x03, 0xe0,
|
||||
0x00, 0x00, 0x7f, 0x80, 0x00, 0x7f, 0xf0,
|
||||
0x00, 0x00, 0xfe, 0x00, 0x03, 0xff, 0xf0,
|
||||
0x00, 0x01, 0xfc, 0x00, 0x0f, 0xff, 0xf0,
|
||||
0x00, 0x01, 0xf8, 0x00, 0x3f, 0xff, 0xf0,
|
||||
0x00, 0x03, 0xf8, 0x00, 0xff, 0xff, 0x80,
|
||||
0x00, 0x07, 0xf0, 0x01, 0xff, 0xe0, 0x00,
|
||||
0x00, 0x0f, 0xe0, 0x03, 0xff, 0x00, 0x00,
|
||||
0x00, 0x0f, 0xc0, 0x0f, 0xf8, 0x00, 0x00,
|
||||
0x00, 0x1f, 0x80, 0x1f, 0xf0, 0x00, 0x00,
|
||||
0x00, 0x1f, 0x80, 0x3f, 0xc0, 0x00, 0x00,
|
||||
0x00, 0x3f, 0x00, 0x3f, 0x80, 0x00, 0x00,
|
||||
0x00, 0x3f, 0x00, 0x7f, 0x00, 0x00, 0x00,
|
||||
0x00, 0x7e, 0x00, 0xfe, 0x00, 0x07, 0xe0,
|
||||
0x00, 0x7e, 0x01, 0xfc, 0x00, 0x1f, 0xf0,
|
||||
0x00, 0xfc, 0x01, 0xf8, 0x00, 0x7f, 0xf0,
|
||||
0x00, 0xfc, 0x03, 0xf0, 0x01, 0xff, 0xf0,
|
||||
0x00, 0xf8, 0x03, 0xf0, 0x03, 0xff, 0xf0,
|
||||
0x01, 0xf8, 0x07, 0xe0, 0x07, 0xff, 0x00,
|
||||
0x01, 0xf8, 0x07, 0xe0, 0x0f, 0xf0, 0x00,
|
||||
0x01, 0xf0, 0x0f, 0xc0, 0x1f, 0xe0, 0x00,
|
||||
0x01, 0xf0, 0x0f, 0xc0, 0x3f, 0x80, 0x00,
|
||||
0x03, 0xf0, 0x0f, 0x80, 0x3f, 0x00, 0x00,
|
||||
0x03, 0xf0, 0x1f, 0x80, 0x7e, 0x00, 0x00,
|
||||
0x03, 0xe0, 0x1f, 0x80, 0x7e, 0x00, 0x00,
|
||||
0x03, 0xe0, 0x1f, 0x00, 0xfc, 0x01, 0xe0,
|
||||
0x03, 0xe0, 0x1f, 0x00, 0xfc, 0x07, 0xf8,
|
||||
0x03, 0xe0, 0x1f, 0x00, 0xf8, 0x0f, 0xfc,
|
||||
0x03, 0xe0, 0x3f, 0x00, 0xf8, 0x0f, 0xfc,
|
||||
0x03, 0xe0, 0x3f, 0x01, 0xf8, 0x1f, 0xfe,
|
||||
0x03, 0xe0, 0x3f, 0x01, 0xf8, 0x1f, 0xfe,
|
||||
0x03, 0xe0, 0x3f, 0x01, 0xf8, 0x1f, 0xfe,
|
||||
0x03, 0xc0, 0x3e, 0x01, 0xf0, 0x1f, 0xfe,
|
||||
0x01, 0xc0, 0x1e, 0x00, 0xf0, 0x0f, 0xfc,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xfc,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xf8,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xe0,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
};
|
||||
|
||||
|
||||
static const uint8_t failed[] = {
|
||||
48, 48,
|
||||
0x00, 0x00, 0x1f, 0xf8, 0x00, 0x00,
|
||||
0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
|
||||
0x00, 0x03, 0xff, 0xff, 0xe0, 0x00,
|
||||
0x00, 0x0f, 0xff, 0xff, 0xf0, 0x00,
|
||||
0x00, 0x3f, 0xff, 0xff, 0xfc, 0x00,
|
||||
0x00, 0x7f, 0xf0, 0x0f, 0xfe, 0x00,
|
||||
0x00, 0xff, 0x80, 0x01, 0xff, 0x00,
|
||||
0x01, 0xfe, 0x00, 0x00, 0x7f, 0x80,
|
||||
0x03, 0xf8, 0x00, 0x00, 0x1f, 0xc0,
|
||||
0x07, 0xf0, 0x00, 0x00, 0x3f, 0xe0,
|
||||
0x0f, 0xe0, 0x00, 0x00, 0x7f, 0xf0,
|
||||
0x0f, 0xc0, 0x00, 0x00, 0xff, 0xf0,
|
||||
0x1f, 0x80, 0x00, 0x01, 0xff, 0xf8,
|
||||
0x1f, 0x00, 0x00, 0x03, 0xff, 0xf8,
|
||||
0x3f, 0x00, 0x00, 0x07, 0xfe, 0xfc,
|
||||
0x3e, 0x00, 0x00, 0x0f, 0xfc, 0x7c,
|
||||
0x7e, 0x00, 0x00, 0x1f, 0xf8, 0x7e,
|
||||
0x7c, 0x00, 0x00, 0x3f, 0xf0, 0x3e,
|
||||
0x7c, 0x00, 0x00, 0x7f, 0xe0, 0x3e,
|
||||
0xfc, 0x00, 0x00, 0xff, 0xc0, 0x3f,
|
||||
0xf8, 0x00, 0x01, 0xff, 0x80, 0x1f,
|
||||
0xf8, 0x00, 0x03, 0xff, 0x00, 0x1f,
|
||||
0xf8, 0x00, 0x07, 0xfe, 0x00, 0x1f,
|
||||
0xf8, 0x00, 0x0f, 0xfc, 0x00, 0x1f,
|
||||
0xf8, 0x00, 0x1f, 0xf8, 0x00, 0x1f,
|
||||
0xf8, 0x00, 0x3f, 0xf0, 0x00, 0x1f,
|
||||
0xf8, 0x00, 0x7f, 0xe0, 0x00, 0x1f,
|
||||
0xf8, 0x00, 0xff, 0xc0, 0x00, 0x1f,
|
||||
0xfc, 0x01, 0xff, 0x80, 0x00, 0x3f,
|
||||
0x7c, 0x03, 0xff, 0x00, 0x00, 0x3e,
|
||||
0x7c, 0x07, 0xfe, 0x00, 0x00, 0x3e,
|
||||
0x7e, 0x0f, 0xfc, 0x00, 0x00, 0x7e,
|
||||
0x3e, 0x1f, 0xf8, 0x00, 0x00, 0x7c,
|
||||
0x3f, 0x3f, 0xf0, 0x00, 0x00, 0xfc,
|
||||
0x3f, 0x7f, 0xe0, 0x00, 0x00, 0xfc,
|
||||
0x1f, 0xff, 0xc0, 0x00, 0x01, 0xf8,
|
||||
0x0f, 0xff, 0x80, 0x00, 0x03, 0xf0,
|
||||
0x0f, 0xff, 0x00, 0x00, 0x07, 0xf0,
|
||||
0x07, 0xfe, 0x00, 0x00, 0x0f, 0xe0,
|
||||
0x03, 0xfc, 0x00, 0x00, 0x1f, 0xc0,
|
||||
0x01, 0xfe, 0x00, 0x00, 0x7f, 0x80,
|
||||
0x00, 0xff, 0x80, 0x01, 0xff, 0x00,
|
||||
0x00, 0x7f, 0xf0, 0x0f, 0xfe, 0x00,
|
||||
0x00, 0x3f, 0xff, 0xff, 0xfc, 0x00,
|
||||
0x00, 0x0f, 0xff, 0xff, 0xf0, 0x00,
|
||||
0x00, 0x03, 0xff, 0xff, 0xe0, 0x00,
|
||||
0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
|
||||
0x00, 0x00, 0x1f, 0xf8, 0x00, 0x00,
|
||||
};
|
||||
|
||||
#if (SCREEN_WIDTH != 128)
|
||||
static const uint8_t ant[] = {
|
||||
16, 16,
|
||||
0x00, 0x40,
|
||||
0x02, 0x20,
|
||||
0x01, 0x20,
|
||||
0x11, 0x20,
|
||||
0x11, 0x20,
|
||||
0x12, 0x20,
|
||||
0x28, 0x40,
|
||||
0x28, 0x00,
|
||||
0x28, 0x00,
|
||||
0x44, 0x00,
|
||||
0x44, 0x00,
|
||||
0x44, 0x00,
|
||||
0x44, 0x00,
|
||||
0x82, 0x00,
|
||||
0x82, 0x00,
|
||||
0xfe, 0x00,
|
||||
};
|
||||
#else
|
||||
static const uint8_t ant[] = {
|
||||
// rotated 90 degrees
|
||||
16,16,
|
||||
0x00, 0x00,
|
||||
0x00, 0x00,
|
||||
0x00, 0x00,
|
||||
0x00, 0x00,
|
||||
0x00, 0x00,
|
||||
0x7c, 0x00,
|
||||
0x82, 0x00,
|
||||
0x00, 0x00,
|
||||
0x38, 0x00,
|
||||
0x44, 0x07,
|
||||
0x00, 0x79,
|
||||
0x03, 0x81,
|
||||
0x1c, 0x01,
|
||||
0x03, 0x81,
|
||||
0x00, 0x79,
|
||||
0x00, 0x07,
|
||||
};
|
||||
#endif
|
||||
static const uint8_t cross[] = {
|
||||
8,8,
|
||||
0x00,
|
||||
0x63,
|
||||
0x77,
|
||||
0x3e,
|
||||
0x1c,
|
||||
0x3e,
|
||||
0x77,
|
||||
0x63
|
||||
};
|
||||
|
||||
#if (SCREEN_WIDTH != 128)
|
||||
static const uint8_t battery[] = {
|
||||
16,10,
|
||||
0x00, 0x00,
|
||||
0x7f, 0xfc,
|
||||
0x40, 0x04,
|
||||
0x58, 0x06,
|
||||
0x58, 0x06,
|
||||
0x58, 0x06,
|
||||
0x58, 0x06,
|
||||
0x40, 0x04,
|
||||
0x7f, 0xfc,
|
||||
0x00, 0x00,
|
||||
};
|
||||
#else
|
||||
// this battery symbol is rotated 90'
|
||||
static const uint8_t battery[] = {
|
||||
16,16,
|
||||
0x00, 0x00,
|
||||
0x03, 0xc0,
|
||||
0x0f, 0xf0,
|
||||
0x08, 0x10,
|
||||
0x08, 0x10,
|
||||
0x08, 0x10,
|
||||
0x08, 0x10,
|
||||
0x08, 0x10,
|
||||
0x08, 0x10,
|
||||
0x08, 0x10,
|
||||
0x08, 0x10,
|
||||
0x0b, 0xd0,
|
||||
0x0b, 0xd0,
|
||||
0x08, 0x10,
|
||||
0x0f, 0xf0,
|
||||
0x00, 0x00,
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
31
ARM_Tag_FW/OpenEPaperLink_TLSR/src/board.h
Normal file
31
ARM_Tag_FW/OpenEPaperLink_TLSR/src/board.h
Normal file
@@ -0,0 +1,31 @@
|
||||
#ifndef _BOARD_H_
|
||||
#define _BOARD_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include "proto.h"
|
||||
#include "main.h"
|
||||
|
||||
//eeprom map
|
||||
#define EEPROM_SETTINGS_AREA_START (0x40000UL)
|
||||
#define EEPROM_SETTINGS_AREA_LEN (0x03000UL)
|
||||
|
||||
#define EEPROM_UPDATA_AREA_START (0x43000UL)
|
||||
#define EEPROM_UPDATE_AREA_LEN (0x20000UL)
|
||||
|
||||
#define EEPROM_IMG_START (0x43000UL)
|
||||
#define EEPROM_IMG_EACH (0x7000UL)
|
||||
#define EEPROM_IMG_LEN (0x20000UL)
|
||||
|
||||
#define EEPROM_PAGE_SIZE (0x01000)
|
||||
//till end of eeprom really. do not put anything after - it will be erased at pairing time!!!
|
||||
#define EEPROM_PROGRESS_BYTES (128)
|
||||
|
||||
|
||||
#define HAS_EEPROM 1
|
||||
#define HAS_SCREEN 1
|
||||
#define AP_EMULATE_TAG 1
|
||||
|
||||
//hw types
|
||||
#define HW_TYPE 0x60
|
||||
|
||||
#endif
|
||||
24
ARM_Tag_FW/OpenEPaperLink_TLSR/src/board_8258_diy.h
Normal file
24
ARM_Tag_FW/OpenEPaperLink_TLSR/src/board_8258_diy.h
Normal file
@@ -0,0 +1,24 @@
|
||||
#ifndef SRC_INCLUDE_BOARD_8258_DIY_H_
|
||||
#define SRC_INCLUDE_BOARD_8258_DIY_H_
|
||||
|
||||
/************************* For 512K Flash only ***************************************/
|
||||
/* Flash map:
|
||||
0x00000 Old Firmware bin
|
||||
0x34000 NV_1
|
||||
0x40000 OTA New bin storage Area
|
||||
0x76000 MAC address
|
||||
0x77000 C_Cfg_Info
|
||||
0x78000 U_Cfg_Info
|
||||
0x7A000 NV_2
|
||||
0x80000 End Flash
|
||||
*/
|
||||
#define USER_DATA_SIZE 0x34000
|
||||
#define BEGIN_USER_DATA1 0x00000
|
||||
#define END_USER_DATA1 (BEGIN_USER_DATA1 + USER_DATA_SIZE)
|
||||
#define BEGIN_USER_DATA2 0x40000
|
||||
#define END_USER_DATA2 (BEGIN_USER_DATA2 + USER_DATA_SIZE)
|
||||
#define GEN_USER_CFG_DATA END_USER_DATA2
|
||||
|
||||
|
||||
|
||||
#endif /* SRC_INCLUDE_BOARD_8258_DIY_H_ */
|
||||
83
ARM_Tag_FW/OpenEPaperLink_TLSR/src/comm_cfg.h
Normal file
83
ARM_Tag_FW/OpenEPaperLink_TLSR/src/comm_cfg.h
Normal file
@@ -0,0 +1,83 @@
|
||||
/********************************************************************************************************
|
||||
* @file comm_cfg.h
|
||||
*
|
||||
* @brief This is the header file for comm_cfg
|
||||
*
|
||||
* @author Zigbee Group
|
||||
* @date 2021
|
||||
*
|
||||
* @par Copyright (c) 2021, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK")
|
||||
* All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*******************************************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* User configuration whether to use boot loader mode.
|
||||
*
|
||||
* NOTE:
|
||||
* We do not recommend using BootLoader mode on 512K flash chips,
|
||||
* because in boot loader mode, it can only support up to 196k firmware
|
||||
* according to the current default Flash Map.
|
||||
*
|
||||
* Please refer to the drv_nv.h file, and check if the firmware size
|
||||
* exceeds the maximum limit.
|
||||
*
|
||||
* The user can configure the CHIP_TYPE used by the corresponding
|
||||
* project in the version.h file according to the actual size
|
||||
* of the flash at hand.
|
||||
*
|
||||
* If BOOT_LOADER_MODE is 0, it means that the SDK uses Normal Mode,
|
||||
* hardware multi-address (0x0000 or 0x40000) startup mode.
|
||||
* If BOOT_LOADER_MODE is 1, it means that the SDK uses Boot Loader Mode.
|
||||
*
|
||||
* Normal mode is used by default.
|
||||
*/
|
||||
#define BOOT_LOADER_MODE 0
|
||||
|
||||
|
||||
|
||||
/* Boot loader address. */
|
||||
#define BOOT_LOADER_IMAGE_ADDR 0x0
|
||||
|
||||
/* APP image address. */
|
||||
#if (BOOT_LOADER_MODE)
|
||||
#define APP_IMAGE_ADDR 0x8000
|
||||
#else
|
||||
#define APP_IMAGE_ADDR 0x0
|
||||
#endif
|
||||
|
||||
|
||||
/* Chip IDs */
|
||||
#define TLSR_8267 0x00
|
||||
#define TLSR_8269 0x01
|
||||
#define TLSR_8258_512K 0x02
|
||||
#define TLSR_8258_1M 0x03
|
||||
#define TLSR_8278 0x04
|
||||
#define TLSR_B91 0x05
|
||||
|
||||
/* Image types */
|
||||
#if (BOOT_LOADER_MODE)
|
||||
#define IMAGE_TYPE_BOOT_FLAG 1
|
||||
#else
|
||||
#define IMAGE_TYPE_BOOT_FLAG 0
|
||||
#endif
|
||||
#define IMAGE_TYPE_BOOTLOADER (0xFF)
|
||||
#define IMAGE_TYPE_GW (0x00 | (IMAGE_TYPE_BOOT_FLAG << 7))
|
||||
#define IMAGE_TYPE_LIGHT (0x01 | (IMAGE_TYPE_BOOT_FLAG << 7))
|
||||
#define IMAGE_TYPE_SWITCH (0x02 | (IMAGE_TYPE_BOOT_FLAG << 7))
|
||||
#define IMAGE_TYPE_CONTACT_SENSOR (0x03 | (IMAGE_TYPE_BOOT_FLAG << 7))
|
||||
45
ARM_Tag_FW/OpenEPaperLink_TLSR/src/comms.c
Normal file
45
ARM_Tag_FW/OpenEPaperLink_TLSR/src/comms.c
Normal file
@@ -0,0 +1,45 @@
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
#include "tl_common.h"
|
||||
#include "proto.h"
|
||||
#include "zigbee.h"
|
||||
#include "comms.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;
|
||||
int8_t mLastRSSI = 0;
|
||||
|
||||
uint8_t commsGetLastPacketLQI(void)
|
||||
{
|
||||
return mLastLqi;
|
||||
}
|
||||
|
||||
int8_t commsGetLastPacketRSSI(void)
|
||||
{
|
||||
return mLastRSSI;
|
||||
}
|
||||
|
||||
int8_t commsRxUnencrypted(uint8_t *data)
|
||||
{
|
||||
memset(data, 0, 128);
|
||||
int8_t rxedLen = radioRxDequeuePkt(data, 128, &mLastRSSI, &mLastLqi);
|
||||
if (rxedLen < 0)
|
||||
return COMMS_RX_ERR_NO_PACKETS;
|
||||
if (memcmp((void *)&data[5], mSelfMac, 8)) // Here we filter for our MAC Address... in software...
|
||||
return COMMS_RX_ERR_INVALID_PACKET;
|
||||
return rxedLen;
|
||||
}
|
||||
|
||||
bool commsTxNoCpy(const void *packetp)
|
||||
{
|
||||
return radioTxLL(packetp);
|
||||
}
|
||||
24
ARM_Tag_FW/OpenEPaperLink_TLSR/src/comms.h
Normal file
24
ARM_Tag_FW/OpenEPaperLink_TLSR/src/comms.h
Normal file
@@ -0,0 +1,24 @@
|
||||
#ifndef _COMMS_H_
|
||||
#define _COMMS_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
|
||||
#define COMMS_MAX_RADIO_WAIT_MSEC 200
|
||||
|
||||
#define COMMS_RX_ERR_NO_PACKETS (-1)
|
||||
#define COMMS_RX_ERR_INVALID_PACKET (-2)
|
||||
|
||||
#define COMMS_MAX_PACKET_SZ (127)
|
||||
|
||||
extern uint8_t mLastLqi;
|
||||
extern int8_t mLastRSSI;
|
||||
|
||||
int8_t commsRxUnencrypted(uint8_t *data);
|
||||
bool commsTxUnencrypted(const void *packetP, uint8_t len);
|
||||
|
||||
bool commsTxNoCpy(const void *packetp);
|
||||
|
||||
|
||||
#endif
|
||||
67
ARM_Tag_FW/OpenEPaperLink_TLSR/src/drawing.c
Normal file
67
ARM_Tag_FW/OpenEPaperLink_TLSR/src/drawing.c
Normal file
@@ -0,0 +1,67 @@
|
||||
#include "drawing.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "tl_common.h"
|
||||
#include "board.h"
|
||||
#include "eeprom.h"
|
||||
#include "proto.h"
|
||||
#include "screen.h"
|
||||
#include "epd.h"
|
||||
|
||||
static uint8_t mClutMap[256];
|
||||
void drawImageAtAddress(uint32_t addr, uint8_t lut)
|
||||
{
|
||||
struct EepromImageHeader *eih = (struct EepromImageHeader *)mClutMap;
|
||||
eepromRead(addr, mClutMap, sizeof(struct EepromImageHeader));
|
||||
switch (eih->dataType)
|
||||
{
|
||||
case DATATYPE_IMG_RAW_1BPP:
|
||||
printf("Doing raw 1bpp\r\n");
|
||||
EPD_Display_start(1);
|
||||
for (uint32_t c = 0; c < (SCREEN_HEIGHT * (SCREEN_WIDTH / 8)); c++)
|
||||
{
|
||||
if (c % 256 == 0)
|
||||
{
|
||||
eepromRead(addr + sizeof(struct EepromImageHeader) + c, mClutMap, 256);
|
||||
}
|
||||
EPD_Display_byte(mClutMap[c % 256]);
|
||||
}
|
||||
EPD_Display_color_change();
|
||||
for (uint32_t c = 0; c < (SCREEN_HEIGHT * (SCREEN_WIDTH / 8)); c++)
|
||||
{
|
||||
EPD_Display_byte(0x00);
|
||||
}
|
||||
EPD_Display_end();
|
||||
break;
|
||||
case DATATYPE_IMG_RAW_2BPP:
|
||||
printf("Doing raw 2bpp\r\n");
|
||||
EPD_Display_start(1);
|
||||
for (uint32_t c = 0; c < (SCREEN_HEIGHT * (SCREEN_WIDTH / 8)); c++)
|
||||
{
|
||||
if (c % 256 == 0)
|
||||
{
|
||||
eepromRead(addr + sizeof(struct EepromImageHeader) + c, mClutMap, 256);
|
||||
}
|
||||
EPD_Display_byte(mClutMap[c % 256]);
|
||||
}
|
||||
EPD_Display_color_change();
|
||||
for (uint32_t c = 0; c < (SCREEN_HEIGHT * (SCREEN_WIDTH / 8)); c++)
|
||||
{
|
||||
if (c % 256 == 0)
|
||||
{
|
||||
eepromRead(addr + sizeof(struct EepromImageHeader) + (SCREEN_HEIGHT * (SCREEN_WIDTH / 8)) + c, mClutMap, 256);
|
||||
}
|
||||
EPD_Display_byte(mClutMap[c % 256]);
|
||||
}
|
||||
EPD_Display_end();
|
||||
break;
|
||||
case DATATYPE_IMG_BMP:;
|
||||
printf("sending BMP to EPD - ");
|
||||
|
||||
printf(" complete.\r\n");
|
||||
break;
|
||||
default: // prevent drawing from an unknown file image type
|
||||
printf("Image with type 0x%02X was requested, but we don't know what to do with that currently...\r\n", eih->dataType);
|
||||
return;
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user