mirror of
https://github.com/OpenEPaperLink/OpenEPaperLink.git
synced 2026-03-21 14:06:31 +01:00
Compare commits
38 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a251ed10e7 | ||
|
|
65410e3e8d | ||
|
|
b2174c2980 | ||
|
|
7db482a6ba | ||
|
|
bac7cf7ab5 | ||
|
|
a3e739b8da | ||
|
|
cc1dcd9d29 | ||
|
|
10468313e1 | ||
|
|
2e55c49a92 | ||
|
|
e45845e00e | ||
|
|
940795d05d | ||
|
|
a3fc1da6d2 | ||
|
|
d778aab553 | ||
|
|
f460046c51 | ||
|
|
e5ddba02ff | ||
|
|
7ba80f57c9 | ||
|
|
d6feb5a8ca | ||
|
|
1e034c83fa | ||
|
|
1e93a24b53 | ||
|
|
dbf76e2176 | ||
|
|
93639ff8ac | ||
|
|
48b2925b9f | ||
|
|
9c83d8b5a5 | ||
|
|
f487092f7f | ||
|
|
eae7c3a159 | ||
|
|
4d78df09cc | ||
|
|
e8740b2022 | ||
|
|
6c4e254db0 | ||
|
|
5ccbcb4719 | ||
|
|
617b49eb86 | ||
|
|
5868abf189 | ||
|
|
94be1ea3aa | ||
|
|
5190327d5a | ||
|
|
6ecf6410ee | ||
|
|
e72e89d85e | ||
|
|
054146677f | ||
|
|
58d9fe2217 | ||
|
|
5196c1b212 |
@@ -1,4 +1,4 @@
|
||||
name: ESP32 build
|
||||
name: ESP32 firmware builf test
|
||||
|
||||
on: [push,pull_request]
|
||||
|
||||
@@ -20,32 +20,38 @@ jobs:
|
||||
- name: Install PlatformIO Core
|
||||
run: pip install --upgrade platformio
|
||||
|
||||
- name: Build firmware for ESP32
|
||||
- name: Build Simple_AP
|
||||
run: |
|
||||
cd ESP32_AP-Flasher
|
||||
pio run --environment Simple_AP
|
||||
|
||||
- name: Build filesystem for ESP32
|
||||
run: |
|
||||
cd ESP32_AP-Flasher
|
||||
pio run --target buildfs --environment Simple_AP
|
||||
|
||||
- name: Build firmware for ESP32-S2
|
||||
- name: Build OpenEPaperLink_Mini_AP
|
||||
run: |
|
||||
cd ESP32_AP-Flasher
|
||||
pio run --environment OpenEPaperLink_Mini_AP
|
||||
pio run --target buildfs --environment OpenEPaperLink_Mini_AP
|
||||
|
||||
- name: Build filesystem for ESP32-S2
|
||||
- name: Build OpenEPaperLink_Nano_AP
|
||||
run: |
|
||||
cd ESP32_AP-Flasher
|
||||
pio run --target buildfs --environment OpenEPaperLink_Mini_AP
|
||||
pio run --environment OpenEPaperLink_Nano_AP
|
||||
pio run --target buildfs --environment OpenEPaperLink_Nano_AP
|
||||
|
||||
- name: Build firmware for ESP32-S3
|
||||
- name: Build OpenEPaperLink_AP_and_Flasher
|
||||
run: |
|
||||
cd ESP32_AP-Flasher
|
||||
pio run --environment OpenEPaperLink_AP_and_Flasher
|
||||
|
||||
- name: Build filesystem for ESP32-S3
|
||||
pio run --target buildfs --environment OpenEPaperLink_AP_and_Flasher
|
||||
|
||||
- name: Build Weemos_AP
|
||||
run: |
|
||||
cd ESP32_AP-Flasher
|
||||
pio run --target buildfs --environment OpenEPaperLink_AP_and_Flasher
|
||||
pio run --environment Weemos_AP
|
||||
pio run --target buildfs --environment Weemos_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
|
||||
276
.github/workflows/release.yml
vendored
276
.github/workflows/release.yml
vendored
@@ -26,6 +26,150 @@ jobs:
|
||||
|
||||
- name: Install esptool
|
||||
run: pip install esptool
|
||||
|
||||
- name: create folders
|
||||
run: |
|
||||
mkdir espbinaries
|
||||
|
||||
- name: Build firmware for Simple_AP
|
||||
run: |
|
||||
cd ESP32_AP-Flasher
|
||||
export PLATFORMIO_BUILD_FLAGS="-D BUILD_VERSION=${{ github.ref_name }} -D SHA=$GITHUB_SHA"
|
||||
pio run --environment Simple_AP
|
||||
pio run --target buildfs --environment Simple_AP
|
||||
mkdir /home/runner/work/OpenEPaperLink/OpenEPaperLink/Simple_AP
|
||||
cp ~/.platformio/packages/framework-arduinoespressif32/tools/partitions/boot_app0.bin /home/runner/work/OpenEPaperLink/OpenEPaperLink/Simple_AP/boot_app0.bin
|
||||
cp .pio/build/Simple_AP/firmware.bin /home/runner/work/OpenEPaperLink/OpenEPaperLink/Simple_AP/firmware.bin
|
||||
cp .pio/build/Simple_AP/bootloader.bin /home/runner/work/OpenEPaperLink/OpenEPaperLink/Simple_AP/bootloader.bin
|
||||
cp .pio/build/Simple_AP/partitions.bin /home/runner/work/OpenEPaperLink/OpenEPaperLink/Simple_AP/partitions.bin
|
||||
cp .pio/build/Simple_AP/littlefs.bin /home/runner/work/OpenEPaperLink/OpenEPaperLink/Simple_AP/littlefs.bin
|
||||
cd /home/runner/work/OpenEPaperLink/OpenEPaperLink/Simple_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 Simple_AP/firmware.bin espbinaries/Simple_AP.bin
|
||||
cp Simple_AP/merged-firmware.bin espbinaries/Simple_AP_full.bin
|
||||
|
||||
- name: Build firmware for Weemos_AP
|
||||
run: |
|
||||
cd ESP32_AP-Flasher
|
||||
export PLATFORMIO_BUILD_FLAGS="-D BUILD_VERSION=${{ github.ref_name }} -D SHA=$GITHUB_SHA"
|
||||
pio run --environment Weemos_AP
|
||||
pio run --target buildfs --environment Weemos_AP
|
||||
mkdir /home/runner/work/OpenEPaperLink/OpenEPaperLink/Weemos_AP
|
||||
cp ~/.platformio/packages/framework-arduinoespressif32/tools/partitions/boot_app0.bin /home/runner/work/OpenEPaperLink/OpenEPaperLink/Weemos_AP/boot_app0.bin
|
||||
cp .pio/build/Weemos_AP/firmware.bin /home/runner/work/OpenEPaperLink/OpenEPaperLink/Weemos_AP/firmware.bin
|
||||
cp .pio/build/Weemos_AP/bootloader.bin /home/runner/work/OpenEPaperLink/OpenEPaperLink/Weemos_AP/bootloader.bin
|
||||
cp .pio/build/Weemos_AP/partitions.bin /home/runner/work/OpenEPaperLink/OpenEPaperLink/Weemos_AP/partitions.bin
|
||||
cp .pio/build/Weemos_AP/littlefs.bin /home/runner/work/OpenEPaperLink/OpenEPaperLink/Weemos_AP/littlefs.bin
|
||||
cd /home/runner/work/OpenEPaperLink/OpenEPaperLink/Weemos_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 Weemos_AP/firmware.bin espbinaries/Weemos_AP.bin
|
||||
cp Weemos_AP/merged-firmware.bin espbinaries/Weemos_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
|
||||
export PLATFORMIO_BUILD_FLAGS="-D BUILD_VERSION=${{ github.ref_name }} -D SHA=$GITHUB_SHA"
|
||||
pio run --environment OpenEPaperLink_Mini_AP
|
||||
pio run --target buildfs --environment OpenEPaperLink_Mini_AP
|
||||
mkdir /home/runner/work/OpenEPaperLink/OpenEPaperLink/OpenEPaperLink_Mini_AP
|
||||
cp ~/.platformio/packages/framework-arduinoespressif32/tools/partitions/boot_app0.bin /home/runner/work/OpenEPaperLink/OpenEPaperLink/OpenEPaperLink_Mini_AP/boot_app0.bin
|
||||
cp .pio/build/OpenEPaperLink_Mini_AP/firmware.bin /home/runner/work/OpenEPaperLink/OpenEPaperLink/OpenEPaperLink_Mini_AP/firmware.bin
|
||||
cp .pio/build/OpenEPaperLink_Mini_AP/bootloader.bin /home/runner/work/OpenEPaperLink/OpenEPaperLink/OpenEPaperLink_Mini_AP/bootloader.bin
|
||||
cp .pio/build/OpenEPaperLink_Mini_AP/partitions.bin /home/runner/work/OpenEPaperLink/OpenEPaperLink/OpenEPaperLink_Mini_AP/partitions.bin
|
||||
cp .pio/build/OpenEPaperLink_Mini_AP/littlefs.bin /home/runner/work/OpenEPaperLink/OpenEPaperLink/OpenEPaperLink_Mini_AP/littlefs.bin
|
||||
cd /home/runner/work/OpenEPaperLink/OpenEPaperLink/OpenEPaperLink_Mini_AP
|
||||
esptool.py --chip esp32-s2 merge_bin -o merged-firmware.bin --flash_mode dio --flash_freq 80m --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 OpenEPaperLink_Mini_AP/firmware.bin espbinaries/OpenEPaperLink_Mini_AP.bin
|
||||
cp OpenEPaperLink_Mini_AP/merged-firmware.bin espbinaries/OpenEPaperLink_Mini_AP_full.bin
|
||||
|
||||
- name: Build firmware for OpenEPaperLink_Nano_AP
|
||||
run: |
|
||||
cd ESP32_AP-Flasher
|
||||
export PLATFORMIO_BUILD_FLAGS="-D BUILD_VERSION=${{ github.ref_name }} -D SHA=$GITHUB_SHA"
|
||||
pio run --environment OpenEPaperLink_Nano_AP
|
||||
pio run --target buildfs --environment OpenEPaperLink_Nano_AP
|
||||
mkdir /home/runner/work/OpenEPaperLink/OpenEPaperLink/OpenEPaperLink_Nano_AP
|
||||
cp ~/.platformio/packages/framework-arduinoespressif32/tools/partitions/boot_app0.bin /home/runner/work/OpenEPaperLink/OpenEPaperLink/OpenEPaperLink_Nano_AP/boot_app0.bin
|
||||
cp .pio/build/OpenEPaperLink_Nano_AP/firmware.bin /home/runner/work/OpenEPaperLink/OpenEPaperLink/OpenEPaperLink_Nano_AP/firmware.bin
|
||||
cp .pio/build/OpenEPaperLink_Nano_AP/bootloader.bin /home/runner/work/OpenEPaperLink/OpenEPaperLink/OpenEPaperLink_Nano_AP/bootloader.bin
|
||||
cp .pio/build/OpenEPaperLink_Nano_AP/partitions.bin /home/runner/work/OpenEPaperLink/OpenEPaperLink/OpenEPaperLink_Nano_AP/partitions.bin
|
||||
cp .pio/build/OpenEPaperLink_Nano_AP/littlefs.bin /home/runner/work/OpenEPaperLink/OpenEPaperLink/OpenEPaperLink_Nano_AP/littlefs.bin
|
||||
cd /home/runner/work/OpenEPaperLink/OpenEPaperLink/OpenEPaperLink_Nano_AP
|
||||
esptool.py --chip esp32-s2 merge_bin -o merged-firmware.bin --flash_mode dio --flash_freq 80m --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 OpenEPaperLink_Nano_AP/firmware.bin espbinaries/OpenEPaperLink_Nano_AP.bin
|
||||
cp OpenEPaperLink_Nano_AP/merged-firmware.bin espbinaries/OpenEPaperLink_Nano_AP_full.bin
|
||||
|
||||
- name: Build firmware for OpenEPaperLink_AP_and_Flasher
|
||||
run: |
|
||||
cd ESP32_AP-Flasher
|
||||
export PLATFORMIO_BUILD_FLAGS="-D BUILD_VERSION=${{ github.ref_name }} -D SHA=$GITHUB_SHA"
|
||||
pio run --environment OpenEPaperLink_AP_and_Flasher
|
||||
pio run --target buildfs --environment OpenEPaperLink_AP_and_Flasher
|
||||
mkdir /home/runner/work/OpenEPaperLink/OpenEPaperLink/OpenEPaperLink_AP_and_Flasher
|
||||
cp ~/.platformio/packages/framework-arduinoespressif32/tools/partitions/boot_app0.bin /home/runner/work/OpenEPaperLink/OpenEPaperLink/OpenEPaperLink_AP_and_Flasher/boot_app0.bin
|
||||
cp .pio/build/OpenEPaperLink_AP_and_Flasher/firmware.bin /home/runner/work/OpenEPaperLink/OpenEPaperLink/OpenEPaperLink_AP_and_Flasher/firmware.bin
|
||||
cp .pio/build/OpenEPaperLink_AP_and_Flasher/bootloader.bin /home/runner/work/OpenEPaperLink/OpenEPaperLink/OpenEPaperLink_AP_and_Flasher/bootloader.bin
|
||||
cp .pio/build/OpenEPaperLink_AP_and_Flasher/partitions.bin /home/runner/work/OpenEPaperLink/OpenEPaperLink/OpenEPaperLink_AP_and_Flasher/partitions.bin
|
||||
cp .pio/build/OpenEPaperLink_AP_and_Flasher/littlefs.bin /home/runner/work/OpenEPaperLink/OpenEPaperLink/OpenEPaperLink_AP_and_Flasher/littlefs.bin
|
||||
cd /home/runner/work/OpenEPaperLink/OpenEPaperLink/OpenEPaperLink_AP_and_Flasher
|
||||
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 0x00c90000 littlefs.bin
|
||||
cd /home/runner/work/OpenEPaperLink/OpenEPaperLink
|
||||
cp OpenEPaperLink_AP_and_Flasher/firmware.bin espbinaries/OpenEPaperLink_AP_and_Flasher.bin
|
||||
cp OpenEPaperLink_AP_and_Flasher/merged-firmware.bin espbinaries/OpenEPaperLink_AP_and_Flasher_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:
|
||||
repo_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
file: jsonfiles/*
|
||||
tag: ${{ github.ref }}
|
||||
file_glob: true
|
||||
overwrite: true
|
||||
|
||||
- name: Add esp bins to release
|
||||
uses: svenstaro/upload-release-action@v2
|
||||
with:
|
||||
repo_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
file: espbinaries/*
|
||||
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
|
||||
|
||||
# - name: Add www folder to release
|
||||
# uses: svenstaro/upload-release-action@v2
|
||||
@@ -50,135 +194,3 @@ jobs:
|
||||
# file: ESP32_AP-Flasher/data/*
|
||||
# tag: ${{ github.ref }}
|
||||
# file_glob: true
|
||||
|
||||
- name: Build firmware for Simple_AP
|
||||
run: |
|
||||
cd ESP32_AP-Flasher
|
||||
export PLATFORMIO_BUILD_FLAGS="-D BUILD_VERSION=${{ github.ref_name }} -D SHA=$GITHUB_SHA"
|
||||
pio run --environment Simple_AP
|
||||
mkdir /home/runner/work/OpenEPaperLink/OpenEPaperLink/Simple_AP
|
||||
cp ~/.platformio/packages/framework-arduinoespressif32/tools/partitions/boot_app0.bin /home/runner/work/OpenEPaperLink/OpenEPaperLink/Simple_AP/boot_app0.bin
|
||||
cp .pio/build/Simple_AP/firmware.bin /home/runner/work/OpenEPaperLink/OpenEPaperLink/Simple_AP/firmware.bin
|
||||
cp .pio/build/Simple_AP/bootloader.bin /home/runner/work/OpenEPaperLink/OpenEPaperLink/Simple_AP/bootloader.bin
|
||||
cp .pio/build/Simple_AP/partitions.bin /home/runner/work/OpenEPaperLink/OpenEPaperLink/Simple_AP/partitions.bin
|
||||
|
||||
- name: Build filesystem for Simple_AP
|
||||
run: |
|
||||
cd ESP32_AP-Flasher
|
||||
pio run --target buildfs --environment Simple_AP
|
||||
cp .pio/build/Simple_AP/littlefs.bin /home/runner/work/OpenEPaperLink/OpenEPaperLink/Simple_AP/littlefs.bin
|
||||
|
||||
- name: Combine binaries for Simple_AP
|
||||
run: |
|
||||
cd /home/runner/work/OpenEPaperLink/OpenEPaperLink/Simple_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
|
||||
|
||||
- name: Build firmware for OpenEPaperLink_Mini_AP
|
||||
run: |
|
||||
cd ESP32_AP-Flasher
|
||||
export PLATFORMIO_BUILD_FLAGS="-D BUILD_VERSION=${{ github.ref_name }} -D SHA=$GITHUB_SHA"
|
||||
pio run --environment OpenEPaperLink_Mini_AP
|
||||
mkdir /home/runner/work/OpenEPaperLink/OpenEPaperLink/OpenEPaperLink_Mini_AP
|
||||
cp ~/.platformio/packages/framework-arduinoespressif32/tools/partitions/boot_app0.bin /home/runner/work/OpenEPaperLink/OpenEPaperLink/OpenEPaperLink_Mini_AP/boot_app0.bin
|
||||
cp .pio/build/OpenEPaperLink_Mini_AP/firmware.bin /home/runner/work/OpenEPaperLink/OpenEPaperLink/OpenEPaperLink_Mini_AP/firmware.bin
|
||||
cp .pio/build/OpenEPaperLink_Mini_AP/bootloader.bin /home/runner/work/OpenEPaperLink/OpenEPaperLink/OpenEPaperLink_Mini_AP/bootloader.bin
|
||||
cp .pio/build/OpenEPaperLink_Mini_AP/partitions.bin /home/runner/work/OpenEPaperLink/OpenEPaperLink/OpenEPaperLink_Mini_AP/partitions.bin
|
||||
|
||||
- name: Build filesystem for OpenEPaperLink_Mini_AP
|
||||
run: |
|
||||
cd ESP32_AP-Flasher
|
||||
pio run --target buildfs --environment OpenEPaperLink_Mini_AP
|
||||
cp .pio/build/OpenEPaperLink_Mini_AP/littlefs.bin /home/runner/work/OpenEPaperLink/OpenEPaperLink/OpenEPaperLink_Mini_AP/littlefs.bin
|
||||
|
||||
- name: Combine binaries for OpenEPaperLink_Mini_AP
|
||||
run: |
|
||||
cd /home/runner/work/OpenEPaperLink/OpenEPaperLink/OpenEPaperLink_Mini_AP
|
||||
esptool.py --chip esp32-s2 merge_bin -o merged-firmware.bin --flash_mode dio --flash_freq 80m --flash_size 4MB 0x1000 bootloader.bin 0x8000 partitions.bin 0xe000 boot_app0.bin 0x10000 firmware.bin 0x290000 littlefs.bin
|
||||
|
||||
- name: Build firmware for OpenEPaperLink_Nano_AP
|
||||
run: |
|
||||
cd ESP32_AP-Flasher
|
||||
export PLATFORMIO_BUILD_FLAGS="-D BUILD_VERSION=${{ github.ref_name }} -D SHA=$GITHUB_SHA"
|
||||
pio run --environment OpenEPaperLink_Nano_AP
|
||||
mkdir /home/runner/work/OpenEPaperLink/OpenEPaperLink/OpenEPaperLink_Nano_AP
|
||||
cp ~/.platformio/packages/framework-arduinoespressif32/tools/partitions/boot_app0.bin /home/runner/work/OpenEPaperLink/OpenEPaperLink/OpenEPaperLink_Nano_AP/boot_app0.bin
|
||||
cp .pio/build/OpenEPaperLink_Nano_AP/firmware.bin /home/runner/work/OpenEPaperLink/OpenEPaperLink/OpenEPaperLink_Nano_AP/firmware.bin
|
||||
cp .pio/build/OpenEPaperLink_Nano_AP/bootloader.bin /home/runner/work/OpenEPaperLink/OpenEPaperLink/OpenEPaperLink_Nano_AP/bootloader.bin
|
||||
cp .pio/build/OpenEPaperLink_Nano_AP/partitions.bin /home/runner/work/OpenEPaperLink/OpenEPaperLink/OpenEPaperLink_Nano_AP/partitions.bin
|
||||
|
||||
- name: Build filesystem for OpenEPaperLink_Nano_AP
|
||||
run: |
|
||||
cd ESP32_AP-Flasher
|
||||
pio run --target buildfs --environment OpenEPaperLink_Nano_AP
|
||||
cp .pio/build/OpenEPaperLink_Nano_AP/littlefs.bin /home/runner/work/OpenEPaperLink/OpenEPaperLink/OpenEPaperLink_Nano_AP/littlefs.bin
|
||||
|
||||
- name: Combine binaries for OpenEPaperLink_Nano_AP
|
||||
run: |
|
||||
cd /home/runner/work/OpenEPaperLink/OpenEPaperLink/OpenEPaperLink_Nano_AP
|
||||
esptool.py --chip esp32-s2 merge_bin -o merged-firmware.bin --flash_mode dio --flash_freq 80m --flash_size 4MB 0x1000 bootloader.bin 0x8000 partitions.bin 0xe000 boot_app0.bin 0x10000 firmware.bin 0x290000 littlefs.bin
|
||||
|
||||
- name: Build firmware for OpenEPaperLink_AP_and_Flasher
|
||||
run: |
|
||||
cd ESP32_AP-Flasher
|
||||
export PLATFORMIO_BUILD_FLAGS="-D BUILD_VERSION=${{ github.ref_name }} -D SHA=$GITHUB_SHA"
|
||||
pio run --environment OpenEPaperLink_AP_and_Flasher
|
||||
mkdir /home/runner/work/OpenEPaperLink/OpenEPaperLink/OpenEPaperLink_AP_and_Flasher
|
||||
cp ~/.platformio/packages/framework-arduinoespressif32/tools/partitions/boot_app0.bin /home/runner/work/OpenEPaperLink/OpenEPaperLink/OpenEPaperLink_AP_and_Flasher/boot_app0.bin
|
||||
cp .pio/build/OpenEPaperLink_AP_and_Flasher/firmware.bin /home/runner/work/OpenEPaperLink/OpenEPaperLink/OpenEPaperLink_AP_and_Flasher/firmware.bin
|
||||
cp .pio/build/OpenEPaperLink_AP_and_Flasher/bootloader.bin /home/runner/work/OpenEPaperLink/OpenEPaperLink/OpenEPaperLink_AP_and_Flasher/bootloader.bin
|
||||
cp .pio/build/OpenEPaperLink_AP_and_Flasher/partitions.bin /home/runner/work/OpenEPaperLink/OpenEPaperLink/OpenEPaperLink_AP_and_Flasher/partitions.bin
|
||||
|
||||
- name: Build filesystem for OpenEPaperLink_AP_and_Flasher
|
||||
run: |
|
||||
cd ESP32_AP-Flasher
|
||||
pio run --target buildfs --environment OpenEPaperLink_AP_and_Flasher
|
||||
cp .pio/build/OpenEPaperLink_AP_and_Flasher/littlefs.bin /home/runner/work/OpenEPaperLink/OpenEPaperLink/OpenEPaperLink_AP_and_Flasher/littlefs.bin
|
||||
|
||||
- name: Combine binaries for OpenEPaperLink_AP_and_Flasher
|
||||
run: |
|
||||
cd /home/runner/work/OpenEPaperLink/OpenEPaperLink/OpenEPaperLink_AP_and_Flasher
|
||||
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 0x00c90000 littlefs.bin
|
||||
|
||||
- name: move binaries
|
||||
run: |
|
||||
mkdir espbinaries
|
||||
cp Simple_AP/firmware.bin espbinaries/Simple_AP.bin
|
||||
cp OpenEPaperLink_Mini_AP/firmware.bin espbinaries/OpenEPaperLink_Mini_AP.bin
|
||||
cp OpenEPaperLink_Nano_AP/firmware.bin espbinaries/OpenEPaperLink_Nano_AP.bin
|
||||
cp OpenEPaperLink_AP_and_Flasher/firmware.bin espbinaries/OpenEPaperLink_AP_and_Flasher.bin
|
||||
cp Simple_AP/merged-firmware.bin espbinaries/Simple_AP_full.bin
|
||||
cp OpenEPaperLink_Mini_AP/merged-firmware.bin espbinaries/OpenEPaperLink_Mini_AP_full.bin
|
||||
cp OpenEPaperLink_Nano_AP/merged-firmware.bin espbinaries/OpenEPaperLink_Nano_AP_full.bin
|
||||
cp OpenEPaperLink_AP_and_Flasher/merged-firmware.bin espbinaries/OpenEPaperLink_AP_and_Flasher_full.bin
|
||||
|
||||
- name: generate release json file
|
||||
run: |
|
||||
python genfilelist.py ${{ github.ref_name }} $GITHUB_REPOSITORY $GITHUB_SHA
|
||||
|
||||
- name: Add file list to release
|
||||
uses: svenstaro/upload-release-action@v2
|
||||
with:
|
||||
repo_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
file: /home/runner/work/OpenEPaperLink/OpenEPaperLink/files.json
|
||||
asset_name: files.json
|
||||
tag: ${{ github.ref }}
|
||||
overwrite: true
|
||||
body: "file list"
|
||||
|
||||
- name: Add esp bins to release
|
||||
uses: svenstaro/upload-release-action@v2
|
||||
with:
|
||||
repo_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
file: espbinaries/*
|
||||
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
|
||||
|
||||
@@ -406,5 +406,132 @@
|
||||
"type": "text"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 17,
|
||||
"name": "Send Command",
|
||||
"desc": "Send a command to a tag to execute",
|
||||
"hwtype": [
|
||||
0,
|
||||
1,
|
||||
2,
|
||||
17,
|
||||
240
|
||||
],
|
||||
"param": [
|
||||
{
|
||||
"key": "cmd",
|
||||
"name": "CMD",
|
||||
"desc": "Action",
|
||||
"type": "select",
|
||||
"options": {
|
||||
"0": "Reboot",
|
||||
"1": "Scan Channels",
|
||||
"2": "Clear settings"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 18,
|
||||
"name": "Set Tag Config",
|
||||
"desc": "Sets tag options. The options you see below are the default options. This may or may not match current tag settings",
|
||||
"hwtype": [
|
||||
0,
|
||||
1,
|
||||
2,
|
||||
17,
|
||||
240
|
||||
],
|
||||
"param": [
|
||||
{
|
||||
"key": "fastboot",
|
||||
"name": "Boot method",
|
||||
"desc": "How the tag should boot, fast or normal",
|
||||
"type": "select",
|
||||
"options": {
|
||||
"0": "-Normal boot",
|
||||
"1": "Fast boot"
|
||||
}
|
||||
},
|
||||
{
|
||||
"key": "rfwake",
|
||||
"name": "RF Wake",
|
||||
"desc": "If the tag should support RF wake or not. This adds a 0.9µA current draw",
|
||||
"type": "select",
|
||||
"options": {
|
||||
"0": "-Disabled",
|
||||
"1": "Enabled"
|
||||
}
|
||||
},
|
||||
{
|
||||
"key": "tagroaming",
|
||||
"name": "Tag Roaming",
|
||||
"desc": "If enabled, the tag will periodically scan for AP's and will switch to a different channel if a stronger signal is found",
|
||||
"type": "select",
|
||||
"options": {
|
||||
"0": "-Disabled",
|
||||
"1": "Enabled"
|
||||
}
|
||||
},
|
||||
{
|
||||
"key": "tagscanontimeout",
|
||||
"name": "Scan for AP on timeout",
|
||||
"desc": "If a tag hasn't found an AP for an hour, should it rescan the channels for another AP?",
|
||||
"type": "select",
|
||||
"options": {
|
||||
"1": "-Enabled",
|
||||
"0": "Disabled"
|
||||
}
|
||||
},
|
||||
{
|
||||
"key": "showlowbat",
|
||||
"name": "Low Battery symbol",
|
||||
"desc": "Should the tag display the 'low battery' symbol if the battery a voltage threshold has been reached?",
|
||||
"type": "select",
|
||||
"options": {
|
||||
"1": "-Enabled",
|
||||
"0": "Disabled"
|
||||
}
|
||||
},
|
||||
{
|
||||
"key": "shownorf",
|
||||
"name": "No AP symbol",
|
||||
"desc": "Should the tag display the 'No-signal/AP' symbol if it hasn't been able to contact an AP?",
|
||||
"type": "select",
|
||||
"options": {
|
||||
"1": "-Enabled",
|
||||
"0": "Disabled"
|
||||
}
|
||||
},
|
||||
{
|
||||
"key": "lowvoltage",
|
||||
"name": "Low voltage threshold",
|
||||
"desc": "Below what voltage should the tag display the 'low bat' symbol?",
|
||||
"type": "select",
|
||||
"options": {
|
||||
"2600": "-2.6v",
|
||||
"2500": "2.5v",
|
||||
"2400": "2.4v",
|
||||
"2300": "2.3v",
|
||||
"2200": "2.2v"
|
||||
}
|
||||
},
|
||||
{
|
||||
"key": "fixedchannel",
|
||||
"name": "Fixed Channel",
|
||||
"desc": "What channel should the tag initially join?",
|
||||
"type": "select",
|
||||
"options": {
|
||||
"0": "-Auto",
|
||||
"11": "11",
|
||||
"15": "15",
|
||||
"20": "20",
|
||||
"25": "25",
|
||||
"26": "26",
|
||||
"27": "27"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
BIN
ESP32_AP-Flasher/data/www/favicon.ico
Normal file
BIN
ESP32_AP-Flasher/data/www/favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 7.0 KiB |
@@ -7,7 +7,7 @@
|
||||
|
||||
<title>Open EPaper Link Access Point</title>
|
||||
<link rel="stylesheet" href="main.css" type="text/css" />
|
||||
<link rel="icon" href="data:,">
|
||||
<link rel="icon" type="image/vnd.icon" href="favicon.ico">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
@@ -160,7 +160,7 @@ Latency will be around 40 seconds.">
|
||||
<div><span id="runstate"></div>
|
||||
<div><span id="apstatecolor">⬤</span> <span id="apstate">loading</span></div>
|
||||
<div><span id="apconfigbutton">AP config</span></div>
|
||||
<div><a href="/edit" target="littlefs" class="filebutton">edit littleFS</a></div>
|
||||
<div><a href="/edit" target="littlefs" class="filebutton">edit contentFS</a></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -206,4 +206,4 @@ Latency will be around 40 seconds.">
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
</html>
|
||||
|
||||
@@ -24,13 +24,13 @@ const apstate = [
|
||||
{ state: "requires power cycle", color: "purple" },
|
||||
{ state: "failed", color: "red" },
|
||||
{ state: "coming online", color: "yellow" }
|
||||
];
|
||||
];
|
||||
const runstate = [
|
||||
{ state: "⏹︎ stopped" },
|
||||
{ state: "⏸pause" },
|
||||
{ state: "" }, // hide running
|
||||
{ state: "⏳︎ init" }
|
||||
];
|
||||
];
|
||||
|
||||
const imageQueue = [];
|
||||
let isProcessing = false;
|
||||
@@ -48,7 +48,7 @@ window.addEventListener("load", function () {
|
||||
this.document.title = data.alias;
|
||||
}
|
||||
});
|
||||
fetch('/content_cards.json')
|
||||
fetch('/content_cards.json')
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
cardconfig = data;
|
||||
@@ -94,7 +94,7 @@ function connect() {
|
||||
processTags(msg.tags);
|
||||
}
|
||||
if (msg.sys) {
|
||||
$('#sysinfo').innerHTML = 'free heap: ' + msg.sys.heap + ' bytes ┇ db size: ' + msg.sys.dbsize + ' bytes ┇ db record count: ' + msg.sys.recordcount + ' ┇ littlefs free: ' + msg.sys.littlefsfree + ' bytes';
|
||||
$('#sysinfo').innerHTML = 'free heap: ' + msg.sys.heap + ' bytes ┇ db size: ' + msg.sys.dbsize + ' bytes ┇ db record count: ' + msg.sys.recordcount + ' ┇ active filesystem free: ' + msg.sys.littlefsfree + ' bytes ' + convertSize(msg.sys.littlefsfree);
|
||||
if (msg.sys.apstate) {
|
||||
$("#apstatecolor").style.color = apstate[msg.sys.apstate].color;
|
||||
$("#apstate").innerHTML = apstate[msg.sys.apstate].state;
|
||||
@@ -127,6 +127,18 @@ function connect() {
|
||||
});
|
||||
}
|
||||
|
||||
// Copied from
|
||||
// https://stackoverflow.com/questions/15900485/correct-way-to-convert-size-in-bytes-to-kb-mb-gb-in-javascript
|
||||
function convertSize(bytes){
|
||||
if (bytes >= 1073741824) { bytes = (bytes / 1073741824).toFixed(2) + " GB"; }
|
||||
else if (bytes >= 1048576) { bytes = (bytes / 1048576).toFixed(2) + " MB"; }
|
||||
else if (bytes >= 1024) { bytes = (bytes / 1024).toFixed(2) + " KB"; }
|
||||
else if (bytes > 1) { bytes = bytes + " bytes"; }
|
||||
else if (bytes == 1) { bytes = bytes + " byte"; }
|
||||
else { bytes = "0 bytes"; }
|
||||
return "(" + bytes + ")";
|
||||
}
|
||||
|
||||
function processTags(tagArray) {
|
||||
for (const element of tagArray) {
|
||||
tagmac = element.mac;
|
||||
@@ -307,7 +319,7 @@ $('#taglist').addEventListener("click", (event) => {
|
||||
$('#cfgalias').value = tagdata.alias;
|
||||
$('#cfgmore').style.display = "none";
|
||||
if (populateSelectTag(tagdata.hwType, tagdata.capabilities)) {
|
||||
$('#cfgcontent').parentNode.style.display = "flex";
|
||||
$('#cfgcontent').parentNode.style.display = "flex";
|
||||
$('#cfgcontent').value = tagdata.contentMode;
|
||||
$('#cfgcontent').dataset.json = tagdata.modecfgjson;
|
||||
contentselected();
|
||||
@@ -354,7 +366,7 @@ $('#cfgsave').onclick = function () {
|
||||
|
||||
formData.append("rotate", $('#cfgrotate').value);
|
||||
formData.append("lut", $('#cfglut').value);
|
||||
|
||||
|
||||
fetch("/save_cfg", {
|
||||
method: "POST",
|
||||
body: formData
|
||||
@@ -530,6 +542,12 @@ function contentselected() {
|
||||
const optionElement = document.createElement("option");
|
||||
optionElement.value = key;
|
||||
optionElement.text = element.options[key];
|
||||
if (element.options[key].substring(0,1)=="-") {
|
||||
optionElement.text = element.options[key].substring(1);
|
||||
optionElement.selected = true;
|
||||
} else {
|
||||
optionElement.selected = false;
|
||||
}
|
||||
input.appendChild(optionElement);
|
||||
}
|
||||
break;
|
||||
|
||||
7
ESP32_AP-Flasher/esp32_sdcard.csv
Normal file
7
ESP32_AP-Flasher/esp32_sdcard.csv
Normal file
@@ -0,0 +1,7 @@
|
||||
# Name, Type, SubType, Offset, Size, Flags
|
||||
nvs, data, nvs, 0x9000, 0x5000,
|
||||
otadata, data, ota, 0xe000, 0x2000,
|
||||
app0, app, ota_0, 0x10000, 0x150000,
|
||||
app1, app, ota_1, 0x160000,0x150000,
|
||||
spiffs, data, spiffs, 0x2B0000,0x140000,
|
||||
coredump, data, coredump,0x3F0000,0x10000,
|
||||
|
24
ESP32_AP-Flasher/include/SPIFFSEditor.h
Normal file
24
ESP32_AP-Flasher/include/SPIFFSEditor.h
Normal file
@@ -0,0 +1,24 @@
|
||||
#ifndef SPIFFSEditor_H_
|
||||
#define SPIFFSEditor_H_
|
||||
#include <ESPAsyncWebServer.h>
|
||||
|
||||
class SPIFFSEditor: public AsyncWebHandler {
|
||||
private:
|
||||
fs::FS _fs;
|
||||
String _username;
|
||||
String _password;
|
||||
bool _authenticated;
|
||||
uint32_t _startTime;
|
||||
public:
|
||||
#ifdef ESP32
|
||||
SPIFFSEditor(const fs::FS& fs, const String& username=String(), const String& password=String());
|
||||
#else
|
||||
SPIFFSEditor(const String& username=String(), const String& password=String(), const fs::FS& fs=SPIFFS);
|
||||
#endif
|
||||
virtual bool canHandle(AsyncWebServerRequest *request) override final;
|
||||
virtual void handleRequest(AsyncWebServerRequest *request) override final;
|
||||
virtual void handleUpload(AsyncWebServerRequest *request, const String& filename, size_t index, uint8_t *data, size_t len, bool final) override final;
|
||||
virtual bool isRequestHandlerTrivial() override final {return false;}
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -107,4 +107,19 @@ struct TagInfo {
|
||||
uint8_t contentMode;
|
||||
} __packed;
|
||||
|
||||
struct tagsettings {
|
||||
uint8_t settingsVer; // the version of the struct as written to the infopage
|
||||
uint8_t enableFastBoot; // default 0; if set, it will skip splashscreen
|
||||
uint8_t enableRFWake; // default 0; if set, it will enable RF wake. This will add about ~0.9µA idle power consumption
|
||||
uint8_t enableTagRoaming; // default 0; if set, the tag will scan for an accesspoint every few check-ins. This will increase power consumption quite a bit
|
||||
uint8_t enableScanForAPAfterTimeout; // default 1; if a the tag failed to check in, after a few attempts it will try to find a an AP on other channels
|
||||
uint8_t enableLowBatSymbol; // default 1; tag will show 'low battery' icon on screen if the battery is depleted
|
||||
uint8_t enableNoRFSymbol; // default 1; tag will show 'no signal' icon on screen if it failed to check in for a longer period of time
|
||||
uint8_t fastBootCapabilities; // holds the byte with 'capabilities' as detected during a normal tag boot; allows the tag to skip detecting buttons and NFC chip
|
||||
uint8_t customMode; // default 0; if anything else, tag will bootup in a different 'mode'
|
||||
uint16_t batLowVoltage; // Low battery threshold voltage (2450 for 2.45v). defaults to BATTERY_VOLTAGE_MINIMUM from powermgt.h
|
||||
uint16_t minimumCheckInTime; // defaults to BASE_INTERVAL from powermgt.h
|
||||
uint8_t fixedChannel; // default 0; if set to a valid channel number, the tag will stick to that channel
|
||||
} __packed;
|
||||
|
||||
#pragma pack(pop)
|
||||
@@ -37,5 +37,6 @@ String windDirectionIcon(int degrees);
|
||||
void getLocation(JsonObject &cfgobj);
|
||||
void prepareNFCReq(uint8_t* dst, const char* url);
|
||||
void prepareLUTreq(uint8_t *dst, String input);
|
||||
void prepareConfigFile(uint8_t *dst, JsonObject config);
|
||||
void getTemplate(JsonDocument &json, const char *filePath, uint8_t id, uint8_t hwtype);
|
||||
void setU8G2Font(const String &title, U8g2_for_TFT_eSPI &u8f);
|
||||
|
||||
@@ -12,6 +12,7 @@ extern void processXferComplete(struct espXferComplete* xfc, bool local);
|
||||
extern void processXferTimeout(struct espXferComplete* xfc, bool local);
|
||||
extern void processDataReq(struct espAvailDataReq* adr, bool local);
|
||||
|
||||
extern bool sendTagCommand(uint8_t* dst, uint8_t cmd, bool local);
|
||||
extern bool sendAPSegmentedData(uint8_t* dst, String data, uint16_t icons, bool inverted, bool local);
|
||||
extern bool showAPSegmentedInfo(uint8_t* dst, bool local);
|
||||
extern void updateTaginfoitem(struct TagInfo* taginfoitem);
|
||||
|
||||
39
ESP32_AP-Flasher/include/storage.h
Normal file
39
ESP32_AP-Flasher/include/storage.h
Normal file
@@ -0,0 +1,39 @@
|
||||
#ifndef _DYN_STORAGE_H_
|
||||
#define _DYN_STORAGE_H_
|
||||
|
||||
#include "FS.h"
|
||||
|
||||
#ifdef HAS_SDCARD
|
||||
#ifndef SD_CARD_SS
|
||||
#error SD_CARD_SS UNDEFINED
|
||||
#endif
|
||||
|
||||
#ifndef SD_CARD_CLK
|
||||
#define SD_CARD_CLK 18
|
||||
#endif
|
||||
|
||||
#ifndef SD_CARD_MISO
|
||||
#define SD_CARD_MISO 19
|
||||
#endif
|
||||
|
||||
#ifndef SD_CARD_MOSI
|
||||
#define SD_CARD_MOSI 23
|
||||
#endif
|
||||
#endif
|
||||
|
||||
class DynStorage {
|
||||
public:
|
||||
DynStorage();
|
||||
void begin();
|
||||
void end();
|
||||
void listFiles();
|
||||
size_t freeSpace();
|
||||
|
||||
private:
|
||||
bool isInited;
|
||||
};
|
||||
|
||||
extern DynStorage Storage;
|
||||
extern fs::FS *contentFS;
|
||||
|
||||
#endif
|
||||
@@ -21,15 +21,17 @@ lib_deps =
|
||||
https://github.com/Bodmer/U8g2_for_TFT_eSPI
|
||||
https://github.com/ricmoo/qrcode
|
||||
fastled/FastLED
|
||||
|
||||
https://github.com/MajenkoLibraries/SoftSPI
|
||||
platform_packages =
|
||||
board_build.filesystem = littlefs
|
||||
monitor_filters = esp32_exception_decoder
|
||||
monitor_speed = 115200
|
||||
board_build.f_cpu = 240000000L
|
||||
;upload_port = COM30
|
||||
;monitor_port = COM30
|
||||
|
||||
; ----------------------------------------------------------------------------------------
|
||||
; !!! this configuration expects the Mini_AP
|
||||
;
|
||||
; ----------------------------------------------------------------------------------------
|
||||
[env:OpenEPaperLink_Mini_AP]
|
||||
platform = https://github.com/platformio/platform-espressif32.git
|
||||
board=lolin_s2_mini
|
||||
@@ -43,12 +45,9 @@ build_flags =
|
||||
-D ARDUINO_USB_MODE=0
|
||||
-D CONFIG_SPIRAM_USE_MALLOC=1
|
||||
-D CONFIG_MBEDTLS_EXTERNAL_MEM_ALLOC=y
|
||||
|
||||
-D HAS_RGB_LED
|
||||
-D BOARD_HAS_PSRAM
|
||||
|
||||
-D POWER_NO_SOFT_POWER
|
||||
|
||||
-D FLASHER_AP_SS=11
|
||||
-D FLASHER_AP_CLK=9
|
||||
-D FLASHER_AP_MOSI=10
|
||||
@@ -60,23 +59,22 @@ build_flags =
|
||||
-D FLASHER_AP_TEST=12
|
||||
-D FLASHER_LED=15
|
||||
-D FLASHER_RGB_LED=33
|
||||
|
||||
-D USER_SETUP_LOADED
|
||||
-D DISABLE_ALL_LIBRARY_WARNINGS
|
||||
-D ILI9341_DRIVER
|
||||
-D SMOOTH_FONT
|
||||
-D LOAD_FONT2
|
||||
|
||||
build_src_filter =
|
||||
+<*>-<usbflasher.cpp>-<serialconsole.cpp>
|
||||
|
||||
board_build.psram_type=qspi_opi
|
||||
board_upload.maximum_size = 4194304
|
||||
;board_upload.maximum_ram_size = 2097152
|
||||
board_upload.maximum_ram_size = 327680
|
||||
board_upload.flash_size = 4MB
|
||||
|
||||
|
||||
; ----------------------------------------------------------------------------------------
|
||||
; !!! this configuration expects the Nano_AP
|
||||
;
|
||||
; ----------------------------------------------------------------------------------------
|
||||
[env:OpenEPaperLink_Nano_AP]
|
||||
platform = https://github.com/platformio/platform-espressif32.git
|
||||
board=lolin_s2_mini
|
||||
@@ -90,9 +88,7 @@ build_flags =
|
||||
-D ARDUINO_USB_MODE=0
|
||||
-D CONFIG_SPIRAM_USE_MALLOC=1
|
||||
-D CONFIG_MBEDTLS_EXTERNAL_MEM_ALLOC=y
|
||||
|
||||
-D BOARD_HAS_PSRAM
|
||||
|
||||
-D FLASHER_AP_SS=38
|
||||
-D FLASHER_AP_CLK=40
|
||||
-D FLASHER_AP_MOSI=39
|
||||
@@ -100,27 +96,22 @@ build_flags =
|
||||
-D FLASHER_AP_RESET=37
|
||||
-D FLASHER_AP_POWER={16,17,18,21}
|
||||
-D FLASHER_AP_TXD=35
|
||||
-D FLASHER_AP_RXD=36
|
||||
-D FLASHER_AP_TEST=34
|
||||
-D FLASHER_AP_RXD=34
|
||||
-D FLASHER_AP_TEST=36
|
||||
-D FLASHER_LED=15
|
||||
-D FLASHER_RGB_LED=-1
|
||||
|
||||
-D USER_SETUP_LOADED
|
||||
-D DISABLE_ALL_LIBRARY_WARNINGS
|
||||
-D ILI9341_DRIVER
|
||||
-D SMOOTH_FONT
|
||||
-D LOAD_FONT2
|
||||
|
||||
build_src_filter =
|
||||
+<*>-<usbflasher.cpp>-<serialconsole.cpp>
|
||||
|
||||
board_build.psram_type=qspi_opi
|
||||
board_upload.maximum_size = 4194304
|
||||
;board_upload.maximum_ram_size = 2097152
|
||||
board_upload.maximum_ram_size = 327680
|
||||
board_upload.flash_size = 4MB
|
||||
|
||||
|
||||
; ----------------------------------------------------------------------------------------
|
||||
; !!! this configuration expects the 16MB Flash / 8MB Ram version of the ESP32-S3-DevkitC1
|
||||
;
|
||||
@@ -129,7 +120,6 @@ board_upload.flash_size = 4MB
|
||||
platform = https://github.com/platformio/platform-espressif32.git
|
||||
board = esp32-s3-devkitc-1
|
||||
board_build.partitions = default_16MB.csv
|
||||
|
||||
build_unflags =
|
||||
-D ARDUINO_USB_MODE=1
|
||||
-D CONFIG_MBEDTLS_INTERNAL_MEM_ALLOC=y
|
||||
@@ -144,10 +134,8 @@ build_flags =
|
||||
-D HAS_RGB_LED
|
||||
-D BOARD_HAS_PSRAM
|
||||
-D CONFIG_MBEDTLS_EXTERNAL_MEM_ALLOC=y
|
||||
|
||||
-D POWER_RAMPING
|
||||
-D POWER_HIGH_SIDE_DRIVER
|
||||
|
||||
-D FLASHER_AP_SS=4
|
||||
-D FLASHER_AP_CLK=5
|
||||
-D FLASHER_AP_MOSI=7
|
||||
@@ -157,7 +145,6 @@ build_flags =
|
||||
-D FLASHER_AP_TXD=16
|
||||
-D FLASHER_AP_RXD=18
|
||||
-D FLASHER_AP_TEST=17
|
||||
|
||||
-D FLASHER_EXT_SS=40
|
||||
-D FLASHER_EXT_CLK=41
|
||||
-D FLASHER_EXT_MOSI=2
|
||||
@@ -167,7 +154,6 @@ build_flags =
|
||||
-D FLASHER_EXT_TXD=38
|
||||
-D FLASHER_EXT_RXD=39
|
||||
-D FLASHER_EXT_TEST=47
|
||||
|
||||
-D FLASHER_ALT_SS=3
|
||||
-D FLASHER_ALT_CLK=46
|
||||
-D FLASHER_ALT_MOSI=10
|
||||
@@ -177,34 +163,32 @@ build_flags =
|
||||
-D FLASHER_ALT_TXD=12
|
||||
-D FLASHER_ALT_RXD=14
|
||||
-D FLASHER_ALT_TEST=13
|
||||
|
||||
-D FLASHER_LED=21
|
||||
-D FLASHER_RGB_LED=48
|
||||
|
||||
-D USER_SETUP_LOADED
|
||||
-D DISABLE_ALL_LIBRARY_WARNINGS
|
||||
-D ILI9341_DRIVER
|
||||
-D SMOOTH_FONT
|
||||
-D LOAD_FONT2
|
||||
|
||||
board_build.flash_mode=qio
|
||||
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
|
||||
|
||||
; ----------------------------------------------------------------------------------------
|
||||
; !!! this configuration expects an esp32
|
||||
;
|
||||
; ----------------------------------------------------------------------------------------
|
||||
[env:Simple_AP]
|
||||
board = esp32dev
|
||||
board_build.partitions = default.csv
|
||||
|
||||
build_flags =
|
||||
-D BUILD_ENV_NAME=$PIOENV
|
||||
-D BUILD_TIME=$UNIX_TIME
|
||||
-D CORE_DEBUG_LEVEL=0
|
||||
-D SIMPLE_AP
|
||||
|
||||
-D FLASHER_AP_SS=5
|
||||
-D FLASHER_AP_CLK=18
|
||||
-D FLASHER_AP_MOSI=23
|
||||
@@ -215,38 +199,76 @@ build_flags =
|
||||
-D FLASHER_AP_TXD=17
|
||||
-D FLASHER_AP_RXD=16
|
||||
-D FLASHER_LED=22
|
||||
|
||||
-D USER_SETUP_LOADED
|
||||
-D DISABLE_ALL_LIBRARY_WARNINGS
|
||||
-D ILI9341_DRIVER
|
||||
-D SMOOTH_FONT
|
||||
-D LOAD_FONT2
|
||||
|
||||
build_src_filter =
|
||||
+<*>-<usbflasher.cpp>-<serialconsole.cpp>
|
||||
|
||||
; ----------------------------------------------------------------------------------------
|
||||
; !!! this configuration expects the alternative 2.9" Flasher PCB
|
||||
; ----------------------------------------------------------------------------------------
|
||||
|
||||
[env:Alternative_PCB]
|
||||
board = esp32dev
|
||||
board_build.partitions = no_ota.csv
|
||||
|
||||
; ----------------------------------------------------------------------------------------
|
||||
; !!! this configuration expects an wemos_d1_mini32
|
||||
;
|
||||
; ----------------------------------------------------------------------------------------
|
||||
[env:Weemos_AP]
|
||||
board = wemos_d1_mini32
|
||||
board_build.partitions = default.csv
|
||||
build_flags =
|
||||
-D BUILD_ENV_NAME=$PIOENV
|
||||
-D BUILD_TIME=$UNIX_TIME
|
||||
-D ALTERNATIVE_PCB
|
||||
-D FLASHER_AP_SS=22
|
||||
-D FLASHER_AP_CLK=13
|
||||
-D CORE_DEBUG_LEVEL=0
|
||||
-D FLASHER_AP_SS=5
|
||||
-D FLASHER_AP_CLK=18
|
||||
-D FLASHER_AP_MOSI=23
|
||||
-D FLASHER_AP_MISO=33
|
||||
-D FLASHER_AP_RESET=27
|
||||
-D FLASHER_AP_POWER={4}
|
||||
-D FLASHER_AP_MISO=19
|
||||
-D FLASHER_AP_RESET=14
|
||||
-D FLASHER_AP_POWER={-1}
|
||||
-D FLASHER_AP_TEST=-1
|
||||
-D FLASHER_AP_TXD=26
|
||||
-D FLASHER_AP_RXD=25
|
||||
|
||||
-D FLASHER_LED=19
|
||||
-D FLASHER_AP_TXD=16
|
||||
-D FLASHER_AP_RXD=17
|
||||
-D FLASHER_LED=22
|
||||
-D USER_SETUP_LOADED
|
||||
-D DISABLE_ALL_LIBRARY_WARNINGS
|
||||
-D ILI9341_DRIVER
|
||||
-D SMOOTH_FONT
|
||||
-D LOAD_FONT2
|
||||
build_src_filter =
|
||||
+<*>-<usbflasher.cpp>-<serialconsole.cpp>
|
||||
|
||||
; ----------------------------------------------------------------------------------------
|
||||
; !!! this configuration expects an m5stack esp32
|
||||
;
|
||||
; ----------------------------------------------------------------------------------------
|
||||
[env:M5Stack_Core_ONE_AP]
|
||||
platform = espressif32
|
||||
board = m5stack-core-esp32
|
||||
board_build.partitions = esp32_sdcard.csv
|
||||
build_flags =
|
||||
-D BUILD_ENV_NAME=$PIOENV
|
||||
-D BUILD_TIME=$UNIX_TIME
|
||||
-D CORE_DEBUG_LEVEL=0
|
||||
-D HAS_SDCARD
|
||||
-D USE_SOFTSPI
|
||||
-D SD_CARD_SS=4
|
||||
-D SD_CARD_CLK=18
|
||||
-D SD_CARD_MISO=19
|
||||
-D SD_CARD_MOSI=23
|
||||
-D FLASHER_AP_SS=5
|
||||
-D FLASHER_AP_CLK=36
|
||||
-D FLASHER_AP_MOSI=26
|
||||
-D FLASHER_AP_MISO=35
|
||||
-D FLASHER_AP_RESET=2
|
||||
-D FLASHER_AP_POWER={-1}
|
||||
-D FLASHER_AP_TEST=-1
|
||||
-D FLASHER_AP_TXD=16
|
||||
-D FLASHER_AP_RXD=17
|
||||
-D FLASHER_LED=-1
|
||||
-D FLASH_TIMEOUT=10
|
||||
-D USER_SETUP_LOADED
|
||||
-D DISABLE_ALL_LIBRARY_WARNINGS
|
||||
-D ILI9341_DRIVER
|
||||
-D SMOOTH_FONT
|
||||
-D LOAD_FONT2
|
||||
build_src_filter =
|
||||
+<*>-<usbflasher.cpp>-<serialconsole.cpp>
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
#ifdef CONTENT_RSS
|
||||
#include <rssClass.h>
|
||||
#endif
|
||||
#include <LittleFS.h>
|
||||
#include "storage.h"
|
||||
#include <time.h>
|
||||
|
||||
#include <map>
|
||||
@@ -143,7 +143,7 @@ void drawNew(uint8_t mac[8], bool buttonPressed, tagRecord *&taginfo) {
|
||||
if (imageParams.hasRed) imageParams.dataType = DATATYPE_IMG_RAW_2BPP;
|
||||
if (prepareDataAvail(&filename, imageParams.dataType, mac, cfgobj["timetolive"].as<int>())) {
|
||||
cfgobj["#fetched"] = true;
|
||||
if (cfgobj["delete"].as<String>() == "1") LittleFS.remove("/" + cfgobj["filename"].as<String>());
|
||||
if (cfgobj["delete"].as<String>() == "1") contentFS->remove("/" + cfgobj["filename"].as<String>());
|
||||
} else {
|
||||
wsErr("Error accessing " + filename);
|
||||
}
|
||||
@@ -286,6 +286,19 @@ void drawNew(uint8_t mac[8], bool buttonPressed, tagRecord *&taginfo) {
|
||||
taginfo->nextupdate = now + (cfgobj["ttl"].as<int>() < 5 ? 5 : cfgobj["ttl"].as<int>()) * 60;
|
||||
updateTagImage(filename, mac, (cfgobj["ttl"].as<int>() < 5 ? 5 : cfgobj["ttl"].as<int>()), taginfo, imageParams);
|
||||
break;
|
||||
|
||||
case 17: // tag command
|
||||
sendTagCommand(mac, cfgobj["cmd"].as<int>(), (taginfo->isExternal == false));
|
||||
cfgobj["filename"] = "";
|
||||
taginfo->nextupdate = 3216153600;
|
||||
taginfo->contentMode = Image;
|
||||
break;
|
||||
case 18:
|
||||
prepareConfigFile(mac, cfgobj);
|
||||
cfgobj["filename"] = "";
|
||||
taginfo->nextupdate = 3216153600;
|
||||
taginfo->contentMode = Image;
|
||||
break;
|
||||
}
|
||||
|
||||
taginfo->modeConfigJson = doc.as<String>();
|
||||
@@ -310,7 +323,7 @@ void drawString(TFT_eSprite &spr, String content, uint16_t posx, uint16_t posy,
|
||||
spr.setTextColor(PAL_BLACK, PAL_WHITE);
|
||||
spr.drawString(content, posx, posy);
|
||||
} else {
|
||||
if (font != "") spr.loadFont(font, LittleFS);
|
||||
if (font != "") spr.loadFont(font, *contentFS);
|
||||
spr.setTextColor(color, PAL_WHITE);
|
||||
spr.drawString(content, posx, posy);
|
||||
if (font != "") spr.unloadFont();
|
||||
@@ -407,7 +420,7 @@ void drawNumber(String &filename, int32_t count, int32_t thresholdred, tagRecord
|
||||
if (count > 99) font = loc["fonts"][1].as<String>();
|
||||
if (count > 999) font = loc["fonts"][2].as<String>();
|
||||
if (count > 9999) font = loc["fonts"][3].as<String>();
|
||||
spr.loadFont(font, LittleFS);
|
||||
spr.loadFont(font, *contentFS);
|
||||
spr.drawString(String(count), loc["xy"][0].as<uint16_t>(), loc["xy"][1].as<uint16_t>());
|
||||
spr.unloadFont();
|
||||
|
||||
@@ -492,7 +505,7 @@ void drawWeather(String &filename, JsonObject &cfgobj, tagRecord *&taginfo, imgP
|
||||
dtostrf(temperature, 2, 1, tmpOutput);
|
||||
drawString(spr, String(tmpOutput), loc["temp"][0], loc["temp"][1], loc["temp"][2], TL_DATUM, (temperature < 0 ? PAL_RED : PAL_BLACK));
|
||||
|
||||
spr.loadFont(loc["icon"][2], LittleFS);
|
||||
spr.loadFont(loc["icon"][2], *contentFS);
|
||||
if (weathercode == 55 || weathercode == 65 || weathercode == 75 || weathercode == 82 || weathercode == 86 || weathercode == 95 || weathercode == 99) {
|
||||
spr.setTextColor(PAL_RED, PAL_WHITE);
|
||||
} else {
|
||||
@@ -502,7 +515,7 @@ void drawWeather(String &filename, JsonObject &cfgobj, tagRecord *&taginfo, imgP
|
||||
spr.printToSprite(weatherIcons[weathercode]);
|
||||
spr.unloadFont();
|
||||
|
||||
spr.loadFont(loc["dir"][2], LittleFS);
|
||||
spr.loadFont(loc["dir"][2], *contentFS);
|
||||
spr.setTextColor(PAL_BLACK, PAL_WHITE);
|
||||
spr.setCursor(loc["dir"][0], loc["dir"][1]);
|
||||
spr.printToSprite(windDirectionIcon(winddirection));
|
||||
@@ -565,7 +578,7 @@ void drawForecast(String &filename, JsonObject &cfgobj, tagRecord *&taginfo, img
|
||||
|
||||
uint8_t weathercode = doc["daily"]["weathercode"][dag].as<int>();
|
||||
if (weathercode > 40) weathercode -= 40;
|
||||
spr.loadFont(loc["icon"][2], LittleFS);
|
||||
spr.loadFont(loc["icon"][2], *contentFS);
|
||||
if (weathercode == 55 || weathercode == 65 || weathercode == 75 || weathercode == 82 || weathercode == 86 || weathercode == 95 || weathercode == 99) {
|
||||
spr.setTextColor(PAL_RED, PAL_WHITE);
|
||||
} else {
|
||||
@@ -584,7 +597,7 @@ void drawForecast(String &filename, JsonObject &cfgobj, tagRecord *&taginfo, img
|
||||
int8_t tmax = round(doc["daily"]["temperature_2m_max"][dag].as<double>());
|
||||
uint8_t wind = windSpeedToBeaufort(doc["daily"]["windspeed_10m_max"][dag].as<double>());
|
||||
|
||||
spr.loadFont(loc["day"][2], LittleFS);
|
||||
spr.loadFont(loc["day"][2], *contentFS);
|
||||
|
||||
if (loc["rain"]) {
|
||||
int8_t rain = round(doc["daily"]["precipitation_sum"][dag].as<double>());
|
||||
@@ -611,7 +624,7 @@ void drawForecast(String &filename, JsonObject &cfgobj, tagRecord *&taginfo, img
|
||||
int getImgURL(String &filename, String URL, time_t fetched, imgParam &imageParams, String MAC) {
|
||||
// https://images.klari.net/kat-bw29.jpg
|
||||
|
||||
LittleFS.begin();
|
||||
Storage.begin();
|
||||
|
||||
Serial.println("get external " + URL);
|
||||
HTTPClient http;
|
||||
@@ -621,7 +634,7 @@ int getImgURL(String &filename, String URL, time_t fetched, imgParam &imageParam
|
||||
http.setTimeout(5000); // timeout in ms
|
||||
int httpCode = http.GET();
|
||||
if (httpCode == 200) {
|
||||
File f = LittleFS.open("/temp/temp.jpg", "w");
|
||||
File f = contentFS->open("/temp/temp.jpg", "w");
|
||||
if (f) {
|
||||
http.writeToStream(&f);
|
||||
f.close();
|
||||
@@ -783,7 +796,7 @@ void drawQR(String &filename, String qrcontent, String title, tagRecord *&taginf
|
||||
#ifdef CONTENT_QR
|
||||
TFT_eSPI tft = TFT_eSPI();
|
||||
TFT_eSprite spr = TFT_eSprite(&tft);
|
||||
LittleFS.begin();
|
||||
Storage.begin();
|
||||
|
||||
const char *text = qrcontent.c_str();
|
||||
QRCode qrcode;
|
||||
@@ -1000,8 +1013,25 @@ void prepareLUTreq(uint8_t *dst, String input) {
|
||||
prepareDataAvail(waveform, waveformLen, DATATYPE_CUSTOM_LUT_OTA, dst);
|
||||
}
|
||||
|
||||
void prepareConfigFile(uint8_t *dst, JsonObject config) {
|
||||
struct tagsettings tagSettings;
|
||||
tagSettings.settingsVer = 1;
|
||||
tagSettings.enableFastBoot = config["fastboot"].as<int>();
|
||||
tagSettings.enableRFWake = config["rfwake"].as<int>();
|
||||
tagSettings.enableTagRoaming = config["tagroaming"].as<int>();
|
||||
tagSettings.enableScanForAPAfterTimeout = config["tagscanontimeout"].as<int>();
|
||||
tagSettings.enableLowBatSymbol = config["showlowbat"].as<int>();
|
||||
tagSettings.enableNoRFSymbol = config["shownorf"].as<int>();
|
||||
tagSettings.customMode = 0;
|
||||
tagSettings.fastBootCapabilities = 0;
|
||||
tagSettings.minimumCheckInTime = 1;
|
||||
tagSettings.fixedChannel = config["fixedchannel"].as<int>();
|
||||
tagSettings.batLowVoltage = config["lowvoltage"].as<int>();
|
||||
prepareDataAvail((uint8_t *)&tagSettings, sizeof(tagSettings), 0xA8, dst);
|
||||
}
|
||||
|
||||
void getTemplate(JsonDocument &json, const char *filePath, uint8_t id, uint8_t hwtype) {
|
||||
File jsonFile = LittleFS.open(filePath, "r");
|
||||
File jsonFile = contentFS->open(filePath, "r");
|
||||
if (!jsonFile) {
|
||||
Serial.println("Failed to open content template file " + String(filePath));
|
||||
return;
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <ArduinoJson.h>
|
||||
#include <LittleFS.h>
|
||||
#include "storage.h"
|
||||
#include "LittleFS.h"
|
||||
#include <MD5Builder.h>
|
||||
// #include <FS.h>
|
||||
|
||||
@@ -109,24 +110,29 @@ class flasher {
|
||||
|
||||
flasher::flasher() {
|
||||
zbs = new ZBS_interface;
|
||||
Storage.end();
|
||||
}
|
||||
flasher::~flasher() {
|
||||
delete zbs;
|
||||
Storage.begin();
|
||||
}
|
||||
|
||||
#ifndef FLASHER_AP_SPEED
|
||||
#define FLASHER_AP_SPEED 4000000
|
||||
#endif
|
||||
|
||||
bool flasher::connectTag(uint8_t port) {
|
||||
bool result;
|
||||
|
||||
switch (port) {
|
||||
case 0:
|
||||
result = zbs->begin(FLASHER_AP_SS, FLASHER_AP_CLK, FLASHER_AP_MOSI, FLASHER_AP_MISO, FLASHER_AP_RESET, (uint8_t *)powerPinsAP, sizeof(powerPinsAP), 8000000);
|
||||
result = zbs->begin(FLASHER_AP_SS, FLASHER_AP_CLK, FLASHER_AP_MOSI, FLASHER_AP_MISO, FLASHER_AP_RESET, (uint8_t *)powerPinsAP, sizeof(powerPinsAP), FLASHER_AP_SPEED);
|
||||
break;
|
||||
#ifdef OPENEPAPERLINK_PCB
|
||||
case 1:
|
||||
result = zbs->begin(FLASHER_EXT_SS, FLASHER_EXT_CLK, FLASHER_EXT_MOSI, FLASHER_EXT_MISO, FLASHER_EXT_RESET, (uint8_t *)powerPinsExt, sizeof(powerPinsExt), 8000000);
|
||||
result = zbs->begin(FLASHER_EXT_SS, FLASHER_EXT_CLK, FLASHER_EXT_MOSI, FLASHER_EXT_MISO, FLASHER_EXT_RESET, (uint8_t *)powerPinsExt, sizeof(powerPinsExt), FLASHER_AP_SPEED);
|
||||
break;
|
||||
case 2:
|
||||
result = zbs->begin(FLASHER_ALT_SS, FLASHER_ALT_CLK, FLASHER_ALT_MOSI, FLASHER_ALT_MISO, FLASHER_ALT_RESET, (uint8_t *)powerPinsAlt, sizeof(powerPinsAlt), 8000000);
|
||||
result = zbs->begin(FLASHER_ALT_SS, FLASHER_ALT_CLK, FLASHER_ALT_MOSI, FLASHER_ALT_MISO, FLASHER_ALT_RESET, (uint8_t *)powerPinsAlt, sizeof(powerPinsAlt), FLASHER_AP_SPEED);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
@@ -206,7 +212,7 @@ bool flasher::getInfoBlockType() {
|
||||
bool flasher::findTagByMD5() {
|
||||
StaticJsonDocument<3000> doc;
|
||||
DynamicJsonDocument APconfig(600);
|
||||
fs::File readfile = LittleFS.open("/tag_md5_db.json", "r");
|
||||
fs::File readfile = contentFS->open("/tag_md5_db.json", "r");
|
||||
DeserializationError err = deserializeJson(doc, readfile);
|
||||
if (!err) {
|
||||
for (JsonObject elem : doc.as<JsonArray>()) {
|
||||
@@ -236,7 +242,7 @@ bool flasher::findTagByMD5() {
|
||||
bool flasher::findTagByType(uint8_t type) {
|
||||
StaticJsonDocument<3000> doc;
|
||||
DynamicJsonDocument APconfig(600);
|
||||
fs::File readfile = LittleFS.open("/tag_md5_db.json", "r");
|
||||
fs::File readfile = contentFS->open("/tag_md5_db.json", "r");
|
||||
DeserializationError err = deserializeJson(doc, readfile);
|
||||
if (!err) {
|
||||
for (JsonObject elem : doc.as<JsonArray>()) {
|
||||
@@ -300,7 +306,7 @@ bool flasher::backupFlash() {
|
||||
getFirmwareMD5();
|
||||
if (!zbs->select_flash(0)) return false;
|
||||
md5char[16] = 0x00;
|
||||
fs::File backup = LittleFS.open("/" + (String)md5char + "_backup.bin", "w", true);
|
||||
fs::File backup = contentFS->open("/" + (String)md5char + "_backup.bin", "w", true);
|
||||
for (uint32_t c = 0; c < 65535; c++) {
|
||||
backup.write(zbs->read_flash(c));
|
||||
}
|
||||
@@ -474,7 +480,7 @@ bool flasher::writeFlashFromPackOffset(fs::File *file, uint16_t length) {
|
||||
bool flasher::writeFlashFromPack(String filename, uint8_t type) {
|
||||
StaticJsonDocument<512> doc;
|
||||
DynamicJsonDocument APconfig(512);
|
||||
fs::File readfile = LittleFS.open(filename, "r");
|
||||
fs::File readfile = contentFS->open(filename, "r");
|
||||
DeserializationError err = deserializeJson(doc, readfile);
|
||||
if (!err) {
|
||||
for (JsonObject elem : doc.as<JsonArray>()) {
|
||||
@@ -505,7 +511,7 @@ bool flasher::writeFlashFromPack(String filename, uint8_t type) {
|
||||
uint16_t getAPUpdateVersion(uint8_t type) {
|
||||
StaticJsonDocument<512> doc;
|
||||
DynamicJsonDocument APconfig(512);
|
||||
fs::File readfile = LittleFS.open("/AP_FW_Pack.bin", "r");
|
||||
fs::File readfile = contentFS->open("/AP_FW_Pack.bin", "r");
|
||||
DeserializationError err = deserializeJson(doc, readfile);
|
||||
if (!err) {
|
||||
for (JsonObject elem : doc.as<JsonArray>()) {
|
||||
@@ -529,7 +535,7 @@ uint16_t getAPUpdateVersion(uint8_t type) {
|
||||
}
|
||||
|
||||
bool checkForcedAPFlash() {
|
||||
return LittleFS.exists("/AP_force_flash.bin");
|
||||
return contentFS->exists("/AP_force_flash.bin");
|
||||
}
|
||||
|
||||
bool doForcedAPFlash() {
|
||||
@@ -547,14 +553,14 @@ bool doForcedAPFlash() {
|
||||
f->writeInfoBlock();
|
||||
}
|
||||
|
||||
fs::File readfile = LittleFS.open("/AP_force_flash.bin", "r");
|
||||
fs::File readfile = contentFS->open("/AP_force_flash.bin", "r");
|
||||
bool res = f->writeFlashFromPackOffset(&readfile, readfile.size());
|
||||
#ifdef HAS_RGB_LED
|
||||
if (res) addFadeColor(CRGB::Green);
|
||||
if (!res) addFadeColor(CRGB::Red);
|
||||
#endif
|
||||
readfile.close();
|
||||
if (res) LittleFS.remove("/AP_force_flash.bin");
|
||||
if (res) contentFS->remove("/AP_force_flash.bin");
|
||||
f->zbs->reset();
|
||||
delete f;
|
||||
return res;
|
||||
|
||||
@@ -263,10 +263,12 @@ void ledTask(void* parameter) {
|
||||
|
||||
ledQueue = xQueueCreate(30, sizeof(struct ledInstruction*));
|
||||
|
||||
digitalWrite(FLASHER_LED, HIGH);
|
||||
pinMode(FLASHER_LED, OUTPUT);
|
||||
ledcSetup(7, 5000, 8);
|
||||
ledcAttachPin(FLASHER_LED, 7);
|
||||
if (FLASHER_LED != -1) {
|
||||
digitalWrite(FLASHER_LED, HIGH);
|
||||
pinMode(FLASHER_LED, OUTPUT);
|
||||
ledcAttachPin(FLASHER_LED, 7);
|
||||
}
|
||||
|
||||
struct ledInstruction* monoled = nullptr;
|
||||
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <WiFi.h>
|
||||
#include <WiFiManager.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "storage.h"
|
||||
#include "contentmanager.h"
|
||||
#include "flasher.h"
|
||||
#include "makeimage.h"
|
||||
@@ -33,12 +35,15 @@ void delayedStart(void* parameter) {
|
||||
|
||||
void timeTask(void* parameter) {
|
||||
wsSendSysteminfo();
|
||||
Serial.printf("Free heap: %.2f KB\n", ESP.getFreeHeap() / 1024.0f);
|
||||
while (1) {
|
||||
time_t now;
|
||||
time(&now);
|
||||
|
||||
if (now % 5 == 0 || apInfo.state != AP_STATE_ONLINE || config.runStatus != RUNSTATUS_RUN) wsSendSysteminfo();
|
||||
if (now % 5 == 0) Serial.printf("Free heap: %.2f KB\n", ESP.getFreeHeap() / 1024.0f);
|
||||
if (now % 300 == 6 && config.runStatus != RUNSTATUS_STOP) saveDB("/current/tagDB.json");
|
||||
|
||||
if (apInfo.state == AP_STATE_ONLINE) contentRunner();
|
||||
|
||||
vTaskDelay(1000 / portTICK_PERIOD_MS);
|
||||
@@ -84,6 +89,8 @@ void setup() {
|
||||
heap_caps_malloc_extmem_enable(64);
|
||||
#endif
|
||||
|
||||
Storage.begin();
|
||||
|
||||
/*
|
||||
Serial.println("\n\n##################################");
|
||||
Serial.printf("Internal Total heap %d, internal Free Heap %d\n", ESP.getHeapSize(), ESP.getFreeHeap());
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#include <Arduino.h>
|
||||
#include <FS.h>
|
||||
#include <LittleFS.h>
|
||||
#include "storage.h"
|
||||
#include <TFT_eSPI.h>
|
||||
#include <TJpg_Decoder.h>
|
||||
#include <makeimage.h>
|
||||
@@ -15,7 +15,7 @@ bool spr_output(int16_t x, int16_t y, uint16_t w, uint16_t h, uint16_t *bitmap)
|
||||
}
|
||||
|
||||
void jpg2buffer(String filein, String fileout, imgParam &imageParams) {
|
||||
LittleFS.begin();
|
||||
Storage.begin();
|
||||
TJpgDec.setSwapBytes(true);
|
||||
TJpgDec.setJpgScale(1);
|
||||
TJpgDec.setCallback(spr_output);
|
||||
@@ -23,7 +23,7 @@ void jpg2buffer(String filein, String fileout, imgParam &imageParams) {
|
||||
if (filein.c_str()[0] != '/') {
|
||||
filein = "/" + filein;
|
||||
}
|
||||
TJpgDec.getFsJpgSize(&w, &h, filein, LittleFS);
|
||||
TJpgDec.getFsJpgSize(&w, &h, filein, *contentFS);
|
||||
if (w==0 && h==0) {
|
||||
wsErr("invalid jpg");
|
||||
return;
|
||||
@@ -47,7 +47,7 @@ void jpg2buffer(String filein, String fileout, imgParam &imageParams) {
|
||||
wsErr("Failed to create sprite in jpg2buffer");
|
||||
} else {
|
||||
spr.fillSprite(TFT_WHITE);
|
||||
TJpgDec.drawFsJpg(0, 0, filein, LittleFS);
|
||||
TJpgDec.drawFsJpg(0, 0, filein, *contentFS);
|
||||
|
||||
spr2buffer(spr, fileout, imageParams);
|
||||
spr.deleteSprite();
|
||||
@@ -74,11 +74,7 @@ uint32_t colorDistance(const Color &c1, const Color &c2, const Error &e1) {
|
||||
return 3 * r_diff * r_diff + 6 * g_diff * g_diff + 1 * b_diff * b_diff;
|
||||
}
|
||||
|
||||
void spr2buffer(TFT_eSprite &spr, String &fileout, imgParam &imageParams) {
|
||||
long t = millis();
|
||||
LittleFS.begin();
|
||||
|
||||
fs::File f_out = LittleFS.open(fileout, "w");
|
||||
uint8_t *spr2color(TFT_eSprite &spr, imgParam &imageParams, size_t *buffer_size, bool is_red) {
|
||||
|
||||
bool dither = true;
|
||||
uint8_t rotate = imageParams.rotate;
|
||||
@@ -90,11 +86,13 @@ void spr2buffer(TFT_eSprite &spr, String &fileout, imgParam &imageParams) {
|
||||
bufh = spr.width();
|
||||
}
|
||||
|
||||
int bufferSize = (bufw * bufh) / 8;
|
||||
uint8_t *blackBuffer = new uint8_t[bufferSize];
|
||||
uint8_t *redBuffer = new uint8_t[bufferSize];
|
||||
memset(blackBuffer, 0, bufferSize);
|
||||
memset(redBuffer, 0, bufferSize);
|
||||
*buffer_size = (bufw * bufh) / 8;
|
||||
uint8_t *buffer = (uint8_t*) malloc(*buffer_size);
|
||||
if (!buffer) {
|
||||
Serial.println("Fallied to allocated buffer");
|
||||
return nullptr;
|
||||
}
|
||||
memset(buffer, 0, *buffer_size);
|
||||
|
||||
std::vector<Color> palette = {
|
||||
{255, 255, 255}, // White
|
||||
@@ -147,15 +145,16 @@ void spr2buffer(TFT_eSprite &spr, String &fileout, imgParam &imageParams) {
|
||||
// this looks a bit ugly, but it's performing better than shorter notations
|
||||
switch (best_color_index) {
|
||||
case 1:
|
||||
blackBuffer[byteIndex] |= (1 << bitIndex);
|
||||
if(!is_red)
|
||||
buffer[byteIndex] |= (1 << bitIndex);
|
||||
break;
|
||||
case 2:
|
||||
imageParams.hasRed = true;
|
||||
redBuffer[byteIndex] |= (1 << bitIndex);
|
||||
if(is_red)
|
||||
buffer[byteIndex] |= (1 << bitIndex);
|
||||
break;
|
||||
case 3:
|
||||
blackBuffer[byteIndex] |= (1 << bitIndex);
|
||||
redBuffer[byteIndex] |= (1 << bitIndex);
|
||||
buffer[byteIndex] |= (1 << bitIndex);
|
||||
imageParams.hasRed = true;
|
||||
break;
|
||||
}
|
||||
@@ -199,14 +198,32 @@ void spr2buffer(TFT_eSprite &spr, String &fileout, imgParam &imageParams) {
|
||||
}
|
||||
memcpy(error_bufferold, error_buffernew, bufw * sizeof(Error));
|
||||
}
|
||||
|
||||
delete[] error_buffernew;
|
||||
delete[] error_bufferold;
|
||||
|
||||
f_out.write(blackBuffer, bufferSize);
|
||||
if (imageParams.hasRed) f_out.write(redBuffer, bufferSize);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
delete[] blackBuffer;
|
||||
delete[] redBuffer;
|
||||
void spr2buffer(TFT_eSprite &spr, String &fileout, imgParam &imageParams) {
|
||||
long t = millis();
|
||||
Storage.begin();
|
||||
|
||||
fs::File f_out = contentFS->open(fileout, "w");
|
||||
size_t bufferSize;
|
||||
|
||||
uint8_t *blackBuffer = (uint8_t*) spr2color(spr, imageParams, &bufferSize, false);
|
||||
if(!blackBuffer)
|
||||
return;
|
||||
f_out.write(blackBuffer, bufferSize);
|
||||
free(blackBuffer);
|
||||
if (imageParams.hasRed) {
|
||||
uint8_t *redBuffer = (uint8_t*) spr2color(spr, imageParams, &bufferSize, true);
|
||||
if(!redBuffer)
|
||||
return;
|
||||
f_out.write(redBuffer, bufferSize);
|
||||
free(redBuffer);
|
||||
}
|
||||
|
||||
f_out.close();
|
||||
Serial.println("finished writing buffer " + String(millis() - t) + "ms");
|
||||
|
||||
@@ -3,12 +3,12 @@
|
||||
#include <Arduino.h>
|
||||
#include <FS.h>
|
||||
#include <HTTPClient.h>
|
||||
#include <LittleFS.h>
|
||||
#include "storage.h"
|
||||
#include <MD5Builder.h>
|
||||
#include <makeimage.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "LittleFS.h"
|
||||
#include "storage.h"
|
||||
#include "commstructs.h"
|
||||
#include "serialap.h"
|
||||
#include "settings.h"
|
||||
@@ -130,14 +130,14 @@ bool prepareDataAvail(String* filename, uint8_t dataType, uint8_t* dst, uint16_t
|
||||
}
|
||||
|
||||
*filename = "/" + *filename;
|
||||
LittleFS.begin();
|
||||
Storage.begin();
|
||||
|
||||
if (!LittleFS.exists(*filename)) {
|
||||
if (!contentFS->exists(*filename)) {
|
||||
wsErr("File not found. " + *filename);
|
||||
return false;
|
||||
}
|
||||
|
||||
fs::File file = LittleFS.open(*filename);
|
||||
fs::File file = contentFS->open(*filename);
|
||||
uint32_t filesize = file.size();
|
||||
if (filesize == 0) {
|
||||
file.close();
|
||||
@@ -161,8 +161,8 @@ bool prepareDataAvail(String* filename, uint8_t dataType, uint8_t* dst, uint16_t
|
||||
if (memcmp(md5bytes, taginfo->md5pending, 16) == 0) {
|
||||
wsLog("new image is the same as current or already pending image. not updating tag.");
|
||||
wsSendTaginfo(dst, SYNC_TAGSTATUS);
|
||||
if (LittleFS.exists(*filename)) {
|
||||
LittleFS.remove(*filename);
|
||||
if (contentFS->exists(*filename)) {
|
||||
contentFS->remove(*filename);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -182,10 +182,10 @@ bool prepareDataAvail(String* filename, uint8_t dataType, uint8_t* dst, uint16_t
|
||||
if (dataType != DATATYPE_FW_UPDATE) {
|
||||
char dst_path[64];
|
||||
sprintf(dst_path, "/current/%02X%02X%02X%02X%02X%02X%02X%02X.pending\0", dst[7], dst[6], dst[5], dst[4], dst[3], dst[2], dst[1], dst[0]);
|
||||
if (LittleFS.exists(dst_path)) {
|
||||
LittleFS.remove(dst_path);
|
||||
if (contentFS->exists(dst_path)) {
|
||||
contentFS->remove(dst_path);
|
||||
}
|
||||
LittleFS.rename(*filename, dst_path);
|
||||
contentFS->rename(*filename, dst_path);
|
||||
*filename = String(dst_path);
|
||||
|
||||
wsLog("new image: " + String(dst_path));
|
||||
@@ -241,7 +241,7 @@ void prepareExternalDataAvail(struct pendingData* pending, IPAddress remoteIP) {
|
||||
case DATATYPE_IMG_RAW_1BPP:
|
||||
case DATATYPE_IMG_RAW_2BPP:
|
||||
case DATATYPE_IMG_RAW_1BPP_DIRECT: {
|
||||
LittleFS.begin();
|
||||
Storage.begin();
|
||||
|
||||
char hexmac[17];
|
||||
mac2hex(pending->targetMac, hexmac);
|
||||
@@ -252,13 +252,13 @@ void prepareExternalDataAvail(struct pendingData* pending, IPAddress remoteIP) {
|
||||
http.begin(imageUrl);
|
||||
int httpCode = http.GET();
|
||||
if (httpCode == 200) {
|
||||
File file = LittleFS.open(filename, "w");
|
||||
File file = contentFS->open(filename, "w");
|
||||
http.writeToStream(&file);
|
||||
file.close();
|
||||
}
|
||||
http.end();
|
||||
|
||||
fs::File file = LittleFS.open(filename);
|
||||
fs::File file = contentFS->open(filename);
|
||||
uint32_t filesize = file.size();
|
||||
if (filesize == 0) {
|
||||
file.close();
|
||||
@@ -338,7 +338,7 @@ void processBlockRequest(struct espBlockRequest* br) {
|
||||
|
||||
if (taginfo->data == nullptr) {
|
||||
// not cached. open file, cache the data
|
||||
fs::File file = LittleFS.open(taginfo->filename);
|
||||
fs::File file = contentFS->open(taginfo->filename);
|
||||
if (!file) {
|
||||
Serial.print("No current file. Canceling request\n");
|
||||
prepareCancelPending(br->src);
|
||||
@@ -380,11 +380,15 @@ void processXferComplete(struct espXferComplete* xfc, bool local) {
|
||||
char dst_path[64];
|
||||
sprintf(src_path, "/current/%02X%02X%02X%02X%02X%02X%02X%02X.pending\0", xfc->src[7], xfc->src[6], xfc->src[5], xfc->src[4], xfc->src[3], xfc->src[2], xfc->src[1], xfc->src[0]);
|
||||
sprintf(dst_path, "/current/%02X%02X%02X%02X%02X%02X%02X%02X.raw\0", xfc->src[7], xfc->src[6], xfc->src[5], xfc->src[4], xfc->src[3], xfc->src[2], xfc->src[1], xfc->src[0]);
|
||||
if (LittleFS.exists(dst_path) && LittleFS.exists(src_path)) {
|
||||
LittleFS.remove(dst_path);
|
||||
if (contentFS->exists(dst_path) && contentFS->exists(src_path)) {
|
||||
contentFS->remove(dst_path);
|
||||
}
|
||||
if (LittleFS.exists(src_path)) {
|
||||
LittleFS.rename(src_path, dst_path);
|
||||
if (contentFS->exists(src_path)) {
|
||||
#ifndef REMOVE_RAW
|
||||
contentFS->rename(src_path, dst_path);
|
||||
#else
|
||||
contentFS->remove(src_path);
|
||||
#endif
|
||||
}
|
||||
|
||||
time_t now;
|
||||
@@ -396,8 +400,8 @@ void processXferComplete(struct espXferComplete* xfc, bool local) {
|
||||
clearPending(taginfo);
|
||||
taginfo->wakeupReason = 0;
|
||||
if (taginfo->contentMode == 12 && local == false) {
|
||||
if (LittleFS.exists(dst_path)) {
|
||||
LittleFS.remove(dst_path);
|
||||
if (contentFS->exists(dst_path)) {
|
||||
contentFS->remove(dst_path);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -587,6 +591,26 @@ bool showAPSegmentedInfo(uint8_t* dst, bool local) {
|
||||
}
|
||||
}
|
||||
|
||||
bool sendTagCommand(uint8_t* dst, uint8_t cmd, bool local) {
|
||||
struct pendingData pending = {0};
|
||||
memcpy(pending.targetMac, dst, 8);
|
||||
pending.availdatainfo.dataType = 0xAF;
|
||||
pending.availdatainfo.dataTypeArgument = cmd;
|
||||
pending.availdatainfo.nextCheckIn = 0;
|
||||
pending.attemptsLeft = 120;
|
||||
char buffer[64];
|
||||
sprintf(buffer, ">Tag CMD %02X%02X%02X%02X%02X%02X%02X%02X\n\0", dst[7], dst[6], dst[5], dst[4], dst[3], dst[2], dst[1], dst[0]);
|
||||
Serial.print(buffer);
|
||||
if (local) {
|
||||
return sendDataAvail(&pending);
|
||||
} else {
|
||||
udpsync.netSendDataAvail(&pending);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void updateTaginfoitem(struct TagInfo* taginfoitem) {
|
||||
tagRecord* taginfo = nullptr;
|
||||
taginfo = tagRecord::findByMAC(taginfoitem->mac);
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#include <ArduinoJson.h>
|
||||
#include <FS.h>
|
||||
#include <HTTPClient.h>
|
||||
#include <LittleFS.h>
|
||||
#include "storage.h"
|
||||
#include <MD5Builder.h>
|
||||
#include <Update.h>
|
||||
|
||||
@@ -51,7 +51,7 @@ void handleCheckFile(AsyncWebServerRequest* request) {
|
||||
}
|
||||
|
||||
String filePath = request->getParam("path")->value();
|
||||
File file = LittleFS.open(filePath, "r");
|
||||
File file = contentFS->open(filePath, "r");
|
||||
if (!file) {
|
||||
StaticJsonDocument<64> doc;
|
||||
doc["filesize"] = 0;
|
||||
@@ -121,7 +121,7 @@ void handleLittleFSUpload(AsyncWebServerRequest* request, String filename, size_
|
||||
} else {
|
||||
path = request->getParam("path", true)->value();
|
||||
Serial.println("update " + path);
|
||||
request->_tempFile = LittleFS.open(path, "w", true);
|
||||
request->_tempFile = contentFS->open(path, "w", true);
|
||||
}
|
||||
}
|
||||
if (len) {
|
||||
@@ -268,7 +268,7 @@ void handleRollback(AsyncWebServerRequest* request) {
|
||||
|
||||
void handleUpdateActions(AsyncWebServerRequest* request) {
|
||||
wsSerial("Performing cleanup");
|
||||
File file = LittleFS.open("/update_actions.json", "r");
|
||||
File file = contentFS->open("/update_actions.json", "r");
|
||||
if (!file) {
|
||||
wsSerial("No update_actions.json present");
|
||||
request->send(200, "No update actions needed");
|
||||
@@ -278,12 +278,12 @@ void handleUpdateActions(AsyncWebServerRequest* request) {
|
||||
DeserializationError error = deserializeJson(doc, file);
|
||||
JsonArray deleteFiles = doc["deletefile"].as<JsonArray>();
|
||||
for (const auto& filePath : deleteFiles) {
|
||||
if (LittleFS.remove(filePath.as<const char*>())) {
|
||||
if (contentFS->remove(filePath.as<const char*>())) {
|
||||
wsSerial("deleted file: " + filePath.as<String>());
|
||||
}
|
||||
}
|
||||
file.close();
|
||||
wsSerial("Cleanup finished");
|
||||
request->send(200, "Clean up finished");
|
||||
LittleFS.remove("/update_actions.json");
|
||||
contentFS->remove("/update_actions.json");
|
||||
}
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <HardwareSerial.h>
|
||||
#include <LittleFS.h>
|
||||
|
||||
#include "commstructs.h"
|
||||
#include "flasher.h"
|
||||
@@ -10,6 +9,7 @@
|
||||
#include "newproto.h"
|
||||
#include "powermgt.h"
|
||||
#include "settings.h"
|
||||
#include "storage.h"
|
||||
#include "web.h"
|
||||
#include "zbs_interface.h"
|
||||
|
||||
@@ -205,6 +205,7 @@ bool sendDataAvail(struct pendingData* pending) {
|
||||
}
|
||||
if (waitCmdReply()) goto sdasend;
|
||||
Serial.printf("SDA send failed in try %d\n", attempt);
|
||||
delay(200);
|
||||
}
|
||||
Serial.print("SDA failed to send...\n");
|
||||
txEnd();
|
||||
@@ -606,7 +607,7 @@ bool bringAPOnline() {
|
||||
}
|
||||
|
||||
void APTask(void* parameter) {
|
||||
xTaskCreate(rxCmdProcessor, "rxCmdProcessor", 3000, NULL, configMAX_PRIORITIES - 10, NULL);
|
||||
xTaskCreate(rxCmdProcessor, "rxCmdProcessor", 4000, NULL, configMAX_PRIORITIES - 10, NULL);
|
||||
xTaskCreate(rxSerialTask, "rxSerialTask", 1750, NULL, configMAX_PRIORITIES - 4, NULL);
|
||||
|
||||
#if (AP_PROCESS_PORT == FLASHER_AP_PORT)
|
||||
@@ -687,6 +688,10 @@ void APTask(void* parameter) {
|
||||
}
|
||||
refreshAllPending();
|
||||
} else {
|
||||
#ifndef FLASH_TIMEOUT
|
||||
#define FLASH_TIMEOUT 30
|
||||
#endif
|
||||
|
||||
// AP unavailable, maybe time to flash?
|
||||
apInfo.isOnline = false;
|
||||
apInfo.state = AP_STATE_OFFLINE;
|
||||
@@ -694,8 +699,8 @@ void APTask(void* parameter) {
|
||||
Serial.printf("This could be the first time this AP is booted and the AP-tag may be unflashed. We'll try to flash it!\n");
|
||||
Serial.printf("If this tag was previously flashed succesfully but this message still shows up, there's probably something wrong with the serial connections.\n");
|
||||
Serial.printf("The build of this firmware expects an AP tag with TXD/RXD on ESP32 pins %d and %d, does this match with your wiring?\n", FLASHER_AP_RXD, FLASHER_AP_TXD);
|
||||
Serial.println("Performing firmware flash in about 30 seconds!\n");
|
||||
flashCountDown(30);
|
||||
Serial.printf("Performing firmware flash in about %d seconds!\n", FLASH_TIMEOUT);
|
||||
flashCountDown(FLASH_TIMEOUT);
|
||||
if (doAPFlash()) {
|
||||
checkWaitPowerCycle();
|
||||
if (bringAPOnline()) {
|
||||
@@ -747,6 +752,15 @@ void APTask(void* parameter) {
|
||||
#endif
|
||||
Serial.println("Please verify your wiring and try again!");
|
||||
}
|
||||
#ifdef HAS_SDCARD
|
||||
if (SD_CARD_CLK == FLASHER_AP_CLK ||
|
||||
SD_CARD_MISO == FLASHER_AP_MISO ||
|
||||
SD_CARD_MOSI == FLASHER_AP_MOSI) {
|
||||
Serial.println("Reseting in 30 seconds to restore SPI state!\n");
|
||||
flashCountDown(30);
|
||||
ESP.restart();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
uint8_t attempts = 0;
|
||||
|
||||
215
ESP32_AP-Flasher/src/storage.cpp
Normal file
215
ESP32_AP-Flasher/src/storage.cpp
Normal file
@@ -0,0 +1,215 @@
|
||||
#include "storage.h"
|
||||
|
||||
#ifdef HAS_SDCARD
|
||||
#include "FS.h"
|
||||
#include "SD.h"
|
||||
#include "SPI.h"
|
||||
#endif
|
||||
|
||||
#include "LittleFS.h"
|
||||
|
||||
DynStorage::DynStorage() : isInited(0) {}
|
||||
|
||||
static void initLittleFS() {
|
||||
LittleFS.begin();
|
||||
contentFS = &LittleFS;
|
||||
}
|
||||
|
||||
#ifdef HAS_SDCARD
|
||||
static SPIClass* spi;
|
||||
|
||||
static void initSDCard() {
|
||||
uint8_t spi_bus = VSPI;
|
||||
|
||||
// SD.begin and spi.begin are allocating memory so we dont want to do that
|
||||
if(!spi) {
|
||||
spi = new SPIClass(spi_bus);
|
||||
spi->begin(SD_CARD_CLK, SD_CARD_MISO, SD_CARD_MOSI, SD_CARD_SS);
|
||||
|
||||
bool res = SD.begin(SD_CARD_SS, *spi, 40000000);
|
||||
if (!res) {
|
||||
Serial.println("Card Mount Failed");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t cardType = SD.cardType();
|
||||
|
||||
if (cardType == CARD_NONE) {
|
||||
Serial.println("No SD card attached");
|
||||
return;
|
||||
}
|
||||
|
||||
contentFS = &SD;
|
||||
}
|
||||
#endif
|
||||
|
||||
size_t DynStorage::freeSpace(){
|
||||
this->begin();
|
||||
#ifdef HAS_SDCARD
|
||||
return SD.totalBytes() - SD.usedBytes();
|
||||
#endif
|
||||
return LittleFS.totalBytes() - LittleFS.usedBytes();
|
||||
}
|
||||
|
||||
void copyFile(File in, File out) {
|
||||
Serial.print("Copying ");
|
||||
Serial.print(in.path());
|
||||
Serial.print(" to ");
|
||||
Serial.println(out.path());
|
||||
|
||||
size_t n;
|
||||
uint8_t buf[64];
|
||||
while ((n = in.read(buf, sizeof(buf))) > 0) {
|
||||
out.write(buf, n);
|
||||
}
|
||||
}
|
||||
|
||||
void copyBetweenFS(FS& sourceFS, const char* source_path, FS& targetFS) {
|
||||
File root = sourceFS.open(source_path);
|
||||
char next_path[128];
|
||||
|
||||
if (root.isDirectory()) {
|
||||
if (!contentFS->exists(root.path())) {
|
||||
if (!contentFS->mkdir(root.path())) {
|
||||
Serial.print("Failed to create directory ");
|
||||
Serial.println(root.path());
|
||||
return;
|
||||
}
|
||||
}
|
||||
File file = root.openNextFile();
|
||||
while (file) {
|
||||
if (file.isDirectory()) {
|
||||
sprintf(next_path, "%s/%s\0", root.path(), file.path());
|
||||
|
||||
copyBetweenFS(sourceFS, file.path(), targetFS);
|
||||
} else {
|
||||
File target = contentFS->open(file.path(), "w");
|
||||
if (target) {
|
||||
copyFile(file, target);
|
||||
target.close();
|
||||
file.close();
|
||||
} else {
|
||||
Serial.print("Couldn't create high target file");
|
||||
Serial.println(file.path());
|
||||
return;
|
||||
}
|
||||
}
|
||||
file = root.openNextFile();
|
||||
}
|
||||
} else {
|
||||
File target = contentFS->open(root.path(), "w");
|
||||
if (target) {
|
||||
copyFile(root, target);
|
||||
} else {
|
||||
Serial.print("Couldn't create target file ");
|
||||
Serial.println(root.path());
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef HAS_SDCARD
|
||||
void copyIfNeeded(const char* path) {
|
||||
if (!contentFS->exists(path) && LittleFS.exists(path)) {
|
||||
Serial.printf("SDCard does not contain %s, littleFS does, copying\n", path);
|
||||
copyBetweenFS(LittleFS, path, *contentFS);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void DynStorage::begin() {
|
||||
initLittleFS();
|
||||
|
||||
#ifdef HAS_SDCARD
|
||||
initSDCard();
|
||||
|
||||
copyIfNeeded("/index.html");
|
||||
copyIfNeeded("/fonts");
|
||||
copyIfNeeded("/www");
|
||||
copyIfNeeded("/AP_FW_Pack.bin");
|
||||
copyIfNeeded("/tag_md5_db.json");
|
||||
copyIfNeeded("/update_actions.json");
|
||||
copyIfNeeded("/content_template.json");
|
||||
#endif
|
||||
|
||||
if (!contentFS->exists("/current")) {
|
||||
contentFS->mkdir("/current");
|
||||
}
|
||||
if (!contentFS->exists("/temp")) {
|
||||
contentFS->mkdir("/temp");
|
||||
}
|
||||
}
|
||||
|
||||
void DynStorage::end() {
|
||||
#ifdef HAS_SDCARD
|
||||
initLittleFS();
|
||||
if (SD_CARD_CLK == FLASHER_AP_CLK ||
|
||||
SD_CARD_MISO == FLASHER_AP_MISO ||
|
||||
SD_CARD_MOSI == FLASHER_AP_MOSI) {
|
||||
Serial.println("Tearing down SD card connection");
|
||||
|
||||
copyBetweenFS(*contentFS, "/tag_md5_db.json", LittleFS);
|
||||
copyBetweenFS(*contentFS, "/AP_FW_Pack.bin", LittleFS);
|
||||
if (contentFS->exists("/AP_force_flash.bin")) {
|
||||
copyBetweenFS(*contentFS, "/AP_force_flash.bin", LittleFS);
|
||||
contentFS->remove("/AP_force_flash.bin");
|
||||
}
|
||||
Serial.println("Swapping to LittleFS");
|
||||
|
||||
contentFS = &LittleFS;
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
void listDir(fs::FS& fs, const char* dirname, uint8_t levels) {
|
||||
Storage.begin();
|
||||
// Print blank line on screen
|
||||
Serial.printf(" \n ");
|
||||
|
||||
Serial.printf("Listing directory: %s\n", dirname);
|
||||
|
||||
File root = fs.open(dirname);
|
||||
if (!root) {
|
||||
Serial.println("Failed to open directory");
|
||||
return;
|
||||
}
|
||||
if (!root.isDirectory()) {
|
||||
Serial.println("Not a directory");
|
||||
return;
|
||||
}
|
||||
|
||||
File file = root.openNextFile();
|
||||
while (file) {
|
||||
if (!strcmp("System Volume Information", file.name())) {
|
||||
file = root.openNextFile();
|
||||
continue;
|
||||
}
|
||||
|
||||
if (file.isDirectory()) {
|
||||
Serial.print(" DIR : ");
|
||||
Serial.println(file.name());
|
||||
if (levels) {
|
||||
listDir(fs, file.path(), levels - 1);
|
||||
}
|
||||
Serial.println();
|
||||
} else {
|
||||
Serial.print(" FILE: ");
|
||||
Serial.print(file.name());
|
||||
Serial.print(" SIZE: ");
|
||||
Serial.println(file.size());
|
||||
}
|
||||
file = root.openNextFile();
|
||||
}
|
||||
}
|
||||
|
||||
void DynStorage::listFiles() {
|
||||
listDir(LittleFS, "/", 1);
|
||||
#ifdef HAS_SDCARD
|
||||
listDir(*contentFS, "/", 1);
|
||||
#endif
|
||||
}
|
||||
|
||||
fs::FS* contentFS;
|
||||
DynStorage Storage;
|
||||
@@ -3,7 +3,7 @@
|
||||
#include <Arduino.h>
|
||||
#include <FS.h>
|
||||
|
||||
#include "LittleFS.h"
|
||||
#include "storage.h"
|
||||
|
||||
void init_time() {
|
||||
struct tm timeinfo;
|
||||
@@ -28,7 +28,7 @@ void logLine(String text) {
|
||||
char timeStr[24];
|
||||
strftime(timeStr, sizeof(timeStr), "%Y-%m-%d %H:%M:%S ", localtime(&now));
|
||||
|
||||
File logFile = LittleFS.open("/log.txt", "a");
|
||||
File logFile = contentFS->open("/log.txt", "a");
|
||||
if (logFile) {
|
||||
logFile.print(timeStr);
|
||||
logFile.println(text);
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#include <FS.h>
|
||||
#include <vector>
|
||||
|
||||
#include "LittleFS.h"
|
||||
#include "storage.h"
|
||||
#include "language.h"
|
||||
|
||||
std::vector<tagRecord*> tagDB;
|
||||
@@ -126,8 +126,8 @@ void saveDB(String filename) {
|
||||
|
||||
long t = millis();
|
||||
|
||||
LittleFS.begin();
|
||||
fs::File file = LittleFS.open(filename, "w");
|
||||
Storage.begin();
|
||||
fs::File file = contentFS->open(filename, "w");
|
||||
if (!file) {
|
||||
Serial.println("saveDB: Failed to open file");
|
||||
return;
|
||||
@@ -161,8 +161,8 @@ void loadDB(String filename) {
|
||||
Serial.println("reading DB from file");
|
||||
long t = millis();
|
||||
|
||||
LittleFS.begin();
|
||||
fs::File readfile = LittleFS.open(filename, "r");
|
||||
Storage.begin();
|
||||
fs::File readfile = contentFS->open(filename, "r");
|
||||
if (!readfile) {
|
||||
Serial.println("loadDB: Failed to open file");
|
||||
return;
|
||||
@@ -264,9 +264,9 @@ void clearPending(tagRecord* taginfo) {
|
||||
}
|
||||
|
||||
void initAPconfig() {
|
||||
LittleFS.begin(true);
|
||||
Storage.begin();
|
||||
DynamicJsonDocument APconfig(500);
|
||||
File configFile = LittleFS.open("/current/apconfig.json", "r");
|
||||
File configFile = contentFS->open("/current/apconfig.json", "r");
|
||||
if (configFile) {
|
||||
DeserializationError error = deserializeJson(APconfig, configFile);
|
||||
if (error) {
|
||||
@@ -285,7 +285,7 @@ void initAPconfig() {
|
||||
}
|
||||
|
||||
void saveAPconfig() {
|
||||
fs::File configFile = LittleFS.open("/current/apconfig.json", "w");
|
||||
fs::File configFile = contentFS->open("/current/apconfig.json", "w");
|
||||
DynamicJsonDocument APconfig(500);
|
||||
APconfig["channel"] = config.channel;
|
||||
APconfig["alias"] = config.alias;
|
||||
|
||||
@@ -6,8 +6,9 @@
|
||||
#include <ESPAsyncWebServer.h>
|
||||
#include <ESPmDNS.h>
|
||||
#include <FS.h>
|
||||
#include <LittleFS.h>
|
||||
#include <SPIFFSEditor.h>
|
||||
#include "storage.h"
|
||||
#include "LittleFS.h"
|
||||
#include "SPIFFSEditor.h"
|
||||
#include <WiFi.h>
|
||||
#include <WiFiManager.h> // https://github.com/tzapu/WiFiManager/tree/feature_asyncwebserver
|
||||
|
||||
@@ -135,7 +136,7 @@ void wsSendSysteminfo() {
|
||||
sys["heap"] = ESP.getFreeHeap();
|
||||
sys["recordcount"] = tagDB.size();
|
||||
sys["dbsize"] = tagDB.size() * sizeof(tagRecord);
|
||||
sys["littlefsfree"] = LittleFS.totalBytes() - LittleFS.usedBytes();
|
||||
sys["littlefsfree"] = Storage.freeSpace();
|
||||
sys["apstate"] = apInfo.state;
|
||||
sys["runstate"] = config.runStatus;
|
||||
|
||||
@@ -215,15 +216,7 @@ uint8_t wsClientCount() {
|
||||
}
|
||||
|
||||
void init_web() {
|
||||
LittleFS.begin(true);
|
||||
|
||||
if (!LittleFS.exists("/current")) {
|
||||
LittleFS.mkdir("/current");
|
||||
}
|
||||
if (!LittleFS.exists("/temp")) {
|
||||
LittleFS.mkdir("/temp");
|
||||
}
|
||||
|
||||
Storage.begin();
|
||||
WiFi.mode(WIFI_STA);
|
||||
|
||||
WiFiManager wm;
|
||||
@@ -243,8 +236,8 @@ void init_web() {
|
||||
Serial.print("Connected! IP address: ");
|
||||
Serial.println(WiFi.localIP());
|
||||
|
||||
// server.addHandler(new SPIFFSEditor(LittleFS, http_username, http_password));
|
||||
server.addHandler(new SPIFFSEditor(LittleFS));
|
||||
// server.addHandler(new SPIFFSEditor(*contentFS, http_username, http_password));
|
||||
server.addHandler(new SPIFFSEditor(*contentFS));
|
||||
|
||||
ws.onEvent(onEvent);
|
||||
server.addHandler(&ws);
|
||||
@@ -260,8 +253,8 @@ void init_web() {
|
||||
ESP.restart();
|
||||
});
|
||||
|
||||
server.serveStatic("/current", LittleFS, "/current/");
|
||||
server.serveStatic("/", LittleFS, "/www/").setDefaultFile("index.html");
|
||||
server.serveStatic("/current", *contentFS, "/current/");
|
||||
server.serveStatic("/", *contentFS, "/www/").setDefaultFile("index.html");
|
||||
|
||||
server.on(
|
||||
"/imgupload", HTTP_POST, [](AsyncWebServerRequest *request) {
|
||||
@@ -371,7 +364,7 @@ void init_web() {
|
||||
server.on("/get_ap_config", HTTP_GET, [](AsyncWebServerRequest *request) {
|
||||
UDPcomm udpsync;
|
||||
udpsync.getAPList();
|
||||
File configFile = LittleFS.open("/current/apconfig.json", "r");
|
||||
File configFile = contentFS->open("/current/apconfig.json", "r");
|
||||
if (!configFile) {
|
||||
request->send(500, "text/plain", "Error opening apconfig.json file");
|
||||
return;
|
||||
@@ -411,7 +404,7 @@ void init_web() {
|
||||
|
||||
server.on("/backup_db", HTTP_GET, [](AsyncWebServerRequest *request) {
|
||||
saveDB("/current/tagDB.json");
|
||||
File file = LittleFS.open("/current/tagDB.json", "r");
|
||||
File file = contentFS->open("/current/tagDB.json", "r");
|
||||
AsyncWebServerResponse *response = request->beginResponse(file, "tagDB.json", String(), true);
|
||||
request->send(response);
|
||||
file.close();
|
||||
@@ -449,7 +442,7 @@ void doImageUpload(AsyncWebServerRequest *request, String filename, size_t index
|
||||
} else {
|
||||
filename = "unknown.jpg";
|
||||
}
|
||||
request->_tempFile = LittleFS.open("/" + filename, "w");
|
||||
request->_tempFile = contentFS->open("/" + filename, "w");
|
||||
}
|
||||
if (len) {
|
||||
// stream the incoming chunk to the opened file
|
||||
|
||||
@@ -7,6 +7,10 @@
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef USE_SOFTSPI
|
||||
#include <SoftSPI.h>
|
||||
#endif
|
||||
|
||||
#include "powermgt.h"
|
||||
|
||||
uint8_t ZBS_interface::begin(uint8_t SS, uint8_t CLK, uint8_t MOSI, uint8_t MISO, uint8_t RESET, uint8_t* POWER, uint8_t powerPins, uint32_t spi_speed) {
|
||||
@@ -27,7 +31,12 @@ uint8_t ZBS_interface::begin(uint8_t SS, uint8_t CLK, uint8_t MOSI, uint8_t MISO
|
||||
digitalWrite(_CLK_PIN, LOW);
|
||||
digitalWrite(_MOSI_PIN, HIGH);
|
||||
|
||||
#ifdef USE_SOFTSPI
|
||||
if (!spi) spi = new SoftSPI(_MOSI_PIN, _MISO_PIN, _CLK_PIN);
|
||||
#else
|
||||
if (!spi) spi = new SPIClass(HSPI);
|
||||
#endif
|
||||
|
||||
|
||||
spiSettings = SPISettings(spi_speed, MSBFIRST, SPI_MODE0);
|
||||
spi_ready = 0;
|
||||
|
||||
BIN
Hardware/2.9-1.54 NanoAP by ATC1441/Antenna_FlexPCB_Gerber.rar
Normal file
BIN
Hardware/2.9-1.54 NanoAP by ATC1441/Antenna_FlexPCB_Gerber.rar
Normal file
Binary file not shown.
BIN
Hardware/2.9-1.54 NanoAP by ATC1441/NanoAP_Case.jpg
Normal file
BIN
Hardware/2.9-1.54 NanoAP by ATC1441/NanoAP_Case.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 233 KiB |
BIN
Hardware/2.9-1.54 NanoAP by ATC1441/NanoAP_Case_V3.stl
Normal file
BIN
Hardware/2.9-1.54 NanoAP by ATC1441/NanoAP_Case_V3.stl
Normal file
Binary file not shown.
BIN
Hardware/2.9-1.54 NanoAP by ATC1441/NanoAP_Flapped.jpg
Normal file
BIN
Hardware/2.9-1.54 NanoAP by ATC1441/NanoAP_Flapped.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 344 KiB |
BIN
Hardware/2.9-1.54 NanoAP by ATC1441/NanoAP_Gerber.rar
Normal file
BIN
Hardware/2.9-1.54 NanoAP by ATC1441/NanoAP_Gerber.rar
Normal file
Binary file not shown.
BIN
Hardware/2.9-1.54 NanoAP by ATC1441/NanoAP_PCB_soldered.jpg
Normal file
BIN
Hardware/2.9-1.54 NanoAP by ATC1441/NanoAP_PCB_soldered.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 565 KiB |
16
Hardware/2.9-1.54 NanoAP by ATC1441/README.md
Normal file
16
Hardware/2.9-1.54 NanoAP by ATC1441/README.md
Normal file
@@ -0,0 +1,16 @@
|
||||
# 3D-printed ESP32-S2 Mini NanoAP with Flex PCB
|
||||
|
||||
## NanoAP by [ATC1441](https://github.com/atc1441)
|
||||
|
||||
The NanoAP is build by using an 1.54" Display with an ZBS243 SoC and an ESP32 S2-Mini Dev-board(2MB SRAM Version)
|
||||
The Flex PCB does also fit on the 2.9" Display, the case will not fit then :D
|
||||
|
||||
<img width="600" alt="NanoAP_Case" src="NanoAP_Case.jpg">
|
||||
|
||||
<img width="600" alt="NanoAP_PCB_soldered" src="NanoAP_PCB_soldered.jpg">
|
||||
|
||||
<img width="600" alt="NanoAP_Flapped" src="NanoAP_Flapped.jpg">
|
||||
|
||||
- The "NanoAP_Case_V3.stl" Case is printed in one go standing up, 0.2mm Layer height no support, infill 20%
|
||||
- The Flex PCB can be ordered via the Gerber File "NanoAP_Gerber.rar"
|
||||
- The Antenna from the Original case needs to be replaced by either a ~3cm wire or the "Antenna_FlexPCB_Gerber.rar"
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -67,6 +67,14 @@ jsonarray = {
|
||||
"tagota": tagota,
|
||||
}
|
||||
|
||||
json_file_path = "files.json"
|
||||
with open(json_file_path, "w") as json_file:
|
||||
with open("jsonfiles/binaries.json", "w") as json_file:
|
||||
json.dump(binaries, json_file, indent=4)
|
||||
|
||||
with open("jsonfiles/files.json", "w") as json_file:
|
||||
json.dump(jsonarray, json_file, indent=4)
|
||||
|
||||
with open("jsonfiles/tagota.json", "w") as json_file:
|
||||
json.dump(tagota, json_file, indent=4)
|
||||
|
||||
with open("jsonfiles/filesystem.json", "w") as json_file:
|
||||
json.dump(files1, json_file, indent=4)
|
||||
|
||||
@@ -20,7 +20,14 @@
|
||||
#define DATATYPE_IMG_RAW_1BPP 0x20 // 2888 bytes for 1.54" / 4736 2.9" / 15000 4.2"
|
||||
#define DATATYPE_IMG_RAW_2BPP 0x21 // 5776 bytes for 1.54" / 9472 2.9" / 30000 4.2"
|
||||
#define DATATYPE_IMG_RAW_1BPP_DIRECT 0x3F // only for 1.54", don't write to EEPROM, but straightaway to the EPD
|
||||
#define DATATYPE_UK_SEGMENTED 0x51 // Segmented data for the UK Segmented display type
|
||||
#define DATATYPE_UK_SEGMENTED 0x51 // Segmented data for the UK Segmented display type (contained in availableData Reply)
|
||||
#define DATATYPE_EU_SEGMENTED 0x52 // Segmented data for the EU/DE Segmented display type (contained in availableData Reply)
|
||||
#define DATATYPE_NFC_RAW_CONTENT 0xA0 // raw memory content for the NT3H1101
|
||||
#define DATATYPE_NFC_URL_DIRECT 0xA1 // URL format for NT3H1101
|
||||
#define DATATYPE_TAG_CONFIG_DATA 0xA8 // Config data for tag
|
||||
#define DATATYPE_COMMAND_DATA 0xAF // Command for the tag to execute (contained in availableData Reply)
|
||||
#define DATATYPE_CUSTOM_LUT_OTA 0xB0 // Custom OTA updated LUT
|
||||
|
||||
#define CMD_DO_REBOOT 0
|
||||
#define CMD_DO_SCAN 1
|
||||
#define CMD_DO_RESET_SETTINGS 2
|
||||
@@ -5,7 +5,7 @@ BUILD ?= zbs29_ssd1619
|
||||
SOURCES += main.c eeprom.c drawing.c
|
||||
SOURCES += comms.c
|
||||
SOURCES += syncedproto.c userinterface.c
|
||||
SOURCES += powermgt.c barcode.c i2cdevices.c
|
||||
SOURCES += powermgt.c barcode.c i2cdevices.c settings.c
|
||||
|
||||
all: #make sure it is the first target
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ bool supportsNFCWake() {
|
||||
}
|
||||
if (pcount < 10000) {
|
||||
// P1_3 (Field Detect) dropped to 'low' pretty fast, this means the load on this pin is high
|
||||
pr("This tag currently does not support NFC wake, load on the FD pin (P1.3) is pretty high.\nOn some boards, a pull-up resistor backpowers the NFC IC. Consider removing it!\n");
|
||||
pr("NFC: This tag currently does not support NFC wake, load on the FD pin (P1.3) is pretty high.\nOn some boards, a pull-up resistor backpowers the NFC IC. Consider removing it!\n");
|
||||
return false;
|
||||
} else {
|
||||
// No reason to believe this pin is currently loaded down severely
|
||||
@@ -121,7 +121,7 @@ bool i2cCheckDevice(uint8_t address) {
|
||||
iictest.deviceAddr = address << 1;
|
||||
uint8_t res = i2cTransact(&iictest, 1);
|
||||
if (res == 0) {
|
||||
pr("Found i2c device at 0x%02X\n", address);
|
||||
pr("I2C: Device found at 0x%02X\n", address);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -23,6 +23,12 @@
|
||||
|
||||
// #define DEBUG_MODE
|
||||
|
||||
static const uint64_t __code __at(0x008b) mVersionRom = 0x1000011300000000ull;
|
||||
|
||||
#define TAG_MODE_CHANSEARCH 0
|
||||
#define TAG_MODE_ASSOCIATED 1
|
||||
uint8_t currentTagMode = TAG_MODE_CHANSEARCH;
|
||||
|
||||
void displayLoop() {
|
||||
powerUp(INIT_BASE | INIT_UART);
|
||||
|
||||
@@ -118,6 +124,7 @@ uint8_t showChannelSelect() { // returns 0 if no accesspoints were found
|
||||
return highestSlot;
|
||||
}
|
||||
uint8_t channelSelect() { // returns 0 if no accesspoints were found
|
||||
powerUp(INIT_RADIO);
|
||||
uint8_t __xdata result[16];
|
||||
memset(result, 0, sizeof(result));
|
||||
|
||||
@@ -128,7 +135,7 @@ uint8_t channelSelect() { // returns 0 if no accesspoints were found
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
powerDown(INIT_RADIO);
|
||||
uint8_t __xdata highestLqi = 0;
|
||||
uint8_t __xdata highestSlot = 0;
|
||||
for (uint8_t c = 0; c < sizeof(result); c++) {
|
||||
@@ -142,79 +149,54 @@ uint8_t channelSelect() { // returns 0 if no accesspoints were found
|
||||
return highestSlot;
|
||||
}
|
||||
|
||||
void main() {
|
||||
// displayLoop(); // remove me
|
||||
setupPortsInitial();
|
||||
powerUp(INIT_BASE | INIT_UART);
|
||||
|
||||
void validateMacAddress() {
|
||||
// check if the mac contains at least some non-0xFF values
|
||||
for (uint8_t __xdata c = 0; c < 8; c++) {
|
||||
if (mSelfMac[c] != 0xFF) goto macIsValid;
|
||||
}
|
||||
// invalid mac address. Display warning screen and sleep forever
|
||||
pr("Mac can't be all FF's.\n");
|
||||
powerUp(INIT_EPD);
|
||||
showNoMAC();
|
||||
powerDown(INIT_EPD | INIT_UART | INIT_EEPROM);
|
||||
doSleep(-1);
|
||||
wdtDeviceReset();
|
||||
macIsValid:
|
||||
return;
|
||||
}
|
||||
uint8_t getFirstWakeUpReason() {
|
||||
if (RESET & 0x01) {
|
||||
wakeUpReason = WAKEUP_REASON_WDT_RESET;
|
||||
pr("WDT reset!\n");
|
||||
} else {
|
||||
wakeUpReason = WAKEUP_REASON_FIRSTBOOT;
|
||||
return WAKEUP_REASON_WDT_RESET;
|
||||
}
|
||||
|
||||
wdt10s();
|
||||
|
||||
boardGetOwnMac(mSelfMac);
|
||||
|
||||
{
|
||||
bool __xdata macSet = false;
|
||||
for (uint8_t __xdata c = 0; c < 8; c++) {
|
||||
if (mSelfMac[c] != 0xFF) {
|
||||
macSet = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!macSet) {
|
||||
pr("Mac can't be all FF's.\n");
|
||||
powerUp(INIT_EPD);
|
||||
showNoMAC();
|
||||
powerDown(INIT_EPD | INIT_UART | INIT_EEPROM);
|
||||
doSleep(-1);
|
||||
wdtDeviceReset();
|
||||
}
|
||||
}
|
||||
|
||||
pr("BOOTED> %d.%d.%d%s\n", fwVersion / 100, (fwVersion % 100) / 10, (fwVersion % 10), fwVersionSuffix);
|
||||
|
||||
return WAKEUP_REASON_FIRSTBOOT;
|
||||
}
|
||||
void checkI2C() {
|
||||
powerUp(INIT_I2C);
|
||||
|
||||
//i2cBusScan();
|
||||
|
||||
// i2cBusScan();
|
||||
if (i2cCheckDevice(0x55)) {
|
||||
powerDown(INIT_I2C);
|
||||
// found something!
|
||||
capabilities |= CAPABILITY_HAS_NFC;
|
||||
if (supportsNFCWake()) {
|
||||
pr("This board supports NFC wake!\n");
|
||||
pr("NFC: NFC Wake Supported\n");
|
||||
capabilities |= CAPABILITY_NFC_WAKE;
|
||||
}
|
||||
} else {
|
||||
pr("I2C: No devices found");
|
||||
// didn't find a NFC chip on the expected ID
|
||||
powerDown(INIT_I2C);
|
||||
}
|
||||
}
|
||||
|
||||
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\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);
|
||||
|
||||
powerUp(INIT_EEPROM);
|
||||
// get the highest slot number, number of slots
|
||||
initializeProto();
|
||||
powerDown(INIT_EEPROM);
|
||||
|
||||
void detectButtonOrJig() {
|
||||
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)
|
||||
// show the screensaver, full LUT (minimal text to prevent image burn-in)
|
||||
powerUp(INIT_EPD);
|
||||
afterFlashScreenSaver();
|
||||
while (1)
|
||||
@@ -225,161 +207,258 @@ void main() {
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// show the splashscreen
|
||||
powerUp(INIT_EPD);
|
||||
showSplashScreen();
|
||||
void TagAssociated() {
|
||||
// associated
|
||||
struct AvailDataInfo *__xdata 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) {
|
||||
doVoltageReading();
|
||||
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();
|
||||
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;
|
||||
}
|
||||
if (tagSettings.enableTagRoaming) {
|
||||
uint8_t roamChannel = channelSelect();
|
||||
if (roamChannel) currentChannel = roamChannel;
|
||||
}
|
||||
} else {
|
||||
powerUp(INIT_RADIO);
|
||||
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.
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t nextCheckin = getNextSleep();
|
||||
longDataReqCounter += nextCheckin;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
// if the AP told us to sleep for a specific period, do so.
|
||||
if (nextCheckInFromAP) {
|
||||
doSleep(nextCheckInFromAP * 60000UL);
|
||||
} else {
|
||||
doSleep(getNextSleep() * 1000UL);
|
||||
}
|
||||
}
|
||||
|
||||
void TagChanSearch() {
|
||||
// not associated
|
||||
if (((scanAttempts != 0) && (scanAttempts % VOLTAGEREADING_DURING_SCAN_INTERVAL == 0)) || (scanAttempts > (INTERVAL_1_ATTEMPTS + INTERVAL_2_ATTEMPTS))) {
|
||||
doVoltageReading();
|
||||
}
|
||||
|
||||
// try to find a working channel
|
||||
currentChannel = channelSelect();
|
||||
|
||||
// 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) {
|
||||
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! set up and bail out of this loop.
|
||||
scanAttempts = 0;
|
||||
wakeUpReason = WAKEUP_REASON_NETWORK_SCAN;
|
||||
initPowerSaving(INTERVAL_BASE);
|
||||
doSleep(getNextSleep() * 1000UL);
|
||||
currentTagMode = TAG_MODE_ASSOCIATED;
|
||||
return;
|
||||
} else {
|
||||
// still not associated
|
||||
doSleep(getNextScanSleep(true) * 1000UL);
|
||||
}
|
||||
}
|
||||
|
||||
void executeCommand(uint8_t cmd) {
|
||||
switch (cmd) {
|
||||
case CMD_DO_REBOOT:
|
||||
wdtDeviceReset();
|
||||
break;
|
||||
case CMD_DO_RESET_SETTINGS:
|
||||
loadDefaultSettings();
|
||||
writeSettings();
|
||||
break;
|
||||
case CMD_DO_SCAN:
|
||||
currentChannel = channelSelect();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void main() {
|
||||
// displayLoop(); // remove me
|
||||
setupPortsInitial();
|
||||
powerUp(INIT_BASE | INIT_UART);
|
||||
pr("BOOTED> %d.%d.%d%s\n", fwVersion / 100, (fwVersion % 100) / 10, (fwVersion % 10), fwVersionSuffix);
|
||||
|
||||
// Find the reason why we're booting; is this a WDT?
|
||||
wakeUpReason = getFirstWakeUpReason();
|
||||
|
||||
// get our own mac address. this is stored in Infopage at offset 0x10-onwards
|
||||
boardGetOwnMac(mSelfMac);
|
||||
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\n", mSelfMac[6], mSelfMac[7]);
|
||||
|
||||
// load settings from infopage
|
||||
loadSettings();
|
||||
|
||||
// get the highest slot number, number of slots
|
||||
initializeProto();
|
||||
|
||||
if (tagSettings.enableFastBoot) {
|
||||
// Fastboot
|
||||
pr("Doing fast boot\n");
|
||||
capabilities = tagSettings.fastBootCapabilities;
|
||||
if (tagSettings.fixedChannel) {
|
||||
currentChannel = tagSettings.fixedChannel;
|
||||
} else {
|
||||
currentChannel = channelSelect();
|
||||
}
|
||||
} else {
|
||||
// Normal boot/startup
|
||||
|
||||
// validate the mac address; this will display a warning on the screen if the mac address is invalid
|
||||
validateMacAddress();
|
||||
|
||||
#if (NFC_TYPE == 1)
|
||||
// initialize I2C
|
||||
checkI2C();
|
||||
#endif
|
||||
|
||||
// Get a voltage reading on the tag, loading down the battery with the radio
|
||||
doVoltageReading();
|
||||
|
||||
// detect button or jig
|
||||
detectButtonOrJig();
|
||||
|
||||
// show the splashscreen
|
||||
pr("EPD: First powerup\n");
|
||||
powerUp(INIT_EPD);
|
||||
showSplashScreen();
|
||||
|
||||
// we've now displayed something on the screen; for the SSD1619, we are now aware of the lut-size
|
||||
#ifdef EPD_SSD1619
|
||||
capabilities |= CAPABILITY_SUPPORTS_CUSTOM_LUTS;
|
||||
if (dispLutSize != 7) {
|
||||
capabilities |= CAPABILITY_ALT_LUT_SIZE;
|
||||
}
|
||||
capabilities |= CAPABILITY_SUPPORTS_CUSTOM_LUTS;
|
||||
if (dispLutSize != 7) {
|
||||
capabilities |= CAPABILITY_ALT_LUT_SIZE;
|
||||
}
|
||||
#endif
|
||||
tagSettings.fastBootCapabilities = capabilities;
|
||||
|
||||
powerUp(INIT_EPD);
|
||||
wdt30s();
|
||||
currentChannel = showChannelSelect();
|
||||
// now that we've collected all possible capabilities, save it to settings
|
||||
writeSettings();
|
||||
|
||||
// scan for channels
|
||||
powerUp(INIT_EPD);
|
||||
wdt30s();
|
||||
if (tagSettings.fixedChannel) {
|
||||
currentChannel = tagSettings.fixedChannel;
|
||||
} else {
|
||||
currentChannel = showChannelSelect();
|
||||
}
|
||||
}
|
||||
|
||||
// end of the fastboot option split
|
||||
wdt10s();
|
||||
|
||||
powerUp(INIT_EPD);
|
||||
if (currentChannel) {
|
||||
showAPFound();
|
||||
initPowerSaving(INTERVAL_BASE);
|
||||
powerDown(INIT_EPD | INIT_UART);
|
||||
currentTagMode = TAG_MODE_ASSOCIATED;
|
||||
doSleep(5000UL);
|
||||
} else {
|
||||
showNoAP();
|
||||
initPowerSaving(INTERVAL_AT_MAX_ATTEMPTS);
|
||||
powerDown(INIT_EPD | INIT_UART);
|
||||
currentTagMode = TAG_MODE_CHANSEARCH;
|
||||
doSleep(120000UL);
|
||||
}
|
||||
|
||||
// this is the loop we'll stay in forever, basically.
|
||||
while (1) {
|
||||
powerUp(INIT_UART);
|
||||
wdt10s();
|
||||
if (currentChannel) {
|
||||
// associated
|
||||
|
||||
struct AvailDataInfo *__xdata avail;
|
||||
// Is there any reason why we should do a long (full) get data request (including reason, status)?
|
||||
if ((longDataReqCounter > LONG_DATAREQ_INTERVAL) || wakeUpReason != WAKEUP_REASON_TIMED) {
|
||||
// check if we should do a voltage measurement (those are pretty expensive)
|
||||
if (voltageCheckCounter == VOLTAGE_CHECK_INTERVAL) {
|
||||
powerUp(INIT_RADIO); // load down the battery using the radio to get a good reading
|
||||
powerUp(INIT_TEMPREADING | INIT_EPD_VOLTREADING);
|
||||
powerDown(INIT_RADIO);
|
||||
voltageCheckCounter = 0;
|
||||
} else {
|
||||
powerUp(INIT_TEMPREADING);
|
||||
}
|
||||
voltageCheckCounter++;
|
||||
|
||||
// check if the battery level is below minimum, and force a redraw of the screen
|
||||
if ((lowBattery && !lowBatteryShown) || (noAPShown)) {
|
||||
// Check if we were already displaying an image
|
||||
if (curImgSlot != 0xFF) {
|
||||
powerUp(INIT_EEPROM | INIT_EPD);
|
||||
wdt60s();
|
||||
drawImageFromEeprom(curImgSlot);
|
||||
powerDown(INIT_EEPROM | INIT_EPD);
|
||||
} else {
|
||||
powerUp(INIT_EPD);
|
||||
showAPFound();
|
||||
powerDown(INIT_EPD);
|
||||
}
|
||||
}
|
||||
powerUp(INIT_RADIO);
|
||||
avail = getAvailDataInfo();
|
||||
powerDown(INIT_RADIO);
|
||||
|
||||
if (avail != NULL) {
|
||||
// we got some data!
|
||||
longDataReqCounter = 0;
|
||||
// since we've had succesful contact, and communicated the wakeup reason succesfully, we can now reset to the 'normal' status
|
||||
wakeUpReason = WAKEUP_REASON_TIMED;
|
||||
}
|
||||
} else {
|
||||
powerUp(INIT_RADIO);
|
||||
avail = getShortAvailDataInfo();
|
||||
powerDown(INIT_RADIO);
|
||||
}
|
||||
|
||||
addAverageValue();
|
||||
|
||||
if (avail == NULL) {
|
||||
// no data :(
|
||||
nextCheckInFromAP = 0; // let the power-saving algorithm determine the next sleep period
|
||||
} else {
|
||||
nextCheckInFromAP = avail->nextCheckIn;
|
||||
// got some data from the AP!
|
||||
if (avail->dataType != DATATYPE_NOUPDATE) {
|
||||
// data transfer
|
||||
if (processAvailDataInfo(avail)) {
|
||||
// succesful transfer, next wake time is determined by the NextCheckin;
|
||||
} else {
|
||||
// failed transfer, let the algorithm determine next sleep interval (not the AP)
|
||||
nextCheckInFromAP = 0;
|
||||
}
|
||||
} else {
|
||||
// no data transfer, just sleep.
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t nextCheckin = getNextSleep();
|
||||
longDataReqCounter += nextCheckin;
|
||||
if (nextCheckin == INTERVAL_AT_MAX_ATTEMPTS) {
|
||||
// disconnected, obviously...
|
||||
currentChannel = 0;
|
||||
}
|
||||
|
||||
// if the AP told us to sleep for a specific period, do so.
|
||||
if (nextCheckInFromAP) {
|
||||
doSleep(nextCheckInFromAP * 60000UL);
|
||||
} else {
|
||||
doSleep(getNextSleep() * 1000UL);
|
||||
}
|
||||
|
||||
} else {
|
||||
// not associated
|
||||
if (((scanAttempts != 0) && (scanAttempts % VOLTAGEREADING_DURING_SCAN_INTERVAL == 0)) || (scanAttempts > (INTERVAL_1_ATTEMPTS + INTERVAL_2_ATTEMPTS))) {
|
||||
powerUp(INIT_RADIO); // load down the battery using the radio to get a good reading
|
||||
powerUp(INIT_EPD_VOLTREADING);
|
||||
powerDown(INIT_RADIO);
|
||||
}
|
||||
// try to find a working channel
|
||||
powerUp(INIT_RADIO);
|
||||
currentChannel = channelSelect();
|
||||
powerDown(INIT_RADIO);
|
||||
|
||||
if ((!currentChannel && !noAPShown) || (lowBattery && !lowBatteryShown) || (scanAttempts == (INTERVAL_1_ATTEMPTS + INTERVAL_2_ATTEMPTS - 1))) {
|
||||
powerUp(INIT_EPD);
|
||||
wdt60s();
|
||||
if (curImgSlot != 0xFF) {
|
||||
powerUp(INIT_EEPROM);
|
||||
drawImageFromEeprom(curImgSlot);
|
||||
powerDown(INIT_EEPROM);
|
||||
} else if ((scanAttempts >= (INTERVAL_1_ATTEMPTS + INTERVAL_2_ATTEMPTS - 1))) {
|
||||
showLongTermSleep();
|
||||
} else {
|
||||
showNoAP();
|
||||
}
|
||||
powerDown(INIT_EPD);
|
||||
}
|
||||
|
||||
// did we find a working channel?
|
||||
if (currentChannel) {
|
||||
// now associated!
|
||||
scanAttempts = 0;
|
||||
wakeUpReason = WAKEUP_REASON_NETWORK_SCAN;
|
||||
initPowerSaving(INTERVAL_BASE);
|
||||
doSleep(getNextSleep() * 1000UL);
|
||||
|
||||
} else {
|
||||
// still not associated
|
||||
doSleep(getNextScanSleep(true) * 1000UL);
|
||||
}
|
||||
switch (currentTagMode) {
|
||||
case TAG_MODE_ASSOCIATED:
|
||||
TagAssociated();
|
||||
break;
|
||||
case TAG_MODE_CHANSEARCH:
|
||||
TagChanSearch();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
45
zbs243_Tag_FW/main.lk
Normal file
45
zbs243_Tag_FW/main.lk
Normal file
@@ -0,0 +1,45 @@
|
||||
-muwx
|
||||
-i main.ihx
|
||||
-M
|
||||
-X 0x2000
|
||||
-C 0xfc00
|
||||
-b HOME = 0x0000
|
||||
-b XSEG = 0xe000
|
||||
-b PSEG = 0xe000
|
||||
-b ISEG = 0x0000
|
||||
-b BSEG = 0x0000
|
||||
-k /usr/local/bin/../share/sdcc/lib/large
|
||||
-k /usr/local/share/sdcc/lib/large
|
||||
-l mcs51
|
||||
-l libsdcc
|
||||
-l libint
|
||||
-l liblong
|
||||
-l libfloat
|
||||
main.rel
|
||||
eeprom.rel
|
||||
drawing.rel
|
||||
comms.rel
|
||||
syncedproto.rel
|
||||
userinterface.rel
|
||||
powermgt.rel
|
||||
barcode.rel
|
||||
i2cdevices.rel
|
||||
settings.rel
|
||||
soc/zbs243/soc.rel
|
||||
soc/zbs243/wdt.rel
|
||||
soc/zbs243/sleep.rel
|
||||
soc/zbs243/spi.rel
|
||||
soc/zbs243/uart.rel
|
||||
soc/zbs243/timer.rel
|
||||
soc/zbs243/radio.rel
|
||||
soc/zbs243/flash.rel
|
||||
soc/zbs243/temperature.rel
|
||||
cpu/8051/random.rel
|
||||
cpu/8051/printf.rel
|
||||
soc/zbs243/i2c.rel
|
||||
cpu/8051/asmUtil.rel
|
||||
cpu/8051/cpu.rel
|
||||
board/zbs29_uc8151/board.rel
|
||||
board/zbs29_uc8151/screen.rel
|
||||
|
||||
-e
|
||||
@@ -34,7 +34,7 @@ uint8_t __xdata wakeUpReason = 0;
|
||||
uint8_t __xdata scanAttempts = 0;
|
||||
|
||||
int8_t __xdata temperature = 0;
|
||||
uint16_t __xdata batteryVoltage = 0;
|
||||
uint16_t __xdata batteryVoltage = 2600;
|
||||
bool __xdata lowBattery = false;
|
||||
uint16_t __xdata longDataReqCounter = 0;
|
||||
uint16_t __xdata voltageCheckCounter = 0;
|
||||
@@ -153,10 +153,11 @@ static void configI2C(const bool setup) {
|
||||
if (setup) {
|
||||
P1DIR &= ~(1 << 6);
|
||||
P1_6 = 1;
|
||||
timerDelay(13330);
|
||||
P1FUNC |= (1 << 4) | (1 << 5);
|
||||
P1PULL |= (1 << 4) | (1 << 5);
|
||||
i2cInit();
|
||||
i2cCheckDevice(0x50); // first transaction after init fails, this makes sure everything is ready for the first transaction
|
||||
// i2cCheckDevice(0x50); // first transaction after init fails, this makes sure everything is ready for the first transaction
|
||||
} else {
|
||||
P1DIR |= (1 << 6);
|
||||
P1_6 = 0;
|
||||
@@ -174,6 +175,7 @@ void powerUp(const uint8_t parts) {
|
||||
timerInit();
|
||||
irqsOn();
|
||||
wdtOn();
|
||||
wdt10s();
|
||||
}
|
||||
|
||||
if (parts & INIT_EPD) {
|
||||
@@ -186,7 +188,7 @@ void powerUp(const uint8_t parts) {
|
||||
epdConfigGPIO(true);
|
||||
configSPI(true);
|
||||
batteryVoltage = epdGetBattery();
|
||||
if (batteryVoltage < BATTERY_VOLTAGE_MINIMUM) {
|
||||
if (batteryVoltage < tagSettings.batLowVoltage) {
|
||||
lowBattery = true;
|
||||
} else {
|
||||
lowBattery = false;
|
||||
@@ -302,7 +304,12 @@ void doSleep(const uint32_t __xdata t) {
|
||||
P1CHSTA &= ~(1 << 3);
|
||||
}
|
||||
|
||||
// sleepy
|
||||
if (tagSettings.enableRFWake) {
|
||||
// enabled RF wake, adds a little extra energy draw!
|
||||
RADIO_RadioPowerCtl &= 0xFB;
|
||||
}
|
||||
|
||||
// sleepy time
|
||||
sleepForMsec(t);
|
||||
P1INTEN = 0;
|
||||
if ((P1CHSTA & (1 << 0)) && (capabilities & CAPABILITY_HAS_WAKE_BUTTON)) {
|
||||
@@ -316,6 +323,12 @@ void doSleep(const uint32_t __xdata t) {
|
||||
}
|
||||
}
|
||||
|
||||
void doVoltageReading() {
|
||||
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);
|
||||
}
|
||||
|
||||
uint32_t getNextScanSleep(const bool increment) {
|
||||
if (increment) {
|
||||
if (scanAttempts < 255)
|
||||
@@ -346,5 +359,8 @@ uint16_t getNextSleep() {
|
||||
avg += dataReqAttemptArr[c];
|
||||
}
|
||||
avg /= POWER_SAVING_SMOOTHING;
|
||||
|
||||
// check if we should sleep longer due to an override in the config
|
||||
if (avg < tagSettings.minimumCheckInTime) return tagSettings.minimumCheckInTime;
|
||||
return avg;
|
||||
}
|
||||
@@ -55,6 +55,8 @@ extern void powerDown(const uint8_t parts);
|
||||
extern void initAfterWake();
|
||||
extern void doSleep(const uint32_t __xdata t);
|
||||
|
||||
void doVoltageReading();
|
||||
|
||||
extern void addAverageValue();
|
||||
extern uint16_t getNextSleep();
|
||||
|
||||
|
||||
95
zbs243_Tag_FW/settings.c
Executable file
95
zbs243_Tag_FW/settings.c
Executable file
@@ -0,0 +1,95 @@
|
||||
#include "settings.h"
|
||||
|
||||
#include <flash.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "asmUtil.h"
|
||||
#include "powermgt.h"
|
||||
#include "printf.h"
|
||||
#include "syncedproto.h"
|
||||
|
||||
struct tagsettings __xdata tagSettings = {0};
|
||||
extern uint8_t __xdata blockXferBuffer[];
|
||||
uint8_t* __xdata infopageTempBuffer = 1024 + blockXferBuffer;
|
||||
|
||||
#define INFOPAGE_SETTINGS_OFFSET 0x50
|
||||
|
||||
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) {
|
||||
pr("SETTINGS: received settings from AP\n");
|
||||
switch (*p) {
|
||||
case SETTINGS_STRUCT_VERSION: // the current tag struct
|
||||
pr("SETTINGS: received matching version\n");
|
||||
memcpy((void*)tagSettings, (void*)p, sizeof(struct tagsettings));
|
||||
break;
|
||||
default:
|
||||
pr("SETTINGS: received something we couldn't really process, version %d\n");
|
||||
break;
|
||||
}
|
||||
tagSettings.fastBootCapabilities = capabilities;
|
||||
writeSettings();
|
||||
}
|
||||
|
||||
static bool compareSettings() {
|
||||
// check if the settings match the settings in the infopage
|
||||
flashRead(FLASH_INFOPAGE_ADDR + INFOPAGE_SETTINGS_OFFSET, (void*)infopageTempBuffer, sizeof(struct tagsettings));
|
||||
if (memcmp((void*)infopageTempBuffer, (void*)tagSettings, sizeof(struct tagsettings)) == 0) {
|
||||
// same
|
||||
return true;
|
||||
}
|
||||
// different
|
||||
return false;
|
||||
}
|
||||
|
||||
static void upgradeSettings() {
|
||||
// add an upgrade strategy whenever you update the struct version
|
||||
}
|
||||
|
||||
void loadSettings() {
|
||||
flashRead((FLASH_INFOPAGE_ADDR + INFOPAGE_SETTINGS_OFFSET), (void*)infopageTempBuffer, sizeof(struct tagsettings));
|
||||
xMemCopy((void*)tagSettings, (void*)infopageTempBuffer, sizeof(struct tagsettings));
|
||||
if (tagSettings.settingsVer == 0xFF) {
|
||||
// settings not set. load the defaults
|
||||
loadDefaultSettings();
|
||||
pr("SETTINGS: Loaded default settings\n");
|
||||
} else {
|
||||
if (tagSettings.settingsVer < SETTINGS_STRUCT_VERSION) {
|
||||
// upgrade
|
||||
upgradeSettings();
|
||||
pr("SETTINGS: Upgraded from previous version\n");
|
||||
} else {
|
||||
// settings are valid
|
||||
pr("SETTINGS: Loaded from infopage\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void writeSettings() {
|
||||
if (compareSettings()) {
|
||||
pr("SETTINGS: Settings matched current settings\n");
|
||||
return;
|
||||
}
|
||||
flashRead(FLASH_INFOPAGE_ADDR, (void*)infopageTempBuffer, 1024);
|
||||
xMemCopy((void*)(infopageTempBuffer + INFOPAGE_SETTINGS_OFFSET), (void*)tagSettings, sizeof(tagSettings));
|
||||
flashErase(FLASH_INFOPAGE_ADDR + 1);
|
||||
flashWrite(FLASH_INFOPAGE_ADDR, (void*)infopageTempBuffer, 1024, false);
|
||||
pr("SETTINGS: Updated settings in infopage\n");
|
||||
}
|
||||
@@ -3,8 +3,39 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define FW_VERSION 017 // version number (max 2.5.5 :) )
|
||||
#define FW_VERSION_SUFFIX "-CLUT" // suffix, like -RC1 or whatever.
|
||||
#define FW_VERSION 18 // version number (max 2.5.5 :) )
|
||||
#define FW_VERSION_SUFFIX "-RW" // 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
|
||||
|
||||
#define SETTINGS_STRUCT_VERSION 0x01
|
||||
|
||||
#define DEFAULT_SETTING_FASTBOOT 0
|
||||
#define DEFAULT_SETTING_RFWAKE 0
|
||||
#define DEFAULT_SETTING_TAGROAMING 0
|
||||
#define DEFAULT_SETTING_SCANFORAP 1
|
||||
#define DEFAULT_SETTING_LOWBATSYMBOL 1
|
||||
#define DEFAULT_SETTING_NORFSYMBOL 1
|
||||
|
||||
struct tagsettings {
|
||||
uint8_t settingsVer; // the version of the struct as written to the infopage
|
||||
uint8_t enableFastBoot; // default 0; if set, it will skip splashscreen
|
||||
uint8_t enableRFWake; // default 0; if set, it will enable RF wake. This will add about ~0.9µA idle power consumption
|
||||
uint8_t enableTagRoaming; // default 0; if set, the tag will scan for an accesspoint every few check-ins. This will increase power consumption quite a bit
|
||||
uint8_t enableScanForAPAfterTimeout; // default 1; if a the tag failed to check in, after a few attempts it will try to find a an AP on other channels
|
||||
uint8_t enableLowBatSymbol; // default 1; tag will show 'low battery' icon on screen if the battery is depleted
|
||||
uint8_t enableNoRFSymbol; // default 1; tag will show 'no signal' icon on screen if it failed to check in for a longer period of time
|
||||
uint8_t fastBootCapabilities; // holds the byte with 'capabilities' as detected during a normal tag boot; allows the tag to skip detecting buttons and NFC chip
|
||||
uint8_t customMode; // default 0; if anything else, tag will bootup in a different 'mode'
|
||||
uint16_t batLowVoltage; // Low battery threshold voltage (2450 for 2.45v). defaults to BATTERY_VOLTAGE_MINIMUM from powermgt.h
|
||||
uint16_t minimumCheckInTime; // defaults to BASE_INTERVAL from powermgt.h
|
||||
uint8_t fixedChannel; // default 0; if set to a valid channel number, the tag will stick to that channel
|
||||
} __packed;
|
||||
|
||||
extern struct tagsettings tagSettings;
|
||||
|
||||
void loadDefaultSettings();
|
||||
void writeSettings();
|
||||
void loadSettings();
|
||||
void loadSettingsFromBuffer(uint8_t* p);
|
||||
#endif
|
||||
@@ -50,6 +50,8 @@ uint8_t __xdata currentChannel = 0;
|
||||
static uint8_t __xdata inBuffer[128] = {0};
|
||||
static uint8_t __xdata outBuffer[128] = {0};
|
||||
|
||||
extern void executeCommand(uint8_t cmd); // this is defined in main.c
|
||||
|
||||
// tools
|
||||
static uint8_t __xdata getPacketType(const void *__xdata buffer) {
|
||||
const struct MacFcs *__xdata fcs = buffer;
|
||||
@@ -471,6 +473,7 @@ static uint32_t getHighSlotId() {
|
||||
return temp;
|
||||
}
|
||||
|
||||
// data transfer stuff
|
||||
static uint8_t __xdata partsThisBlock = 0;
|
||||
static uint8_t __xdata blockAttempts = 0; // these CAN be local to the function, but for some reason, they won't survive sleep?
|
||||
// they get overwritten with 7F 32 44 20 00 00 00 00 11, I don't know why.
|
||||
@@ -570,6 +573,7 @@ static bool getDataBlock(const uint16_t blockSize) {
|
||||
pr("failed getting block\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
uint16_t __xdata dataRequestSize = 0;
|
||||
static bool downloadFWUpdate(const struct AvailDataInfo *__xdata avail) {
|
||||
// check if we already started the transfer of this information & haven't completed it
|
||||
@@ -847,6 +851,37 @@ bool processAvailDataInfo(struct AvailDataInfo *__xdata avail) {
|
||||
}
|
||||
return false;
|
||||
break;
|
||||
case DATATYPE_TAG_CONFIG_DATA:
|
||||
if (curDataInfo.dataSize == 0 && xMemEqual((const void *__xdata) & avail->dataVer, (const void *__xdata) & curDataInfo.dataVer, 8)) {
|
||||
pr("this was the same as the last transfer, disregard\n");
|
||||
powerUp(INIT_RADIO);
|
||||
sendXferComplete();
|
||||
powerDown(INIT_RADIO);
|
||||
return true;
|
||||
}
|
||||
curBlock.blockId = 0;
|
||||
xMemCopy8(&(curBlock.ver), &(avail->dataVer));
|
||||
curBlock.type = avail->dataType;
|
||||
xMemCopyShort(&curDataInfo, (void *)avail, sizeof(struct AvailDataInfo));
|
||||
wdt10s();
|
||||
if (getDataBlock(avail->dataSize)) {
|
||||
curDataInfo.dataSize = 0; // mark as transfer not pending
|
||||
loadSettingsFromBuffer(sizeof(struct blockData) + blockXferBuffer);
|
||||
powerUp(INIT_RADIO);
|
||||
sendXferComplete();
|
||||
powerDown(INIT_RADIO);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
break;
|
||||
case DATATYPE_COMMAND_DATA:
|
||||
pr("CMD received\n");
|
||||
powerUp(INIT_RADIO);
|
||||
sendXferComplete();
|
||||
powerDown(INIT_RADIO);
|
||||
executeCommand(avail->dataTypeArgument);
|
||||
return true;
|
||||
break;
|
||||
case DATATYPE_CUSTOM_LUT_OTA:
|
||||
// Handle data for the NFC IC (if we have it)
|
||||
|
||||
@@ -874,7 +909,7 @@ bool processAvailDataInfo(struct AvailDataInfo *__xdata avail) {
|
||||
wdt10s();
|
||||
if (getDataBlock(avail->dataSize)) {
|
||||
curDataInfo.dataSize = 0; // mark as transfer not pending
|
||||
memcpy(customLUT, sizeof(struct blockData) + blockXferBuffer, dispLutSize * 10);
|
||||
memcpy(customLUT, sizeof(struct blockData) + blockXferBuffer, 6 + (dispLutSize * 10));
|
||||
powerUp(INIT_RADIO);
|
||||
sendXferComplete();
|
||||
powerDown(INIT_RADIO);
|
||||
@@ -888,6 +923,8 @@ bool processAvailDataInfo(struct AvailDataInfo *__xdata avail) {
|
||||
}
|
||||
|
||||
void initializeProto() {
|
||||
powerUp(INIT_EEPROM);
|
||||
getNumSlots();
|
||||
curHighSlotId = getHighSlotId();
|
||||
powerDown(INIT_EEPROM);
|
||||
}
|
||||
2
zbs243_Tag_FW/syncedproto.h
Normal file → Executable file
2
zbs243_Tag_FW/syncedproto.h
Normal file → Executable file
@@ -13,7 +13,7 @@ extern uint8_t __xdata curImgSlot;
|
||||
extern void setupRadio(void);
|
||||
extern void killRadio(void);
|
||||
|
||||
|
||||
void dump(const uint8_t *__xdata a, const uint16_t __xdata l);
|
||||
extern struct AvailDataInfo *__xdata getAvailDataInfo();
|
||||
extern struct AvailDataInfo *__xdata getShortAvailDataInfo();
|
||||
extern void drawImageFromEeprom(const uint8_t imgSlot);
|
||||
|
||||
@@ -51,7 +51,7 @@ void addCapabilities() {
|
||||
}
|
||||
|
||||
void addOverlay() {
|
||||
if (currentChannel == 0) {
|
||||
if ((currentChannel == 0)&&(tagSettings.enableNoRFSymbol)) {
|
||||
#if (SCREEN_WIDTH == 152)
|
||||
loadRawBitmap(ant, SCREEN_WIDTH - 16, 0, EPD_COLOR_BLACK);
|
||||
loadRawBitmap(cross, SCREEN_WIDTH - 8, 7, EPD_COLOR_RED);
|
||||
@@ -67,7 +67,7 @@ void addOverlay() {
|
||||
noAPShown = false;
|
||||
}
|
||||
|
||||
if (batteryVoltage != 2600) {
|
||||
if ((batteryVoltage < tagSettings.batLowVoltage) && (tagSettings.enableLowBatSymbol)) {
|
||||
#if (SCREEN_WIDTH == 152)
|
||||
loadRawBitmap(battery, SCREEN_WIDTH - 16, SCREEN_HEIGHT - 10, EPD_COLOR_BLACK);
|
||||
#elif (SCREEN_WIDTH == 400)
|
||||
@@ -81,7 +81,6 @@ void addOverlay() {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void afterFlashScreenSaver() {
|
||||
selectLUT(EPD_LUT_DEFAULT);
|
||||
clearScreen();
|
||||
@@ -106,7 +105,6 @@ void afterFlashScreenSaver() {
|
||||
drawWithSleep();
|
||||
}
|
||||
|
||||
|
||||
void showSplashScreen() {
|
||||
selectLUT(EPD_LUT_NO_REPEATS);
|
||||
clearScreen();
|
||||
|
||||
@@ -42,6 +42,11 @@
|
||||
#define CMD_YSTART_POS 0x4F
|
||||
#define CMD_ANALOG_BLK_CTRL 0x74
|
||||
#define CMD_DIGITAL_BLK_CTRL 0x7E
|
||||
// added for OTA LUT-support
|
||||
#define CMD_GATE_LEVEL 0x03
|
||||
#define CMD_SOURCE_LEVEL 0x04
|
||||
#define CMD_DUMMY_PERIOD 0x3A
|
||||
#define CMD_GATE_LINE_WIDTH 0x3B
|
||||
|
||||
#define SCREEN_CMD_CLOCK_ON 0x80
|
||||
#define SCREEN_CMD_CLOCK_OFF 0x01
|
||||
@@ -83,7 +88,7 @@ bool __xdata epdGPIOActive = false;
|
||||
|
||||
#define LUT_BUFFER_SIZE 128
|
||||
static uint8_t waveformbuffer[LUT_BUFFER_SIZE];
|
||||
uint8_t __xdata customLUT[LUT_BUFFER_SIZE] = {0};
|
||||
uint8_t __xdata customLUT[LUT_BUFFER_SIZE] = {0};
|
||||
|
||||
struct waveform10* __xdata waveform10 = (struct waveform10*)waveformbuffer; // holds the LUT/waveform
|
||||
struct waveform* __xdata waveform7 = (struct waveform*)waveformbuffer; // holds the LUT/waveform
|
||||
@@ -378,14 +383,6 @@ void selectLUT(uint8_t 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?
|
||||
@@ -447,6 +444,22 @@ void selectLUT(uint8_t lut) {
|
||||
break;
|
||||
}
|
||||
|
||||
// Handling if we received an OTA LUT
|
||||
if (lut == EPD_LUT_OTA) {
|
||||
memcpy(waveformbuffer, customLUT, dispLutSize * 10);
|
||||
writeLut();
|
||||
shortCommand1(CMD_GATE_LEVEL, customLUT[70]);
|
||||
commandBegin(CMD_SOURCE_LEVEL);
|
||||
epdSend(customLUT[71]);
|
||||
epdSend(customLUT[72]);
|
||||
epdSend(customLUT[73]);
|
||||
commandEnd();
|
||||
shortCommand1(CMD_DUMMY_PERIOD, customLUT[74]);
|
||||
shortCommand1(CMD_GATE_LINE_WIDTH, customLUT[75]);
|
||||
currentLut = lut;
|
||||
return;
|
||||
}
|
||||
|
||||
if (dispLutSize == 10) {
|
||||
lutGroupDisable(LUTGROUP_UNUSED);
|
||||
lutGroupDisable(LUTGROUP_UNKNOWN);
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
|
||||
#define HAS_EEPROM 1
|
||||
#define HAS_SCREEN 1
|
||||
#define NFC_TYPE 1
|
||||
#define AP_EMULATE_TAG 1
|
||||
|
||||
//hw types
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
|
||||
#define HAS_EEPROM 1
|
||||
#define HAS_SCREEN 1
|
||||
#define NFC_TYPE 1
|
||||
#define AP_EMULATE_TAG 1
|
||||
|
||||
//hw types
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
|
||||
#define HAS_EEPROM 1
|
||||
#define HAS_SCREEN 1
|
||||
#define NFC_TYPE 1
|
||||
#define AP_EMULATE_TAG 1
|
||||
|
||||
//hw types
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
|
||||
#define HAS_EEPROM 1
|
||||
#define HAS_SCREEN 1
|
||||
#define NFC_TYPE 2
|
||||
#define AP_EMULATE_TAG 1
|
||||
|
||||
//hw types
|
||||
|
||||
Reference in New Issue
Block a user